Skip to content

Commit 4ae3078

Browse files
committed
Tests: IP identifier support tests.
1 parent 2d15d8b commit 4ae3078

File tree

4 files changed

+353
-0
lines changed

4 files changed

+353
-0
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ jobs:
127127
- uses: perl-actions/install-with-cpm@8b1a9840b26cc3885ae2889749a48629be2501b0 # v1.9
128128
with:
129129
install: |
130+
IO::Socket::INET6
130131
IO::Socket::SSL
131132
TimeDate
132133

.github/workflows/sanitizers.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ env:
1818
make openssl patch which
1919
perl-Digest-SHA
2020
perl-FindBin
21+
perl-IO-Socket-INET6
2122
perl-IO-Socket-SSL
2223
perl-Test-Harness
2324
perl-Test-Simple

t/acme_ipv4_identifier.t

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#!/usr/bin/perl
2+
3+
# Copyright (c) F5, Inc.
4+
#
5+
# This source code is licensed under the Apache License, Version 2.0 license
6+
# found in the LICENSE file in the root directory of this source tree.
7+
8+
# Tests for ACME client: IPv4 identifier support.
9+
10+
###############################################################################
11+
12+
use warnings;
13+
use strict;
14+
15+
use Test::More;
16+
17+
BEGIN { use FindBin; chdir($FindBin::Bin); }
18+
19+
use lib 'lib';
20+
use Test::Nginx;
21+
use Test::Nginx::ACME;
22+
use Test::Nginx::DNS;
23+
24+
###############################################################################
25+
26+
select STDERR; $| = 1;
27+
select STDOUT; $| = 1;
28+
29+
my $t = Test::Nginx->new()->has(qw/http http_ssl socket_ssl/)
30+
->has_daemon('openssl');
31+
32+
$t->write_file_expand('nginx.conf', <<'EOF');
33+
34+
%%TEST_GLOBALS%%
35+
36+
daemon off;
37+
38+
events {
39+
}
40+
41+
http {
42+
%%TEST_GLOBALS_HTTP%%
43+
44+
resolver 127.0.0.1:%%PORT_8980_UDP%%;
45+
46+
acme_issuer default {
47+
uri https://acme.test:%%PORT_9000%%/dir;
48+
challenge http-01;
49+
ssl_trusted_certificate acme.test.crt;
50+
state_path %%TESTDIR%%/acme_default;
51+
accept_terms_of_service;
52+
}
53+
54+
acme_issuer tls-alpn {
55+
uri https://acme.test:%%PORT_9000%%/dir;
56+
challenge tls-alpn-01;
57+
ssl_trusted_certificate acme.test.crt;
58+
state_path %%TESTDIR%%/acme_tls-alpn;
59+
accept_terms_of_service;
60+
}
61+
62+
server {
63+
listen 127.0.0.1:8080;
64+
}
65+
66+
server {
67+
listen 127.0.0.1:8443 ssl;
68+
server_name 127.0.0.1;
69+
70+
acme_certificate default;
71+
72+
ssl_certificate $acme_certificate;
73+
ssl_certificate_key $acme_certificate_key;
74+
}
75+
76+
server {
77+
listen 127.0.0.1:8444 ssl;
78+
server_name 127.0.0.1;
79+
80+
acme_certificate tls-alpn;
81+
82+
ssl_certificate $acme_certificate;
83+
ssl_certificate_key $acme_certificate_key;
84+
}
85+
}
86+
87+
EOF
88+
89+
$t->write_file('openssl.conf', <<EOF);
90+
[ req ]
91+
default_bits = 2048
92+
encrypt_key = no
93+
distinguished_name = req_distinguished_name
94+
[ req_distinguished_name ]
95+
EOF
96+
97+
my $d = $t->testdir();
98+
99+
foreach my $name ('acme.test') {
100+
system('openssl req -x509 -new '
101+
. "-config $d/openssl.conf -subj /CN=$name/ "
102+
. "-out $d/$name.crt -keyout $d/$name.key "
103+
. ">>$d/openssl.out 2>&1") == 0
104+
or die "Can't create certificate for $name: $!\n";
105+
}
106+
107+
my $dp = port(8980, udp=>1);
108+
my @dc = (
109+
{ name => 'acme.test', A => '127.0.0.1' },
110+
);
111+
112+
my $acme = Test::Nginx::ACME->new($t, port(9000), port(9001),
113+
$t->testdir . '/acme.test.crt',
114+
$t->testdir . '/acme.test.key',
115+
http_port => port(8080),
116+
tls_port => port(8444),
117+
dns_port => $dp,
118+
nosleep => 1,
119+
);
120+
121+
$t->run_daemon(\&Test::Nginx::DNS::dns_test_daemon, $t, $dp, \@dc);
122+
$t->waitforfile($t->testdir . '/' . $dp);
123+
124+
$t->run_daemon(\&Test::Nginx::ACME::acme_test_daemon, $t, $acme);
125+
$t->waitforsocket('127.0.0.1:' . $acme->port());
126+
$t->write_file('acme-root.crt', $acme->trusted_ca());
127+
128+
$t->write_file('index.html', 'SUCCESS');
129+
$t->plan(2)->run();
130+
131+
###############################################################################
132+
133+
$acme->wait_certificate('acme_default/127.0.0.1') or die "no certificate";
134+
$acme->wait_certificate('acme_tls-alpn/127.0.0.1') or die "no certificate";
135+
136+
like(get('127.0.0.1', 8443, 'acme-root'), qr/SUCCESS/,
137+
'ipv4 cert via http-01');
138+
like(get('127.0.0.1', 8444, 'acme-root'), qr/SUCCESS/,
139+
'ipv4 cert via tls-alpn-01');
140+
141+
###############################################################################
142+
143+
sub get {
144+
my ($addr, $port, $ca) = @_;
145+
146+
$ca = undef if $IO::Socket::SSL::VERSION < 2.062
147+
|| !eval { Net::SSLeay::X509_V_FLAG_PARTIAL_CHAIN() };
148+
149+
http_get('/',
150+
PeerAddr => $addr,
151+
PeerPort => port($port),
152+
SSL => 1,
153+
$ca ? (
154+
SSL_ca_file => "$d/$ca.crt",
155+
SSL_verifycn_name => $addr,
156+
SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_PEER(),
157+
) : ()
158+
);
159+
}
160+
161+
###############################################################################

t/acme_ipv6_identifier.t

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
#!/usr/bin/perl
2+
3+
# Copyright (c) F5, Inc.
4+
#
5+
# This source code is licensed under the Apache License, Version 2.0 license
6+
# found in the LICENSE file in the root directory of this source tree.
7+
8+
# Tests for ACME client: IPv6 identifier support.
9+
10+
###############################################################################
11+
12+
use warnings;
13+
use strict;
14+
15+
use Test::More;
16+
17+
BEGIN { use FindBin; chdir($FindBin::Bin); }
18+
19+
use lib 'lib';
20+
use Test::Nginx;
21+
use Test::Nginx::ACME;
22+
use Test::Nginx::DNS;
23+
24+
###############################################################################
25+
26+
select STDERR; $| = 1;
27+
select STDOUT; $| = 1;
28+
29+
my $t = Test::Nginx->new()->has(qw/http http_ssl socket_ssl/)
30+
->has_daemon('openssl');
31+
32+
eval { require IO::Socket::INET6; };
33+
plan(skip_all => 'IO::Socket::INET6 is not installed') if $@;
34+
35+
$t->write_file_expand('nginx.conf', <<'EOF');
36+
37+
%%TEST_GLOBALS%%
38+
39+
daemon off;
40+
41+
events {
42+
}
43+
44+
http {
45+
%%TEST_GLOBALS_HTTP%%
46+
47+
resolver 127.0.0.1:%%PORT_8980_UDP%%;
48+
49+
acme_issuer default {
50+
uri https://acme.test:%%PORT_9000%%/dir;
51+
challenge http-01;
52+
ssl_trusted_certificate acme.test.crt;
53+
state_path %%TESTDIR%%/acme_default;
54+
accept_terms_of_service;
55+
}
56+
57+
acme_issuer tls-alpn {
58+
uri https://acme.test:%%PORT_9000%%/dir;
59+
challenge tls-alpn-01;
60+
ssl_trusted_certificate acme.test.crt;
61+
state_path %%TESTDIR%%/acme_tls-alpn;
62+
accept_terms_of_service;
63+
}
64+
65+
server {
66+
listen [::1]:%%PORT_8080%%;
67+
}
68+
69+
server {
70+
listen [::1]:%%PORT_8443%% ssl;
71+
server_name 0000:0000:0000:0000:0000:0000:0:1;
72+
73+
acme_certificate default;
74+
75+
ssl_certificate $acme_certificate;
76+
ssl_certificate_key $acme_certificate_key;
77+
}
78+
79+
server {
80+
listen [::1]:%%PORT_8444%% ssl;
81+
server_name ::1;
82+
83+
acme_certificate tls-alpn;
84+
85+
ssl_certificate $acme_certificate;
86+
ssl_certificate_key $acme_certificate_key;
87+
}
88+
}
89+
90+
EOF
91+
92+
$t->write_file('openssl.conf', <<EOF);
93+
[ req ]
94+
default_bits = 2048
95+
encrypt_key = no
96+
distinguished_name = req_distinguished_name
97+
[ req_distinguished_name ]
98+
EOF
99+
100+
my $d = $t->testdir();
101+
102+
foreach my $name ('acme.test') {
103+
system('openssl req -x509 -new '
104+
. "-config $d/openssl.conf -subj /CN=$name/ "
105+
. "-out $d/$name.crt -keyout $d/$name.key "
106+
. ">>$d/openssl.out 2>&1") == 0
107+
or die "Can't create certificate for $name: $!\n";
108+
}
109+
110+
my $dp = port(8980, udp=>1);
111+
my @dc = (
112+
{ name => 'acme.test', A => '127.0.0.1' },
113+
);
114+
115+
my $acme = Test::Nginx::ACME->new($t, port(9000), port(9001),
116+
$t->testdir . '/acme.test.crt',
117+
$t->testdir . '/acme.test.key',
118+
http_port => port(8080),
119+
tls_port => port(8444),
120+
dns_port => $dp,
121+
nosleep => 1,
122+
);
123+
124+
$t->run_daemon(\&Test::Nginx::DNS::dns_test_daemon, $t, $dp, \@dc);
125+
$t->waitforfile($t->testdir . '/' . $dp);
126+
127+
$t->run_daemon(\&Test::Nginx::ACME::acme_test_daemon, $t, $acme);
128+
$t->waitforsocket('127.0.0.1:' . $acme->port());
129+
$t->write_file('acme-root.crt', $acme->trusted_ca());
130+
131+
$t->write_file('index.html', 'SUCCESS');
132+
$t->try_run('no inet6 support')->plan(2);
133+
134+
###############################################################################
135+
136+
$acme->wait_certificate('acme_default/::1') or die "no certificate";
137+
$acme->wait_certificate('acme_tls-alpn/::1') or die "no certificate";
138+
139+
like(get('::1', 8443, 'acme-root'), qr/SUCCESS/, 'ipv6 cert via http-01');
140+
like(get('::1', 8444, 'acme-root'), qr/SUCCESS/, 'ipv6 cert via tls-alpn-01');
141+
142+
###############################################################################
143+
144+
sub get {
145+
my ($addr, $port, $ca) = @_;
146+
147+
my $s = getconn(@_) || return;
148+
149+
$ca = undef if $IO::Socket::SSL::VERSION < 2.062
150+
|| !eval { Net::SSLeay::X509_V_FLAG_PARTIAL_CHAIN() };
151+
152+
http_get('/',
153+
socket => $s,
154+
SSL => 1,
155+
$ca ? (
156+
SSL_ca_file => "$d/$ca.crt",
157+
SSL_verifycn_name => $addr,
158+
SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_PEER(),
159+
) : ()
160+
);
161+
}
162+
163+
sub getconn() {
164+
my ($addr, $port) = @_;
165+
my $s;
166+
167+
eval {
168+
local $SIG{ALRM} = sub { die "timeout\n" };
169+
local $SIG{PIPE} = sub { die "sigpipe\n" };
170+
alarm(8);
171+
172+
$s = IO::Socket::INET6->new(
173+
PeerAddr => $addr,
174+
PeerPort => port($port),
175+
)
176+
or die "Can't connect to nginx: $!\n";
177+
178+
alarm(0);
179+
};
180+
alarm(0);
181+
182+
if ($@) {
183+
log_in("died: $@");
184+
return undef;
185+
}
186+
187+
return $s;
188+
}
189+
190+
###############################################################################

0 commit comments

Comments
 (0)