Home | History | Annotate | Line # | Download | only in test
      1  1.1  christos /*
      2  1.1  christos  * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
      3  1.1  christos  *
      4  1.1  christos  * Licensed under the OpenSSL license (the "License").  You may not use
      5  1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6  1.1  christos  * in the file LICENSE in the source distribution or at
      7  1.1  christos  * https://www.openssl.org/source/license.html
      8  1.1  christos  */
      9  1.1  christos 
     10  1.1  christos /*
     11  1.1  christos  * Unit test for Cisco DTLS1_BAD_VER session resume, as used by
     12  1.1  christos  * AnyConnect VPN protocol.
     13  1.1  christos  *
     14  1.1  christos  * This is designed to exercise the code paths in
     15  1.1  christos  * http://git.infradead.org/users/dwmw2/openconnect.git/blob/HEAD:/dtls.c
     16  1.1  christos  * which have frequently been affected by regressions in DTLS1_BAD_VER
     17  1.1  christos  * support.
     18  1.1  christos  *
     19  1.1  christos  * Note that unlike other SSL tests, we don't test against our own SSL
     20  1.1  christos  * server method. Firstly because we don't have one; we *only* support
     21  1.1  christos  * DTLS1_BAD_VER as a client. And secondly because even if that were
     22  1.1  christos  * fixed up it's the wrong thing to test against - because if changes
     23  1.1  christos  * are made in generic DTLS code which don't take DTLS1_BAD_VER into
     24  1.1  christos  * account, there's plenty of scope for making those changes such that
     25  1.1  christos  * they break *both* the client and the server in the same way.
     26  1.1  christos  *
     27  1.1  christos  * So we handle the server side manually. In a session resume there isn't
     28  1.1  christos  * much to be done anyway.
     29  1.1  christos  */
     30  1.1  christos #include <string.h>
     31  1.1  christos 
     32  1.1  christos #include <openssl/opensslconf.h>
     33  1.1  christos #include <openssl/bio.h>
     34  1.1  christos #include <openssl/crypto.h>
     35  1.1  christos #include <openssl/evp.h>
     36  1.1  christos #include <openssl/ssl.h>
     37  1.1  christos #include <openssl/err.h>
     38  1.1  christos #include <openssl/rand.h>
     39  1.1  christos #include <openssl/kdf.h>
     40  1.1  christos #include "../ssl/packet_local.h"
     41  1.1  christos #include "internal/nelem.h"
     42  1.1  christos #include "testutil.h"
     43  1.1  christos 
     44  1.1  christos /* For DTLS1_BAD_VER packets the MAC doesn't include the handshake header */
     45  1.1  christos #define MAC_OFFSET (DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH)
     46  1.1  christos 
     47  1.1  christos static unsigned char client_random[SSL3_RANDOM_SIZE];
     48  1.1  christos static unsigned char server_random[SSL3_RANDOM_SIZE];
     49  1.1  christos 
     50  1.1  christos /* These are all generated locally, sized purely according to our own whim */
     51  1.1  christos static unsigned char session_id[32];
     52  1.1  christos static unsigned char master_secret[48];
     53  1.1  christos static unsigned char cookie[20];
     54  1.1  christos 
     55  1.1  christos /* We've hard-coded the cipher suite; we know it's 104 bytes */
     56  1.1  christos static unsigned char key_block[104];
     57  1.1  christos #define mac_key (key_block + 20)
     58  1.1  christos #define dec_key (key_block + 40)
     59  1.1  christos #define enc_key (key_block + 56)
     60  1.1  christos 
     61  1.1  christos static EVP_MD_CTX *handshake_md;
     62  1.1  christos 
     63  1.1  christos static int do_PRF(const void *seed1, int seed1_len,
     64  1.1  christos                   const void *seed2, int seed2_len,
     65  1.1  christos                   const void *seed3, int seed3_len,
     66  1.1  christos                   unsigned char *out, int olen)
     67  1.1  christos {
     68  1.1  christos     EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL);
     69  1.1  christos     size_t outlen = olen;
     70  1.1  christos 
     71  1.1  christos     /* No error handling. If it all screws up, the test will fail anyway */
     72  1.1  christos     EVP_PKEY_derive_init(pctx);
     73  1.1  christos     EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_md5_sha1());
     74  1.1  christos     EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, master_secret, sizeof(master_secret));
     75  1.1  christos     EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed1, seed1_len);
     76  1.1  christos     EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed2, seed2_len);
     77  1.1  christos     EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed3, seed3_len);
     78  1.1  christos     EVP_PKEY_derive(pctx, out, &outlen);
     79  1.1  christos     EVP_PKEY_CTX_free(pctx);
     80  1.1  christos     return 1;
     81  1.1  christos }
     82  1.1  christos 
     83  1.1  christos static SSL_SESSION *client_session(void)
     84  1.1  christos {
     85  1.1  christos     static unsigned char session_asn1[] = {
     86  1.1  christos         0x30, 0x5F,              /* SEQUENCE, length 0x5F */
     87  1.1  christos         0x02, 0x01, 0x01,        /* INTEGER, SSL_SESSION_ASN1_VERSION */
     88  1.1  christos         0x02, 0x02, 0x01, 0x00,  /* INTEGER, DTLS1_BAD_VER */
     89  1.1  christos         0x04, 0x02, 0x00, 0x2F,  /* OCTET_STRING, AES128-SHA */
     90  1.1  christos         0x04, 0x20,              /* OCTET_STRING, session id */
     91  1.1  christos #define SS_SESSID_OFS 15 /* Session ID goes here */
     92  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     93  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     94  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     95  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     96  1.1  christos         0x04, 0x30,              /* OCTET_STRING, master secret */
     97  1.1  christos #define SS_SECRET_OFS 49 /* Master secret goes here */
     98  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     99  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    100  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    101  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    102  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    103  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    104  1.1  christos     };
    105  1.1  christos     const unsigned char *p = session_asn1;
    106  1.1  christos 
    107  1.1  christos     /* Copy the randomly-generated fields into the above ASN1 */
    108  1.1  christos     memcpy(session_asn1 + SS_SESSID_OFS, session_id, sizeof(session_id));
    109  1.1  christos     memcpy(session_asn1 + SS_SECRET_OFS, master_secret, sizeof(master_secret));
    110  1.1  christos 
    111  1.1  christos     return d2i_SSL_SESSION(NULL, &p, sizeof(session_asn1));
    112  1.1  christos }
    113  1.1  christos 
    114  1.1  christos /* Returns 1 for initial ClientHello, 2 for ClientHello with cookie */
    115  1.1  christos static int validate_client_hello(BIO *wbio)
    116  1.1  christos {
    117  1.1  christos     PACKET pkt, pkt2;
    118  1.1  christos     long len;
    119  1.1  christos     unsigned char *data;
    120  1.1  christos     int cookie_found = 0;
    121  1.1  christos     unsigned int u = 0;
    122  1.1  christos 
    123  1.1  christos     len = BIO_get_mem_data(wbio, (char **)&data);
    124  1.1  christos     if (!PACKET_buf_init(&pkt, data, len))
    125  1.1  christos         return 0;
    126  1.1  christos 
    127  1.1  christos     /* Check record header type */
    128  1.1  christos     if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_HANDSHAKE)
    129  1.1  christos         return 0;
    130  1.1  christos     /* Version */
    131  1.1  christos     if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
    132  1.1  christos         return 0;
    133  1.1  christos     /* Skip the rest of the record header */
    134  1.1  christos     if (!PACKET_forward(&pkt, DTLS1_RT_HEADER_LENGTH - 3))
    135  1.1  christos         return 0;
    136  1.1  christos 
    137  1.1  christos     /* Check it's a ClientHello */
    138  1.1  christos     if (!PACKET_get_1(&pkt, &u) || u != SSL3_MT_CLIENT_HELLO)
    139  1.1  christos         return 0;
    140  1.1  christos     /* Skip the rest of the handshake message header */
    141  1.1  christos     if (!PACKET_forward(&pkt, DTLS1_HM_HEADER_LENGTH - 1))
    142  1.1  christos         return 0;
    143  1.1  christos 
    144  1.1  christos     /* Check client version */
    145  1.1  christos     if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
    146  1.1  christos         return 0;
    147  1.1  christos 
    148  1.1  christos     /* Store random */
    149  1.1  christos     if (!PACKET_copy_bytes(&pkt, client_random, SSL3_RANDOM_SIZE))
    150  1.1  christos         return 0;
    151  1.1  christos 
    152  1.1  christos     /* Check session id length and content */
    153  1.1  christos     if (!PACKET_get_length_prefixed_1(&pkt, &pkt2) ||
    154  1.1  christos         !PACKET_equal(&pkt2, session_id, sizeof(session_id)))
    155  1.1  christos         return 0;
    156  1.1  christos 
    157  1.1  christos     /* Check cookie */
    158  1.1  christos     if (!PACKET_get_length_prefixed_1(&pkt, &pkt2))
    159  1.1  christos         return 0;
    160  1.1  christos     if (PACKET_remaining(&pkt2)) {
    161  1.1  christos         if (!PACKET_equal(&pkt2, cookie, sizeof(cookie)))
    162  1.1  christos             return 0;
    163  1.1  christos         cookie_found = 1;
    164  1.1  christos     }
    165  1.1  christos 
    166  1.1  christos     /* Skip ciphers */
    167  1.1  christos     if (!PACKET_get_net_2(&pkt, &u) || !PACKET_forward(&pkt, u))
    168  1.1  christos         return 0;
    169  1.1  christos 
    170  1.1  christos     /* Skip compression */
    171  1.1  christos     if (!PACKET_get_1(&pkt, &u) || !PACKET_forward(&pkt, u))
    172  1.1  christos         return 0;
    173  1.1  christos 
    174  1.1  christos     /* Skip extensions */
    175  1.1  christos     if (!PACKET_get_net_2(&pkt, &u) || !PACKET_forward(&pkt, u))
    176  1.1  christos         return 0;
    177  1.1  christos 
    178  1.1  christos     /* Now we are at the end */
    179  1.1  christos     if (PACKET_remaining(&pkt))
    180  1.1  christos         return 0;
    181  1.1  christos 
    182  1.1  christos     /* Update handshake MAC for second ClientHello (with cookie) */
    183  1.1  christos     if (cookie_found && !EVP_DigestUpdate(handshake_md, data + MAC_OFFSET,
    184  1.1  christos                                           len - MAC_OFFSET))
    185  1.1  christos         return 0;
    186  1.1  christos 
    187  1.1  christos     (void)BIO_reset(wbio);
    188  1.1  christos 
    189  1.1  christos     return 1 + cookie_found;
    190  1.1  christos }
    191  1.1  christos 
    192  1.1  christos static int send_hello_verify(BIO *rbio)
    193  1.1  christos {
    194  1.1  christos     static unsigned char hello_verify[] = {
    195  1.1  christos         0x16, /* Handshake */
    196  1.1  christos         0x01, 0x00, /* DTLS1_BAD_VER */
    197  1.1  christos         0x00, 0x00, /* Epoch 0 */
    198  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Seq# 0 */
    199  1.1  christos         0x00, 0x23, /* Length */
    200  1.1  christos         0x03, /* Hello Verify */
    201  1.1  christos         0x00, 0x00, 0x17, /* Length */
    202  1.1  christos         0x00, 0x00, /* Seq# 0 */
    203  1.1  christos         0x00, 0x00, 0x00, /* Fragment offset */
    204  1.1  christos         0x00, 0x00, 0x17, /* Fragment length */
    205  1.1  christos         0x01, 0x00, /* DTLS1_BAD_VER */
    206  1.1  christos         0x14, /* Cookie length */
    207  1.1  christos #define HV_COOKIE_OFS 28 /* Cookie goes here */
    208  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    209  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    210  1.1  christos         0x00, 0x00, 0x00, 0x00,
    211  1.1  christos     };
    212  1.1  christos 
    213  1.1  christos     memcpy(hello_verify + HV_COOKIE_OFS, cookie, sizeof(cookie));
    214  1.1  christos 
    215  1.1  christos     BIO_write(rbio, hello_verify, sizeof(hello_verify));
    216  1.1  christos 
    217  1.1  christos     return 1;
    218  1.1  christos }
    219  1.1  christos 
    220  1.1  christos static int send_server_hello(BIO *rbio)
    221  1.1  christos {
    222  1.1  christos     static unsigned char server_hello[] = {
    223  1.1  christos         0x16, /* Handshake */
    224  1.1  christos         0x01, 0x00, /* DTLS1_BAD_VER */
    225  1.1  christos         0x00, 0x00, /* Epoch 0 */
    226  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* Seq# 1 */
    227  1.1  christos         0x00, 0x52, /* Length */
    228  1.1  christos         0x02, /* Server Hello */
    229  1.1  christos         0x00, 0x00, 0x46, /* Length */
    230  1.1  christos         0x00, 0x01, /* Seq# */
    231  1.1  christos         0x00, 0x00, 0x00, /* Fragment offset */
    232  1.1  christos         0x00, 0x00, 0x46, /* Fragment length */
    233  1.1  christos         0x01, 0x00, /* DTLS1_BAD_VER */
    234  1.1  christos #define SH_RANDOM_OFS 27 /* Server random goes here */
    235  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    236  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    237  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    238  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    239  1.1  christos         0x20, /* Session ID length */
    240  1.1  christos #define SH_SESSID_OFS 60 /* Session ID goes here */
    241  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    242  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    243  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    244  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    245  1.1  christos         0x00, 0x2f, /* Cipher suite AES128-SHA */
    246  1.1  christos         0x00, /* Compression null */
    247  1.1  christos     };
    248  1.1  christos     static unsigned char change_cipher_spec[] = {
    249  1.1  christos         0x14, /* Change Cipher Spec */
    250  1.1  christos         0x01, 0x00, /* DTLS1_BAD_VER */
    251  1.1  christos         0x00, 0x00, /* Epoch 0 */
    252  1.1  christos         0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* Seq# 2 */
    253  1.1  christos         0x00, 0x03, /* Length */
    254  1.1  christos         0x01, 0x00, 0x02, /* Message */
    255  1.1  christos     };
    256  1.1  christos 
    257  1.1  christos     memcpy(server_hello + SH_RANDOM_OFS, server_random, sizeof(server_random));
    258  1.1  christos     memcpy(server_hello + SH_SESSID_OFS, session_id, sizeof(session_id));
    259  1.1  christos 
    260  1.1  christos     if (!EVP_DigestUpdate(handshake_md, server_hello + MAC_OFFSET,
    261  1.1  christos                           sizeof(server_hello) - MAC_OFFSET))
    262  1.1  christos         return 0;
    263  1.1  christos 
    264  1.1  christos     BIO_write(rbio, server_hello, sizeof(server_hello));
    265  1.1  christos     BIO_write(rbio, change_cipher_spec, sizeof(change_cipher_spec));
    266  1.1  christos 
    267  1.1  christos     return 1;
    268  1.1  christos }
    269  1.1  christos 
    270  1.1  christos /* Create header, HMAC, pad, encrypt and send a record */
    271  1.1  christos static int send_record(BIO *rbio, unsigned char type, uint64_t seqnr,
    272  1.1  christos                        const void *msg, size_t len)
    273  1.1  christos {
    274  1.1  christos     /* Note that the order of the record header fields on the wire,
    275  1.1  christos      * and in the HMAC, is different. So we just keep them in separate
    276  1.1  christos      * variables and handle them individually. */
    277  1.1  christos     static unsigned char epoch[2] = { 0x00, 0x01 };
    278  1.1  christos     static unsigned char seq[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    279  1.1  christos     static unsigned char ver[2] = { 0x01, 0x00 }; /* DTLS1_BAD_VER */
    280  1.1  christos     unsigned char lenbytes[2];
    281  1.1  christos     HMAC_CTX *ctx;
    282  1.1  christos     EVP_CIPHER_CTX *enc_ctx;
    283  1.1  christos     unsigned char iv[16];
    284  1.1  christos     unsigned char pad;
    285  1.1  christos     unsigned char *enc;
    286  1.1  christos 
    287  1.1  christos     seq[0] = (seqnr >> 40) & 0xff;
    288  1.1  christos     seq[1] = (seqnr >> 32) & 0xff;
    289  1.1  christos     seq[2] = (seqnr >> 24) & 0xff;
    290  1.1  christos     seq[3] = (seqnr >> 16) & 0xff;
    291  1.1  christos     seq[4] = (seqnr >> 8) & 0xff;
    292  1.1  christos     seq[5] = seqnr & 0xff;
    293  1.1  christos 
    294  1.1  christos     pad = 15 - ((len + SHA_DIGEST_LENGTH) % 16);
    295  1.1  christos     enc = OPENSSL_malloc(len + SHA_DIGEST_LENGTH + 1 + pad);
    296  1.1  christos     if (enc == NULL)
    297  1.1  christos         return 0;
    298  1.1  christos 
    299  1.1  christos     /* Copy record to encryption buffer */
    300  1.1  christos     memcpy(enc, msg, len);
    301  1.1  christos 
    302  1.1  christos     /* Append HMAC to data */
    303  1.1  christos     ctx = HMAC_CTX_new();
    304  1.1  christos     HMAC_Init_ex(ctx, mac_key, 20, EVP_sha1(), NULL);
    305  1.1  christos     HMAC_Update(ctx, epoch, 2);
    306  1.1  christos     HMAC_Update(ctx, seq, 6);
    307  1.1  christos     HMAC_Update(ctx, &type, 1);
    308  1.1  christos     HMAC_Update(ctx, ver, 2); /* Version */
    309  1.1  christos     lenbytes[0] = (unsigned char)(len >> 8);
    310  1.1  christos     lenbytes[1] = (unsigned char)(len);
    311  1.1  christos     HMAC_Update(ctx, lenbytes, 2); /* Length */
    312  1.1  christos     HMAC_Update(ctx, enc, len); /* Finally the data itself */
    313  1.1  christos     HMAC_Final(ctx, enc + len, NULL);
    314  1.1  christos     HMAC_CTX_free(ctx);
    315  1.1  christos 
    316  1.1  christos     /* Append padding bytes */
    317  1.1  christos     len += SHA_DIGEST_LENGTH;
    318  1.1  christos     do {
    319  1.1  christos         enc[len++] = pad;
    320  1.1  christos     } while (len % 16);
    321  1.1  christos 
    322  1.1  christos     /* Generate IV, and encrypt */
    323  1.1  christos     RAND_bytes(iv, sizeof(iv));
    324  1.1  christos     enc_ctx = EVP_CIPHER_CTX_new();
    325  1.1  christos     EVP_CipherInit_ex(enc_ctx, EVP_aes_128_cbc(), NULL, enc_key, iv, 1);
    326  1.1  christos     EVP_Cipher(enc_ctx, enc, enc, len);
    327  1.1  christos     EVP_CIPHER_CTX_free(enc_ctx);
    328  1.1  christos 
    329  1.1  christos     /* Finally write header (from fragmented variables), IV and encrypted record */
    330  1.1  christos     BIO_write(rbio, &type, 1);
    331  1.1  christos     BIO_write(rbio, ver, 2);
    332  1.1  christos     BIO_write(rbio, epoch, 2);
    333  1.1  christos     BIO_write(rbio, seq, 6);
    334  1.1  christos     lenbytes[0] = (unsigned char)((len + sizeof(iv)) >> 8);
    335  1.1  christos     lenbytes[1] = (unsigned char)(len + sizeof(iv));
    336  1.1  christos     BIO_write(rbio, lenbytes, 2);
    337  1.1  christos 
    338  1.1  christos     BIO_write(rbio, iv, sizeof(iv));
    339  1.1  christos     BIO_write(rbio, enc, len);
    340  1.1  christos 
    341  1.1  christos     OPENSSL_free(enc);
    342  1.1  christos     return 1;
    343  1.1  christos }
    344  1.1  christos 
    345  1.1  christos static int send_finished(SSL *s, BIO *rbio)
    346  1.1  christos {
    347  1.1  christos     static unsigned char finished_msg[DTLS1_HM_HEADER_LENGTH +
    348  1.1  christos                                       TLS1_FINISH_MAC_LENGTH] = {
    349  1.1  christos         0x14, /* Finished */
    350  1.1  christos         0x00, 0x00, 0x0c, /* Length */
    351  1.1  christos         0x00, 0x03, /* Seq# 3 */
    352  1.1  christos         0x00, 0x00, 0x00, /* Fragment offset */
    353  1.1  christos         0x00, 0x00, 0x0c, /* Fragment length */
    354  1.1  christos         /* Finished MAC (12 bytes) */
    355  1.1  christos     };
    356  1.1  christos     unsigned char handshake_hash[EVP_MAX_MD_SIZE];
    357  1.1  christos 
    358  1.1  christos     /* Derive key material */
    359  1.1  christos     do_PRF(TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE,
    360  1.1  christos            server_random, SSL3_RANDOM_SIZE,
    361  1.1  christos            client_random, SSL3_RANDOM_SIZE,
    362  1.1  christos            key_block, sizeof(key_block));
    363  1.1  christos 
    364  1.1  christos     /* Generate Finished MAC */
    365  1.1  christos     if (!EVP_DigestFinal_ex(handshake_md, handshake_hash, NULL))
    366  1.1  christos         return 0;
    367  1.1  christos 
    368  1.1  christos     do_PRF(TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
    369  1.1  christos            handshake_hash, EVP_MD_CTX_size(handshake_md),
    370  1.1  christos            NULL, 0,
    371  1.1  christos            finished_msg + DTLS1_HM_HEADER_LENGTH, TLS1_FINISH_MAC_LENGTH);
    372  1.1  christos 
    373  1.1  christos     return send_record(rbio, SSL3_RT_HANDSHAKE, 0,
    374  1.1  christos                        finished_msg, sizeof(finished_msg));
    375  1.1  christos }
    376  1.1  christos 
    377  1.1  christos static int validate_ccs(BIO *wbio)
    378  1.1  christos {
    379  1.1  christos     PACKET pkt;
    380  1.1  christos     long len;
    381  1.1  christos     unsigned char *data;
    382  1.1  christos     unsigned int u;
    383  1.1  christos 
    384  1.1  christos     len = BIO_get_mem_data(wbio, (char **)&data);
    385  1.1  christos     if (!PACKET_buf_init(&pkt, data, len))
    386  1.1  christos         return 0;
    387  1.1  christos 
    388  1.1  christos     /* Check record header type */
    389  1.1  christos     if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_CHANGE_CIPHER_SPEC)
    390  1.1  christos         return 0;
    391  1.1  christos     /* Version */
    392  1.1  christos     if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
    393  1.1  christos         return 0;
    394  1.1  christos     /* Skip the rest of the record header */
    395  1.1  christos     if (!PACKET_forward(&pkt, DTLS1_RT_HEADER_LENGTH - 3))
    396  1.1  christos         return 0;
    397  1.1  christos 
    398  1.1  christos     /* Check ChangeCipherSpec message */
    399  1.1  christos     if (!PACKET_get_1(&pkt, &u) || u != SSL3_MT_CCS)
    400  1.1  christos         return 0;
    401  1.1  christos     /* A DTLS1_BAD_VER ChangeCipherSpec also contains the
    402  1.1  christos      * handshake sequence number (which is 2 here) */
    403  1.1  christos     if (!PACKET_get_net_2(&pkt, &u) || u != 0x0002)
    404  1.1  christos         return 0;
    405  1.1  christos 
    406  1.1  christos     /* Now check the Finished packet */
    407  1.1  christos     if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_HANDSHAKE)
    408  1.1  christos         return 0;
    409  1.1  christos     if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
    410  1.1  christos         return 0;
    411  1.1  christos 
    412  1.1  christos     /* Check epoch is now 1 */
    413  1.1  christos     if (!PACKET_get_net_2(&pkt, &u) || u != 0x0001)
    414  1.1  christos         return 0;
    415  1.1  christos 
    416  1.1  christos     /* That'll do for now. If OpenSSL accepted *our* Finished packet
    417  1.1  christos      * then it's evidently remembered that DTLS1_BAD_VER doesn't
    418  1.1  christos      * include the handshake header in the MAC. There's not a lot of
    419  1.1  christos      * point in implementing decryption here, just to check that it
    420  1.1  christos      * continues to get it right for one more packet. */
    421  1.1  christos 
    422  1.1  christos     return 1;
    423  1.1  christos }
    424  1.1  christos 
    425  1.1  christos #define NODROP(x) { x##UL, 0 }
    426  1.1  christos #define DROP(x)   { x##UL, 1 }
    427  1.1  christos 
    428  1.1  christos static struct {
    429  1.1  christos     uint64_t seq;
    430  1.1  christos     int drop;
    431  1.1  christos } tests[] = {
    432  1.1  christos     NODROP(1), NODROP(3), NODROP(2),
    433  1.1  christos     NODROP(0x1234), NODROP(0x1230), NODROP(0x1235),
    434  1.1  christos     NODROP(0xffff), NODROP(0x10001), NODROP(0xfffe), NODROP(0x10000),
    435  1.1  christos     DROP(0x10001), DROP(0xff), NODROP(0x100000), NODROP(0x800000), NODROP(0x7fffe1),
    436  1.1  christos     NODROP(0xffffff), NODROP(0x1000000), NODROP(0xfffffe), DROP(0xffffff), NODROP(0x1000010),
    437  1.1  christos     NODROP(0xfffffd), NODROP(0x1000011), DROP(0x12), NODROP(0x1000012),
    438  1.1  christos     NODROP(0x1ffffff), NODROP(0x2000000), DROP(0x1ff00fe), NODROP(0x2000001),
    439  1.1  christos     NODROP(0x20fffff), NODROP(0x2105500), DROP(0x20ffffe), NODROP(0x21054ff),
    440  1.1  christos     NODROP(0x211ffff), DROP(0x2110000), NODROP(0x2120000)
    441  1.1  christos     /* The last test should be NODROP, because a DROP wouldn't get tested. */
    442  1.1  christos };
    443  1.1  christos 
    444  1.1  christos static int test_bad_dtls(void)
    445  1.1  christos {
    446  1.1  christos     SSL_SESSION *sess = NULL;
    447  1.1  christos     SSL_CTX *ctx = NULL;
    448  1.1  christos     SSL *con = NULL;
    449  1.1  christos     BIO *rbio = NULL;
    450  1.1  christos     BIO *wbio = NULL;
    451  1.1  christos     time_t now = 0;
    452  1.1  christos     int testresult = 0;
    453  1.1  christos     int ret;
    454  1.1  christos     int i;
    455  1.1  christos 
    456  1.1  christos     RAND_bytes(session_id, sizeof(session_id));
    457  1.1  christos     RAND_bytes(master_secret, sizeof(master_secret));
    458  1.1  christos     RAND_bytes(cookie, sizeof(cookie));
    459  1.1  christos     RAND_bytes(server_random + 4, sizeof(server_random) - 4);
    460  1.1  christos 
    461  1.1  christos     now = time(NULL);
    462  1.1  christos     memcpy(server_random, &now, sizeof(now));
    463  1.1  christos 
    464  1.1  christos     sess = client_session();
    465  1.1  christos     if (!TEST_ptr(sess))
    466  1.1  christos         goto end;
    467  1.1  christos 
    468  1.1  christos     handshake_md = EVP_MD_CTX_new();
    469  1.1  christos     if (!TEST_ptr(handshake_md)
    470  1.1  christos             || !TEST_true(EVP_DigestInit_ex(handshake_md, EVP_md5_sha1(),
    471  1.1  christos                                             NULL)))
    472  1.1  christos         goto end;
    473  1.1  christos 
    474  1.1  christos     ctx = SSL_CTX_new(DTLS_client_method());
    475  1.1  christos     if (!TEST_ptr(ctx)
    476  1.1  christos             || !TEST_true(SSL_CTX_set_min_proto_version(ctx, DTLS1_BAD_VER))
    477  1.1  christos             || !TEST_true(SSL_CTX_set_max_proto_version(ctx, DTLS1_BAD_VER))
    478  1.1  christos             || !TEST_true(SSL_CTX_set_cipher_list(ctx, "AES128-SHA")))
    479  1.1  christos         goto end;
    480  1.1  christos 
    481  1.1  christos     con = SSL_new(ctx);
    482  1.1  christos     if (!TEST_ptr(con)
    483  1.1  christos             || !TEST_true(SSL_set_session(con, sess)))
    484  1.1  christos         goto end;
    485  1.1  christos     SSL_SESSION_free(sess);
    486  1.1  christos 
    487  1.1  christos     rbio = BIO_new(BIO_s_mem());
    488  1.1  christos     wbio = BIO_new(BIO_s_mem());
    489  1.1  christos 
    490  1.1  christos     if (!TEST_ptr(rbio)
    491  1.1  christos             || !TEST_ptr(wbio))
    492  1.1  christos         goto end;
    493  1.1  christos 
    494  1.1  christos     SSL_set_bio(con, rbio, wbio);
    495  1.1  christos 
    496  1.1  christos     if (!TEST_true(BIO_up_ref(rbio))) {
    497  1.1  christos         /*
    498  1.1  christos          * We can't up-ref but we assigned ownership to con, so we shouldn't
    499  1.1  christos          * free in the "end" block
    500  1.1  christos          */
    501  1.1  christos         rbio = wbio = NULL;
    502  1.1  christos         goto end;
    503  1.1  christos     }
    504  1.1  christos 
    505  1.1  christos     if (!TEST_true(BIO_up_ref(wbio))) {
    506  1.1  christos         wbio = NULL;
    507  1.1  christos         goto end;
    508  1.1  christos     }
    509  1.1  christos 
    510  1.1  christos     SSL_set_connect_state(con);
    511  1.1  christos 
    512  1.1  christos     /* Send initial ClientHello */
    513  1.1  christos     ret = SSL_do_handshake(con);
    514  1.1  christos     if (!TEST_int_le(ret, 0)
    515  1.1  christos             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
    516  1.1  christos             || !TEST_int_eq(validate_client_hello(wbio), 1)
    517  1.1  christos             || !TEST_true(send_hello_verify(rbio)))
    518  1.1  christos         goto end;
    519  1.1  christos 
    520  1.1  christos     ret = SSL_do_handshake(con);
    521  1.1  christos     if (!TEST_int_le(ret, 0)
    522  1.1  christos             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
    523  1.1  christos             || !TEST_int_eq(validate_client_hello(wbio), 2)
    524  1.1  christos             || !TEST_true(send_server_hello(rbio)))
    525  1.1  christos         goto end;
    526  1.1  christos 
    527  1.1  christos     ret = SSL_do_handshake(con);
    528  1.1  christos     if (!TEST_int_le(ret, 0)
    529  1.1  christos             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
    530  1.1  christos             || !TEST_true(send_finished(con, rbio)))
    531  1.1  christos         goto end;
    532  1.1  christos 
    533  1.1  christos     ret = SSL_do_handshake(con);
    534  1.1  christos     if (!TEST_int_gt(ret, 0)
    535  1.1  christos             || !TEST_true(validate_ccs(wbio)))
    536  1.1  christos         goto end;
    537  1.1  christos 
    538  1.1  christos     /* While we're here and crafting packets by hand, we might as well do a
    539  1.1  christos        bit of a stress test on the DTLS record replay handling. Not Cisco-DTLS
    540  1.1  christos        specific but useful anyway for the general case. It's been broken
    541  1.1  christos        before, and in fact was broken even for a basic 0, 2, 1 test case
    542  1.1  christos        when this test was first added.... */
    543  1.1  christos     for (i = 0; i < (int)OSSL_NELEM(tests); i++) {
    544  1.1  christos         uint64_t recv_buf[2];
    545  1.1  christos 
    546  1.1  christos         if (!TEST_true(send_record(rbio, SSL3_RT_APPLICATION_DATA, tests[i].seq,
    547  1.1  christos                                    &tests[i].seq, sizeof(uint64_t)))) {
    548  1.1  christos             TEST_error("Failed to send data seq #0x%x%08x (%d)\n",
    549  1.1  christos                        (unsigned int)(tests[i].seq >> 32), (unsigned int)tests[i].seq, i);
    550  1.1  christos             goto end;
    551  1.1  christos         }
    552  1.1  christos 
    553  1.1  christos         if (tests[i].drop)
    554  1.1  christos             continue;
    555  1.1  christos 
    556  1.1  christos         ret = SSL_read(con, recv_buf, 2 * sizeof(uint64_t));
    557  1.1  christos         if (!TEST_int_eq(ret, (int)sizeof(uint64_t))) {
    558  1.1  christos             TEST_error("SSL_read failed or wrong size on seq#0x%x%08x (%d)\n",
    559  1.1  christos                        (unsigned int)(tests[i].seq >> 32), (unsigned int)tests[i].seq, i);
    560  1.1  christos             goto end;
    561  1.1  christos         }
    562  1.1  christos         if (!TEST_true(recv_buf[0] == tests[i].seq))
    563  1.1  christos             goto end;
    564  1.1  christos     }
    565  1.1  christos 
    566  1.1  christos     /* The last test cannot be DROP() */
    567  1.1  christos     if (!TEST_false(tests[i-1].drop))
    568  1.1  christos         goto end;
    569  1.1  christos 
    570  1.1  christos     testresult = 1;
    571  1.1  christos 
    572  1.1  christos  end:
    573  1.1  christos     BIO_free(rbio);
    574  1.1  christos     BIO_free(wbio);
    575  1.1  christos     SSL_free(con);
    576  1.1  christos     SSL_CTX_free(ctx);
    577  1.1  christos     EVP_MD_CTX_free(handshake_md);
    578  1.1  christos 
    579  1.1  christos     return testresult;
    580  1.1  christos }
    581  1.1  christos 
    582  1.1  christos int setup_tests(void)
    583  1.1  christos {
    584  1.1  christos     ADD_TEST(test_bad_dtls);
    585  1.1  christos     return 1;
    586  1.1  christos }
    587