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