+#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