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