Mercurial > hg > nginx
diff src/event/ngx_event_quic_protection.c @ 8562:b31c02454539 quic
QUIC: added stateless reset support.
The new "quic_stateless_reset_token_key" directive is added. It sets the
endpoint key used to generate stateless reset tokens and enables feature.
If the endpoint receives short-header packet that can't be matched to
existing connection, a stateless reset packet is generated with
a proper token.
If a valid stateless reset token is found in the incoming packet,
the connection is closed.
Example configuration:
http {
quic_stateless_reset_token_key "foo";
...
}
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Wed, 30 Sep 2020 20:54:46 +0300 |
parents | 0f37b4ef3cd9 |
children | 0e12c4aca3ab |
line wrap: on
line diff
--- a/src/event/ngx_event_quic_protection.c +++ b/src/event/ngx_event_quic_protection.c @@ -923,6 +923,62 @@ ngx_quic_create_retry_packet(ngx_quic_he } +ngx_int_t +ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid, ngx_str_t *secret, + u_char *token) +{ + uint8_t *p; + size_t is_len, key_len, info_len; + ngx_str_t label; + const EVP_MD *digest; + uint8_t info[20]; + uint8_t is[SHA256_DIGEST_LENGTH]; + uint8_t key[SHA256_DIGEST_LENGTH]; + + /* 10.4.2. Calculating a Stateless Reset Token */ + + digest = EVP_sha256(); + ngx_str_set(&label, "sr_token_key"); + + if (ngx_hkdf_extract(is, &is_len, digest, secret->data, secret->len, + cid->data, cid->len) + != NGX_OK) + { + ngx_ssl_error(NGX_LOG_INFO, c->log, 0, + "ngx_hkdf_extract(%V) failed", &label); + return NGX_ERROR; + } + + key_len = SHA256_DIGEST_LENGTH; + + info_len = 2 + 1 + label.len + 1; + + info[0] = 0; + info[1] = key_len; + info[2] = label.len; + + p = ngx_cpymem(&info[3], label.data, label.len); + *p = '\0'; + + if (ngx_hkdf_expand(key, key_len, digest, is, is_len, info, info_len) + != NGX_OK) + { + ngx_ssl_error(NGX_LOG_INFO, c->log, 0, + "ngx_hkdf_expand(%V) failed", &label); + return NGX_ERROR; + } + + ngx_memcpy(token, key, NGX_QUIC_SR_TOKEN_LEN); + +#if (NGX_DEBUG) + ngx_quic_hexdump(c->log, "quic stateless reset token", token, + NGX_QUIC_SR_TOKEN_LEN); +#endif + + return NGX_OK; +} + + static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask, uint64_t *largest_pn)