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 6567c97..3b03f12 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 573a4d6..7fa6671 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 2a12818..63c4be5 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 e8649c1..a43e094 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 c53a377..100e9b5 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 a5f2f9e..a0f0239 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 a7a7cdc..f5bb466 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 871b8a9..195316b 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 1e79b48..f6a2de2 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 c881d32..cad24d8 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)) {