43733e97b16ce325c1967aa7ab692cac972da4f3
[openssl.git] / test / bad_dtls_test.c
1 /*
2  * Copyright 2016-2017 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 /*
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/opensslconf.h>
33 #include <openssl/bio.h>
34 #include <openssl/crypto.h>
35 #include <openssl/evp.h>
36 #include <openssl/ssl.h>
37 #include <openssl/err.h>
38 #include <openssl/rand.h>
39 #include <openssl/kdf.h>
40
41 #include "../ssl/packet_locl.h"
42 #include "../e_os.h" /* for OSSL_NELEM() */
43
44 #include "test_main.h"
45 #include "testutil.h"
46
47 /* For DTLS1_BAD_VER packets the MAC doesn't include the handshake header */
48 #define MAC_OFFSET (DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH)
49
50 static unsigned char client_random[SSL3_RANDOM_SIZE];
51 static unsigned char server_random[SSL3_RANDOM_SIZE];
52
53 /* These are all generated locally, sized purely according to our own whim */
54 static unsigned char session_id[32];
55 static unsigned char master_secret[48];
56 static unsigned char cookie[20];
57
58 /* We've hard-coded the cipher suite; we know it's 104 bytes */
59 static unsigned char key_block[104];
60 #define mac_key (key_block + 20)
61 #define dec_key (key_block + 40)
62 #define enc_key (key_block + 56)
63
64 static EVP_MD_CTX *handshake_md;
65
66 static int do_PRF(const void *seed1, int seed1_len,
67                   const void *seed2, int seed2_len,
68                   const void *seed3, int seed3_len,
69                   unsigned char *out, int olen)
70 {
71     EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL);
72     size_t outlen = olen;
73
74     /* No error handling. If it all screws up, the test will fail anyway */
75     EVP_PKEY_derive_init(pctx);
76     EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_md5_sha1());
77     EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, master_secret, sizeof(master_secret));
78     EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed1, seed1_len);
79     EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed2, seed2_len);
80     EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed3, seed3_len);
81     EVP_PKEY_derive(pctx, out, &outlen);
82     EVP_PKEY_CTX_free(pctx);
83     return 1;
84 }
85
86 static SSL_SESSION *client_session(void)
87 {
88     static unsigned char session_asn1[] = {
89         0x30, 0x5F,              /* SEQUENCE, length 0x5F */
90         0x02, 0x01, 0x01,        /* INTEGER, SSL_SESSION_ASN1_VERSION */
91         0x02, 0x02, 0x01, 0x00,  /* INTEGER, DTLS1_BAD_VER */
92         0x04, 0x02, 0x00, 0x2F,  /* OCTET_STRING, AES128-SHA */
93         0x04, 0x20,              /* OCTET_STRING, session id */
94 #define SS_SESSID_OFS 15 /* Session ID goes here */
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         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99         0x04, 0x30,              /* OCTET_STRING, master secret */
100 #define SS_SECRET_OFS 49 /* Master secret goes here */
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         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107     };
108     const unsigned char *p = session_asn1;
109
110     /* Copy the randomly-generated fields into the above ASN1 */
111     memcpy(session_asn1 + SS_SESSID_OFS, session_id, sizeof(session_id));
112     memcpy(session_asn1 + SS_SECRET_OFS, master_secret, sizeof(master_secret));
113
114     return d2i_SSL_SESSION(NULL, &p, sizeof(session_asn1));
115 }
116
117 /* Returns 1 for initial ClientHello, 2 for ClientHello with cookie */
118 static int validate_client_hello(BIO *wbio)
119 {
120     PACKET pkt, pkt2;
121     long len;
122     unsigned char *data;
123     int cookie_found = 0;
124     unsigned int u;
125
126     len = BIO_get_mem_data(wbio, (char **)&data);
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
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
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 */
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     HMAC_CTX *ctx;
285     EVP_CIPHER_CTX *enc_ctx;
286     unsigned char iv[16];
287     unsigned char pad;
288     unsigned char *enc;
289
290     seq[0] = (seqnr >> 40) & 0xff;
291     seq[1] = (seqnr >> 32) & 0xff;
292     seq[2] = (seqnr >> 24) & 0xff;
293     seq[3] = (seqnr >> 16) & 0xff;
294     seq[4] = (seqnr >> 8) & 0xff;
295     seq[5] = seqnr & 0xff;
296
297     pad = 15 - ((len + SHA_DIGEST_LENGTH) % 16);
298     enc = OPENSSL_malloc(len + SHA_DIGEST_LENGTH + 1 + pad);
299     if (enc == NULL)
300         return 0;
301
302     /* Copy record to encryption buffer */
303     memcpy(enc, msg, len);
304
305     /* Append HMAC to data */
306     ctx = HMAC_CTX_new();
307     HMAC_Init_ex(ctx, mac_key, 20, EVP_sha1(), NULL);
308     HMAC_Update(ctx, epoch, 2);
309     HMAC_Update(ctx, seq, 6);
310     HMAC_Update(ctx, &type, 1);
311     HMAC_Update(ctx, ver, 2); /* Version */
312     lenbytes[0] = len >> 8;
313     lenbytes[1] = len & 0xff;
314     HMAC_Update(ctx, lenbytes, 2); /* Length */
315     HMAC_Update(ctx, enc, len); /* Finally the data itself */
316     HMAC_Final(ctx, enc + len, NULL);
317     HMAC_CTX_free(ctx);
318
319     /* Append padding bytes */
320     len += SHA_DIGEST_LENGTH;
321     do {
322         enc[len++] = pad;
323     } while (len % 16);
324
325     /* Generate IV, and encrypt */
326     RAND_bytes(iv, sizeof(iv));
327     enc_ctx = EVP_CIPHER_CTX_new();
328     EVP_CipherInit_ex(enc_ctx, EVP_aes_128_cbc(), NULL, enc_key, iv, 1);
329     EVP_Cipher(enc_ctx, enc, enc, len);
330     EVP_CIPHER_CTX_free(enc_ctx);
331
332     /* Finally write header (from fragmented variables), IV and encrypted record */
333     BIO_write(rbio, &type, 1);
334     BIO_write(rbio, ver, 2);
335     BIO_write(rbio, epoch, 2);
336     BIO_write(rbio, seq, 6);
337     lenbytes[0] = (len + sizeof(iv)) >> 8;
338     lenbytes[1] = (len + sizeof(iv)) & 0xff;
339     BIO_write(rbio, lenbytes, 2);
340
341     BIO_write(rbio, iv, sizeof(iv));
342     BIO_write(rbio, enc, len);
343
344     OPENSSL_free(enc);
345     return 1;
346 }
347
348 static int send_finished(SSL *s, BIO *rbio)
349 {
350     static unsigned char finished_msg[DTLS1_HM_HEADER_LENGTH +
351                                       TLS1_FINISH_MAC_LENGTH] = {
352         0x14, /* Finished */
353         0x00, 0x00, 0x0c, /* Length */
354         0x00, 0x03, /* Seq# 3 */
355         0x00, 0x00, 0x00, /* Fragment offset */
356         0x00, 0x00, 0x0c, /* Fragment length */
357         /* Finished MAC (12 bytes) */
358     };
359     unsigned char handshake_hash[EVP_MAX_MD_SIZE];
360
361     /* Derive key material */
362     do_PRF(TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE,
363            server_random, SSL3_RANDOM_SIZE,
364            client_random, SSL3_RANDOM_SIZE,
365            key_block, sizeof(key_block));
366
367     /* Generate Finished MAC */
368     if (!EVP_DigestFinal_ex(handshake_md, handshake_hash, NULL))
369         return 0;
370
371     do_PRF(TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
372            handshake_hash, EVP_MD_CTX_size(handshake_md),
373            NULL, 0,
374            finished_msg + DTLS1_HM_HEADER_LENGTH, TLS1_FINISH_MAC_LENGTH);
375
376     return send_record(rbio, SSL3_RT_HANDSHAKE, 0,
377                        finished_msg, sizeof(finished_msg));
378 }
379
380 static int validate_ccs(BIO *wbio)
381 {
382     PACKET pkt;
383     long len;
384     unsigned char *data;
385     unsigned int u;
386
387     len = BIO_get_mem_data(wbio, (char **)&data);
388     if (!PACKET_buf_init(&pkt, data, len))
389         return 0;
390
391     /* Check record header type */
392     if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_CHANGE_CIPHER_SPEC)
393         return 0;
394     /* Version */
395     if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
396         return 0;
397     /* Skip the rest of the record header */
398     if (!PACKET_forward(&pkt, DTLS1_RT_HEADER_LENGTH - 3))
399         return 0;
400
401     /* Check ChangeCipherSpec message */
402     if (!PACKET_get_1(&pkt, &u) || u != SSL3_MT_CCS)
403         return 0;
404     /* A DTLS1_BAD_VER ChangeCipherSpec also contains the
405      * handshake sequence number (which is 2 here) */
406     if (!PACKET_get_net_2(&pkt, &u) || u != 0x0002)
407         return 0;
408
409     /* Now check the Finished packet */
410     if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_HANDSHAKE)
411         return 0;
412     if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
413         return 0;
414
415     /* Check epoch is now 1 */
416     if (!PACKET_get_net_2(&pkt, &u) || u != 0x0001)
417         return 0;
418
419     /* That'll do for now. If OpenSSL accepted *our* Finished packet
420      * then it's evidently remembered that DTLS1_BAD_VER doesn't
421      * include the handshake header in the MAC. There's not a lot of
422      * point in implementing decryption here, just to check that it
423      * continues to get it right for one more packet. */
424
425     return 1;
426 }
427
428 #define NODROP(x) { x##UL, 0 }
429 #define DROP(x)   { x##UL, 1 }
430
431 static struct {
432     uint64_t seq;
433     int drop;
434 } tests[] = {
435     NODROP(1), NODROP(3), NODROP(2),
436     NODROP(0x1234), NODROP(0x1230), NODROP(0x1235),
437     NODROP(0xffff), NODROP(0x10001), NODROP(0xfffe), NODROP(0x10000),
438     DROP(0x10001), DROP(0xff), NODROP(0x100000), NODROP(0x800000), NODROP(0x7fffe1),
439     NODROP(0xffffff), NODROP(0x1000000), NODROP(0xfffffe), DROP(0xffffff), NODROP(0x1000010),
440     NODROP(0xfffffd), NODROP(0x1000011), DROP(0x12), NODROP(0x1000012),
441     NODROP(0x1ffffff), NODROP(0x2000000), DROP(0x1ff00fe), NODROP(0x2000001),
442     NODROP(0x20fffff), NODROP(0x2105500), DROP(0x20ffffe), NODROP(0x21054ff),
443     NODROP(0x211ffff), DROP(0x2110000), NODROP(0x2120000)
444     /* The last test should be NODROP, because a DROP wouldn't get tested. */
445 };
446
447 static int test_bad_dtls(void)
448 {
449     SSL_SESSION *sess = NULL;
450     SSL_CTX *ctx = NULL;
451     SSL *con = NULL;
452     BIO *rbio = NULL;
453     BIO *wbio = NULL;
454     time_t now = 0;
455     int testresult = 0;
456     int ret;
457     int i;
458
459     RAND_bytes(session_id, sizeof(session_id));
460     RAND_bytes(master_secret, sizeof(master_secret));
461     RAND_bytes(cookie, sizeof(cookie));
462     RAND_bytes(server_random + 4, sizeof(server_random) - 4);
463
464     now = time(NULL);
465     memcpy(server_random, &now, sizeof(now));
466
467     sess = client_session();
468     if (!TEST_ptr(sess))
469         goto end;
470
471     handshake_md = EVP_MD_CTX_new();
472     if (!TEST_ptr(handshake_md)
473             || !TEST_true(EVP_DigestInit_ex(handshake_md, EVP_md5_sha1(),
474                                             NULL)))
475         goto end;
476
477     ctx = SSL_CTX_new(DTLS_client_method());
478     if (!TEST_ptr(ctx)
479             || !TEST_true(SSL_CTX_set_min_proto_version(ctx, DTLS1_BAD_VER))
480             || !TEST_true(SSL_CTX_set_max_proto_version(ctx, DTLS1_BAD_VER))
481             || !TEST_true(SSL_CTX_set_cipher_list(ctx, "AES128-SHA")))
482         goto end;
483
484     con = SSL_new(ctx);
485     if (!TEST_ptr(con)
486             || !TEST_true(SSL_set_session(con, sess)))
487         goto end;
488     SSL_SESSION_free(sess);
489
490     rbio = BIO_new(BIO_s_mem());
491     wbio = BIO_new(BIO_s_mem());
492
493     if (!TEST_ptr(rbio)
494             || !TEST_ptr(wbio))
495         goto end;
496
497     SSL_set_bio(con, rbio, wbio);
498
499     if (!TEST_true(BIO_up_ref(rbio))) {
500         /*
501          * We can't up-ref but we assigned ownership to con, so we shouldn't
502          * free in the "end" block
503          */
504         rbio = wbio = NULL;
505         goto end;
506     }
507
508     if (!TEST_true(BIO_up_ref(wbio))) {
509         wbio = NULL;
510         goto end;
511     }
512
513     SSL_set_connect_state(con);
514
515     /* Send initial ClientHello */
516     ret = SSL_do_handshake(con);
517     if (!TEST_int_le(ret, 0)
518             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
519             || !TEST_int_eq(validate_client_hello(wbio), 1)
520             || !TEST_true(send_hello_verify(rbio)))
521         goto end;
522
523     ret = SSL_do_handshake(con);
524     if (!TEST_int_le(ret, 0)
525             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
526             || !TEST_int_eq(validate_client_hello(wbio), 2)
527             || !TEST_true(send_server_hello(rbio)))
528         goto end;
529
530     ret = SSL_do_handshake(con);
531     if (!TEST_int_le(ret, 0)
532             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
533             || !TEST_true(send_finished(con, rbio)))
534         goto end;
535
536     ret = SSL_do_handshake(con);
537     if (!TEST_int_gt(ret, 0)
538             || !TEST_true(validate_ccs(wbio)))
539         goto end;
540
541     /* While we're here and crafting packets by hand, we might as well do a
542        bit of a stress test on the DTLS record replay handling. Not Cisco-DTLS
543        specific but useful anyway for the general case. It's been broken
544        before, and in fact was broken even for a basic 0, 2, 1 test case
545        when this test was first added.... */
546     for (i = 0; i < (int)OSSL_NELEM(tests); i++) {
547         uint64_t recv_buf[2];
548
549         if (!TEST_true(send_record(rbio, SSL3_RT_APPLICATION_DATA, tests[i].seq,
550                                    &tests[i].seq, sizeof(uint64_t)))) {
551             TEST_error("Failed to send data seq #0x%lx (%d)\n",
552                        tests[i].seq, i);
553             goto end;
554         }
555
556         if (tests[i].drop)
557             continue;
558
559         ret = SSL_read(con, recv_buf, 2 * sizeof(uint64_t));
560         if (!TEST_int_eq(ret, (int)sizeof(uint64_t))) {
561             TEST_error("SSL_read failed or wrong size on seq#0x%lx (%d)\n",
562                        tests[i].seq, i);
563             goto end;
564         }
565         if (!TEST_true(recv_buf[0] == tests[i].seq))
566             goto end;
567     }
568
569     /* The last test cannot be DROP() */
570     if (!TEST_false(tests[i-1].drop))
571         goto end;
572
573     testresult = 1;
574
575  end:
576     BIO_free(rbio);
577     BIO_free(wbio);
578     SSL_free(con);
579     SSL_CTX_free(ctx);
580     EVP_MD_CTX_free(handshake_md);
581
582     return testresult;
583 }
584
585 void register_tests(void)
586 {
587     ADD_TEST(test_bad_dtls);
588 }