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 <sys/socket.h>
60 #include <openssl/ssl.h>
61 #include <openssl/bio.h>
62 #include <openssl/err.h>
63 #include <openssl/conf.h>
64 #include <openssl/engine.h>
67 /* Just a ClientHello without a cookie */
68 const unsigned char clienthello_nocookie[] = {
70 0xFE, 0xFF, /* DTLSv1.0 */
71 0x00, 0x00, /* Epoch */
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
73 0x00, 0x3A, /* Record Length */
74 0x01, /* ClientHello */
75 0x00, 0x00, 0x2E, /* Message length */
76 0x00, 0x00, /* Message sequence */
77 0x00, 0x00, 0x00, /* Fragment offset */
78 0x00, 0x00, 0x2E, /* Fragment length */
79 0xFE, 0xFD, /* DTLSv1.2 */
80 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
81 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
82 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
83 0x00, /* Session id len */
84 0x00, /* Cookie len */
85 0x00, 0x04, /* Ciphersuites len */
86 0x00, 0x2f, /* AES128-SHA */
87 0x00, 0xff, /* Empty reneg info SCSV */
88 0x01, /* Compression methods len */
89 0x00, /* Null compression */
90 0x00, 0x00 /* Extensions len */
93 /* First fragment of a ClientHello without a cookie */
94 const unsigned char clienthello_nocookie_frag[] = {
96 0xFE, 0xFF, /* DTLSv1.0 */
97 0x00, 0x00, /* Epoch */
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
99 0x00, 0x30, /* Record Length */
100 0x01, /* ClientHello */
101 0x00, 0x00, 0x2E, /* Message length */
102 0x00, 0x00, /* Message sequence */
103 0x00, 0x00, 0x00, /* Fragment offset */
104 0x00, 0x00, 0x24, /* Fragment length */
105 0xFE, 0xFD, /* DTLSv1.2 */
106 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
107 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
108 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
109 0x00, /* Session id len */
110 0x00 /* Cookie len */
113 /* First fragment of a ClientHello which is too short */
114 const unsigned char clienthello_nocookie_short[] = {
115 0x16, /* Handshake */
116 0xFE, 0xFF, /* DTLSv1.0 */
117 0x00, 0x00, /* Epoch */
118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
119 0x00, 0x2F, /* Record Length */
120 0x01, /* ClientHello */
121 0x00, 0x00, 0x2E, /* Message length */
122 0x00, 0x00, /* Message sequence */
123 0x00, 0x00, 0x00, /* Fragment offset */
124 0x00, 0x00, 0x23, /* 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 */
132 /* Second fragment of a ClientHello */
133 const unsigned char clienthello_2ndfrag[] = {
134 0x16, /* Handshake */
135 0xFE, 0xFF, /* DTLSv1.0 */
136 0x00, 0x00, /* Epoch */
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
138 0x00, 0x38, /* Record Length */
139 0x01, /* ClientHello */
140 0x00, 0x00, 0x2E, /* Message length */
141 0x00, 0x00, /* Message sequence */
142 0x00, 0x00, 0x02, /* Fragment offset */
143 0x00, 0x00, 0x2C, /* Fragment length */
144 /* Version skipped - sent in first fragment */
145 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
146 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
147 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
148 0x00, /* Session id len */
149 0x00, /* Cookie len */
150 0x00, 0x04, /* Ciphersuites len */
151 0x00, 0x2f, /* AES128-SHA */
152 0x00, 0xff, /* Empty reneg info SCSV */
153 0x01, /* Compression methods len */
154 0x00, /* Null compression */
155 0x00, 0x00 /* Extensions len */
158 /* A ClientHello with a good cookie */
159 const unsigned char clienthello_cookie[] = {
160 0x16, /* Handshake */
161 0xFE, 0xFF, /* DTLSv1.0 */
162 0x00, 0x00, /* Epoch */
163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
164 0x00, 0x4E, /* Record Length */
165 0x01, /* ClientHello */
166 0x00, 0x00, 0x42, /* Message length */
167 0x00, 0x00, /* Message sequence */
168 0x00, 0x00, 0x00, /* Fragment offset */
169 0x00, 0x00, 0x42, /* Fragment length */
170 0xFE, 0xFD, /* DTLSv1.2 */
171 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
172 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
173 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
174 0x00, /* Session id len */
175 0x14, /* Cookie len */
176 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
177 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
178 0x00, 0x04, /* Ciphersuites len */
179 0x00, 0x2f, /* AES128-SHA */
180 0x00, 0xff, /* Empty reneg info SCSV */
181 0x01, /* Compression methods len */
182 0x00, /* Null compression */
183 0x00, 0x00 /* Extensions len */
186 /* A fragmented ClientHello with a good cookie */
187 const unsigned char clienthello_cookie_frag[] = {
188 0x16, /* Handshake */
189 0xFE, 0xFF, /* DTLSv1.0 */
190 0x00, 0x00, /* Epoch */
191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
192 0x00, 0x44, /* Record Length */
193 0x01, /* ClientHello */
194 0x00, 0x00, 0x42, /* Message length */
195 0x00, 0x00, /* Message sequence */
196 0x00, 0x00, 0x00, /* Fragment offset */
197 0x00, 0x00, 0x38, /* Fragment length */
198 0xFE, 0xFD, /* DTLSv1.2 */
199 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
200 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
201 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
202 0x00, /* Session id len */
203 0x14, /* Cookie len */
204 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
205 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
209 /* A ClientHello with a bad cookie */
210 const unsigned char clienthello_badcookie[] = {
211 0x16, /* Handshake */
212 0xFE, 0xFF, /* DTLSv1.0 */
213 0x00, 0x00, /* Epoch */
214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
215 0x00, 0x4E, /* Record Length */
216 0x01, /* ClientHello */
217 0x00, 0x00, 0x42, /* Message length */
218 0x00, 0x00, /* Message sequence */
219 0x00, 0x00, 0x00, /* Fragment offset */
220 0x00, 0x00, 0x42, /* Fragment length */
221 0xFE, 0xFD, /* DTLSv1.2 */
222 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
223 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
224 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
225 0x00, /* Session id len */
226 0x14, /* Cookie len */
227 0x01, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
228 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
229 0x00, 0x04, /* Ciphersuites len */
230 0x00, 0x2f, /* AES128-SHA */
231 0x00, 0xff, /* Empty reneg info SCSV */
232 0x01, /* Compression methods len */
233 0x00, /* Null compression */
234 0x00, 0x00 /* Extensions len */
237 /* A fragmented ClientHello with the fragment boundary mid cookie */
238 const unsigned char clienthello_cookie_short[] = {
239 0x16, /* Handshake */
240 0xFE, 0xFF, /* DTLSv1.0 */
241 0x00, 0x00, /* Epoch */
242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
243 0x00, 0x43, /* Record Length */
244 0x01, /* ClientHello */
245 0x00, 0x00, 0x42, /* Message length */
246 0x00, 0x00, /* Message sequence */
247 0x00, 0x00, 0x00, /* Fragment offset */
248 0x00, 0x00, 0x37, /* Fragment length */
249 0xFE, 0xFD, /* DTLSv1.2 */
250 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
251 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
252 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
253 0x00, /* Session id len */
254 0x14, /* Cookie len */
255 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
256 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12 /* Cookie */
259 /* Bad record - too short */
260 const unsigned char record_short[] = {
261 0x16, /* Handshake */
262 0xFE, 0xFF, /* DTLSv1.0 */
263 0x00, 0x00, /* Epoch */
264 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* Record sequence number */
267 const unsigned char verify[] = {
268 0x16, /* Handshake */
269 0xFE, 0xFF, /* DTLSv1.0 */
270 0x00, 0x00, /* Epoch */
271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
272 0x00, 0x23, /* Record Length */
273 0x03, /* HelloVerifyRequest */
274 0x00, 0x00, 0x17, /* Message length */
275 0x00, 0x00, /* Message sequence */
276 0x00, 0x00, 0x00, /* Fragment offset */
277 0x00, 0x00, 0x17, /* Fragment length */
278 0xFE, 0xFF, /* DTLSv1.0 */
279 0x14, /* Cookie len */
280 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
281 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
285 const unsigned char *in;
288 * GOOD == positive return value from DTLSv1_listen, no output yet
289 * VERIFY == 0 return value, HelloVerifyRequest sent
290 * DROP == 0 return value, no output
292 enum {GOOD, VERIFY, DROP} outtype;
295 clienthello_nocookie,
296 sizeof(clienthello_nocookie),
300 clienthello_nocookie_frag,
301 sizeof(clienthello_nocookie_frag),
305 clienthello_nocookie_short,
306 sizeof(clienthello_nocookie_short),
311 sizeof(clienthello_2ndfrag),
316 sizeof(clienthello_cookie),
320 clienthello_cookie_frag,
321 sizeof(clienthello_cookie_frag),
325 clienthello_badcookie,
326 sizeof(clienthello_badcookie),
330 clienthello_cookie_short,
331 sizeof(clienthello_cookie_short),
336 sizeof(record_short),
341 #define COOKIE_LEN 20
343 static int cookie_gen(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
347 for (i = 0; i < COOKIE_LEN; i++, cookie++) {
350 *cookie_len = COOKIE_LEN;
355 static int cookie_verify(SSL *ssl, const unsigned char *cookie,
356 unsigned int cookie_len)
360 if (cookie_len != COOKIE_LEN)
363 for (i = 0; i < COOKIE_LEN; i++, cookie++) {
377 BIO_ADDR *peer = BIO_ADDR_new();
380 int ret, success = 0;
383 /* Initialise libssl */
384 SSL_load_error_strings();
387 ctx = SSL_CTX_new(DTLS_server_method());
388 if (ctx == NULL || peer == NULL)
391 SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen);
392 SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify);
394 /* Create an SSL object for the connection */
399 outbio = BIO_new(BIO_s_mem());
402 SSL_set_wbio(ssl, outbio);
405 for (i = 0; i < OSSL_NELEM(testpackets) && success; i++) {
406 inbio = BIO_new_mem_buf((char *)testpackets[i].in,
407 testpackets[i].inlen);
412 /* Set Non-blocking IO behaviour */
413 BIO_set_mem_eof_return(inbio, -1);
415 SSL_set_rbio(ssl, inbio);
417 /* Process the incoming packet */
418 ret = DTLSv1_listen(ssl, peer);
424 datalen = BIO_get_mem_data(outbio, &data);
426 if (testpackets[i].outtype == VERIFY) {
428 if (datalen != sizeof(verify)
429 || (memcmp(data, verify, sizeof(verify)) != 0)) {
430 printf("Test %ld failure: incorrect HelloVerifyRequest\n", i);
433 printf("Test %ld success\n", i);
436 printf ("Test %ld failure: should not have succeeded\n", i);
439 } else if (datalen == 0) {
440 if ((ret == 0 && testpackets[i].outtype == DROP)
441 || (ret == 1 && testpackets[i].outtype == GOOD)) {
442 printf("Test %ld success\n", i);
444 printf("Test %ld failure: wrong return value\n", i);
448 printf("Test %ld failure: Unexpected data output\n", i);
451 (void)BIO_reset(outbio);
454 SSL_set_rbio(ssl, NULL);
459 ERR_print_errors_fp(stderr);
460 /* Also frees up outbio */
464 /* Unitialise libssl */
465 #ifndef OPENSSL_NO_ENGINE
468 CONF_modules_unload(1);
469 CRYPTO_cleanup_all_ex_data();
471 ERR_remove_thread_state(NULL);
473 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
474 CRYPTO_mem_leaks_fp(stderr);
476 return success ? 0 : 1;