1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2017-2022 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 <string.h>
11e1051a39Sopenharmony_ci
12e1051a39Sopenharmony_ci#include "helpers/ssltestlib.h"
13e1051a39Sopenharmony_ci#include "testutil.h"
14e1051a39Sopenharmony_ci
15e1051a39Sopenharmony_cistatic char *cert = NULL;
16e1051a39Sopenharmony_cistatic char *privkey = NULL;
17e1051a39Sopenharmony_ci
18e1051a39Sopenharmony_ci#define TEST_PLAINTEXT_OVERFLOW_OK      0
19e1051a39Sopenharmony_ci#define TEST_PLAINTEXT_OVERFLOW_NOT_OK  1
20e1051a39Sopenharmony_ci#define TEST_ENCRYPTED_OVERFLOW_TLS1_3_OK       2
21e1051a39Sopenharmony_ci#define TEST_ENCRYPTED_OVERFLOW_TLS1_3_NOT_OK   3
22e1051a39Sopenharmony_ci#define TEST_ENCRYPTED_OVERFLOW_TLS1_2_OK       4
23e1051a39Sopenharmony_ci#define TEST_ENCRYPTED_OVERFLOW_TLS1_2_NOT_OK   5
24e1051a39Sopenharmony_ci
25e1051a39Sopenharmony_ci#define TOTAL_RECORD_OVERFLOW_TESTS 6
26e1051a39Sopenharmony_ci
27e1051a39Sopenharmony_cistatic int write_record(BIO *b, size_t len, int rectype, int recversion)
28e1051a39Sopenharmony_ci{
29e1051a39Sopenharmony_ci    unsigned char header[SSL3_RT_HEADER_LENGTH];
30e1051a39Sopenharmony_ci    size_t written;
31e1051a39Sopenharmony_ci    unsigned char buf[256];
32e1051a39Sopenharmony_ci
33e1051a39Sopenharmony_ci    memset(buf, 0, sizeof(buf));
34e1051a39Sopenharmony_ci
35e1051a39Sopenharmony_ci    header[0] = rectype;
36e1051a39Sopenharmony_ci    header[1] = (recversion >> 8) & 0xff;
37e1051a39Sopenharmony_ci    header[2] = recversion & 0xff;
38e1051a39Sopenharmony_ci    header[3] = (len >> 8) & 0xff;
39e1051a39Sopenharmony_ci    header[4] = len & 0xff;
40e1051a39Sopenharmony_ci
41e1051a39Sopenharmony_ci    if (!BIO_write_ex(b, header, SSL3_RT_HEADER_LENGTH, &written)
42e1051a39Sopenharmony_ci            || written != SSL3_RT_HEADER_LENGTH)
43e1051a39Sopenharmony_ci        return 0;
44e1051a39Sopenharmony_ci
45e1051a39Sopenharmony_ci    while (len > 0) {
46e1051a39Sopenharmony_ci        size_t outlen;
47e1051a39Sopenharmony_ci
48e1051a39Sopenharmony_ci        if (len > sizeof(buf))
49e1051a39Sopenharmony_ci            outlen = sizeof(buf);
50e1051a39Sopenharmony_ci        else
51e1051a39Sopenharmony_ci            outlen = len;
52e1051a39Sopenharmony_ci
53e1051a39Sopenharmony_ci        if (!BIO_write_ex(b, buf, outlen, &written)
54e1051a39Sopenharmony_ci                || written != outlen)
55e1051a39Sopenharmony_ci            return 0;
56e1051a39Sopenharmony_ci
57e1051a39Sopenharmony_ci        len -= outlen;
58e1051a39Sopenharmony_ci    }
59e1051a39Sopenharmony_ci
60e1051a39Sopenharmony_ci    return 1;
61e1051a39Sopenharmony_ci}
62e1051a39Sopenharmony_ci
63e1051a39Sopenharmony_cistatic int fail_due_to_record_overflow(int enc)
64e1051a39Sopenharmony_ci{
65e1051a39Sopenharmony_ci    long err = ERR_peek_error();
66e1051a39Sopenharmony_ci    int reason;
67e1051a39Sopenharmony_ci
68e1051a39Sopenharmony_ci    if (enc)
69e1051a39Sopenharmony_ci        reason = SSL_R_ENCRYPTED_LENGTH_TOO_LONG;
70e1051a39Sopenharmony_ci    else
71e1051a39Sopenharmony_ci        reason = SSL_R_DATA_LENGTH_TOO_LONG;
72e1051a39Sopenharmony_ci
73e1051a39Sopenharmony_ci    if (ERR_GET_LIB(err) == ERR_LIB_SSL
74e1051a39Sopenharmony_ci            && ERR_GET_REASON(err) == reason)
75e1051a39Sopenharmony_ci        return 1;
76e1051a39Sopenharmony_ci
77e1051a39Sopenharmony_ci    return 0;
78e1051a39Sopenharmony_ci}
79e1051a39Sopenharmony_ci
80e1051a39Sopenharmony_cistatic int test_record_overflow(int idx)
81e1051a39Sopenharmony_ci{
82e1051a39Sopenharmony_ci    SSL_CTX *cctx = NULL, *sctx = NULL;
83e1051a39Sopenharmony_ci    SSL *clientssl = NULL, *serverssl = NULL;
84e1051a39Sopenharmony_ci    int testresult = 0;
85e1051a39Sopenharmony_ci    size_t len = 0;
86e1051a39Sopenharmony_ci    size_t written;
87e1051a39Sopenharmony_ci    int overf_expected;
88e1051a39Sopenharmony_ci    unsigned char buf;
89e1051a39Sopenharmony_ci    BIO *serverbio;
90e1051a39Sopenharmony_ci    int recversion;
91e1051a39Sopenharmony_ci
92e1051a39Sopenharmony_ci#ifdef OPENSSL_NO_TLS1_2
93e1051a39Sopenharmony_ci    if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_OK
94e1051a39Sopenharmony_ci            || idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_NOT_OK)
95e1051a39Sopenharmony_ci        return 1;
96e1051a39Sopenharmony_ci#endif
97e1051a39Sopenharmony_ci#if defined(OPENSSL_NO_TLS1_3) \
98e1051a39Sopenharmony_ci    || (defined(OPENSSL_NO_EC) && defined(OPENSSL_NO_DH))
99e1051a39Sopenharmony_ci    if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_OK
100e1051a39Sopenharmony_ci            || idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_NOT_OK)
101e1051a39Sopenharmony_ci        return 1;
102e1051a39Sopenharmony_ci#endif
103e1051a39Sopenharmony_ci
104e1051a39Sopenharmony_ci    if (!TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(),
105e1051a39Sopenharmony_ci                                       TLS_client_method(),
106e1051a39Sopenharmony_ci                                       TLS1_VERSION, 0,
107e1051a39Sopenharmony_ci                                       &sctx, &cctx, cert, privkey)))
108e1051a39Sopenharmony_ci        goto end;
109e1051a39Sopenharmony_ci
110e1051a39Sopenharmony_ci    if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_OK
111e1051a39Sopenharmony_ci            || idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_NOT_OK) {
112e1051a39Sopenharmony_ci        len = SSL3_RT_MAX_ENCRYPTED_LENGTH;
113e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_COMP
114e1051a39Sopenharmony_ci        len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD;
115e1051a39Sopenharmony_ci#endif
116e1051a39Sopenharmony_ci        SSL_CTX_set_max_proto_version(sctx, TLS1_2_VERSION);
117e1051a39Sopenharmony_ci    } else if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_OK
118e1051a39Sopenharmony_ci               || idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_NOT_OK) {
119e1051a39Sopenharmony_ci        len = SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH;
120e1051a39Sopenharmony_ci    }
121e1051a39Sopenharmony_ci
122e1051a39Sopenharmony_ci    if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
123e1051a39Sopenharmony_ci                                      NULL, NULL)))
124e1051a39Sopenharmony_ci        goto end;
125e1051a39Sopenharmony_ci
126e1051a39Sopenharmony_ci    serverbio = SSL_get_rbio(serverssl);
127e1051a39Sopenharmony_ci
128e1051a39Sopenharmony_ci    if (idx == TEST_PLAINTEXT_OVERFLOW_OK
129e1051a39Sopenharmony_ci            || idx == TEST_PLAINTEXT_OVERFLOW_NOT_OK) {
130e1051a39Sopenharmony_ci        len = SSL3_RT_MAX_PLAIN_LENGTH;
131e1051a39Sopenharmony_ci
132e1051a39Sopenharmony_ci        if (idx == TEST_PLAINTEXT_OVERFLOW_NOT_OK)
133e1051a39Sopenharmony_ci            len++;
134e1051a39Sopenharmony_ci
135e1051a39Sopenharmony_ci        if (!TEST_true(write_record(serverbio, len,
136e1051a39Sopenharmony_ci                                    SSL3_RT_HANDSHAKE, TLS1_VERSION)))
137e1051a39Sopenharmony_ci            goto end;
138e1051a39Sopenharmony_ci
139e1051a39Sopenharmony_ci        if (!TEST_int_le(SSL_accept(serverssl), 0))
140e1051a39Sopenharmony_ci            goto end;
141e1051a39Sopenharmony_ci
142e1051a39Sopenharmony_ci        overf_expected = (idx == TEST_PLAINTEXT_OVERFLOW_OK) ? 0 : 1;
143e1051a39Sopenharmony_ci        if (!TEST_int_eq(fail_due_to_record_overflow(0), overf_expected))
144e1051a39Sopenharmony_ci            goto end;
145e1051a39Sopenharmony_ci
146e1051a39Sopenharmony_ci        goto success;
147e1051a39Sopenharmony_ci    }
148e1051a39Sopenharmony_ci
149e1051a39Sopenharmony_ci    if (!TEST_true(create_ssl_connection(serverssl, clientssl,
150e1051a39Sopenharmony_ci                                         SSL_ERROR_NONE)))
151e1051a39Sopenharmony_ci        goto end;
152e1051a39Sopenharmony_ci
153e1051a39Sopenharmony_ci    if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_NOT_OK
154e1051a39Sopenharmony_ci            || idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_NOT_OK) {
155e1051a39Sopenharmony_ci        overf_expected = 1;
156e1051a39Sopenharmony_ci        len++;
157e1051a39Sopenharmony_ci    } else {
158e1051a39Sopenharmony_ci        overf_expected = 0;
159e1051a39Sopenharmony_ci    }
160e1051a39Sopenharmony_ci
161e1051a39Sopenharmony_ci    recversion = TLS1_2_VERSION;
162e1051a39Sopenharmony_ci
163e1051a39Sopenharmony_ci    if (!TEST_true(write_record(serverbio, len, SSL3_RT_APPLICATION_DATA,
164e1051a39Sopenharmony_ci                                recversion)))
165e1051a39Sopenharmony_ci        goto end;
166e1051a39Sopenharmony_ci
167e1051a39Sopenharmony_ci    if (!TEST_false(SSL_read_ex(serverssl, &buf, sizeof(buf), &written)))
168e1051a39Sopenharmony_ci        goto end;
169e1051a39Sopenharmony_ci
170e1051a39Sopenharmony_ci    if (!TEST_int_eq(fail_due_to_record_overflow(1), overf_expected))
171e1051a39Sopenharmony_ci        goto end;
172e1051a39Sopenharmony_ci
173e1051a39Sopenharmony_ci success:
174e1051a39Sopenharmony_ci    testresult = 1;
175e1051a39Sopenharmony_ci
176e1051a39Sopenharmony_ci end:
177e1051a39Sopenharmony_ci    SSL_free(serverssl);
178e1051a39Sopenharmony_ci    SSL_free(clientssl);
179e1051a39Sopenharmony_ci    SSL_CTX_free(sctx);
180e1051a39Sopenharmony_ci    SSL_CTX_free(cctx);
181e1051a39Sopenharmony_ci    return testresult;
182e1051a39Sopenharmony_ci}
183e1051a39Sopenharmony_ci
184e1051a39Sopenharmony_ciOPT_TEST_DECLARE_USAGE("certfile privkeyfile\n")
185e1051a39Sopenharmony_ci
186e1051a39Sopenharmony_ciint setup_tests(void)
187e1051a39Sopenharmony_ci{
188e1051a39Sopenharmony_ci    if (!test_skip_common_options()) {
189e1051a39Sopenharmony_ci        TEST_error("Error parsing test options\n");
190e1051a39Sopenharmony_ci        return 0;
191e1051a39Sopenharmony_ci    }
192e1051a39Sopenharmony_ci
193e1051a39Sopenharmony_ci    if (!TEST_ptr(cert = test_get_argument(0))
194e1051a39Sopenharmony_ci            || !TEST_ptr(privkey = test_get_argument(1)))
195e1051a39Sopenharmony_ci        return 0;
196e1051a39Sopenharmony_ci
197e1051a39Sopenharmony_ci    ADD_ALL_TESTS(test_record_overflow, TOTAL_RECORD_OVERFLOW_TESTS);
198e1051a39Sopenharmony_ci    return 1;
199e1051a39Sopenharmony_ci}
200e1051a39Sopenharmony_ci
201e1051a39Sopenharmony_civoid cleanup_tests(void)
202e1051a39Sopenharmony_ci{
203e1051a39Sopenharmony_ci    bio_s_mempacket_test_free();
204e1051a39Sopenharmony_ci}
205