Merge "Created an ObjectStore skeleton with functional encryption."
diff --git a/Makefile b/Makefile
index 6a0b5e5..89be111 100644
--- a/Makefile
+++ b/Makefile
@@ -28,6 +28,7 @@
$(OUT)object_mock.o \
$(OUT)object_policy_mock.o \
$(OUT)object_pool_mock.o \
+ $(OUT)object_store_mock.o \
$(OUT)session_mock.o \
$(OUT)slot_manager_mock.o \
$(OUT)tpm_utility_mock.o
@@ -77,7 +78,8 @@
$(OUT)object_policy_secret_key.o \
$(OUT)object_pool_impl.o \
$(OUT)tpm_utility_impl.o \
- $(OUT)chaps_factory_impl.o
+ $(OUT)chaps_factory_impl.o \
+ $(OUT)object_store_impl.o
$(call cxx_binary, -ldl -ltspi)
RM_ON_CLEAN += $(OUT)chapsd
@@ -145,6 +147,12 @@
$(call cxx_binary, -lgtest -lgmock)
RM_ON_CLEAN += $(OUT)object_pool_test
+$(OUT)object_store_test: $(COMMON) \
+ $(OUT)object_store_test.o \
+ $(OUT)object_store_impl.o
+ $(call cxx_binary, -lgtest)
+RM_ON_CLEAN += $(OUT)object_store_test
+
$(OUT)tpm_utility_test: $(COMMON) $(MOCK) \
$(OUT)tpm_utility_test.o \
$(OUT)tpm_utility_impl.o
@@ -173,7 +181,8 @@
$(OUT)session_test \
$(OUT)object_test \
$(OUT)object_policy_test \
- $(OUT)object_pool_test
+ $(OUT)object_pool_test \
+ $(OUT)object_store_test
live_tests: $(OUT)chapsd_test \
$(OUT)chaps_event_generator \
@@ -189,3 +198,4 @@
$(OUT)object_test
$(OUT)object_policy_test
$(OUT)object_pool_test
+ $(OUT)object_store_test
diff --git a/chaps_utility.cc b/chaps_utility.cc
index ef60416..643d059 100644
--- a/chaps_utility.cc
+++ b/chaps_utility.cc
@@ -10,6 +10,9 @@
#include <string>
#include <vector>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
#include <openssl/sha.h>
#include "chaps/attributes.h"
@@ -487,4 +490,24 @@
return ConvertByteBufferToString(digest, SHA_DIGEST_LENGTH);
}
+ScopedOpenSSL::ScopedOpenSSL() {
+ OpenSSL_add_all_algorithms();
+ ERR_load_crypto_strings();
+}
+
+ScopedOpenSSL::~ScopedOpenSSL() {
+ EVP_cleanup();
+ ERR_free_strings();
+}
+
+std::string GetOpenSSLError() {
+ BIO* bio = BIO_new(BIO_s_mem());
+ ERR_print_errors(bio);
+ char* data = NULL;
+ int data_len = BIO_get_mem_data(bio, &data);
+ string error_string(data, data_len);
+ BIO_free(bio);
+ return error_string;
+}
+
} // namespace
diff --git a/chaps_utility.h b/chaps_utility.h
index 406e4cd..f3b8cbe 100644
--- a/chaps_utility.h
+++ b/chaps_utility.h
@@ -194,6 +194,17 @@
// Computes and returns a SHA-1 hash of the given input.
std::string sha1(const std::string& input);
+// Initializes the OpenSSL library on construction and terminates the library on
+// destruction.
+class ScopedOpenSSL {
+ public:
+ ScopedOpenSSL();
+ ~ScopedOpenSSL();
+};
+
+// Returns a description of the OpenSSL error stack.
+std::string GetOpenSSLError();
+
} // namespace chaps
#endif // CHAPS_CHAPS_UTILITY_H
diff --git a/chapsd.cc b/chapsd.cc
index 240e070..3a92c4b 100644
--- a/chapsd.cc
+++ b/chapsd.cc
@@ -23,6 +23,7 @@
#include "chaps/chaps_factory_impl.h"
#include "chaps/chaps_service.h"
#include "chaps/chaps_service_redirect.h"
+#include "chaps/chaps_utility.h"
#include "chaps/slot_manager_impl.h"
#include "chaps/tpm_utility_impl.h"
@@ -95,6 +96,7 @@
CommandLine::Init(argc, argv);
CommandLine* cl = CommandLine::ForCurrentProcess();
chromeos::InitLog(chromeos::kLogToSyslog | chromeos::kLogToStderr);
+ chaps::ScopedOpenSSL openssl;
chaps::g_dispatcher.reset(new DBus::BusDispatcher());
CHECK(chaps::g_dispatcher.get());
DBus::default_dispatcher = chaps::g_dispatcher.get();
diff --git a/object_pool.h b/object_pool.h
index 024183b..e1224b1 100644
--- a/object_pool.h
+++ b/object_pool.h
@@ -21,7 +21,7 @@
// These methods get and set internal persistent blobs. These internal blobs
// are for use by Chaps. PKCS #11 applications will not see these when
// searching for objects. Only persistent implementations need to support
- // internal blobs.
+ // internal blobs. Internal blobs do not need to be encrypted.
// blob_id - The value of this identifier must be managed by the caller.
// Only one blob can be set per blob_id (i.e. a subsequent call
// to SetInternalBlob with the same blob_id will overwrite the
@@ -31,7 +31,7 @@
// SetKey sets the encryption key for objects in this pool. This is only
// relevant if the pool is persistent; an object pool has no obligation to
// encrypt object data in memory.
- virtual void SetKey(const std::string& key) = 0;
+ virtual bool SetEncryptionKey(const std::string& key) = 0;
// This method takes ownership of the 'object' pointer on success.
virtual bool Insert(Object* object) = 0;
virtual bool Delete(const Object* object) = 0;
diff --git a/object_pool_impl.cc b/object_pool_impl.cc
index 01c1e65..42b6fb6 100644
--- a/object_pool_impl.cc
+++ b/object_pool_impl.cc
@@ -68,9 +68,10 @@
return false;
}
-void ObjectPoolImpl::SetKey(const string& key) {
+bool ObjectPoolImpl::SetEncryptionKey(const string& key) {
if (store_.get())
- store_->SetEncryptionKey(key);
+ return store_->SetEncryptionKey(key);
+ return true;
}
bool ObjectPoolImpl::Insert(Object* object) {
diff --git a/object_pool_impl.h b/object_pool_impl.h
index 8840501..3ba6e7a 100644
--- a/object_pool_impl.h
+++ b/object_pool_impl.h
@@ -40,7 +40,7 @@
virtual bool Init();
virtual bool GetInternalBlob(int blob_id, std::string* blob);
virtual bool SetInternalBlob(int blob_id, const std::string& blob);
- virtual void SetKey(const std::string& key);
+ virtual bool SetEncryptionKey(const std::string& key);
virtual bool Insert(Object* object);
virtual bool Delete(const Object* object);
virtual bool Find(const Object* search_template,
diff --git a/object_pool_mock.h b/object_pool_mock.h
index 8fa6d7a..40a23e0 100644
--- a/object_pool_mock.h
+++ b/object_pool_mock.h
@@ -21,7 +21,7 @@
MOCK_METHOD2(GetInternalBlob, bool (int, std::string*));
MOCK_METHOD2(SetInternalBlob, bool (int, const std::string&));
- MOCK_METHOD1(SetKey, void (const std::string&));
+ MOCK_METHOD1(SetEncryptionKey, bool (const std::string&));
MOCK_METHOD1(Insert, bool (Object*));
MOCK_METHOD1(Delete, bool (const Object*));
MOCK_METHOD2(Find, bool (const Object*, std::vector<const Object*>*));
diff --git a/object_pool_test.cc b/object_pool_test.cc
index 2d8ab44..ef43a64 100644
--- a/object_pool_test.cc
+++ b/object_pool_test.cc
@@ -123,12 +123,12 @@
EXPECT_CALL(*store_, SetEncryptionKey(s)).Times(1);
EXPECT_FALSE(pool2_->GetInternalBlob(1, &s));
EXPECT_FALSE(pool2_->SetInternalBlob(1, s));
- pool2_->SetKey(s);
+ pool2_->SetEncryptionKey(s);
EXPECT_FALSE(pool_->GetInternalBlob(1, &s));
EXPECT_TRUE(pool_->GetInternalBlob(1, &s));
EXPECT_FALSE(pool_->SetInternalBlob(1, s));
EXPECT_TRUE(pool_->SetInternalBlob(1, s));
- pool_->SetKey(s);
+ pool_->SetEncryptionKey(s);
}
// Test basic object management operations.
diff --git a/object_store.h b/object_store.h
index e96af94..2cf852e 100644
--- a/object_store.h
+++ b/object_store.h
@@ -8,6 +8,8 @@
#include <map>
#include <string>
+#include "pkcs11/cryptoki.h"
+
namespace chaps {
// An object store provides persistent storage of object blobs and internal
@@ -26,11 +28,13 @@
// Only one blob can be set per blob_id (i.e. a subsequent call
// to SetInternalBlob with the same blob_id will overwrite the
// blob).
- // blob - The blob data.
+ // blob - The blob data. This will not be encrypted.
virtual bool GetInternalBlob(int blob_id, std::string* blob) = 0;
virtual bool SetInternalBlob(int blob_id, const std::string& blob) = 0;
- // SetKey sets the encryption key used to encrypt object blobs.
- virtual void SetEncryptionKey(const std::string& key) = 0;
+ // SetEncryptionKey sets the encryption key used to encrypt all object blobs.
+ // This method must be called before any object blob methods (e.g.
+ // InsertObjectBlob, DeleteObjectBlob, ...).
+ virtual bool SetEncryptionKey(const std::string& key) = 0;
// Inserts a new blob.
virtual bool InsertObjectBlob(bool is_private,
CK_OBJECT_CLASS object_class,
diff --git a/object_store_fake.h b/object_store_fake.h
index 3bea58d..b0f14bb 100644
--- a/object_store_fake.h
+++ b/object_store_fake.h
@@ -27,7 +27,8 @@
internal_blobs_[blob_id] = blob;
return true;
}
- virtual void SetEncryptionKey(const std::string& key) {
+ virtual bool SetEncryptionKey(const std::string& key) {
+ return true;
}
virtual bool InsertObjectBlob(bool is_private,
CK_OBJECT_CLASS object_class,
diff --git a/object_store_impl.cc b/object_store_impl.cc
new file mode 100644
index 0000000..f4c3800
--- /dev/null
+++ b/object_store_impl.cc
@@ -0,0 +1,159 @@
+// 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 "chaps/object_store_impl.h"
+
+#include <map>
+#include <string>
+
+#include <base/logging.h>
+#include <chromeos/utility.h>
+#include <openssl/evp.h>
+
+#include "chaps/chaps_utility.h"
+#include "pkcs11/cryptoki.h"
+
+using std::map;
+using std::string;
+
+namespace chaps {
+
+const int ObjectStoreImpl::kAESBlockSizeBytes = 16;
+const int ObjectStoreImpl::kAESKeySizeBytes = 32;
+
+ObjectStoreImpl::ObjectStoreImpl() : cipher_() {
+ EVP_CIPHER_CTX_init(&cipher_context_);
+}
+
+ObjectStoreImpl::~ObjectStoreImpl() {
+ // TODO(dkrahn): Use SecureBlob. See crosbug.com/27681.
+ chromeos::SecureMemset(const_cast<char*>(key_.data()), 0, key_.length());
+ EVP_CIPHER_CTX_cleanup(&cipher_context_);
+}
+
+bool ObjectStoreImpl::GetInternalBlob(int blob_id, string* blob) {
+ return false;
+}
+
+bool ObjectStoreImpl::SetInternalBlob(int blob_id, const string& blob) {
+ return false;
+}
+
+bool ObjectStoreImpl::SetEncryptionKey(const string& key) {
+ if (key.length() != static_cast<size_t>(kAESKeySizeBytes)) {
+ LOG(ERROR) << "Unexpected key size: " << key.length();
+ return false;
+ }
+ key_ = key;
+ return true;
+}
+
+bool ObjectStoreImpl::InsertObjectBlob(bool is_private,
+ CK_OBJECT_CLASS object_class,
+ const string& key_id,
+ const string& blob,
+ int* handle) {
+ if (key_.empty())
+ return false;
+ return false;
+}
+
+bool ObjectStoreImpl::DeleteObjectBlob(int handle) {
+ if (key_.empty())
+ return false;
+ return false;
+}
+
+bool ObjectStoreImpl::UpdateObjectBlob(int handle, const string& blob) {
+ if (key_.empty())
+ return false;
+ return false;
+}
+
+bool ObjectStoreImpl::LoadAllObjectBlobs(map<int, string>* blobs) {
+ if (key_.empty())
+ return false;
+ return false;
+}
+
+bool ObjectStoreImpl::RunCipher(bool is_encrypt,
+ const string& input,
+ string* output) {
+ if (key_.empty()) {
+ LOG(ERROR) << "Store encryption key has not been initialized.";
+ return false;
+ }
+ int input_length = input.length();
+ string iv;
+ if (is_encrypt) {
+ // Generate a new random IV.
+ iv.resize(kAESBlockSizeBytes);
+ RAND_bytes(ConvertStringToByteBuffer(iv.data()), kAESBlockSizeBytes);
+ } else {
+ // Recover the IV from the input.
+ if (input_length < kAESBlockSizeBytes) {
+ LOG(ERROR) << "Decrypt: Invalid input.";
+ return false;
+ }
+ iv = input.substr(input_length - kAESBlockSizeBytes);
+ input_length -= kAESBlockSizeBytes;
+ }
+ if (!EVP_CipherInit_ex(&cipher_context_,
+ EVP_aes_256_cbc(),
+ NULL,
+ ConvertStringToByteBuffer(key_.data()),
+ ConvertStringToByteBuffer(iv.data()),
+ is_encrypt)) {
+ LOG(ERROR) << "EVP_CipherInit_ex failed: " << GetOpenSSLError();
+ return false;
+ }
+ EVP_CIPHER_CTX_set_padding(&cipher_context_,
+ 1); // Enables PKCS padding.
+ // Set the buffer size to be large enough to hold all output. For encryption,
+ // this will allow space for padding and, for decryption, this will comply
+ // with openssl documentation (even though the final output will be no larger
+ // than input_length).
+ output->resize(input_length + kAESBlockSizeBytes);
+ int output_length = 0;
+ unsigned char* output_bytes = ConvertStringToByteBuffer(output->data());
+ unsigned char* input_bytes = ConvertStringToByteBuffer(input.data());
+ if (!EVP_CipherUpdate(&cipher_context_,
+ output_bytes,
+ &output_length, // Will be set to actual output length.
+ input_bytes,
+ input_length)) {
+ LOG(ERROR) << "EVP_CipherUpdate failed: " << GetOpenSSLError();
+ return false;
+ }
+ // The final block is yet to be computed. This check ensures we have at least
+ // kAESBlockSizeBytes bytes left in the output buffer.
+ CHECK(output_length <= input_length);
+ int output_length2 = 0;
+ if (!EVP_CipherFinal_ex(&cipher_context_,
+ output_bytes + output_length,
+ &output_length2)) {
+ LOG(ERROR) << "EVP_CipherFinal_ex failed: " << GetOpenSSLError();
+ return false;
+ }
+ // Adjust the output size to the number of bytes actually written.
+ output->resize(output_length + output_length2);
+ if (is_encrypt) {
+ // Append the IV so it will be available during decryption.
+ *output += iv;
+ }
+ return true;
+}
+
+bool ObjectStoreImpl::Encrypt(const string& plain_text,
+ string* cipher_text) {
+ return RunCipher(true, plain_text, cipher_text);
+}
+
+bool ObjectStoreImpl::Decrypt(const string& cipher_text,
+ string* plain_text) {
+ return RunCipher(false, cipher_text, plain_text);
+}
+
+} // namespace chaps
+
diff --git a/object_store_impl.h b/object_store_impl.h
new file mode 100644
index 0000000..c43c46c
--- /dev/null
+++ b/object_store_impl.h
@@ -0,0 +1,63 @@
+// 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.
+
+#ifndef CHAPS_OBJECT_STORE_IMPL_H_
+#define CHAPS_OBJECT_STORE_IMPL_H_
+
+#include "chaps/object_store.h"
+
+#include <map>
+#include <string>
+
+#include <base/basictypes.h>
+#include <gtest/gtest.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+
+namespace chaps {
+
+// An ObjectStore implementation based on SQLite.
+class ObjectStoreImpl : public ObjectStore {
+ public:
+ ObjectStoreImpl();
+ virtual ~ObjectStoreImpl();
+
+ // ObjectStore methods.
+ virtual bool GetInternalBlob(int blob_id, std::string* blob);
+ virtual bool SetInternalBlob(int blob_id, const std::string& blob);
+ virtual bool SetEncryptionKey(const std::string& key);
+ virtual bool InsertObjectBlob(bool is_private,
+ CK_OBJECT_CLASS object_class,
+ const std::string& key_id,
+ const std::string& blob,
+ int* handle);
+ virtual bool DeleteObjectBlob(int handle);
+ virtual bool UpdateObjectBlob(int handle, const std::string& blob);
+ virtual bool LoadAllObjectBlobs(std::map<int, std::string>* blobs);
+
+ private:
+ bool RunCipher(bool is_encrypt,
+ const std::string& input,
+ std::string* output);
+ bool Encrypt(const std::string& plain_text, std::string* cipher_text);
+ bool Decrypt(const std::string& cipher_text, std::string* plain_text);
+
+ static const int kAESBlockSizeBytes;
+ static const int kAESKeySizeBytes;
+
+ std::string key_;
+ EVP_CIPHER_CTX cipher_context_;
+ const EVP_CIPHER* cipher_;
+
+ friend class TestObjectStoreEncryption;
+ FRIEND_TEST(TestObjectStoreEncryption, EncryptionInit);
+ FRIEND_TEST(TestObjectStoreEncryption, Encryption);
+ FRIEND_TEST(TestObjectStoreEncryption, CBCMode);
+
+ DISALLOW_COPY_AND_ASSIGN(ObjectStoreImpl);
+};
+
+} // namespace chaps
+
+#endif // CHAPS_OBJECT_STORE_IMPL_H_
diff --git a/object_store_mock.cc b/object_store_mock.cc
new file mode 100644
index 0000000..d07c56d
--- /dev/null
+++ b/object_store_mock.cc
@@ -0,0 +1,12 @@
+// 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 "object_store_mock.h"
+
+namespace chaps {
+
+ObjectStoreMock::ObjectStoreMock() {}
+ObjectStoreMock::~ObjectStoreMock() {}
+
+}
diff --git a/object_store_mock.h b/object_store_mock.h
index 510072f..bb5e27e 100644
--- a/object_store_mock.h
+++ b/object_store_mock.h
@@ -2,21 +2,25 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHAPS_PERSISTENCE_MOCK_H
-#define CHAPS_PERSISTENCE_MOCK_H
+#ifndef CHAPS_OBJECT_STORE_MOCK_H
+#define CHAPS_OBJECT_STORE_MOCK_H
#include "chaps/object_store.h"
+#include <gmock/gmock.h>
+
namespace chaps {
class ObjectStoreMock : public ObjectStore {
public:
+ ObjectStoreMock();
+ virtual ~ObjectStoreMock();
MOCK_METHOD2(GetInternalBlob,
bool(int blob_id, std::string* blob));
MOCK_METHOD2(SetInternalBlob,
bool(int blob_id, const std::string& blob));
MOCK_METHOD1(SetEncryptionKey,
- void(const std::string& key));
+ bool(const std::string& key));
MOCK_METHOD5(InsertObjectBlob,
bool(bool is_private,
CK_OBJECT_CLASS object_class,
@@ -33,4 +37,4 @@
} // namespace
-#endif // CHAPS_PERSISTENCE_MOCK_H
+#endif // CHAPS_OBJECT_STORE_MOCK_H
diff --git a/object_store_test.cc b/object_store_test.cc
new file mode 100644
index 0000000..87752c4
--- /dev/null
+++ b/object_store_test.cc
@@ -0,0 +1,103 @@
+// 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 "chaps/object_store_impl.h"
+
+#include <map>
+#include <string>
+
+#include <base/scoped_ptr.h>
+#include <gtest/gtest.h>
+#include <openssl/err.h>
+
+using std::map;
+using std::string;
+
+namespace chaps {
+
+class TestObjectStoreEncryption : public ::testing::Test {
+ public:
+ bool TestEncryption(ObjectStoreImpl& store,
+ const string& input) {
+ string encrypted;
+ if (!store.Encrypt(input, &encrypted))
+ return false;
+ string decrypted;
+ if (!store.Decrypt(encrypted, &decrypted))
+ return false;
+ return (input == decrypted);
+ }
+};
+
+TEST_F(TestObjectStoreEncryption, EncryptionInit) {
+ ObjectStoreImpl store;
+ string input(10, 0x00), output;
+ EXPECT_FALSE(store.Encrypt(input, &output));
+ EXPECT_FALSE(store.Decrypt(input, &output));
+ EXPECT_FALSE(store.SetEncryptionKey(string()));
+ EXPECT_FALSE(store.SetEncryptionKey(string(16, 0xAA)));
+ EXPECT_FALSE(store.SetEncryptionKey(string(31, 0xAA)));
+ EXPECT_FALSE(store.SetEncryptionKey(string(33, 0xAA)));
+ EXPECT_TRUE(store.SetEncryptionKey(string(32, 0xAA)));
+ EXPECT_TRUE(TestEncryption(store, input));
+}
+
+TEST_F(TestObjectStoreEncryption, Encryption) {
+ ObjectStoreImpl store;
+ string key(32, 0xAA);
+ ASSERT_TRUE(store.SetEncryptionKey(key));
+ string blob(64, 0xBB);
+ // On AES block boundary.
+ EXPECT_TRUE(TestEncryption(store, blob));
+ // Not on AES block boundary.
+ EXPECT_TRUE(TestEncryption(store, string(21, 0xCC)));
+ // One over AES block boundary.
+ EXPECT_TRUE(TestEncryption(store, string(33, 0xDD)));
+ // One under AES block boundary.
+ EXPECT_TRUE(TestEncryption(store, string(31, 0xEE)));
+ // Zero length input.
+ EXPECT_TRUE(TestEncryption(store, string()));
+ // Test random IV: two identical blobs should have different cipher texts.
+ string encrypted1;
+ EXPECT_TRUE(store.Encrypt(blob, &encrypted1));
+ string encrypted2;
+ EXPECT_TRUE(store.Encrypt(blob, &encrypted2));
+ EXPECT_TRUE(encrypted1 != encrypted2);
+ string decrypted1;
+ EXPECT_TRUE(store.Decrypt(encrypted1, &decrypted1));
+ EXPECT_TRUE(decrypted1 == blob);
+ string decrypted2;
+ EXPECT_TRUE(store.Decrypt(encrypted2, &decrypted2));
+ EXPECT_TRUE(decrypted2 == blob);
+ // Invalid decrypt.
+ EXPECT_FALSE(store.Decrypt(blob, &decrypted1));
+ // Test corrupted IV.
+ encrypted1[encrypted1.size()-1]++;
+ EXPECT_TRUE(store.Decrypt(encrypted1, &decrypted1));
+ EXPECT_FALSE(decrypted1 == blob);
+ // Test corrupted cipher text.
+ encrypted2[0]++;
+ EXPECT_TRUE(store.Decrypt(encrypted2, &decrypted2));
+ EXPECT_FALSE(decrypted2 == blob);
+}
+
+TEST_F(TestObjectStoreEncryption, CBCMode) {
+ ObjectStoreImpl store;
+ string key(32, 0xAA);
+ ASSERT_TRUE(store.SetEncryptionKey(key));
+ string two_identical_blocks(32, 0xBB);
+ string encrypted;
+ EXPECT_TRUE(store.Encrypt(two_identical_blocks, &encrypted));
+ string encrypted_block1 = encrypted.substr(0, 16);
+ string encrypted_block2 = encrypted.substr(16, 16);
+ EXPECT_FALSE(encrypted_block1 == encrypted_block2);
+}
+
+} // namespace chaps
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ERR_load_crypto_strings();
+ return RUN_ALL_TESTS();
+}
diff --git a/session_impl.cc b/session_impl.cc
index b6cdea9..5e5b060 100644
--- a/session_impl.cc
+++ b/session_impl.cc
@@ -1012,16 +1012,6 @@
return rsa;
}
-string SessionImpl::GetOpenSSLError() {
- BIO* bio = BIO_new(BIO_s_mem());
- ERR_print_errors(bio);
- char* data = NULL;
- int data_len = BIO_get_mem_data(bio, &data);
- string error_string(data, data_len);
- BIO_free(bio);
- return error_string;
-}
-
const EVP_CIPHER* SessionImpl::GetOpenSSLCipher(CK_MECHANISM_TYPE mechanism,
size_t key_size) {
switch (mechanism) {
diff --git a/session_impl.h b/session_impl.h
index 6533618..3064b4f 100644
--- a/session_impl.h
+++ b/session_impl.h
@@ -181,7 +181,6 @@
BIGNUM* ConvertToBIGNUM(const std::string& big_integer);
// Always returns a non-NULL value.
RSA* CreateKeyFromObject(const Object* key_object);
- std::string GetOpenSSLError();
const EVP_CIPHER* GetOpenSSLCipher(CK_MECHANISM_TYPE mechanism,
size_t key_size);
const EVP_MD* GetOpenSSLDigest(CK_MECHANISM_TYPE mechanism);
diff --git a/slot_manager_impl.cc b/slot_manager_impl.cc
index f5ee08b..111f572 100644
--- a/slot_manager_impl.cc
+++ b/slot_manager_impl.cc
@@ -265,7 +265,11 @@
return;
}
}
- object_pool->SetKey(master_key);
+ if (!object_pool->SetEncryptionKey(master_key)) {
+ LOG(ERROR) << "SetEncryptionKey failed for token at " << path.value();
+ tpm_utility_->UnloadKeysForSlot(slot_id);
+ return;
+ }
// Insert the new token into the empty slot.
slot_list_[slot_id].token_object_pool = object_pool;
slot_list_[slot_id].slot_info.flags |= CKF_TOKEN_PRESENT;
diff --git a/slot_manager_test.cc b/slot_manager_test.cc
index 4085aea..ffb80a7 100644
--- a/slot_manager_test.cc
+++ b/slot_manager_test.cc
@@ -51,7 +51,8 @@
.WillRepeatedly(Return(true));
EXPECT_CALL(*object_pool, SetInternalBlob(1, string("encrypted_master_key")))
.WillRepeatedly(Return(true));
- EXPECT_CALL(*object_pool, SetKey(string("master_key"))).Times(AnyNumber());
+ EXPECT_CALL(*object_pool, SetEncryptionKey(string("master_key")))
+ .WillRepeatedly(Return(true));
return object_pool;
}