Packages
hackney
3.0.0
4.7.2
4.7.1
4.7.0
4.6.1
4.6.0
4.5.2
4.5.1
4.5.0
4.4.5
4.4.3
4.4.2
4.4.1
4.4.0
4.3.0
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.3
4.0.2
4.0.1
4.0.0
3.2.1
3.2.0
3.1.2
3.1.1
3.1.0
3.0.3
3.0.2
3.0.1
3.0.0
retired
2.0.1
2.0.0
2.0.0-beta.1
1.25.0
1.24.1
1.24.0
1.23.0
1.22.0
1.21.0
1.20.1
1.20.0
1.19.1
1.19.0
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.0
1.15.2
1.15.1
1.15.0
1.14.3
1.14.2
1.14.0
1.13.0
1.12.1
1.12.0
1.11.0
1.10.1
1.10.0
1.9.0
1.8.6
1.8.5
1.8.4
1.8.3
1.8.2
1.8.0
1.7.1
1.7.0
1.6.6
retired
1.6.5
1.6.4
retired
1.6.3
1.6.2
1.6.1
1.6.0
1.5.7
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.10
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.6
1.0.5
1.0.2
1.0.1
0.15.2
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
Simple HTTP client with HTTP/1.1, HTTP/2, and HTTP/3 support
Retired package: Release invalid - Use 3.0.1 instead
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
c_src/lsquic/src/liblsquic/lsquic_enc_sess.h
/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */
#ifndef LSQUIC_ENC_SESS_H
#define LSQUIC_ENC_SESS_H 1
#include "lsquic_shared_support.h"
struct lsquic_alarmset;
struct lsquic_engine_public;
struct lsquic_packet_out;
struct lsquic_packet_in;
struct stream_wrapper;
struct ver_neg;
struct lsquic_conn;
struct transport_params;
struct lsquic_cid;
struct ssl_stream_method_st;
struct ssl_st;
struct sockaddr;
struct conn_cid_elem;
struct lsquic_engine_settings;
enum lsquic_version;
#define DNONC_LENGTH 32
#define SRST_LENGTH 16
/* From [draft-ietf-quic-tls-14]:
*
* Data is protected using a number of encryption levels:
*
* o Plaintext
*
* o Early Data (0-RTT) Keys
*
* o Handshake Keys
*
* o Application Data (1-RTT) Keys
*/
/* This enum maps to the list above */
enum enc_level
{
ENC_LEV_INIT,
ENC_LEV_0RTT,
ENC_LEV_HSK,
ENC_LEV_APP,
N_ENC_LEVS
};
enum handshake_error /* TODO: rename this enum */
{
DATA_NOT_ENOUGH = -2,
DATA_FORMAT_ERROR = -1,
HS_ERROR = -1,
DATA_NO_ERROR = 0,
HS_SHLO = 0,
HS_1RTT = 1,
HS_SREJ = 2,
};
#ifndef LSQUIC_KEEP_ENC_SESS_HISTORY
# ifndef NDEBUG
# define LSQUIC_KEEP_ENC_SESS_HISTORY 1
# else
# define LSQUIC_KEEP_ENC_SESS_HISTORY 0
# endif
#endif
#if LSQUIC_KEEP_ENC_SESS_HISTORY
#define ESHIST_BITS 7
#define ESHIST_MASK ((1 << ESHIST_BITS) - 1)
#define ESHIST_STR_SIZE ((1 << ESHIST_BITS) + 1)
#endif
enum enc_packout { ENCPA_OK, ENCPA_NOMEM, ENCPA_BADCRYPT, };
enum dec_packin {
DECPI_OK,
DECPI_NOMEM,
DECPI_TOO_SHORT,
DECPI_NOT_YET,
DECPI_BADCRYPT,
DECPI_VIOLATION,
};
typedef void enc_session_t;
struct enc_session_funcs_common
{
/* Global initialization: call once per implementation */
int (*esf_global_init)(int flags);
/* Global cleanup: call once per implementation */
void (*esf_global_cleanup) (void);
const char *
(*esf_cipher) (enc_session_t *);
int
(*esf_keysize) (enc_session_t *);
int
(*esf_alg_keysize) (enc_session_t *);
const char *
(*esf_get_sni) (enc_session_t *);
/* Need to pass lconn in encrypt and decrypt methods because enc_session
* is allowed to be NULL for gQUIC.
*/
enum enc_packout
(*esf_encrypt_packet) (enc_session_t *, const struct lsquic_engine_public *,
struct lsquic_conn *, struct lsquic_packet_out *);
enum dec_packin
(*esf_decrypt_packet)(enc_session_t *, struct lsquic_engine_public *,
const struct lsquic_conn *, struct lsquic_packet_in *);
struct stack_st_X509 *
(*esf_get_server_cert_chain) (enc_session_t *);
int
(*esf_verify_reset_token) (enc_session_t *, const unsigned char *, size_t);
int
(*esf_did_sess_resume_succeed) (enc_session_t *);
int
(*esf_is_sess_resume_enabled) (enc_session_t *);
void
(*esf_set_conn) (enc_session_t *, struct lsquic_conn *);
/* Optional. This function gets called after packets are encrypted,
* batched, and are about to be sent.
*/
void
(*esf_flush_encryption) (enc_session_t *);
unsigned
esf_tag_len;
};
struct enc_session_funcs_gquic
{
#if LSQUIC_KEEP_ENC_SESS_HISTORY
/* Grab encryption session history */
void (*esf_get_hist) (enc_session_t *,
char buf[ESHIST_STR_SIZE]);
#endif
/* Destroy enc session */
void (*esf_destroy)(enc_session_t *enc_session);
/* Return true if handshake has been completed */
int (*esf_is_hsk_done)(enc_session_t *enc_session);
/* Get value of setting specified by `tag' */
int (*esf_get_peer_setting) (enc_session_t *, uint32_t tag,
uint32_t *val);
/* Get value of peer option (that from COPT array) */
int (*esf_get_peer_option) (enc_session_t *enc_session,
uint32_t tag);
/* Create server session */
enc_session_t *
(*esf_create_server) (struct lsquic_conn *,
lsquic_cid_t cid, struct lsquic_engine_public *);
/* out_len should have init value as the max length of out */
enum handshake_error
(*esf_handle_chlo) (enc_session_t *enc_session, enum lsquic_version,
const uint8_t *in, int in_len, time_t t,
const struct sockaddr *ip_addr, const struct sockaddr *local,
uint8_t *out, size_t *out_len,
uint8_t nonce[DNONC_LENGTH], int *nonce_set);
void (*esf_hsk_destroy)(void *hsk_ctx);
#ifndef NDEBUG
/* Need to expose this function for testing */
int (*esf_determine_diversification_key) (enc_session_t *,
uint8_t *diversification_nonce);
#endif
const char *
(*esf_get_ua) (enc_session_t *);
int
(*esf_have_key_gt_one) (enc_session_t *enc_session);
#ifndef NDEBUG
/* Functions that are only relevant in maintest. We may want to get rid
* of them somehow and only use the public API to test.
*/
uint8_t
(*esf_have_key) (enc_session_t *);
void
(*esf_set_have_key) (enc_session_t *, uint8_t);
const unsigned char *
(*esf_get_enc_key_i) (enc_session_t *);
const unsigned char *
(*esf_get_dec_key_i) (enc_session_t *);
const unsigned char *
(*esf_get_enc_key_nonce_i) (enc_session_t *);
const unsigned char *
(*esf_get_dec_key_nonce_i) (enc_session_t *);
const unsigned char *
(*esf_get_enc_key_nonce_f) (enc_session_t *);
const unsigned char *
(*esf_get_dec_key_nonce_f) (enc_session_t *);
#endif /* !defined(NDEBUG) */
/* Create client session */
enc_session_t *
(*esf_create_client) (struct lsquic_conn *, const char *domain,
lsquic_cid_t cid,
struct lsquic_engine_public *,
const unsigned char *, size_t);
/* -1 error, 0, OK, response in `buf' */
int
(*esf_gen_chlo) (enc_session_t *, enum lsquic_version,
uint8_t *buf, size_t *len);
int
(*esf_handle_chlo_reply) (enc_session_t *,
const uint8_t *data, int len);
size_t
(*esf_mem_used)(enc_session_t *);
/* Session resumption serialization needs the knowledge of the QUIC
* version, that's why there is a separate method for thus. Plus, we
* want to be able to call it after the "handshake is done" callback
* is called.
*/
void (*esf_maybe_dispatch_sess_resume) (enc_session_t *,
void (*cb)(struct lsquic_conn *, const unsigned char *, size_t));
void (*esf_reset_cid) (enc_session_t *, const lsquic_cid_t *);
};
struct crypto_stream_if
{
ssize_t (*csi_write) (void *stream, const void *buf, size_t len);
int (*csi_flush) (void *stream);
ssize_t (*csi_readf) (void *stream,
size_t (*readf)(void *, const unsigned char *, size_t, int), void *ctx);
int (*csi_wantwrite) (void *stream, int is_want);
int (*csi_wantread) (void *stream, int is_want);
enum enc_level
(*csi_enc_level) (void *stream);
};
struct enc_session_funcs_iquic
{
enc_session_t *
(*esfi_create_client) (const char *domain, struct lsquic_engine_public *,
struct lsquic_conn *, const struct lsquic_cid *,
const struct ver_neg *, void *(crypto_streams)[4],
const struct crypto_stream_if *,
const unsigned char *, size_t,
struct lsquic_alarmset *, unsigned, void*);
void
(*esfi_destroy) (enc_session_t *);
struct ssl_st *
(*esfi_get_ssl) (enc_session_t *);
struct transport_params *
(*esfi_get_peer_transport_params) (enc_session_t *);
int
(*esfi_reset_dcid) (enc_session_t *, const struct lsquic_cid *,
const struct lsquic_cid *);
void
(*esfi_set_iscid) (enc_session_t *, const struct lsquic_packet_in *);
int
(*esfi_init_server) (enc_session_t *);
void
(*esfi_set_streams) (enc_session_t *, void *(crypto_streams)[4],
const struct crypto_stream_if *);
enc_session_t *
(*esfi_create_server) (struct lsquic_engine_public *, struct lsquic_conn *,
const struct lsquic_cid *,
void *(crypto_streams)[4],
const struct crypto_stream_if *,
const struct lsquic_cid *odcid,
const struct lsquic_cid *iscid,
const struct lsquic_cid *rscid
);
void
(*esfi_shake_stream)(enc_session_t *, struct lsquic_stream *,
const char *);
void
(*esfi_handshake_confirmed)(enc_session_t *);
int
(*esfi_in_init)(enc_session_t *);
int
(*esfi_data_in)(enc_session_t *, enum enc_level,
const unsigned char *, size_t);
};
LSQUIC_EXTERN
#ifdef NDEBUG
const
#endif
struct enc_session_funcs_common lsquic_enc_session_common_gquic_1;
LSQUIC_EXTERN
#ifdef NDEBUG
const
#endif
struct enc_session_funcs_common lsquic_enc_session_common_gquic_2;
LSQUIC_EXTERN const struct enc_session_funcs_common lsquic_enc_session_common_ietf_v1;
LSQUIC_EXTERN
#ifdef NDEBUG
const
#endif
struct enc_session_funcs_gquic lsquic_enc_session_gquic_gquic_1;
LSQUIC_EXTERN const struct enc_session_funcs_iquic lsquic_enc_session_iquic_ietf_v1;
#define select_esf_common_by_ver(ver) ( \
ver > LSQVER_050 ? &lsquic_enc_session_common_ietf_v1 : \
ver == LSQVER_050 ? &lsquic_enc_session_common_gquic_2 : \
&lsquic_enc_session_common_gquic_1 )
#define select_esf_gquic_by_ver(ver) ( \
ver ? &lsquic_enc_session_gquic_gquic_1 : &lsquic_enc_session_gquic_gquic_1)
#define select_esf_iquic_by_ver(ver) ( \
ver ? &lsquic_enc_session_iquic_ietf_v1 : &lsquic_enc_session_iquic_ietf_v1)
extern const char *const lsquic_enclev2str[];
LSQUIC_EXTERN const struct lsquic_stream_if lsquic_cry_sm_if;
LSQUIC_EXTERN const struct lsquic_stream_if lsquic_mini_cry_sm_if;
/* RFC 7301, Section 3.2 */
#define ALERT_NO_APPLICATION_PROTOCOL 120
enum lsquic_version
lsquic_sess_resume_version (const unsigned char *, size_t);
/* This is seems to be true for all of the ciphers used by IETF QUIC.
* XXX: Perhaps add a check?
*/
#define IQUIC_TAG_LEN 16
/* Return number of bytes written to `buf' or -1 on error */
int
lsquic_enc_sess_ietf_gen_quic_ctx (
const struct lsquic_engine_settings *settings,
enum lsquic_version version, unsigned char *buf, size_t bufsz);
struct enc_sess_iquic;
int
iquic_esfi_init_server_tp (struct enc_sess_iquic *const enc_sess);
int
iquic_esfi_switch_version (enc_session_t *enc_session_p, lsquic_cid_t *dcid,
int backup_keys);
int
iquic_esf_is_enc_level_ready (enc_session_t *enc_session_p,
enum enc_level level);
#endif