2 * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
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
11 #include <openssl/ssl.h>
12 #include <openssl/bio.h>
13 #include <openssl/err.h>
14 #include <openssl/conf.h>
15 #ifndef OPENSSL_NO_ENGINE
16 #include <openssl/engine.h>
20 #ifndef OPENSSL_NO_SOCK
22 /* Just a ClientHello without a cookie */
23 static const unsigned char clienthello_nocookie[] = {
25 0xFE, 0xFF, /* DTLSv1.0 */
26 0x00, 0x00, /* Epoch */
27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
28 0x00, 0x3A, /* Record Length */
29 0x01, /* ClientHello */
30 0x00, 0x00, 0x2E, /* Message length */
31 0x00, 0x00, /* Message sequence */
32 0x00, 0x00, 0x00, /* Fragment offset */
33 0x00, 0x00, 0x2E, /* Fragment length */
34 0xFE, 0xFD, /* DTLSv1.2 */
35 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
36 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
37 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
38 0x00, /* Session id len */
39 0x00, /* Cookie len */
40 0x00, 0x04, /* Ciphersuites len */
41 0x00, 0x2f, /* AES128-SHA */
42 0x00, 0xff, /* Empty reneg info SCSV */
43 0x01, /* Compression methods len */
44 0x00, /* Null compression */
45 0x00, 0x00 /* Extensions len */
48 /* First fragment of a ClientHello without a cookie */
49 static const unsigned char clienthello_nocookie_frag[] = {
51 0xFE, 0xFF, /* DTLSv1.0 */
52 0x00, 0x00, /* Epoch */
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
54 0x00, 0x30, /* Record Length */
55 0x01, /* ClientHello */
56 0x00, 0x00, 0x2E, /* Message length */
57 0x00, 0x00, /* Message sequence */
58 0x00, 0x00, 0x00, /* Fragment offset */
59 0x00, 0x00, 0x24, /* Fragment length */
60 0xFE, 0xFD, /* DTLSv1.2 */
61 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
62 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
63 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
64 0x00, /* Session id len */
68 /* First fragment of a ClientHello which is too short */
69 static const unsigned char clienthello_nocookie_short[] = {
71 0xFE, 0xFF, /* DTLSv1.0 */
72 0x00, 0x00, /* Epoch */
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
74 0x00, 0x2F, /* Record Length */
75 0x01, /* ClientHello */
76 0x00, 0x00, 0x2E, /* Message length */
77 0x00, 0x00, /* Message sequence */
78 0x00, 0x00, 0x00, /* Fragment offset */
79 0x00, 0x00, 0x23, /* Fragment length */
80 0xFE, 0xFD, /* DTLSv1.2 */
81 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
82 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
83 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
84 0x00 /* Session id len */
87 /* Second fragment of a ClientHello */
88 static const unsigned char clienthello_2ndfrag[] = {
90 0xFE, 0xFF, /* DTLSv1.0 */
91 0x00, 0x00, /* Epoch */
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
93 0x00, 0x38, /* Record Length */
94 0x01, /* ClientHello */
95 0x00, 0x00, 0x2E, /* Message length */
96 0x00, 0x00, /* Message sequence */
97 0x00, 0x00, 0x02, /* Fragment offset */
98 0x00, 0x00, 0x2C, /* Fragment length */
99 /* Version skipped - sent in first fragment */
100 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
101 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
102 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
103 0x00, /* Session id len */
104 0x00, /* Cookie len */
105 0x00, 0x04, /* Ciphersuites len */
106 0x00, 0x2f, /* AES128-SHA */
107 0x00, 0xff, /* Empty reneg info SCSV */
108 0x01, /* Compression methods len */
109 0x00, /* Null compression */
110 0x00, 0x00 /* Extensions len */
113 /* A ClientHello with a good cookie */
114 static const unsigned char clienthello_cookie[] = {
115 0x16, /* Handshake */
116 0xFE, 0xFF, /* DTLSv1.0 */
117 0x00, 0x00, /* Epoch */
118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
119 0x00, 0x4E, /* Record Length */
120 0x01, /* ClientHello */
121 0x00, 0x00, 0x42, /* Message length */
122 0x00, 0x00, /* Message sequence */
123 0x00, 0x00, 0x00, /* Fragment offset */
124 0x00, 0x00, 0x42, /* Fragment length */
125 0xFE, 0xFD, /* DTLSv1.2 */
126 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
127 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
128 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
129 0x00, /* Session id len */
130 0x14, /* Cookie len */
131 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
132 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
133 0x00, 0x04, /* Ciphersuites len */
134 0x00, 0x2f, /* AES128-SHA */
135 0x00, 0xff, /* Empty reneg info SCSV */
136 0x01, /* Compression methods len */
137 0x00, /* Null compression */
138 0x00, 0x00 /* Extensions len */
141 /* A fragmented ClientHello with a good cookie */
142 static const unsigned char clienthello_cookie_frag[] = {
143 0x16, /* Handshake */
144 0xFE, 0xFF, /* DTLSv1.0 */
145 0x00, 0x00, /* Epoch */
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
147 0x00, 0x44, /* Record Length */
148 0x01, /* ClientHello */
149 0x00, 0x00, 0x42, /* Message length */
150 0x00, 0x00, /* Message sequence */
151 0x00, 0x00, 0x00, /* Fragment offset */
152 0x00, 0x00, 0x38, /* Fragment length */
153 0xFE, 0xFD, /* DTLSv1.2 */
154 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
155 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
156 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
157 0x00, /* Session id len */
158 0x14, /* Cookie len */
159 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
160 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
164 /* A ClientHello with a bad cookie */
165 static const unsigned char clienthello_badcookie[] = {
166 0x16, /* Handshake */
167 0xFE, 0xFF, /* DTLSv1.0 */
168 0x00, 0x00, /* Epoch */
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
170 0x00, 0x4E, /* Record Length */
171 0x01, /* ClientHello */
172 0x00, 0x00, 0x42, /* Message length */
173 0x00, 0x00, /* Message sequence */
174 0x00, 0x00, 0x00, /* Fragment offset */
175 0x00, 0x00, 0x42, /* Fragment length */
176 0xFE, 0xFD, /* DTLSv1.2 */
177 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
178 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
179 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
180 0x00, /* Session id len */
181 0x14, /* Cookie len */
182 0x01, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
183 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
184 0x00, 0x04, /* Ciphersuites len */
185 0x00, 0x2f, /* AES128-SHA */
186 0x00, 0xff, /* Empty reneg info SCSV */
187 0x01, /* Compression methods len */
188 0x00, /* Null compression */
189 0x00, 0x00 /* Extensions len */
192 /* A fragmented ClientHello with the fragment boundary mid cookie */
193 static const unsigned char clienthello_cookie_short[] = {
194 0x16, /* Handshake */
195 0xFE, 0xFF, /* DTLSv1.0 */
196 0x00, 0x00, /* Epoch */
197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
198 0x00, 0x43, /* Record Length */
199 0x01, /* ClientHello */
200 0x00, 0x00, 0x42, /* Message length */
201 0x00, 0x00, /* Message sequence */
202 0x00, 0x00, 0x00, /* Fragment offset */
203 0x00, 0x00, 0x37, /* Fragment length */
204 0xFE, 0xFD, /* DTLSv1.2 */
205 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
206 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
207 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
208 0x00, /* Session id len */
209 0x14, /* Cookie len */
210 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
211 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12 /* Cookie */
214 /* Bad record - too short */
215 static const unsigned char record_short[] = {
216 0x16, /* Handshake */
217 0xFE, 0xFF, /* DTLSv1.0 */
218 0x00, 0x00, /* Epoch */
219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* Record sequence number */
222 static const unsigned char verify[] = {
223 0x16, /* Handshake */
224 0xFE, 0xFF, /* DTLSv1.0 */
225 0x00, 0x00, /* Epoch */
226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
227 0x00, 0x23, /* Record Length */
228 0x03, /* HelloVerifyRequest */
229 0x00, 0x00, 0x17, /* Message length */
230 0x00, 0x00, /* Message sequence */
231 0x00, 0x00, 0x00, /* Fragment offset */
232 0x00, 0x00, 0x17, /* Fragment length */
233 0xFE, 0xFF, /* DTLSv1.0 */
234 0x14, /* Cookie len */
235 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
236 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
240 const unsigned char *in;
243 * GOOD == positive return value from DTLSv1_listen, no output yet
244 * VERIFY == 0 return value, HelloVerifyRequest sent
245 * DROP == 0 return value, no output
247 enum {GOOD, VERIFY, DROP} outtype;
250 clienthello_nocookie,
251 sizeof(clienthello_nocookie),
255 clienthello_nocookie_frag,
256 sizeof(clienthello_nocookie_frag),
260 clienthello_nocookie_short,
261 sizeof(clienthello_nocookie_short),
266 sizeof(clienthello_2ndfrag),
271 sizeof(clienthello_cookie),
275 clienthello_cookie_frag,
276 sizeof(clienthello_cookie_frag),
280 clienthello_badcookie,
281 sizeof(clienthello_badcookie),
285 clienthello_cookie_short,
286 sizeof(clienthello_cookie_short),
291 sizeof(record_short),
296 # define COOKIE_LEN 20
298 static int cookie_gen(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
302 for (i = 0; i < COOKIE_LEN; i++, cookie++) {
305 *cookie_len = COOKIE_LEN;
310 static int cookie_verify(SSL *ssl, const unsigned char *cookie,
311 unsigned int cookie_len)
315 if (cookie_len != COOKIE_LEN)
318 for (i = 0; i < COOKIE_LEN; i++, cookie++) {
329 #ifndef OPENSSL_NO_SOCK
334 BIO_ADDR *peer = BIO_ADDR_new();
337 int ret, success = 0;
340 ctx = SSL_CTX_new(DTLS_server_method());
341 if (ctx == NULL || peer == NULL)
344 SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen);
345 SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify);
347 /* Create an SSL object for the connection */
352 outbio = BIO_new(BIO_s_mem());
355 SSL_set0_wbio(ssl, outbio);
358 for (i = 0; i < (long)OSSL_NELEM(testpackets) && success; i++) {
359 inbio = BIO_new_mem_buf((char *)testpackets[i].in,
360 testpackets[i].inlen);
365 /* Set Non-blocking IO behaviour */
366 BIO_set_mem_eof_return(inbio, -1);
368 SSL_set0_rbio(ssl, inbio);
370 /* Process the incoming packet */
371 ret = DTLSv1_listen(ssl, peer);
377 datalen = BIO_get_mem_data(outbio, &data);
379 if (testpackets[i].outtype == VERIFY) {
381 if (datalen != sizeof(verify)
382 || (memcmp(data, verify, sizeof(verify)) != 0)) {
383 printf("Test %ld failure: incorrect HelloVerifyRequest\n", i);
386 printf("Test %ld success\n", i);
389 printf ("Test %ld failure: should not have succeeded\n", i);
392 } else if (datalen == 0) {
393 if ((ret == 0 && testpackets[i].outtype == DROP)
394 || (ret == 1 && testpackets[i].outtype == GOOD)) {
395 printf("Test %ld success\n", i);
397 printf("Test %ld failure: wrong return value\n", i);
401 printf("Test %ld failure: Unexpected data output\n", i);
404 (void)BIO_reset(outbio);
407 SSL_set0_rbio(ssl, NULL);
412 ERR_print_errors_fp(stderr);
413 /* Also frees up outbio */
418 # ifndef OPENSSL_NO_CRYPTO_MDEBUG
419 CRYPTO_mem_leaks_fp(stderr);
421 return success ? 0 : 1;
423 printf("DTLSv1_listen() is not supported by this build - skipping\n");