Mercurial > hg > nginx
comparison src/event/quic/ngx_event_quic_openssl_compat.c @ 9172:4ccb0d973206
QUIC: reusing crypto contexts for packet protection.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Fri, 20 Oct 2023 18:05:07 +0400 |
parents | f98636db77ef |
children | f7c9cd726298 |
comparison
equal
deleted
inserted
replaced
9171:f98636db77ef | 9172:4ccb0d973206 |
---|---|
52 ngx_str_t ctp; | 52 ngx_str_t ctp; |
53 }; | 53 }; |
54 | 54 |
55 | 55 |
56 static void ngx_quic_compat_keylog_callback(const SSL *ssl, const char *line); | 56 static void ngx_quic_compat_keylog_callback(const SSL *ssl, const char *line); |
57 static ngx_int_t ngx_quic_compat_set_encryption_secret(ngx_log_t *log, | 57 static ngx_int_t ngx_quic_compat_set_encryption_secret(ngx_connection_t *c, |
58 ngx_quic_compat_keys_t *keys, enum ssl_encryption_level_t level, | 58 ngx_quic_compat_keys_t *keys, enum ssl_encryption_level_t level, |
59 const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len); | 59 const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len); |
60 static void ngx_quic_compat_cleanup_encryption_secret(void *data); | |
60 static int ngx_quic_compat_add_transport_params_callback(SSL *ssl, | 61 static int ngx_quic_compat_add_transport_params_callback(SSL *ssl, |
61 unsigned int ext_type, unsigned int context, const unsigned char **out, | 62 unsigned int ext_type, unsigned int context, const unsigned char **out, |
62 size_t *outlen, X509 *x, size_t chainidx, int *al, void *add_arg); | 63 size_t *outlen, X509 *x, size_t chainidx, int *al, void *add_arg); |
63 static int ngx_quic_compat_parse_transport_params_callback(SSL *ssl, | 64 static int ngx_quic_compat_parse_transport_params_callback(SSL *ssl, |
64 unsigned int ext_type, unsigned int context, const unsigned char *in, | 65 unsigned int ext_type, unsigned int context, const unsigned char *in, |
212 | 213 |
213 } else { | 214 } else { |
214 com->method->set_read_secret((SSL *) ssl, level, cipher, secret, n); | 215 com->method->set_read_secret((SSL *) ssl, level, cipher, secret, n); |
215 com->read_record = 0; | 216 com->read_record = 0; |
216 | 217 |
217 (void) ngx_quic_compat_set_encryption_secret(c->log, &com->keys, level, | 218 (void) ngx_quic_compat_set_encryption_secret(c, &com->keys, level, |
218 cipher, secret, n); | 219 cipher, secret, n); |
219 } | 220 } |
220 } | 221 } |
221 | 222 |
222 | 223 |
223 static ngx_int_t | 224 static ngx_int_t |
224 ngx_quic_compat_set_encryption_secret(ngx_log_t *log, | 225 ngx_quic_compat_set_encryption_secret(ngx_connection_t *c, |
225 ngx_quic_compat_keys_t *keys, enum ssl_encryption_level_t level, | 226 ngx_quic_compat_keys_t *keys, enum ssl_encryption_level_t level, |
226 const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len) | 227 const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len) |
227 { | 228 { |
228 ngx_int_t key_len; | 229 ngx_int_t key_len; |
229 ngx_str_t secret_str; | 230 ngx_str_t secret_str; |
230 ngx_uint_t i; | 231 ngx_uint_t i; |
231 ngx_quic_hkdf_t seq[2]; | 232 ngx_quic_hkdf_t seq[2]; |
232 ngx_quic_secret_t *peer_secret; | 233 ngx_quic_secret_t *peer_secret; |
233 ngx_quic_ciphers_t ciphers; | 234 ngx_quic_ciphers_t ciphers; |
235 ngx_pool_cleanup_t *cln; | |
234 | 236 |
235 peer_secret = &keys->secret; | 237 peer_secret = &keys->secret; |
236 | 238 |
237 keys->cipher = SSL_CIPHER_get_id(cipher); | 239 keys->cipher = SSL_CIPHER_get_id(cipher); |
238 | 240 |
239 key_len = ngx_quic_ciphers(keys->cipher, &ciphers, level); | 241 key_len = ngx_quic_ciphers(keys->cipher, &ciphers, level); |
240 | 242 |
241 if (key_len == NGX_ERROR) { | 243 if (key_len == NGX_ERROR) { |
242 ngx_ssl_error(NGX_LOG_INFO, log, 0, "unexpected cipher"); | 244 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher"); |
243 return NGX_ERROR; | 245 return NGX_ERROR; |
244 } | 246 } |
245 | 247 |
246 if (sizeof(peer_secret->secret.data) < secret_len) { | 248 if (sizeof(peer_secret->secret.data) < secret_len) { |
247 ngx_log_error(NGX_LOG_ALERT, log, 0, | 249 ngx_log_error(NGX_LOG_ALERT, c->log, 0, |
248 "unexpected secret len: %uz", secret_len); | 250 "unexpected secret len: %uz", secret_len); |
249 return NGX_ERROR; | 251 return NGX_ERROR; |
250 } | 252 } |
251 | 253 |
252 peer_secret->secret.len = secret_len; | 254 peer_secret->secret.len = secret_len; |
260 | 262 |
261 ngx_quic_hkdf_set(&seq[0], "tls13 key", &peer_secret->key, &secret_str); | 263 ngx_quic_hkdf_set(&seq[0], "tls13 key", &peer_secret->key, &secret_str); |
262 ngx_quic_hkdf_set(&seq[1], "tls13 iv", &peer_secret->iv, &secret_str); | 264 ngx_quic_hkdf_set(&seq[1], "tls13 iv", &peer_secret->iv, &secret_str); |
263 | 265 |
264 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) { | 266 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) { |
265 if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, log) != NGX_OK) { | 267 if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, c->log) != NGX_OK) { |
266 return NGX_ERROR; | 268 return NGX_ERROR; |
267 } | 269 } |
268 } | 270 } |
269 | 271 |
272 /* register cleanup handler once */ | |
273 | |
274 if (peer_secret->ctx) { | |
275 ngx_quic_crypto_cleanup(peer_secret); | |
276 | |
277 } else { | |
278 cln = ngx_pool_cleanup_add(c->pool, 0); | |
279 if (cln == NULL) { | |
280 return NGX_ERROR; | |
281 } | |
282 | |
283 cln->handler = ngx_quic_compat_cleanup_encryption_secret; | |
284 cln->data = peer_secret; | |
285 } | |
286 | |
287 if (ngx_quic_crypto_init(ciphers.c, peer_secret, 1, c->log) == NGX_ERROR) { | |
288 return NGX_ERROR; | |
289 } | |
290 | |
270 return NGX_OK; | 291 return NGX_OK; |
292 } | |
293 | |
294 | |
295 static void | |
296 ngx_quic_compat_cleanup_encryption_secret(void *data) | |
297 { | |
298 ngx_quic_secret_t *secret = data; | |
299 | |
300 ngx_quic_crypto_cleanup(secret); | |
271 } | 301 } |
272 | 302 |
273 | 303 |
274 static int | 304 static int |
275 ngx_quic_compat_add_transport_params_callback(SSL *ssl, unsigned int ext_type, | 305 ngx_quic_compat_add_transport_params_callback(SSL *ssl, unsigned int ext_type, |
576 secret = &rec->keys->secret; | 606 secret = &rec->keys->secret; |
577 | 607 |
578 ngx_memcpy(nonce, secret->iv.data, secret->iv.len); | 608 ngx_memcpy(nonce, secret->iv.data, secret->iv.len); |
579 ngx_quic_compute_nonce(nonce, sizeof(nonce), rec->number); | 609 ngx_quic_compute_nonce(nonce, sizeof(nonce), rec->number); |
580 | 610 |
581 if (ngx_quic_crypto_seal(ciphers.c, secret, &out, | 611 if (ngx_quic_crypto_seal(secret, &out, nonce, &rec->payload, &ad, rec->log) |
582 nonce, &rec->payload, &ad, rec->log) | |
583 != NGX_OK) | 612 != NGX_OK) |
584 { | 613 { |
585 return NGX_ERROR; | 614 return NGX_ERROR; |
586 } | 615 } |
587 | 616 |