]> git.kaiwu.me - nginx.git/commitdiff
QUIC: posted generating TLS Key Update next keys.
authorSergey Kandaurov <pluknet@nginx.com>
Fri, 25 Aug 2023 09:51:38 +0000 (13:51 +0400)
committerSergey Kandaurov <pluknet@nginx.com>
Fri, 25 Aug 2023 09:51:38 +0000 (13:51 +0400)
Since at least f9fbeb4ee0de and certainly after 924882f42dea, which
TLS Key Update support predates, queued data output is deferred to a
posted push handler.  To address timing signals after these changes,
generating next keys is now posted to run after the push handler.

src/event/quic/ngx_event_quic.c
src/event/quic/ngx_event_quic_connection.h
src/event/quic/ngx_event_quic_protection.c
src/event/quic/ngx_event_quic_protection.h
src/event/quic/ngx_event_quic_ssl.c

index fb211cc9d1a4804e3f170d9d3ce5ea8bb2f1a2ea..2d7cecbc00d3bcb38313565293ce981c849d97ad 100644 (file)
@@ -283,6 +283,10 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_quic_conf_t *conf,
     qc->path_validation.data = c;
     qc->path_validation.handler = ngx_quic_path_handler;
 
+    qc->key_update.log = c->log;
+    qc->key_update.data = c;
+    qc->key_update.handler = ngx_quic_keys_update;
+
     qc->conf = conf;
 
     if (ngx_quic_init_transport_params(&qc->tp, conf) != NGX_OK) {
@@ -562,6 +566,10 @@ ngx_quic_close_connection(ngx_connection_t *c, ngx_int_t rc)
         ngx_delete_posted_event(&qc->push);
     }
 
+    if (qc->key_update.posted) {
+        ngx_delete_posted_event(&qc->key_update);
+    }
+
     if (qc->close.timer_set) {
         return;
     }
@@ -1055,7 +1063,9 @@ ngx_quic_handle_payload(ngx_connection_t *c, ngx_quic_header_t *pkt)
         return rc;
     }
 
-    return ngx_quic_keys_update(c, qc->keys);
+    ngx_post_event(&qc->key_update, &ngx_posted_events);
+
+    return NGX_OK;
 }
 
 
index 5836f94a978991dd56ab2918c9f17e5ee431e8b6..d84e3e63d33e33521db45ea48b2f76ed1bc18db2 100644 (file)
@@ -230,6 +230,8 @@ struct ngx_quic_connection_s {
     ngx_event_t                       pto;
     ngx_event_t                       close;
     ngx_event_t                       path_validation;
+    ngx_event_t                       key_update;
+
     ngx_msec_t                        last_cc;
 
     ngx_msec_t                        first_rtt;
index ecac6f578767df9797817bb51ad5969187ffffa7..5bc3c200f1efee643ac3784c30caa6def1ff481c 100644 (file)
@@ -700,23 +700,32 @@ ngx_quic_keys_switch(ngx_connection_t *c, ngx_quic_keys_t *keys)
 }
 
 
-ngx_int_t
-ngx_quic_keys_update(ngx_connection_t *c, ngx_quic_keys_t *keys)
+void
+ngx_quic_keys_update(ngx_event_t *ev)
 {
-    ngx_uint_t           i;
-    ngx_quic_hkdf_t      seq[6];
-    ngx_quic_ciphers_t   ciphers;
-    ngx_quic_secrets_t  *current, *next;
+    ngx_uint_t              i;
+    ngx_quic_hkdf_t         seq[6];
+    ngx_quic_keys_t        *keys;
+    ngx_connection_t       *c;
+    ngx_quic_ciphers_t      ciphers;
+    ngx_quic_secrets_t     *current, *next;
+    ngx_quic_connection_t  *qc;
+
+    c = ev->data;
+    qc = ngx_quic_get_connection(c);
+    keys = qc->keys;
 
     current = &keys->secrets[ssl_encryption_application];
     next = &keys->next_key;
 
     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic key update");
 
+    c->log->action = "updating keys";
+
     if (ngx_quic_ciphers(keys->cipher, &ciphers, ssl_encryption_application)
         == NGX_ERROR)
     {
-        return NGX_ERROR;
+        goto failed;
     }
 
     next->client.secret.len = current->client.secret.len;
@@ -744,11 +753,15 @@ ngx_quic_keys_update(ngx_connection_t *c, ngx_quic_keys_t *keys)
 
     for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
         if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, c->log) != NGX_OK) {
-            return NGX_ERROR;
+            goto failed;
         }
     }
 
-    return NGX_OK;
+    return;
+
+failed:
+
+    ngx_quic_close_connection(c, NGX_ERROR);
 }
 
 
index 4e56ea9d1db8a917ace76523ffc063da45c8f7ca..2d3006776eecb4ba34ff60c9d33253e44b22a365 100644 (file)
@@ -99,7 +99,7 @@ ngx_uint_t ngx_quic_keys_available(ngx_quic_keys_t *keys,
 void ngx_quic_keys_discard(ngx_quic_keys_t *keys,
     enum ssl_encryption_level_t level);
 void ngx_quic_keys_switch(ngx_connection_t *c, ngx_quic_keys_t *keys);
-ngx_int_t ngx_quic_keys_update(ngx_connection_t *c, ngx_quic_keys_t *keys);
+void ngx_quic_keys_update(ngx_event_t *ev);
 ngx_int_t ngx_quic_encrypt(ngx_quic_header_t *pkt, ngx_str_t *res);
 ngx_int_t ngx_quic_decrypt(ngx_quic_header_t *pkt, uint64_t *largest_pn);
 void ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn);
index e0862e296881b24f86d20d7c98afbe3135848756..316d6b5eb73171d44bce4f387dd94825fb383b3a 100644 (file)
@@ -482,9 +482,7 @@ ngx_quic_crypto_input(ngx_connection_t *c, ngx_chain_t *data)
      * Generating next keys before a key update is received.
      */
 
-    if (ngx_quic_keys_update(c, qc->keys) != NGX_OK) {
-        return NGX_ERROR;
-    }
+    ngx_post_event(&qc->key_update, &ngx_posted_events);
 
     /*
      * RFC 9001, 4.9.2.  Discarding Handshake Keys