Add crypto module.
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Fri, 4 Jul 2014 16:54:03 +0000 (18:54 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Fri, 12 Sep 2014 12:58:49 +0000 (14:58 +0200)
Reiplementation of crypto-logic (old name DBCryptoModule).

Change-Id: Id1bdd4d48ee342ede3cf8cb78ff6c30a294ec541

src/CMakeLists.txt
src/manager/CMakeLists.txt
src/manager/common/aesCrypt.cpp [deleted file]
src/manager/common/aesCrypt.h [deleted file]
src/manager/common/crypto.h [new file with mode: 0644]
src/manager/service/DBCryptoModule.cpp [deleted file]
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/crypto-logic.cpp [new file with mode: 0644]
src/manager/service/crypto-logic.h [moved from src/manager/service/DBCryptoModule.h with 59% similarity]

index d0aadae..1c9a353 100644 (file)
@@ -19,7 +19,7 @@ SET(KEY_MANAGER_SOURCES
     ${KEY_MANAGER_PATH}/service/ckm-logic.cpp
     ${KEY_MANAGER_PATH}/service/key-provider.cpp
     ${KEY_MANAGER_PATH}/service/ocsp.cpp
-    ${KEY_MANAGER_PATH}/service/DBCryptoModule.cpp
+    ${KEY_MANAGER_PATH}/service/crypto-logic.cpp
     ${KEY_MANAGER_PATH}/service/CryptoService.cpp
     ${KEY_MANAGER_PATH}/service/file-system.cpp
     ${KEY_MANAGER_PATH}/service/db-crypto.cpp
index d8772cd..cdf1285 100644 (file)
@@ -17,7 +17,6 @@ SET(COMMON_PATH ${PROJECT_SOURCE_DIR}/src/manager)
 SET(COMMON_SOURCES
     ${COMMON_PATH}/common/base64.cpp
     ${COMMON_PATH}/common/digest.cpp
-    ${COMMON_PATH}/common/aesCrypt.cpp
     ${COMMON_PATH}/common/protocols.cpp
     ${COMMON_PATH}/common/message-buffer.cpp
     ${COMMON_PATH}/common/smack-check.cpp
diff --git a/src/manager/common/aesCrypt.cpp b/src/manager/common/aesCrypt.cpp
deleted file mode 100644 (file)
index 46bcf52..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-#include <features.h>
-
-#include <dpl/log/log.h>
-
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-
-#include <aesCrypt.h>
-
-namespace CKM {
-
-CryptoAlgConf::CryptoAlgConf(const EVP_CIPHER *cipher) :
-    m_key(EVP_MAX_KEY_LENGTH),
-    m_salt(PKCS5_SALT_LEN)
-{
-    preinit(cipher);
-}
-
-CryptoAlgConf::CryptoAlgConf(const EVP_CIPHER *cipher, std::string &password) :
-    m_key(EVP_MAX_KEY_LENGTH),
-    m_salt(PKCS5_SALT_LEN)
-{
-    preinit(cipher);
-    if (not password.empty())
-        generateKey(password);
-}
-
-CryptoAlgConf::~CryptoAlgConf()
-{
-}
-
-const EVP_CIPHER *CryptoAlgConf::getCipher(void)
-{
-    return m_cipher;
-}
-
-void CryptoAlgConf::generateKey(std::string &password, bool use_iv)
-{
-    int ret = -1;
-
-    if (password.empty()) {
-        ThrowMsg(Exception::InternalError, "Password is empty.");
-    }
-    if (not use_iv)
-        generateRandIV();
-    ret = PKCS5_PBKDF2_HMAC_SHA1(password.c_str(), password.length(), NULL, 0,
-                                 m_pkcs5_password_iter, m_keyLen,
-                                 m_key.data());
-    if (ret != 1) {
-        ThrowMsg(Exception::InternalError,
-                 "PKCS5_PBKDF2_HMAC_SHA1 has failed.");
-    }
-}
-
-void CryptoAlgConf::generateRandIV()
-{
-    RawBuffer civ(EVP_MAX_IV_LENGTH);
-
-    if (RAND_bytes(civ.data(), civ.size()) != 1) {
-        ThrowMsg(Exception::InternalError,
-                 "RAND_bytes failed to generate IV.");
-    }
-    m_iv = civ;
-}
-
-void CryptoAlgConf::setKey(const RawBuffer &key)
-{
-    if (key.size() != m_keyLen) {
-        ThrowMsg(Exception::InternalError, "Invalid key length.");
-    }
-    m_key = key;
-}
-
-void CryptoAlgConf::setIV(const RawBuffer &iv)
-{
-    if ((iv.size() != m_ivLen) && (iv.size() != 0)) {
-        ThrowMsg(Exception::InternalError, "Invalid IV length.");
-    }
-    m_iv = iv;
-}
-
-void CryptoAlgConf::setSalt(const RawBuffer &salt)
-{
-    if (salt.size() != m_saltLen) {
-        ThrowMsg(Exception::InternalError, "Invalid salt length.");
-    }
-    m_salt = salt;
-}
-
-RawBuffer CryptoAlgConf::getKey()
-{
-    return m_key;
-}
-
-RawBuffer CryptoAlgConf::getIV()
-{
-    return m_iv;
-}
-
-RawBuffer CryptoAlgConf::getSalt()
-{
-    return m_salt;
-}
-
-void CryptoAlgConf::preinit(const EVP_CIPHER *cipher)
-{
-    m_cipher = cipher;
-    if (m_cipher == nullptr)
-        m_cipher = EVP_aes_256_cbc();
-    m_keyLen = EVP_CIPHER_key_length(m_cipher);
-    m_ivLen = EVP_CIPHER_iv_length(m_cipher);
-    m_saltLen = PKCS5_SALT_LEN;
-    m_key.resize(m_keyLen);
-    m_pkcs5_password_iter = 1024;
-    generateRandIV();
-}
-
-std::size_t CryptoAlgConf::maxBufLen(std::size_t len)
-{
-    return len + EVP_CIPHER_block_size(m_cipher);
-}
-
-/******************************************************************************
- *****************************************************************************/
-
-AesCrypt::AesCrypt(AESCryptMode mode, std::string password) :
-    conf(nullptr, password)
-{
-    m_ctx = nullptr;
-    if ((mode != AESCryptMode::ENCODER) && (mode != AESCryptMode::DECODER)) {
-        ThrowMsg(Exception::InternalError,
-                 "Unknown mode of crypto operations.");
-    } else
-        m_mode = mode;
-    m_initialized = false;
-    m_finalized = false;
-    m_padding = true;
-    if (m_mode == AESCryptMode::ENCODER) {
-        m_fInit = EVP_EncryptInit_ex;
-        m_fUpdate = EVP_EncryptUpdate;
-        m_fFinal = EVP_EncryptFinal_ex;
-    } else {
-        m_fInit = EVP_DecryptInit_ex;
-        m_fUpdate = EVP_DecryptUpdate;
-        m_fFinal = EVP_DecryptFinal_ex;
-    }
-}
-
-AesCrypt::~AesCrypt()
-{
-    EVP_CIPHER_CTX_free(m_ctx);
-}
-
-void AesCrypt::reset()
-{
-    int ret = -1;
-
-    if (m_initialized) {
-        EVP_CIPHER_CTX_free(m_ctx);
-        m_ctx = nullptr;
-    }
-    m_initialized = false;
-    m_finalized = false;
-    m_ctx = EVP_CIPHER_CTX_new();
-    if (m_ctx == nullptr) {
-        ThrowMsg(Exception::InternalError,
-                 "Failed to alloc security context.");
-    }
-    ret = m_fInit(m_ctx, conf.getCipher(), NULL, conf.getKey().data(),
-                  conf.getIV().data());
-    if (ret != 1) {
-        ThrowMsg(Exception::InternalError,
-                 "Failed to initialize encryption in openssl.");
-    }
-    if (m_padding)
-        EVP_CIPHER_CTX_set_padding(m_ctx, 1);
-    m_bufWritePos = 0;
-    m_buf.clear();
-    m_initialized = true;
-}
-
-RawBuffer AesCrypt::finalize()
-{
-    int ret = -1;
-    int outlf;
-
-    if (not m_initialized) {
-        ThrowMsg(Exception::InternalError, "Not initialized.");
-    }
-    if (m_finalized) {
-        ThrowMsg(Exception::InternalError, "Already finalized.");
-    }
-    if (m_buf.size() == 0) {
-        ThrowMsg(Exception::InternalError,
-                 "Empty buffor: append() was missing?");
-    }
-    m_buf.resize(conf.maxBufLen(m_bufWritePos));
-    ret = m_fFinal(m_ctx, m_buf.data() + m_bufWritePos, &outlf);
-    if (ret != 1) {
-        ThrowMsg(Exception::InternalError,
-                 "Failed to encrypt data in openssl (final)");
-    }
-    m_bufWritePos += outlf;
-    if (0 == m_bufWritePos) {
-        ThrowMsg(Exception::InternalError,
-                 "No output data.");
-    }
-    EVP_CIPHER_CTX_free(m_ctx);
-    m_ctx = nullptr;
-    m_buf.resize(m_bufWritePos);
-    m_initialized = false;
-    m_finalized = true;
-
-    return m_buf;
-}
-
-int AesCrypt::append(const RawBuffer &data)
-{
-    int ret = -1;
-    int outl = -1;
-
-    if (data.size() == 0) {
-        ThrowMsg(Exception::InternalError, "Empty data.");
-    }
-    if (m_finalized) {
-        ThrowMsg(Exception::InternalError, "Already finalized.");
-    }
-    if (not m_initialized)
-        reset();
-
-    m_buf.resize(conf.maxBufLen(data.size()));
-    ret = m_fUpdate(m_ctx, m_buf.data() + m_bufWritePos, &outl, data.data(),
-                    data.size());
-    if (ret != 1) {
-        ThrowMsg(Exception::InternalError,
-                 "Failed to encrypt data in openssl");
-    }
-    m_bufWritePos += outl;
-
-    return outl;
-}
-
-RawBuffer AesCrypt::get()
-{
-    if (m_finalized)
-        return m_buf;
-    else
-        return RawBuffer();
-}
-
-AESCryptMode AesCrypt::getMode()
-{
-    return m_mode;
-}
-
-/******************************************************************************
- *****************************************************************************/
-
-AesEncrypt::AesEncrypt() :
-    AesCrypt(AESCryptMode::ENCODER, "")
-{
-}
-
-AesEncrypt::AesEncrypt(std::string password) :
-    AesCrypt(AESCryptMode::ENCODER, password)
-{
-}
-
-AesEncrypt::~AesEncrypt()
-{
-}
-
-/******************************************************************************
- *****************************************************************************/
-
-AesDecrypt::AesDecrypt() :
-    AesCrypt(AESCryptMode::DECODER, "")
-{
-}
-
-AesDecrypt::AesDecrypt(std::string password) :
-    AesCrypt(AESCryptMode::DECODER, password)
-{
-}
-
-AesDecrypt::~AesDecrypt()
-{
-}
-
-} // namespace CKM
-
diff --git a/src/manager/common/aesCrypt.h b/src/manager/common/aesCrypt.h
deleted file mode 100644 (file)
index 234a257..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-#pragma once
-
-#include <string>
-
-#include <dpl/noncopyable.h>
-#include <dpl/exception.h>
-
-#include <ckm/ckm-type.h>
-
-/*
- * Taken from openssl/ossl_typ.h
- */
-struct evp_cipher_st;
-typedef evp_cipher_st EVP_CIPHER;
-struct evp_cipher_ctx_st;
-typedef evp_cipher_ctx_st EVP_CIPHER_CTX;
-struct engine_st;
-typedef engine_st ENGINE;
-
-namespace CKM {
-
-class CryptoAlgConf
-{
-    public:
-        class Exception
-        {
-            public:
-                DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
-                DECLARE_EXCEPTION_TYPE(Base, InternalError)
-        };
-
-        CryptoAlgConf(const EVP_CIPHER *cipher);
-        CryptoAlgConf(const EVP_CIPHER *cipher, std::string &password);
-        ~CryptoAlgConf();
-
-        const EVP_CIPHER *getCipher(void);
-        void setKey(const RawBuffer &key);
-        void setIV(const RawBuffer &iv);
-        void setSalt(const RawBuffer &salt); // TODO: not used yet
-        RawBuffer getKey(void);
-        RawBuffer getIV(void);
-        RawBuffer getSalt(void);
-        void generateKey(std::string &password, bool use_iv = false);
-        void generateRandIV(void);
-        std::size_t maxBufLen(std::size_t len);
-
-    private:
-        RawBuffer m_key;
-        RawBuffer m_iv;
-        RawBuffer m_salt; // TODO:  not used yet
-        const EVP_CIPHER *m_cipher;
-        std::size_t m_keyLen;
-        std::size_t m_ivLen;
-        std::size_t m_saltLen;
-        int m_pkcs5_password_iter;
-
-        void preinit(const EVP_CIPHER *cipher);
-};
-
-enum class AESCryptMode : int {
-    ENCODER,
-    DECODER
-};
-
-class AesCrypt : public CKM::Noncopyable
-{
-    public:
-        class Exception
-        {
-            public:
-                DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
-                DECLARE_EXCEPTION_TYPE(Base, InternalError)
-        };
-
-        AesCrypt(AESCryptMode mode, std::string password);
-        ~AesCrypt();
-
-        void reset(void);
-        RawBuffer finalize(void);
-        RawBuffer get(void);
-        int append(const RawBuffer &data);
-        AESCryptMode getMode(void);
-        CryptoAlgConf conf;
-
-    private:
-        EVP_CIPHER_CTX *m_ctx;
-        RawBuffer m_buf;
-        bool m_initialized;
-        bool m_finalized;
-        int m_bufWritePos;
-        AESCryptMode m_mode;
-        bool m_padding;
-
-        int (*m_fInit)(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
-                       ENGINE *impl, const unsigned char *key,
-                       const unsigned char *iv);
-        int (*m_fUpdate)(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
-                         const unsigned char *in, int inl);
-        int (*m_fFinal)(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
-};
-
-class AesEncrypt : public AesCrypt
-{
-    public:
-        AesEncrypt();
-        AesEncrypt(std::string password);
-        ~AesEncrypt();
-};
-
-class AesDecrypt : public AesCrypt
-{
-    public:
-        AesDecrypt();
-        AesDecrypt(std::string password);
-        ~AesDecrypt();
-};
-
-} // namespace CKM
-
diff --git a/src/manager/common/crypto.h b/src/manager/common/crypto.h
new file mode 100644 (file)
index 0000000..82122c4
--- /dev/null
@@ -0,0 +1,134 @@
+/* Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ *
+ *
+ * @file        crypto.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Crypto module implementation.
+ */
+#pragma once
+
+#include <dpl/log/log.h>
+
+#include <openssl/evp.h>
+
+#include <vector>
+
+namespace CKM {
+
+typedef std::vector<unsigned char> RawBuffer;
+
+namespace Crypto {
+
+class Exception
+{
+public:
+    DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
+    DECLARE_EXCEPTION_TYPE(Base, InternalError)
+};
+
+namespace Cipher {
+
+template<class T>
+struct Base {
+    Base()
+      : m_ctx(EVP_CIPHER_CTX_new())
+    {
+        static_assert(sizeof(typename T::value_type) == 1, "Unsupported type inside conatainer.");
+    }
+    Base(const Base&) = delete;
+    Base(Base &&) = delete;
+    Base<T>& operator=(const Base&) = delete;
+    Base<T>& operator=(Base &&) = delete;
+
+    virtual T Append(const T&) = 0;
+    virtual T Finalize() = 0;
+    virtual ~Base(){
+        EVP_CIPHER_CTX_free(m_ctx);
+    }
+protected:
+    EVP_CIPHER_CTX *m_ctx;
+};
+
+template<class T>
+class EvpCipherWrapper : public Base<T> {
+public:
+    using Base<T>::m_ctx;
+
+    EvpCipherWrapper(const EVP_CIPHER *type, const T &key, const T &iv, bool encryption)
+    {
+        if (static_cast<int>(key.size()) != EVP_CIPHER_key_length(type)) {
+            LogError("Wrong key size! Expected: "
+                << EVP_CIPHER_key_length(type) << " Get: " << key.size());
+            ThrowMsg(CKM::Crypto::Exception::InternalError, "Wrong key size! Expected: "
+                << EVP_CIPHER_key_length(type) << " Get: " << key.size());
+        }
+
+        if (static_cast<int>(iv.size()) < EVP_CIPHER_iv_length(type)) {
+            LogError("Wrong iv size! Expected: "
+                << EVP_CIPHER_iv_length(type) << " Get: " << iv.size());
+            ThrowMsg(CKM::Crypto::Exception::InternalError, "Wrong iv size! Expected: "
+                << EVP_CIPHER_iv_length(type) << " Get: " << iv.size());
+        }
+
+        if (1 != EVP_CipherInit_ex(m_ctx, type, NULL, key.data(), iv.data(), encryption ? 1 : 0)) {
+            LogError("Failed in EVP_CipherInit");
+            ThrowMsg(CKM::Crypto::Exception::InternalError, "Failed in EVP_CipherInit");
+        }
+
+        EVP_CIPHER_CTX_set_padding(m_ctx, 1);
+    }
+
+    T Append(const T& data) {
+        static_assert(sizeof(typename T::value_type) == 1, "Unsupported type inside container.");
+        int bytesLen = static_cast<int>(data.size() + EVP_CIPHER_CTX_block_size(m_ctx));
+        T output(bytesLen);
+        if (1 != EVP_CipherUpdate(m_ctx, output.data(), &bytesLen, data.data(), data.size())) {
+            LogError("Failed in EVP_CipherUpdate");
+            ThrowMsg(CKM::Crypto::Exception::InternalError, "Failed in EVP_CipherUpdate");
+        }
+        output.resize(bytesLen);
+        return output;
+    }
+
+    T Finalize() {
+        int bytesLen = EVP_CIPHER_CTX_block_size(m_ctx);
+        T output(bytesLen);
+        if (1 != EVP_CipherFinal_ex(m_ctx, output.data(), &bytesLen)) {
+            LogError("Failed in EVP_CipherFinal");
+            ThrowMsg(CKM::Crypto::Exception::InternalError, "Failed in EVP_CipherFinal");
+        }
+        output.resize(bytesLen);
+        return output;
+    }
+};
+
+#define DEFINE_CIPHER(__classname, __type, __evpcipher, __encryption) \
+class __classname : public EvpCipherWrapper<__type> {                 \
+public:                                                               \
+    __classname(const __type &key, const __type &iv)                  \
+      : EvpCipherWrapper(__evpcipher, key, iv, __encryption)          \
+    {}                                                                \
+}
+
+DEFINE_CIPHER(AesCbcEncryption, RawBuffer, EVP_aes_256_cbc(), true);
+DEFINE_CIPHER(AesCbcDecryption, RawBuffer, EVP_aes_256_cbc(), false);
+
+#undef DEFINE_CIPHER
+
+} // namespace Cipher
+} // namespace Crypto
+} // namespace CKM
+
diff --git a/src/manager/service/DBCryptoModule.cpp b/src/manager/service/DBCryptoModule.cpp
deleted file mode 100644 (file)
index a6be10b..0000000
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- *    Licensed under the Apache License, Version 2.0 (the "License");
- *    you may not use this file except in compliance with the License.
- *    You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- */
-
-#include <iostream>
-#include <fstream>
-#include <stdio.h>
-#include <string.h>
-
-#include <dpl/log/log.h>
-#include <base64.h>
-#include <ckm/ckm-error.h>
-#include <digest.h>
-
-#include <DBCryptoModule.h>
-
-namespace CKM {
-
-DBCryptoModule::DBCryptoModule(){}
-
-DBCryptoModule::DBCryptoModule(DBCryptoModule &&second) {
-    m_keyMap = std::move(second.m_keyMap);
-}
-
-DBCryptoModule& DBCryptoModule::operator=(DBCryptoModule &&second) {
-    if (this == &second)
-        return *this;
-    m_keyMap = std::move(second.m_keyMap);
-    return *this;
-}
-
-bool DBCryptoModule::haveKey(const std::string &smackLabel)
-{
-    return (m_keyMap.count(smackLabel) > 0);
-}
-
-int DBCryptoModule::pushKey(const std::string &smackLabel,
-                            const RawBuffer &applicationKey)
-{
-    if (smackLabel.length() == 0) {
-        ThrowMsg(Exception::InternalError, "Empty smack label.");
-    }
-    if (applicationKey.size() == 0) {
-        ThrowMsg(Exception::InternalError, "Empty application key.");
-    }
-    if (haveKey(smackLabel)) {
-        ThrowMsg(Exception::InternalError, "Application key for " << smackLabel
-                 << "label already exists.");
-    }
-    m_keyMap[smackLabel] = applicationKey;
-    return CKM_API_SUCCESS;
-}
-
-std::size_t DBCryptoModule::insertDigest(RawBuffer &data, const int dataSize)
-{
-    RawBuffer digest;
-
-    try {
-        Digest dig;
-        dig.append(data, dataSize);
-        digest = dig.finalize();
-    } catch (Digest::Exception::Base &e) {
-        LogError("Failed to calculate digest in insertDigest: " <<
-                 e.DumpToString());
-        throw;
-    }
-    data.insert(data.begin(), digest.begin(), digest.end());
-    return digest.size();
-}
-
-void DBCryptoModule::removeDigest(RawBuffer &data, RawBuffer &digest)
-{
-    unsigned int dlen = Digest().length();
-
-    if (data.size() < dlen) {
-        ThrowMsg(Exception::InternalError,
-                 "Cannot remove digest: data size mismatch.");
-    }
-
-    digest.assign(data.begin(), data.begin() + dlen);
-    data.erase(data.begin(), data.begin() + dlen);
-}
-
-int DBCryptoModule::encryptRow(const std::string &password, DBRow &row)
-{
-    RawBuffer emptyiv;
-    RawBuffer emptykey;
-    DBRow crow = row;
-    RawBuffer appkey;
-
-    crow.algorithmType = DBCMAlgType::NONE;
-    if (row.dataSize <= 0) {
-        ThrowMsg(Exception::EncryptDBRowError, "Invalid dataSize.");
-    }
-    if (!haveKey(row.smackLabel)) {
-        ThrowMsg(Exception::EncryptDBRowError, "Missing application key for " <<
-                 row.smackLabel << " label.");
-    }
-    appkey = m_keyMap[row.smackLabel];
-    crow.encryptionScheme = 0;
-
-    try {
-        insertDigest(crow.data, crow.dataSize);
-        cryptAES(crow.data, appkey, emptyiv, "");
-        crow.encryptionScheme |= ENCR_APPKEY;
-        if (!password.empty()) {
-            crow.iv = cryptAES(crow.data, emptykey, emptyiv, password).getIV();
-            crow.encryptionScheme |= ENCR_PASSWORD;
-        }
-        encBase64(crow.data);
-        crow.encryptionScheme |= ENCR_BASE64;
-        encBase64(crow.iv);
-    } catch (Exception::Base &e) {
-        LogError("Failed to encrypt db row: " << e.DumpToString());
-        throw;
-    } catch (AesCrypt::Exception::Base &e) {
-        LogError("Failed to encrypt db row: " << e.DumpToString());
-        throw;
-    }
-    crow.algorithmType = DBCMAlgType::AES_CBC_256;
-    row = crow;
-
-    return CKM_API_SUCCESS;
-}
-
-int DBCryptoModule::decryptRow(const std::string &password, DBRow &row)
-{
-    DBRow crow = row;
-    RawBuffer appkey;
-    RawBuffer emptykey;
-    RawBuffer dropiv;
-    RawBuffer emptyiv;
-    RawBuffer digest, dataDigest;
-
-    if (row.dataSize <= 0) {
-        ThrowMsg(Exception::DecryptDBRowError, "Invalid dataSize.");
-    }
-    if (row.algorithmType != DBCMAlgType::AES_CBC_256) {
-        ThrowMsg(Exception::DecryptDBRowError, "Invalid algorithm type.");
-    }
-    if (row.encryptionScheme & ENCR_PASSWORD)
-        if (password.empty()) {
-            ThrowMsg(Exception::DecryptDBRowError,
-                     "DB row is password protected, but given password is "
-                     "empty.");
-        }
-    if (!haveKey(row.smackLabel)) {
-        ThrowMsg(Exception::DecryptDBRowError, "Missing application key for " <<
-                 row.smackLabel << " label.");
-    }
-    appkey = m_keyMap[row.smackLabel];
-
-    try {
-        decBase64(crow.iv);
-        if (crow.encryptionScheme & ENCR_BASE64) {
-            decBase64(crow.data);
-        }
-        if (crow.encryptionScheme & ENCR_PASSWORD) {
-            decryptAES(crow.data, emptykey, crow.iv, password);
-        }
-        if (crow.encryptionScheme & ENCR_APPKEY) {
-            decryptAES(crow.data, appkey, emptyiv, "");
-        }
-        removeDigest(crow.data, digest);
-        if (static_cast<std::size_t>(crow.dataSize) != crow.data.size()) {
-            ThrowMsg(Exception::DecryptDBRowError,
-                     "Decrypted db row data size mismatch.");
-        }
-        Digest dig;
-        dig.append(crow.data);
-        dataDigest = dig.finalize();
-    } catch (Exception::Base &e) {
-        LogError("Failed to decrypt db row: " << e.DumpToString());
-        throw;
-    } catch (AesCrypt::Exception::Base &e) {
-        LogError("Failed to decrypt db row: " << e.DumpToString());
-        throw;
-    } catch (Digest::Exception::Base &e) {
-        LogError("Failed to decrypt db row: " << e.DumpToString());
-        throw;
-    }
-    if (not equalDigests(digest, dataDigest)) {
-        ThrowMsg(Exception::DecryptDBRowError,
-                 "Decrypted db row data digest mismatch.");
-    }
-    row = crow;
-
-    return CKM_API_SUCCESS;
-}
-
-CryptoAlgConf DBCryptoModule::cryptAES(RawBuffer &data,
-                                       const RawBuffer &key,
-                                       const RawBuffer &iv,
-                                       std::string password)
-{
-    try {
-        AesEncrypt enc(password);
-
-        if (password.empty()) {
-            enc.conf.setKey(key);
-            enc.conf.setIV(iv);
-        }
-        enc.append(data);
-        data = enc.finalize();
-        return enc.conf;
-    } catch (CryptoAlgConf::Exception::Base &e) {
-        LogError("Failed to configure AES encryption: " << e.DumpToString());
-        throw;
-    } catch (AesCrypt::Exception::Base &e) {
-        LogError("AES encryption failed: " << e.DumpToString());
-        throw;
-    }
-}
-
-void DBCryptoModule::decryptAES(RawBuffer &data, const RawBuffer &key,
-                                const RawBuffer &iv, std::string password)
-{
-    try {
-        AesDecrypt dec(password);
-
-        if (password.empty()) {
-            dec.conf.setKey(key);
-        }
-        dec.conf.setIV(iv);
-        dec.append(data);
-        data = dec.finalize();
-    } catch (CryptoAlgConf::Exception::Base &e) {
-        LogError("Failed to configure AES decryption: " << e.DumpToString());
-        throw;
-    } catch (AesCrypt::Exception::Base &e) {
-        LogError("AES Decryption failed: " << e.DumpToString());
-        throw;
-    }
-}
-
-void DBCryptoModule::encBase64(RawBuffer &data)
-{
-    Base64Encoder benc;
-    RawBuffer encdata;
-
-    try {
-        benc.append(data);
-        benc.finalize();
-        encdata = benc.get();
-    } catch (Base64Encoder::Exception::Base &e) {
-        LogError("Failed to encode data in Base64Encoder: " <<
-                 e.DumpToString());
-        throw;
-    }
-
-    if (encdata.size() == 0) {
-        ThrowMsg(Exception::Base64EncoderError, "Base64Encoder returned empty data.");
-    }
-
-    data = std::move(encdata);
-}
-
-void DBCryptoModule::decBase64(RawBuffer &data)
-{
-    Base64Decoder bdec;
-    RawBuffer decdata;
-
-    try {
-        bdec.reset();
-        bdec.append(data);
-        if (not bdec.finalize()) {
-            ThrowMsg(Exception::Base64DecoderError,
-                     "Failed in Base64Decoder.finalize.");
-        }
-
-        decdata = bdec.get();
-    } catch (Base64Decoder::Exception::Base &e) {
-        LogError("Failed to decode data in Base64Decoder: " <<
-                 e.DumpToString());
-        throw;
-    }
-    if (decdata.size() == 0) {
-        ThrowMsg(Exception::Base64DecoderError, "Base64Decoder returned empty data.");
-    }
-
-    data = std::move(decdata);
-}
-
-bool DBCryptoModule::equalDigests(RawBuffer &dig1, RawBuffer &dig2)
-{
-    unsigned int dlen = Digest().length();
-
-    if ((dig1.size() != dlen) || (dig2.size() != dlen))
-        return false;
-    return (dig1 == dig2);
-}
-
-} // namespace CKM
-
index b271782..696ff73 100644 (file)
@@ -71,12 +71,18 @@ RawBuffer CKMLogic::unlockUserKey(uid_t user, const std::string &password) {
 
             RawBuffer key = handle.keyProvider.getPureDomainKEK();
             handle.database = DBCrypto(fs.getDBPath(), key);
-            handle.crypto = DBCryptoModule();
+            handle.crypto = CryptoLogic();
             // TODO wipe key
         }
     } catch (const KeyProvider::Exception::Base &e) {
         LogError("Error in KeyProvider " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
+    } catch (const CryptoLogic::Exception::Base &e) {
+        LogError("CryptoLogic error: " << e.GetMessage());
+        retCode = CKM_API_ERROR_SERVER_ERROR;
+    } catch (const CKM::Exception &e) {
+        LogError("CKM::Exception: " << e.GetMessage());
+        retCode = CKM_API_ERROR_SERVER_ERROR;
     }
 
     MessageBuffer response;
@@ -158,7 +164,7 @@ int CKMLogic::saveDataHelper(
 
     DBRow row = { alias, cred.smackLabel, policy.restricted,
          policy.extractable, dataType, DBCMAlgType::NONE,
-         0, RawBuffer(10, 'c'), static_cast<int>(key.size()), key };
+         0, RawBuffer(), static_cast<int>(key.size()), key };
 
     auto &handler = m_userDataMap[cred.uid];
     DBCrypto::Transaction transaction(&handler.database);
@@ -199,8 +205,8 @@ RawBuffer CKMLogic::saveData(
     } catch (const KeyProvider::Exception::Base &e) {
         LogError("KeyProvider failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
-    } catch (const DBCryptoModule::Exception::Base &e) {
-        LogError("DBCryptoModule failed with message: " << e.GetMessage());
+    } catch (const CryptoLogic::Exception::Base &e) {
+        LogError("CryptoLogic failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
     } catch (const DBCrypto::Exception::InternalError &e) {
         LogError("DBCrypto failed with message: " << e.GetMessage());
@@ -312,8 +318,8 @@ RawBuffer CKMLogic::getData(
     } catch (const KeyProvider::Exception::Base &e) {
         LogError("KeyProvider failed with error: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
-    } catch (const DBCryptoModule::Exception::Base &e) {
-        LogError("DBCryptoModule failed with message: " << e.GetMessage());
+    } catch (const CryptoLogic::Exception::Base &e) {
+        LogError("CryptoLogic failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
     } catch (const DBCrypto::Exception::Base &e) {
         LogError("DBCrypto failed with message: " << e.GetMessage());
@@ -439,6 +445,9 @@ RawBuffer CKMLogic::createKeyPairRSA(
     } catch (DBCrypto::Exception::TransactionError &e) {
         LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
+    } catch (CKM::CryptoLogic::Exception::Base &e) {
+        LogDebug("CryptoLogic error: " << e.GetMessage());
+        retCode = CKM_API_ERROR_SERVER_ERROR;
     } catch (DBCrypto::Exception::InternalError &e) {
         LogDebug("DBCrypto internal error: " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
@@ -524,6 +533,9 @@ RawBuffer CKMLogic::createKeyPairECDSA(
     } catch (const DBCrypto::Exception::TransactionError &e) {
         LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
+    } catch (const CKM::CryptoLogic::Exception::Base &e) {
+        LogDebug("CryptoLogic error: " << e.GetMessage());
+        retCode = CKM_API_ERROR_SERVER_ERROR;
     } catch (const DBCrypto::Exception::InternalError &e) {
         LogDebug("DBCrypto internal error: " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
@@ -606,7 +618,7 @@ RawBuffer CKMLogic::getCertificateChain(
         for (auto &i: chainVector)
             chainRawVector.push_back(i.getDER());
 
-    } catch (const DBCryptoModule::Exception::Base &e) {
+    } catch (const CryptoLogic::Exception::Base &e) {
         LogError("DBCyptorModule failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
     } catch (const DBCrypto::Exception::Base &e) {
@@ -657,12 +669,15 @@ RawBuffer CKMLogic::createSignature(
     } catch (const KeyProvider::Exception::Base &e) {
         LogError("KeyProvider failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
-    } catch (const DBCryptoModule::Exception::Base &e) {
-        LogError("DBCryptoModule failed with message: " << e.GetMessage());
+    } catch (const CryptoLogic::Exception::Base &e) {
+        LogError("CryptoLogic failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
     } catch (const DBCrypto::Exception::Base &e) {
         LogError("DBCrypto failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
+    } catch (const CKM::Exception &e) {
+        LogError("Unknown CKM::Exception: " << e.GetMessage());
+        retCode = CKM_API_ERROR_SERVER_ERROR;
     }
 
     MessageBuffer response;
@@ -721,12 +736,15 @@ RawBuffer CKMLogic::verifySignature(
     } catch (const KeyProvider::Exception::Base &e) {
         LogError("KeyProvider failed with error: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
-    } catch (const DBCryptoModule::Exception::Base &e) {
-        LogError("DBCryptoModule failed with message: " << e.GetMessage());
+    } catch (const CryptoLogic::Exception::Base &e) {
+        LogError("CryptoLogic failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_SERVER_ERROR;
     } catch (const DBCrypto::Exception::Base &e) {
         LogError("DBCrypto failed with message: " << e.GetMessage());
         retCode = CKM_API_ERROR_DB_ERROR;
+    } catch (const CKM::Exception &e) {
+        LogError("Unknown CKM::Exception: " << e.GetMessage());
+        retCode = CKM_API_ERROR_SERVER_ERROR;
     }
 
     MessageBuffer response;
index 59f02a0..661a6a7 100644 (file)
@@ -30,7 +30,7 @@
 #include <connection-info.h>
 #include <db-crypto.h>
 #include <key-provider.h>
-#include <DBCryptoModule.h>
+#include <crypto-logic.h>
 #include <certificate-store.h>
 
 namespace CKM {
@@ -38,7 +38,7 @@ namespace CKM {
 struct UserData {
     KeyProvider    keyProvider;
     DBCrypto       database;
-    DBCryptoModule crypto;
+    CryptoLogic    crypto;
 };
 
 class CKMLogic {
diff --git a/src/manager/service/crypto-logic.cpp b/src/manager/service/crypto-logic.cpp
new file mode 100644 (file)
index 0000000..4b71210
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ * @file        crypto-logic.cpp
+ * @author      Sebastian Grabowski (s.grabowski@samsung.com)
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Crypto module implementation.
+ */
+
+#include <iostream>
+#include <fstream>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+
+#include <ckm/ckm-error.h>
+
+#include <dpl/log/log.h>
+
+#include <base64.h>
+#include <digest.h>
+#include <crypto.h>
+#include <crypto-logic.h>
+
+#define AES_CBC_KEY_SIZE 32
+
+namespace CKM {
+
+CryptoLogic::CryptoLogic(){}
+
+CryptoLogic::CryptoLogic(CryptoLogic &&second) {
+    m_keyMap = std::move(second.m_keyMap);
+}
+
+CryptoLogic& CryptoLogic::operator=(CryptoLogic &&second) {
+    if (this == &second)
+        return *this;
+    m_keyMap = std::move(second.m_keyMap);
+    return *this;
+}
+
+bool CryptoLogic::haveKey(const std::string &smackLabel)
+{
+    return (m_keyMap.count(smackLabel) > 0);
+}
+
+void CryptoLogic::pushKey(const std::string &smackLabel,
+                            const RawBuffer &applicationKey)
+{
+    if (smackLabel.length() == 0) {
+        ThrowMsg(Exception::InternalError, "Empty smack label.");
+    }
+    if (applicationKey.size() == 0) {
+        ThrowMsg(Exception::InternalError, "Empty application key.");
+    }
+    if (haveKey(smackLabel)) {
+        ThrowMsg(Exception::InternalError, "Application key for " << smackLabel
+                 << "label already exists.");
+    }
+    m_keyMap[smackLabel] = applicationKey;
+}
+
+std::size_t CryptoLogic::insertDigest(RawBuffer &data, const int dataSize)
+{
+    RawBuffer digest;
+
+    try {
+        Digest dig;
+        dig.append(data, dataSize);
+        digest = dig.finalize();
+    } catch (Digest::Exception::Base &e) {
+        LogError("Failed to calculate digest in insertDigest: " <<
+                 e.DumpToString());
+        ThrowMsg(Exception::InternalError, e.GetMessage());
+    }
+    data.insert(data.begin(), digest.begin(), digest.end());
+    return digest.size();
+}
+
+void CryptoLogic::removeDigest(RawBuffer &data, RawBuffer &digest)
+{
+    unsigned int dlen = Digest().length();
+
+    if (data.size() < dlen) {
+        ThrowMsg(Exception::InternalError,
+                 "Cannot remove digest: data size mismatch.");
+    }
+
+    digest.assign(data.begin(), data.begin() + dlen);
+    data.erase(data.begin(), data.begin() + dlen);
+}
+
+RawBuffer CryptoLogic::encryptData(
+    const RawBuffer &data,
+    const RawBuffer &key,
+    const RawBuffer &iv) const
+{
+    Crypto::Cipher::AesCbcEncryption enc(key, iv);
+    RawBuffer result = enc.Append(data);
+    RawBuffer tmp = enc.Finalize();
+    std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
+    return result;
+}
+
+RawBuffer CryptoLogic::decryptData(
+    const RawBuffer &data,
+    const RawBuffer &key,
+    const RawBuffer &iv) const
+{
+    Crypto::Cipher::AesCbcDecryption dec(key, iv);
+    RawBuffer result = dec.Append(data);
+    RawBuffer tmp = dec.Finalize();
+    std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
+    return result;
+}
+
+RawBuffer CryptoLogic::passwordToKey(
+    const std::string &password,
+    const RawBuffer &salt,
+    size_t keySize) const
+{
+    RawBuffer result(keySize);
+
+    if (1 != PKCS5_PBKDF2_HMAC_SHA1(
+                password.c_str(),
+                password.size(),
+                salt.data(),
+                salt.size(),
+                1024,
+                result.size(),
+                result.data()))
+    {
+        ThrowMsg(Exception::InternalError, "PCKS5_PKKDF_HMAC_SHA1 failed.");
+    }
+    return result;
+}
+
+RawBuffer CryptoLogic::generateRandIV() const {
+    RawBuffer civ(EVP_MAX_IV_LENGTH);
+
+    if (1 != RAND_bytes(civ.data(), civ.size())) {
+        ThrowMsg(Exception::InternalError,
+          "RAND_bytes failed to generate IV.");
+    }
+
+    return civ;
+}
+
+void CryptoLogic::encryptRow(const std::string &password, DBRow &row)
+{
+    try {
+        DBRow crow = row;
+        RawBuffer key;
+        RawBuffer result1;
+        RawBuffer result2;
+
+        crow.algorithmType = DBCMAlgType::AES_CBC_256;
+
+        if (crow.dataSize <= 0) {
+            ThrowMsg(Exception::EncryptDBRowError, "Invalid dataSize.");
+        }
+
+        if (!haveKey(row.smackLabel)) {
+            ThrowMsg(Exception::EncryptDBRowError, "Missing application key for " <<
+              row.smackLabel << " label.");
+        }
+
+        if (crow.iv.empty()) {
+            crow.iv = generateRandIV();
+        }
+
+        key = m_keyMap[row.smackLabel];
+        crow.encryptionScheme = ENCR_APPKEY;
+
+        insertDigest(crow.data, crow.dataSize);
+        crow.data = encryptData(crow.data, key, crow.iv);
+
+        if (!password.empty()) {
+            key = passwordToKey(password, crow.iv, AES_CBC_KEY_SIZE);
+            crow.data = encryptData(crow.data, key, crow.iv);
+            crow.encryptionScheme |= ENCR_PASSWORD;
+        }
+
+        encBase64(crow.data);
+        crow.encryptionScheme |= ENCR_BASE64;
+        encBase64(crow.iv);
+
+        row = crow;
+    } catch(const CKM::Base64Encoder::Exception::Base &e) {
+        LogDebug("Base64Encoder error: " << e.GetMessage());
+        ThrowMsg(Exception::Base64EncoderError, e.GetMessage());
+    } catch(const CKM::Base64Decoder::Exception::Base &e) {
+        LogDebug("Base64Encoder error: " << e.GetMessage());
+        ThrowMsg(Exception::Base64DecoderError, e.GetMessage());
+    } catch(const CKM::Crypto::Exception::Base &e) {
+        LogDebug("Crypto error: " << e.GetMessage());
+        ThrowMsg(Exception::EncryptDBRowError, e.GetMessage());
+    }
+}
+
+void CryptoLogic::decryptRow(const std::string &password, DBRow &row)
+{
+    try {
+        DBRow crow = row;
+        RawBuffer key;
+        RawBuffer digest, dataDigest;
+
+        if (row.algorithmType != DBCMAlgType::AES_CBC_256) {
+            ThrowMsg(Exception::DecryptDBRowError, "Invalid algorithm type.");
+        }
+
+        if ((row.encryptionScheme & ENCR_PASSWORD) && password.empty()) {
+            ThrowMsg(Exception::DecryptDBRowError,
+              "DB row is password protected, but given password is "
+              "empty.");
+        }
+
+        if ((row.encryptionScheme & ENCR_APPKEY) && !haveKey(row.smackLabel)) {
+            ThrowMsg(Exception::DecryptDBRowError, "Missing application key for " <<
+              row.smackLabel << " label.");
+        }
+
+        decBase64(crow.iv);
+        if (crow.encryptionScheme & ENCR_BASE64) {
+            decBase64(crow.data);
+        }
+
+        if (crow.encryptionScheme & ENCR_PASSWORD) {
+            key = passwordToKey(password, crow.iv, AES_CBC_KEY_SIZE);
+            crow.data = decryptData(crow.data, key, crow.iv);
+        }
+
+        if (crow.encryptionScheme & ENCR_APPKEY) {
+            key = m_keyMap[crow.smackLabel];
+            crow.data = decryptData(crow.data, key, crow.iv);
+        }
+
+        removeDigest(crow.data, digest);
+
+        if (static_cast<std::size_t>(crow.dataSize) != crow.data.size()) {
+            ThrowMsg(Exception::DecryptDBRowError,
+              "Decrypted db row data size mismatch.");
+        }
+
+        Digest dig;
+        dig.append(crow.data);
+        dataDigest = dig.finalize();
+
+        if (not equalDigests(digest, dataDigest)) {
+            ThrowMsg(Exception::DecryptDBRowError,
+              "Decrypted db row data digest mismatch.");
+        }
+        row = crow;
+    } catch(const CKM::Base64Encoder::Exception::Base &e) {
+        LogDebug("Base64Encoder error: " << e.GetMessage());
+        ThrowMsg(Exception::Base64EncoderError, e.GetMessage());
+    } catch(const CKM::Base64Decoder::Exception::Base &e) {
+        LogDebug("Base64Encoder error: " << e.GetMessage());
+        ThrowMsg(Exception::Base64DecoderError, e.GetMessage());
+    } catch(const CKM::Crypto::Exception::Base &e) {
+        LogDebug("Crypto error: " << e.GetMessage());
+        ThrowMsg(Exception::DecryptDBRowError, e.GetMessage());
+    }
+}
+
+void CryptoLogic::encBase64(RawBuffer &data)
+{
+    Base64Encoder benc;
+    RawBuffer encdata;
+
+    benc.append(data);
+    benc.finalize();
+    encdata = benc.get();
+
+    if (encdata.size() == 0) {
+        ThrowMsg(Exception::Base64EncoderError, "Base64Encoder returned empty data.");
+    }
+
+    data = std::move(encdata);
+}
+
+void CryptoLogic::decBase64(RawBuffer &data)
+{
+    Base64Decoder bdec;
+    RawBuffer decdata;
+
+    bdec.reset();
+    bdec.append(data);
+    if (not bdec.finalize()) {
+        ThrowMsg(Exception::Base64DecoderError,
+          "Failed in Base64Decoder.finalize.");
+    }
+
+    decdata = bdec.get();
+
+    if (decdata.size() == 0) {
+        ThrowMsg(Exception::Base64DecoderError, "Base64Decoder returned empty data.");
+    }
+
+    data = std::move(decdata);
+}
+
+bool CryptoLogic::equalDigests(RawBuffer &dig1, RawBuffer &dig2)
+{
+    unsigned int dlen = Digest().length();
+
+    if ((dig1.size() != dlen) || (dig2.size() != dlen))
+        return false;
+    return (dig1 == dig2);
+}
+
+} // namespace CKM
+
similarity index 59%
rename from src/manager/service/DBCryptoModule.h
rename to src/manager/service/crypto-logic.h
index c1f0a8e..00eed7f 100644 (file)
  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *    See the License for the specific language governing permissions and
  *    limitations under the License.
+ *
+ * @file        crypto-logic.h
+ * @author      Sebastian Grabowski (s.grabowski@samsung.com)
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Crypto module implementation.
  */
-
 #pragma once
 
 #include <map>
 #include <ckm/ckm-type.h>
 #include <db-crypto.h>
 #include <dpl/exception.h>
-#include <aesCrypt.h>
 
 namespace CKM {
 
-class DBCryptoModule {
+class CryptoLogic {
 public:
     class Exception
     {
@@ -36,39 +40,47 @@ public:
             DECLARE_EXCEPTION_TYPE(Base, EncryptDBRowError)
             DECLARE_EXCEPTION_TYPE(Base, DecryptDBRowError)
     };
-    DBCryptoModule();
-    DBCryptoModule(const DBCryptoModule &second) = delete;
-    DBCryptoModule(DBCryptoModule &&second);
-    DBCryptoModule& operator=(DBCryptoModule &&second);
-    DBCryptoModule& operator=(const DBCryptoModule &second) = delete;
+    CryptoLogic();
+    CryptoLogic(const CryptoLogic &second) = delete;
+    CryptoLogic(CryptoLogic &&second);
+    CryptoLogic& operator=(CryptoLogic &&second);
+    CryptoLogic& operator=(const CryptoLogic &second) = delete;
 
-    virtual ~DBCryptoModule(){}
+    virtual ~CryptoLogic(){}
 
-    int decryptRow(const std::string &password, DBRow &row);
-    int encryptRow(const std::string &password, DBRow &row);
+    void decryptRow(const std::string &password, DBRow &row);
+    void encryptRow(const std::string &password, DBRow &row);
 
     bool haveKey(const std::string &smackLabel);
-    int pushKey(const std::string &smackLabel,
-                const RawBuffer &applicationKey);
+    void pushKey(const std::string &smackLabel,
+                 const RawBuffer &applicationKey);
 
 private:
        static const int ENCR_BASE64 =   1 << 0;
        static const int ENCR_APPKEY =   1 << 1;
        static const int ENCR_PASSWORD = 1 << 2;
-       
+
        std::map<std::string, RawBuffer> m_keyMap;
 
-    /* TODO: Move it to private/protected after tests (or remove if not needed) */
-    CryptoAlgConf cryptAES(RawBuffer &data, const RawBuffer &key,
-                           const RawBuffer &iv, std::string password);
-    void decryptAES(RawBuffer &data, const RawBuffer &key, const RawBuffer &iv,
-                    std::string password);
+    RawBuffer generateRandIV() const;
+    RawBuffer passwordToKey(const std::string &password,
+                            const RawBuffer &salt,
+                            size_t keySize) const;
+
+    RawBuffer encryptData(
+        const RawBuffer &data,
+        const RawBuffer &key,
+        const RawBuffer &iv) const;
+
+    RawBuffer decryptData(
+        const RawBuffer &data,
+        const RawBuffer &key,
+        const RawBuffer &iv) const;
+
     void decBase64(RawBuffer &data);
     void encBase64(RawBuffer &data);
     bool equalDigests(RawBuffer &dig1, RawBuffer &dig2);
     std::size_t insertDigest(RawBuffer &data, const int dataSize);
-    void generateKeysFromPassword(const std::string &password,
-                                  RawBuffer &key, RawBuffer &iv);
     void removeDigest(RawBuffer &data, RawBuffer &digest);
 };