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 #include <openssl/engine.h>
66 /* Just a ClientHello without a cookie */
67 static const unsigned char clienthello_nocookie[] = {
69 0xFE, 0xFF, /* DTLSv1.0 */
70 0x00, 0x00, /* Epoch */
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
72 0x00, 0x3A, /* Record Length */
73 0x01, /* ClientHello */
74 0x00, 0x00, 0x2E, /* Message length */
75 0x00, 0x00, /* Message sequence */
76 0x00, 0x00, 0x00, /* Fragment offset */
77 0x00, 0x00, 0x2E, /* Fragment length */
78 0xFE, 0xFD, /* DTLSv1.2 */
79 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
80 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
81 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
82 0x00, /* Session id len */
83 0x00, /* Cookie len */
84 0x00, 0x04, /* Ciphersuites len */
85 0x00, 0x2f, /* AES128-SHA */
86 0x00, 0xff, /* Empty reneg info SCSV */
87 0x01, /* Compression methods len */
88 0x00, /* Null compression */
89 0x00, 0x00 /* Extensions len */
92 /* First fragment of a ClientHello without a cookie */
93 static const unsigned char clienthello_nocookie_frag[] = {
95 0xFE, 0xFF, /* DTLSv1.0 */
96 0x00, 0x00, /* Epoch */
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
98 0x00, 0x30, /* Record Length */
99 0x01, /* ClientHello */
100 0x00, 0x00, 0x2E, /* Message length */
101 0x00, 0x00, /* Message sequence */
102 0x00, 0x00, 0x00, /* Fragment offset */
103 0x00, 0x00, 0x24, /* Fragment length */
104 0xFE, 0xFD, /* DTLSv1.2 */
105 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
106 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
107 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
108 0x00, /* Session id len */
109 0x00 /* Cookie len */
112 /* First fragment of a ClientHello which is too short */
113 static const unsigned char clienthello_nocookie_short[] = {
114 0x16, /* Handshake */
115 0xFE, 0xFF, /* DTLSv1.0 */
116 0x00, 0x00, /* Epoch */
117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
118 0x00, 0x2F, /* Record Length */
119 0x01, /* ClientHello */
120 0x00, 0x00, 0x2E, /* Message length */
121 0x00, 0x00, /* Message sequence */
122 0x00, 0x00, 0x00, /* Fragment offset */
123 0x00, 0x00, 0x23, /* Fragment length */
124 0xFE, 0xFD, /* DTLSv1.2 */
125 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
126 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
127 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
128 0x00 /* Session id len */
131 /* Second fragment of a ClientHello */
132 static const unsigned char clienthello_2ndfrag[] = {
133 0x16, /* Handshake */
134 0xFE, 0xFF, /* DTLSv1.0 */
135 0x00, 0x00, /* Epoch */
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
137 0x00, 0x38, /* Record Length */
138 0x01, /* ClientHello */
139 0x00, 0x00, 0x2E, /* Message length */
140 0x00, 0x00, /* Message sequence */
141 0x00, 0x00, 0x02, /* Fragment offset */
142 0x00, 0x00, 0x2C, /* Fragment length */
143 /* Version skipped - sent in first fragment */
144 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
145 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
146 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
147 0x00, /* Session id len */
148 0x00, /* Cookie len */
149 0x00, 0x04, /* Ciphersuites len */
150 0x00, 0x2f, /* AES128-SHA */
151 0x00, 0xff, /* Empty reneg info SCSV */
152 0x01, /* Compression methods len */
153 0x00, /* Null compression */
154 0x00, 0x00 /* Extensions len */
157 /* A ClientHello with a good cookie */
158 static const unsigned char clienthello_cookie[] = {
159 0x16, /* Handshake */
160 0xFE, 0xFF, /* DTLSv1.0 */
161 0x00, 0x00, /* Epoch */
162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
163 0x00, 0x4E, /* Record Length */
164 0x01, /* ClientHello */
165 0x00, 0x00, 0x42, /* Message length */
166 0x00, 0x00, /* Message sequence */
167 0x00, 0x00, 0x00, /* Fragment offset */
168 0x00, 0x00, 0x42, /* Fragment length */
169 0xFE, 0xFD, /* DTLSv1.2 */
170 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
171 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
172 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
173 0x00, /* Session id len */
174 0x14, /* Cookie len */
175 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
176 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
177 0x00, 0x04, /* Ciphersuites len */
178 0x00, 0x2f, /* AES128-SHA */
179 0x00, 0xff, /* Empty reneg info SCSV */
180 0x01, /* Compression methods len */
181 0x00, /* Null compression */
182 0x00, 0x00 /* Extensions len */
185 /* A fragmented ClientHello with a good cookie */
186 static const unsigned char clienthello_cookie_frag[] = {
187 0x16, /* Handshake */
188 0xFE, 0xFF, /* DTLSv1.0 */
189 0x00, 0x00, /* Epoch */
190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
191 0x00, 0x44, /* Record Length */
192 0x01, /* ClientHello */
193 0x00, 0x00, 0x42, /* Message length */
194 0x00, 0x00, /* Message sequence */
195 0x00, 0x00, 0x00, /* Fragment offset */
196 0x00, 0x00, 0x38, /* Fragment length */
197 0xFE, 0xFD, /* DTLSv1.2 */
198 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
199 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
200 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
201 0x00, /* Session id len */
202 0x14, /* Cookie len */
203 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
204 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
208 /* A ClientHello with a bad cookie */
209 static const unsigned char clienthello_badcookie[] = {
210 0x16, /* Handshake */
211 0xFE, 0xFF, /* DTLSv1.0 */
212 0x00, 0x00, /* Epoch */
213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
214 0x00, 0x4E, /* Record Length */
215 0x01, /* ClientHello */
216 0x00, 0x00, 0x42, /* Message length */
217 0x00, 0x00, /* Message sequence */
218 0x00, 0x00, 0x00, /* Fragment offset */
219 0x00, 0x00, 0x42, /* Fragment length */
220 0xFE, 0xFD, /* DTLSv1.2 */
221 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
222 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
223 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
224 0x00, /* Session id len */
225 0x14, /* Cookie len */
226 0x01, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
227 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
228 0x00, 0x04, /* Ciphersuites len */
229 0x00, 0x2f, /* AES128-SHA */
230 0x00, 0xff, /* Empty reneg info SCSV */
231 0x01, /* Compression methods len */
232 0x00, /* Null compression */
233 0x00, 0x00 /* Extensions len */
236 /* A fragmented ClientHello with the fragment boundary mid cookie */
237 static const unsigned char clienthello_cookie_short[] = {
238 0x16, /* Handshake */
239 0xFE, 0xFF, /* DTLSv1.0 */
240 0x00, 0x00, /* Epoch */
241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
242 0x00, 0x43, /* Record Length */
243 0x01, /* ClientHello */
244 0x00, 0x00, 0x42, /* Message length */
245 0x00, 0x00, /* Message sequence */
246 0x00, 0x00, 0x00, /* Fragment offset */
247 0x00, 0x00, 0x37, /* Fragment length */
248 0xFE, 0xFD, /* DTLSv1.2 */
249 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
250 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
251 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
252 0x00, /* Session id len */
253 0x14, /* Cookie len */
254 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
255 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12 /* Cookie */
258 /* Bad record - too short */
259 static const unsigned char record_short[] = {
260 0x16, /* Handshake */
261 0xFE, 0xFF, /* DTLSv1.0 */
262 0x00, 0x00, /* Epoch */
263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* Record sequence number */
266 static const unsigned char verify[] = {
267 0x16, /* Handshake */
268 0xFE, 0xFF, /* DTLSv1.0 */
269 0x00, 0x00, /* Epoch */
270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
271 0x00, 0x23, /* Record Length */
272 0x03, /* HelloVerifyRequest */
273 0x00, 0x00, 0x17, /* Message length */
274 0x00, 0x00, /* Message sequence */
275 0x00, 0x00, 0x00, /* Fragment offset */
276 0x00, 0x00, 0x17, /* Fragment length */
277 0xFE, 0xFF, /* DTLSv1.0 */
278 0x14, /* Cookie len */
279 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
280 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
284 const unsigned char *in;
287 * GOOD == positive return value from DTLSv1_listen, no output yet
288 * VERIFY == 0 return value, HelloVerifyRequest sent
289 * DROP == 0 return value, no output
291 enum {GOOD, VERIFY, DROP} outtype;
294 clienthello_nocookie,
295 sizeof(clienthello_nocookie),
299 clienthello_nocookie_frag,
300 sizeof(clienthello_nocookie_frag),
304 clienthello_nocookie_short,
305 sizeof(clienthello_nocookie_short),
310 sizeof(clienthello_2ndfrag),
315 sizeof(clienthello_cookie),
319 clienthello_cookie_frag,
320 sizeof(clienthello_cookie_frag),
324 clienthello_badcookie,
325 sizeof(clienthello_badcookie),
329 clienthello_cookie_short,
330 sizeof(clienthello_cookie_short),
335 sizeof(record_short),
340 #define COOKIE_LEN 20
342 static int cookie_gen(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
346 for (i = 0; i < COOKIE_LEN; i++, cookie++) {
349 *cookie_len = COOKIE_LEN;
354 static int cookie_verify(SSL *ssl, const unsigned char *cookie,
355 unsigned int cookie_len)
359 if (cookie_len != COOKIE_LEN)
362 for (i = 0; i < COOKIE_LEN; i++, cookie++) {
376 BIO_ADDR *peer = BIO_ADDR_new();
379 int ret, success = 0;
382 ctx = SSL_CTX_new(DTLS_server_method());
383 if (ctx == NULL || peer == NULL)
386 SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen);
387 SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify);
389 /* Create an SSL object for the connection */
394 outbio = BIO_new(BIO_s_mem());
397 SSL_set_wbio(ssl, outbio);
400 for (i = 0; i < (long)OSSL_NELEM(testpackets) && success; i++) {
401 inbio = BIO_new_mem_buf((char *)testpackets[i].in,
402 testpackets[i].inlen);
407 /* Set Non-blocking IO behaviour */
408 BIO_set_mem_eof_return(inbio, -1);
410 SSL_set_rbio(ssl, inbio);
412 /* Process the incoming packet */
413 ret = DTLSv1_listen(ssl, peer);
419 datalen = BIO_get_mem_data(outbio, &data);
421 if (testpackets[i].outtype == VERIFY) {
423 if (datalen != sizeof(verify)
424 || (memcmp(data, verify, sizeof(verify)) != 0)) {
425 printf("Test %ld failure: incorrect HelloVerifyRequest\n", i);
428 printf("Test %ld success\n", i);
431 printf ("Test %ld failure: should not have succeeded\n", i);
434 } else if (datalen == 0) {
435 if ((ret == 0 && testpackets[i].outtype == DROP)
436 || (ret == 1 && testpackets[i].outtype == GOOD)) {
437 printf("Test %ld success\n", i);
439 printf("Test %ld failure: wrong return value\n", i);
443 printf("Test %ld failure: Unexpected data output\n", i);
446 (void)BIO_reset(outbio);
449 SSL_set_rbio(ssl, NULL);
454 ERR_print_errors_fp(stderr);
455 /* Also frees up outbio */
460 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
461 CRYPTO_mem_leaks_fp(stderr);
463 return success ? 0 : 1;