]>
Commit | Line | Data |
---|---|---|
1c55e372 | 1 | #! /usr/bin/env perl |
b6461792 | 2 | # Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. |
1c55e372 | 3 | # |
909f1a2e | 4 | # Licensed under the Apache License 2.0 (the "License"). You may not use |
1c55e372 MC |
5 | # this file except in compliance with the License. You can obtain a copy |
6 | # in the file LICENSE in the source distribution or at | |
7 | # https://www.openssl.org/source/license.html | |
8 | ||
70bf33d1 AP |
9 | use strict; |
10 | use warnings; | |
11 | ||
8a85df7c | 12 | use OpenSSL::Test qw/:DEFAULT srctop_file with/; |
1c55e372 MC |
13 | use OpenSSL::Test::Utils; |
14 | ||
70bf33d1 AP |
15 | use Encode; |
16 | ||
17 | setup("test_pkcs12"); | |
18 | ||
70bf33d1 AP |
19 | my $pass = "σύνθημα γνώρισμα"; |
20 | ||
21 | my $savedcp; | |
652c52a6 | 22 | if (eval { require Win32::API; 1; }) { |
70bf33d1 | 23 | # Trouble is that Win32 perl uses CreateProcessA, which |
652c52a6 AP |
24 | # makes it problematic to pass non-ASCII arguments, from perl[!] |
25 | # that is. This is because CreateProcessA is just a wrapper for | |
26 | # CreateProcessW and will call MultiByteToWideChar and use | |
27 | # system default locale. Since we attempt Greek pass-phrase | |
28 | # conversion can be done only with Greek locale. | |
70bf33d1 | 29 | |
652c52a6 AP |
30 | Win32::API->Import("kernel32","UINT GetSystemDefaultLCID()"); |
31 | if (GetSystemDefaultLCID() != 0x408) { | |
32 | plan skip_all => "Non-Greek system locale"; | |
33 | } else { | |
34 | # Ensure correct code page so that VERBOSE output is right. | |
35 | Win32::API->Import("kernel32","UINT GetConsoleOutputCP()"); | |
36 | Win32::API->Import("kernel32","BOOL SetConsoleOutputCP(UINT cp)"); | |
37 | $savedcp = GetConsoleOutputCP(); | |
38 | SetConsoleOutputCP(1253); | |
39 | $pass = Encode::encode("cp1253",Encode::decode("utf-8",$pass)); | |
40 | } | |
d4c499f5 AP |
41 | } elsif ($^O eq "MSWin32") { |
42 | plan skip_all => "Win32::API unavailable"; | |
46399d9d | 43 | } elsif ($^O ne "VMS") { |
46f4e1be | 44 | # Running MinGW tests transparently under Wine apparently requires |
1194ea8d AP |
45 | # UTF-8 locale... |
46 | ||
47 | foreach(`locale -a`) { | |
48 | s/\R$//; | |
49 | if ($_ =~ m/^C\.UTF\-?8/i) { | |
50 | $ENV{LC_ALL} = $_; | |
51 | last; | |
52 | } | |
53 | } | |
70bf33d1 | 54 | } |
fb5d9f1d | 55 | $ENV{OPENSSL_WIN32_UTF8}=1; |
70bf33d1 | 56 | |
a4cbffcd | 57 | plan tests => 31; |
c5ec6dcf JS |
58 | |
59 | # Test different PKCS#12 formats | |
60 | ok(run(test(["pkcs12_format_test"])), "test pkcs12 formats"); | |
b536880c JS |
61 | # Test with legacy APIs |
62 | ok(run(test(["pkcs12_format_test", "-legacy"])), "test pkcs12 formats using legacy APIs"); | |
63 | # Test with a non-default library context (and no loaded providers in the default context) | |
64 | ok(run(test(["pkcs12_format_test", "-context"])), "test pkcs12 formats using a non-default library context"); | |
652c52a6 | 65 | |
46399d9d RL |
66 | SKIP: { |
67 | skip "VMS doesn't have command line UTF-8 support yet in DCL", 1 | |
68 | if $^O eq "VMS"; | |
69 | ||
70 | # just see that we can read shibboleth.pfx protected with $pass | |
71 | ok(run(app(["openssl", "pkcs12", "-noout", | |
72 | "-password", "pass:$pass", | |
73 | "-in", srctop_file("test", "shibboleth.pfx")])), | |
74 | "test_load_cert_pkcs12"); | |
75 | } | |
70bf33d1 | 76 | |
b3c5aadf | 77 | my @path = qw(test certs); |
279b61d0 DO |
78 | my $outfile1 = "out1.p12"; |
79 | my $outfile2 = "out2.p12"; | |
80 | my $outfile3 = "out3.p12"; | |
e5808784 | 81 | my $outfile4 = "out4.p12"; |
35258435 | 82 | my $outfile5 = "out5.p12"; |
cfd24cde | 83 | my $outfile6 = "out6.p12"; |
e869c867 | 84 | my $outfile7 = "out7.p12"; |
b3c5aadf | 85 | |
1d6c8670 DDO |
86 | # Test the -chain option with -untrusted |
87 | ok(run(app(["openssl", "pkcs12", "-export", "-chain", | |
88 | "-CAfile", srctop_file(@path, "sroot-cert.pem"), | |
89 | "-untrusted", srctop_file(@path, "ca-cert.pem"), | |
90 | "-in", srctop_file(@path, "ee-cert.pem"), | |
279b61d0 | 91 | "-nokeys", "-passout", "pass:", "-out", $outfile1])), |
1d6c8670 DDO |
92 | "test_pkcs12_chain_untrusted"); |
93 | ||
b3c5aadf | 94 | # Test the -passcerts option |
b536880c JS |
95 | SKIP: { |
96 | skip "Skipping PKCS#12 test because DES is disabled in this build", 1 | |
97 | if disabled("des"); | |
98 | ok(run(app(["openssl", "pkcs12", "-export", | |
b3c5aadf DDO |
99 | "-in", srctop_file(@path, "ee-cert.pem"), |
100 | "-certfile", srctop_file(@path, "v3-certs-TDES.p12"), | |
101 | "-passcerts", "pass:v3-certs", | |
102 | "-nokeys", "-passout", "pass:v3-certs", "-descert", | |
279b61d0 DO |
103 | "-out", $outfile2])), |
104 | "test_pkcs12_passcerts"); | |
b536880c | 105 | } |
b3c5aadf | 106 | |
2d840893 | 107 | SKIP: { |
67cd4308 P |
108 | skip "Skipping legacy PKCS#12 test because the required algorithms are disabled", 1 |
109 | if disabled("des") || disabled("rc2") || disabled("legacy"); | |
2d840893 MC |
110 | # Test reading legacy PKCS#12 file |
111 | ok(run(app(["openssl", "pkcs12", "-export", | |
112 | "-in", srctop_file(@path, "v3-certs-RC2.p12"), | |
113 | "-passin", "pass:v3-certs", | |
114 | "-provider", "default", "-provider", "legacy", | |
115 | "-nokeys", "-passout", "pass:v3-certs", "-descert", | |
116 | "-out", $outfile3])), | |
117 | "test_pkcs12_passcerts_legacy"); | |
118 | } | |
b3c5aadf | 119 | |
e5808784 TM |
120 | # Test export of PEM file with both cert and key |
121 | # -nomac necessary to avoid legacy provider requirement | |
122 | ok(run(app(["openssl", "pkcs12", "-export", | |
123 | "-inkey", srctop_file(@path, "cert-key-cert.pem"), | |
124 | "-in", srctop_file(@path, "cert-key-cert.pem"), | |
125 | "-passout", "pass:v3-certs", | |
126 | "-nomac", "-out", $outfile4], stderr => "outerr.txt")), | |
127 | "test_export_pkcs12_cert_key_cert"); | |
128 | open DATA, "outerr.txt"; | |
129 | my @match = grep /:error:/, <DATA>; | |
130 | close DATA; | |
131 | ok(scalar @match > 0 ? 0 : 1, "test_export_pkcs12_outerr_empty"); | |
132 | ||
133 | ok(run(app(["openssl", "pkcs12", | |
134 | "-in", $outfile4, | |
135 | "-passin", "pass:v3-certs", | |
136 | "-nomacver", "-nodes"])), | |
137 | "test_import_pkcs12_cert_key_cert"); | |
138 | ||
35258435 MC |
139 | ok(run(app(["openssl", "pkcs12", "-export", "-out", $outfile5, |
140 | "-in", srctop_file(@path, "ee-cert.pem"), "-caname", "testname", | |
141 | "-nokeys", "-passout", "pass:", "-certpbe", "NONE"])), | |
142 | "test nokeys single cert"); | |
143 | ||
144 | my @pkcs12info = run(app(["openssl", "pkcs12", "-info", "-in", $outfile5, | |
145 | "-passin", "pass:"]), capture => 1); | |
146 | ||
147 | # Test that with one input certificate, we get one output certificate | |
7e399f03 | 148 | ok(grep(/subject=CN\s*=\s*server.example/, @pkcs12info) == 1, |
35258435 | 149 | "test one cert in output"); |
e869c867 | 150 | |
35258435 MC |
151 | # Test that the expected friendly name is present in the output |
152 | ok(grep(/testname/, @pkcs12info) == 1, "test friendly name in output"); | |
e5808784 | 153 | |
e869c867 GW |
154 | # Test there's no Oracle Trusted Key Usage bag attribute |
155 | ok(grep(/Trusted key usage (Oracle)/, @pkcs12info) == 0, | |
156 | "test no oracle trusted key usage"); | |
157 | ||
cfd24cde DF |
158 | # Test export of PEM file with both cert and key, without password. |
159 | # -nomac necessary to avoid legacy provider requirement | |
160 | { | |
161 | ok(run(app(["openssl", "pkcs12", "-export", | |
162 | "-inkey", srctop_file(@path, "cert-key-cert.pem"), | |
163 | "-in", srctop_file(@path, "cert-key-cert.pem"), | |
164 | "-passout", "pass:", | |
165 | "-nomac", "-out", $outfile6], stderr => "outerr6.txt")), | |
166 | "test_export_pkcs12_cert_key_cert_no_pass"); | |
167 | open DATA, "outerr6.txt"; | |
168 | my @match = grep /:error:/, <DATA>; | |
169 | close DATA; | |
170 | ok(scalar @match > 0 ? 0 : 1, "test_export_pkcs12_outerr6_empty"); | |
171 | } | |
172 | ||
8a85df7c MC |
173 | # Test some bad pkcs12 files |
174 | my $bad1 = srctop_file("test", "recipes", "80-test_pkcs12_data", "bad1.p12"); | |
175 | my $bad2 = srctop_file("test", "recipes", "80-test_pkcs12_data", "bad2.p12"); | |
176 | my $bad3 = srctop_file("test", "recipes", "80-test_pkcs12_data", "bad3.p12"); | |
177 | ||
178 | with({ exit_checker => sub { return shift == 1; } }, | |
179 | sub { | |
180 | ok(run(app(["openssl", "pkcs12", "-in", $bad1, "-password", "pass:"])), | |
181 | "test bad pkcs12 file 1"); | |
182 | ||
183 | ok(run(app(["openssl", "pkcs12", "-in", $bad1, "-password", "pass:", | |
184 | "-nomacver"])), | |
185 | "test bad pkcs12 file 1 (nomacver)"); | |
186 | ||
a4cbffcd VL |
187 | ok(run(app(["openssl", "pkcs12", "-in", $bad1, "-password", "pass:", |
188 | "-info"])), | |
189 | "test bad pkcs12 file 1 (info)"); | |
190 | ||
8a85df7c MC |
191 | ok(run(app(["openssl", "pkcs12", "-in", $bad2, "-password", "pass:"])), |
192 | "test bad pkcs12 file 2"); | |
193 | ||
a4cbffcd VL |
194 | ok(run(app(["openssl", "pkcs12", "-in", $bad2, "-password", "pass:", |
195 | "-info"])), | |
196 | "test bad pkcs12 file 2 (info)"); | |
197 | ||
8a85df7c MC |
198 | ok(run(app(["openssl", "pkcs12", "-in", $bad3, "-password", "pass:"])), |
199 | "test bad pkcs12 file 3"); | |
a4cbffcd VL |
200 | |
201 | ok(run(app(["openssl", "pkcs12", "-in", $bad3, "-password", "pass:", | |
202 | "-info"])), | |
203 | "test bad pkcs12 file 3 (info)"); | |
8a85df7c MC |
204 | }); |
205 | ||
e869c867 GW |
206 | # Test with Oracle Trusted Key Usage specified in openssl.cnf |
207 | { | |
e869c867 | 208 | ok(run(app(["openssl", "pkcs12", "-export", "-out", $outfile7, |
21f7a09c | 209 | "-jdktrust", "anyExtendedKeyUsage", "-in", srctop_file(@path, "ee-cert.pem"), |
e869c867 GW |
210 | "-nokeys", "-passout", "pass:", "-certpbe", "NONE"])), |
211 | "test nokeys single cert"); | |
212 | ||
213 | my @pkcs12info = run(app(["openssl", "pkcs12", "-info", "-in", $outfile7, | |
214 | "-passin", "pass:"]), capture => 1); | |
215 | ok(grep(/Trusted key usage \(Oracle\): Any Extended Key Usage \(2.5.29.37.0\)/, @pkcs12info) == 1, | |
216 | "test oracle trusted key usage is set"); | |
217 | ||
218 | delete $ENV{OPENSSL_CONF} | |
219 | } | |
220 | ||
cfd24cde DF |
221 | # Tests for pkcs12_parse |
222 | ok(run(test(["pkcs12_api_test", | |
223 | "-in", $outfile1, | |
224 | "-has-ca", 1, | |
225 | ])), "Test pkcs12_parse()"); | |
226 | ||
227 | SKIP: { | |
228 | skip "Skipping PKCS#12 parse test because DES is disabled in this build", 1 | |
229 | if disabled("des"); | |
230 | ok(run(test(["pkcs12_api_test", | |
231 | "-in", $outfile2, | |
232 | "-pass", "v3-certs", | |
233 | "-has-ca", 1, | |
234 | ])), "Test pkcs12_parse()"); | |
235 | } | |
236 | ||
237 | SKIP: { | |
238 | skip "Skipping PKCS#12 parse test because the required algorithms are disabled", 1 | |
239 | if disabled("des") || disabled("rc2") || disabled("legacy"); | |
240 | ok(run(test(["pkcs12_api_test", | |
241 | "-in", $outfile3, | |
242 | "-pass", "v3-certs", | |
243 | "-has-ca", 1, | |
244 | ])), "Test pkcs12_parse()"); | |
245 | } | |
246 | ||
247 | ok(run(test(["pkcs12_api_test", | |
248 | "-in", $outfile4, | |
249 | "-pass", "v3-certs", | |
250 | "-has-ca", 1, | |
251 | "-has-key", 1, | |
252 | "-has-cert", 1, | |
253 | ])), "Test pkcs12_parse()"); | |
254 | ||
255 | ok(run(test(["pkcs12_api_test", | |
256 | "-in", $outfile5, | |
257 | "-has-ca", 1, | |
258 | ])), "Test pkcs12_parse()"); | |
259 | ||
260 | ok(run(test(["pkcs12_api_test", | |
261 | "-in", $outfile6, | |
262 | "-pass", "", | |
263 | "-has-ca", 1, | |
264 | "-has-key", 1, | |
265 | "-has-cert", 1, | |
266 | ])), "Test pkcs12_parse()"); | |
267 | ||
652c52a6 | 268 | SetConsoleOutputCP($savedcp) if (defined($savedcp)); |