xref: /aosp_15_r20/external/boringssl/src/crypto/pkcs8/pkcs8_test.cc (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1 /* Copyright (c) 2015, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include <gtest/gtest.h>
16 
17 #include <openssl/crypto.h>
18 #include <openssl/err.h>
19 #include <openssl/pkcs8.h>
20 #include <openssl/x509.h>
21 
22 #include "../internal.h"
23 
24 
25 // kEncryptedPBES2WithDESAndSHA1 is a PKCS#8 encrypted private key using PBES2
26 // with DES-EDE3-CBC and HMAC-SHA-1 and a password of "testing". It was
27 // generated with:
28 //
29 // clang-format off
30 //
31 // openssl ecparam -genkey -name prime256v1 > test.key
32 // openssl pkcs8 -topk8 -in test.key -out test.key.encrypted -v2 des3 -v2prf hmacWithSHA1 -outform der
33 // xxd -i test.key.encrypted
34 //
35 // clang-format on
36 static const uint8_t kEncryptedPBES2WithDESAndSHA1[] = {
37     0x30, 0x81, 0xd5, 0x30, 0x40, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
38     0x0d, 0x01, 0x05, 0x0d, 0x30, 0x33, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86,
39     0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, 0x30, 0x0e, 0x04, 0x08, 0x65,
40     0x0b, 0xb8, 0x2a, 0x45, 0x13, 0x65, 0x4c, 0x02, 0x02, 0x08, 0x00, 0x30,
41     0x14, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, 0x04,
42     0x08, 0x16, 0x42, 0xa5, 0x98, 0xc2, 0x38, 0xdd, 0x80, 0x04, 0x81, 0x90,
43     0x8a, 0xfd, 0xc1, 0xb1, 0x6c, 0x8a, 0x26, 0x80, 0xff, 0x15, 0x9a, 0x15,
44     0x72, 0x04, 0x25, 0xe2, 0x2d, 0xfd, 0xfe, 0xfd, 0xbb, 0x1d, 0xcb, 0xbc,
45     0x3c, 0x07, 0xf2, 0x3e, 0x97, 0xe6, 0x24, 0x2d, 0x06, 0x1f, 0xa2, 0xc8,
46     0x72, 0xa0, 0x1b, 0x1f, 0xe2, 0x41, 0x1a, 0x53, 0xe5, 0xba, 0x17, 0x62,
47     0x49, 0xe8, 0xae, 0x1a, 0x5a, 0xf0, 0x4c, 0x5f, 0x74, 0x05, 0x3f, 0xc3,
48     0xb3, 0xa2, 0x8b, 0xb8, 0xc5, 0x17, 0x20, 0xec, 0xca, 0x3a, 0xf9, 0x00,
49     0xd8, 0xb1, 0x97, 0x61, 0x98, 0x28, 0xfe, 0x79, 0x1e, 0xe0, 0x7e, 0xb4,
50     0x7c, 0x40, 0x89, 0x1e, 0x56, 0xa6, 0x63, 0x4f, 0x32, 0x6e, 0x00, 0x77,
51     0x7d, 0xf1, 0xb9, 0x77, 0x92, 0xbf, 0x02, 0xbb, 0x9d, 0x45, 0x15, 0xd4,
52     0x4a, 0xb5, 0xe7, 0xb5, 0xb4, 0x9d, 0x06, 0x3c, 0x57, 0xf3, 0x8a, 0x9b,
53     0x58, 0x85, 0xad, 0x99, 0x16, 0x2d, 0xe9, 0x14, 0xa4, 0xa8, 0xad, 0x51,
54     0xce, 0x29, 0x55, 0x52, 0xb7, 0x42, 0xb3, 0x25, 0x6d, 0x2f, 0x00, 0x91,
55 };
56 
57 // kEncryptedPBES2WithAESAndSHA256 is a PKCS#8 encrypted private key using PBES2
58 // with AES-128-CBC and HMAC-SHA-256 and a password of "testing". It was generated with:
59 //
60 // clang-format off
61 //
62 // openssl ecparam -genkey -name prime256v1 > test.key
63 // openssl pkcs8 -topk8 -in test.key -out test.key.encrypted -v2 aes-128-cbc -v2prf hmacWithSHA256 -outform der
64 // xxd -i test.key.encrypted
65 //
66 // clang-format on
67 static const uint8_t kEncryptedPBES2WithAESAndSHA256[] = {
68     0x30, 0x81, 0xec, 0x30, 0x57, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
69     0x0d, 0x01, 0x05, 0x0d, 0x30, 0x4a, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86,
70     0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, 0x30, 0x1c, 0x04, 0x08, 0xfc,
71     0x66, 0x7f, 0x51, 0xe7, 0xb8, 0x2a, 0x22, 0x02, 0x02, 0x08, 0x00, 0x30,
72     0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x09, 0x05,
73     0x00, 0x30, 0x1d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
74     0x01, 0x02, 0x04, 0x10, 0xde, 0x59, 0xa1, 0x6c, 0xbc, 0xca, 0xd2, 0x04,
75     0x64, 0x93, 0xcb, 0xae, 0x0d, 0x57, 0xcd, 0x71, 0x04, 0x81, 0x90, 0x66,
76     0x84, 0x20, 0x5b, 0x8d, 0xfc, 0xa8, 0x08, 0x2c, 0xf1, 0x05, 0xea, 0xef,
77     0x74, 0x6b, 0xa7, 0xf5, 0xce, 0xf5, 0xef, 0x71, 0x55, 0xcd, 0x6c, 0x4a,
78     0xdd, 0xda, 0x6b, 0xc8, 0x51, 0xf5, 0x59, 0x87, 0x18, 0x48, 0x4e, 0xac,
79     0x8d, 0x3f, 0xa4, 0xd7, 0x51, 0x81, 0xf1, 0x4b, 0x18, 0x66, 0x3c, 0x4e,
80     0xf3, 0x08, 0x3e, 0x76, 0xf0, 0x12, 0x30, 0x93, 0x4e, 0x49, 0x86, 0xe0,
81     0xb3, 0xd1, 0x82, 0x92, 0xaa, 0x1f, 0x2b, 0x62, 0xe2, 0x6d, 0x0d, 0x0d,
82     0xad, 0xb8, 0xcf, 0xe8, 0x9a, 0x4e, 0xab, 0x31, 0x21, 0x5d, 0x6e, 0xec,
83     0xbc, 0xa1, 0x10, 0xef, 0x5f, 0xc5, 0xd3, 0x93, 0x57, 0x19, 0x95, 0xee,
84     0x0e, 0xce, 0x6c, 0x07, 0x08, 0xf1, 0xab, 0xe6, 0x0b, 0x06, 0x3f, 0xbd,
85     0x6d, 0x19, 0x48, 0x3c, 0xa0, 0xd7, 0x81, 0x5f, 0xa6, 0x06, 0x05, 0xac,
86     0x47, 0xb0, 0x51, 0x5b, 0xc5, 0x8b, 0xbe, 0x46, 0x43, 0x10, 0x9a, 0xd4,
87     0xc3, 0x49, 0xc2, 0x0a, 0xe7, 0xd0, 0x34, 0x8b, 0xad, 0xfb, 0x4d,
88 };
89 
90 // kNullPassword is a PKCS#8 encrypted private key using the null password.
91 static const uint8_t kNullPassword[] = {
92     0x30, 0x81, 0xb0, 0x30, 0x1b, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
93     0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0d, 0x04, 0x08, 0xb2, 0xfe, 0x68,
94     0xc2, 0xea, 0x0f, 0x10, 0x9c, 0x02, 0x01, 0x01, 0x04, 0x81, 0x90, 0xe2,
95     0xf6, 0x1c, 0xca, 0xad, 0x64, 0x30, 0xbf, 0x88, 0x04, 0x35, 0xe5, 0x0f,
96     0x11, 0x49, 0x06, 0x01, 0x14, 0x33, 0x80, 0xa2, 0x78, 0x44, 0x5b, 0xaa,
97     0x0d, 0xd7, 0x00, 0x36, 0x9d, 0x91, 0x97, 0x37, 0x20, 0x7b, 0x27, 0xc1,
98     0xa0, 0xa2, 0x73, 0x06, 0x15, 0xdf, 0xc8, 0x13, 0x9b, 0xc9, 0x8c, 0x9c,
99     0xce, 0x00, 0xd0, 0xc8, 0x42, 0xc1, 0xda, 0x2b, 0x07, 0x2b, 0x12, 0xa3,
100     0xce, 0x10, 0x39, 0x7a, 0xf1, 0x55, 0x69, 0x8d, 0xa5, 0xc4, 0x2a, 0x00,
101     0x0d, 0x94, 0xc6, 0xde, 0x6a, 0x3d, 0xb7, 0xe5, 0x6d, 0x59, 0x3e, 0x09,
102     0xb5, 0xe3, 0x3e, 0xfc, 0x50, 0x56, 0xe9, 0x50, 0x42, 0x7c, 0xe7, 0xf0,
103     0x19, 0xbd, 0x31, 0xa7, 0x85, 0x47, 0xb3, 0xe9, 0xb3, 0x50, 0x3c, 0xc9,
104     0x32, 0x37, 0x1a, 0x93, 0x78, 0x48, 0x78, 0x82, 0xde, 0xad, 0x5c, 0xf2,
105     0xcf, 0xf2, 0xbb, 0x2c, 0x44, 0x05, 0x7f, 0x4a, 0xf9, 0xb1, 0x2b, 0xdd,
106     0x49, 0xf6, 0x7e, 0xd0, 0x42, 0xaa, 0x14, 0x3c, 0x24, 0x77, 0xb4,
107 };
108 
109 // kNullPasswordNSS is a PKCS#8 encrypted private key using the null password
110 // and generated by NSS.
111 static const uint8_t kNullPasswordNSS[] = {
112     0x30, 0x81, 0xb8, 0x30, 0x23, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7,
113     0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x15, 0x04, 0x10, 0x3f, 0xac, 0xe9,
114     0x38, 0xdb, 0x40, 0x6b, 0x26, 0x89, 0x09, 0x73, 0x18, 0x8d, 0x7f, 0x1c,
115     0x82, 0x02, 0x01, 0x01, 0x04, 0x81, 0x90, 0x5e, 0x5e, 0x11, 0xef, 0xbb,
116     0x7c, 0x4d, 0xec, 0xc0, 0xdc, 0xc7, 0x23, 0xd2, 0xc4, 0x77, 0xbc, 0xf4,
117     0x5d, 0x59, 0x4c, 0x07, 0xc2, 0x8a, 0x26, 0xfa, 0x25, 0x1c, 0xaa, 0x42,
118     0xed, 0xd0, 0xed, 0xbb, 0x5c, 0xe9, 0x13, 0x07, 0xaa, 0xdd, 0x52, 0x3c,
119     0x65, 0x25, 0xbf, 0x94, 0x02, 0xaf, 0xd6, 0x97, 0xe9, 0x33, 0x00, 0x76,
120     0x64, 0x4a, 0x73, 0xab, 0xfb, 0x99, 0x6e, 0x83, 0x12, 0x05, 0x86, 0x72,
121     0x6c, 0xd5, 0xa4, 0xcf, 0xb1, 0xd5, 0x4d, 0x54, 0x87, 0x8b, 0x4b, 0x95,
122     0x1d, 0xcd, 0xf3, 0xfe, 0xa8, 0xda, 0xe0, 0xb6, 0x72, 0x13, 0x3f, 0x2e,
123     0x66, 0xe0, 0xb9, 0x2e, 0xfa, 0x69, 0x40, 0xbe, 0xd7, 0x67, 0x6e, 0x53,
124     0x2b, 0x3f, 0x53, 0xe5, 0x39, 0x54, 0x77, 0xe1, 0x1d, 0xe6, 0x81, 0x92,
125     0x58, 0x82, 0x14, 0xfb, 0x47, 0x85, 0x3c, 0xc3, 0xdf, 0xdd, 0xcc, 0x79,
126     0x9f, 0x41, 0x83, 0x72, 0xf2, 0x0a, 0xe9, 0xe1, 0x2c, 0x12, 0xb0, 0xb0,
127     0x0a, 0xb2, 0x1d, 0xca, 0x15, 0xb2, 0xca,
128 };
129 
130 // kEmptyPasswordOpenSSL is a PKCS#8 encrypted private key using the empty
131 // password and generated by OpenSSL.
132 static const uint8_t kEmptyPasswordOpenSSL[] = {
133     0x30, 0x82, 0x01, 0xa1, 0x30, 0x1b, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86,
134     0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0d, 0x04, 0x08, 0x86, 0xaa,
135     0xd7, 0xdf, 0x3b, 0x91, 0x97, 0x60, 0x02, 0x01, 0x01, 0x04, 0x82, 0x01,
136     0x80, 0xcb, 0x2a, 0x14, 0xaa, 0x4f, 0x38, 0x4c, 0xe1, 0x49, 0x00, 0xe2,
137     0x1a, 0x3a, 0x75, 0x87, 0x7e, 0x3d, 0xea, 0x4d, 0x53, 0xd4, 0x46, 0x47,
138     0x23, 0x8f, 0xa1, 0x72, 0x51, 0x92, 0x86, 0x8b, 0xeb, 0x53, 0xe6, 0x6a,
139     0x0a, 0x6b, 0xb6, 0xa0, 0xdc, 0x0f, 0xdc, 0x20, 0xc3, 0x45, 0x85, 0xf1,
140     0x95, 0x90, 0x5c, 0xf4, 0xfa, 0xee, 0x47, 0xaf, 0x35, 0xd0, 0xd0, 0xd3,
141     0x14, 0xde, 0x0d, 0xca, 0x1b, 0xd3, 0xbb, 0x20, 0xec, 0x9d, 0x6a, 0xd4,
142     0xc1, 0xce, 0x60, 0x81, 0xab, 0x0c, 0x72, 0x10, 0xfa, 0x28, 0x3c, 0xac,
143     0x87, 0x7b, 0x82, 0x85, 0x00, 0xb8, 0x58, 0x9c, 0x07, 0xc4, 0x7d, 0xa9,
144     0xc5, 0x94, 0x95, 0xf7, 0x23, 0x93, 0x3f, 0xed, 0xef, 0x92, 0x55, 0x25,
145     0x74, 0xbb, 0xd3, 0xd1, 0x67, 0x3b, 0x3d, 0x5a, 0xfe, 0x84, 0xf8, 0x97,
146     0x7d, 0x7c, 0x01, 0xc7, 0xd7, 0x0d, 0xf8, 0xc3, 0x6d, 0xd6, 0xf1, 0xaa,
147     0x9d, 0x1f, 0x69, 0x97, 0x45, 0x06, 0xc4, 0x1c, 0x95, 0x3c, 0xe0, 0xef,
148     0x11, 0xb2, 0xb3, 0x72, 0x91, 0x9e, 0x7d, 0x0f, 0x7f, 0xc8, 0xf6, 0x64,
149     0x49, 0x5e, 0x3c, 0x53, 0x37, 0x79, 0x03, 0x1c, 0x3f, 0x29, 0x6c, 0x6b,
150     0xea, 0x4c, 0x35, 0x9b, 0x6d, 0x1b, 0x59, 0x43, 0x4c, 0x14, 0x47, 0x2a,
151     0x36, 0x39, 0x2a, 0xd8, 0x96, 0x90, 0xdc, 0xfc, 0xd2, 0xdd, 0x23, 0x0e,
152     0x2c, 0xb3, 0x83, 0xf9, 0xf2, 0xe3, 0xe6, 0x99, 0x53, 0x57, 0x33, 0xc5,
153     0x5f, 0xf9, 0xfd, 0x56, 0x0b, 0x32, 0xd4, 0xf3, 0x9d, 0x5b, 0x34, 0xe5,
154     0x94, 0xbf, 0xb6, 0xc0, 0xce, 0xe1, 0x73, 0x5c, 0x02, 0x7a, 0x4c, 0xed,
155     0xde, 0x23, 0x38, 0x89, 0x9f, 0xcd, 0x51, 0xf3, 0x90, 0x80, 0xd3, 0x4b,
156     0x83, 0xd3, 0xee, 0xf2, 0x9e, 0x35, 0x91, 0xa5, 0xa3, 0xc0, 0x5c, 0xce,
157     0xdb, 0xaa, 0x70, 0x1e, 0x1d, 0xc1, 0x44, 0xea, 0x3b, 0xa7, 0x5a, 0x11,
158     0xd1, 0xf3, 0xf3, 0xd0, 0xf4, 0x5a, 0xc4, 0x99, 0xaf, 0x8d, 0xe2, 0xbc,
159     0xa2, 0xb9, 0x3d, 0x86, 0x5e, 0xba, 0xa0, 0xdf, 0x78, 0x81, 0x7c, 0x54,
160     0x31, 0xe3, 0x98, 0xb5, 0x46, 0xcb, 0x4d, 0x26, 0x4b, 0xf8, 0xac, 0x3a,
161     0x54, 0x1b, 0x77, 0x5a, 0x18, 0xa5, 0x43, 0x0e, 0x14, 0xde, 0x7b, 0xb7,
162     0x4e, 0x45, 0x99, 0x03, 0xd1, 0x3d, 0x18, 0xb2, 0x36, 0x00, 0x48, 0x07,
163     0x72, 0xbb, 0x4f, 0x21, 0x25, 0x3e, 0xda, 0x25, 0x24, 0x5b, 0xc8, 0xa0,
164     0x28, 0xd5, 0x9b, 0x96, 0x87, 0x07, 0x77, 0x84, 0xff, 0xd7, 0xac, 0x71,
165     0xf6, 0x61, 0x63, 0x0b, 0xfb, 0x42, 0xfd, 0x52, 0xf4, 0xc4, 0x35, 0x0c,
166     0xc2, 0xc1, 0x55, 0x22, 0x42, 0x2f, 0x13, 0x7d, 0x93, 0x27, 0xc8, 0x11,
167     0x35, 0xc5, 0xe3, 0xc5, 0xaa, 0x15, 0x3c, 0xac, 0x30, 0xbc, 0x45, 0x16,
168     0xed,
169 };
170 
171 // kExplicitHMACWithSHA1 is a PBES2-encrypted private key with an explicit
172 // hmacWithSHA1 AlgorithmIdentifier in the PBKDF2 parameters.
173 static const uint8_t kExplicitHMACWithSHA1[] = {
174     0x30, 0x81, 0xec, 0x30, 0x57, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
175     0x0d, 0x01, 0x05, 0x0d, 0x30, 0x4a, 0x30, 0x29, 0x06, 0x09, 0x2a, 0x86,
176     0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, 0x30, 0x1c, 0x04, 0x08, 0x90,
177     0xcd, 0x1e, 0x47, 0x1d, 0xff, 0x4c, 0xa8, 0x02, 0x02, 0x08, 0x00, 0x30,
178     0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x07, 0x05,
179     0x00, 0x30, 0x1d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
180     0x01, 0x02, 0x04, 0x10, 0x34, 0xe7, 0x5b, 0x9b, 0xf9, 0x17, 0xcf, 0x15,
181     0x59, 0x7c, 0xfd, 0xc1, 0xac, 0xed, 0x6f, 0xdd, 0x04, 0x81, 0x90, 0xe3,
182     0xd7, 0xfc, 0xbe, 0xe6, 0xe8, 0x92, 0xc1, 0xa2, 0x57, 0x42, 0x4b, 0xf1,
183     0x35, 0x6c, 0x4f, 0x58, 0x61, 0x14, 0x30, 0x4e, 0xa3, 0x8d, 0x4f, 0xde,
184     0x2d, 0x0b, 0xa2, 0x62, 0x4b, 0xee, 0x9f, 0xc4, 0xeb, 0x89, 0x33, 0x76,
185     0x3f, 0x0c, 0x20, 0xad, 0x75, 0x29, 0x42, 0xbc, 0xbd, 0x83, 0x46, 0x1d,
186     0x5c, 0xae, 0xec, 0x10, 0x05, 0xbb, 0xd3, 0x98, 0xc9, 0x5a, 0x5e, 0x0a,
187     0x95, 0x12, 0x1e, 0x65, 0x93, 0xdd, 0xdd, 0x51, 0xd5, 0x56, 0xc2, 0xa9,
188     0xf9, 0x43, 0x0f, 0x68, 0x8a, 0x14, 0x40, 0xe5, 0x62, 0x9e, 0x0d, 0xd7,
189     0x67, 0x62, 0xf4, 0x49, 0xb1, 0x62, 0x22, 0x42, 0xb1, 0xe1, 0xb2, 0x1d,
190     0x37, 0x3e, 0x95, 0x52, 0xe9, 0x61, 0x89, 0xc7, 0x62, 0xcc, 0xb1, 0x44,
191     0x40, 0xef, 0x89, 0xc8, 0xc4, 0x0e, 0xae, 0xa8, 0xf9, 0x17, 0x42, 0x2b,
192     0x8c, 0x0b, 0x26, 0xf6, 0x07, 0x00, 0xab, 0x25, 0x2b, 0x64, 0xcf, 0xc3,
193     0x68, 0xf9, 0x5e, 0x01, 0x66, 0x59, 0x5f, 0x3f, 0x05, 0x57, 0xcd,
194 };
195 
TestDecrypt(const uint8_t * der,size_t der_len,const char * password)196 static void TestDecrypt(const uint8_t *der, size_t der_len,
197                         const char *password) {
198   const uint8_t *data = der;
199   bssl::UniquePtr<X509_SIG> sig(d2i_X509_SIG(NULL, &data, der_len));
200   ASSERT_TRUE(sig.get());
201   ASSERT_EQ(der + der_len, data);
202 
203   bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> keypair(
204       PKCS8_decrypt(sig.get(), password, -1));
205   ASSERT_TRUE(keypair);
206 }
207 
TestRoundTrip(int pbe_nid,const EVP_CIPHER * cipher,const char * password,const uint8_t * salt,size_t salt_len,int iterations)208 static void TestRoundTrip(int pbe_nid, const EVP_CIPHER *cipher,
209                           const char *password, const uint8_t *salt,
210                           size_t salt_len, int iterations) {
211   static const uint8_t kSampleKey[] = {
212       0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
213       0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
214       0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20,
215       0x8a, 0x87, 0x2f, 0xb6, 0x28, 0x93, 0xc4, 0xd1, 0xff, 0xc5, 0xb9, 0xf0,
216       0xf9, 0x17, 0x58, 0x06, 0x9f, 0x83, 0x52, 0xe0, 0x8f, 0xa0, 0x5a, 0x49,
217       0xf8, 0xdb, 0x92, 0x6c, 0xb5, 0x72, 0x87, 0x25, 0xa1, 0x44, 0x03, 0x42,
218       0x00, 0x04, 0x2c, 0x15, 0x0f, 0x42, 0x9c, 0xe7, 0x0f, 0x21, 0x6c, 0x25,
219       0x2c, 0xf5, 0xe0, 0x62, 0xce, 0x1f, 0x63, 0x9c, 0xd5, 0xd1, 0x65, 0xc7,
220       0xf8, 0x94, 0x24, 0x07, 0x2c, 0x27, 0x19, 0x7d, 0x78, 0xb3, 0x3b, 0x92,
221       0x0e, 0x95, 0xcd, 0xb6, 0x64, 0xe9, 0x90, 0xdc, 0xf0, 0xcf, 0xea, 0x0d,
222       0x94, 0xe2, 0xa8, 0xe6, 0xaf, 0x9d, 0x0e, 0x58, 0x05, 0x6e, 0x65, 0x31,
223       0x04, 0x92, 0x5b, 0x9f, 0xe6, 0xc9,
224   };
225 
226   const uint8_t *ptr = kSampleKey;
227   bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> key(
228       d2i_PKCS8_PRIV_KEY_INFO(nullptr, &ptr, sizeof(kSampleKey)));
229   ASSERT_TRUE(key);
230   ASSERT_EQ(kSampleKey + sizeof(kSampleKey), ptr);
231 
232   bssl::UniquePtr<X509_SIG> encrypted(PKCS8_encrypt(
233       pbe_nid, cipher, password, -1, salt, salt_len, iterations, key.get()));
234   ASSERT_TRUE(encrypted);
235 
236   bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> key2(
237       PKCS8_decrypt(encrypted.get(), password, -1));
238   ASSERT_TRUE(key2);
239 
240   uint8_t *encoded = nullptr;
241   int len = i2d_PKCS8_PRIV_KEY_INFO(key2.get(), &encoded);
242   bssl::UniquePtr<uint8_t> free_encoded(encoded);
243   ASSERT_GE(len, 0);
244   ASSERT_EQ(static_cast<size_t>(len), sizeof(kSampleKey));
245   ASSERT_EQ(0, OPENSSL_memcmp(encoded, kSampleKey, sizeof(kSampleKey)));
246 }
247 
TEST(PKCS8Test,DecryptString)248 TEST(PKCS8Test, DecryptString) {
249   TestDecrypt(kEncryptedPBES2WithDESAndSHA1,
250               sizeof(kEncryptedPBES2WithDESAndSHA1), "testing");
251   TestDecrypt(kEncryptedPBES2WithAESAndSHA256,
252               sizeof(kEncryptedPBES2WithAESAndSHA256), "testing");
253 }
254 
TEST(PKCS8Test,DecryptNull)255 TEST(PKCS8Test, DecryptNull) {
256   TestDecrypt(kNullPassword, sizeof(kNullPassword), NULL);
257 }
258 
TEST(PKCS8Test,DecryptNullNSS)259 TEST(PKCS8Test, DecryptNullNSS) {
260   TestDecrypt(kNullPasswordNSS, sizeof(kNullPasswordNSS), NULL);
261 }
262 
TEST(PKCS8Test,DecryptEmptyStringOpenSSL)263 TEST(PKCS8Test, DecryptEmptyStringOpenSSL) {
264   TestDecrypt(kEmptyPasswordOpenSSL, sizeof(kEmptyPasswordOpenSSL), "");
265 }
266 
TEST(PKCS8Test,DecryptExplicitHMACWithSHA1)267 TEST(PKCS8Test, DecryptExplicitHMACWithSHA1) {
268   TestDecrypt(kExplicitHMACWithSHA1, sizeof(kExplicitHMACWithSHA1), "foo");
269 }
270 
TEST(PKCS8Test,RoundTripPBEWithrSHA1And3KeyTripleDES)271 TEST(PKCS8Test, RoundTripPBEWithrSHA1And3KeyTripleDES) {
272   // Test with different salts.
273   TestRoundTrip(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, nullptr,
274                 "password", nullptr, 0, 10);
275   TestRoundTrip(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, nullptr,
276                 "password", nullptr, 4, 10);
277   TestRoundTrip(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, nullptr,
278                 "password", (const uint8_t *)"salt", 4, 10);
279   // Test with a different iteration count.
280   TestRoundTrip(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, nullptr,
281                 "password", nullptr, 0, 1);
282 }
283 
284 // Test that both "" (empty password, encoded as "\0\0") and nullptr (no
285 // password, encoded as "") work.
TEST(PKCS8Test,RoundTripPBEWithSHA1And3KeyTripleDESEmptyPassword)286 TEST(PKCS8Test, RoundTripPBEWithSHA1And3KeyTripleDESEmptyPassword) {
287   TestRoundTrip(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, nullptr, "",
288                 nullptr, 0, 1);
289   TestRoundTrip(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, nullptr, nullptr,
290                 nullptr, 0, 1);
291 }
292 
TEST(PKCS8Test,RoundTripPBEWithSHA1And40BitRC2CBC)293 TEST(PKCS8Test, RoundTripPBEWithSHA1And40BitRC2CBC) {
294   TestRoundTrip(NID_pbe_WithSHA1And40BitRC2_CBC, nullptr, "password",
295                 nullptr, 0, 10);
296 }
297 
TEST(PKCS8Test,RoundTripPBEWithSHA1And128BitRC4)298 TEST(PKCS8Test, RoundTripPBEWithSHA1And128BitRC4) {
299   TestRoundTrip(NID_pbe_WithSHA1And128BitRC4, nullptr, "password",
300                 nullptr, 0, 10);
301 }
302 
TEST(PKCS8Test,RoundTripPBES2)303 TEST(PKCS8Test, RoundTripPBES2) {
304   TestRoundTrip(-1, EVP_aes_128_cbc(), "password", nullptr, 0, 10);
305   TestRoundTrip(-1, EVP_aes_128_cbc(), "password", nullptr, 4, 10);
306   TestRoundTrip(-1, EVP_aes_128_cbc(), "password", (const uint8_t *)"salt",
307                 4, 10);
308   TestRoundTrip(-1, EVP_aes_128_cbc(), "password", nullptr, 0, 1);
309   TestRoundTrip(-1, EVP_rc2_cbc(), "password", nullptr, 0, 10);
310 }
311 
TEST(PKCS8Test,InvalidPBES1NIDs)312 TEST(PKCS8Test, InvalidPBES1NIDs) {
313   static const uint8_t kSampleKey[] = {
314       0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
315       0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
316       0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20,
317       0x8a, 0x87, 0x2f, 0xb6, 0x28, 0x93, 0xc4, 0xd1, 0xff, 0xc5, 0xb9, 0xf0,
318       0xf9, 0x17, 0x58, 0x06, 0x9f, 0x83, 0x52, 0xe0, 0x8f, 0xa0, 0x5a, 0x49,
319       0xf8, 0xdb, 0x92, 0x6c, 0xb5, 0x72, 0x87, 0x25, 0xa1, 0x44, 0x03, 0x42,
320       0x00, 0x04, 0x2c, 0x15, 0x0f, 0x42, 0x9c, 0xe7, 0x0f, 0x21, 0x6c, 0x25,
321       0x2c, 0xf5, 0xe0, 0x62, 0xce, 0x1f, 0x63, 0x9c, 0xd5, 0xd1, 0x65, 0xc7,
322       0xf8, 0x94, 0x24, 0x07, 0x2c, 0x27, 0x19, 0x7d, 0x78, 0xb3, 0x3b, 0x92,
323       0x0e, 0x95, 0xcd, 0xb6, 0x64, 0xe9, 0x90, 0xdc, 0xf0, 0xcf, 0xea, 0x0d,
324       0x94, 0xe2, 0xa8, 0xe6, 0xaf, 0x9d, 0x0e, 0x58, 0x05, 0x6e, 0x65, 0x31,
325       0x04, 0x92, 0x5b, 0x9f, 0xe6, 0xc9,
326   };
327 
328   const uint8_t *ptr = kSampleKey;
329   bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> key(
330       d2i_PKCS8_PRIV_KEY_INFO(nullptr, &ptr, sizeof(kSampleKey)));
331   ASSERT_TRUE(key);
332   ASSERT_EQ(kSampleKey + sizeof(kSampleKey), ptr);
333 
334   bssl::UniquePtr<X509_SIG> encrypted(PKCS8_encrypt(
335       NID_pbes2, nullptr, "password", -1, nullptr, 0, 0, key.get()));
336   EXPECT_FALSE(encrypted);
337 
338   encrypted.reset(PKCS8_encrypt(NID_undef, nullptr, "password", -1, nullptr, 0,
339                                 0, key.get()));
340   EXPECT_FALSE(encrypted);
341 
342   encrypted.reset(PKCS8_encrypt(NID_rsaEncryption, nullptr, "password", -1,
343                                 nullptr, 0, 0, key.get()));
344   EXPECT_FALSE(encrypted);
345 }
346