[openssl-commits] [openssl] master update
Matt Caswell
matt at openssl.org
Mon Mar 6 20:11:03 UTC 2017
The branch master has been updated
via c1074ce096e98d3175292cbd2240ead7f1f67b32 (commit)
via 432196951390796cf2353de2d92f952f1deaa9d0 (commit)
from febb0afaef47ed74b2bdbde0b4278263390f4185 (commit)
- Log -----------------------------------------------------------------
commit c1074ce096e98d3175292cbd2240ead7f1f67b32
Author: Matt Caswell <matt at openssl.org>
Date: Mon Mar 6 16:56:42 2017 +0000
Add a test to check that we correctly handle record overflows
Reviewed-by: Rich Salz <rsalz at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2861)
commit 432196951390796cf2353de2d92f952f1deaa9d0
Author: Matt Caswell <matt at openssl.org>
Date: Mon Mar 6 15:13:25 2017 +0000
Tweak the TLSv1.3 record overflow limits
Reviewed-by: Rich Salz <rsalz at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2861)
-----------------------------------------------------------------------
Summary of changes:
include/openssl/ssl3.h | 11 +-
ssl/record/ssl3_record.c | 26 ++-
test/build.info | 6 +-
.../{90-test_sslapi.t => 70-test_recordlen.t} | 8 +-
test/recordlentest.c | 221 +++++++++++++++++++++
5 files changed, 256 insertions(+), 16 deletions(-)
copy test/recipes/{90-test_sslapi.t => 70-test_recordlen.t} (68%)
create mode 100644 test/recordlentest.c
diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h
index e6df97b..604a704 100644
--- a/include/openssl/ssl3.h
+++ b/include/openssl/ssl3.h
@@ -170,7 +170,8 @@ extern "C" {
* practice the value is lower than this. The overhead is the maximum number
* of padding bytes (256) plus the mac size.
*/
-# define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE)
+# define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE)
+# define SSL3_RT_MAX_TLS13_ENCRYPTED_OVERHEAD 256
/*
* OpenSSL currently only uses a padding length of at most one block so the
@@ -186,12 +187,14 @@ extern "C" {
# define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH
# else
# define SSL3_RT_MAX_COMPRESSED_LENGTH \
- (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD)
+ (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD)
# endif
# define SSL3_RT_MAX_ENCRYPTED_LENGTH \
- (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH)
+ (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH)
+# define SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH \
+ (SSL3_RT_MAX_PLAIN_LENGTH + SSL3_RT_MAX_TLS13_ENCRYPTED_OVERHEAD)
# define SSL3_RT_MAX_PACKET_SIZE \
- (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
+ (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
# define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54"
# define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52"
diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c
index 4149969..1e281fc 100644
--- a/ssl/record/ssl3_record.c
+++ b/ssl/record/ssl3_record.c
@@ -340,6 +340,25 @@ int ssl3_get_record(SSL *s)
/* now s->rlayer.rstate == SSL_ST_READ_BODY */
}
+ if (SSL_IS_TLS13(s)) {
+ if (thisrr->length > SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH) {
+ al = SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+ } else {
+ size_t len = SSL3_RT_MAX_ENCRYPTED_LENGTH;
+
+ if (s->expand == NULL)
+ len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD;
+
+ if (thisrr->length > len) {
+ al = SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+ }
+
/*
* s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data.
* Calculate how much more data we need to read for the rest of the
@@ -388,13 +407,6 @@ int ssl3_get_record(SSL *s)
* thisrr->length bytes of encrypted compressed stuff.
*/
- /* check is not needed I believe */
- if (thisrr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
- al = SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
- goto f_err;
- }
-
/* decrypt in place in 'thisrr->input' */
thisrr->data = thisrr->input;
thisrr->orig_len = thisrr->length;
diff --git a/test/build.info b/test/build.info
index 6bdeb85..f1f97f9 100644
--- a/test/build.info
+++ b/test/build.info
@@ -28,7 +28,7 @@ IF[{- !$disabled{tests} -}]
dtlsv1listentest ct_test threadstest afalgtest d2i_test \
ssl_test_ctx_test ssl_test x509aux cipherlist_test asynciotest \
bioprinttest sslapitest dtlstest sslcorrupttest bio_enc_test \
- pkey_meth_test uitest cipherbytes_test x509_time_test
+ pkey_meth_test uitest cipherbytes_test x509_time_test recordlentest
SOURCE[aborttest]=aborttest.c
INCLUDE[aborttest]=../include
@@ -283,6 +283,10 @@ IF[{- !$disabled{tests} -}]
INCLUDE[x509_time_test]=.. ../include
DEPEND[x509_time_test]=../libcrypto
+ SOURCE[recordlentest]=recordlentest.c ssltestlib.c testutil.c test_main_custom.c
+ INCLUDE[recordlentest]=../include .
+ DEPEND[recordlentest]=../libcrypto ../libssl
+
IF[{- !$disabled{psk} -}]
PROGRAMS_NO_INST=dtls_mtu_test
SOURCE[dtls_mtu_test]=dtls_mtu_test.c ssltestlib.c
diff --git a/test/recipes/90-test_sslapi.t b/test/recipes/70-test_recordlen.t
similarity index 68%
copy from test/recipes/90-test_sslapi.t
copy to test/recipes/70-test_recordlen.t
index efaae3b..12647a2 100644
--- a/test/recipes/90-test_sslapi.t
+++ b/test/recipes/70-test_recordlen.t
@@ -1,5 +1,5 @@
#! /usr/bin/env perl
-# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the OpenSSL license (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
@@ -10,12 +10,12 @@
use OpenSSL::Test::Utils;
use OpenSSL::Test qw/:DEFAULT srctop_file/;
-setup("test_sslapi");
+setup("test_recordlen");
plan skip_all => "No TLS/SSL protocols are supported by this OpenSSL build"
if alldisabled(grep { $_ ne "ssl3" } available_protocols("tls"));
plan tests => 1;
-ok(run(test(["sslapitest", srctop_file("apps", "server.pem"),
- srctop_file("apps", "server.pem")])), "running sslapitest");
+ok(run(test(["recordlentest", srctop_file("apps", "server.pem"),
+ srctop_file("apps", "server.pem")])), "running recordlentest");
diff --git a/test/recordlentest.c b/test/recordlentest.c
new file mode 100644
index 0000000..6bb1db4
--- /dev/null
+++ b/test/recordlentest.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (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 "ssltestlib.h"
+#include "testutil.h"
+#include "test_main_custom.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_plain_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
+#ifdef OPENSSL_NO_TLS1_3
+ if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_OK
+ || idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_NOT_OK)
+ return 1;
+#endif
+
+ ERR_clear_error();
+
+ if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx,
+ &cctx, cert, privkey)) {
+ printf("Unable to create SSL_CTX pair\n");
+ goto end;
+ }
+
+ if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_OK
+ || idx == TEST_ENCRYPTED_OVERFLOW_TLS1_2_NOT_OK) {
+ len = SSL3_RT_MAX_ENCRYPTED_LENGTH - SSL3_RT_MAX_COMPRESSED_OVERHEAD;
+ 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 (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) {
+ printf("Unable to create SSL objects\n");
+ 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 (!write_record(serverbio, len, SSL3_RT_HANDSHAKE, TLS1_VERSION)) {
+ printf("Unable to write plaintext record\n");
+ goto end;
+ }
+
+ if (SSL_accept(serverssl) > 0) {
+ printf("Unexpected success reading plaintext record\n");
+ goto end;
+ }
+
+ overf_expected = (idx == TEST_PLAINTEXT_OVERFLOW_OK) ? 0 : 1;
+ if (fail_due_to_record_overflow(0) != overf_expected) {
+ printf("Unexpected error value received\n");
+ goto end;
+ }
+
+ goto success;
+ }
+
+ if (!create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)) {
+ printf("Unable to create SSL connection\n");
+ 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;
+ }
+
+ if (idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_OK
+ || idx == TEST_ENCRYPTED_OVERFLOW_TLS1_3_NOT_OK)
+ recversion = TLS1_VERSION;
+ else
+ recversion = TLS1_2_VERSION;
+
+ if (!write_record(serverbio, len, SSL3_RT_APPLICATION_DATA, recversion)) {
+ printf("Unable to write encryprted record\n");
+ goto end;
+ }
+
+ if (SSL_read_ex(serverssl, &buf, sizeof(buf), &written)) {
+ printf("Unexpected success reading encrypted record\n");
+ goto end;
+ }
+
+ if (fail_due_to_record_overflow(1) != overf_expected) {
+ printf("Unexpected error value received\n");
+ goto end;
+ }
+
+ success:
+ testresult = 1;
+
+ end:
+ if(!testresult)
+ ERR_print_errors_fp(stdout);
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+
+ return testresult;
+}
+
+int test_main(int argc, char *argv[])
+{
+ int testresult = 1;
+
+ if (argc != 3) {
+ printf("Invalid argument count\n");
+ return 1;
+ }
+
+ cert = argv[1];
+ privkey = argv[2];
+
+ ADD_ALL_TESTS(test_record_plain_overflow, TOTAL_RECORD_OVERFLOW_TESTS);
+
+ testresult = run_tests(argv[0]);
+
+ bio_s_mempacket_test_free();
+
+ return testresult;
+}
More information about the openssl-commits
mailing list