Mercurial > hg > nginx-quic
comparison src/event/ngx_event_quic.c @ 7772: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
7771:e35f824f644d | 7772: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; |