xref: /aosp_15_r20/external/boringssl/src/crypto/pkcs8/pkcs12_test.cc (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
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