comparison src/event/ngx_event_quic.c @ 8306:058a5af7ddfc quic

Refactored QUIC secrets storage. The quic->keys[4] array now contains secrets related to the corresponding encryption level. All protection-level functions get proper keys and do not need to switch manually between levels.
author Vladimir Homutov <vl@nginx.com>
date Wed, 01 Apr 2020 14:25:25 +0300
parents e35f824f644d
children dc7ac778aafe
comparison
equal deleted inserted replaced
8305:e35f824f644d 8306:058a5af7ddfc
40 /* current packet numbers for each namespace */ 40 /* current packet numbers for each namespace */
41 ngx_uint_t initial_pn; 41 ngx_uint_t initial_pn;
42 ngx_uint_t handshake_pn; 42 ngx_uint_t handshake_pn;
43 ngx_uint_t appdata_pn; 43 ngx_uint_t appdata_pn;
44 44
45 ngx_quic_secrets_t secrets; 45 ngx_quic_secrets_t keys[NGX_QUIC_ENCRYPTION_LAST];
46 uint64_t crypto_offset[NGX_QUIC_ENCRYPTION_LAST];
47
46 ngx_ssl_t *ssl; 48 ngx_ssl_t *ssl;
47 ngx_quic_frame_t *frames; 49 ngx_quic_frame_t *frames;
48 ngx_quic_frame_t *free_frames; 50 ngx_quic_frame_t *free_frames;
49 51
50 #if (NGX_DEBUG) 52 #if (NGX_DEBUG)
54 ngx_quic_streams_t streams; 56 ngx_quic_streams_t streams;
55 ngx_uint_t max_data; 57 ngx_uint_t max_data;
56 58
57 unsigned send_timer_set:1; 59 unsigned send_timer_set:1;
58 unsigned closing:1; 60 unsigned closing:1;
59
60 #define SSL_ECRYPTION_LAST ((ssl_encryption_application) + 1)
61 uint64_t crypto_offset[SSL_ECRYPTION_LAST];
62 }; 61 };
63 62
64 63
65 #if BORINGSSL_API_VERSION >= 10 64 #if BORINGSSL_API_VERSION >= 10
66 static int ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn, 65 static int ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn,
154 static int 153 static int
155 ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn, 154 ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn,
156 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, 155 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher,
157 const uint8_t *rsecret, size_t secret_len) 156 const uint8_t *rsecret, size_t secret_len)
158 { 157 {
159 ngx_connection_t *c; 158 ngx_connection_t *c;
159 ngx_quic_secrets_t *keys;
160 160
161 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); 161 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
162 162
163 ngx_quic_hexdump(c->log, "level:%d read secret", 163 ngx_quic_hexdump(c->log, "level:%d read secret",
164 rsecret, secret_len, level); 164 rsecret, secret_len, level);
165 165
166 keys = &c->quic->keys[level];
167
166 if (level == ssl_encryption_early_data) { 168 if (level == ssl_encryption_early_data) {
167 c->quic->state = NGX_QUIC_ST_EARLY_DATA; 169 c->quic->state = NGX_QUIC_ST_EARLY_DATA;
168 } 170 }
169 171
170 return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level, 172 return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level,
171 rsecret, secret_len, 173 rsecret, secret_len,
172 &c->quic->secrets.client); 174 &keys->client);
173 } 175 }
174 176
175 177
176 static int 178 static int
177 ngx_quic_set_write_secret(ngx_ssl_conn_t *ssl_conn, 179 ngx_quic_set_write_secret(ngx_ssl_conn_t *ssl_conn,
178 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, 180 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher,
179 const uint8_t *wsecret, size_t secret_len) 181 const uint8_t *wsecret, size_t secret_len)
180 { 182 {
181 ngx_connection_t *c; 183 ngx_connection_t *c;
184 ngx_quic_secrets_t *keys;
182 185
183 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); 186 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
184 187
185 ngx_quic_hexdump(c->log, "level:%d write secret", 188 ngx_quic_hexdump(c->log, "level:%d write secret",
186 wsecret, secret_len, level); 189 wsecret, secret_len, level);
187 190
191 keys = &c->quic->keys[level];
192
188 return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level, 193 return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level,
189 wsecret, secret_len, 194 wsecret, secret_len,
190 &c->quic->secrets.server); 195 &keys->server);
191 } 196 }
192 197
193 #else 198 #else
194 199
195 static int 200 static int
196 ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, 201 ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn,
197 enum ssl_encryption_level_t level, const uint8_t *rsecret, 202 enum ssl_encryption_level_t level, const uint8_t *rsecret,
198 const uint8_t *wsecret, size_t secret_len) 203 const uint8_t *wsecret, size_t secret_len)
199 { 204 {
200 ngx_int_t rc; 205 ngx_int_t rc;
201 ngx_connection_t *c; 206 ngx_connection_t *c;
207 ngx_quic_secrets_t *keys;
202 208
203 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); 209 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
204 210
205 ngx_quic_hexdump(c->log, "level:%d read", rsecret, secret_len, level); 211 ngx_quic_hexdump(c->log, "level:%d read", rsecret, secret_len, level);
212
213 keys = &c->quic->secrets[level];
206 214
207 rc = ngx_quic_set_encryption_secret(c->pool, ssl_conn, level, 215 rc = ngx_quic_set_encryption_secret(c->pool, ssl_conn, level,
208 rsecret, secret_len, 216 rsecret, secret_len,
209 &c->quic->secrets.client); 217 &keys->client);
210 if (rc != 1) { 218 if (rc != 1) {
211 return rc; 219 return rc;
212 } 220 }
213 221
214 if (level == ssl_encryption_early_data) { 222 if (level == ssl_encryption_early_data) {
218 226
219 ngx_quic_hexdump(c->log, "level:%d write", wsecret, secret_len, level); 227 ngx_quic_hexdump(c->log, "level:%d write", wsecret, secret_len, level);
220 228
221 return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level, 229 return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level,
222 wsecret, secret_len, 230 wsecret, secret_len,
223 &c->quic->secrets.server); 231 &keys->server);
224 } 232 }
225 233
226 #endif 234 #endif
227 235
228 236
378 static ngx_int_t 386 static ngx_int_t
379 ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp, 387 ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_quic_tp_t *tp,
380 ngx_quic_header_t *pkt, ngx_connection_handler_pt handler) 388 ngx_quic_header_t *pkt, ngx_connection_handler_pt handler)
381 { 389 {
382 ngx_quic_tp_t *ctp; 390 ngx_quic_tp_t *ctp;
391 ngx_quic_secrets_t *keys;
383 ngx_quic_connection_t *qc; 392 ngx_quic_connection_t *qc;
384 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; 393 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
385 394
386 if (ngx_buf_size(pkt->raw) < 1200) { 395 if (ngx_buf_size(pkt->raw) < 1200) {
387 ngx_log_error(NGX_LOG_INFO, c->log, 0, "too small UDP datagram"); 396 ngx_log_error(NGX_LOG_INFO, c->log, 0, "too small UDP datagram");
443 if (qc->token.data == NULL) { 452 if (qc->token.data == NULL) {
444 return NGX_ERROR; 453 return NGX_ERROR;
445 } 454 }
446 ngx_memcpy(qc->token.data, pkt->token.data, qc->token.len); 455 ngx_memcpy(qc->token.data, pkt->token.data, qc->token.len);
447 456
448 457 keys = &c->quic->keys[ssl_encryption_initial];
449 if (ngx_quic_set_initial_secret(c->pool, &qc->secrets, &qc->dcid) 458
459 if (ngx_quic_set_initial_secret(c->pool, &keys->client, &keys->server,
460 &qc->dcid)
450 != NGX_OK) 461 != NGX_OK)
451 { 462 {
452 return NGX_ERROR; 463 return NGX_ERROR;
453 } 464 }
454 465
455 pkt->secret = &qc->secrets.client.in; 466 pkt->secret = &keys->client;
456 pkt->level = ssl_encryption_initial; 467 pkt->level = ssl_encryption_initial;
457 pkt->plaintext = buf; 468 pkt->plaintext = buf;
458 469
459 if (ngx_quic_decrypt(pkt, NULL) != NGX_OK) { 470 if (ngx_quic_decrypt(pkt, NULL) != NGX_OK) {
460 return NGX_ERROR; 471 return NGX_ERROR;
741 752
742 753
743 static ngx_int_t 754 static ngx_int_t
744 ngx_quic_initial_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 755 ngx_quic_initial_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
745 { 756 {
746 ngx_ssl_conn_t *ssl_conn; 757 ngx_ssl_conn_t *ssl_conn;
747 ngx_quic_connection_t *qc; 758 ngx_quic_secrets_t *keys;
748 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; 759 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
749 760
750 c->log->action = "processing initial quic packet"; 761 c->log->action = "processing initial quic packet";
751 762
752 qc = c->quic;
753 ssl_conn = c->ssl->connection; 763 ssl_conn = c->ssl->connection;
754 764
755 if (ngx_quic_parse_long_header(pkt) != NGX_OK) { 765 if (ngx_quic_parse_long_header(pkt) != NGX_OK) {
756 return NGX_ERROR; 766 return NGX_ERROR;
757 } 767 }
758 768
759 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) { 769 if (ngx_quic_parse_initial_header(pkt) != NGX_OK) {
760 return NGX_ERROR; 770 return NGX_ERROR;
761 } 771 }
762 772
763 pkt->secret = &qc->secrets.client.in; 773 keys = &c->quic->keys[ssl_encryption_initial];
774
775 pkt->secret = &keys->client;
764 pkt->level = ssl_encryption_initial; 776 pkt->level = ssl_encryption_initial;
765 pkt->plaintext = buf; 777 pkt->plaintext = buf;
766 778
767 if (ngx_quic_decrypt(pkt, ssl_conn) != NGX_OK) { 779 if (ngx_quic_decrypt(pkt, ssl_conn) != NGX_OK) {
768 return NGX_ERROR; 780 return NGX_ERROR;
773 785
774 786
775 static ngx_int_t 787 static ngx_int_t
776 ngx_quic_handshake_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 788 ngx_quic_handshake_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
777 { 789 {
790 ngx_quic_secrets_t *keys;
778 ngx_quic_connection_t *qc; 791 ngx_quic_connection_t *qc;
779 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; 792 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
780 793
781 c->log->action = "processing handshake quic packet"; 794 c->log->action = "processing handshake quic packet";
782 795
815 828
816 if (ngx_quic_parse_handshake_header(pkt) != NGX_OK) { 829 if (ngx_quic_parse_handshake_header(pkt) != NGX_OK) {
817 return NGX_ERROR; 830 return NGX_ERROR;
818 } 831 }
819 832
820 pkt->secret = &qc->secrets.client.hs; 833 keys = &c->quic->keys[ssl_encryption_handshake];
834
835 pkt->secret = &keys->client;
821 pkt->level = ssl_encryption_handshake; 836 pkt->level = ssl_encryption_handshake;
822 pkt->plaintext = buf; 837 pkt->plaintext = buf;
823 838
824 if (ngx_quic_decrypt(pkt, c->ssl->connection) != NGX_OK) { 839 if (ngx_quic_decrypt(pkt, c->ssl->connection) != NGX_OK) {
825 return NGX_ERROR; 840 return NGX_ERROR;
830 845
831 846
832 static ngx_int_t 847 static ngx_int_t
833 ngx_quic_early_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 848 ngx_quic_early_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
834 { 849 {
850 ngx_quic_secrets_t *keys;
835 ngx_quic_connection_t *qc; 851 ngx_quic_connection_t *qc;
836 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; 852 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
837 853
838 c->log->action = "processing early data quic packet"; 854 c->log->action = "processing early data quic packet";
839 855
877 if (c->quic->state != NGX_QUIC_ST_EARLY_DATA) { 893 if (c->quic->state != NGX_QUIC_ST_EARLY_DATA) {
878 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unexpected 0-RTT packet"); 894 ngx_log_error(NGX_LOG_INFO, c->log, 0, "unexpected 0-RTT packet");
879 return NGX_OK; 895 return NGX_OK;
880 } 896 }
881 897
882 pkt->secret = &qc->secrets.client.ed; 898 keys = &c->quic->keys[ssl_encryption_early_data];
899
900 pkt->secret = &keys->client;
883 pkt->level = ssl_encryption_early_data; 901 pkt->level = ssl_encryption_early_data;
884 pkt->plaintext = buf; 902 pkt->plaintext = buf;
885 903
886 if (ngx_quic_decrypt(pkt, c->ssl->connection) != NGX_OK) { 904 if (ngx_quic_decrypt(pkt, c->ssl->connection) != NGX_OK) {
887 return NGX_ERROR; 905 return NGX_ERROR;
892 910
893 911
894 static ngx_int_t 912 static ngx_int_t
895 ngx_quic_app_input(ngx_connection_t *c, ngx_quic_header_t *pkt) 913 ngx_quic_app_input(ngx_connection_t *c, ngx_quic_header_t *pkt)
896 { 914 {
915 ngx_quic_secrets_t *keys;
897 ngx_quic_connection_t *qc; 916 ngx_quic_connection_t *qc;
898 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; 917 static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
899 918
900 c->log->action = "processing application data quic packet"; 919 c->log->action = "processing application data quic packet";
901 920
902 qc = c->quic; 921 qc = c->quic;
903 922
904 if (qc->secrets.client.ad.key.len == 0) { 923 keys = &c->quic->keys[ssl_encryption_application];
924
925 if (keys->client.key.len == 0) {
905 ngx_log_error(NGX_LOG_INFO, c->log, 0, 926 ngx_log_error(NGX_LOG_INFO, c->log, 0,
906 "no read keys yet, packet ignored"); 927 "no read keys yet, packet ignored");
907 return NGX_DECLINED; 928 return NGX_DECLINED;
908 } 929 }
909 930
910 if (ngx_quic_parse_short_header(pkt, &qc->dcid) != NGX_OK) { 931 if (ngx_quic_parse_short_header(pkt, &qc->dcid) != NGX_OK) {
911 return NGX_ERROR; 932 return NGX_ERROR;
912 } 933 }
913 934
914 pkt->secret = &qc->secrets.client.ad; 935 pkt->secret = &keys->client;
915 pkt->level = ssl_encryption_application; 936 pkt->level = ssl_encryption_application;
916 pkt->plaintext = buf; 937 pkt->plaintext = buf;
917 938
918 if (ngx_quic_decrypt(pkt, c->ssl->connection) != NGX_OK) { 939 if (ngx_quic_decrypt(pkt, c->ssl->connection) != NGX_OK) {
919 return NGX_ERROR; 940 return NGX_ERROR;
1083 ack_frame = ngx_quic_alloc_frame(c, 0); 1104 ack_frame = ngx_quic_alloc_frame(c, 0);
1084 if (ack_frame == NULL) { 1105 if (ack_frame == NULL) {
1085 return NGX_ERROR; 1106 return NGX_ERROR;
1086 } 1107 }
1087 1108
1088 ack_frame->level = (pkt->level == ssl_encryption_early_data) 1109 ack_frame->level = pkt->level;
1089 ? ssl_encryption_application
1090 : pkt->level;
1091 ack_frame->type = NGX_QUIC_FT_ACK; 1110 ack_frame->type = NGX_QUIC_FT_ACK;
1092 ack_frame->u.ack.pn = pkt->pn; 1111 ack_frame->u.ack.pn = pkt->pn;
1093 1112
1094 ngx_sprintf(ack_frame->info, "ACK for PN=%d from frame handler level=%d", pkt->pn, pkt->level); 1113 ngx_sprintf(ack_frame->info, "ACK for PN=%d from frame handler level=%d", pkt->pn, pkt->level);
1095 ngx_quic_queue_frame(qc, ack_frame); 1114 ngx_quic_queue_frame(qc, ack_frame);
1432 ssize_t len; 1451 ssize_t len;
1433 u_char *p; 1452 u_char *p;
1434 ngx_str_t out, res; 1453 ngx_str_t out, res;
1435 ngx_quic_frame_t *f; 1454 ngx_quic_frame_t *f;
1436 ngx_quic_header_t pkt; 1455 ngx_quic_header_t pkt;
1456 ngx_quic_secrets_t *keys;
1437 ngx_quic_connection_t *qc; 1457 ngx_quic_connection_t *qc;
1438 static ngx_str_t initial_token = ngx_null_string; 1458 static ngx_str_t initial_token = ngx_null_string;
1439 static u_char src[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; 1459 static u_char src[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
1440 static u_char dst[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; 1460 static u_char dst[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE];
1441 1461
1470 "packet ready: %ui bytes at level %d", 1490 "packet ready: %ui bytes at level %d",
1471 out.len, start->level); 1491 out.len, start->level);
1472 1492
1473 qc = c->quic; 1493 qc = c->quic;
1474 1494
1495 keys = &c->quic->keys[start->level];
1496
1497 pkt.secret = &keys->server;
1498
1475 if (start->level == ssl_encryption_initial) { 1499 if (start->level == ssl_encryption_initial) {
1476 pkt.number = &qc->initial_pn; 1500 pkt.number = &qc->initial_pn;
1477 pkt.flags = NGX_QUIC_PKT_INITIAL; 1501 pkt.flags = NGX_QUIC_PKT_INITIAL;
1478 pkt.secret = &qc->secrets.server.in;
1479 pkt.token = initial_token; 1502 pkt.token = initial_token;
1480 1503
1481 } else if (start->level == ssl_encryption_handshake) { 1504 } else if (start->level == ssl_encryption_handshake) {
1482 pkt.number = &qc->handshake_pn; 1505 pkt.number = &qc->handshake_pn;
1483 pkt.flags = NGX_QUIC_PKT_HANDSHAKE; 1506 pkt.flags = NGX_QUIC_PKT_HANDSHAKE;
1484 pkt.secret = &qc->secrets.server.hs;
1485 1507
1486 } else { 1508 } else {
1487 pkt.number = &qc->appdata_pn; 1509 pkt.number = &qc->appdata_pn;
1488 pkt.secret = &qc->secrets.server.ad;
1489 } 1510 }
1490 1511
1491 pkt.log = c->log; 1512 pkt.log = c->log;
1492 pkt.level = start->level; 1513 pkt.level = start->level;
1493 pkt.dcid = qc->dcid; 1514 pkt.dcid = qc->dcid;