diff options
-rw-r--r-- | ssl/record/ssl3_record.c | 27 | ||||
-rw-r--r-- | test/recipes/80-test_ssl_old.t | 22 | ||||
-rw-r--r-- | test/ssl_old_test.c | 11 |
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; |