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