summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ssl/record/ssl3_record.c27
-rw-r--r--test/recipes/80-test_ssl_old.t22
-rw-r--r--test/ssl_old_test.c11
3 files changed, 48 insertions, 12 deletions
diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c
index 86203849a9..5534814305 100644
--- a/ssl/record/ssl3_record.c
+++ b/ssl/record/ssl3_record.c
@@ -191,7 +191,7 @@ int ssl3_get_record(SSL *s)
rr = RECORD_LAYER_get_rrec(&s->rlayer);
rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
- is_ktls_left = (rbuf->left > 0);
+ is_ktls_left = (SSL3_BUFFER_get_left(rbuf) > 0);
max_recs = s->max_pipelines;
if (max_recs == 0)
max_recs = 1;
@@ -408,7 +408,11 @@ int ssl3_get_record(SSL *s)
len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD;
#endif
- if (thisrr->length > len && !BIO_get_ktls_recv(s->rbio)) {
+ /* KTLS may use all of the buffer */
+ if (BIO_get_ktls_recv(s->rbio) && !is_ktls_left)
+ len = SSL3_BUFFER_get_left(rbuf);
+
+ if (thisrr->length > len) {
SSLfatal(s, SSL_AD_RECORD_OVERFLOW,
SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
return -1;
@@ -711,16 +715,27 @@ int ssl3_get_record(SSL *s)
goto end;
}
+ /*
+ * Usually thisrr->length is the length of a single record, but when
+ * KTLS handles the decryption, thisrr->length may be larger than
+ * SSL3_RT_MAX_PLAIN_LENGTH because the kernel may have coalesced
+ * multiple records.
+ * Therefore we have to rely on KTLS to check the plaintext length
+ * limit in the kernel.
+ */
if (thisrr->length > SSL3_RT_MAX_PLAIN_LENGTH
- && !BIO_get_ktls_recv(s->rbio)) {
+ && (!BIO_get_ktls_recv(s->rbio) || is_ktls_left)) {
SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
goto end;
}
- /* If received packet overflows current Max Fragment Length setting */
+ /*
+ * Check if the received packet overflows the current
+ * Max Fragment Length setting.
+ * Note: USE_MAX_FRAGMENT_LENGTH_EXT and KTLS are mutually exclusive.
+ */
if (s->session != NULL && USE_MAX_FRAGMENT_LENGTH_EXT(s->session)
- && thisrr->length > GET_MAX_FRAGMENT_LENGTH(s->session)
- && !BIO_get_ktls_recv(s->rbio)) {
+ && thisrr->length > GET_MAX_FRAGMENT_LENGTH(s->session)) {
SSLfatal(s, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG);
goto end;
}
diff --git a/test/recipes/80-test_ssl_old.t b/test/recipes/80-test_ssl_old.t
index b144bc9fb9..c1fb30f6b2 100644
--- a/test/recipes/80-test_ssl_old.t
+++ b/test/recipes/80-test_ssl_old.t
@@ -346,11 +346,9 @@ sub testssl {
}
- # plan tests => 11;
-
subtest 'standard SSL tests' => sub {
######################################################################
- plan tests => 13;
+ plan tests => 19;
SKIP: {
skip "SSLv3 is not supported by this OpenSSL build", 4
@@ -378,7 +376,7 @@ sub testssl {
}
SKIP: {
- skip "Neither SSLv3 nor any TLS version are supported by this OpenSSL build", 8
+ skip "Neither SSLv3 nor any TLS version are supported by this OpenSSL build", 14
if $no_anytls;
SKIP: {
@@ -406,17 +404,29 @@ sub testssl {
'test sslv2/sslv3 with both client and server authentication via BIO pair and app verify');
SKIP: {
- skip "No IPv4 available on this machine", 1
+ skip "No IPv4 available on this machine", 4
unless !disabled("sock") && have_IPv4();
ok(run(test([@ssltest, "-ipv4"])),
'test TLS via IPv4');
+ ok(run(test([@ssltest, "-ipv4", "-client_ktls"])),
+ 'test TLS via IPv4 + ktls(client)');
+ ok(run(test([@ssltest, "-ipv4", "-server_ktls"])),
+ 'test TLS via IPv4 + ktls(server)');
+ ok(run(test([@ssltest, "-ipv4", "-client_ktls", "-server_ktls"])),
+ 'test TLS via IPv4 + ktls');
}
SKIP: {
- skip "No IPv6 available on this machine", 1
+ skip "No IPv6 available on this machine", 4
unless !disabled("sock") && have_IPv6();
ok(run(test([@ssltest, "-ipv6"])),
'test TLS via IPv6');
+ ok(run(test([@ssltest, "-ipv6", "-client_ktls"])),
+ 'test TLS via IPv6 + ktls(client)');
+ ok(run(test([@ssltest, "-ipv6", "-server_ktls"])),
+ 'test TLS via IPv6 + ktls(client)');
+ ok(run(test([@ssltest, "-ipv6", "-client_ktls", "-server_ktls"])),
+ 'test TLS via IPv6 + ktls');
}
}
};
diff --git a/test/ssl_old_test.c b/test/ssl_old_test.c
index 1b1983b7c3..7c6fa5d9c7 100644
--- a/test/ssl_old_test.c
+++ b/test/ssl_old_test.c
@@ -711,6 +711,8 @@ static void sv_usage(void)
fprintf(stderr, " -client_sess_in <file> - Read the client session from a file\n");
fprintf(stderr, " -should_reuse <number> - The expected state of reusing the session\n");
fprintf(stderr, " -no_ticket - do not issue TLS session ticket\n");
+ fprintf(stderr, " -client_ktls - try to enable client KTLS\n");
+ fprintf(stderr, " -server_ktls - try to enable server KTLS\n");
fprintf(stderr, " -provider <name> - Load the given provider into the library context\n");
fprintf(stderr, " -config <cnf> - Load the given config file into the library context\n");
}
@@ -883,6 +885,7 @@ int main(int argc, char *argv[])
int number = 1, reuse = 0;
int should_reuse = -1;
int no_ticket = 0;
+ int client_ktls = 0, server_ktls = 0;
long bytes = 256L;
#ifndef OPENSSL_NO_DH
EVP_PKEY *dhpkey;
@@ -1167,6 +1170,10 @@ int main(int argc, char *argv[])
should_reuse = !!atoi(*(++argv));
} else if (strcmp(*argv, "-no_ticket") == 0) {
no_ticket = 1;
+ } else if (strcmp(*argv, "-client_ktls") == 0) {
+ client_ktls = 1;
+ } else if (strcmp(*argv, "-server_ktls") == 0) {
+ server_ktls = 1;
} else if (strcmp(*argv, "-provider") == 0) {
if (--argc < 1)
goto bad;
@@ -1724,6 +1731,10 @@ int main(int argc, char *argv[])
if (sn_client)
SSL_set_tlsext_host_name(c_ssl, sn_client);
+ if (client_ktls)
+ SSL_set_options(c_ssl, SSL_OP_ENABLE_KTLS);
+ if (server_ktls)
+ SSL_set_options(s_ssl, SSL_OP_ENABLE_KTLS);
if (!set_protocol_version(server_min_proto, s_ssl, SSL_CTRL_SET_MIN_PROTO_VERSION))
goto end;