| // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <string> |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| #include "chaps/object_mock.h" |
| #include "chaps/object_policy_cert.h" |
| #include "chaps/object_policy_data.h" |
| #include "chaps/object_policy_secret_key.h" |
| |
| using std::string; |
| using ::testing::_; |
| using ::testing::AnyNumber; |
| using ::testing::Invoke; |
| using ::testing::Return; |
| using ::testing::SetArgPointee; |
| |
| namespace chaps { |
| |
| // Test fixture for an initialized ObjectImpl instance. |
| class TestObjectPolicy : public ::testing::Test { |
| public: |
| TestObjectPolicy() { |
| object_.SetupFake(); |
| EXPECT_CALL(object_, GetObjectClass()).Times(AnyNumber()); |
| EXPECT_CALL(object_, GetAttributeBool(_, _)).Times(AnyNumber()); |
| EXPECT_CALL(object_, SetAttributeBool(_, _)).Times(AnyNumber()); |
| EXPECT_CALL(object_, GetAttributeInt(_, _)).Times(AnyNumber()); |
| EXPECT_CALL(object_, SetAttributeInt(_, _)).Times(AnyNumber()); |
| EXPECT_CALL(object_, GetAttributeString(_)).Times(AnyNumber()); |
| EXPECT_CALL(object_, SetAttributeString(_, _)).Times(AnyNumber()); |
| EXPECT_CALL(object_, SetAttributes(_, _)).Times(AnyNumber()); |
| EXPECT_CALL(object_, IsAttributePresent(_)).Times(AnyNumber()); |
| EXPECT_CALL(object_, RemoveAttribute(_)).Times(AnyNumber()); |
| EXPECT_CALL(object_, GetStage()).WillRepeatedly(Return(kCreate)); |
| } |
| |
| ObjectMock object_; |
| }; |
| |
| TEST(DeathTest, NotInit) { |
| ObjectPolicyData policy; |
| EXPECT_DEATH_IF_SUPPORTED(policy.IsReadAllowed(CKA_CLASS), "Check failed"); |
| EXPECT_DEATH_IF_SUPPORTED(policy.IsModifyAllowed(CKA_CLASS, ""), |
| "Check failed"); |
| EXPECT_DEATH_IF_SUPPORTED(policy.IsObjectComplete(), "Check failed"); |
| EXPECT_DEATH_IF_SUPPORTED(policy.SetDefaultAttributes(), "Check failed"); |
| } |
| |
| TEST_F(TestObjectPolicy, IsReadAllowed) { |
| ObjectPolicySecretKey policy; |
| policy.Init(&object_); |
| EXPECT_TRUE(policy.IsReadAllowed(CKA_CLASS)); |
| EXPECT_TRUE(policy.IsReadAllowed(CKA_DEFAULT_CMS_ATTRIBUTES)); |
| EXPECT_FALSE(policy.IsReadAllowed(CKA_VALUE)); |
| object_.SetAttributeBool(CKA_SENSITIVE, true); |
| object_.SetAttributeBool(CKA_EXTRACTABLE, false); |
| EXPECT_FALSE(policy.IsReadAllowed(CKA_VALUE)); |
| object_.SetAttributeBool(CKA_SENSITIVE, false); |
| object_.SetAttributeBool(CKA_EXTRACTABLE, true); |
| EXPECT_TRUE(policy.IsReadAllowed(CKA_VALUE)); |
| } |
| |
| TEST_F(TestObjectPolicy, IsModifyAllowed) { |
| ObjectPolicySecretKey policy; |
| policy.Init(&object_); |
| // Create stage. |
| EXPECT_CALL(object_, GetStage()).WillRepeatedly(Return(kCreate)); |
| EXPECT_TRUE(policy.IsModifyAllowed(CKA_LABEL, "")); |
| EXPECT_TRUE(policy.IsModifyAllowed(CKA_PRIVATE, "")); |
| EXPECT_TRUE(policy.IsModifyAllowed(CKA_TOKEN, "")); |
| EXPECT_FALSE(policy.IsModifyAllowed(CKA_LOCAL, "")); |
| // Copy stage. |
| EXPECT_CALL(object_, GetStage()).WillRepeatedly(Return(kCopy)); |
| EXPECT_TRUE(policy.IsModifyAllowed(CKA_LABEL, "")); |
| EXPECT_TRUE(policy.IsModifyAllowed(CKA_PRIVATE, "")); |
| EXPECT_FALSE(policy.IsModifyAllowed(CKA_TOKEN, "")); |
| EXPECT_FALSE(policy.IsModifyAllowed(CKA_LOCAL, "")); |
| // Modify stage. |
| EXPECT_CALL(object_, GetStage()).WillRepeatedly(Return(kModify)); |
| EXPECT_TRUE(policy.IsModifyAllowed(CKA_LABEL, "")); |
| EXPECT_FALSE(policy.IsModifyAllowed(CKA_PRIVATE, "")); |
| EXPECT_FALSE(policy.IsModifyAllowed(CKA_TOKEN, "")); |
| EXPECT_FALSE(policy.IsModifyAllowed(CKA_LOCAL, "")); |
| // Special cases. |
| string false_str(1, 0); |
| string true_str(1, 1); |
| object_.SetAttributeBool(CKA_SENSITIVE, false); |
| EXPECT_TRUE(policy.IsModifyAllowed(CKA_SENSITIVE, false_str)); |
| EXPECT_TRUE(policy.IsModifyAllowed(CKA_SENSITIVE, true_str)); |
| object_.SetAttributeBool(CKA_SENSITIVE, true); |
| EXPECT_FALSE(policy.IsModifyAllowed(CKA_SENSITIVE, false_str)); |
| EXPECT_TRUE(policy.IsModifyAllowed(CKA_SENSITIVE, true_str)); |
| object_.SetAttributeBool(CKA_EXTRACTABLE, true); |
| EXPECT_TRUE(policy.IsModifyAllowed(CKA_EXTRACTABLE, false_str)); |
| EXPECT_TRUE(policy.IsModifyAllowed(CKA_EXTRACTABLE, true_str)); |
| object_.SetAttributeBool(CKA_EXTRACTABLE, false); |
| EXPECT_TRUE(policy.IsModifyAllowed(CKA_EXTRACTABLE, false_str)); |
| EXPECT_FALSE(policy.IsModifyAllowed(CKA_EXTRACTABLE, true_str)); |
| } |
| |
| TEST_F(TestObjectPolicy, IsObjectComplete) { |
| ObjectPolicyCert policy; |
| policy.Init(&object_); |
| EXPECT_FALSE(policy.IsObjectComplete()); |
| object_.SetAttributeInt(CKA_CLASS, CKO_CERTIFICATE); |
| EXPECT_FALSE(policy.IsObjectComplete()); |
| object_.SetAttributeString(CKA_VALUE, ""); |
| EXPECT_FALSE(policy.IsObjectComplete()); |
| object_.SetAttributeInt(CKA_CERTIFICATE_TYPE, CKC_X_509_ATTR_CERT); |
| EXPECT_FALSE(policy.IsObjectComplete()); |
| object_.SetAttributeString(CKA_OWNER, ""); |
| EXPECT_TRUE(policy.IsObjectComplete()); |
| object_.SetAttributeInt(CKA_CERTIFICATE_TYPE, CKC_X_509); |
| object_.SetAttributeString(CKA_SUBJECT, ""); |
| EXPECT_FALSE(policy.IsObjectComplete()); |
| object_.SetAttributeString(CKA_VALUE, "123"); |
| EXPECT_TRUE(policy.IsObjectComplete()); |
| object_.SetAttributeString(CKA_VALUE, ""); |
| object_.SetAttributeString(CKA_URL, ""); |
| EXPECT_FALSE(policy.IsObjectComplete()); |
| object_.SetAttributeString(CKA_URL, "123"); |
| EXPECT_FALSE(policy.IsObjectComplete()); |
| object_.SetAttributeString(CKA_HASH_OF_ISSUER_PUBLIC_KEY, ""); |
| object_.SetAttributeString(CKA_HASH_OF_SUBJECT_PUBLIC_KEY, ""); |
| EXPECT_FALSE(policy.IsObjectComplete()); |
| object_.SetAttributeString(CKA_HASH_OF_SUBJECT_PUBLIC_KEY, "123"); |
| EXPECT_FALSE(policy.IsObjectComplete()); |
| object_.SetAttributeString(CKA_HASH_OF_ISSUER_PUBLIC_KEY, "123"); |
| EXPECT_TRUE(policy.IsObjectComplete()); |
| object_.RemoveAttribute(CKA_VALUE); |
| EXPECT_FALSE(policy.IsObjectComplete()); |
| } |
| |
| TEST_F(TestObjectPolicy, SetDefaultAttributes) { |
| ObjectPolicySecretKey policy; |
| policy.Init(&object_); |
| object_.SetAttributeBool(CKA_ENCRYPT, true); |
| policy.SetDefaultAttributes(); |
| EXPECT_TRUE(object_.GetAttributeBool(CKA_ENCRYPT, false)); |
| EXPECT_FALSE(object_.GetAttributeBool(CKA_DECRYPT, true)); |
| } |
| |
| TEST_F(TestObjectPolicy, LatchingAttributes) { |
| for (bool keygen_known : {false, true}) { |
| for (bool extractable : {false, true}) { |
| for (bool sensitive : {false, true}) { |
| ObjectPolicySecretKey policy; |
| policy.Init(&object_); |
| if (keygen_known) { |
| object_.SetAttributeInt(CKA_KEY_GEN_MECHANISM, CKM_DES3_KEY_GEN); |
| } else { |
| object_.RemoveAttribute(CKA_KEY_GEN_MECHANISM); |
| } |
| object_.SetAttributeBool(CKA_EXTRACTABLE, extractable); |
| object_.SetAttributeBool(CKA_SENSITIVE, sensitive); |
| policy.SetDefaultAttributes(); |
| |
| if (!keygen_known) { |
| // Can't claim the key was never extractable or always sensitive |
| // if we don't know how it was generated. |
| EXPECT_FALSE(object_.GetAttributeBool(CKA_ALWAYS_SENSITIVE, true)); |
| EXPECT_FALSE(object_.GetAttributeBool(CKA_NEVER_EXTRACTABLE, true)); |
| EXPECT_EQ( |
| static_cast<int>(CK_UNAVAILABLE_INFORMATION), |
| object_.GetAttributeInt(CKA_KEY_GEN_MECHANISM, CKM_DES3_KEY_GEN)); |
| } else { |
| EXPECT_EQ(sensitive, |
| object_.GetAttributeBool(CKA_ALWAYS_SENSITIVE, !sensitive)); |
| EXPECT_EQ(!extractable, object_.GetAttributeBool( |
| CKA_NEVER_EXTRACTABLE, extractable)); |
| EXPECT_EQ( |
| CKM_DES3_KEY_GEN, |
| object_.GetAttributeInt(CKA_KEY_GEN_MECHANISM, CKM_AES_KEY_GEN)); |
| } |
| } |
| } |
| } |
| } |
| |
| } // namespace chaps |