1 /*
2 * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <stdint.h>
29 #include <errno.h>
30
31 #include "brssl.h"
32 #include "bearssl.h"
33
34 static struct {
35 int err;
36 const char *name;
37 const char *comment;
38 } errors[] = {
39 {
40 BR_ERR_BAD_PARAM,
41 "BR_ERR_BAD_PARAM",
42 "Caller-provided parameter is incorrect."
43 }, {
44 BR_ERR_BAD_STATE,
45 "BR_ERR_BAD_STATE",
46 "Operation requested by the caller cannot be applied with"
47 " the current context state (e.g. reading data while"
48 " outgoing data is waiting to be sent)."
49 }, {
50 BR_ERR_UNSUPPORTED_VERSION,
51 "BR_ERR_UNSUPPORTED_VERSION",
52 "Incoming protocol or record version is unsupported."
53 }, {
54 BR_ERR_BAD_VERSION,
55 "BR_ERR_BAD_VERSION",
56 "Incoming record version does not match the expected version."
57 }, {
58 BR_ERR_BAD_LENGTH,
59 "BR_ERR_BAD_LENGTH",
60 "Incoming record length is invalid."
61 }, {
62 BR_ERR_TOO_LARGE,
63 "BR_ERR_TOO_LARGE",
64 "Incoming record is too large to be processed, or buffer"
65 " is too small for the handshake message to send."
66 }, {
67 BR_ERR_BAD_MAC,
68 "BR_ERR_BAD_MAC",
69 "Decryption found an invalid padding, or the record MAC is"
70 " not correct."
71 }, {
72 BR_ERR_NO_RANDOM,
73 "BR_ERR_NO_RANDOM",
74 "No initial entropy was provided, and none can be obtained"
75 " from the OS."
76 }, {
77 BR_ERR_UNKNOWN_TYPE,
78 "BR_ERR_UNKNOWN_TYPE",
79 "Incoming record type is unknown."
80 }, {
81 BR_ERR_UNEXPECTED,
82 "BR_ERR_UNEXPECTED",
83 "Incoming record or message has wrong type with regards to"
84 " the current engine state."
85 }, {
86 BR_ERR_BAD_CCS,
87 "BR_ERR_BAD_CCS",
88 "ChangeCipherSpec message from the peer has invalid contents."
89 }, {
90 BR_ERR_BAD_ALERT,
91 "BR_ERR_BAD_ALERT",
92 "Alert message from the peer has invalid contents"
93 " (odd length)."
94 }, {
95 BR_ERR_BAD_HANDSHAKE,
96 "BR_ERR_BAD_HANDSHAKE",
97 "Incoming handshake message decoding failed."
98 }, {
99 BR_ERR_OVERSIZED_ID,
100 "BR_ERR_OVERSIZED_ID",
101 "ServerHello contains a session ID which is larger than"
102 " 32 bytes."
103 }, {
104 BR_ERR_BAD_CIPHER_SUITE,
105 "BR_ERR_BAD_CIPHER_SUITE",
106 "Server wants to use a cipher suite that we did not claim"
107 " to support. This is also reported if we tried to advertise"
108 " a cipher suite that we do not support."
109 }, {
110 BR_ERR_BAD_COMPRESSION,
111 "BR_ERR_BAD_COMPRESSION",
112 "Server wants to use a compression that we did not claim"
113 " to support."
114 }, {
115 BR_ERR_BAD_FRAGLEN,
116 "BR_ERR_BAD_FRAGLEN",
117 "Server's max fragment length does not match client's."
118 }, {
119 BR_ERR_BAD_SECRENEG,
120 "BR_ERR_BAD_SECRENEG",
121 "Secure renegotiation failed."
122 }, {
123 BR_ERR_EXTRA_EXTENSION,
124 "BR_ERR_EXTRA_EXTENSION",
125 "Server sent an extension type that we did not announce,"
126 " or used the same extension type several times in a"
127 " single ServerHello."
128 }, {
129 BR_ERR_BAD_SNI,
130 "BR_ERR_BAD_SNI",
131 "Invalid Server Name Indication contents (when used by"
132 " the server, this extension shall be empty)."
133 }, {
134 BR_ERR_BAD_HELLO_DONE,
135 "BR_ERR_BAD_HELLO_DONE",
136 "Invalid ServerHelloDone from the server (length is not 0)."
137 }, {
138 BR_ERR_LIMIT_EXCEEDED,
139 "BR_ERR_LIMIT_EXCEEDED",
140 "Internal limit exceeded (e.g. server's public key is too"
141 " large)."
142 }, {
143 BR_ERR_BAD_FINISHED,
144 "BR_ERR_BAD_FINISHED",
145 "Finished message from peer does not match the expected"
146 " value."
147 }, {
148 BR_ERR_RESUME_MISMATCH,
149 "BR_ERR_RESUME_MISMATCH",
150 "Session resumption attempt with distinct version or cipher"
151 " suite."
152 }, {
153 BR_ERR_INVALID_ALGORITHM,
154 "BR_ERR_INVALID_ALGORITHM",
155 "Unsupported or invalid algorithm (ECDHE curve, signature"
156 " algorithm, hash function)."
157 }, {
158 BR_ERR_BAD_SIGNATURE,
159 "BR_ERR_BAD_SIGNATURE",
160 "Invalid signature in ServerKeyExchange or"
161 " CertificateVerify message."
162 }, {
163 BR_ERR_WRONG_KEY_USAGE,
164 "BR_ERR_WRONG_KEY_USAGE",
165 "Peer's public key does not have the proper type or is"
166 " not allowed for the requested operation."
167 }, {
168 BR_ERR_NO_CLIENT_AUTH,
169 "BR_ERR_NO_CLIENT_AUTH",
170 "Client did not send a certificate upon request, or the"
171 " client certificate could not be validated."
172 }, {
173 BR_ERR_IO,
174 "BR_ERR_IO",
175 "I/O error or premature close on transport stream."
176 }, {
177 BR_ERR_X509_INVALID_VALUE,
178 "BR_ERR_X509_INVALID_VALUE",
179 "Invalid value in an ASN.1 structure."
180 },
181 {
182 BR_ERR_X509_TRUNCATED,
183 "BR_ERR_X509_TRUNCATED",
184 "Truncated certificate or other ASN.1 object."
185 },
186 {
187 BR_ERR_X509_EMPTY_CHAIN,
188 "BR_ERR_X509_EMPTY_CHAIN",
189 "Empty certificate chain (no certificate at all)."
190 },
191 {
192 BR_ERR_X509_INNER_TRUNC,
193 "BR_ERR_X509_INNER_TRUNC",
194 "Decoding error: inner element extends beyond outer element"
195 " size."
196 },
197 {
198 BR_ERR_X509_BAD_TAG_CLASS,
199 "BR_ERR_X509_BAD_TAG_CLASS",
200 "Decoding error: unsupported tag class (application or"
201 " private)."
202 },
203 {
204 BR_ERR_X509_BAD_TAG_VALUE,
205 "BR_ERR_X509_BAD_TAG_VALUE",
206 "Decoding error: unsupported tag value."
207 },
208 {
209 BR_ERR_X509_INDEFINITE_LENGTH,
210 "BR_ERR_X509_INDEFINITE_LENGTH",
211 "Decoding error: indefinite length."
212 },
213 {
214 BR_ERR_X509_EXTRA_ELEMENT,
215 "BR_ERR_X509_EXTRA_ELEMENT",
216 "Decoding error: extraneous element."
217 },
218 {
219 BR_ERR_X509_UNEXPECTED,
220 "BR_ERR_X509_UNEXPECTED",
221 "Decoding error: unexpected element."
222 },
223 {
224 BR_ERR_X509_NOT_CONSTRUCTED,
225 "BR_ERR_X509_NOT_CONSTRUCTED",
226 "Decoding error: expected constructed element, but is"
227 " primitive."
228 },
229 {
230 BR_ERR_X509_NOT_PRIMITIVE,
231 "BR_ERR_X509_NOT_PRIMITIVE",
232 "Decoding error: expected primitive element, but is"
233 " constructed."
234 },
235 {
236 BR_ERR_X509_PARTIAL_BYTE,
237 "BR_ERR_X509_PARTIAL_BYTE",
238 "Decoding error: BIT STRING length is not multiple of 8."
239 },
240 {
241 BR_ERR_X509_BAD_BOOLEAN,
242 "BR_ERR_X509_BAD_BOOLEAN",
243 "Decoding error: BOOLEAN value has invalid length."
244 },
245 {
246 BR_ERR_X509_OVERFLOW,
247 "BR_ERR_X509_OVERFLOW",
248 "Decoding error: value is off-limits."
249 },
250 {
251 BR_ERR_X509_BAD_DN,
252 "BR_ERR_X509_BAD_DN",
253 "Invalid distinguished name."
254 },
255 {
256 BR_ERR_X509_BAD_TIME,
257 "BR_ERR_X509_BAD_TIME",
258 "Invalid date/time representation."
259 },
260 {
261 BR_ERR_X509_UNSUPPORTED,
262 "BR_ERR_X509_UNSUPPORTED",
263 "Certificate contains unsupported features that cannot be"
264 " ignored."
265 },
266 {
267 BR_ERR_X509_LIMIT_EXCEEDED,
268 "BR_ERR_X509_LIMIT_EXCEEDED",
269 "Key or signature size exceeds internal limits."
270 },
271 {
272 BR_ERR_X509_WRONG_KEY_TYPE,
273 "BR_ERR_X509_WRONG_KEY_TYPE",
274 "Key type does not match that which was expected."
275 },
276 {
277 BR_ERR_X509_BAD_SIGNATURE,
278 "BR_ERR_X509_BAD_SIGNATURE",
279 "Signature is invalid."
280 },
281 {
282 BR_ERR_X509_TIME_UNKNOWN,
283 "BR_ERR_X509_TIME_UNKNOWN",
284 "Validation time is unknown."
285 },
286 {
287 BR_ERR_X509_EXPIRED,
288 "BR_ERR_X509_EXPIRED",
289 "Certificate is expired or not yet valid."
290 },
291 {
292 BR_ERR_X509_DN_MISMATCH,
293 "BR_ERR_X509_DN_MISMATCH",
294 "Issuer/Subject DN mismatch in the chain."
295 },
296 {
297 BR_ERR_X509_BAD_SERVER_NAME,
298 "BR_ERR_X509_BAD_SERVER_NAME",
299 "Expected server name was not found in the chain."
300 },
301 {
302 BR_ERR_X509_CRITICAL_EXTENSION,
303 "BR_ERR_X509_CRITICAL_EXTENSION",
304 "Unknown critical extension in certificate."
305 },
306 {
307 BR_ERR_X509_NOT_CA,
308 "BR_ERR_X509_NOT_CA",
309 "Not a CA, or path length constraint violation."
310 },
311 {
312 BR_ERR_X509_FORBIDDEN_KEY_USAGE,
313 "BR_ERR_X509_FORBIDDEN_KEY_USAGE",
314 "Key Usage extension prohibits intended usage."
315 },
316 {
317 BR_ERR_X509_WEAK_PUBLIC_KEY,
318 "BR_ERR_X509_WEAK_PUBLIC_KEY",
319 "Public key found in certificate is too small."
320 },
321 {
322 BR_ERR_X509_NOT_TRUSTED,
323 "BR_ERR_X509_NOT_TRUSTED",
324 "Chain could not be linked to a trust anchor."
325 },
326 { 0, 0, 0 }
327 };
328
329 /* see brssl.h */
330 const char *
find_error_name(int err,const char ** comment)331 find_error_name(int err, const char **comment)
332 {
333 size_t u;
334
335 for (u = 0; errors[u].name; u ++) {
336 if (errors[u].err == err) {
337 if (comment != NULL) {
338 *comment = errors[u].comment;
339 }
340 return errors[u].name;
341 }
342 }
343 return NULL;
344 }
345