Fix invalid function type casts.
[openssl.git] / test / tls13ccstest.c
1 /*
2  * Copyright 2017 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 <openssl/ssl.h>
11 #include <string.h>
12 #include "ssltestlib.h"
13 #include "testutil.h"
14 #include "../ssl/packet_locl.h"
15
16 static char *cert = NULL;
17 static char *privkey = NULL;
18
19 static BIO *s_to_c_fbio = NULL, *c_to_s_fbio = NULL;
20 static int chseen = 0, shseen = 0, sccsseen = 0, ccsaftersh = 0;
21 static int ccsbeforesh = 0, sappdataseen = 0, cappdataseen = 0, badccs = 0;
22 static int badvers = 0, badsessid = 0;
23
24 static unsigned char chsessid[SSL_MAX_SSL_SESSION_ID_LENGTH];
25 static size_t chsessidlen = 0;
26
27 static int watchccs_new(BIO *bi);
28 static int watchccs_free(BIO *a);
29 static int watchccs_read(BIO *b, char *out, int outl);
30 static int watchccs_write(BIO *b, const char *in, int inl);
31 static long watchccs_ctrl(BIO *b, int cmd, long num, void *ptr);
32 static int watchccs_gets(BIO *bp, char *buf, int size);
33 static int watchccs_puts(BIO *bp, const char *str);
34
35 /* Choose a sufficiently large type likely to be unused for this custom BIO */
36 # define BIO_TYPE_WATCHCCS_FILTER  (0x80 | BIO_TYPE_FILTER)
37
38 static BIO_METHOD *method_watchccs = NULL;
39
40 static const BIO_METHOD *bio_f_watchccs_filter()
41 {
42     if (method_watchccs == NULL) {
43         method_watchccs = BIO_meth_new(BIO_TYPE_WATCHCCS_FILTER,
44                                        "Watch CCS filter");
45         if (   method_watchccs == NULL
46             || !BIO_meth_set_write(method_watchccs, watchccs_write)
47             || !BIO_meth_set_read(method_watchccs, watchccs_read)
48             || !BIO_meth_set_puts(method_watchccs, watchccs_puts)
49             || !BIO_meth_set_gets(method_watchccs, watchccs_gets)
50             || !BIO_meth_set_ctrl(method_watchccs, watchccs_ctrl)
51             || !BIO_meth_set_create(method_watchccs, watchccs_new)
52             || !BIO_meth_set_destroy(method_watchccs, watchccs_free))
53             return NULL;
54     }
55     return method_watchccs;
56 }
57
58 static int watchccs_new(BIO *bio)
59 {
60     BIO_set_init(bio, 1);
61     return 1;
62 }
63
64 static int watchccs_free(BIO *bio)
65 {
66     BIO_set_init(bio, 0);
67     return 1;
68 }
69
70 static int watchccs_read(BIO *bio, char *out, int outl)
71 {
72     int ret = 0;
73     BIO *next = BIO_next(bio);
74
75     if (outl <= 0)
76         return 0;
77     if (next == NULL)
78         return 0;
79
80     BIO_clear_retry_flags(bio);
81
82     ret = BIO_read(next, out, outl);
83     if (ret <= 0 && BIO_should_read(next))
84         BIO_set_retry_read(bio);
85
86     return ret;
87 }
88
89 static int watchccs_write(BIO *bio, const char *in, int inl)
90 {
91     int ret = 0;
92     BIO *next = BIO_next(bio);
93     PACKET pkt, msg, msgbody, sessionid;
94     unsigned int rectype, recvers, msgtype, expectedrecvers;
95
96     if (inl <= 0)
97         return 0;
98     if (next == NULL)
99         return 0;
100
101     BIO_clear_retry_flags(bio);
102
103     if (!PACKET_buf_init(&pkt, (const unsigned char *)in, inl))
104         return 0;
105
106     /* We assume that we always write complete records each time */
107     while (PACKET_remaining(&pkt)) {
108         if (!PACKET_get_1(&pkt, &rectype)
109                 || !PACKET_get_net_2(&pkt, &recvers)
110                 || !PACKET_get_length_prefixed_2(&pkt, &msg))
111             return 0;
112
113         expectedrecvers = TLS1_2_VERSION;
114
115         if (rectype == SSL3_RT_HANDSHAKE) {
116             if (!PACKET_get_1(&msg, &msgtype)
117                     || !PACKET_get_length_prefixed_3(&msg, &msgbody))
118                 return 0;
119             if (msgtype == SSL3_MT_CLIENT_HELLO) {
120                 chseen++;
121                 expectedrecvers = TLS1_VERSION;
122                 /*
123                  * Skip legacy_version (2 bytes) and Random (32 bytes) to read
124                  * session_id.
125                  */
126                 if (!PACKET_forward(&msgbody, 34)
127                         || !PACKET_get_length_prefixed_1(&msgbody, &sessionid))
128                     return 0;
129
130                 if (chseen == 1) {
131                     /* Save the session id for later */
132                     chsessidlen = PACKET_remaining(&sessionid);
133                     if (!PACKET_copy_bytes(&sessionid, chsessid, chsessidlen))
134                         return 0;
135                 } else {
136                     /*
137                      * Check the session id for the second ClientHello is the
138                      * same as the first one.
139                      */
140                     if (PACKET_remaining(&sessionid) != chsessidlen
141                             || (chsessidlen > 0
142                                 && memcmp(chsessid, PACKET_data(&sessionid),
143                                           chsessidlen) != 0))
144                         badsessid = 1;
145                 }
146             } else if (msgtype == SSL3_MT_SERVER_HELLO) {
147                 shseen++;
148                 /*
149                  * Skip legacy_version (2 bytes) and Random (32 bytes) to read
150                  * session_id.
151                  */
152                 if (!PACKET_forward(&msgbody, 34)
153                         || !PACKET_get_length_prefixed_1(&msgbody, &sessionid))
154                     return 0;
155
156                 /*
157                  * Check the session id is the same as the one in the
158                  * ClientHello
159                  */
160                 if (PACKET_remaining(&sessionid) != chsessidlen
161                         || (chsessidlen > 0
162                             && memcmp(chsessid, PACKET_data(&sessionid),
163                                       chsessidlen) != 0))
164                     badsessid = 1;
165             }
166         } else if (rectype == SSL3_RT_CHANGE_CIPHER_SPEC) {
167             if (bio == s_to_c_fbio) {
168                 /*
169                  * Server writing. We shouldn't have written any app data
170                  * yet, and we should have seen both the ClientHello and the
171                  * ServerHello
172                  */
173                 if (!sappdataseen
174                         && chseen == 1
175                         && shseen == 1
176                         && !sccsseen)
177                     sccsseen = 1;
178                 else
179                     badccs = 1;
180             } else if (!cappdataseen) {
181                 /*
182                  * Client writing. We shouldn't have written any app data
183                  * yet, and we should have seen the ClientHello
184                  */
185                 if (shseen == 1 && !ccsaftersh)
186                     ccsaftersh = 1;
187                 else if (shseen == 0 && !ccsbeforesh)
188                     ccsbeforesh = 1;
189                 else
190                     badccs = 1;
191             } else {
192                 badccs = 1;
193             }
194         } else if(rectype == SSL3_RT_APPLICATION_DATA) {
195             if (bio == s_to_c_fbio)
196                 sappdataseen = 1;
197             else
198                 cappdataseen = 1;
199         }
200         if (recvers != expectedrecvers)
201             badvers = 1;
202     }
203
204     ret = BIO_write(next, in, inl);
205     if (ret <= 0 && BIO_should_write(next))
206         BIO_set_retry_write(bio);
207
208     return ret;
209 }
210
211 static long watchccs_ctrl(BIO *bio, int cmd, long num, void *ptr)
212 {
213     long ret;
214     BIO *next = BIO_next(bio);
215
216     if (next == NULL)
217         return 0;
218
219     switch (cmd) {
220     case BIO_CTRL_DUP:
221         ret = 0;
222         break;
223     default:
224         ret = BIO_ctrl(next, cmd, num, ptr);
225         break;
226     }
227     return ret;
228 }
229
230 static int watchccs_gets(BIO *bio, char *buf, int size)
231 {
232     /* We don't support this - not needed anyway */
233     return -1;
234 }
235
236 static int watchccs_puts(BIO *bio, const char *str)
237 {
238     return watchccs_write(bio, str, strlen(str));
239 }
240
241 static int test_tls13ccs(int tst)
242 {
243     SSL_CTX *sctx = NULL, *cctx = NULL;
244     SSL *sssl = NULL, *cssl = NULL;
245     int ret = 0;
246     const char msg[] = "Dummy data";
247     char buf[80];
248     size_t written, readbytes;
249     SSL_SESSION *sess = NULL;
250
251     chseen = shseen = sccsseen = ccsaftersh = ccsbeforesh = 0;
252     sappdataseen = cappdataseen = badccs = badvers = badsessid = 0;
253     chsessidlen = 0;
254
255     if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
256                                        &sctx, &cctx, cert, privkey)))
257         goto err;
258
259     /*
260      * Test 0: Simple Handshake
261      * Test 1: Simple Handshake, client middlebox compat mode disabled
262      * Test 2: Simple Handshake, server middlebox compat mode disabled
263      * Test 3: HRR Handshake
264      * Test 4: HRR Handshake, client middlebox compat mode disabled
265      * Test 5: HRR Handshake, server middlebox compat mode disabled
266      * Test 6: Early data handshake
267      * Test 7: Early data handshake, client middlebox compat mode disabled
268      * Test 8: Early data handshake, server middlebox compat mode disabled
269      * Test 9: Early data then HRR
270      * Test 10: Early data then HRR, client middlebox compat mode disabled
271      * Test 11: Early data then HRR, server middlebox compat mode disabled
272      */
273     switch (tst) {
274     case 0:
275     case 3:
276     case 6:
277     case 9:
278         break;
279     case 1:
280     case 4:
281     case 7:
282     case 10:
283         SSL_CTX_clear_options(cctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
284         break;
285     case 2:
286     case 5:
287     case 8:
288     case 11:
289         SSL_CTX_clear_options(sctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
290         break;
291     default:
292         TEST_error("Invalid test value");
293         goto err;
294     }
295
296     if (tst >= 6) {
297         /* Get a session suitable for early_data */
298         if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
299                 || !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE)))
300             goto err;
301         sess = SSL_get1_session(cssl);
302         if (!TEST_ptr(sess))
303             goto err;
304         SSL_shutdown(cssl);
305         SSL_shutdown(sssl);
306         SSL_free(sssl);
307         SSL_free(cssl);
308         sssl = cssl = NULL;
309     }
310
311     if ((tst >= 3 && tst <= 5) || tst >= 9) {
312         /* HRR handshake */
313         if (!TEST_true(SSL_CTX_set1_groups_list(sctx, "P-256")))
314             goto err;
315     }
316
317     s_to_c_fbio = BIO_new(bio_f_watchccs_filter());
318     c_to_s_fbio = BIO_new(bio_f_watchccs_filter());
319     if (!TEST_ptr(s_to_c_fbio)
320             || !TEST_ptr(c_to_s_fbio)) {
321         BIO_free(s_to_c_fbio);
322         BIO_free(c_to_s_fbio);
323         goto err;
324     }
325
326     /* BIOs get freed on error */
327     if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, s_to_c_fbio,
328                                       c_to_s_fbio)))
329         goto err;
330
331     if (tst >= 6) {
332         /* Early data */
333         if (!TEST_true(SSL_set_session(cssl, sess))
334                 || !TEST_true(SSL_write_early_data(cssl, msg, strlen(msg),
335                                                    &written))
336                 || (tst <= 8
337                     && !TEST_int_eq(SSL_read_early_data(sssl, buf,  sizeof(buf),
338                                                 &readbytes),
339                                                 SSL_READ_EARLY_DATA_SUCCESS)))
340             goto err;
341         if (tst <= 8) {
342             if (!TEST_int_gt(SSL_connect(cssl), 0))
343                 goto err;
344         } else {
345             if (!TEST_int_le(SSL_connect(cssl), 0))
346                 goto err;
347         }
348         if (!TEST_int_eq(SSL_read_early_data(sssl, buf,  sizeof(buf),
349                                              &readbytes),
350                          SSL_READ_EARLY_DATA_FINISH))
351             goto err;
352     }
353
354     /* Perform handshake (or complete it if doing early data ) */
355     if (!TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE)))
356         goto err;
357
358     /*
359      * Check there were no unexpected CCS messages, all record versions
360      * were as expected, and that the session ids were reflected by the server
361      * correctly.
362      */
363     if (!TEST_false(badccs) || !TEST_false(badvers) || !TEST_false(badsessid))
364         goto err;
365
366     switch (tst) {
367     case 0:
368         if (!TEST_true(sccsseen)
369                 || !TEST_true(ccsaftersh)
370                 || !TEST_false(ccsbeforesh)
371                 || !TEST_size_t_gt(chsessidlen, 0))
372             goto err;
373         break;
374
375     case 1:
376         if (!TEST_true(sccsseen)
377                 || !TEST_false(ccsaftersh)
378                 || !TEST_false(ccsbeforesh)
379                 || !TEST_size_t_eq(chsessidlen, 0))
380             goto err;
381         break;
382
383     case 2:
384         if (!TEST_false(sccsseen)
385                 || !TEST_true(ccsaftersh)
386                 || !TEST_false(ccsbeforesh)
387                 || !TEST_size_t_gt(chsessidlen, 0))
388             goto err;
389         break;
390
391     case 3:
392         if (!TEST_true(sccsseen)
393                 || !TEST_true(ccsaftersh)
394                 || !TEST_false(ccsbeforesh)
395                 || !TEST_size_t_gt(chsessidlen, 0))
396             goto err;
397         break;
398
399     case 4:
400         if (!TEST_true(sccsseen)
401                 || !TEST_false(ccsaftersh)
402                 || !TEST_false(ccsbeforesh)
403                 || !TEST_size_t_eq(chsessidlen, 0))
404             goto err;
405         break;
406
407     case 5:
408         if (!TEST_false(sccsseen)
409                 || !TEST_true(ccsaftersh)
410                 || !TEST_false(ccsbeforesh)
411                 || !TEST_size_t_gt(chsessidlen, 0))
412             goto err;
413         break;
414
415     case 6:
416         if (!TEST_true(sccsseen)
417                 || !TEST_false(ccsaftersh)
418                 || !TEST_true(ccsbeforesh)
419                 || !TEST_size_t_gt(chsessidlen, 0))
420             goto err;
421         break;
422
423     case 7:
424         if (!TEST_true(sccsseen)
425                 || !TEST_false(ccsaftersh)
426                 || !TEST_false(ccsbeforesh)
427                 || !TEST_size_t_eq(chsessidlen, 0))
428             goto err;
429         break;
430
431     case 8:
432         if (!TEST_false(sccsseen)
433                 || !TEST_false(ccsaftersh)
434                 || !TEST_true(ccsbeforesh)
435                 || !TEST_size_t_gt(chsessidlen, 0))
436             goto err;
437         break;
438
439     case 9:
440         if (!TEST_true(sccsseen)
441                 || !TEST_false(ccsaftersh)
442                 || !TEST_true(ccsbeforesh)
443                 || !TEST_size_t_gt(chsessidlen, 0))
444             goto err;
445         break;
446
447     case 10:
448         if (!TEST_true(sccsseen)
449                 || !TEST_false(ccsaftersh)
450                 || !TEST_false(ccsbeforesh)
451                 || !TEST_size_t_eq(chsessidlen, 0))
452             goto err;
453         break;
454
455     case 11:
456         if (!TEST_false(sccsseen)
457                 || !TEST_false(ccsaftersh)
458                 || !TEST_true(ccsbeforesh)
459                 || !TEST_size_t_gt(chsessidlen, 0))
460             goto err;
461         break;
462
463     default:
464         TEST_error("Invalid test value");
465         goto err;
466     }
467
468     ret = 1;
469  err:
470     SSL_SESSION_free(sess);
471     SSL_free(sssl);
472     SSL_free(cssl);
473     SSL_CTX_free(sctx);
474     SSL_CTX_free(cctx);
475
476     return ret;
477 }
478
479 int setup_tests(void)
480 {
481     if (!TEST_ptr(cert = test_get_argument(0))
482             || !TEST_ptr(privkey = test_get_argument(1)))
483         return 0;
484
485     ADD_ALL_TESTS(test_tls13ccs, 12);
486
487     return 1;
488 }
489
490 void cleanup_tests(void)
491 {
492     BIO_meth_free(method_watchccs);
493 }