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