e8649c104c02852c5cd52c432aa47df54e214863
[platform/core/security/key-manager.git] / src / manager / common / openssl-error-handler.cpp
1 /*
2  *  Copyright (c) 2017 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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
15  *
16  *  @file   openssl-error-handler.cpp
17  *  @author Pawel Kowalski (p.kowalski2@partner.samsung.com)
18  */
19
20 #include <string.h>
21
22 #include <openssl/err.h>
23 #include <openssl/pem.h>
24 #include <openssl/pkcs12.h>
25 #include <openssl/dsa.h>
26
27 #include <ckm/ckm-error.h>
28 #include <dpl/log/log.h>
29
30 #include "openssl-error-handler.h"
31 #include <exception>
32
33 #include <sstream>
34 #include <string>
35 #include <utility>
36 #include <vector>
37
38 #define OPENSSL_SUCCESS 1
39
40 namespace CKM {
41
42 static const int GENERIC_REASON_MAX = 99;
43
44 #define ERRORDESCRIBE(name) case name: return #name
45 const char *ckm_debug_translate_error(int err)
46 {
47         switch (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";
55         }
56 }
57 #undef ERRORDESCRIBE
58
59 void errorDump()
60 {
61         typedef std::unique_ptr<BIO, std::function<void(BIO *)>> BioUniquePtr;
62         BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all);
63         if (!bio.get())
64                 return;
65
66         ERR_print_errors(bio.get());
67
68         std::vector<char> message(1024);
69         int len = BIO_read(bio.get(), message.data(), message.size());
70         if (len > 0) {
71                 message.resize(len);
72                 LogError(std::string(message.begin(), message.end()));
73         }
74 }
75
76 void errorHandle(const char *file, int line, const char *function, int openssl_ret)
77 {
78         if (openssl_ret >= OPENSSL_SUCCESS)
79                 return;
80
81         int ret = CKM_API_SUCCESS;
82
83         unsigned long err = ERR_peek_error();
84
85         if (err == 0)
86                 ret = CKM_API_ERROR_SERVER_ERROR;
87
88         /* known errors */
89         switch (err) {
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;
120                 break;
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;
128                 break;
129         }
130
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;
152                         break;
153                 }
154         }
155
156         /* fatal errors */
157         int reason = ERR_GET_REASON(err);
158         if (ret == CKM_API_SUCCESS && reason <= GENERIC_REASON_MAX && (err & ERR_R_FATAL) > 0) {
159                 switch (reason) {
160                 case ERR_R_MALLOC_FAILURE:
161                         ret = CKM_API_ERROR_OUT_OF_MEMORY;
162                         break;
163                 case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED:
164                 case ERR_R_PASSED_NULL_PARAMETER:
165                         ret = CKM_API_ERROR_INPUT_PARAM;
166                         break;
167                 case ERR_R_INTERNAL_ERROR:
168                 case ERR_R_DISABLED:
169                         ret = CKM_API_ERROR_SERVER_ERROR;
170                         break;
171                 }
172         }
173
174         /* neither known nor fatal, unknown */
175         if (ret == CKM_API_SUCCESS) {
176                 errorDump();
177         }
178
179         /* remove all errors from queue */
180         ERR_clear_error();
181
182         switch(ret) {
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, "");
193         default:
194                 throw CKM::Exc::InternalError(file, function, line, "Error not described");
195         }
196
197 }
198
199 } // namespace CKM