Release 2.16.2
- [BUGFIX] ID-28: do not use TLS middlebox compatibility mode in ClientHello. This change requires using a newer version of BoringSSL. - [BUGFIX] Free connections in Advisory Tick Time Queue in engine dtor. - [BUGFIX] IETF QUIC client: narrow migration check to a single path. - [BUGFIX] NULL dereference: set function pointers for alarm for path challenges 2 and 3. - [BUGFIX] HTTP/3 headers may be followed immediately by trailers. - [BUGFIX] Log messages when SCID changes.
This commit is contained in:
parent
8ae5ecb45e
commit
f913a2972b
|
@ -8,7 +8,7 @@ task:
|
|||
- cd boringssl
|
||||
# This is so that both GQUIC and IETF branches build. Just picking
|
||||
# a known good revision:
|
||||
- git checkout bfe527fa35735e8e045cbfb42b012e13ca68f9cf
|
||||
- git checkout 251b5169fd44345f455438312ec4e18ae07fd58c
|
||||
- cmake .
|
||||
- make
|
||||
- cd -
|
||||
|
|
|
@ -31,7 +31,7 @@ before_script:
|
|||
- cd boringssl
|
||||
# This is so that both GQUIC and IETF branches build. Just picking
|
||||
# a known good revision:
|
||||
- git checkout bfe527fa35735e8e045cbfb42b012e13ca68f9cf
|
||||
- git checkout 251b5169fd44345f455438312ec4e18ae07fd58c
|
||||
- cmake .
|
||||
- make
|
||||
- cd -
|
||||
|
|
11
CHANGELOG
11
CHANGELOG
|
@ -1,3 +1,14 @@
|
|||
2020-06-12
|
||||
- 2.16.2
|
||||
- [BUGFIX] ID-28: do not use TLS middlebox compatibility mode in
|
||||
ClientHello. This change requires using a newer version of BoringSSL.
|
||||
- [BUGFIX] Free connections in Advisory Tick Time Queue in engine dtor.
|
||||
- [BUGFIX] IETF QUIC client: narrow migration check to a single path.
|
||||
- [BUGFIX] NULL dereference: set function pointers for alarm for path
|
||||
challenges 2 and 3.
|
||||
- [BUGFIX] HTTP/3 headers may be followed immediately by trailers.
|
||||
- [BUGFIX] Log messages when SCID changes.
|
||||
|
||||
2020-06-09
|
||||
- 2.16.1
|
||||
- [FEATURE] Use "no-progress timeout" after which connection is closed.
|
||||
|
|
|
@ -50,7 +50,7 @@ You may need to install pre-requisites like zlib and libevent.
|
|||
2. Use specific BoringSSL version
|
||||
|
||||
```
|
||||
git checkout bfe527fa35735e8e045cbfb42b012e13ca68f9cf
|
||||
git checkout 251b5169fd44345f455438312ec4e18ae07fd58c
|
||||
```
|
||||
|
||||
3. Compile the library
|
||||
|
|
|
@ -30,7 +30,7 @@ build_script:
|
|||
|
||||
cd boringssl
|
||||
|
||||
git checkout bfe527fa35735e8e045cbfb42b012e13ca68f9cf
|
||||
git checkout 251b5169fd44345f455438312ec4e18ae07fd58c
|
||||
|
||||
cmake -DCMAKE_GENERATOR_PLATFORM=x64 --config Debug -DBUILD_SHARED_LIBS=OFF -DOPENSSL_NO_ASM=1 .
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ author = u'LiteSpeed Technologies'
|
|||
# The short X.Y version
|
||||
version = u'2.16'
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = u'2.16.1'
|
||||
release = u'2.16.2'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
|||
|
||||
#define LSQUIC_MAJOR_VERSION 2
|
||||
#define LSQUIC_MINOR_VERSION 16
|
||||
#define LSQUIC_PATCH_VERSION 1
|
||||
#define LSQUIC_PATCH_VERSION 2
|
||||
|
||||
/**
|
||||
* Engine flags:
|
||||
|
|
|
@ -106,7 +106,7 @@ no_sess_ticket (enum alarm_id alarm_id, void *ctx,
|
|||
|
||||
|
||||
typedef void (*gen_hp_mask_f)(struct enc_sess_iquic *,
|
||||
const struct header_prot *, unsigned cliser,
|
||||
const struct header_prot *, unsigned rw,
|
||||
const unsigned char *sample, unsigned char mask[16]);
|
||||
|
||||
|
||||
|
@ -243,8 +243,6 @@ struct enc_sess_iquic
|
|||
ESI_ISCID = 1 << 15,
|
||||
ESI_RETRY = 1 << 16, /* Connection was retried */
|
||||
} esi_flags;
|
||||
enum evp_aead_direction_t
|
||||
esi_dir[2]; /* client, server */
|
||||
enum enc_level esi_last_w;
|
||||
unsigned esi_trasec_sz;
|
||||
char *esi_hostname;
|
||||
|
@ -278,14 +276,14 @@ struct enc_sess_iquic
|
|||
|
||||
static void
|
||||
gen_hp_mask_aes (struct enc_sess_iquic *enc_sess,
|
||||
const struct header_prot *hp, unsigned cliser,
|
||||
const struct header_prot *hp, unsigned rw,
|
||||
const unsigned char *sample, unsigned char mask[EVP_MAX_BLOCK_LENGTH])
|
||||
{
|
||||
EVP_CIPHER_CTX hp_ctx;
|
||||
int out_len;
|
||||
|
||||
EVP_CIPHER_CTX_init(&hp_ctx);
|
||||
if (EVP_EncryptInit_ex(&hp_ctx, hp->hp_cipher, NULL, hp->hp_buf[cliser], 0)
|
||||
if (EVP_EncryptInit_ex(&hp_ctx, hp->hp_cipher, NULL, hp->hp_buf[rw], 0)
|
||||
&& EVP_EncryptUpdate(&hp_ctx, mask, &out_len, sample, 16))
|
||||
{
|
||||
assert(out_len >= 5);
|
||||
|
@ -304,7 +302,7 @@ gen_hp_mask_aes (struct enc_sess_iquic *enc_sess,
|
|||
|
||||
static void
|
||||
gen_hp_mask_chacha20 (struct enc_sess_iquic *enc_sess,
|
||||
const struct header_prot *hp, unsigned cliser,
|
||||
const struct header_prot *hp, unsigned rw,
|
||||
const unsigned char *sample, unsigned char mask[EVP_MAX_BLOCK_LENGTH])
|
||||
{
|
||||
const uint8_t *nonce;
|
||||
|
@ -317,19 +315,19 @@ gen_hp_mask_chacha20 (struct enc_sess_iquic *enc_sess,
|
|||
#endif
|
||||
nonce = sample + sizeof(counter);
|
||||
CRYPTO_chacha_20(mask, (unsigned char [5]) { 0, 0, 0, 0, 0, }, 5,
|
||||
hp->hp_buf[cliser], nonce, counter);
|
||||
hp->hp_buf[rw], nonce, counter);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
apply_hp (struct enc_sess_iquic *enc_sess,
|
||||
const struct header_prot *hp, unsigned cliser,
|
||||
const struct header_prot *hp,
|
||||
unsigned char *dst, unsigned packno_off, unsigned packno_len)
|
||||
{
|
||||
unsigned char mask[EVP_MAX_BLOCK_LENGTH];
|
||||
char mask_str[5 * 2 + 1];
|
||||
|
||||
hp->hp_gen_mask(enc_sess, hp, cliser, dst + packno_off + 4, mask);
|
||||
hp->hp_gen_mask(enc_sess, hp, 1, dst + packno_off + 4, mask);
|
||||
LSQ_DEBUG("apply header protection using mask %s",
|
||||
HEXSTR(mask, 5, mask_str));
|
||||
if (enc_sess->esi_flags & ESI_SEND_QL_BITS)
|
||||
|
@ -380,7 +378,7 @@ decode_packno (lsquic_packno_t max_packno, lsquic_packno_t packno,
|
|||
|
||||
static lsquic_packno_t
|
||||
strip_hp (struct enc_sess_iquic *enc_sess,
|
||||
const struct header_prot *hp, unsigned cliser,
|
||||
const struct header_prot *hp,
|
||||
const unsigned char *iv, unsigned char *dst, unsigned packno_off,
|
||||
unsigned *packno_len)
|
||||
{
|
||||
|
@ -390,7 +388,7 @@ strip_hp (struct enc_sess_iquic *enc_sess,
|
|||
unsigned char mask[EVP_MAX_BLOCK_LENGTH];
|
||||
char mask_str[5 * 2 + 1];
|
||||
|
||||
hp->hp_gen_mask(enc_sess, hp, cliser, iv, mask);
|
||||
hp->hp_gen_mask(enc_sess, hp, 0, iv, mask);
|
||||
LSQ_DEBUG("strip header protection using mask %s",
|
||||
HEXSTR(mask, 5, mask_str));
|
||||
if (enc_sess->esi_flags & ESI_RECV_QL_BITS)
|
||||
|
@ -739,9 +737,6 @@ iquic_esfi_create_client (const char *hostname,
|
|||
enc_sess->esi_conn = lconn;
|
||||
enc_sess->esi_ver_neg = ver_neg;
|
||||
|
||||
enc_sess->esi_dir[0] = evp_aead_seal;
|
||||
enc_sess->esi_dir[1] = evp_aead_open;
|
||||
|
||||
enc_sess->esi_odcid = *dcid;
|
||||
enc_sess->esi_flags |= ESI_ODCID;
|
||||
|
||||
|
@ -831,9 +826,6 @@ iquic_esfi_create_server (struct lsquic_engine_public *enpub,
|
|||
enc_sess->esi_enpub = enpub;
|
||||
enc_sess->esi_conn = lconn;
|
||||
|
||||
enc_sess->esi_dir[0] = evp_aead_open;
|
||||
enc_sess->esi_dir[1] = evp_aead_seal;
|
||||
|
||||
if (odcid)
|
||||
{
|
||||
enc_sess->esi_odcid = *odcid;
|
||||
|
@ -868,23 +860,31 @@ iquic_esfi_create_server (struct lsquic_engine_public *enpub,
|
|||
}
|
||||
|
||||
|
||||
static const char *const rw2str[] = { "read", "write", };
|
||||
|
||||
typedef char evp_aead_enum_has_expected_values[
|
||||
(int) evp_aead_open == 0 && (int) evp_aead_seal == 1 ? 1 : -1];
|
||||
#define rw2dir(rw_) ((enum evp_aead_direction_t) (rw_))
|
||||
|
||||
|
||||
static void
|
||||
log_crypto_ctx (const struct enc_sess_iquic *enc_sess,
|
||||
const struct crypto_ctx *ctx, const char *name, int rw)
|
||||
{
|
||||
char hexbuf[EVP_MAX_MD_SIZE * 2 + 1];
|
||||
LSQ_DEBUG("%s %s key: %s", name, rw2str[rw],
|
||||
HEXSTR(ctx->yk_key_buf, ctx->yk_key_sz, hexbuf));
|
||||
LSQ_DEBUG("%s %s iv: %s", name, rw2str[rw],
|
||||
HEXSTR(ctx->yk_iv_buf, ctx->yk_iv_sz, hexbuf));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
log_crypto_pair (const struct enc_sess_iquic *enc_sess,
|
||||
const struct crypto_ctx_pair *pair, const char *name)
|
||||
{
|
||||
char hexbuf[EVP_MAX_MD_SIZE * 2 + 1];
|
||||
LSQ_DEBUG("client %s key: %s", name,
|
||||
HEXSTR(pair->ykp_ctx[0].yk_key_buf, pair->ykp_ctx[0].yk_key_sz,
|
||||
hexbuf));
|
||||
LSQ_DEBUG("client %s iv: %s", name,
|
||||
HEXSTR(pair->ykp_ctx[0].yk_iv_buf, pair->ykp_ctx[0].yk_iv_sz,
|
||||
hexbuf));
|
||||
LSQ_DEBUG("server %s key: %s", name,
|
||||
HEXSTR(pair->ykp_ctx[1].yk_key_buf, pair->ykp_ctx[1].yk_key_sz,
|
||||
hexbuf));
|
||||
LSQ_DEBUG("server %s iv: %s", name,
|
||||
HEXSTR(pair->ykp_ctx[1].yk_iv_buf, pair->ykp_ctx[1].yk_iv_sz,
|
||||
hexbuf));
|
||||
log_crypto_ctx(enc_sess, &pair->ykp_ctx[0], name, 0);
|
||||
log_crypto_ctx(enc_sess, &pair->ykp_ctx[1], name, 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -893,9 +893,9 @@ log_hp (const struct enc_sess_iquic *enc_sess,
|
|||
const struct header_prot *hp, const char *name)
|
||||
{
|
||||
char hexbuf[EVP_MAX_MD_SIZE * 2 + 1];
|
||||
LSQ_DEBUG("client %s hp: %s", name,
|
||||
LSQ_DEBUG("read %s hp: %s", name,
|
||||
HEXSTR(hp->hp_buf[0], hp->hp_sz, hexbuf));
|
||||
LSQ_DEBUG("server %s hp: %s", name,
|
||||
LSQ_DEBUG("write %s hp: %s", name,
|
||||
HEXSTR(hp->hp_buf[1], hp->hp_sz, hexbuf));
|
||||
}
|
||||
|
||||
|
@ -909,6 +909,7 @@ setup_handshake_keys (struct enc_sess_iquic *enc_sess, const lsquic_cid_t *cid)
|
|||
struct crypto_ctx_pair *pair;
|
||||
struct header_prot *hp;
|
||||
size_t hsk_secret_sz;
|
||||
unsigned cliser;
|
||||
unsigned char hsk_secret[EVP_MAX_MD_SIZE];
|
||||
unsigned char secret[2][SHA256_DIGEST_LENGTH]; /* client, server */
|
||||
char hexbuf[EVP_MAX_MD_SIZE * 2 + 1];
|
||||
|
@ -941,17 +942,22 @@ setup_handshake_keys (struct enc_sess_iquic *enc_sess, const lsquic_cid_t *cid)
|
|||
|
||||
lsquic_qhkdf_expand(md, hsk_secret, hsk_secret_sz, CLIENT_LABEL,
|
||||
CLIENT_LABEL_SZ, secret[0], sizeof(secret[0]));
|
||||
LSQ_DEBUG("client handshake secret: %s",
|
||||
HEXSTR(secret[0], sizeof(secret[0]), hexbuf));
|
||||
if (0 != init_crypto_ctx(&pair->ykp_ctx[0], md, aead, secret[0],
|
||||
sizeof(secret[0]), enc_sess->esi_dir[0]))
|
||||
goto err;
|
||||
lsquic_qhkdf_expand(md, hsk_secret, hsk_secret_sz, SERVER_LABEL,
|
||||
SERVER_LABEL_SZ, secret[1], sizeof(secret[1]));
|
||||
LSQ_DEBUG("server handshake secret: %s",
|
||||
HEXSTR(secret[1], sizeof(secret[1]), hexbuf));
|
||||
if (0 != init_crypto_ctx(&pair->ykp_ctx[1], md, aead, secret[1],
|
||||
sizeof(secret[1]), enc_sess->esi_dir[1]))
|
||||
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
||||
{
|
||||
LSQ_DEBUG("client handshake secret: %s",
|
||||
HEXSTR(secret[0], sizeof(secret[0]), hexbuf));
|
||||
LSQ_DEBUG("server handshake secret: %s",
|
||||
HEXSTR(secret[1], sizeof(secret[1]), hexbuf));
|
||||
}
|
||||
|
||||
cliser = !!(enc_sess->esi_flags & ESI_SERVER);
|
||||
if (0 != init_crypto_ctx(&pair->ykp_ctx[!cliser], md, aead, secret[0],
|
||||
sizeof(secret[0]), rw2dir(!cliser)))
|
||||
goto err;
|
||||
if (0 != init_crypto_ctx(&pair->ykp_ctx[cliser], md, aead, secret[1],
|
||||
sizeof(secret[1]), rw2dir(cliser)))
|
||||
goto err;
|
||||
|
||||
/* [draft-ietf-quic-tls-12] Section 5.6.1: AEAD_AES_128_GCM implies
|
||||
|
@ -960,7 +966,7 @@ setup_handshake_keys (struct enc_sess_iquic *enc_sess, const lsquic_cid_t *cid)
|
|||
hp->hp_cipher = EVP_aes_128_ecb();
|
||||
hp->hp_gen_mask = gen_hp_mask_aes;
|
||||
hp->hp_enc_level = ENC_LEV_CLEAR;
|
||||
derive_hp_secrets(hp, md, aead, sizeof(secret[0]), secret[0], secret[1]);
|
||||
derive_hp_secrets(hp, md, aead, sizeof(secret[0]), secret[!cliser], secret[cliser]);
|
||||
|
||||
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
||||
{
|
||||
|
@ -1419,13 +1425,11 @@ struct crypto_params
|
|||
|
||||
static int
|
||||
get_crypto_params (const struct enc_sess_iquic *enc_sess,
|
||||
struct crypto_params *params)
|
||||
const SSL_CIPHER *cipher, struct crypto_params *params)
|
||||
{
|
||||
const SSL_CIPHER *cipher;
|
||||
unsigned key_sz, iv_sz;
|
||||
uint32_t id;
|
||||
|
||||
cipher = SSL_get_current_cipher(enc_sess->esi_ssl);
|
||||
id = SSL_CIPHER_get_id(cipher);
|
||||
|
||||
LSQ_DEBUG("Negotiated cipher ID is 0x%"PRIX32, id);
|
||||
|
@ -1475,6 +1479,9 @@ get_crypto_params (const struct enc_sess_iquic *enc_sess,
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* FIXME: figure out why this duplicate check is here and either fix it
|
||||
* or get rid of it.
|
||||
*/
|
||||
if (key_sz > EVP_MAX_KEY_LENGTH)
|
||||
{
|
||||
LSQ_DEBUG("PN size %u is too large", key_sz);
|
||||
|
@ -1802,7 +1809,7 @@ iquic_esf_encrypt_packet (enc_session_t *enc_session_p,
|
|||
size_t out_sz, dst_sz;
|
||||
int header_sz;
|
||||
int ipv6;
|
||||
unsigned packno_off, packno_len, cliser;
|
||||
unsigned packno_off, packno_len;
|
||||
enum packnum_space pns;
|
||||
char errbuf[ERR_ERROR_STRING_BUF_LEN];
|
||||
|
||||
|
@ -1810,17 +1817,16 @@ iquic_esf_encrypt_packet (enc_session_t *enc_session_p,
|
|||
/* TODO Obviously, will need more logic for 0-RTT */
|
||||
enc_level = pns2enc_level[ pns ];
|
||||
|
||||
cliser = !!(enc_sess->esi_flags & ESI_SERVER);
|
||||
if (enc_level == ENC_LEV_FORW)
|
||||
{
|
||||
pair = &enc_sess->esi_pairs[ enc_sess->esi_key_phase ];
|
||||
crypto_ctx = &pair->ykp_ctx[ cliser ];
|
||||
crypto_ctx = &pair->ykp_ctx[ 1 ];
|
||||
hp = &enc_sess->esi_hp;
|
||||
}
|
||||
else if (enc_sess->esi_hsk_pairs)
|
||||
{
|
||||
pair = &enc_sess->esi_hsk_pairs[ enc_level ];
|
||||
crypto_ctx = &pair->ykp_ctx[ cliser ];
|
||||
crypto_ctx = &pair->ykp_ctx[ 1 ];
|
||||
hp = &enc_sess->esi_hsk_hps[ enc_level ];
|
||||
}
|
||||
else
|
||||
|
@ -1909,7 +1915,7 @@ iquic_esf_encrypt_packet (enc_session_t *enc_session_p,
|
|||
const unsigned sample_off = packno_off + 4;
|
||||
assert(sample_off + IQUIC_TAG_LEN <= dst_sz);
|
||||
#endif
|
||||
apply_hp(enc_sess, hp, cliser, dst, packno_off, packno_len);
|
||||
apply_hp(enc_sess, hp, dst, packno_off, packno_len);
|
||||
|
||||
packet_out->po_enc_data = dst;
|
||||
packet_out->po_enc_data_sz = dst_sz;
|
||||
|
@ -1952,7 +1958,7 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
|
|||
struct crypto_ctx *crypto_ctx = NULL;
|
||||
unsigned char nonce_buf[ sizeof(crypto_ctx->yk_iv_buf) + 8 ];
|
||||
unsigned char *nonce, *begin_xor;
|
||||
unsigned sample_off, packno_len, cliser, key_phase;
|
||||
unsigned sample_off, packno_len, key_phase;
|
||||
enum enc_level enc_level;
|
||||
enum packnum_space pns;
|
||||
lsquic_packno_t packno;
|
||||
|
@ -2000,10 +2006,9 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
|
|||
dec_packin = DECPI_TOO_SHORT;
|
||||
goto err;
|
||||
}
|
||||
cliser = !(enc_sess->esi_flags & ESI_SERVER);
|
||||
memcpy(dst, packet_in->pi_data, sample_off);
|
||||
packet_in->pi_packno =
|
||||
packno = strip_hp(enc_sess, hp, cliser,
|
||||
packno = strip_hp(enc_sess, hp,
|
||||
packet_in->pi_data + sample_off,
|
||||
dst, packet_in->pi_header_sz, &packno_len);
|
||||
|
||||
|
@ -2012,7 +2017,7 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
|
|||
key_phase = (dst[0] & 0x04) > 0;
|
||||
pair = &enc_sess->esi_pairs[ key_phase ];
|
||||
if (key_phase == enc_sess->esi_key_phase)
|
||||
crypto_ctx = &pair->ykp_ctx[ cliser ];
|
||||
crypto_ctx = &pair->ykp_ctx[ 0 ];
|
||||
else if (!is_valid_packno(
|
||||
enc_sess->esi_pairs[enc_sess->esi_key_phase].ykp_thresh)
|
||||
|| packet_in->pi_packno
|
||||
|
@ -2020,7 +2025,7 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
|
|||
{
|
||||
const struct ku_label kl = select_ku_label(enc_sess);
|
||||
lsquic_qhkdf_expand(enc_sess->esi_md,
|
||||
enc_sess->esi_traffic_secrets[cliser], enc_sess->esi_trasec_sz,
|
||||
enc_sess->esi_traffic_secrets[0], enc_sess->esi_trasec_sz,
|
||||
kl.str, kl.len, new_secret, enc_sess->esi_trasec_sz);
|
||||
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
||||
LSQ_DEBUG("key phase changed to %u, will try decrypting using "
|
||||
|
@ -2043,7 +2048,7 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
|
|||
}
|
||||
else
|
||||
{
|
||||
crypto_ctx = &pair->ykp_ctx[ cliser ];
|
||||
crypto_ctx = &pair->ykp_ctx[ 0 ];
|
||||
if (UNLIKELY(0 == (crypto_ctx->yk_flags & YK_INITED)))
|
||||
{
|
||||
LSQ_DEBUG("supposedly older context is not initialized (key "
|
||||
|
@ -2058,7 +2063,7 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
|
|||
key_phase = 0;
|
||||
assert(enc_sess->esi_hsk_pairs);
|
||||
pair = &enc_sess->esi_hsk_pairs[ enc_level ];
|
||||
crypto_ctx = &pair->ykp_ctx[ cliser ];
|
||||
crypto_ctx = &pair->ykp_ctx[ 0 ];
|
||||
if (UNLIKELY(0 == (crypto_ctx->yk_flags & YK_INITED)))
|
||||
{
|
||||
LSQ_WARN("decrypt crypto context at level %s not initialized",
|
||||
|
@ -2128,21 +2133,21 @@ iquic_esf_decrypt_packet (enc_session_t *enc_session_p,
|
|||
"keys", key_phase);
|
||||
const struct ku_label kl = select_ku_label(enc_sess);
|
||||
pair->ykp_thresh = packet_in->pi_packno;
|
||||
pair->ykp_ctx[ cliser ] = crypto_ctx_buf;
|
||||
memcpy(enc_sess->esi_traffic_secrets[ cliser ], new_secret,
|
||||
pair->ykp_ctx[ 0 ] = crypto_ctx_buf;
|
||||
memcpy(enc_sess->esi_traffic_secrets[ 0 ], new_secret,
|
||||
enc_sess->esi_trasec_sz);
|
||||
lsquic_qhkdf_expand(enc_sess->esi_md,
|
||||
enc_sess->esi_traffic_secrets[!cliser], enc_sess->esi_trasec_sz,
|
||||
enc_sess->esi_traffic_secrets[1], enc_sess->esi_trasec_sz,
|
||||
kl.str, kl.len, new_secret, enc_sess->esi_trasec_sz);
|
||||
memcpy(enc_sess->esi_traffic_secrets[ !cliser ], new_secret,
|
||||
memcpy(enc_sess->esi_traffic_secrets[1], new_secret,
|
||||
enc_sess->esi_trasec_sz);
|
||||
s = init_crypto_ctx(&pair->ykp_ctx[ !cliser ], enc_sess->esi_md,
|
||||
s = init_crypto_ctx(&pair->ykp_ctx[1], enc_sess->esi_md,
|
||||
enc_sess->esi_aead, new_secret, enc_sess->esi_trasec_sz,
|
||||
evp_aead_seal);
|
||||
if (s != 0)
|
||||
{
|
||||
LSQ_ERROR("could not init seal crypto ctx (key phase)");
|
||||
cleanup_crypto_ctx(&pair->ykp_ctx[ !cliser ]);
|
||||
cleanup_crypto_ctx(&pair->ykp_ctx[1]);
|
||||
/* This is a severe error, abort connection */
|
||||
enc_sess->esi_conn->cn_if->ci_internal_error(enc_sess->esi_conn,
|
||||
"crypto ctx failure during key phase shift");
|
||||
|
@ -2522,20 +2527,17 @@ typedef char enums_have_the_same_value[
|
|||
(int) ssl_encryption_application == (int) ENC_LEV_FORW ? 1 : -1];
|
||||
|
||||
static int
|
||||
cry_sm_set_encryption_secret (SSL *ssl, enum ssl_encryption_level_t level,
|
||||
const uint8_t *read_secret, const uint8_t *write_secret,
|
||||
size_t secret_len)
|
||||
set_secret (SSL *ssl, enum ssl_encryption_level_t level,
|
||||
const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len, int rw)
|
||||
{
|
||||
struct enc_sess_iquic *enc_sess;
|
||||
struct crypto_ctx_pair *pair;
|
||||
struct header_prot *hp;
|
||||
struct crypto_params crypa;
|
||||
int i;
|
||||
int have_alpn;
|
||||
const unsigned char *alpn;
|
||||
unsigned alpn_len;
|
||||
const enum enc_level enc_level = (enum enc_level) level;
|
||||
const uint8_t *secrets[2];
|
||||
char errbuf[ERR_ERROR_STRING_BUF_LEN];
|
||||
#define hexbuf errbuf
|
||||
|
||||
|
@ -2560,13 +2562,15 @@ cry_sm_set_encryption_secret (SSL *ssl, enum ssl_encryption_level_t level,
|
|||
}
|
||||
}
|
||||
|
||||
if (0 != get_crypto_params(enc_sess, &crypa))
|
||||
if (0 != get_crypto_params(enc_sess, cipher, &crypa))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
if (enc_sess->esi_flags & ESI_SERVER)
|
||||
secrets[0] = read_secret, secrets[1] = write_secret;
|
||||
else
|
||||
secrets[0] = write_secret, secrets[1] = read_secret;
|
||||
*/
|
||||
|
||||
if (enc_level < ENC_LEV_FORW)
|
||||
{
|
||||
|
@ -2579,39 +2583,45 @@ cry_sm_set_encryption_secret (SSL *ssl, enum ssl_encryption_level_t level,
|
|||
pair = &enc_sess->esi_pairs[0];
|
||||
hp = &enc_sess->esi_hp;
|
||||
enc_sess->esi_trasec_sz = secret_len;
|
||||
memcpy(enc_sess->esi_traffic_secrets[0], secrets[0], secret_len);
|
||||
memcpy(enc_sess->esi_traffic_secrets[1], secrets[1], secret_len);
|
||||
memcpy(enc_sess->esi_traffic_secrets[rw], secret, secret_len);
|
||||
enc_sess->esi_md = crypa.md;
|
||||
enc_sess->esi_aead = crypa.aead;
|
||||
}
|
||||
pair->ykp_thresh = IQUIC_INVALID_PACKNO;
|
||||
|
||||
LSQ_DEBUG("set encryption for level %u", enc_level);
|
||||
for (i = 1; i >= 0; --i)
|
||||
{
|
||||
if (secrets[i])
|
||||
{
|
||||
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
||||
LSQ_DEBUG("new %s secret: %s", i ? "server" : "client",
|
||||
HEXSTR(secrets[i], secret_len, hexbuf));
|
||||
if (0 != init_crypto_ctx(&pair->ykp_ctx[i], crypa.md,
|
||||
crypa.aead, secrets[i], secret_len, enc_sess->esi_dir[i]))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
assert(level == ssl_encryption_early_data);
|
||||
}
|
||||
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
||||
LSQ_DEBUG("set %s secret for level %u: %s", rw2str[rw], enc_level,
|
||||
HEXSTR(secret, secret_len, hexbuf));
|
||||
else
|
||||
LSQ_DEBUG("set %s for level %u", rw2str[rw], enc_level);
|
||||
|
||||
hp->hp_enc_level = enc_level;
|
||||
hp->hp_cipher = crypa.hp;
|
||||
hp->hp_gen_mask = crypa.gen_hp_mask;
|
||||
derive_hp_secrets(hp, crypa.md, crypa.aead, secret_len, secrets[0],
|
||||
secrets[1]);
|
||||
if (0 != init_crypto_ctx(&pair->ykp_ctx[rw], crypa.md,
|
||||
crypa.aead, secret, secret_len, rw2dir(rw)))
|
||||
goto err;
|
||||
|
||||
if (pair->ykp_ctx[!rw].yk_flags & YK_INITED)
|
||||
{
|
||||
/* Sanity check that the two sides end up with the same header
|
||||
* protection logic, as they should.
|
||||
*/
|
||||
assert(hp->hp_cipher == crypa.hp);
|
||||
assert(hp->hp_gen_mask == crypa.gen_hp_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
hp->hp_enc_level = enc_level;
|
||||
hp->hp_cipher = crypa.hp;
|
||||
hp->hp_gen_mask = crypa.gen_hp_mask;
|
||||
hp->hp_sz = EVP_AEAD_key_length(crypa.aead);
|
||||
}
|
||||
lsquic_qhkdf_expand(crypa.md, secret, secret_len, PN_LABEL, PN_LABEL_SZ,
|
||||
hp->hp_buf[rw], hp->hp_sz);
|
||||
|
||||
if (enc_sess->esi_flags & ESI_LOG_SECRETS)
|
||||
{
|
||||
log_crypto_pair(enc_sess, pair, "new");
|
||||
log_hp(enc_sess, hp, "new");
|
||||
log_crypto_ctx(enc_sess, &pair->ykp_ctx[rw], "new", rw);
|
||||
LSQ_DEBUG("%s hp: %s", rw2str[rw],
|
||||
HEXSTR(hp->hp_buf[rw], hp->hp_sz, hexbuf));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -2624,6 +2634,22 @@ cry_sm_set_encryption_secret (SSL *ssl, enum ssl_encryption_level_t level,
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
cry_sm_set_read_secret (SSL *ssl, enum ssl_encryption_level_t level,
|
||||
const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len)
|
||||
{
|
||||
return set_secret(ssl, level, cipher, secret, secret_len, 0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cry_sm_set_write_secret (SSL *ssl, enum ssl_encryption_level_t level,
|
||||
const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len)
|
||||
{
|
||||
return set_secret(ssl, level, cipher, secret, secret_len, 1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cry_sm_write_message (SSL *ssl, enum ssl_encryption_level_t level,
|
||||
const uint8_t *data, size_t len)
|
||||
|
@ -2721,7 +2747,8 @@ cry_sm_send_alert (SSL *ssl, enum ssl_encryption_level_t level, uint8_t alert)
|
|||
|
||||
static const SSL_QUIC_METHOD cry_quic_method =
|
||||
{
|
||||
.set_encryption_secrets = cry_sm_set_encryption_secret,
|
||||
.set_read_secret = cry_sm_set_read_secret,
|
||||
.set_write_secret = cry_sm_set_write_secret,
|
||||
.add_handshake_data = cry_sm_write_message,
|
||||
.flush_flight = cry_sm_flush_flight,
|
||||
.send_alert = cry_sm_send_alert,
|
||||
|
|
|
@ -1447,6 +1447,9 @@ lsquic_engine_destroy (lsquic_engine_t *engine)
|
|||
}
|
||||
lsquic_hash_destroy(engine->conns_hash);
|
||||
|
||||
while ((conn = lsquic_attq_pop(engine->attq, UINT64_MAX)))
|
||||
(void) engine_decref_conn(engine, conn, LSCONN_ATTQ);
|
||||
|
||||
assert(0 == engine->n_conns);
|
||||
assert(0 == engine->mini_conns_count);
|
||||
if (engine->pr_queue)
|
||||
|
|
|
@ -591,9 +591,10 @@ wipe_path (struct ietf_full_conn *conn, unsigned path_id)
|
|||
|
||||
static void
|
||||
path_chal_alarm_expired (enum alarm_id al_id, void *ctx,
|
||||
lsquic_time_t expiry, lsquic_time_t now, unsigned path_id)
|
||||
lsquic_time_t expiry, lsquic_time_t now)
|
||||
{
|
||||
struct ietf_full_conn *const conn = (struct ietf_full_conn *) ctx;
|
||||
const unsigned path_id = al_id - AL_PATH_CHAL;
|
||||
struct conn_path *const copath = &conn->ifc_paths[path_id];
|
||||
|
||||
if (copath->cop_n_chals < sizeof(copath->cop_path_chals)
|
||||
|
@ -614,22 +615,6 @@ path_chal_alarm_expired (enum alarm_id al_id, void *ctx,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
path_chal_0_alarm_expired (enum alarm_id al_id, void *ctx,
|
||||
lsquic_time_t expiry, lsquic_time_t now)
|
||||
{
|
||||
path_chal_alarm_expired(al_id, ctx, expiry, now, 0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
path_chal_1_alarm_expired (enum alarm_id al_id, void *ctx,
|
||||
lsquic_time_t expiry, lsquic_time_t now)
|
||||
{
|
||||
path_chal_alarm_expired(al_id, ctx, expiry, now, 1);
|
||||
}
|
||||
|
||||
|
||||
/* Sending DATA_BLOCKED and STREAM_DATA_BLOCKED frames is a way to elicit
|
||||
* incoming packets from peer when it is too slow to read data. This is
|
||||
* recommended by [draft-ietf-quic-transport-25] Section 4.1.
|
||||
|
@ -670,10 +655,10 @@ blocked_ka_alarm_expired (enum alarm_id al_id, void *ctx,
|
|||
|
||||
|
||||
static int
|
||||
migra_is_on (const struct ietf_full_conn *conn)
|
||||
migra_is_on (const struct ietf_full_conn *conn, unsigned path_id)
|
||||
{
|
||||
return (conn->ifc_send_flags & SF_SEND_PATH_CHAL_ALL)
|
||||
|| lsquic_alarmset_are_set(&conn->ifc_alset, ALBIT_PATH_CHAL_0|ALBIT_PATH_CHAL_1);
|
||||
return (conn->ifc_send_flags & (SF_SEND_PATH_CHAL << path_id))
|
||||
|| lsquic_alarmset_is_set(&conn->ifc_alset, AL_PATH_CHAL + path_id);
|
||||
}
|
||||
|
||||
|
||||
|
@ -682,7 +667,7 @@ migra_begin (struct ietf_full_conn *conn, struct conn_path *copath,
|
|||
struct dcid_elem *dce, const struct sockaddr *dest_sa,
|
||||
const struct transport_params *params)
|
||||
{
|
||||
assert(!(migra_is_on(conn)));
|
||||
assert(!(migra_is_on(conn, copath - conn->ifc_paths)));
|
||||
|
||||
dce->de_flags |= DE_ASSIGNED;
|
||||
copath->cop_flags |= COP_INITIALIZED;
|
||||
|
@ -1126,8 +1111,10 @@ ietf_full_conn_init (struct ietf_full_conn *conn,
|
|||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_PING, ping_alarm_expired, conn);
|
||||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_HANDSHAKE, handshake_alarm_expired, conn);
|
||||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_CID_THROT, cid_throt_alarm_expired, conn);
|
||||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_PATH_CHAL_0, path_chal_0_alarm_expired, conn);
|
||||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_PATH_CHAL_1, path_chal_1_alarm_expired, conn);
|
||||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_PATH_CHAL_0, path_chal_alarm_expired, conn);
|
||||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_PATH_CHAL_1, path_chal_alarm_expired, conn);
|
||||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_PATH_CHAL_2, path_chal_alarm_expired, conn);
|
||||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_PATH_CHAL_3, path_chal_alarm_expired, conn);
|
||||
lsquic_alarmset_init_alarm(&conn->ifc_alset, AL_BLOCKED_KA, blocked_ka_alarm_expired, conn);
|
||||
lsquic_rechist_init(&conn->ifc_rechist[PNS_INIT], &conn->ifc_conn, 1);
|
||||
lsquic_rechist_init(&conn->ifc_rechist[PNS_HSK], &conn->ifc_conn, 1);
|
||||
|
@ -5461,11 +5448,11 @@ process_retire_connection_id_frame (struct ietf_full_conn *conn,
|
|||
cce = find_cce_by_cid(conn, &packet_in->pi_dcid);
|
||||
if (cce)
|
||||
{
|
||||
cce->cce_flags |= CCE_USED;
|
||||
lconn->cn_cur_cce_idx = cce - lconn->cn_cces;
|
||||
LSQ_DEBUGC("current SCID was retired; set current SCID to "
|
||||
"%"CID_FMT" based on DCID in incoming packet",
|
||||
CID_BITS(&packet_in->pi_dcid));
|
||||
cce->cce_flags |= CCE_USED;
|
||||
lconn->cn_cur_cce_idx = cce - lconn->cn_cces;
|
||||
}
|
||||
else
|
||||
LSQ_WARN("current SCID was retired; no new SCID candidate");
|
||||
|
@ -6310,7 +6297,7 @@ process_regular_packet (struct ietf_full_conn *conn,
|
|||
if (packet_in->pi_path_id != conn->ifc_cur_path_id
|
||||
&& 0 == (conn->ifc_flags & IFC_SERVER)
|
||||
&& !(packet_in->pi_path_id == conn->ifc_mig_path_id
|
||||
&& migra_is_on(conn)))
|
||||
&& migra_is_on(conn, conn->ifc_mig_path_id)))
|
||||
{
|
||||
/* The "known server address" is recorded in the current path. */
|
||||
switch ((NP_IS_IPv6(CUR_NPATH(conn)) << 1) |
|
||||
|
|
|
@ -4140,6 +4140,7 @@ update_type_hist_and_check (const struct lsquic_stream *stream,
|
|||
0123, /* HD+ */
|
||||
012, /* HD */
|
||||
01, /* H */
|
||||
013, /* H+ */ /* Really HH, but we don't record it like this */
|
||||
01231, /* HD+H */
|
||||
0121, /* HDH */
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue