Mercurial > hg > nginx-quic
comparison src/event/quic/ngx_event_quic_protection.c @ 8287:cef042935003 quic
QUIC: the "quic_host_key" directive.
The token generation in QUIC is reworked. Single host key is used to generate
all required keys of needed sizes using HKDF.
The "quic_stateless_reset_token_key" directive is removed. Instead, the
"quic_host_key" directive is used, which reads key from file, or sets it
to random bytes if not specified.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Mon, 08 Feb 2021 16:49:33 +0300 |
parents | 3443ee341cc1 |
children | d4e02b3b734f |
comparison
equal
deleted
inserted
replaced
8286:3956bbf91002 | 8287:cef042935003 |
---|---|
940 return NGX_OK; | 940 return NGX_OK; |
941 } | 941 } |
942 | 942 |
943 | 943 |
944 ngx_int_t | 944 ngx_int_t |
945 ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid, ngx_str_t *secret, | 945 ngx_quic_derive_key(ngx_log_t *log, const char *label, ngx_str_t *secret, |
946 u_char *token) | 946 ngx_str_t *salt, u_char *out, size_t len) |
947 { | 947 { |
948 size_t is_len, info_len; | |
948 uint8_t *p; | 949 uint8_t *p; |
949 size_t is_len, key_len, info_len; | |
950 ngx_str_t label; | |
951 const EVP_MD *digest; | 950 const EVP_MD *digest; |
952 uint8_t info[20]; | 951 |
953 uint8_t is[SHA256_DIGEST_LENGTH]; | 952 uint8_t is[SHA256_DIGEST_LENGTH]; |
954 uint8_t key[SHA256_DIGEST_LENGTH]; | 953 uint8_t info[20]; |
955 | |
956 /* 10.4.2. Calculating a Stateless Reset Token */ | |
957 | 954 |
958 digest = EVP_sha256(); | 955 digest = EVP_sha256(); |
959 ngx_str_set(&label, "sr_token_key"); | |
960 | 956 |
961 if (ngx_hkdf_extract(is, &is_len, digest, secret->data, secret->len, | 957 if (ngx_hkdf_extract(is, &is_len, digest, secret->data, secret->len, |
962 cid->data, cid->len) | 958 salt->data, salt->len) |
963 != NGX_OK) | 959 != NGX_OK) |
964 { | 960 { |
965 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | 961 ngx_ssl_error(NGX_LOG_INFO, log, 0, |
966 "ngx_hkdf_extract(%V) failed", &label); | 962 "ngx_hkdf_extract(%s) failed", label); |
967 return NGX_ERROR; | 963 return NGX_ERROR; |
968 } | 964 } |
969 | |
970 key_len = SHA256_DIGEST_LENGTH; | |
971 | |
972 info_len = 2 + 1 + label.len + 1; | |
973 | 965 |
974 info[0] = 0; | 966 info[0] = 0; |
975 info[1] = key_len; | 967 info[1] = len; |
976 info[2] = label.len; | 968 info[2] = ngx_strlen(label); |
977 | 969 |
978 p = ngx_cpymem(&info[3], label.data, label.len); | 970 info_len = 2 + 1 + info[2] + 1; |
971 | |
972 if (info_len >= 20) { | |
973 ngx_log_error(NGX_LOG_INFO, log, 0, | |
974 "ngx_quic_create_key label \"%s\" too long", label); | |
975 return NGX_ERROR; | |
976 } | |
977 | |
978 p = ngx_cpymem(&info[3], label, info[2]); | |
979 *p = '\0'; | 979 *p = '\0'; |
980 | 980 |
981 if (ngx_hkdf_expand(key, key_len, digest, is, is_len, info, info_len) | 981 if (ngx_hkdf_expand(out, len, digest, is, is_len, info, info_len) != NGX_OK) |
982 != NGX_OK) | 982 { |
983 { | 983 ngx_ssl_error(NGX_LOG_INFO, log, 0, |
984 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | 984 "ngx_hkdf_expand(%s) failed", label); |
985 "ngx_hkdf_expand(%V) failed", &label); | 985 return NGX_ERROR; |
986 return NGX_ERROR; | 986 } |
987 } | |
988 | |
989 ngx_memcpy(token, key, NGX_QUIC_SR_TOKEN_LEN); | |
990 | |
991 #if (NGX_DEBUG) | |
992 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
993 "quic stateless reset token %*xs", | |
994 (size_t) NGX_QUIC_SR_TOKEN_LEN, token); | |
995 #endif | |
996 | 987 |
997 return NGX_OK; | 988 return NGX_OK; |
998 } | 989 } |
999 | 990 |
1000 | 991 |