]> pd.if.org Git - zpackage/commitdiff
add tlse header
authorNathan Wagner <nw@hydaspes.if.org>
Fri, 15 Feb 2019 18:30:14 +0000 (18:30 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Fri, 15 Feb 2019 18:30:14 +0000 (18:30 +0000)
crypto/tlse.h [new file with mode: 0644]

diff --git a/crypto/tlse.h b/crypto/tlse.h
new file mode 100644 (file)
index 0000000..9645195
--- /dev/null
@@ -0,0 +1,715 @@
+#ifndef TLSE_H
+#define TLSE_H
+
+#include <sys/types.h>
+
+#include "tomcrypt.h"
+
+#include "buffer.h"
+#include "chacha.h"
+
+#define TLS_CLIENT 0
+#define TLS_SERVER 1
+
+#define TLS_CHANGE_CIPHER       0x14
+#define TLS_ALERT               0x15
+#define TLS_HANDSHAKE           0x16
+#define TLS_APPLICATION_DATA    0x17
+
+#define TLS_SERIALIZED_OBJECT   0xFE
+
+#define TLS_BLOB_INCREMENT        0xFFF
+#define TLS_ASN1_MAXLEVEL         0xFF
+
+#define DTLS_COOKIE_SIZE          32
+
+#define TLS_MAX_SHA_SIZE 48
+#define TLS_MAX_HASH_SIZE TLS_MAX_SHA_SIZE
+#define TLS_MAX_RSA_KEY   2048 /* 16kbits */
+
+/* 16 KB - 5 byte header - 32 byte mac - 256 bytes of padding - 3 bytes
+ * for an 8 byte header */
+/* so, minimum app size would be 5+32+256+3+1 = 302, but that's 1 +
+ * record overhead, so it can just be 1, and we don't need to
+ * worry about it */
+#define TLS_MAXTLS_APP_SIZE 16088
+
+
+/* max 1 second sleep */
+#define TLS_MAX_ERROR_SLEEP_uS    1000000
+/* max 5 seconds context sleep */
+#define TLS_MAX_ERROR_IDLE_S      5
+
+#define TLS_V13_MAX_KEY_SIZE      32
+#define TLS_V13_MAX_IV_SIZE       12
+
+#ifndef TLS_MALLOC
+#define TLS_MALLOC(size)        malloc(size)
+#endif
+#ifndef TLS_REALLOC
+#define TLS_REALLOC(ptr, size)  realloc(ptr, size)
+#endif
+#ifndef TLS_FREE
+#define TLS_FREE(ptr)           if (ptr) free(ptr)
+#endif
+
+#ifdef DEBUG
+#define DEBUG_PRINTLN(...)            do { fprintf(stderr, "line %d: ", __LINE__); fprintf(stderr, __VA_ARGS__); } while (0)
+#define DEBUG_PRINT(...)            fprintf(stderr, __VA_ARGS__)
+
+#define DEBUG_DUMP_HEX(buf, len)    do {int _i_; for (_i_ = 0; _i_ < (int)len; _i_++) { DEBUG_PRINT("%02X ", (unsigned int)(buf)[_i_]); } } while (0)
+
+#define DEBUG_INDEX(fields)         print_index(fields)
+#define DEBUG_DUMP(buf, length)     fwrite(buf, 1, length, stderr);
+
+#define DEBUG_DUMP_HEX_LABEL(title, buf, len)    do {fprintf(stderr, "%s (%i): ", title, (int)len); DEBUG_DUMP_HEX(buf, len); fprintf(stderr, "\n");} while (0)
+#else
+#define DEBUG_PRINTLN(...)
+#define DEBUG_PRINT(...)            { }
+#define DEBUG_DUMP_HEX(buf, len)    { }
+#define DEBUG_INDEX(fields)         { }
+#define DEBUG_DUMP(buf, length)     { }
+#define DEBUG_DUMP_HEX_LABEL(title, buf, len) { }
+#endif
+
+#define TLS_WITH_CHACHA20_POLY1305
+#define WITH_TLS_13
+#define TLS_FORWARD_SECRECY
+#define TLS_CLIENT_ECDHE
+#define TLS_CLIENT_ECDSA
+#define TLS_ROBOT_MITIGATION
+#define TLS_ECDSA_SUPPORTED
+
+/* basic superficial X509v1 certificate support */
+#ifndef NO_TLS_X509_V1_SUPPORT
+#define TLS_X509_V1_SUPPORT
+#endif
+
+
+#if 0
+#define SSL_V30                 0x0300
+#define TLS_V10                 0x0301
+#define DTLS_V10                0xFEFF
+#define TLS_V11                 0x0302
+#define TLS_V11_HASH_SIZE 36   /* 16(md5) + 20(sha1) */
+#endif
+
+#define TLS_V12                 0x0303
+#define TLS_V13                 0x0304
+#define DTLS_V12                0xFEFD
+#define DTLS_V13                0xFEFC
+#define TLS_VERSION12 0x0102
+#define TLS_VERSION13 0x0103
+
+#define TLS_NEED_MORE_DATA       0
+#define TLS_GENERIC_ERROR       -1
+#define TLS_BROKEN_PACKET       -2
+#define TLS_NOT_UNDERSTOOD      -3
+#define TLS_NOT_SAFE            -4
+#define TLS_NO_COMMON_CIPHER    -5
+#define TLS_UNEXPECTED_MESSAGE  -6
+#define TLS_CLOSE_CONNECTION    -7
+#define TLS_COMPRESSION_NOT_SUPPORTED -8
+#define TLS_NO_MEMORY           -9
+#define TLS_NOT_VERIFIED        -10
+#define TLS_INTEGRITY_FAILED    -11
+#define TLS_ERROR_ALERT         -12
+#define TLS_BROKEN_CONNECTION   -13
+#define TLS_BAD_CERTIFICATE     -14
+#define TLS_UNSUPPORTED_CERTIFICATE -15
+#define TLS_NO_RENEGOTIATION    -16
+#define TLS_FEATURE_NOT_SUPPORTED   -17
+#define TLS_DECRYPTION_FAILED   -20
+
+#define TLS_AES_128_GCM_SHA256                0x1301
+#define TLS_AES_256_GCM_SHA384                0x1302
+#define TLS_CHACHA20_POLY1305_SHA256          0x1303
+#define TLS_AES_128_CCM_SHA256                0x1304
+#define TLS_AES_128_CCM_8_SHA256              0x1305
+
+#define TLS_RSA_WITH_AES_128_CBC_SHA          0x002F
+#define TLS_RSA_WITH_AES_256_CBC_SHA          0x0035
+#define TLS_RSA_WITH_AES_128_CBC_SHA256       0x003C
+#define TLS_RSA_WITH_AES_256_CBC_SHA256       0x003D
+#define TLS_RSA_WITH_AES_128_GCM_SHA256       0x009C
+#define TLS_RSA_WITH_AES_256_GCM_SHA384       0x009D
+
+/* forward secrecy */
+#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA      0x0033
+#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA      0x0039
+#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256   0x0067
+#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256   0x006B
+#define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256   0x009E
+#define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384   0x009F
+
+#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA    0xC013
+#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA    0xC014
+#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027
+#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F
+#define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030
+
+#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA    0xC009
+#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA    0xC00A
+#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023
+#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024
+#define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B
+#define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C
+
+#define TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256     0xCCA8
+#define TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256   0xCCA9
+#define TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256       0xCCAA
+
+#define TLS_FALLBACK_SCSV                     0x5600
+
+#define TLS_UNSUPPORTED_ALGORITHM   0x00
+#define TLS_RSA_SIGN_RSA            0x01
+#define TLS_RSA_SIGN_MD5            0x04
+#define TLS_RSA_SIGN_SHA1           0x05
+#define TLS_RSA_SIGN_SHA256         0x0B
+#define TLS_RSA_SIGN_SHA384         0x0C
+#define TLS_RSA_SIGN_SHA512         0x0D
+
+#define TLS_EC_PUBLIC_KEY           0x11
+#define TLS_EC_prime192v1           0x12
+#define TLS_EC_prime192v2           0x13
+#define TLS_EC_prime192v3           0x14
+#define TLS_EC_prime239v1           0x15
+#define TLS_EC_prime239v2           0x16
+#define TLS_EC_prime239v3           0x17
+#define TLS_EC_prime256v1           0x18
+#define TLS_EC_secp224r1            21
+#define TLS_EC_secp256r1            23
+#define TLS_EC_secp384r1            24
+#define TLS_EC_secp521r1            25
+
+#define TLS_ALERT_WARNING           0x01
+#define TLS_ALERT_CRITICAL          0x02
+
+#define TLS_CLIENT_HELLO_MINSIZE    41
+#define TLS_CLIENT_RANDOM_SIZE      32
+#define TLS_SERVER_RANDOM_SIZE      32
+#define TLS_MAX_SESSION_ID          32
+#define TLS_SHA256_MAC_SIZE         32
+#define TLS_SHA1_MAC_SIZE           20
+#define TLS_SHA384_MAC_SIZE         48
+#define TLS_MAX_MAC_SIZE            TLS_SHA384_MAC_SIZE
+#define TLS_MAX_KEY_EXPANSION_SIZE  192 /* 160 */
+/* 512bits (sha256) = 64 bytes */
+#define TLS_MAX_HASH_LEN            64
+#define TLS_AES_IV_LENGTH           16
+#define TLS_AES_BLOCK_SIZE          16
+#define TLS_AES_GCM_IV_LENGTH       4
+#define TLS_13_AES_GCM_IV_LENGTH    12
+#define TLS_GCM_TAG_LEN             16
+#define TLS_MAX_TAG_LEN             16
+#define TLS_MIN_FINISHED_OPAQUE_LEN 12
+
+/*
+ * state machine states, per RFC 8446 A.2
+ */
+/* initial state for client or server */
+#define TLS_START 0
+
+/* Client Only */
+#define TLS_WAIT_SH 1
+#define TLS_WAIT_EE 2
+#define TLS_WAIT_CERT_CR 3
+
+/* Client or Server */
+#define TLS_WAIT_CERT 4
+#define TLS_WAIT_CV 5
+#define TLS_WAIT_FINISHED 6
+#define TLS_CONNECTED 7
+/* Server Only */
+#define TLS_RECVD_CH 0x11
+#define TLS_NEGOTIATED 0x12
+#define TLS_WAIT_EOED 0x13
+#define TLS_WAIT_FLIGHT2 0x14
+
+enum tls_alert_description {
+       close_notify = 0,
+       unexpected_message = 10,
+       bad_record_mac = 20,
+       record_overflow = 22,
+#if 1
+       decryption_failed_RESERVED = 21,
+       decompression_failure_RESERVED = 30,
+       no_certificate_RESERVED = 41,
+       export_restriction_RESERVED = 60,
+       no_renegotiation_RESERVED = 100,
+#endif
+       handshake_failure = 40,
+       bad_certificate = 42,
+       unsupported_certificate = 43,
+       certificate_revoked = 44,
+       certificate_expired = 45,
+       certificate_unknown = 46,
+       illegal_parameter = 47,
+       unknown_ca = 48,
+       access_denied = 49,
+       decode_error = 50,
+       decrypt_error = 51,
+       protocol_version = 70,
+       insufficient_security = 71,
+       internal_error = 80,
+       inappropriate_fallback = 86,
+       user_canceled = 90,
+       missing_extension = 109,
+       unsupported_extension = 110,
+       unrecognized_name = 112,
+       bad_certificate_status_response = 113,
+       unknown_psk_identity = 115,
+       certificate_required = 116,
+       no_application_protocol = 120,
+       no_error = 255
+};
+
+enum {
+       client_hello = 1,
+       server_hello = 2,
+       new_session_ticket = 4,
+       end_of_early_data = 5,
+       encrypted_extensions = 8,
+       certificate = 11,
+       certificate_request = 13,
+       certificate_verify = 15,
+       finished = 20,
+       key_update = 24,
+       message_hash = 254
+} tls_handshake_type;
+
+struct DHKey {
+       int iana;
+       void *x;
+       void *y;
+       void *p;
+       void *g;
+};
+
+struct TLSCipher {
+       union {
+               symmetric_CBC aes_local;
+               gcm_state aes_gcm_local;
+               struct chacha_ctx chacha_local;
+       } ctx_local;
+       union {
+               symmetric_CBC aes_remote;
+               gcm_state aes_gcm_remote;
+               struct chacha_ctx chacha_remote;
+       } ctx_remote;
+       union {
+               unsigned char local_mac[TLS_MAX_MAC_SIZE];
+               unsigned char local_aead_iv[TLS_AES_GCM_IV_LENGTH];
+               unsigned char local_iv[TLS_13_AES_GCM_IV_LENGTH];
+               unsigned char local_nonce[TLS_CHACHA20_IV_LENGTH];
+       } ctx_local_mac;
+       union {
+               unsigned char remote_aead_iv[TLS_AES_GCM_IV_LENGTH];
+               unsigned char remote_mac[TLS_MAX_MAC_SIZE];
+               unsigned char remote_iv[TLS_13_AES_GCM_IV_LENGTH];
+               unsigned char remote_nonce[TLS_CHACHA20_IV_LENGTH];
+       } ctx_remote_mac;
+       unsigned char created;
+};
+
+struct TLSCertificate {
+       unsigned short version;
+       unsigned int algorithm;
+       unsigned int key_algorithm;
+       unsigned int ec_algorithm;
+       unsigned char *exponent;
+       unsigned int exponent_len;
+       unsigned char *pk;
+       unsigned int pk_len;
+       unsigned char *priv;
+       unsigned int priv_len;
+       unsigned char *issuer_country;
+       unsigned char *issuer_state;
+       unsigned char *issuer_location;
+       unsigned char *issuer_entity;
+       unsigned char *issuer_subject;
+       char not_before[16]; /* as string */
+       char not_after[16]; /* as string */
+       unsigned char *country;
+       unsigned char *state;
+       unsigned char *location;
+       unsigned char *entity;
+       unsigned char *subject;
+       unsigned char **san;
+       unsigned short san_length;
+       unsigned char *ocsp;
+       unsigned char *serial_number;
+       unsigned int serial_len;
+       unsigned char *sign_key;
+       unsigned int sign_len;
+       unsigned char *fingerprint;
+       unsigned char fp[32];
+       unsigned char *der_bytes;
+       unsigned int der_len;
+       unsigned char *bytes;
+       unsigned int len;
+};
+
+struct TLSContext {
+       unsigned char remote_random[TLS_CLIENT_RANDOM_SIZE];
+       unsigned char local_random[TLS_SERVER_RANDOM_SIZE];
+
+       unsigned char session[TLS_MAX_SESSION_ID];
+       unsigned char session_size;
+
+       unsigned short cipher;
+       unsigned short version;
+
+       uint16_t tlsver;
+       unsigned char is_server;
+
+       struct TLSCertificate **certificates;
+       struct TLSCertificate *private_key;
+       struct TLSCertificate *ec_private_key;
+
+       /* forward secrecy */
+       struct DHKey *dhe;
+       ecc_key *ecc_dhe;
+       char *default_dhe_p;
+       char *default_dhe_g;
+       const struct ECCCurveParameters *curve;
+
+       struct TLSCertificate **client_certificates;
+       int certificates_count;
+       int client_certificates_count;
+
+       unsigned char *master_key;
+       unsigned int master_key_len;
+
+       unsigned char *premaster_key;
+       unsigned int premaster_key_len;
+
+       unsigned char cipher_spec_set;
+       struct TLSCipher crypto;
+
+       hash_state hs_hash;
+       int hs_index;
+       int hs_created;
+       int (*handshake_init)(hash_state *hash);
+       int  (*handshake_process)(hash_state *hash, const unsigned char *in,
+                       unsigned long  inlen);
+       int  (*handshake_done)(hash_state *hash, unsigned char *out);
+       int  (*handshake_get)(hash_state *hash, unsigned char *out);
+
+       uint64_t remote_sequence_number;
+       uint64_t local_sequence_number;
+
+       /* TODO status should be an enum */
+       /* FF = handshake done, should be getting and sending application data
+        */
+       unsigned char connection_status;
+       int state;
+
+       unsigned char critical_error;
+       unsigned char error_code;
+
+       /* next two seem to be for handshake messages */
+       /* hold pending output */
+       struct tls_buffer output_buffer;
+       /* pending input */
+       struct tls_buffer input_buffer;
+
+       /* this is application data read from the peer */
+       struct tls_buffer application_buffer;
+
+       unsigned char is_child;
+
+       char *sni;
+
+       unsigned char request_client_certificate;
+       struct tls_buffer cached_handshake;
+
+       unsigned char client_verified;
+       /* handshake messages flags */
+       unsigned char hs_messages[11];
+
+        int fd;
+       int sync;
+
+       int (*certificate_verify)(struct TLSContext *context, struct TLSCertificate **certificate_chain, int len);
+        void *user_data;
+       ssize_t (*recv)(int sockfd, void *buf, size_t len, int flags);
+       ssize_t (*send)(int sockfd, const void *buf, size_t len, int flags);
+
+       struct TLSCertificate **root_certificates;
+       int root_count;
+       unsigned char *finished_key;
+       unsigned char *remote_finished_key;
+       unsigned char *server_finished_hash;
+
+       char **alpn;
+       unsigned char alpn_count;
+       char *negotiated_alpn;
+
+       struct timespec sleep_until;
+
+       unsigned short tls13_version;
+};
+
+typedef int (*tls_validation_function)(struct TLSContext *context, struct TLSCertificate **certificate_chain, int len);
+
+struct TLSPacket {
+       unsigned char *buf;
+       int payload_pos;
+       size_t len; /* used */
+       size_t size; /* allocated */
+       int broken;
+       struct TLSContext *context;
+};
+
+struct ECCCurveParameters {
+       int size;
+       int iana;
+       const char *name;
+       const char *P;
+       const char *A;
+       const char *B;
+       const char *Gx;
+       const char *Gy;
+       const char *order;
+       ltc_ecc_set_type dp;
+};
+
+unsigned char *tls_pem_decode(const unsigned char *data_in, unsigned int input_length, int cert_index, unsigned int *output_len);
+struct TLSCertificate *tls_create_certificate();
+int tls_certificate_valid_subject(struct TLSCertificate *cert, const char *subject);
+int tls_certificate_valid_subject_name(const unsigned char *cert_subject, const char *subject);
+int tls_certificate_is_valid(struct TLSCertificate *cert);
+void tls_certificate_set_copy(unsigned char **member, const unsigned char *val, int len);
+void tls_certificate_set_copy_date(unsigned char *member, const unsigned char *val, int len);
+void tls_certificate_set_key(struct TLSCertificate *cert, const unsigned char *val, int len);
+void tls_certificate_set_priv(struct TLSCertificate *cert, const unsigned char *val, int len);
+void tls_certificate_set_sign_key(struct TLSCertificate *cert, const unsigned char *val, int len);
+void tls_certificate_set_exponent(struct TLSCertificate *cert, const unsigned char *val, int len);
+void tls_certificate_set_serial(struct TLSCertificate *cert, const unsigned char *val, int len);
+void tls_certificate_set_algorithm(unsigned int *algorithm, const unsigned char *val, int len);
+void tls_destroy_certificate(struct TLSCertificate *cert);
+struct TLSPacket *tls_create_packet(struct TLSContext *context, unsigned char type, unsigned short version, int payload_size_hint);
+void tls_destroy_packet(struct TLSPacket *packet);
+void tls_packet_update(struct TLSPacket *packet);
+int tls_packet_append(struct TLSPacket *packet, const unsigned char *buf, unsigned int len);
+int tls_packet_uint8(struct TLSPacket *packet, unsigned char i);
+int tls_packet_uint16(struct TLSPacket *packet, unsigned short i);
+int tls_packet_uint32(struct TLSPacket *packet, unsigned int i);
+int tls_packet_uint24(struct TLSPacket *packet, unsigned int i);
+int tls_random(unsigned char *key, int len);
+
+/*
+ * Get encrypted data to write, if any. Once you've sent all of it, call
+ * tls_buffer_clear().
+ */
+const unsigned char *tls_get_write_buffer(struct TLSContext *context, unsigned
+               int *outlen);
+
+void tls_buffer_clear(struct TLSContext *context);
+
+/* Returns 1 for established, 0 for not established yet, and -1 for a critical
+ * error. */
+int tls_established(struct TLSContext *context);
+
+/* Discards any unread decrypted data not consumed by tls_read(). */
+void tls_read_clear(struct TLSContext *context);
+
+/*
+ * Reads any unread decrypted data (see tls_consume_stream). If you don't read
+ * all of it, the remainder will be left in the internal buffers for next
+ * tls_read(). Returns -1 for fatal error, 0 for no more data, or otherwise the
+ * number of bytes copied into the buffer (up to a maximum of the given size).
+ */
+ssize_t tls_read(struct TLSContext *context, void *buf, size_t size);
+
+struct TLSContext *tls_create_context(int is_server, unsigned short version);
+
+const struct ECCCurveParameters *tls_set_curve(struct TLSContext *context, const struct ECCCurveParameters *curve);
+
+/* Create a context for a given client, from a server context. Returns NULL on
+ * error. */
+struct TLSContext *tls_accept(struct TLSContext *context);
+
+int tls_set_default_dhe_pg(struct TLSContext *context, const char *p_hex_str, const char *g_hex_str);
+void tls_destroy_context(struct TLSContext *context);
+int tls_choose_cipher(struct TLSContext *context, const unsigned char *buf, int buf_len, int *scsv_set);
+int tls_cipher_supported(struct TLSContext *context, unsigned short cipher);
+int tls_cipher_is_ephemeral(struct TLSContext *context);
+const char *tls_cipher_name(struct TLSContext *context);
+int tls_is_ecdsa(struct TLSContext *context);
+void tls_send_client_key_exchange(struct TLSContext *context);
+size_t tls_queue_packet(struct TLSPacket *packet);
+struct TLSPacket *tls_build_server_key_exchange(struct TLSContext *context, int method);
+struct TLSPacket *tls_build_hello(struct TLSContext *context, int tls13_downgrade);
+struct TLSPacket *tls_build_client_hello(struct TLSContext *context); 
+struct TLSPacket *tls_certificate_request(struct TLSContext *context);
+struct TLSPacket *tls_build_verify_request(struct TLSContext *context);
+
+int tls_parse_client_hello(struct TLSContext *context, const unsigned char *buf, int buf_len, unsigned int *write_packets);
+
+int tls_parse_certificate(struct TLSContext *context, const unsigned char *buf, int buf_len, int is_client);
+int tls_parse_server_key_exchange(struct TLSContext *context, const unsigned char *buf, int buf_len);
+int tls_parse_client_key_exchange(struct TLSContext *context, const unsigned char *buf, int buf_len);
+int tls_parse_finished(struct TLSContext *context, const unsigned char *buf, int buf_len, unsigned int *write_packets);
+int tls_parse_verify(struct TLSContext *context, const unsigned char *buf, int buf_len);
+int tls_parse_payload(struct TLSContext *context, const unsigned char *buf, int buf_len);
+int tls_parse_message(struct TLSContext *context, unsigned char *buf, int buf_len);
+int tls_certificate_verify_signature(struct TLSCertificate *cert, struct TLSCertificate *parent);
+int tls_certificate_chain_is_valid(struct TLSCertificate **certificates, int len);
+int tls_certificate_chain_is_valid_root(struct TLSContext *context, struct TLSCertificate **certificates, int len);
+
+/*
+ * Add a certificate or a certificate chain to the given context, in PEM form.
+ * Returns a negative value (TLS_GENERIC_ERROR etc.) on error, 0 if there were
+ * no certificates in the buffer, or the number of loaded certificates on
+ * success.
+ */
+int tls_load_certificates(struct TLSContext *context, const unsigned char *pem_buffer, int pem_size);
+
+/*
+ * Add a private key to the given context, in PEM form. Returns a negative
+ * value (TLS_GENERIC_ERROR etc.) on error, 0 if there was no private key in
+ * the buffer, or 1 on success.
+ */
+int tls_load_private_key(struct TLSContext *context, const unsigned char *pem_buffer, int pem_size);
+struct TLSPacket *tls_build_certificate(struct TLSContext *context);
+struct TLSPacket *tls_build_finished(struct TLSContext *context);
+struct TLSPacket *tls_build_change_cipher_spec(struct TLSContext *context);
+struct TLSPacket *tls_build_message(struct TLSContext *context, const unsigned char *data, unsigned int len);
+int tls_client_connect(struct TLSContext *context);
+ssize_t tls_write(struct TLSContext *context, const void *buf, size_t count);
+
+/*
+ * Process a given number of input bytes from a socket. If the other side just
+ * presented a certificate and certificate_verify is not NULL, it will be
+ * called.
+ *
+ * Returns 0 if there's no data ready yet, a negative value (see
+ * TLS_GENERIC_ERROR etc.) for an error, or a positive value (the number of
+ * bytes used from buf) if one or more complete TLS messages were received. The
+ * data is copied into an internal buffer even if not all of it was consumed,
+ * so you should not re-send it the next time.
+ *
+ * Decrypted data, if any, should be read back with tls_read(). Can change the
+ * status of tls_established(). If the library has anything to send back on the
+ * socket (e.g. as part of the handshake), tls_get_write_buffer() will return
+ * non-NULL.
+ */
+int tls_consume_stream(struct TLSContext *context);
+void tls_close_notify(struct TLSContext *context);
+void tls_alert(struct TLSContext *context, int critical, int code);
+
+/* Whether tls_consume_stream() has data in its buffer that is not processed
+ * yet. */
+int tls_pending(struct TLSContext *context);
+
+int tls_is_broken(struct TLSContext *context);
+int tls_request_client_certificate(struct TLSContext *context);
+int tls_client_verified(struct TLSContext *context);
+const char *tls_sni(struct TLSContext *context);
+int tls_sni_set(struct TLSContext *context, const char *sni);
+int tls_load_root_certificates(struct TLSContext *context, const unsigned char *pem_buffer, int pem_size);
+int tls_default_verify(struct TLSContext *context, struct TLSCertificate **certificate_chain, int len);
+void tls_print_certificate(const char *fname);
+int tls_add_alpn(struct TLSContext *context, const char *alpn);
+int tls_alpn_contains(struct TLSContext *context, const char *alpn, unsigned char alpn_size);
+/* useful when renewing certificates for servers, without the need to restart
+ * the server */
+int tls_clear_certificates(struct TLSContext *context);
+int tls_make_ktls(struct TLSContext *context, int socket);
+int tls_unmake_ktls(struct TLSContext *context, int socket);
+
+int x25519(uint8_t *r, const uint8_t *k, const uint8_t *u);
+
+int tls_load_root_file(struct TLSContext *context, const char *pem_filename);
+void tls_set_verify(struct TLSContext *context, tls_validation_function verify_callback);
+int tls_set_fd(struct TLSContext *context, int socket);
+int tls_connect(struct TLSContext *context);
+int tls_shutdown(struct TLSContext *context);
+void tls_free(struct TLSContext *context);
+int base64decode(const char *in, size_t inLen, unsigned char *out, size_t *outLen); 
+ssize_t tls_fsync(struct TLSContext *context);
+struct TLSCertificate *asn1_parse(struct TLSContext *context,
+                                 const unsigned char *buffer, int size,
+                                 int client_cert);
+int tls_mac_length(struct TLSContext *context);
+int tls_is_aead(struct TLSContext *context);
+int tls_crypto_create(struct TLSContext *context, int key_length,
+               unsigned char *localkey,
+               unsigned char *localiv,
+               unsigned char *remotekey,
+               unsigned char *remoteiv);
+
+/* DH forward secrecy */
+unsigned char *tls_decrypt_dhe(struct TLSContext *context, const unsigned char
+               *buffer, unsigned int len, unsigned int *size, int clear_key);
+unsigned char *tls_decrypt_ecc_dhe(struct TLSContext *context, const unsigned
+               char *buffer, unsigned int len, unsigned int *size, int
+               clear_key);
+void tls_dhe_free(struct TLSContext *context);
+void tls_ecc_dhe_free(struct TLSContext *context);
+void tls_dh_clear_key(struct DHKey * key);
+void tls_dhe_create(struct TLSContext *context);
+void tls_ecc_dhe_create(struct TLSContext *context);
+int tls_dh_make_key(int keysize, struct DHKey *key, const char *pbuf,
+                            const char *gbuf, int pbuf_len, int gbuf_len); 
+void tls_dhe_free(struct TLSContext *context);
+int tls_dh_export_Y(unsigned char *Ybuf, unsigned long *Ylen,
+                            struct DHKey *key);
+int tls_dh_export_pqY(unsigned char *pbuf, unsigned long *plen,
+                              unsigned char *gbuf, unsigned long *glen,
+                              unsigned char *Ybuf, unsigned long *Ylen,
+                              struct DHKey *key);
+void tls_ecc_init_curves();
+int tls_update_hash(struct TLSContext *context, const unsigned char *in,
+               unsigned int len);
+int tls_done_hash(struct TLSContext *context, unsigned char *hout);
+void tls_set_packet_length(struct TLSPacket *packet, uint32_t length);
+int tls_compute_key(struct TLSContext *context, unsigned int key_len);
+int tls_parse_server_hello(struct TLSContext *ctx, const unsigned char *buf, size_t len);
+int tls_supported_version(uint16_t ver);
+int tls_parse_key_share(struct TLSContext *context, const unsigned char *buf,
+               int buf_len);
+unsigned int tls_hmac_message(unsigned char local,
+                              struct TLSContext *context,
+                              const unsigned char *buf,
+                              int buf_len,
+                              const unsigned char *buf2,
+                              int buf_len2, unsigned char *out,
+                              unsigned int outlen);
+void tls_hkdf_expand_label(unsigned int mac_length,
+                                   unsigned char *output,
+                                   unsigned int outlen,
+                                   const unsigned char *secret,
+                                   unsigned int secret_len,
+                                   const char *label,
+                                   unsigned char label_len,
+                                   const unsigned char *data,
+                                   unsigned char data_len);
+int tls_hkdf_extract(unsigned int mac_length,
+                             unsigned char *output, unsigned int outlen,
+                             const unsigned char *salt,
+                             unsigned int salt_len,
+                             const unsigned char *ikm,
+                             unsigned char ikm_len);
+void tls_destroy_hash(struct TLSContext *context);
+int tls_get_hash(struct TLSContext *context, unsigned char *hout);
+int tls_get_hash_idx(struct TLSContext *context);
+
+extern struct ECCCurveParameters secp192r1; 
+extern struct ECCCurveParameters secp224k1; 
+extern struct ECCCurveParameters secp224r1; 
+extern struct ECCCurveParameters secp256k1; 
+extern struct ECCCurveParameters secp256r1; 
+extern struct ECCCurveParameters secp384r1; 
+extern struct ECCCurveParameters secp521r1; 
+extern struct ECCCurveParameters curve25519; 
+extern struct DHKey ffdhe2048;
+extern struct DHKey ffdhe4096;
+extern struct DHKey ffdhe8192;
+extern struct DHKey ffdhe6144;
+extern struct DHKey ffdhe3072;
+extern struct ECCCurveParameters *const tls_ecc_default_curve;
+
+#endif