585df582019529dc8c601d272d13bc6604da3ec9
[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                 ret = CKM_API_ERROR_INPUT_PARAM;
145                 break;
146         case ERR_PACK(ERR_LIB_X509, 0, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY):
147         case ERR_PACK(ERR_LIB_X509, 0, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED):
148         case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE):
149         case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATON_NOT_INITIALIZED):
150                 ret = CKM_API_ERROR_VERIFICATION_FAILED;
151                 break;
152         }
153
154         /* fatal errors */
155         int reason = ERR_GET_REASON(err);
156         if (ret == CKM_API_SUCCESS && reason <= GENERIC_REASON_MAX && (err & ERR_R_FATAL) > 0) {
157                 switch (reason) {
158                 case ERR_R_MALLOC_FAILURE:
159                         ret = CKM_API_ERROR_OUT_OF_MEMORY;
160                         break;
161                 case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED:
162                 case ERR_R_PASSED_NULL_PARAMETER:
163                         ret = CKM_API_ERROR_INPUT_PARAM;
164                         break;
165                 case ERR_R_INTERNAL_ERROR:
166                 case ERR_R_DISABLED:
167                         ret = CKM_API_ERROR_SERVER_ERROR;
168                         break;
169                 }
170         }
171
172         /* neither known nor fatal, unknown */
173         if (ret == CKM_API_SUCCESS) {
174                 errorDump();
175         }
176
177         /* remove all errors from queue */
178         ERR_clear_error();
179
180         switch(ret) {
181         case CKM_API_ERROR_INPUT_PARAM:
182                 throw CKM::Exc::InputParam(file, function, line, "");
183         case CKM_API_ERROR_OUT_OF_MEMORY:
184                 throw CKM::Exc::InternalError(file, function, line, "Out of memory");
185         case CKM_API_ERROR_SERVER_ERROR:
186                 throw CKM::Exc::InternalError(file, function, line, "");
187         case CKM_API_ERROR_AUTHENTICATION_FAILED:
188                 throw CKM::Exc::AuthenticationFailed(file, function, line, "");
189         case CKM_API_ERROR_VERIFICATION_FAILED:
190                 throw CKM::Exc::VerificationFailed(file, function, line, "");
191         default:
192                 throw CKM::Exc::InternalError(file, function, line, "Error not described");
193         }
194
195 }
196
197 } // namespace CKM