blob: 579ae3e1afccea777664e6e9d6587a3be22f38aa [file] [log] [blame]
// 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