mirror of
https://github.com/openssl/openssl.git
synced 2024-12-09 05:51:54 +08:00
c4220c0f9a
This fixes only those tests that were failing when network data was fragmented. Remaining ones might succeed for "wrong reasons". Bunch of tests have to fail to be considered successful and when data is fragmented they might fail for reasons other than originally intended. Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/5975)
237 lines
7.1 KiB
Perl
237 lines
7.1 KiB
Perl
#! /usr/bin/env perl
|
|
# Copyright 2015-2018 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
|
|
|
|
use strict;
|
|
use feature 'state';
|
|
|
|
use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/;
|
|
use OpenSSL::Test::Utils;
|
|
use TLSProxy::Proxy;
|
|
|
|
my $test_name = "test_sslextension";
|
|
setup($test_name);
|
|
|
|
plan skip_all => "TLSProxy isn't usable on $^O"
|
|
if $^O =~ /^(VMS)$/;
|
|
|
|
plan skip_all => "$test_name needs the dynamic engine feature enabled"
|
|
if disabled("engine") || disabled("dynamic-engine");
|
|
|
|
plan skip_all => "$test_name needs the sock feature enabled"
|
|
if disabled("sock");
|
|
|
|
plan skip_all => "$test_name needs TLS enabled"
|
|
if alldisabled(available_protocols("tls"));
|
|
|
|
my $no_below_tls13 = alldisabled(("tls1", "tls1_1", "tls1_2"))
|
|
|| (!disabled("tls1_3") && disabled("tls1_2"));
|
|
|
|
use constant {
|
|
UNSOLICITED_SERVER_NAME => 0,
|
|
UNSOLICITED_SERVER_NAME_TLS13 => 1,
|
|
UNSOLICITED_SCT => 2,
|
|
NONCOMPLIANT_SUPPORTED_GROUPS => 3
|
|
};
|
|
|
|
my $testtype;
|
|
my $fatal_alert = 0; # set by filter on fatal alert
|
|
|
|
$ENV{OPENSSL_ia32cap} = '~0x200000200000000';
|
|
my $proxy = TLSProxy::Proxy->new(
|
|
\&inject_duplicate_extension_clienthello,
|
|
cmdstr(app(["openssl"]), display => 1),
|
|
srctop_file("apps", "server.pem"),
|
|
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
|
|
);
|
|
|
|
|
|
sub extension_filter
|
|
{
|
|
my $proxy = shift;
|
|
|
|
if ($proxy->flight == 1) {
|
|
# Change the ServerRandom so that the downgrade sentinel doesn't cause
|
|
# the connection to fail
|
|
my $message = ${$proxy->message_list}[1];
|
|
$message->random("\0"x32);
|
|
$message->repack();
|
|
return;
|
|
}
|
|
|
|
# We're only interested in the initial ClientHello
|
|
if ($proxy->flight != 0) {
|
|
return;
|
|
}
|
|
|
|
foreach my $message (@{$proxy->message_list}) {
|
|
if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) {
|
|
# Remove all extensions and set the extension len to zero
|
|
$message->extension_data({});
|
|
$message->extensions_len(0);
|
|
# Extensions have been removed so make sure we don't try to use them
|
|
$message->process_extensions();
|
|
|
|
$message->repack();
|
|
}
|
|
}
|
|
}
|
|
|
|
sub inject_duplicate_extension
|
|
{
|
|
my ($proxy, $message_type) = @_;
|
|
|
|
foreach my $message (@{$proxy->message_list}) {
|
|
if ($message->mt == $message_type) {
|
|
my %extensions = %{$message->extension_data};
|
|
# Add a duplicate (unknown) extension.
|
|
$message->set_extension(TLSProxy::Message::EXT_DUPLICATE_EXTENSION, "");
|
|
$message->set_extension(TLSProxy::Message::EXT_DUPLICATE_EXTENSION, "");
|
|
$message->repack();
|
|
}
|
|
}
|
|
}
|
|
|
|
sub inject_duplicate_extension_clienthello
|
|
{
|
|
my $proxy = shift;
|
|
|
|
# We're only interested in the initial ClientHello
|
|
if ($proxy->flight == 0) {
|
|
inject_duplicate_extension($proxy, TLSProxy::Message::MT_CLIENT_HELLO);
|
|
return;
|
|
}
|
|
|
|
my $last_record = @{$proxy->{record_list}}[-1];
|
|
$fatal_alert = 1 if $last_record->is_fatal_alert(1);
|
|
}
|
|
|
|
sub inject_duplicate_extension_serverhello
|
|
{
|
|
my $proxy = shift;
|
|
|
|
# We're only interested in the initial ServerHello
|
|
if ($proxy->flight == 0) {
|
|
return;
|
|
} elsif ($proxy->flight == 1) {
|
|
inject_duplicate_extension($proxy, TLSProxy::Message::MT_SERVER_HELLO);
|
|
return;
|
|
}
|
|
|
|
my $last_record = @{$proxy->{record_list}}[-1];
|
|
$fatal_alert = 1 if $last_record->is_fatal_alert(0);
|
|
}
|
|
|
|
sub inject_unsolicited_extension
|
|
{
|
|
my $proxy = shift;
|
|
my $message;
|
|
state $sent_unsolisited_extension;
|
|
|
|
if ($proxy->flight == 0) {
|
|
$sent_unsolisited_extension = 0;
|
|
return;
|
|
}
|
|
|
|
# We're only interested in the initial ServerHello/EncryptedExtensions
|
|
if ($proxy->flight != 1) {
|
|
if ($sent_unsolisited_extension) {
|
|
my $last_record = @{$proxy->record_list}[-1];
|
|
$fatal_alert = 1 if $last_record->is_fatal_alert(0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if ($testtype == UNSOLICITED_SERVER_NAME_TLS13) {
|
|
return if (!defined($message = ${$proxy->message_list}[2]));
|
|
die "Expecting EE message ".($message->mt).","
|
|
.${$proxy->message_list}[1]->mt.", "
|
|
.${$proxy->message_list}[3]->mt
|
|
if $message->mt != TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS;
|
|
} else {
|
|
$message = ${$proxy->message_list}[1];
|
|
}
|
|
|
|
my $ext = pack "C2",
|
|
0x00, 0x00; #Extension length
|
|
|
|
my $type;
|
|
if ($testtype == UNSOLICITED_SERVER_NAME
|
|
|| $testtype == UNSOLICITED_SERVER_NAME_TLS13) {
|
|
$type = TLSProxy::Message::EXT_SERVER_NAME;
|
|
} elsif ($testtype == UNSOLICITED_SCT) {
|
|
$type = TLSProxy::Message::EXT_SCT;
|
|
} elsif ($testtype == NONCOMPLIANT_SUPPORTED_GROUPS) {
|
|
$type = TLSProxy::Message::EXT_SUPPORTED_GROUPS;
|
|
}
|
|
$message->set_extension($type, $ext);
|
|
$message->repack();
|
|
$sent_unsolisited_extension = 1;
|
|
}
|
|
|
|
# Test 1-2: Sending a duplicate extension should fail.
|
|
$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
|
|
plan tests => 7;
|
|
ok($fatal_alert, "Duplicate ClientHello extension");
|
|
|
|
$fatal_alert = 0;
|
|
$proxy->clear();
|
|
$proxy->filter(\&inject_duplicate_extension_serverhello);
|
|
$proxy->start();
|
|
ok($fatal_alert, "Duplicate ServerHello extension");
|
|
|
|
SKIP: {
|
|
skip "TLS <= 1.2 disabled", 3 if $no_below_tls13;
|
|
|
|
#Test 3: Sending a zero length extension block should pass
|
|
$proxy->clear();
|
|
$proxy->filter(\&extension_filter);
|
|
$proxy->start();
|
|
ok(TLSProxy::Message->success, "Zero extension length test");
|
|
|
|
#Test 4: Inject an unsolicited extension (<= TLSv1.2)
|
|
$fatal_alert = 0;
|
|
$proxy->clear();
|
|
$proxy->filter(\&inject_unsolicited_extension);
|
|
$testtype = UNSOLICITED_SERVER_NAME;
|
|
$proxy->clientflags("-no_tls1_3 -noservername");
|
|
$proxy->start();
|
|
ok($fatal_alert, "Unsolicited server name extension");
|
|
|
|
#Test 5: Inject a noncompliant supported_groups extension (<= TLSv1.2)
|
|
$proxy->clear();
|
|
$proxy->filter(\&inject_unsolicited_extension);
|
|
$testtype = NONCOMPLIANT_SUPPORTED_GROUPS;
|
|
$proxy->clientflags("-no_tls1_3");
|
|
$proxy->start();
|
|
ok(TLSProxy::Message->success(), "Noncompliant supported_groups extension");
|
|
}
|
|
|
|
SKIP: {
|
|
skip "TLS <= 1.2 or CT disabled", 1
|
|
if $no_below_tls13 || disabled("ct");
|
|
#Test 6: Same as above for the SCT extension which has special handling
|
|
$fatal_alert = 0;
|
|
$proxy->clear();
|
|
$testtype = UNSOLICITED_SCT;
|
|
$proxy->clientflags("-no_tls1_3");
|
|
$proxy->start();
|
|
ok($fatal_alert, "Unsolicited sct extension");
|
|
}
|
|
|
|
SKIP: {
|
|
skip "TLS 1.3 disabled", 1 if disabled("tls1_3");
|
|
#Test 7: Inject an unsolicited extension (TLSv1.3)
|
|
$fatal_alert = 0;
|
|
$proxy->clear();
|
|
$proxy->filter(\&inject_unsolicited_extension);
|
|
$testtype = UNSOLICITED_SERVER_NAME_TLS13;
|
|
$proxy->clientflags("-noservername");
|
|
$proxy->start();
|
|
ok($fatal_alert, "Unsolicited server name extension (TLSv1.3)");
|
|
}
|