diff options
author | David Monniaux <david.monniaux@univ-grenoble-alpes.fr> | 2020-03-03 08:17:40 +0100 |
---|---|---|
committer | David Monniaux <david.monniaux@univ-grenoble-alpes.fr> | 2020-03-03 08:17:40 +0100 |
commit | 1ab7b51c30e1b10ac45b0bd64cefdc01da0f7f68 (patch) | |
tree | 210ffc156c83f04fb0c61a40b4f9037d7ba8a7e1 /test/monniaux/BearSSL/tools/brssl.h | |
parent | 222c9047d61961db9c6b19fed5ca49829223fd33 (diff) | |
parent | 12be46d59a2483a10d77fa8ee67f7e0ca1bd702f (diff) | |
download | compcert-kvx-1ab7b51c30e1b10ac45b0bd64cefdc01da0f7f68.tar.gz compcert-kvx-1ab7b51c30e1b10ac45b0bd64cefdc01da0f7f68.zip |
Merge branch 'mppa-cse2' of gricad-gitlab.univ-grenoble-alpes.fr:sixcy/CompCert into mppa-work
Diffstat (limited to 'test/monniaux/BearSSL/tools/brssl.h')
-rw-r--r-- | test/monniaux/BearSSL/tools/brssl.h | 567 |
1 files changed, 567 insertions, 0 deletions
diff --git a/test/monniaux/BearSSL/tools/brssl.h b/test/monniaux/BearSSL/tools/brssl.h new file mode 100644 index 00000000..a23ba00f --- /dev/null +++ b/test/monniaux/BearSSL/tools/brssl.h @@ -0,0 +1,567 @@ +/* + * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BRSSL_H__ +#define BRSSL_H__ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> + +#include "bearssl.h" + +/* + * malloc() wrapper: + * -- If len is 0, then NULL is returned. + * -- If len is non-zero, and allocation fails, then an error message is + * printed and the process exits with an error code. + */ +void *xmalloc(size_t len); + +/* + * free() wrapper, meant to release blocks allocated with xmalloc(). + */ +void xfree(void *buf); + +/* + * Duplicate a character string into a newly allocated block. + */ +char *xstrdup(const void *src); + +/* + * Allocate a new block with the provided length, filled with a copy + * of exactly that many bytes starting at address 'src'. + */ +void *xblobdup(const void *src, size_t len); + +/* + * Duplicate a public key, into newly allocated blocks. The returned + * key must be later on released with xfreepkey(). + */ +br_x509_pkey *xpkeydup(const br_x509_pkey *pk); + +/* + * Release a public key that was allocated with xpkeydup(). If pk is NULL, + * this function does nothing. + */ +void xfreepkey(br_x509_pkey *pk); + +/* + * Macros for growable arrays. + */ + +/* + * Make a structure type for a vector of 'type'. + */ +#define VECTOR(type) struct { \ + type *buf; \ + size_t ptr, len; \ + } + +/* + * Constant initialiser for a vector. + */ +#define VEC_INIT { 0, 0, 0 } + +/* + * Clear a vector. + */ +#define VEC_CLEAR(vec) do { \ + xfree((vec).buf); \ + (vec).buf = NULL; \ + (vec).ptr = 0; \ + (vec).len = 0; \ + } while (0) + +/* + * Clear a vector, first calling the provided function on each vector + * element. + */ +#define VEC_CLEAREXT(vec, fun) do { \ + size_t vec_tmp; \ + for (vec_tmp = 0; vec_tmp < (vec).ptr; vec_tmp ++) { \ + (fun)(&(vec).buf[vec_tmp]); \ + } \ + VEC_CLEAR(vec); \ + } while (0) + +/* + * Add a value at the end of a vector. + */ +#define VEC_ADD(vec, x) do { \ + (vec).buf = vector_expand((vec).buf, sizeof *((vec).buf), \ + &(vec).ptr, &(vec).len, 1); \ + (vec).buf[(vec).ptr ++] = (x); \ + } while (0) + +/* + * Add several values at the end of a vector. + */ +#define VEC_ADDMANY(vec, xp, num) do { \ + size_t vec_num = (num); \ + (vec).buf = vector_expand((vec).buf, sizeof *((vec).buf), \ + &(vec).ptr, &(vec).len, vec_num); \ + memcpy((vec).buf + (vec).ptr, \ + (xp), vec_num * sizeof *((vec).buf)); \ + (vec).ptr += vec_num; \ + } while (0) + +/* + * Access a vector element by index. This is a lvalue, and can be modified. + */ +#define VEC_ELT(vec, idx) ((vec).buf[idx]) + +/* + * Get current vector length. + */ +#define VEC_LEN(vec) ((vec).ptr) + +/* + * Copy all vector elements into a newly allocated block. + */ +#define VEC_TOARRAY(vec) xblobdup((vec).buf, sizeof *((vec).buf) * (vec).ptr) + +/* + * Internal function used to handle memory allocations for vectors. + */ +void *vector_expand(void *buf, + size_t esize, size_t *ptr, size_t *len, size_t extra); + +/* + * Type for a vector of bytes. + */ +typedef VECTOR(unsigned char) bvector; + +/* + * Compare two strings for equality; returned value is 1 if the strings + * are to be considered equal, 0 otherwise. Comparison is case-insensitive + * (ASCII letters only) and skips some characters (all whitespace, defined + * as ASCII codes 0 to 32 inclusive, and also '-', '_', '.', '/', '+' and + * ':'). + */ +int eqstr(const char *s1, const char *s2); + +/* + * Convert a string to a positive integer (size_t). Returned value is + * (size_t)-1 on error. On error, an explicit error message is printed. + */ +size_t parse_size(const char *s); + +/* + * Structure for a known protocol version. + */ +typedef struct { + const char *name; + unsigned version; + const char *comment; +} protocol_version; + +/* + * Known protocol versions. Last element has a NULL name. + */ +extern const protocol_version protocol_versions[]; + +/* + * Parse a version name. If the name is not recognized, then an error + * message is printed, and 0 is returned. + */ +unsigned parse_version(const char *name, size_t len); + +/* + * Type for a known hash function. + */ +typedef struct { + const char *name; + const br_hash_class *hclass; + const char *comment; +} hash_function; + +/* + * Known hash functions. Last element has a NULL name. + */ +extern const hash_function hash_functions[]; + +/* + * Parse hash function names. This function expects a comma-separated + * list of names, and returns a bit mask corresponding to the matched + * names. If one of the name does not match, or the list is empty, then + * an error message is printed, and 0 is returned. + */ +unsigned parse_hash_functions(const char *arg); + +/* + * Get a curve name (by ID). If the curve ID is not known, this returns + * NULL. + */ +const char *get_curve_name(int id); + +/* + * Get a curve name (by ID). The name is written in the provided buffer + * (zero-terminated). If the curve ID is not known, the name is + * "unknown (***)" where "***" is the decimal value of the identifier. + * If the name does not fit in the provided buffer, then dst[0] is set + * to 0 (unless len is 0, in which case nothing is written), and -1 is + * returned. Otherwise, the name is written in dst[] (with a terminating + * 0), and this function returns 0. + */ +int get_curve_name_ext(int id, char *dst, size_t len); + +/* + * Type for a known cipher suite. + */ +typedef struct { + const char *name; + uint16_t suite; + unsigned req; + const char *comment; +} cipher_suite; + +/* + * Known cipher suites. Last element has a NULL name. + */ +extern const cipher_suite cipher_suites[]; + +/* + * Flags for cipher suite requirements. + */ +#define REQ_TLS12 0x0001 /* suite needs TLS 1.2 */ +#define REQ_SHA1 0x0002 /* suite needs SHA-1 */ +#define REQ_SHA256 0x0004 /* suite needs SHA-256 */ +#define REQ_SHA384 0x0008 /* suite needs SHA-384 */ +#define REQ_AESCBC 0x0010 /* suite needs AES/CBC encryption */ +#define REQ_AESGCM 0x0020 /* suite needs AES/GCM encryption */ +#define REQ_AESCCM 0x0040 /* suite needs AES/CCM encryption */ +#define REQ_CHAPOL 0x0080 /* suite needs ChaCha20+Poly1305 */ +#define REQ_3DESCBC 0x0100 /* suite needs 3DES/CBC encryption */ +#define REQ_RSAKEYX 0x0200 /* suite uses RSA key exchange */ +#define REQ_ECDHE_RSA 0x0400 /* suite uses ECDHE_RSA key exchange */ +#define REQ_ECDHE_ECDSA 0x0800 /* suite uses ECDHE_ECDSA key exchange */ +#define REQ_ECDH 0x1000 /* suite uses static ECDH key exchange */ + +/* + * Parse a list of cipher suite names. The names are comma-separated. If + * one of the name is not recognised, or the list is empty, then an + * appropriate error message is printed, and NULL is returned. + * The returned array is allocated with xmalloc() and must be released + * by the caller. That array is terminated with a dummy entry whose 'name' + * field is NULL. The number of entries (not counting the dummy entry) + * is also written into '*num'. + */ +cipher_suite *parse_suites(const char *arg, size_t *num); + +/* + * Get the name of a cipher suite. Returned value is NULL if the suite is + * not recognized. + */ +const char *get_suite_name(unsigned suite); + +/* + * Get the name of a cipher suite. The name is written in the provided + * buffer; if the suite is not recognised, then the name is + * "unknown (0x****)" where "****" is the hexadecimal value of the suite. + * If the name does not fit in the provided buffer, then dst[0] is set + * to 0 (unless len is 0, in which case nothing is written), and -1 is + * returned. Otherwise, the name is written in dst[] (with a terminating + * 0), and this function returns 0. + */ +int get_suite_name_ext(unsigned suite, char *dst, size_t len); + +/* + * Tell whether a cipher suite uses ECDHE key exchange. + */ +int uses_ecdhe(unsigned suite); + +/* + * Print out all known names (for protocol versions, cipher suites...). + */ +void list_names(void); + +/* + * Print out all known elliptic curve names. + */ +void list_curves(void); + +/* + * Get the symbolic name for an elliptic curve (by ID). + */ +const char *ec_curve_name(int curve); + +/* + * Get a curve by symbolic name. If the name is not recognized, -1 is + * returned. + */ +int get_curve_by_name(const char *str); + +/* + * Get the symbolic name for a hash function name (by ID). + */ +const char *hash_function_name(int id); + +/* + * Read a file completely. The returned block is allocated with xmalloc() + * and must be released by the caller. + * If the file cannot be found or read completely, or is empty, then an + * appropriate error message is written, and NULL is returned. + */ +unsigned char *read_file(const char *fname, size_t *len); + +/* + * Write a file completely. This returns 0 on success, -1 on error. On + * error, an appropriate error message is printed. + */ +int write_file(const char *fname, const void *data, size_t len); + +/* + * This function returns non-zero if the provided buffer "looks like" + * a DER-encoded ASN.1 object (criteria: it has the tag for a SEQUENCE + * with a definite length that matches the total object length). + */ +int looks_like_DER(const unsigned char *buf, size_t len); + +/* + * Type for a named blob (the 'name' is a normalised PEM header name). + */ +typedef struct { + char *name; + unsigned char *data; + size_t data_len; +} pem_object; + +/* + * Release the contents of a named blob (buffer and name). + */ +void free_pem_object_contents(pem_object *po); + +/* + * Decode a buffer as a PEM file, and return all objects. On error, NULL + * is returned and an error message is printed. Absence of any object + * is an error. + * + * The returned array is terminated by a dummy object whose 'name' is + * NULL. The number of objects (not counting the dummy terminator) is + * written in '*num'. + */ +pem_object *decode_pem(const void *src, size_t len, size_t *num); + +/* + * Get the certificate(s) from a file. This accepts both a single + * DER-encoded certificate, and a text file that contains + * PEM-encoded certificates (and possibly other objects, which are + * then ignored). + * + * On decoding error, or if the file turns out to contain no certificate + * at all, then an error message is printed and NULL is returned. + * + * The returned array, and all referenced buffers, are allocated with + * xmalloc() and must be released by the caller. The returned array + * ends with a dummy entry whose 'data' field is NULL. + * The number of decoded certificates (not counting the dummy entry) + * is written into '*num'. + */ +br_x509_certificate *read_certificates(const char *fname, size_t *num); + +/* + * Release certificates. This releases all certificate data arrays, + * and the whole array as well. + */ +void free_certificates(br_x509_certificate *certs, size_t num); + +/* + * Interpret a certificate as a trust anchor. The trust anchor is + * newly allocated with xmalloc() and the caller must release it. + * On decoding error, an error message is printed, and this function + * returns NULL. + */ +br_x509_trust_anchor *certificate_to_trust_anchor(br_x509_certificate *xc); + +/* + * Type for a vector of trust anchors. + */ +typedef VECTOR(br_x509_trust_anchor) anchor_list; + +/* + * Release contents for a trust anchor (assuming they were dynamically + * allocated with xmalloc()). The structure itself is NOT released. + */ +void free_ta_contents(br_x509_trust_anchor *ta); + +/* + * Decode certificates from a file and interpret them as trust anchors. + * The trust anchors are added to the provided list. The number of found + * anchors is returned; on error, 0 is returned (finding no anchor at + * all is considered an error). An appropriate error message is displayed. + */ +size_t read_trust_anchors(anchor_list *dst, const char *fname); + +/* + * Get the "signer key type" for the certificate (key type of the + * issuing CA). On error, this prints a message on stderr, and returns 0. + */ +int get_cert_signer_algo(br_x509_certificate *xc); + +/* + * Special "no anchor" X.509 validator that wraps around another X.509 + * validator and turns "not trusted" error codes into success. This is + * by definition insecure, but convenient for debug purposes. + */ +typedef struct { + const br_x509_class *vtable; + const br_x509_class **inner; +} x509_noanchor_context; +extern const br_x509_class x509_noanchor_vtable; + +/* + * Initialise a "no anchor" X.509 validator. + */ +void x509_noanchor_init(x509_noanchor_context *xwc, + const br_x509_class **inner); + +/* + * Aggregate type for a private key. + */ +typedef struct { + int key_type; /* BR_KEYTYPE_RSA or BR_KEYTYPE_EC */ + union { + br_rsa_private_key rsa; + br_ec_private_key ec; + } key; +} private_key; + +/* + * Decode a private key from a file. On error, this prints an error + * message and returns NULL. + */ +private_key *read_private_key(const char *fname); + +/* + * Free a private key. + */ +void free_private_key(private_key *sk); + +/* + * Get the encoded OID for a given hash function (to use with PKCS#1 + * signatures). If the hash function ID is 0 (for MD5+SHA-1), or if + * the ID is not one of the SHA-* functions (SHA-1, SHA-224, SHA-256, + * SHA-384, SHA-512), then this function returns NULL. + */ +const unsigned char *get_hash_oid(int id); + +/* + * Get a hash implementation by ID. This returns NULL if the hash + * implementation is not available. + */ +const br_hash_class *get_hash_impl(int id); + +/* + * Find the symbolic name and the description for an error. If 'err' is + * recognised then the error symbolic name is returned; if 'comment' is + * not NULL then '*comment' is then set to a descriptive human-readable + * message. If the error code 'err' is not recognised, then '*comment' is + * untouched and this function returns NULL. + */ +const char *find_error_name(int err, const char **comment); + +/* + * Find the symbolic name for an algorithm implementation. Provided + * pointer should be a pointer to a vtable or to a function, where + * appropriate. If not recognised, then the string "UNKNOWN" is returned. + * + * If 'long_name' is non-zero, then the returned name recalls the + * algorithm type as well; otherwise, only the core implementation name + * is returned (e.g. the long name could be 'aes_big_cbcenc' while the + * short name is 'big'). + */ +const char *get_algo_name(const void *algo, int long_name); + +/* + * Run a SSL engine, with a socket connected to the peer, and using + * stdin/stdout to exchange application data. The socket must be a + * non-blocking descriptor. + * + * To help with Win32 compatibility, the socket descriptor is provided + * as an "unsigned long" value. + * + * Returned value: + * 0 SSL connection closed successfully + * x > 0 SSL error "x" + * -1 early socket close + * -2 stdout was closed, or something failed badly + */ +int run_ssl_engine(br_ssl_engine_context *eng, + unsigned long fd, unsigned flags); + +#define RUN_ENGINE_VERBOSE 0x0001 /* enable verbose messages */ +#define RUN_ENGINE_TRACE 0x0002 /* hex dump of records */ + +/* + * Do the "client" command. Returned value is 0 on success, -1 on failure. + * Command-line arguments start _after_ the command name. + */ +int do_client(int argc, char *argv[]); + +/* + * Do the "server" command. Returned value is 0 on success, -1 on failure. + * Command-line arguments start _after_ the command name. + */ +int do_server(int argc, char *argv[]); + +/* + * Do the "verify" command. Returned value is 0 on success, -1 on failure. + * Command-line arguments start _after_ the command name. + */ +int do_verify(int argc, char *argv[]); + +/* + * Do the "skey" command. Returned value is 0 on success, -1 on failure. + * Command-line arguments start _after_ the command name. + */ +int do_skey(int argc, char *argv[]); + +/* + * Do the "ta" command. Returned value is 0 on success, -1 on failure. + * Command-line arguments start _after_ the command name. + */ +int do_ta(int argc, char *argv[]); + +/* + * Do the "chain" command. Returned value is 0 on success, -1 on failure. + * Command-line arguments start _after_ the command name. + */ +int do_chain(int argc, char *argv[]); + +/* + * Do the "twrch" command. Returned value is 0 on success, -1 on failure + * (processing or arguments), or a non-zero exit code. Command-line + * arguments start _after_ the command name. + */ +int do_twrch(int argc, char *argv[]); + +/* + * Do the "impl" command. Returned value is 0 on success, -1 on failure. + * Command-line arguments start _after_ the command name. + */ +int do_impl(int argc, char *argv[]); + +#endif |