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
34static 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 */
330const char *
331find_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