Adjust openssl error handling to latest release
[platform/core/security/key-manager.git] / src / manager / common / openssl-error-handler.cpp
1 /*
2  *  Copyright (c) 2017-2020 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 #include <utils.h>
30
31 #include "openssl-error-handler.h"
32 #include <exception>
33
34 #include <functional>
35 #include <sstream>
36 #include <string>
37 #include <utility>
38 #include <vector>
39
40 #define OPENSSL_SUCCESS 1
41
42 namespace CKM {
43
44 static const int GENERIC_REASON_MAX = 99;
45
46 #define ERRORDESCRIBE(name) case name: return #name
47 const char *ckm_debug_translate_error(int err)
48 {
49         switch (err) {
50         ERRORDESCRIBE(CKM_API_SUCCESS);
51         ERRORDESCRIBE(CKM_API_ERROR_INPUT_PARAM);
52         ERRORDESCRIBE(CKM_API_ERROR_OUT_OF_MEMORY);
53         ERRORDESCRIBE(CKM_API_ERROR_SERVER_ERROR);
54         ERRORDESCRIBE(CKM_API_ERROR_AUTHENTICATION_FAILED);
55         ERRORDESCRIBE(CKM_API_ERROR_VERIFICATION_FAILED);
56         default: return "Error not defined";
57         }
58 }
59 #undef ERRORDESCRIBE
60
61 void errorDump()
62 {
63         auto bio = uptr<BIO_free_all>(BIO_new(BIO_s_mem()));
64         if (!bio.get())
65                 return;
66
67         ERR_print_errors(bio.get());
68
69         std::vector<char> message(1024);
70         int len = BIO_read(bio.get(), message.data(), message.size());
71         if (len > 0) {
72                 message.resize(len);
73                 LogError(std::string(message.begin(), message.end()));
74         }
75 }
76
77 void errorHandle(const char *file, int line, const char *function, int openssl_ret)
78 {
79         if (openssl_ret >= OPENSSL_SUCCESS)
80                 return;
81
82         int ret = CKM_API_SUCCESS;
83
84         unsigned long err = ERR_peek_error();
85
86         if (err == 0)
87                 ret = CKM_API_ERROR_SERVER_ERROR;
88
89         /* known errors */
90         switch (err) {
91         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_GREATER_THAN_MOD_LEN):
92         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_LARGE_FOR_MODULUS):
93         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_KEY_SIZE_TOO_SMALL):
94         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MISSING_PRIVATE_KEY):
95         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PADDING_MODE):
96         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_X931_DIGEST):
97         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_LARGE):
98         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE):
99         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE):
100         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OAEP_DECODING_ERROR):
101         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_LENGTH):
102         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PADDING):
103         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BLOCK_TYPE_IS_NOT_01):
104         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_FIXED_HEADER_DECRYPT):
105         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NULL_BEFORE_BLOCK_MISSING):
106         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_PAD_BYTE_COUNT):
107         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PKCS_DECODING_ERROR):
108         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_SLEN_CHECK_FAILED):
109         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_FIRST_OCTET_INVALID):
110         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_LAST_OCTET_INVALID):
111         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_SLEN_RECOVERY_FAILED):
112         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_HEADER):
113         case ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_TRAILER):
114         case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_COMMAND_NOT_SUPPORTED):
115         case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_OPERATION_SET):
116         case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION):
117         case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH):
118         case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRONG_FINAL_BLOCK_LENGTH):
119         case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_PARAMETERS):
120         case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_DECRYPT):
121         case ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_DIGEST_TYPE):
122         case ERR_PACK(ERR_LIB_EC, 0, EC_R_MISSING_PRIVATE_KEY):
123         case ERR_PACK(ERR_LIB_DSA, 0, DSA_R_INVALID_DIGEST_TYPE):
124         case ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MISSING_PRIVATE_KEY):
125         case ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TOO_LONG):
126         case ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_HEADER_TOO_LONG):
127         case ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_WRONG_TAG):
128         case ERR_PACK(ERR_LIB_ASN1, 0, ERR_R_NESTED_ASN1_ERROR):
129         case ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NOT_ENOUGH_DATA):
130         case ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_DECRYPT):
131         case ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_PASSWORD_READ):
132         case ERR_PACK(ERR_LIB_PEM, 0, PEM_R_NO_START_LINE):
133         case ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_X931_DIGEST):
134         case ERR_PACK(ERR_LIB_PROV, 0, ERR_R_NESTED_ASN1_ERROR):
135         case ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_PADDING_MODE):
136         case ERR_PACK(ERR_LIB_PROV, 0, PROV_R_DIGEST_NOT_ALLOWED):
137         case ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DIGEST):
138         case ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DIGEST_LENGTH):
139         case ERR_PACK(ERR_LIB_PROV, 0, PROV_R_KEY_SIZE_TOO_SMALL):
140         case ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SIGNATURE_SIZE):
141         case ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ALGORITHM_MISMATCH):
142         case ERR_PACK(ERR_LIB_PROV, 0, PROV_R_OUTPUT_BUFFER_TOO_SMALL):
143         case ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_DECRYPT):
144         case ERR_PACK(ERR_LIB_OSSL_DECODER, 0, ERR_R_UNSUPPORTED):
145                 ret = CKM_API_ERROR_INPUT_PARAM;
146                 break;
147         case ERR_PACK(ERR_LIB_X509, 0, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY):
148         case ERR_PACK(ERR_LIB_X509, 0, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED):
149         case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE):
150         case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATON_NOT_INITIALIZED):
151                 ret = CKM_API_ERROR_VERIFICATION_FAILED;
152                 break;
153         }
154
155         /* fatal errors */
156         int reason = ERR_GET_REASON(err);
157         if (ret == CKM_API_SUCCESS && reason <= GENERIC_REASON_MAX && (err & ERR_R_FATAL) > 0) {
158                 switch (reason) {
159                 case ERR_R_MALLOC_FAILURE:
160                         ret = CKM_API_ERROR_OUT_OF_MEMORY;
161                         break;
162                 case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED:
163                 case ERR_R_PASSED_NULL_PARAMETER:
164                         ret = CKM_API_ERROR_INPUT_PARAM;
165                         break;
166                 case ERR_R_INTERNAL_ERROR:
167                 case ERR_R_DISABLED:
168                         ret = CKM_API_ERROR_SERVER_ERROR;
169                         break;
170                 }
171         }
172
173         /* neither known nor fatal, unknown */
174         if (ret == CKM_API_SUCCESS) {
175                 errorDump();
176         }
177
178         /* remove all errors from queue */
179         ERR_clear_error();
180
181         switch(ret) {
182         case CKM_API_ERROR_INPUT_PARAM:
183                 throw CKM::Exc::InputParam(file, function, line, "");
184         case CKM_API_ERROR_OUT_OF_MEMORY:
185                 throw CKM::Exc::InternalError(file, function, line, "Out of memory");
186         case CKM_API_ERROR_SERVER_ERROR:
187                 throw CKM::Exc::InternalError(file, function, line, "");
188         case CKM_API_ERROR_AUTHENTICATION_FAILED:
189                 throw CKM::Exc::AuthenticationFailed(file, function, line, "");
190         case CKM_API_ERROR_VERIFICATION_FAILED:
191                 throw CKM::Exc::VerificationFailed(file, function, line, "");
192         default:
193                 throw CKM::Exc::InternalError(file, function, line, "Error not described");
194         }
195
196 }
197
198 } // namespace CKM