2 * Written by Matt Caswell for the OpenSSL project.
4 /* ====================================================================
5 * Copyright (c) 2016 The OpenSSL Project. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * openssl-core@openssl.org.
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
33 * 6. Redistributions of any form whatsoever must retain the following
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com).
59 #include <openssl/ssl.h>
60 #include <openssl/bio.h>
61 #include <openssl/err.h>
62 #include <openssl/conf.h>
63 #ifndef OPENSSL_NO_ENGINE
64 #include <openssl/engine.h>
68 #ifndef OPENSSL_NO_SOCK
70 /* Just a ClientHello without a cookie */
71 static const unsigned char clienthello_nocookie[] = {
73 0xFE, 0xFF, /* DTLSv1.0 */
74 0x00, 0x00, /* Epoch */
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
76 0x00, 0x3A, /* Record Length */
77 0x01, /* ClientHello */
78 0x00, 0x00, 0x2E, /* Message length */
79 0x00, 0x00, /* Message sequence */
80 0x00, 0x00, 0x00, /* Fragment offset */
81 0x00, 0x00, 0x2E, /* Fragment length */
82 0xFE, 0xFD, /* DTLSv1.2 */
83 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
84 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
85 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
86 0x00, /* Session id len */
87 0x00, /* Cookie len */
88 0x00, 0x04, /* Ciphersuites len */
89 0x00, 0x2f, /* AES128-SHA */
90 0x00, 0xff, /* Empty reneg info SCSV */
91 0x01, /* Compression methods len */
92 0x00, /* Null compression */
93 0x00, 0x00 /* Extensions len */
96 /* First fragment of a ClientHello without a cookie */
97 static const unsigned char clienthello_nocookie_frag[] = {
99 0xFE, 0xFF, /* DTLSv1.0 */
100 0x00, 0x00, /* Epoch */
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
102 0x00, 0x30, /* Record Length */
103 0x01, /* ClientHello */
104 0x00, 0x00, 0x2E, /* Message length */
105 0x00, 0x00, /* Message sequence */
106 0x00, 0x00, 0x00, /* Fragment offset */
107 0x00, 0x00, 0x24, /* Fragment length */
108 0xFE, 0xFD, /* DTLSv1.2 */
109 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
110 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
111 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
112 0x00, /* Session id len */
113 0x00 /* Cookie len */
116 /* First fragment of a ClientHello which is too short */
117 static const unsigned char clienthello_nocookie_short[] = {
118 0x16, /* Handshake */
119 0xFE, 0xFF, /* DTLSv1.0 */
120 0x00, 0x00, /* Epoch */
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
122 0x00, 0x2F, /* Record Length */
123 0x01, /* ClientHello */
124 0x00, 0x00, 0x2E, /* Message length */
125 0x00, 0x00, /* Message sequence */
126 0x00, 0x00, 0x00, /* Fragment offset */
127 0x00, 0x00, 0x23, /* Fragment length */
128 0xFE, 0xFD, /* DTLSv1.2 */
129 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
130 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
131 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
132 0x00 /* Session id len */
135 /* Second fragment of a ClientHello */
136 static const unsigned char clienthello_2ndfrag[] = {
137 0x16, /* Handshake */
138 0xFE, 0xFF, /* DTLSv1.0 */
139 0x00, 0x00, /* Epoch */
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
141 0x00, 0x38, /* Record Length */
142 0x01, /* ClientHello */
143 0x00, 0x00, 0x2E, /* Message length */
144 0x00, 0x00, /* Message sequence */
145 0x00, 0x00, 0x02, /* Fragment offset */
146 0x00, 0x00, 0x2C, /* Fragment length */
147 /* Version skipped - sent in first fragment */
148 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
149 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
150 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
151 0x00, /* Session id len */
152 0x00, /* Cookie len */
153 0x00, 0x04, /* Ciphersuites len */
154 0x00, 0x2f, /* AES128-SHA */
155 0x00, 0xff, /* Empty reneg info SCSV */
156 0x01, /* Compression methods len */
157 0x00, /* Null compression */
158 0x00, 0x00 /* Extensions len */
161 /* A ClientHello with a good cookie */
162 static const unsigned char clienthello_cookie[] = {
163 0x16, /* Handshake */
164 0xFE, 0xFF, /* DTLSv1.0 */
165 0x00, 0x00, /* Epoch */
166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
167 0x00, 0x4E, /* Record Length */
168 0x01, /* ClientHello */
169 0x00, 0x00, 0x42, /* Message length */
170 0x00, 0x00, /* Message sequence */
171 0x00, 0x00, 0x00, /* Fragment offset */
172 0x00, 0x00, 0x42, /* Fragment length */
173 0xFE, 0xFD, /* DTLSv1.2 */
174 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
175 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
176 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
177 0x00, /* Session id len */
178 0x14, /* Cookie len */
179 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
180 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
181 0x00, 0x04, /* Ciphersuites len */
182 0x00, 0x2f, /* AES128-SHA */
183 0x00, 0xff, /* Empty reneg info SCSV */
184 0x01, /* Compression methods len */
185 0x00, /* Null compression */
186 0x00, 0x00 /* Extensions len */
189 /* A fragmented ClientHello with a good cookie */
190 static const unsigned char clienthello_cookie_frag[] = {
191 0x16, /* Handshake */
192 0xFE, 0xFF, /* DTLSv1.0 */
193 0x00, 0x00, /* Epoch */
194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
195 0x00, 0x44, /* Record Length */
196 0x01, /* ClientHello */
197 0x00, 0x00, 0x42, /* Message length */
198 0x00, 0x00, /* Message sequence */
199 0x00, 0x00, 0x00, /* Fragment offset */
200 0x00, 0x00, 0x38, /* Fragment length */
201 0xFE, 0xFD, /* DTLSv1.2 */
202 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
203 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
204 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
205 0x00, /* Session id len */
206 0x14, /* Cookie len */
207 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
208 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
212 /* A ClientHello with a bad cookie */
213 static const unsigned char clienthello_badcookie[] = {
214 0x16, /* Handshake */
215 0xFE, 0xFF, /* DTLSv1.0 */
216 0x00, 0x00, /* Epoch */
217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
218 0x00, 0x4E, /* Record Length */
219 0x01, /* ClientHello */
220 0x00, 0x00, 0x42, /* Message length */
221 0x00, 0x00, /* Message sequence */
222 0x00, 0x00, 0x00, /* Fragment offset */
223 0x00, 0x00, 0x42, /* Fragment length */
224 0xFE, 0xFD, /* DTLSv1.2 */
225 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
226 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
227 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
228 0x00, /* Session id len */
229 0x14, /* Cookie len */
230 0x01, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
231 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
232 0x00, 0x04, /* Ciphersuites len */
233 0x00, 0x2f, /* AES128-SHA */
234 0x00, 0xff, /* Empty reneg info SCSV */
235 0x01, /* Compression methods len */
236 0x00, /* Null compression */
237 0x00, 0x00 /* Extensions len */
240 /* A fragmented ClientHello with the fragment boundary mid cookie */
241 static const unsigned char clienthello_cookie_short[] = {
242 0x16, /* Handshake */
243 0xFE, 0xFF, /* DTLSv1.0 */
244 0x00, 0x00, /* Epoch */
245 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
246 0x00, 0x43, /* Record Length */
247 0x01, /* ClientHello */
248 0x00, 0x00, 0x42, /* Message length */
249 0x00, 0x00, /* Message sequence */
250 0x00, 0x00, 0x00, /* Fragment offset */
251 0x00, 0x00, 0x37, /* Fragment length */
252 0xFE, 0xFD, /* DTLSv1.2 */
253 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
254 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
255 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
256 0x00, /* Session id len */
257 0x14, /* Cookie len */
258 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
259 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12 /* Cookie */
262 /* Bad record - too short */
263 static const unsigned char record_short[] = {
264 0x16, /* Handshake */
265 0xFE, 0xFF, /* DTLSv1.0 */
266 0x00, 0x00, /* Epoch */
267 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* Record sequence number */
270 static const unsigned char verify[] = {
271 0x16, /* Handshake */
272 0xFE, 0xFF, /* DTLSv1.0 */
273 0x00, 0x00, /* Epoch */
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
275 0x00, 0x23, /* Record Length */
276 0x03, /* HelloVerifyRequest */
277 0x00, 0x00, 0x17, /* Message length */
278 0x00, 0x00, /* Message sequence */
279 0x00, 0x00, 0x00, /* Fragment offset */
280 0x00, 0x00, 0x17, /* Fragment length */
281 0xFE, 0xFF, /* DTLSv1.0 */
282 0x14, /* Cookie len */
283 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
284 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
288 const unsigned char *in;
291 * GOOD == positive return value from DTLSv1_listen, no output yet
292 * VERIFY == 0 return value, HelloVerifyRequest sent
293 * DROP == 0 return value, no output
295 enum {GOOD, VERIFY, DROP} outtype;
298 clienthello_nocookie,
299 sizeof(clienthello_nocookie),
303 clienthello_nocookie_frag,
304 sizeof(clienthello_nocookie_frag),
308 clienthello_nocookie_short,
309 sizeof(clienthello_nocookie_short),
314 sizeof(clienthello_2ndfrag),
319 sizeof(clienthello_cookie),
323 clienthello_cookie_frag,
324 sizeof(clienthello_cookie_frag),
328 clienthello_badcookie,
329 sizeof(clienthello_badcookie),
333 clienthello_cookie_short,
334 sizeof(clienthello_cookie_short),
339 sizeof(record_short),
344 # define COOKIE_LEN 20
346 static int cookie_gen(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
350 for (i = 0; i < COOKIE_LEN; i++, cookie++) {
353 *cookie_len = COOKIE_LEN;
358 static int cookie_verify(SSL *ssl, const unsigned char *cookie,
359 unsigned int cookie_len)
363 if (cookie_len != COOKIE_LEN)
366 for (i = 0; i < COOKIE_LEN; i++, cookie++) {
377 #ifndef OPENSSL_NO_SOCK
382 BIO_ADDR *peer = BIO_ADDR_new();
385 int ret, success = 0;
388 ctx = SSL_CTX_new(DTLS_server_method());
389 if (ctx == NULL || peer == NULL)
392 SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen);
393 SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify);
395 /* Create an SSL object for the connection */
400 outbio = BIO_new(BIO_s_mem());
403 SSL_set_wbio(ssl, outbio);
406 for (i = 0; i < (long)OSSL_NELEM(testpackets) && success; i++) {
407 inbio = BIO_new_mem_buf((char *)testpackets[i].in,
408 testpackets[i].inlen);
413 /* Set Non-blocking IO behaviour */
414 BIO_set_mem_eof_return(inbio, -1);
416 SSL_set_rbio(ssl, inbio);
418 /* Process the incoming packet */
419 ret = DTLSv1_listen(ssl, peer);
425 datalen = BIO_get_mem_data(outbio, &data);
427 if (testpackets[i].outtype == VERIFY) {
429 if (datalen != sizeof(verify)
430 || (memcmp(data, verify, sizeof(verify)) != 0)) {
431 printf("Test %ld failure: incorrect HelloVerifyRequest\n", i);
434 printf("Test %ld success\n", i);
437 printf ("Test %ld failure: should not have succeeded\n", i);
440 } else if (datalen == 0) {
441 if ((ret == 0 && testpackets[i].outtype == DROP)
442 || (ret == 1 && testpackets[i].outtype == GOOD)) {
443 printf("Test %ld success\n", i);
445 printf("Test %ld failure: wrong return value\n", i);
449 printf("Test %ld failure: Unexpected data output\n", i);
452 (void)BIO_reset(outbio);
455 SSL_set_rbio(ssl, NULL);
460 ERR_print_errors_fp(stderr);
461 /* Also frees up outbio */
466 # ifndef OPENSSL_NO_CRYPTO_MDEBUG
467 CRYPTO_mem_leaks_fp(stderr);
469 return success ? 0 : 1;
471 printf("DTLSv1_listen() is not supported by this build - skipping\n");