2 * Copyright (c) 2017 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
16 * @file openssl-error-handler.cpp
17 * @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
22 #include <openssl/err.h>
23 #include <openssl/pem.h>
24 #include <openssl/pkcs12.h>
25 #include <openssl/dsa.h>
27 #include <ckm/ckm-error.h>
28 #include <dpl/log/log.h>
30 #include "openssl-error-handler.h"
38 #define OPENSSL_SUCCESS 1
42 static const int GENERIC_REASON_MAX = 99;
44 #define ERRORDESCRIBE(name) case name: return #name
45 const char *ckm_debug_translate_error(int err)
48 ERRORDESCRIBE(CKM_API_SUCCESS);
49 ERRORDESCRIBE(CKM_API_ERROR_INPUT_PARAM);
50 ERRORDESCRIBE(CKM_API_ERROR_OUT_OF_MEMORY);
51 ERRORDESCRIBE(CKM_API_ERROR_SERVER_ERROR);
52 ERRORDESCRIBE(CKM_API_ERROR_AUTHENTICATION_FAILED);
53 ERRORDESCRIBE(CKM_API_ERROR_VERIFICATION_FAILED);
54 default: return "Error not defined";
61 typedef std::unique_ptr<BIO, std::function<void(BIO *)>> BioUniquePtr;
62 BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all);
66 ERR_print_errors(bio.get());
68 std::vector<char> message(1024);
69 int len = BIO_read(bio.get(), message.data(), message.size());
72 LogError(std::string(message.begin(), message.end()));
76 void errorHandle(const char *file, int line, const char *function, int openssl_ret)
78 if (openssl_ret >= OPENSSL_SUCCESS)
81 int ret = CKM_API_SUCCESS;
83 unsigned long err = ERR_peek_error();
86 ret = CKM_API_ERROR_SERVER_ERROR;
90 #if OPENSSL_VERSION_NUMBER > 0x10100000L
91 case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
92 case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
93 #else /* OPENSSL_VERSION_NUMBER > 0x10100000L */
94 case ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS):
95 case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS):
96 case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
97 case ERR_PACK(ERR_LIB_RSA, RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN):
98 #endif /* OPENSSL_VERSION_NUMBER > 0x10100000L */
99 case ERR_PACK(ERR_LIB_RSA, RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL):
100 case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED):
101 case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET):
102 case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION):
103 case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO, PEM_R_NO_START_LINE):
104 case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA):
105 case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_ENCRYPTFINAL_EX, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH):
106 case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH):
107 case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH):
108 case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS):
109 case ERR_PACK(ERR_LIB_EC, EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE):
110 case ERR_PACK(ERR_LIB_DSA, DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE):
111 case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG):
112 case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG):
113 case ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG):
114 case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT):
115 case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT):
116 case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, PEM_R_BAD_PASSWORD_READ):
117 case ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ):
118 case ERR_PACK(ERR_LIB_PEM, PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ):
119 ret = CKM_API_ERROR_INPUT_PARAM;
121 case ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY):
122 case ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED):
123 case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE):
124 case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED):
125 case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE):
126 case ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_VERIFYFINAL, EVP_R_NO_VERIFY_FUNCTION_CONFIGURED):
127 ret = CKM_API_ERROR_VERIFICATION_FAILED;
131 /* known rsa padding errors */
132 if (ret == CKM_API_SUCCESS && ERR_GET_LIB(err) == ERR_LIB_RSA) {
133 switch (ERR_GET_FUNC(err)) {
134 case RSA_F_CHECK_PADDING_MD:
135 case RSA_F_RSA_PADDING_CHECK_NONE:
136 case RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP:
137 case RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1:
138 case RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1:
139 case RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2:
140 case RSA_F_RSA_PADDING_CHECK_SSLV23:
141 case RSA_F_RSA_PADDING_CHECK_X931:
142 case RSA_F_RSA_PADDING_ADD_NONE:
143 case RSA_F_RSA_PADDING_ADD_PKCS1_OAEP:
144 case RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1:
145 case RSA_F_RSA_PADDING_ADD_PKCS1_PSS:
146 case RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1:
147 case RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1:
148 case RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2:
149 case RSA_F_RSA_PADDING_ADD_SSLV23:
150 case RSA_F_RSA_PADDING_ADD_X931:
151 ret = CKM_API_ERROR_INPUT_PARAM;
157 int reason = ERR_GET_REASON(err);
158 if (ret == CKM_API_SUCCESS && reason <= GENERIC_REASON_MAX && (err & ERR_R_FATAL) > 0) {
160 case ERR_R_MALLOC_FAILURE:
161 ret = CKM_API_ERROR_OUT_OF_MEMORY;
163 case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED:
164 case ERR_R_PASSED_NULL_PARAMETER:
165 ret = CKM_API_ERROR_INPUT_PARAM;
167 case ERR_R_INTERNAL_ERROR:
169 ret = CKM_API_ERROR_SERVER_ERROR;
174 /* neither known nor fatal, unknown */
175 if (ret == CKM_API_SUCCESS) {
179 /* remove all errors from queue */
183 case CKM_API_ERROR_INPUT_PARAM:
184 throw CKM::Exc::InputParam(file, function, line, "");
185 case CKM_API_ERROR_OUT_OF_MEMORY:
186 throw CKM::Exc::InternalError(file, function, line, "Out of memory");
187 case CKM_API_ERROR_SERVER_ERROR:
188 throw CKM::Exc::InternalError(file, function, line, "");
189 case CKM_API_ERROR_AUTHENTICATION_FAILED:
190 throw CKM::Exc::AuthenticationFailed(file, function, line, "");
191 case CKM_API_ERROR_VERIFICATION_FAILED:
192 throw CKM::Exc::VerificationFailed(file, function, line, "");
194 throw CKM::Exc::InternalError(file, function, line, "Error not described");