Latest update
This commit is contained in:
@@ -195,7 +195,7 @@ ngx_quic_rtt_sample(ngx_connection_t *c, ngx_quic_ack_frame_t *ack,
|
|||||||
} else {
|
} else {
|
||||||
qc->min_rtt = ngx_min(qc->min_rtt, latest_rtt);
|
qc->min_rtt = ngx_min(qc->min_rtt, latest_rtt);
|
||||||
|
|
||||||
ack_delay = ack->delay * (1 << qc->ctp.ack_delay_exponent) / 1000;
|
ack_delay = (ack->delay << qc->ctp.ack_delay_exponent) / 1000;
|
||||||
|
|
||||||
if (c->ssl->handshaked) {
|
if (c->ssl->handshaked) {
|
||||||
ack_delay = ngx_min(ack_delay, qc->ctp.max_ack_delay);
|
ack_delay = ngx_min(ack_delay, qc->ctp.max_ack_delay);
|
||||||
|
|||||||
@@ -48,12 +48,10 @@ typedef struct {
|
|||||||
const u_char *label;
|
const u_char *label;
|
||||||
} ngx_quic_hkdf_t;
|
} ngx_quic_hkdf_t;
|
||||||
|
|
||||||
#define ngx_quic_hkdf_set(label, out, prk) \
|
#define ngx_quic_hkdf_set(seq, _label, _out, _prk) \
|
||||||
{ \
|
(seq)->out_len = (_out)->len; (seq)->out = (_out)->data; \
|
||||||
(out)->len, (out)->data, \
|
(seq)->prk_len = (_prk)->len, (seq)->prk = (_prk)->data, \
|
||||||
(prk)->len, (prk)->data, \
|
(seq)->label_len = (sizeof(_label) - 1); (seq)->label = (u_char *)(_label);
|
||||||
(sizeof(label) - 1), (u_char *)(label), \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t ngx_hkdf_expand(u_char *out_key, size_t out_len,
|
static ngx_int_t ngx_hkdf_expand(u_char *out_key, size_t out_len,
|
||||||
@@ -149,8 +147,10 @@ ngx_quic_keys_set_initial_secret(ngx_quic_keys_t *keys, ngx_str_t *secret,
|
|||||||
{
|
{
|
||||||
size_t is_len;
|
size_t is_len;
|
||||||
uint8_t is[SHA256_DIGEST_LENGTH];
|
uint8_t is[SHA256_DIGEST_LENGTH];
|
||||||
|
ngx_str_t iss;
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
const EVP_MD *digest;
|
const EVP_MD *digest;
|
||||||
|
ngx_quic_hkdf_t seq[8];
|
||||||
ngx_quic_secret_t *client, *server;
|
ngx_quic_secret_t *client, *server;
|
||||||
|
|
||||||
static const uint8_t salt[20] =
|
static const uint8_t salt[20] =
|
||||||
@@ -177,10 +177,8 @@ ngx_quic_keys_set_initial_secret(ngx_quic_keys_t *keys, ngx_str_t *secret,
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_str_t iss = {
|
iss.len = is_len;
|
||||||
.data = is,
|
iss.data = is;
|
||||||
.len = is_len
|
|
||||||
};
|
|
||||||
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, log, 0,
|
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, log, 0,
|
||||||
"quic ngx_quic_set_initial_secret");
|
"quic ngx_quic_set_initial_secret");
|
||||||
@@ -203,17 +201,15 @@ ngx_quic_keys_set_initial_secret(ngx_quic_keys_t *keys, ngx_str_t *secret,
|
|||||||
client->iv.len = NGX_QUIC_IV_LEN;
|
client->iv.len = NGX_QUIC_IV_LEN;
|
||||||
server->iv.len = NGX_QUIC_IV_LEN;
|
server->iv.len = NGX_QUIC_IV_LEN;
|
||||||
|
|
||||||
ngx_quic_hkdf_t seq[] = {
|
/* labels per RFC 9001, 5.1. Packet Protection Keys */
|
||||||
/* labels per RFC 9001, 5.1. Packet Protection Keys */
|
ngx_quic_hkdf_set(&seq[0], "tls13 client in", &client->secret, &iss);
|
||||||
ngx_quic_hkdf_set("tls13 client in", &client->secret, &iss),
|
ngx_quic_hkdf_set(&seq[1], "tls13 quic key", &client->key, &client->secret);
|
||||||
ngx_quic_hkdf_set("tls13 quic key", &client->key, &client->secret),
|
ngx_quic_hkdf_set(&seq[2], "tls13 quic iv", &client->iv, &client->secret);
|
||||||
ngx_quic_hkdf_set("tls13 quic iv", &client->iv, &client->secret),
|
ngx_quic_hkdf_set(&seq[3], "tls13 quic hp", &client->hp, &client->secret);
|
||||||
ngx_quic_hkdf_set("tls13 quic hp", &client->hp, &client->secret),
|
ngx_quic_hkdf_set(&seq[4], "tls13 server in", &server->secret, &iss);
|
||||||
ngx_quic_hkdf_set("tls13 server in", &server->secret, &iss),
|
ngx_quic_hkdf_set(&seq[5], "tls13 quic key", &server->key, &server->secret);
|
||||||
ngx_quic_hkdf_set("tls13 quic key", &server->key, &server->secret),
|
ngx_quic_hkdf_set(&seq[6], "tls13 quic iv", &server->iv, &server->secret);
|
||||||
ngx_quic_hkdf_set("tls13 quic iv", &server->iv, &server->secret),
|
ngx_quic_hkdf_set(&seq[7], "tls13 quic hp", &server->hp, &server->secret);
|
||||||
ngx_quic_hkdf_set("tls13 quic hp", &server->hp, &server->secret),
|
|
||||||
};
|
|
||||||
|
|
||||||
for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
|
for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
|
||||||
if (ngx_quic_hkdf_expand(&seq[i], digest, log) != NGX_OK) {
|
if (ngx_quic_hkdf_expand(&seq[i], digest, log) != NGX_OK) {
|
||||||
@@ -639,6 +635,7 @@ ngx_quic_keys_set_encryption_secret(ngx_log_t *log, ngx_uint_t is_write,
|
|||||||
ngx_int_t key_len;
|
ngx_int_t key_len;
|
||||||
ngx_str_t secret_str;
|
ngx_str_t secret_str;
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
|
ngx_quic_hkdf_t seq[3];
|
||||||
ngx_quic_secret_t *peer_secret;
|
ngx_quic_secret_t *peer_secret;
|
||||||
ngx_quic_ciphers_t ciphers;
|
ngx_quic_ciphers_t ciphers;
|
||||||
|
|
||||||
@@ -670,11 +667,10 @@ ngx_quic_keys_set_encryption_secret(ngx_log_t *log, ngx_uint_t is_write,
|
|||||||
secret_str.len = secret_len;
|
secret_str.len = secret_len;
|
||||||
secret_str.data = (u_char *) secret;
|
secret_str.data = (u_char *) secret;
|
||||||
|
|
||||||
ngx_quic_hkdf_t seq[] = {
|
ngx_quic_hkdf_set(&seq[0], "tls13 quic key",
|
||||||
ngx_quic_hkdf_set("tls13 quic key", &peer_secret->key, &secret_str),
|
&peer_secret->key, &secret_str);
|
||||||
ngx_quic_hkdf_set("tls13 quic iv", &peer_secret->iv, &secret_str),
|
ngx_quic_hkdf_set(&seq[1], "tls13 quic iv", &peer_secret->iv, &secret_str);
|
||||||
ngx_quic_hkdf_set("tls13 quic hp", &peer_secret->hp, &secret_str),
|
ngx_quic_hkdf_set(&seq[2], "tls13 quic hp", &peer_secret->hp, &secret_str);
|
||||||
};
|
|
||||||
|
|
||||||
for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
|
for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
|
||||||
if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, log) != NGX_OK) {
|
if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, log) != NGX_OK) {
|
||||||
@@ -720,6 +716,7 @@ ngx_int_t
|
|||||||
ngx_quic_keys_update(ngx_connection_t *c, ngx_quic_keys_t *keys)
|
ngx_quic_keys_update(ngx_connection_t *c, ngx_quic_keys_t *keys)
|
||||||
{
|
{
|
||||||
ngx_uint_t i;
|
ngx_uint_t i;
|
||||||
|
ngx_quic_hkdf_t seq[6];
|
||||||
ngx_quic_ciphers_t ciphers;
|
ngx_quic_ciphers_t ciphers;
|
||||||
ngx_quic_secrets_t *current, *next;
|
ngx_quic_secrets_t *current, *next;
|
||||||
|
|
||||||
@@ -744,20 +741,18 @@ ngx_quic_keys_update(ngx_connection_t *c, ngx_quic_keys_t *keys)
|
|||||||
next->server.iv.len = NGX_QUIC_IV_LEN;
|
next->server.iv.len = NGX_QUIC_IV_LEN;
|
||||||
next->server.hp = current->server.hp;
|
next->server.hp = current->server.hp;
|
||||||
|
|
||||||
ngx_quic_hkdf_t seq[] = {
|
ngx_quic_hkdf_set(&seq[0], "tls13 quic ku",
|
||||||
ngx_quic_hkdf_set("tls13 quic ku",
|
&next->client.secret, ¤t->client.secret);
|
||||||
&next->client.secret, ¤t->client.secret),
|
ngx_quic_hkdf_set(&seq[1], "tls13 quic key",
|
||||||
ngx_quic_hkdf_set("tls13 quic key",
|
&next->client.key, &next->client.secret);
|
||||||
&next->client.key, &next->client.secret),
|
ngx_quic_hkdf_set(&seq[2], "tls13 quic iv",
|
||||||
ngx_quic_hkdf_set("tls13 quic iv",
|
&next->client.iv, &next->client.secret);
|
||||||
&next->client.iv, &next->client.secret),
|
ngx_quic_hkdf_set(&seq[3], "tls13 quic ku",
|
||||||
ngx_quic_hkdf_set("tls13 quic ku",
|
&next->server.secret, ¤t->server.secret);
|
||||||
&next->server.secret, ¤t->server.secret),
|
ngx_quic_hkdf_set(&seq[4], "tls13 quic key",
|
||||||
ngx_quic_hkdf_set("tls13 quic key",
|
&next->server.key, &next->server.secret);
|
||||||
&next->server.key, &next->server.secret),
|
ngx_quic_hkdf_set(&seq[5], "tls13 quic iv",
|
||||||
ngx_quic_hkdf_set("tls13 quic iv",
|
&next->server.iv, &next->server.secret);
|
||||||
&next->server.iv, &next->server.secret),
|
|
||||||
};
|
|
||||||
|
|
||||||
for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
|
for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
|
||||||
if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, c->log) != NGX_OK) {
|
if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, c->log) != NGX_OK) {
|
||||||
@@ -993,8 +988,9 @@ ngx_quic_decrypt(ngx_quic_header_t *pkt, uint64_t *largest_pn)
|
|||||||
u_char *p, *sample;
|
u_char *p, *sample;
|
||||||
size_t len;
|
size_t len;
|
||||||
uint64_t pn, lpn;
|
uint64_t pn, lpn;
|
||||||
ngx_int_t pnl, rc, key_phase;
|
ngx_int_t pnl, rc;
|
||||||
ngx_str_t in, ad;
|
ngx_str_t in, ad;
|
||||||
|
ngx_uint_t key_phase;
|
||||||
ngx_quic_secret_t *secret;
|
ngx_quic_secret_t *secret;
|
||||||
ngx_quic_ciphers_t ciphers;
|
ngx_quic_ciphers_t ciphers;
|
||||||
uint8_t nonce[NGX_QUIC_IV_LEN], mask[NGX_QUIC_HP_LEN];
|
uint8_t nonce[NGX_QUIC_IV_LEN], mask[NGX_QUIC_HP_LEN];
|
||||||
|
|||||||
@@ -39,19 +39,6 @@ static int ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn,
|
|||||||
static ngx_int_t ngx_quic_crypto_input(ngx_connection_t *c, ngx_chain_t *data);
|
static ngx_int_t ngx_quic_crypto_input(ngx_connection_t *c, ngx_chain_t *data);
|
||||||
|
|
||||||
|
|
||||||
static SSL_QUIC_METHOD quic_method = {
|
|
||||||
#if defined OPENSSL_IS_BORINGSSL || defined LIBRESSL_VERSION_NUMBER
|
|
||||||
.set_read_secret = ngx_quic_set_read_secret,
|
|
||||||
.set_write_secret = ngx_quic_set_write_secret,
|
|
||||||
#else
|
|
||||||
.set_encryption_secrets = ngx_quic_set_encryption_secrets,
|
|
||||||
#endif
|
|
||||||
.add_handshake_data = ngx_quic_add_handshake_data,
|
|
||||||
.flush_flight = ngx_quic_flush_flight,
|
|
||||||
.send_alert = ngx_quic_send_alert,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#if defined OPENSSL_IS_BORINGSSL || defined LIBRESSL_VERSION_NUMBER
|
#if defined OPENSSL_IS_BORINGSSL || defined LIBRESSL_VERSION_NUMBER
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -533,13 +520,14 @@ ngx_quic_crypto_input(ngx_connection_t *c, ngx_chain_t *data)
|
|||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_quic_init_connection(ngx_connection_t *c)
|
ngx_quic_init_connection(ngx_connection_t *c)
|
||||||
{
|
{
|
||||||
u_char *p;
|
u_char *p;
|
||||||
size_t clen;
|
size_t clen;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
ngx_str_t dcid;
|
ngx_str_t dcid;
|
||||||
ngx_ssl_conn_t *ssl_conn;
|
ngx_ssl_conn_t *ssl_conn;
|
||||||
ngx_quic_socket_t *qsock;
|
ngx_quic_socket_t *qsock;
|
||||||
ngx_quic_connection_t *qc;
|
ngx_quic_connection_t *qc;
|
||||||
|
static SSL_QUIC_METHOD quic_method;
|
||||||
|
|
||||||
qc = ngx_quic_get_connection(c);
|
qc = ngx_quic_get_connection(c);
|
||||||
|
|
||||||
@@ -551,6 +539,18 @@ ngx_quic_init_connection(ngx_connection_t *c)
|
|||||||
|
|
||||||
ssl_conn = c->ssl->connection;
|
ssl_conn = c->ssl->connection;
|
||||||
|
|
||||||
|
if (!quic_method.send_alert) {
|
||||||
|
#if defined OPENSSL_IS_BORINGSSL || defined LIBRESSL_VERSION_NUMBER
|
||||||
|
quic_method.set_read_secret = ngx_quic_set_read_secret;
|
||||||
|
quic_method.set_write_secret = ngx_quic_set_write_secret;
|
||||||
|
#else
|
||||||
|
quic_method.set_encryption_secrets = ngx_quic_set_encryption_secrets;
|
||||||
|
#endif
|
||||||
|
quic_method.add_handshake_data = ngx_quic_add_handshake_data;
|
||||||
|
quic_method.flush_flight = ngx_quic_flush_flight;
|
||||||
|
quic_method.send_alert = ngx_quic_send_alert;
|
||||||
|
}
|
||||||
|
|
||||||
if (SSL_set_quic_method(ssl_conn, &quic_method) == 0) {
|
if (SSL_set_quic_method(ssl_conn, &quic_method) == 0) {
|
||||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
"quic SSL_set_quic_method() failed");
|
"quic SSL_set_quic_method() failed");
|
||||||
|
|||||||
@@ -178,6 +178,10 @@ ngx_quic_validate_token(ngx_connection_t *c, u_char *key,
|
|||||||
u_char addr_hash[20];
|
u_char addr_hash[20];
|
||||||
u_char tdec[NGX_QUIC_MAX_TOKEN_SIZE];
|
u_char tdec[NGX_QUIC_MAX_TOKEN_SIZE];
|
||||||
|
|
||||||
|
#if NGX_SUPPRESS_WARN
|
||||||
|
ngx_str_null(&odcid);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Retry token or NEW_TOKEN in a previous connection */
|
/* Retry token or NEW_TOKEN in a previous connection */
|
||||||
|
|
||||||
cipher = EVP_aes_256_cbc();
|
cipher = EVP_aes_256_cbc();
|
||||||
|
|||||||
@@ -804,11 +804,23 @@ ngx_quic_parse_frame(ngx_quic_header_t *pkt, u_char *start, u_char *end,
|
|||||||
case NGX_QUIC_FT_ACK:
|
case NGX_QUIC_FT_ACK:
|
||||||
case NGX_QUIC_FT_ACK_ECN:
|
case NGX_QUIC_FT_ACK_ECN:
|
||||||
|
|
||||||
if (!((p = ngx_quic_parse_int(p, end, &f->u.ack.largest))
|
p = ngx_quic_parse_int(p, end, &f->u.ack.largest);
|
||||||
&& (p = ngx_quic_parse_int(p, end, &f->u.ack.delay))
|
if (p == NULL) {
|
||||||
&& (p = ngx_quic_parse_int(p, end, &f->u.ack.range_count))
|
goto error;
|
||||||
&& (p = ngx_quic_parse_int(p, end, &f->u.ack.first_range))))
|
}
|
||||||
{
|
|
||||||
|
p = ngx_quic_parse_int(p, end, &f->u.ack.delay);
|
||||||
|
if (p == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = ngx_quic_parse_int(p, end, &f->u.ack.range_count);
|
||||||
|
if (p == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = ngx_quic_parse_int(p, end, &f->u.ack.first_range);
|
||||||
|
if (p == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -818,10 +830,11 @@ ngx_quic_parse_frame(ngx_quic_header_t *pkt, u_char *start, u_char *end,
|
|||||||
for (i = 0; i < f->u.ack.range_count; i++) {
|
for (i = 0; i < f->u.ack.range_count; i++) {
|
||||||
|
|
||||||
p = ngx_quic_parse_int(p, end, &varint);
|
p = ngx_quic_parse_int(p, end, &varint);
|
||||||
if (p) {
|
if (p == NULL) {
|
||||||
p = ngx_quic_parse_int(p, end, &varint);
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p = ngx_quic_parse_int(p, end, &varint);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@@ -833,10 +846,18 @@ ngx_quic_parse_frame(ngx_quic_header_t *pkt, u_char *start, u_char *end,
|
|||||||
|
|
||||||
if (f->type == NGX_QUIC_FT_ACK_ECN) {
|
if (f->type == NGX_QUIC_FT_ACK_ECN) {
|
||||||
|
|
||||||
if (!((p = ngx_quic_parse_int(p, end, &f->u.ack.ect0))
|
p = ngx_quic_parse_int(p, end, &f->u.ack.ect0);
|
||||||
&& (p = ngx_quic_parse_int(p, end, &f->u.ack.ect1))
|
if (p == NULL) {
|
||||||
&& (p = ngx_quic_parse_int(p, end, &f->u.ack.ce))))
|
goto error;
|
||||||
{
|
}
|
||||||
|
|
||||||
|
p = ngx_quic_parse_int(p, end, &f->u.ack.ect1);
|
||||||
|
if (p == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = ngx_quic_parse_int(p, end, &f->u.ack.ce);
|
||||||
|
if (p == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -989,11 +1010,18 @@ ngx_quic_parse_frame(ngx_quic_header_t *pkt, u_char *start, u_char *end,
|
|||||||
|
|
||||||
case NGX_QUIC_FT_RESET_STREAM:
|
case NGX_QUIC_FT_RESET_STREAM:
|
||||||
|
|
||||||
if (!((p = ngx_quic_parse_int(p, end, &f->u.reset_stream.id))
|
p = ngx_quic_parse_int(p, end, &f->u.reset_stream.id);
|
||||||
&& (p = ngx_quic_parse_int(p, end, &f->u.reset_stream.error_code))
|
if (p == NULL) {
|
||||||
&& (p = ngx_quic_parse_int(p, end,
|
goto error;
|
||||||
&f->u.reset_stream.final_size))))
|
}
|
||||||
{
|
|
||||||
|
p = ngx_quic_parse_int(p, end, &f->u.reset_stream.error_code);
|
||||||
|
if (p == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = ngx_quic_parse_int(p, end, &f->u.reset_stream.final_size);
|
||||||
|
if (p == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#define NGX_WRITE_SHUTDOWN SD_SEND
|
#define NGX_WRITE_SHUTDOWN SD_SEND
|
||||||
|
#define NGX_READ_SHUTDOWN SD_RECEIVE
|
||||||
|
#define NGX_RDWR_SHUTDOWN SD_BOTH
|
||||||
|
|
||||||
|
|
||||||
typedef SOCKET ngx_socket_t;
|
typedef SOCKET ngx_socket_t;
|
||||||
|
|||||||
Reference in New Issue
Block a user