Skip to content

Commit c7849ad

Browse files
committed
Tests: tests for loading "store:..." keys.
1 parent 98d6acc commit c7849ad

File tree

2 files changed

+362
-0
lines changed

2 files changed

+362
-0
lines changed

ssl_provider_keys.t

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
#!/usr/bin/perl
2+
3+
# (C) Sergey Kandaurov
4+
# (C) Aleksei Bavshin
5+
# (C) Nginx, Inc.
6+
7+
# Tests for http ssl module, loading "store:..." keys from OpenSSL providers.
8+
9+
###############################################################################
10+
11+
use warnings;
12+
use strict;
13+
14+
use Test::More;
15+
16+
BEGIN { use FindBin; chdir($FindBin::Bin); }
17+
18+
use lib 'lib';
19+
use Test::Nginx;
20+
21+
###############################################################################
22+
23+
select STDERR; $| = 1;
24+
select STDOUT; $| = 1;
25+
26+
plan(skip_all => 'win32') if $^O eq 'MSWin32';
27+
28+
my $t = Test::Nginx->new()->has(qw/http proxy http_ssl openssl:3/)
29+
->has_daemon('openssl')->has_daemon('softhsm2-util');
30+
31+
plan(skip_all => "not yet") unless $t->has_version('1.29.0');
32+
33+
$t->write_file_expand('nginx.conf', <<'EOF');
34+
35+
%%TEST_GLOBALS%%
36+
37+
daemon off;
38+
39+
events {
40+
}
41+
42+
env SOFTHSM2_CONF;
43+
44+
http {
45+
%%TEST_GLOBALS_HTTP%%
46+
47+
server {
48+
listen 127.0.0.1:8081 ssl;
49+
listen 127.0.0.1:8080;
50+
server_name localhost;
51+
52+
ssl_certificate localhost.crt;
53+
ssl_certificate_key "store:pkcs11:token=NginxZero;object=nx_key_0";
54+
55+
ssl_password_file pin.txt;
56+
57+
location / {
58+
# index index.html by default
59+
}
60+
61+
location /proxy {
62+
proxy_pass https://127.0.0.1:8081/;
63+
}
64+
65+
location /var {
66+
proxy_pass https://127.0.0.1:8082/;
67+
proxy_ssl_name localhost;
68+
proxy_ssl_server_name on;
69+
}
70+
}
71+
72+
server {
73+
listen 127.0.0.1:8082 ssl;
74+
server_name localhost;
75+
76+
ssl_certificate $ssl_server_name.crt;
77+
ssl_certificate_key "store:pkcs11:token=NginxZero;object=nx_key_0";
78+
79+
ssl_password_file pin.txt;
80+
81+
location / {
82+
# index index.html by default
83+
}
84+
}
85+
}
86+
87+
EOF
88+
89+
# Create a SoftHSM token with a secret key, and configure OpenSSL to access it
90+
# using the pkcs11 provider (https://github.com/latchset/pkcs11-provider).
91+
#
92+
# Note that library paths vary on different systems,
93+
# and may need to be adjusted.
94+
95+
my $libsofthsm2_path;
96+
my @so_paths = (
97+
'/usr/lib/softhsm', # Debian-based
98+
'/usr/local/lib/softhsm', # FreeBSD
99+
'/opt/local/lib/softhsm', # MacPorts
100+
'/lib64', # RHEL-based
101+
split /:/, $ENV{TEST_NGINX_SOFTHSM} || ''
102+
);
103+
104+
for my $so_path (@so_paths) {
105+
$so_path .= '/libsofthsm2.so';
106+
if (-e $so_path) {
107+
$libsofthsm2_path = $so_path;
108+
last;
109+
}
110+
};
111+
112+
plan(skip_all => "libsofthsm2.so not found") unless $libsofthsm2_path;
113+
114+
my $openssl_conf = <<EOF;
115+
openssl_conf = openssl_def
116+
117+
[openssl_def]
118+
providers = provider_sect
119+
120+
[provider_sect]
121+
default = default_sect
122+
pkcs11 = pkcs11_sect
123+
124+
[default_sect]
125+
activate = 1
126+
127+
[pkcs11_sect]
128+
pkcs11-module-path = $libsofthsm2_path
129+
pkcs11-module-cache-pins = cache
130+
# https://github.com/latchset/pkcs11-provider/commit/ab6370fd
131+
pkcs11-module-quirks = no-deinit no-operation-state
132+
module = /usr/local/lib/ossl-modules/pkcs11.so
133+
activate = 1
134+
135+
[ req ]
136+
default_bits = 2048
137+
encrypt_key = no
138+
distinguished_name = req_distinguished_name
139+
[ req_distinguished_name ]
140+
EOF
141+
142+
$openssl_conf =~ s|^(?=module)|# |m if $^O ne 'freebsd';
143+
$t->write_file('openssl.conf', $openssl_conf);
144+
145+
my $d = $t->testdir();
146+
147+
$t->write_file('softhsm2.conf', <<EOF);
148+
directories.tokendir = $d/tokens/
149+
objectstore.backend = file
150+
EOF
151+
152+
mkdir($d . '/tokens');
153+
154+
$ENV{SOFTHSM2_CONF} = "$d/softhsm2.conf";
155+
$ENV{OPENSSL_CONF} = "$d/openssl.conf";
156+
157+
foreach my $name ('localhost') {
158+
system('softhsm2-util --init-token --slot 0 --label NginxZero '
159+
. '--pin 1234 --so-pin 1234 '
160+
. ">>$d/openssl.out 2>&1");
161+
162+
system("openssl genrsa -out $d/$name.key 2048 "
163+
. ">>$d/openssl.out 2>&1") == 0
164+
or die "Can't create private key: $!\n";
165+
166+
system("softhsm2-util --import $d/$name.key --id 00 --label nx_key_0 "
167+
. '--token NginxZero --pin 1234 '
168+
. ">>$d/openssl.out 2>&1") == 0
169+
or die "Can't import private key: $!\n";
170+
171+
system('openssl req -x509 -new '
172+
. "-subj /CN=$name/ -out $d/$name.crt -text -passin pass:1234 "
173+
. '-key "pkcs11:token=NginxZero;object=nx_key_0" '
174+
. ">>$d/openssl.out 2>&1") == 0
175+
or plan(skip_all => "missing pkcs11-provider");
176+
}
177+
178+
$t->write_file('pin.txt', '1234');
179+
$t->write_file('index.html', '');
180+
181+
$t->run()->plan(2);
182+
183+
###############################################################################
184+
185+
like(http_get('/proxy'), qr/200 OK/, 'ssl provider keys');
186+
like(http_get('/var'), qr/200 OK/, 'ssl_certificate with variable');
187+
188+
###############################################################################

ssl_store_keys.t

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
#!/usr/bin/perl
2+
3+
# (C) Aleksei Bavshin
4+
# (C) Nginx, Inc.
5+
6+
# Tests for http ssl module, loading "store:..." keys.
7+
8+
###############################################################################
9+
10+
use warnings;
11+
use strict;
12+
13+
use Test::More;
14+
15+
BEGIN { use FindBin; chdir($FindBin::Bin); }
16+
17+
use lib 'lib';
18+
use Test::Nginx qw/ :DEFAULT http_end /;
19+
20+
###############################################################################
21+
22+
select STDERR; $| = 1;
23+
select STDOUT; $| = 1;
24+
25+
my $t = Test::Nginx->new()
26+
->has(qw/http http_ssl geo openssl:1.1.1 socket_ssl_sni/)
27+
->has_daemon('openssl');
28+
29+
plan(skip_all => 'BoringSSL') if $t->has_module('BoringSSL|AWS-LC');
30+
plan(skip_all => 'not yet') unless $t->has_version('1.29.0');
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+
geo $localhost {
45+
default localhost;
46+
}
47+
48+
geo $pass {
49+
default pass;
50+
}
51+
52+
add_header X-SSL $ssl_server_name;
53+
54+
server {
55+
listen 127.0.0.1:8080 ssl;
56+
server_name default;
57+
58+
ssl_certificate localhost.crt;
59+
ssl_certificate_key store:file:%%TESTDIR%%/localhost.key;
60+
}
61+
62+
server {
63+
listen 127.0.0.1:8080 ssl;
64+
server_name variable;
65+
66+
ssl_certificate localhost.crt;
67+
ssl_certificate_key store:file:%%TESTDIR%%/$localhost.key;
68+
}
69+
70+
server {
71+
listen 127.0.0.1:8080 ssl;
72+
server_name pass;
73+
74+
ssl_certificate pass.crt;
75+
ssl_certificate_key store:file:%%TESTDIR%%/pass.key;
76+
77+
ssl_password_file password;
78+
}
79+
80+
server {
81+
listen 127.0.0.1:8080 ssl;
82+
server_name variable-pass;
83+
84+
ssl_certificate pass.crt;
85+
ssl_certificate_key store:file:%%TESTDIR%%/$pass.key;
86+
87+
ssl_password_file password;
88+
}
89+
90+
server {
91+
listen 127.0.0.1:8080 ssl;
92+
server_name variable-no-pass;
93+
94+
ssl_certificate pass.crt;
95+
ssl_certificate_key store:file:%%TESTDIR%%/$pass.key;
96+
}
97+
}
98+
99+
EOF
100+
101+
$t->write_file('openssl.conf', <<EOF);
102+
[ req ]
103+
default_bits = 2048
104+
encrypt_key = no
105+
distinguished_name = req_distinguished_name
106+
[ req_distinguished_name ]
107+
EOF
108+
109+
my $d = $t->testdir();
110+
111+
foreach my $name ('localhost') {
112+
system('openssl req -x509 -new '
113+
. "-config $d/openssl.conf -subj /CN=$name/ "
114+
. "-out $d/$name.crt -keyout $d/$name.key "
115+
. ">>$d/openssl.out 2>&1") == 0
116+
or die "Can't create certificate for $name: $!\n";
117+
}
118+
119+
foreach my $name ('pass') {
120+
system("openssl genrsa -out $d/$name.key -passout pass:$name "
121+
. "-aes128 2048 >>$d/openssl.out 2>&1") == 0
122+
or die "Can't create private key: $!\n";
123+
system('openssl req -x509 -new '
124+
. "-config $d/openssl.conf -subj /CN=$name/ "
125+
. "-out $d/$name.crt "
126+
. "-key $d/$name.key -passin pass:$name"
127+
. ">>$d/openssl.out 2>&1") == 0
128+
or die "Can't create certificate for $name: $!\n";
129+
}
130+
131+
132+
$t->write_file('password', 'pass');
133+
$t->write_file('index.html', '');
134+
135+
$t->run()->plan(9);
136+
137+
###############################################################################
138+
139+
like(cert('default'), qr/CN=localhost/, 'default key');
140+
like(get('default'), qr/default/, 'default context');
141+
142+
like(cert('variable'), qr/CN=localhost/, 'key with vars');
143+
like(get('variable'), qr/variable/, 'context with vars');
144+
145+
like(cert('pass'), qr/CN=pass/, 'encrypted key');
146+
like(get('pass'), qr/pass/, 'encrypted context');
147+
148+
like(cert('variable-pass'), qr/CN=pass/, 'encrypted key - vars');
149+
like(get('variable-pass'), qr/variable-pass/, 'encrypted context - vars');
150+
151+
is(cert('variable-no-pass'), undef, 'encrypted key - no pass');
152+
153+
###############################################################################
154+
155+
sub get {
156+
my $s = get_socket(@_) || return;
157+
return http_end($s);
158+
}
159+
160+
sub cert {
161+
my $s = get_socket(@_) || return;
162+
return $s->dump_peer_certificate();
163+
}
164+
165+
sub get_socket {
166+
my ($host) = @_;
167+
return http_get(
168+
'/', start => 1, PeerAddr => '127.0.0.1:' . port(8080),
169+
SSL => 1,
170+
SSL_hostname => $host,
171+
);
172+
}
173+
174+
###############################################################################

0 commit comments

Comments
 (0)