Home | History | Annotate | Line # | Download | only in test
      1       1.1  christos /*
      2  1.1.1.10  christos  * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved.
      3       1.1  christos  *
      4   1.1.1.9  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.1.4  christos #include <string.h>
     11       1.1  christos #include <openssl/bio.h>
     12       1.1  christos #include <openssl/crypto.h>
     13       1.1  christos #include <openssl/ssl.h>
     14       1.1  christos #include <openssl/err.h>
     15       1.1  christos 
     16   1.1.1.9  christos #include "helpers/ssltestlib.h"
     17       1.1  christos #include "testutil.h"
     18       1.1  christos 
     19       1.1  christos static char *cert = NULL;
     20       1.1  christos static char *privkey = NULL;
     21   1.1.1.3  christos static unsigned int timer_cb_count;
     22       1.1  christos 
     23       1.1  christos #define NUM_TESTS   2
     24       1.1  christos 
     25       1.1  christos 
     26       1.1  christos #define DUMMY_CERT_STATUS_LEN  12
     27       1.1  christos 
     28       1.1  christos static unsigned char certstatus[] = {
     29       1.1  christos     SSL3_RT_HANDSHAKE, /* Content type */
     30       1.1  christos     0xfe, 0xfd, /* Record version */
     31       1.1  christos     0, 1, /* Epoch */
     32       1.1  christos     0, 0, 0, 0, 0, 0x0f, /* Record sequence number */
     33       1.1  christos     0, DTLS1_HM_HEADER_LENGTH + DUMMY_CERT_STATUS_LEN - 2,
     34       1.1  christos     SSL3_MT_CERTIFICATE_STATUS, /* Cert Status handshake message type */
     35       1.1  christos     0, 0, DUMMY_CERT_STATUS_LEN, /* Message len */
     36       1.1  christos     0, 5, /* Message sequence */
     37       1.1  christos     0, 0, 0, /* Fragment offset */
     38       1.1  christos     0, 0, DUMMY_CERT_STATUS_LEN - 2, /* Fragment len */
     39       1.1  christos     0x80, 0x80, 0x80, 0x80, 0x80,
     40       1.1  christos     0x80, 0x80, 0x80, 0x80, 0x80 /* Dummy data */
     41       1.1  christos };
     42       1.1  christos 
     43       1.1  christos #define RECORD_SEQUENCE 10
     44       1.1  christos 
     45   1.1.1.9  christos static const char dummy_cookie[] = "0123456";
     46   1.1.1.9  christos 
     47   1.1.1.9  christos static int generate_cookie_cb(SSL *ssl, unsigned char *cookie,
     48   1.1.1.9  christos                               unsigned int *cookie_len)
     49   1.1.1.9  christos {
     50   1.1.1.9  christos     memcpy(cookie, dummy_cookie, sizeof(dummy_cookie));
     51   1.1.1.9  christos     *cookie_len = sizeof(dummy_cookie);
     52   1.1.1.9  christos     return 1;
     53   1.1.1.9  christos }
     54   1.1.1.9  christos 
     55   1.1.1.9  christos static int verify_cookie_cb(SSL *ssl, const unsigned char *cookie,
     56   1.1.1.9  christos                             unsigned int cookie_len)
     57   1.1.1.9  christos {
     58   1.1.1.9  christos     return TEST_mem_eq(cookie, cookie_len, dummy_cookie, sizeof(dummy_cookie));
     59   1.1.1.9  christos }
     60   1.1.1.9  christos 
     61   1.1.1.3  christos static unsigned int timer_cb(SSL *s, unsigned int timer_us)
     62   1.1.1.3  christos {
     63   1.1.1.3  christos     ++timer_cb_count;
     64   1.1.1.3  christos 
     65   1.1.1.3  christos     if (timer_us == 0)
     66   1.1.1.3  christos         return 50000;
     67   1.1.1.3  christos     else
     68   1.1.1.3  christos         return 2 * timer_us;
     69   1.1.1.3  christos }
     70   1.1.1.3  christos 
     71       1.1  christos static int test_dtls_unprocessed(int testidx)
     72       1.1  christos {
     73       1.1  christos     SSL_CTX *sctx = NULL, *cctx = NULL;
     74       1.1  christos     SSL *serverssl1 = NULL, *clientssl1 = NULL;
     75       1.1  christos     BIO *c_to_s_fbio, *c_to_s_mempacket;
     76       1.1  christos     int testresult = 0;
     77       1.1  christos 
     78   1.1.1.3  christos     timer_cb_count = 0;
     79       1.1  christos 
     80   1.1.1.9  christos     if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
     81   1.1.1.3  christos                                        DTLS_client_method(),
     82   1.1.1.9  christos                                        DTLS1_VERSION, 0,
     83   1.1.1.3  christos                                        &sctx, &cctx, cert, privkey)))
     84       1.1  christos         return 0;
     85       1.1  christos 
     86   1.1.1.9  christos #ifndef OPENSSL_NO_DTLS1_2
     87   1.1.1.3  christos     if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "AES128-SHA")))
     88   1.1.1.3  christos         goto end;
     89   1.1.1.9  christos #else
     90   1.1.1.9  christos     /* Default sigalgs are SHA1 based in <DTLS1.2 which is in security level 0 */
     91   1.1.1.9  christos     if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "AES128-SHA:@SECLEVEL=0"))
     92   1.1.1.9  christos             || !TEST_true(SSL_CTX_set_cipher_list(cctx,
     93   1.1.1.9  christos                                                   "AES128-SHA:@SECLEVEL=0")))
     94   1.1.1.9  christos         goto end;
     95   1.1.1.9  christos #endif
     96       1.1  christos 
     97       1.1  christos     c_to_s_fbio = BIO_new(bio_f_tls_dump_filter());
     98   1.1.1.3  christos     if (!TEST_ptr(c_to_s_fbio))
     99       1.1  christos         goto end;
    100       1.1  christos 
    101       1.1  christos     /* BIO is freed by create_ssl_connection on error */
    102   1.1.1.3  christos     if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1,
    103   1.1.1.3  christos                                       NULL, c_to_s_fbio)))
    104       1.1  christos         goto end;
    105   1.1.1.3  christos 
    106   1.1.1.3  christos     DTLS_set_timer_cb(clientssl1, timer_cb);
    107       1.1  christos 
    108       1.1  christos     if (testidx == 1)
    109       1.1  christos         certstatus[RECORD_SEQUENCE] = 0xff;
    110       1.1  christos 
    111       1.1  christos     /*
    112       1.1  christos      * Inject a dummy record from the next epoch. In test 0, this should never
    113       1.1  christos      * get used because the message sequence number is too big. In test 1 we set
    114   1.1.1.5  christos      * the record sequence number to be way off in the future.
    115       1.1  christos      */
    116       1.1  christos     c_to_s_mempacket = SSL_get_wbio(clientssl1);
    117       1.1  christos     c_to_s_mempacket = BIO_next(c_to_s_mempacket);
    118       1.1  christos     mempacket_test_inject(c_to_s_mempacket, (char *)certstatus,
    119       1.1  christos                           sizeof(certstatus), 1, INJECT_PACKET_IGNORE_REC_SEQ);
    120       1.1  christos 
    121   1.1.1.5  christos     /*
    122   1.1.1.5  christos      * Create the connection. We use "create_bare_ssl_connection" here so that
    123   1.1.1.6  christos      * we can force the connection to not do "SSL_read" once partly connected.
    124   1.1.1.5  christos      * We don't want to accidentally read the dummy records we injected because
    125   1.1.1.5  christos      * they will fail to decrypt.
    126   1.1.1.5  christos      */
    127   1.1.1.5  christos     if (!TEST_true(create_bare_ssl_connection(serverssl1, clientssl1,
    128   1.1.1.5  christos                                               SSL_ERROR_NONE, 0)))
    129   1.1.1.3  christos         goto end;
    130   1.1.1.3  christos 
    131   1.1.1.3  christos     if (timer_cb_count == 0) {
    132   1.1.1.3  christos         printf("timer_callback was not called.\n");
    133       1.1  christos         goto end;
    134       1.1  christos     }
    135       1.1  christos 
    136       1.1  christos     testresult = 1;
    137       1.1  christos  end:
    138       1.1  christos     SSL_free(serverssl1);
    139       1.1  christos     SSL_free(clientssl1);
    140       1.1  christos     SSL_CTX_free(sctx);
    141       1.1  christos     SSL_CTX_free(cctx);
    142       1.1  christos 
    143       1.1  christos     return testresult;
    144       1.1  christos }
    145       1.1  christos 
    146   1.1.1.9  christos /* One record for the cookieless initial ClientHello */
    147   1.1.1.9  christos #define CLI_TO_SRV_COOKIE_EXCH 1
    148   1.1.1.9  christos 
    149   1.1.1.9  christos /*
    150   1.1.1.9  christos  * In a resumption handshake we use 2 records for the initial ClientHello in
    151   1.1.1.9  christos  * this test because we are using a very small MTU and the ClientHello is
    152   1.1.1.9  christos  * bigger than in the non resumption case.
    153   1.1.1.9  christos  */
    154   1.1.1.9  christos #define CLI_TO_SRV_RESUME_COOKIE_EXCH 2
    155   1.1.1.9  christos #define SRV_TO_CLI_COOKIE_EXCH 1
    156   1.1.1.9  christos 
    157   1.1.1.3  christos #define CLI_TO_SRV_EPOCH_0_RECS 3
    158   1.1.1.3  christos #define CLI_TO_SRV_EPOCH_1_RECS 1
    159   1.1.1.3  christos #if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
    160   1.1.1.7  christos # define SRV_TO_CLI_EPOCH_0_RECS 10
    161   1.1.1.3  christos #else
    162   1.1.1.3  christos /*
    163   1.1.1.3  christos  * In this case we have no ServerKeyExchange message, because we don't have
    164   1.1.1.3  christos  * ECDHE or DHE. When it is present it gets fragmented into 3 records in this
    165   1.1.1.3  christos  * test.
    166   1.1.1.3  christos  */
    167   1.1.1.3  christos # define SRV_TO_CLI_EPOCH_0_RECS 9
    168   1.1.1.3  christos #endif
    169   1.1.1.3  christos #define SRV_TO_CLI_EPOCH_1_RECS 1
    170   1.1.1.3  christos #define TOTAL_FULL_HAND_RECORDS \
    171   1.1.1.9  christos             (CLI_TO_SRV_COOKIE_EXCH + SRV_TO_CLI_COOKIE_EXCH + \
    172   1.1.1.9  christos              CLI_TO_SRV_EPOCH_0_RECS + CLI_TO_SRV_EPOCH_1_RECS + \
    173   1.1.1.3  christos              SRV_TO_CLI_EPOCH_0_RECS + SRV_TO_CLI_EPOCH_1_RECS)
    174   1.1.1.3  christos 
    175   1.1.1.3  christos #define CLI_TO_SRV_RESUME_EPOCH_0_RECS 3
    176   1.1.1.3  christos #define CLI_TO_SRV_RESUME_EPOCH_1_RECS 1
    177   1.1.1.3  christos #define SRV_TO_CLI_RESUME_EPOCH_0_RECS 2
    178   1.1.1.3  christos #define SRV_TO_CLI_RESUME_EPOCH_1_RECS 1
    179   1.1.1.3  christos #define TOTAL_RESUME_HAND_RECORDS \
    180   1.1.1.9  christos             (CLI_TO_SRV_RESUME_COOKIE_EXCH + SRV_TO_CLI_COOKIE_EXCH + \
    181   1.1.1.9  christos              CLI_TO_SRV_RESUME_EPOCH_0_RECS + CLI_TO_SRV_RESUME_EPOCH_1_RECS + \
    182   1.1.1.3  christos              SRV_TO_CLI_RESUME_EPOCH_0_RECS + SRV_TO_CLI_RESUME_EPOCH_1_RECS)
    183   1.1.1.3  christos 
    184   1.1.1.3  christos #define TOTAL_RECORDS (TOTAL_FULL_HAND_RECORDS + TOTAL_RESUME_HAND_RECORDS)
    185   1.1.1.3  christos 
    186   1.1.1.9  christos /*
    187   1.1.1.9  christos  * We are assuming a ServerKeyExchange message is sent in this test. If we don't
    188   1.1.1.9  christos  * have either DH or EC, then it won't be
    189   1.1.1.9  christos  */
    190   1.1.1.9  christos #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)
    191   1.1.1.3  christos static int test_dtls_drop_records(int idx)
    192       1.1  christos {
    193   1.1.1.3  christos     SSL_CTX *sctx = NULL, *cctx = NULL;
    194   1.1.1.3  christos     SSL *serverssl = NULL, *clientssl = NULL;
    195   1.1.1.3  christos     BIO *c_to_s_fbio, *mempackbio;
    196   1.1.1.3  christos     int testresult = 0;
    197   1.1.1.3  christos     int epoch = 0;
    198   1.1.1.3  christos     SSL_SESSION *sess = NULL;
    199   1.1.1.9  christos     int cli_to_srv_cookie, cli_to_srv_epoch0, cli_to_srv_epoch1;
    200   1.1.1.9  christos     int srv_to_cli_epoch0;
    201   1.1.1.3  christos 
    202   1.1.1.9  christos     if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
    203   1.1.1.3  christos                                        DTLS_client_method(),
    204   1.1.1.9  christos                                        DTLS1_VERSION, 0,
    205   1.1.1.3  christos                                        &sctx, &cctx, cert, privkey)))
    206   1.1.1.3  christos         return 0;
    207       1.1  christos 
    208   1.1.1.9  christos #ifdef OPENSSL_NO_DTLS1_2
    209   1.1.1.9  christos     /* Default sigalgs are SHA1 based in <DTLS1.2 which is in security level 0 */
    210   1.1.1.9  christos     if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "DEFAULT:@SECLEVEL=0"))
    211   1.1.1.9  christos             || !TEST_true(SSL_CTX_set_cipher_list(cctx,
    212   1.1.1.9  christos                                                   "DEFAULT:@SECLEVEL=0")))
    213   1.1.1.9  christos         goto end;
    214   1.1.1.9  christos #endif
    215   1.1.1.9  christos 
    216   1.1.1.9  christos     if (!TEST_true(SSL_CTX_set_dh_auto(sctx, 1)))
    217   1.1.1.9  christos         goto end;
    218   1.1.1.9  christos 
    219   1.1.1.9  christos     SSL_CTX_set_options(sctx, SSL_OP_COOKIE_EXCHANGE);
    220   1.1.1.9  christos     SSL_CTX_set_cookie_generate_cb(sctx, generate_cookie_cb);
    221   1.1.1.9  christos     SSL_CTX_set_cookie_verify_cb(sctx, verify_cookie_cb);
    222   1.1.1.9  christos 
    223   1.1.1.3  christos     if (idx >= TOTAL_FULL_HAND_RECORDS) {
    224   1.1.1.3  christos         /* We're going to do a resumption handshake. Get a session first. */
    225   1.1.1.3  christos         if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
    226   1.1.1.3  christos                                           NULL, NULL))
    227   1.1.1.3  christos                 || !TEST_true(create_ssl_connection(serverssl, clientssl,
    228   1.1.1.3  christos                               SSL_ERROR_NONE))
    229   1.1.1.3  christos                 || !TEST_ptr(sess = SSL_get1_session(clientssl)))
    230   1.1.1.3  christos             goto end;
    231   1.1.1.3  christos 
    232   1.1.1.3  christos         SSL_shutdown(clientssl);
    233   1.1.1.3  christos         SSL_shutdown(serverssl);
    234   1.1.1.3  christos         SSL_free(serverssl);
    235   1.1.1.3  christos         SSL_free(clientssl);
    236   1.1.1.3  christos         serverssl = clientssl = NULL;
    237   1.1.1.3  christos 
    238   1.1.1.3  christos         cli_to_srv_epoch0 = CLI_TO_SRV_RESUME_EPOCH_0_RECS;
    239   1.1.1.3  christos         cli_to_srv_epoch1 = CLI_TO_SRV_RESUME_EPOCH_1_RECS;
    240   1.1.1.3  christos         srv_to_cli_epoch0 = SRV_TO_CLI_RESUME_EPOCH_0_RECS;
    241   1.1.1.9  christos         cli_to_srv_cookie = CLI_TO_SRV_RESUME_COOKIE_EXCH;
    242   1.1.1.3  christos         idx -= TOTAL_FULL_HAND_RECORDS;
    243   1.1.1.3  christos     } else {
    244   1.1.1.3  christos         cli_to_srv_epoch0 = CLI_TO_SRV_EPOCH_0_RECS;
    245   1.1.1.3  christos         cli_to_srv_epoch1 = CLI_TO_SRV_EPOCH_1_RECS;
    246   1.1.1.3  christos         srv_to_cli_epoch0 = SRV_TO_CLI_EPOCH_0_RECS;
    247   1.1.1.9  christos         cli_to_srv_cookie = CLI_TO_SRV_COOKIE_EXCH;
    248       1.1  christos     }
    249       1.1  christos 
    250   1.1.1.3  christos     c_to_s_fbio = BIO_new(bio_f_tls_dump_filter());
    251   1.1.1.3  christos     if (!TEST_ptr(c_to_s_fbio))
    252   1.1.1.3  christos         goto end;
    253       1.1  christos 
    254   1.1.1.3  christos     /* BIO is freed by create_ssl_connection on error */
    255   1.1.1.3  christos     if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
    256   1.1.1.3  christos                                       NULL, c_to_s_fbio)))
    257   1.1.1.3  christos         goto end;
    258       1.1  christos 
    259   1.1.1.3  christos     if (sess != NULL) {
    260   1.1.1.3  christos         if (!TEST_true(SSL_set_session(clientssl, sess)))
    261   1.1.1.3  christos             goto end;
    262   1.1.1.3  christos     }
    263   1.1.1.3  christos 
    264   1.1.1.3  christos     DTLS_set_timer_cb(clientssl, timer_cb);
    265   1.1.1.3  christos     DTLS_set_timer_cb(serverssl, timer_cb);
    266   1.1.1.3  christos 
    267   1.1.1.3  christos     /* Work out which record to drop based on the test number */
    268   1.1.1.9  christos     if (idx >= cli_to_srv_cookie + cli_to_srv_epoch0 + cli_to_srv_epoch1) {
    269   1.1.1.3  christos         mempackbio = SSL_get_wbio(serverssl);
    270   1.1.1.9  christos         idx -= cli_to_srv_cookie + cli_to_srv_epoch0 + cli_to_srv_epoch1;
    271   1.1.1.9  christos         if (idx >= SRV_TO_CLI_COOKIE_EXCH + srv_to_cli_epoch0) {
    272   1.1.1.3  christos             epoch = 1;
    273   1.1.1.9  christos             idx -= SRV_TO_CLI_COOKIE_EXCH + srv_to_cli_epoch0;
    274   1.1.1.3  christos         }
    275   1.1.1.3  christos     } else {
    276   1.1.1.3  christos         mempackbio = SSL_get_wbio(clientssl);
    277   1.1.1.9  christos         if (idx >= cli_to_srv_cookie + cli_to_srv_epoch0) {
    278   1.1.1.3  christos             epoch = 1;
    279   1.1.1.9  christos             idx -= cli_to_srv_cookie + cli_to_srv_epoch0;
    280   1.1.1.3  christos         }
    281   1.1.1.3  christos          mempackbio = BIO_next(mempackbio);
    282   1.1.1.3  christos     }
    283   1.1.1.3  christos     BIO_ctrl(mempackbio, MEMPACKET_CTRL_SET_DROP_EPOCH, epoch, NULL);
    284   1.1.1.3  christos     BIO_ctrl(mempackbio, MEMPACKET_CTRL_SET_DROP_REC, idx, NULL);
    285       1.1  christos 
    286   1.1.1.3  christos     if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
    287   1.1.1.3  christos         goto end;
    288       1.1  christos 
    289   1.1.1.3  christos     if (sess != NULL && !TEST_true(SSL_session_reused(clientssl)))
    290   1.1.1.3  christos         goto end;
    291       1.1  christos 
    292   1.1.1.3  christos     /* If the test did what we planned then it should have dropped a record */
    293   1.1.1.3  christos     if (!TEST_int_eq((int)BIO_ctrl(mempackbio, MEMPACKET_CTRL_GET_DROP_REC, 0,
    294   1.1.1.3  christos                                    NULL), -1))
    295   1.1.1.3  christos         goto end;
    296       1.1  christos 
    297   1.1.1.3  christos     testresult = 1;
    298   1.1.1.3  christos  end:
    299   1.1.1.3  christos     SSL_SESSION_free(sess);
    300   1.1.1.3  christos     SSL_free(serverssl);
    301   1.1.1.3  christos     SSL_free(clientssl);
    302   1.1.1.3  christos     SSL_CTX_free(sctx);
    303   1.1.1.3  christos     SSL_CTX_free(cctx);
    304       1.1  christos 
    305       1.1  christos     return testresult;
    306       1.1  christos }
    307   1.1.1.9  christos #endif /* !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) */
    308   1.1.1.4  christos 
    309   1.1.1.4  christos static int test_cookie(void)
    310   1.1.1.4  christos {
    311   1.1.1.4  christos     SSL_CTX *sctx = NULL, *cctx = NULL;
    312   1.1.1.4  christos     SSL *serverssl = NULL, *clientssl = NULL;
    313   1.1.1.4  christos     int testresult = 0;
    314   1.1.1.4  christos 
    315   1.1.1.9  christos     if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
    316   1.1.1.4  christos                                        DTLS_client_method(),
    317   1.1.1.9  christos                                        DTLS1_VERSION, 0,
    318   1.1.1.4  christos                                        &sctx, &cctx, cert, privkey)))
    319   1.1.1.4  christos         return 0;
    320   1.1.1.4  christos 
    321   1.1.1.4  christos     SSL_CTX_set_options(sctx, SSL_OP_COOKIE_EXCHANGE);
    322   1.1.1.4  christos     SSL_CTX_set_cookie_generate_cb(sctx, generate_cookie_cb);
    323   1.1.1.4  christos     SSL_CTX_set_cookie_verify_cb(sctx, verify_cookie_cb);
    324   1.1.1.4  christos 
    325   1.1.1.9  christos #ifdef OPENSSL_NO_DTLS1_2
    326   1.1.1.9  christos     /* Default sigalgs are SHA1 based in <DTLS1.2 which is in security level 0 */
    327   1.1.1.9  christos     if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "DEFAULT:@SECLEVEL=0"))
    328   1.1.1.9  christos             || !TEST_true(SSL_CTX_set_cipher_list(cctx,
    329   1.1.1.9  christos                                                   "DEFAULT:@SECLEVEL=0")))
    330   1.1.1.9  christos         goto end;
    331   1.1.1.9  christos #endif
    332   1.1.1.9  christos 
    333   1.1.1.4  christos     if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
    334   1.1.1.4  christos                                       NULL, NULL))
    335   1.1.1.4  christos             || !TEST_true(create_ssl_connection(serverssl, clientssl,
    336   1.1.1.4  christos                                                 SSL_ERROR_NONE)))
    337   1.1.1.4  christos         goto end;
    338   1.1.1.4  christos 
    339   1.1.1.4  christos     testresult = 1;
    340   1.1.1.4  christos  end:
    341   1.1.1.4  christos     SSL_free(serverssl);
    342   1.1.1.4  christos     SSL_free(clientssl);
    343   1.1.1.4  christos     SSL_CTX_free(sctx);
    344   1.1.1.4  christos     SSL_CTX_free(cctx);
    345   1.1.1.4  christos 
    346   1.1.1.4  christos     return testresult;
    347   1.1.1.4  christos }
    348   1.1.1.4  christos 
    349   1.1.1.4  christos static int test_dtls_duplicate_records(void)
    350   1.1.1.4  christos {
    351   1.1.1.4  christos     SSL_CTX *sctx = NULL, *cctx = NULL;
    352   1.1.1.4  christos     SSL *serverssl = NULL, *clientssl = NULL;
    353   1.1.1.4  christos     int testresult = 0;
    354   1.1.1.4  christos 
    355   1.1.1.9  christos     if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
    356   1.1.1.4  christos                                        DTLS_client_method(),
    357   1.1.1.9  christos                                        DTLS1_VERSION, 0,
    358   1.1.1.4  christos                                        &sctx, &cctx, cert, privkey)))
    359   1.1.1.4  christos         return 0;
    360   1.1.1.4  christos 
    361   1.1.1.9  christos #ifdef OPENSSL_NO_DTLS1_2
    362   1.1.1.9  christos     /* Default sigalgs are SHA1 based in <DTLS1.2 which is in security level 0 */
    363   1.1.1.9  christos     if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "DEFAULT:@SECLEVEL=0"))
    364   1.1.1.9  christos             || !TEST_true(SSL_CTX_set_cipher_list(cctx,
    365   1.1.1.9  christos                                                   "DEFAULT:@SECLEVEL=0")))
    366   1.1.1.9  christos         goto end;
    367   1.1.1.9  christos #endif
    368   1.1.1.9  christos 
    369   1.1.1.4  christos     if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
    370   1.1.1.4  christos                                       NULL, NULL)))
    371   1.1.1.4  christos         goto end;
    372   1.1.1.4  christos 
    373   1.1.1.4  christos     DTLS_set_timer_cb(clientssl, timer_cb);
    374   1.1.1.4  christos     DTLS_set_timer_cb(serverssl, timer_cb);
    375   1.1.1.4  christos 
    376   1.1.1.4  christos     BIO_ctrl(SSL_get_wbio(clientssl), MEMPACKET_CTRL_SET_DUPLICATE_REC, 1, NULL);
    377   1.1.1.4  christos     BIO_ctrl(SSL_get_wbio(serverssl), MEMPACKET_CTRL_SET_DUPLICATE_REC, 1, NULL);
    378   1.1.1.4  christos 
    379   1.1.1.4  christos     if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
    380   1.1.1.4  christos         goto end;
    381   1.1.1.4  christos 
    382   1.1.1.4  christos     testresult = 1;
    383   1.1.1.4  christos  end:
    384   1.1.1.4  christos     SSL_free(serverssl);
    385   1.1.1.4  christos     SSL_free(clientssl);
    386   1.1.1.4  christos     SSL_CTX_free(sctx);
    387   1.1.1.4  christos     SSL_CTX_free(cctx);
    388   1.1.1.4  christos 
    389   1.1.1.4  christos     return testresult;
    390   1.1.1.4  christos }
    391   1.1.1.4  christos 
    392   1.1.1.8  christos /*
    393   1.1.1.9  christos  * Test just sending a Finished message as the first message. Should fail due
    394   1.1.1.9  christos  * to an unexpected message.
    395   1.1.1.9  christos  */
    396   1.1.1.9  christos static int test_just_finished(void)
    397   1.1.1.9  christos {
    398   1.1.1.9  christos     int testresult = 0, ret;
    399   1.1.1.9  christos     SSL_CTX *sctx = NULL;
    400   1.1.1.9  christos     SSL *serverssl = NULL;
    401   1.1.1.9  christos     BIO *rbio = NULL, *wbio = NULL, *sbio = NULL;
    402   1.1.1.9  christos     unsigned char buf[] = {
    403   1.1.1.9  christos         /* Record header */
    404   1.1.1.9  christos         SSL3_RT_HANDSHAKE, /* content type */
    405   1.1.1.9  christos         (DTLS1_2_VERSION >> 8) & 0xff, /* protocol version hi byte */
    406   1.1.1.9  christos         DTLS1_2_VERSION & 0xff, /* protocol version lo byte */
    407   1.1.1.9  christos         0, 0, /* epoch */
    408   1.1.1.9  christos         0, 0, 0, 0, 0, 0, /* record sequence */
    409   1.1.1.9  christos         0, DTLS1_HM_HEADER_LENGTH + SHA_DIGEST_LENGTH, /* record length */
    410   1.1.1.9  christos 
    411   1.1.1.9  christos         /* Message header */
    412   1.1.1.9  christos         SSL3_MT_FINISHED, /* message type */
    413   1.1.1.9  christos         0, 0, SHA_DIGEST_LENGTH, /* message length */
    414   1.1.1.9  christos         0, 0, /* message sequence */
    415   1.1.1.9  christos         0, 0, 0, /* fragment offset */
    416   1.1.1.9  christos         0, 0, SHA_DIGEST_LENGTH, /* fragment length */
    417   1.1.1.9  christos 
    418   1.1.1.9  christos         /* Message body */
    419   1.1.1.9  christos         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    420   1.1.1.9  christos     };
    421   1.1.1.9  christos 
    422   1.1.1.9  christos 
    423   1.1.1.9  christos     if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
    424   1.1.1.9  christos                                        NULL, 0, 0,
    425   1.1.1.9  christos                                        &sctx, NULL, cert, privkey)))
    426   1.1.1.9  christos         return 0;
    427   1.1.1.9  christos 
    428   1.1.1.9  christos     serverssl = SSL_new(sctx);
    429   1.1.1.9  christos     rbio = BIO_new(BIO_s_mem());
    430   1.1.1.9  christos     wbio = BIO_new(BIO_s_mem());
    431   1.1.1.9  christos 
    432   1.1.1.9  christos     if (!TEST_ptr(serverssl) || !TEST_ptr(rbio) || !TEST_ptr(wbio))
    433   1.1.1.9  christos         goto end;
    434   1.1.1.9  christos 
    435   1.1.1.9  christos     sbio = rbio;
    436   1.1.1.9  christos     SSL_set0_rbio(serverssl, rbio);
    437   1.1.1.9  christos     SSL_set0_wbio(serverssl, wbio);
    438   1.1.1.9  christos     rbio = wbio = NULL;
    439   1.1.1.9  christos     DTLS_set_timer_cb(serverssl, timer_cb);
    440   1.1.1.9  christos 
    441   1.1.1.9  christos     if (!TEST_int_eq(BIO_write(sbio, buf, sizeof(buf)), sizeof(buf)))
    442   1.1.1.9  christos         goto end;
    443   1.1.1.9  christos 
    444   1.1.1.9  christos     /* We expect the attempt to process the message to fail */
    445   1.1.1.9  christos     if (!TEST_int_le(ret = SSL_accept(serverssl), 0))
    446   1.1.1.9  christos         goto end;
    447   1.1.1.9  christos 
    448   1.1.1.9  christos     /* Check that we got the error we were expecting */
    449   1.1.1.9  christos     if (!TEST_int_eq(SSL_get_error(serverssl, ret), SSL_ERROR_SSL))
    450   1.1.1.9  christos         goto end;
    451   1.1.1.9  christos 
    452   1.1.1.9  christos     if (!TEST_int_eq(ERR_GET_REASON(ERR_get_error()), SSL_R_UNEXPECTED_MESSAGE))
    453   1.1.1.9  christos         goto end;
    454   1.1.1.9  christos 
    455   1.1.1.9  christos     testresult = 1;
    456   1.1.1.9  christos  end:
    457   1.1.1.9  christos     BIO_free(rbio);
    458   1.1.1.9  christos     BIO_free(wbio);
    459   1.1.1.9  christos     SSL_free(serverssl);
    460   1.1.1.9  christos     SSL_CTX_free(sctx);
    461   1.1.1.9  christos 
    462   1.1.1.9  christos     return testresult;
    463   1.1.1.9  christos }
    464   1.1.1.9  christos 
    465   1.1.1.9  christos /*
    466  1.1.1.10  christos  * Test that swapping later records before Finished or CCS still works
    467  1.1.1.10  christos  * Test 0: Test receiving a handshake record early from next epoch on server side
    468  1.1.1.10  christos  * Test 1: Test receiving a handshake record early from next epoch on client side
    469  1.1.1.10  christos  * Test 2: Test receiving an app data record early from next epoch on client side
    470  1.1.1.10  christos  * Test 3: Test receiving an app data before Finished on client side
    471   1.1.1.8  christos  */
    472  1.1.1.10  christos static int test_swap_records(int idx)
    473   1.1.1.8  christos {
    474   1.1.1.8  christos     SSL_CTX *sctx = NULL, *cctx = NULL;
    475   1.1.1.8  christos     SSL *sssl = NULL, *cssl = NULL;
    476   1.1.1.8  christos     int testresult = 0;
    477   1.1.1.8  christos     BIO *bio;
    478   1.1.1.8  christos     char msg[] = { 0x00, 0x01, 0x02, 0x03 };
    479   1.1.1.8  christos     char buf[10];
    480   1.1.1.8  christos 
    481   1.1.1.9  christos     if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(),
    482   1.1.1.8  christos                                        DTLS_client_method(),
    483   1.1.1.8  christos                                        DTLS1_VERSION, 0,
    484   1.1.1.8  christos                                        &sctx, &cctx, cert, privkey)))
    485   1.1.1.8  christos         return 0;
    486   1.1.1.8  christos 
    487   1.1.1.8  christos #ifndef OPENSSL_NO_DTLS1_2
    488   1.1.1.8  christos     if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "AES128-SHA")))
    489   1.1.1.8  christos         goto end;
    490   1.1.1.8  christos #else
    491   1.1.1.8  christos     /* Default sigalgs are SHA1 based in <DTLS1.2 which is in security level 0 */
    492   1.1.1.8  christos     if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "AES128-SHA:@SECLEVEL=0"))
    493   1.1.1.8  christos             || !TEST_true(SSL_CTX_set_cipher_list(cctx,
    494   1.1.1.8  christos                                                   "AES128-SHA:@SECLEVEL=0")))
    495   1.1.1.8  christos         goto end;
    496   1.1.1.8  christos #endif
    497   1.1.1.8  christos 
    498   1.1.1.8  christos     if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl,
    499   1.1.1.8  christos                                       NULL, NULL)))
    500   1.1.1.8  christos         goto end;
    501   1.1.1.8  christos 
    502   1.1.1.8  christos     /* Send flight 1: ClientHello */
    503   1.1.1.8  christos     if (!TEST_int_le(SSL_connect(cssl), 0))
    504   1.1.1.8  christos         goto end;
    505   1.1.1.8  christos 
    506   1.1.1.8  christos     /* Recv flight 1, send flight 2: ServerHello, Certificate, ServerHelloDone */
    507   1.1.1.8  christos     if (!TEST_int_le(SSL_accept(sssl), 0))
    508   1.1.1.8  christos         goto end;
    509   1.1.1.8  christos 
    510   1.1.1.8  christos     /* Recv flight 2, send flight 3: ClientKeyExchange, CCS, Finished */
    511   1.1.1.8  christos     if (!TEST_int_le(SSL_connect(cssl), 0))
    512   1.1.1.8  christos         goto end;
    513   1.1.1.8  christos 
    514  1.1.1.10  christos     if (idx == 0) {
    515  1.1.1.10  christos         /* Swap Finished and CCS within the datagram */
    516  1.1.1.10  christos         bio = SSL_get_wbio(cssl);
    517  1.1.1.10  christos         if (!TEST_ptr(bio)
    518  1.1.1.10  christos                 || !TEST_true(mempacket_swap_epoch(bio)))
    519  1.1.1.10  christos             goto end;
    520  1.1.1.10  christos     }
    521  1.1.1.10  christos 
    522  1.1.1.10  christos     /* Recv flight 3, send flight 4: datagram 0(NST, CCS) datagram 1(Finished) */
    523   1.1.1.8  christos     if (!TEST_int_gt(SSL_accept(sssl), 0))
    524   1.1.1.8  christos         goto end;
    525   1.1.1.8  christos 
    526  1.1.1.10  christos     /* Send flight 4 (cont'd): datagram 2(app data) */
    527   1.1.1.8  christos     if (!TEST_int_eq(SSL_write(sssl, msg, sizeof(msg)), (int)sizeof(msg)))
    528   1.1.1.8  christos         goto end;
    529   1.1.1.8  christos 
    530   1.1.1.8  christos     bio = SSL_get_wbio(sssl);
    531  1.1.1.10  christos     if (!TEST_ptr(bio))
    532   1.1.1.8  christos         goto end;
    533  1.1.1.10  christos     if (idx == 1) {
    534  1.1.1.10  christos         /* Finished comes before NST/CCS */
    535  1.1.1.10  christos         if (!TEST_true(mempacket_move_packet(bio, 0, 1)))
    536  1.1.1.10  christos             goto end;
    537  1.1.1.10  christos     } else if (idx == 2) {
    538  1.1.1.10  christos         /* App data comes before NST/CCS */
    539  1.1.1.10  christos         if (!TEST_true(mempacket_move_packet(bio, 0, 2)))
    540  1.1.1.10  christos             goto end;
    541  1.1.1.10  christos     } else if (idx == 3) {
    542  1.1.1.10  christos         /* App data comes before Finished */
    543  1.1.1.10  christos         bio = SSL_get_wbio(sssl);
    544  1.1.1.10  christos         if (!TEST_true(mempacket_move_packet(bio, 1, 2)))
    545  1.1.1.10  christos             goto end;
    546  1.1.1.10  christos     }
    547   1.1.1.8  christos 
    548   1.1.1.8  christos     /*
    549   1.1.1.8  christos      * Recv flight 4 (datagram 1): NST, CCS, + flight 5: app data
    550   1.1.1.8  christos      *      + flight 4 (datagram 2): Finished
    551   1.1.1.8  christos      */
    552   1.1.1.8  christos     if (!TEST_int_gt(SSL_connect(cssl), 0))
    553   1.1.1.8  christos         goto end;
    554   1.1.1.8  christos 
    555  1.1.1.10  christos     if (idx == 0 || idx == 1) {
    556  1.1.1.10  christos         /* App data was not received early, so it should not be pending */
    557  1.1.1.10  christos         if (!TEST_int_eq(SSL_pending(cssl), 0)
    558  1.1.1.10  christos                 || !TEST_false(SSL_has_pending(cssl)))
    559  1.1.1.10  christos             goto end;
    560  1.1.1.10  christos 
    561  1.1.1.10  christos     } else {
    562  1.1.1.10  christos         /* We received the app data early so it should be buffered already */
    563  1.1.1.10  christos         if (!TEST_int_eq(SSL_pending(cssl), (int)sizeof(msg))
    564  1.1.1.10  christos                 || !TEST_true(SSL_has_pending(cssl)))
    565  1.1.1.10  christos             goto end;
    566  1.1.1.10  christos     }
    567   1.1.1.8  christos 
    568   1.1.1.8  christos     /*
    569  1.1.1.10  christos     * Recv flight 5 (app data)
    570  1.1.1.10  christos     */
    571   1.1.1.8  christos     if (!TEST_int_eq(SSL_read(cssl, buf, sizeof(buf)), (int)sizeof(msg)))
    572   1.1.1.8  christos         goto end;
    573   1.1.1.8  christos 
    574   1.1.1.8  christos     testresult = 1;
    575   1.1.1.8  christos  end:
    576   1.1.1.8  christos     SSL_free(cssl);
    577   1.1.1.8  christos     SSL_free(sssl);
    578   1.1.1.8  christos     SSL_CTX_free(cctx);
    579   1.1.1.8  christos     SSL_CTX_free(sctx);
    580   1.1.1.8  christos     return testresult;
    581   1.1.1.8  christos }
    582   1.1.1.8  christos 
    583   1.1.1.9  christos OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n")
    584   1.1.1.9  christos 
    585   1.1.1.3  christos int setup_tests(void)
    586   1.1.1.3  christos {
    587   1.1.1.9  christos     if (!test_skip_common_options()) {
    588   1.1.1.9  christos         TEST_error("Error parsing test options\n");
    589   1.1.1.9  christos         return 0;
    590   1.1.1.9  christos     }
    591   1.1.1.9  christos 
    592   1.1.1.3  christos     if (!TEST_ptr(cert = test_get_argument(0))
    593   1.1.1.3  christos             || !TEST_ptr(privkey = test_get_argument(1)))
    594   1.1.1.3  christos         return 0;
    595   1.1.1.3  christos 
    596   1.1.1.3  christos     ADD_ALL_TESTS(test_dtls_unprocessed, NUM_TESTS);
    597   1.1.1.9  christos #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)
    598   1.1.1.3  christos     ADD_ALL_TESTS(test_dtls_drop_records, TOTAL_RECORDS);
    599   1.1.1.9  christos #endif
    600   1.1.1.4  christos     ADD_TEST(test_cookie);
    601   1.1.1.4  christos     ADD_TEST(test_dtls_duplicate_records);
    602   1.1.1.9  christos     ADD_TEST(test_just_finished);
    603  1.1.1.10  christos     ADD_ALL_TESTS(test_swap_records, 4);
    604   1.1.1.3  christos 
    605   1.1.1.3  christos     return 1;
    606   1.1.1.3  christos }
    607   1.1.1.3  christos 
    608   1.1.1.3  christos void cleanup_tests(void)
    609   1.1.1.3  christos {
    610   1.1.1.3  christos     bio_f_tls_dump_filter_free();
    611   1.1.1.3  christos     bio_s_mempacket_test_free();
    612   1.1.1.3  christos }
    613