mirror of
				https://github.com/esp8266/Arduino.git
				synced 2025-10-31 15:50:55 +03:00 
			
		
		
		
	Fix a buffer overflow error in private key decoding. https://bearssl.org/gitweb/?p=BearSSL;a=commit;h=b715b43e411dc5d5949df6f75ef7bb65952db11c
		
			
				
	
	
		
			4309 lines
		
	
	
		
			148 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			4309 lines
		
	
	
		
			148 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * 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 BR_BEARSSL_SSL_H__
 | |
| #define BR_BEARSSL_SSL_H__
 | |
| 
 | |
| #include <stddef.h>
 | |
| #include <stdint.h>
 | |
| 
 | |
| #include "bearssl_block.h"
 | |
| #include "bearssl_hash.h"
 | |
| #include "bearssl_hmac.h"
 | |
| #include "bearssl_prf.h"
 | |
| #include "bearssl_rand.h"
 | |
| #include "bearssl_x509.h"
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| extern "C" {
 | |
| #endif
 | |
| 
 | |
| /** \file bearssl_ssl.h
 | |
|  *
 | |
|  * # SSL
 | |
|  *
 | |
|  * For an overview of the SSL/TLS API, see [the BearSSL Web
 | |
|  * site](https://www.bearssl.org/api1.html).
 | |
|  *
 | |
|  * The `BR_TLS_*` constants correspond to the standard cipher suites and
 | |
|  * their values in the [IANA
 | |
|  * registry](http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4).
 | |
|  *
 | |
|  * The `BR_ALERT_*` constants are for standard TLS alert messages. When
 | |
|  * a fatal alert message is sent of received, then the SSL engine context
 | |
|  * status is set to the sum of that alert value (an integer in the 0..255
 | |
|  * range) and a fixed offset (`BR_ERR_SEND_FATAL_ALERT` for a sent alert,
 | |
|  * `BR_ERR_RECV_FATAL_ALERT` for a received alert).
 | |
|  */
 | |
| 
 | |
| /** \brief Optimal input buffer size. */
 | |
| #define BR_SSL_BUFSIZE_INPUT    (16384 + 325)
 | |
| 
 | |
| /** \brief Optimal output buffer size. */
 | |
| #define BR_SSL_BUFSIZE_OUTPUT   (16384 + 85)
 | |
| 
 | |
| /** \brief Optimal buffer size for monodirectional engine
 | |
|     (shared input/output buffer). */
 | |
| #define BR_SSL_BUFSIZE_MONO     BR_SSL_BUFSIZE_INPUT
 | |
| 
 | |
| /** \brief Optimal buffer size for bidirectional engine
 | |
|     (single buffer split into two separate input/output buffers). */
 | |
| #define BR_SSL_BUFSIZE_BIDI     (BR_SSL_BUFSIZE_INPUT + BR_SSL_BUFSIZE_OUTPUT)
 | |
| 
 | |
| /*
 | |
|  * Constants for known SSL/TLS protocol versions (SSL 3.0, TLS 1.0, TLS 1.1
 | |
|  * and TLS 1.2). Note that though there is a constant for SSL 3.0, that
 | |
|  * protocol version is not actually supported.
 | |
|  */
 | |
| 
 | |
| /** \brief Protocol version: SSL 3.0 (unsupported). */
 | |
| #define BR_SSL30   0x0300
 | |
| /** \brief Protocol version: TLS 1.0. */
 | |
| #define BR_TLS10   0x0301
 | |
| /** \brief Protocol version: TLS 1.1. */
 | |
| #define BR_TLS11   0x0302
 | |
| /** \brief Protocol version: TLS 1.2. */
 | |
| #define BR_TLS12   0x0303
 | |
| 
 | |
| /*
 | |
|  * Error constants. They are used to report the reason why a context has
 | |
|  * been marked as failed.
 | |
|  *
 | |
|  * Implementation note: SSL-level error codes should be in the 1..31
 | |
|  * range. The 32..63 range is for certificate decoding and validation
 | |
|  * errors. Received fatal alerts imply an error code in the 256..511 range.
 | |
|  */
 | |
| 
 | |
| /** \brief SSL status: no error so far (0). */
 | |
| #define BR_ERR_OK                      0
 | |
| 
 | |
| /** \brief SSL status: caller-provided parameter is incorrect. */
 | |
| #define BR_ERR_BAD_PARAM               1
 | |
| 
 | |
| /** \brief SSL status: operation requested by the caller cannot be applied
 | |
|     with the current context state (e.g. reading data while outgoing data
 | |
|     is waiting to be sent). */
 | |
| #define BR_ERR_BAD_STATE               2
 | |
| 
 | |
| /** \brief SSL status: incoming protocol or record version is unsupported. */
 | |
| #define BR_ERR_UNSUPPORTED_VERSION     3
 | |
| 
 | |
| /** \brief SSL status: incoming record version does not match the expected
 | |
|     version. */
 | |
| #define BR_ERR_BAD_VERSION             4
 | |
| 
 | |
| /** \brief SSL status: incoming record length is invalid. */
 | |
| #define BR_ERR_BAD_LENGTH              5
 | |
| 
 | |
| /** \brief SSL status: incoming record is too large to be processed, or
 | |
|     buffer is too small for the handshake message to send. */
 | |
| #define BR_ERR_TOO_LARGE               6
 | |
| 
 | |
| /** \brief SSL status: decryption found an invalid padding, or the record
 | |
|     MAC is not correct. */
 | |
| #define BR_ERR_BAD_MAC                 7
 | |
| 
 | |
| /** \brief SSL status: no initial entropy was provided, and none can be
 | |
|     obtained from the OS. */
 | |
| #define BR_ERR_NO_RANDOM               8
 | |
| 
 | |
| /** \brief SSL status: incoming record type is unknown. */
 | |
| #define BR_ERR_UNKNOWN_TYPE            9
 | |
| 
 | |
| /** \brief SSL status: incoming record or message has wrong type with
 | |
|     regards to the current engine state. */
 | |
| #define BR_ERR_UNEXPECTED             10
 | |
| 
 | |
| /** \brief SSL status: ChangeCipherSpec message from the peer has invalid
 | |
|     contents. */
 | |
| #define BR_ERR_BAD_CCS                12
 | |
| 
 | |
| /** \brief SSL status: alert message from the peer has invalid contents
 | |
|     (odd length). */
 | |
| #define BR_ERR_BAD_ALERT              13
 | |
| 
 | |
| /** \brief SSL status: incoming handshake message decoding failed. */
 | |
| #define BR_ERR_BAD_HANDSHAKE          14
 | |
| 
 | |
| /** \brief SSL status: ServerHello contains a session ID which is larger
 | |
|     than 32 bytes. */
 | |
| #define BR_ERR_OVERSIZED_ID           15
 | |
| 
 | |
| /** \brief SSL status: server wants to use a cipher suite that we did
 | |
|     not claim to support. This is also reported if we tried to advertise
 | |
|     a cipher suite that we do not support. */
 | |
| #define BR_ERR_BAD_CIPHER_SUITE       16
 | |
| 
 | |
| /** \brief SSL status: server wants to use a compression that we did not
 | |
|     claim to support. */
 | |
| #define BR_ERR_BAD_COMPRESSION        17
 | |
| 
 | |
| /** \brief SSL status: server's max fragment length does not match
 | |
|     client's. */
 | |
| #define BR_ERR_BAD_FRAGLEN            18
 | |
| 
 | |
| /** \brief SSL status: secure renegotiation failed. */
 | |
| #define BR_ERR_BAD_SECRENEG           19
 | |
| 
 | |
| /** \brief SSL status: server sent an extension type that we did not
 | |
|     announce, or used the same extension type several times in a single
 | |
|     ServerHello. */
 | |
| #define BR_ERR_EXTRA_EXTENSION        20
 | |
| 
 | |
| /** \brief SSL status: invalid Server Name Indication contents (when
 | |
|     used by the server, this extension shall be empty). */
 | |
| #define BR_ERR_BAD_SNI                21
 | |
| 
 | |
| /** \brief SSL status: invalid ServerHelloDone from the server (length
 | |
|     is not 0). */
 | |
| #define BR_ERR_BAD_HELLO_DONE         22
 | |
| 
 | |
| /** \brief SSL status: internal limit exceeded (e.g. server's public key
 | |
|     is too large). */
 | |
| #define BR_ERR_LIMIT_EXCEEDED         23
 | |
| 
 | |
| /** \brief SSL status: Finished message from peer does not match the
 | |
|     expected value. */
 | |
| #define BR_ERR_BAD_FINISHED           24
 | |
| 
 | |
| /** \brief SSL status: session resumption attempt with distinct version
 | |
|     or cipher suite. */
 | |
| #define BR_ERR_RESUME_MISMATCH        25
 | |
| 
 | |
| /** \brief SSL status: unsupported or invalid algorithm (ECDHE curve,
 | |
|     signature algorithm, hash function). */
 | |
| #define BR_ERR_INVALID_ALGORITHM      26
 | |
| 
 | |
| /** \brief SSL status: invalid signature (on ServerKeyExchange from
 | |
|     server, or in CertificateVerify from client). */
 | |
| #define BR_ERR_BAD_SIGNATURE          27
 | |
| 
 | |
| /** \brief SSL status: peer's public key does not have the proper type
 | |
|     or is not allowed for requested operation. */
 | |
| #define BR_ERR_WRONG_KEY_USAGE        28
 | |
| 
 | |
| /** \brief SSL status: client did not send a certificate upon request,
 | |
|     or the client certificate could not be validated. */
 | |
| #define BR_ERR_NO_CLIENT_AUTH         29
 | |
| 
 | |
| /** \brief SSL status: I/O error or premature close on underlying
 | |
|     transport stream. This error code is set only by the simplified
 | |
|     I/O API ("br_sslio_*"). */
 | |
| #define BR_ERR_IO                     31
 | |
| 
 | |
| /** \brief SSL status: base value for a received fatal alert.
 | |
| 
 | |
|     When a fatal alert is received from the peer, the alert value
 | |
|     is added to this constant. */
 | |
| #define BR_ERR_RECV_FATAL_ALERT      256
 | |
| 
 | |
| /** \brief SSL status: base value for a sent fatal alert.
 | |
| 
 | |
|     When a fatal alert is sent to the peer, the alert value is added
 | |
|     to this constant. */
 | |
| #define BR_ERR_SEND_FATAL_ALERT      512
 | |
| 
 | |
| /* ===================================================================== */
 | |
| 
 | |
| /**
 | |
|  * \brief Decryption engine for SSL.
 | |
|  *
 | |
|  * When processing incoming records, the SSL engine will use a decryption
 | |
|  * engine that uses a specific context structure, and has a set of
 | |
|  * methods (a vtable) that follows this template.
 | |
|  *
 | |
|  * The decryption engine is responsible for applying decryption, verifying
 | |
|  * MAC, and keeping track of the record sequence number.
 | |
|  */
 | |
| typedef struct br_sslrec_in_class_ br_sslrec_in_class;
 | |
| struct br_sslrec_in_class_ {
 | |
| 	/**
 | |
| 	 * \brief Context size (in bytes).
 | |
| 	 */
 | |
| 	size_t context_size;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Test validity of the incoming record length.
 | |
| 	 *
 | |
| 	 * This function returns 1 if the announced length for an
 | |
| 	 * incoming record is valid, 0 otherwise,
 | |
| 	 *
 | |
| 	 * \param ctx          decryption engine context.
 | |
| 	 * \param record_len   incoming record length.
 | |
| 	 * \return  1 of a valid length, 0 otherwise.
 | |
| 	 */
 | |
| 	int (*check_length)(const br_sslrec_in_class *const *ctx,
 | |
| 		size_t record_len);
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Decrypt the incoming record.
 | |
| 	 *
 | |
| 	 * This function may assume that the record length is valid
 | |
| 	 * (it has been previously tested with `check_length()`).
 | |
| 	 * Decryption is done in place; `*len` is updated with the
 | |
| 	 * cleartext length, and the address of the first plaintext
 | |
| 	 * byte is returned. If the record is correct but empty, then
 | |
| 	 * `*len` is set to 0 and a non-`NULL` pointer is returned.
 | |
| 	 *
 | |
| 	 * On decryption/MAC error, `NULL` is returned.
 | |
| 	 *
 | |
| 	 * \param ctx           decryption engine context.
 | |
| 	 * \param record_type   record type (23 for application data, etc).
 | |
| 	 * \param version       record version.
 | |
| 	 * \param payload       address of encrypted payload.
 | |
| 	 * \param len           pointer to payload length (updated).
 | |
| 	 * \return  pointer to plaintext, or `NULL` on error.
 | |
| 	 */
 | |
| 	unsigned char *(*decrypt)(const br_sslrec_in_class **ctx,
 | |
| 		int record_type, unsigned version,
 | |
| 		void *payload, size_t *len);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * \brief Encryption engine for SSL.
 | |
|  *
 | |
|  * When building outgoing records, the SSL engine will use an encryption
 | |
|  * engine that uses a specific context structure, and has a set of
 | |
|  * methods (a vtable) that follows this template.
 | |
|  *
 | |
|  * The encryption engine is responsible for applying encryption and MAC,
 | |
|  * and keeping track of the record sequence number.
 | |
|  */
 | |
| typedef struct br_sslrec_out_class_ br_sslrec_out_class;
 | |
| struct br_sslrec_out_class_ {
 | |
| 	/**
 | |
| 	 * \brief Context size (in bytes).
 | |
| 	 */
 | |
| 	size_t context_size;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Compute maximum plaintext sizes and offsets.
 | |
| 	 *
 | |
| 	 * When this function is called, the `*start` and `*end`
 | |
| 	 * values contain offsets designating the free area in the
 | |
| 	 * outgoing buffer for plaintext data; that free area is
 | |
| 	 * preceded by a 5-byte space which will receive the record
 | |
| 	 * header.
 | |
| 	 *
 | |
| 	 * The `max_plaintext()` function is responsible for adjusting
 | |
| 	 * both `*start` and `*end` to make room for any record-specific
 | |
| 	 * header, MAC, padding, and possible split.
 | |
| 	 *
 | |
| 	 * \param ctx     encryption engine context.
 | |
| 	 * \param start   pointer to start of plaintext offset (updated).
 | |
| 	 * \param end     pointer to start of plaintext offset (updated).
 | |
| 	 */
 | |
| 	void (*max_plaintext)(const br_sslrec_out_class *const *ctx,
 | |
| 		size_t *start, size_t *end);
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Perform record encryption.
 | |
| 	 *
 | |
| 	 * This function encrypts the record. The plaintext address and
 | |
| 	 * length are provided. Returned value is the start of the
 | |
| 	 * encrypted record (or sequence of records, if a split was
 | |
| 	 * performed), _including_ the 5-byte header, and `*len` is
 | |
| 	 * adjusted to the total size of the record(s), there again
 | |
| 	 * including the header(s).
 | |
| 	 *
 | |
| 	 * \param ctx           decryption engine context.
 | |
| 	 * \param record_type   record type (23 for application data, etc).
 | |
| 	 * \param version       record version.
 | |
| 	 * \param plaintext     address of plaintext.
 | |
| 	 * \param len           pointer to plaintext length (updated).
 | |
| 	 * \return  pointer to start of built record.
 | |
| 	 */
 | |
| 	unsigned char *(*encrypt)(const br_sslrec_out_class **ctx,
 | |
| 		int record_type, unsigned version,
 | |
| 		void *plaintext, size_t *len);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * \brief Context for a no-encryption engine.
 | |
|  *
 | |
|  * The no-encryption engine processes outgoing records during the initial
 | |
|  * handshake, before encryption is applied.
 | |
|  */
 | |
| typedef struct {
 | |
| 	/** \brief No-encryption engine vtable. */
 | |
| 	const br_sslrec_out_class *vtable;
 | |
| } br_sslrec_out_clear_context;
 | |
| 
 | |
| /** \brief Static, constant vtable for the no-encryption engine. */
 | |
| extern const br_sslrec_out_class br_sslrec_out_clear_vtable;
 | |
| 
 | |
| /* ===================================================================== */
 | |
| 
 | |
| /**
 | |
|  * \brief Record decryption engine class, for CBC mode.
 | |
|  *
 | |
|  * This class type extends the decryption engine class with an
 | |
|  * initialisation method that receives the parameters needed
 | |
|  * for CBC processing: block cipher implementation, block cipher key,
 | |
|  * HMAC parameters (hash function, key, MAC length), and IV. If the
 | |
|  * IV is `NULL`, then a per-record IV will be used (TLS 1.1+).
 | |
|  */
 | |
| typedef struct br_sslrec_in_cbc_class_ br_sslrec_in_cbc_class;
 | |
| struct br_sslrec_in_cbc_class_ {
 | |
| 	/**
 | |
| 	 * \brief Superclass, as first vtable field.
 | |
| 	 */
 | |
| 	br_sslrec_in_class inner;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Engine initialisation method.
 | |
| 	 *
 | |
| 	 * This method sets the vtable field in the context.
 | |
| 	 *
 | |
| 	 * \param ctx           context to initialise.
 | |
| 	 * \param bc_impl       block cipher implementation (CBC decryption).
 | |
| 	 * \param bc_key        block cipher key.
 | |
| 	 * \param bc_key_len    block cipher key length (in bytes).
 | |
| 	 * \param dig_impl      hash function for HMAC.
 | |
| 	 * \param mac_key       HMAC key.
 | |
| 	 * \param mac_key_len   HMAC key length (in bytes).
 | |
| 	 * \param mac_out_len   HMAC output length (in bytes).
 | |
| 	 * \param iv            initial IV (or `NULL`).
 | |
| 	 */
 | |
| 	void (*init)(const br_sslrec_in_cbc_class **ctx,
 | |
| 		const br_block_cbcdec_class *bc_impl,
 | |
| 		const void *bc_key, size_t bc_key_len,
 | |
| 		const br_hash_class *dig_impl,
 | |
| 		const void *mac_key, size_t mac_key_len, size_t mac_out_len,
 | |
| 		const void *iv);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * \brief Record encryption engine class, for CBC mode.
 | |
|  *
 | |
|  * This class type extends the encryption engine class with an
 | |
|  * initialisation method that receives the parameters needed
 | |
|  * for CBC processing: block cipher implementation, block cipher key,
 | |
|  * HMAC parameters (hash function, key, MAC length), and IV. If the
 | |
|  * IV is `NULL`, then a per-record IV will be used (TLS 1.1+).
 | |
|  */
 | |
| typedef struct br_sslrec_out_cbc_class_ br_sslrec_out_cbc_class;
 | |
| struct br_sslrec_out_cbc_class_ {
 | |
| 	/**
 | |
| 	 * \brief Superclass, as first vtable field.
 | |
| 	 */
 | |
| 	br_sslrec_out_class inner;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Engine initialisation method.
 | |
| 	 *
 | |
| 	 * This method sets the vtable field in the context.
 | |
| 	 *
 | |
| 	 * \param ctx           context to initialise.
 | |
| 	 * \param bc_impl       block cipher implementation (CBC encryption).
 | |
| 	 * \param bc_key        block cipher key.
 | |
| 	 * \param bc_key_len    block cipher key length (in bytes).
 | |
| 	 * \param dig_impl      hash function for HMAC.
 | |
| 	 * \param mac_key       HMAC key.
 | |
| 	 * \param mac_key_len   HMAC key length (in bytes).
 | |
| 	 * \param mac_out_len   HMAC output length (in bytes).
 | |
| 	 * \param iv            initial IV (or `NULL`).
 | |
| 	 */
 | |
| 	void (*init)(const br_sslrec_out_cbc_class **ctx,
 | |
| 		const br_block_cbcenc_class *bc_impl,
 | |
| 		const void *bc_key, size_t bc_key_len,
 | |
| 		const br_hash_class *dig_impl,
 | |
| 		const void *mac_key, size_t mac_key_len, size_t mac_out_len,
 | |
| 		const void *iv);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * \brief Context structure for decrypting incoming records with
 | |
|  * CBC + HMAC.
 | |
|  *
 | |
|  * The first field points to the vtable. The other fields are opaque
 | |
|  * and shall not be accessed directly.
 | |
|  */
 | |
| typedef struct {
 | |
| 	/** \brief Pointer to vtable. */
 | |
| 	const br_sslrec_in_cbc_class *vtable;
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| 	uint64_t seq;
 | |
| 	union {
 | |
| 		const br_block_cbcdec_class *vtable;
 | |
| 		br_aes_gen_cbcdec_keys aes;
 | |
| 		br_des_gen_cbcdec_keys des;
 | |
| 	} bc;
 | |
| 	br_hmac_key_context mac;
 | |
| 	size_t mac_len;
 | |
| 	unsigned char iv[16];
 | |
| 	int explicit_IV;
 | |
| #endif
 | |
| } br_sslrec_in_cbc_context;
 | |
| 
 | |
| /**
 | |
|  * \brief Static, constant vtable for record decryption with CBC.
 | |
|  */
 | |
| extern const br_sslrec_in_cbc_class br_sslrec_in_cbc_vtable;
 | |
| 
 | |
| /**
 | |
|  * \brief Context structure for encrypting outgoing records with
 | |
|  * CBC + HMAC.
 | |
|  *
 | |
|  * The first field points to the vtable. The other fields are opaque
 | |
|  * and shall not be accessed directly.
 | |
|  */
 | |
| typedef struct {
 | |
| 	/** \brief Pointer to vtable. */
 | |
| 	const br_sslrec_out_cbc_class *vtable;
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| 	uint64_t seq;
 | |
| 	union {
 | |
| 		const br_block_cbcenc_class *vtable;
 | |
| 		br_aes_gen_cbcenc_keys aes;
 | |
| 		br_des_gen_cbcenc_keys des;
 | |
| 	} bc;
 | |
| 	br_hmac_key_context mac;
 | |
| 	size_t mac_len;
 | |
| 	unsigned char iv[16];
 | |
| 	int explicit_IV;
 | |
| #endif
 | |
| } br_sslrec_out_cbc_context;
 | |
| 
 | |
| /**
 | |
|  * \brief Static, constant vtable for record encryption with CBC.
 | |
|  */
 | |
| extern const br_sslrec_out_cbc_class br_sslrec_out_cbc_vtable;
 | |
| 
 | |
| /* ===================================================================== */
 | |
| 
 | |
| /**
 | |
|  * \brief Record decryption engine class, for GCM mode.
 | |
|  *
 | |
|  * This class type extends the decryption engine class with an
 | |
|  * initialisation method that receives the parameters needed
 | |
|  * for GCM processing: block cipher implementation, block cipher key,
 | |
|  * GHASH implementation, and 4-byte IV.
 | |
|  */
 | |
| typedef struct br_sslrec_in_gcm_class_ br_sslrec_in_gcm_class;
 | |
| struct br_sslrec_in_gcm_class_ {
 | |
| 	/**
 | |
| 	 * \brief Superclass, as first vtable field.
 | |
| 	 */
 | |
| 	br_sslrec_in_class inner;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Engine initialisation method.
 | |
| 	 *
 | |
| 	 * This method sets the vtable field in the context.
 | |
| 	 *
 | |
| 	 * \param ctx           context to initialise.
 | |
| 	 * \param bc_impl       block cipher implementation (CTR).
 | |
| 	 * \param key           block cipher key.
 | |
| 	 * \param key_len       block cipher key length (in bytes).
 | |
| 	 * \param gh_impl       GHASH implementation.
 | |
| 	 * \param iv            static IV (4 bytes).
 | |
| 	 */
 | |
| 	void (*init)(const br_sslrec_in_gcm_class **ctx,
 | |
| 		const br_block_ctr_class *bc_impl,
 | |
| 		const void *key, size_t key_len,
 | |
| 		br_ghash gh_impl,
 | |
| 		const void *iv);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * \brief Record encryption engine class, for GCM mode.
 | |
|  *
 | |
|  * This class type extends the encryption engine class with an
 | |
|  * initialisation method that receives the parameters needed
 | |
|  * for GCM processing: block cipher implementation, block cipher key,
 | |
|  * GHASH implementation, and 4-byte IV.
 | |
|  */
 | |
| typedef struct br_sslrec_out_gcm_class_ br_sslrec_out_gcm_class;
 | |
| struct br_sslrec_out_gcm_class_ {
 | |
| 	/**
 | |
| 	 * \brief Superclass, as first vtable field.
 | |
| 	 */
 | |
| 	br_sslrec_out_class inner;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Engine initialisation method.
 | |
| 	 *
 | |
| 	 * This method sets the vtable field in the context.
 | |
| 	 *
 | |
| 	 * \param ctx           context to initialise.
 | |
| 	 * \param bc_impl       block cipher implementation (CTR).
 | |
| 	 * \param key           block cipher key.
 | |
| 	 * \param key_len       block cipher key length (in bytes).
 | |
| 	 * \param gh_impl       GHASH implementation.
 | |
| 	 * \param iv            static IV (4 bytes).
 | |
| 	 */
 | |
| 	void (*init)(const br_sslrec_out_gcm_class **ctx,
 | |
| 		const br_block_ctr_class *bc_impl,
 | |
| 		const void *key, size_t key_len,
 | |
| 		br_ghash gh_impl,
 | |
| 		const void *iv);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * \brief Context structure for processing records with GCM.
 | |
|  *
 | |
|  * The same context structure is used for encrypting and decrypting.
 | |
|  *
 | |
|  * The first field points to the vtable. The other fields are opaque
 | |
|  * and shall not be accessed directly.
 | |
|  */
 | |
| typedef struct {
 | |
| 	/** \brief Pointer to vtable. */
 | |
| 	union {
 | |
| 		const void *gen;
 | |
| 		const br_sslrec_in_gcm_class *in;
 | |
| 		const br_sslrec_out_gcm_class *out;
 | |
| 	} vtable;
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| 	uint64_t seq;
 | |
| 	union {
 | |
| 		const br_block_ctr_class *vtable;
 | |
| 		br_aes_gen_ctr_keys aes;
 | |
| 	} bc;
 | |
| 	br_ghash gh;
 | |
| 	unsigned char iv[4];
 | |
| 	unsigned char h[16];
 | |
| #endif
 | |
| } br_sslrec_gcm_context;
 | |
| 
 | |
| /**
 | |
|  * \brief Static, constant vtable for record decryption with GCM.
 | |
|  */
 | |
| extern const br_sslrec_in_gcm_class br_sslrec_in_gcm_vtable;
 | |
| 
 | |
| /**
 | |
|  * \brief Static, constant vtable for record encryption with GCM.
 | |
|  */
 | |
| extern const br_sslrec_out_gcm_class br_sslrec_out_gcm_vtable;
 | |
| 
 | |
| /* ===================================================================== */
 | |
| 
 | |
| /**
 | |
|  * \brief Record decryption engine class, for ChaCha20+Poly1305.
 | |
|  *
 | |
|  * This class type extends the decryption engine class with an
 | |
|  * initialisation method that receives the parameters needed
 | |
|  * for ChaCha20+Poly1305 processing: ChaCha20 implementation,
 | |
|  * Poly1305 implementation, key, and 12-byte IV.
 | |
|  */
 | |
| typedef struct br_sslrec_in_chapol_class_ br_sslrec_in_chapol_class;
 | |
| struct br_sslrec_in_chapol_class_ {
 | |
| 	/**
 | |
| 	 * \brief Superclass, as first vtable field.
 | |
| 	 */
 | |
| 	br_sslrec_in_class inner;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Engine initialisation method.
 | |
| 	 *
 | |
| 	 * This method sets the vtable field in the context.
 | |
| 	 *
 | |
| 	 * \param ctx           context to initialise.
 | |
| 	 * \param ichacha       ChaCha20 implementation.
 | |
| 	 * \param ipoly         Poly1305 implementation.
 | |
| 	 * \param key           secret key (32 bytes).
 | |
| 	 * \param iv            static IV (12 bytes).
 | |
| 	 */
 | |
| 	void (*init)(const br_sslrec_in_chapol_class **ctx,
 | |
| 		br_chacha20_run ichacha,
 | |
| 		br_poly1305_run ipoly,
 | |
| 		const void *key, const void *iv);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * \brief Record encryption engine class, for ChaCha20+Poly1305.
 | |
|  *
 | |
|  * This class type extends the encryption engine class with an
 | |
|  * initialisation method that receives the parameters needed
 | |
|  * for ChaCha20+Poly1305 processing: ChaCha20 implementation,
 | |
|  * Poly1305 implementation, key, and 12-byte IV.
 | |
|  */
 | |
| typedef struct br_sslrec_out_chapol_class_ br_sslrec_out_chapol_class;
 | |
| struct br_sslrec_out_chapol_class_ {
 | |
| 	/**
 | |
| 	 * \brief Superclass, as first vtable field.
 | |
| 	 */
 | |
| 	br_sslrec_out_class inner;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Engine initialisation method.
 | |
| 	 *
 | |
| 	 * This method sets the vtable field in the context.
 | |
| 	 *
 | |
| 	 * \param ctx           context to initialise.
 | |
| 	 * \param ichacha       ChaCha20 implementation.
 | |
| 	 * \param ipoly         Poly1305 implementation.
 | |
| 	 * \param key           secret key (32 bytes).
 | |
| 	 * \param iv            static IV (12 bytes).
 | |
| 	 */
 | |
| 	void (*init)(const br_sslrec_out_chapol_class **ctx,
 | |
| 		br_chacha20_run ichacha,
 | |
| 		br_poly1305_run ipoly,
 | |
| 		const void *key, const void *iv);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * \brief Context structure for processing records with ChaCha20+Poly1305.
 | |
|  *
 | |
|  * The same context structure is used for encrypting and decrypting.
 | |
|  *
 | |
|  * The first field points to the vtable. The other fields are opaque
 | |
|  * and shall not be accessed directly.
 | |
|  */
 | |
| typedef struct {
 | |
| 	/** \brief Pointer to vtable. */
 | |
| 	union {
 | |
| 		const void *gen;
 | |
| 		const br_sslrec_in_chapol_class *in;
 | |
| 		const br_sslrec_out_chapol_class *out;
 | |
| 	} vtable;
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| 	uint64_t seq;
 | |
| 	unsigned char key[32];
 | |
| 	unsigned char iv[12];
 | |
| 	br_chacha20_run ichacha;
 | |
| 	br_poly1305_run ipoly;
 | |
| #endif
 | |
| } br_sslrec_chapol_context;
 | |
| 
 | |
| /**
 | |
|  * \brief Static, constant vtable for record decryption with ChaCha20+Poly1305.
 | |
|  */
 | |
| extern const br_sslrec_in_chapol_class br_sslrec_in_chapol_vtable;
 | |
| 
 | |
| /**
 | |
|  * \brief Static, constant vtable for record encryption with ChaCha20+Poly1305.
 | |
|  */
 | |
| extern const br_sslrec_out_chapol_class br_sslrec_out_chapol_vtable;
 | |
| 
 | |
| /* ===================================================================== */
 | |
| 
 | |
| /**
 | |
|  * \brief Record decryption engine class, for CCM mode.
 | |
|  *
 | |
|  * This class type extends the decryption engine class with an
 | |
|  * initialisation method that receives the parameters needed
 | |
|  * for CCM processing: block cipher implementation, block cipher key,
 | |
|  * and 4-byte IV.
 | |
|  */
 | |
| typedef struct br_sslrec_in_ccm_class_ br_sslrec_in_ccm_class;
 | |
| struct br_sslrec_in_ccm_class_ {
 | |
| 	/**
 | |
| 	 * \brief Superclass, as first vtable field.
 | |
| 	 */
 | |
| 	br_sslrec_in_class inner;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Engine initialisation method.
 | |
| 	 *
 | |
| 	 * This method sets the vtable field in the context.
 | |
| 	 *
 | |
| 	 * \param ctx           context to initialise.
 | |
| 	 * \param bc_impl       block cipher implementation (CTR+CBC).
 | |
| 	 * \param key           block cipher key.
 | |
| 	 * \param key_len       block cipher key length (in bytes).
 | |
| 	 * \param iv            static IV (4 bytes).
 | |
| 	 * \param tag_len       tag length (in bytes)
 | |
| 	 */
 | |
| 	void (*init)(const br_sslrec_in_ccm_class **ctx,
 | |
| 		const br_block_ctrcbc_class *bc_impl,
 | |
| 		const void *key, size_t key_len,
 | |
| 		const void *iv, size_t tag_len);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * \brief Record encryption engine class, for CCM mode.
 | |
|  *
 | |
|  * This class type extends the encryption engine class with an
 | |
|  * initialisation method that receives the parameters needed
 | |
|  * for CCM processing: block cipher implementation, block cipher key,
 | |
|  * and 4-byte IV.
 | |
|  */
 | |
| typedef struct br_sslrec_out_ccm_class_ br_sslrec_out_ccm_class;
 | |
| struct br_sslrec_out_ccm_class_ {
 | |
| 	/**
 | |
| 	 * \brief Superclass, as first vtable field.
 | |
| 	 */
 | |
| 	br_sslrec_out_class inner;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Engine initialisation method.
 | |
| 	 *
 | |
| 	 * This method sets the vtable field in the context.
 | |
| 	 *
 | |
| 	 * \param ctx           context to initialise.
 | |
| 	 * \param bc_impl       block cipher implementation (CTR+CBC).
 | |
| 	 * \param key           block cipher key.
 | |
| 	 * \param key_len       block cipher key length (in bytes).
 | |
| 	 * \param iv            static IV (4 bytes).
 | |
| 	 * \param tag_len       tag length (in bytes)
 | |
| 	 */
 | |
| 	void (*init)(const br_sslrec_out_ccm_class **ctx,
 | |
| 		const br_block_ctrcbc_class *bc_impl,
 | |
| 		const void *key, size_t key_len,
 | |
| 		const void *iv, size_t tag_len);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * \brief Context structure for processing records with CCM.
 | |
|  *
 | |
|  * The same context structure is used for encrypting and decrypting.
 | |
|  *
 | |
|  * The first field points to the vtable. The other fields are opaque
 | |
|  * and shall not be accessed directly.
 | |
|  */
 | |
| typedef struct {
 | |
| 	/** \brief Pointer to vtable. */
 | |
| 	union {
 | |
| 		const void *gen;
 | |
| 		const br_sslrec_in_ccm_class *in;
 | |
| 		const br_sslrec_out_ccm_class *out;
 | |
| 	} vtable;
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| 	uint64_t seq;
 | |
| 	union {
 | |
| 		const br_block_ctrcbc_class *vtable;
 | |
| 		br_aes_gen_ctrcbc_keys aes;
 | |
| 	} bc;
 | |
| 	unsigned char iv[4];
 | |
| 	size_t tag_len;
 | |
| #endif
 | |
| } br_sslrec_ccm_context;
 | |
| 
 | |
| /**
 | |
|  * \brief Static, constant vtable for record decryption with CCM.
 | |
|  */
 | |
| extern const br_sslrec_in_ccm_class br_sslrec_in_ccm_vtable;
 | |
| 
 | |
| /**
 | |
|  * \brief Static, constant vtable for record encryption with CCM.
 | |
|  */
 | |
| extern const br_sslrec_out_ccm_class br_sslrec_out_ccm_vtable;
 | |
| 
 | |
| /* ===================================================================== */
 | |
| 
 | |
| /**
 | |
|  * \brief Type for session parameters, to be saved for session resumption.
 | |
|  */
 | |
| typedef struct {
 | |
| 	/** \brief Session ID buffer. */
 | |
| 	unsigned char session_id[32];
 | |
| 	/** \brief Session ID length (in bytes, at most 32). */
 | |
| 	unsigned char session_id_len;
 | |
| 	/** \brief Protocol version. */
 | |
| 	uint16_t version;
 | |
| 	/** \brief Cipher suite. */
 | |
| 	uint16_t cipher_suite;
 | |
| 	/** \brief Master secret. */
 | |
| 	unsigned char master_secret[48];
 | |
| } br_ssl_session_parameters;
 | |
| 
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| /*
 | |
|  * Maximum number of cipher suites supported by a client or server.
 | |
|  */
 | |
| #define BR_MAX_CIPHER_SUITES   48
 | |
| #endif
 | |
| 
 | |
| /**
 | |
|  * \brief Context structure for SSL engine.
 | |
|  *
 | |
|  * This strucuture is common to the client and server; both the client
 | |
|  * context (`br_ssl_client_context`) and the server context
 | |
|  * (`br_ssl_server_context`) include a `br_ssl_engine_context` as their
 | |
|  * first field.
 | |
|  *
 | |
|  * The engine context manages records, including alerts, closures, and
 | |
|  * transitions to new encryption/MAC algorithms. Processing of handshake
 | |
|  * records is delegated to externally provided code. This structure
 | |
|  * should not be used directly.
 | |
|  *
 | |
|  * Structure contents are opaque and shall not be accessed directly.
 | |
|  */
 | |
| typedef struct {
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| 	/*
 | |
| 	 * The error code. When non-zero, then the state is "failed" and
 | |
| 	 * no I/O may occur until reset.
 | |
| 	 */
 | |
| 	int err;
 | |
| 
 | |
| 	/*
 | |
| 	 * Configured I/O buffers. They are either disjoint, or identical.
 | |
| 	 */
 | |
| 	unsigned char *ibuf, *obuf;
 | |
| 	size_t ibuf_len, obuf_len;
 | |
| 
 | |
| 	/*
 | |
| 	 * Maximum fragment length applies to outgoing records; incoming
 | |
| 	 * records can be processed as long as they fit in the input
 | |
| 	 * buffer. It is guaranteed that incoming records at least as big
 | |
| 	 * as max_frag_len can be processed.
 | |
| 	 */
 | |
| 	uint16_t max_frag_len;
 | |
| 	unsigned char log_max_frag_len;
 | |
| 	unsigned char max_frag_len_negotiated;
 | |
| 	unsigned char peer_log_max_frag_len;
 | |
| 
 | |
| 	/*
 | |
| 	 * Buffering management registers.
 | |
| 	 */
 | |
| 	size_t ixa, ixb, ixc;
 | |
| 	size_t oxa, oxb, oxc;
 | |
| 	unsigned char iomode;
 | |
| 	unsigned char incrypt;
 | |
| 
 | |
| 	/*
 | |
| 	 * Shutdown flag: when set to non-zero, incoming record bytes
 | |
| 	 * will not be accepted anymore. This is used after a close_notify
 | |
| 	 * has been received: afterwards, the engine no longer claims that
 | |
| 	 * it could receive bytes from the transport medium.
 | |
| 	 */
 | |
| 	unsigned char shutdown_recv;
 | |
| 
 | |
| 	/*
 | |
| 	 * 'record_type_in' is set to the incoming record type when the
 | |
| 	 * record header has been received.
 | |
| 	 * 'record_type_out' is used to make the next outgoing record
 | |
| 	 * header when it is ready to go.
 | |
| 	 */
 | |
| 	unsigned char record_type_in, record_type_out;
 | |
| 
 | |
| 	/*
 | |
| 	 * When a record is received, its version is extracted:
 | |
| 	 * -- if 'version_in' is 0, then it is set to the received version;
 | |
| 	 * -- otherwise, if the received version is not identical to
 | |
| 	 *    the 'version_in' contents, then a failure is reported.
 | |
| 	 *
 | |
| 	 * This implements the SSL requirement that all records shall
 | |
| 	 * use the negotiated protocol version, once decided (in the
 | |
| 	 * ServerHello). It is up to the handshake handler to adjust this
 | |
| 	 * field when necessary.
 | |
| 	 */
 | |
| 	uint16_t version_in;
 | |
| 
 | |
| 	/*
 | |
| 	 * 'version_out' is used when the next outgoing record is ready
 | |
| 	 * to go.
 | |
| 	 */
 | |
| 	uint16_t version_out;
 | |
| 
 | |
| 	/*
 | |
| 	 * Record handler contexts.
 | |
| 	 */
 | |
| 	union {
 | |
| 		const br_sslrec_in_class *vtable;
 | |
| 		br_sslrec_in_cbc_context cbc;
 | |
| 		br_sslrec_gcm_context gcm;
 | |
| 		br_sslrec_chapol_context chapol;
 | |
| 		br_sslrec_ccm_context ccm;
 | |
| 	} in;
 | |
| 	union {
 | |
| 		const br_sslrec_out_class *vtable;
 | |
| 		br_sslrec_out_clear_context clear;
 | |
| 		br_sslrec_out_cbc_context cbc;
 | |
| 		br_sslrec_gcm_context gcm;
 | |
| 		br_sslrec_chapol_context chapol;
 | |
| 		br_sslrec_ccm_context ccm;
 | |
| 	} out;
 | |
| 
 | |
| 	/*
 | |
| 	 * The "application data" flag. Value:
 | |
| 	 *   0   handshake is in process, no application data acceptable
 | |
| 	 *   1   application data can be sent and received
 | |
| 	 *   2   closing, no application data can be sent, but some
 | |
| 	 *       can still be received (and discarded)
 | |
| 	 */
 | |
| 	unsigned char application_data;
 | |
| 
 | |
| 	/*
 | |
| 	 * Context RNG.
 | |
| 	 *
 | |
| 	 *   rng_init_done is initially 0. It is set to 1 when the
 | |
| 	 *   basic structure of the RNG is set, and 2 when some
 | |
| 	 *   entropy has been pushed in. The value 2 marks the RNG
 | |
| 	 *   as "properly seeded".
 | |
| 	 *
 | |
| 	 *   rng_os_rand_done is initially 0. It is set to 1 when
 | |
| 	 *   some seeding from the OS or hardware has been attempted.
 | |
| 	 */
 | |
| 	br_hmac_drbg_context rng;
 | |
| 	int rng_init_done;
 | |
| 	int rng_os_rand_done;
 | |
| 
 | |
| 	/*
 | |
| 	 * Supported minimum and maximum versions, and cipher suites.
 | |
| 	 */
 | |
| 	uint16_t version_min;
 | |
| 	uint16_t version_max;
 | |
| 	uint16_t suites_buf[BR_MAX_CIPHER_SUITES];
 | |
| 	unsigned char suites_num;
 | |
| 
 | |
| 	/*
 | |
| 	 * For clients, the server name to send as a SNI extension. For
 | |
| 	 * servers, the name received in the SNI extension (if any).
 | |
| 	 */
 | |
| 	char server_name[256];
 | |
| 
 | |
| 	/*
 | |
| 	 * "Security parameters". These are filled by the handshake
 | |
| 	 * handler, and used when switching encryption state.
 | |
| 	 */
 | |
| 	unsigned char client_random[32];
 | |
| 	unsigned char server_random[32];
 | |
| 	br_ssl_session_parameters session;
 | |
| 
 | |
| 	/*
 | |
| 	 * ECDHE elements: curve and point from the peer. The server also
 | |
| 	 * uses that buffer for the point to send to the client.
 | |
| 	 */
 | |
| 	unsigned char ecdhe_curve;
 | |
| 	unsigned char ecdhe_point[133];
 | |
| 	unsigned char ecdhe_point_len;
 | |
| 
 | |
| 	/*
 | |
| 	 * Secure renegotiation (RFC 5746): 'reneg' can be:
 | |
| 	 *   0   first handshake (server support is not known)
 | |
| 	 *   1   peer does not support secure renegotiation
 | |
| 	 *   2   peer supports secure renegotiation
 | |
| 	 *
 | |
| 	 * The saved_finished buffer contains the client and the
 | |
| 	 * server "Finished" values from the last handshake, in
 | |
| 	 * that order (12 bytes each).
 | |
| 	 */
 | |
| 	unsigned char reneg;
 | |
| 	unsigned char saved_finished[24];
 | |
| 
 | |
| 	/*
 | |
| 	 * Behavioural flags.
 | |
| 	 */
 | |
| 	uint32_t flags;
 | |
| 
 | |
| 	/*
 | |
| 	 * Context variables for the handshake processor. The 'pad' must
 | |
| 	 * be large enough to accommodate an RSA-encrypted pre-master
 | |
| 	 * secret, or an RSA signature; since we want to support up to
 | |
| 	 * RSA-4096, this means at least 512 bytes. (Other pad usages
 | |
| 	 * require its length to be at least 256.)
 | |
| 	 */
 | |
| 	struct {
 | |
| 		uint32_t *dp;
 | |
| 		uint32_t *rp;
 | |
| 		const unsigned char *ip;
 | |
| 	} cpu;
 | |
| 	uint32_t dp_stack[32];
 | |
| 	uint32_t rp_stack[32];
 | |
| 	unsigned char pad[512];
 | |
| 	unsigned char *hbuf_in, *hbuf_out, *saved_hbuf_out;
 | |
| 	size_t hlen_in, hlen_out;
 | |
| 	void (*hsrun)(void *ctx);
 | |
| 
 | |
| 	/*
 | |
| 	 * The 'action' value communicates OOB information between the
 | |
| 	 * engine and the handshake processor.
 | |
| 	 *
 | |
| 	 * From the engine:
 | |
| 	 *   0  invocation triggered by I/O
 | |
| 	 *   1  invocation triggered by explicit close
 | |
| 	 *   2  invocation triggered by explicit renegotiation
 | |
| 	 */
 | |
| 	unsigned char action;
 | |
| 
 | |
| 	/*
 | |
| 	 * State for alert messages. Value is either 0, or the value of
 | |
| 	 * the alert level byte (level is either 1 for warning, or 2 for
 | |
| 	 * fatal; we convert all other values to 'fatal').
 | |
| 	 */
 | |
| 	unsigned char alert;
 | |
| 
 | |
| 	/*
 | |
| 	 * Closure flags. This flag is set when a close_notify has been
 | |
| 	 * received from the peer.
 | |
| 	 */
 | |
| 	unsigned char close_received;
 | |
| 
 | |
| 	/*
 | |
| 	 * Multi-hasher for the handshake messages. The handshake handler
 | |
| 	 * is responsible for resetting it when appropriate.
 | |
| 	 */
 | |
| 	br_multihash_context mhash;
 | |
| 
 | |
| 	/*
 | |
| 	 * Pointer to the X.509 engine. The engine is supposed to be
 | |
| 	 * already initialized. It is used to validate the peer's
 | |
| 	 * certificate.
 | |
| 	 */
 | |
| 	const br_x509_class **x509ctx;
 | |
| 
 | |
| 	/*
 | |
| 	 * Certificate chain to send. This is used by both client and
 | |
| 	 * server, when they send their respective Certificate messages.
 | |
| 	 * If chain_len is 0, then chain may be NULL.
 | |
| 	 */
 | |
| 	const br_x509_certificate *chain;
 | |
| 	size_t chain_len;
 | |
| 	const unsigned char *cert_cur;
 | |
| 	size_t cert_len;
 | |
| 
 | |
| 	/*
 | |
| 	 * List of supported protocol names (ALPN extension). If unset,
 | |
| 	 * (number of names is 0), then:
 | |
| 	 *  - the client sends no ALPN extension;
 | |
| 	 *  - the server ignores any incoming ALPN extension.
 | |
| 	 *
 | |
| 	 * Otherwise:
 | |
| 	 *  - the client sends an ALPN extension with all the names;
 | |
| 	 *  - the server selects the first protocol in its list that
 | |
| 	 *    the client also supports, or fails (fatal alert 120)
 | |
| 	 *    if the client sends an ALPN extension and there is no
 | |
| 	 *    match.
 | |
| 	 *
 | |
| 	 * The 'selected_protocol' field contains 1+n if the matching
 | |
| 	 * name has index n in the list (the value is 0 if no match was
 | |
| 	 * performed, e.g. the peer did not send an ALPN extension).
 | |
| 	 */
 | |
| 	const char **protocol_names;
 | |
| 	uint16_t protocol_names_num;
 | |
| 	uint16_t selected_protocol;
 | |
| 
 | |
| 	/*
 | |
| 	 * Pointers to implementations; left to NULL for unsupported
 | |
| 	 * functions. For the raw hash functions, implementations are
 | |
| 	 * referenced from the multihasher (mhash field).
 | |
| 	 */
 | |
| 	br_tls_prf_impl prf10;
 | |
| 	br_tls_prf_impl prf_sha256;
 | |
| 	br_tls_prf_impl prf_sha384;
 | |
| 	const br_block_cbcenc_class *iaes_cbcenc;
 | |
| 	const br_block_cbcdec_class *iaes_cbcdec;
 | |
| 	const br_block_ctr_class *iaes_ctr;
 | |
| 	const br_block_ctrcbc_class *iaes_ctrcbc;
 | |
| 	const br_block_cbcenc_class *ides_cbcenc;
 | |
| 	const br_block_cbcdec_class *ides_cbcdec;
 | |
| 	br_ghash ighash;
 | |
| 	br_chacha20_run ichacha;
 | |
| 	br_poly1305_run ipoly;
 | |
| 	const br_sslrec_in_cbc_class *icbc_in;
 | |
| 	const br_sslrec_out_cbc_class *icbc_out;
 | |
| 	const br_sslrec_in_gcm_class *igcm_in;
 | |
| 	const br_sslrec_out_gcm_class *igcm_out;
 | |
| 	const br_sslrec_in_chapol_class *ichapol_in;
 | |
| 	const br_sslrec_out_chapol_class *ichapol_out;
 | |
| 	const br_sslrec_in_ccm_class *iccm_in;
 | |
| 	const br_sslrec_out_ccm_class *iccm_out;
 | |
| 	const br_ec_impl *iec;
 | |
| 	br_rsa_pkcs1_vrfy irsavrfy;
 | |
| 	br_ecdsa_vrfy iecdsa;
 | |
| #endif
 | |
| } br_ssl_engine_context;
 | |
| 
 | |
| /**
 | |
|  * \brief Get currently defined engine behavioural flags.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  * \return  the flags.
 | |
|  */
 | |
| static inline uint32_t
 | |
| br_ssl_engine_get_flags(br_ssl_engine_context *cc)
 | |
| {
 | |
| 	return cc->flags;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set all engine behavioural flags.
 | |
|  *
 | |
|  * \param cc      SSL engine context.
 | |
|  * \param flags   new value for all flags.
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_all_flags(br_ssl_engine_context *cc, uint32_t flags)
 | |
| {
 | |
| 	cc->flags = flags;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set some engine behavioural flags.
 | |
|  *
 | |
|  * The flags set in the `flags` parameter are set in the context; other
 | |
|  * flags are untouched.
 | |
|  *
 | |
|  * \param cc      SSL engine context.
 | |
|  * \param flags   additional set flags.
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_add_flags(br_ssl_engine_context *cc, uint32_t flags)
 | |
| {
 | |
| 	cc->flags |= flags;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Clear some engine behavioural flags.
 | |
|  *
 | |
|  * The flags set in the `flags` parameter are cleared from the context; other
 | |
|  * flags are untouched.
 | |
|  *
 | |
|  * \param cc      SSL engine context.
 | |
|  * \param flags   flags to remove.
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_remove_flags(br_ssl_engine_context *cc, uint32_t flags)
 | |
| {
 | |
| 	cc->flags &= ~flags;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Behavioural flag: enforce server preferences.
 | |
|  *
 | |
|  * If this flag is set, then the server will enforce its own cipher suite
 | |
|  * preference order; otherwise, it follows the client preferences.
 | |
|  */
 | |
| #define BR_OPT_ENFORCE_SERVER_PREFERENCES      ((uint32_t)1 << 0)
 | |
| 
 | |
| /**
 | |
|  * \brief Behavioural flag: disable renegotiation.
 | |
|  *
 | |
|  * If this flag is set, then renegotiations are rejected unconditionally:
 | |
|  * they won't be honoured if asked for programmatically, and requests from
 | |
|  * the peer are rejected.
 | |
|  */
 | |
| #define BR_OPT_NO_RENEGOTIATION                ((uint32_t)1 << 1)
 | |
| 
 | |
| /**
 | |
|  * \brief Behavioural flag: tolerate lack of client authentication.
 | |
|  *
 | |
|  * If this flag is set in a server and the server requests a client
 | |
|  * certificate, but the authentication fails (the client does not send
 | |
|  * a certificate, or the client's certificate chain cannot be validated),
 | |
|  * then the connection keeps on. Without this flag, a failed client
 | |
|  * authentication terminates the connection.
 | |
|  *
 | |
|  * Notes:
 | |
|  *
 | |
|  *   - If the client's certificate can be validated and its public key is
 | |
|  *     supported, then a wrong signature value terminates the connection
 | |
|  *     regardless of that flag.
 | |
|  *
 | |
|  *   - If using full-static ECDH, then a failure to validate the client's
 | |
|  *     certificate prevents the handshake from succeeding.
 | |
|  */
 | |
| #define BR_OPT_TOLERATE_NO_CLIENT_AUTH         ((uint32_t)1 << 2)
 | |
| 
 | |
| /**
 | |
|  * \brief Behavioural flag: fail on application protocol mismatch.
 | |
|  *
 | |
|  * The ALPN extension ([RFC 7301](https://tools.ietf.org/html/rfc7301))
 | |
|  * allows the client to send a list of application protocol names, and
 | |
|  * the server to select one. A mismatch is one of the following occurrences:
 | |
|  *
 | |
|  *   - On the client: the client sends a list of names, the server
 | |
|  *     responds with a protocol name which is _not_ part of the list of
 | |
|  *     names sent by the client.
 | |
|  *
 | |
|  *   - On the server: the client sends a list of names, and the server
 | |
|  *     is also configured with a list of names, but there is no common
 | |
|  *     protocol name between the two lists.
 | |
|  *
 | |
|  * Normal behaviour in case of mismatch is to report no matching name
 | |
|  * (`br_ssl_engine_get_selected_protocol()` returns `NULL`) and carry on.
 | |
|  * If the flag is set, then a mismatch implies a protocol failure (if
 | |
|  * the mismatch is detected by the server, it will send a fatal alert).
 | |
|  *
 | |
|  * Note: even with this flag, `br_ssl_engine_get_selected_protocol()`
 | |
|  * may still return `NULL` if the client or the server does not send an
 | |
|  * ALPN extension at all.
 | |
|  */
 | |
| #define BR_OPT_FAIL_ON_ALPN_MISMATCH           ((uint32_t)1 << 3)
 | |
| 
 | |
| /**
 | |
|  * \brief Set the minimum and maximum supported protocol versions.
 | |
|  *
 | |
|  * The two provided versions MUST be supported by the implementation
 | |
|  * (i.e. TLS 1.0, 1.1 and 1.2), and `version_max` MUST NOT be lower
 | |
|  * than `version_min`.
 | |
|  *
 | |
|  * \param cc            SSL engine context.
 | |
|  * \param version_min   minimum supported TLS version.
 | |
|  * \param version_max   maximum supported TLS version.
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_versions(br_ssl_engine_context *cc,
 | |
| 	unsigned version_min, unsigned version_max)
 | |
| {
 | |
| 	cc->version_min = (uint16_t)version_min;
 | |
| 	cc->version_max = (uint16_t)version_max;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the list of cipher suites advertised by this context.
 | |
|  *
 | |
|  * The provided array is copied into the context. It is the caller
 | |
|  * responsibility to ensure that all provided suites will be supported
 | |
|  * by the context. The engine context has enough room to receive _all_
 | |
|  * suites supported by the implementation. The provided array MUST NOT
 | |
|  * contain duplicates.
 | |
|  *
 | |
|  * If the engine is for a client, the "signaling" pseudo-cipher suite
 | |
|  * `TLS_FALLBACK_SCSV` can be added at the end of the list, if the
 | |
|  * calling application is performing a voluntary downgrade (voluntary
 | |
|  * downgrades are not recommended, but if such a downgrade is done, then
 | |
|  * adding the fallback pseudo-suite is a good idea).
 | |
|  *
 | |
|  * \param cc           SSL engine context.
 | |
|  * \param suites       cipher suites.
 | |
|  * \param suites_num   number of cipher suites.
 | |
|  */
 | |
| void br_ssl_engine_set_suites(br_ssl_engine_context *cc,
 | |
| 	const uint16_t *suites, size_t suites_num);
 | |
| 
 | |
| /**
 | |
|  * \brief Set the X.509 engine.
 | |
|  *
 | |
|  * The caller shall ensure that the X.509 engine is properly initialised.
 | |
|  *
 | |
|  * \param cc        SSL engine context.
 | |
|  * \param x509ctx   X.509 certificate validation context.
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_x509(br_ssl_engine_context *cc, const br_x509_class **x509ctx)
 | |
| {
 | |
| 	cc->x509ctx = x509ctx;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the supported protocol names.
 | |
|  *
 | |
|  * Protocol names are part of the ALPN extension ([RFC
 | |
|  * 7301](https://tools.ietf.org/html/rfc7301)). Each protocol name is a
 | |
|  * character string, containing no more than 255 characters (256 with the
 | |
|  * terminating zero). When names are set, then:
 | |
|  *
 | |
|  *   - The client will send an ALPN extension, containing the names. If
 | |
|  *     the server responds with an ALPN extension, the client will verify
 | |
|  *     that the response contains one of its name, and report that name
 | |
|  *     through `br_ssl_engine_get_selected_protocol()`.
 | |
|  *
 | |
|  *   - The server will parse incoming ALPN extension (from clients), and
 | |
|  *     try to find a common protocol; if none is found, the connection
 | |
|  *     is aborted with a fatal alert. On match, a response ALPN extension
 | |
|  *     is sent, and name is reported through
 | |
|  *     `br_ssl_engine_get_selected_protocol()`.
 | |
|  *
 | |
|  * The provided array is linked in, and must remain valid while the
 | |
|  * connection is live.
 | |
|  *
 | |
|  * Names MUST NOT be empty. Names MUST NOT be longer than 255 characters
 | |
|  * (excluding the terminating 0).
 | |
|  *
 | |
|  * \param ctx     SSL engine context.
 | |
|  * \param names   list of protocol names (zero-terminated).
 | |
|  * \param num     number of protocol names (MUST be 1 or more).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_protocol_names(br_ssl_engine_context *ctx,
 | |
| 	const char **names, size_t num)
 | |
| {
 | |
| 	ctx->protocol_names = names;
 | |
| 	ctx->protocol_names_num = (uint16_t)num;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Get the selected protocol.
 | |
|  *
 | |
|  * If this context was initialised with a non-empty list of protocol
 | |
|  * names, and both client and server sent ALPN extensions during the
 | |
|  * handshake, and a common name was found, then that name is returned.
 | |
|  * Otherwise, `NULL` is returned.
 | |
|  *
 | |
|  * The returned pointer is one of the pointers provided to the context
 | |
|  * with `br_ssl_engine_set_protocol_names()`.
 | |
|  *
 | |
|  * \return  the selected protocol, or `NULL`.
 | |
|  */
 | |
| static inline const char *
 | |
| br_ssl_engine_get_selected_protocol(br_ssl_engine_context *ctx)
 | |
| {
 | |
| 	unsigned k;
 | |
| 
 | |
| 	k = ctx->selected_protocol;
 | |
| 	return (k == 0 || k == 0xFFFF) ? NULL : ctx->protocol_names[k - 1];
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set a hash function implementation (by ID).
 | |
|  *
 | |
|  * Hash functions set with this call will be used for SSL/TLS specific
 | |
|  * usages, not X.509 certificate validation. Only "standard" hash functions
 | |
|  * may be set (MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512). If `impl`
 | |
|  * is `NULL`, then the hash function support is removed, not added.
 | |
|  *
 | |
|  * \param ctx    SSL engine context.
 | |
|  * \param id     hash function identifier.
 | |
|  * \param impl   hash function implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_hash(br_ssl_engine_context *ctx,
 | |
| 	int id, const br_hash_class *impl)
 | |
| {
 | |
| 	br_multihash_setimpl(&ctx->mhash, id, impl);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Get a hash function implementation (by ID).
 | |
|  *
 | |
|  * This function retrieves a hash function implementation which was
 | |
|  * set with `br_ssl_engine_set_hash()`.
 | |
|  *
 | |
|  * \param ctx   SSL engine context.
 | |
|  * \param id    hash function identifier.
 | |
|  * \return  the hash function implementation (or `NULL`).
 | |
|  */
 | |
| static inline const br_hash_class *
 | |
| br_ssl_engine_get_hash(br_ssl_engine_context *ctx, int id)
 | |
| {
 | |
| 	return br_multihash_getimpl(&ctx->mhash, id);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the PRF implementation (for TLS 1.0 and 1.1).
 | |
|  *
 | |
|  * This function sets (or removes, if `impl` is `NULL`) the implementation
 | |
|  * for the PRF used in TLS 1.0 and 1.1.
 | |
|  *
 | |
|  * \param cc     SSL engine context.
 | |
|  * \param impl   PRF implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_prf10(br_ssl_engine_context *cc, br_tls_prf_impl impl)
 | |
| {
 | |
| 	cc->prf10 = impl;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the PRF implementation with SHA-256 (for TLS 1.2).
 | |
|  *
 | |
|  * This function sets (or removes, if `impl` is `NULL`) the implementation
 | |
|  * for the SHA-256 variant of the PRF used in TLS 1.2.
 | |
|  *
 | |
|  * \param cc     SSL engine context.
 | |
|  * \param impl   PRF implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_prf_sha256(br_ssl_engine_context *cc, br_tls_prf_impl impl)
 | |
| {
 | |
| 	cc->prf_sha256 = impl;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the PRF implementation with SHA-384 (for TLS 1.2).
 | |
|  *
 | |
|  * This function sets (or removes, if `impl` is `NULL`) the implementation
 | |
|  * for the SHA-384 variant of the PRF used in TLS 1.2.
 | |
|  *
 | |
|  * \param cc     SSL engine context.
 | |
|  * \param impl   PRF implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_prf_sha384(br_ssl_engine_context *cc, br_tls_prf_impl impl)
 | |
| {
 | |
| 	cc->prf_sha384 = impl;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the AES/CBC implementations.
 | |
|  *
 | |
|  * \param cc         SSL engine context.
 | |
|  * \param impl_enc   AES/CBC encryption implementation (or `NULL`).
 | |
|  * \param impl_dec   AES/CBC decryption implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_aes_cbc(br_ssl_engine_context *cc,
 | |
| 	const br_block_cbcenc_class *impl_enc,
 | |
| 	const br_block_cbcdec_class *impl_dec)
 | |
| {
 | |
| 	cc->iaes_cbcenc = impl_enc;
 | |
| 	cc->iaes_cbcdec = impl_dec;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the "default" AES/CBC implementations.
 | |
|  *
 | |
|  * This function configures in the engine the AES implementations that
 | |
|  * should provide best runtime performance on the local system, while
 | |
|  * still being safe (in particular, constant-time). It also sets the
 | |
|  * handlers for CBC records.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  */
 | |
| void br_ssl_engine_set_default_aes_cbc(br_ssl_engine_context *cc);
 | |
| 
 | |
| /**
 | |
|  * \brief Set the AES/CTR implementation.
 | |
|  *
 | |
|  * \param cc     SSL engine context.
 | |
|  * \param impl   AES/CTR encryption/decryption implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_aes_ctr(br_ssl_engine_context *cc,
 | |
| 	const br_block_ctr_class *impl)
 | |
| {
 | |
| 	cc->iaes_ctr = impl;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the "default" implementations for AES/GCM (AES/CTR + GHASH).
 | |
|  *
 | |
|  * This function configures in the engine the AES/CTR and GHASH
 | |
|  * implementation that should provide best runtime performance on the local
 | |
|  * system, while still being safe (in particular, constant-time). It also
 | |
|  * sets the handlers for GCM records.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  */
 | |
| void br_ssl_engine_set_default_aes_gcm(br_ssl_engine_context *cc);
 | |
| 
 | |
| /**
 | |
|  * \brief Set the DES/CBC implementations.
 | |
|  *
 | |
|  * \param cc         SSL engine context.
 | |
|  * \param impl_enc   DES/CBC encryption implementation (or `NULL`).
 | |
|  * \param impl_dec   DES/CBC decryption implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_des_cbc(br_ssl_engine_context *cc,
 | |
| 	const br_block_cbcenc_class *impl_enc,
 | |
| 	const br_block_cbcdec_class *impl_dec)
 | |
| {
 | |
| 	cc->ides_cbcenc = impl_enc;
 | |
| 	cc->ides_cbcdec = impl_dec;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the "default" DES/CBC implementations.
 | |
|  *
 | |
|  * This function configures in the engine the DES implementations that
 | |
|  * should provide best runtime performance on the local system, while
 | |
|  * still being safe (in particular, constant-time). It also sets the
 | |
|  * handlers for CBC records.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  */
 | |
| void br_ssl_engine_set_default_des_cbc(br_ssl_engine_context *cc);
 | |
| 
 | |
| /**
 | |
|  * \brief Set the GHASH implementation (used in GCM mode).
 | |
|  *
 | |
|  * \param cc     SSL engine context.
 | |
|  * \param impl   GHASH implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_ghash(br_ssl_engine_context *cc, br_ghash impl)
 | |
| {
 | |
| 	cc->ighash = impl;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the ChaCha20 implementation.
 | |
|  *
 | |
|  * \param cc        SSL engine context.
 | |
|  * \param ichacha   ChaCha20 implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_chacha20(br_ssl_engine_context *cc,
 | |
| 	br_chacha20_run ichacha)
 | |
| {
 | |
| 	cc->ichacha = ichacha;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the Poly1305 implementation.
 | |
|  *
 | |
|  * \param cc      SSL engine context.
 | |
|  * \param ipoly   Poly1305 implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_poly1305(br_ssl_engine_context *cc,
 | |
| 	br_poly1305_run ipoly)
 | |
| {
 | |
| 	cc->ipoly = ipoly;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the "default" ChaCha20 and Poly1305 implementations.
 | |
|  *
 | |
|  * This function configures in the engine the ChaCha20 and Poly1305
 | |
|  * implementations that should provide best runtime performance on the
 | |
|  * local system, while still being safe (in particular, constant-time).
 | |
|  * It also sets the handlers for ChaCha20+Poly1305 records.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  */
 | |
| void br_ssl_engine_set_default_chapol(br_ssl_engine_context *cc);
 | |
| 
 | |
| /**
 | |
|  * \brief Set the AES/CTR+CBC implementation.
 | |
|  *
 | |
|  * \param cc     SSL engine context.
 | |
|  * \param impl   AES/CTR+CBC encryption/decryption implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_aes_ctrcbc(br_ssl_engine_context *cc,
 | |
| 	const br_block_ctrcbc_class *impl)
 | |
| {
 | |
| 	cc->iaes_ctrcbc = impl;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the "default" implementations for AES/CCM.
 | |
|  *
 | |
|  * This function configures in the engine the AES/CTR+CBC
 | |
|  * implementation that should provide best runtime performance on the local
 | |
|  * system, while still being safe (in particular, constant-time). It also
 | |
|  * sets the handlers for CCM records.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  */
 | |
| void br_ssl_engine_set_default_aes_ccm(br_ssl_engine_context *cc);
 | |
| 
 | |
| /**
 | |
|  * \brief Set the record encryption and decryption engines for CBC + HMAC.
 | |
|  *
 | |
|  * \param cc         SSL engine context.
 | |
|  * \param impl_in    record CBC decryption implementation (or `NULL`).
 | |
|  * \param impl_out   record CBC encryption implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_cbc(br_ssl_engine_context *cc,
 | |
| 	const br_sslrec_in_cbc_class *impl_in,
 | |
| 	const br_sslrec_out_cbc_class *impl_out)
 | |
| {
 | |
| 	cc->icbc_in = impl_in;
 | |
| 	cc->icbc_out = impl_out;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the record encryption and decryption engines for GCM.
 | |
|  *
 | |
|  * \param cc         SSL engine context.
 | |
|  * \param impl_in    record GCM decryption implementation (or `NULL`).
 | |
|  * \param impl_out   record GCM encryption implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_gcm(br_ssl_engine_context *cc,
 | |
| 	const br_sslrec_in_gcm_class *impl_in,
 | |
| 	const br_sslrec_out_gcm_class *impl_out)
 | |
| {
 | |
| 	cc->igcm_in = impl_in;
 | |
| 	cc->igcm_out = impl_out;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the record encryption and decryption engines for CCM.
 | |
|  *
 | |
|  * \param cc         SSL engine context.
 | |
|  * \param impl_in    record CCM decryption implementation (or `NULL`).
 | |
|  * \param impl_out   record CCM encryption implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_ccm(br_ssl_engine_context *cc,
 | |
| 	const br_sslrec_in_ccm_class *impl_in,
 | |
| 	const br_sslrec_out_ccm_class *impl_out)
 | |
| {
 | |
| 	cc->iccm_in = impl_in;
 | |
| 	cc->iccm_out = impl_out;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the record encryption and decryption engines for
 | |
|  * ChaCha20+Poly1305.
 | |
|  *
 | |
|  * \param cc         SSL engine context.
 | |
|  * \param impl_in    record ChaCha20 decryption implementation (or `NULL`).
 | |
|  * \param impl_out   record ChaCha20 encryption implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_chapol(br_ssl_engine_context *cc,
 | |
| 	const br_sslrec_in_chapol_class *impl_in,
 | |
| 	const br_sslrec_out_chapol_class *impl_out)
 | |
| {
 | |
| 	cc->ichapol_in = impl_in;
 | |
| 	cc->ichapol_out = impl_out;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the EC implementation.
 | |
|  *
 | |
|  * The elliptic curve implementation will be used for ECDH and ECDHE
 | |
|  * cipher suites, and for ECDSA support.
 | |
|  *
 | |
|  * \param cc    SSL engine context.
 | |
|  * \param iec   EC implementation (or `NULL`).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_ec(br_ssl_engine_context *cc, const br_ec_impl *iec)
 | |
| {
 | |
| 	cc->iec = iec;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the "default" EC implementation.
 | |
|  *
 | |
|  * This function sets the elliptic curve implementation for ECDH and
 | |
|  * ECDHE cipher suites, and for ECDSA support. It selects the fastest
 | |
|  * implementation on the current system.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  */
 | |
| void br_ssl_engine_set_default_ec(br_ssl_engine_context *cc);
 | |
| 
 | |
| /**
 | |
|  * \brief Get the EC implementation configured in the provided engine.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  * \return  the EC implementation.
 | |
|  */
 | |
| static inline const br_ec_impl *
 | |
| br_ssl_engine_get_ec(br_ssl_engine_context *cc)
 | |
| {
 | |
| 	return cc->iec;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the RSA signature verification implementation.
 | |
|  *
 | |
|  * On the client, this is used to verify the server's signature on its
 | |
|  * ServerKeyExchange message (for ECDHE_RSA cipher suites). On the server,
 | |
|  * this is used to verify the client's CertificateVerify message (if a
 | |
|  * client certificate is requested, and that certificate contains a RSA key).
 | |
|  *
 | |
|  * \param cc         SSL engine context.
 | |
|  * \param irsavrfy   RSA signature verification implementation.
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_rsavrfy(br_ssl_engine_context *cc, br_rsa_pkcs1_vrfy irsavrfy)
 | |
| {
 | |
| 	cc->irsavrfy = irsavrfy;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the "default" RSA implementation (signature verification).
 | |
|  *
 | |
|  * This function sets the RSA implementation (signature verification)
 | |
|  * to the fastest implementation available on the current platform.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  */
 | |
| void br_ssl_engine_set_default_rsavrfy(br_ssl_engine_context *cc);
 | |
| 
 | |
| /**
 | |
|  * \brief Get the RSA implementation (signature verification) configured
 | |
|  * in the provided engine.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  * \return  the RSA signature verification implementation.
 | |
|  */
 | |
| static inline br_rsa_pkcs1_vrfy
 | |
| br_ssl_engine_get_rsavrfy(br_ssl_engine_context *cc)
 | |
| {
 | |
| 	return cc->irsavrfy;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * \brief Set the ECDSA implementation (signature verification).
 | |
|  *
 | |
|  * On the client, this is used to verify the server's signature on its
 | |
|  * ServerKeyExchange message (for ECDHE_ECDSA cipher suites). On the server,
 | |
|  * this is used to verify the client's CertificateVerify message (if a
 | |
|  * client certificate is requested, that certificate contains an EC key,
 | |
|  * and full-static ECDH is not used).
 | |
|  *
 | |
|  * The ECDSA implementation will use the EC core implementation configured
 | |
|  * in the engine context.
 | |
|  *
 | |
|  * \param cc       client context.
 | |
|  * \param iecdsa   ECDSA verification implementation.
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_ecdsa(br_ssl_engine_context *cc, br_ecdsa_vrfy iecdsa)
 | |
| {
 | |
| 	cc->iecdsa = iecdsa;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the "default" ECDSA implementation (signature verification).
 | |
|  *
 | |
|  * This function sets the ECDSA implementation (signature verification)
 | |
|  * to the fastest implementation available on the current platform. This
 | |
|  * call also sets the elliptic curve implementation itself, there again
 | |
|  * to the fastest EC implementation available.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  */
 | |
| void br_ssl_engine_set_default_ecdsa(br_ssl_engine_context *cc);
 | |
| 
 | |
| /**
 | |
|  * \brief Get the ECDSA implementation (signature verification) configured
 | |
|  * in the provided engine.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  * \return  the ECDSA signature verification implementation.
 | |
|  */
 | |
| static inline br_ecdsa_vrfy
 | |
| br_ssl_engine_get_ecdsa(br_ssl_engine_context *cc)
 | |
| {
 | |
| 	return cc->iecdsa;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the I/O buffer for the SSL engine.
 | |
|  *
 | |
|  * Once this call has been made, `br_ssl_client_reset()` or
 | |
|  * `br_ssl_server_reset()` MUST be called before using the context.
 | |
|  *
 | |
|  * The provided buffer will be used as long as the engine context is
 | |
|  * used. The caller is responsible for keeping it available.
 | |
|  *
 | |
|  * If `bidi` is 0, then the engine will operate in half-duplex mode
 | |
|  * (it won't be able to send data while there is unprocessed incoming
 | |
|  * data in the buffer, and it won't be able to receive data while there
 | |
|  * is unsent data in the buffer). The optimal buffer size in half-duplex
 | |
|  * mode is `BR_SSL_BUFSIZE_MONO`; if the buffer is larger, then extra
 | |
|  * bytes are ignored. If the buffer is smaller, then this limits the
 | |
|  * capacity of the engine to support all allowed record sizes.
 | |
|  *
 | |
|  * If `bidi` is 1, then the engine will split the buffer into two
 | |
|  * parts, for separate handling of outgoing and incoming data. This
 | |
|  * enables full-duplex processing, but requires more RAM. The optimal
 | |
|  * buffer size in full-duplex mode is `BR_SSL_BUFSIZE_BIDI`; if the
 | |
|  * buffer is larger, then extra bytes are ignored. If the buffer is
 | |
|  * smaller, then the split will favour the incoming part, so that
 | |
|  * interoperability is maximised.
 | |
|  *
 | |
|  * \param cc          SSL engine context
 | |
|  * \param iobuf       I/O buffer.
 | |
|  * \param iobuf_len   I/O buffer length (in bytes).
 | |
|  * \param bidi        non-zero for full-duplex mode.
 | |
|  */
 | |
| void br_ssl_engine_set_buffer(br_ssl_engine_context *cc,
 | |
| 	void *iobuf, size_t iobuf_len, int bidi);
 | |
| 
 | |
| /**
 | |
|  * \brief Set the I/O buffers for the SSL engine.
 | |
|  *
 | |
|  * Once this call has been made, `br_ssl_client_reset()` or
 | |
|  * `br_ssl_server_reset()` MUST be called before using the context.
 | |
|  *
 | |
|  * This function is similar to `br_ssl_engine_set_buffer()`, except
 | |
|  * that it enforces full-duplex mode, and the two I/O buffers are
 | |
|  * provided as separate chunks.
 | |
|  *
 | |
|  * The macros `BR_SSL_BUFSIZE_INPUT` and `BR_SSL_BUFSIZE_OUTPUT`
 | |
|  * evaluate to the optimal (maximum) sizes for the input and output
 | |
|  * buffer, respectively.
 | |
|  *
 | |
|  * \param cc         SSL engine context
 | |
|  * \param ibuf       input buffer.
 | |
|  * \param ibuf_len   input buffer length (in bytes).
 | |
|  * \param obuf       output buffer.
 | |
|  * \param obuf_len   output buffer length (in bytes).
 | |
|  */
 | |
| void br_ssl_engine_set_buffers_bidi(br_ssl_engine_context *cc,
 | |
| 	void *ibuf, size_t ibuf_len, void *obuf, size_t obuf_len);
 | |
| 
 | |
| /**
 | |
|  * \brief Determine if MFLN negotiation was successful
 | |
|  *
 | |
|  * \param cc     SSL engine context.
 | |
|  */
 | |
| static inline uint8_t
 | |
| br_ssl_engine_get_mfln_negotiated(br_ssl_engine_context *cc)
 | |
| {
 | |
|         return cc->max_frag_len_negotiated;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Inject some "initial entropy" in the context.
 | |
|  *
 | |
|  * This entropy will be added to what can be obtained from the
 | |
|  * underlying operating system, if that OS is supported.
 | |
|  *
 | |
|  * This function may be called several times; all injected entropy chunks
 | |
|  * are cumulatively mixed.
 | |
|  *
 | |
|  * If entropy gathering from the OS is supported and compiled in, then this
 | |
|  * step is optional. Otherwise, it is mandatory to inject randomness, and
 | |
|  * the caller MUST take care to push (as one or several successive calls)
 | |
|  * enough entropy to achieve cryptographic resistance (at least 80 bits,
 | |
|  * preferably 128 or more). The engine will report an error if no entropy
 | |
|  * was provided and none can be obtained from the OS.
 | |
|  *
 | |
|  * Take care that this function cannot assess the cryptographic quality of
 | |
|  * the provided bytes.
 | |
|  *
 | |
|  * In all generality, "entropy" must here be considered to mean "that
 | |
|  * which the attacker cannot predict". If your OS/architecture does not
 | |
|  * have a suitable source of randomness, then you can make do with the
 | |
|  * combination of a large enough secret value (possibly a copy of an
 | |
|  * asymmetric private key that you also store on the system) AND a
 | |
|  * non-repeating value (e.g. current time, provided that the local clock
 | |
|  * cannot be reset or altered by the attacker).
 | |
|  *
 | |
|  * \param cc     SSL engine context.
 | |
|  * \param data   extra entropy to inject.
 | |
|  * \param len    length of the extra data (in bytes).
 | |
|  */
 | |
| void br_ssl_engine_inject_entropy(br_ssl_engine_context *cc,
 | |
| 	const void *data, size_t len);
 | |
| 
 | |
| /**
 | |
|  * \brief Get the "server name" in this engine.
 | |
|  *
 | |
|  * For clients, this is the name provided with `br_ssl_client_reset()`;
 | |
|  * for servers, this is the name received from the client as part of the
 | |
|  * ClientHello message. If there is no such name (e.g. the client did
 | |
|  * not send an SNI extension) then the returned string is empty
 | |
|  * (returned pointer points to a byte of value 0).
 | |
|  *
 | |
|  * The returned pointer refers to a buffer inside the context, which may
 | |
|  * be overwritten as part of normal SSL activity (even within the same
 | |
|  * connection, if a renegotiation occurs).
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  * \return  the server name (possibly empty).
 | |
|  */
 | |
| static inline const char *
 | |
| br_ssl_engine_get_server_name(const br_ssl_engine_context *cc)
 | |
| {
 | |
| 	return cc->server_name;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Get the protocol version.
 | |
|  *
 | |
|  * This function returns the protocol version that is used by the
 | |
|  * engine. That value is set after sending (for a server) or receiving
 | |
|  * (for a client) the ServerHello message.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  * \return  the protocol version.
 | |
|  */
 | |
| static inline unsigned
 | |
| br_ssl_engine_get_version(const br_ssl_engine_context *cc)
 | |
| {
 | |
| 	return cc->session.version;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Get a copy of the session parameters.
 | |
|  *
 | |
|  * The session parameters are filled during the handshake, so this
 | |
|  * function shall not be called before completion of the handshake.
 | |
|  * The initial handshake is completed when the context first allows
 | |
|  * application data to be injected.
 | |
|  *
 | |
|  * This function copies the current session parameters into the provided
 | |
|  * structure. Beware that the session parameters include the master
 | |
|  * secret, which is sensitive data, to handle with great care.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  * \param pp   destination structure for the session parameters.
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_get_session_parameters(const br_ssl_engine_context *cc,
 | |
| 	br_ssl_session_parameters *pp)
 | |
| {
 | |
| 	memcpy(pp, &cc->session, sizeof *pp);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the session parameters to the provided values.
 | |
|  *
 | |
|  * This function is meant to be used in the client, before doing a new
 | |
|  * handshake; a session resumption will be attempted with these
 | |
|  * parameters. In the server, this function has no effect.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  * \param pp   source structure for the session parameters.
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_engine_set_session_parameters(br_ssl_engine_context *cc,
 | |
| 	const br_ssl_session_parameters *pp)
 | |
| {
 | |
| 	memcpy(&cc->session, pp, sizeof *pp);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Get identifier for the curve used for key exchange.
 | |
|  *
 | |
|  * If the cipher suite uses ECDHE, then this function returns the
 | |
|  * identifier for the curve used for transient parameters. This is
 | |
|  * defined during the course of the handshake, when the ServerKeyExchange
 | |
|  * is sent (on the server) or received (on the client). If the
 | |
|  * cipher suite does not use ECDHE (e.g. static ECDH, or RSA key
 | |
|  * exchange), then this value is indeterminate.
 | |
|  *
 | |
|  * @param cc   SSL engine context.
 | |
|  * @return  the ECDHE curve identifier.
 | |
|  */
 | |
| static inline int
 | |
| br_ssl_engine_get_ecdhe_curve(br_ssl_engine_context *cc)
 | |
| {
 | |
| 	return cc->ecdhe_curve;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Get the current engine state.
 | |
|  *
 | |
|  * An SSL engine (client or server) has, at any time, a state which is
 | |
|  * the combination of zero, one or more of these flags:
 | |
|  *
 | |
|  *   - `BR_SSL_CLOSED`
 | |
|  *
 | |
|  *     Engine is finished, no more I/O (until next reset).
 | |
|  *
 | |
|  *   - `BR_SSL_SENDREC`
 | |
|  *
 | |
|  *     Engine has some bytes to send to the peer.
 | |
|  *
 | |
|  *   - `BR_SSL_RECVREC`
 | |
|  *
 | |
|  *     Engine expects some bytes from the peer.
 | |
|  *
 | |
|  *   - `BR_SSL_SENDAPP`
 | |
|  *
 | |
|  *     Engine may receive application data to send (or flush).
 | |
|  *
 | |
|  *   - `BR_SSL_RECVAPP`
 | |
|  *
 | |
|  *     Engine has obtained some application data from the peer,
 | |
|  *     that should be read by the caller.
 | |
|  *
 | |
|  * If no flag at all is set (state value is 0), then the engine is not
 | |
|  * fully initialised yet.
 | |
|  *
 | |
|  * The `BR_SSL_CLOSED` flag is exclusive; when it is set, no other flag
 | |
|  * is set. To distinguish between a normal closure and an error, use
 | |
|  * `br_ssl_engine_last_error()`.
 | |
|  *
 | |
|  * Generally speaking, `BR_SSL_SENDREC` and `BR_SSL_SENDAPP` are mutually
 | |
|  * exclusive: the input buffer, at any point, either accumulates
 | |
|  * plaintext data, or contains an assembled record that is being sent.
 | |
|  * Similarly, `BR_SSL_RECVREC` and `BR_SSL_RECVAPP` are mutually exclusive.
 | |
|  * This may change in a future library version.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  * \return  the current engine state.
 | |
|  */
 | |
| unsigned br_ssl_engine_current_state(const br_ssl_engine_context *cc);
 | |
| 
 | |
| /** \brief SSL engine state: closed or failed. */
 | |
| #define BR_SSL_CLOSED    0x0001
 | |
| /** \brief SSL engine state: record data is ready to be sent to the peer. */
 | |
| #define BR_SSL_SENDREC   0x0002
 | |
| /** \brief SSL engine state: engine may receive records from the peer. */
 | |
| #define BR_SSL_RECVREC   0x0004
 | |
| /** \brief SSL engine state: engine may accept application data to send. */
 | |
| #define BR_SSL_SENDAPP   0x0008
 | |
| /** \brief SSL engine state: engine has received application data. */
 | |
| #define BR_SSL_RECVAPP   0x0010
 | |
| 
 | |
| /**
 | |
|  * \brief Get the engine error indicator.
 | |
|  *
 | |
|  * The error indicator is `BR_ERR_OK` (0) if no error was encountered
 | |
|  * since the last call to `br_ssl_client_reset()` or
 | |
|  * `br_ssl_server_reset()`. Other status values are "sticky": they
 | |
|  * remain set, and prevent all I/O activity, until cleared. Only the
 | |
|  * reset calls clear the error indicator.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  * \return  0, or a non-zero error code.
 | |
|  */
 | |
| static inline int
 | |
| br_ssl_engine_last_error(const br_ssl_engine_context *cc)
 | |
| {
 | |
| 	return cc->err;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * There are four I/O operations, each identified by a symbolic name:
 | |
|  *
 | |
|  *   sendapp   inject application data in the engine
 | |
|  *   recvapp   retrieving application data from the engine
 | |
|  *   sendrec   sending records on the transport medium
 | |
|  *   recvrec   receiving records from the transport medium
 | |
|  *
 | |
|  * Terminology works thus: in a layered model where the SSL engine sits
 | |
|  * between the application and the network, "send" designates operations
 | |
|  * where bytes flow from application to network, and "recv" for the
 | |
|  * reverse operation. Application data (the plaintext that is to be
 | |
|  * conveyed through SSL) is "app", while encrypted records are "rec".
 | |
|  * Note that from the SSL engine point of view, "sendapp" and "recvrec"
 | |
|  * designate bytes that enter the engine ("inject" operation), while
 | |
|  * "recvapp" and "sendrec" designate bytes that exit the engine
 | |
|  * ("extract" operation).
 | |
|  *
 | |
|  * For the operation 'xxx', two functions are defined:
 | |
|  *
 | |
|  *   br_ssl_engine_xxx_buf
 | |
|  *      Returns a pointer and length to the buffer to use for that
 | |
|  *      operation. '*len' is set to the number of bytes that may be read
 | |
|  *      from the buffer (extract operation) or written to the buffer
 | |
|  *      (inject operation). If no byte may be exchanged for that operation
 | |
|  *      at that point, then '*len' is set to zero, and NULL is returned.
 | |
|  *      The engine state is unmodified by this call.
 | |
|  *
 | |
|  *   br_ssl_engine_xxx_ack
 | |
|  *      Informs the engine that 'len' bytes have been read from the buffer
 | |
|  *      (extract operation) or written to the buffer (inject operation).
 | |
|  *      The 'len' value MUST NOT be zero. The 'len' value MUST NOT exceed
 | |
|  *      that which was obtained from a preceding br_ssl_engine_xxx_buf()
 | |
|  *      call.
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * \brief Get buffer for application data to send.
 | |
|  *
 | |
|  * If the engine is ready to accept application data to send to the
 | |
|  * peer, then this call returns a pointer to the buffer where such
 | |
|  * data shall be written, and its length is written in `*len`.
 | |
|  * Otherwise, `*len` is set to 0 and `NULL` is returned.
 | |
|  *
 | |
|  * \param cc    SSL engine context.
 | |
|  * \param len   receives the application data output buffer length, or 0.
 | |
|  * \return  the application data output buffer, or `NULL`.
 | |
|  */
 | |
| unsigned char *br_ssl_engine_sendapp_buf(
 | |
| 	const br_ssl_engine_context *cc, size_t *len);
 | |
| 
 | |
| /**
 | |
|  * \brief Inform the engine of some new application data.
 | |
|  *
 | |
|  * After writing `len` bytes in the buffer returned by
 | |
|  * `br_ssl_engine_sendapp_buf()`, the application shall call this
 | |
|  * function to trigger any relevant processing. The `len` parameter
 | |
|  * MUST NOT be 0, and MUST NOT exceed the value obtained in the
 | |
|  * `br_ssl_engine_sendapp_buf()` call.
 | |
|  *
 | |
|  * \param cc    SSL engine context.
 | |
|  * \param len   number of bytes pushed (not zero).
 | |
|  */
 | |
| void br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len);
 | |
| 
 | |
| /**
 | |
|  * \brief Get buffer for received application data.
 | |
|  *
 | |
|  * If the engine has received application data from the peer, hen this
 | |
|  * call returns a pointer to the buffer from where such data shall be
 | |
|  * read, and its length is written in `*len`. Otherwise, `*len` is set
 | |
|  * to 0 and `NULL` is returned.
 | |
|  *
 | |
|  * \param cc    SSL engine context.
 | |
|  * \param len   receives the application data input buffer length, or 0.
 | |
|  * \return  the application data input buffer, or `NULL`.
 | |
|  */
 | |
| unsigned char *br_ssl_engine_recvapp_buf(
 | |
| 	const br_ssl_engine_context *cc, size_t *len);
 | |
| 
 | |
| /**
 | |
|  * \brief Acknowledge some received application data.
 | |
|  *
 | |
|  * After reading `len` bytes from the buffer returned by
 | |
|  * `br_ssl_engine_recvapp_buf()`, the application shall call this
 | |
|  * function to trigger any relevant processing. The `len` parameter
 | |
|  * MUST NOT be 0, and MUST NOT exceed the value obtained in the
 | |
|  * `br_ssl_engine_recvapp_buf()` call.
 | |
|  *
 | |
|  * \param cc    SSL engine context.
 | |
|  * \param len   number of bytes read (not zero).
 | |
|  */
 | |
| void br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len);
 | |
| 
 | |
| /**
 | |
|  * \brief Get buffer for record data to send.
 | |
|  *
 | |
|  * If the engine has prepared some records to send to the peer, then this
 | |
|  * call returns a pointer to the buffer from where such data shall be
 | |
|  * read, and its length is written in `*len`. Otherwise, `*len` is set
 | |
|  * to 0 and `NULL` is returned.
 | |
|  *
 | |
|  * \param cc    SSL engine context.
 | |
|  * \param len   receives the record data output buffer length, or 0.
 | |
|  * \return  the record data output buffer, or `NULL`.
 | |
|  */
 | |
| unsigned char *br_ssl_engine_sendrec_buf(
 | |
| 	const br_ssl_engine_context *cc, size_t *len);
 | |
| 
 | |
| /**
 | |
|  * \brief Acknowledge some sent record data.
 | |
|  *
 | |
|  * After reading `len` bytes from the buffer returned by
 | |
|  * `br_ssl_engine_sendrec_buf()`, the application shall call this
 | |
|  * function to trigger any relevant processing. The `len` parameter
 | |
|  * MUST NOT be 0, and MUST NOT exceed the value obtained in the
 | |
|  * `br_ssl_engine_sendrec_buf()` call.
 | |
|  *
 | |
|  * \param cc    SSL engine context.
 | |
|  * \param len   number of bytes read (not zero).
 | |
|  */
 | |
| void br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len);
 | |
| 
 | |
| /**
 | |
|  * \brief Get buffer for incoming records.
 | |
|  *
 | |
|  * If the engine is ready to accept records from the peer, then this
 | |
|  * call returns a pointer to the buffer where such data shall be
 | |
|  * written, and its length is written in `*len`. Otherwise, `*len` is
 | |
|  * set to 0 and `NULL` is returned.
 | |
|  *
 | |
|  * \param cc    SSL engine context.
 | |
|  * \param len   receives the record data input buffer length, or 0.
 | |
|  * \return  the record data input buffer, or `NULL`.
 | |
|  */
 | |
| unsigned char *br_ssl_engine_recvrec_buf(
 | |
| 	const br_ssl_engine_context *cc, size_t *len);
 | |
| 
 | |
| /**
 | |
|  * \brief Inform the engine of some new record data.
 | |
|  *
 | |
|  * After writing `len` bytes in the buffer returned by
 | |
|  * `br_ssl_engine_recvrec_buf()`, the application shall call this
 | |
|  * function to trigger any relevant processing. The `len` parameter
 | |
|  * MUST NOT be 0, and MUST NOT exceed the value obtained in the
 | |
|  * `br_ssl_engine_recvrec_buf()` call.
 | |
|  *
 | |
|  * \param cc    SSL engine context.
 | |
|  * \param len   number of bytes pushed (not zero).
 | |
|  */
 | |
| void br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len);
 | |
| 
 | |
| /**
 | |
|  * \brief Flush buffered application data.
 | |
|  *
 | |
|  * If some application data has been buffered in the engine, then wrap
 | |
|  * it into a record and mark it for sending. If no application data has
 | |
|  * been buffered but the engine would be ready to accept some, AND the
 | |
|  * `force` parameter is non-zero, then an empty record is assembled and
 | |
|  * marked for sending. In all other cases, this function does nothing.
 | |
|  *
 | |
|  * Empty records are technically legal, but not all existing SSL/TLS
 | |
|  * implementations support them. Empty records can be useful as a
 | |
|  * transparent "keep-alive" mechanism to maintain some low-level
 | |
|  * network activity.
 | |
|  *
 | |
|  * \param cc      SSL engine context.
 | |
|  * \param force   non-zero to force sending an empty record.
 | |
|  */
 | |
| void br_ssl_engine_flush(br_ssl_engine_context *cc, int force);
 | |
| 
 | |
| /**
 | |
|  * \brief Initiate a closure.
 | |
|  *
 | |
|  * If, at that point, the context is open and in ready state, then a
 | |
|  * `close_notify` alert is assembled and marked for sending; this
 | |
|  * triggers the closure protocol. Otherwise, no such alert is assembled.
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  */
 | |
| void br_ssl_engine_close(br_ssl_engine_context *cc);
 | |
| 
 | |
| /**
 | |
|  * \brief Initiate a renegotiation.
 | |
|  *
 | |
|  * If the engine is failed or closed, or if the peer is known not to
 | |
|  * support secure renegotiation (RFC 5746), or if renegotiations have
 | |
|  * been disabled with the `BR_OPT_NO_RENEGOTIATION` flag, or if there
 | |
|  * is buffered incoming application data, then this function returns 0
 | |
|  * and nothing else happens.
 | |
|  *
 | |
|  * Otherwise, this function returns 1, and a renegotiation attempt is
 | |
|  * triggered (if a handshake is already ongoing at that point, then
 | |
|  * no new handshake is triggered).
 | |
|  *
 | |
|  * \param cc   SSL engine context.
 | |
|  * \return  1 on success, 0 on error.
 | |
|  */
 | |
| int br_ssl_engine_renegotiate(br_ssl_engine_context *cc);
 | |
| 
 | |
| /**
 | |
|  * \brief Export key material from a connected SSL engine (RFC 5705).
 | |
|  *
 | |
|  * This calls compute a secret key of arbitrary length from the master
 | |
|  * secret of a connected SSL engine. If the provided context is not
 | |
|  * currently in "application data" state (initial handshake is not
 | |
|  * finished, another handshake is ongoing, or the connection failed or
 | |
|  * was closed), then this function returns 0. Otherwise, a secret key of
 | |
|  * length `len` bytes is computed and written in the buffer pointed to
 | |
|  * by `dst`, and 1 is returned.
 | |
|  *
 | |
|  * The computed key follows the specification described in RFC 5705.
 | |
|  * That RFC includes two key computations, with and without a "context
 | |
|  * value". If `context` is `NULL`, then the variant without context is
 | |
|  * used; otherwise, the `context_len` bytes located at the address
 | |
|  * pointed to by `context` are used in the computation. Note that it
 | |
|  * is possible to have a "with context" key with a context length of
 | |
|  * zero bytes, by setting `context` to a non-`NULL` value but
 | |
|  * `context_len` to 0.
 | |
|  *
 | |
|  * When context bytes are used, the context length MUST NOT exceed
 | |
|  * 65535 bytes.
 | |
|  *
 | |
|  * \param cc            SSL engine context.
 | |
|  * \param dst           destination buffer for exported key.
 | |
|  * \param len           exported key length (in bytes).
 | |
|  * \param label         disambiguation label.
 | |
|  * \param context       context value (or `NULL`).
 | |
|  * \param context_len   context length (in bytes).
 | |
|  * \return  1 on success, 0 on error.
 | |
|  */
 | |
| int br_ssl_key_export(br_ssl_engine_context *cc,
 | |
| 	void *dst, size_t len, const char *label,
 | |
| 	const void *context, size_t context_len);
 | |
| 
 | |
| /*
 | |
|  * Pre-declaration for the SSL client context.
 | |
|  */
 | |
| typedef struct br_ssl_client_context_ br_ssl_client_context;
 | |
| 
 | |
| /**
 | |
|  * \brief Type for the client certificate, if requested by the server.
 | |
|  */
 | |
| typedef struct {
 | |
| 	/**
 | |
| 	 * \brief Authentication type.
 | |
| 	 *
 | |
| 	 * This is either `BR_AUTH_RSA` (RSA signature), `BR_AUTH_ECDSA`
 | |
| 	 * (ECDSA signature), or `BR_AUTH_ECDH` (static ECDH key exchange).
 | |
| 	 */
 | |
| 	int auth_type;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Hash function for computing the CertificateVerify.
 | |
| 	 *
 | |
| 	 * This is the symbolic identifier for the hash function that
 | |
| 	 * will be used to produce the hash of handshake messages, to
 | |
| 	 * be signed into the CertificateVerify. For full static ECDH
 | |
| 	 * (client and server certificates are both EC in the same
 | |
| 	 * curve, and static ECDH is used), this value is set to -1.
 | |
| 	 *
 | |
| 	 * Take care that with TLS 1.0 and 1.1, that value MUST match
 | |
| 	 * the protocol requirements: value must be 0 (MD5+SHA-1) for
 | |
| 	 * a RSA signature, or 2 (SHA-1) for an ECDSA signature. Only
 | |
| 	 * TLS 1.2 allows for other hash functions.
 | |
| 	 */
 | |
| 	int hash_id;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Certificate chain to send to the server.
 | |
| 	 *
 | |
| 	 * This is an array of `br_x509_certificate` objects, each
 | |
| 	 * normally containing a DER-encoded certificate. The client
 | |
| 	 * code does not try to decode these elements. If there is no
 | |
| 	 * chain to send to the server, then this pointer shall be
 | |
| 	 * set to `NULL`.
 | |
| 	 */
 | |
| 	const br_x509_certificate *chain;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Certificate chain length (number of certificates).
 | |
| 	 *
 | |
| 	 * If there is no chain to send to the server, then this value
 | |
| 	 * shall be set to 0.
 | |
| 	 */
 | |
| 	size_t chain_len;
 | |
| 
 | |
| } br_ssl_client_certificate;
 | |
| 
 | |
| /*
 | |
|  * Note: the constants below for signatures match the TLS constants.
 | |
|  */
 | |
| 
 | |
| /** \brief Client authentication type: static ECDH. */
 | |
| #define BR_AUTH_ECDH    0
 | |
| /** \brief Client authentication type: RSA signature. */
 | |
| #define BR_AUTH_RSA     1
 | |
| /** \brief Client authentication type: ECDSA signature. */
 | |
| #define BR_AUTH_ECDSA   3
 | |
| 
 | |
| /**
 | |
|  * \brief Class type for a certificate handler (client side).
 | |
|  *
 | |
|  * A certificate handler selects a client certificate chain to send to
 | |
|  * the server, upon explicit request from that server. It receives
 | |
|  * the list of trust anchor DN from the server, and supported types
 | |
|  * of certificates and signatures, and returns the chain to use. It
 | |
|  * is also invoked to perform the corresponding private key operation
 | |
|  * (a signature, or an ECDH computation).
 | |
|  *
 | |
|  * The SSL client engine will first push the trust anchor DN with
 | |
|  * `start_name_list()`, `start_name()`, `append_name()`, `end_name()`
 | |
|  * and `end_name_list()`. Then it will call `choose()`, to select the
 | |
|  * actual chain (and signature/hash algorithms). Finally, it will call
 | |
|  * either `do_sign()` or `do_keyx()`, depending on the algorithm choices.
 | |
|  */
 | |
| typedef struct br_ssl_client_certificate_class_ br_ssl_client_certificate_class;
 | |
| struct br_ssl_client_certificate_class_ {
 | |
| 	/**
 | |
| 	 * \brief Context size (in bytes).
 | |
| 	 */
 | |
| 	size_t context_size;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Begin reception of a list of trust anchor names. This
 | |
| 	 * is called while parsing the incoming CertificateRequest.
 | |
| 	 *
 | |
| 	 * \param pctx   certificate handler context.
 | |
| 	 */
 | |
| 	void (*start_name_list)(const br_ssl_client_certificate_class **pctx);
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Begin reception of a new trust anchor name.
 | |
| 	 *
 | |
| 	 * The total encoded name length is provided; it is less than
 | |
| 	 * 65535 bytes.
 | |
| 	 *
 | |
| 	 * \param pctx   certificate handler context.
 | |
| 	 * \param len    encoded name length (in bytes).
 | |
| 	 */
 | |
| 	void (*start_name)(const br_ssl_client_certificate_class **pctx,
 | |
| 		size_t len);
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Receive some more bytes for the current trust anchor name.
 | |
| 	 *
 | |
| 	 * The provided reference (`data`) points to a transient buffer
 | |
| 	 * they may be reused as soon as this function returns. The chunk
 | |
| 	 * length (`len`) is never zero.
 | |
| 	 *
 | |
| 	 * \param pctx   certificate handler context.
 | |
| 	 * \param data   anchor name chunk.
 | |
| 	 * \param len    anchor name chunk length (in bytes).
 | |
| 	 */
 | |
| 	void (*append_name)(const br_ssl_client_certificate_class **pctx,
 | |
| 		const unsigned char *data, size_t len);
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief End current trust anchor name.
 | |
| 	 *
 | |
| 	 * This function is called when all the encoded anchor name data
 | |
| 	 * has been provided.
 | |
| 	 *
 | |
| 	 * \param pctx   certificate handler context.
 | |
| 	 */
 | |
| 	void (*end_name)(const br_ssl_client_certificate_class **pctx);
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief End list of trust anchor names.
 | |
| 	 *
 | |
| 	 * This function is called when all the anchor names in the
 | |
| 	 * CertificateRequest message have been obtained.
 | |
| 	 *
 | |
| 	 * \param pctx   certificate handler context.
 | |
| 	 */
 | |
| 	void (*end_name_list)(const br_ssl_client_certificate_class **pctx);
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Select client certificate and algorithms.
 | |
| 	 *
 | |
| 	 * This callback function shall fill the provided `choices`
 | |
| 	 * structure with the selected algorithms and certificate chain.
 | |
| 	 * The `hash_id`, `chain` and `chain_len` fields must be set. If
 | |
| 	 * the client cannot or does not wish to send a certificate,
 | |
| 	 * then it shall set `chain` to `NULL` and `chain_len` to 0.
 | |
| 	 *
 | |
| 	 * The `auth_types` parameter describes the authentication types,
 | |
| 	 * signature algorithms and hash functions that are supported by
 | |
| 	 * both the client context and the server, and compatible with
 | |
| 	 * the current protocol version. This is a bit field with the
 | |
| 	 * following contents:
 | |
| 	 *
 | |
| 	 *   - If RSA signatures with hash function x are supported, then
 | |
| 	 *     bit x is set.
 | |
| 	 *
 | |
| 	 *   - If ECDSA signatures with hash function x are supported,
 | |
| 	 *     then bit 8+x is set.
 | |
| 	 *
 | |
| 	 *   - If static ECDH is supported, with a RSA-signed certificate,
 | |
| 	 *     then bit 16 is set.
 | |
| 	 *
 | |
| 	 *   - If static ECDH is supported, with an ECDSA-signed certificate,
 | |
| 	 *     then bit 17 is set.
 | |
| 	 *
 | |
| 	 * Notes:
 | |
| 	 *
 | |
| 	 *   - When using TLS 1.0 or 1.1, the hash function for RSA
 | |
| 	 *     signatures is always the special MD5+SHA-1 (id 0), and the
 | |
| 	 *     hash function for ECDSA signatures is always SHA-1 (id 2).
 | |
| 	 *
 | |
| 	 *   - When using TLS 1.2, the list of hash functions is trimmed
 | |
| 	 *     down to include only hash functions that the client context
 | |
| 	 *     can support. The actual server list can be obtained with
 | |
| 	 *     `br_ssl_client_get_server_hashes()`; that list may be used
 | |
| 	 *     to select the certificate chain to send to the server.
 | |
| 	 *
 | |
| 	 * \param pctx         certificate handler context.
 | |
| 	 * \param cc           SSL client context.
 | |
| 	 * \param auth_types   supported authentication types and algorithms.
 | |
| 	 * \param choices      destination structure for the policy choices.
 | |
| 	 */
 | |
| 	void (*choose)(const br_ssl_client_certificate_class **pctx,
 | |
| 		const br_ssl_client_context *cc, uint32_t auth_types,
 | |
| 		br_ssl_client_certificate *choices);
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Perform key exchange (client part).
 | |
| 	 *
 | |
| 	 * This callback is invoked in case of a full static ECDH key
 | |
| 	 * exchange:
 | |
| 	 *
 | |
| 	 *   - the cipher suite uses `ECDH_RSA` or `ECDH_ECDSA`;
 | |
| 	 *
 | |
| 	 *   - the server requests a client certificate;
 | |
| 	 *
 | |
| 	 *   - the client has, and sends, a client certificate that
 | |
| 	 *     uses an EC key in the same curve as the server's key,
 | |
| 	 *     and chooses static ECDH (the `hash_id` field in the choice
 | |
| 	 *     structure was set to -1).
 | |
| 	 *
 | |
| 	 * In that situation, this callback is invoked to compute the
 | |
| 	 * client-side ECDH: the provided `data` (of length `*len` bytes)
 | |
| 	 * is the server's public key point (as decoded from its
 | |
| 	 * certificate), and the client shall multiply that point with
 | |
| 	 * its own private key, and write back the X coordinate of the
 | |
| 	 * resulting point in the same buffer, starting at offset 0.
 | |
| 	 * The `*len` value shall be modified to designate the actual
 | |
| 	 * length of the X coordinate.
 | |
| 	 *
 | |
| 	 * The callback must uphold the following:
 | |
| 	 *
 | |
| 	 *   - If the input array does not have the proper length for
 | |
| 	 *     an encoded curve point, then an error (0) shall be reported.
 | |
| 	 *
 | |
| 	 *   - If the input array has the proper length, then processing
 | |
| 	 *     MUST be constant-time, even if the data is not a valid
 | |
| 	 *     encoded point.
 | |
| 	 *
 | |
| 	 *   - This callback MUST check that the input point is valid.
 | |
| 	 *
 | |
| 	 * Returned value is 1 on success, 0 on error.
 | |
| 	 *
 | |
| 	 * \param pctx   certificate handler context.
 | |
| 	 * \param data   server public key point.
 | |
| 	 * \param len    public key point length / X coordinate length.
 | |
| 	 * \return  1 on success, 0 on error.
 | |
| 	 */
 | |
| 	uint32_t (*do_keyx)(const br_ssl_client_certificate_class **pctx,
 | |
| 		unsigned char *data, size_t *len);
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Perform a signature (client authentication).
 | |
| 	 *
 | |
| 	 * This callback is invoked when a client certificate was sent,
 | |
| 	 * and static ECDH is not used. It shall compute a signature,
 | |
| 	 * using the client's private key, over the provided hash value
 | |
| 	 * (which is the hash of all previous handshake messages).
 | |
| 	 *
 | |
| 	 * On input, the hash value to sign is in `data`, of size
 | |
| 	 * `hv_len`; the involved hash function is identified by
 | |
| 	 * `hash_id`. The signature shall be computed and written
 | |
| 	 * back into `data`; the total size of that buffer is `len`
 | |
| 	 * bytes.
 | |
| 	 *
 | |
| 	 * This callback shall verify that the signature length does not
 | |
| 	 * exceed `len` bytes, and abstain from writing the signature if
 | |
| 	 * it does not fit.
 | |
| 	 *
 | |
| 	 * For RSA signatures, the `hash_id` may be 0, in which case
 | |
| 	 * this is the special header-less signature specified in TLS 1.0
 | |
| 	 * and 1.1, with a 36-byte hash value. Otherwise, normal PKCS#1
 | |
| 	 * v1.5 signatures shall be computed.
 | |
| 	 *
 | |
| 	 * For ECDSA signatures, the signature value shall use the ASN.1
 | |
| 	 * based encoding.
 | |
| 	 *
 | |
| 	 * Returned value is the signature length (in bytes), or 0 on error.
 | |
| 	 *
 | |
| 	 * \param pctx      certificate handler context.
 | |
| 	 * \param hash_id   hash function identifier.
 | |
| 	 * \param hv_len    hash value length (in bytes).
 | |
| 	 * \param data      input/output buffer (hash value, then signature).
 | |
| 	 * \param len       total buffer length (in bytes).
 | |
| 	 * \return  signature length (in bytes) on success, or 0 on error.
 | |
| 	 */
 | |
| 	size_t (*do_sign)(const br_ssl_client_certificate_class **pctx,
 | |
| 		int hash_id, size_t hv_len, unsigned char *data, size_t len);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * \brief A single-chain RSA client certificate handler.
 | |
|  *
 | |
|  * This handler uses a single certificate chain, with a RSA
 | |
|  * signature. The list of trust anchor DN is ignored.
 | |
|  *
 | |
|  * Apart from the first field (vtable pointer), its contents are
 | |
|  * opaque and shall not be accessed directly.
 | |
|  */
 | |
| typedef struct {
 | |
| 	/** \brief Pointer to vtable. */
 | |
| 	const br_ssl_client_certificate_class *vtable;
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| 	const br_x509_certificate *chain;
 | |
| 	size_t chain_len;
 | |
| 	const br_rsa_private_key *sk;
 | |
| 	br_rsa_pkcs1_sign irsasign;
 | |
| #endif
 | |
| } br_ssl_client_certificate_rsa_context;
 | |
| 
 | |
| /**
 | |
|  * \brief A single-chain EC client certificate handler.
 | |
|  *
 | |
|  * This handler uses a single certificate chain, with a RSA
 | |
|  * signature. The list of trust anchor DN is ignored.
 | |
|  *
 | |
|  * This handler may support both static ECDH, and ECDSA signatures
 | |
|  * (either usage may be selectively disabled).
 | |
|  *
 | |
|  * Apart from the first field (vtable pointer), its contents are
 | |
|  * opaque and shall not be accessed directly.
 | |
|  */
 | |
| typedef struct {
 | |
| 	/** \brief Pointer to vtable. */
 | |
| 	const br_ssl_client_certificate_class *vtable;
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| 	const br_x509_certificate *chain;
 | |
| 	size_t chain_len;
 | |
| 	const br_ec_private_key *sk;
 | |
| 	unsigned allowed_usages;
 | |
| 	unsigned issuer_key_type;
 | |
| 	const br_multihash_context *mhash;
 | |
| 	const br_ec_impl *iec;
 | |
| 	br_ecdsa_sign iecdsa;
 | |
| #endif
 | |
| } br_ssl_client_certificate_ec_context;
 | |
| 
 | |
| /**
 | |
|  * \brief Context structure for a SSL client.
 | |
|  *
 | |
|  * The first field (called `eng`) is the SSL engine; all functions that
 | |
|  * work on a `br_ssl_engine_context` structure shall take as parameter
 | |
|  * a pointer to that field. The other structure fields are opaque and
 | |
|  * must not be accessed directly.
 | |
|  */
 | |
| struct br_ssl_client_context_ {
 | |
| 	/**
 | |
| 	 * \brief The encapsulated engine context.
 | |
| 	 */
 | |
| 	br_ssl_engine_context eng;
 | |
| 
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| 	/*
 | |
| 	 * Minimum ClientHello length; padding with an extension (RFC
 | |
| 	 * 7685) is added if necessary to match at least that length.
 | |
| 	 * Such padding is nominally unnecessary, but it has been used
 | |
| 	 * to work around some server implementation bugs.
 | |
| 	 */
 | |
| 	uint16_t min_clienthello_len;
 | |
| 
 | |
| 	/*
 | |
| 	 * Bit field for algoithms (hash + signature) supported by the
 | |
| 	 * server when requesting a client certificate.
 | |
| 	 */
 | |
| 	uint32_t hashes;
 | |
| 
 | |
| 	/*
 | |
| 	 * Server's public key curve.
 | |
| 	 */
 | |
| 	int server_curve;
 | |
| 
 | |
| 	/*
 | |
| 	 * Context for certificate handler.
 | |
| 	 */
 | |
| 	const br_ssl_client_certificate_class **client_auth_vtable;
 | |
| 
 | |
| 	/*
 | |
| 	 * Client authentication type.
 | |
| 	 */
 | |
| 	unsigned char auth_type;
 | |
| 
 | |
| 	/*
 | |
| 	 * Hash function to use for the client signature. This is 0xFF
 | |
| 	 * if static ECDH is used.
 | |
| 	 */
 | |
| 	unsigned char hash_id;
 | |
| 
 | |
| 	/*
 | |
| 	 * For the core certificate handlers, thus avoiding (in most
 | |
| 	 * cases) the need for an externally provided policy context.
 | |
| 	 */
 | |
| 	union {
 | |
| 		const br_ssl_client_certificate_class *vtable;
 | |
| 		br_ssl_client_certificate_rsa_context single_rsa;
 | |
| 		br_ssl_client_certificate_ec_context single_ec;
 | |
| 	} client_auth;
 | |
| 
 | |
| 	/*
 | |
| 	 * Implementations.
 | |
| 	 */
 | |
| 	br_rsa_public irsapub;
 | |
| #endif
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * \brief Get the hash functions and signature algorithms supported by
 | |
|  * the server.
 | |
|  *
 | |
|  * This value is a bit field:
 | |
|  *
 | |
|  *   - If RSA (PKCS#1 v1.5) is supported with hash function of ID `x`,
 | |
|  *     then bit `x` is set (hash function ID is 0 for the special MD5+SHA-1,
 | |
|  *     or 2 to 6 for the SHA family).
 | |
|  *
 | |
|  *   - If ECDSA is supported with hash function of ID `x`, then bit `8+x`
 | |
|  *     is set.
 | |
|  *
 | |
|  *   - Newer algorithms are symbolic 16-bit identifiers that do not
 | |
|  *     represent signature algorithm and hash function separately. If
 | |
|  *     the TLS-level identifier is `0x0800+x` for a `x` in the 0..15
 | |
|  *     range, then bit `16+x` is set.
 | |
|  *
 | |
|  * "New algorithms" are currently defined only in draft documents, so
 | |
|  * this support is subject to possible change. Right now (early 2017),
 | |
|  * this maps ed25519 (EdDSA on Curve25519) to bit 23, and ed448 (EdDSA
 | |
|  * on Curve448) to bit 24. If the identifiers on the wire change in
 | |
|  * future document, then the decoding mechanism in BearSSL will be
 | |
|  * amended to keep mapping ed25519 and ed448 on bits 23 and 24,
 | |
|  * respectively. Mapping of other new algorithms (e.g. RSA/PSS) is not
 | |
|  * guaranteed yet.
 | |
|  *
 | |
|  * \param cc   client context.
 | |
|  * \return  the server-supported hash functions and signature algorithms.
 | |
|  */
 | |
| static inline uint32_t
 | |
| br_ssl_client_get_server_hashes(const br_ssl_client_context *cc)
 | |
| {
 | |
| 	return cc->hashes;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Get the server key curve.
 | |
|  *
 | |
|  * This function returns the ID for the curve used by the server's public
 | |
|  * key. This is set when the server's certificate chain is processed;
 | |
|  * this value is 0 if the server's key is not an EC key.
 | |
|  *
 | |
|  * \return  the server's public key curve ID, or 0.
 | |
|  */
 | |
| static inline int
 | |
| br_ssl_client_get_server_curve(const br_ssl_client_context *cc)
 | |
| {
 | |
| 	return cc->server_curve;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Each br_ssl_client_init_xxx() function sets the list of supported
 | |
|  * cipher suites and used implementations, as specified by the profile
 | |
|  * name 'xxx'. Defined profile names are:
 | |
|  *
 | |
|  *    full    all supported versions and suites; constant-time implementations
 | |
|  *    TODO: add other profiles
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * \brief SSL client profile: full.
 | |
|  *
 | |
|  * This function initialises the provided SSL client context with
 | |
|  * all supported algorithms and cipher suites. It also initialises
 | |
|  * a companion X.509 validation engine with all supported algorithms,
 | |
|  * and the provided trust anchors; the X.509 engine will be used by
 | |
|  * the client context to validate the server's certificate.
 | |
|  *
 | |
|  * \param cc                  client context to initialise.
 | |
|  * \param xc                  X.509 validation context to initialise.
 | |
|  * \param trust_anchors       trust anchors to use.
 | |
|  * \param trust_anchors_num   number of trust anchors.
 | |
|  */
 | |
| void br_ssl_client_init_full(br_ssl_client_context *cc,
 | |
| 	br_x509_minimal_context *xc,
 | |
| 	const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num);
 | |
| 
 | |
| /**
 | |
|  * \brief Clear the complete contents of a SSL client context.
 | |
|  *
 | |
|  * Everything is cleared, including the reference to the configured buffer,
 | |
|  * implementations, cipher suites and state. This is a preparatory step
 | |
|  * to assembling a custom profile.
 | |
|  *
 | |
|  * \param cc   client context to clear.
 | |
|  */
 | |
| void br_ssl_client_zero(br_ssl_client_context *cc);
 | |
| 
 | |
| /**
 | |
|  * \brief Set an externally provided client certificate handler context.
 | |
|  *
 | |
|  * The handler's methods are invoked when the server requests a client
 | |
|  * certificate.
 | |
|  *
 | |
|  * \param cc     client context.
 | |
|  * \param pctx   certificate handler context (pointer to its vtable field).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_client_set_client_certificate(br_ssl_client_context *cc,
 | |
| 	const br_ssl_client_certificate_class **pctx)
 | |
| {
 | |
| 	cc->client_auth_vtable = pctx;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the RSA public-key operations implementation.
 | |
|  *
 | |
|  * This will be used to encrypt the pre-master secret with the server's
 | |
|  * RSA public key (RSA-encryption cipher suites only).
 | |
|  *
 | |
|  * \param cc        client context.
 | |
|  * \param irsapub   RSA public-key encryption implementation.
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_client_set_rsapub(br_ssl_client_context *cc, br_rsa_public irsapub)
 | |
| {
 | |
| 	cc->irsapub = irsapub;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the "default" RSA implementation for public-key operations.
 | |
|  *
 | |
|  * This sets the RSA implementation in the client context (for encrypting
 | |
|  * the pre-master secret, in `TLS_RSA_*` cipher suites) to the fastest
 | |
|  * available on the current platform.
 | |
|  *
 | |
|  * \param cc   client context.
 | |
|  */
 | |
| void br_ssl_client_set_default_rsapub(br_ssl_client_context *cc);
 | |
| 
 | |
| /**
 | |
|  * \brief Set the minimum ClientHello length (RFC 7685 padding).
 | |
|  *
 | |
|  * If this value is set and the ClientHello would be shorter, then
 | |
|  * the Pad ClientHello extension will be added with enough padding bytes
 | |
|  * to reach the target size. Because of the extension header, the resulting
 | |
|  * size will sometimes be slightly more than `len` bytes if the target
 | |
|  * size cannot be exactly met.
 | |
|  *
 | |
|  * The target length relates to the _contents_ of the ClientHello, not
 | |
|  * counting its 4-byte header. For instance, if `len` is set to 512,
 | |
|  * then the padding will bring the ClientHello size to 516 bytes with its
 | |
|  * header, and 521 bytes when counting the 5-byte record header.
 | |
|  *
 | |
|  * \param cc    client context.
 | |
|  * \param len   minimum ClientHello length (in bytes).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_client_set_min_clienthello_len(br_ssl_client_context *cc, uint16_t len)
 | |
| {
 | |
| 	cc->min_clienthello_len = len;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Prepare or reset a client context for a new connection.
 | |
|  *
 | |
|  * The `server_name` parameter is used to fill the SNI extension; the
 | |
|  * X.509 "minimal" engine will also match that name against the server
 | |
|  * names included in the server's certificate. If the parameter is
 | |
|  * `NULL` then no SNI extension will be sent, and the X.509 "minimal"
 | |
|  * engine (if used for server certificate validation) will not check
 | |
|  * presence of any specific name in the received certificate.
 | |
|  *
 | |
|  * Therefore, setting the `server_name` to `NULL` shall be reserved
 | |
|  * to cases where alternate or additional methods are used to ascertain
 | |
|  * that the right server public key is used (e.g. a "known key" model).
 | |
|  *
 | |
|  * If `resume_session` is non-zero and the context was previously used
 | |
|  * then the session parameters may be reused (depending on whether the
 | |
|  * server previously sent a non-empty session ID, and accepts the session
 | |
|  * resumption). The session parameters for session resumption can also
 | |
|  * be set explicitly with `br_ssl_engine_set_session_parameters()`.
 | |
|  *
 | |
|  * On failure, the context is marked as failed, and this function
 | |
|  * returns 0. A possible failure condition is when no initial entropy
 | |
|  * was injected, and none could be obtained from the OS (either OS
 | |
|  * randomness gathering is not supported, or it failed).
 | |
|  *
 | |
|  * \param cc               client context.
 | |
|  * \param server_name      target server name, or `NULL`.
 | |
|  * \param resume_session   non-zero to try session resumption.
 | |
|  * \return  0 on failure, 1 on success.
 | |
|  */
 | |
| int br_ssl_client_reset(br_ssl_client_context *cc,
 | |
| 	const char *server_name, int resume_session);
 | |
| 
 | |
| /**
 | |
|  * \brief Forget any session in the context.
 | |
|  *
 | |
|  * This means that the next handshake that uses this context will
 | |
|  * necessarily be a full handshake (this applies both to new connections
 | |
|  * and to renegotiations).
 | |
|  *
 | |
|  * \param cc   client context.
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_client_forget_session(br_ssl_client_context *cc)
 | |
| {
 | |
| 	cc->eng.session.session_id_len = 0;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set client certificate chain and key (single RSA case).
 | |
|  *
 | |
|  * This function sets a client certificate chain, that the client will
 | |
|  * send to the server whenever a client certificate is requested. This
 | |
|  * certificate uses an RSA public key; the corresponding private key is
 | |
|  * invoked for authentication. Trust anchor names sent by the server are
 | |
|  * ignored.
 | |
|  *
 | |
|  * The provided chain and private key are linked in the client context;
 | |
|  * they must remain valid as long as they may be used, i.e. normally
 | |
|  * for the duration of the connection, since they might be invoked
 | |
|  * again upon renegotiations.
 | |
|  *
 | |
|  * \param cc          SSL client context.
 | |
|  * \param chain       client certificate chain (SSL order: EE comes first).
 | |
|  * \param chain_len   client chain length (number of certificates).
 | |
|  * \param sk          client private key.
 | |
|  * \param irsasign    RSA signature implementation (PKCS#1 v1.5).
 | |
|  */
 | |
| void br_ssl_client_set_single_rsa(br_ssl_client_context *cc,
 | |
| 	const br_x509_certificate *chain, size_t chain_len,
 | |
| 	const br_rsa_private_key *sk, br_rsa_pkcs1_sign irsasign);
 | |
| 
 | |
| /*
 | |
|  * \brief Set the client certificate chain and key (single EC case).
 | |
|  *
 | |
|  * This function sets a client certificate chain, that the client will
 | |
|  * send to the server whenever a client certificate is requested. This
 | |
|  * certificate uses an EC public key; the corresponding private key is
 | |
|  * invoked for authentication. Trust anchor names sent by the server are
 | |
|  * ignored.
 | |
|  *
 | |
|  * The provided chain and private key are linked in the client context;
 | |
|  * they must remain valid as long as they may be used, i.e. normally
 | |
|  * for the duration of the connection, since they might be invoked
 | |
|  * again upon renegotiations.
 | |
|  *
 | |
|  * The `allowed_usages` is a combination of usages, namely
 | |
|  * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`. The `BR_KEYTYPE_KEYX`
 | |
|  * value allows full static ECDH, while the `BR_KEYTYPE_SIGN` value
 | |
|  * allows ECDSA signatures. If ECDSA signatures are used, then an ECDSA
 | |
|  * signature implementation must be provided; otherwise, the `iecdsa`
 | |
|  * parameter may be 0.
 | |
|  *
 | |
|  * The `cert_issuer_key_type` value is either `BR_KEYTYPE_RSA` or
 | |
|  * `BR_KEYTYPE_EC`; it is the type of the public key used the the CA
 | |
|  * that issued (signed) the client certificate. That value is used with
 | |
|  * full static ECDH: support of the certificate by the server depends
 | |
|  * on how the certificate was signed. (Note: when using TLS 1.2, this
 | |
|  * parameter is ignored; but its value matters for TLS 1.0 and 1.1.)
 | |
|  *
 | |
|  * \param cc                     server context.
 | |
|  * \param chain                  server certificate chain to send.
 | |
|  * \param chain_len              chain length (number of certificates).
 | |
|  * \param sk                     server private key (EC).
 | |
|  * \param allowed_usages         allowed private key usages.
 | |
|  * \param cert_issuer_key_type   issuing CA's key type.
 | |
|  * \param iec                    EC core implementation.
 | |
|  * \param iecdsa                 ECDSA signature implementation ("asn1" format).
 | |
|  */
 | |
| void br_ssl_client_set_single_ec(br_ssl_client_context *cc,
 | |
| 	const br_x509_certificate *chain, size_t chain_len,
 | |
| 	const br_ec_private_key *sk, unsigned allowed_usages,
 | |
| 	unsigned cert_issuer_key_type,
 | |
| 	const br_ec_impl *iec, br_ecdsa_sign iecdsa);
 | |
| 
 | |
| /**
 | |
|  * \brief Type for a "translated cipher suite", as an array of two
 | |
|  * 16-bit integers.
 | |
|  *
 | |
|  * The first element is the cipher suite identifier (as used on the wire).
 | |
|  * The second element is the concatenation of four 4-bit elements which
 | |
|  * characterise the cipher suite contents. In most to least significant
 | |
|  * order, these 4-bit elements are:
 | |
|  *
 | |
|  *   - Bits 12 to 15: key exchange + server key type
 | |
|  *
 | |
|  *     | val | symbolic constant        | suite type  | details                                          |
 | |
|  *     | :-- | :----------------------- | :---------- | :----------------------------------------------- |
 | |
|  *     |  0  | `BR_SSLKEYX_RSA`         | RSA         | RSA key exchange, key is RSA (encryption)        |
 | |
|  *     |  1  | `BR_SSLKEYX_ECDHE_RSA`   | ECDHE_RSA   | ECDHE key exchange, key is RSA (signature)       |
 | |
|  *     |  2  | `BR_SSLKEYX_ECDHE_ECDSA` | ECDHE_ECDSA | ECDHE key exchange, key is EC (signature)        |
 | |
|  *     |  3  | `BR_SSLKEYX_ECDH_RSA`    | ECDH_RSA    | Key is EC (key exchange), cert signed with RSA   |
 | |
|  *     |  4  | `BR_SSLKEYX_ECDH_ECDSA`  | ECDH_ECDSA  | Key is EC (key exchange), cert signed with ECDSA |
 | |
|  *
 | |
|  *   - Bits 8 to 11: symmetric encryption algorithm
 | |
|  *
 | |
|  *     | val | symbolic constant      | symmetric encryption | key strength (bits) |
 | |
|  *     | :-- | :--------------------- | :------------------- | :------------------ |
 | |
|  *     |  0  | `BR_SSLENC_3DES_CBC`   | 3DES/CBC             | 168                 |
 | |
|  *     |  1  | `BR_SSLENC_AES128_CBC` | AES-128/CBC          | 128                 |
 | |
|  *     |  2  | `BR_SSLENC_AES256_CBC` | AES-256/CBC          | 256                 |
 | |
|  *     |  3  | `BR_SSLENC_AES128_GCM` | AES-128/GCM          | 128                 |
 | |
|  *     |  4  | `BR_SSLENC_AES256_GCM` | AES-256/GCM          | 256                 |
 | |
|  *     |  5  | `BR_SSLENC_CHACHA20`   | ChaCha20/Poly1305    | 256                 |
 | |
|  *
 | |
|  *   - Bits 4 to 7: MAC algorithm
 | |
|  *
 | |
|  *     | val | symbolic constant  | MAC type     | details                               |
 | |
|  *     | :-- | :----------------- | :----------- | :------------------------------------ |
 | |
|  *     |  0  | `BR_SSLMAC_AEAD`   | AEAD         | No dedicated MAC (encryption is AEAD) |
 | |
|  *     |  2  | `BR_SSLMAC_SHA1`   | HMAC/SHA-1   | Value matches `br_sha1_ID`            |
 | |
|  *     |  4  | `BR_SSLMAC_SHA256` | HMAC/SHA-256 | Value matches `br_sha256_ID`          |
 | |
|  *     |  5  | `BR_SSLMAC_SHA384` | HMAC/SHA-384 | Value matches `br_sha384_ID`          |
 | |
|  *
 | |
|  *   - Bits 0 to 3: hash function for PRF when used with TLS-1.2
 | |
|  *
 | |
|  *     | val | symbolic constant  | hash function | details                              |
 | |
|  *     | :-- | :----------------- | :------------ | :----------------------------------- |
 | |
|  *     |  4  | `BR_SSLPRF_SHA256` | SHA-256       | Value matches `br_sha256_ID`         |
 | |
|  *     |  5  | `BR_SSLPRF_SHA384` | SHA-384       | Value matches `br_sha384_ID`         |
 | |
|  *
 | |
|  * For instance, cipher suite `TLS_RSA_WITH_AES_128_GCM_SHA256` has
 | |
|  * standard identifier 0x009C, and is translated to 0x0304, for, in
 | |
|  * that order: RSA key exchange (0), AES-128/GCM (3), AEAD integrity (0),
 | |
|  * SHA-256 in the TLS PRF (4).
 | |
|  */
 | |
| typedef uint16_t br_suite_translated[2];
 | |
| 
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| /*
 | |
|  * Constants are already documented in the br_suite_translated type.
 | |
|  */
 | |
| 
 | |
| #define BR_SSLKEYX_RSA           0
 | |
| #define BR_SSLKEYX_ECDHE_RSA     1
 | |
| #define BR_SSLKEYX_ECDHE_ECDSA   2
 | |
| #define BR_SSLKEYX_ECDH_RSA      3
 | |
| #define BR_SSLKEYX_ECDH_ECDSA    4
 | |
| 
 | |
| #define BR_SSLENC_3DES_CBC       0
 | |
| #define BR_SSLENC_AES128_CBC     1
 | |
| #define BR_SSLENC_AES256_CBC     2
 | |
| #define BR_SSLENC_AES128_GCM     3
 | |
| #define BR_SSLENC_AES256_GCM     4
 | |
| #define BR_SSLENC_CHACHA20       5
 | |
| 
 | |
| #define BR_SSLMAC_AEAD           0
 | |
| #define BR_SSLMAC_SHA1           br_sha1_ID
 | |
| #define BR_SSLMAC_SHA256         br_sha256_ID
 | |
| #define BR_SSLMAC_SHA384         br_sha384_ID
 | |
| 
 | |
| #define BR_SSLPRF_SHA256         br_sha256_ID
 | |
| #define BR_SSLPRF_SHA384         br_sha384_ID
 | |
| 
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|  * Pre-declaration for the SSL server context.
 | |
|  */
 | |
| typedef struct br_ssl_server_context_ br_ssl_server_context;
 | |
| 
 | |
| /**
 | |
|  * \brief Type for the server policy choices, taken after analysis of
 | |
|  * the client message (ClientHello).
 | |
|  */
 | |
| typedef struct {
 | |
| 	/**
 | |
| 	 * \brief Cipher suite to use with that client.
 | |
| 	 */
 | |
| 	uint16_t cipher_suite;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Hash function or algorithm for signing the ServerKeyExchange.
 | |
| 	 *
 | |
| 	 * This parameter is ignored for `TLS_RSA_*` and `TLS_ECDH_*`
 | |
| 	 * cipher suites; it is used only for `TLS_ECDHE_*` suites, in
 | |
| 	 * which the server _signs_ the ephemeral EC Diffie-Hellman
 | |
| 	 * parameters sent to the client.
 | |
| 	 *
 | |
| 	 * This identifier must be one of the following values:
 | |
| 	 *
 | |
| 	 *   - `0xFF00 + id`, where `id` is a hash function identifier
 | |
| 	 *     (0 for MD5+SHA-1, or 2 to 6 for one of the SHA functions);
 | |
| 	 *
 | |
| 	 *   - a full 16-bit identifier, lower than `0xFF00`.
 | |
| 	 *
 | |
| 	 * If the first option is used, then the SSL engine will
 | |
| 	 * compute the hash of the data that is to be signed, with the
 | |
| 	 * designated hash function. The `do_sign()` method will be
 | |
| 	 * invoked with that hash value provided in the the `data`
 | |
| 	 * buffer.
 | |
| 	 *
 | |
| 	 * If the second option is used, then the SSL engine will NOT
 | |
| 	 * compute a hash on the data; instead, it will provide the
 | |
| 	 * to-be-signed data itself in `data`, i.e. the concatenation of
 | |
| 	 * the client random, server random, and encoded ECDH
 | |
| 	 * parameters. Furthermore, with TLS-1.2 and later, the 16-bit
 | |
| 	 * identifier will be used "as is" in the protocol, in the
 | |
| 	 * SignatureAndHashAlgorithm; for instance, `0x0401` stands for
 | |
| 	 * RSA PKCS#1 v1.5 signature (the `01`) with SHA-256 as hash
 | |
| 	 * function (the `04`).
 | |
| 	 *
 | |
| 	 * Take care that with TLS 1.0 and 1.1, the hash function is
 | |
| 	 * constrainted by the protocol: RSA signature must use
 | |
| 	 * MD5+SHA-1 (so use `0xFF00`), while ECDSA must use SHA-1
 | |
| 	 * (`0xFF02`). Since TLS 1.0 and 1.1 don't include a
 | |
| 	 * SignatureAndHashAlgorithm field in their ServerKeyExchange
 | |
| 	 * messages, any value below `0xFF00` will be usable to send the
 | |
| 	 * raw ServerKeyExchange data to the `do_sign()` callback, but
 | |
| 	 * that callback must still follow the protocol requirements
 | |
| 	 * when generating the signature.
 | |
| 	 */
 | |
| 	unsigned algo_id;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Certificate chain to send to the client.
 | |
| 	 *
 | |
| 	 * This is an array of `br_x509_certificate` objects, each
 | |
| 	 * normally containing a DER-encoded certificate. The server
 | |
| 	 * code does not try to decode these elements.
 | |
| 	 */
 | |
| 	const br_x509_certificate *chain;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Certificate chain length (number of certificates).
 | |
| 	 */
 | |
| 	size_t chain_len;
 | |
| 
 | |
| } br_ssl_server_choices;
 | |
| 
 | |
| /**
 | |
|  * \brief Class type for a policy handler (server side).
 | |
|  *
 | |
|  * A policy handler selects the policy parameters for a connection
 | |
|  * (cipher suite and other algorithms, and certificate chain to send to
 | |
|  * the client); it also performs the server-side computations involving
 | |
|  * its permanent private key.
 | |
|  *
 | |
|  * The SSL server engine will invoke first `choose()`, once the
 | |
|  * ClientHello message has been received, then either `do_keyx()`
 | |
|  * `do_sign()`, depending on the cipher suite.
 | |
|  */
 | |
| typedef struct br_ssl_server_policy_class_ br_ssl_server_policy_class;
 | |
| struct br_ssl_server_policy_class_ {
 | |
| 	/**
 | |
| 	 * \brief Context size (in bytes).
 | |
| 	 */
 | |
| 	size_t context_size;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Select algorithms and certificates for this connection.
 | |
| 	 *
 | |
| 	 * This callback function shall fill the provided `choices`
 | |
| 	 * structure with the policy choices for this connection. This
 | |
| 	 * entails selecting the cipher suite, hash function for signing
 | |
| 	 * the ServerKeyExchange (applicable only to ECDHE cipher suites),
 | |
| 	 * and certificate chain to send.
 | |
| 	 *
 | |
| 	 * The callback receives a pointer to the server context that
 | |
| 	 * contains the relevant data. In particular, the functions
 | |
| 	 * `br_ssl_server_get_client_suites()`,
 | |
| 	 * `br_ssl_server_get_client_hashes()` and
 | |
| 	 * `br_ssl_server_get_client_curves()` can be used to obtain
 | |
| 	 * the cipher suites, hash functions and elliptic curves
 | |
| 	 * supported by both the client and server, respectively. The
 | |
| 	 * `br_ssl_engine_get_version()` and `br_ssl_engine_get_server_name()`
 | |
| 	 * functions yield the protocol version and requested server name
 | |
| 	 * (SNI), respectively.
 | |
| 	 *
 | |
| 	 * This function may modify its context structure (`pctx`) in
 | |
| 	 * arbitrary ways to keep track of its own choices.
 | |
| 	 *
 | |
| 	 * This function shall return 1 if appropriate policy choices
 | |
| 	 * could be made, or 0 if this connection cannot be pursued.
 | |
| 	 *
 | |
| 	 * \param pctx      policy context.
 | |
| 	 * \param cc        SSL server context.
 | |
| 	 * \param choices   destination structure for the policy choices.
 | |
| 	 * \return  1 on success, 0 on error.
 | |
| 	 */
 | |
| 	int (*choose)(const br_ssl_server_policy_class **pctx,
 | |
| 		const br_ssl_server_context *cc,
 | |
| 		br_ssl_server_choices *choices);
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Perform key exchange (server part).
 | |
| 	 *
 | |
| 	 * This callback is invoked to perform the server-side cryptographic
 | |
| 	 * operation for a key exchange that is not ECDHE. This callback
 | |
| 	 * uses the private key.
 | |
| 	 *
 | |
| 	 * **For RSA key exchange**, the provided `data` (of length `*len`
 | |
| 	 * bytes) shall be decrypted with the server's private key, and
 | |
| 	 * the 48-byte premaster secret copied back to the first 48 bytes
 | |
| 	 * of `data`.
 | |
| 	 *
 | |
| 	 *   - The caller makes sure that `*len` is at least 59 bytes.
 | |
| 	 *
 | |
| 	 *   - This callback MUST check that the provided length matches
 | |
| 	 *     that of the key modulus; it shall report an error otherwise.
 | |
| 	 *
 | |
| 	 *   - If the length matches that of the RSA key modulus, then
 | |
| 	 *     processing MUST be constant-time, even if decryption fails,
 | |
| 	 *     or the padding is incorrect, or the plaintext message length
 | |
| 	 *     is not exactly 48 bytes.
 | |
| 	 *
 | |
| 	 *   - This callback needs not check the two first bytes of the
 | |
| 	 *     obtained pre-master secret (the caller will do that).
 | |
| 	 *
 | |
| 	 *   - If an error is reported (0), then what the callback put
 | |
| 	 *     in the first 48 bytes of `data` is unimportant (the caller
 | |
| 	 *     will use random bytes instead).
 | |
| 	 *
 | |
| 	 * **For ECDH key exchange**, the provided `data` (of length `*len`
 | |
| 	 * bytes) is the elliptic curve point from the client. The
 | |
| 	 * callback shall multiply it with its private key, and store
 | |
| 	 * the resulting X coordinate in `data`, starting at offset 0,
 | |
| 	 * and set `*len` to the length of the X coordinate.
 | |
| 	 *
 | |
| 	 *   - If the input array does not have the proper length for
 | |
| 	 *     an encoded curve point, then an error (0) shall be reported.
 | |
| 	 *
 | |
| 	 *   - If the input array has the proper length, then processing
 | |
| 	 *     MUST be constant-time, even if the data is not a valid
 | |
| 	 *     encoded point.
 | |
| 	 *
 | |
| 	 *   - This callback MUST check that the input point is valid.
 | |
| 	 *
 | |
| 	 * Returned value is 1 on success, 0 on error.
 | |
| 	 *
 | |
| 	 * \param pctx   policy context.
 | |
| 	 * \param data   key exchange data from the client.
 | |
| 	 * \param len    key exchange data length (in bytes).
 | |
| 	 * \return  1 on success, 0 on error.
 | |
| 	 */
 | |
| 	uint32_t (*do_keyx)(const br_ssl_server_policy_class **pctx,
 | |
| 		unsigned char *data, size_t *len);
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Perform a signature (for a ServerKeyExchange message).
 | |
| 	 *
 | |
| 	 * This callback function is invoked for ECDHE cipher suites. On
 | |
| 	 * input, the hash value or message to sign is in `data`, of
 | |
| 	 * size `hv_len`; the involved hash function or algorithm is
 | |
| 	 * identified by `algo_id`. The signature shall be computed and
 | |
| 	 * written back into `data`; the total size of that buffer is
 | |
| 	 * `len` bytes.
 | |
| 	 *
 | |
| 	 * This callback shall verify that the signature length does not
 | |
| 	 * exceed `len` bytes, and abstain from writing the signature if
 | |
| 	 * it does not fit.
 | |
| 	 *
 | |
| 	 * The `algo_id` value matches that which was written in the
 | |
| 	 * `choices` structures by the `choose()` callback. This will be
 | |
| 	 * one of the following:
 | |
| 	 *
 | |
| 	 *   - `0xFF00 + id` for a hash function identifier `id`. In
 | |
| 	 *     that case, the `data` buffer contains a hash value
 | |
| 	 *     already computed over the data that is to be signed,
 | |
| 	 *     of length `hv_len`. The `id` may be 0 to designate the
 | |
| 	 *     special MD5+SHA-1 concatenation (old-style RSA signing).
 | |
| 	 *
 | |
| 	 *   - Another value, lower than `0xFF00`. The `data` buffer
 | |
| 	 *     then contains the raw, non-hashed data to be signed
 | |
| 	 *     (concatenation of the client and server randoms and
 | |
| 	 *     ECDH parameters). The callback is responsible to apply
 | |
| 	 *     any relevant hashing as part of the signing process.
 | |
| 	 *
 | |
| 	 * Returned value is the signature length (in bytes), or 0 on error.
 | |
| 	 *
 | |
| 	 * \param pctx      policy context.
 | |
| 	 * \param algo_id   hash function / algorithm identifier.
 | |
| 	 * \param data      input/output buffer (message/hash, then signature).
 | |
| 	 * \param hv_len    hash value or message length (in bytes).
 | |
| 	 * \param len       total buffer length (in bytes).
 | |
| 	 * \return  signature length (in bytes) on success, or 0 on error.
 | |
| 	 */
 | |
| 	size_t (*do_sign)(const br_ssl_server_policy_class **pctx,
 | |
| 		unsigned algo_id,
 | |
| 		unsigned char *data, size_t hv_len, size_t len);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * \brief A single-chain RSA policy handler.
 | |
|  *
 | |
|  * This policy context uses a single certificate chain, and a RSA
 | |
|  * private key. The context can be restricted to only signatures or
 | |
|  * only key exchange.
 | |
|  *
 | |
|  * Apart from the first field (vtable pointer), its contents are
 | |
|  * opaque and shall not be accessed directly.
 | |
|  */
 | |
| typedef struct {
 | |
| 	/** \brief Pointer to vtable. */
 | |
| 	const br_ssl_server_policy_class *vtable;
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| 	const br_x509_certificate *chain;
 | |
| 	size_t chain_len;
 | |
| 	const br_rsa_private_key *sk;
 | |
| 	unsigned allowed_usages;
 | |
| 	br_rsa_private irsacore;
 | |
| 	br_rsa_pkcs1_sign irsasign;
 | |
| #endif
 | |
| } br_ssl_server_policy_rsa_context;
 | |
| 
 | |
| /**
 | |
|  * \brief A single-chain EC policy handler.
 | |
|  *
 | |
|  * This policy context uses a single certificate chain, and an EC
 | |
|  * private key. The context can be restricted to only signatures or
 | |
|  * only key exchange.
 | |
|  *
 | |
|  * Due to how TLS is defined, this context must be made aware whether
 | |
|  * the server certificate was itself signed with RSA or ECDSA. The code
 | |
|  * does not try to decode the certificate to obtain that information.
 | |
|  *
 | |
|  * Apart from the first field (vtable pointer), its contents are
 | |
|  * opaque and shall not be accessed directly.
 | |
|  */
 | |
| typedef struct {
 | |
| 	/** \brief Pointer to vtable. */
 | |
| 	const br_ssl_server_policy_class *vtable;
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| 	const br_x509_certificate *chain;
 | |
| 	size_t chain_len;
 | |
| 	const br_ec_private_key *sk;
 | |
| 	unsigned allowed_usages;
 | |
| 	unsigned cert_issuer_key_type;
 | |
| 	const br_multihash_context *mhash;
 | |
| 	const br_ec_impl *iec;
 | |
| 	br_ecdsa_sign iecdsa;
 | |
| #endif
 | |
| } br_ssl_server_policy_ec_context;
 | |
| 
 | |
| /**
 | |
|  * \brief Class type for a session parameter cache.
 | |
|  *
 | |
|  * Session parameters are saved in the cache with `save()`, and
 | |
|  * retrieved with `load()`. The cache implementation can apply any
 | |
|  * storage and eviction strategy that it sees fit. The SSL server
 | |
|  * context that performs the request is provided, so that its
 | |
|  * functionalities may be used by the implementation (e.g. hash
 | |
|  * functions or random number generation).
 | |
|  */
 | |
| typedef struct br_ssl_session_cache_class_ br_ssl_session_cache_class;
 | |
| struct br_ssl_session_cache_class_ {
 | |
| 	/**
 | |
| 	 * \brief Context size (in bytes).
 | |
| 	 */
 | |
| 	size_t context_size;
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Record a session.
 | |
| 	 *
 | |
| 	 * This callback should record the provided session parameters.
 | |
| 	 * The `params` structure is transient, so its contents shall
 | |
| 	 * be copied into the cache. The session ID has been randomly
 | |
| 	 * generated and always has length exactly 32 bytes.
 | |
| 	 *
 | |
| 	 * \param ctx          session cache context.
 | |
| 	 * \param server_ctx   SSL server context.
 | |
| 	 * \param params       session parameters to save.
 | |
| 	 */
 | |
| 	void (*save)(const br_ssl_session_cache_class **ctx,
 | |
| 		br_ssl_server_context *server_ctx,
 | |
| 		const br_ssl_session_parameters *params);
 | |
| 
 | |
| 	/**
 | |
| 	 * \brief Lookup a session in the cache.
 | |
| 	 *
 | |
| 	 * The session ID to lookup is in `params` and always has length
 | |
| 	 * exactly 32 bytes. If the session parameters are found in the
 | |
| 	 * cache, then the parameters shall be copied into the `params`
 | |
| 	 * structure. Returned value is 1 on successful lookup, 0
 | |
| 	 * otherwise.
 | |
| 	 *
 | |
| 	 * \param ctx          session cache context.
 | |
| 	 * \param server_ctx   SSL server context.
 | |
| 	 * \param params       destination for session parameters.
 | |
| 	 * \return  1 if found, 0 otherwise.
 | |
| 	 */
 | |
| 	int (*load)(const br_ssl_session_cache_class **ctx,
 | |
| 		br_ssl_server_context *server_ctx,
 | |
| 		br_ssl_session_parameters *params);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * \brief Context for a basic cache system.
 | |
|  *
 | |
|  * The system stores session parameters in a buffer provided at
 | |
|  * initialisation time. Each entry uses exactly 100 bytes, and
 | |
|  * buffer sizes up to 4294967295 bytes are supported.
 | |
|  *
 | |
|  * Entries are evicted with a LRU (Least Recently Used) policy. A
 | |
|  * search tree is maintained to keep lookups fast even with large
 | |
|  * caches.
 | |
|  *
 | |
|  * Apart from the first field (vtable pointer), the structure
 | |
|  * contents are opaque and shall not be accessed directly.
 | |
|  */
 | |
| typedef struct {
 | |
| 	/** \brief Pointer to vtable. */
 | |
| 	const br_ssl_session_cache_class *vtable;
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| 	unsigned char *store;
 | |
| 	size_t store_len, store_ptr;
 | |
| 	unsigned char index_key[32];
 | |
| 	const br_hash_class *hash;
 | |
| 	int init_done;
 | |
| 	uint32_t head, tail, root;
 | |
| #endif
 | |
| } br_ssl_session_cache_lru;
 | |
| 
 | |
| /**
 | |
|  * \brief Initialise a LRU session cache with the provided storage space.
 | |
|  *
 | |
|  * The provided storage space must remain valid as long as the cache
 | |
|  * is used. Arbitrary lengths are supported, up to 4294967295 bytes;
 | |
|  * each entry uses up exactly 100 bytes.
 | |
|  *
 | |
|  * \param cc          session cache context.
 | |
|  * \param store       storage space for cached entries.
 | |
|  * \param store_len   storage space length (in bytes).
 | |
|  */
 | |
| void br_ssl_session_cache_lru_init(br_ssl_session_cache_lru *cc,
 | |
| 	unsigned char *store, size_t store_len);
 | |
| 
 | |
| /**
 | |
|  * \brief Forget an entry in an LRU session cache.
 | |
|  *
 | |
|  * The session cache context must have been initialised. The entry
 | |
|  * with the provided session ID (of exactly 32 bytes) is looked for
 | |
|  * in the cache; if located, it is disabled.
 | |
|  *
 | |
|  * \param cc   session cache context.
 | |
|  * \param id   session ID to forget.
 | |
|  */
 | |
| void br_ssl_session_cache_lru_forget(
 | |
| 	br_ssl_session_cache_lru *cc, const unsigned char *id);
 | |
| 
 | |
| /**
 | |
|  * \brief Context structure for a SSL server.
 | |
|  *
 | |
|  * The first field (called `eng`) is the SSL engine; all functions that
 | |
|  * work on a `br_ssl_engine_context` structure shall take as parameter
 | |
|  * a pointer to that field. The other structure fields are opaque and
 | |
|  * must not be accessed directly.
 | |
|  */
 | |
| struct br_ssl_server_context_ {
 | |
| 	/**
 | |
| 	 * \brief The encapsulated engine context.
 | |
| 	 */
 | |
| 	br_ssl_engine_context eng;
 | |
| 
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| 	/*
 | |
| 	 * Maximum version from the client.
 | |
| 	 */
 | |
| 	uint16_t client_max_version;
 | |
| 
 | |
| 	/*
 | |
| 	 * Session cache.
 | |
| 	 */
 | |
| 	const br_ssl_session_cache_class **cache_vtable;
 | |
| 
 | |
| 	/*
 | |
| 	 * Translated cipher suites supported by the client. The list
 | |
| 	 * is trimmed to include only the cipher suites that the
 | |
| 	 * server also supports; they are in the same order as in the
 | |
| 	 * client message.
 | |
| 	 */
 | |
| 	br_suite_translated client_suites[BR_MAX_CIPHER_SUITES];
 | |
| 	unsigned char client_suites_num;
 | |
| 
 | |
| 	/*
 | |
| 	 * Hash functions supported by the client, with ECDSA and RSA
 | |
| 	 * (bit mask). For hash function with id 'x', set bit index is
 | |
| 	 * x for RSA, x+8 for ECDSA. For newer algorithms, with ID
 | |
| 	 * 0x08**, bit 16+k is set for algorithm 0x0800+k.
 | |
| 	 */
 | |
| 	uint32_t hashes;
 | |
| 
 | |
| 	/*
 | |
| 	 * Curves supported by the client (bit mask, for named curves).
 | |
| 	 */
 | |
| 	uint32_t curves;
 | |
| 
 | |
| 	/*
 | |
| 	 * Context for chain handler.
 | |
| 	 */
 | |
| 	const br_ssl_server_policy_class **policy_vtable;
 | |
| 	uint16_t sign_hash_id;
 | |
| 
 | |
| 	/*
 | |
| 	 * For the core handlers, thus avoiding (in most cases) the
 | |
| 	 * need for an externally provided policy context.
 | |
| 	 */
 | |
| 	union {
 | |
| 		const br_ssl_server_policy_class *vtable;
 | |
| 		br_ssl_server_policy_rsa_context single_rsa;
 | |
| 		br_ssl_server_policy_ec_context single_ec;
 | |
| 	} chain_handler;
 | |
| 
 | |
| 	/*
 | |
| 	 * Buffer for the ECDHE private key.
 | |
| 	 */
 | |
| 	unsigned char ecdhe_key[70];
 | |
| 	size_t ecdhe_key_len;
 | |
| 
 | |
| 	/*
 | |
| 	 * Trust anchor names for client authentication. "ta_names" and
 | |
| 	 * "tas" cannot be both non-NULL.
 | |
| 	 */
 | |
| 	const br_x500_name *ta_names;
 | |
| 	const br_x509_trust_anchor *tas;
 | |
| 	size_t num_tas;
 | |
| 	size_t cur_dn_index;
 | |
| 	const unsigned char *cur_dn;
 | |
| 	size_t cur_dn_len;
 | |
| 
 | |
| 	/*
 | |
| 	 * Buffer for the hash value computed over all handshake messages
 | |
| 	 * prior to CertificateVerify, and identifier for the hash function.
 | |
| 	 */
 | |
| 	unsigned char hash_CV[64];
 | |
| 	size_t hash_CV_len;
 | |
| 	int hash_CV_id;
 | |
| 
 | |
| 	/*
 | |
| 	 * Server-specific implementations.
 | |
| 	 * (none for now)
 | |
| 	 */
 | |
| #endif
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * Each br_ssl_server_init_xxx() function sets the list of supported
 | |
|  * cipher suites and used implementations, as specified by the profile
 | |
|  * name 'xxx'. Defined profile names are:
 | |
|  *
 | |
|  *    full_rsa    all supported algorithm, server key type is RSA
 | |
|  *    full_ec     all supported algorithm, server key type is EC
 | |
|  *    TODO: add other profiles
 | |
|  *
 | |
|  * Naming scheme for "minimal" profiles: min123
 | |
|  *
 | |
|  * -- character 1: key exchange
 | |
|  *      r = RSA
 | |
|  *      e = ECDHE_RSA
 | |
|  *      f = ECDHE_ECDSA
 | |
|  *      u = ECDH_RSA
 | |
|  *      v = ECDH_ECDSA
 | |
|  * -- character 2: version / PRF
 | |
|  *      0 = TLS 1.0 / 1.1 with MD5+SHA-1
 | |
|  *      2 = TLS 1.2 with SHA-256
 | |
|  *      3 = TLS 1.2 with SHA-384
 | |
|  * -- character 3: encryption
 | |
|  *      a = AES/CBC
 | |
|  *      d = 3DES/CBC
 | |
|  *      g = AES/GCM
 | |
|  *      c = ChaCha20+Poly1305
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * \brief SSL server profile: full_rsa.
 | |
|  *
 | |
|  * This function initialises the provided SSL server context with
 | |
|  * all supported algorithms and cipher suites that rely on a RSA
 | |
|  * key pair.
 | |
|  *
 | |
|  * \param cc          server context to initialise.
 | |
|  * \param chain       server certificate chain.
 | |
|  * \param chain_len   certificate chain length (number of certificate).
 | |
|  * \param sk          RSA private key.
 | |
|  */
 | |
| void br_ssl_server_init_full_rsa(br_ssl_server_context *cc,
 | |
| 	const br_x509_certificate *chain, size_t chain_len,
 | |
| 	const br_rsa_private_key *sk);
 | |
| 
 | |
| /**
 | |
|  * \brief SSL server profile: full_ec.
 | |
|  *
 | |
|  * This function initialises the provided SSL server context with
 | |
|  * all supported algorithms and cipher suites that rely on an EC
 | |
|  * key pair.
 | |
|  *
 | |
|  * The key type of the CA that issued the server's certificate must
 | |
|  * be provided, since it matters for ECDH cipher suites (ECDH_RSA
 | |
|  * suites require a RSA-powered CA). The key type is either
 | |
|  * `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`.
 | |
|  *
 | |
|  * \param cc                     server context to initialise.
 | |
|  * \param chain                  server certificate chain.
 | |
|  * \param chain_len              chain length (number of certificates).
 | |
|  * \param cert_issuer_key_type   certificate issuer's key type.
 | |
|  * \param sk                     EC private key.
 | |
|  */
 | |
| void br_ssl_server_init_full_ec(br_ssl_server_context *cc,
 | |
| 	const br_x509_certificate *chain, size_t chain_len,
 | |
| 	unsigned cert_issuer_key_type, const br_ec_private_key *sk);
 | |
| 
 | |
| /**
 | |
|  * \brief SSL server profile: minr2g.
 | |
|  *
 | |
|  * This profile uses only TLS_RSA_WITH_AES_128_GCM_SHA256. Server key is
 | |
|  * RSA, and RSA key exchange is used (not forward secure, but uses little
 | |
|  * CPU in the client).
 | |
|  *
 | |
|  * \param cc          server context to initialise.
 | |
|  * \param chain       server certificate chain.
 | |
|  * \param chain_len   certificate chain length (number of certificate).
 | |
|  * \param sk          RSA private key.
 | |
|  */
 | |
| void br_ssl_server_init_minr2g(br_ssl_server_context *cc,
 | |
| 	const br_x509_certificate *chain, size_t chain_len,
 | |
| 	const br_rsa_private_key *sk);
 | |
| 
 | |
| /**
 | |
|  * \brief SSL server profile: mine2g.
 | |
|  *
 | |
|  * This profile uses only TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256. Server key
 | |
|  * is RSA, and ECDHE key exchange is used. This suite provides forward
 | |
|  * security, with a higher CPU expense on the client, and a somewhat
 | |
|  * larger code footprint (compared to "minr2g").
 | |
|  *
 | |
|  * \param cc          server context to initialise.
 | |
|  * \param chain       server certificate chain.
 | |
|  * \param chain_len   certificate chain length (number of certificate).
 | |
|  * \param sk          RSA private key.
 | |
|  */
 | |
| void br_ssl_server_init_mine2g(br_ssl_server_context *cc,
 | |
| 	const br_x509_certificate *chain, size_t chain_len,
 | |
| 	const br_rsa_private_key *sk);
 | |
| 
 | |
| /**
 | |
|  * \brief SSL server profile: minf2g.
 | |
|  *
 | |
|  * This profile uses only TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.
 | |
|  * Server key is EC, and ECDHE key exchange is used. This suite provides
 | |
|  * forward security, with a higher CPU expense on the client and server
 | |
|  * (by a factor of about 3 to 4), and a somewhat larger code footprint
 | |
|  * (compared to "minu2g" and "minv2g").
 | |
|  *
 | |
|  * \param cc          server context to initialise.
 | |
|  * \param chain       server certificate chain.
 | |
|  * \param chain_len   certificate chain length (number of certificate).
 | |
|  * \param sk          EC private key.
 | |
|  */
 | |
| void br_ssl_server_init_minf2g(br_ssl_server_context *cc,
 | |
| 	const br_x509_certificate *chain, size_t chain_len,
 | |
| 	const br_ec_private_key *sk);
 | |
| 
 | |
| /**
 | |
|  * \brief SSL server profile: minu2g.
 | |
|  *
 | |
|  * This profile uses only TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256.
 | |
|  * Server key is EC, and ECDH key exchange is used; the issuing CA used
 | |
|  * a RSA key.
 | |
|  *
 | |
|  * The "minu2g" and "minv2g" profiles do not provide forward secrecy,
 | |
|  * but are the lightest on the server (for CPU usage), and are rather
 | |
|  * inexpensive on the client as well.
 | |
|  *
 | |
|  * \param cc          server context to initialise.
 | |
|  * \param chain       server certificate chain.
 | |
|  * \param chain_len   certificate chain length (number of certificate).
 | |
|  * \param sk          EC private key.
 | |
|  */
 | |
| void br_ssl_server_init_minu2g(br_ssl_server_context *cc,
 | |
| 	const br_x509_certificate *chain, size_t chain_len,
 | |
| 	const br_ec_private_key *sk);
 | |
| 
 | |
| /**
 | |
|  * \brief SSL server profile: minv2g.
 | |
|  *
 | |
|  * This profile uses only TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256.
 | |
|  * Server key is EC, and ECDH key exchange is used; the issuing CA used
 | |
|  * an EC key.
 | |
|  *
 | |
|  * The "minu2g" and "minv2g" profiles do not provide forward secrecy,
 | |
|  * but are the lightest on the server (for CPU usage), and are rather
 | |
|  * inexpensive on the client as well.
 | |
|  *
 | |
|  * \param cc          server context to initialise.
 | |
|  * \param chain       server certificate chain.
 | |
|  * \param chain_len   certificate chain length (number of certificate).
 | |
|  * \param sk          EC private key.
 | |
|  */
 | |
| void br_ssl_server_init_minv2g(br_ssl_server_context *cc,
 | |
| 	const br_x509_certificate *chain, size_t chain_len,
 | |
| 	const br_ec_private_key *sk);
 | |
| 
 | |
| /**
 | |
|  * \brief SSL server profile: mine2c.
 | |
|  *
 | |
|  * This profile uses only TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256.
 | |
|  * Server key is RSA, and ECDHE key exchange is used. This suite
 | |
|  * provides forward security.
 | |
|  *
 | |
|  * \param cc          server context to initialise.
 | |
|  * \param chain       server certificate chain.
 | |
|  * \param chain_len   certificate chain length (number of certificate).
 | |
|  * \param sk          RSA private key.
 | |
|  */
 | |
| void br_ssl_server_init_mine2c(br_ssl_server_context *cc,
 | |
| 	const br_x509_certificate *chain, size_t chain_len,
 | |
| 	const br_rsa_private_key *sk);
 | |
| 
 | |
| /**
 | |
|  * \brief SSL server profile: minf2c.
 | |
|  *
 | |
|  * This profile uses only TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256.
 | |
|  * Server key is EC, and ECDHE key exchange is used. This suite provides
 | |
|  * forward security.
 | |
|  *
 | |
|  * \param cc          server context to initialise.
 | |
|  * \param chain       server certificate chain.
 | |
|  * \param chain_len   certificate chain length (number of certificate).
 | |
|  * \param sk          EC private key.
 | |
|  */
 | |
| void br_ssl_server_init_minf2c(br_ssl_server_context *cc,
 | |
| 	const br_x509_certificate *chain, size_t chain_len,
 | |
| 	const br_ec_private_key *sk);
 | |
| 
 | |
| /**
 | |
|  * \brief Get the supported client suites.
 | |
|  *
 | |
|  * This function shall be called only after the ClientHello has been
 | |
|  * processed, typically from the policy engine. The returned array
 | |
|  * contains the cipher suites that are supported by both the client
 | |
|  * and the server; these suites are in client preference order, unless
 | |
|  * the `BR_OPT_ENFORCE_SERVER_PREFERENCES` flag was set, in which case
 | |
|  * they are in server preference order.
 | |
|  *
 | |
|  * The suites are _translated_, which means that each suite is given
 | |
|  * as two 16-bit integers: the standard suite identifier, and its
 | |
|  * translated version, broken down into its individual components,
 | |
|  * as explained with the `br_suite_translated` type.
 | |
|  *
 | |
|  * The returned array is allocated in the context and will be rewritten
 | |
|  * by each handshake.
 | |
|  *
 | |
|  * \param cc    server context.
 | |
|  * \param num   receives the array size (number of suites).
 | |
|  * \return  the translated common cipher suites, in preference order.
 | |
|  */
 | |
| static inline const br_suite_translated *
 | |
| br_ssl_server_get_client_suites(const br_ssl_server_context *cc, size_t *num)
 | |
| {
 | |
| 	*num = cc->client_suites_num;
 | |
| 	return cc->client_suites;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Get the hash functions and signature algorithms supported by
 | |
|  * the client.
 | |
|  *
 | |
|  * This value is a bit field:
 | |
|  *
 | |
|  *   - If RSA (PKCS#1 v1.5) is supported with hash function of ID `x`,
 | |
|  *     then bit `x` is set (hash function ID is 0 for the special MD5+SHA-1,
 | |
|  *     or 2 to 6 for the SHA family).
 | |
|  *
 | |
|  *   - If ECDSA is supported with hash function of ID `x`, then bit `8+x`
 | |
|  *     is set.
 | |
|  *
 | |
|  *   - Newer algorithms are symbolic 16-bit identifiers that do not
 | |
|  *     represent signature algorithm and hash function separately. If
 | |
|  *     the TLS-level identifier is `0x0800+x` for a `x` in the 0..15
 | |
|  *     range, then bit `16+x` is set.
 | |
|  *
 | |
|  * "New algorithms" are currently defined only in draft documents, so
 | |
|  * this support is subject to possible change. Right now (early 2017),
 | |
|  * this maps ed25519 (EdDSA on Curve25519) to bit 23, and ed448 (EdDSA
 | |
|  * on Curve448) to bit 24. If the identifiers on the wire change in
 | |
|  * future document, then the decoding mechanism in BearSSL will be
 | |
|  * amended to keep mapping ed25519 and ed448 on bits 23 and 24,
 | |
|  * respectively. Mapping of other new algorithms (e.g. RSA/PSS) is not
 | |
|  * guaranteed yet.
 | |
|  *
 | |
|  * \param cc   server context.
 | |
|  * \return  the client-supported hash functions and signature algorithms.
 | |
|  */
 | |
| static inline uint32_t
 | |
| br_ssl_server_get_client_hashes(const br_ssl_server_context *cc)
 | |
| {
 | |
| 	return cc->hashes;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Get the elliptic curves supported by the client.
 | |
|  *
 | |
|  * This is a bit field (bit x is set if curve of ID x is supported).
 | |
|  *
 | |
|  * \param cc   server context.
 | |
|  * \return  the client-supported elliptic curves.
 | |
|  */
 | |
| static inline uint32_t
 | |
| br_ssl_server_get_client_curves(const br_ssl_server_context *cc)
 | |
| {
 | |
| 	return cc->curves;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Clear the complete contents of a SSL server context.
 | |
|  *
 | |
|  * Everything is cleared, including the reference to the configured buffer,
 | |
|  * implementations, cipher suites and state. This is a preparatory step
 | |
|  * to assembling a custom profile.
 | |
|  *
 | |
|  * \param cc   server context to clear.
 | |
|  */
 | |
| void br_ssl_server_zero(br_ssl_server_context *cc);
 | |
| 
 | |
| /**
 | |
|  * \brief Set an externally provided policy context.
 | |
|  *
 | |
|  * The policy context's methods are invoked to decide the cipher suite
 | |
|  * and certificate chain, and to perform operations involving the server's
 | |
|  * private key.
 | |
|  *
 | |
|  * \param cc     server context.
 | |
|  * \param pctx   policy context (pointer to its vtable field).
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_server_set_policy(br_ssl_server_context *cc,
 | |
| 	const br_ssl_server_policy_class **pctx)
 | |
| {
 | |
| 	cc->policy_vtable = pctx;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Set the server certificate chain and key (single RSA case).
 | |
|  *
 | |
|  * This function uses a policy context included in the server context.
 | |
|  * It configures use of a single server certificate chain with a RSA
 | |
|  * private key. The `allowed_usages` is a combination of usages, namely
 | |
|  * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`; this enables or disables
 | |
|  * the corresponding cipher suites (i.e. `TLS_RSA_*` use the RSA key for
 | |
|  * key exchange, while `TLS_ECDHE_RSA_*` use the RSA key for signatures).
 | |
|  *
 | |
|  * \param cc               server context.
 | |
|  * \param chain            server certificate chain to send to the client.
 | |
|  * \param chain_len        chain length (number of certificates).
 | |
|  * \param sk               server private key (RSA).
 | |
|  * \param allowed_usages   allowed private key usages.
 | |
|  * \param irsacore         RSA core implementation.
 | |
|  * \param irsasign         RSA signature implementation (PKCS#1 v1.5).
 | |
|  */
 | |
| void br_ssl_server_set_single_rsa(br_ssl_server_context *cc,
 | |
| 	const br_x509_certificate *chain, size_t chain_len,
 | |
| 	const br_rsa_private_key *sk, unsigned allowed_usages,
 | |
| 	br_rsa_private irsacore, br_rsa_pkcs1_sign irsasign);
 | |
| 
 | |
| /**
 | |
|  * \brief Set the server certificate chain and key (single EC case).
 | |
|  *
 | |
|  * This function uses a policy context included in the server context.
 | |
|  * It configures use of a single server certificate chain with an EC
 | |
|  * private key. The `allowed_usages` is a combination of usages, namely
 | |
|  * `BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`; this enables or disables
 | |
|  * the corresponding cipher suites (i.e. `TLS_ECDH_*` use the EC key for
 | |
|  * key exchange, while `TLS_ECDHE_ECDSA_*` use the EC key for signatures).
 | |
|  *
 | |
|  * In order to support `TLS_ECDH_*` cipher suites (non-ephemeral ECDH),
 | |
|  * the algorithm type of the key used by the issuing CA to sign the
 | |
|  * server's certificate must be provided, as `cert_issuer_key_type`
 | |
|  * parameter (this value is either `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`).
 | |
|  *
 | |
|  * \param cc                     server context.
 | |
|  * \param chain                  server certificate chain to send.
 | |
|  * \param chain_len              chain length (number of certificates).
 | |
|  * \param sk                     server private key (EC).
 | |
|  * \param allowed_usages         allowed private key usages.
 | |
|  * \param cert_issuer_key_type   issuing CA's key type.
 | |
|  * \param iec                    EC core implementation.
 | |
|  * \param iecdsa                 ECDSA signature implementation ("asn1" format).
 | |
|  */
 | |
| void br_ssl_server_set_single_ec(br_ssl_server_context *cc,
 | |
| 	const br_x509_certificate *chain, size_t chain_len,
 | |
| 	const br_ec_private_key *sk, unsigned allowed_usages,
 | |
| 	unsigned cert_issuer_key_type,
 | |
| 	const br_ec_impl *iec, br_ecdsa_sign iecdsa);
 | |
| 
 | |
| /**
 | |
|  * \brief Activate client certificate authentication.
 | |
|  *
 | |
|  * The trust anchor encoded X.500 names (DN) to send to the client are
 | |
|  * provided. A client certificate will be requested and validated through
 | |
|  * the X.509 validator configured in the SSL engine. If `num` is 0, then
 | |
|  * client certificate authentication is disabled.
 | |
|  *
 | |
|  * If the client does not send a certificate, or on validation failure,
 | |
|  * the handshake aborts. Unauthenticated clients can be tolerated by
 | |
|  * setting the `BR_OPT_TOLERATE_NO_CLIENT_AUTH` flag.
 | |
|  *
 | |
|  * The provided array is linked in, not copied, so that pointer must
 | |
|  * remain valid as long as anchor names may be used.
 | |
|  *
 | |
|  * \param cc         server context.
 | |
|  * \param ta_names   encoded trust anchor names.
 | |
|  * \param num        number of encoded trust anchor names.
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_server_set_trust_anchor_names(br_ssl_server_context *cc,
 | |
| 	const br_x500_name *ta_names, size_t num)
 | |
| {
 | |
| 	cc->ta_names = ta_names;
 | |
| 	cc->tas = NULL;
 | |
| 	cc->num_tas = num;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Activate client certificate authentication.
 | |
|  *
 | |
|  * This is a variant for `br_ssl_server_set_trust_anchor_names()`: the
 | |
|  * trust anchor names are provided not as an array of stand-alone names
 | |
|  * (`br_x500_name` structures), but as an array of trust anchors
 | |
|  * (`br_x509_trust_anchor` structures). The server engine itself will
 | |
|  * only use the `dn` field of each trust anchor. This is meant to allow
 | |
|  * defining a single array of trust anchors, to be used here and in the
 | |
|  * X.509 validation engine itself.
 | |
|  *
 | |
|  * The provided array is linked in, not copied, so that pointer must
 | |
|  * remain valid as long as anchor names may be used.
 | |
|  *
 | |
|  * \param cc    server context.
 | |
|  * \param tas   trust anchors (only names are used).
 | |
|  * \param num   number of trust anchors.
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_server_set_trust_anchor_names_alt(br_ssl_server_context *cc,
 | |
| 	const br_x509_trust_anchor *tas, size_t num)
 | |
| {
 | |
| 	cc->ta_names = NULL;
 | |
| 	cc->tas = tas;
 | |
| 	cc->num_tas = num;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Configure the cache for session parameters.
 | |
|  *
 | |
|  * The cache context is provided as a pointer to its first field (vtable
 | |
|  * pointer).
 | |
|  *
 | |
|  * \param cc       server context.
 | |
|  * \param vtable   session cache context.
 | |
|  */
 | |
| static inline void
 | |
| br_ssl_server_set_cache(br_ssl_server_context *cc,
 | |
| 	const br_ssl_session_cache_class **vtable)
 | |
| {
 | |
| 	cc->cache_vtable = vtable;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * \brief Prepare or reset a server context for handling an incoming client.
 | |
|  *
 | |
|  * \param cc   server context.
 | |
|  * \return  1 on success, 0 on error.
 | |
|  */
 | |
| int br_ssl_server_reset(br_ssl_server_context *cc);
 | |
| 
 | |
| /* ===================================================================== */
 | |
| 
 | |
| /*
 | |
|  * Context for the simplified I/O context. The transport medium is accessed
 | |
|  * through the low_read() and low_write() callback functions, each with
 | |
|  * its own opaque context pointer.
 | |
|  *
 | |
|  *  low_read()    read some bytes, at most 'len' bytes, into data[]. The
 | |
|  *                returned value is the number of read bytes, or -1 on error.
 | |
|  *                The 'len' parameter is guaranteed never to exceed 20000,
 | |
|  *                so the length always fits in an 'int' on all platforms.
 | |
|  *
 | |
|  *  low_write()   write up to 'len' bytes, to be read from data[]. The
 | |
|  *                returned value is the number of written bytes, or -1 on
 | |
|  *                error. The 'len' parameter is guaranteed never to exceed
 | |
|  *                20000, so the length always fits in an 'int' on all
 | |
|  *                parameters.
 | |
|  *
 | |
|  * A socket closure (if the transport medium is a socket) should be reported
 | |
|  * as an error (-1). The callbacks shall endeavour to block until at least
 | |
|  * one byte can be read or written; a callback returning 0 at times is
 | |
|  * acceptable, but this normally leads to the callback being immediately
 | |
|  * called again, so the callback should at least always try to block for
 | |
|  * some time if no I/O can take place.
 | |
|  *
 | |
|  * The SSL engine naturally applies some buffering, so the callbacks need
 | |
|  * not apply buffers of their own.
 | |
|  */
 | |
| /**
 | |
|  * \brief Context structure for the simplified SSL I/O wrapper.
 | |
|  *
 | |
|  * This structure is initialised with `br_sslio_init()`. Its contents
 | |
|  * are opaque and shall not be accessed directly.
 | |
|  */
 | |
| typedef struct {
 | |
| #ifndef BR_DOXYGEN_IGNORE
 | |
| 	br_ssl_engine_context *engine;
 | |
| 	int (*low_read)(void *read_context,
 | |
| 		unsigned char *data, size_t len);
 | |
| 	void *read_context;
 | |
| 	int (*low_write)(void *write_context,
 | |
| 		const unsigned char *data, size_t len);
 | |
| 	void *write_context;
 | |
| #endif
 | |
| } br_sslio_context;
 | |
| 
 | |
| /**
 | |
|  * \brief Initialise a simplified I/O wrapper context.
 | |
|  *
 | |
|  * The simplified I/O wrapper offers a simpler read/write API for a SSL
 | |
|  * engine (client or server), using the provided callback functions for
 | |
|  * reading data from, or writing data to, the transport medium.
 | |
|  *
 | |
|  * The callback functions have the following semantics:
 | |
|  *
 | |
|  *   - Each callback receives an opaque context value (of type `void *`)
 | |
|  *     that the callback may use arbitrarily (or possibly ignore).
 | |
|  *
 | |
|  *   - `low_read()` reads at least one byte, at most `len` bytes, from
 | |
|  *     the transport medium. Read bytes shall be written in `data`.
 | |
|  *
 | |
|  *   - `low_write()` writes at least one byte, at most `len` bytes, unto
 | |
|  *     the transport medium. The bytes to write are read from `data`.
 | |
|  *
 | |
|  *   - The `len` parameter is never zero, and is always lower than 20000.
 | |
|  *
 | |
|  *   - The number of processed bytes (read or written) is returned. Since
 | |
|  *     that number is less than 20000, it always fits on an `int`.
 | |
|  *
 | |
|  *   - On error, the callbacks return -1. Reaching end-of-stream is an
 | |
|  *     error. Errors are permanent: the SSL connection is terminated.
 | |
|  *
 | |
|  *   - Callbacks SHOULD NOT return 0. This is tolerated, as long as
 | |
|  *     callbacks endeavour to block for some non-negligible amount of
 | |
|  *     time until at least one byte can be sent or received (if a
 | |
|  *     callback returns 0, then the wrapper invokes it again
 | |
|  *     immediately).
 | |
|  *
 | |
|  *   - Callbacks MAY return as soon as at least one byte is processed;
 | |
|  *     they MAY also insist on reading or writing _all_ requested bytes.
 | |
|  *     Since SSL is a self-terminated protocol (each record has a length
 | |
|  *     header), this does not change semantics.
 | |
|  *
 | |
|  *   - Callbacks need not apply any buffering (for performance) since SSL
 | |
|  *     itself uses buffers.
 | |
|  *
 | |
|  * \param ctx             wrapper context to initialise.
 | |
|  * \param engine          SSL engine to wrap.
 | |
|  * \param low_read        callback for reading data from the transport.
 | |
|  * \param read_context    context pointer for `low_read()`.
 | |
|  * \param low_write       callback for writing data on the transport.
 | |
|  * \param write_context   context pointer for `low_write()`.
 | |
|  */
 | |
| void br_sslio_init(br_sslio_context *ctx,
 | |
| 	br_ssl_engine_context *engine,
 | |
| 	int (*low_read)(void *read_context,
 | |
| 		unsigned char *data, size_t len),
 | |
| 	void *read_context,
 | |
| 	int (*low_write)(void *write_context,
 | |
| 		const unsigned char *data, size_t len),
 | |
| 	void *write_context);
 | |
| 
 | |
| /**
 | |
|  * \brief Read some application data from a SSL connection.
 | |
|  *
 | |
|  * If `len` is zero, then this function returns 0 immediately. In
 | |
|  * all other cases, it never returns 0.
 | |
|  *
 | |
|  * This call returns only when at least one byte has been obtained.
 | |
|  * Returned value is the number of bytes read, or -1 on error. The
 | |
|  * number of bytes always fits on an 'int' (data from a single SSL/TLS
 | |
|  * record is returned).
 | |
|  *
 | |
|  * On error or SSL closure, this function returns -1. The caller should
 | |
|  * inspect the error status on the SSL engine to distinguish between
 | |
|  * normal closure and error.
 | |
|  *
 | |
|  * \param cc    SSL wrapper context.
 | |
|  * \param dst   destination buffer for application data.
 | |
|  * \param len   maximum number of bytes to obtain.
 | |
|  * \return  number of bytes obtained, or -1 on error.
 | |
|  */
 | |
| int br_sslio_read(br_sslio_context *cc, void *dst, size_t len);
 | |
| 
 | |
| /**
 | |
|  * \brief Read application data from a SSL connection.
 | |
|  *
 | |
|  * This calls returns only when _all_ requested `len` bytes are read,
 | |
|  * or an error is reached. Returned value is 0 on success, -1 on error.
 | |
|  * A normal (verified) SSL closure before that many bytes are obtained
 | |
|  * is reported as an error by this function.
 | |
|  *
 | |
|  * \param cc    SSL wrapper context.
 | |
|  * \param dst   destination buffer for application data.
 | |
|  * \param len   number of bytes to obtain.
 | |
|  * \return  0 on success, or -1 on error.
 | |
|  */
 | |
| int br_sslio_read_all(br_sslio_context *cc, void *dst, size_t len);
 | |
| 
 | |
| /**
 | |
|  * \brief Write some application data unto a SSL connection.
 | |
|  *
 | |
|  * If `len` is zero, then this function returns 0 immediately. In
 | |
|  * all other cases, it never returns 0.
 | |
|  *
 | |
|  * This call returns only when at least one byte has been written.
 | |
|  * Returned value is the number of bytes written, or -1 on error. The
 | |
|  * number of bytes always fits on an 'int' (less than 20000).
 | |
|  *
 | |
|  * On error or SSL closure, this function returns -1. The caller should
 | |
|  * inspect the error status on the SSL engine to distinguish between
 | |
|  * normal closure and error.
 | |
|  *
 | |
|  * **Important:** SSL is buffered; a "written" byte is a byte that was
 | |
|  * injected into the wrapped SSL engine, but this does not necessarily mean
 | |
|  * that it has been scheduled for sending. Use `br_sslio_flush()` to
 | |
|  * ensure that all pending data has been sent to the transport medium.
 | |
|  *
 | |
|  * \param cc    SSL wrapper context.
 | |
|  * \param src   source buffer for application data.
 | |
|  * \param len   maximum number of bytes to write.
 | |
|  * \return  number of bytes written, or -1 on error.
 | |
|  */
 | |
| int br_sslio_write(br_sslio_context *cc, const void *src, size_t len);
 | |
| 
 | |
| /**
 | |
|  * \brief Write application data unto a SSL connection.
 | |
|  *
 | |
|  * This calls returns only when _all_ requested `len` bytes have been
 | |
|  * written, or an error is reached. Returned value is 0 on success, -1
 | |
|  * on error. A normal (verified) SSL closure before that many bytes are
 | |
|  * written is reported as an error by this function.
 | |
|  *
 | |
|  * **Important:** SSL is buffered; a "written" byte is a byte that was
 | |
|  * injected into the wrapped SSL engine, but this does not necessarily mean
 | |
|  * that it has been scheduled for sending. Use `br_sslio_flush()` to
 | |
|  * ensure that all pending data has been sent to the transport medium.
 | |
|  *
 | |
|  * \param cc    SSL wrapper context.
 | |
|  * \param src   source buffer for application data.
 | |
|  * \param len   number of bytes to write.
 | |
|  * \return  0 on success, or -1 on error.
 | |
|  */
 | |
| int br_sslio_write_all(br_sslio_context *cc, const void *src, size_t len);
 | |
| 
 | |
| /**
 | |
|  * \brief Flush pending data.
 | |
|  *
 | |
|  * This call makes sure that any buffered application data in the
 | |
|  * provided context (including the wrapped SSL engine) has been sent
 | |
|  * to the transport medium (i.e. accepted by the `low_write()` callback
 | |
|  * method). If there is no such pending data, then this function does
 | |
|  * nothing (and returns a success, i.e. 0).
 | |
|  *
 | |
|  * If the underlying transport medium has its own buffers, then it is
 | |
|  * up to the caller to ensure the corresponding flushing.
 | |
|  *
 | |
|  * Returned value is 0 on success, -1 on error.
 | |
|  *
 | |
|  * \param cc    SSL wrapper context.
 | |
|  * \return  0 on success, or -1 on error.
 | |
|  */
 | |
| int br_sslio_flush(br_sslio_context *cc);
 | |
| 
 | |
| /**
 | |
|  * \brief Close the SSL connection.
 | |
|  *
 | |
|  * This call runs the SSL closure protocol (sending a `close_notify`,
 | |
|  * receiving the response `close_notify`). When it returns, the SSL
 | |
|  * connection is finished. It is still up to the caller to manage the
 | |
|  * possible transport-level termination, if applicable (alternatively,
 | |
|  * the underlying transport stream may be reused for non-SSL messages).
 | |
|  *
 | |
|  * Returned value is 0 on success, -1 on error. A failure by the peer
 | |
|  * to process the complete closure protocol (i.e. sending back the
 | |
|  * `close_notify`) is an error.
 | |
|  *
 | |
|  * \param cc    SSL wrapper context.
 | |
|  * \return  0 on success, or -1 on error.
 | |
|  */
 | |
| int br_sslio_close(br_sslio_context *cc);
 | |
| 
 | |
| /* ===================================================================== */
 | |
| 
 | |
| /*
 | |
|  * Symbolic constants for cipher suites.
 | |
|  */
 | |
| 
 | |
| /* From RFC 5246 */
 | |
| #define BR_TLS_NULL_WITH_NULL_NULL                   0x0000
 | |
| #define BR_TLS_RSA_WITH_NULL_MD5                     0x0001
 | |
| #define BR_TLS_RSA_WITH_NULL_SHA                     0x0002
 | |
| #define BR_TLS_RSA_WITH_NULL_SHA256                  0x003B
 | |
| #define BR_TLS_RSA_WITH_RC4_128_MD5                  0x0004
 | |
| #define BR_TLS_RSA_WITH_RC4_128_SHA                  0x0005
 | |
| #define BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA             0x000A
 | |
| #define BR_TLS_RSA_WITH_AES_128_CBC_SHA              0x002F
 | |
| #define BR_TLS_RSA_WITH_AES_256_CBC_SHA              0x0035
 | |
| #define BR_TLS_RSA_WITH_AES_128_CBC_SHA256           0x003C
 | |
| #define BR_TLS_RSA_WITH_AES_256_CBC_SHA256           0x003D
 | |
| #define BR_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA          0x000D
 | |
| #define BR_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA          0x0010
 | |
| #define BR_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA         0x0013
 | |
| #define BR_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA         0x0016
 | |
| #define BR_TLS_DH_DSS_WITH_AES_128_CBC_SHA           0x0030
 | |
| #define BR_TLS_DH_RSA_WITH_AES_128_CBC_SHA           0x0031
 | |
| #define BR_TLS_DHE_DSS_WITH_AES_128_CBC_SHA          0x0032
 | |
| #define BR_TLS_DHE_RSA_WITH_AES_128_CBC_SHA          0x0033
 | |
| #define BR_TLS_DH_DSS_WITH_AES_256_CBC_SHA           0x0036
 | |
| #define BR_TLS_DH_RSA_WITH_AES_256_CBC_SHA           0x0037
 | |
| #define BR_TLS_DHE_DSS_WITH_AES_256_CBC_SHA          0x0038
 | |
| #define BR_TLS_DHE_RSA_WITH_AES_256_CBC_SHA          0x0039
 | |
| #define BR_TLS_DH_DSS_WITH_AES_128_CBC_SHA256        0x003E
 | |
| #define BR_TLS_DH_RSA_WITH_AES_128_CBC_SHA256        0x003F
 | |
| #define BR_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256       0x0040
 | |
| #define BR_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256       0x0067
 | |
| #define BR_TLS_DH_DSS_WITH_AES_256_CBC_SHA256        0x0068
 | |
| #define BR_TLS_DH_RSA_WITH_AES_256_CBC_SHA256        0x0069
 | |
| #define BR_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256       0x006A
 | |
| #define BR_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256       0x006B
 | |
| #define BR_TLS_DH_anon_WITH_RC4_128_MD5              0x0018
 | |
| #define BR_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA         0x001B
 | |
| #define BR_TLS_DH_anon_WITH_AES_128_CBC_SHA          0x0034
 | |
| #define BR_TLS_DH_anon_WITH_AES_256_CBC_SHA          0x003A
 | |
| #define BR_TLS_DH_anon_WITH_AES_128_CBC_SHA256       0x006C
 | |
| #define BR_TLS_DH_anon_WITH_AES_256_CBC_SHA256       0x006D
 | |
| 
 | |
| /* From RFC 4492 */
 | |
| #define BR_TLS_ECDH_ECDSA_WITH_NULL_SHA              0xC001
 | |
| #define BR_TLS_ECDH_ECDSA_WITH_RC4_128_SHA           0xC002
 | |
| #define BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA      0xC003
 | |
| #define BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA       0xC004
 | |
| #define BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA       0xC005
 | |
| #define BR_TLS_ECDHE_ECDSA_WITH_NULL_SHA             0xC006
 | |
| #define BR_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA          0xC007
 | |
| #define BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA     0xC008
 | |
| #define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA      0xC009
 | |
| #define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA      0xC00A
 | |
| #define BR_TLS_ECDH_RSA_WITH_NULL_SHA                0xC00B
 | |
| #define BR_TLS_ECDH_RSA_WITH_RC4_128_SHA             0xC00C
 | |
| #define BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA        0xC00D
 | |
| #define BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA         0xC00E
 | |
| #define BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA         0xC00F
 | |
| #define BR_TLS_ECDHE_RSA_WITH_NULL_SHA               0xC010
 | |
| #define BR_TLS_ECDHE_RSA_WITH_RC4_128_SHA            0xC011
 | |
| #define BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA       0xC012
 | |
| #define BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA        0xC013
 | |
| #define BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA        0xC014
 | |
| #define BR_TLS_ECDH_anon_WITH_NULL_SHA               0xC015
 | |
| #define BR_TLS_ECDH_anon_WITH_RC4_128_SHA            0xC016
 | |
| #define BR_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA       0xC017
 | |
| #define BR_TLS_ECDH_anon_WITH_AES_128_CBC_SHA        0xC018
 | |
| #define BR_TLS_ECDH_anon_WITH_AES_256_CBC_SHA        0xC019
 | |
| 
 | |
| /* From RFC 5288 */
 | |
| #define BR_TLS_RSA_WITH_AES_128_GCM_SHA256           0x009C
 | |
| #define BR_TLS_RSA_WITH_AES_256_GCM_SHA384           0x009D
 | |
| #define BR_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256       0x009E
 | |
| #define BR_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384       0x009F
 | |
| #define BR_TLS_DH_RSA_WITH_AES_128_GCM_SHA256        0x00A0
 | |
| #define BR_TLS_DH_RSA_WITH_AES_256_GCM_SHA384        0x00A1
 | |
| #define BR_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256       0x00A2
 | |
| #define BR_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384       0x00A3
 | |
| #define BR_TLS_DH_DSS_WITH_AES_128_GCM_SHA256        0x00A4
 | |
| #define BR_TLS_DH_DSS_WITH_AES_256_GCM_SHA384        0x00A5
 | |
| #define BR_TLS_DH_anon_WITH_AES_128_GCM_SHA256       0x00A6
 | |
| #define BR_TLS_DH_anon_WITH_AES_256_GCM_SHA384       0x00A7
 | |
| 
 | |
| /* From RFC 5289 */
 | |
| #define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256   0xC023
 | |
| #define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384   0xC024
 | |
| #define BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256    0xC025
 | |
| #define BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384    0xC026
 | |
| #define BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256     0xC027
 | |
| #define BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384     0xC028
 | |
| #define BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256      0xC029
 | |
| #define BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384      0xC02A
 | |
| #define BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256   0xC02B
 | |
| #define BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384   0xC02C
 | |
| #define BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256    0xC02D
 | |
| #define BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384    0xC02E
 | |
| #define BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256     0xC02F
 | |
| #define BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384     0xC030
 | |
| #define BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256      0xC031
 | |
| #define BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384      0xC032
 | |
| 
 | |
| /* From RFC 6655 and 7251 */
 | |
| #define BR_TLS_RSA_WITH_AES_128_CCM                  0xC09C
 | |
| #define BR_TLS_RSA_WITH_AES_256_CCM                  0xC09D
 | |
| #define BR_TLS_RSA_WITH_AES_128_CCM_8                0xC0A0
 | |
| #define BR_TLS_RSA_WITH_AES_256_CCM_8                0xC0A1
 | |
| #define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM          0xC0AC
 | |
| #define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM          0xC0AD
 | |
| #define BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8        0xC0AE
 | |
| #define BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8        0xC0AF
 | |
| 
 | |
| /* From RFC 7905 */
 | |
| #define BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256     0xCCA8
 | |
| #define BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256   0xCCA9
 | |
| #define BR_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256       0xCCAA
 | |
| #define BR_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256           0xCCAB
 | |
| #define BR_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256     0xCCAC
 | |
| #define BR_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256       0xCCAD
 | |
| #define BR_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256       0xCCAE
 | |
| 
 | |
| /* From RFC 7507 */
 | |
| #define BR_TLS_FALLBACK_SCSV                         0x5600
 | |
| 
 | |
| /*
 | |
|  * Symbolic constants for alerts.
 | |
|  */
 | |
| #define BR_ALERT_CLOSE_NOTIFY                0
 | |
| #define BR_ALERT_UNEXPECTED_MESSAGE         10
 | |
| #define BR_ALERT_BAD_RECORD_MAC             20
 | |
| #define BR_ALERT_RECORD_OVERFLOW            22
 | |
| #define BR_ALERT_DECOMPRESSION_FAILURE      30
 | |
| #define BR_ALERT_HANDSHAKE_FAILURE          40
 | |
| #define BR_ALERT_BAD_CERTIFICATE            42
 | |
| #define BR_ALERT_UNSUPPORTED_CERTIFICATE    43
 | |
| #define BR_ALERT_CERTIFICATE_REVOKED        44
 | |
| #define BR_ALERT_CERTIFICATE_EXPIRED        45
 | |
| #define BR_ALERT_CERTIFICATE_UNKNOWN        46
 | |
| #define BR_ALERT_ILLEGAL_PARAMETER          47
 | |
| #define BR_ALERT_UNKNOWN_CA                 48
 | |
| #define BR_ALERT_ACCESS_DENIED              49
 | |
| #define BR_ALERT_DECODE_ERROR               50
 | |
| #define BR_ALERT_DECRYPT_ERROR              51
 | |
| #define BR_ALERT_PROTOCOL_VERSION           70
 | |
| #define BR_ALERT_INSUFFICIENT_SECURITY      71
 | |
| #define BR_ALERT_INTERNAL_ERROR             80
 | |
| #define BR_ALERT_USER_CANCELED              90
 | |
| #define BR_ALERT_NO_RENEGOTIATION          100
 | |
| #define BR_ALERT_UNSUPPORTED_EXTENSION     110
 | |
| #define BR_ALERT_NO_APPLICATION_PROTOCOL   120
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #endif
 |