return 1;
}
+static int c2s_pull_timeout_once(gnutls_transport_ptr_t tr, unsigned ms)
+{
+ return c2s.head != c2s.tail ? 1 : 0;
+}
+
static ssize_t server_pull(gnutls_transport_ptr_t tr, void *b, size_t l)
{
return queue_get(&c2s, (gnutls_session_t)tr, b, l);
gnutls_certificate_free_credentials(scred);
}
+static void test_malicious1816(void)
+{
+ /* dgram1: msg_len=50, frag_offset=25, frag_len=25 */
+ static const uint8_t dgram1_hdr[] = {
+ 0x16, /* type: handshake */
+ 0xfe, 0xfd, /* version: DTLS 1.2 */
+ 0x00, 0x00, /* epoch: 0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* seq: 0 */
+ 0x00, 0x25, /* record_length: 37 */
+ 0x01, /* msg_type: ClientHello */
+ 0x00, 0x00, 0x32, /* msg_length: 50 */
+ 0x00, 0x00, /* msg_seq: 0 */
+ 0x00, 0x00, 0x19, /* frag_offset: 25 */
+ 0x00, 0x00, 0x19, /* frag_length: 25 */
+ };
+ /* dgram2: msg_len=3000, frag_offset=0, frag_len=48 */
+ static const uint8_t dgram2_hdr[] = {
+ 0x16, /* type: handshake */
+ 0xfe, 0xfd, /* version: DTLS 1.2 */
+ 0x00, 0x00, /* epoch: 0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* seq: 1 */
+ 0x00, 0x3c, /* record_length: 60 */
+ 0x01, /* msg_type: ClientHello */
+ 0x00, 0x0b, 0xb8, /* msg_length: 3000 */
+ 0x00, 0x00, /* msg_seq: 0 */
+ 0x00, 0x00, 0x00, /* frag_offset: 0 */
+ 0x00, 0x00, 0x30, /* frag_length: 48 */
+ };
+ /* dgram3: msg_len=3000, frag_offset=40, frag_len=1475 */
+ static const uint8_t dgram3_hdr[] = {
+ 0x16, /* type: handshake */
+ 0xfe, 0xfd, /* version: DTLS 1.2 */
+ 0x00, 0x00, /* epoch: 0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* seq: 2 */
+ 0x05, 0xcf, /* record_length: 1487 */
+ 0x01, /* msg_type: ClientHello */
+ 0x00, 0x0b, 0xb8, /* msg_length: 3000 */
+ 0x00, 0x00, /* msg_seq: 0 */
+ 0x00, 0x00, 0x28, /* frag_offset: 40 */
+ 0x00, 0x05, 0xc3, /* frag_length: 1475 */
+ };
+ /* dgram4: msg_len=3000, frag_offset=1500, frag_len=1475 */
+ static const uint8_t dgram4_hdr[] = {
+ 0x16, /* type: handshake */
+ 0xfe, 0xfd, /* version: DTLS 1.2 */
+ 0x00, 0x00, /* epoch: 0 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* seq: 3 */
+ 0x05, 0xcf, /* record_length: 1487 */
+ 0x01, /* msg_type: ClientHello */
+ 0x00, 0x0b, 0xb8, /* msg_length: 3000 */
+ 0x00, 0x00, /* msg_seq: 0 */
+ 0x00, 0x05, 0xdc, /* frag_offset: 1500 */
+ 0x00, 0x05, 0xc3, /* frag_length: 1475 */
+ };
+ gnutls_session_t server;
+ gnutls_certificate_credentials_t scred;
+ uint8_t dgram[1500];
+ int sr;
+
+ if (debug)
+ gnutls_global_set_log_level(4711);
+
+ gnutls_certificate_allocate_credentials(&scred);
+ gnutls_certificate_set_x509_key_mem(scred, &server_cert, &server_key,
+ GNUTLS_X509_FMT_PEM);
+
+ gnutls_init(&server, GNUTLS_SERVER | GNUTLS_DATAGRAM);
+ gnutls_priority_set_direct(server, "NORMAL:+VERS-DTLS1.2", NULL);
+ gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, scred);
+
+ gnutls_dtls_set_timeouts(server, get_dtls_retransmit_timeout(),
+ get_timeout());
+
+ gnutls_transport_set_ptr(server, server);
+ gnutls_transport_set_push_function(server, server_push);
+ gnutls_transport_set_pull_function(server, server_pull);
+ gnutls_transport_set_pull_timeout_function(server,
+ c2s_pull_timeout_once);
+
+ memset(dgram, 0, sizeof(dgram));
+ memcpy(dgram, dgram1_hdr, 25);
+ queue_put(&c2s, dgram, 25 + 25);
+
+ memset(dgram, 0, sizeof(dgram));
+ memcpy(dgram, dgram2_hdr, 25);
+ queue_put(&c2s, dgram, 25 + 48);
+
+ memset(dgram, 0, sizeof(dgram));
+ memcpy(dgram, dgram3_hdr, 25);
+ queue_put(&c2s, dgram, 25 + 1475);
+
+ memset(dgram, 0, sizeof(dgram));
+ memcpy(dgram, dgram4_hdr, 25);
+ queue_put(&c2s, dgram, 25 + 1475);
+
+ gnutls_global_set_log_function(server_log_func);
+ do {
+ sr = gnutls_handshake(server); /* invalid write if vulnerable */
+ } while (c2s.head != c2s.tail && !gnutls_error_is_fatal(sr));
+ if (sr != GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
+ fail("server: expected GNUTLS_E_UNEXPECTED_PACKET_LENGTH, "
+ "got: %s\n",
+ gnutls_strerror(sr));
+
+ success("OK\n");
+
+ queue_reset(&c2s);
+ queue_reset(&s2c);
+
+ gnutls_deinit(server);
+ gnutls_certificate_free_credentials(scred);
+}
+
void doit(void)
{
global_init();
test(client_push_normal);
+ success("malicious reassembly bug exploitation (#1816):\n");
+ test_malicious1816();
gnutls_global_deinit();
}