Add a DTLS unprocesed records test
[openssl.git] / ssl / dtlstest.c
1 /*
2  * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <openssl/bio.h>
11 #include <openssl/crypto.h>
12 #include <openssl/ssl.h>
13 #include <openssl/err.h>
14
15 #include "ssltestlib.h"
16 #include "testutil.h"
17
18 static char *cert = NULL;
19 static char *privkey = NULL;
20
21
22 #define DUMMY_CERT_STATUS_LEN  12
23
24 unsigned char certstatus[] = {
25     SSL3_RT_HANDSHAKE, /* Content type */
26     0xfe, 0xfd, /* Record version */
27     0, 1, /* Epoch */
28     0, 0, 0, 0, 0, 0x0f, /* Record sequence number */
29     0, DTLS1_HM_HEADER_LENGTH + DUMMY_CERT_STATUS_LEN - 2,
30     SSL3_MT_CERTIFICATE_STATUS, /* Cert Status handshake message type */
31     0, 0, DUMMY_CERT_STATUS_LEN, /* Message len */
32     0, 5, /* Message sequence */
33     0, 0, 0, /* Fragment offset */
34     0, 0, DUMMY_CERT_STATUS_LEN - 2, /* Fragment len */
35     0x80, 0x80, 0x80, 0x80, 0x80,
36     0x80, 0x80, 0x80, 0x80, 0x80 /* Dummy data */
37 };
38
39 static int test_dtls_unprocessed(void)
40 {
41     SSL_CTX *sctx = NULL, *cctx = NULL;
42     SSL *serverssl1 = NULL, *clientssl1 = NULL;
43     BIO *c_to_s_fbio, *c_to_s_mempacket;
44     int testresult = 0;
45
46     if (!create_ssl_ctx_pair(DTLS_server_method(), DTLS_client_method(), &sctx,
47                              &cctx, cert, privkey)) {
48         printf("Unable to create SSL_CTX pair\n");
49         return 0;
50     }
51
52     if (!SSL_CTX_set_ecdh_auto(sctx, 1)) {
53         printf("Failed configuring auto ECDH\n");
54     }
55
56     if (!SSL_CTX_set_cipher_list(cctx, "ECDHE-RSA-AES256-SHA384")) {
57         printf("Failed setting cipher list\n");
58     }
59
60     c_to_s_fbio = BIO_new(bio_f_tls_dump_filter());
61     if (c_to_s_fbio == NULL) {
62         printf("Failed to create filter BIO\n");
63         goto end;
64     }
65
66     /* BIO is freed by create_ssl_connection on error */
67     if (!create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1, NULL,
68                                c_to_s_fbio)) {
69         printf("Unable to create SSL objects\n");
70         ERR_print_errors_fp(stdout);
71         goto end;
72     }
73
74     /*
75      * Inject a dummy record from the next epoch. This should never get used
76      * because the message sequence number is too big
77      */
78     c_to_s_mempacket = SSL_get_wbio(clientssl1);
79     c_to_s_mempacket = BIO_next(c_to_s_mempacket);
80     mempacket_test_inject(c_to_s_mempacket, (char *)certstatus,
81                           sizeof(certstatus), 1, INJECT_PACKET_IGNORE_REC_SEQ);
82
83     if (!create_ssl_connection(serverssl1, clientssl1)) {
84         printf("Unable to create SSL connection\n");
85         ERR_print_errors_fp(stdout);
86         goto end;
87     }
88
89     testresult = 1;
90  end:
91     SSL_free(serverssl1);
92     SSL_free(clientssl1);
93     SSL_CTX_free(sctx);
94     SSL_CTX_free(cctx);
95
96     return testresult;
97 }
98
99 int main(int argc, char *argv[])
100 {
101     BIO *err = NULL;
102     int testresult = 0;
103
104     if (argc != 3) {
105         printf("Invalid argument count\n");
106         return 1;
107     }
108
109     cert = argv[1];
110     privkey = argv[2];
111
112     err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
113
114     SSL_library_init();
115     SSL_load_error_strings();
116
117     CRYPTO_malloc_debug_init();
118     CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
119     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
120
121     if (!test_dtls_unprocessed())
122         testresult = 1;
123
124     ERR_free_strings();
125     ERR_remove_thread_state(NULL);
126     EVP_cleanup();
127     CRYPTO_cleanup_all_ex_data();
128     CRYPTO_mem_leaks(err);
129     BIO_free(err);
130
131     if (!testresult)
132         printf("PASS\n");
133
134     return testresult;
135 }