comparison src/event/ngx_event_quic.c @ 8319:29354c6fc5f2 quic

TLS Key Update in QUIC. Old keys retention is yet to be implemented.
author Sergey Kandaurov <pluknet@nginx.com>
date Mon, 06 Apr 2020 14:54:08 +0300
parents 0dc0552335bd
children 6e1213ef469a
comparison
equal deleted inserted replaced
8318:1bb5e8538d0c 8319:29354c6fc5f2
66 66
67 ngx_quic_state_t state; 67 ngx_quic_state_t state;
68 68
69 ngx_quic_namespace_t ns[NGX_QUIC_NAMESPACE_LAST]; 69 ngx_quic_namespace_t ns[NGX_QUIC_NAMESPACE_LAST];
70 ngx_quic_secrets_t keys[NGX_QUIC_ENCRYPTION_LAST]; 70 ngx_quic_secrets_t keys[NGX_QUIC_ENCRYPTION_LAST];
71 ngx_quic_secrets_t next_key;
71 uint64_t crypto_offset[NGX_QUIC_ENCRYPTION_LAST]; 72 uint64_t crypto_offset[NGX_QUIC_ENCRYPTION_LAST];
72 73
73 ngx_ssl_t *ssl; 74 ngx_ssl_t *ssl;
74 75
75 ngx_event_t push; 76 ngx_event_t push;
86 uint64_t cur_streams; 87 uint64_t cur_streams;
87 uint64_t max_streams; 88 uint64_t max_streams;
88 89
89 unsigned send_timer_set:1; 90 unsigned send_timer_set:1;
90 unsigned closing:1; 91 unsigned closing:1;
92 unsigned key_phase:1;
91 }; 93 };
92 94
93 95
94 #if BORINGSSL_API_VERSION >= 10 96 #if BORINGSSL_API_VERSION >= 10
95 static int ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn, 97 static int ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn,
977 979
978 980
979 static ngx_int_t 981 static ngx_int_t
980 ngx_quic_app_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 982 ngx_quic_app_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
981 { 983 {
982 ngx_quic_secrets_t *keys; 984 ngx_int_t rc;
985 ngx_quic_secrets_t *keys, *next, tmp;
983 ngx_quic_connection_t *qc; 986 ngx_quic_connection_t *qc;
984 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; 987 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
985 988
986 c->log->action = "processing application data quic packet"; 989 c->log->action = "processing application data quic packet";
987 990
988 qc = c->quic; 991 qc = c->quic;
989 992
990 keys = &c->quic->keys[ssl_encryption_application]; 993 keys = &c->quic->keys[ssl_encryption_application];
994 next = &c->quic->next_key;
991 995
992 if (keys->client.key.len == 0) { 996 if (keys->client.key.len == 0) {
993 ngx_log_error(NGX_LOG_INFO, c->log, 0, 997 ngx_log_error(NGX_LOG_INFO, c->log, 0,
994 "no read keys yet, packet ignored"); 998 "no read keys yet, packet ignored");
995 return NGX_DECLINED; 999 return NGX_DECLINED;
998 if (ngx_quic_parse_short_header(pkt, &qc->dcid) != NGX_OK) { 1002 if (ngx_quic_parse_short_header(pkt, &qc->dcid) != NGX_OK) {
999 return NGX_ERROR; 1003 return NGX_ERROR;
1000 } 1004 }
1001 1005
1002 pkt->secret = &keys->client; 1006 pkt->secret = &keys->client;
1007 pkt->next = &next->client;
1008 pkt->key_phase = c->quic->key_phase;
1003 pkt->level = ssl_encryption_application; 1009 pkt->level = ssl_encryption_application;
1004 pkt->plaintext = buf; 1010 pkt->plaintext = buf;
1005 1011
1006 if (ngx_quic_decrypt(pkt, c->ssl->connection) != NGX_OK) { 1012 if (ngx_quic_decrypt(pkt, c->ssl->connection) != NGX_OK) {
1007 return NGX_ERROR; 1013 return NGX_ERROR;
1008 } 1014 }
1009 1015
1010 return ngx_quic_payload_handler(c, pkt); 1016 /* switch keys on Key Phase change */
1017
1018 if (pkt->key_update) {
1019 c->quic->key_phase ^= 1;
1020
1021 tmp = *keys;
1022 *keys = *next;
1023 *next = tmp;
1024 }
1025
1026 rc = ngx_quic_payload_handler(c, pkt);
1027
1028 if (rc == NGX_ERROR) {
1029 return NGX_ERROR;
1030 }
1031
1032 /* generate next keys */
1033
1034 if (pkt->key_update) {
1035 if (ngx_quic_key_update(c, keys, next) != NGX_OK) {
1036 return NGX_ERROR;
1037 }
1038 }
1039
1040 return rc;
1011 } 1041 }
1012 1042
1013 1043
1014 static ngx_int_t 1044 static ngx_int_t
1015 ngx_quic_payload_handler(ngx_connection_t *c, ngx_quic_header_t *pkt) 1045 ngx_quic_payload_handler(ngx_connection_t *c, ngx_quic_header_t *pkt)
1328 frame->type = NGX_QUIC_FT_HANDSHAKE_DONE; 1358 frame->type = NGX_QUIC_FT_HANDSHAKE_DONE;
1329 ngx_sprintf(frame->info, "HANDSHAKE DONE on handshake completed"); 1359 ngx_sprintf(frame->info, "HANDSHAKE DONE on handshake completed");
1330 ngx_quic_queue_frame(c->quic, frame); 1360 ngx_quic_queue_frame(c->quic, frame);
1331 } 1361 }
1332 #endif 1362 #endif
1363
1364 /*
1365 * Generating next keys before a key update is received.
1366 * See quic-tls 9.4 Header Protection Timing Side-Channels.
1367 */
1368
1369 if (ngx_quic_key_update(c, &c->quic->keys[ssl_encryption_application],
1370 &c->quic->next_key)
1371 != NGX_OK)
1372 {
1373 return NGX_ERROR;
1374 }
1333 } 1375 }
1334 1376
1335 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 1377 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
1336 "SSL_quic_read_level: %d, SSL_quic_write_level: %d", 1378 "SSL_quic_read_level: %d, SSL_quic_write_level: %d",
1337 (int) SSL_quic_read_level(ssl_conn), 1379 (int) SSL_quic_read_level(ssl_conn),
1754 1796
1755 } else if (start->level == ssl_encryption_handshake) { 1797 } else if (start->level == ssl_encryption_handshake) {
1756 pkt.flags = NGX_QUIC_PKT_HANDSHAKE; 1798 pkt.flags = NGX_QUIC_PKT_HANDSHAKE;
1757 1799
1758 } else { 1800 } else {
1759 pkt.flags = 0x40; // TODO: macro, set FIXED bit 1801 // TODO: macro, set FIXED bit
1802 pkt.flags = 0x40 | (c->quic->key_phase ? NGX_QUIC_PKT_KPHASE : 0);
1760 } 1803 }
1761 1804
1762 ngx_quic_set_packet_number(&pkt, ns); 1805 ngx_quic_set_packet_number(&pkt, ns);
1763 1806
1764 pkt.log = c->log; 1807 pkt.log = c->log;