Skip to content

Commit

Permalink
Fix SNI tests for LibreSSL
Browse files Browse the repository at this point in the history
Since beginning of 2022, LibreSSL dropped support for IP addresses in
SNI. This is aligned to RFC 6066, section 3:

> Literal IPv4 and IPv6 addresses are not permitted in "HostName".

In order to deal with it, clients connect to "localhost" instead of
"127.0.0.1" and adjust "server.crt" to use "localhost" as Common Name
instead of "127.0.0.1".

Adjust TLS version for LibreSSL deprecation of TLSv1.1 and older.
  • Loading branch information
lgv5 committed Dec 30, 2023
1 parent 7a1cd71 commit 044e4d5
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 58 deletions.
14 changes: 7 additions & 7 deletions t/mojo/certs/server.crt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
-----BEGIN CERTIFICATE-----
MIIBsjCCARsCCQCptEBZlSnk3jANBgkqhkiG9w0BAQUFADAaMQswCQYDVQQGEwJV
UzELMAkGA1UEAxMCY2EwHhcNMTQxMjEyMDUwMzI1WhcNMzQxMjA3MDUwMzI1WjAh
MQswCQYDVQQGEwJVUzESMBAGA1UEAxMJMTI3LjAuMC4xMIGfMA0GCSqGSIb3DQEB
MIIBsjCCARsCCQCM8WLoRPCPATANBgkqhkiG9w0BAQsFADAaMQswCQYDVQQGEwJV
UzELMAkGA1UEAxMCY2EwHhcNMjMwMjI1MTc1NjAwWhcNNDMwMjIwMTc1NjAwWjAh
MQswCQYDVQQGEwJVUzESMBAGA1UEAwwJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEB
AQUAA4GNADCBiQKBgQDDhbj7nsfzahPilwn6pGdo6nKYCR21WZ73CuwPN86DmsZi
5LIRYRfKA0unape2BQBnMnSmInaXvHHBdVsTyt3XSFZj5+iCF9RcorXAqcDygScj
8MTWYAZxCu3lGAjtw0bGGYutlLg5jtEXvZwfe61XfJj9xDUPNQrP7mf/HTBmgQID
AQABMA0GCSqGSIb3DQEBBQUAA4GBACRIx9fB4x8UO44C9TGj3bKb1NX3bkuHMz0m
WdhCkzUUiANtRMxp2oLA3KHY4yOusZLZIUNyP10Ri5q/U1mR0poYCMm7AYee2OV7
NdQIyppeDLoWQ9uPISPjp1d+zjpGOrLrSkpD1rYLVw4R56A9ZQks/LNs6TSceZjZ
c5QST/9i
AQABMA0GCSqGSIb3DQEBCwUAA4GBABjuNiXMWmGIr4LU7hypd4QKFZDfHyFFw21h
dRhFp4cBq+A/9cDW7CBmKuVvBwYtkLSzQf0Y2/55mx1hz85NjRiSdDENWLncW8sA
qt0mS9eX6s9HMeYNcT9ngPoAAUmkGT3/tAXwmejvu2XKBt8UBcnpJdt40YYq1wIH
9lcg5Hni
-----END CERTIFICATE-----
6 changes: 3 additions & 3 deletions t/mojo/daemon_ipv6_tls.t
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ subtest 'IPv6, TLS, SNI and a proxy' => sub {
$daemon = Mojo::Server::Daemon->new(app => app, silent => 1);
my $listen
= 'https://[::1]'
. '?127.0.0.1_cert=t/mojo/certs/server.crt'
. '&127.0.0.1_key=t/mojo/certs/server.key'
. '?localhost_cert=t/mojo/certs/server.crt'
. '&localhost_key=t/mojo/certs/server.key'
. '&example.com_cert=t/mojo/certs/domain.crt'
. '&example.com_key=t/mojo/certs/domain.key';
my $forward = $daemon->listen([$listen])->start->ports->[0];
Expand All @@ -54,7 +54,7 @@ subtest 'IPv6, TLS, SNI and a proxy' => sub {
is $tx->res->code, 200, 'right status';
is $tx->res->body, 'works!', 'right content';
ok !$tx->error, 'no error';
$tx = $ua->get("https://127.0.0.1/");
$tx = $ua->get("https://localhost/");
is $tx->res->code, 200, 'right status';
is $tx->res->body, 'works!', 'right content';
ok !$tx->error, 'no error';
Expand Down
30 changes: 19 additions & 11 deletions t/mojo/ioloop_tls.t
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ plan skip_all => 'IO::Socket::SSL 2.009+ required for this test!' unless Moj
# openssl req -x509 -days 7300 -key ca.key -in ca.csr -out ca.crt
#
# openssl genrsa -out server.key 1024
# openssl req -new -key server.key -out server.csr -subj "/C=US/CN=127.0.0.1"
# openssl req -new -key server.key -out server.csr -subj "/C=US/CN=localhost"
# openssl x509 -req -days 7300 -in server.csr -out server.crt -CA ca.crt \
# -CAkey ca.key -CAcreateserial
#
Expand Down Expand Up @@ -46,7 +46,7 @@ my $id = $loop->server(
my $port = $loop->acceptor($id)->port;
my $promise2 = Mojo::Promise->new->ioloop($loop);
$loop->client(
{port => $port, tls => 1, tls_options => {SSL_verify_mode => 0x00}} => sub {
{address => 'localhost', port => $port, tls => 1, tls_options => {SSL_verify_mode => 0x00}} => sub {
my ($loop, $err, $stream) = @_;
$stream->write('tset' => sub { shift->write('123') });
$stream->on(close => sub { $promise2->resolve });
Expand Down Expand Up @@ -88,6 +88,7 @@ $id = Mojo::IOLoop->server(
$port = Mojo::IOLoop->acceptor($id)->port;
$promise2 = Mojo::Promise->new;
Mojo::IOLoop->client(
address => 'localhost',
port => $port,
tls => 1,
tls_cert => 't/mojo/certs/client.crt',
Expand Down Expand Up @@ -118,6 +119,7 @@ ok !$server_err, 'no error';
# Invalid client certificate
my $client_err;
Mojo::IOLoop->client(
address => 'localhost',
port => $port,
tls => 1,
tls_cert => 't/mojo/certs/bad.crt',
Expand All @@ -133,7 +135,7 @@ ok $client_err, 'has error';
# Missing client certificate
($server_err, $client_err) = ();
Mojo::IOLoop->client(
{port => $port, tls => 1} => sub {
{address => 'localhost', port => $port, tls => 1} => sub {
shift->stop;
$client_err = shift;
}
Expand All @@ -155,6 +157,7 @@ $id = $loop->server(
);
$port = $loop->acceptor($id)->port;
$loop->client(
address => 'localhost',
port => $port,
tls => 1,
tls_cert => 't/mojo/certs/client.crt',
Expand Down Expand Up @@ -195,6 +198,7 @@ $id = Mojo::IOLoop->server(
$port = Mojo::IOLoop->acceptor($id)->port;
$promise2 = Mojo::Promise->new;
Mojo::IOLoop->client(
address => 'localhost',
port => $port,
tls => 1,
tls_ca => 't/mojo/certs/ca.crt',
Expand Down Expand Up @@ -235,9 +239,10 @@ $id = $loop->server(
);
$port = $loop->acceptor($id)->port;
$loop->client(
port => $port,
tls => 1,
tls_ca => 't/mojo/certs/ca.crt',
address => 'localhost',
port => $port,
tls => 1,
tls_ca => 't/mojo/certs/ca.crt',
sub {
shift->stop;
$client_err = shift;
Expand All @@ -259,7 +264,7 @@ $id = $loop->server(
);
$port = $loop->acceptor($id)->port;
$loop->client(
address => '127.0.0.1',
address => 'localhost',
port => $port,
tls => 1,
tls_ca => 't/mojo/certs/ca.crt',
Expand All @@ -284,9 +289,10 @@ $id = $loop->server(
);
$port = $loop->acceptor($id)->port;
$loop->client(
port => $port,
tls => 1,
tls_ca => 'no cert',
address => 'localhost',
port => $port,
tls => 1,
tls_ca => 'no cert',
sub {
shift->stop;
$client_err = shift;
Expand Down Expand Up @@ -315,6 +321,7 @@ $id = $loop->server(
);
$port = $loop->acceptor($id)->port;
$loop->client(
address => 'localhost',
port => $port,
tls => 1,
tls_cert => 't/mojo/certs/bad.crt',
Expand Down Expand Up @@ -350,7 +357,7 @@ $id = Mojo::IOLoop->server(
);
$port = Mojo::IOLoop->acceptor($id)->port;
Mojo::IOLoop->client(
{port => $port, tls => 1, tls_options => {SSL_verify_mode => 0x00}} => sub {
{address => 'localhost', port => $port, tls => 1, tls_options => {SSL_verify_mode => 0x00}} => sub {
shift->stop;
$client = 'connected';
$client_err = shift;
Expand All @@ -376,6 +383,7 @@ subtest 'ALPN' => sub {
);
$port = Mojo::IOLoop->acceptor($id)->port;
Mojo::IOLoop->client(
address => 'localhost',
port => $port,
tls => 1,
tls_options => {SSL_alpn_protocols => ['baz', 'bar'], SSL_verify_mode => 0x00},
Expand Down
41 changes: 23 additions & 18 deletions t/mojo/user_agent_tls.t
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@ subtest 'Web server with valid certificates' => sub {

subtest 'No certificate' => sub {
my $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
my $tx = $ua->get("https://127.0.0.1:$port");
my $tx = $ua->get("https://localhost:$port");
ok $tx->error, 'has error';
$tx = $ua->get("https://127.0.0.1:$port");
$tx = $ua->get("https://localhost:$port");
ok $tx->error, 'has error';
$tx = $ua->ca('t/mojo/certs/ca.crt')->get("https://127.0.0.1:$port");
$tx = $ua->ca('t/mojo/certs/ca.crt')->get("https://localhost:$port");
ok $tx->error, 'has error';
$tx = $ua->get("https://127.0.0.1:$port");
$tx = $ua->get("https://localhost:$port");
ok $tx->error, 'has error';
};

subtest 'Valid certificates' => sub {
my $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
$ua->ca('t/mojo/certs/ca.crt')->cert('t/mojo/certs/client.crt')->key('t/mojo/certs/client.key');
my $tx = $ua->get("https://127.0.0.1:$port");
my $tx = $ua->get("https://localhost:$port");
ok !$tx->error, 'no error';
is $tx->res->code, 200, 'right status';
is $tx->res->body, 'works!', 'right content';
Expand All @@ -54,7 +54,7 @@ subtest 'Web server with valid certificates' => sub {
local $ENV{MOJO_CERT_FILE} = 't/mojo/certs/client.crt';
local $ENV{MOJO_KEY_FILE} = 't/mojo/certs/client.key';
local $ENV{MOJO_INSECURE} = 0;
my $tx = $ua->get("https://127.0.0.1:$port");
my $tx = $ua->get("https://localhost:$port");
is $ua->ca, 't/mojo/certs/ca.crt', 'right path';
is $ua->cert, 't/mojo/certs/client.crt', 'right path';
is $ua->key, 't/mojo/certs/client.key', 'right path';
Expand All @@ -67,7 +67,7 @@ subtest 'Web server with valid certificates' => sub {
subtest 'Invalid certificate' => sub {
my $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
$ua->cert('t/mojo/certs/bad.crt')->key('t/mojo/certs/bad.key');
my $tx = $ua->get("https://127.0.0.1:$port");
my $tx = $ua->get("https://localhost:$port");
ok $tx->error, 'has error';
};
};
Expand All @@ -82,43 +82,48 @@ subtest 'Web server with valid certificates and no verification' => sub {
. '&ca=t/mojo/certs/ca.crt'
. '&ciphers=AES256-SHA:ALL'
. '&verify=0x00'
. '&version=TLSv1';
. '&version=TLSv1_2';
my $port = $daemon->listen([$listen])->start->ports->[0];

# Invalid certificate
my $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
$ua->cert('t/mojo/certs/bad.crt')->key('t/mojo/certs/bad.key');
my $tx = $ua->get("https://127.0.0.1:$port");
my $tx = $ua->get("https://localhost:$port");
ok $tx->error, 'has error';
$ua = Mojo::UserAgent->new(ioloop => $ua->ioloop, insecure => 1);
$ua->cert('t/mojo/certs/bad.crt')->key('t/mojo/certs/bad.key');
$tx = $ua->get("https://127.0.0.1:$port");
$tx = $ua->get("https://localhost:$port");
ok !$tx->error, 'no error';
is $ua->ioloop->stream($tx->connection)->handle->get_cipher, 'AES256-SHA', 'AES256-SHA has been negotiatied';
is $ua->ioloop->stream($tx->connection)->handle->get_sslversion, 'TLSv1', 'TLSv1 has been negotiatied';
is $ua->ioloop->stream($tx->connection)->handle->get_sslversion, 'TLSv1_2', 'TLSv1.2 has been negotiatied';
};

subtest 'Client side TLS options' => sub {
my $daemon = Mojo::Server::Daemon->new(app => app, ioloop => Mojo::IOLoop->singleton, silent => 1);
my $listen = 'https://127.0.0.1/?version=TLSv1_1';
my $port = $daemon->listen([$listen])->start->ports->[0];
my $listen
= 'https://127.0.0.1'
. '?cert=t/mojo/certs/server.crt'
. '&key=t/mojo/certs/server.key'
. '&ca=t/mojo/certs/ca.crt'
. '&version=TLSv1_2';
my $port = $daemon->listen([$listen])->start->ports->[0];

subtest '(Not) setting verification mode' => sub {
my $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
my $tx = $ua->get("https://127.0.0.1:$port");
my $tx = $ua->get("https://localhost:$port");
like $tx->error->{message}, qr/certificate verify failed/, 'has error';

$ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
$ua->tls_options({SSL_verify_mode => 0x00});
$tx = $ua->get("https://127.0.0.1:$port");
$tx = $ua->get("https://localhost:$port");
ok !$tx->error, 'no error';
};

subtest 'Setting acceptable protocol version' => sub {
my $ua = Mojo::UserAgent->new(ioloop => Mojo::IOLoop->singleton);
$ua->tls_options({SSL_version => 'TLSv1_2'});
my $tx = $ua->get("https://127.0.0.1:$port");
like $tx->error->{message}, qr/wrong ssl version/, 'has error';
$ua->tls_options({SSL_version => 'TLSv1_3'});
my $tx = $ua->get("https://localhost:$port");
like $tx->error->{message}, qr/tlsv1 alert protocol version/, 'has error';
};
};

Expand Down
Loading

0 comments on commit 044e4d5

Please sign in to comment.