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
# 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 <p.kowalski2@partner.samsung.com>
# @author Jaroslaw Pelczar <j.pelczar@samsung.com>
#
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)
COMMAND $<TARGET_FILE:bin2c> ${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})
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
${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}
/******************************************************************
- *
- * Copyright 2019 Samsung Electronics All Rights Reserved.
+ * Copyright 2019 - 2020 Samsung Electronics All Rights Reserved.
*
* Author: Pawel Kowalski <p.kowalski2@partner.samsung.com>
*
*
******************************************************************/
-#include "dummycryptobackendcontext.h"
#include <string>
+
#include <device-certificate-manager-backend/dcm-backend-api.h>
+#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<dummy_crypto_backend_context*>(ctx.backend);
+void dcm_backend_free_key_context(dcm_backend_context& ctx)
+{
+ LOGD("Delete backend context");
+ delete static_cast<dummy_backend*>(ctx.backend);
ctx.backend = nullptr;
}
int dcm_backend_request_certificate_chain(dcm_backend_context& ctx,
- std::string& mutable_chain) {
- return ctx.backend ? static_cast<dummy_crypto_backend_context*>(ctx.backend)
- ->request_certificate_chain(mutable_chain) : -1;
+ std::string& mutable_chain)
+{
+ return ctx.backend ? static_cast<dummy_backend*>(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<dummy_crypto_backend_context*>(ctx.backend)
- ->sign_crypto_data(digestType, dataToSign, digestResult) : -1;
+ MessageDigestType digestType,
+ const std::string& dataToSign,
+ std::string& digestResult)
+{
+ return ctx.backend ? static_cast<dummy_backend*>(ctx.backend)
+ ->sign_data(digestType, dataToSign, digestResult) : -1;
}
-CryptoKeyType dcm_backend_key_type(dcm_backend_context& ctx) {
- return ctx.backend ? static_cast<dummy_crypto_backend_context*>(ctx.backend)->key_type() : CryptoKeyType::CRYPTO_KEY_TYPE_INVALID;
+CryptoKeyType dcm_backend_key_type(dcm_backend_context& ctx)
+{
+ return ctx.backend ? static_cast<dummy_backend*>(ctx.backend)
+ ->key_type() : CryptoKeyType::CRYPTO_KEY_TYPE_INVALID;
}
-unsigned int dcm_backend_key_length(dcm_backend_context& ctx) {
- return ctx.backend ? static_cast<dummy_crypto_backend_context*>(ctx.backend)->key_length() : 0;
+unsigned int dcm_backend_key_length(dcm_backend_context& ctx)
+{
+ return ctx.backend ? static_cast<dummy_backend*>(ctx.backend)
+ ->key_length() : 0;
}
--- /dev/null
+/******************************************************************
+ * Copyright 2017 - 2020 Samsung Electronics All Rights Reserved.
+ *
+ * Author: Jaroslaw Pelczar <j.pelczar@samsung.com>
+ *
+ * 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 <string>
+#include <iostream>
+
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+#include <openssl/bio.h>
+#include <openssl/rsa.h>
+
+#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<EVP_PKEY_CTX, decltype(EVP_PKEY_CTX_free)*> 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;
+}
/******************************************************************
- *
- * Copyright 2017 - 2019 Samsung Electronics All Rights Reserved.
+ * Copyright 2017 - 2020 Samsung Electronics All Rights Reserved.
*
* Author: Jaroslaw Pelczar <j.pelczar@samsung.com>
*
*
******************************************************************/
-#ifndef DUMMY_BACKEND_DUMMYCRYPTOBACKENDCONTEXT_H_
-#define DUMMY_BACKEND_DUMMYCRYPTOBACKENDCONTEXT_H_
+#ifndef DUMMY_BACKEND_DUMMY_BACKEND_H_
+#define DUMMY_BACKEND_DUMMY_BACKEND_H_
-#include <mbedtls/ctr_drbg.h>
-#include <mbedtls/entropy.h>
#include <string>
+
#include <device-certificate-manager-backend/dcm-backend-api.h>
-class dummy_crypto_backend_context {
+class dummy_backend {
public:
- dummy_crypto_backend_context(const std::string& keyType);
- ~dummy_crypto_backend_context();
+ dummy_backend(const std::string& keyType);
+ ~dummy_backend();
int request_certificate_chain(std::string& mutable_chain);
- int sign_crypto_data(MessageDigestType digestType, const std::string& dataToSign,
- std::string& digestResult);
+ int sign_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;
+ CryptoKeyType fKey;
};
-#endif /* DUMMY_BACKEND_DUMMYCRYPTOBACKENDCONTEXT_H_ */
+#endif /* DUMMY_BACKEND_DUMMY_BACKEND_H_ */
+++ /dev/null
-/******************************************************************
- *
- * Copyright 2017 - 2019 Samsung Electronics All Rights Reserved.
- *
- * Author: Jaroslaw Pelczar <j.pelczar@samsung.com>
- *
- * 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 <mbedtls/pk.h>
-#include <mbedtls/ctr_drbg.h>
-#include <iostream>
-#include "log.h"
-#include <string>
-
-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<mbedtls_md_type_t>(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;
-}