comparison src/event/quic/ngx_event_quic.c @ 8694: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 3956bbf91002
children 0b3d70fbba99
comparison
equal deleted inserted replaced
8693:3956bbf91002 8694:cef042935003
223 223
224 static ngx_quic_connection_t *ngx_quic_new_connection(ngx_connection_t *c, 224 static ngx_quic_connection_t *ngx_quic_new_connection(ngx_connection_t *c,
225 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); 225 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
226 static ngx_int_t ngx_quic_send_stateless_reset(ngx_connection_t *c, 226 static ngx_int_t ngx_quic_send_stateless_reset(ngx_connection_t *c,
227 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); 227 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
228 static ngx_int_t ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid,
229 u_char *secret, u_char *token);
228 static ngx_int_t ngx_quic_process_stateless_reset(ngx_connection_t *c, 230 static ngx_int_t ngx_quic_process_stateless_reset(ngx_connection_t *c,
229 ngx_quic_header_t *pkt); 231 ngx_quic_header_t *pkt);
230 static ngx_int_t ngx_quic_negotiate_version(ngx_connection_t *c, 232 static ngx_int_t ngx_quic_negotiate_version(ngx_connection_t *c,
231 ngx_quic_header_t *inpkt); 233 ngx_quic_header_t *inpkt);
232 static ngx_int_t ngx_quic_create_server_id(ngx_connection_t *c, u_char *id); 234 static ngx_int_t ngx_quic_create_server_id(ngx_connection_t *c, u_char *id);
1243 buf[0] &= ~NGX_QUIC_PKT_LONG; 1245 buf[0] &= ~NGX_QUIC_PKT_LONG;
1244 buf[0] |= NGX_QUIC_PKT_FIXED_BIT; 1246 buf[0] |= NGX_QUIC_PKT_FIXED_BIT;
1245 1247
1246 token = &buf[len - NGX_QUIC_SR_TOKEN_LEN]; 1248 token = &buf[len - NGX_QUIC_SR_TOKEN_LEN];
1247 1249
1248 if (ngx_quic_new_sr_token(c, &pkt->dcid, &conf->sr_token_key, token) 1250 if (ngx_quic_new_sr_token(c, &pkt->dcid, conf->sr_token_key, token)
1249 != NGX_OK) 1251 != NGX_OK)
1250 { 1252 {
1251 return NGX_ERROR; 1253 return NGX_ERROR;
1252 } 1254 }
1253 1255
1254 (void) ngx_quic_send(c, buf, len); 1256 (void) ngx_quic_send(c, buf, len);
1255 1257
1256 return NGX_DECLINED; 1258 return NGX_DECLINED;
1259 }
1260
1261
1262 static ngx_int_t
1263 ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid, u_char *secret,
1264 u_char *token)
1265 {
1266 ngx_str_t tmp;
1267
1268 tmp.data = secret;
1269 tmp.len = NGX_QUIC_SR_KEY_LEN;
1270
1271 if (ngx_quic_derive_key(c->log, "sr_token_key", &tmp, cid, token,
1272 NGX_QUIC_SR_TOKEN_LEN)
1273 != NGX_OK)
1274 {
1275 return NGX_ERROR;
1276 }
1277
1278 #if (NGX_DEBUG)
1279 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
1280 "quic stateless reset token %*xs",
1281 (size_t) NGX_QUIC_SR_TOKEN_LEN, token);
1282 #endif
1283
1284 return NGX_OK;
1257 } 1285 }
1258 1286
1259 1287
1260 static ngx_int_t 1288 static ngx_int_t
1261 ngx_quic_process_stateless_reset(ngx_connection_t *c, ngx_quic_header_t *pkt) 1289 ngx_quic_process_stateless_reset(ngx_connection_t *c, ngx_quic_header_t *pkt)
1389 ngx_quic_header_t pkt; 1417 ngx_quic_header_t pkt;
1390 1418
1391 u_char buf[NGX_QUIC_RETRY_BUFFER_SIZE]; 1419 u_char buf[NGX_QUIC_RETRY_BUFFER_SIZE];
1392 u_char dcid[NGX_QUIC_SERVER_CID_LEN]; 1420 u_char dcid[NGX_QUIC_SERVER_CID_LEN];
1393 1421
1394 expires = ngx_time() + NGX_QUIC_RETRY_LIFETIME; 1422 expires = ngx_time() + NGX_QUIC_RETRY_TOKEN_LIFETIME;
1395 1423
1396 if (ngx_quic_new_token(c, conf->token_key, &token, &inpkt->dcid, expires, 1) 1424 if (ngx_quic_new_token(c, conf->av_token_key, &token, &inpkt->dcid,
1425 expires, 1)
1397 != NGX_OK) 1426 != NGX_OK)
1398 { 1427 {
1399 return NGX_ERROR; 1428 return NGX_ERROR;
1400 } 1429 }
1401 1430
1721 if (SSL_CTX_get_max_early_data(qc->conf->ssl->ctx)) { 1750 if (SSL_CTX_get_max_early_data(qc->conf->ssl->ctx)) {
1722 SSL_set_quic_early_data_enabled(ssl_conn, 1); 1751 SSL_set_quic_early_data_enabled(ssl_conn, 1);
1723 } 1752 }
1724 #endif 1753 #endif
1725 1754
1726 if (ngx_quic_new_sr_token(c, &qc->dcid, &qc->conf->sr_token_key, 1755 if (ngx_quic_new_sr_token(c, &qc->dcid, qc->conf->sr_token_key,
1727 qc->tp.sr_token) 1756 qc->tp.sr_token)
1728 != NGX_OK) 1757 != NGX_OK)
1729 { 1758 {
1730 return NGX_ERROR; 1759 return NGX_ERROR;
1731 } 1760 }
2233 pkt->scid.len, &pkt->scid); 2262 pkt->scid.len, &pkt->scid);
2234 } 2263 }
2235 2264
2236 if (pkt->level == ssl_encryption_initial) { 2265 if (pkt->level == ssl_encryption_initial) {
2237 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 2266 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
2238 "quic token len:%uz %xV", 2267 "quic address validation token len:%uz %xV",
2239 pkt->token.len, &pkt->token); 2268 pkt->token.len, &pkt->token);
2240 } 2269 }
2241 #endif 2270 #endif
2242 2271
2243 qc = ngx_quic_get_connection(c); 2272 qc = ngx_quic_get_connection(c);
2304 2333
2305 /* process retry and initialize connection IDs */ 2334 /* process retry and initialize connection IDs */
2306 2335
2307 if (pkt->token.len) { 2336 if (pkt->token.len) {
2308 2337
2309 rc = ngx_quic_validate_token(c, conf->token_key, pkt); 2338 rc = ngx_quic_validate_token(c, conf->av_token_key, pkt);
2310 2339
2311 if (rc == NGX_ERROR) { 2340 if (rc == NGX_ERROR) {
2312 /* internal error */ 2341 /* internal error */
2313 return NGX_ERROR; 2342 return NGX_ERROR;
2314 2343
2319 "cannot decrypt token"); 2348 "cannot decrypt token");
2320 } else if (rc == NGX_DECLINED) { 2349 } else if (rc == NGX_DECLINED) {
2321 /* token is invalid */ 2350 /* token is invalid */
2322 2351
2323 if (pkt->retried) { 2352 if (pkt->retried) {
2324 /* invalid Retry token */ 2353 /* invalid address validation token */
2325 return ngx_quic_send_early_cc(c, pkt, 2354 return ngx_quic_send_early_cc(c, pkt,
2326 NGX_QUIC_ERR_INVALID_TOKEN, 2355 NGX_QUIC_ERR_INVALID_TOKEN,
2327 "invalid token"); 2356 "invalid address validation token");
2328 } else if (conf->retry) { 2357 } else if (conf->retry) {
2329 /* invalid NEW_TOKEN */ 2358 /* invalid NEW_TOKEN */
2330 return ngx_quic_send_retry(c, conf, pkt); 2359 return ngx_quic_send_retry(c, conf, pkt);
2331 } 2360 }
2332 } 2361 }
3284 return NGX_OK; 3313 return NGX_OK;
3285 } 3314 }
3286 3315
3287 expires = ngx_time() + NGX_QUIC_NEW_TOKEN_LIFETIME; 3316 expires = ngx_time() + NGX_QUIC_NEW_TOKEN_LIFETIME;
3288 3317
3289 if (ngx_quic_new_token(c, qc->conf->token_key, &token, NULL, expires, 0) 3318 if (ngx_quic_new_token(c, qc->conf->av_token_key, &token, NULL, expires, 0)
3290 != NGX_OK) 3319 != NGX_OK)
3291 { 3320 {
3292 return NGX_ERROR; 3321 return NGX_ERROR;
3293 } 3322 }
3294 3323
4665 frame->u.ncid.seqnum = sid->seqnum; 4694 frame->u.ncid.seqnum = sid->seqnum;
4666 frame->u.ncid.retire = 0; 4695 frame->u.ncid.retire = 0;
4667 frame->u.ncid.len = NGX_QUIC_SERVER_CID_LEN; 4696 frame->u.ncid.len = NGX_QUIC_SERVER_CID_LEN;
4668 ngx_memcpy(frame->u.ncid.cid, id, NGX_QUIC_SERVER_CID_LEN); 4697 ngx_memcpy(frame->u.ncid.cid, id, NGX_QUIC_SERVER_CID_LEN);
4669 4698
4670 if (ngx_quic_new_sr_token(c, &dcid, &qc->conf->sr_token_key, 4699 if (ngx_quic_new_sr_token(c, &dcid, qc->conf->sr_token_key,
4671 frame->u.ncid.srt) 4700 frame->u.ncid.srt)
4672 != NGX_OK) 4701 != NGX_OK)
4673 { 4702 {
4674 return NGX_ERROR; 4703 return NGX_ERROR;
4675 } 4704 }