Functions
unlikely ()
if
unlikely ();
REAL_HSK_TYPE()
#define REAL_HSK_TYPE(t) ((t)==GNUTLS_HANDSHAKE_HELLO_RETRY_REQUEST?GNUTLS_HANDSHAKE_SERVER_HELLO:t)
IS_SERVER()
#define IS_SERVER(session) (session->security_parameters.entity == GNUTLS_SERVER)
IS_DTLS()
#define IS_DTLS(session) (session->internals.transport == GNUTLS_DGRAM)
IS_KTLS_ENABLED()
#define IS_KTLS_ENABLED(session, interface) (session->internals.ktls_enabled & interface)
RECORD_HEADER_SIZE()
#define RECORD_HEADER_SIZE(session) (IS_DTLS(session) ? DTLS_RECORD_HEADER_SIZE : TLS_RECORD_HEADER_SIZE)
MAX_RECORD_SEND_OVERHEAD()
#define MAX_RECORD_SEND_OVERHEAD(session) (MAX_CIPHER_BLOCK_SIZE/*iv*/+MAX_PAD_SIZE+MAX_HASH_SIZE/*MAC*/)
MAX_RECORD_SEND_SIZE()
#define MAX_RECORD_SEND_SIZE(session)
HANDSHAKE_HEADER_SIZE()
#define HANDSHAKE_HEADER_SIZE(session) (IS_DTLS(session) ? DTLS_HANDSHAKE_HEADER_SIZE : TLS_HANDSHAKE_HEADER_SIZE)
MEMSUB()
#define MEMSUB(x,y) ((ssize_t)((ptrdiff_t)x-(ptrdiff_t)y))
DECR_LEN()
#define DECR_LEN(len, x) DECR_LENGTH_RET(len, x, GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
DECR_LEN_FINAL()
#define DECR_LEN_FINAL(len, x)
DECR_LENGTH_RET()
#define DECR_LENGTH_RET(len, x, RET) DECR_LENGTH_COM(len, x, return RET)
DECR_LENGTH_COM()
#define DECR_LENGTH_COM(len, x, COM) do { if (len<x) {gnutls_assert(); COM;} else len-=x; } while (0)
GNUTLS_POINTER_TO_INT()
#define GNUTLS_POINTER_TO_INT(_) ((int) GNUTLS_POINTER_TO_INT_CAST (_))
GNUTLS_INT_TO_POINTER()
#define GNUTLS_INT_TO_POINTER(_) ((void*) GNUTLS_POINTER_TO_INT_CAST (_))
ENABLE_COMPAT()
#define ENABLE_COMPAT(x)
ENABLE_PRIO_COMPAT()
#define ENABLE_PRIO_COMPAT(x)
reset_cand_groups()
#define reset_cand_groups(session)
set_adv_version()
#define set_adv_version(session, major, minor)
Types and Values
HAVE_SSIZE_T
#define HAVE_SSIZE_T
ssize_t
typedef int ssize_t;
ENABLE_ALIGN16
#define ENABLE_ALIGN16
MAX_HANDSHAKE_PACKET_SIZE
#define MAX_HANDSHAKE_PACKET_SIZE 128*1024
GNUTLS_DEF_SESSION_ID_SIZE
#define GNUTLS_DEF_SESSION_ID_SIZE 32
MAX_FILENAME
#define MAX_FILENAME 512
MAX_HASH_SIZE
#define MAX_HASH_SIZE 64
MAX_MAC_KEY_SIZE
#define MAX_MAC_KEY_SIZE 64
MAX_CIPHER_BLOCK_SIZE
#define MAX_CIPHER_BLOCK_SIZE 64 /* CHACHA20 */
MAX_CIPHER_KEY_SIZE
#define MAX_CIPHER_KEY_SIZE 32
MAX_CIPHER_IV_SIZE
#define MAX_CIPHER_IV_SIZE 16
MAX_USERNAME_SIZE
#define MAX_USERNAME_SIZE 128
MAX_SERVER_NAME_SIZE
#define MAX_SERVER_NAME_SIZE 256
AEAD_EXPLICIT_DATA_SIZE
#define AEAD_EXPLICIT_DATA_SIZE 8
AEAD_IMPLICIT_DATA_SIZE
#define AEAD_IMPLICIT_DATA_SIZE 4
GNUTLS_MASTER_SIZE
#define GNUTLS_MASTER_SIZE 48
GNUTLS_RANDOM_SIZE
#define GNUTLS_RANDOM_SIZE 32
DTLS_RETRANS_TIMEOUT
#define DTLS_RETRANS_TIMEOUT 1000
MAX_EXT_TYPES
#define MAX_EXT_TYPES 64
DEFAULT_EXPIRE_TIME
#define DEFAULT_EXPIRE_TIME 21600
STEK_ROTATION_PERIOD_PRODUCT
#define STEK_ROTATION_PERIOD_PRODUCT 3
DEFAULT_HANDSHAKE_TIMEOUT_MS
#define DEFAULT_HANDSHAKE_TIMEOUT_MS 40*1000
DEFAULT_EC_GROUP
#define DEFAULT_EC_GROUP GNUTLS_GROUP_SECP256R1
DEFAULT_MAX_RECORD_SIZE
#define DEFAULT_MAX_RECORD_SIZE 16384
DEFAULT_MAX_EARLY_DATA_SIZE
#define DEFAULT_MAX_EARLY_DATA_SIZE 16384
TLS_RECORD_HEADER_SIZE
#define TLS_RECORD_HEADER_SIZE 5
DTLS_RECORD_HEADER_SIZE
#define DTLS_RECORD_HEADER_SIZE (TLS_RECORD_HEADER_SIZE+8)
MAX_RECORD_HEADER_SIZE
#define MAX_RECORD_HEADER_SIZE DTLS_RECORD_HEADER_SIZE
MIN_RECORD_SIZE
#define MIN_RECORD_SIZE 512
MIN_RECORD_SIZE_SMALL
#define MIN_RECORD_SIZE_SMALL 64
MAX_PAD_SIZE
#define MAX_PAD_SIZE 255
EXTRA_COMP_SIZE
#define EXTRA_COMP_SIZE 2048
TLS_HANDSHAKE_HEADER_SIZE
#define TLS_HANDSHAKE_HEADER_SIZE 4
DTLS_HANDSHAKE_HEADER_SIZE
#define DTLS_HANDSHAKE_HEADER_SIZE (TLS_HANDSHAKE_HEADER_SIZE+8)
MAX_HANDSHAKE_HEADER_SIZE
#define MAX_HANDSHAKE_HEADER_SIZE DTLS_HANDSHAKE_HEADER_SIZE
MAX_PVP_SEED_SIZE
#define MAX_PVP_SEED_SIZE 256
DTLS_DEFAULT_MTU
#define DTLS_DEFAULT_MTU 1200
DTLS_MAX_COOKIE_SIZE
#define DTLS_MAX_COOKIE_SIZE 32
MAX_HANDSHAKE_HELLO_VERIFY_REQUESTS
#define MAX_HANDSHAKE_HELLO_VERIFY_REQUESTS 5
MAX_PK_PARAM_SIZE
#define MAX_PK_PARAM_SIZE 2048
DEFAULT_MAX_VERIFY_DEPTH
#define DEFAULT_MAX_VERIFY_DEPTH 16
DEFAULT_MAX_VERIFY_BITS
#define DEFAULT_MAX_VERIFY_BITS (MAX_PK_PARAM_SIZE*8)
MAX_VERIFY_DEPTH
#define MAX_VERIFY_DEPTH 4096
GNUTLS_KX_INVALID
#define GNUTLS_KX_INVALID (-1)
TICKET_STATE
#define TICKET_STATE session->internals.ticket_state
BYE_STATE
#define BYE_STATE session->internals.bye_state
REAUTH_STATE
#define REAUTH_STATE session->internals.reauth_state
MAX_ALGOS
#define MAX_ALGOS GNUTLS_MAX_ALGORITHM_NUM
GNUTLS_EXTENSION_MAX_VALUE
#define GNUTLS_EXTENSION_MAX_VALUE 63
ext_track_t
#define ext_track_t uint64_t
GNUTLS_PK_ANY
#define GNUTLS_PK_ANY (gnutls_pk_algorithm_t)-1
GNUTLS_PK_NONE
#define GNUTLS_PK_NONE (gnutls_pk_algorithm_t)-2
MAX_HANDSHAKE_MSGS
#define MAX_HANDSHAKE_MSGS 6
handshake_buffer_st
typedef struct {
/* Handshake layer type and sequence of message */
gnutls_handshake_description_t htype;
/* The "real" type received; that is, it does not distinguish
* HRR from server hello, while htype does */
gnutls_handshake_description_t rtype;
uint32_t length;
/* valid in DTLS */
uint16_t sequence;
/* indicate whether that message is complete.
* complete means start_offset == 0 and end_offset == length
*/
uint32_t start_offset;
uint32_t end_offset;
uint8_t header[MAX_HANDSHAKE_HEADER_SIZE];
int header_size;
gnutls_buffer_st data;
} handshake_buffer_st;
mbuffer_st
typedef struct {
/* when used in mbuffer_head_st */
struct mbuffer_st *next;
struct mbuffer_st *prev;
/* msg->size - mark = number of bytes left to process in this
message. Mark should only be non-zero when this buffer is the
head of the queue. */
size_t mark;
/* the data */
gnutls_datum_t msg;
size_t maximum_size;
/* used during fill in, to separate header from data
* body. */
unsigned int uhead_mark;
/* Filled in by record layer on recv:
* type, record_sequence
*/
/* record layer content type */
content_type_t type;
/* record layer sequence */
uint64_t record_sequence;
/* Filled in by handshake layer on send:
* type, epoch, htype, handshake_sequence
*/
/* Record layer epoch of message */
uint16_t epoch;
/* Handshake layer type and sequence of message */
gnutls_handshake_description_t htype;
uint16_t handshake_sequence;
} mbuffer_st;
mbuffer_head_st
typedef struct {
mbuffer_st *head;
mbuffer_st *tail;
unsigned int length;
size_t byte_length;
} mbuffer_head_st;
auth_cred_st
typedef struct {
gnutls_credentials_type_t algorithm;
/* the type of credentials depends on algorithm
*/
void *credentials;
struct auth_cred_st *next;
} auth_cred_st;
TICKET_MASTER_KEY_SIZE
#define TICKET_MASTER_KEY_SIZE (TICKET_KEY_NAME_SIZE+TICKET_CIPHER_KEY_SIZE+TICKET_MAC_SECRET_SIZE)
TICKET_KEY_NAME_SIZE
#define TICKET_KEY_NAME_SIZE 16
TICKET_CIPHER_KEY_SIZE
#define TICKET_CIPHER_KEY_SIZE 32
TICKET_MAC_SECRET_SIZE
#define TICKET_MAC_SECRET_SIZE 16
TICKET_CIPHER
#define TICKET_CIPHER GNUTLS_CIPHER_AES_256_CBC
TICKET_IV_SIZE
#define TICKET_IV_SIZE 16
TICKET_BLOCK_SIZE
#define TICKET_BLOCK_SIZE 16
TICKET_MAC_ALGO
#define TICKET_MAC_ALGO GNUTLS_MAC_SHA1
TICKET_MAC_SIZE
#define TICKET_MAC_SIZE 20 /* HMAC-SHA1 */
struct ticket_st
struct ticket_st {
uint8_t key_name[TICKET_KEY_NAME_SIZE];
uint8_t IV[TICKET_IV_SIZE];
uint8_t *encrypted_state;
uint16_t encrypted_state_len;
uint8_t mac[TICKET_MAC_SIZE];
};
struct binder_data_st
struct binder_data_st {
const struct mac_entry_st *prf; /* non-null if this struct is set */
gnutls_datum_t psk;
/* 0-based index of the selected PSK.
* This only applies if the HSK_PSK_SELECTED flag is set in internals.hsk_flags,
* which signals a PSK has indeed been selected. */
uint8_t idx;
uint8_t resumption; /* whether it is a resumption binder */
};
struct gnutls_key_st
struct gnutls_key_st {
struct { /* These are kept outside the TLS1.3 union as they are
* negotiated via extension, even before protocol is negotiated */
gnutls_pk_params_st ecdh_params;
gnutls_pk_params_st ecdhx_params;
gnutls_pk_params_st dh_params;
} kshare;
/* The union contents depend on the negotiated protocol.
* It should not contain any values which are allocated
* prior to protocol negotiation, as it would be impossible
* to deinitialize.
*/
union {
struct {
/* the current (depending on state) secret, can be
* early_secret, client_early_traffic_secret, ... */
uint8_t temp_secret[MAX_HASH_SIZE];
unsigned temp_secret_size; /* depends on negotiated PRF size */
uint8_t e_ckey[MAX_HASH_SIZE]; /* client_early_traffic_secret */
uint8_t hs_ckey[MAX_HASH_SIZE]; /* client_hs_traffic_secret */
uint8_t hs_skey[MAX_HASH_SIZE]; /* server_hs_traffic_secret */
uint8_t ap_ckey[MAX_HASH_SIZE]; /* client_ap_traffic_secret */
uint8_t ap_skey[MAX_HASH_SIZE]; /* server_ap_traffic_secret */
uint8_t ap_expkey[MAX_HASH_SIZE]; /* {early_,}exporter_master_secret */
uint8_t ap_rms[MAX_HASH_SIZE]; /* resumption_master_secret */
} tls13; /* tls1.3 */
/* Follow the SSL3.0 and TLS1.2 key exchanges */
struct {
/* For ECDH KX */
struct {
gnutls_pk_params_st params; /* private part */
/* public part */
bigint_t x;
bigint_t y;
gnutls_datum_t raw; /* public key used in ECDHX (point) */
} ecdh;
/* For DH KX */
struct {
gnutls_pk_params_st params;
bigint_t client_Y;
} dh;
/* for SRP KX */
struct {
bigint_t srp_key;
bigint_t srp_g;
bigint_t srp_p;
bigint_t A;
bigint_t B;
bigint_t u;
bigint_t b;
bigint_t a;
bigint_t x;
} srp;
} tls12; /* from ssl3.0 to tls12 */
} proto;
/* binders / pre-shared keys in use; temporary storage.
* On client side it will hold data for the resumption and external
* PSKs After server hello is received the selected binder is set on 0 position
* and HSK_PSK_SELECTED is set.
*
* On server side the first value is populated with
* the selected PSK data if HSK_PSK_SELECTED flag is set. */
struct binder_data_st binders[2];
/* TLS pre-master key; applies to 1.2 and 1.3 */
gnutls_datum_t key;
uint8_t
/* The key to encrypt and decrypt session tickets */
session_ticket_key[TICKET_MASTER_KEY_SIZE],
/* Static buffer for the previous key, whenever we need it */
previous_ticket_key[TICKET_MASTER_KEY_SIZE],
/* Initial key supplied by the caller */
initial_stek[TICKET_MASTER_KEY_SIZE];
/* this is used to hold the peers authentication data
*/
/* auth_info_t structures SHOULD NOT contain malloced
* elements. Check gnutls_session_pack.c, and gnutls_auth.c.
* Remember that this should be calloced!
*/
void *auth_info;
gnutls_credentials_type_t auth_info_type;
int auth_info_size; /* needed in order to store to db for restoring
*/
auth_cred_st *cred; /* used to specify keys/certificates etc */
struct {
uint64_t last_result;
uint8_t was_rotated;
gnutls_stek_rotation_callback_t cb;
} totp;
};
struct pin_info_st
struct pin_info_st {
gnutls_pin_callback_t cb;
void *data;
};
record_state_st
typedef struct record_state_st record_state_st;
record_parameters_st
typedef struct record_parameters_st record_parameters_st;
GNUTLS_CIPHER_FLAG_ONLY_AEAD
#define GNUTLS_CIPHER_FLAG_ONLY_AEAD (1 << 0) /* When set, this cipher is only available through the new AEAD API */
GNUTLS_CIPHER_FLAG_XOR_NONCE
#define GNUTLS_CIPHER_FLAG_XOR_NONCE (1 << 1) /* In this TLS AEAD cipher xor the implicit_iv with the nonce */
GNUTLS_CIPHER_FLAG_NO_REKEY
#define GNUTLS_CIPHER_FLAG_NO_REKEY (1 << 2) /* whether this tls1.3 cipher doesn't need to rekey after 2^24 messages */
cipher_entry_st
typedef struct {
const char *name;
gnutls_cipher_algorithm_t id;
uint16_t blocksize;
uint16_t keysize;
cipher_type_t type;
uint16_t implicit_iv; /* the size of implicit IV - the IV generated but not sent */
uint16_t explicit_iv; /* the size of explicit IV - the IV stored in record */
uint16_t cipher_iv; /* the size of IV needed by the cipher */
uint16_t tagsize;
unsigned flags;
} cipher_entry_st;
gnutls_cipher_suite_entry_st
typedef struct {
const char *name;
const uint8_t id[2];
const char *canonical_name;
gnutls_cipher_algorithm_t block_algorithm;
gnutls_kx_algorithm_t kx_algorithm;
gnutls_mac_algorithm_t mac_algorithm;
gnutls_protocol_t min_version; /* this cipher suite is supported
* from 'version' and above;
*/
gnutls_protocol_t max_version; /* this cipher suite is not supported
* after 'version' and above;
*/
gnutls_protocol_t min_dtls_version; /* DTLS min version */
gnutls_protocol_t max_dtls_version; /* DTLS max version */
gnutls_mac_algorithm_t prf;
} gnutls_cipher_suite_entry_st;
gnutls_group_entry_st
typedef struct {
const char *name;
gnutls_group_t id;
const gnutls_datum_t *prime;
const gnutls_datum_t *q;
const gnutls_datum_t *generator;
const unsigned *q_bits;
gnutls_ecc_curve_t curve;
gnutls_pk_algorithm_t pk;
unsigned tls_id; /* The RFC4492 namedCurve ID or TLS 1.3 group ID */
} gnutls_group_entry_st;
GNUTLS_MAC_FLAG_PREIMAGE_INSECURE
#define GNUTLS_MAC_FLAG_PREIMAGE_INSECURE 1 /* if this algorithm should not be trusted for pre-image attacks */
GNUTLS_MAC_FLAG_CONTINUOUS_MAC
#define GNUTLS_MAC_FLAG_CONTINUOUS_MAC (1 << 1) /* if this MAC should be used in a 'continuous' way in TLS */
GNUTLS_MAC_FLAG_PREIMAGE_INSECURE_REVERTIBLE
#define GNUTLS_MAC_FLAG_PREIMAGE_INSECURE_REVERTIBLE (1 << 2) /* if this algorithm should not be trusted for pre-image attacks, but can be enabled through API */
GNUTLS_MAC_FLAG_ALLOW_INSECURE_REVERTIBLE
#define GNUTLS_MAC_FLAG_ALLOW_INSECURE_REVERTIBLE (1 << 3) /* when checking with _gnutls_digest_is_insecure2, don't treat revertible setting as fatal */
mac_entry_st
typedef struct {
const char *name;
const char *oid; /* OID of the hash - if it is a hash */
const char *mac_oid; /* OID of the MAC algorithm - if it is a MAC */
gnutls_mac_algorithm_t id;
unsigned output_size;
unsigned key_size;
unsigned nonce_size;
unsigned placeholder; /* if set, then not a real MAC */
unsigned block_size; /* internal block size for HMAC */
unsigned flags;
} mac_entry_st;
version_entry_st
typedef struct {
const char *name;
gnutls_protocol_t id; /* gnutls internal version number */
unsigned age; /* internal ordering by protocol age */
uint8_t major; /* defined by the protocol */
uint8_t minor; /* defined by the protocol */
transport_t transport; /* Type of transport, stream or datagram */
bool supported; /* 0 not supported, > 0 is supported */
bool supported_revertible;
bool explicit_iv;
bool extensions; /* whether it supports extensions */
bool selectable_sighash; /* whether signatures can be selected */
bool selectable_prf; /* whether the PRF is ciphersuite-defined */
/* if SSL3 is disabled this flag indicates that this protocol is a placeholder,
* otherwise it prevents this protocol from being set as record version */
bool obsolete;
bool tls13_sem; /* The TLS 1.3 handshake semantics */
bool false_start; /* That version can be used with false start */
bool only_extension; /* negotiated only with an extension */
bool post_handshake_auth; /* Supports the TLS 1.3 post handshake auth */
bool key_shares; /* TLS 1.3 key share key exchange */
bool multi_ocsp; /* TLS 1.3 multiple OCSP responses */
/*
* TLS versions modify the semantics of signature algorithms. This number
* is there to distinguish signature algorithms semantics between versions
* (maps to sign_algorithm_st->tls_sem)
*/
uint8_t tls_sig_sem;
} version_entry_st;
sign_algorithm_st
typedef struct {
uint8_t id[2]; /* used to be (in TLS 1.2) hash algorithm , PK algorithm */
uint8_t tls_sem; /* should match the protocol version's tls_sig_sem. */
} sign_algorithm_st;
MAX_VERIFY_DATA_SIZE
#define MAX_VERIFY_DATA_SIZE 36 /* in SSL 3.0, 12 in TLS 1.0 */
security_parameters_st
typedef struct {
unsigned int entity; /* GNUTLS_SERVER or GNUTLS_CLIENT */
/* The epoch used to read and write */
uint16_t epoch_read;
uint16_t epoch_write;
/* The epoch that the next handshake will initialize. */
uint16_t epoch_next;
/* The epoch at index 0 of record_parameters. */
uint16_t epoch_min;
/* this is the ciphersuite we are going to use
* moved here from internals in order to be restored
* on resume;
*/
const struct gnutls_cipher_suite_entry_st *cs;
/* This is kept outside the ciphersuite entry as on certain
* TLS versions we need a separate PRF MAC, i.e., MD5_SHA1. */
const mac_entry_st *prf;
uint8_t master_secret[GNUTLS_MASTER_SIZE];
uint8_t client_random[GNUTLS_RANDOM_SIZE];
uint8_t server_random[GNUTLS_RANDOM_SIZE];
uint8_t session_id[GNUTLS_MAX_SESSION_ID_SIZE];
uint8_t session_id_size;
time_t timestamp;
/* whether client has agreed in post handshake auth - only set on server side */
uint8_t post_handshake_auth;
/* The maximum amount of plaintext sent in a record,
* negotiated with the peer.
*/
uint16_t max_record_send_size;
uint16_t max_record_recv_size;
/* The maximum amount of plaintext sent in a record, set by
* the programmer.
*/
uint16_t max_user_record_send_size;
uint16_t max_user_record_recv_size;
/* The maximum amount of early data */
uint32_t max_early_data_size;
/* holds the negotiated certificate types */
gnutls_certificate_type_t client_ctype;
gnutls_certificate_type_t server_ctype;
/* The selected (after server hello EC or DH group */
const gnutls_group_entry_st *grp;
/* Holds the signature algorithm that will be used in this session,
* selected by the server at the time of Ciphersuite/certificate
* selection - see select_sign_algorithm() */
gnutls_sign_algorithm_t server_sign_algo;
/* Holds the signature algorithm used in this session - If any */
gnutls_sign_algorithm_t client_sign_algo;
/* Whether the master secret negotiation will be according to
* draft-ietf-tls-session-hash-01
*/
uint8_t ext_master_secret;
/* encrypt-then-mac -> rfc7366 */
uint8_t etm;
uint8_t client_auth_type; /* gnutls_credentials_type_t */
uint8_t server_auth_type;
/* Note: if you add anything in Security_Parameters struct, then
* also modify CPY_COMMON in constate.c, and session_pack.c,
* in order to save it in the session storage.
*/
/* Used by extensions that enable supplemental data: Which ones
* do that? Do they belong in security parameters?
*/
int do_recv_supplemental, do_send_supplemental;
const version_entry_st *pversion;
} security_parameters_st;
api_aead_cipher_hd_st
typedef struct {
cipher_hd_st ctx_enc;
} api_aead_cipher_hd_st;
EPOCH_READ_CURRENT
#define EPOCH_READ_CURRENT 70000
EPOCH_WRITE_CURRENT
#define EPOCH_WRITE_CURRENT 70001
EPOCH_NEXT
#define EPOCH_NEXT 70002
priority_st
typedef struct {
unsigned int priorities[MAX_ALGOS];
unsigned int num_priorities;
} priority_st;
enum safe_renegotiation_t
MAX_CIPHERSUITE_SIZE
#define MAX_CIPHERSUITE_SIZE 256
ciphersuite_list_st
typedef struct {
const gnutls_cipher_suite_entry_st *entry[MAX_CIPHERSUITE_SIZE];
unsigned int size;
} ciphersuite_list_st;
group_list_st
typedef struct {
const gnutls_group_entry_st *entry[MAX_ALGOS];
unsigned int size;
bool have_ffdhe;
} group_list_st;
sign_algo_list_st
typedef struct {
const struct gnutls_sign_entry_st *entry[MAX_ALGOS];
unsigned int size;
} sign_algo_list_st;
struct gnutls_priority_st
struct gnutls_priority_st {
priority_st protocol;
priority_st client_ctype;
priority_st server_ctype;
/* The following are not necessary to be stored in
* the structure; however they are required by the
* external APIs: gnutls_priority_*_list() */
priority_st _cipher;
priority_st _mac;
priority_st _kx;
priority_st _sign_algo;
priority_st _supported_ecc;
/* the supported groups */
group_list_st groups;
/* the supported signature algorithms */
sign_algo_list_st sigalg;
/* the supported ciphersuites */
ciphersuite_list_st cs;
/* to disable record padding */
bool no_extensions;
safe_renegotiation_t sr;
bool min_record_version;
bool server_precedence;
bool allow_server_key_usage_violation; /* for test suite purposes only */
bool no_tickets;
bool have_cbc;
bool have_psk;
bool force_etm;
unsigned int additional_verify_flags;
bool tls13_compat_mode;
/* TLS_FALLBACK_SCSV */
bool fallback;
/* The session's expected security level.
* Will be used to determine the minimum DH bits,
* (or the acceptable certificate security level).
*/
gnutls_sec_param_t level;
/* these should be accessed from
* session->internals.VAR names */
bool _allow_large_records;
bool _allow_small_records;
bool _no_etm;
bool _no_ext_master_secret;
bool _allow_key_usage_violation;
bool _allow_wrong_pms;
bool _dumbfw;
unsigned int _dh_prime_bits; /* old (deprecated) variable */
DEF_ATOMIC_INT(usage_cnt);
};
DEFAULT_MAX_EMPTY_RECORDS
#define DEFAULT_MAX_EMPTY_RECORDS 200
dh_params_st
typedef struct {
/* [0] is the prime, [1] is the generator, [2] is Q if available.
*/
bigint_t params[3];
int q_bits; /* length of q in bits. If zero then length is unknown.
*/
} dh_params_st;
tls13_ticket_st
typedef struct {
struct timespec arrival_time;
struct timespec creation_time;
uint32_t lifetime;
uint32_t age_add;
uint8_t nonce[255];
size_t nonce_size;
const mac_entry_st *prf;
uint8_t resumption_master_secret[MAX_HASH_SIZE];
gnutls_datum_t ticket;
} tls13_ticket_st;
dtls_st
typedef struct {
/* HelloVerifyRequest DOS prevention cookie */
gnutls_datum_t dcookie;
/* For DTLS handshake fragmentation and reassembly. */
uint16_t hsk_write_seq;
/* the sequence number of the expected packet */
unsigned int hsk_read_seq;
uint16_t mtu;
/* a flight transmission is in process */
bool flight_init;
/* whether this is the last flight in the protocol */
bool last_flight;
/* the retransmission timeout in milliseconds */
unsigned int retrans_timeout_ms;
unsigned int hsk_hello_verify_requests;
/* The actual retrans_timeout for the next message (e.g. doubled or so)
*/
unsigned int actual_retrans_timeout_ms;
/* timers to handle async handshake after gnutls_handshake()
* has terminated. Required to handle retransmissions.
*/
time_t async_term;
/* last retransmission triggered by record layer */
struct timespec last_retransmit;
unsigned int packets_dropped;
} dtls_st;
tfo_st
typedef struct {
int fd;
int flags;
bool connect_only; /* a previous sendmsg() failed, attempting connect() */
struct sockaddr_storage connect_addr;
socklen_t connect_addrlen;
} tfo_st;
internals_st
typedef struct {
/* holds all the parsed data received by the record layer */
mbuffer_head_st record_buffer;
int handshake_hash_buffer_prev_len; /* keeps the length of handshake_hash_buffer, excluding
* the last received message */
unsigned handshake_hash_buffer_client_hello_len; /* if non-zero it is the length of data until the client hello message */
unsigned handshake_hash_buffer_client_kx_len;/* if non-zero it is the length of data until the
* the client key exchange message */
unsigned handshake_hash_buffer_server_finished_len;/* if non-zero it is the length of data until the
* the server finished message */
unsigned handshake_hash_buffer_client_finished_len;/* if non-zero it is the length of data until the
* the client finished message */
gnutls_buffer_st handshake_hash_buffer; /* used to keep the last received handshake
* message */
bool resumable; /* if we can resume that session */
send_ticket_state_t ticket_state; /* used by gnutls_session_ticket_send() */
bye_state_t bye_state; /* used by gnutls_bye() */
reauth_state_t reauth_state; /* used by gnutls_reauth() */
handshake_state_t handshake_final_state;
handshake_state_t handshake_state; /* holds
* a number which indicates where
* the handshake procedure has been
* interrupted. If it is 0 then
* no interruption has happened.
*/
bool invalid_connection; /* if this session is valid */
bool may_not_read; /* if it's 0 then we can read/write, otherwise it's forbidden to read/write
*/
bool may_not_write;
bool read_eof; /* non-zero if we have received a closure alert. */
int last_alert; /* last alert received */
/* The last handshake messages sent or received.
*/
int last_handshake_in;
int last_handshake_out;
/* priorities */
struct gnutls_priority_st *priorities;
/* variables directly set when setting the priorities above, or
* when overriding them */
bool allow_large_records;
bool allow_small_records;
bool no_etm;
bool no_ext_master_secret;
bool allow_key_usage_violation;
bool allow_wrong_pms;
bool dumbfw;
/* old (deprecated) variable. This is used for both srp_prime_bits
* and dh_prime_bits as they don't overlap */
/* For SRP: minimum bits to allow for SRP
* use gnutls_srp_set_prime_bits() to adjust it.
*/
uint16_t dh_prime_bits; /* srp_prime_bits */
/* resumed session */
bool resumed; /* if we are resuming a session */
/* server side: non-zero if resumption was requested by client
* client side: non-zero if we set resumption parameters */
bool resumption_requested;
security_parameters_st resumed_security_parameters;
gnutls_datum_t resumption_data; /* copy of input to gnutls_session_set_data() */
/* These buffers are used in the handshake
* protocol only. freed using _gnutls_handshake_io_buffer_clear();
*/
mbuffer_head_st handshake_send_buffer;
mbuffer_head_st handshake_header_recv_buffer;
handshake_buffer_st handshake_recv_buffer[MAX_HANDSHAKE_MSGS];
int handshake_recv_buffer_size;
/* this buffer holds a record packet -mostly used for
* non blocking IO.
*/
mbuffer_head_st record_recv_buffer; /* buffer holding the unparsed record that is currently
* being received */
mbuffer_head_st record_send_buffer; /* holds cached data
* for the gnutls_io_write_buffered()
* function.
*/
size_t record_send_buffer_user_size; /* holds the
* size of the user specified data to
* send.
*/
mbuffer_head_st early_data_recv_buffer;
gnutls_buffer_st early_data_presend_buffer;
record_send_state_t rsend_state;
/* buffer used temporarily during key update */
gnutls_buffer_st record_key_update_buffer;
gnutls_buffer_st record_presend_buffer; /* holds cached data
* for the gnutls_record_send()
* function.
*/
/* buffer used temporarily during TLS1.3 reauthentication */
gnutls_buffer_st reauth_buffer;
time_t expire_time; /* after expire_time seconds this session will expire */
const struct mod_auth_st_int *auth_struct; /* used in handshake packets and KX algorithms */
/* this is the highest version available
* to the peer. (advertized version).
* This is obtained by the Handshake Client Hello
* message. (some implementations read the Record version)
*/
uint8_t adv_version_major;
uint8_t adv_version_minor;
/* if this is non zero a certificate request message
* will be sent to the client. - only if the ciphersuite
* supports it. In server side it contains GNUTLS_CERT_REQUIRE
* or similar.
*/
gnutls_certificate_request_t send_cert_req;
/* callback to print the full path of certificate
* validation to the trusted root.
*/
gnutls_verify_output_function *cert_output_callback;
size_t max_handshake_data_buffer_size;
/* PUSH & PULL functions.
*/
gnutls_pull_timeout_func pull_timeout_func;
gnutls_pull_func pull_func;
gnutls_push_func push_func;
gnutls_vec_push_func vec_push_func;
gnutls_errno_func errno_func;
/* Holds the first argument of PUSH and PULL
* functions;
*/
gnutls_transport_ptr_t transport_recv_ptr;
gnutls_transport_ptr_t transport_send_ptr;
/* STORE & RETRIEVE functions. Only used if other
* backend than gdbm is used.
*/
gnutls_db_store_func db_store_func;
gnutls_db_retr_func db_retrieve_func;
gnutls_db_remove_func db_remove_func;
void *db_ptr;
/* post client hello callback (server side only)
*/
gnutls_handshake_post_client_hello_func user_hello_func;
/* handshake hook function */
gnutls_handshake_hook_func h_hook;
unsigned int h_type; /* the hooked type */
int16_t h_post; /* whether post-generation/receive */
gnutls_handshake_read_func h_read_func;
gnutls_handshake_secret_func h_secret_func;
gnutls_alert_read_func alert_read_func;
gnutls_keylog_func keylog_func;
/* holds the selected certificate and key.
* use _gnutls_selected_certs_deinit() and _gnutls_selected_certs_set()
* to change them.
*/
gnutls_pcert_st *selected_cert_list;
uint16_t selected_cert_list_length;
struct gnutls_privkey_st *selected_key;
/* new callbacks such as gnutls_certificate_retrieve_function3
* set the selected_ocsp datum values. The older OCSP callback-based
* functions, set the ocsp_func. The former takes precedence when
* set.
*/
gnutls_ocsp_data_st *selected_ocsp;
uint16_t selected_ocsp_length;
gnutls_status_request_ocsp_func selected_ocsp_func;
void *selected_ocsp_func_ptr;
bool selected_need_free;
/* This holds the default version that our first
* record packet will have. */
uint8_t default_record_version[2];
uint8_t default_hello_version[2];
void *user_ptr;
/* Holds 0 if the last called function was interrupted while
* receiving, and non zero otherwise.
*/
bool direction;
/* If non zero the server will not advertise the CA's he
* trusts (do not send an RDN sequence).
*/
bool ignore_rdn_sequence;
/* This is used to set an arbitrary version in the RSA
* PMS secret. Can be used by clients to test whether the
* server checks that version. (** only used in gnutls-cli-debug)
*/
uint8_t rsa_pms_version[2];
/* To avoid using global variables, and especially on Windows where
* the application may use a different errno variable than GnuTLS,
* it is possible to use gnutls_transport_set_errno to set a
* session-specific errno variable in the user-replaceable push/pull
* functions. This value is used by the send/recv functions. (The
* strange name of this variable is because 'errno' is typically
* #define'd.)
*/
int errnum;
/* A handshake process has been completed */
bool initial_negotiation_completed;
void *post_negotiation_lock; /* protects access to the variable above
* in the cases where negotiation is incomplete
* after gnutls_handshake() - early/false start */
/* The type of transport protocol; stream or datagram */
transport_t transport;
/* DTLS session state */
dtls_st dtls;
/* Protect from infinite loops due to GNUTLS_E_LARGE_PACKET non-handling
* or due to multiple alerts being received. */
unsigned handshake_suspicious_loops;
/* should be non-zero when a handshake is in progress */
bool handshake_in_progress;
/* if set it means that the master key was set using
* gnutls_session_set_master() rather than being negotiated. */
bool premaster_set;
unsigned int cb_tls_unique_len;
unsigned char cb_tls_unique[MAX_VERIFY_DATA_SIZE];
/* starting time of current handshake */
struct timespec handshake_start_time;
/* expected end time of current handshake (start+timeout);
* this is only filled if a handshake_time_ms is set. */
struct timespec handshake_abs_timeout;
/* An estimation of round-trip time under TLS1.3; populated in client side only */
unsigned ertt;
unsigned int handshake_timeout_ms; /* timeout in milliseconds */
unsigned int record_timeout_ms; /* timeout in milliseconds */
/* saved context of post handshake certificate request. In
* client side is what we received in server's certificate request;
* in server side is what we sent to client. */
gnutls_datum_t post_handshake_cr_context;
/* it is a copy of the handshake hash buffer if post handshake is used */
gnutls_buffer_st post_handshake_hash_buffer;
/* When either of PSK or DHE-PSK is received */
#define HSK_PSK_KE_MODES_RECEIVED (HSK_PSK_KE_MODE_PSK|HSK_PSK_KE_MODE_DHE_PSK|HSK_PSK_KE_MODE_INVALID)
#define HSK_CRT_VRFY_EXPECTED 1
#define HSK_CRT_ASKED (1<<2)
#define HSK_HRR_SENT (1<<3)
#define HSK_HRR_RECEIVED (1<<4)
#define HSK_CRT_REQ_SENT (1<<5)
#define HSK_KEY_UPDATE_ASKED (1<<7) /* flag is not used during handshake */
#define HSK_FALSE_START_USED (1<<8) /* TLS1.2 only */
#define HSK_HAVE_FFDHE (1<<9) /* whether the peer has advertized at least an FFDHE group */
#define HSK_USED_FFDHE (1<<10) /* whether ffdhe was actually negotiated and used */
#define HSK_PSK_KE_MODES_SENT (1<<11)
#define HSK_PSK_KE_MODE_PSK (1<<12) /* client: whether PSK without DH is allowed,
* server: whether PSK without DH is selected. */
#define HSK_PSK_KE_MODE_INVALID (1<<13) /* server: no compatible PSK modes were seen */
#define HSK_PSK_KE_MODE_DHE_PSK (1<<14) /* server: whether PSK with DH is selected
* client: whether PSK with DH is allowed
*/
#define HSK_PSK_SELECTED (1<<15) /* server: whether PSK was selected, either for resumption or not;
* on resumption session->internals.resumed will be set as well.
* client: the same */
#define HSK_KEY_SHARE_SENT (1<<16) /* server: key share was sent to client */
#define HSK_KEY_SHARE_RECEIVED (1<<17) /* client: key share was received
* server: key share was received and accepted */
#define HSK_TLS13_TICKET_SENT (1<<18) /* client: sent a ticket under TLS1.3;
* server: a ticket was sent to client.
*/
#define HSK_TLS12_TICKET_SENT (1<<19) /* client: sent a ticket under TLS1.2;
* server: a ticket was sent to client.
*/
#define HSK_TICKET_RECEIVED (1<<20) /* client: a session ticket was received */
#define HSK_EARLY_START_USED (1<<21)
#define HSK_EARLY_DATA_IN_FLIGHT (1<<22) /* client: sent early_data extension in ClientHello
* server: early_data extension was seen in ClientHello
*/
#define HSK_EARLY_DATA_ACCEPTED (1<<23) /* client: early_data extension was seen in EncryptedExtensions
* server: intend to process early data
*/
#define HSK_RECORD_SIZE_LIMIT_NEGOTIATED (1<<24)
#define HSK_RECORD_SIZE_LIMIT_SENT (1<<25) /* record_size_limit extension was sent */
#define HSK_RECORD_SIZE_LIMIT_RECEIVED (1<<26) /* server: record_size_limit extension was seen but not accepted yet */
#define HSK_OCSP_REQUESTED (1<<27) /* server: client requested OCSP stapling */
#define HSK_CLIENT_OCSP_REQUESTED (1<<28) /* client: server requested OCSP stapling */
#define HSK_SERVER_HELLO_RECEIVED (1<<29) /* client: Server Hello message has been received */
/* The hsk_flags are for use within the ongoing handshake;
* they are reset to zero prior to handshake start by gnutls_handshake. */
unsigned hsk_flags;
struct timespec last_key_update;
unsigned key_update_count;
/* Read-only pointer to the full ClientHello message */
gnutls_buffer_st full_client_hello;
/* The offset at which extensions start in the ClientHello buffer */
int extensions_offset;
gnutls_buffer_st hb_local_data;
gnutls_buffer_st hb_remote_data;
struct timespec hb_ping_start; /* timestamp: when first HeartBeat ping was sent */
struct timespec hb_ping_sent; /* timestamp: when last HeartBeat ping was sent */
unsigned int hb_actual_retrans_timeout_ms; /* current timeout, in milliseconds */
unsigned int hb_retrans_timeout_ms; /* the default timeout, in milliseconds */
unsigned int hb_total_timeout_ms; /* the total timeout, in milliseconds */
bool ocsp_check_ok; /* will be zero if the OCSP response TLS extension
* check failed (OCSP was old/unrelated or so). */
heartbeat_state_t hb_state; /* for ping */
recv_state_t recv_state; /* state of the receive function */
/* if set, server and client random were set by the application */
bool sc_random_set;
#define INT_FLAG_NO_TLS13 (1LL<<60)
uint64_t flags; /* the flags in gnutls_init() and GNUTLS_INT_FLAGS */
/* a verify callback to override the verify callback from the credentials
* structure */
gnutls_certificate_verify_function *verify_callback;
gnutls_typed_vdata_st *vc_data;
gnutls_typed_vdata_st vc_sdata;
unsigned vc_elements;
unsigned vc_status;
unsigned int additional_verify_flags; /* may be set by priorities or the vc functions */
/* we append the verify flags because these can be set,
* either by this function or by gnutls_session_set_verify_cert().
* However, we ensure that a single profile is set. */
#define ADD_PROFILE_VFLAGS(session, vflags) do { \
if ((session->internals.additional_verify_flags & GNUTLS_VFLAGS_PROFILE_MASK) && \
(vflags & GNUTLS_VFLAGS_PROFILE_MASK)) \
session->internals.additional_verify_flags &= ~GNUTLS_VFLAGS_PROFILE_MASK; \
session->internals.additional_verify_flags |= vflags; \
} while(0)
/* the SHA256 hash of the peer's certificate */
uint8_t cert_hash[32];
bool cert_hash_set;
/* The saved username from PSK or SRP auth */
char saved_username[MAX_USERNAME_SIZE+1];
int saved_username_size;
/* Needed for TCP Fast Open (TFO), set by gnutls_transport_set_fastopen() */
tfo_st tfo;
struct gnutls_supplemental_entry_st *rsup;
unsigned rsup_size;
struct hello_ext_entry_st *rexts;
unsigned rexts_size;
struct { /* ext_data[id] contains data for extension_t id */
gnutls_ext_priv_data_t priv;
gnutls_ext_priv_data_t resumed_priv;
uint8_t set;
uint8_t resumed_set;
} ext_data[MAX_EXT_TYPES];
/* In case of a client holds the extensions we sent to the peer;
* otherwise the extensions we received from the client. This is
* an OR of (1<<extensions_t values).
*/
ext_track_t used_exts;
gnutls_ext_flags_t ext_msg; /* accessed through _gnutls_ext_get/set_msg() */
/* this is not the negotiated max_record_recv_size, but the actual maximum
* receive size */
unsigned max_recv_size;
/* candidate groups to be selected for security params groups, they are
* prioritized in isolation under TLS1.2 */
const gnutls_group_entry_st *cand_ec_group;
const gnutls_group_entry_st *cand_dh_group;
/* used under TLS1.3+ */
const gnutls_group_entry_st *cand_group;
/* the ciphersuite received in HRR */
uint8_t hrr_cs[2];
/* this is only used under TLS1.2 or earlier */
int session_ticket_renew;
tls13_ticket_st tls13_ticket;
/* the amount of early data received so far */
uint32_t early_data_received;
/* anti-replay measure for 0-RTT mode */
gnutls_anti_replay_t anti_replay;
/* Protects _gnutls_epoch_gc() from _gnutls_epoch_get(); these may be
* called in parallel when false start is used and false start is used. */
void *epoch_lock;
/* indicates whether or not was KTLS initialized properly. */
int ktls_enabled;
/* Compression method for certificate compression */
gnutls_compression_method_t compress_certificate_method;
/* If you add anything here, check _gnutls_handshake_internal_state_clear().
*/
} internals_st;
MAX_EPOCH_INDEX
#define MAX_EPOCH_INDEX 4
struct gnutls_session_int
struct gnutls_session_int {
security_parameters_st security_parameters;
record_parameters_st *record_parameters[MAX_EPOCH_INDEX];
internals_st internals;
gnutls_key_st key;
};
timespec_sub_ms
#define timespec_sub_ms _gnutls_timespec_sub_ms