Mercurial > hg > nginx
comparison src/event/ngx_event_quic_protection.c @ 8386:81f85c479d7e quic
Discard packets without fixed bit or reserved bits set.
Section 17.2 and 17.3 of QUIC transport:
Fixed bit: Packets containing a zero value for this bit are not
valid packets in this version and MUST be discarded.
Reserved bit: An endpoint MUST treat receipt of a packet that has
a non-zero value for these bits, after removing both packet and
header protection, as a connection error of type PROTOCOL_VIOLATION.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Thu, 14 May 2020 01:06:45 +0300 |
parents | 7ea34e13937f |
children | df18ae7161b8 |
comparison
equal
deleted
inserted
replaced
8385:fb7422074258 | 8386:81f85c479d7e |
---|---|
1012 ngx_int_t | 1012 ngx_int_t |
1013 ngx_quic_decrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn, | 1013 ngx_quic_decrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn, |
1014 uint64_t *largest_pn) | 1014 uint64_t *largest_pn) |
1015 { | 1015 { |
1016 u_char clearflags, *p, *sample; | 1016 u_char clearflags, *p, *sample; |
1017 uint8_t badflags; | |
1017 uint64_t pn; | 1018 uint64_t pn; |
1018 ngx_int_t pnl, rc, key_phase; | 1019 ngx_int_t pnl, rc, key_phase; |
1019 ngx_str_t in, ad; | 1020 ngx_str_t in, ad; |
1020 ngx_quic_secret_t *secret; | 1021 ngx_quic_secret_t *secret; |
1021 ngx_quic_ciphers_t ciphers; | 1022 ngx_quic_ciphers_t ciphers; |
1046 /* header protection */ | 1047 /* header protection */ |
1047 | 1048 |
1048 if (ngx_quic_tls_hp(pkt->log, ciphers.hp, secret, mask, sample) | 1049 if (ngx_quic_tls_hp(pkt->log, ciphers.hp, secret, mask, sample) |
1049 != NGX_OK) | 1050 != NGX_OK) |
1050 { | 1051 { |
1052 pkt->error = NGX_QUIC_ERR_CRYPTO_ERROR; | |
1051 return NGX_ERROR; | 1053 return NGX_ERROR; |
1052 } | 1054 } |
1053 | 1055 |
1054 if (ngx_quic_long_pkt(pkt->flags)) { | 1056 if (ngx_quic_long_pkt(pkt->flags)) { |
1055 clearflags = pkt->flags ^ (mask[0] & 0x0f); | 1057 clearflags = pkt->flags ^ (mask[0] & 0x0f); |
1083 | 1085 |
1084 in.data = p; | 1086 in.data = p; |
1085 | 1087 |
1086 if (ngx_quic_long_pkt(pkt->flags)) { | 1088 if (ngx_quic_long_pkt(pkt->flags)) { |
1087 in.len = pkt->len - pnl; | 1089 in.len = pkt->len - pnl; |
1090 badflags = clearflags & NGX_QUIC_PKT_LONG_RESERVED_BIT; | |
1088 | 1091 |
1089 } else { | 1092 } else { |
1090 in.len = pkt->data + pkt->len - p; | 1093 in.len = pkt->data + pkt->len - p; |
1094 badflags = clearflags & NGX_QUIC_PKT_SHORT_RESERVED_BIT; | |
1091 } | 1095 } |
1092 | 1096 |
1093 ad.len = p - pkt->data; | 1097 ad.len = p - pkt->data; |
1094 ad.data = pkt->plaintext; | 1098 ad.data = pkt->plaintext; |
1095 | 1099 |
1122 #if defined(NGX_QUIC_DEBUG_CRYPTO) && defined(NGX_QUIC_DEBUG_PACKETS) | 1126 #if defined(NGX_QUIC_DEBUG_CRYPTO) && defined(NGX_QUIC_DEBUG_PACKETS) |
1123 ngx_quic_hexdump(pkt->log, "quic packet payload", | 1127 ngx_quic_hexdump(pkt->log, "quic packet payload", |
1124 pkt->payload.data, pkt->payload.len); | 1128 pkt->payload.data, pkt->payload.len); |
1125 #endif | 1129 #endif |
1126 | 1130 |
1127 return rc; | 1131 if (rc != NGX_OK) { |
1128 } | 1132 pkt->error = NGX_QUIC_ERR_CRYPTO_ERROR; |
1129 | 1133 return rc; |
1134 } | |
1135 | |
1136 if (badflags) { | |
1137 /* | |
1138 * An endpoint MUST treat receipt of a packet that has | |
1139 * a non-zero value for these bits, after removing both | |
1140 * packet and header protection, as a connection error | |
1141 * of type PROTOCOL_VIOLATION. | |
1142 */ | |
1143 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
1144 "quic reserved bit set in packet"); | |
1145 pkt->error = NGX_QUIC_ERR_PROTOCOL_VIOLATION; | |
1146 return NGX_ERROR; | |
1147 } | |
1148 | |
1149 return NGX_OK; | |
1150 } | |
1151 |