+RawBuffer CKMLogic::createKeyPairRSA(
+ Credentials &cred,
+ int commandId,
+ int size,
+ 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<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
+ Serialization::Serialize(response, commandId);
+ 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<ElipticCurve>(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 &aliasPrivate,
+ const Alias &aliasPublic,
+ const PolicySerializable &policyPrivate,
+ const PolicySerializable &policyPublic)
+{
+ 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<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();
+}