提交 9ce3ed2a 编写于 作者: M Matt Caswell

Add tests for new extension code

Extend test_tls13messages to additionally check the expected extensions
under different options given to s_client/s_server.

Perl changes reviewed by Richard Levitte. Non-perl changes reviewed by Rich
Salz
Reviewed-by: NRich Salz <rsalz@openssl.org>
Reviewed-by: NRichard Levitte <levitte@openssl.org>
上级 3434f40b
......@@ -27,6 +27,7 @@ plan skip_all => "$test_name needs TLSv1.3 enabled"
if disabled("tls1_3");
$ENV{OPENSSL_ia32cap} = '~0x200000200000000';
$ENV{CTLOG_FILE} = srctop_file("test", "ct", "log_list.conf");
use constant {
DEFAULT_HANDSHAKE => 1,
......@@ -36,6 +37,17 @@ use constant {
ALL_HANDSHAKES => 15
};
use constant {
DEFAULT_EXTENSIONS => 0x00000001,
SERVER_NAME_CLI_EXTENSION => 0x00000002,
SERVER_NAME_SRV_EXTENSION => 0x00000004,
STATUS_REQUEST_CLI_EXTENSION => 0x00000008,
STATUS_REQUEST_SRV_EXTENSION => 0x00000010,
ALPN_CLI_EXTENSION => 0x00000020,
ALPN_SRV_EXTENSION => 0x00000040,
SCT_CLI_EXTENSION => 0x00000080
};
my @handmessages = (
[TLSProxy::Message::MT_CLIENT_HELLO, ALL_HANDSHAKES],
[TLSProxy::Message::MT_SERVER_HELLO, ALL_HANDSHAKES],
......@@ -50,6 +62,28 @@ my @handmessages = (
[0, 0]
);
my @extensions = (
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME, SERVER_NAME_CLI_EXTENSION],
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST, STATUS_REQUEST_CLI_EXTENSION],
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS, DEFAULT_EXTENSIONS],
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS, DEFAULT_EXTENSIONS],
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS, DEFAULT_EXTENSIONS],
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN, ALPN_CLI_EXTENSION],
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT, SCT_CLI_EXTENSION],
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC, DEFAULT_EXTENSIONS],
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET, DEFAULT_EXTENSIONS],
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET, DEFAULT_EXTENSIONS],
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE, DEFAULT_EXTENSIONS],
[TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, DEFAULT_EXTENSIONS],
[TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE, DEFAULT_EXTENSIONS],
[TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_SERVER_NAME, SERVER_NAME_SRV_EXTENSION],
[TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_STATUS_REQUEST, STATUS_REQUEST_SRV_EXTENSION],
[TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_ALPN, ALPN_SRV_EXTENSION],
[0,0,0]
);
my $proxy = TLSProxy::Proxy->new(
undef,
cmdstr(app(["openssl"]), display => 1),
......@@ -57,15 +91,15 @@ my $proxy = TLSProxy::Proxy->new(
(!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
);
sub checkmessages($$);
sub checkmessages($$$);
#Test 1: Check we get all the right messages for a default handshake
(undef, my $session) = tempfile();
#$proxy->serverconnects(2);
$proxy->clientflags("-sess_out ".$session);
$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
plan tests => 3;
checkmessages(DEFAULT_HANDSHAKE, "Default handshake test");
plan tests => 12;
checkmessages(DEFAULT_HANDSHAKE, DEFAULT_EXTENSIONS, "Default handshake test");
#TODO(TLS1.3): Test temporarily disabled until we implement TLS1.3 resumption
#Test 2: Resumption handshake
......@@ -75,7 +109,23 @@ checkmessages(DEFAULT_HANDSHAKE, "Default handshake test");
#checkmessages(RESUME_HANDSHAKE, "Resumption handshake test");
unlink $session;
#Test 3: A default handshake, but with a CertificateStatus message
#Test 3: A status_request handshake (client request only)
$proxy->clear();
$proxy->clientflags("-status");
$proxy->start();
checkmessages(DEFAULT_HANDSHAKE,
DEFAULT_EXTENSIONS | STATUS_REQUEST_CLI_EXTENSION,
"status_request handshake test (client)");
#Test 4: A status_request handshake (server support only)
$proxy->clear();
$proxy->serverflags("-status_file "
.srctop_file("test", "recipes", "ocsp-response.der"));
$proxy->start();
checkmessages(DEFAULT_HANDSHAKE, DEFAULT_EXTENSIONS,
"status_request handshake test (server)");
#Test 5: A status_request handshake (client and server)
#TODO(TLS1.3): TLS1.3 doesn't actually have CertificateStatus messages. This is
#a temporary test until such time as we do proper TLS1.3 style certificate
#status
......@@ -84,28 +134,102 @@ $proxy->clientflags("-status");
$proxy->serverflags("-status_file "
.srctop_file("test", "recipes", "ocsp-response.der"));
$proxy->start();
checkmessages(OCSP_HANDSHAKE, "OCSP handshake test");
checkmessages(OCSP_HANDSHAKE,
DEFAULT_EXTENSIONS | STATUS_REQUEST_CLI_EXTENSION
| STATUS_REQUEST_SRV_EXTENSION,
"status_request handshake test");
#Test 4: A client auth handshake
#Test 6: A client auth handshake
$proxy->clear();
$proxy->clientflags("-cert ".srctop_file("apps", "server.pem"));
$proxy->serverflags("-Verify 5");
$proxy->start();
checkmessages(CLIENT_AUTH_HANDSHAKE, "Client auth handshake test");
checkmessages(CLIENT_AUTH_HANDSHAKE, DEFAULT_EXTENSIONS,
"Client auth handshake test");
sub checkmessages($$)
#Test 7: Server name handshake (client request only)
$proxy->clear();
$proxy->clientflags("-servername testhost");
$proxy->start();
checkmessages(DEFAULT_HANDSHAKE, DEFAULT_EXTENSIONS | SERVER_NAME_CLI_EXTENSION,
"Server name handshake test (client)");
#Test 8: Server name handshake (server support only)
$proxy->clear();
$proxy->serverflags("-servername testhost");
$proxy->start();
checkmessages(DEFAULT_HANDSHAKE, DEFAULT_EXTENSIONS,
"Server name handshake test (server)");
#Test 9: Server name handshake (client and server)
$proxy->clear();
$proxy->clientflags("-servername testhost");
$proxy->serverflags("-servername testhost");
$proxy->start();
checkmessages(DEFAULT_HANDSHAKE,
DEFAULT_EXTENSIONS | SERVER_NAME_CLI_EXTENSION
| SERVER_NAME_SRV_EXTENSION,
"Server name handshake test");
#Test 10: ALPN handshake (client request only)
$proxy->clear();
$proxy->clientflags("-alpn test");
$proxy->start();
checkmessages(DEFAULT_HANDSHAKE, DEFAULT_EXTENSIONS | ALPN_CLI_EXTENSION,
"ALPN handshake test (client)");
#Test 11: ALPN handshake (server support only)
$proxy->clear();
$proxy->serverflags("-alpn test");
$proxy->start();
checkmessages(DEFAULT_HANDSHAKE, DEFAULT_EXTENSIONS,
"ALPN handshake test (server)");
#Test 12: ALPN handshake (client and server)
$proxy->clear();
$proxy->clientflags("-alpn test");
$proxy->serverflags("-alpn test");
$proxy->start();
checkmessages(DEFAULT_HANDSHAKE,
DEFAULT_EXTENSIONS | ALPN_CLI_EXTENSION | ALPN_SRV_EXTENSION,
"ALPN handshake test");
#Test 13: SCT handshake (client request only)
#TODO(TLS1.3): This only checks that the client side extension appears. The
#SCT extension is unusual in that we have no built-in server side implementation
#The server side implementation can nomrally be added using the custom
#extensions framework (e.g. by using the "-serverinfo" s_server option). However
#currently we only support <= TLS1.2 for custom extensions because the existing
#framework and API has no knowledge of the TLS1.3 messages
$proxy->clear();
#Note: -ct also sends status_request
$proxy->clientflags("-ct");
$proxy->serverflags("-status_file "
.srctop_file("test", "recipes", "ocsp-response.der"));
$proxy->start();
checkmessages(OCSP_HANDSHAKE,
DEFAULT_EXTENSIONS | SCT_CLI_EXTENSION
| STATUS_REQUEST_CLI_EXTENSION | STATUS_REQUEST_SRV_EXTENSION,
"SCT handshake test");
sub checkmessages($$$)
{
my ($handtype, $testname) = @_;
my ($handtype, $exttype, $testname) = @_;
subtest $testname => sub {
my $loop = 0;
my $numtests;
my $extcount;
#First count the number of tests
for ($numtests = 1; $handmessages[$loop][1] != 0; $loop++) {
$numtests++ if (($handmessages[$loop][1] & $handtype) != 0);
}
#Add number of extensions we check plus 3 for the number of messages
#that contain extensions
$numtests += $#extensions + 3;
plan tests => $numtests;
$loop = 0;
......@@ -119,6 +243,27 @@ sub checkmessages($$)
"Message type check. Got ".$message->mt
.", expected ".$handmessages[$loop][0]);
$loop++;
next if ($message->mt() != TLSProxy::Message::MT_CLIENT_HELLO
&& $message->mt() != TLSProxy::Message::MT_SERVER_HELLO
&& $message->mt() !=
TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS);
#Now check that we saw the extensions we expected
my $msgexts = $message->extension_data();
for (my $extloop = 0, $extcount = 0; $extensions[$extloop][2] != 0;
$extloop++) {
next if ($message->mt() != $extensions[$extloop][0]);
ok (($extensions[$extloop][2] & $exttype) == 0
|| defined ($msgexts->{$extensions[$extloop][1]}),
"Extension presence check (Message: ".$message->mt()
." Extension: ".($extensions[$extloop][2] & $exttype).", "
.$extloop.")");
$extcount++ if (($extensions[$extloop][2] & $exttype) != 0);
}
ok($extcount == keys %$msgexts, "Extensions count mismatch ("
.$extcount.", ".(keys %$msgexts)
.")");
}
ok($handmessages[$loop][1] == 0, "All expected messages processed");
}
......
# Copyright 2016 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;
package TLSProxy::EncryptedExtensions;
use vars '@ISA';
push @ISA, 'TLSProxy::Message';
sub new
{
my $class = shift;
my ($server,
$data,
$records,
$startoffset,
$message_frag_lens) = @_;
my $self = $class->SUPER::new(
$server,
TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS,
$data,
$records,
$startoffset,
$message_frag_lens);
$self->{extension_data} = "";
return $self;
}
sub parse
{
my $self = shift;
my $extensions_len = unpack('n', $self->data);
if (!defined $extensions_len) {
$extensions_len = 0;
}
my $extension_data;
if ($extensions_len != 0) {
$extension_data = substr($self->data, 2);
if (length($extension_data) != $extensions_len) {
die "Invalid extension length\n";
}
} else {
if (length($self->data) != 2) {
die "Invalid extension length\n";
}
$extension_data = "";
}
my %extensions = ();
while (length($extension_data) >= 4) {
my ($type, $size) = unpack("nn", $extension_data);
my $extdata = substr($extension_data, 4, $size);
$extension_data = substr($extension_data, 4 + $size);
$extensions{$type} = $extdata;
}
$self->extension_data(\%extensions);
print " Extensions Len:".$extensions_len."\n";
}
#Reconstruct the on-the-wire message data following changes
sub set_message_contents
{
my $self = shift;
my $data;
my $extensions = "";
foreach my $key (keys %{$self->extension_data}) {
my $extdata = ${$self->extension_data}{$key};
$extensions .= pack("n", $key);
$extensions .= pack("n", length($extdata));
$extensions .= $extdata;
if ($key == TLSProxy::Message::EXT_DUPLICATE_EXTENSION) {
$extensions .= pack("n", $key);
$extensions .= pack("n", length($extdata));
$extensions .= $extdata;
}
}
$data = pack('n', length($extensions));
$data .= $extensions;
$self->data($data);
}
#Read/write accessors
sub extension_data
{
my $self = shift;
if (@_) {
$self->{extension_data} = shift;
}
return $self->{extension_data};
}
sub set_extension
{
my ($self, $ext_type, $ext_data) = @_;
$self->{extension_data}{$ext_type} = $ext_data;
}
sub delete_extension
{
my ($self, $ext_type) = @_;
delete $self->{extension_data}{$ext_type};
}
1;
......@@ -60,13 +60,23 @@ my %message_type = (
);
use constant {
EXT_SERVER_NAME => 0,
EXT_STATUS_REQUEST => 5,
EXT_SUPPORTED_GROUPS => 10,
EXT_EC_POINT_FORMATS => 11,
EXT_SRP => 12,
EXT_SIG_ALGS => 13,
EXT_USE_SRTP => 14,
EXT_ALPN => 16,
EXT_SCT => 18,
EXT_PADDING => 21,
EXT_ENCRYPT_THEN_MAC => 22,
EXT_EXTENDED_MASTER_SECRET => 23,
EXT_SESSION_TICKET => 35,
EXT_SUPPORTED_VERSIONS => 43,
EXT_KEY_SHARE => 40,
EXT_SUPPORTED_VERSIONS => 43,
EXT_RENEGOTIATE => 65281,
EXT_NPN => 13172,
# This extension is an unofficial extension only ever written by OpenSSL
# (i.e. not read), and even then only when enabled. We use it to test
# handling of duplicate extensions.
......@@ -245,6 +255,15 @@ sub create_message
[@message_frag_lens]
);
$message->parse();
} elsif ($mt == MT_ENCRYPTED_EXTENSIONS) {
$message = TLSProxy::EncryptedExtensions->new(
$server,
$data,
[@message_rec_list],
$startoffset,
[@message_frag_lens]
);
$message->parse();
} elsif ($mt == MT_SERVER_KEY_EXCHANGE) {
$message = TLSProxy::ServerKeyExchange->new(
$server,
......
......@@ -17,6 +17,7 @@ use TLSProxy::Record;
use TLSProxy::Message;
use TLSProxy::ClientHello;
use TLSProxy::ServerHello;
use TLSProxy::EncryptedExtensions;
use TLSProxy::ServerKeyExchange;
use TLSProxy::NewSessionTicket;
......@@ -153,7 +154,8 @@ sub start
my $execcmd = $self->execute
." s_server -no_comp -rev -engine ossltest -accept "
.($self->server_port)
." -cert ".$self->cert." -naccept ".$self->serverconnects;
." -cert ".$self->cert." -cert2 ".$self->cert
." -naccept ".$self->serverconnects;
if ($self->ciphers ne "") {
$execcmd .= " -cipher ".$self->ciphers;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册