1 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
2 | * project 1999. |
3 | */ |
4 | /* ==================================================================== |
5 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions |
9 | * are met: |
10 | * |
11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. |
13 | * |
14 | * 2. Redistributions in binary form must reproduce the above copyright |
15 | * notice, this list of conditions and the following disclaimer in |
16 | * the documentation and/or other materials provided with the |
17 | * distribution. |
18 | * |
19 | * 3. All advertising materials mentioning features or use of this |
20 | * software must display the following acknowledgment: |
21 | * "This product includes software developed by the OpenSSL Project |
22 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" |
23 | * |
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
25 | * endorse or promote products derived from this software without |
26 | * prior written permission. For written permission, please contact |
27 | * licensing@OpenSSL.org. |
28 | * |
29 | * 5. Products derived from this software may not be called "OpenSSL" |
30 | * nor may "OpenSSL" appear in their names without prior written |
31 | * permission of the OpenSSL Project. |
32 | * |
33 | * 6. Redistributions of any form whatsoever must retain the following |
34 | * acknowledgment: |
35 | * "This product includes software developed by the OpenSSL Project |
36 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" |
37 | * |
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. |
50 | * ==================================================================== |
51 | * |
52 | * This product includes cryptographic software written by Eric Young |
53 | * (eay@cryptsoft.com). This product includes software written by Tim |
54 | * Hudson (tjh@cryptsoft.com). */ |
55 | |
56 | #include <openssl/pkcs8.h> |
57 | |
58 | #include <limits.h> |
59 | |
60 | #include <openssl/asn1t.h> |
61 | #include <openssl/asn1.h> |
62 | #include <openssl/bio.h> |
63 | #include <openssl/buf.h> |
64 | #include <openssl/bytestring.h> |
65 | #include <openssl/err.h> |
66 | #include <openssl/evp.h> |
67 | #include <openssl/digest.h> |
68 | #include <openssl/hmac.h> |
69 | #include <openssl/mem.h> |
70 | #include <openssl/rand.h> |
71 | #include <openssl/x509.h> |
72 | |
73 | #include "internal.h" |
74 | #include "../bytestring/internal.h" |
75 | #include "../internal.h" |
76 | |
77 | |
78 | int pkcs12_iterations_acceptable(uint64_t iterations) { |
79 | #if defined(BORINGSSL_UNSAFE_FUZZER_MODE) |
80 | static const uint64_t kIterationsLimit = 2048; |
81 | #else |
82 | // Windows imposes a limit of 600K. Mozilla say: “so them increasing |
83 | // maximum to something like 100M or 1G (to have few decades of breathing |
84 | // room) would be very welcome”[1]. So here we set the limit to 100M. |
85 | // |
86 | // [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1436873#c14 |
87 | static const uint64_t kIterationsLimit = 100 * 1000000; |
88 | #endif |
89 | |
90 | return 0 < iterations && iterations <= kIterationsLimit; |
91 | } |
92 | |
93 | // Minor tweak to operation: zero private key data |
94 | static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, |
95 | void *exarg) { |
96 | // Since the structure must still be valid use ASN1_OP_FREE_PRE |
97 | if (operation == ASN1_OP_FREE_PRE) { |
98 | PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval; |
99 | if (key->pkey && key->pkey->type == V_ASN1_OCTET_STRING && |
100 | key->pkey->value.octet_string) { |
101 | OPENSSL_cleanse(key->pkey->value.octet_string->data, |
102 | key->pkey->value.octet_string->length); |
103 | } |
104 | } |
105 | return 1; |
106 | } |
107 | |
108 | ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = { |
109 | ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER), |
110 | ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR), |
111 | ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_ANY), |
112 | ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0) |
113 | } ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) |
114 | |
115 | IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) |
116 | |
117 | EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) { |
118 | uint8_t *der = NULL; |
119 | int der_len = i2d_PKCS8_PRIV_KEY_INFO(p8, &der); |
120 | if (der_len < 0) { |
121 | return NULL; |
122 | } |
123 | |
124 | CBS cbs; |
125 | CBS_init(&cbs, der, (size_t)der_len); |
126 | EVP_PKEY *ret = EVP_parse_private_key(&cbs); |
127 | if (ret == NULL || CBS_len(&cbs) != 0) { |
128 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); |
129 | EVP_PKEY_free(ret); |
130 | OPENSSL_free(der); |
131 | return NULL; |
132 | } |
133 | |
134 | OPENSSL_free(der); |
135 | return ret; |
136 | } |
137 | |
138 | PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) { |
139 | CBB cbb; |
140 | uint8_t *der = NULL; |
141 | size_t der_len; |
142 | if (!CBB_init(&cbb, 0) || |
143 | !EVP_marshal_private_key(&cbb, pkey) || |
144 | !CBB_finish(&cbb, &der, &der_len) || |
145 | der_len > LONG_MAX) { |
146 | CBB_cleanup(&cbb); |
147 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ENCODE_ERROR); |
148 | goto err; |
149 | } |
150 | |
151 | const uint8_t *p = der; |
152 | PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, (long)der_len); |
153 | if (p8 == NULL || p != der + der_len) { |
154 | PKCS8_PRIV_KEY_INFO_free(p8); |
155 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); |
156 | goto err; |
157 | } |
158 | |
159 | OPENSSL_free(der); |
160 | return p8; |
161 | |
162 | err: |
163 | OPENSSL_free(der); |
164 | return NULL; |
165 | } |
166 | |
167 | PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8, const char *pass, |
168 | int pass_len_in) { |
169 | size_t pass_len; |
170 | if (pass_len_in == -1 && pass != NULL) { |
171 | pass_len = strlen(pass); |
172 | } else { |
173 | pass_len = (size_t)pass_len_in; |
174 | } |
175 | |
176 | PKCS8_PRIV_KEY_INFO *ret = NULL; |
177 | EVP_PKEY *pkey = NULL; |
178 | uint8_t *in = NULL; |
179 | |
180 | // Convert the legacy ASN.1 object to a byte string. |
181 | int in_len = i2d_X509_SIG(pkcs8, &in); |
182 | if (in_len < 0) { |
183 | goto err; |
184 | } |
185 | |
186 | CBS cbs; |
187 | CBS_init(&cbs, in, in_len); |
188 | pkey = PKCS8_parse_encrypted_private_key(&cbs, pass, pass_len); |
189 | if (pkey == NULL || CBS_len(&cbs) != 0) { |
190 | goto err; |
191 | } |
192 | |
193 | ret = EVP_PKEY2PKCS8(pkey); |
194 | |
195 | err: |
196 | OPENSSL_free(in); |
197 | EVP_PKEY_free(pkey); |
198 | return ret; |
199 | } |
200 | |
201 | X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass, |
202 | int pass_len_in, const uint8_t *salt, size_t salt_len, |
203 | int iterations, PKCS8_PRIV_KEY_INFO *p8inf) { |
204 | size_t pass_len; |
205 | if (pass_len_in == -1 && pass != NULL) { |
206 | pass_len = strlen(pass); |
207 | } else { |
208 | pass_len = (size_t)pass_len_in; |
209 | } |
210 | |
211 | // Parse out the private key. |
212 | EVP_PKEY *pkey = EVP_PKCS82PKEY(p8inf); |
213 | if (pkey == NULL) { |
214 | return NULL; |
215 | } |
216 | |
217 | X509_SIG *ret = NULL; |
218 | uint8_t *der = NULL; |
219 | size_t der_len; |
220 | CBB cbb; |
221 | if (!CBB_init(&cbb, 128) || |
222 | !PKCS8_marshal_encrypted_private_key(&cbb, pbe_nid, cipher, pass, |
223 | pass_len, salt, salt_len, iterations, |
224 | pkey) || |
225 | !CBB_finish(&cbb, &der, &der_len)) { |
226 | CBB_cleanup(&cbb); |
227 | goto err; |
228 | } |
229 | |
230 | // Convert back to legacy ASN.1 objects. |
231 | const uint8_t *ptr = der; |
232 | ret = d2i_X509_SIG(NULL, &ptr, der_len); |
233 | if (ret == NULL || ptr != der + der_len) { |
234 | OPENSSL_PUT_ERROR(PKCS8, ERR_R_INTERNAL_ERROR); |
235 | X509_SIG_free(ret); |
236 | ret = NULL; |
237 | } |
238 | |
239 | err: |
240 | OPENSSL_free(der); |
241 | EVP_PKEY_free(pkey); |
242 | return ret; |
243 | } |
244 | |
245 | struct pkcs12_context { |
246 | EVP_PKEY **out_key; |
247 | STACK_OF(X509) *out_certs; |
248 | const char *password; |
249 | size_t password_len; |
250 | }; |
251 | |
252 | // PKCS12_handle_sequence parses a BER-encoded SEQUENCE of elements in a PKCS#12 |
253 | // structure. |
254 | static int PKCS12_handle_sequence( |
255 | CBS *sequence, struct pkcs12_context *ctx, |
256 | int (*handle_element)(CBS *cbs, struct pkcs12_context *ctx)) { |
257 | uint8_t *storage = NULL; |
258 | CBS in; |
259 | int ret = 0; |
260 | |
261 | // Although a BER->DER conversion is done at the beginning of |PKCS12_parse|, |
262 | // the ASN.1 data gets wrapped in OCTETSTRINGs and/or encrypted and the |
263 | // conversion cannot see through those wrappings. So each time we step |
264 | // through one we need to convert to DER again. |
265 | if (!CBS_asn1_ber_to_der(sequence, &in, &storage)) { |
266 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
267 | return 0; |
268 | } |
269 | |
270 | CBS child; |
271 | if (!CBS_get_asn1(&in, &child, CBS_ASN1_SEQUENCE) || |
272 | CBS_len(&in) != 0) { |
273 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
274 | goto err; |
275 | } |
276 | |
277 | while (CBS_len(&child) > 0) { |
278 | CBS element; |
279 | if (!CBS_get_asn1(&child, &element, CBS_ASN1_SEQUENCE)) { |
280 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
281 | goto err; |
282 | } |
283 | |
284 | if (!handle_element(&element, ctx)) { |
285 | goto err; |
286 | } |
287 | } |
288 | |
289 | ret = 1; |
290 | |
291 | err: |
292 | OPENSSL_free(storage); |
293 | return ret; |
294 | } |
295 | |
296 | // 1.2.840.113549.1.12.10.1.1 |
297 | static const uint8_t kKeyBag[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, |
298 | 0x01, 0x0c, 0x0a, 0x01, 0x01}; |
299 | |
300 | // 1.2.840.113549.1.12.10.1.2 |
301 | static const uint8_t kPKCS8ShroudedKeyBag[] = { |
302 | 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02}; |
303 | |
304 | // 1.2.840.113549.1.12.10.1.3 |
305 | static const uint8_t kCertBag[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, |
306 | 0x01, 0x0c, 0x0a, 0x01, 0x03}; |
307 | |
308 | // 1.2.840.113549.1.9.20 |
309 | static const uint8_t kFriendlyName[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, |
310 | 0x0d, 0x01, 0x09, 0x14}; |
311 | |
312 | // 1.2.840.113549.1.9.21 |
313 | static const uint8_t kLocalKeyID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, |
314 | 0x0d, 0x01, 0x09, 0x15}; |
315 | |
316 | // 1.2.840.113549.1.9.22.1 |
317 | static const uint8_t kX509Certificate[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, |
318 | 0x0d, 0x01, 0x09, 0x16, 0x01}; |
319 | |
320 | // parse_bag_attributes parses the bagAttributes field of a SafeBag structure. |
321 | // It sets |*out_friendly_name| to a newly-allocated copy of the friendly name, |
322 | // encoded as a UTF-8 string, or NULL if there is none. It returns one on |
323 | // success and zero on error. |
324 | static int parse_bag_attributes(CBS *attrs, uint8_t **out_friendly_name, |
325 | size_t *out_friendly_name_len) { |
326 | *out_friendly_name = NULL; |
327 | *out_friendly_name_len = 0; |
328 | |
329 | // See https://tools.ietf.org/html/rfc7292#section-4.2. |
330 | while (CBS_len(attrs) != 0) { |
331 | CBS attr, oid, values; |
332 | if (!CBS_get_asn1(attrs, &attr, CBS_ASN1_SEQUENCE) || |
333 | !CBS_get_asn1(&attr, &oid, CBS_ASN1_OBJECT) || |
334 | !CBS_get_asn1(&attr, &values, CBS_ASN1_SET) || |
335 | CBS_len(&attr) != 0) { |
336 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
337 | goto err; |
338 | } |
339 | if (CBS_mem_equal(&oid, kFriendlyName, sizeof(kFriendlyName))) { |
340 | // See https://tools.ietf.org/html/rfc2985, section 5.5.1. |
341 | CBS value; |
342 | if (*out_friendly_name != NULL || |
343 | !CBS_get_asn1(&values, &value, CBS_ASN1_BMPSTRING) || |
344 | CBS_len(&values) != 0 || |
345 | CBS_len(&value) == 0) { |
346 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
347 | goto err; |
348 | } |
349 | // Convert the friendly name to UTF-8. |
350 | CBB cbb; |
351 | if (!CBB_init(&cbb, CBS_len(&value))) { |
352 | OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); |
353 | goto err; |
354 | } |
355 | while (CBS_len(&value) != 0) { |
356 | uint32_t c; |
357 | if (!cbs_get_ucs2_be(&value, &c) || |
358 | !cbb_add_utf8(&cbb, c)) { |
359 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INVALID_CHARACTERS); |
360 | CBB_cleanup(&cbb); |
361 | goto err; |
362 | } |
363 | } |
364 | if (!CBB_finish(&cbb, out_friendly_name, out_friendly_name_len)) { |
365 | OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); |
366 | CBB_cleanup(&cbb); |
367 | goto err; |
368 | } |
369 | } |
370 | } |
371 | |
372 | return 1; |
373 | |
374 | err: |
375 | OPENSSL_free(*out_friendly_name); |
376 | *out_friendly_name = NULL; |
377 | *out_friendly_name_len = 0; |
378 | return 0; |
379 | } |
380 | |
381 | // PKCS12_handle_safe_bag parses a single SafeBag element in a PKCS#12 |
382 | // structure. |
383 | static int PKCS12_handle_safe_bag(CBS *safe_bag, struct pkcs12_context *ctx) { |
384 | CBS bag_id, wrapped_value, bag_attrs; |
385 | if (!CBS_get_asn1(safe_bag, &bag_id, CBS_ASN1_OBJECT) || |
386 | !CBS_get_asn1(safe_bag, &wrapped_value, |
387 | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { |
388 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
389 | return 0; |
390 | } |
391 | if (CBS_len(safe_bag) == 0) { |
392 | CBS_init(&bag_attrs, NULL, 0); |
393 | } else if (!CBS_get_asn1(safe_bag, &bag_attrs, CBS_ASN1_SET) || |
394 | CBS_len(safe_bag) != 0) { |
395 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
396 | return 0; |
397 | } |
398 | |
399 | const int is_key_bag = CBS_mem_equal(&bag_id, kKeyBag, sizeof(kKeyBag)); |
400 | const int is_shrouded_key_bag = CBS_mem_equal(&bag_id, kPKCS8ShroudedKeyBag, |
401 | sizeof(kPKCS8ShroudedKeyBag)); |
402 | if (is_key_bag || is_shrouded_key_bag) { |
403 | // See RFC 7292, section 4.2.1 and 4.2.2. |
404 | if (*ctx->out_key) { |
405 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12); |
406 | return 0; |
407 | } |
408 | |
409 | EVP_PKEY *pkey = |
410 | is_key_bag ? EVP_parse_private_key(&wrapped_value) |
411 | : PKCS8_parse_encrypted_private_key( |
412 | &wrapped_value, ctx->password, ctx->password_len); |
413 | if (pkey == NULL) { |
414 | return 0; |
415 | } |
416 | |
417 | if (CBS_len(&wrapped_value) != 0) { |
418 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
419 | EVP_PKEY_free(pkey); |
420 | return 0; |
421 | } |
422 | |
423 | *ctx->out_key = pkey; |
424 | return 1; |
425 | } |
426 | |
427 | if (CBS_mem_equal(&bag_id, kCertBag, sizeof(kCertBag))) { |
428 | // See RFC 7292, section 4.2.3. |
429 | CBS cert_bag, cert_type, wrapped_cert, cert; |
430 | if (!CBS_get_asn1(&wrapped_value, &cert_bag, CBS_ASN1_SEQUENCE) || |
431 | !CBS_get_asn1(&cert_bag, &cert_type, CBS_ASN1_OBJECT) || |
432 | !CBS_get_asn1(&cert_bag, &wrapped_cert, |
433 | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || |
434 | !CBS_get_asn1(&wrapped_cert, &cert, CBS_ASN1_OCTETSTRING)) { |
435 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
436 | return 0; |
437 | } |
438 | |
439 | // Skip unknown certificate types. |
440 | if (!CBS_mem_equal(&cert_type, kX509Certificate, |
441 | sizeof(kX509Certificate))) { |
442 | return 1; |
443 | } |
444 | |
445 | if (CBS_len(&cert) > LONG_MAX) { |
446 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
447 | return 0; |
448 | } |
449 | |
450 | const uint8_t *inp = CBS_data(&cert); |
451 | X509 *x509 = d2i_X509(NULL, &inp, (long)CBS_len(&cert)); |
452 | if (!x509) { |
453 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
454 | return 0; |
455 | } |
456 | |
457 | if (inp != CBS_data(&cert) + CBS_len(&cert)) { |
458 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
459 | X509_free(x509); |
460 | return 0; |
461 | } |
462 | |
463 | uint8_t *friendly_name; |
464 | size_t friendly_name_len; |
465 | if (!parse_bag_attributes(&bag_attrs, &friendly_name, &friendly_name_len)) { |
466 | X509_free(x509); |
467 | return 0; |
468 | } |
469 | int ok = friendly_name_len == 0 || |
470 | X509_alias_set1(x509, friendly_name, friendly_name_len); |
471 | OPENSSL_free(friendly_name); |
472 | if (!ok || |
473 | 0 == sk_X509_push(ctx->out_certs, x509)) { |
474 | X509_free(x509); |
475 | return 0; |
476 | } |
477 | |
478 | return 1; |
479 | } |
480 | |
481 | // Unknown element type - ignore it. |
482 | return 1; |
483 | } |
484 | |
485 | // 1.2.840.113549.1.7.1 |
486 | static const uint8_t kPKCS7Data[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, |
487 | 0x0d, 0x01, 0x07, 0x01}; |
488 | |
489 | // 1.2.840.113549.1.7.6 |
490 | static const uint8_t kPKCS7EncryptedData[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, |
491 | 0x0d, 0x01, 0x07, 0x06}; |
492 | |
493 | // PKCS12_handle_content_info parses a single PKCS#7 ContentInfo element in a |
494 | // PKCS#12 structure. |
495 | static int PKCS12_handle_content_info(CBS *content_info, |
496 | struct pkcs12_context *ctx) { |
497 | CBS content_type, wrapped_contents, contents; |
498 | int ret = 0; |
499 | uint8_t *storage = NULL; |
500 | |
501 | if (!CBS_get_asn1(content_info, &content_type, CBS_ASN1_OBJECT) || |
502 | !CBS_get_asn1(content_info, &wrapped_contents, |
503 | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || |
504 | CBS_len(content_info) != 0) { |
505 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
506 | goto err; |
507 | } |
508 | |
509 | if (CBS_mem_equal(&content_type, kPKCS7EncryptedData, |
510 | sizeof(kPKCS7EncryptedData))) { |
511 | // See https://tools.ietf.org/html/rfc2315#section-13. |
512 | // |
513 | // PKCS#7 encrypted data inside a PKCS#12 structure is generally an |
514 | // encrypted certificate bag and it's generally encrypted with 40-bit |
515 | // RC2-CBC. |
516 | CBS version_bytes, eci, contents_type, ai, encrypted_contents; |
517 | uint8_t *out; |
518 | size_t out_len; |
519 | |
520 | if (!CBS_get_asn1(&wrapped_contents, &contents, CBS_ASN1_SEQUENCE) || |
521 | !CBS_get_asn1(&contents, &version_bytes, CBS_ASN1_INTEGER) || |
522 | // EncryptedContentInfo, see |
523 | // https://tools.ietf.org/html/rfc2315#section-10.1 |
524 | !CBS_get_asn1(&contents, &eci, CBS_ASN1_SEQUENCE) || |
525 | !CBS_get_asn1(&eci, &contents_type, CBS_ASN1_OBJECT) || |
526 | // AlgorithmIdentifier, see |
527 | // https://tools.ietf.org/html/rfc5280#section-4.1.1.2 |
528 | !CBS_get_asn1(&eci, &ai, CBS_ASN1_SEQUENCE) || |
529 | !CBS_get_asn1_implicit_string( |
530 | &eci, &encrypted_contents, &storage, |
531 | CBS_ASN1_CONTEXT_SPECIFIC | 0, CBS_ASN1_OCTETSTRING)) { |
532 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
533 | goto err; |
534 | } |
535 | |
536 | if (!CBS_mem_equal(&contents_type, kPKCS7Data, sizeof(kPKCS7Data))) { |
537 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
538 | goto err; |
539 | } |
540 | |
541 | if (!pkcs8_pbe_decrypt(&out, &out_len, &ai, ctx->password, |
542 | ctx->password_len, CBS_data(&encrypted_contents), |
543 | CBS_len(&encrypted_contents))) { |
544 | goto err; |
545 | } |
546 | |
547 | CBS safe_contents; |
548 | CBS_init(&safe_contents, out, out_len); |
549 | ret = PKCS12_handle_sequence(&safe_contents, ctx, PKCS12_handle_safe_bag); |
550 | OPENSSL_free(out); |
551 | } else if (CBS_mem_equal(&content_type, kPKCS7Data, sizeof(kPKCS7Data))) { |
552 | CBS octet_string_contents; |
553 | |
554 | if (!CBS_get_asn1(&wrapped_contents, &octet_string_contents, |
555 | CBS_ASN1_OCTETSTRING)) { |
556 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
557 | goto err; |
558 | } |
559 | |
560 | ret = PKCS12_handle_sequence(&octet_string_contents, ctx, |
561 | PKCS12_handle_safe_bag); |
562 | } else { |
563 | // Unknown element type - ignore it. |
564 | ret = 1; |
565 | } |
566 | |
567 | err: |
568 | OPENSSL_free(storage); |
569 | return ret; |
570 | } |
571 | |
572 | static int pkcs12_check_mac(int *out_mac_ok, const char *password, |
573 | size_t password_len, const CBS *salt, |
574 | unsigned iterations, const EVP_MD *md, |
575 | const CBS *authsafes, const CBS *expected_mac) { |
576 | int ret = 0; |
577 | uint8_t hmac_key[EVP_MAX_MD_SIZE]; |
578 | if (!pkcs12_key_gen(password, password_len, CBS_data(salt), CBS_len(salt), |
579 | PKCS12_MAC_ID, iterations, EVP_MD_size(md), hmac_key, |
580 | md)) { |
581 | goto err; |
582 | } |
583 | |
584 | uint8_t hmac[EVP_MAX_MD_SIZE]; |
585 | unsigned hmac_len; |
586 | if (NULL == HMAC(md, hmac_key, EVP_MD_size(md), CBS_data(authsafes), |
587 | CBS_len(authsafes), hmac, &hmac_len)) { |
588 | goto err; |
589 | } |
590 | |
591 | *out_mac_ok = CBS_mem_equal(expected_mac, hmac, hmac_len); |
592 | #if defined(BORINGSSL_UNSAFE_FUZZER_MODE) |
593 | *out_mac_ok = 1; |
594 | #endif |
595 | ret = 1; |
596 | |
597 | err: |
598 | OPENSSL_cleanse(hmac_key, sizeof(hmac_key)); |
599 | return ret; |
600 | } |
601 | |
602 | |
603 | int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs, |
604 | CBS *ber_in, const char *password) { |
605 | uint8_t *storage = NULL; |
606 | CBS in, pfx, mac_data, authsafe, content_type, wrapped_authsafes, authsafes; |
607 | uint64_t version; |
608 | int ret = 0; |
609 | struct pkcs12_context ctx; |
610 | const size_t original_out_certs_len = sk_X509_num(out_certs); |
611 | |
612 | // The input may be in BER format. |
613 | if (!CBS_asn1_ber_to_der(ber_in, &in, &storage)) { |
614 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
615 | return 0; |
616 | } |
617 | |
618 | *out_key = NULL; |
619 | OPENSSL_memset(&ctx, 0, sizeof(ctx)); |
620 | |
621 | // See ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1.pdf, section |
622 | // four. |
623 | if (!CBS_get_asn1(&in, &pfx, CBS_ASN1_SEQUENCE) || |
624 | CBS_len(&in) != 0 || |
625 | !CBS_get_asn1_uint64(&pfx, &version)) { |
626 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
627 | goto err; |
628 | } |
629 | |
630 | if (version < 3) { |
631 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_VERSION); |
632 | goto err; |
633 | } |
634 | |
635 | if (!CBS_get_asn1(&pfx, &authsafe, CBS_ASN1_SEQUENCE)) { |
636 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
637 | goto err; |
638 | } |
639 | |
640 | if (CBS_len(&pfx) == 0) { |
641 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MISSING_MAC); |
642 | goto err; |
643 | } |
644 | |
645 | if (!CBS_get_asn1(&pfx, &mac_data, CBS_ASN1_SEQUENCE)) { |
646 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
647 | goto err; |
648 | } |
649 | |
650 | // authsafe is a PKCS#7 ContentInfo. See |
651 | // https://tools.ietf.org/html/rfc2315#section-7. |
652 | if (!CBS_get_asn1(&authsafe, &content_type, CBS_ASN1_OBJECT) || |
653 | !CBS_get_asn1(&authsafe, &wrapped_authsafes, |
654 | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { |
655 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
656 | goto err; |
657 | } |
658 | |
659 | // The content type can either be data or signedData. The latter indicates |
660 | // that it's signed by a public key, which isn't supported. |
661 | if (!CBS_mem_equal(&content_type, kPKCS7Data, sizeof(kPKCS7Data))) { |
662 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED); |
663 | goto err; |
664 | } |
665 | |
666 | if (!CBS_get_asn1(&wrapped_authsafes, &authsafes, CBS_ASN1_OCTETSTRING)) { |
667 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
668 | goto err; |
669 | } |
670 | |
671 | ctx.out_key = out_key; |
672 | ctx.out_certs = out_certs; |
673 | ctx.password = password; |
674 | ctx.password_len = password != NULL ? strlen(password) : 0; |
675 | |
676 | // Verify the MAC. |
677 | { |
678 | CBS mac, salt, expected_mac; |
679 | if (!CBS_get_asn1(&mac_data, &mac, CBS_ASN1_SEQUENCE)) { |
680 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
681 | goto err; |
682 | } |
683 | |
684 | const EVP_MD *md = EVP_parse_digest_algorithm(&mac); |
685 | if (md == NULL) { |
686 | goto err; |
687 | } |
688 | |
689 | if (!CBS_get_asn1(&mac, &expected_mac, CBS_ASN1_OCTETSTRING) || |
690 | !CBS_get_asn1(&mac_data, &salt, CBS_ASN1_OCTETSTRING)) { |
691 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
692 | goto err; |
693 | } |
694 | |
695 | // The iteration count is optional and the default is one. |
696 | uint64_t iterations = 1; |
697 | if (CBS_len(&mac_data) > 0) { |
698 | if (!CBS_get_asn1_uint64(&mac_data, &iterations) || |
699 | !pkcs12_iterations_acceptable(iterations)) { |
700 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); |
701 | goto err; |
702 | } |
703 | } |
704 | |
705 | int mac_ok; |
706 | if (!pkcs12_check_mac(&mac_ok, ctx.password, ctx.password_len, &salt, |
707 | iterations, md, &authsafes, &expected_mac)) { |
708 | goto err; |
709 | } |
710 | if (!mac_ok && ctx.password_len == 0) { |
711 | // PKCS#12 encodes passwords as NUL-terminated UCS-2, so the empty |
712 | // password is encoded as {0, 0}. Some implementations use the empty byte |
713 | // array for "no password". OpenSSL considers a non-NULL password as {0, |
714 | // 0} and a NULL password as {}. It then, in high-level PKCS#12 parsing |
715 | // code, tries both options. We match this behavior. |
716 | ctx.password = ctx.password != NULL ? NULL : "" ; |
717 | if (!pkcs12_check_mac(&mac_ok, ctx.password, ctx.password_len, &salt, |
718 | iterations, md, &authsafes, &expected_mac)) { |
719 | goto err; |
720 | } |
721 | } |
722 | if (!mac_ok) { |
723 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INCORRECT_PASSWORD); |
724 | goto err; |
725 | } |
726 | } |
727 | |
728 | // authsafes contains a series of PKCS#7 ContentInfos. |
729 | if (!PKCS12_handle_sequence(&authsafes, &ctx, PKCS12_handle_content_info)) { |
730 | goto err; |
731 | } |
732 | |
733 | ret = 1; |
734 | |
735 | err: |
736 | OPENSSL_free(storage); |
737 | if (!ret) { |
738 | EVP_PKEY_free(*out_key); |
739 | *out_key = NULL; |
740 | while (sk_X509_num(out_certs) > original_out_certs_len) { |
741 | X509 *x509 = sk_X509_pop(out_certs); |
742 | X509_free(x509); |
743 | } |
744 | } |
745 | |
746 | return ret; |
747 | } |
748 | |
749 | void PKCS12_PBE_add(void) {} |
750 | |
751 | struct pkcs12_st { |
752 | uint8_t *ber_bytes; |
753 | size_t ber_len; |
754 | }; |
755 | |
756 | PKCS12 *d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes, |
757 | size_t ber_len) { |
758 | PKCS12 *p12; |
759 | |
760 | p12 = OPENSSL_malloc(sizeof(PKCS12)); |
761 | if (!p12) { |
762 | return NULL; |
763 | } |
764 | |
765 | p12->ber_bytes = OPENSSL_malloc(ber_len); |
766 | if (!p12->ber_bytes) { |
767 | OPENSSL_free(p12); |
768 | return NULL; |
769 | } |
770 | |
771 | OPENSSL_memcpy(p12->ber_bytes, *ber_bytes, ber_len); |
772 | p12->ber_len = ber_len; |
773 | *ber_bytes += ber_len; |
774 | |
775 | if (out_p12) { |
776 | PKCS12_free(*out_p12); |
777 | |
778 | *out_p12 = p12; |
779 | } |
780 | |
781 | return p12; |
782 | } |
783 | |
784 | PKCS12* d2i_PKCS12_bio(BIO *bio, PKCS12 **out_p12) { |
785 | size_t used = 0; |
786 | BUF_MEM *buf; |
787 | const uint8_t *dummy; |
788 | static const size_t kMaxSize = 256 * 1024; |
789 | PKCS12 *ret = NULL; |
790 | |
791 | buf = BUF_MEM_new(); |
792 | if (buf == NULL) { |
793 | return NULL; |
794 | } |
795 | if (BUF_MEM_grow(buf, 8192) == 0) { |
796 | goto out; |
797 | } |
798 | |
799 | for (;;) { |
800 | int n = BIO_read(bio, &buf->data[used], buf->length - used); |
801 | if (n < 0) { |
802 | if (used == 0) { |
803 | goto out; |
804 | } |
805 | // Workaround a bug in node.js. It uses a memory BIO for this in the wrong |
806 | // mode. |
807 | n = 0; |
808 | } |
809 | |
810 | if (n == 0) { |
811 | break; |
812 | } |
813 | used += n; |
814 | |
815 | if (used < buf->length) { |
816 | continue; |
817 | } |
818 | |
819 | if (buf->length > kMaxSize || |
820 | BUF_MEM_grow(buf, buf->length * 2) == 0) { |
821 | goto out; |
822 | } |
823 | } |
824 | |
825 | dummy = (uint8_t*) buf->data; |
826 | ret = d2i_PKCS12(out_p12, &dummy, used); |
827 | |
828 | out: |
829 | BUF_MEM_free(buf); |
830 | return ret; |
831 | } |
832 | |
833 | PKCS12* d2i_PKCS12_fp(FILE *fp, PKCS12 **out_p12) { |
834 | BIO *bio; |
835 | PKCS12 *ret; |
836 | |
837 | bio = BIO_new_fp(fp, 0 /* don't take ownership */); |
838 | if (!bio) { |
839 | return NULL; |
840 | } |
841 | |
842 | ret = d2i_PKCS12_bio(bio, out_p12); |
843 | BIO_free(bio); |
844 | return ret; |
845 | } |
846 | |
847 | int i2d_PKCS12(const PKCS12 *p12, uint8_t **out) { |
848 | if (p12->ber_len > INT_MAX) { |
849 | OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); |
850 | return -1; |
851 | } |
852 | |
853 | if (out == NULL) { |
854 | return (int)p12->ber_len; |
855 | } |
856 | |
857 | if (*out == NULL) { |
858 | *out = OPENSSL_malloc(p12->ber_len); |
859 | if (*out == NULL) { |
860 | OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); |
861 | return -1; |
862 | } |
863 | OPENSSL_memcpy(*out, p12->ber_bytes, p12->ber_len); |
864 | } else { |
865 | OPENSSL_memcpy(*out, p12->ber_bytes, p12->ber_len); |
866 | *out += p12->ber_len; |
867 | } |
868 | return (int)p12->ber_len; |
869 | } |
870 | |
871 | int i2d_PKCS12_bio(BIO *bio, const PKCS12 *p12) { |
872 | return BIO_write_all(bio, p12->ber_bytes, p12->ber_len); |
873 | } |
874 | |
875 | int i2d_PKCS12_fp(FILE *fp, const PKCS12 *p12) { |
876 | BIO *bio = BIO_new_fp(fp, 0 /* don't take ownership */); |
877 | if (bio == NULL) { |
878 | return 0; |
879 | } |
880 | |
881 | int ret = i2d_PKCS12_bio(bio, p12); |
882 | BIO_free(bio); |
883 | return ret; |
884 | } |
885 | |
886 | int PKCS12_parse(const PKCS12 *p12, const char *password, EVP_PKEY **out_pkey, |
887 | X509 **out_cert, STACK_OF(X509) **out_ca_certs) { |
888 | CBS ber_bytes; |
889 | STACK_OF(X509) *ca_certs = NULL; |
890 | char ca_certs_alloced = 0; |
891 | |
892 | if (out_ca_certs != NULL && *out_ca_certs != NULL) { |
893 | ca_certs = *out_ca_certs; |
894 | } |
895 | |
896 | if (!ca_certs) { |
897 | ca_certs = sk_X509_new_null(); |
898 | if (ca_certs == NULL) { |
899 | OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); |
900 | return 0; |
901 | } |
902 | ca_certs_alloced = 1; |
903 | } |
904 | |
905 | CBS_init(&ber_bytes, p12->ber_bytes, p12->ber_len); |
906 | if (!PKCS12_get_key_and_certs(out_pkey, ca_certs, &ber_bytes, password)) { |
907 | if (ca_certs_alloced) { |
908 | sk_X509_free(ca_certs); |
909 | } |
910 | return 0; |
911 | } |
912 | |
913 | // OpenSSL selects the last certificate which matches the private key as |
914 | // |out_cert|. |
915 | // |
916 | // TODO(davidben): OpenSSL additionally reverses the order of the |
917 | // certificates, which was likely originally a bug, but may be a feature by |
918 | // now. See https://crbug.com/boringssl/250 and |
919 | // https://github.com/openssl/openssl/issues/6698. |
920 | *out_cert = NULL; |
921 | size_t num_certs = sk_X509_num(ca_certs); |
922 | if (*out_pkey != NULL && num_certs > 0) { |
923 | for (size_t i = num_certs - 1; i < num_certs; i--) { |
924 | X509 *cert = sk_X509_value(ca_certs, i); |
925 | if (X509_check_private_key(cert, *out_pkey)) { |
926 | *out_cert = cert; |
927 | sk_X509_delete(ca_certs, i); |
928 | break; |
929 | } |
930 | ERR_clear_error(); |
931 | } |
932 | } |
933 | |
934 | if (out_ca_certs) { |
935 | *out_ca_certs = ca_certs; |
936 | } else { |
937 | sk_X509_pop_free(ca_certs, X509_free); |
938 | } |
939 | |
940 | return 1; |
941 | } |
942 | |
943 | int PKCS12_verify_mac(const PKCS12 *p12, const char *password, |
944 | int password_len) { |
945 | if (password == NULL) { |
946 | if (password_len != 0) { |
947 | return 0; |
948 | } |
949 | } else if (password_len != -1 && |
950 | (password[password_len] != 0 || |
951 | OPENSSL_memchr(password, 0, password_len) != NULL)) { |
952 | return 0; |
953 | } |
954 | |
955 | EVP_PKEY *pkey = NULL; |
956 | X509 *cert = NULL; |
957 | if (!PKCS12_parse(p12, password, &pkey, &cert, NULL)) { |
958 | ERR_clear_error(); |
959 | return 0; |
960 | } |
961 | |
962 | EVP_PKEY_free(pkey); |
963 | X509_free(cert); |
964 | |
965 | return 1; |
966 | } |
967 | |
968 | // add_bag_attributes adds the bagAttributes field of a SafeBag structure, |
969 | // containing the specified friendlyName and localKeyId attributes. |
970 | static int add_bag_attributes(CBB *bag, const char *name, const uint8_t *key_id, |
971 | size_t key_id_len) { |
972 | if (name == NULL && key_id_len == 0) { |
973 | return 1; // Omit the OPTIONAL SET. |
974 | } |
975 | // See https://tools.ietf.org/html/rfc7292#section-4.2. |
976 | CBB attrs, attr, oid, values, value; |
977 | if (!CBB_add_asn1(bag, &attrs, CBS_ASN1_SET)) { |
978 | return 0; |
979 | } |
980 | if (name != NULL) { |
981 | // See https://tools.ietf.org/html/rfc2985, section 5.5.1. |
982 | if (!CBB_add_asn1(&attrs, &attr, CBS_ASN1_SEQUENCE) || |
983 | !CBB_add_asn1(&attr, &oid, CBS_ASN1_OBJECT) || |
984 | !CBB_add_bytes(&oid, kFriendlyName, sizeof(kFriendlyName)) || |
985 | !CBB_add_asn1(&attr, &values, CBS_ASN1_SET) || |
986 | !CBB_add_asn1(&values, &value, CBS_ASN1_BMPSTRING)) { |
987 | return 0; |
988 | } |
989 | // Convert the friendly name to a BMPString. |
990 | CBS name_cbs; |
991 | CBS_init(&name_cbs, (const uint8_t *)name, strlen(name)); |
992 | while (CBS_len(&name_cbs) != 0) { |
993 | uint32_t c; |
994 | if (!cbs_get_utf8(&name_cbs, &c) || |
995 | !cbb_add_ucs2_be(&value, c)) { |
996 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INVALID_CHARACTERS); |
997 | return 0; |
998 | } |
999 | } |
1000 | } |
1001 | if (key_id_len != 0) { |
1002 | // See https://tools.ietf.org/html/rfc2985, section 5.5.2. |
1003 | if (!CBB_add_asn1(&attrs, &attr, CBS_ASN1_SEQUENCE) || |
1004 | !CBB_add_asn1(&attr, &oid, CBS_ASN1_OBJECT) || |
1005 | !CBB_add_bytes(&oid, kLocalKeyID, sizeof(kLocalKeyID)) || |
1006 | !CBB_add_asn1(&attr, &values, CBS_ASN1_SET) || |
1007 | !CBB_add_asn1(&values, &value, CBS_ASN1_OCTETSTRING) || |
1008 | !CBB_add_bytes(&value, key_id, key_id_len)) { |
1009 | return 0; |
1010 | } |
1011 | } |
1012 | return CBB_flush_asn1_set_of(&attrs) && |
1013 | CBB_flush(bag); |
1014 | } |
1015 | |
1016 | static int add_cert_bag(CBB *cbb, X509 *cert, const char *name, |
1017 | const uint8_t *key_id, size_t key_id_len) { |
1018 | CBB bag, bag_oid, bag_contents, cert_bag, cert_type, wrapped_cert, cert_value; |
1019 | if (// See https://tools.ietf.org/html/rfc7292#section-4.2. |
1020 | !CBB_add_asn1(cbb, &bag, CBS_ASN1_SEQUENCE) || |
1021 | !CBB_add_asn1(&bag, &bag_oid, CBS_ASN1_OBJECT) || |
1022 | !CBB_add_bytes(&bag_oid, kCertBag, sizeof(kCertBag)) || |
1023 | !CBB_add_asn1(&bag, &bag_contents, |
1024 | CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || |
1025 | // See https://tools.ietf.org/html/rfc7292#section-4.2.3. |
1026 | !CBB_add_asn1(&bag_contents, &cert_bag, CBS_ASN1_SEQUENCE) || |
1027 | !CBB_add_asn1(&cert_bag, &cert_type, CBS_ASN1_OBJECT) || |
1028 | !CBB_add_bytes(&cert_type, kX509Certificate, sizeof(kX509Certificate)) || |
1029 | !CBB_add_asn1(&cert_bag, &wrapped_cert, |
1030 | CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || |
1031 | !CBB_add_asn1(&wrapped_cert, &cert_value, CBS_ASN1_OCTETSTRING)) { |
1032 | return 0; |
1033 | } |
1034 | uint8_t *buf; |
1035 | int len = i2d_X509(cert, NULL); |
1036 | if (len < 0 || |
1037 | !CBB_add_space(&cert_value, &buf, (size_t)len) || |
1038 | i2d_X509(cert, &buf) < 0 || |
1039 | !add_bag_attributes(&bag, name, key_id, key_id_len) || |
1040 | !CBB_flush(cbb)) { |
1041 | return 0; |
1042 | } |
1043 | return 1; |
1044 | } |
1045 | |
1046 | static int make_cert_safe_contents(uint8_t **out_data, size_t *out_len, |
1047 | X509 *cert, const STACK_OF(X509) *chain, |
1048 | const char *name, const uint8_t *key_id, |
1049 | size_t key_id_len) { |
1050 | int ret = 0; |
1051 | CBB cbb, safe_contents; |
1052 | if (!CBB_init(&cbb, 0) || |
1053 | !CBB_add_asn1(&cbb, &safe_contents, CBS_ASN1_SEQUENCE) || |
1054 | (cert != NULL && |
1055 | !add_cert_bag(&safe_contents, cert, name, key_id, key_id_len))) { |
1056 | goto err; |
1057 | } |
1058 | |
1059 | for (size_t i = 0; i < sk_X509_num(chain); i++) { |
1060 | // Only the leaf certificate gets attributes. |
1061 | if (!add_cert_bag(&safe_contents, sk_X509_value(chain, i), NULL, NULL, 0)) { |
1062 | goto err; |
1063 | } |
1064 | } |
1065 | |
1066 | ret = CBB_finish(&cbb, out_data, out_len); |
1067 | |
1068 | err: |
1069 | CBB_cleanup(&cbb); |
1070 | return ret; |
1071 | } |
1072 | |
1073 | static int add_encrypted_data(CBB *out, int pbe_nid, const char *password, |
1074 | size_t password_len, unsigned iterations, |
1075 | const uint8_t *in, size_t in_len) { |
1076 | uint8_t salt[PKCS5_SALT_LEN]; |
1077 | if (!RAND_bytes(salt, sizeof(salt))) { |
1078 | return 0; |
1079 | } |
1080 | |
1081 | int ret = 0; |
1082 | EVP_CIPHER_CTX ctx; |
1083 | EVP_CIPHER_CTX_init(&ctx); |
1084 | CBB content_info, type, wrapper, encrypted_data, encrypted_content_info, |
1085 | inner_type, encrypted_content; |
1086 | if (// Add the ContentInfo wrapping. |
1087 | !CBB_add_asn1(out, &content_info, CBS_ASN1_SEQUENCE) || |
1088 | !CBB_add_asn1(&content_info, &type, CBS_ASN1_OBJECT) || |
1089 | !CBB_add_bytes(&type, kPKCS7EncryptedData, sizeof(kPKCS7EncryptedData)) || |
1090 | !CBB_add_asn1(&content_info, &wrapper, |
1091 | CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || |
1092 | // See https://tools.ietf.org/html/rfc2315#section-13. |
1093 | !CBB_add_asn1(&wrapper, &encrypted_data, CBS_ASN1_SEQUENCE) || |
1094 | !CBB_add_asn1_uint64(&encrypted_data, 0 /* version */) || |
1095 | // See https://tools.ietf.org/html/rfc2315#section-10.1. |
1096 | !CBB_add_asn1(&encrypted_data, &encrypted_content_info, |
1097 | CBS_ASN1_SEQUENCE) || |
1098 | !CBB_add_asn1(&encrypted_content_info, &inner_type, CBS_ASN1_OBJECT) || |
1099 | !CBB_add_bytes(&inner_type, kPKCS7Data, sizeof(kPKCS7Data)) || |
1100 | // Set up encryption and fill in contentEncryptionAlgorithm. |
1101 | !pkcs12_pbe_encrypt_init(&encrypted_content_info, &ctx, pbe_nid, |
1102 | iterations, password, password_len, salt, |
1103 | sizeof(salt)) || |
1104 | // Note this tag is primitive. It is an implicitly-tagged OCTET_STRING, so |
1105 | // it inherits the inner tag's constructed bit. |
1106 | !CBB_add_asn1(&encrypted_content_info, &encrypted_content, |
1107 | CBS_ASN1_CONTEXT_SPECIFIC | 0)) { |
1108 | goto err; |
1109 | } |
1110 | |
1111 | size_t max_out = in_len + EVP_CIPHER_CTX_block_size(&ctx); |
1112 | if (max_out < in_len) { |
1113 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_TOO_LONG); |
1114 | goto err; |
1115 | } |
1116 | |
1117 | uint8_t *ptr; |
1118 | int n1, n2; |
1119 | if (!CBB_reserve(&encrypted_content, &ptr, max_out) || |
1120 | !EVP_CipherUpdate(&ctx, ptr, &n1, in, in_len) || |
1121 | !EVP_CipherFinal_ex(&ctx, ptr + n1, &n2) || |
1122 | !CBB_did_write(&encrypted_content, n1 + n2) || |
1123 | !CBB_flush(out)) { |
1124 | goto err; |
1125 | } |
1126 | |
1127 | ret = 1; |
1128 | |
1129 | err: |
1130 | EVP_CIPHER_CTX_cleanup(&ctx); |
1131 | return ret; |
1132 | } |
1133 | |
1134 | PKCS12 *PKCS12_create(const char *password, const char *name, |
1135 | const EVP_PKEY *pkey, X509 *cert, |
1136 | const STACK_OF(X509)* chain, int key_nid, int cert_nid, |
1137 | int iterations, int mac_iterations, int key_type) { |
1138 | if (key_nid == 0) { |
1139 | key_nid = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; |
1140 | } |
1141 | if (cert_nid == 0) { |
1142 | cert_nid = NID_pbe_WithSHA1And40BitRC2_CBC; |
1143 | } |
1144 | if (iterations == 0) { |
1145 | iterations = PKCS5_DEFAULT_ITERATIONS; |
1146 | } |
1147 | if (mac_iterations == 0) { |
1148 | mac_iterations = 1; |
1149 | } |
1150 | if (// In OpenSSL, this specifies a non-standard Microsoft key usage extension |
1151 | // which we do not currently support. |
1152 | key_type != 0 || |
1153 | // In OpenSSL, -1 here means to use no encryption, which we do not |
1154 | // currently support. |
1155 | key_nid < 0 || cert_nid < 0 || |
1156 | // In OpenSSL, -1 here means to omit the MAC, which we do not |
1157 | // currently support. Omitting it is also invalid for a password-based |
1158 | // PKCS#12 file. |
1159 | mac_iterations < 0 || |
1160 | // Don't encode empty objects. |
1161 | (pkey == NULL && cert == NULL && sk_X509_num(chain) == 0)) { |
1162 | OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_OPTIONS); |
1163 | return 0; |
1164 | } |
1165 | |
1166 | // Note that |password| may be NULL to specify no password, rather than the |
1167 | // empty string. They are encoded differently in PKCS#12. (One is the empty |
1168 | // byte array and the other is NUL-terminated UCS-2.) |
1169 | size_t password_len = password != NULL ? strlen(password) : 0; |
1170 | |
1171 | uint8_t key_id[EVP_MAX_MD_SIZE]; |
1172 | unsigned key_id_len = 0; |
1173 | if (cert != NULL && pkey != NULL) { |
1174 | if (!X509_check_private_key(cert, pkey) || |
1175 | // Matching OpenSSL, use the SHA-1 hash of the certificate as the local |
1176 | // key ID. Some PKCS#12 consumers require one to connect the private key |
1177 | // and certificate. |
1178 | !X509_digest(cert, EVP_sha1(), key_id, &key_id_len)) { |
1179 | return 0; |
1180 | } |
1181 | } |
1182 | |
1183 | // See https://tools.ietf.org/html/rfc7292#section-4. |
1184 | PKCS12 *ret = NULL; |
1185 | CBB cbb, pfx, auth_safe, auth_safe_oid, auth_safe_wrapper, auth_safe_data, |
1186 | content_infos; |
1187 | uint8_t mac_key[EVP_MAX_MD_SIZE]; |
1188 | if (!CBB_init(&cbb, 0) || |
1189 | !CBB_add_asn1(&cbb, &pfx, CBS_ASN1_SEQUENCE) || |
1190 | !CBB_add_asn1_uint64(&pfx, 3) || |
1191 | // auth_safe is a data ContentInfo. |
1192 | !CBB_add_asn1(&pfx, &auth_safe, CBS_ASN1_SEQUENCE) || |
1193 | !CBB_add_asn1(&auth_safe, &auth_safe_oid, CBS_ASN1_OBJECT) || |
1194 | !CBB_add_bytes(&auth_safe_oid, kPKCS7Data, sizeof(kPKCS7Data)) || |
1195 | !CBB_add_asn1(&auth_safe, &auth_safe_wrapper, |
1196 | CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || |
1197 | !CBB_add_asn1(&auth_safe_wrapper, &auth_safe_data, |
1198 | CBS_ASN1_OCTETSTRING) || |
1199 | // See https://tools.ietf.org/html/rfc7292#section-4.1. |auth_safe|'s |
1200 | // contains a SEQUENCE of ContentInfos. |
1201 | !CBB_add_asn1(&auth_safe_data, &content_infos, CBS_ASN1_SEQUENCE)) { |
1202 | goto err; |
1203 | } |
1204 | |
1205 | // If there are any certificates, place them in CertBags wrapped in a single |
1206 | // encrypted ContentInfo. |
1207 | if (cert != NULL || sk_X509_num(chain) > 0) { |
1208 | uint8_t *data; |
1209 | size_t len; |
1210 | if (!make_cert_safe_contents(&data, &len, cert, chain, name, key_id, |
1211 | key_id_len)) { |
1212 | goto err; |
1213 | } |
1214 | int ok = add_encrypted_data(&content_infos, cert_nid, password, |
1215 | password_len, iterations, data, len); |
1216 | OPENSSL_free(data); |
1217 | if (!ok) { |
1218 | goto err; |
1219 | } |
1220 | } |
1221 | |
1222 | // If there is a key, place it in a single PKCS8ShroudedKeyBag wrapped in an |
1223 | // unencrypted ContentInfo. (One could also place it in a KeyBag inside an |
1224 | // encrypted ContentInfo, but OpenSSL does not do this and some PKCS#12 |
1225 | // consumers do not support KeyBags.) |
1226 | if (pkey != NULL) { |
1227 | CBB content_info, oid, wrapper, data, safe_contents, bag, bag_oid, |
1228 | bag_contents; |
1229 | if (// Add another data ContentInfo. |
1230 | !CBB_add_asn1(&content_infos, &content_info, CBS_ASN1_SEQUENCE) || |
1231 | !CBB_add_asn1(&content_info, &oid, CBS_ASN1_OBJECT) || |
1232 | !CBB_add_bytes(&oid, kPKCS7Data, sizeof(kPKCS7Data)) || |
1233 | !CBB_add_asn1(&content_info, &wrapper, |
1234 | CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || |
1235 | !CBB_add_asn1(&wrapper, &data, CBS_ASN1_OCTETSTRING) || |
1236 | !CBB_add_asn1(&data, &safe_contents, CBS_ASN1_SEQUENCE) || |
1237 | // Add a SafeBag containing a PKCS8ShroudedKeyBag. |
1238 | !CBB_add_asn1(&safe_contents, &bag, CBS_ASN1_SEQUENCE) || |
1239 | !CBB_add_asn1(&bag, &bag_oid, CBS_ASN1_OBJECT) || |
1240 | !CBB_add_bytes(&bag_oid, kPKCS8ShroudedKeyBag, |
1241 | sizeof(kPKCS8ShroudedKeyBag)) || |
1242 | !CBB_add_asn1(&bag, &bag_contents, |
1243 | CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || |
1244 | !PKCS8_marshal_encrypted_private_key( |
1245 | &bag_contents, key_nid, NULL, password, password_len, |
1246 | NULL /* generate a random salt */, 0 /* use default salt length */, |
1247 | iterations, pkey) || |
1248 | !add_bag_attributes(&bag, name, key_id, key_id_len) || |
1249 | !CBB_flush(&content_infos)) { |
1250 | goto err; |
1251 | } |
1252 | } |
1253 | |
1254 | // Compute the MAC. Match OpenSSL in using SHA-1 as the hash function. The MAC |
1255 | // covers |auth_safe_data|. |
1256 | const EVP_MD *mac_md = EVP_sha1(); |
1257 | uint8_t mac_salt[PKCS5_SALT_LEN]; |
1258 | uint8_t mac[EVP_MAX_MD_SIZE]; |
1259 | unsigned mac_len; |
1260 | if (!CBB_flush(&auth_safe_data) || |
1261 | !RAND_bytes(mac_salt, sizeof(mac_salt)) || |
1262 | !pkcs12_key_gen(password, password_len, mac_salt, sizeof(mac_salt), |
1263 | PKCS12_MAC_ID, mac_iterations, EVP_MD_size(mac_md), |
1264 | mac_key, mac_md) || |
1265 | !HMAC(mac_md, mac_key, EVP_MD_size(mac_md), CBB_data(&auth_safe_data), |
1266 | CBB_len(&auth_safe_data), mac, &mac_len)) { |
1267 | goto err; |
1268 | } |
1269 | |
1270 | CBB mac_data, digest_info, mac_cbb, mac_salt_cbb; |
1271 | if (!CBB_add_asn1(&pfx, &mac_data, CBS_ASN1_SEQUENCE) || |
1272 | !CBB_add_asn1(&mac_data, &digest_info, CBS_ASN1_SEQUENCE) || |
1273 | !EVP_marshal_digest_algorithm(&digest_info, mac_md) || |
1274 | !CBB_add_asn1(&digest_info, &mac_cbb, CBS_ASN1_OCTETSTRING) || |
1275 | !CBB_add_bytes(&mac_cbb, mac, mac_len) || |
1276 | !CBB_add_asn1(&mac_data, &mac_salt_cbb, CBS_ASN1_OCTETSTRING) || |
1277 | !CBB_add_bytes(&mac_salt_cbb, mac_salt, sizeof(mac_salt)) || |
1278 | // The iteration count has a DEFAULT of 1, but RFC 7292 says "The default |
1279 | // is for historical reasons and its use is deprecated." Thus we |
1280 | // explicitly encode the iteration count, though it is not valid DER. |
1281 | !CBB_add_asn1_uint64(&mac_data, mac_iterations)) { |
1282 | goto err; |
1283 | } |
1284 | |
1285 | ret = OPENSSL_malloc(sizeof(PKCS12)); |
1286 | if (ret == NULL || |
1287 | !CBB_finish(&cbb, &ret->ber_bytes, &ret->ber_len)) { |
1288 | OPENSSL_free(ret); |
1289 | ret = NULL; |
1290 | goto err; |
1291 | } |
1292 | |
1293 | err: |
1294 | OPENSSL_cleanse(mac_key, sizeof(mac_key)); |
1295 | CBB_cleanup(&cbb); |
1296 | return ret; |
1297 | } |
1298 | |
1299 | void PKCS12_free(PKCS12 *p12) { |
1300 | if (p12 == NULL) { |
1301 | return; |
1302 | } |
1303 | OPENSSL_free(p12->ber_bytes); |
1304 | OPENSSL_free(p12); |
1305 | } |
1306 | |