comparison src/event/ngx_event_quic_protection.c @ 8383:7ea34e13937f quic

Address validation using Retry packets. The behaviour is toggled with the new directive "quic_retry on|off". QUIC token construction is made suitable for issuing with NEW_TOKEN.
author Sergey Kandaurov <pluknet@nginx.com>
date Thu, 14 May 2020 15:47:18 +0300
parents 2d0f4aa78ed6
children 81f85c479d7e
comparison
equal deleted inserted replaced
8382:b7704303a7e5 8383:7ea34e13937f
55 55
56 static ngx_int_t ngx_quic_create_long_packet(ngx_quic_header_t *pkt, 56 static ngx_int_t ngx_quic_create_long_packet(ngx_quic_header_t *pkt,
57 ngx_ssl_conn_t *ssl_conn, ngx_str_t *res); 57 ngx_ssl_conn_t *ssl_conn, ngx_str_t *res);
58 static ngx_int_t ngx_quic_create_short_packet(ngx_quic_header_t *pkt, 58 static ngx_int_t ngx_quic_create_short_packet(ngx_quic_header_t *pkt,
59 ngx_ssl_conn_t *ssl_conn, ngx_str_t *res); 59 ngx_ssl_conn_t *ssl_conn, ngx_str_t *res);
60 static ngx_int_t ngx_quic_create_retry_packet(ngx_quic_header_t *pkt,
61 ngx_str_t *res);
60 62
61 63
62 static ngx_int_t 64 static ngx_int_t
63 ngx_quic_ciphers(ngx_ssl_conn_t *ssl_conn, ngx_quic_ciphers_t *ciphers, 65 ngx_quic_ciphers(ngx_ssl_conn_t *ssl_conn, ngx_quic_ciphers_t *ciphers,
64 enum ssl_encryption_level_t level) 66 enum ssl_encryption_level_t level)
889 891
890 return NGX_OK; 892 return NGX_OK;
891 } 893 }
892 894
893 895
896 static ngx_int_t
897 ngx_quic_create_retry_packet(ngx_quic_header_t *pkt, ngx_str_t *res)
898 {
899 u_char *start;
900 ngx_str_t ad, itag;
901 ngx_quic_secret_t secret;
902 ngx_quic_ciphers_t ciphers;
903
904 /* 5.8. Retry Packet Integrity */
905 static u_char key[16] =
906 "\x4d\x32\xec\xdb\x2a\x21\x33\xc8"
907 "\x41\xe4\x04\x3d\xf2\x7d\x44\x30";
908 static u_char nonce[12] =
909 "\x4d\x16\x11\xd0\x55\x13"
910 "\xa5\x52\xc5\x87\xd5\x75";
911 static ngx_str_t in = ngx_string("");
912
913 ad.data = res->data;
914 ad.len = ngx_quic_create_retry_itag(pkt, ad.data, &start);
915
916 itag.data = ad.data + ad.len;
917
918 #ifdef NGX_QUIC_DEBUG_CRYPTO
919 ngx_quic_hexdump(pkt->log, "quic retry itag", ad.data, ad.len);
920 #endif
921
922 if (ngx_quic_ciphers(NULL, &ciphers, pkt->level) == NGX_ERROR) {
923 return NGX_ERROR;
924 }
925
926 secret.key.len = sizeof(key);
927 secret.key.data = key;
928 secret.iv.len = sizeof(nonce);
929
930 if (ngx_quic_tls_seal(ciphers.c, &secret, &itag, nonce, &in, &ad, pkt->log)
931 != NGX_OK)
932 {
933 return NGX_ERROR;
934 }
935
936 res->len = itag.data + itag.len - start;
937 res->data = start;
938
939 return NGX_OK;
940 }
941
942
894 static uint64_t 943 static uint64_t
895 ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask, 944 ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask,
896 uint64_t *largest_pn) 945 uint64_t *largest_pn)
897 { 946 {
898 u_char *p; 947 u_char *p;
948 ngx_quic_encrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn, 997 ngx_quic_encrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn,
949 ngx_str_t *res) 998 ngx_str_t *res)
950 { 999 {
951 if (ngx_quic_short_pkt(pkt->flags)) { 1000 if (ngx_quic_short_pkt(pkt->flags)) {
952 return ngx_quic_create_short_packet(pkt, ssl_conn, res); 1001 return ngx_quic_create_short_packet(pkt, ssl_conn, res);
1002 }
1003
1004 if (ngx_quic_pkt_retry(pkt->flags)) {
1005 return ngx_quic_create_retry_packet(pkt, res);
953 } 1006 }
954 1007
955 return ngx_quic_create_long_packet(pkt, ssl_conn, res); 1008 return ngx_quic_create_long_packet(pkt, ssl_conn, res);
956 } 1009 }
957 1010