Adapt key-manager to work with OpenSSL 1.1 preserving 1.0 compatibility 97/172597/9
authorDariusz Michaluk <d.michaluk@samsung.com>
Fri, 23 Feb 2018 12:04:02 +0000 (13:04 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 17 Jun 2019 13:20:51 +0000 (15:20 +0200)
Change-Id: Ia62003a44d3dcb6d8c076706387e88399bf6cfb1

src/manager/client-capi/ckmc-type.cpp
src/manager/common/crypto-init.cpp
src/manager/common/key-impl.cpp
src/manager/common/openssl-error-handler.cpp
src/manager/common/pkcs12-impl.cpp
src/manager/crypto/sw-backend/internals.cpp
src/manager/crypto/sw-backend/obj.cpp
src/manager/service/certificate-store.cpp
src/manager/service/ss-crypto.cpp
src/manager/sqlcipher/sqlcipher.c

index 6567c97ad05cb1f18e6bb25c43285eb40bb3a65e..3b03f1294b4b75b7c671b3d749d09c3f364a4245 100644 (file)
@@ -414,7 +414,7 @@ int ckmc_load_from_pkcs12_file(const char *file_path, const char *passphrase,
 
                        output.resize(size);
 
-                       int type = EVP_PKEY_type(pkey->type);
+                       int type = EVP_PKEY_type(EVP_PKEY_id(pkey));
                        ckmc_key_type_e key_type = CKMC_KEY_NONE;
 
                        switch (type) {
index 573a4d63f22c23009c2c0b0235674bf5c42d3f04..7fa66715f3784c2dc4c00fecb7a049363226cf0d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000 - 2019 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.
@@ -43,6 +43,25 @@ const char *DEV_HW_RANDOM_FILE = "/dev/hwrng";
 const char *DEV_URANDOM_FILE = "/dev/urandom";
 const size_t RANDOM_BUFFER_LEN = 32;
 
+void initializeEntropy() // entropy sources - /dev/random,/dev/urandom(Default)
+{
+       int ret = 0;
+
+       std::ifstream ifile(DEV_HW_RANDOM_FILE);
+
+       if (ifile.is_open())
+               ret = RAND_load_file(DEV_HW_RANDOM_FILE, RANDOM_BUFFER_LEN);
+
+       if (ret != RANDOM_BUFFER_LEN) {
+               LogWarning("Error in HW_RAND file load");
+               ret = RAND_load_file(DEV_URANDOM_FILE, RANDOM_BUFFER_LEN);
+
+               if (ret != RANDOM_BUFFER_LEN)
+                       LogError("Error in U_RAND_file_load");
+       }
+}
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 std::mutex *g_mutexes = NULL;
 
 void lockingCallback(int mode, int type, const char *, int)
@@ -94,24 +113,7 @@ void initOpenSsl(bool isLib)
 
        // below initializes only for executable client. (key-manager daemon)
 
-       /*
-        * Initialize entropy
-        * entropy sources - /dev/random,/dev/urandom(Default)
-        */
-       int ret = 0;
-
-       std::ifstream ifile(DEV_HW_RANDOM_FILE);
-
-       if (ifile.is_open())
-               ret = RAND_load_file(DEV_HW_RANDOM_FILE, RANDOM_BUFFER_LEN);
-
-       if (ret != RANDOM_BUFFER_LEN) {
-               LogWarning("Error in HW_RAND file load");
-               ret = RAND_load_file(DEV_URANDOM_FILE, RANDOM_BUFFER_LEN);
-
-               if (ret != RANDOM_BUFFER_LEN)
-                       LogError("Error in U_RAND_file_load");
-       }
+       initializeEntropy();
 
        /*
         *  Initialize libssl (OCSP uses it)
@@ -162,9 +164,10 @@ void initOpenSslAndDetach()
                initFn.store(&initEmpty, std::memory_order_release);
        }
 }
-
+#endif
 } // namespace anonymous
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 void initOpenSsl()
 {
        initOpenSsl(false);
@@ -193,5 +196,15 @@ void initOpenSslOnce()
         */
        initFn.load(std::memory_order_acquire)();
 }
+#else
+void initOpenSsl()
+{
+       initializeEntropy();
+}
+
+void deinitOpenSsl() {}
+void deinitOpenSslThread() {}
+void initOpenSslOnce() {}
+#endif
 
 } // namespace CKM
index 2a1281868385b2558af188824b96e1c8d6cfbc0b..63c4be5879911e9fe46ebe6c57fc8357e64d6a77 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+/* Copyright (c) 2000 - 2019 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.
@@ -145,7 +145,7 @@ KeyImpl::KeyImpl(const RawBuffer &buf, const Password &password) :
 
        m_pkey.reset(pkey, EVP_PKEY_free);
 
-       switch (EVP_PKEY_type(pkey->type)) {
+       switch (EVP_PKEY_type(EVP_PKEY_id(pkey))) {
        case EVP_PKEY_RSA:
                m_type = isPrivate ? KeyType::KEY_RSA_PRIVATE : KeyType::KEY_RSA_PUBLIC;
                break;
@@ -193,7 +193,7 @@ KeyImpl::KeyImpl(EvpShPtr pkey, KeyType type) : m_pkey(pkey), m_type(type)
        }
 
        // verify if actual key type matches the expected tpe
-       int given_key_type = EVP_PKEY_type(pkey->type);
+       int given_key_type = EVP_PKEY_type(EVP_PKEY_id(pkey.get()));
 
        if (given_key_type == EVP_PKEY_NONE || expected_type != given_key_type) {
                m_pkey.reset();
index e8649c104c02852c5cd52c432aa47df54e214863..a43e09445575ba506bb9ffb8b4d76ef57ae35b57 100644 (file)
@@ -90,6 +90,10 @@ void errorHandle(const char *file, int line, const char *function, int openssl_r
 #if OPENSSL_VERSION_NUMBER > 0x10100000L
        case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
        case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
+       case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS):
+       case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS):
+       case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS):
+       case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS):
 #else /* OPENSSL_VERSION_NUMBER > 0x10100000L */
        case ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS):
        case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS):
@@ -122,8 +126,10 @@ void errorHandle(const char *file, int line, const char *function, int openssl_r
        case ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED):
        case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE):
        case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED):
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
        case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE):
        case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, EVP_R_NO_VERIFY_FUNCTION_CONFIGURED):
+#endif
                ret = CKM_API_ERROR_VERIFICATION_FAILED;
                break;
        }
index c53a3773c14e1751c3cfa218a39b223fe4fc0905..100e9b5b6c9b334b534cf0c934e74ed6a3b20a20 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014 Samsung Electronics Co.
+/* Copyright (c) 2014 - 2019 Samsung Electronics Co.
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -87,7 +87,7 @@ PKCS12Impl::PKCS12Impl(const RawBuffer &buffer, const Password &password)
        if (pkey) {
                KeyImpl::EvpShPtr ptr(pkey, EVP_PKEY_free);
 
-               switch (EVP_PKEY_type(pkey->type)) {
+               switch (EVP_PKEY_type(EVP_PKEY_id(pkey))) {
                case EVP_PKEY_RSA:
                        m_pkey = std::make_shared<KeyImpl>(ptr, KeyType::KEY_RSA_PRIVATE);
                        break;
@@ -189,4 +189,3 @@ PKCS12ShPtr PKCS12::create(const RawBuffer &rawBuffer, const Password &password)
 }
 
 } // namespace CKM
-
index a5f2f9e96b7154599d096b41fbfc1c6c5fcca8d3..a0f02395a214d2a346b27ced3b41ac3f12e6609c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000 - 2019 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.
@@ -817,7 +817,7 @@ RawBuffer signMessage(EVP_PKEY *privKey,
                                          const RawBuffer &message,
                                          const int rsa_padding)
 {
-       if (EVP_PKEY_type(privKey->type) != EVP_PKEY_RSA)
+       if (EVP_PKEY_type(EVP_PKEY_id(privKey)) != EVP_PKEY_RSA)
                ThrowErr(Exc::Crypto::InputParam, "Only RSA supports no hash option");
 
        EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(privKey, NULL), EVP_PKEY_CTX_free);
@@ -828,7 +828,7 @@ RawBuffer signMessage(EVP_PKEY *privKey,
        OPENSSL_ERROR_HANDLE(EVP_PKEY_sign_init(pctx.get()));
 
        /* Set padding algorithm */
-       if (EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA)
+       if (EVP_PKEY_type(EVP_PKEY_id(privKey)) == EVP_PKEY_RSA)
                OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding));
 
        /* Finalize the Sign operation */
@@ -853,18 +853,23 @@ RawBuffer digestSignMessage(EVP_PKEY *privKey,
                                                        const EVP_MD *md_algo,
                                                        const int rsa_padding)
 {
-       EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
-
        EVP_PKEY_CTX *pctx = NULL;
 
        // Create the Message Digest Context
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+       EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
        if (!mdctx.get())
                ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
+#else
+       EvpMdCtxUPtr mdctx(EVP_MD_CTX_new(), EVP_MD_CTX_free);
+       if (!mdctx.get())
+               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_new function");
+#endif
 
        OPENSSL_ERROR_HANDLE(EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL, privKey));
 
        /* Set padding algorithm */
-       if (EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA)
+       if (EVP_PKEY_type(EVP_PKEY_id(privKey)) == EVP_PKEY_RSA)
                OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding));
 
        /* Call update with the message */
@@ -934,7 +939,7 @@ int verifyMessage(EVP_PKEY *pubKey,
                                  const RawBuffer &signature,
                                  const int rsa_padding)
 {
-       if (EVP_PKEY_type(pubKey->type) != EVP_PKEY_RSA)
+       if (EVP_PKEY_type(EVP_PKEY_id(pubKey)) != EVP_PKEY_RSA)
                ThrowErr(Exc::Crypto::InputParam, "Only RSA supports no hash option");
 
        EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(pubKey, NULL), EVP_PKEY_CTX_free);
@@ -945,7 +950,7 @@ int verifyMessage(EVP_PKEY *pubKey,
        OPENSSL_ERROR_HANDLE(EVP_PKEY_verify_init(pctx.get()));
 
        /* Set padding algorithm */
-       if (EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA)
+       if (EVP_PKEY_type(EVP_PKEY_id(pubKey)) == EVP_PKEY_RSA)
                OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding));
 
        if (OPENSSL_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(),
@@ -962,15 +967,22 @@ int digestVerifyMessage(EVP_PKEY *pubKey,
                                                const EVP_MD *md_algo,
                                                const int rsa_padding)
 {
-       EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
        EVP_PKEY_CTX *pctx = NULL;
 
+       // Create the Message Digest Context
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+       EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
        if (!mdctx.get())
                ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
+#else
+       EvpMdCtxUPtr mdctx(EVP_MD_CTX_new(), EVP_MD_CTX_free);
+       if (!mdctx.get())
+               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_new function");
+#endif
 
        OPENSSL_ERROR_HANDLE(EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, pubKey));
 
-       if (EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA)
+       if (EVP_PKEY_type(EVP_PKEY_id(pubKey)) == EVP_PKEY_RSA)
                OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding));
 
        OPENSSL_ERROR_HANDLE(EVP_DigestVerifyUpdate(mdctx.get(), message.data(), message.size()));
index a7a7cdc092021c9a21b9848067ff13f23833389e..f5bb466006dec04191fd3a147d38fffacdf9b26d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2000 - 2019 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.
@@ -87,7 +87,7 @@ int AKey::verify(const CryptoAlgorithm &alg, const RawBuffer &message,
 
        // setup algorithm type basing on evp key type if it doesn't exist
        if (!algWithType.getParam(ParamName::ALGO_TYPE, type)) {
-               int subType = EVP_PKEY_type(evp->type);
+               int subType = EVP_PKEY_type(EVP_PKEY_id(evp));
 
                switch (subType) {
                case EVP_PKEY_RSA:
index 871b8a9a9ab12bbaf6219d32d59888d1b81c9e92..195316b5e3bcd59c8721c6638ec35f4907747176 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+/* Copyright (c) 2000 - 2019 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.
@@ -103,7 +103,7 @@ int CertificateStore::verifyCertificate(
        }
 
        if (stateCCMode)
-               X509_VERIFY_PARAM_set_flags(csc->param, X509_V_FLAG_X509_STRICT);
+               X509_VERIFY_PARAM_set_flags(X509_STORE_CTX_get0_param(csc.get()), X509_V_FLAG_X509_STRICT);
 
        int result = X509_verify_cert(csc.get()); // 1 == ok; 0 == fail; -1 == error
 
index 1e79b483ab53ec26ff26470e2ddbc0a960786c0b..f6a2de223f15f28ec483dfc19273216094900b88 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2016 - 2019 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.
@@ -81,7 +81,8 @@ RawBuffer _get_iv(const RawBuffer &src)
 RawBuffer _decrypt(const RawBuffer &key, const RawBuffer &iv, const RawBuffer &ciphertext)
 {
        auto algo = ::EVP_aes_128_cbc();
-       int tmp_len = (ciphertext.size() / algo->block_size + 1) * algo->block_size;
+       auto block_size = ::EVP_CIPHER_block_size(algo);
+       int tmp_len = (ciphertext.size() / block_size + 1) * block_size;
 
        if (key.size() != KEY_SIZE) {
                LogError("Invalid key size: " << key.size() << ", expected: " << KEY_SIZE);
index c881d32c8073284988036b33c40fe486f001f9ec..cad24d875fd87da46a47221fe69cdb819cd99801 100644 (file)
@@ -13193,8 +13193,8 @@ SQLCIPHER_PRIVATE void sqlcipher3CodecGetKey(sqlcipher3* db, int nDb, void **zKe
 typedef struct {
   int derive_key;
   EVP_CIPHER *evp_cipher;
-  EVP_CIPHER_CTX ectx;
-  HMAC_CTX hctx;
+  EVP_CIPHER_CTX *ectx;
+  HMAC_CTX *hctx;
   int kdf_iter;
   int fast_kdf_iter;
   int key_sz;
@@ -13598,18 +13598,43 @@ void sqlcipher_codec_ctx_free(codec_ctx **iCtx) {
   sqlcipher_free(ctx, sizeof(codec_ctx)); 
 }
 
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+static HMAC_CTX *HMAC_CTX_new(void)
+{
+  HMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx));
+  if (ctx != NULL) {
+    HMAC_CTX_init(ctx);
+  }
+  return ctx;
+}
+
+// Per 1.1.0 (https://wiki.openssl.org/index.php/1.1_API_Changes)
+// HMAC_CTX_free should call HMAC_CTX_cleanup, then EVP_MD_CTX_Cleanup.
+// HMAC_CTX_cleanup internally calls EVP_MD_CTX_cleanup so these
+// calls are not needed.
+static void HMAC_CTX_free(HMAC_CTX *ctx)
+{
+  if (ctx != NULL) {
+    HMAC_CTX_cleanup(ctx);
+    OPENSSL_free(ctx);
+  }
+}
+#endif
+
 int sqlcipher_page_hmac(cipher_ctx *ctx, Pgno pgno, unsigned char *in, int in_sz, unsigned char *out) {
-  HMAC_CTX_init(&ctx->hctx);
-  
-  HMAC_Init_ex(&ctx->hctx, ctx->hmac_key, ctx->key_sz, EVP_sha1(), NULL);
+  ctx->hctx = HMAC_CTX_new();
+  if(ctx->hctx == NULL) return SQLCIPHER_NOMEM;
+
+  HMAC_Init_ex(ctx->hctx, ctx->hmac_key, ctx->key_sz, EVP_sha1(), NULL);
 
   /* include the encrypted page data,  initialization vector, and page number in HMAC. This will 
      prevent both tampering with the ciphertext, manipulation of the IV, or resequencing otherwise
      valid pages out of order in a database */ 
-  HMAC_Update(&ctx->hctx, in, in_sz);
-  HMAC_Update(&ctx->hctx, (const unsigned char*) &pgno, sizeof(Pgno));
-  HMAC_Final(&ctx->hctx, out, NULL);
-  HMAC_CTX_cleanup(&ctx->hctx);
+  HMAC_Update(ctx->hctx, in, in_sz);
+  HMAC_Update(ctx->hctx, (const unsigned char*) &pgno, sizeof(Pgno));
+  HMAC_Final(ctx->hctx, out, NULL);
+  HMAC_CTX_free(ctx->hctx);
   return SQLCIPHER_OK; 
 }
 
@@ -13671,15 +13696,17 @@ int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mode, int
     }
   } 
 
-  EVP_CipherInit(&c_ctx->ectx, c_ctx->evp_cipher, NULL, NULL, mode);
-  EVP_CIPHER_CTX_set_padding(&c_ctx->ectx, 0);
-  EVP_CipherInit(&c_ctx->ectx, NULL, c_ctx->key, iv_out, mode);
-  EVP_CipherUpdate(&c_ctx->ectx, out, &tmp_csz, in, size);
+  c_ctx->ectx = EVP_CIPHER_CTX_new();
+  if(c_ctx->ectx == NULL) return SQLCIPHER_NOMEM;
+  EVP_CipherInit(c_ctx->ectx, c_ctx->evp_cipher, NULL, NULL, mode);
+  EVP_CIPHER_CTX_set_padding(c_ctx->ectx, 0);
+  EVP_CipherInit(c_ctx->ectx, NULL, c_ctx->key, iv_out, mode);
+  EVP_CipherUpdate(c_ctx->ectx, out, &tmp_csz, in, size);
   csz = tmp_csz;  
   out += tmp_csz;
-  EVP_CipherFinal(&c_ctx->ectx, out, &tmp_csz);
+  EVP_CipherFinal(c_ctx->ectx, out, &tmp_csz);
   csz += tmp_csz;
-  EVP_CIPHER_CTX_cleanup(&c_ctx->ectx);
+  EVP_CIPHER_CTX_free(c_ctx->ectx);
   assert(size == csz);
 
   if(c_ctx->use_hmac && (mode == CIPHER_ENCRYPT)) {