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[] = "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, "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
TEST(PKCS12Test,CreateWithAlias)603 TEST(PKCS12Test, CreateWithAlias) {
604 bssl::UniquePtr<EVP_PKEY> key = MakeTestKey();
605 ASSERT_TRUE(key);
606 bssl::UniquePtr<X509> cert1 = MakeTestCert(key.get());
607 ASSERT_TRUE(cert1);
608 bssl::UniquePtr<X509> cert2 = MakeTestCert(key.get());
609 ASSERT_TRUE(cert2);
610
611 std::string alias = "I'm an alias";
612 int res = X509_alias_set1(
613 cert1.get(), reinterpret_cast<const unsigned char *>(alias.data()),
614 alias.size());
615 ASSERT_EQ(res, 1);
616
617 std::vector<X509 *> certs = {cert1.get(), cert2.get()};
618 std::vector<uint8_t> der;
619 ASSERT_TRUE(PKCS12CreateVector(&der, key.get(), certs));
620
621 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(der.data(), der.size()));
622 ASSERT_TRUE(bio);
623 bssl::UniquePtr<PKCS12> p12(d2i_PKCS12_bio(bio.get(), nullptr));
624 ASSERT_TRUE(p12);
625
626 EVP_PKEY *parsed_key = nullptr;
627 X509 *parsed_cert = nullptr;
628 STACK_OF(X509) *ca_certs = nullptr;
629 ASSERT_TRUE(
630 PKCS12_parse(p12.get(), kPassword, &parsed_key, &parsed_cert, &ca_certs));
631
632 bssl::UniquePtr<EVP_PKEY> delete_key(parsed_key);
633 bssl::UniquePtr<X509> delete_cert(parsed_cert);
634 bssl::UniquePtr<STACK_OF(X509)> delete_ca_certs(ca_certs);
635 ASSERT_EQ(sk_X509_num(ca_certs), 1UL);
636
637 int alias_len = 0;
638 const unsigned char *parsed_alias =
639 X509_alias_get0(sk_X509_value(ca_certs, 0), &alias_len);
640 ASSERT_TRUE(parsed_alias);
641 ASSERT_EQ(alias, std::string(reinterpret_cast<const char *>(parsed_alias),
642 static_cast<size_t>(alias_len)));
643 }
644