xref: /freebsd-src/contrib/bearssl/tools/brssl.h (revision 2aaf9152a852aba9eb2036b95f4948ee77988826)
1*0957b409SSimon J. Gerraty /*
2*0957b409SSimon J. Gerraty  * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
3*0957b409SSimon J. Gerraty  *
4*0957b409SSimon J. Gerraty  * Permission is hereby granted, free of charge, to any person obtaining
5*0957b409SSimon J. Gerraty  * a copy of this software and associated documentation files (the
6*0957b409SSimon J. Gerraty  * "Software"), to deal in the Software without restriction, including
7*0957b409SSimon J. Gerraty  * without limitation the rights to use, copy, modify, merge, publish,
8*0957b409SSimon J. Gerraty  * distribute, sublicense, and/or sell copies of the Software, and to
9*0957b409SSimon J. Gerraty  * permit persons to whom the Software is furnished to do so, subject to
10*0957b409SSimon J. Gerraty  * the following conditions:
11*0957b409SSimon J. Gerraty  *
12*0957b409SSimon J. Gerraty  * The above copyright notice and this permission notice shall be
13*0957b409SSimon J. Gerraty  * included in all copies or substantial portions of the Software.
14*0957b409SSimon J. Gerraty  *
15*0957b409SSimon J. Gerraty  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*0957b409SSimon J. Gerraty  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*0957b409SSimon J. Gerraty  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18*0957b409SSimon J. Gerraty  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19*0957b409SSimon J. Gerraty  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20*0957b409SSimon J. Gerraty  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21*0957b409SSimon J. Gerraty  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22*0957b409SSimon J. Gerraty  * SOFTWARE.
23*0957b409SSimon J. Gerraty  */
24*0957b409SSimon J. Gerraty 
25*0957b409SSimon J. Gerraty #ifndef BRSSL_H__
26*0957b409SSimon J. Gerraty #define BRSSL_H__
27*0957b409SSimon J. Gerraty 
28*0957b409SSimon J. Gerraty #ifndef _STANDALONE
29*0957b409SSimon J. Gerraty #include <stdio.h>
30*0957b409SSimon J. Gerraty #include <stdlib.h>
31*0957b409SSimon J. Gerraty #include <string.h>
32*0957b409SSimon J. Gerraty #include <stdint.h>
33*0957b409SSimon J. Gerraty 
34*0957b409SSimon J. Gerraty #elif !defined(STAND_H)
35*0957b409SSimon J. Gerraty #include <stand.h>
36*0957b409SSimon J. Gerraty #endif
37*0957b409SSimon J. Gerraty 
38*0957b409SSimon J. Gerraty #include "bearssl.h"
39*0957b409SSimon J. Gerraty 
40*0957b409SSimon J. Gerraty /*
41*0957b409SSimon J. Gerraty  * malloc() wrapper:
42*0957b409SSimon J. Gerraty  * -- If len is 0, then NULL is returned.
43*0957b409SSimon J. Gerraty  * -- If len is non-zero, and allocation fails, then an error message is
44*0957b409SSimon J. Gerraty  *    printed and the process exits with an error code.
45*0957b409SSimon J. Gerraty  */
46*0957b409SSimon J. Gerraty void *xmalloc(size_t len);
47*0957b409SSimon J. Gerraty 
48*0957b409SSimon J. Gerraty /*
49*0957b409SSimon J. Gerraty  * free() wrapper, meant to release blocks allocated with xmalloc().
50*0957b409SSimon J. Gerraty  */
51*0957b409SSimon J. Gerraty void xfree(void *buf);
52*0957b409SSimon J. Gerraty 
53*0957b409SSimon J. Gerraty /*
54*0957b409SSimon J. Gerraty  * Duplicate a character string into a newly allocated block.
55*0957b409SSimon J. Gerraty  */
56*0957b409SSimon J. Gerraty char *xstrdup(const void *src);
57*0957b409SSimon J. Gerraty 
58*0957b409SSimon J. Gerraty /*
59*0957b409SSimon J. Gerraty  * Allocate a new block with the provided length, filled with a copy
60*0957b409SSimon J. Gerraty  * of exactly that many bytes starting at address 'src'.
61*0957b409SSimon J. Gerraty  */
62*0957b409SSimon J. Gerraty void *xblobdup(const void *src, size_t len);
63*0957b409SSimon J. Gerraty 
64*0957b409SSimon J. Gerraty /*
65*0957b409SSimon J. Gerraty  * Duplicate a public key, into newly allocated blocks. The returned
66*0957b409SSimon J. Gerraty  * key must be later on released with xfreepkey().
67*0957b409SSimon J. Gerraty  */
68*0957b409SSimon J. Gerraty br_x509_pkey *xpkeydup(const br_x509_pkey *pk);
69*0957b409SSimon J. Gerraty 
70*0957b409SSimon J. Gerraty /*
71*0957b409SSimon J. Gerraty  * Release a public key that was allocated with xpkeydup(). If pk is NULL,
72*0957b409SSimon J. Gerraty  * this function does nothing.
73*0957b409SSimon J. Gerraty  */
74*0957b409SSimon J. Gerraty void xfreepkey(br_x509_pkey *pk);
75*0957b409SSimon J. Gerraty 
76*0957b409SSimon J. Gerraty /*
77*0957b409SSimon J. Gerraty  * Macros for growable arrays.
78*0957b409SSimon J. Gerraty  */
79*0957b409SSimon J. Gerraty 
80*0957b409SSimon J. Gerraty /*
81*0957b409SSimon J. Gerraty  * Make a structure type for a vector of 'type'.
82*0957b409SSimon J. Gerraty  */
83*0957b409SSimon J. Gerraty #define VECTOR(type)   struct { \
84*0957b409SSimon J. Gerraty 		type *buf; \
85*0957b409SSimon J. Gerraty 		size_t ptr, len; \
86*0957b409SSimon J. Gerraty 	}
87*0957b409SSimon J. Gerraty 
88*0957b409SSimon J. Gerraty /*
89*0957b409SSimon J. Gerraty  * Constant initialiser for a vector.
90*0957b409SSimon J. Gerraty  */
91*0957b409SSimon J. Gerraty #define VEC_INIT   { 0, 0, 0 }
92*0957b409SSimon J. Gerraty 
93*0957b409SSimon J. Gerraty /*
94*0957b409SSimon J. Gerraty  * Clear a vector.
95*0957b409SSimon J. Gerraty  */
96*0957b409SSimon J. Gerraty #define VEC_CLEAR(vec)   do { \
97*0957b409SSimon J. Gerraty 		xfree((vec).buf); \
98*0957b409SSimon J. Gerraty 		(vec).buf = NULL; \
99*0957b409SSimon J. Gerraty 		(vec).ptr = 0; \
100*0957b409SSimon J. Gerraty 		(vec).len = 0; \
101*0957b409SSimon J. Gerraty 	} while (0)
102*0957b409SSimon J. Gerraty 
103*0957b409SSimon J. Gerraty /*
104*0957b409SSimon J. Gerraty  * Clear a vector, first calling the provided function on each vector
105*0957b409SSimon J. Gerraty  * element.
106*0957b409SSimon J. Gerraty  */
107*0957b409SSimon J. Gerraty #define VEC_CLEAREXT(vec, fun)   do { \
108*0957b409SSimon J. Gerraty 		size_t vec_tmp; \
109*0957b409SSimon J. Gerraty 		for (vec_tmp = 0; vec_tmp < (vec).ptr; vec_tmp ++) { \
110*0957b409SSimon J. Gerraty 			(fun)(&(vec).buf[vec_tmp]); \
111*0957b409SSimon J. Gerraty 		} \
112*0957b409SSimon J. Gerraty 		VEC_CLEAR(vec); \
113*0957b409SSimon J. Gerraty 	} while (0)
114*0957b409SSimon J. Gerraty 
115*0957b409SSimon J. Gerraty /*
116*0957b409SSimon J. Gerraty  * Add a value at the end of a vector.
117*0957b409SSimon J. Gerraty  */
118*0957b409SSimon J. Gerraty #define VEC_ADD(vec, x)   do { \
119*0957b409SSimon J. Gerraty 		(vec).buf = vector_expand((vec).buf, sizeof *((vec).buf), \
120*0957b409SSimon J. Gerraty 			&(vec).ptr, &(vec).len, 1); \
121*0957b409SSimon J. Gerraty 		(vec).buf[(vec).ptr ++] = (x); \
122*0957b409SSimon J. Gerraty 	} while (0)
123*0957b409SSimon J. Gerraty 
124*0957b409SSimon J. Gerraty /*
125*0957b409SSimon J. Gerraty  * Add several values at the end of a vector.
126*0957b409SSimon J. Gerraty  */
127*0957b409SSimon J. Gerraty #define VEC_ADDMANY(vec, xp, num)   do { \
128*0957b409SSimon J. Gerraty 		size_t vec_num = (num); \
129*0957b409SSimon J. Gerraty 		(vec).buf = vector_expand((vec).buf, sizeof *((vec).buf), \
130*0957b409SSimon J. Gerraty 			&(vec).ptr, &(vec).len, vec_num); \
131*0957b409SSimon J. Gerraty 		memcpy((vec).buf + (vec).ptr, \
132*0957b409SSimon J. Gerraty 			(xp), vec_num * sizeof *((vec).buf)); \
133*0957b409SSimon J. Gerraty 		(vec).ptr += vec_num; \
134*0957b409SSimon J. Gerraty 	} while (0)
135*0957b409SSimon J. Gerraty 
136*0957b409SSimon J. Gerraty /*
137*0957b409SSimon J. Gerraty  * Access a vector element by index. This is a lvalue, and can be modified.
138*0957b409SSimon J. Gerraty  */
139*0957b409SSimon J. Gerraty #define VEC_ELT(vec, idx)   ((vec).buf[idx])
140*0957b409SSimon J. Gerraty 
141*0957b409SSimon J. Gerraty /*
142*0957b409SSimon J. Gerraty  * Get current vector length.
143*0957b409SSimon J. Gerraty  */
144*0957b409SSimon J. Gerraty #define VEC_LEN(vec)   ((vec).ptr)
145*0957b409SSimon J. Gerraty 
146*0957b409SSimon J. Gerraty /*
147*0957b409SSimon J. Gerraty  * Copy all vector elements into a newly allocated block.
148*0957b409SSimon J. Gerraty  */
149*0957b409SSimon J. Gerraty #define VEC_TOARRAY(vec)    xblobdup((vec).buf, sizeof *((vec).buf) * (vec).ptr)
150*0957b409SSimon J. Gerraty 
151*0957b409SSimon J. Gerraty /*
152*0957b409SSimon J. Gerraty  * Internal function used to handle memory allocations for vectors.
153*0957b409SSimon J. Gerraty  */
154*0957b409SSimon J. Gerraty void *vector_expand(void *buf,
155*0957b409SSimon J. Gerraty 	size_t esize, size_t *ptr, size_t *len, size_t extra);
156*0957b409SSimon J. Gerraty 
157*0957b409SSimon J. Gerraty /*
158*0957b409SSimon J. Gerraty  * Type for a vector of bytes.
159*0957b409SSimon J. Gerraty  */
160*0957b409SSimon J. Gerraty typedef VECTOR(unsigned char) bvector;
161*0957b409SSimon J. Gerraty 
162*0957b409SSimon J. Gerraty /*
163*0957b409SSimon J. Gerraty  * Compare two strings for equality; returned value is 1 if the strings
164*0957b409SSimon J. Gerraty  * are to be considered equal, 0 otherwise. Comparison is case-insensitive
165*0957b409SSimon J. Gerraty  * (ASCII letters only) and skips some characters (all whitespace, defined
166*0957b409SSimon J. Gerraty  * as ASCII codes 0 to 32 inclusive, and also '-', '_', '.', '/', '+' and
167*0957b409SSimon J. Gerraty  * ':').
168*0957b409SSimon J. Gerraty  */
169*0957b409SSimon J. Gerraty int eqstr(const char *s1, const char *s2);
170*0957b409SSimon J. Gerraty 
171*0957b409SSimon J. Gerraty /*
172*0957b409SSimon J. Gerraty  * Convert a string to a positive integer (size_t). Returned value is
173*0957b409SSimon J. Gerraty  * (size_t)-1 on error. On error, an explicit error message is printed.
174*0957b409SSimon J. Gerraty  */
175*0957b409SSimon J. Gerraty size_t parse_size(const char *s);
176*0957b409SSimon J. Gerraty 
177*0957b409SSimon J. Gerraty /*
178*0957b409SSimon J. Gerraty  * Structure for a known protocol version.
179*0957b409SSimon J. Gerraty  */
180*0957b409SSimon J. Gerraty typedef struct {
181*0957b409SSimon J. Gerraty 	const char *name;
182*0957b409SSimon J. Gerraty 	unsigned version;
183*0957b409SSimon J. Gerraty 	const char *comment;
184*0957b409SSimon J. Gerraty } protocol_version;
185*0957b409SSimon J. Gerraty 
186*0957b409SSimon J. Gerraty /*
187*0957b409SSimon J. Gerraty  * Known protocol versions. Last element has a NULL name.
188*0957b409SSimon J. Gerraty  */
189*0957b409SSimon J. Gerraty extern const protocol_version protocol_versions[];
190*0957b409SSimon J. Gerraty 
191*0957b409SSimon J. Gerraty /*
192*0957b409SSimon J. Gerraty  * Parse a version name. If the name is not recognized, then an error
193*0957b409SSimon J. Gerraty  * message is printed, and 0 is returned.
194*0957b409SSimon J. Gerraty  */
195*0957b409SSimon J. Gerraty unsigned parse_version(const char *name, size_t len);
196*0957b409SSimon J. Gerraty 
197*0957b409SSimon J. Gerraty /*
198*0957b409SSimon J. Gerraty  * Type for a known hash function.
199*0957b409SSimon J. Gerraty  */
200*0957b409SSimon J. Gerraty typedef struct {
201*0957b409SSimon J. Gerraty 	const char *name;
202*0957b409SSimon J. Gerraty 	const br_hash_class *hclass;
203*0957b409SSimon J. Gerraty 	const char *comment;
204*0957b409SSimon J. Gerraty } hash_function;
205*0957b409SSimon J. Gerraty 
206*0957b409SSimon J. Gerraty /*
207*0957b409SSimon J. Gerraty  * Known hash functions. Last element has a NULL name.
208*0957b409SSimon J. Gerraty  */
209*0957b409SSimon J. Gerraty extern const hash_function hash_functions[];
210*0957b409SSimon J. Gerraty 
211*0957b409SSimon J. Gerraty /*
212*0957b409SSimon J. Gerraty  * Parse hash function names. This function expects a comma-separated
213*0957b409SSimon J. Gerraty  * list of names, and returns a bit mask corresponding to the matched
214*0957b409SSimon J. Gerraty  * names. If one of the name does not match, or the list is empty, then
215*0957b409SSimon J. Gerraty  * an error message is printed, and 0 is returned.
216*0957b409SSimon J. Gerraty  */
217*0957b409SSimon J. Gerraty unsigned parse_hash_functions(const char *arg);
218*0957b409SSimon J. Gerraty 
219*0957b409SSimon J. Gerraty /*
220*0957b409SSimon J. Gerraty  * Get a curve name (by ID). If the curve ID is not known, this returns
221*0957b409SSimon J. Gerraty  * NULL.
222*0957b409SSimon J. Gerraty  */
223*0957b409SSimon J. Gerraty const char *get_curve_name(int id);
224*0957b409SSimon J. Gerraty 
225*0957b409SSimon J. Gerraty /*
226*0957b409SSimon J. Gerraty  * Get a curve name (by ID). The name is written in the provided buffer
227*0957b409SSimon J. Gerraty  * (zero-terminated). If the curve ID is not known, the name is
228*0957b409SSimon J. Gerraty  * "unknown (***)" where "***" is the decimal value of the identifier.
229*0957b409SSimon J. Gerraty  * If the name does not fit in the provided buffer, then dst[0] is set
230*0957b409SSimon J. Gerraty  * to 0 (unless len is 0, in which case nothing is written), and -1 is
231*0957b409SSimon J. Gerraty  * returned. Otherwise, the name is written in dst[] (with a terminating
232*0957b409SSimon J. Gerraty  * 0), and this function returns 0.
233*0957b409SSimon J. Gerraty  */
234*0957b409SSimon J. Gerraty int get_curve_name_ext(int id, char *dst, size_t len);
235*0957b409SSimon J. Gerraty 
236*0957b409SSimon J. Gerraty /*
237*0957b409SSimon J. Gerraty  * Type for a known cipher suite.
238*0957b409SSimon J. Gerraty  */
239*0957b409SSimon J. Gerraty typedef struct {
240*0957b409SSimon J. Gerraty 	const char *name;
241*0957b409SSimon J. Gerraty 	uint16_t suite;
242*0957b409SSimon J. Gerraty 	unsigned req;
243*0957b409SSimon J. Gerraty 	const char *comment;
244*0957b409SSimon J. Gerraty } cipher_suite;
245*0957b409SSimon J. Gerraty 
246*0957b409SSimon J. Gerraty /*
247*0957b409SSimon J. Gerraty  * Known cipher suites. Last element has a NULL name.
248*0957b409SSimon J. Gerraty  */
249*0957b409SSimon J. Gerraty extern const cipher_suite cipher_suites[];
250*0957b409SSimon J. Gerraty 
251*0957b409SSimon J. Gerraty /*
252*0957b409SSimon J. Gerraty  * Flags for cipher suite requirements.
253*0957b409SSimon J. Gerraty  */
254*0957b409SSimon J. Gerraty #define REQ_TLS12          0x0001   /* suite needs TLS 1.2 */
255*0957b409SSimon J. Gerraty #define REQ_SHA1           0x0002   /* suite needs SHA-1 */
256*0957b409SSimon J. Gerraty #define REQ_SHA256         0x0004   /* suite needs SHA-256 */
257*0957b409SSimon J. Gerraty #define REQ_SHA384         0x0008   /* suite needs SHA-384 */
258*0957b409SSimon J. Gerraty #define REQ_AESCBC         0x0010   /* suite needs AES/CBC encryption */
259*0957b409SSimon J. Gerraty #define REQ_AESGCM         0x0020   /* suite needs AES/GCM encryption */
260*0957b409SSimon J. Gerraty #define REQ_AESCCM         0x0040   /* suite needs AES/CCM encryption */
261*0957b409SSimon J. Gerraty #define REQ_CHAPOL         0x0080   /* suite needs ChaCha20+Poly1305 */
262*0957b409SSimon J. Gerraty #define REQ_3DESCBC        0x0100   /* suite needs 3DES/CBC encryption */
263*0957b409SSimon J. Gerraty #define REQ_RSAKEYX        0x0200   /* suite uses RSA key exchange */
264*0957b409SSimon J. Gerraty #define REQ_ECDHE_RSA      0x0400   /* suite uses ECDHE_RSA key exchange */
265*0957b409SSimon J. Gerraty #define REQ_ECDHE_ECDSA    0x0800   /* suite uses ECDHE_ECDSA key exchange */
266*0957b409SSimon J. Gerraty #define REQ_ECDH           0x1000   /* suite uses static ECDH key exchange */
267*0957b409SSimon J. Gerraty 
268*0957b409SSimon J. Gerraty /*
269*0957b409SSimon J. Gerraty  * Parse a list of cipher suite names. The names are comma-separated. If
270*0957b409SSimon J. Gerraty  * one of the name is not recognised, or the list is empty, then an
271*0957b409SSimon J. Gerraty  * appropriate error message is printed, and NULL is returned.
272*0957b409SSimon J. Gerraty  * The returned array is allocated with xmalloc() and must be released
273*0957b409SSimon J. Gerraty  * by the caller. That array is terminated with a dummy entry whose 'name'
274*0957b409SSimon J. Gerraty  * field is NULL. The number of entries (not counting the dummy entry)
275*0957b409SSimon J. Gerraty  * is also written into '*num'.
276*0957b409SSimon J. Gerraty  */
277*0957b409SSimon J. Gerraty cipher_suite *parse_suites(const char *arg, size_t *num);
278*0957b409SSimon J. Gerraty 
279*0957b409SSimon J. Gerraty /*
280*0957b409SSimon J. Gerraty  * Get the name of a cipher suite. Returned value is NULL if the suite is
281*0957b409SSimon J. Gerraty  * not recognized.
282*0957b409SSimon J. Gerraty  */
283*0957b409SSimon J. Gerraty const char *get_suite_name(unsigned suite);
284*0957b409SSimon J. Gerraty 
285*0957b409SSimon J. Gerraty /*
286*0957b409SSimon J. Gerraty  * Get the name of a cipher suite. The name is written in the provided
287*0957b409SSimon J. Gerraty  * buffer; if the suite is not recognised, then the name is
288*0957b409SSimon J. Gerraty  * "unknown (0x****)" where "****" is the hexadecimal value of the suite.
289*0957b409SSimon J. Gerraty  * If the name does not fit in the provided buffer, then dst[0] is set
290*0957b409SSimon J. Gerraty  * to 0 (unless len is 0, in which case nothing is written), and -1 is
291*0957b409SSimon J. Gerraty  * returned. Otherwise, the name is written in dst[] (with a terminating
292*0957b409SSimon J. Gerraty  * 0), and this function returns 0.
293*0957b409SSimon J. Gerraty  */
294*0957b409SSimon J. Gerraty int get_suite_name_ext(unsigned suite, char *dst, size_t len);
295*0957b409SSimon J. Gerraty 
296*0957b409SSimon J. Gerraty /*
297*0957b409SSimon J. Gerraty  * Tell whether a cipher suite uses ECDHE key exchange.
298*0957b409SSimon J. Gerraty  */
299*0957b409SSimon J. Gerraty int uses_ecdhe(unsigned suite);
300*0957b409SSimon J. Gerraty 
301*0957b409SSimon J. Gerraty /*
302*0957b409SSimon J. Gerraty  * Print out all known names (for protocol versions, cipher suites...).
303*0957b409SSimon J. Gerraty  */
304*0957b409SSimon J. Gerraty void list_names(void);
305*0957b409SSimon J. Gerraty 
306*0957b409SSimon J. Gerraty /*
307*0957b409SSimon J. Gerraty  * Print out all known elliptic curve names.
308*0957b409SSimon J. Gerraty  */
309*0957b409SSimon J. Gerraty void list_curves(void);
310*0957b409SSimon J. Gerraty 
311*0957b409SSimon J. Gerraty /*
312*0957b409SSimon J. Gerraty  * Get the symbolic name for an elliptic curve (by ID).
313*0957b409SSimon J. Gerraty  */
314*0957b409SSimon J. Gerraty const char *ec_curve_name(int curve);
315*0957b409SSimon J. Gerraty 
316*0957b409SSimon J. Gerraty /*
317*0957b409SSimon J. Gerraty  * Get a curve by symbolic name. If the name is not recognized, -1 is
318*0957b409SSimon J. Gerraty  * returned.
319*0957b409SSimon J. Gerraty  */
320*0957b409SSimon J. Gerraty int get_curve_by_name(const char *str);
321*0957b409SSimon J. Gerraty 
322*0957b409SSimon J. Gerraty /*
323*0957b409SSimon J. Gerraty  * Get the symbolic name for a hash function name (by ID).
324*0957b409SSimon J. Gerraty  */
325*0957b409SSimon J. Gerraty const char *hash_function_name(int id);
326*0957b409SSimon J. Gerraty 
327*0957b409SSimon J. Gerraty /*
328*0957b409SSimon J. Gerraty  * Read a file completely. The returned block is allocated with xmalloc()
329*0957b409SSimon J. Gerraty  * and must be released by the caller.
330*0957b409SSimon J. Gerraty  * If the file cannot be found or read completely, or is empty, then an
331*0957b409SSimon J. Gerraty  * appropriate error message is written, and NULL is returned.
332*0957b409SSimon J. Gerraty  */
333*0957b409SSimon J. Gerraty unsigned char *read_file(const char *fname, size_t *len);
334*0957b409SSimon J. Gerraty 
335*0957b409SSimon J. Gerraty /*
336*0957b409SSimon J. Gerraty  * Write a file completely. This returns 0 on success, -1 on error. On
337*0957b409SSimon J. Gerraty  * error, an appropriate error message is printed.
338*0957b409SSimon J. Gerraty  */
339*0957b409SSimon J. Gerraty int write_file(const char *fname, const void *data, size_t len);
340*0957b409SSimon J. Gerraty 
341*0957b409SSimon J. Gerraty /*
342*0957b409SSimon J. Gerraty  * This function returns non-zero if the provided buffer "looks like"
343*0957b409SSimon J. Gerraty  * a DER-encoded ASN.1 object (criteria: it has the tag for a SEQUENCE
344*0957b409SSimon J. Gerraty  * with a definite length that matches the total object length).
345*0957b409SSimon J. Gerraty  */
346*0957b409SSimon J. Gerraty int looks_like_DER(const unsigned char *buf, size_t len);
347*0957b409SSimon J. Gerraty 
348*0957b409SSimon J. Gerraty /*
349*0957b409SSimon J. Gerraty  * Type for a named blob (the 'name' is a normalised PEM header name).
350*0957b409SSimon J. Gerraty  */
351*0957b409SSimon J. Gerraty typedef struct {
352*0957b409SSimon J. Gerraty 	char *name;
353*0957b409SSimon J. Gerraty 	unsigned char *data;
354*0957b409SSimon J. Gerraty 	size_t data_len;
355*0957b409SSimon J. Gerraty } pem_object;
356*0957b409SSimon J. Gerraty 
357*0957b409SSimon J. Gerraty /*
358*0957b409SSimon J. Gerraty  * Release the contents of a named blob (buffer and name).
359*0957b409SSimon J. Gerraty  */
360*0957b409SSimon J. Gerraty void free_pem_object_contents(pem_object *po);
361*0957b409SSimon J. Gerraty 
362*0957b409SSimon J. Gerraty /*
363*0957b409SSimon J. Gerraty  * Decode a buffer as a PEM file, and return all objects. On error, NULL
364*0957b409SSimon J. Gerraty  * is returned and an error message is printed. Absence of any object
365*0957b409SSimon J. Gerraty  * is an error.
366*0957b409SSimon J. Gerraty  *
367*0957b409SSimon J. Gerraty  * The returned array is terminated by a dummy object whose 'name' is
368*0957b409SSimon J. Gerraty  * NULL. The number of objects (not counting the dummy terminator) is
369*0957b409SSimon J. Gerraty  * written in '*num'.
370*0957b409SSimon J. Gerraty  */
371*0957b409SSimon J. Gerraty pem_object *decode_pem(const void *src, size_t len, size_t *num);
372*0957b409SSimon J. Gerraty 
373*0957b409SSimon J. Gerraty /*
374*0957b409SSimon J. Gerraty  * Get the certificate(s) from a file. This accepts both a single
375*0957b409SSimon J. Gerraty  * DER-encoded certificate, and a text file that contains
376*0957b409SSimon J. Gerraty  * PEM-encoded certificates (and possibly other objects, which are
377*0957b409SSimon J. Gerraty  * then ignored).
378*0957b409SSimon J. Gerraty  *
379*0957b409SSimon J. Gerraty  * On decoding error, or if the file turns out to contain no certificate
380*0957b409SSimon J. Gerraty  * at all, then an error message is printed and NULL is returned.
381*0957b409SSimon J. Gerraty  *
382*0957b409SSimon J. Gerraty  * The returned array, and all referenced buffers, are allocated with
383*0957b409SSimon J. Gerraty  * xmalloc() and must be released by the caller. The returned array
384*0957b409SSimon J. Gerraty  * ends with a dummy entry whose 'data' field is NULL.
385*0957b409SSimon J. Gerraty  * The number of decoded certificates (not counting the dummy entry)
386*0957b409SSimon J. Gerraty  * is written into '*num'.
387*0957b409SSimon J. Gerraty  */
388*0957b409SSimon J. Gerraty br_x509_certificate *read_certificates(const char *fname, size_t *num);
389*0957b409SSimon J. Gerraty 
390*0957b409SSimon J. Gerraty /*
391*0957b409SSimon J. Gerraty  * Release certificates. This releases all certificate data arrays,
392*0957b409SSimon J. Gerraty  * and the whole array as well.
393*0957b409SSimon J. Gerraty  */
394*0957b409SSimon J. Gerraty void free_certificates(br_x509_certificate *certs, size_t num);
395*0957b409SSimon J. Gerraty 
396*0957b409SSimon J. Gerraty /*
397*0957b409SSimon J. Gerraty  * Interpret a certificate as a trust anchor. The trust anchor is
398*0957b409SSimon J. Gerraty  * newly allocated with xmalloc() and the caller must release it.
399*0957b409SSimon J. Gerraty  * On decoding error, an error message is printed, and this function
400*0957b409SSimon J. Gerraty  * returns NULL.
401*0957b409SSimon J. Gerraty  */
402*0957b409SSimon J. Gerraty br_x509_trust_anchor *certificate_to_trust_anchor(br_x509_certificate *xc);
403*0957b409SSimon J. Gerraty 
404*0957b409SSimon J. Gerraty /*
405*0957b409SSimon J. Gerraty  * Type for a vector of trust anchors.
406*0957b409SSimon J. Gerraty  */
407*0957b409SSimon J. Gerraty typedef VECTOR(br_x509_trust_anchor) anchor_list;
408*0957b409SSimon J. Gerraty 
409*0957b409SSimon J. Gerraty /*
410*0957b409SSimon J. Gerraty  * Release contents for a trust anchor (assuming they were dynamically
411*0957b409SSimon J. Gerraty  * allocated with xmalloc()). The structure itself is NOT released.
412*0957b409SSimon J. Gerraty  */
413*0957b409SSimon J. Gerraty void free_ta_contents(br_x509_trust_anchor *ta);
414*0957b409SSimon J. Gerraty 
415*0957b409SSimon J. Gerraty /*
416*0957b409SSimon J. Gerraty  * Decode certificates from a file and interpret them as trust anchors.
417*0957b409SSimon J. Gerraty  * The trust anchors are added to the provided list. The number of found
418*0957b409SSimon J. Gerraty  * anchors is returned; on error, 0 is returned (finding no anchor at
419*0957b409SSimon J. Gerraty  * all is considered an error). An appropriate error message is displayed.
420*0957b409SSimon J. Gerraty  */
421*0957b409SSimon J. Gerraty size_t read_trust_anchors(anchor_list *dst, const char *fname);
422*0957b409SSimon J. Gerraty 
423*0957b409SSimon J. Gerraty /*
424*0957b409SSimon J. Gerraty  * Get the "signer key type" for the certificate (key type of the
425*0957b409SSimon J. Gerraty  * issuing CA). On error, this prints a message on stderr, and returns 0.
426*0957b409SSimon J. Gerraty  */
427*0957b409SSimon J. Gerraty int get_cert_signer_algo(br_x509_certificate *xc);
428*0957b409SSimon J. Gerraty 
429*0957b409SSimon J. Gerraty /*
430*0957b409SSimon J. Gerraty  * Special "no anchor" X.509 validator that wraps around another X.509
431*0957b409SSimon J. Gerraty  * validator and turns "not trusted" error codes into success. This is
432*0957b409SSimon J. Gerraty  * by definition insecure, but convenient for debug purposes.
433*0957b409SSimon J. Gerraty  */
434*0957b409SSimon J. Gerraty typedef struct {
435*0957b409SSimon J. Gerraty 	const br_x509_class *vtable;
436*0957b409SSimon J. Gerraty 	const br_x509_class **inner;
437*0957b409SSimon J. Gerraty } x509_noanchor_context;
438*0957b409SSimon J. Gerraty extern const br_x509_class x509_noanchor_vtable;
439*0957b409SSimon J. Gerraty 
440*0957b409SSimon J. Gerraty /*
441*0957b409SSimon J. Gerraty  * Initialise a "no anchor" X.509 validator.
442*0957b409SSimon J. Gerraty  */
443*0957b409SSimon J. Gerraty void x509_noanchor_init(x509_noanchor_context *xwc,
444*0957b409SSimon J. Gerraty 	const br_x509_class **inner);
445*0957b409SSimon J. Gerraty 
446*0957b409SSimon J. Gerraty /*
447*0957b409SSimon J. Gerraty  * Aggregate type for a private key.
448*0957b409SSimon J. Gerraty  */
449*0957b409SSimon J. Gerraty typedef struct {
450*0957b409SSimon J. Gerraty 	int key_type;  /* BR_KEYTYPE_RSA or BR_KEYTYPE_EC */
451*0957b409SSimon J. Gerraty 	union {
452*0957b409SSimon J. Gerraty 		br_rsa_private_key rsa;
453*0957b409SSimon J. Gerraty 		br_ec_private_key ec;
454*0957b409SSimon J. Gerraty 	} key;
455*0957b409SSimon J. Gerraty } private_key;
456*0957b409SSimon J. Gerraty 
457*0957b409SSimon J. Gerraty /*
458*0957b409SSimon J. Gerraty  * Decode a private key from a file. On error, this prints an error
459*0957b409SSimon J. Gerraty  * message and returns NULL.
460*0957b409SSimon J. Gerraty  */
461*0957b409SSimon J. Gerraty private_key *read_private_key(const char *fname);
462*0957b409SSimon J. Gerraty 
463*0957b409SSimon J. Gerraty /*
464*0957b409SSimon J. Gerraty  * Free a private key.
465*0957b409SSimon J. Gerraty  */
466*0957b409SSimon J. Gerraty void free_private_key(private_key *sk);
467*0957b409SSimon J. Gerraty 
468*0957b409SSimon J. Gerraty /*
469*0957b409SSimon J. Gerraty  * Get the encoded OID for a given hash function (to use with PKCS#1
470*0957b409SSimon J. Gerraty  * signatures). If the hash function ID is 0 (for MD5+SHA-1), or if
471*0957b409SSimon J. Gerraty  * the ID is not one of the SHA-* functions (SHA-1, SHA-224, SHA-256,
472*0957b409SSimon J. Gerraty  * SHA-384, SHA-512), then this function returns NULL.
473*0957b409SSimon J. Gerraty  */
474*0957b409SSimon J. Gerraty const unsigned char *get_hash_oid(int id);
475*0957b409SSimon J. Gerraty 
476*0957b409SSimon J. Gerraty /*
477*0957b409SSimon J. Gerraty  * Get a hash implementation by ID. This returns NULL if the hash
478*0957b409SSimon J. Gerraty  * implementation is not available.
479*0957b409SSimon J. Gerraty  */
480*0957b409SSimon J. Gerraty const br_hash_class *get_hash_impl(int id);
481*0957b409SSimon J. Gerraty 
482*0957b409SSimon J. Gerraty /*
483*0957b409SSimon J. Gerraty  * Find the symbolic name and the description for an error. If 'err' is
484*0957b409SSimon J. Gerraty  * recognised then the error symbolic name is returned; if 'comment' is
485*0957b409SSimon J. Gerraty  * not NULL then '*comment' is then set to a descriptive human-readable
486*0957b409SSimon J. Gerraty  * message. If the error code 'err' is not recognised, then '*comment' is
487*0957b409SSimon J. Gerraty  * untouched and this function returns NULL.
488*0957b409SSimon J. Gerraty  */
489*0957b409SSimon J. Gerraty const char *find_error_name(int err, const char **comment);
490*0957b409SSimon J. Gerraty 
491*0957b409SSimon J. Gerraty /*
492*0957b409SSimon J. Gerraty  * Find the symbolic name for an algorithm implementation. Provided
493*0957b409SSimon J. Gerraty  * pointer should be a pointer to a vtable or to a function, where
494*0957b409SSimon J. Gerraty  * appropriate. If not recognised, then the string "UNKNOWN" is returned.
495*0957b409SSimon J. Gerraty  *
496*0957b409SSimon J. Gerraty  * If 'long_name' is non-zero, then the returned name recalls the
497*0957b409SSimon J. Gerraty  * algorithm type as well; otherwise, only the core implementation name
498*0957b409SSimon J. Gerraty  * is returned (e.g. the long name could be 'aes_big_cbcenc' while the
499*0957b409SSimon J. Gerraty  * short name is 'big').
500*0957b409SSimon J. Gerraty  */
501*0957b409SSimon J. Gerraty const char *get_algo_name(const void *algo, int long_name);
502*0957b409SSimon J. Gerraty 
503*0957b409SSimon J. Gerraty /*
504*0957b409SSimon J. Gerraty  * Run a SSL engine, with a socket connected to the peer, and using
505*0957b409SSimon J. Gerraty  * stdin/stdout to exchange application data. The socket must be a
506*0957b409SSimon J. Gerraty  * non-blocking descriptor.
507*0957b409SSimon J. Gerraty  *
508*0957b409SSimon J. Gerraty  * To help with Win32 compatibility, the socket descriptor is provided
509*0957b409SSimon J. Gerraty  * as an "unsigned long" value.
510*0957b409SSimon J. Gerraty  *
511*0957b409SSimon J. Gerraty  * Returned value:
512*0957b409SSimon J. Gerraty  *    0        SSL connection closed successfully
513*0957b409SSimon J. Gerraty  *    x > 0    SSL error "x"
514*0957b409SSimon J. Gerraty  *   -1        early socket close
515*0957b409SSimon J. Gerraty  *   -2        stdout was closed, or something failed badly
516*0957b409SSimon J. Gerraty  */
517*0957b409SSimon J. Gerraty int run_ssl_engine(br_ssl_engine_context *eng,
518*0957b409SSimon J. Gerraty 	unsigned long fd, unsigned flags);
519*0957b409SSimon J. Gerraty 
520*0957b409SSimon J. Gerraty #define RUN_ENGINE_VERBOSE     0x0001  /* enable verbose messages */
521*0957b409SSimon J. Gerraty #define RUN_ENGINE_TRACE       0x0002  /* hex dump of records */
522*0957b409SSimon J. Gerraty 
523*0957b409SSimon J. Gerraty /*
524*0957b409SSimon J. Gerraty  * Do the "client" command. Returned value is 0 on success, -1 on failure.
525*0957b409SSimon J. Gerraty  * Command-line arguments start _after_ the command name.
526*0957b409SSimon J. Gerraty  */
527*0957b409SSimon J. Gerraty int do_client(int argc, char *argv[]);
528*0957b409SSimon J. Gerraty 
529*0957b409SSimon J. Gerraty /*
530*0957b409SSimon J. Gerraty  * Do the "server" command. Returned value is 0 on success, -1 on failure.
531*0957b409SSimon J. Gerraty  * Command-line arguments start _after_ the command name.
532*0957b409SSimon J. Gerraty  */
533*0957b409SSimon J. Gerraty int do_server(int argc, char *argv[]);
534*0957b409SSimon J. Gerraty 
535*0957b409SSimon J. Gerraty /*
536*0957b409SSimon J. Gerraty  * Do the "verify" command. Returned value is 0 on success, -1 on failure.
537*0957b409SSimon J. Gerraty  * Command-line arguments start _after_ the command name.
538*0957b409SSimon J. Gerraty  */
539*0957b409SSimon J. Gerraty int do_verify(int argc, char *argv[]);
540*0957b409SSimon J. Gerraty 
541*0957b409SSimon J. Gerraty /*
542*0957b409SSimon J. Gerraty  * Do the "skey" command. Returned value is 0 on success, -1 on failure.
543*0957b409SSimon J. Gerraty  * Command-line arguments start _after_ the command name.
544*0957b409SSimon J. Gerraty  */
545*0957b409SSimon J. Gerraty int do_skey(int argc, char *argv[]);
546*0957b409SSimon J. Gerraty 
547*0957b409SSimon J. Gerraty /*
548*0957b409SSimon J. Gerraty  * Do the "ta" command. Returned value is 0 on success, -1 on failure.
549*0957b409SSimon J. Gerraty  * Command-line arguments start _after_ the command name.
550*0957b409SSimon J. Gerraty  */
551*0957b409SSimon J. Gerraty int do_ta(int argc, char *argv[]);
552*0957b409SSimon J. Gerraty 
553*0957b409SSimon J. Gerraty /*
554*0957b409SSimon J. Gerraty  * Do the "chain" command. Returned value is 0 on success, -1 on failure.
555*0957b409SSimon J. Gerraty  * Command-line arguments start _after_ the command name.
556*0957b409SSimon J. Gerraty  */
557*0957b409SSimon J. Gerraty int do_chain(int argc, char *argv[]);
558*0957b409SSimon J. Gerraty 
559*0957b409SSimon J. Gerraty /*
560*0957b409SSimon J. Gerraty  * Do the "twrch" command. Returned value is 0 on success, -1 on failure
561*0957b409SSimon J. Gerraty  * (processing or arguments), or a non-zero exit code. Command-line
562*0957b409SSimon J. Gerraty  * arguments start _after_ the command name.
563*0957b409SSimon J. Gerraty  */
564*0957b409SSimon J. Gerraty int do_twrch(int argc, char *argv[]);
565*0957b409SSimon J. Gerraty 
566*0957b409SSimon J. Gerraty /*
567*0957b409SSimon J. Gerraty  * Do the "impl" command. Returned value is 0 on success, -1 on failure.
568*0957b409SSimon J. Gerraty  * Command-line arguments start _after_ the command name.
569*0957b409SSimon J. Gerraty  */
570*0957b409SSimon J. Gerraty int do_impl(int argc, char *argv[]);
571*0957b409SSimon J. Gerraty 
572*0957b409SSimon J. Gerraty #endif
573