Add openssl error handling in key-manager 03/152203/27
authorPawel Kowalski <p.kowalski2@partner.samsung.com>
Mon, 25 Sep 2017 08:36:02 +0000 (10:36 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 7 Feb 2018 09:38:52 +0000 (09:38 +0000)
There was no distinction between different types of errors returned
by OpenSSL functions. Because of that the information returned to
a developer could be not complete and misleading.

In order to solve this problem, translator of OpenSSL errors to CKM
errors was written. Now, macro OPENSSL_ERROR_HANDLE may be used to
handle OpenSSL errors and provide full error information into log
system.

Change-Id: I63b54f76faaa5b36385bed167db03d97f034402f

12 files changed:
src/include/ckmc/ckmc-manager.h
src/manager/CMakeLists.txt
src/manager/common/exception.h
src/manager/common/openssl-error-handler.cpp [new file with mode: 0644]
src/manager/common/openssl-error-handler.h [new file with mode: 0644]
src/manager/crypto/generic-backend/exception.h
src/manager/crypto/sw-backend/crypto.h
src/manager/crypto/sw-backend/internals.cpp
src/manager/crypto/sw-backend/internals.h
src/manager/crypto/sw-backend/obj.cpp
src/manager/crypto/sw-backend/store.cpp
src/manager/service/crypto-logic.cpp

index 7cc2d9a..3924929 100644 (file)
@@ -814,7 +814,7 @@ int ckmc_remove_alias(const char *alias);
  *         otherwise a negative error value
  * @retval #CKMC_ERROR_NONE Successful
  * @retval #CKMC_ERROR_INVALID_PARAMETER Input parameter is invalid (missing or invalid
- *                                       mandatory algorithm parameter, decrypted = NULL,
+ *                                       mandatory algorithm parameter or RSA data too long, decrypted = NULL,
  *                                       ppencrypted = NULL)
  * @retval #CKMC_ERROR_DB_LOCKED A user key is not loaded in memory (a user is not logged in)
  * @retval #CKMC_ERROR_DB_ERROR Failed due to the error with unknown reason
@@ -851,8 +851,8 @@ int ckmc_encrypt_data(ckmc_param_list_h params, const char *key_alias, const cha
  *         otherwise a negative error value
  * @retval #CKMC_ERROR_NONE Successful
  * @retval #CKMC_ERROR_INVALID_PARAMETER Input parameter is invalid (missing or invalid
- *                                       mandatory algorithm parameter, encrypted = NULL,
- *                                       ppdecrypted = NULL)
+ *                                       mandatory algorithm parameter, GCM tag authentication failed, key or data is wrong,
+ *                                       in case of RSA key is wrong or data too long, encrypted = NULL, ppdecrypted = NULL)
  * @retval #CKMC_ERROR_DB_LOCKED A user key is not loaded in memory (a user is not logged in)
  * @retval #CKMC_ERROR_DB_ERROR Failed due to the error with unknown reason
  * @retval #CKMC_ERROR_DB_ALIAS_UNKNOWN Key with given alias does not exist
index d07b817..4247a74 100644 (file)
@@ -17,6 +17,7 @@ SET(COMMON_SOURCES
     ${COMMON_PATH}/common/base64.cpp
     ${COMMON_PATH}/common/crypto-init.cpp
     ${COMMON_PATH}/common/data-type.cpp
+    ${COMMON_PATH}/common/openssl-error-handler.cpp
     ${COMMON_PATH}/common/exception.cpp
     ${COMMON_PATH}/common/protocols.cpp
     ${COMMON_PATH}/common/message-buffer.cpp
index 2218830..10414b9 100644 (file)
@@ -124,6 +124,8 @@ using InputParam =
        DefineException<CKM_API_ERROR_INPUT_PARAM, true, PrintDebug>;
 using AuthenticationFailed =
        DefineException<CKM_API_ERROR_AUTHENTICATION_FAILED, true, PrintDebug>;
+using VerificationFailed =
+       DefineException<CKM_API_ERROR_VERIFICATION_FAILED, true, PrintDebug>;
 using InvalidFormat =
        DefineException<CKM_API_ERROR_INVALID_FORMAT, true, PrintDebug>;
 using BadResponse =
diff --git a/src/manager/common/openssl-error-handler.cpp b/src/manager/common/openssl-error-handler.cpp
new file mode 100644 (file)
index 0000000..cac3834
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ *  Copyright (c) 2017 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   openssl-error-handler.cpp
+ *  @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
+ */
+
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+#include <openssl/dsa.h>
+
+#include <ckm/ckm-error.h>
+#include <dpl/log/log.h>
+
+#include "openssl-error-handler.h"
+#include <exception>
+
+#include <sstream>
+#include <string>
+#include <utility>
+
+#define OPENSSL_SUCCESS 1
+
+namespace CKM {
+
+static const int GENERIC_REASON_MAX = 99;
+
+#define ERRORDESCRIBE(name) case name: return #name
+const char *ckm_debug_translate_error(int err)
+{
+       switch (err) {
+       ERRORDESCRIBE(CKM_API_SUCCESS);
+       ERRORDESCRIBE(CKM_API_ERROR_INPUT_PARAM);
+       ERRORDESCRIBE(CKM_API_ERROR_OUT_OF_MEMORY);
+       ERRORDESCRIBE(CKM_API_ERROR_SERVER_ERROR);
+       ERRORDESCRIBE(CKM_API_ERROR_AUTHENTICATION_FAILED);
+       ERRORDESCRIBE(CKM_API_ERROR_VERIFICATION_FAILED);
+       default: return "Error not defined";
+       }
+}
+#undef ERRORDESCRIBE
+
+void errorDump()
+{
+       BIO *bio = BIO_new(BIO_s_mem());
+       ERR_print_errors(bio);
+       char *buf = NULL;
+       size_t len = BIO_get_mem_data(bio, &buf);
+       BIO_free(bio);
+       std::string ret(buf, len);
+       free(buf);
+       LogError(ret);
+}
+
+void errorHandle(const char *file, int line, const char *function, int openssl_ret)
+{
+       if (openssl_ret >= OPENSSL_SUCCESS)
+               return;
+
+       int ret = CKM_API_SUCCESS;
+
+       unsigned long err = ERR_peek_error();
+
+       if (err == 0)
+               ret = CKM_API_ERROR_SERVER_ERROR;
+
+       /* known errors */
+       switch (err) {
+#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):
+#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):
+       case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
+       case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
+#endif /* OPENSSL_VERSION_NUMBER > 0x10100000L */
+       case ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL):
+       case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED):
+       case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET):
+       case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION):
+       case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO, PEM_R_NO_START_LINE):
+       case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA):
+       case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH):
+       case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH):
+       case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH):
+       case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS):
+       case ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE):
+       case ERR_PACK(ERR_LIB_DSA, DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE):
+       case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG):
+       case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG):
+       case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG):
+       case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT):
+       case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT):
+       case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, PEM_R_BAD_PASSWORD_READ):
+       case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ):
+       case ERR_PACK(ERR_LIB_PEM, PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ):
+               ret = CKM_API_ERROR_INPUT_PARAM;
+               break;
+       case ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY):
+       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):
+       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):
+               ret = CKM_API_ERROR_VERIFICATION_FAILED;
+               break;
+       }
+
+       /* known rsa padding errors */
+       if (ret == CKM_API_SUCCESS && ERR_GET_LIB(err) == ERR_LIB_RSA) {
+               switch (ERR_GET_FUNC(err)) {
+               case RSA_F_CHECK_PADDING_MD:
+               case RSA_F_RSA_PADDING_CHECK_NONE:
+               case RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP:
+               case RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1:
+               case RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1:
+               case RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2:
+               case RSA_F_RSA_PADDING_CHECK_SSLV23:
+               case RSA_F_RSA_PADDING_CHECK_X931:
+               case RSA_F_RSA_PADDING_ADD_NONE:
+               case RSA_F_RSA_PADDING_ADD_PKCS1_OAEP:
+               case RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1:
+               case RSA_F_RSA_PADDING_ADD_PKCS1_PSS:
+               case RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1:
+               case RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1:
+               case RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2:
+               case RSA_F_RSA_PADDING_ADD_SSLV23:
+               case RSA_F_RSA_PADDING_ADD_X931:
+                       ret = CKM_API_ERROR_INPUT_PARAM;
+                       break;
+               }
+       }
+
+       /* fatal errors */
+       int reason = ERR_GET_REASON(err);
+       if (ret == CKM_API_SUCCESS && reason <= GENERIC_REASON_MAX && (err & ERR_R_FATAL) > 0) {
+               switch (reason) {
+               case ERR_R_MALLOC_FAILURE:
+                       ret = CKM_API_ERROR_OUT_OF_MEMORY;
+                       break;
+               case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED:
+               case ERR_R_PASSED_NULL_PARAMETER:
+                       ret = CKM_API_ERROR_INPUT_PARAM;
+                       break;
+               case ERR_R_INTERNAL_ERROR:
+               case ERR_R_DISABLED:
+                       ret = CKM_API_ERROR_SERVER_ERROR;
+                       break;
+               }
+       }
+
+       /* neither known nor fatal, unknown */
+       if (ret == CKM_API_SUCCESS) {
+               errorDump();
+       }
+
+       /* remove all errors from queue */
+       ERR_clear_error();
+
+       switch(ret) {
+       case CKM_API_ERROR_INPUT_PARAM:
+               throw CKM::Exc::InputParam(file, function, line, "");
+       case CKM_API_ERROR_OUT_OF_MEMORY:
+               throw CKM::Exc::InternalError(file, function, line, "Out of memory");
+       case CKM_API_ERROR_SERVER_ERROR:
+               throw CKM::Exc::InternalError(file, function, line, "");
+       case CKM_API_ERROR_AUTHENTICATION_FAILED:
+               throw CKM::Exc::AuthenticationFailed(file, function, line, "");
+       case CKM_API_ERROR_VERIFICATION_FAILED:
+               throw CKM::Exc::VerificationFailed(file, function, line, "");
+       default:
+               throw CKM::Exc::InternalError(file, function, line, "Error not described");
+       }
+
+}
+
+} // namespace CKM
\ No newline at end of file
diff --git a/src/manager/common/openssl-error-handler.h b/src/manager/common/openssl-error-handler.h
new file mode 100644 (file)
index 0000000..407d2fa
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *  Copyright (c) 2017 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   openssl-error-handler.h
+ *  @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
+ */
+
+#pragma once
+
+#include <ckm/ckm-type.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <sw-backend/obj.h>
+
+#include <symbol-visibility.h>
+
+#include <sstream>
+#include <string>
+#include <utility>
+
+namespace CKM {
+
+COMMON_API void errorDump();
+#define OPENSSL_ERROR_DUMP() errorDump()
+#define OPENSSL_ERROR_CLEAR() ERR_clear_error()
+
+/**
+ * Function responsible for translating the OpenSSL error to CKM error and
+ * clearing/dumping the OpenSSL error queue.
+ *
+ * The function checks only first error in the queue.
+ * If the function doesn't find any error in OpenSSL queue or is not
+ * able to translate it, it will return CKM_API_ERROR_SERVER_ERROR and
+ * dump OpenSSL errors if any. The function clears the error queue and
+ * returns the result of translation.
+ */
+COMMON_API void errorHandle(const char *file, int line, const char *function, int openssl_ret);
+#define OPENSSL_ERROR_HANDLE(openssl_ret) { \
+       ERR_clear_error(); \
+       errorHandle(__FILE__, __LINE__, __func__, openssl_ret); \
+}
+
+} // namespace CKM
\ No newline at end of file
index cdd4415..f1155e1 100644 (file)
@@ -31,6 +31,7 @@ typedef CKM::Exc::InternalError InternalError;
 typedef CKM::Exc::InternalError DataTypeNotSupported;
 typedef CKM::Exc::InternalError OperationNotSupported;
 typedef CKM::Exc::InternalError WrongBackend;
+typedef CKM::Exc::AuthenticationFailed AuthenticationFailed;
 
 } // namespace Exc
 } // namespace Crypto
index 9925197..08ba272 100644 (file)
 #include <vector>
 
 #include <openssl/evp.h>
+#include <openssl/err.h>
 
 #include <dpl/log/log.h>
 #include <dpl/raw-buffer.h>
 
 #include <generic-backend/exception.h>
 
+#include <openssl-error-handler.h>
+
 namespace CKM {
 namespace Crypto {
 namespace SW {
@@ -48,9 +51,9 @@ struct Base {
 
        // Low level api.
        // Allows various cipher specific parameters to be determined and set.
-       int Control(int type, int arg, void *ptr)
+       void Control(int type, int arg, void *ptr)
        {
-               return EVP_CIPHER_CTX_ctrl(m_ctx, type, arg, ptr);
+               OPENSSL_ERROR_HANDLE(EVP_CIPHER_CTX_ctrl(m_ctx, type, arg, ptr));
        }
 
        virtual void AppendAAD(const T &) = 0;
@@ -75,15 +78,14 @@ public:
        {
                if (static_cast<int>(key.size()) != EVP_CIPHER_key_length(type))
                        ThrowErr(Exc::Crypto::InternalError, "Wrong key size! Expected: ",
-                                        EVP_CIPHER_key_length(type), " Get: ", key.size());
+                                       EVP_CIPHER_key_length(type), " Get: ", key.size());
 
                if (static_cast<int>(iv.size()) < EVP_CIPHER_iv_length(type))
                        ThrowErr(Exc::Crypto::InternalError, "Wrong iv size! Expected: ",
                                         EVP_CIPHER_iv_length(type), " Get: ", iv.size());
 
-               if (1 != EVP_CipherInit_ex(m_ctx, type, NULL, key.data(), iv.data(),
-                                                                  encryption ? 1 : 0))
-                       ThrowErr(Exc::Crypto::InternalError, "Failed in EVP_CipherInit");
+               OPENSSL_ERROR_HANDLE(EVP_CipherInit_ex(m_ctx, type, NULL, key.data(), iv.data(),
+                                              encryption ? 1 : 0));
 
                EVP_CIPHER_CTX_set_padding(m_ctx, 1);
        }
@@ -94,8 +96,7 @@ public:
                                          "Unsupported type inside container.");
                int bytesLen;
 
-               if (1 != EVP_CipherUpdate(m_ctx, NULL, &bytesLen, data.data(), data.size()))
-                       ThrowErr(Exc::Crypto::InternalError, "AppendAAD(): Failed in EVP_CipherUpdate");
+               OPENSSL_ERROR_HANDLE(EVP_CipherUpdate(m_ctx, NULL, &bytesLen, data.data(), data.size()));
        }
 
        T Append(const T &data)
@@ -105,9 +106,8 @@ public:
                int bytesLen = static_cast<int>(data.size() + EVP_CIPHER_CTX_block_size(m_ctx));
                T output(bytesLen);
 
-               if (1 != EVP_CipherUpdate(m_ctx, output.data(), &bytesLen, data.data(),
-                                                                 data.size()))
-                       ThrowErr(Exc::Crypto::InternalError, "Append(): Failed in EVP_CipherUpdate");
+               OPENSSL_ERROR_HANDLE(EVP_CipherUpdate(m_ctx, output.data(), &bytesLen, data.data(),
+                                             data.size()));
 
                output.resize(bytesLen);
                return output;
@@ -118,8 +118,7 @@ public:
                int bytesLen = EVP_CIPHER_CTX_block_size(m_ctx);
                T output(bytesLen);
 
-               if (1 != EVP_CipherFinal_ex(m_ctx, output.data(), &bytesLen))
-                       ThrowErr(Exc::Crypto::InternalError, "Failed in EVP_CipherFinal");
+               OPENSSL_ERROR_HANDLE(EVP_CipherFinal_ex(m_ctx, output.data(), &bytesLen));
 
                output.resize(bytesLen);
                return output;
index b519e11..afa3c88 100644 (file)
 #include <sw-backend/internals.h>
 #include <sw-backend/crypto.h>
 
-#define OPENSSL_SUCCESS 1       // DO NOTCHANGE THIS VALUE
-#define OPENSSL_FAIL    0       // DO NOTCHANGE THIS VALUE
+#include <openssl-error-handler.h>
+
+#define OPENSSL_SUCCESS 1       // DO NOT CHANGE THIS VALUE
+#define OPENSSL_FAIL    0       // DO NOT CHANGE THIS VALUE
 
 namespace CKM {
 namespace Crypto {
@@ -323,15 +325,17 @@ RawBuffer asymmetricHelper(int (*cryptoFn)(int, const unsigned char *,
         */
        RawBuffer output;
        output.resize(RSA_size(rsa));
-       int ret = cryptoFn(data.size(),
-                                          data.data(),
-                                          output.data(),
-                                          rsa,
-                                          RSA_PKCS1_OAEP_PADDING);
-       RSA_free(rsa);
-
-       if (ret < 0)
-               ThrowErr(Exc::Crypto::InternalError, logPrefix, "failed");
+       int ret;
+       try {
+               OPENSSL_ERROR_HANDLE(ret = cryptoFn(data.size(),
+                                    data.data(),
+                                    output.data(),
+                                    rsa,
+                                    RSA_PKCS1_OAEP_PADDING));
+       } catch (...) {
+               RSA_free(rsa);
+               throw;
+       }
 
        output.resize(ret);
        return output;
@@ -409,18 +413,13 @@ DataPair createKeyPairRSA(const int size)
                ThrowErr(Exc::Crypto::InternalError,
                                 "Error in EVP_PKEY_CTX_new_id function !!");
 
-       if (EVP_PKEY_keygen_init(ctx.get()) <= 0)
-               ThrowErr(Exc::Crypto::InternalError,
-                                "Error in EVP_PKEY_keygen_init function !!");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen_init(ctx.get()));
 
-       if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size) <= 0)
-               ThrowErr(Exc::Crypto::InternalError,
-                                "Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size));
 
        EVP_PKEY *pkeyTmp = NULL;
 
-       if (!EVP_PKEY_keygen(ctx.get(), &pkeyTmp))
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen(ctx.get(), &pkeyTmp));
 
        pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
 
@@ -445,19 +444,14 @@ DataPair createKeyPairDSA(const int size)
        if (!pctx)
                ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
 
-       if (EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get()))
-               ThrowErr(Exc::Crypto::InternalError,
-                                "Error in EVP_PKEY_paramgen_init function");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen_init(pctx.get()));
 
-       if (EVP_SUCCESS != EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size))
-               ThrowErr(Exc::Crypto::InternalError,
-                                "Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(", size, ") function");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size));
 
        /* Generate parameters */
        EVP_PKEY *pparamTmp = NULL;
 
-       if (EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp))
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen(pctx.get(), &pparamTmp));
 
        pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
 
@@ -467,14 +461,12 @@ DataPair createKeyPairDSA(const int size)
        if (!kctx)
                ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
 
-       if (EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get()))
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen_init(kctx.get()));
 
        /* Generate the key */
        EVP_PKEY *pkeyTmp = NULL;
 
-       if (!EVP_PKEY_keygen(kctx.get(), &pkeyTmp))
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen(kctx.get(), &pkeyTmp));
 
        pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
 
@@ -512,19 +504,14 @@ DataPair createKeyPairECDSA(ElipticCurve type)
        if (!pctx)
                ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function");
 
-       if (EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get()))
-               ThrowErr(Exc::Crypto::InternalError,
-                                "Error in EVP_PKEY_paramgen_init function");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen_init(pctx.get()));
 
-       if (EVP_SUCCESS != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve))
-               ThrowErr(Exc::Crypto::InternalError,
-                                "Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve));
 
        /* Generate parameters */
        EVP_PKEY *pparamTmp = NULL;
 
-       if (EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp))
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_paramgen(pctx.get(), &pparamTmp));
 
        pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free);
 
@@ -534,14 +521,12 @@ DataPair createKeyPairECDSA(ElipticCurve type)
        if (!kctx)
                ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
 
-       if (EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get()))
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen_init(kctx.get()));
 
        /* Generate the key */
        EVP_PKEY *pkeyTmp = NULL;
 
-       if (!EVP_PKEY_keygen(kctx.get(), &pkeyTmp))
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_keygen(kctx.get(), &pkeyTmp));
 
        pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free);
 
@@ -626,9 +611,7 @@ std::pair<RawBuffer, RawBuffer> encryptDataAesGcm(
        RawBuffer tmp = enc->Finalize();
        std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
 
-       if (0 == enc->Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data()))
-               ThrowErr(Exc::Crypto::InternalError,
-                                "Error in AES control function. Get tag failed.");
+       enc->Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data());
 
        return std::make_pair(result, tag);
 }
@@ -655,7 +638,12 @@ RawBuffer decryptDataAes(
        EvpCipherPtr dec;
        selectCipher(type, key.size(), false)(dec, key, iv);
        RawBuffer result = dec->Append(data);
-       RawBuffer tmp = dec->Finalize();
+       RawBuffer tmp;
+       try {
+               tmp = dec->Finalize();
+       } catch (const Exc::Exception &e) {
+               ThrowErr(Exc::InputParam, "Authentication failed in AES finalize function (wrong key/data was used).");
+       }
        std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
        return result;
 }
@@ -671,15 +659,18 @@ RawBuffer decryptDataAesGcm(
        selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, iv);
        void *ptr = (void *)tag.data();
 
-       if (0 == dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr))
-               ThrowErr(Exc::Crypto::InternalError,
-                                "Error in AES control function. Set tag failed.");
+       dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr);
 
        if (!aad.empty())
                dec->AppendAAD(aad);
 
        RawBuffer result = dec->Append(data);
-       RawBuffer tmp = dec->Finalize();
+       RawBuffer tmp;
+       try {
+               tmp = dec->Finalize();
+       } catch (const Exc::Exception &e) {
+               ThrowErr(Exc::InputParam, "Tag authentication failed in AES finalize function (the tag doesn't match).");
+       }
        std::copy(tmp.begin(), tmp.end(), std::back_inserter(result));
        return result;
 }
@@ -831,39 +822,27 @@ RawBuffer signMessage(EVP_PKEY *privKey,
        if (!pctx.get())
                ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
 
-       if (EVP_PKEY_sign_init(pctx.get()) != EVP_SUCCESS)
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign_init function");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_sign_init(pctx.get()));
 
        /* Set padding algorithm */
        if (EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA)
-               if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding))
-                       ThrowErr(Exc::Crypto::InputParam,
-                                        "Error in EVP_PKEY_CTX_set_rsa_padding function");
+               OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding));
 
        /* 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.get(), NULL, &slen, message.data(),
-                                                                        message.size()))
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign function");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_sign(pctx.get(), NULL, &slen, message.data(), message.size()));
 
        /* Allocate memory for the signature based on size in slen */
        RawBuffer sig(slen);
 
-       if (EVP_SUCCESS == EVP_PKEY_sign(pctx.get(),
-                                                                        sig.data(),
-                                                                        &slen,
-                                                                        message.data(),
-                                                                        message.size())) {
-               // Set value to return RawData
-               sig.resize(slen);
-               return sig;
-       }
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_sign(pctx.get(), sig.data(), &slen, message.data(), message.size()));
 
-       ThrowErr(Exc::Crypto::InputParam,
-                        "Error in EVP_PKEY_sign function. Input param error.");
+       // Set value to return RawData
+       sig.resize(slen);
+       return sig;
 }
 
 RawBuffer digestSignMessage(EVP_PKEY *privKey,
@@ -879,35 +858,27 @@ RawBuffer digestSignMessage(EVP_PKEY *privKey,
        if (!mdctx.get())
                ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
 
-       if (EVP_SUCCESS != EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL,
-                                                                                 privKey))
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignInit function");
+       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_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding))
-                       ThrowErr(Exc::Crypto::InputParam,
-                                        "Error in EVP_PKEY_CTX_set_rsa_padding function");
+               OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding));
 
        /* Call update with the message */
-       if (EVP_SUCCESS != EVP_DigestSignUpdate(mdctx.get(), message.data(),
-                                                                                       message.size()))
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignUpdate function");
+       OPENSSL_ERROR_HANDLE(EVP_DigestSignUpdate(mdctx.get(), message.data(), message.size()));
 
        /* 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.get(), NULL, &slen))
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function");
+       OPENSSL_ERROR_HANDLE(EVP_DigestSignFinal(mdctx.get(), NULL, &slen));
 
        /* Allocate memory for the signature based on size in slen */
        RawBuffer sig(slen);
 
        /* Obtain the signature */
-       if (EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen))
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function");
+       OPENSSL_ERROR_HANDLE(EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen));
 
        // Set value to return RawData
        sig.resize(slen);
@@ -965,16 +936,13 @@ int verifyMessage(EVP_PKEY *pubKey,
        if (!pctx.get())
                ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function");
 
-       if (EVP_PKEY_verify_init(pctx.get()) != EVP_SUCCESS)
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_verify_init function");
+       OPENSSL_ERROR_HANDLE(EVP_PKEY_verify_init(pctx.get()));
 
-       /* Set padding algorithm  */
+       /* Set padding algorithm */
        if (EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA)
-               if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding))
-                       ThrowErr(Exc::Crypto::InputParam,
-                                        "Error in EVP_PKEY_CTX_set_rsa_padding function");
+               OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding));
 
-       if (EVP_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(),
+       if (OPENSSL_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(),
                                                                           signature.size(), message.data(), message.size()))
                return CKM_API_SUCCESS;
 
@@ -991,25 +959,17 @@ int digestVerifyMessage(EVP_PKEY *pubKey,
        EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
        EVP_PKEY_CTX *pctx = NULL;
 
-       /* Create the Message Digest Context */
        if (!mdctx.get())
                ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function");
 
-       if (EVP_SUCCESS != EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL,
-                                                                                       pubKey))
-               ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyInit function");
+       OPENSSL_ERROR_HANDLE(EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, pubKey));
 
        if (EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA)
-               if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding))
-                       ThrowErr(Exc::Crypto::InputParam,
-                                        "Error in EVP_PKEY_CTX_set_rsa_padding function");
+               OPENSSL_ERROR_HANDLE(EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding));
 
-       if (EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx.get(), message.data(),
-                       message.size()))
-               ThrowErr(Exc::Crypto::InternalError,
-                                "Error in EVP_DigestVerifyUpdate function");
+       OPENSSL_ERROR_HANDLE(EVP_DigestVerifyUpdate(mdctx.get(), message.data(), message.size()));
 
-       if (EVP_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(),
+       if (OPENSSL_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(),
                        const_cast<unsigned char *>(signature.data()), signature.size()))
                return CKM_API_SUCCESS;
 
@@ -1088,5 +1048,4 @@ bool verifyBinaryData(DataType dataType, const RawBuffer &buffer)
 } // namespace Internals
 } // namespace SW
 } // namespace Crypto
-} // namespace CKM
-
+} // namespace CKM
\ No newline at end of file
index 56a1e00..0c984c6 100644 (file)
@@ -24,9 +24,6 @@
 #include <openssl/evp.h>
 #include <sw-backend/obj.h>
 
-#define EVP_SUCCESS 1    // DO NOTCHANGE THIS VALUE
-#define EVP_FAIL    0    // DO NOTCHANGE THIS VALUE
-
 #define CKM_CRYPTO_INIT_SUCCESS 1
 #define CKM_CRYPTO_CREATEKEY_SUCCESS 2
 #define CKM_VERIFY_CHAIN_SUCCESS 5
@@ -131,5 +128,4 @@ bool verifyBinaryData(DataType dataType, const RawBuffer &buffer);
 } // namespace Internals
 } // namespace SW
 } // namespace Crypto
-} // namespace CKM
-
+} // namespace CKM
\ No newline at end of file
index 8b5e21a..a7a7cdc 100644 (file)
@@ -30,9 +30,6 @@
 #include <sw-backend/obj.h>
 #include <sw-backend/internals.h>
 
-#define EVP_SUCCESS 1    // DO NOTCHANGE THIS VALUE
-#define EVP_FAIL    0    // DO NOTCHANGE THIS VALUE
-
 namespace CKM {
 namespace Crypto {
 namespace SW {
index d9a7353..63cd046 100644 (file)
@@ -112,8 +112,10 @@ RawBuffer unpack(const RawBuffer &packed, const Password &pass)
 
        try {
                ret = Crypto::SW::Internals::decryptDataAesGcm(key, encrypted, iv, tag);
-       } catch (const Exc::Crypto::InternalError &e) {
-               ThrowErr(Exc::AuthenticationFailed, "Decryption with custom password failed");
+       } catch (const Exc::Crypto::InputParam &e) {
+               ThrowErr(Exc::AuthenticationFailed, "Decryption with custom password failed, authentication failed");
+       } catch (const Exc::Exception &e) {
+               ThrowErr(Exc::InternalError, "Decryption with custom password failed, internal error");
        }
 
        return ret;
@@ -133,8 +135,8 @@ RawBuffer pack(const RawBuffer &data, const Password &pass)
                try {
                        ret = Crypto::SW::Internals::encryptDataAesGcm(key, data, iv,
                                        Params::DEFAULT_AES_GCM_TAG_LEN_BYTES);
-               } catch (const Exc::Crypto::InternalError &e) {
-                       ThrowErr(Exc::AuthenticationFailed, "Encryption with custom password failed");
+               } catch (const Exc::Exception &e) {
+                       ThrowErr(Exc::InternalError, "Encryption with custom password failed, internal error");
                }
 
                scheme |= EncryptionScheme::PASSWORD;
index 536783c..3cbfedb 100644 (file)
@@ -127,8 +127,6 @@ void CryptoLogic::encryptRow(DB::Row &row)
 {
        DB::Row crow = row;
        RawBuffer key;
-       RawBuffer result1;
-       RawBuffer result2;
 
        crow.algorithmType = DBCMAlgType::AES_GCM_256;
        crow.dataSize = crow.data.size();
@@ -147,8 +145,13 @@ void CryptoLogic::encryptRow(DB::Row &row)
        CLEAR_FLAGS(crow.encryptionScheme);
        SET_FLAG(ENCR_APPKEY, crow.encryptionScheme);
 
-       auto dataPair = Crypto::SW::Internals::encryptDataAesGcm(key, crow.data,
+       std::pair<RawBuffer, RawBuffer> dataPair;
+       try {
+               dataPair = Crypto::SW::Internals::encryptDataAesGcm(key, crow.data,
                                        crow.iv, AES_GCM_TAG_SIZE);
+       } catch (const Exc::Exception &e) {
+               ThrowErr(Exc::InternalError, "Encryption failed in encryptRow");
+       }
        crow.data = dataPair.first;
 
        crow.tag = dataPair.second;
@@ -171,7 +174,6 @@ void CryptoLogic::decryptRow(const Password &password, DB::Row &row)
 {
        DB::Row crow = row;
        RawBuffer key;
-       RawBuffer digest, dataDigest;
 
        if (row.algorithmType != DBCMAlgType::AES_GCM_256)
                ThrowErr(Exc::AuthenticationFailed, "Invalid algorithm type.");
@@ -215,8 +217,10 @@ void CryptoLogic::decryptRow(const Password &password, DB::Row &row)
                                                        crow.tag);
                        }
                }
-       } catch (const Exc::Exception &e) {
+       } catch (const Exc::Crypto::InputParam &e) {
                ThrowErr(Exc::AuthenticationFailed, e.message());
+       } catch (const Exc::Exception &e) {
+               ThrowErr(Exc::InternalError, "Internal error during decryption");
        }
 
        if (static_cast<int>(crow.data.size()) < crow.dataSize)