mirror of
https://github.com/openssl/openssl.git
synced 2024-11-27 05:21:51 +08:00
a763ca1177
Even if EC and DH are disabled then we may still be able to use TLSv1.3 if we have groups that have been plugged in by an external provider. Fixes #13767 Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/13916)
207 lines
5.4 KiB
C
207 lines
5.4 KiB
C
/*
|
|
* Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
|
|
*
|
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
|
* this file except in compliance with the License. You can obtain a copy
|
|
* in the file LICENSE in the source distribution or at
|
|
* https://www.openssl.org/source/license.html
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include "helpers/ssltestlib.h"
|
|
#include "testutil.h"
|
|
|
|
static char *cert = NULL;
|
|
static char *privkey = NULL;
|
|
|
|
#define TEST_PLAINTEXT_OVERFLOW_OK 0
|
|
#define TEST_PLAINTEXT_OVERFLOW_NOT_OK 1
|
|
#define TEST_ENCRYPTED_OVERFLOW_TLS1_3_OK 2
|
|
#define TEST_ENCRYPTED_OVERFLOW_TLS1_3_NOT_OK 3
|
|
#define TEST_ENCRYPTED_OVERFLOW_TLS1_2_OK 4
|
|
#define TEST_ENCRYPTED_OVERFLOW_TLS1_2_NOT_OK 5
|
|
|
|
#define TOTAL_RECORD_OVERFLOW_TESTS 6
|
|
|
|
static int write_record(BIO *b, size_t len, int rectype, int recversion)
|
|
{
|
|
unsigned char header[SSL3_RT_HEADER_LENGTH];
|
|
size_t written;
|
|
unsigned char buf[256];
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
header[0] = rectype;
|
|
header[1] = (recversion >> 8) & 0xff;
|
|
header[2] = recversion & 0xff;
|
|
header[3] = (len >> 8) & 0xff;
|
|
header[4] = len & 0xff;
|
|
|
|
if (!BIO_write_ex(b, header, SSL3_RT_HEADER_LENGTH, &written)
|
|
|| written != SSL3_RT_HEADER_LENGTH)
|
|
return 0;
|
|
|
|
while (len > 0) {
|
|
size_t outlen;
|
|
|
|
if (len > sizeof(buf))
|
|
outlen = sizeof(buf);
|
|
else
|
|
outlen = len;
|
|
|
|
if (!BIO_write_ex(b, buf, outlen, &written)
|
|
|| written != outlen)
|
|
return 0;
|
|
|
|
len -= outlen;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int fail_due_to_record_overflow(int enc)
|
|
{
|
|
long err = ERR_peek_error();
|
|
int reason;
|
|
|
|
if (enc)
|
|
reason = SSL_R_ENCRYPTED_LENGTH_TOO_LONG;
|
|
else
|
|
reason = SSL_R_DATA_LENGTH_TOO_LONG;
|
|
|
|
if (ERR_GET_LIB(err) == ERR_LIB_SSL
|
|
&& ERR_GET_REASON(err) == reason)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int test_record_overflow(int idx)
|
|
{
|
|
SSL_CTX *cctx = NULL, *sctx = NULL;
|
|
SSL *clientssl = NULL, *serverssl = NULL;
|
|
int testresult = 0;
|
|
size_t len = 0;
|
|
size_t written;
|
|
int overf_expected;
|
|
unsigned char buf;
|
|
BIO *serverbio;
|
|
int recversion;
|
|
|
|
#ifdef OPENSSL_NO_TLS1_2
|
|
if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_OK
|
|
|| idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_NOT_OK)
|
|
return 1;
|
|
#endif
|
|
#if defined(OPENSSL_NO_TLS1_3) \
|
|
|| (defined(OPENSSL_NO_EC) && defined(OPENSSL_NO_DH))
|
|
if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_OK
|
|
|| idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_NOT_OK)
|
|
return 1;
|
|
#endif
|
|
|
|
ERR_clear_error();
|
|
|
|
if (!TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(),
|
|
TLS_client_method(),
|
|
TLS1_VERSION, 0,
|
|
&sctx, &cctx, cert, privkey)))
|
|
goto end;
|
|
|
|
if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_OK
|
|
|| idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_NOT_OK) {
|
|
len = SSL3_RT_MAX_ENCRYPTED_LENGTH;
|
|
#ifndef OPENSSL_NO_COMP
|
|
len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD;
|
|
#endif
|
|
SSL_CTX_set_max_proto_version(sctx, TLS1_2_VERSION);
|
|
} else if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_OK
|
|
|| idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_NOT_OK) {
|
|
len = SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH;
|
|
}
|
|
|
|
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
|
|
NULL, NULL)))
|
|
goto end;
|
|
|
|
serverbio = SSL_get_rbio(serverssl);
|
|
|
|
if (idx == TEST_PLAINTEXT_OVERFLOW_OK
|
|
|| idx == TEST_PLAINTEXT_OVERFLOW_NOT_OK) {
|
|
len = SSL3_RT_MAX_PLAIN_LENGTH;
|
|
|
|
if (idx == TEST_PLAINTEXT_OVERFLOW_NOT_OK)
|
|
len++;
|
|
|
|
if (!TEST_true(write_record(serverbio, len,
|
|
SSL3_RT_HANDSHAKE, TLS1_VERSION)))
|
|
goto end;
|
|
|
|
if (!TEST_int_le(SSL_accept(serverssl), 0))
|
|
goto end;
|
|
|
|
overf_expected = (idx == TEST_PLAINTEXT_OVERFLOW_OK) ? 0 : 1;
|
|
if (!TEST_int_eq(fail_due_to_record_overflow(0), overf_expected))
|
|
goto end;
|
|
|
|
goto success;
|
|
}
|
|
|
|
if (!TEST_true(create_ssl_connection(serverssl, clientssl,
|
|
SSL_ERROR_NONE)))
|
|
goto end;
|
|
|
|
if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_NOT_OK
|
|
|| idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_NOT_OK) {
|
|
overf_expected = 1;
|
|
len++;
|
|
} else {
|
|
overf_expected = 0;
|
|
}
|
|
|
|
recversion = TLS1_2_VERSION;
|
|
|
|
if (!TEST_true(write_record(serverbio, len, SSL3_RT_APPLICATION_DATA,
|
|
recversion)))
|
|
goto end;
|
|
|
|
if (!TEST_false(SSL_read_ex(serverssl, &buf, sizeof(buf), &written)))
|
|
goto end;
|
|
|
|
if (!TEST_int_eq(fail_due_to_record_overflow(1), overf_expected))
|
|
goto end;
|
|
|
|
success:
|
|
testresult = 1;
|
|
|
|
end:
|
|
SSL_free(serverssl);
|
|
SSL_free(clientssl);
|
|
SSL_CTX_free(sctx);
|
|
SSL_CTX_free(cctx);
|
|
return testresult;
|
|
}
|
|
|
|
OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n")
|
|
|
|
int setup_tests(void)
|
|
{
|
|
if (!test_skip_common_options()) {
|
|
TEST_error("Error parsing test options\n");
|
|
return 0;
|
|
}
|
|
|
|
if (!TEST_ptr(cert = test_get_argument(0))
|
|
|| !TEST_ptr(privkey = test_get_argument(1)))
|
|
return 0;
|
|
|
|
ADD_ALL_TESTS(test_record_overflow, TOTAL_RECORD_OVERFLOW_TESTS);
|
|
return 1;
|
|
}
|
|
|
|
void cleanup_tests(void)
|
|
{
|
|
bio_s_mempacket_test_free();
|
|
}
|