Fix implementation of exportable flag.
[platform/core/security/key-manager.git] / src / manager / service / ckm-logic.cpp
old mode 100644 (file)
new mode 100755 (executable)
index d40e972..69434f7
@@ -21,7 +21,6 @@
  */
 #include <dpl/serialization.h>
 #include <dpl/log/log.h>
-
 #include <ckm/ckm-error.h>
 #include <ckm/ckm-type.h>
 #include <key-provider.h>
 #include <ckm-logic.h>
 #include <generic-key.h>
 
+namespace {
+const char * const CERT_SYSTEM_DIR = "/etc/ssl/certs";
+} // anonymous namespace
+
 namespace CKM {
 
-CKMLogic::CKMLogic(){
+CKMLogic::CKMLogic()
+{
     int retCode = FileSystem::init();
     // TODO what can I do when init went wrong? exit(-1) ??
     if (retCode) {
         LogError("Fatal error in FileSystem::init()");
     }
+
+    if (CKM_API_SUCCESS != m_certStore.setSystemCertificateDir(CERT_SYSTEM_DIR)) {
+        LogError("Fatal error in CertificateStore::setSystemCertificateDir. Chain creation will not work");
+    }
 }
 
 CKMLogic::~CKMLogic(){}
 
-RawBuffer CKMLogic::unlockUserKey(uid_t user, const std::string &password) {
+RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password) {
     // TODO try catch for all errors that should be supported by error code
-    int retCode = KEY_MANAGER_API_SUCCESS;
+    int retCode = CKM_API_SUCCESS;
 
     try {
         if (0 == m_userDataMap.count(user) || !(m_userDataMap[user].keyProvider.isInitialized())) {
@@ -61,12 +69,21 @@ RawBuffer CKMLogic::unlockUserKey(uid_t user, const std::string &password) {
 
             RawBuffer key = handle.keyProvider.getPureDomainKEK();
             handle.database = DBCrypto(fs.getDBPath(), key);
-            handle.crypto = DBCryptoModule(key);
+            handle.crypto = CryptoLogic();
             // TODO wipe key
         }
+    } catch (const KeyProvider::Exception::PassWordError &e) {
+        LogError("Incorrect Password " << e.GetMessage());
+        retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
     } catch (const KeyProvider::Exception::Base &e) {
         LogError("Error in KeyProvider " << e.GetMessage());
-        retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
+        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;
@@ -75,7 +92,7 @@ RawBuffer CKMLogic::unlockUserKey(uid_t user, const std::string &password) {
 }
 
 RawBuffer CKMLogic::lockUserKey(uid_t user) {
-    int retCode = KEY_MANAGER_API_SUCCESS;
+    int retCode = CKM_API_SUCCESS;
     // TODO try catch for all errors that should be supported by error code
     m_userDataMap.erase(user);
 
@@ -85,7 +102,7 @@ RawBuffer CKMLogic::lockUserKey(uid_t user) {
 }
 
 RawBuffer CKMLogic::removeUserData(uid_t user) {
-    int retCode = KEY_MANAGER_API_SUCCESS;
+    int retCode = CKM_API_SUCCESS;
     // TODO try catch for all errors that should be supported by error code
     m_userDataMap.erase(user);
 
@@ -99,19 +116,30 @@ RawBuffer CKMLogic::removeUserData(uid_t user) {
 
 RawBuffer CKMLogic::changeUserPassword(
     uid_t user,
-    const std::string &oldPassword,
-    const std::string &newPassword)
+    const Password &oldPassword,
+    const Password &newPassword)
 {
-    int retCode = KEY_MANAGER_API_SUCCESS;
-    // TODO try-catch
-    FileSystem fs(user);
-    auto wrappedDomainKEK = fs.getDomainKEK();
-    if (wrappedDomainKEK.empty()) {
-        retCode = KEY_MANAGER_API_ERROR_BAD_REQUEST;
-    } else {
-        wrappedDomainKEK = KeyProvider::reencrypt(wrappedDomainKEK, oldPassword, newPassword);
-        fs.saveDomainKEK(wrappedDomainKEK);
+    int retCode = CKM_API_SUCCESS;
+    try {
+        FileSystem fs(user);
+        auto wrappedDomainKEK = fs.getDomainKEK();
+        if (wrappedDomainKEK.empty()) {
+            retCode = CKM_API_ERROR_BAD_REQUEST;
+        } else {
+            wrappedDomainKEK = KeyProvider::reencrypt(wrappedDomainKEK, oldPassword, newPassword);
+            fs.saveDomainKEK(wrappedDomainKEK);
+        }
+    } catch (const KeyProvider::Exception::PassWordError &e) {
+        LogError("Incorrect Password " << e.GetMessage());
+        retCode = CKM_API_ERROR_AUTHENTICATION_FAILED;
+    } catch (const KeyProvider::Exception::Base &e) {
+        LogError("Error in KeyProvider " << 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;
     Serialization::Serialize(response, retCode);
     return response.Pop();
@@ -119,12 +147,12 @@ RawBuffer CKMLogic::changeUserPassword(
 
 RawBuffer CKMLogic::resetUserPassword(
     uid_t user,
-    const std::string &newPassword)
+    const Password &newPassword)
 {
-    int retCode = KEY_MANAGER_API_SUCCESS;
+    int retCode = CKM_API_SUCCESS;
     // TODO try-catch
     if (0 == m_userDataMap.count(user)) {
-        retCode = KEY_MANAGER_API_ERROR_BAD_REQUEST;
+        retCode = CKM_API_ERROR_BAD_REQUEST;
     } else {
         auto &handler = m_userDataMap[user];
         FileSystem fs(user);
@@ -144,11 +172,11 @@ int CKMLogic::saveDataHelper(
     const PolicySerializable &policy)
 {
     if (0 == m_userDataMap.count(cred.uid))
-        return KEY_MANAGER_API_ERROR_DB_LOCKED;
+        return CKM_API_ERROR_DB_LOCKED;
 
     DBRow row = { alias, cred.smackLabel, policy.restricted,
          policy.extractable, dataType, DBCMAlgType::NONE,
-         0, RawBuffer(10, 'c'), key.size(), key };
+         0, RawBuffer(), static_cast<int>(key.size()), key };
 
     auto &handler = m_userDataMap[cred.uid];
     DBCrypto::Transaction transaction(&handler.database);
@@ -159,18 +187,19 @@ int CKMLogic::saveDataHelper(
             LogDebug("No Key in database found. Generating new one for label: "
                     << cred.smackLabel);
             key = handler.keyProvider.generateDEK(cred.smackLabel);
+            handler.database.saveKey(cred.smackLabel, key);
         } else {
+            LogDebug("Key from DB");
             key = *key_optional;
         }
 
         key = handler.keyProvider.getPureDEK(key);
         handler.crypto.pushKey(cred.smackLabel, key);
-        handler.database.saveKey(cred.smackLabel, key);
     }
     handler.crypto.encryptRow(policy.password, row);
     handler.database.saveDBRow(row);
     transaction.commit();
-    return KEY_MANAGER_API_SUCCESS;
+    return CKM_API_SUCCESS;
 }
 
 RawBuffer CKMLogic::saveData(
@@ -181,25 +210,25 @@ RawBuffer CKMLogic::saveData(
     const RawBuffer &key,
     const PolicySerializable &policy)
 {
-    int retCode = KEY_MANAGER_API_SUCCESS;
+    int retCode = CKM_API_SUCCESS;
     try {
         retCode = saveDataHelper(cred, dataType, alias, key, policy);
         LogDebug("SaveDataHelper returned: " << retCode);
     } catch (const KeyProvider::Exception::Base &e) {
         LogError("KeyProvider failed with message: " << e.GetMessage());
-        retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
-    } catch (const DBCryptoModule::Exception::Base &e) {
-        LogError("DBCryptoModule failed with message: " << e.GetMessage());
-        retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
+        retCode = CKM_API_ERROR_SERVER_ERROR;
+    } 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());
-        retCode = KEY_MANAGER_API_ERROR_DB_ERROR;
+        retCode = CKM_API_ERROR_DB_ERROR;
     } catch (const DBCrypto::Exception::AliasExists &e) {
         LogError("DBCrypto couldn't save duplicate alias");
-        retCode = KEY_MANAGER_API_ERROR_DB_ALIAS_EXISTS;
+        retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
     } catch (const DBCrypto::Exception::TransactionError &e) {
         LogError("DBCrypto transaction failed with message " << e.GetMessage());
-        retCode = KEY_MANAGER_API_ERROR_DB_ERROR;
+        retCode = CKM_API_ERROR_DB_ERROR;
     }
 
     MessageBuffer response;
@@ -217,17 +246,22 @@ RawBuffer CKMLogic::removeData(
     DBDataType dataType,
     const Alias &alias)
 {
-    int retCode = KEY_MANAGER_API_SUCCESS;
+    int retCode = CKM_API_SUCCESS;
 
     if (0 < m_userDataMap.count(cred.uid)) {
         Try {
-            m_userDataMap[cred.uid].database.deleteDBRow(alias, cred.smackLabel);
+            auto erased = m_userDataMap[cred.uid].database.deleteDBRow(alias, cred.smackLabel);
+            // check if the data existed or not
+            if(!erased) {
+                LogError("No row for given alias and label");
+                retCode = CKM_API_ERROR_DB_ALIAS_UNKNOWN;
+            }
         } Catch (CKM::Exception) {
             LogError("Error in deleting row!");
-            retCode = KEY_MANAGER_API_ERROR_DB_ERROR;
+            retCode = CKM_API_ERROR_DB_ERROR;
         }
     } else {
-        retCode = KEY_MANAGER_API_ERROR_DB_LOCKED;
+        retCode = CKM_API_ERROR_DB_LOCKED;
     }
 
     MessageBuffer response;
@@ -243,12 +277,12 @@ int CKMLogic::getDataHelper(
     Credentials &cred,
     DBDataType dataType,
     const Alias &alias,
-    const std::string &password,
+    const Password &password,
     DBRow &row)
 {
 
     if (0 == m_userDataMap.count(cred.uid))
-        return KEY_MANAGER_API_ERROR_DB_LOCKED;
+        return CKM_API_ERROR_DB_LOCKED;
 
     auto &handler = m_userDataMap[cred.uid];
 
@@ -261,11 +295,11 @@ int CKMLogic::getDataHelper(
         row_optional = handler.database.getKeyDBRow(alias, cred.smackLabel);
     } else {
         LogError("Unknown type of requested data" << (int)dataType);
-        return KEY_MANAGER_API_ERROR_BAD_REQUEST;
+        return CKM_API_ERROR_BAD_REQUEST;
     }
     if(!row_optional) {
         LogError("No row for given alias, label and type");
-        return KEY_MANAGER_API_ERROR_DB_ALIAS_UNKNOWN;
+        return CKM_API_ERROR_DB_ALIAS_UNKNOWN;
     } else {
         row = *row_optional;
     }
@@ -275,7 +309,7 @@ int CKMLogic::getDataHelper(
         auto key_optional = handler.database.getKey(row.smackLabel);
         if(!key_optional) {
             LogError("No key for given label in database");
-            return KEY_MANAGER_API_ERROR_DB_ERROR;
+            return CKM_API_ERROR_DB_ERROR;
         }
         key = *key_optional;
         key = handler.keyProvider.getPureDEK(key);
@@ -283,9 +317,7 @@ int CKMLogic::getDataHelper(
     }
     handler.crypto.decryptRow(password, row);
 
-    LogError("Datatype: " << (int) row.dataType);
-
-    return KEY_MANAGER_API_SUCCESS;
+    return CKM_API_SUCCESS;
 }
 
 RawBuffer CKMLogic::getData(
@@ -293,30 +325,33 @@ RawBuffer CKMLogic::getData(
     int commandId,
     DBDataType dataType,
     const Alias &alias,
-    const std::string &password)
+    const Password &password)
 {
-    int retCode = KEY_MANAGER_API_SUCCESS;
+    int retCode = CKM_API_SUCCESS;
     DBRow row;
 
     try {
         retCode = getDataHelper(cred, dataType, alias, password, row);
     } catch (const KeyProvider::Exception::Base &e) {
         LogError("KeyProvider failed with error: " << e.GetMessage());
-        retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
-    } catch (const DBCryptoModule::Exception::Base &e) {
-        LogError("DBCryptoModule failed with message: " << e.GetMessage());
-        retCode = KEY_MANAGER_API_ERROR_SERVER_ERROR;
+        retCode = CKM_API_ERROR_SERVER_ERROR;
+    } 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 = KEY_MANAGER_API_ERROR_DB_ERROR;
+        retCode = CKM_API_ERROR_DB_ERROR;
     }
 
-    if (KEY_MANAGER_API_SUCCESS != retCode) {
+    if (CKM_API_SUCCESS != retCode) {
         row.data.clear();
         row.dataType = dataType;
     }
 
-    LogError("Sending dataType: " << (int)row.dataType);
+    if ((CKM_API_SUCCESS == retCode) && (row.exportable == 0)) {
+        row.data.clear();
+        retCode = CKM_API_ERROR_NOT_EXPORTABLE;
+    }
 
     MessageBuffer response;
     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET));
@@ -332,7 +367,7 @@ RawBuffer CKMLogic::getDataList(
     int commandId,
     DBDataType dataType)
 {
-    int retCode = KEY_MANAGER_API_SUCCESS;
+    int retCode = CKM_API_SUCCESS;
     AliasVector aliasVector;
 
     if (0 < m_userDataMap.count(cred.uid)) {
@@ -345,10 +380,10 @@ RawBuffer CKMLogic::getDataList(
             }
         } Catch (CKM::Exception) {
             LogError("Failed to get aliases");
-            retCode = KEY_MANAGER_API_ERROR_DB_ERROR;
+            retCode = CKM_API_ERROR_DB_ERROR;
         }
     } else {
-        retCode = KEY_MANAGER_API_ERROR_DB_LOCKED;
+        retCode = CKM_API_ERROR_DB_LOCKED;
     }
 
     MessageBuffer response;
@@ -369,7 +404,7 @@ int CKMLogic::createKeyPairRSAHelper(
     const PolicySerializable &policyPublic)
 {
     if (0 >= m_userDataMap.count(cred.uid))
-        return KEY_MANAGER_API_ERROR_DB_LOCKED;
+        return CKM_API_ERROR_DB_LOCKED;
 
     auto &handler = m_userDataMap[cred.uid];
     GenericKey prv, pub;
@@ -379,7 +414,7 @@ int CKMLogic::createKeyPairRSAHelper(
         (retCode = CryptoService::createKeyPairRSA(size, prv, pub)))
     {
         LogDebug("CryptoService error with code: " << retCode);
-        return KEY_MANAGER_API_ERROR_SERVER_ERROR; // TODO error code
+        return CKM_API_ERROR_SERVER_ERROR; // TODO error code
     }
 
     DBCrypto::Transaction transaction(&handler.database);
@@ -389,7 +424,7 @@ int CKMLogic::createKeyPairRSAHelper(
                             prv.getDER(),
                             policyPrivate);
 
-    if (KEY_MANAGER_API_SUCCESS != retCode)
+    if (CKM_API_SUCCESS != retCode)
         return retCode;
 
     retCode = saveDataHelper(cred,
@@ -398,7 +433,7 @@ int CKMLogic::createKeyPairRSAHelper(
                             pub.getDER(),
                             policyPublic);
 
-    if (KEY_MANAGER_API_SUCCESS != retCode)
+    if (CKM_API_SUCCESS != retCode)
         return retCode;
 
     transaction.commit();
@@ -415,7 +450,7 @@ RawBuffer CKMLogic::createKeyPairRSA(
     const PolicySerializable &policyPrivate,
     const PolicySerializable &policyPublic)
 {
-    int retCode = KEY_MANAGER_API_SUCCESS;
+    int retCode = CKM_API_SUCCESS;
 
     try {
         retCode = createKeyPairRSAHelper(
@@ -432,16 +467,19 @@ 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 = KEY_MANAGER_API_ERROR_DB_ERROR;
+        retCode = CKM_API_ERROR_DB_ERROR;
     }
 
     MessageBuffer response;
     Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
     Serialization::Serialize(response, commandId);
     Serialization::Serialize(response, retCode);
+
     return response.Pop();
 }
 
@@ -454,7 +492,7 @@ int CKMLogic::createKeyPairECDSAHelper(
     const PolicySerializable &policyPublic)
 {
     if (0 >= m_userDataMap.count(cred.uid))
-        return KEY_MANAGER_API_ERROR_DB_LOCKED;
+        return CKM_API_ERROR_DB_LOCKED;
 
     auto &handler = m_userDataMap[cred.uid];
     GenericKey prv, pub;
@@ -464,7 +502,7 @@ int CKMLogic::createKeyPairECDSAHelper(
         (retCode = CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(type), prv, pub)))
     {
         LogError("CryptoService failed with code: " << retCode);
-        return KEY_MANAGER_API_ERROR_SERVER_ERROR; // TODO error code
+        return CKM_API_ERROR_SERVER_ERROR; // TODO error code
     }
 
     DBCrypto::Transaction transaction(&handler.database);
@@ -475,7 +513,7 @@ int CKMLogic::createKeyPairECDSAHelper(
                             prv.getDER(),
                             policyPrivate);
 
-    if (KEY_MANAGER_API_SUCCESS != retCode)
+    if (CKM_API_SUCCESS != retCode)
         return retCode;
 
     retCode = saveDataHelper(cred,
@@ -484,7 +522,7 @@ int CKMLogic::createKeyPairECDSAHelper(
                             pub.getDER(),
                             policyPublic);
 
-    if (KEY_MANAGER_API_SUCCESS != retCode)
+    if (CKM_API_SUCCESS != retCode)
         return retCode;
 
     transaction.commit();
@@ -501,8 +539,8 @@ RawBuffer CKMLogic::createKeyPairECDSA(
     const PolicySerializable &policyPrivate,
     const PolicySerializable &policyPublic)
 {
-    int retCode = KEY_MANAGER_API_SUCCESS;
-    
+    int retCode = CKM_API_SUCCESS;
+
     try {
         retCode = createKeyPairECDSAHelper(
                         cred,
@@ -517,18 +555,226 @@ 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 = KEY_MANAGER_API_ERROR_DB_ERROR;
+        retCode = CKM_API_ERROR_DB_ERROR;
     }
 
     MessageBuffer response;
     Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
     Serialization::Serialize(response, commandId);
     Serialization::Serialize(response, retCode);
+
+    return response.Pop();
+}
+
+RawBuffer CKMLogic::getCertificateChain(
+    Credentials &cred,
+    int commandId,
+    const RawBuffer &certificate,
+    const RawBufferVector &untrustedRawCertVector)
+{
+    (void)cred;
+
+    CertificateImpl cert(certificate, DataFormat::FORM_DER);
+    CertificateImplVector untrustedCertVector;
+    CertificateImplVector chainVector;
+    RawBufferVector chainRawVector;
+
+    for (auto &e: untrustedRawCertVector)
+        untrustedCertVector.push_back(CertificateImpl(e, DataFormat::FORM_DER));
+
+    LogDebug("Cert is empty: " << cert.empty());
+
+    int retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
+
+    if (retCode == CKM_API_SUCCESS) {
+        for (auto &e : chainVector)
+            chainRawVector.push_back(e.getDER());
+    }
+
+    MessageBuffer response;
+    Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_CHAIN_CERT));
+    Serialization::Serialize(response, commandId);
+    Serialization::Serialize(response, retCode);
+    Serialization::Serialize(response, chainRawVector);
     return response.Pop();
 }
 
+RawBuffer CKMLogic::getCertificateChain(
+    Credentials &cred,
+    int commandId,
+    const RawBuffer &certificate,
+    const AliasVector &aliasVector)
+{
+    int retCode = CKM_API_SUCCESS;
+    RawBufferVector chainRawVector;
+    try {
+        CertificateImpl cert(certificate, DataFormat::FORM_DER);
+        CertificateImplVector untrustedCertVector;
+        CertificateImplVector chainVector;
+        DBRow row;
+
+        if (cert.empty()) {
+            retCode = CKM_API_ERROR_SERVER_ERROR;
+            goto senderror;
+        }
+
+        for (auto &i: aliasVector) {
+            retCode = getDataHelper(cred, DBDataType::CERTIFICATE, i, Password(), row);
+
+            if (retCode != CKM_API_SUCCESS)
+                goto senderror;
+
+            untrustedCertVector.push_back(CertificateImpl(row.data, DataFormat::FORM_DER));
+        }
+
+        retCode = m_certStore.verifyCertificate(cert, untrustedCertVector, chainVector);
+
+        if (retCode != CKM_API_SUCCESS)
+            goto senderror;
+
+        for (auto &i: chainVector)
+            chainRawVector.push_back(i.getDER());
+
+    } 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) {
+        LogError("DBCrypto failed with message: " << e.GetMessage());
+        retCode = CKM_API_ERROR_DB_ERROR;
+    } catch (...) {
+        LogError("Unknown error.");
+    }
+
+senderror:
+    MessageBuffer response;
+    Serialization::Serialize(response, static_cast<int>(LogicCommand::GET_CHAIN_ALIAS));
+    Serialization::Serialize(response, commandId);
+    Serialization::Serialize(response, retCode);
+    Serialization::Serialize(response, chainRawVector);
+    return response.Pop();
+}
+
+RawBuffer CKMLogic::createSignature(
+        Credentials &cred,
+        int commandId,
+        const Alias &privateKeyAlias,
+        const Password &password,           // password for private_key
+        const RawBuffer &message,
+        const HashAlgorithm hash,
+        const RSAPaddingAlgorithm padding)
+{
+    DBRow row;
+    CryptoService cs;
+    RawBuffer signature;
+
+    int retCode = CKM_API_SUCCESS;
+
+    try {
+        do {
+            retCode = getDataHelper(cred, DBDataType::KEY_RSA_PUBLIC, privateKeyAlias, password, row);
+            if (CKM_API_SUCCESS != retCode) {
+                LogError("getDataHelper return error");
+                break;
+            }
+
+            GenericKey keyParsed(row.data, Password());
+            if (keyParsed.empty())
+                retCode = CKM_API_ERROR_SERVER_ERROR;
+            else
+                cs.createSignature(keyParsed, message, hash, padding, signature);
+        } while(0);
+    } catch (const KeyProvider::Exception::Base &e) {
+        LogError("KeyProvider failed with message: " << e.GetMessage());
+        retCode = CKM_API_ERROR_SERVER_ERROR;
+    } 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;
+    Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_SIGNATURE));
+    Serialization::Serialize(response, commandId);
+    Serialization::Serialize(response, retCode);
+    Serialization::Serialize(response, signature);
+    return response.Pop();
+}
+
+RawBuffer CKMLogic::verifySignature(
+        Credentials &cred,
+        int commandId,
+        const Alias &publicKeyOrCertAlias,
+        const Password &password,           // password for public_key (optional)
+        const RawBuffer &message,
+        const RawBuffer &signature,
+        const HashAlgorithm hash,
+        const RSAPaddingAlgorithm padding)
+{
+    int retCode = CKM_API_ERROR_VERIFICATION_FAILED;
+
+    try {
+        do {
+            CryptoService cs;
+            DBRow row;
+            GenericKey key;
+
+            retCode = getDataHelper(cred, DBDataType::DB_KEY_FIRST, publicKeyOrCertAlias, password, row);
+
+            if (retCode == CKM_API_SUCCESS) {
+                key = GenericKey(row.data);
+            } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) {
+                retCode = getDataHelper(cred, DBDataType::CERTIFICATE, publicKeyOrCertAlias, password, row);
+                if (retCode != CKM_API_SUCCESS)
+                    break;
+                CertificateImpl cert(row.data, DataFormat::FORM_DER);
+                key = cert.getGenericKey();
+            } else {
+                break;
+            }
+
+            if (key.empty()) {
+                retCode = CKM_API_ERROR_SERVER_ERROR;
+                break;
+            }
+
+            retCode = cs.verifySignature(key, message, signature, hash, padding);
+        } while(0);
+    } catch (const CryptoService::Exception::Crypto_internal &e) {
+        LogError("KeyProvider failed with message: " << e.GetMessage());
+        retCode = CKM_API_ERROR_SERVER_ERROR;
+    } catch (const CryptoService::Exception::opensslError &e) {
+        LogError("KeyProvider failed with message: " << e.GetMessage());
+        retCode = CKM_API_ERROR_SERVER_ERROR;
+    } catch (const KeyProvider::Exception::Base &e) {
+        LogError("KeyProvider failed with error: " << e.GetMessage());
+        retCode = CKM_API_ERROR_SERVER_ERROR;
+    } 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;
+    Serialization::Serialize(response, static_cast<int>(LogicCommand::VERIFY_SIGNATURE));
+    Serialization::Serialize(response, commandId);
+    Serialization::Serialize(response, retCode);
+
+    return response.Pop();
+}
 } // namespace CKM