From a72b6b9606d382e3c4b883484743735b3e2ed241 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 18 Nov 2019 10:34:26 +0100 Subject: ngtcp2: handle key updates as ngtcp2 master branch tells us Reviewed-by: Tatsuhiro Tsujikawa Fixes #4612 Closes #4613 --- lib/vquic/ngtcp2.c | 36 +++++++++++++++++++++++++++++++++--- lib/vquic/ngtcp2.h | 3 +++ 2 files changed, 36 insertions(+), 3 deletions(-) (limited to 'lib/vquic') diff --git a/lib/vquic/ngtcp2.c b/lib/vquic/ngtcp2.c index 86151b8a2..b97c0c3d4 100644 --- a/lib/vquic/ngtcp2.c +++ b/lib/vquic/ngtcp2.c @@ -174,8 +174,19 @@ static int quic_set_encryption_secrets(SSL *ssl, tx_secret, secretlen, NGTCP2_CRYPTO_SIDE_CLIENT) != 0) return 0; - if(level == NGTCP2_CRYPTO_LEVEL_APP && init_ngh3_conn(qs) != CURLE_OK) - return 0; + if(level == NGTCP2_CRYPTO_LEVEL_APP) { + if(init_ngh3_conn(qs) != CURLE_OK) + return 0; + + /* malloc an area big enough for both secrets */ + qs->rx_secret = malloc(secretlen * 2); + if(!qs->rx_secret) + return 0; + memcpy(qs->rx_secret, rx_secret, secretlen); + memcpy(&qs->rx_secret[secretlen], tx_secret, secretlen); + qs->tx_secret = &qs->rx_secret[secretlen]; + qs->rx_secretlen = secretlen; + } return 1; } @@ -503,6 +514,25 @@ static int cb_get_new_connection_id(ngtcp2_conn *tconn, ngtcp2_cid *cid, return 0; } +static int cb_update_key(ngtcp2_conn *tconn, uint8_t *rx_key, + uint8_t *rx_iv, uint8_t *tx_key, + uint8_t *tx_iv, void *user_data) +{ + struct quicsocket *qs = (struct quicsocket *)user_data; + uint8_t rx_secret[64]; + uint8_t tx_secret[64]; + + if(ngtcp2_crypto_update_key(tconn, rx_secret, tx_secret, + rx_key, rx_iv, tx_key, tx_iv, qs->rx_secret, + qs->tx_secret, qs->rx_secretlen) != 0) + return NGTCP2_ERR_CALLBACK_FAILURE; + + /* store the updated secrets */ + memcpy(qs->rx_secret, rx_secret, qs->rx_secretlen); + memcpy(qs->tx_secret, tx_secret, qs->rx_secretlen); + return 0; +} + static ngtcp2_conn_callbacks ng_callbacks = { cb_initial, NULL, /* recv_client_initial */ @@ -524,7 +554,7 @@ static ngtcp2_conn_callbacks ng_callbacks = { NULL, /* rand */ cb_get_new_connection_id, NULL, /* remove_connection_id */ - NULL, /* update_key */ + cb_update_key, /* update_key */ NULL, /* path_validation */ NULL, /* select_preferred_addr */ cb_stream_reset, diff --git a/lib/vquic/ngtcp2.h b/lib/vquic/ngtcp2.h index 5570fc7e7..62eae4895 100644 --- a/lib/vquic/ngtcp2.h +++ b/lib/vquic/ngtcp2.h @@ -46,6 +46,9 @@ struct quicsocket { ngtcp2_settings settings; SSL_CTX *sslctx; SSL *ssl; + uint8_t *rx_secret; /* malloced */ + uint8_t *tx_secret; /* points into the above buffer */ + size_t rx_secretlen; struct quic_handshake client_crypto_data[3]; /* the last TLS alert description generated by the local endpoint */ uint8_t tls_alert; -- cgit v1.2.3