From f998e4d1758b214b390f6b7f841e6f698fb6f3f1 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Tue, 29 Jan 2019 11:34:18 +0100 Subject: Use common function for PKEK1&2 generation Change-Id: Ic9c6286b3672836c2bde976adb1b79ba34793918 --- src/manager/service/key-provider.cpp | 222 +++++++++++------------------------ src/manager/service/key-provider.h | 4 - 2 files changed, 70 insertions(+), 156 deletions(-) diff --git a/src/manager/service/key-provider.cpp b/src/manager/service/key-provider.cpp index 47425e62..2895b6c0 100644 --- a/src/manager/service/key-provider.cpp +++ b/src/manager/service/key-provider.cpp @@ -19,12 +19,16 @@ #include #include +#include + +using namespace CKM; + namespace { template -CKM::RawBuffer toRawBuffer(const T &data) +RawBuffer toRawBuffer(const T &data) { - CKM::RawBuffer output; + RawBuffer output; const unsigned char *ptr = reinterpret_cast(&data); output.assign(ptr, ptr + sizeof(T)); return output; @@ -32,18 +36,53 @@ CKM::RawBuffer toRawBuffer(const T &data) // You cannot use toRawBuffer template with pointers template -CKM::RawBuffer toRawBuffer(T *) +RawBuffer toRawBuffer(T *) { class NoPointerAllowed { NoPointerAllowed() {} }; NoPointerAllowed a; - return CKM::RawBuffer(); + return RawBuffer(); } -} // anonymous namespace +typedef std::array KeyData; -using namespace CKM; +// derives a key used for DomainKEK encryption (aka PKEK1) from random salt & user password +KeyData makePKEK1(const KeyComponentsInfo& keyInfo, const Password &password) +{ + std::string concatPasswordClient(password.c_str()); + concatPasswordClient += std::string(keyInfo.client); + + KeyData key; + if (!PKCS5_PBKDF2_HMAC_SHA1(concatPasswordClient.c_str(), + concatPasswordClient.size(), + keyInfo.salt, + MAX_SALT_SIZE, + PBKDF2_ITERATIONS, + key.size(), + key.data())) { + ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); + } + return key; +} + +// derives a key used for DB DEK encryption (aka PKEK2) from DomainKEK and user id +KeyData makePKEK2(const uint8_t *domainKEK, const std::string &user) +{ + KeyData key; + if (!PKCS5_PBKDF2_HMAC_SHA1(user.c_str(), + user.size(), + domainKEK, + MAX_SALT_SIZE, + PBKDF2_ITERATIONS, + key.size(), + key.data())) { + ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); + } + return key; +} + +} // anonymous namespace WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer() { @@ -167,34 +206,14 @@ KeyProvider::KeyProvider( WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer( domainKEKInWrapForm.data()); - char *concat_user_pass = NULL; - uint8_t PKEK1[MAX_KEY_SIZE]; - - concat_user_pass = concat_password_user( - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.client, - password.c_str()); - - if (!PKCS5_PBKDF2_HMAC_SHA1( - concat_user_pass, - strlen(concat_user_pass), - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt, - MAX_SALT_SIZE, - PBKDF2_ITERATIONS, - MAX_KEY_SIZE, - PKEK1)) { - delete[] concat_user_pass; - ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - } - - delete[] concat_user_pass; + KeyData PKEK1 = makePKEK1(wkmcDKEK.getWrappedKeyAndInfo().keyInfo, password); int keyLength; - if (0 > (keyLength = decryptAes256Gcm( wkmcDKEK.getWrappedKeyAndInfo().wrappedKey, wkmcDKEK.getWrappedKeyAndInfo().keyInfo.keyLength, wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag, - PKEK1, + PKEK1.data(), wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv, m_kmcDKEK->getKeyAndInfo().key))) { ThrowErr(Exc::AuthenticationFailed, @@ -250,36 +269,16 @@ RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password) ThrowErr(Exc::InternalError, "Object not initialized!"); WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer(); - - char *concat_user_pass = NULL; - uint8_t PKEK1[MAX_KEY_SIZE]; - - concat_user_pass = concat_password_user( - m_kmcDKEK->getKeyAndInfo().keyInfo.client, - password.c_str()); - - if (!PKCS5_PBKDF2_HMAC_SHA1( - concat_user_pass, - strlen(concat_user_pass), - m_kmcDKEK->getKeyAndInfo().keyInfo.salt, - MAX_SALT_SIZE, - PBKDF2_ITERATIONS, - MAX_KEY_SIZE, - PKEK1)) { - delete[] concat_user_pass; - ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - } - - delete[] concat_user_pass; - wkmcDKEK.setKeyInfo(&(m_kmcDKEK->getKeyAndInfo().keyInfo)); + KeyData PKEK1 = makePKEK1(wkmcDKEK.getWrappedKeyAndInfo().keyInfo, password); + int wrappedKeyLength; if (0 > (wrappedKeyLength = encryptAes256Gcm( m_kmcDKEK->getKeyAndInfo().key, m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength, - PKEK1, + PKEK1.data(), m_kmcDKEK->getKeyAndInfo().keyInfo.iv, wkmcDKEK.getWrappedKeyAndInfo().wrappedKey, wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag))) @@ -309,24 +308,15 @@ RawBuffer KeyProvider::getPureDEK(const RawBuffer &DEKInWrapForm) WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer( DEKInWrapForm.data()); - uint8_t PKEK2[MAX_KEY_SIZE]; - int keyLength; - - if (!PKCS5_PBKDF2_HMAC_SHA1( - wkmcDEK.getWrappedKeyAndInfo().keyInfo.client, - strlen(wkmcDEK.getWrappedKeyAndInfo().keyInfo.client), - m_kmcDKEK->getKeyAndInfo().key, - MAX_SALT_SIZE, - PBKDF2_ITERATIONS, - MAX_KEY_SIZE, - PKEK2)) - ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); + KeyData PKEK2 = makePKEK2(m_kmcDKEK->getKeyAndInfo().key, + wkmcDEK.getWrappedKeyAndInfo().keyInfo.client); + int keyLength; if (0 > (keyLength = decryptAes256Gcm( wkmcDEK.getWrappedKeyAndInfo().wrappedKey, wkmcDEK.getWrappedKeyAndInfo().keyInfo.keyLength, wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag, - PKEK2, + PKEK2.data(), wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, kmcDEK.getKeyAndInfo().key))) ThrowErr(Exc::InternalError, @@ -353,28 +343,19 @@ RawBuffer KeyProvider::generateDEK(const ClientId &client) else resized_client = client.substr(0, MAX_CLIENT_ID_SIZE - 1); - uint8_t key[MAX_KEY_SIZE], PKEK2[MAX_KEY_SIZE]; + uint8_t key[MAX_KEY_SIZE]; if (!RAND_bytes(key, m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength) || !RAND_bytes(wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, MAX_IV_SIZE)) ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - if (!PKCS5_PBKDF2_HMAC_SHA1( - resized_client.c_str(), - strlen(resized_client.c_str()), - m_kmcDKEK->getKeyAndInfo().key, - MAX_SALT_SIZE, - PBKDF2_ITERATIONS, - MAX_KEY_SIZE, - PKEK2)) - ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); + KeyData PKEK2 = makePKEK2(m_kmcDKEK->getKeyAndInfo().key, resized_client); int wrappedKeyLength; - if (0 > (wrappedKeyLength = encryptAes256Gcm( key, m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength, - PKEK2, + PKEK2.data(), wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, wkmcDEK.getWrappedKeyAndInfo().wrappedKey, wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag))) @@ -405,34 +386,14 @@ RawBuffer KeyProvider::reencrypt( WrappedKeyAndInfoContainer wkmcNewDKEK = WrappedKeyAndInfoContainer(); KeyAndInfoContainer kmcDKEK = KeyAndInfoContainer(); - char *concat_user_pass = NULL; - uint8_t PKEK1[MAX_KEY_SIZE]; - int keyLength = 0; - - - concat_user_pass = concat_password_user( - wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.client, - oldPass.c_str()); - - if (!PKCS5_PBKDF2_HMAC_SHA1( - concat_user_pass, - strlen(concat_user_pass), - wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.salt, - MAX_SALT_SIZE, - PBKDF2_ITERATIONS, - MAX_KEY_SIZE, - PKEK1)) { - delete[] concat_user_pass; - ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - } - - delete[] concat_user_pass; + KeyData PKEK1 = makePKEK1(wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo, oldPass); + int keyLength = 0; if (0 > (keyLength = decryptAes256Gcm( wkmcOldDKEK.getWrappedKeyAndInfo().wrappedKey, wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.keyLength, wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.tag, - PKEK1, + PKEK1.data(), wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.iv, kmcDKEK.getKeyAndInfo().key))) ThrowErr(Exc::AuthenticationFailed, "Incorrect Old Password "); @@ -440,31 +401,15 @@ RawBuffer KeyProvider::reencrypt( kmcDKEK.setKeyInfo(&(wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo)); kmcDKEK.setKeyInfoKeyLength((unsigned int)keyLength); - concat_user_pass = concat_password_user( - kmcDKEK.getKeyAndInfo().keyInfo.client, - newPass.c_str()); - - if (!PKCS5_PBKDF2_HMAC_SHA1( - concat_user_pass, - strlen(concat_user_pass), - kmcDKEK.getKeyAndInfo().keyInfo.salt, - MAX_SALT_SIZE, - PBKDF2_ITERATIONS, - MAX_KEY_SIZE, - PKEK1)) { - delete[] concat_user_pass; - ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - } - - delete[] concat_user_pass; + PKEK1 = makePKEK1(wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo, newPass); - int wrappedKeyLength = 0; wkmcNewDKEK.setKeyInfo(&(kmcDKEK.getKeyAndInfo().keyInfo)); + int wrappedKeyLength = 0; if (0 > (wrappedKeyLength = encryptAes256Gcm( kmcDKEK.getKeyAndInfo().key, kmcDKEK.getKeyAndInfo().keyInfo.keyLength, - PKEK1, + PKEK1.data(), kmcDKEK.getKeyAndInfo().keyInfo.iv, wkmcNewDKEK.getWrappedKeyAndInfo().wrappedKey, wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo.tag))) @@ -477,41 +422,27 @@ RawBuffer KeyProvider::reencrypt( return toRawBuffer(wkmcNewDKEK.getWrappedKeyAndInfo()); } - RawBuffer KeyProvider::generateDomainKEK( const std::string &user, const Password &userPassword) { WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer(); - uint8_t key[MAX_KEY_SIZE], PKEK1[MAX_KEY_SIZE]; + uint8_t key[MAX_KEY_SIZE]; + int wrappedKeyLength; + + wkmcDKEK.setKeyInfoClient(user); if (!RAND_bytes(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt, MAX_SALT_SIZE) || !RAND_bytes(key, MAX_KEY_SIZE) || !RAND_bytes(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv, MAX_IV_SIZE)) ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - int wrappedKeyLength; - char *concat_user_pass = NULL; - concat_user_pass = concat_password_user(user.c_str(), userPassword.c_str()); - - if (!PKCS5_PBKDF2_HMAC_SHA1( - concat_user_pass, - strlen(concat_user_pass), - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt, - MAX_SALT_SIZE, - PBKDF2_ITERATIONS, - MAX_KEY_SIZE, - PKEK1)) { - delete[] concat_user_pass; - ThrowErr(Exc::InternalError, "OPENSSL_ENGINED_ERROR"); - } - - delete[] concat_user_pass; + KeyData PKEK1 = makePKEK1(wkmcDKEK.getWrappedKeyAndInfo().keyInfo, userPassword); if (0 > (wrappedKeyLength = encryptAes256Gcm( key, - MAX_KEY_SIZE, - PKEK1, + sizeof(key), + PKEK1.data(), wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv, wkmcDKEK.getWrappedKeyAndInfo().wrappedKey, wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag))) @@ -621,16 +552,3 @@ int KeyProvider::decryptAes256Gcm(const unsigned char *ciphertext, return -1; } } - -char *KeyProvider::concat_password_user(const char *user, const char *password) -{ - std::string result(password); - result += user; - - if (strlen(user) > MAX_CLIENT_ID_SIZE - 1) - result.resize(strlen(password) + MAX_CLIENT_ID_SIZE - 1); - - char *ret = new char[result.size() + 1]; - memcpy(ret, result.c_str(), result.size() + 1); - return ret; -} diff --git a/src/manager/service/key-provider.h b/src/manager/service/key-provider.h index bcc999f2..5f6e0cb2 100644 --- a/src/manager/service/key-provider.h +++ b/src/manager/service/key-provider.h @@ -183,10 +183,6 @@ private: const unsigned char *key, const unsigned char *iv, unsigned char *plaintext); - - static char *concat_password_user( - const char *user, - const char *password); }; } // namespace CKM -- cgit v1.2.3