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