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 /* Just a ClientHello without a cookie */
69 static const unsigned char clienthello_nocookie[] = {
71 0xFE, 0xFF, /* DTLSv1.0 */
72 0x00, 0x00, /* Epoch */
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
74 0x00, 0x3A, /* 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, 0x2E, /* 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 */
85 0x00, /* Cookie len */
86 0x00, 0x04, /* Ciphersuites len */
87 0x00, 0x2f, /* AES128-SHA */
88 0x00, 0xff, /* Empty reneg info SCSV */
89 0x01, /* Compression methods len */
90 0x00, /* Null compression */
91 0x00, 0x00 /* Extensions len */
94 /* First fragment of a ClientHello without a cookie */
95 static const unsigned char clienthello_nocookie_frag[] = {
97 0xFE, 0xFF, /* DTLSv1.0 */
98 0x00, 0x00, /* Epoch */
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
100 0x00, 0x30, /* Record Length */
101 0x01, /* ClientHello */
102 0x00, 0x00, 0x2E, /* Message length */
103 0x00, 0x00, /* Message sequence */
104 0x00, 0x00, 0x00, /* Fragment offset */
105 0x00, 0x00, 0x24, /* Fragment length */
106 0xFE, 0xFD, /* DTLSv1.2 */
107 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
108 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
109 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
110 0x00, /* Session id len */
111 0x00 /* Cookie len */
114 /* First fragment of a ClientHello which is too short */
115 static const unsigned char clienthello_nocookie_short[] = {
116 0x16, /* Handshake */
117 0xFE, 0xFF, /* DTLSv1.0 */
118 0x00, 0x00, /* Epoch */
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
120 0x00, 0x2F, /* Record Length */
121 0x01, /* ClientHello */
122 0x00, 0x00, 0x2E, /* Message length */
123 0x00, 0x00, /* Message sequence */
124 0x00, 0x00, 0x00, /* Fragment offset */
125 0x00, 0x00, 0x23, /* Fragment length */
126 0xFE, 0xFD, /* DTLSv1.2 */
127 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
128 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
129 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
130 0x00 /* Session id len */
133 /* Second fragment of a ClientHello */
134 static const unsigned char clienthello_2ndfrag[] = {
135 0x16, /* Handshake */
136 0xFE, 0xFF, /* DTLSv1.0 */
137 0x00, 0x00, /* Epoch */
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
139 0x00, 0x38, /* Record Length */
140 0x01, /* ClientHello */
141 0x00, 0x00, 0x2E, /* Message length */
142 0x00, 0x00, /* Message sequence */
143 0x00, 0x00, 0x02, /* Fragment offset */
144 0x00, 0x00, 0x2C, /* Fragment length */
145 /* Version skipped - sent in first fragment */
146 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
147 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
148 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
149 0x00, /* Session id len */
150 0x00, /* Cookie len */
151 0x00, 0x04, /* Ciphersuites len */
152 0x00, 0x2f, /* AES128-SHA */
153 0x00, 0xff, /* Empty reneg info SCSV */
154 0x01, /* Compression methods len */
155 0x00, /* Null compression */
156 0x00, 0x00 /* Extensions len */
159 /* A ClientHello with a good cookie */
160 static const unsigned char clienthello_cookie[] = {
161 0x16, /* Handshake */
162 0xFE, 0xFF, /* DTLSv1.0 */
163 0x00, 0x00, /* Epoch */
164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
165 0x00, 0x4E, /* Record Length */
166 0x01, /* ClientHello */
167 0x00, 0x00, 0x42, /* Message length */
168 0x00, 0x00, /* Message sequence */
169 0x00, 0x00, 0x00, /* Fragment offset */
170 0x00, 0x00, 0x42, /* Fragment length */
171 0xFE, 0xFD, /* DTLSv1.2 */
172 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
173 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
174 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
175 0x00, /* Session id len */
176 0x14, /* Cookie len */
177 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
178 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
179 0x00, 0x04, /* Ciphersuites len */
180 0x00, 0x2f, /* AES128-SHA */
181 0x00, 0xff, /* Empty reneg info SCSV */
182 0x01, /* Compression methods len */
183 0x00, /* Null compression */
184 0x00, 0x00 /* Extensions len */
187 /* A fragmented ClientHello with a good cookie */
188 static const unsigned char clienthello_cookie_frag[] = {
189 0x16, /* Handshake */
190 0xFE, 0xFF, /* DTLSv1.0 */
191 0x00, 0x00, /* Epoch */
192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
193 0x00, 0x44, /* Record Length */
194 0x01, /* ClientHello */
195 0x00, 0x00, 0x42, /* Message length */
196 0x00, 0x00, /* Message sequence */
197 0x00, 0x00, 0x00, /* Fragment offset */
198 0x00, 0x00, 0x38, /* Fragment length */
199 0xFE, 0xFD, /* DTLSv1.2 */
200 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
201 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
202 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
203 0x00, /* Session id len */
204 0x14, /* Cookie len */
205 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
206 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
210 /* A ClientHello with a bad cookie */
211 static const unsigned char clienthello_badcookie[] = {
212 0x16, /* Handshake */
213 0xFE, 0xFF, /* DTLSv1.0 */
214 0x00, 0x00, /* Epoch */
215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
216 0x00, 0x4E, /* Record Length */
217 0x01, /* ClientHello */
218 0x00, 0x00, 0x42, /* Message length */
219 0x00, 0x00, /* Message sequence */
220 0x00, 0x00, 0x00, /* Fragment offset */
221 0x00, 0x00, 0x42, /* Fragment length */
222 0xFE, 0xFD, /* DTLSv1.2 */
223 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
224 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
225 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
226 0x00, /* Session id len */
227 0x14, /* Cookie len */
228 0x01, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
229 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
230 0x00, 0x04, /* Ciphersuites len */
231 0x00, 0x2f, /* AES128-SHA */
232 0x00, 0xff, /* Empty reneg info SCSV */
233 0x01, /* Compression methods len */
234 0x00, /* Null compression */
235 0x00, 0x00 /* Extensions len */
238 /* A fragmented ClientHello with the fragment boundary mid cookie */
239 static const unsigned char clienthello_cookie_short[] = {
240 0x16, /* Handshake */
241 0xFE, 0xFF, /* DTLSv1.0 */
242 0x00, 0x00, /* Epoch */
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
244 0x00, 0x43, /* Record Length */
245 0x01, /* ClientHello */
246 0x00, 0x00, 0x42, /* Message length */
247 0x00, 0x00, /* Message sequence */
248 0x00, 0x00, 0x00, /* Fragment offset */
249 0x00, 0x00, 0x37, /* Fragment length */
250 0xFE, 0xFD, /* DTLSv1.2 */
251 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
252 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
253 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
254 0x00, /* Session id len */
255 0x14, /* Cookie len */
256 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
257 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12 /* Cookie */
260 /* Bad record - too short */
261 static const unsigned char record_short[] = {
262 0x16, /* Handshake */
263 0xFE, 0xFF, /* DTLSv1.0 */
264 0x00, 0x00, /* Epoch */
265 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* Record sequence number */
268 static const unsigned char verify[] = {
269 0x16, /* Handshake */
270 0xFE, 0xFF, /* DTLSv1.0 */
271 0x00, 0x00, /* Epoch */
272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
273 0x00, 0x23, /* Record Length */
274 0x03, /* HelloVerifyRequest */
275 0x00, 0x00, 0x17, /* Message length */
276 0x00, 0x00, /* Message sequence */
277 0x00, 0x00, 0x00, /* Fragment offset */
278 0x00, 0x00, 0x17, /* Fragment length */
279 0xFE, 0xFF, /* DTLSv1.0 */
280 0x14, /* Cookie len */
281 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
282 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
286 const unsigned char *in;
289 * GOOD == positive return value from DTLSv1_listen, no output yet
290 * VERIFY == 0 return value, HelloVerifyRequest sent
291 * DROP == 0 return value, no output
293 enum {GOOD, VERIFY, DROP} outtype;
296 clienthello_nocookie,
297 sizeof(clienthello_nocookie),
301 clienthello_nocookie_frag,
302 sizeof(clienthello_nocookie_frag),
306 clienthello_nocookie_short,
307 sizeof(clienthello_nocookie_short),
312 sizeof(clienthello_2ndfrag),
317 sizeof(clienthello_cookie),
321 clienthello_cookie_frag,
322 sizeof(clienthello_cookie_frag),
326 clienthello_badcookie,
327 sizeof(clienthello_badcookie),
331 clienthello_cookie_short,
332 sizeof(clienthello_cookie_short),
337 sizeof(record_short),
342 #define COOKIE_LEN 20
344 static int cookie_gen(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
348 for (i = 0; i < COOKIE_LEN; i++, cookie++) {
351 *cookie_len = COOKIE_LEN;
356 static int cookie_verify(SSL *ssl, const unsigned char *cookie,
357 unsigned int cookie_len)
361 if (cookie_len != COOKIE_LEN)
364 for (i = 0; i < COOKIE_LEN; i++, cookie++) {
378 BIO_ADDR *peer = BIO_ADDR_new();
381 int ret, success = 0;
384 ctx = SSL_CTX_new(DTLS_server_method());
385 if (ctx == NULL || peer == NULL)
388 SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen);
389 SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify);
391 /* Create an SSL object for the connection */
396 outbio = BIO_new(BIO_s_mem());
399 SSL_set_wbio(ssl, outbio);
402 for (i = 0; i < (long)OSSL_NELEM(testpackets) && success; i++) {
403 inbio = BIO_new_mem_buf((char *)testpackets[i].in,
404 testpackets[i].inlen);
409 /* Set Non-blocking IO behaviour */
410 BIO_set_mem_eof_return(inbio, -1);
412 SSL_set_rbio(ssl, inbio);
414 /* Process the incoming packet */
415 ret = DTLSv1_listen(ssl, peer);
421 datalen = BIO_get_mem_data(outbio, &data);
423 if (testpackets[i].outtype == VERIFY) {
425 if (datalen != sizeof(verify)
426 || (memcmp(data, verify, sizeof(verify)) != 0)) {
427 printf("Test %ld failure: incorrect HelloVerifyRequest\n", i);
430 printf("Test %ld success\n", i);
433 printf ("Test %ld failure: should not have succeeded\n", i);
436 } else if (datalen == 0) {
437 if ((ret == 0 && testpackets[i].outtype == DROP)
438 || (ret == 1 && testpackets[i].outtype == GOOD)) {
439 printf("Test %ld success\n", i);
441 printf("Test %ld failure: wrong return value\n", i);
445 printf("Test %ld failure: Unexpected data output\n", i);
448 (void)BIO_reset(outbio);
451 SSL_set_rbio(ssl, NULL);
456 ERR_print_errors_fp(stderr);
457 /* Also frees up outbio */
462 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
463 CRYPTO_mem_leaks_fp(stderr);
465 return success ? 0 : 1;