summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2019-11-18 10:34:26 +0100
committerDaniel Stenberg <daniel@haxx.se>2019-11-18 14:42:51 +0100
commita72b6b9606d382e3c4b883484743735b3e2ed241 (patch)
tree56412e27a7a0901b940fb13f2023d421968e82fe
parentd1476aa11e26019bc47cb8a3c7cd3445ac051283 (diff)
downloadcurl-a72b6b9606d382e3c4b883484743735b3e2ed241.tar.gz
ngtcp2: handle key updates as ngtcp2 master branch tells us
Reviewed-by: Tatsuhiro Tsujikawa Fixes #4612 Closes #4613
-rw-r--r--lib/vquic/ngtcp2.c36
-rw-r--r--lib/vquic/ngtcp2.h3
2 files changed, 36 insertions, 3 deletions
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;