ngx_uint_t handshake_pn;
ngx_uint_t appdata_pn;
- ngx_quic_secrets_t secrets;
+ ngx_quic_secrets_t keys[NGX_QUIC_ENCRYPTION_LAST];
+ uint64_t crypto_offset[NGX_QUIC_ENCRYPTION_LAST];
+
ngx_ssl_t *ssl;
ngx_quic_frame_t *frames;
ngx_quic_frame_t *free_frames;
unsigned send_timer_set:1;
unsigned closing:1;
-
-#define SSL_ECRYPTION_LAST ((ssl_encryption_application) + 1)
- uint64_t crypto_offset[SSL_ECRYPTION_LAST];
};
enum ssl_encryption_level_t level, const SSL_CIPHER *cipher,
const uint8_t *rsecret, size_t secret_len)
{
- ngx_connection_t *c;
+ ngx_connection_t *c;
+ ngx_quic_secrets_t *keys;
c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
ngx_quic_hexdump(c->log, "level:%d read secret",
rsecret, secret_len, level);
+ keys = &c->quic->keys[level];
+
if (level == ssl_encryption_early_data) {
c->quic->state = NGX_QUIC_ST_EARLY_DATA;
}
return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level,
rsecret, secret_len,
- &c->quic->secrets.client);
+ &keys->client);
}
enum ssl_encryption_level_t level, const SSL_CIPHER *cipher,
const uint8_t *wsecret, size_t secret_len)
{
- ngx_connection_t *c;
+ ngx_connection_t *c;
+ ngx_quic_secrets_t *keys;
c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
ngx_quic_hexdump(c->log, "level:%d write secret",
wsecret, secret_len, level);
+ keys = &c->quic->keys[level];
+
return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level,
wsecret, secret_len,
- &c->quic->secrets.server);
+ &keys->server);
}
#else
enum ssl_encryption_level_t level, const uint8_t *rsecret,
const uint8_t *wsecret, size_t secret_len)
{
- ngx_int_t rc;
- ngx_connection_t *c;
+ ngx_int_t rc;
+ ngx_connection_t *c;
+ ngx_quic_secrets_t *keys;
c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
ngx_quic_hexdump(c->log, "level:%d read", rsecret, secret_len, level);
+ keys = &c->quic->secrets[level];
+
rc = ngx_quic_set_encryption_secret(c->pool, ssl_conn, level,
rsecret, secret_len,
- &c->quic->secrets.client);
+ &keys->client);
if (rc != 1) {
return rc;
}
return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level,
wsecret, secret_len,
- &c->quic->secrets.server);
+ &keys->server);
}
#endif
ngx_quic_header_t *pkt, ngx_connection_handler_pt handler)
{
ngx_quic_tp_t *ctp;
+ ngx_quic_secrets_t *keys;
ngx_quic_connection_t *qc;
static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
}
ngx_memcpy(qc->token.data, pkt->token.data, qc->token.len);
+ keys = &c->quic->keys[ssl_encryption_initial];
- if (ngx_quic_set_initial_secret(c->pool, &qc->secrets, &qc->dcid)
+ if (ngx_quic_set_initial_secret(c->pool, &keys->client, &keys->server,
+ &qc->dcid)
!= NGX_OK)
{
return NGX_ERROR;
}
- pkt->secret = &qc->secrets.client.in;
+ pkt->secret = &keys->client;
pkt->level = ssl_encryption_initial;
pkt->plaintext = buf;
static ngx_int_t
ngx_quic_initial_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
{
- ngx_ssl_conn_t *ssl_conn;
- ngx_quic_connection_t *qc;
- static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
+ ngx_ssl_conn_t *ssl_conn;
+ ngx_quic_secrets_t *keys;
+ static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
c->log->action = "processing initial quic packet";
- qc = c->quic;
ssl_conn = c->ssl->connection;
if (ngx_quic_parse_long_header(pkt) != NGX_OK) {
return NGX_ERROR;
}
- pkt->secret = &qc->secrets.client.in;
+ keys = &c->quic->keys[ssl_encryption_initial];
+
+ pkt->secret = &keys->client;
pkt->level = ssl_encryption_initial;
pkt->plaintext = buf;
static ngx_int_t
ngx_quic_handshake_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
{
+ ngx_quic_secrets_t *keys;
ngx_quic_connection_t *qc;
static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
return NGX_ERROR;
}
- pkt->secret = &qc->secrets.client.hs;
+ keys = &c->quic->keys[ssl_encryption_handshake];
+
+ pkt->secret = &keys->client;
pkt->level = ssl_encryption_handshake;
pkt->plaintext = buf;
static ngx_int_t
ngx_quic_early_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
{
+ ngx_quic_secrets_t *keys;
ngx_quic_connection_t *qc;
static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
return NGX_OK;
}
- pkt->secret = &qc->secrets.client.ed;
+ keys = &c->quic->keys[ssl_encryption_early_data];
+
+ pkt->secret = &keys->client;
pkt->level = ssl_encryption_early_data;
pkt->plaintext = buf;
static ngx_int_t
ngx_quic_app_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
{
+ ngx_quic_secrets_t *keys;
ngx_quic_connection_t *qc;
static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
qc = c->quic;
- if (qc->secrets.client.ad.key.len == 0) {
+ keys = &c->quic->keys[ssl_encryption_application];
+
+ if (keys->client.key.len == 0) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"no read keys yet, packet ignored");
return NGX_DECLINED;
return NGX_ERROR;
}
- pkt->secret = &qc->secrets.client.ad;
+ pkt->secret = &keys->client;
pkt->level = ssl_encryption_application;
pkt->plaintext = buf;
return NGX_ERROR;
}
- ack_frame->level = (pkt->level == ssl_encryption_early_data)
- ? ssl_encryption_application
- : pkt->level;
+ ack_frame->level = pkt->level;
ack_frame->type = NGX_QUIC_FT_ACK;
ack_frame->u.ack.pn = pkt->pn;
ngx_str_t out, res;
ngx_quic_frame_t *f;
ngx_quic_header_t pkt;
+ ngx_quic_secrets_t *keys;
ngx_quic_connection_t *qc;
static ngx_str_t initial_token = ngx_null_string;
static u_char src[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
qc = c->quic;
+ keys = &c->quic->keys[start->level];
+
+ pkt.secret = &keys->server;
+
if (start->level == ssl_encryption_initial) {
pkt.number = &qc->initial_pn;
pkt.flags = NGX_QUIC_PKT_INITIAL;
- pkt.secret = &qc->secrets.server.in;
pkt.token = initial_token;
} else if (start->level == ssl_encryption_handshake) {
pkt.number = &qc->handshake_pn;
pkt.flags = NGX_QUIC_PKT_HANDSHAKE;
- pkt.secret = &qc->secrets.server.hs;
} else {
pkt.number = &qc->appdata_pn;
- pkt.secret = &qc->secrets.server.ad;
}
pkt.log = c->log;
ngx_int_t
-ngx_quic_set_initial_secret(ngx_pool_t *pool, ngx_quic_secrets_t *qsec,
- ngx_str_t *secret)
+ngx_quic_set_initial_secret(ngx_pool_t *pool, ngx_quic_secret_t *client,
+ ngx_quic_secret_t *server, ngx_str_t *secret)
{
size_t is_len;
uint8_t is[SHA256_DIGEST_LENGTH];
ngx_quic_hexdump0(pool->log, "initial secret", is, is_len);
/* draft-ietf-quic-tls-23#section-5.2 */
- qsec->client.in.secret.len = SHA256_DIGEST_LENGTH;
- qsec->server.in.secret.len = SHA256_DIGEST_LENGTH;
+ client->secret.len = SHA256_DIGEST_LENGTH;
+ server->secret.len = SHA256_DIGEST_LENGTH;
- qsec->client.in.key.len = EVP_CIPHER_key_length(cipher);
- qsec->server.in.key.len = EVP_CIPHER_key_length(cipher);
+ client->key.len = EVP_CIPHER_key_length(cipher);
+ server->key.len = EVP_CIPHER_key_length(cipher);
- qsec->client.in.hp.len = EVP_CIPHER_key_length(cipher);
- qsec->server.in.hp.len = EVP_CIPHER_key_length(cipher);
+ client->hp.len = EVP_CIPHER_key_length(cipher);
+ server->hp.len = EVP_CIPHER_key_length(cipher);
- qsec->client.in.iv.len = EVP_CIPHER_iv_length(cipher);
- qsec->server.in.iv.len = EVP_CIPHER_iv_length(cipher);
+ client->iv.len = EVP_CIPHER_iv_length(cipher);
+ server->iv.len = EVP_CIPHER_iv_length(cipher);
struct {
ngx_str_t label;
} seq[] = {
/* draft-ietf-quic-tls-23#section-5.2 */
- { ngx_string("tls13 client in"), &qsec->client.in.secret, &iss },
+ { ngx_string("tls13 client in"), &client->secret, &iss },
{
ngx_string("tls13 quic key"),
- &qsec->client.in.key,
- &qsec->client.in.secret,
+ &client->key,
+ &client->secret,
},
{
ngx_string("tls13 quic iv"),
- &qsec->client.in.iv,
- &qsec->client.in.secret,
+ &client->iv,
+ &client->secret,
},
{
/* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */
ngx_string("tls13 quic hp"),
- &qsec->client.in.hp,
- &qsec->client.in.secret,
+ &client->hp,
+ &client->secret,
},
- { ngx_string("tls13 server in"), &qsec->server.in.secret, &iss },
+ { ngx_string("tls13 server in"), &server->secret, &iss },
{
/* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.3 */
ngx_string("tls13 quic key"),
- &qsec->server.in.key,
- &qsec->server.in.secret,
+ &server->key,
+ &server->secret,
},
{
ngx_string("tls13 quic iv"),
- &qsec->server.in.iv,
- &qsec->server.in.secret,
+ &server->iv,
+ &server->secret,
},
{
/* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */
ngx_string("tls13 quic hp"),
- &qsec->server.in.hp,
- &qsec->server.in.secret,
+ &server->hp,
+ &server->secret,
},
};
int
ngx_quic_set_encryption_secret(ngx_pool_t *pool, ngx_ssl_conn_t *ssl_conn,
enum ssl_encryption_level_t level, const uint8_t *secret,
- size_t secret_len, ngx_quic_peer_secrets_t *qsec)
+ size_t secret_len, ngx_quic_secret_t *peer_secret)
{
- ngx_int_t key_len;
- ngx_uint_t i;
- ngx_quic_secret_t *peer_secret;
- ngx_quic_ciphers_t ciphers;
+ ngx_int_t key_len;
+ ngx_uint_t i;
+ ngx_quic_ciphers_t ciphers;
key_len = ngx_quic_ciphers(ssl_conn, &ciphers, level);
return 0;
}
- switch (level) {
-
- case ssl_encryption_early_data:
- peer_secret = &qsec->ed;
- break;
-
- case ssl_encryption_handshake:
- peer_secret = &qsec->hs;
- break;
-
- case ssl_encryption_application:
- peer_secret = &qsec->ad;
- break;
-
- default:
+ if (level == ssl_encryption_initial) {
return 0;
}