1 /*
2 * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (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
8 */
9
10 #include <string.h>
11 #include <openssl/ssl.h>
12 #include <openssl/bio.h>
13 #include <openssl/err.h>
14 #include <openssl/conf.h>
15 #include "internal/nelem.h"
16 #include "testutil.h"
17
18 #ifndef OPENSSL_NO_SOCK
19
20 /* Just a ClientHello without a cookie */
21 static const unsigned char clienthello_nocookie[] = {
22 0x16, /* Handshake */
23 0xFE, 0xFF, /* DTLSv1.0 */
24 0x00, 0x00, /* Epoch */
25 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
26 0x00, 0x3A, /* Record Length */
27 0x01, /* ClientHello */
28 0x00, 0x00, 0x2E, /* Message length */
29 0x00, 0x00, /* Message sequence */
30 0x00, 0x00, 0x00, /* Fragment offset */
31 0x00, 0x00, 0x2E, /* Fragment length */
32 0xFE, 0xFD, /* DTLSv1.2 */
33 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
34 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
35 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
36 0x00, /* Session id len */
37 0x00, /* Cookie len */
38 0x00, 0x04, /* Ciphersuites len */
39 0x00, 0x2f, /* AES128-SHA */
40 0x00, 0xff, /* Empty reneg info SCSV */
41 0x01, /* Compression methods len */
42 0x00, /* Null compression */
43 0x00, 0x00 /* Extensions len */
44 };
45
46 /* First fragment of a ClientHello without a cookie */
47 static const unsigned char clienthello_nocookie_frag[] = {
48 0x16, /* Handshake */
49 0xFE, 0xFF, /* DTLSv1.0 */
50 0x00, 0x00, /* Epoch */
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
52 0x00, 0x30, /* Record Length */
53 0x01, /* ClientHello */
54 0x00, 0x00, 0x2E, /* Message length */
55 0x00, 0x00, /* Message sequence */
56 0x00, 0x00, 0x00, /* Fragment offset */
57 0x00, 0x00, 0x24, /* Fragment length */
58 0xFE, 0xFD, /* DTLSv1.2 */
59 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
60 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
61 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
62 0x00, /* Session id len */
63 0x00 /* Cookie len */
64 };
65
66 /* First fragment of a ClientHello which is too short */
67 static const unsigned char clienthello_nocookie_short[] = {
68 0x16, /* Handshake */
69 0xFE, 0xFF, /* DTLSv1.0 */
70 0x00, 0x00, /* Epoch */
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
72 0x00, 0x2F, /* 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, 0x23, /* 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 };
84
85 /* Second fragment of a ClientHello */
86 static const unsigned char clienthello_2ndfrag[] = {
87 0x16, /* Handshake */
88 0xFE, 0xFF, /* DTLSv1.0 */
89 0x00, 0x00, /* Epoch */
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
91 0x00, 0x38, /* Record Length */
92 0x01, /* ClientHello */
93 0x00, 0x00, 0x2E, /* Message length */
94 0x00, 0x00, /* Message sequence */
95 0x00, 0x00, 0x02, /* Fragment offset */
96 0x00, 0x00, 0x2C, /* Fragment length */
97 /* Version skipped - sent in first fragment */
98 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
99 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
100 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
101 0x00, /* Session id len */
102 0x00, /* Cookie len */
103 0x00, 0x04, /* Ciphersuites len */
104 0x00, 0x2f, /* AES128-SHA */
105 0x00, 0xff, /* Empty reneg info SCSV */
106 0x01, /* Compression methods len */
107 0x00, /* Null compression */
108 0x00, 0x00 /* Extensions len */
109 };
110
111 /* A ClientHello with a good cookie */
112 static const unsigned char clienthello_cookie[] = {
113 0x16, /* Handshake */
114 0xFE, 0xFF, /* DTLSv1.0 */
115 0x00, 0x00, /* Epoch */
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
117 0x00, 0x4E, /* Record Length */
118 0x01, /* ClientHello */
119 0x00, 0x00, 0x42, /* Message length */
120 0x00, 0x00, /* Message sequence */
121 0x00, 0x00, 0x00, /* Fragment offset */
122 0x00, 0x00, 0x42, /* Fragment length */
123 0xFE, 0xFD, /* DTLSv1.2 */
124 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
125 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
126 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
127 0x00, /* Session id len */
128 0x14, /* Cookie len */
129 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
130 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
131 0x00, 0x04, /* Ciphersuites len */
132 0x00, 0x2f, /* AES128-SHA */
133 0x00, 0xff, /* Empty reneg info SCSV */
134 0x01, /* Compression methods len */
135 0x00, /* Null compression */
136 0x00, 0x00 /* Extensions len */
137 };
138
139 /* A fragmented ClientHello with a good cookie */
140 static const unsigned char clienthello_cookie_frag[] = {
141 0x16, /* Handshake */
142 0xFE, 0xFF, /* DTLSv1.0 */
143 0x00, 0x00, /* Epoch */
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
145 0x00, 0x44, /* Record Length */
146 0x01, /* ClientHello */
147 0x00, 0x00, 0x42, /* Message length */
148 0x00, 0x00, /* Message sequence */
149 0x00, 0x00, 0x00, /* Fragment offset */
150 0x00, 0x00, 0x38, /* Fragment length */
151 0xFE, 0xFD, /* DTLSv1.2 */
152 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
153 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
154 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
155 0x00, /* Session id len */
156 0x14, /* Cookie len */
157 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
158 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
159 };
160
161
162 /* A ClientHello with a bad cookie */
163 static const unsigned char clienthello_badcookie[] = {
164 0x16, /* Handshake */
165 0xFE, 0xFF, /* DTLSv1.0 */
166 0x00, 0x00, /* Epoch */
167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
168 0x00, 0x4E, /* Record Length */
169 0x01, /* ClientHello */
170 0x00, 0x00, 0x42, /* Message length */
171 0x00, 0x00, /* Message sequence */
172 0x00, 0x00, 0x00, /* Fragment offset */
173 0x00, 0x00, 0x42, /* Fragment length */
174 0xFE, 0xFD, /* DTLSv1.2 */
175 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
176 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
177 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
178 0x00, /* Session id len */
179 0x14, /* Cookie len */
180 0x01, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
181 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
182 0x00, 0x04, /* Ciphersuites len */
183 0x00, 0x2f, /* AES128-SHA */
184 0x00, 0xff, /* Empty reneg info SCSV */
185 0x01, /* Compression methods len */
186 0x00, /* Null compression */
187 0x00, 0x00 /* Extensions len */
188 };
189
190 /* A fragmented ClientHello with the fragment boundary mid cookie */
191 static const unsigned char clienthello_cookie_short[] = {
192 0x16, /* Handshake */
193 0xFE, 0xFF, /* DTLSv1.0 */
194 0x00, 0x00, /* Epoch */
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
196 0x00, 0x43, /* Record Length */
197 0x01, /* ClientHello */
198 0x00, 0x00, 0x42, /* Message length */
199 0x00, 0x00, /* Message sequence */
200 0x00, 0x00, 0x00, /* Fragment offset */
201 0x00, 0x00, 0x37, /* Fragment length */
202 0xFE, 0xFD, /* DTLSv1.2 */
203 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
204 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
205 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
206 0x00, /* Session id len */
207 0x14, /* Cookie len */
208 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
209 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12 /* Cookie */
210 };
211
212 /* Bad record - too short */
213 static const unsigned char record_short[] = {
214 0x16, /* Handshake */
215 0xFE, 0xFF, /* DTLSv1.0 */
216 0x00, 0x00, /* Epoch */
217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* Record sequence number */
218 };
219
220 static const unsigned char verify[] = {
221 0x16, /* Handshake */
222 0xFE, 0xFF, /* DTLSv1.0 */
223 0x00, 0x00, /* Epoch */
224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
225 0x00, 0x23, /* Record Length */
226 0x03, /* HelloVerifyRequest */
227 0x00, 0x00, 0x17, /* Message length */
228 0x00, 0x00, /* Message sequence */
229 0x00, 0x00, 0x00, /* Fragment offset */
230 0x00, 0x00, 0x17, /* Fragment length */
231 0xFE, 0xFF, /* DTLSv1.0 */
232 0x14, /* Cookie len */
233 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
234 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
235 };
236
237 typedef struct {
238 const unsigned char *in;
239 unsigned int inlen;
240 /*
241 * GOOD == positive return value from DTLSv1_listen, no output yet
242 * VERIFY == 0 return value, HelloVerifyRequest sent
243 * DROP == 0 return value, no output
244 */
245 enum {GOOD, VERIFY, DROP} outtype;
246 } tests;
247
248 static tests testpackets[9] = {
249 { clienthello_nocookie, sizeof(clienthello_nocookie), VERIFY },
250 { clienthello_nocookie_frag, sizeof(clienthello_nocookie_frag), VERIFY },
251 { clienthello_nocookie_short, sizeof(clienthello_nocookie_short), DROP },
252 { clienthello_2ndfrag, sizeof(clienthello_2ndfrag), DROP },
253 { clienthello_cookie, sizeof(clienthello_cookie), GOOD },
254 { clienthello_cookie_frag, sizeof(clienthello_cookie_frag), GOOD },
255 { clienthello_badcookie, sizeof(clienthello_badcookie), VERIFY },
256 { clienthello_cookie_short, sizeof(clienthello_cookie_short), DROP },
257 { record_short, sizeof(record_short), DROP }
258 };
259
260 # define COOKIE_LEN 20
261
cookie_gen(SSL * ssl,unsigned char * cookie,unsigned int * cookie_len)262 static int cookie_gen(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
263 {
264 unsigned int i;
265
266 for (i = 0; i < COOKIE_LEN; i++, cookie++)
267 *cookie = i;
268 *cookie_len = COOKIE_LEN;
269
270 return 1;
271 }
272
cookie_verify(SSL * ssl,const unsigned char * cookie,unsigned int cookie_len)273 static int cookie_verify(SSL *ssl, const unsigned char *cookie,
274 unsigned int cookie_len)
275 {
276 unsigned int i;
277
278 if (cookie_len != COOKIE_LEN)
279 return 0;
280
281 for (i = 0; i < COOKIE_LEN; i++, cookie++) {
282 if (*cookie != i)
283 return 0;
284 }
285
286 return 1;
287 }
288
dtls_listen_test(int i)289 static int dtls_listen_test(int i)
290 {
291 SSL_CTX *ctx = NULL;
292 SSL *ssl = NULL;
293 BIO *outbio = NULL;
294 BIO *inbio = NULL;
295 BIO_ADDR *peer = NULL;
296 tests *tp = &testpackets[i];
297 char *data;
298 long datalen;
299 int ret, success = 0;
300
301 if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))
302 || !TEST_ptr(peer = BIO_ADDR_new()))
303 goto err;
304 SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen);
305 SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify);
306
307 /* Create an SSL object and set the BIO */
308 if (!TEST_ptr(ssl = SSL_new(ctx))
309 || !TEST_ptr(outbio = BIO_new(BIO_s_mem())))
310 goto err;
311 SSL_set0_wbio(ssl, outbio);
312
313 /* Set Non-blocking IO behaviour */
314 if (!TEST_ptr(inbio = BIO_new_mem_buf((char *)tp->in, tp->inlen)))
315 goto err;
316 BIO_set_mem_eof_return(inbio, -1);
317 SSL_set0_rbio(ssl, inbio);
318
319 /* Process the incoming packet */
320 if (!TEST_int_ge(ret = DTLSv1_listen(ssl, peer), 0))
321 goto err;
322 datalen = BIO_get_mem_data(outbio, &data);
323
324 if (tp->outtype == VERIFY) {
325 if (!TEST_int_eq(ret, 0)
326 || !TEST_mem_eq(data, datalen, verify, sizeof(verify)))
327 goto err;
328 } else if (datalen == 0) {
329 if (!TEST_true((ret == 0 && tp->outtype == DROP)
330 || (ret == 1 && tp->outtype == GOOD)))
331 goto err;
332 } else {
333 TEST_info("Test %d: unexpected data output", i);
334 goto err;
335 }
336 (void)BIO_reset(outbio);
337 inbio = NULL;
338 SSL_set0_rbio(ssl, NULL);
339 success = 1;
340
341 err:
342 /* Also frees up outbio */
343 SSL_free(ssl);
344 SSL_CTX_free(ctx);
345 BIO_free(inbio);
346 OPENSSL_free(peer);
347 return success;
348 }
349 #endif
350
setup_tests(void)351 int setup_tests(void)
352 {
353 #ifndef OPENSSL_NO_SOCK
354 ADD_ALL_TESTS(dtls_listen_test, (int)OSSL_NELEM(testpackets));
355 #endif
356 return 1;
357 }
358