testutil: Remove test_puts_std{out,err}, they are superfluous
[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 "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
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
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 */
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;
124
125     len = BIO_get_mem_data(wbio, (char **)&data);
126     if (!PACKET_buf_init(&pkt, data, len))
127         return 0;
128
129     /* Check record header type */
130     if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_HANDSHAKE)
131         return 0;
132     /* Version */
133     if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
134         return 0;
135     /* Skip the rest of the record header */
136     if (!PACKET_forward(&pkt, DTLS1_RT_HEADER_LENGTH - 3))
137         return 0;
138
139     /* Check it's a ClientHello */
140     if (!PACKET_get_1(&pkt, &u) || u != SSL3_MT_CLIENT_HELLO)
141         return 0;
142     /* Skip the rest of the handshake message header */
143     if (!PACKET_forward(&pkt, DTLS1_HM_HEADER_LENGTH - 1))
144         return 0;
145
146     /* Check client version */
147     if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
148         return 0;
149
150     /* Store random */
151     if (!PACKET_copy_bytes(&pkt, client_random, SSL3_RANDOM_SIZE))
152         return 0;
153
154     /* Check session id length and content */
155     if (!PACKET_get_length_prefixed_1(&pkt, &pkt2) ||
156         !PACKET_equal(&pkt2, session_id, sizeof(session_id)))
157         return 0;
158
159     /* Check cookie */
160     if (!PACKET_get_length_prefixed_1(&pkt, &pkt2))
161         return 0;
162     if (PACKET_remaining(&pkt2)) {
163         if (!PACKET_equal(&pkt2, cookie, sizeof(cookie)))
164             return 0;
165         cookie_found = 1;
166     }
167
168     /* Skip ciphers */
169     if (!PACKET_get_net_2(&pkt, &u) || !PACKET_forward(&pkt, u))
170         return 0;
171
172     /* Skip compression */
173     if (!PACKET_get_1(&pkt, &u) || !PACKET_forward(&pkt, u))
174         return 0;
175
176     /* Skip extensions */
177     if (!PACKET_get_net_2(&pkt, &u) || !PACKET_forward(&pkt, u))
178         return 0;
179
180     /* Now we are at the end */
181     if (PACKET_remaining(&pkt))
182         return 0;
183
184     /* Update handshake MAC for second ClientHello (with cookie) */
185     if (cookie_found && !EVP_DigestUpdate(handshake_md, data + MAC_OFFSET,
186                                           len - MAC_OFFSET))
187         return 0;
188
189     (void)BIO_reset(wbio);
190
191     return 1 + cookie_found;
192 }
193
194 static int send_hello_verify(BIO *rbio)
195 {
196     static unsigned char hello_verify[] = {
197         0x16, /* Handshake */
198         0x01, 0x00, /* DTLS1_BAD_VER */
199         0x00, 0x00, /* Epoch 0 */
200         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Seq# 0 */
201         0x00, 0x23, /* Length */
202         0x03, /* Hello Verify */
203         0x00, 0x00, 0x17, /* Length */
204         0x00, 0x00, /* Seq# 0 */
205         0x00, 0x00, 0x00, /* Fragment offset */
206         0x00, 0x00, 0x17, /* Fragment length */
207         0x01, 0x00, /* DTLS1_BAD_VER */
208         0x14, /* Cookie length */
209 #define HV_COOKIE_OFS 28 /* Cookie goes here */
210         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212         0x00, 0x00, 0x00, 0x00,
213     };
214
215     memcpy(hello_verify + HV_COOKIE_OFS, cookie, sizeof(cookie));
216
217     BIO_write(rbio, hello_verify, sizeof(hello_verify));
218
219     return 1;
220 }
221
222 static int send_server_hello(BIO *rbio)
223 {
224     static unsigned char server_hello[] = {
225         0x16, /* Handshake */
226         0x01, 0x00, /* DTLS1_BAD_VER */
227         0x00, 0x00, /* Epoch 0 */
228         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* Seq# 1 */
229         0x00, 0x52, /* Length */
230         0x02, /* Server Hello */
231         0x00, 0x00, 0x46, /* Length */
232         0x00, 0x01, /* Seq# */
233         0x00, 0x00, 0x00, /* Fragment offset */
234         0x00, 0x00, 0x46, /* Fragment length */
235         0x01, 0x00, /* DTLS1_BAD_VER */
236 #define SH_RANDOM_OFS 27 /* Server random goes here */
237         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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         0x20, /* Session ID length */
242 #define SH_SESSID_OFS 60 /* Session ID goes here */
243         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x2f, /* Cipher suite AES128-SHA */
248         0x00, /* Compression null */
249     };
250     static unsigned char change_cipher_spec[] = {
251         0x14, /* Change Cipher Spec */
252         0x01, 0x00, /* DTLS1_BAD_VER */
253         0x00, 0x00, /* Epoch 0 */
254         0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* Seq# 2 */
255         0x00, 0x03, /* Length */
256         0x01, 0x00, 0x02, /* Message */
257     };
258
259     memcpy(server_hello + SH_RANDOM_OFS, server_random, sizeof(server_random));
260     memcpy(server_hello + SH_SESSID_OFS, session_id, sizeof(session_id));
261
262     if (!EVP_DigestUpdate(handshake_md, server_hello + MAC_OFFSET,
263                           sizeof(server_hello) - MAC_OFFSET))
264         return 0;
265
266     BIO_write(rbio, server_hello, sizeof(server_hello));
267     BIO_write(rbio, change_cipher_spec, sizeof(change_cipher_spec));
268
269     return 1;
270 }
271
272 /* Create header, HMAC, pad, encrypt and send a record */
273 static int send_record(BIO *rbio, unsigned char type, uint64_t seqnr,
274                        const void *msg, size_t len)
275 {
276     /* Note that the order of the record header fields on the wire,
277      * and in the HMAC, is different. So we just keep them in separate
278      * variables and handle them individually. */
279     static unsigned char epoch[2] = { 0x00, 0x01 };
280     static unsigned char seq[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
281     static unsigned char ver[2] = { 0x01, 0x00 }; /* DTLS1_BAD_VER */
282     unsigned char lenbytes[2];
283     HMAC_CTX *ctx;
284     EVP_CIPHER_CTX *enc_ctx;
285     unsigned char iv[16];
286     unsigned char pad;
287     unsigned char *enc;
288
289     seq[0] = (seqnr >> 40) & 0xff;
290     seq[1] = (seqnr >> 32) & 0xff;
291     seq[2] = (seqnr >> 24) & 0xff;
292     seq[3] = (seqnr >> 16) & 0xff;
293     seq[4] = (seqnr >> 8) & 0xff;
294     seq[5] = seqnr & 0xff;
295
296     pad = 15 - ((len + SHA_DIGEST_LENGTH) % 16);
297     enc = OPENSSL_malloc(len + SHA_DIGEST_LENGTH + 1 + pad);
298     if (enc == NULL)
299         return 0;
300
301     /* Copy record to encryption buffer */
302     memcpy(enc, msg, len);
303
304     /* Append HMAC to data */
305     ctx = HMAC_CTX_new();
306     HMAC_Init_ex(ctx, mac_key, 20, EVP_sha1(), NULL);
307     HMAC_Update(ctx, epoch, 2);
308     HMAC_Update(ctx, seq, 6);
309     HMAC_Update(ctx, &type, 1);
310     HMAC_Update(ctx, ver, 2); /* Version */
311     lenbytes[0] = len >> 8;
312     lenbytes[1] = len & 0xff;
313     HMAC_Update(ctx, lenbytes, 2); /* Length */
314     HMAC_Update(ctx, enc, len); /* Finally the data itself */
315     HMAC_Final(ctx, enc + len, NULL);
316     HMAC_CTX_free(ctx);
317
318     /* Append padding bytes */
319     len += SHA_DIGEST_LENGTH;
320     do {
321         enc[len++] = pad;
322     } while (len % 16);
323
324     /* Generate IV, and encrypt */
325     RAND_bytes(iv, sizeof(iv));
326     enc_ctx = EVP_CIPHER_CTX_new();
327     EVP_CipherInit_ex(enc_ctx, EVP_aes_128_cbc(), NULL, enc_key, iv, 1);
328     EVP_Cipher(enc_ctx, enc, enc, len);
329     EVP_CIPHER_CTX_free(enc_ctx);
330
331     /* Finally write header (from fragmented variables), IV and encrypted record */
332     BIO_write(rbio, &type, 1);
333     BIO_write(rbio, ver, 2);
334     BIO_write(rbio, epoch, 2);
335     BIO_write(rbio, seq, 6);
336     lenbytes[0] = (len + sizeof(iv)) >> 8;
337     lenbytes[1] = (len + sizeof(iv)) & 0xff;
338     BIO_write(rbio, lenbytes, 2);
339
340     BIO_write(rbio, iv, sizeof(iv));
341     BIO_write(rbio, enc, len);
342
343     OPENSSL_free(enc);
344     return 1;
345 }
346
347 static int send_finished(SSL *s, BIO *rbio)
348 {
349     static unsigned char finished_msg[DTLS1_HM_HEADER_LENGTH +
350                                       TLS1_FINISH_MAC_LENGTH] = {
351         0x14, /* Finished */
352         0x00, 0x00, 0x0c, /* Length */
353         0x00, 0x03, /* Seq# 3 */
354         0x00, 0x00, 0x00, /* Fragment offset */
355         0x00, 0x00, 0x0c, /* Fragment length */
356         /* Finished MAC (12 bytes) */
357     };
358     unsigned char handshake_hash[EVP_MAX_MD_SIZE];
359
360     /* Derive key material */
361     do_PRF(TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE,
362            server_random, SSL3_RANDOM_SIZE,
363            client_random, SSL3_RANDOM_SIZE,
364            key_block, sizeof(key_block));
365
366     /* Generate Finished MAC */
367     if (!EVP_DigestFinal_ex(handshake_md, handshake_hash, NULL))
368         return 0;
369
370     do_PRF(TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
371            handshake_hash, EVP_MD_CTX_size(handshake_md),
372            NULL, 0,
373            finished_msg + DTLS1_HM_HEADER_LENGTH, TLS1_FINISH_MAC_LENGTH);
374
375     return send_record(rbio, SSL3_RT_HANDSHAKE, 0,
376                        finished_msg, sizeof(finished_msg));
377 }
378
379 static int validate_ccs(BIO *wbio)
380 {
381     PACKET pkt;
382     long len;
383     unsigned char *data;
384     unsigned int u;
385
386     len = BIO_get_mem_data(wbio, (char **)&data);
387     if (!PACKET_buf_init(&pkt, data, len))
388         return 0;
389
390     /* Check record header type */
391     if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_CHANGE_CIPHER_SPEC)
392         return 0;
393     /* Version */
394     if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
395         return 0;
396     /* Skip the rest of the record header */
397     if (!PACKET_forward(&pkt, DTLS1_RT_HEADER_LENGTH - 3))
398         return 0;
399
400     /* Check ChangeCipherSpec message */
401     if (!PACKET_get_1(&pkt, &u) || u != SSL3_MT_CCS)
402         return 0;
403     /* A DTLS1_BAD_VER ChangeCipherSpec also contains the
404      * handshake sequence number (which is 2 here) */
405     if (!PACKET_get_net_2(&pkt, &u) || u != 0x0002)
406         return 0;
407
408     /* Now check the Finished packet */
409     if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_HANDSHAKE)
410         return 0;
411     if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
412         return 0;
413
414     /* Check epoch is now 1 */
415     if (!PACKET_get_net_2(&pkt, &u) || u != 0x0001)
416         return 0;
417
418     /* That'll do for now. If OpenSSL accepted *our* Finished packet
419      * then it's evidently remembered that DTLS1_BAD_VER doesn't
420      * include the handshake header in the MAC. There's not a lot of
421      * point in implementing decryption here, just to check that it
422      * continues to get it right for one more packet. */
423
424     return 1;
425 }
426
427 #define NODROP(x) { x##UL, 0 }
428 #define DROP(x)   { x##UL, 1 }
429
430 static struct {
431     uint64_t seq;
432     int drop;
433 } tests[] = {
434     NODROP(1), NODROP(3), NODROP(2),
435     NODROP(0x1234), NODROP(0x1230), NODROP(0x1235),
436     NODROP(0xffff), NODROP(0x10001), NODROP(0xfffe), NODROP(0x10000),
437     DROP(0x10001), DROP(0xff), NODROP(0x100000), NODROP(0x800000), NODROP(0x7fffe1),
438     NODROP(0xffffff), NODROP(0x1000000), NODROP(0xfffffe), DROP(0xffffff), NODROP(0x1000010),
439     NODROP(0xfffffd), NODROP(0x1000011), DROP(0x12), NODROP(0x1000012),
440     NODROP(0x1ffffff), NODROP(0x2000000), DROP(0x1ff00fe), NODROP(0x2000001),
441     NODROP(0x20fffff), NODROP(0x2105500), DROP(0x20ffffe), NODROP(0x21054ff),
442     NODROP(0x211ffff), DROP(0x2110000), NODROP(0x2120000)
443     /* The last test should be NODROP, because a DROP wouldn't get tested. */
444 };
445
446 static int test_bad_dtls(void)
447 {
448     SSL_SESSION *sess = NULL;
449     SSL_CTX *ctx = NULL;
450     SSL *con = NULL;
451     BIO *rbio = NULL;
452     BIO *wbio = NULL;
453     time_t now = 0;
454     int testresult = 0;
455     int ret;
456     int i;
457
458     RAND_bytes(session_id, sizeof(session_id));
459     RAND_bytes(master_secret, sizeof(master_secret));
460     RAND_bytes(cookie, sizeof(cookie));
461     RAND_bytes(server_random + 4, sizeof(server_random) - 4);
462
463     now = time(NULL);
464     memcpy(server_random, &now, sizeof(now));
465
466     sess = client_session();
467     if (!TEST_ptr(sess))
468         goto end;
469
470     handshake_md = EVP_MD_CTX_new();
471     if (!TEST_ptr(handshake_md)
472             || !TEST_true(EVP_DigestInit_ex(handshake_md, EVP_md5_sha1(),
473                                             NULL)))
474         goto end;
475
476     ctx = SSL_CTX_new(DTLS_client_method());
477     if (!TEST_ptr(ctx)
478             || !TEST_true(SSL_CTX_set_min_proto_version(ctx, DTLS1_BAD_VER))
479             || !TEST_true(SSL_CTX_set_max_proto_version(ctx, DTLS1_BAD_VER))
480             || !TEST_true(SSL_CTX_set_cipher_list(ctx, "AES128-SHA")))
481         goto end;
482
483     con = SSL_new(ctx);
484     if (!TEST_ptr(con)
485             || !TEST_true(SSL_set_session(con, sess)))
486         goto end;
487     SSL_SESSION_free(sess);
488
489     rbio = BIO_new(BIO_s_mem());
490     wbio = BIO_new(BIO_s_mem());
491
492     if (!TEST_ptr(rbio)
493             || !TEST_ptr(wbio))
494         goto end;
495
496     SSL_set_bio(con, rbio, wbio);
497
498     if (!TEST_true(BIO_up_ref(rbio))) {
499         /*
500          * We can't up-ref but we assigned ownership to con, so we shouldn't
501          * free in the "end" block
502          */
503         rbio = wbio = NULL;
504         goto end;
505     }
506
507     if (!TEST_true(BIO_up_ref(wbio))) {
508         wbio = NULL;
509         goto end;
510     }
511
512     SSL_set_connect_state(con);
513
514     /* Send initial ClientHello */
515     ret = SSL_do_handshake(con);
516     if (!TEST_int_le(ret, 0)
517             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
518             || !TEST_int_eq(validate_client_hello(wbio), 1)
519             || !TEST_true(send_hello_verify(rbio)))
520         goto end;
521
522     ret = SSL_do_handshake(con);
523     if (!TEST_int_le(ret, 0)
524             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
525             || !TEST_int_eq(validate_client_hello(wbio), 2)
526             || !TEST_true(send_server_hello(rbio)))
527         goto end;
528
529     ret = SSL_do_handshake(con);
530     if (!TEST_int_le(ret, 0)
531             || !TEST_int_eq(SSL_get_error(con, ret), SSL_ERROR_WANT_READ)
532             || !TEST_true(send_finished(con, rbio)))
533         goto end;
534
535     ret = SSL_do_handshake(con);
536     if (!TEST_int_gt(ret, 0)
537             || !TEST_true(validate_ccs(wbio)))
538         goto end;
539
540     /* While we're here and crafting packets by hand, we might as well do a
541        bit of a stress test on the DTLS record replay handling. Not Cisco-DTLS
542        specific but useful anyway for the general case. It's been broken
543        before, and in fact was broken even for a basic 0, 2, 1 test case
544        when this test was first added.... */
545     for (i = 0; i < (int)OSSL_NELEM(tests); i++) {
546         uint64_t recv_buf[2];
547
548         if (!TEST_true(send_record(rbio, SSL3_RT_APPLICATION_DATA, tests[i].seq,
549                                    &tests[i].seq, sizeof(uint64_t)))) {
550             TEST_error("Failed to send data seq #0x%x%08x (%d)\n",
551                        (unsigned int)(tests[i].seq >> 32), (unsigned int)tests[i].seq, i);
552             goto end;
553         }
554
555         if (tests[i].drop)
556             continue;
557
558         ret = SSL_read(con, recv_buf, 2 * sizeof(uint64_t));
559         if (!TEST_int_eq(ret, (int)sizeof(uint64_t))) {
560             TEST_error("SSL_read failed or wrong size on seq#0x%x%08x (%d)\n",
561                        (unsigned int)(tests[i].seq >> 32), (unsigned int)tests[i].seq, i);
562             goto end;
563         }
564         if (!TEST_true(recv_buf[0] == tests[i].seq))
565             goto end;
566     }
567
568     /* The last test cannot be DROP() */
569     if (!TEST_false(tests[i-1].drop))
570         goto end;
571
572     testresult = 1;
573
574  end:
575     BIO_free(rbio);
576     BIO_free(wbio);
577     SSL_free(con);
578     SSL_CTX_free(ctx);
579     EVP_MD_CTX_free(handshake_md);
580
581     return testresult;
582 }
583
584 void register_tests(void)
585 {
586     ADD_TEST(test_bad_dtls);
587 }