X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmanager%2Fservice%2Fckm-logic.cpp;h=69434f7e11681173ed8a49e1434c25189e816e7d;hb=b9a144d24ec4f1b1583e1cee7004f81a7923ef7e;hp=2c8f1b07cabef4f8aa153fc832500f8001348b83;hpb=ba61c50260aedaabb11857b5a462ccac37ad7413;p=platform%2Fcore%2Fsecurity%2Fkey-manager.git diff --git a/src/manager/service/ckm-logic.cpp b/src/manager/service/ckm-logic.cpp old mode 100644 new mode 100755 index 2c8f1b0..69434f7 --- a/src/manager/service/ckm-logic.cpp +++ b/src/manager/service/ckm-logic.cpp @@ -21,44 +21,69 @@ */ #include #include - #include #include #include #include - +#include #include +#include + +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; - UserData &handle = m_userDataMap[user]; + try { + if (0 == m_userDataMap.count(user) || !(m_userDataMap[user].keyProvider.isInitialized())) { + auto &handle = m_userDataMap[user]; + FileSystem fs(user); + auto wrappedDomainKEK = fs.getDomainKEK(); - if (!(handle.keyProvider.isInitialized())) { - auto &handle = m_userDataMap[user]; + if (wrappedDomainKEK.empty()) { + wrappedDomainKEK = KeyProvider::generateDomainKEK(std::to_string(user), password); + fs.saveDomainKEK(wrappedDomainKEK); + } - FileSystem fs(user); - auto wrappedDomainKEK = fs.getDomainKEK(); + handle.keyProvider = KeyProvider(wrappedDomainKEK, password); - if (wrappedDomainKEK.empty()) { - wrappedDomainKEK = KeyProvider::generateDomainKEK(std::to_string(user), password); - fs.saveDomainKEK(wrappedDomainKEK); + RawBuffer key = handle.keyProvider.getPureDomainKEK(); + handle.database = DBCrypto(fs.getDBPath(), key); + handle.crypto = CryptoLogic(); + // TODO wipe key } - - handle.keyProvider = KeyProvider(wrappedDomainKEK, password); - handle.database = DBCrypto(fs.getDBPath(), handle.keyProvider.getPureDomainKEK()); + } 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 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; @@ -67,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); @@ -77,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); @@ -91,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(); @@ -111,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); @@ -128,35 +164,71 @@ RawBuffer CKMLogic::resetUserPassword( return response.Pop(); } -RawBuffer CKMLogic::saveData( +int CKMLogic::saveDataHelper( Credentials &cred, - int commandId, DBDataType dataType, const Alias &alias, const RawBuffer &key, const PolicySerializable &policy) { - int retCode = KEY_MANAGER_API_SUCCESS; + if (0 == m_userDataMap.count(cred.uid)) + return CKM_API_ERROR_DB_LOCKED; + + DBRow row = { alias, cred.smackLabel, policy.restricted, + policy.extractable, dataType, DBCMAlgType::NONE, + 0, RawBuffer(), static_cast(key.size()), key }; + + auto &handler = m_userDataMap[cred.uid]; + DBCrypto::Transaction transaction(&handler.database); + if (!handler.crypto.haveKey(cred.smackLabel)) { + RawBuffer key; + auto key_optional = handler.database.getKey(cred.smackLabel); + if(!key_optional) { + 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; + } - if (0 == m_userDataMap.count(cred.uid)) { - retCode = KEY_MANAGER_API_ERROR_DB_LOCKED; - } else { - RawBuffer iv(10,'c'); - - DBRow row = { - alias, - cred.smackLabel, - policy.restricted, - policy.extractable, - dataType, - DBCMAlgType::NONE, - 0, - iv, - key.size(), - key }; + key = handler.keyProvider.getPureDEK(key); + handler.crypto.pushKey(cred.smackLabel, key); + } + handler.crypto.encryptRow(policy.password, row); + handler.database.saveDBRow(row); + transaction.commit(); + return CKM_API_SUCCESS; +} - auto &handler = m_userDataMap[cred.uid]; - retCode = handler.database.saveDBRow(row); +RawBuffer CKMLogic::saveData( + Credentials &cred, + int commandId, + DBDataType dataType, + const Alias &alias, + const RawBuffer &key, + const PolicySerializable &policy) +{ + 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 = 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 = CKM_API_ERROR_DB_ERROR; + } catch (const DBCrypto::Exception::AliasExists &e) { + LogError("DBCrypto couldn't save duplicate alias"); + retCode = CKM_API_ERROR_DB_ALIAS_EXISTS; + } catch (const DBCrypto::Exception::TransactionError &e) { + LogError("DBCrypto transaction failed with message " << e.GetMessage()); + retCode = CKM_API_ERROR_DB_ERROR; } MessageBuffer response; @@ -174,17 +246,22 @@ RawBuffer CKMLogic::removeData( DBDataType dataType, const Alias &alias) { - (void)cred; - (void)alias; - - int retCode = KEY_MANAGER_API_SUCCESS; - - if (0 == m_userDataMap.count(cred.uid)) { - retCode = KEY_MANAGER_API_ERROR_DB_LOCKED; + int retCode = CKM_API_SUCCESS; + + if (0 < m_userDataMap.count(cred.uid)) { + Try { + 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 = CKM_API_ERROR_DB_ERROR; + } } else { - // TODO - auto &handler = m_userDataMap[cred.uid]; - (void)handler; + retCode = CKM_API_ERROR_DB_LOCKED; } MessageBuffer response; @@ -196,24 +273,84 @@ RawBuffer CKMLogic::removeData( return response.Pop(); } +int CKMLogic::getDataHelper( + Credentials &cred, + DBDataType dataType, + const Alias &alias, + const Password &password, + DBRow &row) +{ + + if (0 == m_userDataMap.count(cred.uid)) + return CKM_API_ERROR_DB_LOCKED; + + auto &handler = m_userDataMap[cred.uid]; + + DBCrypto::DBRowOptional row_optional; + if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) { + row_optional = handler.database.getDBRow(alias, cred.smackLabel, dataType); + } else if ((static_cast(dataType) >= static_cast(DBDataType::DB_KEY_FIRST)) + && (static_cast(dataType) <= static_cast(DBDataType::DB_KEY_LAST))) + { + row_optional = handler.database.getKeyDBRow(alias, cred.smackLabel); + } else { + LogError("Unknown type of requested data" << (int)dataType); + return CKM_API_ERROR_BAD_REQUEST; + } + if(!row_optional) { + LogError("No row for given alias, label and type"); + return CKM_API_ERROR_DB_ALIAS_UNKNOWN; + } else { + row = *row_optional; + } + + if (!handler.crypto.haveKey(row.smackLabel)) { + RawBuffer key; + auto key_optional = handler.database.getKey(row.smackLabel); + if(!key_optional) { + LogError("No key for given label in database"); + return CKM_API_ERROR_DB_ERROR; + } + key = *key_optional; + key = handler.keyProvider.getPureDEK(key); + handler.crypto.pushKey(cred.smackLabel, key); + } + handler.crypto.decryptRow(password, row); + + return CKM_API_SUCCESS; +} + RawBuffer CKMLogic::getData( Credentials &cred, int commandId, DBDataType dataType, const Alias &alias, - const std::string &password) + const Password &password) { - (void)dataType; - (void)password; - - int retCode = KEY_MANAGER_API_SUCCESS; + int retCode = CKM_API_SUCCESS; DBRow row; - if (0 == m_userDataMap.count(cred.uid)) { - retCode = KEY_MANAGER_API_ERROR_DB_LOCKED; - } else { - auto &handler = m_userDataMap[cred.uid]; - retCode = handler.database.getDBRow(alias, cred.smackLabel, row); + try { + retCode = getDataHelper(cred, dataType, alias, password, row); + } 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; + } + + if (CKM_API_SUCCESS != retCode) { + row.data.clear(); + row.dataType = dataType; + } + + if ((CKM_API_SUCCESS == retCode) && (row.exportable == 0)) { + row.data.clear(); + retCode = CKM_API_ERROR_NOT_EXPORTABLE; } MessageBuffer response; @@ -230,14 +367,23 @@ 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)) { - retCode = KEY_MANAGER_API_ERROR_DB_LOCKED; - } else { + if (0 < m_userDataMap.count(cred.uid)) { auto &handler = m_userDataMap[cred.uid]; - // TODO - (void)handler; + Try { + if (dataType == DBDataType::CERTIFICATE || dataType == DBDataType::BINARY_DATA) { + handler.database.getAliases(dataType, cred.smackLabel, aliasVector); + } else { + handler.database.getKeyAliases(cred.smackLabel, aliasVector); + } + } Catch (CKM::Exception) { + LogError("Failed to get aliases"); + retCode = CKM_API_ERROR_DB_ERROR; + } + } else { + retCode = CKM_API_ERROR_DB_LOCKED; } MessageBuffer response; @@ -245,56 +391,390 @@ RawBuffer CKMLogic::getDataList( Serialization::Serialize(response, commandId); Serialization::Serialize(response, retCode); Serialization::Serialize(response, static_cast(dataType)); - Serialization::Serialize(response, AliasVector()); + Serialization::Serialize(response, aliasVector); return response.Pop(); } +int CKMLogic::createKeyPairRSAHelper( + Credentials &cred, + int size, + const Alias &aliasPrivate, + const Alias &aliasPublic, + const PolicySerializable &policyPrivate, + const PolicySerializable &policyPublic) +{ + if (0 >= m_userDataMap.count(cred.uid)) + return CKM_API_ERROR_DB_LOCKED; + + auto &handler = m_userDataMap[cred.uid]; + GenericKey prv, pub; + int retCode; + + if (CKM_CRYPTO_CREATEKEY_SUCCESS != + (retCode = CryptoService::createKeyPairRSA(size, prv, pub))) + { + LogDebug("CryptoService error with code: " << retCode); + return CKM_API_ERROR_SERVER_ERROR; // TODO error code + } + + DBCrypto::Transaction transaction(&handler.database); + retCode = saveDataHelper(cred, + toDBDataType(prv.getType()), + aliasPrivate, + prv.getDER(), + policyPrivate); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + retCode = saveDataHelper(cred, + toDBDataType(pub.getType()), + aliasPublic, + pub.getDER(), + policyPublic); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + transaction.commit(); + + return retCode; +} + RawBuffer CKMLogic::createKeyPairRSA( Credentials &cred, int commandId, int size, - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - PolicySerializable policyPrivateKey, - PolicySerializable policyPublicKey) -{ - (void)cred; - (void)size; - (void)privateKeyAlias; - (void)publicKeyAlias, - (void)policyPrivateKey; - (void)policyPublicKey; + const Alias &aliasPrivate, + const Alias &aliasPublic, + const PolicySerializable &policyPrivate, + const PolicySerializable &policyPublic) +{ + int retCode = CKM_API_SUCCESS; + + try { + retCode = createKeyPairRSAHelper( + cred, + size, + aliasPrivate, + aliasPublic, + policyPrivate, + policyPublic); + + } catch (DBCrypto::Exception::AliasExists &e) { + LogDebug("DBCrypto error: alias exists: " << e.GetMessage()); + retCode = CKM_API_ERROR_DB_ALIAS_EXISTS; + } 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; + } + MessageBuffer response; Serialization::Serialize(response, static_cast(LogicCommand::CREATE_KEY_PAIR_RSA)); Serialization::Serialize(response, commandId); - Serialization::Serialize(response, static_cast(KEY_MANAGER_API_SUCCESS)); - + Serialization::Serialize(response, retCode); + return response.Pop(); } +int CKMLogic::createKeyPairECDSAHelper( + Credentials &cred, + int type, + const Alias &aliasPrivate, + const Alias &aliasPublic, + const PolicySerializable &policyPrivate, + const PolicySerializable &policyPublic) +{ + if (0 >= m_userDataMap.count(cred.uid)) + return CKM_API_ERROR_DB_LOCKED; + + auto &handler = m_userDataMap[cred.uid]; + GenericKey prv, pub; + int retCode; + + if (CKM_CRYPTO_CREATEKEY_SUCCESS != + (retCode = CryptoService::createKeyPairECDSA(static_cast(type), prv, pub))) + { + LogError("CryptoService failed with code: " << retCode); + return CKM_API_ERROR_SERVER_ERROR; // TODO error code + } + + DBCrypto::Transaction transaction(&handler.database); + + retCode = saveDataHelper(cred, + toDBDataType(prv.getType()), + aliasPrivate, + prv.getDER(), + policyPrivate); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + retCode = saveDataHelper(cred, + toDBDataType(pub.getType()), + aliasPublic, + pub.getDER(), + policyPublic); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + transaction.commit(); + + return retCode; +} + RawBuffer CKMLogic::createKeyPairECDSA( Credentials &cred, int commandId, int type, - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - PolicySerializable policyPrivateKey, - PolicySerializable policyPublicKey) + const Alias &aliasPrivate, + const Alias &aliasPublic, + const PolicySerializable &policyPrivate, + const PolicySerializable &policyPublic) { - (void)cred; - (void)type; - (void)privateKeyAlias; - (void)publicKeyAlias, - (void)policyPrivateKey; - (void)policyPublicKey; - + int retCode = CKM_API_SUCCESS; + + try { + retCode = createKeyPairECDSAHelper( + cred, + type, + aliasPrivate, + aliasPublic, + policyPrivate, + policyPublic); + } catch (const DBCrypto::Exception::AliasExists &e) { + LogDebug("DBCrypto error: alias exists: " << e.GetMessage()); + retCode = CKM_API_ERROR_DB_ALIAS_EXISTS; + } 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; + } + MessageBuffer response; Serialization::Serialize(response, static_cast(LogicCommand::CREATE_KEY_PAIR_RSA)); Serialization::Serialize(response, commandId); - Serialization::Serialize(response, static_cast(KEY_MANAGER_API_SUCCESS)); - + 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(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(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(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(LogicCommand::VERIFY_SIGNATURE)); + Serialization::Serialize(response, commandId); + Serialization::Serialize(response, retCode); + + return response.Pop(); +} } // namespace CKM