xref: /freebsd/crypto/openssl/test/recipes/25-test_pkcs8.t (revision e7be843b4a162e68651d3911f0357ed464915629)
1*e7be843bSPierre Pronchery#! /usr/bin/env perl
2*e7be843bSPierre Pronchery# Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.
3*e7be843bSPierre Pronchery#
4*e7be843bSPierre Pronchery# Licensed under the Apache License 2.0 (the "License").  You may not use
5*e7be843bSPierre Pronchery# this file except in compliance with the License.  You can obtain a copy
6*e7be843bSPierre Pronchery# in the file LICENSE in the source distribution or at
7*e7be843bSPierre Pronchery# https://www.openssl.org/source/license.html
8*e7be843bSPierre Pronchery
9*e7be843bSPierre Proncheryuse strict;
10*e7be843bSPierre Proncheryuse warnings;
11*e7be843bSPierre Pronchery
12*e7be843bSPierre Proncheryuse OpenSSL::Test::Utils;
13*e7be843bSPierre Proncheryuse File::Copy;
14*e7be843bSPierre Proncheryuse File::Compare qw(compare_text compare);
15*e7be843bSPierre Proncheryuse OpenSSL::Test qw/:DEFAULT srctop_file ok_nofips is_nofips/;
16*e7be843bSPierre Pronchery
17*e7be843bSPierre Proncherysetup("test_pkcs8");
18*e7be843bSPierre Pronchery
19*e7be843bSPierre Proncheryplan tests => 18;
20*e7be843bSPierre Pronchery
21*e7be843bSPierre Proncherymy $pc5_key = srctop_file('test', 'certs', 'pc5-key.pem');
22*e7be843bSPierre Pronchery
23*e7be843bSPierre Proncherymy $inout = 'inout.pem';
24*e7be843bSPierre Proncherycopy($pc5_key, $inout);
25*e7be843bSPierre Proncheryok(run(app(['openssl', 'pkcs8', '-topk8', '-in', $inout,
26*e7be843bSPierre Pronchery            '-out', $inout, '-passout', 'pass:password'])),
27*e7be843bSPierre Pronchery   "identical infile and outfile, to PKCS#8");
28*e7be843bSPierre Proncheryok(run(app(['openssl', 'pkcs8', '-in', $inout,
29*e7be843bSPierre Pronchery            '-out', $inout, '-passin', 'pass:password'])),
30*e7be843bSPierre Pronchery   "identical infile and outfile, from PKCS#8");
31*e7be843bSPierre Proncheryis(compare_text($pc5_key, $inout), 0,
32*e7be843bSPierre Pronchery   "Same file contents after converting forth and back");
33*e7be843bSPierre Pronchery
34*e7be843bSPierre Proncheryok(run(app(([ 'openssl', 'pkcs8', '-topk8',
35*e7be843bSPierre Pronchery              '-in', $pc5_key,
36*e7be843bSPierre Pronchery              '-out', 'pbkdf2_default_saltlen.pem',
37*e7be843bSPierre Pronchery              '-passout', 'pass:password']))),
38*e7be843bSPierre Pronchery   "Convert a private key to PKCS5 v2.0 format using PBKDF2 with the default saltlen");
39*e7be843bSPierre Pronchery
40*e7be843bSPierre Pronchery# We expect the output to be of the form "0:d=0  hl=2 l=  16 prim: OCTET STRING      [HEX DUMP]:FAC7F37508E6B7A805BF4B13861B3687"
41*e7be843bSPierre Pronchery# i.e. 2 byte header + 16 byte salt.
42*e7be843bSPierre Proncheryok(run(app(([ 'openssl', 'asn1parse',
43*e7be843bSPierre Pronchery              '-in', 'pbkdf2_default_saltlen.pem',
44*e7be843bSPierre Pronchery              '-offset', '34', '-length', '18']))),
45*e7be843bSPierre Pronchery   "Check the default size of the PBKDF2 PARAM 'salt length' is 16");
46*e7be843bSPierre Pronchery
47*e7be843bSPierre ProncherySKIP: {
48*e7be843bSPierre Pronchery    skip "scrypt is not supported by this OpenSSL build", 4
49*e7be843bSPierre Pronchery        if disabled("scrypt");
50*e7be843bSPierre Pronchery
51*e7be843bSPierre Pronchery    ok(run(app(([ 'openssl', 'pkcs8', '-topk8',
52*e7be843bSPierre Pronchery                  '-in', $pc5_key,
53*e7be843bSPierre Pronchery                  '-scrypt',
54*e7be843bSPierre Pronchery                  '-out', 'scrypt_default_saltlen.pem',
55*e7be843bSPierre Pronchery                  '-passout', 'pass:password']))),
56*e7be843bSPierre Pronchery       "Convert a private key to PKCS5 v2.0 format using scrypt with the default saltlen");
57*e7be843bSPierre Pronchery
58*e7be843bSPierre Pronchery# We expect the output to be of the form "0:d=0  hl=2 l=  8 prim: OCTET STRING      [HEX DUMP]:FAC7F37508E6B7A805BF4B13861B3687"
59*e7be843bSPierre Pronchery# i.e. 2 byte header + 16 byte salt.
60*e7be843bSPierre Pronchery    ok(run(app(([ 'openssl', 'asn1parse',
61*e7be843bSPierre Pronchery                  '-in', 'scrypt_default_saltlen.pem',
62*e7be843bSPierre Pronchery                  '-offset', '34', '-length', '18']))),
63*e7be843bSPierre Pronchery       "Check the default size of the SCRYPT PARAM 'salt length' = 16");
64*e7be843bSPierre Pronchery
65*e7be843bSPierre Pronchery    ok(run(app(([ 'openssl', 'pkcs8', '-topk8',
66*e7be843bSPierre Pronchery                  '-in', $pc5_key,
67*e7be843bSPierre Pronchery                  '-scrypt',
68*e7be843bSPierre Pronchery                  '-saltlen', '8',
69*e7be843bSPierre Pronchery                  '-out', 'scrypt_64bit_saltlen.pem',
70*e7be843bSPierre Pronchery                  '-passout', 'pass:password']))),
71*e7be843bSPierre Pronchery       "Convert a private key to PKCS5 v2.0 format using scrypt with a salt length of 8 bytes");
72*e7be843bSPierre Pronchery
73*e7be843bSPierre Pronchery# We expect the output to be of the form "0:d=0  hl=2 l=   8 prim: OCTET STRING      [HEX DUMP]:3C1147976A2B61CA"
74*e7be843bSPierre Pronchery# i.e. 2 byte header + 8 byte salt.
75*e7be843bSPierre Pronchery    ok(run(app(([ 'openssl', 'asn1parse',
76*e7be843bSPierre Pronchery                  '-in', 'scrypt_64bit_saltlen.pem',
77*e7be843bSPierre Pronchery                  '-offset', '34', '-length', '10']))),
78*e7be843bSPierre Pronchery       "Check the size of the SCRYPT PARAM 'salt length' is 8");
79*e7be843bSPierre Pronchery}
80*e7be843bSPierre Pronchery
81*e7be843bSPierre ProncherySKIP: {
82*e7be843bSPierre Pronchery    skip "legacy provider is not supported by this OpenSSL build", 4
83*e7be843bSPierre Pronchery        if disabled('legacy') || disabled("des");
84*e7be843bSPierre Pronchery
85*e7be843bSPierre Pronchery    ok(run(app(([ 'openssl', 'pkcs8', '-topk8',
86*e7be843bSPierre Pronchery                  '-in', $pc5_key,
87*e7be843bSPierre Pronchery                  '-v1', "PBE-MD5-DES",
88*e7be843bSPierre Pronchery                  '-provider', 'legacy',
89*e7be843bSPierre Pronchery                  '-provider', 'default',
90*e7be843bSPierre Pronchery                  '-out', 'pbe1.pem',
91*e7be843bSPierre Pronchery                  '-passout', 'pass:password']))),
92*e7be843bSPierre Pronchery       "Convert a private key to PKCS5 v1.5 format using pbeWithMD5AndDES-CBC with the default saltlen");
93*e7be843bSPierre Pronchery
94*e7be843bSPierre Pronchery    ok(run(app(([ 'openssl', 'asn1parse',
95*e7be843bSPierre Pronchery                  '-in', 'pbe1.pem',
96*e7be843bSPierre Pronchery                  '-offset', '19', '-length', '10']))),
97*e7be843bSPierre Pronchery       "Check the default size of the PBE PARAM 'salt length' = 8");
98*e7be843bSPierre Pronchery
99*e7be843bSPierre Pronchery    ok(run(app(([ 'openssl', 'pkcs8', '-topk8',
100*e7be843bSPierre Pronchery                  '-in', $pc5_key,
101*e7be843bSPierre Pronchery                  '-v1', "PBE-MD5-DES",
102*e7be843bSPierre Pronchery                  '-saltlen', '16',
103*e7be843bSPierre Pronchery                  '-provider', 'legacy',
104*e7be843bSPierre Pronchery                  '-provider', 'default',
105*e7be843bSPierre Pronchery                  '-out', 'pbe1_128bitsalt.pem',
106*e7be843bSPierre Pronchery                  '-passout', 'pass:password']))),
107*e7be843bSPierre Pronchery       "Convert a private key to PKCS5 v1.5 format using pbeWithMD5AndDES-CBC with the 16 byte saltlen");
108*e7be843bSPierre Pronchery
109*e7be843bSPierre Pronchery    ok(run(app(([ 'openssl', 'asn1parse',
110*e7be843bSPierre Pronchery                  '-in', 'pbe1_128bitsalt.pem',
111*e7be843bSPierre Pronchery                  '-offset', '19', '-length', '18']))),
112*e7be843bSPierre Pronchery       "Check the size of the PBE PARAM 'salt length' = 16");
113*e7be843bSPierre Pronchery};
114*e7be843bSPierre Pronchery
115*e7be843bSPierre Pronchery
116*e7be843bSPierre Proncheryok(run(app(([ 'openssl', 'pkcs8', '-topk8',
117*e7be843bSPierre Pronchery              '-in', $pc5_key,
118*e7be843bSPierre Pronchery              '-saltlen', '8',
119*e7be843bSPierre Pronchery              '-out', 'pbkdf2_64bit_saltlen.pem',
120*e7be843bSPierre Pronchery              '-passout', 'pass:password']))),
121*e7be843bSPierre Pronchery   "Convert a private key to PKCS5 v2.0 format using pbkdf2 with a salt length of 8 bytes");
122*e7be843bSPierre Pronchery
123*e7be843bSPierre Pronchery# We expect the output to be of the form "0:d=0  hl=2 l=   8 prim: OCTET STRING      [HEX DUMP]:3C1147976A2B61CA"
124*e7be843bSPierre Pronchery# i.e. 2 byte header + 8 byte salt.
125*e7be843bSPierre Proncheryok(run(app(([ 'openssl', 'asn1parse',
126*e7be843bSPierre Pronchery              '-in', 'pbkdf2_64bit_saltlen.pem',
127*e7be843bSPierre Pronchery              '-offset', '34', '-length', '10']))),
128*e7be843bSPierre Pronchery   "Check the size of the PBKDF2 PARAM 'salt length' is 8");
129*e7be843bSPierre Pronchery
130*e7be843bSPierre Pronchery
131*e7be843bSPierre ProncherySKIP: {
132*e7be843bSPierre Pronchery    skip "SM2, SM3 or SM4 is not supported by this OpenSSL build", 3
133*e7be843bSPierre Pronchery        if disabled("sm2") || disabled("sm3") || disabled("sm4");
134*e7be843bSPierre Pronchery
135*e7be843bSPierre Pronchery    ok_nofips(run(app(([ 'openssl', 'pkcs8', '-topk8',
136*e7be843bSPierre Pronchery                      '-in', srctop_file('test', 'certs', 'sm2.key'),
137*e7be843bSPierre Pronchery                      '-out', 'sm2-pbes2-sm4-hmacWithSM3.key',
138*e7be843bSPierre Pronchery                      '-passout', 'pass:password',
139*e7be843bSPierre Pronchery                      '-v2', 'sm4', '-v2prf', 'hmacWithSM3']))),
140*e7be843bSPierre Pronchery                      "Convert a private key to PKCS#5 v2.0 format using SM4 and hmacWithSM3");
141*e7be843bSPierre Pronchery
142*e7be843bSPierre Pronchery    ok_nofips(run(app(([ 'openssl', 'pkcs8', '-topk8',
143*e7be843bSPierre Pronchery                      '-in', 'sm2-pbes2-sm4-hmacWithSM3.key',
144*e7be843bSPierre Pronchery                      '-out', 'sm2.key',
145*e7be843bSPierre Pronchery                      '-passin', 'pass:password', '-nocrypt',
146*e7be843bSPierre Pronchery                      '-v2', 'sm4', '-v2prf', 'hmacWithSM3']))),
147*e7be843bSPierre Pronchery                      "Convert from PKCS#5 v2.0 format to PKCS#8 unencrypted format");
148*e7be843bSPierre Pronchery
149*e7be843bSPierre Pronchery    is_nofips(compare_text(srctop_file('test', 'certs', 'sm2.key'), 'sm2.key',
150*e7be843bSPierre Pronchery        sub {
151*e7be843bSPierre Pronchery            my $in1 = $_[0];
152*e7be843bSPierre Pronchery            my $in2 = $_[1];
153*e7be843bSPierre Pronchery            $in1 =~ s/\r\n/\n/g;
154*e7be843bSPierre Pronchery            $in2 =~ s/\r\n/\n/g;
155*e7be843bSPierre Pronchery            $in1 ne $in2
156*e7be843bSPierre Pronchery        }), 0, "compare test/certs/sm2.key to sm2.key")
157*e7be843bSPierre Pronchery}
158