]> git.ipfire.org Git - thirdparty/openssl.git/blame - test/bad_dtls_test.c
Fix x_int64.c
[thirdparty/openssl.git] / test / bad_dtls_test.c
CommitLineData
16938284
DW
1/*
2 * Copyright 2016 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
9cc76cc4
RL
41#include "../ssl/packet_locl.h"
42#include "../e_os.h" /* for OSSL_NELEM() */
16938284
DW
43
44/* For DTLS1_BAD_VER packets the MAC doesn't include the handshake header */
45#define MAC_OFFSET (DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH)
46
47static unsigned char client_random[SSL3_RANDOM_SIZE];
48static unsigned char server_random[SSL3_RANDOM_SIZE];
49
50/* These are all generated locally, sized purely according to our own whim */
51static unsigned char session_id[32];
52static unsigned char master_secret[48];
53static unsigned char cookie[20];
54
55/* We've hard-coded the cipher suite; we know it's 104 bytes */
56static unsigned char key_block[104];
57#define mac_key (key_block + 20)
58#define dec_key (key_block + 40)
59#define enc_key (key_block + 56)
60
61static EVP_MD_CTX *handshake_md;
62
63static int do_PRF(const void *seed1, int seed1_len,
64 const void *seed2, int seed2_len,
65 const void *seed3, int seed3_len,
66 unsigned char *out, int olen)
67{
68 EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL);
69 size_t outlen = olen;
70
71 /* No error handling. If it all screws up, the test will fail anyway */
72 EVP_PKEY_derive_init(pctx);
73 EVP_PKEY_CTX_set_tls1_prf_md(pctx, EVP_md5_sha1());
74 EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, master_secret, sizeof(master_secret));
75 EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed1, seed1_len);
76 EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed2, seed2_len);
77 EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed3, seed3_len);
78 EVP_PKEY_derive(pctx, out, &outlen);
79 EVP_PKEY_CTX_free(pctx);
80 return 1;
81}
82
83static SSL_SESSION *client_session(void)
84{
85 static unsigned char session_asn1[] = {
86 0x30, 0x5F, /* SEQUENCE, length 0x5F */
87 0x02, 0x01, 0x01, /* INTEGER, SSL_SESSION_ASN1_VERSION */
88 0x02, 0x02, 0x01, 0x00, /* INTEGER, DTLS1_BAD_VER */
89 0x04, 0x02, 0x00, 0x2F, /* OCTET_STRING, AES128-SHA */
90 0x04, 0x20, /* OCTET_STRING, session id */
91#define SS_SESSID_OFS 15 /* Session ID goes here */
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x04, 0x30, /* OCTET_STRING, master secret */
97#define SS_SECRET_OFS 49 /* Master secret goes here */
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 };
105 const unsigned char *p = session_asn1;
106
107 /* Copy the randomly-generated fields into the above ASN1 */
108 memcpy(session_asn1 + SS_SESSID_OFS, session_id, sizeof(session_id));
109 memcpy(session_asn1 + SS_SECRET_OFS, master_secret, sizeof(master_secret));
110
111 return d2i_SSL_SESSION(NULL, &p, sizeof(session_asn1));
112}
113
16938284
DW
114/* Returns 1 for initial ClientHello, 2 for ClientHello with cookie */
115static int validate_client_hello(BIO *wbio)
116{
eb633d03 117 PACKET pkt, pkt2;
16938284
DW
118 long len;
119 unsigned char *data;
120 int cookie_found = 0;
121 unsigned int u;
122
123 len = BIO_get_mem_data(wbio, (char **)&data);
124 if (!PACKET_buf_init(&pkt, data, len))
125 return 0;
126
127 /* Check record header type */
128 if (!PACKET_get_1(&pkt, &u) || u != SSL3_RT_HANDSHAKE)
129 return 0;
130 /* Version */
131 if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
132 return 0;
133 /* Skip the rest of the record header */
134 if (!PACKET_forward(&pkt, DTLS1_RT_HEADER_LENGTH - 3))
135 return 0;
136
137 /* Check it's a ClientHello */
138 if (!PACKET_get_1(&pkt, &u) || u != SSL3_MT_CLIENT_HELLO)
139 return 0;
140 /* Skip the rest of the handshake message header */
141 if (!PACKET_forward(&pkt, DTLS1_HM_HEADER_LENGTH - 1))
142 return 0;
143
144 /* Check client version */
145 if (!PACKET_get_net_2(&pkt, &u) || u != DTLS1_BAD_VER)
146 return 0;
147
148 /* Store random */
149 if (!PACKET_copy_bytes(&pkt, client_random, SSL3_RANDOM_SIZE))
150 return 0;
151
152 /* Check session id length and content */
eb633d03
DW
153 if (!PACKET_get_length_prefixed_1(&pkt, &pkt2) ||
154 !PACKET_equal(&pkt2, session_id, sizeof(session_id)))
16938284
DW
155 return 0;
156
157 /* Check cookie */
eb633d03 158 if (!PACKET_get_length_prefixed_1(&pkt, &pkt2))
16938284 159 return 0;
eb633d03
DW
160 if (PACKET_remaining(&pkt2)) {
161 if (!PACKET_equal(&pkt2, cookie, sizeof(cookie)))
16938284
DW
162 return 0;
163 cookie_found = 1;
164 }
165
166 /* Skip ciphers */
167 if (!PACKET_get_net_2(&pkt, &u) || !PACKET_forward(&pkt, u))
168 return 0;
169
170 /* Skip compression */
171 if (!PACKET_get_1(&pkt, &u) || !PACKET_forward(&pkt, u))
172 return 0;
173
174 /* Skip extensions */
175 if (!PACKET_get_net_2(&pkt, &u) || !PACKET_forward(&pkt, u))
176 return 0;
177
178 /* Now we are at the end */
179 if (PACKET_remaining(&pkt))
180 return 0;
181
182 /* Update handshake MAC for second ClientHello (with cookie) */
183 if (cookie_found && !EVP_DigestUpdate(handshake_md, data + MAC_OFFSET,
184 len - MAC_OFFSET))
185 printf("EVP_DigestUpdate() failed\n");
186
187 (void)BIO_reset(wbio);
188
189 return 1 + cookie_found;
190}
191
192static int send_hello_verify(BIO *rbio)
193{
194 static unsigned char hello_verify[] = {
195 0x16, /* Handshake */
196 0x01, 0x00, /* DTLS1_BAD_VER */
197 0x00, 0x00, /* Epoch 0 */
198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Seq# 0 */
199 0x00, 0x23, /* Length */
200 0x03, /* Hello Verify */
201 0x00, 0x00, 0x17, /* Length */
202 0x00, 0x00, /* Seq# 0 */
203 0x00, 0x00, 0x00, /* Fragment offset */
204 0x00, 0x00, 0x17, /* Fragment length */
205 0x01, 0x00, /* DTLS1_BAD_VER */
206 0x14, /* Cookie length */
207#define HV_COOKIE_OFS 28 /* Cookie goes here */
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00,
211 };
212
213 memcpy(hello_verify + HV_COOKIE_OFS, cookie, sizeof(cookie));
214
215 BIO_write(rbio, hello_verify, sizeof(hello_verify));
216
217 return 1;
218}
219
220static int send_server_hello(BIO *rbio)
221{
222 static unsigned char server_hello[] = {
223 0x16, /* Handshake */
224 0x01, 0x00, /* DTLS1_BAD_VER */
225 0x00, 0x00, /* Epoch 0 */
226 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* Seq# 1 */
227 0x00, 0x52, /* Length */
228 0x02, /* Server Hello */
229 0x00, 0x00, 0x46, /* Length */
230 0x00, 0x01, /* Seq# */
231 0x00, 0x00, 0x00, /* Fragment offset */
232 0x00, 0x00, 0x46, /* Fragment length */
233 0x01, 0x00, /* DTLS1_BAD_VER */
234#define SH_RANDOM_OFS 27 /* Server random goes here */
235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x20, /* Session ID length */
240#define SH_SESSID_OFS 60 /* Session ID goes here */
241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245 0x00, 0x2f, /* Cipher suite AES128-SHA */
246 0x00, /* Compression null */
247 };
248 static unsigned char change_cipher_spec[] = {
249 0x14, /* Change Cipher Spec */
250 0x01, 0x00, /* DTLS1_BAD_VER */
251 0x00, 0x00, /* Epoch 0 */
252 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* Seq# 2 */
253 0x00, 0x03, /* Length */
254 0x01, 0x00, 0x02, /* Message */
255 };
256
257 memcpy(server_hello + SH_RANDOM_OFS, server_random, sizeof(server_random));
258 memcpy(server_hello + SH_SESSID_OFS, session_id, sizeof(session_id));
259
260 if (!EVP_DigestUpdate(handshake_md, server_hello + MAC_OFFSET,
261 sizeof(server_hello) - MAC_OFFSET))
262 printf("EVP_DigestUpdate() failed\n");
263
264 BIO_write(rbio, server_hello, sizeof(server_hello));
265 BIO_write(rbio, change_cipher_spec, sizeof(change_cipher_spec));
266
267 return 1;
268}
269
270/* Create header, HMAC, pad, encrypt and send a record */
271static int send_record(BIO *rbio, unsigned char type, unsigned long seqnr,
272 const void *msg, size_t len)
273{
274 /* Note that the order of the record header fields on the wire,
275 * and in the HMAC, is different. So we just keep them in separate
276 * variables and handle them individually. */
277 static unsigned char epoch[2] = { 0x00, 0x01 };
278 static unsigned char seq[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
279 static unsigned char ver[2] = { 0x01, 0x00 }; /* DTLS1_BAD_VER */
280 unsigned char lenbytes[2];
281 HMAC_CTX *ctx;
282 EVP_CIPHER_CTX *enc_ctx;
283 unsigned char iv[16];
284 unsigned char pad;
285 unsigned char *enc;
286
287#ifdef SIXTY_FOUR_BIT_LONG
288 seq[0] = (seqnr >> 40) & 0xff;
289 seq[1] = (seqnr >> 32) & 0xff;
290#endif
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
347static 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 printf("EVP_DigestFinal_ex() failed\n");
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
379static 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
430static struct {
431 unsigned long 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
446int main(int argc, char *argv[])
447{
448 SSL_SESSION *sess;
449 SSL_CTX *ctx;
450 SSL *con;
451 BIO *rbio;
452 BIO *wbio;
453 BIO *err;
af5883fe 454 time_t now = 0;
16938284
DW
455 int testresult = 0;
456 int ret;
457 int i;
458
459 err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
460
461 CRYPTO_set_mem_debug(1);
462 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
463
464 RAND_bytes(session_id, sizeof(session_id));
465 RAND_bytes(master_secret, sizeof(master_secret));
466 RAND_bytes(cookie, sizeof(cookie));
467 RAND_bytes(server_random + 4, sizeof(server_random) - 4);
af5883fe
MK
468
469 now = time(NULL);
470 memcpy(server_random, &now, sizeof(now));
16938284
DW
471
472 sess = client_session();
473 if (sess == NULL) {
474 printf("Failed to generate SSL_SESSION\n");
475 goto end;
476 }
477
478 handshake_md = EVP_MD_CTX_new();
479 if (handshake_md == NULL ||
480 !EVP_DigestInit_ex(handshake_md, EVP_md5_sha1(), NULL)) {
481 printf("Failed to initialise handshake_md\n");
482 goto end;
483 }
484
485 ctx = SSL_CTX_new(DTLS_client_method());
486 if (ctx == NULL) {
487 printf("Failed to allocate SSL_CTX\n");
488 goto end_md;
489 }
490 if (!SSL_CTX_set_min_proto_version(ctx, DTLS1_BAD_VER)) {
491 printf("SSL_CTX_set_min_proto_version() failed\n");
492 goto end_ctx;
493 }
494 if (!SSL_CTX_set_max_proto_version(ctx, DTLS1_BAD_VER)) {
495 printf("SSL_CTX_set_max_proto_version() failed\n");
496 goto end_ctx;
497 }
498
499 if (!SSL_CTX_set_cipher_list(ctx, "AES128-SHA")) {
500 printf("SSL_CTX_set_cipher_list() failed\n");
501 goto end_ctx;
502 }
503
504 con = SSL_new(ctx);
505 if (!SSL_set_session(con, sess)) {
506 printf("SSL_set_session() failed\n");
507 goto end_con;
508 }
509 SSL_SESSION_free(sess);
510
511 rbio = BIO_new(BIO_s_mem());
512 wbio = BIO_new(BIO_s_mem());
513
514 BIO_set_nbio(rbio, 1);
515 BIO_set_nbio(wbio, 1);
516
517 SSL_set_bio(con, rbio, wbio);
518 SSL_set_connect_state(con);
519
520 /* Send initial ClientHello */
521 ret = SSL_do_handshake(con);
522 if (ret > 0 || SSL_get_error(con, ret) != SSL_ERROR_WANT_READ) {
523 printf("Unexpected handshake result at initial call!\n");
524 goto end_con;
525 }
526
527 if (validate_client_hello(wbio) != 1) {
528 printf("Initial ClientHello failed validation\n");
529 goto end_con;
530 }
531 if (send_hello_verify(rbio) != 1) {
532 printf("Failed to send HelloVerify\n");
533 goto end_con;
534 }
535 ret = SSL_do_handshake(con);
536 if (ret > 0 || SSL_get_error(con, ret) != SSL_ERROR_WANT_READ) {
537 printf("Unexpected handshake result after HelloVerify!\n");
538 goto end_con;
539 }
540 if (validate_client_hello(wbio) != 2) {
541 printf("Second ClientHello failed validation\n");
542 goto end_con;
543 }
544 if (send_server_hello(rbio) != 1) {
545 printf("Failed to send ServerHello\n");
546 goto end_con;
547 }
548 ret = SSL_do_handshake(con);
549 if (ret > 0 || SSL_get_error(con, ret) != SSL_ERROR_WANT_READ) {
550 printf("Unexpected handshake result after ServerHello!\n");
551 goto end_con;
552 }
553 if (send_finished(con, rbio) != 1) {
554 printf("Failed to send Finished\n");
555 goto end_con;
556 }
557 ret = SSL_do_handshake(con);
558 if (ret < 1) {
559 printf("Handshake not successful after Finished!\n");
560 goto end_con;
561 }
562 if (validate_ccs(wbio) != 1) {
563 printf("Failed to validate client CCS/Finished\n");
564 goto end_con;
565 }
566
567 /* While we're here and crafting packets by hand, we might as well do a
568 bit of a stress test on the DTLS record replay handling. Not Cisco-DTLS
569 specific but useful anyway for the general case. It's been broken
570 before, and in fact was broken even for a basic 0, 2, 1 test case
571 when this test was first added.... */
572 for (i = 0; i < (int)OSSL_NELEM(tests); i++) {
573 unsigned long recv_buf[2];
574
575 if (send_record(rbio, SSL3_RT_APPLICATION_DATA, tests[i].seq,
576 &tests[i].seq, sizeof(unsigned long)) != 1) {
577 printf("Failed to send data seq #0x%lx (%d)\n",
578 tests[i].seq, i);
579 goto end_con;
580 }
581
582 if (tests[i].drop)
583 continue;
584
585 ret = SSL_read(con, recv_buf, 2 * sizeof(unsigned long));
586 if (ret != sizeof(unsigned long)) {
587 printf("SSL_read failed or wrong size on seq#0x%lx (%d)\n",
588 tests[i].seq, i);
589 goto end_con;
590 }
591 if (recv_buf[0] != tests[i].seq) {
592 printf("Wrong data packet received (0x%lx not 0x%lx) at packet %d\n",
593 recv_buf[0], tests[i].seq, i);
594 goto end_con;
595 }
596 }
597 if (tests[i-1].drop) {
598 printf("Error: last test cannot be DROP()\n");
599 goto end_con;
600 }
601 testresult=1;
602
603 end_con:
604 SSL_free(con);
605 end_ctx:
606 SSL_CTX_free(ctx);
607 end_md:
608 EVP_MD_CTX_free(handshake_md);
609 end:
610 ERR_print_errors_fp(stderr);
611
612 if (!testresult) {
613 printf("Cisco BadDTLS test: FAILED\n");
614 }
615
616
617#ifndef OPENSSL_NO_CRYPTO_MDEBUG
618 if (CRYPTO_mem_leaks(err) <= 0)
619 testresult = 0;
620#endif
621 BIO_free(err);
622
623 return testresult?0:1;
624}