1 // Copyright 2014 The BoringSSL Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <gtest/gtest.h>
16
17 #include <openssl/bio.h>
18 #include <openssl/bytestring.h>
19 #include <openssl/crypto.h>
20 #include <openssl/err.h>
21 #include <openssl/evp.h>
22 #include <openssl/pkcs8.h>
23 #include <openssl/mem.h>
24 #include <openssl/span.h>
25 #include <openssl/stack.h>
26 #include <openssl/x509.h>
27
28 #include "../test/test_data.h"
29 #include "../test/test_util.h"
30
31
32 // kPassword is the password shared by most of the sample PKCS#12 files.
33 static const char kPassword[] = "foo";
34
35 // kUnicodePassword is the password for unicode_password.p12
36 static const char kUnicodePassword[] = "Hello, 世界";
37
TestImpl(const char * name,bssl::Span<const uint8_t> der,const char * password,const char * friendly_name)38 static void TestImpl(const char *name, bssl::Span<const uint8_t> der,
39 const char *password,
40 const char *friendly_name) {
41 SCOPED_TRACE(name);
42 bssl::UniquePtr<STACK_OF(X509)> certs(sk_X509_new_null());
43 ASSERT_TRUE(certs);
44
45 EVP_PKEY *key = nullptr;
46 CBS pkcs12 = der;
47 ASSERT_TRUE(PKCS12_get_key_and_certs(&key, certs.get(), &pkcs12, password));
48 bssl::UniquePtr<EVP_PKEY> delete_key(key);
49
50 ASSERT_EQ(1u, sk_X509_num(certs.get()));
51 ASSERT_TRUE(key);
52
53 int actual_name_len;
54 const uint8_t *actual_name =
55 X509_alias_get0(sk_X509_value(certs.get(), 0), &actual_name_len);
56 if (friendly_name == nullptr) {
57 EXPECT_EQ(nullptr, actual_name);
58 } else {
59 EXPECT_EQ(friendly_name, bssl::BytesAsStringView(
60 bssl::Span(actual_name, actual_name_len)));
61 }
62 }
63
TestCompat(bssl::Span<const uint8_t> der)64 static void TestCompat(bssl::Span<const uint8_t> der) {
65 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(der.data(), der.size()));
66 ASSERT_TRUE(bio);
67
68 bssl::UniquePtr<PKCS12> p12(d2i_PKCS12_bio(bio.get(), nullptr));
69 ASSERT_TRUE(p12);
70
71 ASSERT_FALSE(PKCS12_verify_mac(p12.get(), "badpass", 7));
72 ASSERT_TRUE(PKCS12_verify_mac(p12.get(), kPassword, sizeof(kPassword) - 1));
73
74 EVP_PKEY *key = nullptr;
75 X509 *cert = nullptr;
76 STACK_OF(X509) *ca_certs = nullptr;
77 ASSERT_TRUE(PKCS12_parse(p12.get(), kPassword, &key, &cert, &ca_certs));
78
79 bssl::UniquePtr<EVP_PKEY> delete_key(key);
80 bssl::UniquePtr<X509> delete_cert(cert);
81 bssl::UniquePtr<STACK_OF(X509)> delete_ca_certs(ca_certs);
82
83 ASSERT_TRUE(key);
84 ASSERT_TRUE(cert);
85 ASSERT_EQ(0u, sk_X509_num(ca_certs));
86 }
87
TEST(PKCS12Test,TestOpenSSL)88 TEST(PKCS12Test, TestOpenSSL) {
89 // openssl.p12 was generated by OpenSSL with:
90 // openssl pkcs12 -export -inkey key.pem -in cacert.pem
91 std::string data = GetTestData("crypto/pkcs8/test/openssl.p12");
92 TestImpl("OpenSSL", bssl::StringAsBytes(data), kPassword, nullptr);
93 }
94
TEST(PKCS12Test,TestNSS)95 TEST(PKCS12Test, TestNSS) {
96 // nss.p12 is the result of importing the OpenSSL example PKCS#12 into Chrome
97 // on Linux and then exporting it again.
98 std::string data = GetTestData("crypto/pkcs8/test/nss.p12");
99 TestImpl("NSS", bssl::StringAsBytes(data), kPassword,
100 "Internet Widgits Pty Ltd");
101 }
102
TEST(PKCS12Test,TestWindows)103 TEST(PKCS12Test, TestWindows) {
104 // windows.p12 is a dummy key and certificate exported from the certificate
105 // manager on Windows 7. It has a friendlyName, but only on the key, where we
106 // ignore it, and not the certificate.
107 std::string data = GetTestData("crypto/pkcs8/test/windows.p12");
108 TestImpl("Windows", bssl::StringAsBytes(data), kPassword, nullptr);
109 }
110
TEST(PKCS12Test,TestPBES2)111 TEST(PKCS12Test, TestPBES2) {
112 // pbes2_sha1.p12 is a PKCS#12 file using PBES2 and HMAC-SHA-1 created with:
113 // openssl pkcs12 -export -inkey key.pem -in cert.pem -keypbe AES-128-CBC
114 // -certpbe AES-128-CBC
115 //
116 // This was generated with an older OpenSSL, which used hmacWithSHA1 as the
117 // PRF. (There is currently no way to specify the PRF in the pkcs12 command.)
118 std::string data = GetTestData("crypto/pkcs8/test/pbes2_sha1.p12");
119 TestImpl("kPBES2WithSHA1", bssl::StringAsBytes(data), kPassword, nullptr);
120
121 // pbes2_sha256.p12 is a PKCS#12 file using PBES2 and HMAC-SHA-256. It was
122 // generated in the same way as pbes2_sha1.p12, but using OpenSSL 1.1.1b,
123 // which uses hmacWithSHA256 as the PRF.
124 data = GetTestData("crypto/pkcs8/test/pbes2_sha256.p12");
125 TestImpl("kPBES2WithSHA256", bssl::StringAsBytes(data), kPassword, nullptr);
126 }
127
TEST(PKCS12Test,TestNoEncryption)128 TEST(PKCS12Test, TestNoEncryption) {
129 // no_encryption.p12 is a PKCS#12 file with neither the key or certificate is
130 // encrypted. It was generated with:
131 //
132 // openssl pkcs12 -export -inkey ecdsa_p256_key.pem -in ecdsa_p256_cert.pem -keypbe NONE -certpbe NONE -password pass:foo
133 std::string data = GetTestData("crypto/pkcs8/test/no_encryption.p12");
134 TestImpl("kNoEncryption", bssl::StringAsBytes(data), kPassword, nullptr);
135 }
136
TEST(PKCS12Test,TestEmptyPassword)137 TEST(PKCS12Test, TestEmptyPassword) {
138 // Generated with
139 // openssl pkcs12 -export -inkey ecdsa_p256_key.pem -in ecdsa_p256_cert.pem -password pass:
140 std::string data = GetTestData("crypto/pkcs8/test/empty_password.p12");
141 TestImpl("EmptyPassword (empty password)", bssl::StringAsBytes(data), "",
142 nullptr);
143 TestImpl("EmptyPassword (null password)", bssl::StringAsBytes(data), nullptr,
144 nullptr);
145
146 // The above input, modified to have a constructed string.
147 data = GetTestData("crypto/pkcs8/test/empty_password_ber.p12");
148 TestImpl("EmptyPassword (BER, empty password)", bssl::StringAsBytes(data), "",
149 nullptr);
150 TestImpl("EmptyPassword (BER, null password)", bssl::StringAsBytes(data),
151 nullptr, nullptr);
152
153 // The constructed string with too much recursion.
154 data = GetTestData("crypto/pkcs8/test/empty_password_ber_nested.p12");
155 bssl::UniquePtr<STACK_OF(X509)> certs(sk_X509_new_null());
156 ASSERT_TRUE(certs);
157 EVP_PKEY *key = nullptr;
158 CBS pkcs12 = bssl::StringAsBytes(data);
159 EXPECT_FALSE(PKCS12_get_key_and_certs(&key, certs.get(), &pkcs12, ""));
160 }
161
TEST(PKCS12Test,TestNullPassword)162 TEST(PKCS12Test, TestNullPassword) {
163 // Generated with
164 // openssl pkcs12 -export -inkey ecdsa_p256_key.pem -in ecdsa_p256_cert.pem -password pass:
165 // But with OpenSSL patched to pass NULL into PKCS12_create and
166 // PKCS12_set_mac.
167 std::string data = GetTestData("crypto/pkcs8/test/null_password.p12");
168 TestImpl("NullPassword (empty password)", bssl::StringAsBytes(data), "",
169 nullptr);
170 TestImpl("NullPassword (null password)", bssl::StringAsBytes(data), nullptr,
171 nullptr);
172 }
173
TEST(PKCS12Test,TestUnicode)174 TEST(PKCS12Test, TestUnicode) {
175 // Generated with
176 // openssl pkcs12 -export -inkey ecdsa_p256_key.pem -in ecdsa_p256_cert.pem -password pass:"Hello, 世界"
177 std::string data = GetTestData("crypto/pkcs8/test/unicode_password.p12");
178 TestImpl("Unicode", bssl::StringAsBytes(data), kUnicodePassword, nullptr);
179 }
180
TEST(PKCS12Test,TestWindowsCompat)181 TEST(PKCS12Test, TestWindowsCompat) {
182 std::string data = GetTestData("crypto/pkcs8/test/windows.p12");
183 TestCompat(bssl::StringAsBytes(data));
184 }
185
186 // kTestKey is a test P-256 key.
187 static const uint8_t kTestKey[] = {
188 0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
189 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
190 0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20,
191 0x07, 0x0f, 0x08, 0x72, 0x7a, 0xd4, 0xa0, 0x4a, 0x9c, 0xdd, 0x59, 0xc9,
192 0x4d, 0x89, 0x68, 0x77, 0x08, 0xb5, 0x6f, 0xc9, 0x5d, 0x30, 0x77, 0x0e,
193 0xe8, 0xd1, 0xc9, 0xce, 0x0a, 0x8b, 0xb4, 0x6a, 0xa1, 0x44, 0x03, 0x42,
194 0x00, 0x04, 0xe6, 0x2b, 0x69, 0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f,
195 0x1e, 0x0d, 0x94, 0x8a, 0x4c, 0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e, 0x0d,
196 0x46, 0xfb, 0xdd, 0xa9, 0xa9, 0x1e, 0x9d, 0xdc, 0xba, 0x5a, 0x01, 0xe7,
197 0xd6, 0x97, 0xa8, 0x0a, 0x18, 0xf9, 0xc3, 0xc4, 0xa3, 0x1e, 0x56, 0xe2,
198 0x7c, 0x83, 0x48, 0xdb, 0x16, 0x1a, 0x1c, 0xf5, 0x1d, 0x7e, 0xf1, 0x94,
199 0x2d, 0x4b, 0xcf, 0x72, 0x22, 0xc1};
200
201 // kTestCert is a certificate for |kTestKey|.
202 static const uint8_t kTestCert[] = {
203 0x30, 0x82, 0x01, 0xcf, 0x30, 0x82, 0x01, 0x76, 0xa0, 0x03, 0x02, 0x01,
204 0x02, 0x02, 0x09, 0x00, 0xd9, 0x4c, 0x04, 0xda, 0x49, 0x7d, 0xbf, 0xeb,
205 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x30,
206 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
207 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
208 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31,
209 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49, 0x6e,
210 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69,
211 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e,
212 0x17, 0x0d, 0x31, 0x34, 0x30, 0x34, 0x32, 0x33, 0x32, 0x33, 0x32, 0x31,
213 0x35, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x35, 0x32, 0x33, 0x32,
214 0x33, 0x32, 0x31, 0x35, 0x37, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09,
215 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30,
216 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65,
217 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
218 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
219 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74,
220 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a,
221 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
222 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xe6, 0x2b, 0x69, 0xe2,
223 0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f, 0x1e, 0x0d, 0x94, 0x8a, 0x4c, 0xd5,
224 0x97, 0x6b, 0xb7, 0xa9, 0x1e, 0x0d, 0x46, 0xfb, 0xdd, 0xa9, 0xa9, 0x1e,
225 0x9d, 0xdc, 0xba, 0x5a, 0x01, 0xe7, 0xd6, 0x97, 0xa8, 0x0a, 0x18, 0xf9,
226 0xc3, 0xc4, 0xa3, 0x1e, 0x56, 0xe2, 0x7c, 0x83, 0x48, 0xdb, 0x16, 0x1a,
227 0x1c, 0xf5, 0x1d, 0x7e, 0xf1, 0x94, 0x2d, 0x4b, 0xcf, 0x72, 0x22, 0xc1,
228 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
229 0x16, 0x04, 0x14, 0xab, 0x84, 0xd2, 0xac, 0xab, 0x95, 0xf0, 0x82, 0x4e,
230 0x16, 0x78, 0x07, 0x55, 0x57, 0x5f, 0xe4, 0x26, 0x8d, 0x82, 0xd1, 0x30,
231 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
232 0xab, 0x84, 0xd2, 0xac, 0xab, 0x95, 0xf0, 0x82, 0x4e, 0x16, 0x78, 0x07,
233 0x55, 0x57, 0x5f, 0xe4, 0x26, 0x8d, 0x82, 0xd1, 0x30, 0x0c, 0x06, 0x03,
234 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x09,
235 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x03, 0x48, 0x00,
236 0x30, 0x45, 0x02, 0x21, 0x00, 0xf2, 0xa0, 0x35, 0x5e, 0x51, 0x3a, 0x36,
237 0xc3, 0x82, 0x79, 0x9b, 0xee, 0x27, 0x50, 0x85, 0x8e, 0x70, 0x06, 0x74,
238 0x95, 0x57, 0xd2, 0x29, 0x74, 0x00, 0xf4, 0xbe, 0x15, 0x87, 0x5d, 0xc4,
239 0x07, 0x02, 0x20, 0x7c, 0x1e, 0x79, 0x14, 0x6a, 0x21, 0x83, 0xf0, 0x7a,
240 0x74, 0x68, 0x79, 0x5f, 0x14, 0x99, 0x9a, 0x68, 0xb4, 0xf1, 0xcb, 0x9e,
241 0x15, 0x5e, 0xe6, 0x1f, 0x32, 0x52, 0x61, 0x5e, 0x75, 0xc9, 0x14};
242
243 // kTestCert2 is a different test certificate.
244 static const uint8_t kTestCert2[] = {
245 0x30, 0x82, 0x02, 0x65, 0x30, 0x82, 0x01, 0xeb, 0xa0, 0x03, 0x02, 0x01,
246 0x02, 0x02, 0x09, 0x00, 0xdf, 0xbf, 0x2e, 0xe6, 0xe9, 0x0f, 0x0c, 0x4d,
247 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x30,
248 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
249 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
250 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31,
251 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e,
252 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69,
253 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e,
254 0x17, 0x0d, 0x31, 0x36, 0x30, 0x37, 0x30, 0x39, 0x30, 0x30, 0x30, 0x31,
255 0x33, 0x32, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x30, 0x38, 0x30,
256 0x30, 0x30, 0x31, 0x33, 0x32, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09,
257 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30,
258 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65,
259 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
260 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
261 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74,
262 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a,
263 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00,
264 0x22, 0x03, 0x62, 0x00, 0x04, 0x0e, 0x75, 0x32, 0x4d, 0xab, 0x18, 0x99,
265 0xf8, 0x1e, 0xbc, 0xb4, 0x26, 0x55, 0xe0, 0x61, 0x09, 0xc0, 0x32, 0x75,
266 0xf2, 0x32, 0xbd, 0x80, 0x5c, 0xef, 0x79, 0xf7, 0x04, 0x01, 0x09, 0x6e,
267 0x06, 0x28, 0xe3, 0xac, 0xc8, 0xdf, 0x94, 0xbf, 0x91, 0x64, 0x04, 0xfa,
268 0xe0, 0x4c, 0x56, 0xcd, 0xe7, 0x51, 0x32, 0x9f, 0x4f, 0x0f, 0xd0, 0x96,
269 0x4f, 0x3f, 0x61, 0x1b, 0xf2, 0xb3, 0xe2, 0xaf, 0xe5, 0xf7, 0x9d, 0x98,
270 0xb0, 0x88, 0x72, 0xec, 0xb4, 0xc6, 0x5f, 0x3c, 0x32, 0xef, 0x9e, 0x3d,
271 0x59, 0x43, 0xa2, 0xf8, 0xdd, 0xda, 0x5b, 0xca, 0x6c, 0x0e, 0x3b, 0x70,
272 0xcd, 0x63, 0x59, 0x5e, 0xa5, 0xa3, 0x81, 0xa7, 0x30, 0x81, 0xa4, 0x30,
273 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa9, 0x98,
274 0x3e, 0x30, 0x03, 0x70, 0xe9, 0x68, 0x80, 0xe3, 0x14, 0xe8, 0x3f, 0x70,
275 0x95, 0xfb, 0x48, 0x58, 0xc8, 0xfa, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d,
276 0x23, 0x04, 0x6e, 0x30, 0x6c, 0x80, 0x14, 0xa9, 0x98, 0x3e, 0x30, 0x03,
277 0x70, 0xe9, 0x68, 0x80, 0xe3, 0x14, 0xe8, 0x3f, 0x70, 0x95, 0xfb, 0x48,
278 0x58, 0xc8, 0xfa, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, 0x0b, 0x30,
279 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13,
280 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d,
281 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06,
282 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e,
283 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50,
284 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0xdf, 0xbf, 0x2e,
285 0xe6, 0xe9, 0x0f, 0x0c, 0x4d, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13,
286 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x09, 0x06, 0x07, 0x2a,
287 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x03, 0x69, 0x00, 0x30, 0x66, 0x02,
288 0x31, 0x00, 0xd3, 0x7c, 0xbd, 0x0e, 0x91, 0x11, 0xa7, 0x4b, 0x96, 0x5e,
289 0xb6, 0xcc, 0x5a, 0x80, 0x0b, 0x99, 0xa8, 0xcd, 0x99, 0xca, 0xfe, 0x5a,
290 0xda, 0x0e, 0xee, 0xe9, 0xe1, 0x4b, 0x0b, 0x1d, 0xab, 0xa5, 0x3b, 0x90,
291 0x9d, 0xd5, 0x8e, 0xb4, 0x49, 0xe6, 0x56, 0x8d, 0xf0, 0x8d, 0x30, 0xed,
292 0x90, 0x37, 0x02, 0x31, 0x00, 0xa0, 0xfb, 0x4e, 0x57, 0x4a, 0xa1, 0x05,
293 0x72, 0xac, 0x5d, 0x5c, 0xc6, 0x49, 0x32, 0x1a, 0xa3, 0xda, 0x34, 0xbe,
294 0xb5, 0x6b, 0x9c, 0x76, 0x00, 0xec, 0xb6, 0x9f, 0xf5, 0x2b, 0x32, 0x64,
295 0x6e, 0xcb, 0xa9, 0x4a, 0x30, 0x73, 0x23, 0x27, 0x23, 0x54, 0x12, 0x8b,
296 0x75, 0x1c, 0x2d, 0x36, 0x0f};
297
LoadX509(bssl::Span<const uint8_t> der)298 static bssl::UniquePtr<X509> LoadX509(bssl::Span<const uint8_t> der) {
299 const uint8_t *ptr = der.data();
300 return bssl::UniquePtr<X509>(d2i_X509(nullptr, &ptr, der.size()));
301 }
302
LoadPrivateKey(bssl::Span<const uint8_t> der)303 static bssl::UniquePtr<EVP_PKEY> LoadPrivateKey(bssl::Span<const uint8_t> der) {
304 CBS cbs = der;
305 return bssl::UniquePtr<EVP_PKEY>(EVP_parse_private_key(&cbs));
306 }
307
TestRoundTrip(const char * password,const char * name,bssl::Span<const uint8_t> key_der,bssl::Span<const uint8_t> cert_der,std::vector<bssl::Span<const uint8_t>> chain_der,int key_nid,int cert_nid,int iterations,int mac_iterations)308 static void TestRoundTrip(const char *password, const char *name,
309 bssl::Span<const uint8_t> key_der,
310 bssl::Span<const uint8_t> cert_der,
311 std::vector<bssl::Span<const uint8_t>> chain_der,
312 int key_nid, int cert_nid, int iterations,
313 int mac_iterations) {
314 bssl::UniquePtr<EVP_PKEY> key;
315 if (!key_der.empty()) {
316 key = LoadPrivateKey(key_der);
317 ASSERT_TRUE(key);
318 }
319 bssl::UniquePtr<X509> cert;
320 if (!cert_der.empty()) {
321 cert = LoadX509(cert_der);
322 ASSERT_TRUE(cert);
323 }
324 bssl::UniquePtr<STACK_OF(X509)> chain;
325 if (!chain_der.empty()) {
326 chain.reset(sk_X509_new_null());
327 ASSERT_TRUE(chain);
328 for (auto der : chain_der) {
329 bssl::UniquePtr<X509> x509 = LoadX509(der);
330 ASSERT_TRUE(x509);
331 ASSERT_TRUE(bssl::PushToStack(chain.get(), std::move(x509)));
332 }
333 }
334
335 // Make a PKCS#12 blob.
336 bssl::UniquePtr<PKCS12> pkcs12(
337 PKCS12_create(password, name, key.get(), cert.get(), chain.get(), key_nid,
338 cert_nid, iterations, mac_iterations, 0));
339 ASSERT_TRUE(pkcs12);
340 uint8_t *der = nullptr;
341 int len = i2d_PKCS12(pkcs12.get(), &der);
342 ASSERT_GT(len, 0);
343 bssl::UniquePtr<uint8_t> free_der(der);
344
345 // Check that the result round-trips.
346 CBS cbs;
347 CBS_init(&cbs, der, len);
348 EVP_PKEY *key2 = nullptr;
349 bssl::UniquePtr<STACK_OF(X509)> certs2(sk_X509_new_null());
350 ASSERT_TRUE(certs2);
351 ASSERT_TRUE(PKCS12_get_key_and_certs(&key2, certs2.get(), &cbs, password));
352 bssl::UniquePtr<EVP_PKEY> free_key2(key2);
353 // Note |EVP_PKEY_cmp| returns one for equality while |X509_cmp| returns zero.
354 if (key) {
355 EXPECT_EQ(1, EVP_PKEY_cmp(key2, key.get()));
356 } else {
357 EXPECT_FALSE(key2);
358 }
359 size_t offset = cert ? 1 : 0;
360 ASSERT_EQ(offset + chain_der.size(), sk_X509_num(certs2.get()));
361 if (cert) {
362 EXPECT_EQ(0, X509_cmp(cert.get(), sk_X509_value(certs2.get(), 0)));
363 }
364 for (size_t i = 0; i < chain_der.size(); i++) {
365 EXPECT_EQ(0, X509_cmp(sk_X509_value(chain.get(), i),
366 sk_X509_value(certs2.get(), i + offset)));
367 }
368 if (sk_X509_num(certs2.get()) > 0) {
369 int actual_name_len;
370 const uint8_t *actual_name =
371 X509_alias_get0(sk_X509_value(certs2.get(), 0), &actual_name_len);
372 if (name == NULL) {
373 EXPECT_EQ(nullptr, actual_name);
374 } else {
375 EXPECT_EQ(name, bssl::BytesAsStringView(
376 bssl::Span(actual_name, actual_name_len)));
377 }
378 }
379
380 // Check that writing to a |BIO| does the same thing.
381 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
382 ASSERT_TRUE(bio);
383 ASSERT_TRUE(i2d_PKCS12_bio(bio.get(), pkcs12.get()));
384 const uint8_t *bio_data;
385 size_t bio_len;
386 ASSERT_TRUE(BIO_mem_contents(bio.get(), &bio_data, &bio_len));
387 EXPECT_EQ(Bytes(bio_data, bio_len), Bytes(der, len));
388 }
389
TEST(PKCS12Test,RoundTrip)390 TEST(PKCS12Test, RoundTrip) {
391 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
392 {kTestCert2}, 0, 0, 0, 0);
393
394 // Test some Unicode.
395 TestRoundTrip(kPassword, "Hello, 世界!", kTestKey, kTestCert, {kTestCert2}, 0,
396 0, 0, 0);
397 TestRoundTrip(kUnicodePassword, nullptr /* no name */, kTestKey, kTestCert,
398 {kTestCert2}, 0, 0, 0, 0);
399
400 // Test various fields being missing.
401 TestRoundTrip(kPassword, nullptr /* no name */, {} /* no key */, kTestCert,
402 {kTestCert2}, 0, 0, 0, 0);
403 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
404 {} /* no chain */, 0, 0, 0, 0);
405 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, {} /* no leaf */,
406 {} /* no chain */, 0, 0, 0, 0);
407
408 // Test encryption parameters.
409 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
410 {kTestCert2}, NID_pbe_WithSHA1And40BitRC2_CBC,
411 NID_pbe_WithSHA1And40BitRC2_CBC, 100, 100);
412 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
413 {kTestCert2}, NID_pbe_WithSHA1And128BitRC4,
414 NID_pbe_WithSHA1And128BitRC4, 100, 100);
415 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
416 {kTestCert2}, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
417 NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 100, 100);
418
419 // PBES2 ciphers.
420 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
421 {kTestCert2}, NID_rc2_cbc, NID_rc2_cbc, 100, 100);
422 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
423 {kTestCert2}, NID_des_ede3_cbc, NID_des_ede3_cbc, 100, 100);
424 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
425 {kTestCert2}, NID_aes_128_cbc, NID_aes_128_cbc, 100, 100);
426 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
427 {kTestCert2}, NID_aes_192_cbc, NID_aes_192_cbc, 100, 100);
428 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
429 {kTestCert2}, NID_aes_256_cbc, NID_aes_256_cbc, 100, 100);
430
431 // Mix and match.
432 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
433 {kTestCert2}, NID_pbe_WithSHA1And40BitRC2_CBC,
434 NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 100, 100);
435 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
436 {kTestCert2}, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
437 NID_aes_256_cbc, 100, 100);
438 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
439 {kTestCert2}, NID_aes_256_cbc,
440 NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 100, 100);
441 TestRoundTrip(kPassword, nullptr /* no name */, kTestKey, kTestCert,
442 {kTestCert2}, NID_aes_128_cbc, NID_aes_256_cbc, 100, 100);
443
444 // Test unencrypted and partially unencrypted PKCS#12 files.
445 TestRoundTrip(kPassword, /*name=*/nullptr, kTestKey, kTestCert, {kTestCert2},
446 /*key_nid=*/-1,
447 /*cert_nid=*/-1, /*iterations=*/100, /*mac_iterations=*/100);
448 TestRoundTrip(kPassword, /*name=*/nullptr, kTestKey, kTestCert, {kTestCert2},
449 /*key_nid=*/NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
450 /*cert_nid=*/-1, /*iterations=*/100, /*mac_iterations=*/100);
451 TestRoundTrip(kPassword, /*name=*/nullptr, kTestKey, kTestCert, {kTestCert2},
452 /*key_nid=*/-1,
453 /*cert_nid=*/NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
454 /*iterations=*/100, /*mac_iterations=*/100);
455 }
456
MakeTestKey()457 static bssl::UniquePtr<EVP_PKEY> MakeTestKey() {
458 bssl::UniquePtr<EC_KEY> ec_key(
459 EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
460 if (!ec_key ||
461 !EC_KEY_generate_key(ec_key.get())) {
462 return nullptr;
463 }
464 bssl::UniquePtr<EVP_PKEY> evp_pkey(EVP_PKEY_new());
465 if (!evp_pkey ||
466 !EVP_PKEY_assign_EC_KEY(evp_pkey.get(), ec_key.release())) {
467 return nullptr;
468 }
469 return evp_pkey;
470 }
471
MakeTestCert(EVP_PKEY * key)472 static bssl::UniquePtr<X509> MakeTestCert(EVP_PKEY *key) {
473 bssl::UniquePtr<X509> x509(X509_new());
474 if (!x509) {
475 return nullptr;
476 }
477 X509_NAME* subject = X509_get_subject_name(x509.get());
478 if (!X509_gmtime_adj(X509_get_notBefore(x509.get()), 0) ||
479 !X509_gmtime_adj(X509_get_notAfter(x509.get()), 60 * 60 * 24) ||
480 !X509_NAME_add_entry_by_txt(subject, "CN", MBSTRING_ASC,
481 reinterpret_cast<const uint8_t *>("Test"), -1,
482 -1, 0) ||
483 !X509_set_issuer_name(x509.get(), subject) ||
484 !X509_set_pubkey(x509.get(), key) ||
485 !X509_sign(x509.get(), key, EVP_sha256())) {
486 return nullptr;
487 }
488 return x509;
489 }
490
PKCS12CreateVector(std::vector<uint8_t> * out,EVP_PKEY * pkey,const std::vector<X509 * > & certs)491 static bool PKCS12CreateVector(std::vector<uint8_t> *out, EVP_PKEY *pkey,
492 const std::vector<X509 *> &certs) {
493 bssl::UniquePtr<STACK_OF(X509)> chain(sk_X509_new_null());
494 if (!chain) {
495 return false;
496 }
497
498 for (X509 *cert : certs) {
499 if (!bssl::PushToStack(chain.get(), bssl::UpRef(cert))) {
500 return false;
501 }
502 }
503
504 bssl::UniquePtr<PKCS12> p12(PKCS12_create(kPassword, nullptr /* name */, pkey,
505 nullptr /* cert */, chain.get(), 0,
506 0, 0, 0, 0));
507 if (!p12) {
508 return false;
509 }
510
511 int len = i2d_PKCS12(p12.get(), nullptr);
512 if (len < 0) {
513 return false;
514 }
515 out->resize(static_cast<size_t>(len));
516 uint8_t *ptr = out->data();
517 return i2d_PKCS12(p12.get(), &ptr) == len;
518 }
519
ExpectPKCS12Parse(bssl::Span<const uint8_t> in,EVP_PKEY * expect_key,X509 * expect_cert,const std::vector<X509 * > & expect_ca_certs)520 static void ExpectPKCS12Parse(bssl::Span<const uint8_t> in,
521 EVP_PKEY *expect_key, X509 *expect_cert,
522 const std::vector<X509 *> &expect_ca_certs) {
523 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(in.data(), in.size()));
524 ASSERT_TRUE(bio);
525
526 bssl::UniquePtr<PKCS12> p12(d2i_PKCS12_bio(bio.get(), nullptr));
527 ASSERT_TRUE(p12);
528
529 EVP_PKEY *key = nullptr;
530 X509 *cert = nullptr;
531 STACK_OF(X509) *ca_certs = nullptr;
532 ASSERT_TRUE(PKCS12_parse(p12.get(), kPassword, &key, &cert, &ca_certs));
533
534 bssl::UniquePtr<EVP_PKEY> delete_key(key);
535 bssl::UniquePtr<X509> delete_cert(cert);
536 bssl::UniquePtr<STACK_OF(X509)> delete_ca_certs(ca_certs);
537
538 if (expect_key == nullptr) {
539 EXPECT_FALSE(key);
540 } else {
541 ASSERT_TRUE(key);
542 EXPECT_EQ(1, EVP_PKEY_cmp(key, expect_key));
543 }
544
545 if (expect_cert == nullptr) {
546 EXPECT_FALSE(cert);
547 } else {
548 ASSERT_TRUE(cert);
549 EXPECT_EQ(0, X509_cmp(cert, expect_cert));
550 }
551
552 ASSERT_EQ(expect_ca_certs.size(), sk_X509_num(ca_certs));
553 for (size_t i = 0; i < expect_ca_certs.size(); i++) {
554 EXPECT_EQ(0, X509_cmp(expect_ca_certs[i], sk_X509_value(ca_certs, i)));
555 }
556 }
557
558 // Test that |PKCS12_parse| returns values in the expected order.
TEST(PKCS12Test,Order)559 TEST(PKCS12Test, Order) {
560 bssl::UniquePtr<EVP_PKEY> key1 = MakeTestKey();
561 ASSERT_TRUE(key1);
562 bssl::UniquePtr<X509> cert1 = MakeTestCert(key1.get());
563 ASSERT_TRUE(cert1);
564 bssl::UniquePtr<X509> cert1b = MakeTestCert(key1.get());
565 ASSERT_TRUE(cert1b);
566 bssl::UniquePtr<EVP_PKEY> key2 = MakeTestKey();
567 ASSERT_TRUE(key2);
568 bssl::UniquePtr<X509> cert2 = MakeTestCert(key2.get());
569 ASSERT_TRUE(cert2);
570 bssl::UniquePtr<EVP_PKEY> key3 = MakeTestKey();
571 ASSERT_TRUE(key3);
572 bssl::UniquePtr<X509> cert3 = MakeTestCert(key3.get());
573 ASSERT_TRUE(cert3);
574
575 // PKCS12_parse uses the key to select the main certificate.
576 std::vector<uint8_t> p12;
577 ASSERT_TRUE(PKCS12CreateVector(&p12, key1.get(),
578 {cert1.get(), cert2.get(), cert3.get()}));
579 ExpectPKCS12Parse(p12, key1.get(), cert1.get(), {cert2.get(), cert3.get()});
580
581 ASSERT_TRUE(PKCS12CreateVector(&p12, key1.get(),
582 {cert3.get(), cert1.get(), cert2.get()}));
583 ExpectPKCS12Parse(p12, key1.get(), cert1.get(), {cert3.get(), cert2.get()});
584
585 ASSERT_TRUE(PKCS12CreateVector(&p12, key1.get(),
586 {cert2.get(), cert3.get(), cert1.get()}));
587 ExpectPKCS12Parse(p12, key1.get(), cert1.get(), {cert2.get(), cert3.get()});
588
589 // In case of duplicates, the last one is selected. (It is unlikely anything
590 // depends on which is selected, but we match OpenSSL.)
591 ASSERT_TRUE(
592 PKCS12CreateVector(&p12, key1.get(), {cert1.get(), cert1b.get()}));
593 ExpectPKCS12Parse(p12, key1.get(), cert1b.get(), {cert1.get()});
594
595 // If there is no key, all certificates are returned as "CA" certificates.
596 ASSERT_TRUE(PKCS12CreateVector(&p12, nullptr,
597 {cert1.get(), cert2.get(), cert3.get()}));
598 ExpectPKCS12Parse(p12, nullptr, nullptr,
599 {cert1.get(), cert2.get(), cert3.get()});
600
601 // The same happens if there is a key, but it does not match any certificate.
602 ASSERT_TRUE(PKCS12CreateVector(&p12, key1.get(), {cert2.get(), cert3.get()}));
603 ExpectPKCS12Parse(p12, key1.get(), nullptr, {cert2.get(), cert3.get()});
604 }
605
TEST(PKCS12Test,CreateWithAlias)606 TEST(PKCS12Test, CreateWithAlias) {
607 bssl::UniquePtr<EVP_PKEY> key = MakeTestKey();
608 ASSERT_TRUE(key);
609 bssl::UniquePtr<X509> cert1 = MakeTestCert(key.get());
610 ASSERT_TRUE(cert1);
611 bssl::UniquePtr<X509> cert2 = MakeTestCert(key.get());
612 ASSERT_TRUE(cert2);
613
614 std::string alias = "I'm an alias";
615 int res = X509_alias_set1(
616 cert1.get(), reinterpret_cast<const unsigned char *>(alias.data()),
617 alias.size());
618 ASSERT_EQ(res, 1);
619
620 std::vector<X509 *> certs = {cert1.get(), cert2.get()};
621 std::vector<uint8_t> der;
622 ASSERT_TRUE(PKCS12CreateVector(&der, key.get(), certs));
623
624 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(der.data(), der.size()));
625 ASSERT_TRUE(bio);
626 bssl::UniquePtr<PKCS12> p12(d2i_PKCS12_bio(bio.get(), nullptr));
627 ASSERT_TRUE(p12);
628
629 EVP_PKEY *parsed_key = nullptr;
630 X509 *parsed_cert = nullptr;
631 STACK_OF(X509) *ca_certs = nullptr;
632 ASSERT_TRUE(
633 PKCS12_parse(p12.get(), kPassword, &parsed_key, &parsed_cert, &ca_certs));
634
635 bssl::UniquePtr<EVP_PKEY> delete_key(parsed_key);
636 bssl::UniquePtr<X509> delete_cert(parsed_cert);
637 bssl::UniquePtr<STACK_OF(X509)> delete_ca_certs(ca_certs);
638 ASSERT_EQ(sk_X509_num(ca_certs), 1UL);
639
640 int alias_len = 0;
641 const unsigned char *parsed_alias =
642 X509_alias_get0(sk_X509_value(ca_certs, 0), &alias_len);
643 ASSERT_TRUE(parsed_alias);
644 ASSERT_EQ(alias,
645 bssl::BytesAsStringView(bssl::Span(parsed_alias, alias_len)));
646 }
647
648 // PKCS#12 is built on top of PKCS#7, a misdesigned, overgeneralized combinator
649 // format. One of the features of PKCS#7 is that the content of every
650 // ContentInfo may be omitted, to indicate that the value is "supplied by other
651 // means". This is commonly used for "detached signatures", where the signature
652 // is supplied separately.
653 //
654 // This does not make sense in the context of PKCS#12. But because PKCS#7
655 // combined many unrelated use cases into the same format, so PKCS#12 (and any
656 // other use of PKCS#7) must account for and reject inputs.
TEST(PKCS12Test,MissingContent)657 TEST(PKCS12Test, MissingContent) {
658 {
659 std::string data = GetTestData("crypto/pkcs8/test/bad1.p12");
660 bssl::UniquePtr<STACK_OF(X509)> certs(sk_X509_new_null());
661 ASSERT_TRUE(certs);
662 EVP_PKEY *key = nullptr;
663 CBS cbs = bssl::StringAsBytes(data);
664 EXPECT_FALSE(PKCS12_get_key_and_certs(&key, certs.get(), &cbs, ""));
665 }
666 {
667 std::string data = GetTestData("crypto/pkcs8/test/bad2.p12");
668 bssl::UniquePtr<STACK_OF(X509)> certs(sk_X509_new_null());
669 ASSERT_TRUE(certs);
670 EVP_PKEY *key = nullptr;
671 CBS cbs = bssl::StringAsBytes(data);
672 EXPECT_FALSE(PKCS12_get_key_and_certs(&key, certs.get(), &cbs, ""));
673 }
674 {
675 std::string data = GetTestData("crypto/pkcs8/test/bad3.p12");
676 bssl::UniquePtr<STACK_OF(X509)> certs(sk_X509_new_null());
677 ASSERT_TRUE(certs);
678 EVP_PKEY *key = nullptr;
679 CBS cbs = bssl::StringAsBytes(data);
680 EXPECT_FALSE(PKCS12_get_key_and_certs(&key, certs.get(), &cbs, ""));
681 }
682 }
683