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