xref: /openssl/test/bad_dtls_test.c (revision 7ed6de99)
1 /*
2  * Copyright 2016-2024 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, 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 
116 /* Returns 1 for initial ClientHello, 2 for ClientHello with cookie */
validate_client_hello(BIO * wbio)117 static int validate_client_hello(BIO *wbio)
118 {
119     PACKET pkt, pkt2;
120     long len;
121     unsigned char *data;
122     int cookie_found = 0;
123     unsigned int u = 0;
124 
125     if ((len = BIO_get_mem_data(wbio, (char **)&data)) < 0)
126         return 0;
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 */
156     if (!PACKET_get_length_prefixed_1(&pkt, &pkt2) ||
157         !PACKET_equal(&pkt2, session_id, sizeof(session_id)))
158         return 0;
159 
160     /* Check cookie */
161     if (!PACKET_get_length_prefixed_1(&pkt, &pkt2))
162         return 0;
163     if (PACKET_remaining(&pkt2)) {
164         if (!PACKET_equal(&pkt2, cookie, sizeof(cookie)))
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))
188         return 0;
189 
190     (void)BIO_reset(wbio);
191 
192     return 1 + cookie_found;
193 }
194 
send_hello_verify(BIO * rbio)195 static 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 
send_server_hello(BIO * rbio)223 static 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))
265         return 0;
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 */
send_record(BIO * rbio,unsigned char type,uint64_t seqnr,const void * msg,size_t len)274 static int send_record(BIO *rbio, unsigned char type, uint64_t seqnr,
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];
284     EVP_MAC *hmac = NULL;
285     EVP_MAC_CTX *ctx = NULL;
286     EVP_CIPHER_CTX *enc_ctx = NULL;
287     unsigned char iv[16];
288     unsigned char pad;
289     unsigned char *enc;
290     OSSL_PARAM params[2];
291     int ret = 0;
292 
293     seq[0] = (seqnr >> 40) & 0xff;
294     seq[1] = (seqnr >> 32) & 0xff;
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 */
309     if (!TEST_ptr(hmac = EVP_MAC_fetch(NULL, "HMAC", NULL))
310             || !TEST_ptr(ctx = EVP_MAC_CTX_new(hmac)))
311         goto end;
312     params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
313                                                  "SHA1", 0);
314     params[1] = OSSL_PARAM_construct_end();
315     lenbytes[0] = (unsigned char)(len >> 8);
316     lenbytes[1] = (unsigned char)(len);
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;
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 */
334     if (!TEST_int_gt(RAND_bytes(iv, sizeof(iv)), 0)
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;
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);
346     lenbytes[0] = (unsigned char)((len + sizeof(iv)) >> 8);
347     lenbytes[1] = (unsigned char)(len + sizeof(iv));
348     BIO_write(rbio, lenbytes, 2);
349 
350     BIO_write(rbio, iv, sizeof(iv));
351     BIO_write(rbio, enc, len);
352     ret = 1;
353  end:
354     EVP_MAC_free(hmac);
355     EVP_MAC_CTX_free(ctx);
356     EVP_CIPHER_CTX_free(enc_ctx);
357     OPENSSL_free(enc);
358     return ret;
359 }
360 
send_finished(SSL * s,BIO * rbio)361 static 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];
373     int md_size;
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))
383         return 0;
384 
385     md_size = EVP_MD_CTX_get_size(handshake_md);
386     if (md_size <= 0)
387         return 0;
388     do_PRF(TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
389            handshake_hash, md_size,
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 
validate_ccs(BIO * wbio)397 static 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);
405     if (len < 0)
406         return 0;
407 
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 
451 static struct {
452     uint64_t seq;
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 
test_bad_dtls(void)467 static int test_bad_dtls(void)
468 {
469     SSL_SESSION *sess = NULL;
470     SSL_CTX *ctx = NULL;
471     SSL *con = NULL;
472     BIO *rbio = NULL;
473     BIO *wbio = NULL;
474     time_t now = 0;
475     int testresult = 0;
476     int ret;
477     int i;
478 
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);
483 
484     now = time(NULL);
485     memcpy(server_random, &now, sizeof(now));
486 
487     sess = client_session();
488     if (!TEST_ptr(sess))
489         goto end;
490 
491     handshake_md = EVP_MD_CTX_new();
492     if (!TEST_ptr(handshake_md)
493             || !TEST_true(EVP_DigestInit_ex(handshake_md, EVP_md5_sha1(),
494                                             NULL)))
495         goto end;
496 
497     ctx = SSL_CTX_new(DTLS_client_method());
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))
501             || !TEST_true(SSL_CTX_set_options(ctx,
502                                               SSL_OP_LEGACY_SERVER_CONNECT))
503             || !TEST_true(SSL_CTX_set_cipher_list(ctx, "AES128-SHA")))
504         goto end;
505 
506     SSL_CTX_set_security_level(ctx, 0);
507     con = SSL_new(ctx);
508     if (!TEST_ptr(con)
509             || !TEST_true(SSL_set_session(con, sess)))
510         goto end;
511 
512     rbio = BIO_new(BIO_s_mem());
513     wbio = BIO_new(BIO_s_mem());
514 
515     if (!TEST_ptr(rbio)
516             || !TEST_ptr(wbio))
517         goto end;
518 
519     SSL_set_bio(con, rbio, wbio);
520 
521     if (!TEST_true(BIO_up_ref(rbio))) {
522         /*
523          * We can't up-ref but we assigned ownership to con, so we shouldn't
524          * free in the "end" block
525          */
526         rbio = wbio = NULL;
527         goto end;
528     }
529 
530     if (!TEST_true(BIO_up_ref(wbio))) {
531         wbio = NULL;
532         goto end;
533     }
534 
535     SSL_set_connect_state(con);
536 
537     /* Send initial ClientHello */
538     ret = SSL_do_handshake(con);
539     if (!TEST_int_le(ret, 0)
540             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
541             || !TEST_int_eq(validate_client_hello(wbio), 1)
542             || !TEST_true(send_hello_verify(rbio)))
543         goto end;
544 
545     ret = SSL_do_handshake(con);
546     if (!TEST_int_le(ret, 0)
547             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
548             || !TEST_int_eq(validate_client_hello(wbio), 2)
549             || !TEST_true(send_server_hello(rbio)))
550         goto end;
551 
552     ret = SSL_do_handshake(con);
553     if (!TEST_int_le(ret, 0)
554             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
555             || !TEST_true(send_finished(con, rbio)))
556         goto end;
557 
558     ret = SSL_do_handshake(con);
559     if (!TEST_int_gt(ret, 0)
560             || !TEST_true(validate_ccs(wbio)))
561         goto end;
562 
563     /* While we're here and crafting packets by hand, we might as well do a
564        bit of a stress test on the DTLS record replay handling. Not Cisco-DTLS
565        specific but useful anyway for the general case. It's been broken
566        before, and in fact was broken even for a basic 0, 2, 1 test case
567        when this test was first added.... */
568     for (i = 0; i < (int)OSSL_NELEM(tests); i++) {
569         uint64_t recv_buf[2];
570 
571         if (!TEST_true(send_record(rbio, SSL3_RT_APPLICATION_DATA, tests[i].seq,
572                                    &tests[i].seq, sizeof(uint64_t)))) {
573             TEST_error("Failed to send data seq #0x%x%08x (%d)\n",
574                        (unsigned int)(tests[i].seq >> 32), (unsigned int)tests[i].seq, i);
575             goto end;
576         }
577 
578         if (tests[i].drop)
579             continue;
580 
581         ret = SSL_read(con, recv_buf, 2 * sizeof(uint64_t));
582         if (!TEST_int_eq(ret, (int)sizeof(uint64_t))) {
583             TEST_error("SSL_read failed or wrong size on seq#0x%x%08x (%d)\n",
584                        (unsigned int)(tests[i].seq >> 32), (unsigned int)tests[i].seq, i);
585             goto end;
586         }
587         if (!TEST_true(recv_buf[0] == tests[i].seq))
588             goto end;
589     }
590 
591     /* The last test cannot be DROP() */
592     if (!TEST_false(tests[i-1].drop))
593         goto end;
594 
595     testresult = 1;
596 
597  end:
598     SSL_SESSION_free(sess);
599     BIO_free(rbio);
600     BIO_free(wbio);
601     SSL_free(con);
602     SSL_CTX_free(ctx);
603     EVP_MD_CTX_free(handshake_md);
604 
605     return testresult;
606 }
607 
setup_tests(void)608 int setup_tests(void)
609 {
610     ADD_TEST(test_bad_dtls);
611     return 1;
612 }
613