From: Bartlomiej Grzelewski Date: Wed, 13 May 2015 14:56:08 +0000 (+0200) Subject: Use new classes to sign and verify messages. X-Git-Tag: accepted/tizen/mobile/20150629.000431~19 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fsecurity%2Fkey-manager.git;a=commitdiff_plain;h=68ef1034badf1554b572989f42bf0d9dbd53d95f Use new classes to sign and verify messages. Remove old implementation of sign/verify methods. Change-Id: I391d29ffc3ae8a2fe49b09259387efa2023abec2 --- diff --git a/src/include/ckm/ckm-type.h b/src/include/ckm/ckm-type.h index 9d93421..d17f8a9 100644 --- a/src/include/ckm/ckm-type.h +++ b/src/include/ckm/ckm-type.h @@ -22,6 +22,7 @@ #pragma once #include +#include #include #include @@ -188,7 +189,32 @@ protected: std::map m_params; }; +template +bool CryptoAlgorithm::getParam(ParamName name, T& value) const { + auto param = m_params.find(name); + if (param == m_params.end()) + return false; + assert(param->second); + + uint64_t valueTmp; + if (param->second->getInt(valueTmp)) { + value = static_cast(valueTmp); + return true; + } + return false; +} + +template <> +bool CryptoAlgorithm::getParam(ParamName name, RawBuffer& value) const; + +template +bool CryptoAlgorithm::addParam(ParamName name, const T& value) { + return m_params.emplace(name, IntParam::create(static_cast(value))).second; +} + +template <> +bool CryptoAlgorithm::addParam(ParamName name, const RawBuffer& value); } // namespace CKM diff --git a/src/manager/common/algo-param.cpp b/src/manager/common/algo-param.cpp index 7585d96..7846ce5 100644 --- a/src/manager/common/algo-param.cpp +++ b/src/manager/common/algo-param.cpp @@ -48,18 +48,7 @@ CryptoAlgorithm::BaseParamPtr CryptoAlgorithm::IntParam::create(uint64_t value) } template <> -bool CryptoAlgorithm::getParam(ParamName name, uint64_t& value) const -{ - auto param = m_params.find(name); - if (param == m_params.end()) - return false; - - assert(param->second); - return param->second->getInt(value); -} - -template <> -bool CryptoAlgorithm::getParam(ParamName name, RawBuffer& value) const +bool CryptoAlgorithm::getParam(ParamName name, RawBuffer& value) const { auto param = m_params.find(name); if (param == m_params.end()) @@ -70,19 +59,7 @@ bool CryptoAlgorithm::getParam(ParamName name, RawBuffer& value) cons } template <> -bool CryptoAlgorithm::addParam(ParamName name, const uint64_t& value) -{ - return m_params.emplace(name, IntParam::create(value)).second; -} - -template <> -bool CryptoAlgorithm::addParam(ParamName name, const int& value) -{ - return m_params.emplace(name, IntParam::create(value)).second; -} - -template <> -bool CryptoAlgorithm::addParam(ParamName name, const RawBuffer& value) +bool CryptoAlgorithm::addParam(ParamName name, const RawBuffer& value) { return m_params.emplace(name, BufferParam::create(value)).second; } diff --git a/src/manager/crypto/generic-backend/exception.h b/src/manager/crypto/generic-backend/exception.h index 647f9e9..756db7b 100644 --- a/src/manager/crypto/generic-backend/exception.h +++ b/src/manager/crypto/generic-backend/exception.h @@ -31,6 +31,7 @@ DECLARE_EXCEPTION_TYPE(Base, InternalError) DECLARE_EXCEPTION_TYPE(Base, KeyNotSupported) DECLARE_EXCEPTION_TYPE(Base, OperationNotSupported) DECLARE_EXCEPTION_TYPE(Base, WrongBackend) +DECLARE_EXCEPTION_TYPE(Base, InputParam) } // namespace Exception } // namespace Crypto diff --git a/src/manager/crypto/generic-backend/gkey.h b/src/manager/crypto/generic-backend/gkey.h index 5d03c8d..8ad6eda 100644 --- a/src/manager/crypto/generic-backend/gkey.h +++ b/src/manager/crypto/generic-backend/gkey.h @@ -49,7 +49,7 @@ public: Throw(Exception::OperationNotSupported); } - virtual bool verify(const CryptoAlgorithm &, const RawBuffer &, const RawBuffer &) { + virtual int verify(const CryptoAlgorithm &, const RawBuffer &, const RawBuffer &) { Throw(Exception::OperationNotSupported); } diff --git a/src/manager/crypto/generic-backend/gstore.h b/src/manager/crypto/generic-backend/gstore.h index c7b796c..49fb545 100644 --- a/src/manager/crypto/generic-backend/gstore.h +++ b/src/manager/crypto/generic-backend/gstore.h @@ -46,8 +46,6 @@ protected: CryptoBackend m_backendId; }; -typedef std::shared_ptr GStoreShPtr; - } // namespace Crypto } // namespace CKM diff --git a/src/manager/crypto/platform/decider.cpp b/src/manager/crypto/platform/decider.cpp index b3e4413..aad14b8 100644 --- a/src/manager/crypto/platform/decider.cpp +++ b/src/manager/crypto/platform/decider.cpp @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2000 - 2015 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 decider.cpp + * @author Bartłomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + */ +#include + +#include + #include #include @@ -6,14 +30,22 @@ namespace CKM { namespace Crypto { Decider::Decider() - : m_store(new SW::Store(CryptoBackend::OpenSSL)) + : m_swStore(new SW::Store(CryptoBackend::OpenSSL)) {} -GStoreShPtr Decider::getStore(const Token &) { +GStore& Decider::getStore(const Token &) { // This the place where we should choose backend bases on token information. - return m_store; + if (!m_swStore) { + LogError("No backend available."); + ThrowMsg(CKM::Crypto::Exception::Base, "No backend available."); + } + return *m_swStore; }; +CryptoBackend Decider::chooseCryptoBackend(DataType, const Policy &) const { + return CryptoBackend::OpenSSL; +} + } // namespace Crypto } // namespace CKM diff --git a/src/manager/crypto/platform/decider.h b/src/manager/crypto/platform/decider.h index aec56c1..17a00aa 100644 --- a/src/manager/crypto/platform/decider.h +++ b/src/manager/crypto/platform/decider.h @@ -1,7 +1,31 @@ +/* + * Copyright (c) 2000 - 2015 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 decider.h + * @author Bartłomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + */ #pragma once #include +#include + +#include + #include #include @@ -11,10 +35,12 @@ namespace Crypto { class Decider { public: Decider(); - GStoreShPtr getStore(const Token &token); + GStore& getStore(const Token &token); + CryptoBackend chooseCryptoBackend(DataType data, const Policy &policy) const; + virtual ~Decider(){} private: - GStoreShPtr m_store; + std::unique_ptr m_swStore; }; } // Crypto diff --git a/src/manager/crypto/sw-backend/crypto-service.cpp b/src/manager/crypto/sw-backend/crypto-service.cpp index c98b52f..9959cce 100644 --- a/src/manager/crypto/sw-backend/crypto-service.cpp +++ b/src/manager/crypto/sw-backend/crypto-service.cpp @@ -38,8 +38,6 @@ CryptoService::CryptoService(){ CryptoService::~CryptoService(){ } - - int CryptoService::initialize() { int hw_rand_ret = 0; int u_rand_ret = 0; @@ -66,50 +64,6 @@ int CryptoService::initialize() { return CKM_CRYPTO_INIT_SUCCESS; } -const EVP_MD *CryptoService::getMdAlgo(const HashAlgorithm hashAlgo) { - const EVP_MD *md_algo=NULL; - switch(hashAlgo) { - case HashAlgorithm::NONE: - md_algo = NULL; - break; - case HashAlgorithm::SHA1: - md_algo = EVP_sha1(); - break; - case HashAlgorithm::SHA256: - md_algo = EVP_sha256(); - break; - case HashAlgorithm::SHA384: - md_algo = EVP_sha384(); - break; - case HashAlgorithm::SHA512: - md_algo = EVP_sha512(); - break; - default: - LogError("Error in hashAlgorithm value"); - ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in hashAlgorithm value"); - } - return md_algo; -} - -int CryptoService::getRsaPadding(const RSAPaddingAlgorithm padAlgo) { - int rsa_padding = -1; - switch(padAlgo) { - case RSAPaddingAlgorithm::NONE: - rsa_padding = RSA_NO_PADDING; - break; - case RSAPaddingAlgorithm::PKCS1: - rsa_padding = RSA_PKCS1_PADDING; - break; - case RSAPaddingAlgorithm::X931: - rsa_padding = RSA_X931_PADDING; - break; - default: - LogError("Error in RSAPaddingAlgorithm value"); - ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in RSAPaddingAlgorithm value"); - } - return rsa_padding; -} - int CryptoService::createKeyPairRSA(const int size, // size in bits [1024, 2048, 4096] KeyImpl &createdPrivateKey, // returned value KeyImpl &createdPublicKey) // returned value @@ -414,316 +368,6 @@ int CryptoService::createKeyPairECDSA(ElipticCurve type, return CKM_CRYPTO_CREATEKEY_SUCCESS; } -int CryptoService::createSignature(const KeyImpl &privateKey, - const RawBuffer &message, - const HashAlgorithm hashAlgo, - const RSAPaddingAlgorithm padAlgo, - RawBuffer &signature) -{ - int retCode = CKM_API_SUCCESS; - int rsa_padding = NOT_DEFINED; - const EVP_MD *md_algo = NULL; - - md_algo = getMdAlgo(hashAlgo); - - - if((privateKey.getType() != KeyType::KEY_RSA_PRIVATE) && - (privateKey.getType() != KeyType::KEY_DSA_PRIVATE) && - (privateKey.getType() != KeyType::KEY_ECDSA_PRIVATE)) - { - LogError("Error in private key type"); - ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in private key type"); - } - - if(privateKey.getType()==KeyType::KEY_RSA_PRIVATE) { - rsa_padding = getRsaPadding(padAlgo); - } - - auto shrPKey = privateKey.getEvpShPtr(); - if (NULL == shrPKey.get()) { - LogError("Error in EVP_PKEY_keygen function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen function"); - } - - if(md_algo == NULL) { - retCode = signMessage(shrPKey.get(), message, rsa_padding, signature); - }else { - retCode = digestSignMessage(shrPKey.get(),message, md_algo, rsa_padding, signature); - } - - return retCode; -} - -int CryptoService::signMessage(EVP_PKEY *privKey, - const RawBuffer &message, - const int rsa_padding, - RawBuffer &signature) -{ - int retCode = CKM_API_SUCCESS; - EVP_PKEY_CTX *pctx = NULL; - - Try { - if(!(pctx = EVP_PKEY_CTX_new(privKey, NULL))) { - LogError("Error in EVP_PKEY_CTX_new function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new function"); - } - - if(EVP_PKEY_sign_init(pctx) != EVP_SUCCESS) { - LogError("Error in EVP_PKEY_sign_init function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_sign_init function"); - } - - /* Set padding algorithm */ - if(EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) { - if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) { - LogError("Error in EVP_PKEY_CTX_set_rsa_padding function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_rsa_padding function"); - } - } - - /* Finalize the Sign operation */ - /* First call EVP_PKEY_sign with a NULL sig parameter to obtain the length of the - * signature. Length is returned in slen */ - size_t slen; - if(EVP_SUCCESS != EVP_PKEY_sign(pctx, NULL, &slen, message.data(), message.size())) { - LogError("Error in EVP_PKEY_sign function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_sign function"); - } - - /* Allocate memory for the signature based on size in slen */ - unsigned char sig[slen]; - - if(EVP_SUCCESS == EVP_PKEY_sign(pctx, sig, &slen, message.data(), message.size())) { - // Set value to return RawData - signature.assign(sig, sig+slen); - retCode = CKM_API_SUCCESS; - }else { - LogError("Error in EVP_PKEY_sign function: check input parameter"); - retCode = CKM_API_ERROR_INPUT_PARAM; - } - } Catch(CryptoService::Exception::opensslError) { - if(pctx != NULL) { - EVP_PKEY_CTX_free(pctx); - } - ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!"); - } - - if(pctx != NULL) { - EVP_PKEY_CTX_free(pctx); - } - return retCode; -} - -int CryptoService::digestSignMessage(EVP_PKEY *privKey, - const RawBuffer &message, - const EVP_MD *md_algo, - const int rsa_padding, - RawBuffer &signature) -{ - EVP_MD_CTX *mdctx = NULL; - EVP_PKEY_CTX *pctx = NULL; - - Try { - // Create the Message Digest Context - if(!(mdctx = EVP_MD_CTX_create())) { - LogError("Error in EVP_MD_CTX_create function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_MD_CTX_create function"); - } - - if(EVP_SUCCESS != EVP_DigestSignInit(mdctx, &pctx, md_algo, NULL, privKey)) { - LogError("Error in EVP_DigestSignInit function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_DigestSignInit function"); - } - - /* Set padding algorithm */ - if(EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) { - if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) { - LogError("Error in EVP_PKEY_CTX_set_rsa_padding function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_rsa_padding function"); - } - } - - /* Call update with the message */ - if(EVP_SUCCESS != EVP_DigestSignUpdate(mdctx, message.data(), message.size())) { - LogError("Error in EVP_DigestSignUpdate function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_DigestSignUpdate function"); - } - - /* Finalize the DigestSign operation */ - /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the - * signature. Length is returned in slen */ - size_t slen; - if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx, NULL, &slen)) { - LogError("Error in EVP_DigestSignFinal function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_DigestSignFinal function"); - } - /* Allocate memory for the signature based on size in slen */ - unsigned char sig[slen]; - - /* Obtain the signature */ - if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx, sig, &slen)) { - LogError("Error in EVP_DigestSignFinal function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_DigestSignFinal function"); - } - - // Set value to return RawData - signature.assign(sig, sig+slen); - } Catch(CryptoService::Exception::opensslError) { - if(mdctx != NULL) { - EVP_MD_CTX_destroy(mdctx); - } - - ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!"); - } - - if(mdctx != NULL) { - EVP_MD_CTX_destroy(mdctx); - } - - return CKM_API_SUCCESS; -} - -int CryptoService::verifySignature(const KeyImpl &publicKey, - const RawBuffer &message, - const RawBuffer &signature, - const HashAlgorithm hashAlgo, - const RSAPaddingAlgorithm padAlgo) -{ - int rsa_padding = NOT_DEFINED; - const EVP_MD *md_algo; - int retCode = CKM_API_ERROR_VERIFICATION_FAILED; - - md_algo = getMdAlgo(hashAlgo); - - - if((publicKey.getType() != KeyType::KEY_RSA_PUBLIC) && - (publicKey.getType() != KeyType::KEY_DSA_PUBLIC) && - (publicKey.getType() != KeyType::KEY_ECDSA_PUBLIC)) - { - LogError("Error in private key type"); - ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in private key type"); - } - - if(publicKey.getType()==KeyType::KEY_RSA_PUBLIC) { - rsa_padding = getRsaPadding(padAlgo); - } - - auto shrPKey = publicKey.getEvpShPtr(); - if (NULL == shrPKey.get()) { - LogError("Error in getEvpShPtr function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in getEvpShPtr function"); - } - - if(md_algo == NULL) { - retCode = verifyMessage(shrPKey.get(), message, signature, rsa_padding); - }else { - retCode = digestVerifyMessage(shrPKey.get(),message, signature, md_algo, rsa_padding); - } - - return retCode; -} - -int CryptoService::verifyMessage(EVP_PKEY *pubKey, - const RawBuffer &message, - const RawBuffer &signature, - const int rsa_padding) -{ - int ret = CKM_API_ERROR_VERIFICATION_FAILED; - EVP_PKEY_CTX *pctx = NULL; - - Try { - if(!(pctx = EVP_PKEY_CTX_new(pubKey, NULL))) { - LogError("Error in EVP_PKEY_CTX_new function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new function"); - } - - if(EVP_PKEY_verify_init(pctx) != EVP_SUCCESS) { - LogError("Error in EVP_PKEY_verify_init function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_verify_init function"); - } - - /* Set padding algorithm */ - if(EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) { - if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) { - LogError("Error in EVP_PKEY_CTX_set_rsa_padding function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_rsa_padding function"); - } - } - - if(EVP_SUCCESS == EVP_PKEY_verify(pctx, signature.data(), signature.size(), message.data(), message.size())) { - ret = CKM_API_SUCCESS; - }else { - LogError("EVP_PKEY_verify Failed"); - ret = CKM_API_ERROR_VERIFICATION_FAILED; - } - } Catch(CryptoService::Exception::opensslError) { - if(pctx != NULL) { - EVP_PKEY_CTX_free(pctx); - } - ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!"); - } - - if(pctx != NULL) { - EVP_PKEY_CTX_free(pctx); - } - - return ret; -} - -int CryptoService::digestVerifyMessage(EVP_PKEY *pubKey, - const RawBuffer &message, - const RawBuffer &signature, - const EVP_MD *md_algo, - const int rsa_padding) -{ - int ret = CKM_API_ERROR_VERIFICATION_FAILED; - EVP_MD_CTX *mdctx = NULL; - EVP_PKEY_CTX *pctx = NULL; - - Try { - /* Create the Message Digest Context */ - if(!(mdctx = EVP_MD_CTX_create())) { - LogError("Error in EVP_MD_CTX_create function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_MD_CTX_create function"); - } - - if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx, &pctx, md_algo, NULL, pubKey)) { - LogError("Error in EVP_DigestVerifyInit function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_DigestVerifyInit function"); - } - - if(EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) { - if(EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) { - LogError("Error in EVP_PKEY_CTX_set_rsa_padding function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_rsa_padding function"); - } - } - - if(EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx, message.data(), message.size()) ) { - LogError("Error in EVP_DigestVerifyUpdate function"); - ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_DigestVerifyUpdate function"); - } - - if(EVP_SUCCESS == EVP_DigestVerifyFinal(mdctx, const_cast(signature.data()), signature.size()) ) { - ret = CKM_API_SUCCESS; - }else { - LogError("EVP_PKEY_verify Failed"); - ret = CKM_API_ERROR_VERIFICATION_FAILED; - } - } Catch(CryptoService::Exception::opensslError) { - if(mdctx != NULL) { - EVP_MD_CTX_destroy(mdctx); - } - ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!"); - } - - if(mdctx != NULL) { - EVP_MD_CTX_destroy(mdctx); - } - - return ret; -} - } // namespace SW } // namespace Crypto } // namespace CKM diff --git a/src/manager/crypto/sw-backend/crypto-service.h b/src/manager/crypto/sw-backend/crypto-service.h index f98764d..fb8ce4d 100644 --- a/src/manager/crypto/sw-backend/crypto-service.h +++ b/src/manager/crypto/sw-backend/crypto-service.h @@ -64,42 +64,8 @@ public: KeyImpl &createdPrivateKey, // returned value KeyImpl &createdPublicKey); // returned value - int createSignature(const KeyImpl &privateKey, - const RawBuffer &message, - const HashAlgorithm hashAlgo, - const RSAPaddingAlgorithm padAlgo, - RawBuffer &signature); - - int verifySignature(const KeyImpl &publicKey, - const RawBuffer &message, - const RawBuffer &signature, - const HashAlgorithm hashAlgo, - const RSAPaddingAlgorithm padAlgo); - private: - const EVP_MD *getMdAlgo(const HashAlgorithm hashAlgo); - int getRsaPadding(const RSAPaddingAlgorithm padAlgo); - - int signMessage(EVP_PKEY *privKey, - const RawBuffer &message, - const int rsa_padding, - RawBuffer &signature); - int digestSignMessage(EVP_PKEY *privKey, - const RawBuffer &message, - const EVP_MD *md_algo, - const int rsa_padding, - RawBuffer &signature); - - int verifyMessage(EVP_PKEY *pubKey, - const RawBuffer &message, - const RawBuffer &signature, - const int rsa_padding); - int digestVerifyMessage(EVP_PKEY *pubKey, - const RawBuffer &message, - const RawBuffer &signature, - const EVP_MD *md_algo, - const int rsa_padding); }; } // namespace SW diff --git a/src/manager/crypto/sw-backend/internals.cpp b/src/manager/crypto/sw-backend/internals.cpp index 826e7a5..d121118 100644 --- a/src/manager/crypto/sw-backend/internals.cpp +++ b/src/manager/crypto/sw-backend/internals.cpp @@ -433,8 +433,14 @@ RawBuffer sign(EVP_PKEY *pkey, int rsa_padding = NOT_DEFINED; const EVP_MD *md_algo = NULL; - (void) alg; -// md_algo = getMdAlgo(hashAlgo); + HashAlgorithm hashTmp = HashAlgorithm::NONE; + alg.getParam(ParamName::SV_HASH_ALGO, hashTmp); + md_algo = getMdAlgo(hashTmp); + + RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE; + alg.getParam(ParamName::SV_RSA_PADDING, rsaPad); + rsa_padding = getRsaPadding(rsaPad); + // // if((privateKey.getType() != KeyType::KEY_RSA_PRIVATE) && // (privateKey.getType() != KeyType::KEY_DSA_PRIVATE) && @@ -508,8 +514,8 @@ RawBuffer signMessage(EVP_PKEY *privKey, return sig; } - LogError("Error in EVP_PKEY_sign function"); - ThrowMsg(Crypto::Exception::InternalError, "Error in EVP_PKEY_sign function"); + LogError("Error in EVP_PKEY_sign function. Input param error."); + ThrowMsg(Crypto::Exception::InputParam, "Error in EVP_PKEY_sign function. Input param error."); } RawBuffer digestSignMessage(EVP_PKEY *privKey, @@ -577,8 +583,14 @@ int verify(EVP_PKEY *pkey, int rsa_padding = NOT_DEFINED; const EVP_MD *md_algo = NULL; - (void)alg; -// md_algo = getMdAlgo(hashAlgo); + HashAlgorithm hashTmp = HashAlgorithm::NONE; + alg.getParam(ParamName::SV_HASH_ALGO, hashTmp); + md_algo = getMdAlgo(hashTmp); + + RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE; + alg.getParam(ParamName::SV_RSA_PADDING, rsaPad); + rsa_padding = getRsaPadding(rsaPad); + // // if((publicKey.getType() != KeyType::KEY_RSA_PUBLIC) && // (publicKey.getType() != KeyType::KEY_DSA_PUBLIC) && diff --git a/src/manager/crypto/sw-backend/key.cpp b/src/manager/crypto/sw-backend/key.cpp index cf358b4..93a32e1 100644 --- a/src/manager/crypto/sw-backend/key.cpp +++ b/src/manager/crypto/sw-backend/key.cpp @@ -46,7 +46,7 @@ RawBuffer AKey::sign( return Internals::sign(getEvpShPtr().get(), alg, message); } -bool AKey::verify(const CryptoAlgorithm &alg, const RawBuffer &message, const RawBuffer &sign) { +int AKey::verify(const CryptoAlgorithm &alg, const RawBuffer &message, const RawBuffer &sign) { return Internals::verify(getEvpShPtr().get(), alg, message, sign); } @@ -82,6 +82,25 @@ EvpShPtr AKey::getEvpShPtr() { return m_evp; } +EvpShPtr Cert::getEvpShPtr() { + if (m_evp) + return m_evp; + + int size = static_cast(m_key.size()); + const unsigned char *ptr = reinterpret_cast(m_key.data()); + + X509 *x509 = d2i_X509(NULL, &ptr, size); + + if (!x509) { + LogError("Failed to parse certificate."); + ThrowMsg(Exception::InternalError, "Failed to parse certificate."); + } + + m_evp.reset(X509_get_pubkey(x509), EVP_PKEY_free); + X509_free(x509); + return m_evp; +} + } // namespace SW } // namespace Crypto } // namespace CKM diff --git a/src/manager/crypto/sw-backend/key.h b/src/manager/crypto/sw-backend/key.h index fb0a36e..47ea514 100644 --- a/src/manager/crypto/sw-backend/key.h +++ b/src/manager/crypto/sw-backend/key.h @@ -46,12 +46,12 @@ protected: class AKey : public GKey { public: - AKey(RawBuffer buffer, DataType dataType = DataType::KEY_AES) + AKey(RawBuffer buffer, DataType dataType) : m_key(std::move(buffer)) , m_type(dataType) {} virtual RawBuffer sign(const CryptoAlgorithm &alg, const RawBuffer &message); - virtual bool verify(const CryptoAlgorithm &alg, const RawBuffer &message, const RawBuffer &sign); + virtual int verify(const CryptoAlgorithm &alg, const RawBuffer &message, const RawBuffer &sign); virtual ~AKey(){} protected: virtual EvpShPtr getEvpShPtr(); @@ -61,6 +61,16 @@ protected: DataType m_type; }; +class Cert : public AKey { +public: + Cert(RawBuffer buffer, DataType dataType) + : AKey(std::move(buffer), dataType) + {} + virtual ~Cert(){} +protected: + virtual EvpShPtr getEvpShPtr(); +}; + } // namespace SW } // namespace Crypto } // namespace CKM diff --git a/src/manager/crypto/sw-backend/store.cpp b/src/manager/crypto/sw-backend/store.cpp index 2bc374e..24d890d 100644 --- a/src/manager/crypto/sw-backend/store.cpp +++ b/src/manager/crypto/sw-backend/store.cpp @@ -32,7 +32,7 @@ namespace SW { GKeyShPtr Store::getKey(const Token &token) { if (token.backendId != m_backendId) { - LogDebug("Decider choose wrong backend!"); + LogError("Decider choose wrong backend!"); ThrowMsg(Exception::WrongBackend, "Decider choose wrong backend!"); } @@ -44,6 +44,10 @@ GKeyShPtr Store::getKey(const Token &token) { return std::make_shared(token.data, token.dataType); } + if (token.dataType.isCertificate()) { + return std::make_shared(token.data, token.dataType); + } + LogDebug( "This type of data is not supported by openssl backend: " << (int)token.dataType); ThrowMsg(Exception::KeyNotSupported, diff --git a/src/manager/service/ckm-logic.cpp b/src/manager/service/ckm-logic.cpp index b6ed4f5..b9b5301 100644 --- a/src/manager/service/ckm-logic.cpp +++ b/src/manager/service/ckm-logic.cpp @@ -30,6 +30,7 @@ #include #include +#include #include namespace { @@ -392,6 +393,7 @@ DB::Row CKMLogic::createEncryptedRow( const Policy &policy) const { DB::Row row(name, label, static_cast(policy.extractable), dataType, data, static_cast(data.size())); + row.backendId = m_decider.chooseCryptoBackend(dataType, policy); // do not encrypt data with password during cc_mode on if(m_accessControl.isCCMode()) { @@ -1415,20 +1417,17 @@ RawBuffer CKMLogic::createSignature( const RSAPaddingAlgorithm padding) { DB::Row row; - Crypto::SW::CryptoService cs; RawBuffer signature; + CryptoAlgorithm cryptoAlg; + cryptoAlg.addParam(ParamName::SV_HASH_ALGO, hash); + cryptoAlg.addParam(ParamName::SV_RSA_PADDING, padding); int retCode = CKM_API_SUCCESS; try { retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, row); - if(retCode == CKM_API_SUCCESS) - { - KeyImpl keyParsed(row.data, Password()); - if (keyParsed.empty()) - retCode = CKM_API_ERROR_SERVER_ERROR; - else - retCode = cs.createSignature(keyParsed, message, hash, padding, signature); + if(retCode == CKM_API_SUCCESS) { + signature = m_decider.getStore(row).getKey(row)->sign(cryptoAlg, message); } } catch (const KeyProvider::Exception::Base &e) { LogError("KeyProvider failed with message: " << e.GetMessage()); @@ -1445,6 +1444,12 @@ RawBuffer CKMLogic::createSignature( } catch (const CKMLogic::Exception::DatabaseLocked &e) { LogError("Error " << e.GetMessage()); retCode = CKM_API_ERROR_DB_LOCKED; + } catch (const CKM::Crypto::Exception::InputParam &e) { + LogError("CKM::Crypto failed with message: " << e.GetMessage()); + retCode = CKM_API_ERROR_INPUT_PARAM; + } catch (const CKM::Crypto::Exception::Base &e) { + LogError("CKM::Crypto failed with message: " << e.GetMessage()); + retCode = CKM_API_ERROR_SERVER_ERROR; } catch (const CKM::Exception &e) { LogError("Unknown CKM::Exception: " << e.GetMessage()); retCode = CKM_API_ERROR_SERVER_ERROR; @@ -1471,34 +1476,24 @@ RawBuffer CKMLogic::verifySignature( int retCode = CKM_API_ERROR_VERIFICATION_FAILED; try { - do { - Crypto::SW::CryptoService cs; - DB::Row row; - KeyImpl key; - - // try certificate first - looking for a public key. - // in case of PKCS, pub key from certificate will be found first - // rather than private key from the same PKCS. - retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row); - if (retCode == CKM_API_SUCCESS) { - CertificateImpl cert(row.data, DataFormat::FORM_DER); - key = cert.getKeyImpl(); - } else if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) { - retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row); - if (retCode != CKM_API_SUCCESS) - break; - key = KeyImpl(row.data); - } else { - break; - } - - if (key.empty()) { - retCode = CKM_API_ERROR_SERVER_ERROR; - break; - } + DB::Row row; + KeyImpl key; + + CryptoAlgorithm params; + params.addParam(ParamName::SV_HASH_ALGO, hash); + params.addParam(ParamName::SV_RSA_PADDING, padding); + + // try certificate first - looking for a public key. + // in case of PKCS, pub key from certificate will be found first + // rather than private key from the same PKCS. + retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, row); + if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) { + retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, row); + } - retCode = cs.verifySignature(key, message, signature, hash, padding); - } while(0); + if (retCode == CKM_API_SUCCESS) { + retCode = m_decider.getStore(row).getKey(row)->verify(params, message, signature); + } } catch (const Crypto::SW::CryptoService::Exception::Crypto_internal &e) { LogError("KeyProvider failed with message: " << e.GetMessage()); retCode = CKM_API_ERROR_SERVER_ERROR; diff --git a/src/manager/service/ckm-logic.h b/src/manager/service/ckm-logic.h index eb5e948..124cfc8 100644 --- a/src/manager/service/ckm-logic.h +++ b/src/manager/service/ckm-logic.h @@ -36,6 +36,8 @@ #include #include +#include + namespace CKM { struct UserData { @@ -350,6 +352,7 @@ private: std::map m_userDataMap; AccessControl m_accessControl; + Crypto::Decider m_decider; //FileLock m_lock; };