xref: /openssl/test/quic_newcid_test.c (revision 8d8c0a90)
1 /*
2  * Copyright 2023 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 "helpers/quictestlib.h"
13 #include "internal/quic_error.h"
14 #include "testutil.h"
15 
16 static char *cert = NULL;
17 static char *privkey = NULL;
18 
19 /*
20  * Inject NEW_CONNECTION_ID frame
21  */
22 static size_t ncid_injected;
add_ncid_frame_cb(QTEST_FAULT * fault,QUIC_PKT_HDR * hdr,unsigned char * buf,size_t len,void * cbarg)23 static int add_ncid_frame_cb(QTEST_FAULT *fault, QUIC_PKT_HDR *hdr,
24                              unsigned char *buf, size_t len, void *cbarg)
25 {
26     /*
27      * We inject NEW_CONNECTION_ID frame to trigger change of the DCID.
28      * The connection id length must be 8, otherwise the tserver won't be
29      * able to receive packets with this new id.
30      */
31     static unsigned char new_conn_id_frame[] = {
32         0x18,                           /* Type */
33         0x01,                           /* Sequence Number */
34         0x01,                           /* Retire Prior To */
35         0x08,                           /* Connection ID Length */
36         0x33, 0x44, 0x55, 0x66, 0xde, 0xad, 0xbe, 0xef, /* Connection ID */
37         0xab, 0xcd, 0xef, 0x01, 0x12, 0x32, 0x23, 0x45, /* Stateless Reset Token */
38         0x56, 0x06, 0x08, 0x89, 0xa1, 0xb2, 0xc3, 0xd4
39     };
40 
41     /* We only ever add the unknown frame to one packet */
42     if (ncid_injected++)
43         return 1;
44 
45     return qtest_fault_prepend_frame(fault, new_conn_id_frame,
46                                      sizeof(new_conn_id_frame));
47 }
48 
test_ncid_frame(int fail)49 static int test_ncid_frame(int fail)
50 {
51     int testresult = 0;
52     SSL_CTX *cctx = SSL_CTX_new(OSSL_QUIC_client_method());
53     QUIC_TSERVER *qtserv = NULL;
54     SSL *cssl = NULL;
55     char *msg = "Hello World!";
56     size_t msglen = strlen(msg);
57     unsigned char buf[80];
58     size_t byteswritten;
59     size_t bytesread;
60     QTEST_FAULT *fault = NULL;
61     static const QUIC_CONN_ID conn_id = {
62         0x08,
63         {0x33, 0x44, 0x55, 0x66, 0xde, 0xad, 0xbe, 0xef}
64     };
65 
66     ncid_injected = 0;
67     if (!TEST_ptr(cctx))
68         goto err;
69 
70     if (!TEST_true(qtest_create_quic_objects(NULL, cctx, NULL, cert, privkey, 0,
71                                              &qtserv, &cssl, &fault, NULL)))
72         goto err;
73 
74     if (!TEST_true(qtest_create_quic_connection(qtserv, cssl)))
75         goto err;
76 
77     if (!TEST_int_eq(SSL_write(cssl, msg, msglen), msglen))
78         goto err;
79 
80     ossl_quic_tserver_tick(qtserv);
81     if (!TEST_true(ossl_quic_tserver_read(qtserv, 0, buf, sizeof(buf),
82                                           &bytesread)))
83         goto err;
84 
85     /*
86      * We assume the entire message is read from the server in one go. In
87      * theory this could get fragmented but its a small message so we assume
88      * not.
89      */
90     if (!TEST_mem_eq(msg, msglen, buf, bytesread))
91         goto err;
92 
93     /*
94      * Write a message from the server to the client and add
95      * a NEW_CONNECTION_ID frame.
96      */
97     if (!TEST_true(qtest_fault_set_packet_plain_listener(fault,
98                                                          add_ncid_frame_cb,
99                                                          NULL)))
100         goto err;
101     if (!fail && !TEST_true(ossl_quic_tserver_set_new_local_cid(qtserv, &conn_id)))
102         goto err;
103     if (!TEST_true(ossl_quic_tserver_write(qtserv, 0,
104                                            (unsigned char *)msg, msglen,
105                                            &byteswritten)))
106         goto err;
107 
108     if (!TEST_true(ncid_injected))
109         goto err;
110 
111     if (!TEST_size_t_eq(msglen, byteswritten))
112         goto err;
113 
114     ossl_quic_tserver_tick(qtserv);
115     if (!TEST_true(SSL_handle_events(cssl)))
116         goto err;
117 
118     if (!TEST_int_eq(SSL_read(cssl, buf, sizeof(buf)), msglen))
119         goto err;
120 
121     if (!TEST_mem_eq(msg, msglen, buf, bytesread))
122         goto err;
123 
124     if (!TEST_int_eq(SSL_write(cssl, msg, msglen), msglen))
125         goto err;
126 
127     ossl_quic_tserver_tick(qtserv);
128     if (!TEST_true(ossl_quic_tserver_read(qtserv, 0, buf, sizeof(buf),
129                                           &bytesread)))
130         goto err;
131 
132     if (fail) {
133         if (!TEST_size_t_eq(bytesread, 0))
134             goto err;
135     } else {
136         if (!TEST_mem_eq(msg, msglen, buf, bytesread))
137             goto err;
138     }
139 
140     testresult = 1;
141  err:
142     qtest_fault_free(fault);
143     SSL_free(cssl);
144     ossl_quic_tserver_free(qtserv);
145     SSL_CTX_free(cctx);
146     return testresult;
147 }
148 
149 OPT_TEST_DECLARE_USAGE("certsdir\n")
150 
setup_tests(void)151 int setup_tests(void)
152 {
153     char *certsdir = NULL;
154 
155     if (!test_skip_common_options()) {
156         TEST_error("Error parsing test options\n");
157         return 0;
158     }
159 
160     if (!TEST_ptr(certsdir = test_get_argument(0)))
161         return 0;
162 
163     cert = test_mk_file_path(certsdir, "servercert.pem");
164     if (cert == NULL)
165         goto err;
166 
167     privkey = test_mk_file_path(certsdir, "serverkey.pem");
168     if (privkey == NULL)
169         goto err;
170 
171     ADD_ALL_TESTS(test_ncid_frame, 2);
172 
173     return 1;
174 
175  err:
176     OPENSSL_free(cert);
177     OPENSSL_free(privkey);
178     return 0;
179 }
180 
cleanup_tests(void)181 void cleanup_tests(void)
182 {
183     OPENSSL_free(cert);
184     OPENSSL_free(privkey);
185 }
186