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