mirror of
https://github.com/nginx/nginx.git
synced 2024-12-04 22:09:01 +08:00
Address validation using NEW_TOKEN frame.
This commit is contained in:
parent
ad2289e70e
commit
9b1800d09a
@ -187,6 +187,7 @@ static ngx_int_t ngx_quic_payload_handler(ngx_connection_t *c,
|
||||
static ngx_int_t ngx_quic_send_ack(ngx_connection_t *c, ngx_quic_header_t *pkt);
|
||||
static ngx_int_t ngx_quic_send_cc(ngx_connection_t *c,
|
||||
enum ssl_encryption_level_t level, ngx_uint_t err);
|
||||
static ngx_int_t ngx_quic_send_new_token(ngx_connection_t *c);
|
||||
|
||||
static ngx_int_t ngx_quic_handle_ack_frame(ngx_connection_t *c,
|
||||
ngx_quic_header_t *pkt, ngx_quic_ack_frame_t *f);
|
||||
@ -544,6 +545,7 @@ static ngx_int_t
|
||||
ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp,
|
||||
ngx_quic_header_t *pkt, ngx_connection_handler_pt handler)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t i;
|
||||
ngx_quic_tp_t *ctp;
|
||||
ngx_quic_secrets_t *keys;
|
||||
@ -642,7 +644,22 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp,
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (tp->retry) {
|
||||
if (pkt->token.len) {
|
||||
rc = ngx_quic_validate_token(c, pkt);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, 0, "quic invalid token");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, 0, "quic expired token");
|
||||
return ngx_quic_retry(c);
|
||||
}
|
||||
|
||||
/* NGX_OK */
|
||||
|
||||
} else if (tp->retry) {
|
||||
return ngx_quic_retry(c);
|
||||
}
|
||||
|
||||
@ -1950,6 +1967,35 @@ ngx_quic_send_cc(ngx_connection_t *c, enum ssl_encryption_level_t level,
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_quic_send_new_token(ngx_connection_t *c)
|
||||
{
|
||||
ngx_str_t token;
|
||||
ngx_quic_frame_t *frame;
|
||||
|
||||
if (!c->quic->tp.retry) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_quic_new_token(c, &token) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
frame = ngx_quic_alloc_frame(c, 0);
|
||||
if (frame == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
frame->level = ssl_encryption_application;
|
||||
frame->type = NGX_QUIC_FT_NEW_TOKEN;
|
||||
frame->u.token.length = token.len;
|
||||
frame->u.token.data = token.data;
|
||||
ngx_sprintf(frame->info, "NEW_TOKEN");
|
||||
ngx_quic_queue_frame(c->quic, frame);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
static ngx_int_t
|
||||
ngx_quic_handle_ack_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
|
||||
ngx_quic_ack_frame_t *ack)
|
||||
@ -2405,6 +2451,10 @@ ngx_quic_crypto_input(ngx_connection_t *c, ngx_quic_frame_t *frame, void *data)
|
||||
ngx_sprintf(frame->info, "HANDSHAKE DONE on handshake completed");
|
||||
ngx_quic_queue_frame(c->quic, frame);
|
||||
|
||||
if (ngx_quic_send_new_token(c) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generating next keys before a key update is received.
|
||||
* See quic-tls 9.4 Header Protection Timing Side-Channels.
|
||||
|
@ -72,6 +72,8 @@ static size_t ngx_quic_create_ack(u_char *p, ngx_quic_ack_frame_t *ack);
|
||||
static size_t ngx_quic_create_crypto(u_char *p,
|
||||
ngx_quic_crypto_frame_t *crypto);
|
||||
static size_t ngx_quic_create_hs_done(u_char *p);
|
||||
static size_t ngx_quic_create_new_token(u_char *p,
|
||||
ngx_quic_new_token_frame_t *token);
|
||||
static size_t ngx_quic_create_stream(u_char *p, ngx_quic_stream_frame_t *sf);
|
||||
static size_t ngx_quic_create_max_streams(u_char *p,
|
||||
ngx_quic_max_streams_frame_t *ms);
|
||||
@ -1128,6 +1130,9 @@ ngx_quic_create_frame(u_char *p, ngx_quic_frame_t *f)
|
||||
case NGX_QUIC_FT_HANDSHAKE_DONE:
|
||||
return ngx_quic_create_hs_done(p);
|
||||
|
||||
case NGX_QUIC_FT_NEW_TOKEN:
|
||||
return ngx_quic_create_new_token(p, &f->u.token);
|
||||
|
||||
case NGX_QUIC_FT_STREAM0:
|
||||
case NGX_QUIC_FT_STREAM1:
|
||||
case NGX_QUIC_FT_STREAM2:
|
||||
@ -1231,6 +1236,30 @@ ngx_quic_create_hs_done(u_char *p)
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
ngx_quic_create_new_token(u_char *p, ngx_quic_new_token_frame_t *token)
|
||||
{
|
||||
size_t len;
|
||||
u_char *start;
|
||||
|
||||
if (p == NULL) {
|
||||
len = ngx_quic_varint_len(NGX_QUIC_FT_NEW_TOKEN);
|
||||
len += ngx_quic_varint_len(token->length);
|
||||
len += token->length;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
start = p;
|
||||
|
||||
ngx_quic_build_int(&p, NGX_QUIC_FT_NEW_TOKEN);
|
||||
ngx_quic_build_int(&p, token->length);
|
||||
p = ngx_cpymem(p, token->data, token->length);
|
||||
|
||||
return p - start;
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
ngx_quic_create_stream(u_char *p, ngx_quic_stream_frame_t *sf)
|
||||
{
|
||||
|
@ -132,6 +132,11 @@ typedef struct {
|
||||
} ngx_quic_new_conn_id_frame_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint64_t length;
|
||||
u_char *data;
|
||||
} ngx_quic_new_token_frame_t;
|
||||
|
||||
/*
|
||||
* common layout for CRYPTO and STREAM frames;
|
||||
* conceptually, CRYPTO frame is also a stream
|
||||
@ -242,6 +247,7 @@ struct ngx_quic_frame_s {
|
||||
ngx_quic_crypto_frame_t crypto;
|
||||
ngx_quic_ordered_frame_t ord;
|
||||
ngx_quic_new_conn_id_frame_t ncid;
|
||||
ngx_quic_new_token_frame_t token;
|
||||
ngx_quic_stream_frame_t stream;
|
||||
ngx_quic_max_data_frame_t max_data;
|
||||
ngx_quic_close_frame_t close;
|
||||
|
Loading…
Reference in New Issue
Block a user