From: Dariusz Michaluk Date: Tue, 23 Jun 2020 10:12:59 +0000 (+0200) Subject: Refactor dummy-backend, replace mbedtls with openssl X-Git-Tag: submit/tizen/20200728.071123^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=48e4156982187ba3600b99311e60aadbcfdd4f71;p=platform%2Fcore%2Fsecurity%2Fdevice-certificate-manager-backend.git Refactor dummy-backend, replace mbedtls with openssl mbedtls is a part of a big iotivity project, which is not used on a product sometimes. We can use openssl instead, which is a base package. Change-Id: I881e4f257b23b2efa83043c3b7951ba3141e09d0 --- diff --git a/packaging/device-certificate-manager-backend-dummy.spec b/packaging/device-certificate-manager-backend-dummy.spec index e68d391..b79ada3 100644 --- a/packaging/device-certificate-manager-backend-dummy.spec +++ b/packaging/device-certificate-manager-backend-dummy.spec @@ -8,7 +8,7 @@ Source0: %{name}-%{version}.tar.gz Source1001: device-certificate-manager-backend.manifest BuildRequires: cmake BuildRequires: pkgconfig(dlog) -BuildRequires: pkgconfig(iotivity) +BuildRequires: pkgconfig(openssl1.1) BuildRequires: pkgconfig(device-certificate-manager-backend) BuildRequires: openssl1.1 Requires(post): /sbin/ldconfig diff --git a/src/dummy-backend/CMakeLists.txt b/src/dummy-backend/CMakeLists.txt index 220cdff..57ec8a9 100644 --- a/src/dummy-backend/CMakeLists.txt +++ b/src/dummy-backend/CMakeLists.txt @@ -12,15 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# @file src/see-backend/CMakeLists.txt +# @file src/dummy-backend/CMakeLists.txt # @author Pawel Kowalski # @author Jaroslaw Pelczar # FIND_PROGRAM(OPENSSL_TOOL openssl REQUIRED) FIND_PACKAGE(PkgConfig REQUIRED) -FIND_LIBRARY(MBEDTLS_LIB mbedtls) -FIND_LIBRARY(MBEDCRYPTO_LIB mbedcrypto) ADD_EXECUTABLE(bin2c bin2c.c) @@ -58,7 +56,11 @@ ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/rootCA_ecdsa_cert.c COMMAND $ ${CMAKE_CURRENT_BINARY_DIR}/rootECDSA.pem ${CMAKE_CURRENT_BINARY_DIR}/rootCA_ecdsa_cert.c dummy_rootca_ecdsa_cert DEPENDS bin2c ${CMAKE_CURRENT_BINARY_DIR}/rootECDSA.pem) -PKG_CHECK_MODULES(DUMMY_DEPS REQUIRED dlog device-certificate-manager-backend) +PKG_CHECK_MODULES(DUMMY_DEPS REQUIRED + dlog + device-certificate-manager-backend + openssl1.1) + INCLUDE_DIRECTORIES(SYSTEM ${DUMMY_DEPS_INCLUDE_DIRS}) LINK_DIRECTORIES(${DUMMY_DEPS_LIBRARY_DIRS}) @@ -67,7 +69,7 @@ INCLUDE_DIRECTORIES(../shared) ADD_LIBRARY(${DCM_BACKEND_API} SHARED dcm-backend-api-dummy.cpp - dummycryptobackendcontext.cpp + dummy_backend.cpp ../shared/log.cpp ${CMAKE_CURRENT_BINARY_DIR}/rootCA_ecdsa_key.c ${CMAKE_CURRENT_BINARY_DIR}/rootCA_ecdsa_cert.c @@ -75,8 +77,6 @@ ADD_LIBRARY(${DCM_BACKEND_API} ${CMAKE_CURRENT_BINARY_DIR}/rootCA_rsa_cert.c) TARGET_LINK_LIBRARIES(${DCM_BACKEND_API} - ${MBEDTLS_LIB} - ${MBEDCRYPTO_LIB} ${DUMMY_DEPS_LIBRARIES}) SET_TARGET_PROPERTIES(${DCM_BACKEND_API} diff --git a/src/dummy-backend/dcm-backend-api-dummy.cpp b/src/dummy-backend/dcm-backend-api-dummy.cpp index 2f4c876..f926847 100644 --- a/src/dummy-backend/dcm-backend-api-dummy.cpp +++ b/src/dummy-backend/dcm-backend-api-dummy.cpp @@ -1,6 +1,5 @@ /****************************************************************** - * - * Copyright 2019 Samsung Electronics All Rights Reserved. + * Copyright 2019 - 2020 Samsung Electronics All Rights Reserved. * * Author: Pawel Kowalski * @@ -18,38 +17,51 @@ * ******************************************************************/ -#include "dummycryptobackendcontext.h" #include + #include +#include "dummy_backend.h" +#include "log.h" + void dcm_backend_create_key_context(dcm_backend_context& ctx, - const std::string& keyType) { - ctx.backend = new dummy_crypto_backend_context(keyType); + const std::string& keyType) +{ + LOGD("Create backend context"); + ctx.backend = new dummy_backend(keyType); } -void dcm_backend_free_key_context(dcm_backend_context& ctx) { - delete static_cast(ctx.backend); +void dcm_backend_free_key_context(dcm_backend_context& ctx) +{ + LOGD("Delete backend context"); + delete static_cast(ctx.backend); ctx.backend = nullptr; } int dcm_backend_request_certificate_chain(dcm_backend_context& ctx, - std::string& mutable_chain) { - return ctx.backend ? static_cast(ctx.backend) - ->request_certificate_chain(mutable_chain) : -1; + std::string& mutable_chain) +{ + return ctx.backend ? static_cast(ctx.backend) + ->request_certificate_chain(mutable_chain) : -1; } int dcm_backend_sign_crypto_data(dcm_backend_context& ctx, - MessageDigestType digestType, - const std::string& dataToSign, - std::string& digestResult) { - return ctx.backend ? static_cast(ctx.backend) - ->sign_crypto_data(digestType, dataToSign, digestResult) : -1; + MessageDigestType digestType, + const std::string& dataToSign, + std::string& digestResult) +{ + return ctx.backend ? static_cast(ctx.backend) + ->sign_data(digestType, dataToSign, digestResult) : -1; } -CryptoKeyType dcm_backend_key_type(dcm_backend_context& ctx) { - return ctx.backend ? static_cast(ctx.backend)->key_type() : CryptoKeyType::CRYPTO_KEY_TYPE_INVALID; +CryptoKeyType dcm_backend_key_type(dcm_backend_context& ctx) +{ + return ctx.backend ? static_cast(ctx.backend) + ->key_type() : CryptoKeyType::CRYPTO_KEY_TYPE_INVALID; } -unsigned int dcm_backend_key_length(dcm_backend_context& ctx) { - return ctx.backend ? static_cast(ctx.backend)->key_length() : 0; +unsigned int dcm_backend_key_length(dcm_backend_context& ctx) +{ + return ctx.backend ? static_cast(ctx.backend) + ->key_length() : 0; } diff --git a/src/dummy-backend/dummy_backend.cpp b/src/dummy-backend/dummy_backend.cpp new file mode 100644 index 0000000..f1615ae --- /dev/null +++ b/src/dummy-backend/dummy_backend.cpp @@ -0,0 +1,235 @@ +/****************************************************************** + * Copyright 2017 - 2020 Samsung Electronics All Rights Reserved. + * + * Author: Jaroslaw Pelczar + * + * 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 +#include + +#include +#include +#include +#include + +#include "dummy_backend.h" +#include "log.h" + +extern "C" { + extern size_t dummy_rootca_rsa_key_size; + extern char dummy_rootca_rsa_key[]; + extern size_t dummy_rootca_rsa_cert_size; + extern char dummy_rootca_rsa_cert[]; + extern size_t dummy_rootca_ecdsa_key_size; + extern char dummy_rootca_ecdsa_key[]; + extern size_t dummy_rootca_ecdsa_cert_size; + extern char dummy_rootca_ecdsa_cert[]; +} + +EVP_PKEY* get_rsa_pkey() +{ + EVP_PKEY* pkey = NULL; + BIO* bio = NULL; + + if(!(bio = BIO_new_mem_buf(dummy_rootca_rsa_key, dummy_rootca_rsa_key_size))) { + LOGE("Can't parse private RSA key"); + return pkey; + } + + if(!(pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL))) { + LOGE("Can't parse private RSA key"); + } + + BIO_free(bio); + return pkey; +} + +EVP_PKEY* get_ecdsa_pkey() +{ + EVP_PKEY* pkey = NULL; + EC_KEY* eckey = NULL; + BIO* bio = NULL; + + if(!(bio = BIO_new_mem_buf(dummy_rootca_ecdsa_key, dummy_rootca_ecdsa_key_size))) { + LOGE("Can't parse private ECDSA key"); + return pkey; + } + + eckey = PEM_read_bio_ECPrivateKey(bio, NULL, NULL, NULL); + BIO_free(bio); + if(!eckey) { + LOGE("Can't parse private ECDSA key"); + return pkey; + } + + if(!(pkey = EVP_PKEY_new())) { + LOGE("Can't allocate EVP_PKEY"); + EC_KEY_free(eckey); + return pkey; + } + + if(1 != EVP_PKEY_assign_EC_KEY(pkey, eckey)) { + LOGE("Can't assign EC key to PKEY"); + EC_KEY_free(eckey); + EVP_PKEY_free(pkey); + pkey = NULL; + } + + return pkey; +} + +const EVP_MD* to_openssl_md_type(MessageDigestType digestType) +{ + switch(digestType) { + case MD_NONE: + return nullptr; + case MD_MD2: + return EVP_md2(); + case MD_MD4: + return EVP_md4(); + case MD_MD5: + return EVP_md5(); + case MD_SHA1: + return EVP_sha1(); + case MD_SHA224: + return EVP_sha224(); + case MD_SHA256: + return EVP_sha256(); + case MD_SHA384: + return EVP_sha384(); + case MD_SHA512: + return EVP_sha512(); + case MD_RIPEMD160: + return EVP_ripemd160(); + default: + return nullptr; + } +} + +dummy_backend::dummy_backend(const std::string& keyType) +{ + if(keyType.empty() || keyType == "RSA") { + fKey = CRYPTO_KEY_TYPE_RSA; + } else if(keyType == "ECDSA") { + fKey = CRYPTO_KEY_TYPE_ECDSA; + } else { + LOGE("Unsupported key type"); + throw std::invalid_argument("Unsupported key type"); + } +} + +dummy_backend::~dummy_backend() +{ +} + +int dummy_backend::request_certificate_chain(std::string& mutable_chain) +{ + if(fKey == CRYPTO_KEY_TYPE_RSA) { + mutable_chain.assign(dummy_rootca_rsa_cert, dummy_rootca_rsa_cert_size); + } else { + mutable_chain.assign(dummy_rootca_ecdsa_cert, dummy_rootca_ecdsa_cert_size); + } + + return 0; +} + +int dummy_backend::sign_data(MessageDigestType digestType, + const std::string& dataToSign, std::string& digestResult) +{ + int error = -1; + + EVP_PKEY* pkey = NULL; + size_t sig_len = 0; + + if(fKey == CRYPTO_KEY_TYPE_RSA) { + pkey = get_rsa_pkey(); + } else { + pkey = get_ecdsa_pkey(); + } + + if(!pkey) { + LOGE("Can't load private key"); + return error; + } + + typedef std::unique_ptr CtxPtr; + CtxPtr ctx(EVP_PKEY_CTX_new(pkey, NULL), EVP_PKEY_CTX_free); + EVP_PKEY_free(pkey); + if(!ctx.get()) { + LOGE("Can't create pkey context"); + return error; + } + + if(1 != EVP_PKEY_sign_init(ctx.get())) { + LOGE("Can't initialise sign operation"); + return error; + } + + if(fKey == CRYPTO_KEY_TYPE_RSA) { + if(1 != EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING)) { + LOGE("Can't set padding"); + return error; + } + } + + if(1 != EVP_PKEY_CTX_set_signature_md(ctx.get(), to_openssl_md_type(digestType))) { + LOGE("Can't set signature digest"); + return error; + } + + if(1 != EVP_PKEY_sign(ctx.get(), NULL, &sig_len, + (const unsigned char*)dataToSign.c_str(), dataToSign.size())) { + LOGE("Can't get signature length"); + return error; + } + + digestResult.assign(sig_len, 0); + + if(1 != EVP_PKEY_sign(ctx.get(), (unsigned char*) &digestResult[0], &sig_len, + (const unsigned char*)dataToSign.c_str(), dataToSign.size())) { + LOGE("Can't get signature"); + return error; + } + + digestResult.resize(sig_len); + return 0; +} + +CryptoKeyType dummy_backend::dummy_backend::key_type() +{ + return fKey; +} + +unsigned int dummy_backend::key_length() +{ + unsigned int keyLength = 0; + EVP_PKEY* pkey = NULL; + + if(fKey == CRYPTO_KEY_TYPE_RSA) { + pkey = get_rsa_pkey(); + } else { + pkey = get_ecdsa_pkey(); + } + + if(!pkey) { + LOGE("Can't load private key"); + return keyLength; + } + + keyLength = EVP_PKEY_bits(pkey); + EVP_PKEY_free(pkey); + return keyLength; +} diff --git a/src/dummy-backend/dummy_backend.h b/src/dummy-backend/dummy_backend.h new file mode 100644 index 0000000..05961c3 --- /dev/null +++ b/src/dummy-backend/dummy_backend.h @@ -0,0 +1,45 @@ +/****************************************************************** + * Copyright 2017 - 2020 Samsung Electronics All Rights Reserved. + * + * Author: Jaroslaw Pelczar + * + * 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. + * + ******************************************************************/ + +#ifndef DUMMY_BACKEND_DUMMY_BACKEND_H_ +#define DUMMY_BACKEND_DUMMY_BACKEND_H_ + +#include + +#include + +class dummy_backend { +public: + dummy_backend(const std::string& keyType); + ~dummy_backend(); + + int request_certificate_chain(std::string& mutable_chain); + + int sign_data(MessageDigestType digestType, + const std::string& dataToSign, std::string& digestResult); + + CryptoKeyType key_type(); + + unsigned int key_length(); + +private: + CryptoKeyType fKey; +}; + +#endif /* DUMMY_BACKEND_DUMMY_BACKEND_H_ */ diff --git a/src/dummy-backend/dummycryptobackendcontext.cpp b/src/dummy-backend/dummycryptobackendcontext.cpp deleted file mode 100644 index 11fa2f5..0000000 --- a/src/dummy-backend/dummycryptobackendcontext.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/****************************************************************** - * - * Copyright 2017 - 2019 Samsung Electronics All Rights Reserved. - * - * Author: Jaroslaw Pelczar - * - * 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 "dummycryptobackendcontext.h" -#include -#include -#include -#include "log.h" -#include - -extern "C" { - extern size_t dummy_rootca_rsa_key_size; - extern char dummy_rootca_rsa_key[]; - extern size_t dummy_rootca_rsa_cert_size; - extern char dummy_rootca_rsa_cert[]; - extern size_t dummy_rootca_ecdsa_key_size; - extern char dummy_rootca_ecdsa_key[]; - extern size_t dummy_rootca_ecdsa_cert_size; - extern char dummy_rootca_ecdsa_cert[]; -} - -dummy_crypto_backend_context::dummy_crypto_backend_context(const std::string& keyType) { - if(keyType.empty() || keyType == "RSA") { - fKey = CRYPTO_KEY_TYPE_RSA; - } else if(keyType == "ECDSA") { - fKey = CRYPTO_KEY_TYPE_ECDSA; - } else { - throw std::invalid_argument("Unsupported key type"); - } - - mbedtls_entropy_init( &fEntropy ); - mbedtls_ctr_drbg_init( &fCtrDrbg ); - - int ret = mbedtls_ctr_drbg_seed( &fCtrDrbg, - mbedtls_entropy_func, - &fEntropy, - (const unsigned char *)this, - sizeof(dummy_crypto_backend_context) ); - - if(!ret) { - LOGE("Can't seed entropy source"); - mbedtls_ctr_drbg_free( &fCtrDrbg ); - mbedtls_entropy_free( &fEntropy ); - throw std::runtime_error("seed failure"); - } -} - -dummy_crypto_backend_context::~dummy_crypto_backend_context() { - mbedtls_ctr_drbg_free( &fCtrDrbg ); - mbedtls_entropy_free( &fEntropy ); -} - -int dummy_crypto_backend_context::request_certificate_chain(std::string& mutable_chain) -{ - if(fKey == CRYPTO_KEY_TYPE_RSA) { - mutable_chain.assign(dummy_rootca_rsa_cert, dummy_rootca_rsa_cert_size); - } else { - mutable_chain.assign(dummy_rootca_ecdsa_cert, dummy_rootca_ecdsa_cert_size); - } - - return 0; -} - -int dummy_crypto_backend_context::sign_crypto_data(MessageDigestType digestType, - const std::string& dataToSign, - std::string& digestResult) -{ - int error; - - mbedtls_pk_context pk; - mbedtls_pk_init(&pk); - - if(fKey == CRYPTO_KEY_TYPE_RSA) { - error = mbedtls_pk_parse_key(&pk, - (const unsigned char *)dummy_rootca_rsa_key, - dummy_rootca_rsa_key_size + 1, // Include 0 byte for PEM - nullptr, 0); - - } else { - error = mbedtls_pk_parse_key(&pk, - (const unsigned char *)dummy_rootca_ecdsa_key, - dummy_rootca_ecdsa_key_size + 1, // Include 0 byte for PEM - nullptr, 0); - } - - if(error != 0) { - LOGE("Can't parse private key"); - mbedtls_pk_free(&pk); - return error; - } - - size_t sig_len = 0; - - LOGD("Maximum digest size is " << MBEDTLS_MPI_MAX_SIZE); - - char* output = (char*)malloc(MBEDTLS_MPI_MAX_SIZE); - - if (!output) { - LOGE("Can't allocate output buffer for signing"); - error = -1; - mbedtls_pk_free(&pk); - return error; - } - - error = mbedtls_pk_sign(&pk, - static_cast(digestType), - (const unsigned char *)dataToSign.c_str(), - dataToSign.size(), - (unsigned char *)output, - &sig_len, - &mbedtls_ctr_drbg_random, - &fCtrDrbg); - - if(error != 0) { - LOGE("Signature generation failed"); - } else { - LOGD("Signature size is " << sig_len); - digestResult = std::string(output, sig_len); - } - - mbedtls_pk_free(&pk); - free(output); - - return error; -} - -CryptoKeyType dummy_crypto_backend_context::dummy_crypto_backend_context::key_type() -{ - return fKey; -} - -unsigned int dummy_crypto_backend_context::key_length() -{ - size_t keyLength = 0; - - mbedtls_pk_context pk; - mbedtls_pk_init(&pk); - - if(fKey == CRYPTO_KEY_TYPE_RSA) { - int error = mbedtls_pk_parse_key(&pk, - (const unsigned char *)dummy_rootca_rsa_key, - dummy_rootca_rsa_key_size + 1, // Include 0 byte for PEM - nullptr, 0); - - assert(error == 0); - assert(mbedtls_pk_get_type(&pk) == MBEDTLS_PK_RSA); - (void)error; - } else { - int error = mbedtls_pk_parse_key(&pk, - (const unsigned char *)dummy_rootca_ecdsa_key, - dummy_rootca_ecdsa_key_size + 1, // Include 0 byte for PEM - nullptr, 0); - - assert(error == 0); - assert(mbedtls_pk_get_type(&pk) == MBEDTLS_PK_ECKEY); - (void)error; - } - - keyLength = mbedtls_pk_get_bitlen(&pk); - mbedtls_pk_free(&pk); - - assert(UINT_MAX >= keyLength); - - return keyLength; -} diff --git a/src/dummy-backend/dummycryptobackendcontext.h b/src/dummy-backend/dummycryptobackendcontext.h deleted file mode 100644 index 7061b0e..0000000 --- a/src/dummy-backend/dummycryptobackendcontext.h +++ /dev/null @@ -1,49 +0,0 @@ -/****************************************************************** - * - * Copyright 2017 - 2019 Samsung Electronics All Rights Reserved. - * - * Author: Jaroslaw Pelczar - * - * 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. - * - ******************************************************************/ - -#ifndef DUMMY_BACKEND_DUMMYCRYPTOBACKENDCONTEXT_H_ -#define DUMMY_BACKEND_DUMMYCRYPTOBACKENDCONTEXT_H_ - -#include -#include -#include -#include - -class dummy_crypto_backend_context { -public: - dummy_crypto_backend_context(const std::string& keyType); - ~dummy_crypto_backend_context(); - - int request_certificate_chain(std::string& mutable_chain); - - int sign_crypto_data(MessageDigestType digestType, const std::string& dataToSign, - std::string& digestResult); - - CryptoKeyType key_type(); - - unsigned int key_length(); - -private: - CryptoKeyType fKey; - mbedtls_entropy_context fEntropy; - mbedtls_ctr_drbg_context fCtrDrbg; -}; - -#endif /* DUMMY_BACKEND_DUMMYCRYPTOBACKENDCONTEXT_H_ */