*/
static inline int quic_tls_ctx_keys_alloc(struct quic_tls_ctx *ctx)
{
+ if (ctx->rx.key)
+ goto write;
+
if (!(ctx->rx.iv = pool_alloc(pool_head_quic_tls_iv)) ||
- !(ctx->rx.key = pool_alloc(pool_head_quic_tls_key)) ||
- !(ctx->tx.iv = pool_alloc(pool_head_quic_tls_iv)) ||
+ !(ctx->rx.key = pool_alloc(pool_head_quic_tls_key)))
+ goto err;
+
+ write:
+ if (ctx->tx.key)
+ goto out;
+
+ if (!(ctx->tx.iv = pool_alloc(pool_head_quic_tls_iv)) ||
!(ctx->tx.key = pool_alloc(pool_head_quic_tls_key)))
goto err;
ctx->rx.ivlen = ctx->tx.ivlen = QUIC_TLS_IV_LEN;
ctx->rx.keylen = ctx->tx.keylen = QUIC_TLS_KEY_LEN;
+out:
return 1;
err:
rx->md = tx->md = tls_md(cipher);
rx->hp = tx->hp = tls_hp(cipher);
+ if (!read_secret)
+ goto write;
+
if (!quic_tls_derive_keys(rx->aead, rx->hp, rx->md, ver, rx->key, rx->keylen,
rx->iv, rx->ivlen, rx->hp_key, sizeof rx->hp_key,
read_secret, secret_len)) {
quic_accept_push_qc(qc);
}
+write:
+
if (!write_secret)
goto out;
goto leave;
}
- memcpy(rx->secret, read_secret, secret_len);
- rx->secretlen = secret_len;
- memcpy(tx->secret, write_secret, secret_len);
- tx->secretlen = secret_len;
+ if (read_secret) {
+ memcpy(rx->secret, read_secret, secret_len);
+ rx->secretlen = secret_len;
+ }
+ if (write_secret) {
+ memcpy(tx->secret, write_secret, secret_len);
+ tx->secretlen = secret_len;
+ }
/* Initialize all the secret keys lengths */
prv_rx->secretlen = nxt_rx->secretlen = nxt_tx->secretlen = secret_len;
/* Prepare the next key update */
- if (!quic_tls_key_update(qc)) {
- // trace already emitted by function above
- goto leave;
- }
}
out:
else {
qc->state = QUIC_HS_ST_COMPLETE;
}
+
+ if (!quic_tls_key_update(qc)) {
+ TRACE_ERROR("quic_tls_key_update() failed", QUIC_EV_CONN_IO_CB, qc);
+ goto leave;
+ }
} else {
ssl_err = SSL_process_quic_post_handshake(ctx->ssl);
if (ssl_err != 1) {