1 | /*
|
---|
2 | * Copyright 2017-2020 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 <openssl/ssl.h>
|
---|
11 | #include <string.h>
|
---|
12 | #include "helpers/ssltestlib.h"
|
---|
13 | #include "testutil.h"
|
---|
14 | #include "internal/packet.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(void)
|
---|
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 |
|
---|
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 | expectedrecvers = TLS1_VERSION;
|
---|
132 |
|
---|
133 | /* Save the session id for later */
|
---|
134 | chsessidlen = PACKET_remaining(&sessionid);
|
---|
135 | if (!PACKET_copy_bytes(&sessionid, chsessid, chsessidlen))
|
---|
136 | return 0;
|
---|
137 | } else {
|
---|
138 | /*
|
---|
139 | * Check the session id for the second ClientHello is the
|
---|
140 | * same as the first one.
|
---|
141 | */
|
---|
142 | if (PACKET_remaining(&sessionid) != chsessidlen
|
---|
143 | || (chsessidlen > 0
|
---|
144 | && memcmp(chsessid, PACKET_data(&sessionid),
|
---|
145 | chsessidlen) != 0))
|
---|
146 | badsessid = 1;
|
---|
147 | }
|
---|
148 | } else if (msgtype == SSL3_MT_SERVER_HELLO) {
|
---|
149 | shseen++;
|
---|
150 | /*
|
---|
151 | * Skip legacy_version (2 bytes) and Random (32 bytes) to read
|
---|
152 | * session_id.
|
---|
153 | */
|
---|
154 | if (!PACKET_forward(&msgbody, 34)
|
---|
155 | || !PACKET_get_length_prefixed_1(&msgbody, &sessionid))
|
---|
156 | return 0;
|
---|
157 |
|
---|
158 | /*
|
---|
159 | * Check the session id is the same as the one in the
|
---|
160 | * ClientHello
|
---|
161 | */
|
---|
162 | if (PACKET_remaining(&sessionid) != chsessidlen
|
---|
163 | || (chsessidlen > 0
|
---|
164 | && memcmp(chsessid, PACKET_data(&sessionid),
|
---|
165 | chsessidlen) != 0))
|
---|
166 | badsessid = 1;
|
---|
167 | }
|
---|
168 | } else if (rectype == SSL3_RT_CHANGE_CIPHER_SPEC) {
|
---|
169 | if (bio == s_to_c_fbio) {
|
---|
170 | /*
|
---|
171 | * Server writing. We shouldn't have written any app data
|
---|
172 | * yet, and we should have seen both the ClientHello and the
|
---|
173 | * ServerHello
|
---|
174 | */
|
---|
175 | if (!sappdataseen
|
---|
176 | && chseen == 1
|
---|
177 | && shseen == 1
|
---|
178 | && !sccsseen)
|
---|
179 | sccsseen = 1;
|
---|
180 | else
|
---|
181 | badccs = 1;
|
---|
182 | } else if (!cappdataseen) {
|
---|
183 | /*
|
---|
184 | * Client writing. We shouldn't have written any app data
|
---|
185 | * yet, and we should have seen the ClientHello
|
---|
186 | */
|
---|
187 | if (shseen == 1 && !ccsaftersh)
|
---|
188 | ccsaftersh = 1;
|
---|
189 | else if (shseen == 0 && !ccsbeforesh)
|
---|
190 | ccsbeforesh = 1;
|
---|
191 | else
|
---|
192 | badccs = 1;
|
---|
193 | } else {
|
---|
194 | badccs = 1;
|
---|
195 | }
|
---|
196 | } else if(rectype == SSL3_RT_APPLICATION_DATA) {
|
---|
197 | if (bio == s_to_c_fbio)
|
---|
198 | sappdataseen = 1;
|
---|
199 | else
|
---|
200 | cappdataseen = 1;
|
---|
201 | }
|
---|
202 | if (recvers != expectedrecvers)
|
---|
203 | badvers = 1;
|
---|
204 | }
|
---|
205 |
|
---|
206 | ret = BIO_write(next, in, inl);
|
---|
207 | if (ret <= 0 && BIO_should_write(next))
|
---|
208 | BIO_set_retry_write(bio);
|
---|
209 |
|
---|
210 | return ret;
|
---|
211 | }
|
---|
212 |
|
---|
213 | static long watchccs_ctrl(BIO *bio, int cmd, long num, void *ptr)
|
---|
214 | {
|
---|
215 | long ret;
|
---|
216 | BIO *next = BIO_next(bio);
|
---|
217 |
|
---|
218 | if (next == NULL)
|
---|
219 | return 0;
|
---|
220 |
|
---|
221 | switch (cmd) {
|
---|
222 | case BIO_CTRL_DUP:
|
---|
223 | ret = 0;
|
---|
224 | break;
|
---|
225 | default:
|
---|
226 | ret = BIO_ctrl(next, cmd, num, ptr);
|
---|
227 | break;
|
---|
228 | }
|
---|
229 | return ret;
|
---|
230 | }
|
---|
231 |
|
---|
232 | static int watchccs_gets(BIO *bio, char *buf, int size)
|
---|
233 | {
|
---|
234 | /* We don't support this - not needed anyway */
|
---|
235 | return -1;
|
---|
236 | }
|
---|
237 |
|
---|
238 | static int watchccs_puts(BIO *bio, const char *str)
|
---|
239 | {
|
---|
240 | return watchccs_write(bio, str, strlen(str));
|
---|
241 | }
|
---|
242 |
|
---|
243 | static int test_tls13ccs(int tst)
|
---|
244 | {
|
---|
245 | SSL_CTX *sctx = NULL, *cctx = NULL;
|
---|
246 | SSL *sssl = NULL, *cssl = NULL;
|
---|
247 | int ret = 0;
|
---|
248 | const char msg[] = "Dummy data";
|
---|
249 | char buf[80];
|
---|
250 | size_t written, readbytes;
|
---|
251 | SSL_SESSION *sess = NULL;
|
---|
252 |
|
---|
253 | chseen = shseen = sccsseen = ccsaftersh = ccsbeforesh = 0;
|
---|
254 | sappdataseen = cappdataseen = badccs = badvers = badsessid = 0;
|
---|
255 | chsessidlen = 0;
|
---|
256 |
|
---|
257 | if (!TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(),
|
---|
258 | TLS_client_method(), TLS1_VERSION, 0,
|
---|
259 | &sctx, &cctx, cert, privkey))
|
---|
260 | || !TEST_true(SSL_CTX_set_max_early_data(sctx,
|
---|
261 | SSL3_RT_MAX_PLAIN_LENGTH)))
|
---|
262 | goto err;
|
---|
263 |
|
---|
264 | /*
|
---|
265 | * Test 0: Simple Handshake
|
---|
266 | * Test 1: Simple Handshake, client middlebox compat mode disabled
|
---|
267 | * Test 2: Simple Handshake, server middlebox compat mode disabled
|
---|
268 | * Test 3: HRR Handshake
|
---|
269 | * Test 4: HRR Handshake, client middlebox compat mode disabled
|
---|
270 | * Test 5: HRR Handshake, server middlebox compat mode disabled
|
---|
271 | * Test 6: Early data handshake
|
---|
272 | * Test 7: Early data handshake, client middlebox compat mode disabled
|
---|
273 | * Test 8: Early data handshake, server middlebox compat mode disabled
|
---|
274 | * Test 9: Early data then HRR
|
---|
275 | * Test 10: Early data then HRR, client middlebox compat mode disabled
|
---|
276 | * Test 11: Early data then HRR, server middlebox compat mode disabled
|
---|
277 | */
|
---|
278 | switch (tst) {
|
---|
279 | case 0:
|
---|
280 | case 3:
|
---|
281 | case 6:
|
---|
282 | case 9:
|
---|
283 | break;
|
---|
284 | case 1:
|
---|
285 | case 4:
|
---|
286 | case 7:
|
---|
287 | case 10:
|
---|
288 | SSL_CTX_clear_options(cctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
|
---|
289 | break;
|
---|
290 | case 2:
|
---|
291 | case 5:
|
---|
292 | case 8:
|
---|
293 | case 11:
|
---|
294 | SSL_CTX_clear_options(sctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
|
---|
295 | break;
|
---|
296 | default:
|
---|
297 | TEST_error("Invalid test value");
|
---|
298 | goto err;
|
---|
299 | }
|
---|
300 |
|
---|
301 | if (tst >= 6) {
|
---|
302 | /* Get a session suitable for early_data */
|
---|
303 | if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
|
---|
304 | || !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE)))
|
---|
305 | goto err;
|
---|
306 | sess = SSL_get1_session(cssl);
|
---|
307 | if (!TEST_ptr(sess))
|
---|
308 | goto err;
|
---|
309 | SSL_shutdown(cssl);
|
---|
310 | SSL_shutdown(sssl);
|
---|
311 | SSL_free(sssl);
|
---|
312 | SSL_free(cssl);
|
---|
313 | sssl = cssl = NULL;
|
---|
314 | }
|
---|
315 |
|
---|
316 | if ((tst >= 3 && tst <= 5) || tst >= 9) {
|
---|
317 | /* HRR handshake */
|
---|
318 | #if defined(OPENSSL_NO_EC)
|
---|
319 | # if !defined(OPENSSL_NO_DH)
|
---|
320 | if (!TEST_true(SSL_CTX_set1_groups_list(sctx, "ffdhe3072")))
|
---|
321 | goto err;
|
---|
322 | # endif
|
---|
323 | #else
|
---|
324 | if (!TEST_true(SSL_CTX_set1_groups_list(sctx, "P-256")))
|
---|
325 | goto err;
|
---|
326 | #endif
|
---|
327 | }
|
---|
328 |
|
---|
329 | s_to_c_fbio = BIO_new(bio_f_watchccs_filter());
|
---|
330 | c_to_s_fbio = BIO_new(bio_f_watchccs_filter());
|
---|
331 | if (!TEST_ptr(s_to_c_fbio)
|
---|
332 | || !TEST_ptr(c_to_s_fbio)) {
|
---|
333 | BIO_free(s_to_c_fbio);
|
---|
334 | BIO_free(c_to_s_fbio);
|
---|
335 | goto err;
|
---|
336 | }
|
---|
337 |
|
---|
338 | /* BIOs get freed on error */
|
---|
339 | if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, s_to_c_fbio,
|
---|
340 | c_to_s_fbio)))
|
---|
341 | goto err;
|
---|
342 |
|
---|
343 | if (tst >= 6) {
|
---|
344 | /* Early data */
|
---|
345 | if (!TEST_true(SSL_set_session(cssl, sess))
|
---|
346 | || !TEST_true(SSL_write_early_data(cssl, msg, strlen(msg),
|
---|
347 | &written))
|
---|
348 | || (tst <= 8
|
---|
349 | && !TEST_int_eq(SSL_read_early_data(sssl, buf, sizeof(buf),
|
---|
350 | &readbytes),
|
---|
351 | SSL_READ_EARLY_DATA_SUCCESS)))
|
---|
352 | goto err;
|
---|
353 | if (tst <= 8) {
|
---|
354 | if (!TEST_int_gt(SSL_connect(cssl), 0))
|
---|
355 | goto err;
|
---|
356 | } else {
|
---|
357 | if (!TEST_int_le(SSL_connect(cssl), 0))
|
---|
358 | goto err;
|
---|
359 | }
|
---|
360 | if (!TEST_int_eq(SSL_read_early_data(sssl, buf, sizeof(buf),
|
---|
361 | &readbytes),
|
---|
362 | SSL_READ_EARLY_DATA_FINISH))
|
---|
363 | goto err;
|
---|
364 | }
|
---|
365 |
|
---|
366 | /* Perform handshake (or complete it if doing early data ) */
|
---|
367 | if (!TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE)))
|
---|
368 | goto err;
|
---|
369 |
|
---|
370 | /*
|
---|
371 | * Check there were no unexpected CCS messages, all record versions
|
---|
372 | * were as expected, and that the session ids were reflected by the server
|
---|
373 | * correctly.
|
---|
374 | */
|
---|
375 | if (!TEST_false(badccs) || !TEST_false(badvers) || !TEST_false(badsessid))
|
---|
376 | goto err;
|
---|
377 |
|
---|
378 | switch (tst) {
|
---|
379 | case 0:
|
---|
380 | if (!TEST_true(sccsseen)
|
---|
381 | || !TEST_true(ccsaftersh)
|
---|
382 | || !TEST_false(ccsbeforesh)
|
---|
383 | || !TEST_size_t_gt(chsessidlen, 0))
|
---|
384 | goto err;
|
---|
385 | break;
|
---|
386 |
|
---|
387 | case 1:
|
---|
388 | if (!TEST_true(sccsseen)
|
---|
389 | || !TEST_false(ccsaftersh)
|
---|
390 | || !TEST_false(ccsbeforesh)
|
---|
391 | || !TEST_size_t_eq(chsessidlen, 0))
|
---|
392 | goto err;
|
---|
393 | break;
|
---|
394 |
|
---|
395 | case 2:
|
---|
396 | if (!TEST_false(sccsseen)
|
---|
397 | || !TEST_true(ccsaftersh)
|
---|
398 | || !TEST_false(ccsbeforesh)
|
---|
399 | || !TEST_size_t_gt(chsessidlen, 0))
|
---|
400 | goto err;
|
---|
401 | break;
|
---|
402 |
|
---|
403 | case 3:
|
---|
404 | if (!TEST_true(sccsseen)
|
---|
405 | || !TEST_true(ccsaftersh)
|
---|
406 | || !TEST_false(ccsbeforesh)
|
---|
407 | || !TEST_size_t_gt(chsessidlen, 0))
|
---|
408 | goto err;
|
---|
409 | break;
|
---|
410 |
|
---|
411 | case 4:
|
---|
412 | if (!TEST_true(sccsseen)
|
---|
413 | || !TEST_false(ccsaftersh)
|
---|
414 | || !TEST_false(ccsbeforesh)
|
---|
415 | || !TEST_size_t_eq(chsessidlen, 0))
|
---|
416 | goto err;
|
---|
417 | break;
|
---|
418 |
|
---|
419 | case 5:
|
---|
420 | if (!TEST_false(sccsseen)
|
---|
421 | || !TEST_true(ccsaftersh)
|
---|
422 | || !TEST_false(ccsbeforesh)
|
---|
423 | || !TEST_size_t_gt(chsessidlen, 0))
|
---|
424 | goto err;
|
---|
425 | break;
|
---|
426 |
|
---|
427 | case 6:
|
---|
428 | if (!TEST_true(sccsseen)
|
---|
429 | || !TEST_false(ccsaftersh)
|
---|
430 | || !TEST_true(ccsbeforesh)
|
---|
431 | || !TEST_size_t_gt(chsessidlen, 0))
|
---|
432 | goto err;
|
---|
433 | break;
|
---|
434 |
|
---|
435 | case 7:
|
---|
436 | if (!TEST_true(sccsseen)
|
---|
437 | || !TEST_false(ccsaftersh)
|
---|
438 | || !TEST_false(ccsbeforesh)
|
---|
439 | || !TEST_size_t_eq(chsessidlen, 0))
|
---|
440 | goto err;
|
---|
441 | break;
|
---|
442 |
|
---|
443 | case 8:
|
---|
444 | if (!TEST_false(sccsseen)
|
---|
445 | || !TEST_false(ccsaftersh)
|
---|
446 | || !TEST_true(ccsbeforesh)
|
---|
447 | || !TEST_size_t_gt(chsessidlen, 0))
|
---|
448 | goto err;
|
---|
449 | break;
|
---|
450 |
|
---|
451 | case 9:
|
---|
452 | if (!TEST_true(sccsseen)
|
---|
453 | || !TEST_false(ccsaftersh)
|
---|
454 | || !TEST_true(ccsbeforesh)
|
---|
455 | || !TEST_size_t_gt(chsessidlen, 0))
|
---|
456 | goto err;
|
---|
457 | break;
|
---|
458 |
|
---|
459 | case 10:
|
---|
460 | if (!TEST_true(sccsseen)
|
---|
461 | || !TEST_false(ccsaftersh)
|
---|
462 | || !TEST_false(ccsbeforesh)
|
---|
463 | || !TEST_size_t_eq(chsessidlen, 0))
|
---|
464 | goto err;
|
---|
465 | break;
|
---|
466 |
|
---|
467 | case 11:
|
---|
468 | if (!TEST_false(sccsseen)
|
---|
469 | || !TEST_false(ccsaftersh)
|
---|
470 | || !TEST_true(ccsbeforesh)
|
---|
471 | || !TEST_size_t_gt(chsessidlen, 0))
|
---|
472 | goto err;
|
---|
473 | break;
|
---|
474 |
|
---|
475 | default:
|
---|
476 | TEST_error("Invalid test value");
|
---|
477 | goto err;
|
---|
478 | }
|
---|
479 |
|
---|
480 | ret = 1;
|
---|
481 | err:
|
---|
482 | SSL_SESSION_free(sess);
|
---|
483 | SSL_free(sssl);
|
---|
484 | SSL_free(cssl);
|
---|
485 | SSL_CTX_free(sctx);
|
---|
486 | SSL_CTX_free(cctx);
|
---|
487 |
|
---|
488 | return ret;
|
---|
489 | }
|
---|
490 |
|
---|
491 | OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n")
|
---|
492 |
|
---|
493 | int setup_tests(void)
|
---|
494 | {
|
---|
495 | if (!test_skip_common_options()) {
|
---|
496 | TEST_error("Error parsing test options\n");
|
---|
497 | return 0;
|
---|
498 | }
|
---|
499 |
|
---|
500 | if (!TEST_ptr(cert = test_get_argument(0))
|
---|
501 | || !TEST_ptr(privkey = test_get_argument(1)))
|
---|
502 | return 0;
|
---|
503 |
|
---|
504 | ADD_ALL_TESTS(test_tls13ccs, 12);
|
---|
505 |
|
---|
506 | return 1;
|
---|
507 | }
|
---|
508 |
|
---|
509 | void cleanup_tests(void)
|
---|
510 | {
|
---|
511 | BIO_meth_free(method_watchccs);
|
---|
512 | }
|
---|