]> git.ipfire.org Git - thirdparty/openssl.git/blob - test/dtlsv1listentest.c
Simplify and rename SSL_set_rbio() and SSL_set_wbio()
[thirdparty/openssl.git] / test / dtlsv1listentest.c
1 /*
2 * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (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 #ifndef OPENSSL_NO_ENGINE
16 #include <openssl/engine.h>
17 #endif
18 #include "e_os.h"
19
20 #ifndef OPENSSL_NO_SOCK
21
22 /* Just a ClientHello without a cookie */
23 static const unsigned char clienthello_nocookie[] = {
24 0x16, /* Handshake */
25 0xFE, 0xFF, /* DTLSv1.0 */
26 0x00, 0x00, /* Epoch */
27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
28 0x00, 0x3A, /* Record Length */
29 0x01, /* ClientHello */
30 0x00, 0x00, 0x2E, /* Message length */
31 0x00, 0x00, /* Message sequence */
32 0x00, 0x00, 0x00, /* Fragment offset */
33 0x00, 0x00, 0x2E, /* Fragment length */
34 0xFE, 0xFD, /* DTLSv1.2 */
35 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
36 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
37 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
38 0x00, /* Session id len */
39 0x00, /* Cookie len */
40 0x00, 0x04, /* Ciphersuites len */
41 0x00, 0x2f, /* AES128-SHA */
42 0x00, 0xff, /* Empty reneg info SCSV */
43 0x01, /* Compression methods len */
44 0x00, /* Null compression */
45 0x00, 0x00 /* Extensions len */
46 };
47
48 /* First fragment of a ClientHello without a cookie */
49 static const unsigned char clienthello_nocookie_frag[] = {
50 0x16, /* Handshake */
51 0xFE, 0xFF, /* DTLSv1.0 */
52 0x00, 0x00, /* Epoch */
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
54 0x00, 0x30, /* Record Length */
55 0x01, /* ClientHello */
56 0x00, 0x00, 0x2E, /* Message length */
57 0x00, 0x00, /* Message sequence */
58 0x00, 0x00, 0x00, /* Fragment offset */
59 0x00, 0x00, 0x24, /* Fragment length */
60 0xFE, 0xFD, /* DTLSv1.2 */
61 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
62 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
63 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
64 0x00, /* Session id len */
65 0x00 /* Cookie len */
66 };
67
68 /* First fragment of a ClientHello which is too short */
69 static const unsigned char clienthello_nocookie_short[] = {
70 0x16, /* Handshake */
71 0xFE, 0xFF, /* DTLSv1.0 */
72 0x00, 0x00, /* Epoch */
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
74 0x00, 0x2F, /* 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, 0x23, /* 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 };
86
87 /* Second fragment of a ClientHello */
88 static const unsigned char clienthello_2ndfrag[] = {
89 0x16, /* Handshake */
90 0xFE, 0xFF, /* DTLSv1.0 */
91 0x00, 0x00, /* Epoch */
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
93 0x00, 0x38, /* Record Length */
94 0x01, /* ClientHello */
95 0x00, 0x00, 0x2E, /* Message length */
96 0x00, 0x00, /* Message sequence */
97 0x00, 0x00, 0x02, /* Fragment offset */
98 0x00, 0x00, 0x2C, /* Fragment length */
99 /* Version skipped - sent in first fragment */
100 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
101 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
102 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
103 0x00, /* Session id len */
104 0x00, /* Cookie len */
105 0x00, 0x04, /* Ciphersuites len */
106 0x00, 0x2f, /* AES128-SHA */
107 0x00, 0xff, /* Empty reneg info SCSV */
108 0x01, /* Compression methods len */
109 0x00, /* Null compression */
110 0x00, 0x00 /* Extensions len */
111 };
112
113 /* A ClientHello with a good cookie */
114 static const unsigned char clienthello_cookie[] = {
115 0x16, /* Handshake */
116 0xFE, 0xFF, /* DTLSv1.0 */
117 0x00, 0x00, /* Epoch */
118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
119 0x00, 0x4E, /* Record Length */
120 0x01, /* ClientHello */
121 0x00, 0x00, 0x42, /* Message length */
122 0x00, 0x00, /* Message sequence */
123 0x00, 0x00, 0x00, /* Fragment offset */
124 0x00, 0x00, 0x42, /* 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 */
130 0x14, /* Cookie len */
131 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
132 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
133 0x00, 0x04, /* Ciphersuites len */
134 0x00, 0x2f, /* AES128-SHA */
135 0x00, 0xff, /* Empty reneg info SCSV */
136 0x01, /* Compression methods len */
137 0x00, /* Null compression */
138 0x00, 0x00 /* Extensions len */
139 };
140
141 /* A fragmented ClientHello with a good cookie */
142 static const unsigned char clienthello_cookie_frag[] = {
143 0x16, /* Handshake */
144 0xFE, 0xFF, /* DTLSv1.0 */
145 0x00, 0x00, /* Epoch */
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
147 0x00, 0x44, /* Record Length */
148 0x01, /* ClientHello */
149 0x00, 0x00, 0x42, /* Message length */
150 0x00, 0x00, /* Message sequence */
151 0x00, 0x00, 0x00, /* Fragment offset */
152 0x00, 0x00, 0x38, /* Fragment length */
153 0xFE, 0xFD, /* DTLSv1.2 */
154 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
155 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
156 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
157 0x00, /* Session id len */
158 0x14, /* Cookie len */
159 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
160 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
161 };
162
163
164 /* A ClientHello with a bad cookie */
165 static const unsigned char clienthello_badcookie[] = {
166 0x16, /* Handshake */
167 0xFE, 0xFF, /* DTLSv1.0 */
168 0x00, 0x00, /* Epoch */
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
170 0x00, 0x4E, /* Record Length */
171 0x01, /* ClientHello */
172 0x00, 0x00, 0x42, /* Message length */
173 0x00, 0x00, /* Message sequence */
174 0x00, 0x00, 0x00, /* Fragment offset */
175 0x00, 0x00, 0x42, /* Fragment length */
176 0xFE, 0xFD, /* DTLSv1.2 */
177 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
178 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
179 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
180 0x00, /* Session id len */
181 0x14, /* Cookie len */
182 0x01, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
183 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
184 0x00, 0x04, /* Ciphersuites len */
185 0x00, 0x2f, /* AES128-SHA */
186 0x00, 0xff, /* Empty reneg info SCSV */
187 0x01, /* Compression methods len */
188 0x00, /* Null compression */
189 0x00, 0x00 /* Extensions len */
190 };
191
192 /* A fragmented ClientHello with the fragment boundary mid cookie */
193 static const unsigned char clienthello_cookie_short[] = {
194 0x16, /* Handshake */
195 0xFE, 0xFF, /* DTLSv1.0 */
196 0x00, 0x00, /* Epoch */
197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
198 0x00, 0x43, /* Record Length */
199 0x01, /* ClientHello */
200 0x00, 0x00, 0x42, /* Message length */
201 0x00, 0x00, /* Message sequence */
202 0x00, 0x00, 0x00, /* Fragment offset */
203 0x00, 0x00, 0x37, /* Fragment length */
204 0xFE, 0xFD, /* DTLSv1.2 */
205 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
206 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
207 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
208 0x00, /* Session id len */
209 0x14, /* Cookie len */
210 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
211 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12 /* Cookie */
212 };
213
214 /* Bad record - too short */
215 static const unsigned char record_short[] = {
216 0x16, /* Handshake */
217 0xFE, 0xFF, /* DTLSv1.0 */
218 0x00, 0x00, /* Epoch */
219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* Record sequence number */
220 };
221
222 static const unsigned char verify[] = {
223 0x16, /* Handshake */
224 0xFE, 0xFF, /* DTLSv1.0 */
225 0x00, 0x00, /* Epoch */
226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
227 0x00, 0x23, /* Record Length */
228 0x03, /* HelloVerifyRequest */
229 0x00, 0x00, 0x17, /* Message length */
230 0x00, 0x00, /* Message sequence */
231 0x00, 0x00, 0x00, /* Fragment offset */
232 0x00, 0x00, 0x17, /* Fragment length */
233 0xFE, 0xFF, /* DTLSv1.0 */
234 0x14, /* Cookie len */
235 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
236 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
237 };
238
239 static struct {
240 const unsigned char *in;
241 unsigned int inlen;
242 /*
243 * GOOD == positive return value from DTLSv1_listen, no output yet
244 * VERIFY == 0 return value, HelloVerifyRequest sent
245 * DROP == 0 return value, no output
246 */
247 enum {GOOD, VERIFY, DROP} outtype;
248 } testpackets[9] = {
249 {
250 clienthello_nocookie,
251 sizeof(clienthello_nocookie),
252 VERIFY
253 },
254 {
255 clienthello_nocookie_frag,
256 sizeof(clienthello_nocookie_frag),
257 VERIFY
258 },
259 {
260 clienthello_nocookie_short,
261 sizeof(clienthello_nocookie_short),
262 DROP
263 },
264 {
265 clienthello_2ndfrag,
266 sizeof(clienthello_2ndfrag),
267 DROP
268 },
269 {
270 clienthello_cookie,
271 sizeof(clienthello_cookie),
272 GOOD
273 },
274 {
275 clienthello_cookie_frag,
276 sizeof(clienthello_cookie_frag),
277 GOOD
278 },
279 {
280 clienthello_badcookie,
281 sizeof(clienthello_badcookie),
282 VERIFY
283 },
284 {
285 clienthello_cookie_short,
286 sizeof(clienthello_cookie_short),
287 DROP
288 },
289 {
290 record_short,
291 sizeof(record_short),
292 DROP
293 }
294 };
295
296 # define COOKIE_LEN 20
297
298 static int cookie_gen(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
299 {
300 unsigned int i;
301
302 for (i = 0; i < COOKIE_LEN; i++, cookie++) {
303 *cookie = i;
304 }
305 *cookie_len = COOKIE_LEN;
306
307 return 1;
308 }
309
310 static int cookie_verify(SSL *ssl, const unsigned char *cookie,
311 unsigned int cookie_len)
312 {
313 unsigned int i;
314
315 if (cookie_len != COOKIE_LEN)
316 return 0;
317
318 for (i = 0; i < COOKIE_LEN; i++, cookie++) {
319 if (*cookie != i)
320 return 0;
321 }
322
323 return 1;
324 }
325 #endif
326
327 int main(void)
328 {
329 #ifndef OPENSSL_NO_SOCK
330 SSL_CTX *ctx = NULL;
331 SSL *ssl = NULL;
332 BIO *outbio = NULL;
333 BIO *inbio = NULL;
334 BIO_ADDR *peer = BIO_ADDR_new();
335 char *data;
336 long datalen;
337 int ret, success = 0;
338 long i;
339
340 ctx = SSL_CTX_new(DTLS_server_method());
341 if (ctx == NULL || peer == NULL)
342 goto err;
343
344 SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen);
345 SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify);
346
347 /* Create an SSL object for the connection */
348 ssl = SSL_new(ctx);
349 if (ssl == NULL)
350 goto err;
351
352 outbio = BIO_new(BIO_s_mem());
353 if (outbio == NULL)
354 goto err;
355 SSL_set0_wbio(ssl, outbio);
356
357 success = 1;
358 for (i = 0; i < (long)OSSL_NELEM(testpackets) && success; i++) {
359 inbio = BIO_new_mem_buf((char *)testpackets[i].in,
360 testpackets[i].inlen);
361 if (inbio == NULL) {
362 success = 0;
363 goto err;
364 }
365 /* Set Non-blocking IO behaviour */
366 BIO_set_mem_eof_return(inbio, -1);
367
368 SSL_set0_rbio(ssl, inbio);
369
370 /* Process the incoming packet */
371 ret = DTLSv1_listen(ssl, peer);
372 if (ret < 0) {
373 success = 0;
374 goto err;
375 }
376
377 datalen = BIO_get_mem_data(outbio, &data);
378
379 if (testpackets[i].outtype == VERIFY) {
380 if (ret == 0) {
381 if (datalen != sizeof(verify)
382 || (memcmp(data, verify, sizeof(verify)) != 0)) {
383 printf("Test %ld failure: incorrect HelloVerifyRequest\n", i);
384 success = 0;
385 } else {
386 printf("Test %ld success\n", i);
387 }
388 } else {
389 printf ("Test %ld failure: should not have succeeded\n", i);
390 success = 0;
391 }
392 } else if (datalen == 0) {
393 if ((ret == 0 && testpackets[i].outtype == DROP)
394 || (ret == 1 && testpackets[i].outtype == GOOD)) {
395 printf("Test %ld success\n", i);
396 } else {
397 printf("Test %ld failure: wrong return value\n", i);
398 success = 0;
399 }
400 } else {
401 printf("Test %ld failure: Unexpected data output\n", i);
402 success = 0;
403 }
404 (void)BIO_reset(outbio);
405 inbio = NULL;
406 /* Frees up inbio */
407 SSL_set0_rbio(ssl, NULL);
408 }
409
410 err:
411 if (!success)
412 ERR_print_errors_fp(stderr);
413 /* Also frees up outbio */
414 SSL_free(ssl);
415 SSL_CTX_free(ctx);
416 BIO_free(inbio);
417 OPENSSL_free(peer);
418 # ifndef OPENSSL_NO_CRYPTO_MDEBUG
419 CRYPTO_mem_leaks_fp(stderr);
420 # endif
421 return success ? 0 : 1;
422 #else
423 printf("DTLSv1_listen() is not supported by this build - skipping\n");
424 return 0;
425 #endif
426 }