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