1 /*
2 * Copyright (C) 2003-2012 Free Software Foundation, Inc.
3 * Copyright (C) 2012 Nikos Mavrogiannopoulos
4 * Copyright (C) 2017 Red Hat, Inc.
5 *
6 * Author: Nikos Mavrogiannopoulos
7 *
8 * This file is part of GnuTLS.
9 *
10 * The GnuTLS is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation; either version 2.1 of
13 * the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>
22 *
23 */
24
25 /* Functions that relate on PKCS12 packet parsing.
26 */
27
28 #include "gnutls_int.h"
29 #include <libtasn1.h>
30
31 #include <datum.h>
32 #include <global.h>
33 #include "errors.h"
34 #include <num.h>
35 #include <common.h>
36 #include <x509_b64.h>
37 #include "x509_int.h"
38 #include "pkcs7_int.h"
39 #include <random.h>
40
41
42 /* Decodes the PKCS #12 auth_safe, and returns the allocated raw data,
43 * which holds them. Returns an ASN1_TYPE of authenticatedSafe.
44 */
45 static int
_decode_pkcs12_auth_safe(ASN1_TYPE pkcs12,ASN1_TYPE * authen_safe,gnutls_datum_t * raw)46 _decode_pkcs12_auth_safe(ASN1_TYPE pkcs12, ASN1_TYPE * authen_safe,
47 gnutls_datum_t * raw)
48 {
49 char oid[MAX_OID_SIZE];
50 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
51 gnutls_datum_t auth_safe = { NULL, 0 };
52 int len, result;
53 char error_str[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
54
55 len = sizeof(oid) - 1;
56 result =
57 asn1_read_value(pkcs12, "authSafe.contentType", oid, &len);
58 if (result != ASN1_SUCCESS) {
59 gnutls_assert();
60 return _gnutls_asn2err(result);
61 }
62
63 if (strcmp(oid, DATA_OID) != 0) {
64 gnutls_assert();
65 _gnutls_debug_log("Unknown PKCS12 Content OID '%s'\n",
66 oid);
67 return GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE;
68 }
69
70 /* Step 1. Read the content data
71 */
72
73 result =
74 _gnutls_x509_read_string(pkcs12, "authSafe.content",
75 &auth_safe, ASN1_ETYPE_OCTET_STRING, 1);
76 if (result < 0) {
77 gnutls_assert();
78 goto cleanup;
79 }
80
81 /* Step 2. Extract the authenticatedSafe.
82 */
83
84 if ((result = asn1_create_element
85 (_gnutls_get_pkix(), "PKIX1.pkcs-12-AuthenticatedSafe",
86 &c2)) != ASN1_SUCCESS) {
87 gnutls_assert();
88 result = _gnutls_asn2err(result);
89 goto cleanup;
90 }
91
92 result =
93 asn1_der_decoding(&c2, auth_safe.data, auth_safe.size,
94 error_str);
95 if (result != ASN1_SUCCESS) {
96 gnutls_assert();
97 _gnutls_debug_log("DER error: %s\n", error_str);
98 result = _gnutls_asn2err(result);
99 goto cleanup;
100 }
101
102 if (raw == NULL) {
103 _gnutls_free_datum(&auth_safe);
104 } else {
105 raw->data = auth_safe.data;
106 raw->size = auth_safe.size;
107 }
108
109 if (authen_safe)
110 *authen_safe = c2;
111 else
112 asn1_delete_structure(&c2);
113
114 return 0;
115
116 cleanup:
117 if (c2)
118 asn1_delete_structure(&c2);
119 _gnutls_free_datum(&auth_safe);
120 return result;
121 }
122
pkcs12_reinit(gnutls_pkcs12_t pkcs12)123 static int pkcs12_reinit(gnutls_pkcs12_t pkcs12)
124 {
125 int result;
126
127 if (pkcs12->pkcs12)
128 asn1_delete_structure(&pkcs12->pkcs12);
129
130 result = asn1_create_element(_gnutls_get_pkix(),
131 "PKIX1.pkcs-12-PFX",
132 &pkcs12->pkcs12);
133 if (result != ASN1_SUCCESS) {
134 gnutls_assert();
135 return _gnutls_asn2err(result);
136 }
137
138 return 0;
139 }
140
141 /**
142 * gnutls_pkcs12_init:
143 * @pkcs12: A pointer to the type to be initialized
144 *
145 * This function will initialize a PKCS12 type. PKCS12 structures
146 * usually contain lists of X.509 Certificates and X.509 Certificate
147 * revocation lists.
148 *
149 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
150 * negative error value.
151 **/
gnutls_pkcs12_init(gnutls_pkcs12_t * pkcs12)152 int gnutls_pkcs12_init(gnutls_pkcs12_t * pkcs12)
153 {
154 *pkcs12 = gnutls_calloc(1, sizeof(gnutls_pkcs12_int));
155
156 if (*pkcs12) {
157 int result = pkcs12_reinit(*pkcs12);
158 if (result < 0) {
159 gnutls_assert();
160 gnutls_free(*pkcs12);
161 return result;
162 }
163 return 0; /* success */
164 }
165 return GNUTLS_E_MEMORY_ERROR;
166 }
167
168 /**
169 * gnutls_pkcs12_deinit:
170 * @pkcs12: The type to be initialized
171 *
172 * This function will deinitialize a PKCS12 type.
173 **/
gnutls_pkcs12_deinit(gnutls_pkcs12_t pkcs12)174 void gnutls_pkcs12_deinit(gnutls_pkcs12_t pkcs12)
175 {
176 if (!pkcs12)
177 return;
178
179 if (pkcs12->pkcs12)
180 asn1_delete_structure(&pkcs12->pkcs12);
181
182 gnutls_free(pkcs12);
183 }
184
185 /**
186 * gnutls_pkcs12_import:
187 * @pkcs12: The data to store the parsed PKCS12.
188 * @data: The DER or PEM encoded PKCS12.
189 * @format: One of DER or PEM
190 * @flags: an ORed sequence of gnutls_privkey_pkcs8_flags
191 *
192 * This function will convert the given DER or PEM encoded PKCS12
193 * to the native gnutls_pkcs12_t format. The output will be stored in 'pkcs12'.
194 *
195 * If the PKCS12 is PEM encoded it should have a header of "PKCS12".
196 *
197 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
198 * negative error value.
199 **/
200 int
gnutls_pkcs12_import(gnutls_pkcs12_t pkcs12,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t format,unsigned int flags)201 gnutls_pkcs12_import(gnutls_pkcs12_t pkcs12,
202 const gnutls_datum_t * data,
203 gnutls_x509_crt_fmt_t format, unsigned int flags)
204 {
205 int result = 0, need_free = 0;
206 gnutls_datum_t _data;
207 char error_str[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
208
209 _data.data = data->data;
210 _data.size = data->size;
211
212 if (pkcs12 == NULL) {
213 gnutls_assert();
214 return GNUTLS_E_INVALID_REQUEST;
215 }
216
217 /* If the PKCS12 is in PEM format then decode it
218 */
219 if (format == GNUTLS_X509_FMT_PEM) {
220 result =
221 _gnutls_fbase64_decode(PEM_PKCS12, data->data,
222 data->size, &_data);
223
224 if (result < 0) {
225 gnutls_assert();
226 return result;
227 }
228
229 need_free = 1;
230 }
231
232 if (pkcs12->expanded) {
233 result = pkcs12_reinit(pkcs12);
234 if (result < 0) {
235 gnutls_assert();
236 goto cleanup;
237 }
238 }
239 pkcs12->expanded = 1;
240
241 result =
242 asn1_der_decoding(&pkcs12->pkcs12, _data.data, _data.size,
243 error_str);
244 if (result != ASN1_SUCCESS) {
245 result = _gnutls_asn2err(result);
246 _gnutls_debug_log("DER error: %s\n", error_str);
247 gnutls_assert();
248 goto cleanup;
249 }
250
251 if (need_free)
252 _gnutls_free_datum(&_data);
253
254 return 0;
255
256 cleanup:
257 if (need_free)
258 _gnutls_free_datum(&_data);
259 return result;
260 }
261
262
263 /**
264 * gnutls_pkcs12_export:
265 * @pkcs12: A pkcs12 type
266 * @format: the format of output params. One of PEM or DER.
267 * @output_data: will contain a structure PEM or DER encoded
268 * @output_data_size: holds the size of output_data (and will be
269 * replaced by the actual size of parameters)
270 *
271 * This function will export the pkcs12 structure to DER or PEM format.
272 *
273 * If the buffer provided is not long enough to hold the output, then
274 * *output_data_size will be updated and GNUTLS_E_SHORT_MEMORY_BUFFER
275 * will be returned.
276 *
277 * If the structure is PEM encoded, it will have a header
278 * of "BEGIN PKCS12".
279 *
280 * Returns: In case of failure a negative error code will be
281 * returned, and 0 on success.
282 **/
283 int
gnutls_pkcs12_export(gnutls_pkcs12_t pkcs12,gnutls_x509_crt_fmt_t format,void * output_data,size_t * output_data_size)284 gnutls_pkcs12_export(gnutls_pkcs12_t pkcs12,
285 gnutls_x509_crt_fmt_t format, void *output_data,
286 size_t * output_data_size)
287 {
288 if (pkcs12 == NULL) {
289 gnutls_assert();
290 return GNUTLS_E_INVALID_REQUEST;
291 }
292
293 return _gnutls_x509_export_int(pkcs12->pkcs12, format, PEM_PKCS12,
294 output_data, output_data_size);
295 }
296
297 /**
298 * gnutls_pkcs12_export2:
299 * @pkcs12: A pkcs12 type
300 * @format: the format of output params. One of PEM or DER.
301 * @out: will contain a structure PEM or DER encoded
302 *
303 * This function will export the pkcs12 structure to DER or PEM format.
304 *
305 * The output buffer is allocated using gnutls_malloc().
306 *
307 * If the structure is PEM encoded, it will have a header
308 * of "BEGIN PKCS12".
309 *
310 * Returns: In case of failure a negative error code will be
311 * returned, and 0 on success.
312 *
313 * Since: 3.1.3
314 **/
315 int
gnutls_pkcs12_export2(gnutls_pkcs12_t pkcs12,gnutls_x509_crt_fmt_t format,gnutls_datum_t * out)316 gnutls_pkcs12_export2(gnutls_pkcs12_t pkcs12,
317 gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
318 {
319 if (pkcs12 == NULL) {
320 gnutls_assert();
321 return GNUTLS_E_INVALID_REQUEST;
322 }
323
324 return _gnutls_x509_export_int2(pkcs12->pkcs12, format, PEM_PKCS12,
325 out);
326 }
327
oid2bag(const char * oid)328 static int oid2bag(const char *oid)
329 {
330 if (strcmp(oid, BAG_PKCS8_KEY) == 0)
331 return GNUTLS_BAG_PKCS8_KEY;
332 if (strcmp(oid, BAG_PKCS8_ENCRYPTED_KEY) == 0)
333 return GNUTLS_BAG_PKCS8_ENCRYPTED_KEY;
334 if (strcmp(oid, BAG_CERTIFICATE) == 0)
335 return GNUTLS_BAG_CERTIFICATE;
336 if (strcmp(oid, BAG_CRL) == 0)
337 return GNUTLS_BAG_CRL;
338 if (strcmp(oid, BAG_SECRET) == 0)
339 return GNUTLS_BAG_SECRET;
340
341 return GNUTLS_BAG_UNKNOWN;
342 }
343
bag_to_oid(int bag)344 static const char *bag_to_oid(int bag)
345 {
346 switch (bag) {
347 case GNUTLS_BAG_PKCS8_KEY:
348 return BAG_PKCS8_KEY;
349 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
350 return BAG_PKCS8_ENCRYPTED_KEY;
351 case GNUTLS_BAG_CERTIFICATE:
352 return BAG_CERTIFICATE;
353 case GNUTLS_BAG_CRL:
354 return BAG_CRL;
355 case GNUTLS_BAG_SECRET:
356 return BAG_SECRET;
357 }
358 return NULL;
359 }
360
361 /* Decodes the SafeContents, and puts the output in
362 * the given bag.
363 */
364 int
_pkcs12_decode_safe_contents(const gnutls_datum_t * content,gnutls_pkcs12_bag_t bag)365 _pkcs12_decode_safe_contents(const gnutls_datum_t * content,
366 gnutls_pkcs12_bag_t bag)
367 {
368 char oid[MAX_OID_SIZE], root[MAX_NAME_SIZE];
369 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
370 int len, result;
371 int bag_type;
372 gnutls_datum_t attr_val;
373 gnutls_datum_t t;
374 int count = 0, attributes, j;
375 unsigned i;
376
377 /* Step 1. Extract the SEQUENCE.
378 */
379
380 if ((result = asn1_create_element
381 (_gnutls_get_pkix(), "PKIX1.pkcs-12-SafeContents",
382 &c2)) != ASN1_SUCCESS) {
383 gnutls_assert();
384 result = _gnutls_asn2err(result);
385 goto cleanup;
386 }
387
388 result =
389 asn1_der_decoding(&c2, content->data, content->size, NULL);
390 if (result != ASN1_SUCCESS) {
391 gnutls_assert();
392 result = _gnutls_asn2err(result);
393 goto cleanup;
394 }
395
396 /* Count the number of bags
397 */
398 result = asn1_number_of_elements(c2, "", &count);
399 if (result != ASN1_SUCCESS) {
400 gnutls_assert();
401 result = _gnutls_asn2err(result);
402 goto cleanup;
403 }
404
405 bag->bag_elements = MIN(MAX_BAG_ELEMENTS, count);
406
407 for (i = 0; i < bag->bag_elements; i++) {
408
409 snprintf(root, sizeof(root), "?%u.bagId", i + 1);
410
411 len = sizeof(oid);
412 result = asn1_read_value(c2, root, oid, &len);
413 if (result != ASN1_SUCCESS) {
414 gnutls_assert();
415 result = _gnutls_asn2err(result);
416 goto cleanup;
417 }
418
419 /* Read the Bag type
420 */
421 bag_type = oid2bag(oid);
422
423 if (bag_type < 0) {
424 gnutls_assert();
425 goto cleanup;
426 }
427
428 /* Read the Bag Value
429 */
430
431 snprintf(root, sizeof(root), "?%u.bagValue", i + 1);
432
433 result =
434 _gnutls_x509_read_value(c2, root,
435 &bag->element[i].data);
436 if (result < 0) {
437 gnutls_assert();
438 goto cleanup;
439 }
440
441 if (bag_type == GNUTLS_BAG_CERTIFICATE
442 || bag_type == GNUTLS_BAG_CRL
443 || bag_type == GNUTLS_BAG_SECRET) {
444 gnutls_datum_t tmp = bag->element[i].data;
445 bag->element[i].data.data = NULL;
446 bag->element[i].data.size = 0;
447
448 result =
449 _pkcs12_decode_crt_bag(bag_type, &tmp,
450 &bag->element[i].data);
451 _gnutls_free_datum(&tmp);
452 if (result < 0) {
453 gnutls_assert();
454 goto cleanup;
455 }
456 }
457
458 /* read the bag attributes
459 */
460 snprintf(root, sizeof(root), "?%u.bagAttributes", i + 1);
461
462 result = asn1_number_of_elements(c2, root, &attributes);
463 if (result != ASN1_SUCCESS
464 && result != ASN1_ELEMENT_NOT_FOUND) {
465 gnutls_assert();
466 result = _gnutls_asn2err(result);
467 goto cleanup;
468 }
469
470 if (attributes < 0)
471 attributes = 1;
472
473 if (result != ASN1_ELEMENT_NOT_FOUND)
474 for (j = 0; j < attributes; j++) {
475
476 snprintf(root, sizeof(root),
477 "?%u.bagAttributes.?%u", i + 1,
478 j + 1);
479
480 result =
481 _gnutls_x509_decode_and_read_attribute
482 (c2, root, oid, sizeof(oid), &attr_val,
483 1, 0);
484
485 if (result < 0) {
486 gnutls_assert();
487 continue; /* continue in case we find some known attributes */
488 }
489
490 if (strcmp(oid, KEY_ID_OID) == 0) {
491 result =
492 _gnutls_x509_decode_string
493 (ASN1_ETYPE_OCTET_STRING,
494 attr_val.data, attr_val.size,
495 &t, 1);
496
497 _gnutls_free_datum(&attr_val);
498 if (result < 0) {
499 gnutls_assert();
500 _gnutls_debug_log
501 ("Error decoding PKCS12 Bag Attribute OID '%s'\n",
502 oid);
503 continue;
504 }
505
506 _gnutls_free_datum(&bag->element[i].local_key_id);
507 bag->element[i].local_key_id.data = t.data;
508 bag->element[i].local_key_id.size = t.size;
509 } else if (strcmp(oid, FRIENDLY_NAME_OID) == 0 && bag->element[i].friendly_name == NULL) {
510 result =
511 _gnutls_x509_decode_string
512 (ASN1_ETYPE_BMP_STRING,
513 attr_val.data, attr_val.size,
514 &t, 1);
515
516 _gnutls_free_datum(&attr_val);
517 if (result < 0) {
518 gnutls_assert();
519 _gnutls_debug_log
520 ("Error decoding PKCS12 Bag Attribute OID '%s'\n",
521 oid);
522 continue;
523 }
524
525 gnutls_free(bag->element[i].friendly_name);
526 bag->element[i].friendly_name = (char *) t.data;
527 } else {
528 _gnutls_free_datum(&attr_val);
529 _gnutls_debug_log
530 ("Unknown PKCS12 Bag Attribute OID '%s'\n",
531 oid);
532 }
533 }
534
535
536 bag->element[i].type = bag_type;
537
538 }
539
540 result = 0;
541
542 cleanup:
543 if (c2)
544 asn1_delete_structure(&c2);
545 return result;
546
547 }
548
549
550 static int
_parse_safe_contents(ASN1_TYPE sc,const char * sc_name,gnutls_pkcs12_bag_t bag)551 _parse_safe_contents(ASN1_TYPE sc, const char *sc_name,
552 gnutls_pkcs12_bag_t bag)
553 {
554 gnutls_datum_t content = { NULL, 0 };
555 int result;
556
557 /* Step 1. Extract the content.
558 */
559
560 result =
561 _gnutls_x509_read_string(sc, sc_name, &content,
562 ASN1_ETYPE_OCTET_STRING, 1);
563 if (result < 0) {
564 gnutls_assert();
565 goto cleanup;
566 }
567
568 result = _pkcs12_decode_safe_contents(&content, bag);
569 if (result < 0) {
570 gnutls_assert();
571 goto cleanup;
572 }
573
574 _gnutls_free_datum(&content);
575
576 return 0;
577
578 cleanup:
579 _gnutls_free_datum(&content);
580 return result;
581 }
582
583
584 /**
585 * gnutls_pkcs12_get_bag:
586 * @pkcs12: A pkcs12 type
587 * @indx: contains the index of the bag to extract
588 * @bag: An initialized bag, where the contents of the bag will be copied
589 *
590 * This function will return a Bag from the PKCS12 structure.
591 *
592 * After the last Bag has been read
593 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
594 *
595 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
596 * negative error value.
597 **/
598 int
gnutls_pkcs12_get_bag(gnutls_pkcs12_t pkcs12,int indx,gnutls_pkcs12_bag_t bag)599 gnutls_pkcs12_get_bag(gnutls_pkcs12_t pkcs12,
600 int indx, gnutls_pkcs12_bag_t bag)
601 {
602 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
603 int result, len;
604 char root2[MAX_NAME_SIZE];
605 char oid[MAX_OID_SIZE];
606
607 if (pkcs12 == NULL) {
608 gnutls_assert();
609 return GNUTLS_E_INVALID_REQUEST;
610 }
611
612 /* Step 1. decode the data.
613 */
614 result = _decode_pkcs12_auth_safe(pkcs12->pkcs12, &c2, NULL);
615 if (result < 0) {
616 gnutls_assert();
617 return result;
618 }
619
620 /* Step 2. Parse the AuthenticatedSafe
621 */
622
623 snprintf(root2, sizeof(root2), "?%u.contentType", indx + 1);
624
625 len = sizeof(oid) - 1;
626 result = asn1_read_value(c2, root2, oid, &len);
627
628 if (result == ASN1_ELEMENT_NOT_FOUND) {
629 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
630 goto cleanup;
631 }
632
633 if (result != ASN1_SUCCESS) {
634 gnutls_assert();
635 result = _gnutls_asn2err(result);
636 goto cleanup;
637 }
638
639 /* Not encrypted Bag
640 */
641
642 snprintf(root2, sizeof(root2), "?%u.content", indx + 1);
643
644 if (strcmp(oid, DATA_OID) == 0) {
645 result = _parse_safe_contents(c2, root2, bag);
646 goto cleanup;
647 }
648
649 /* ENC_DATA_OID needs decryption */
650
651 result = _gnutls_x509_read_value(c2, root2, &bag->element[0].data);
652 if (result < 0) {
653 gnutls_assert();
654 goto cleanup;
655 }
656
657 bag->element[0].type = GNUTLS_BAG_ENCRYPTED;
658 bag->bag_elements = 1;
659
660 result = 0;
661
662 cleanup:
663 if (c2)
664 asn1_delete_structure(&c2);
665 return result;
666 }
667
668 /* Creates an empty PFX structure for the PKCS12 structure.
669 */
create_empty_pfx(ASN1_TYPE pkcs12)670 static int create_empty_pfx(ASN1_TYPE pkcs12)
671 {
672 uint8_t three = 3;
673 int result;
674 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
675
676 /* Use version 3
677 */
678 result = asn1_write_value(pkcs12, "version", &three, 1);
679 if (result != ASN1_SUCCESS) {
680 gnutls_assert();
681 result = _gnutls_asn2err(result);
682 goto cleanup;
683 }
684
685 /* Write the content type of the data
686 */
687 result =
688 asn1_write_value(pkcs12, "authSafe.contentType", DATA_OID, 1);
689 if (result != ASN1_SUCCESS) {
690 gnutls_assert();
691 result = _gnutls_asn2err(result);
692 goto cleanup;
693 }
694
695 /* Check if the authenticatedSafe content is empty, and encode a
696 * null one in that case.
697 */
698
699 if ((result = asn1_create_element
700 (_gnutls_get_pkix(), "PKIX1.pkcs-12-AuthenticatedSafe",
701 &c2)) != ASN1_SUCCESS) {
702 gnutls_assert();
703 result = _gnutls_asn2err(result);
704 goto cleanup;
705 }
706
707 result =
708 _gnutls_x509_der_encode_and_copy(c2, "", pkcs12,
709 "authSafe.content", 1);
710 if (result < 0) {
711 gnutls_assert();
712 goto cleanup;
713 }
714 asn1_delete_structure(&c2);
715
716 return 0;
717
718 cleanup:
719 asn1_delete_structure(&c2);
720 return result;
721
722 }
723
724 /**
725 * gnutls_pkcs12_set_bag:
726 * @pkcs12: should contain a gnutls_pkcs12_t type
727 * @bag: An initialized bag
728 *
729 * This function will insert a Bag into the PKCS12 structure.
730 *
731 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
732 * negative error value.
733 **/
gnutls_pkcs12_set_bag(gnutls_pkcs12_t pkcs12,gnutls_pkcs12_bag_t bag)734 int gnutls_pkcs12_set_bag(gnutls_pkcs12_t pkcs12, gnutls_pkcs12_bag_t bag)
735 {
736 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
737 ASN1_TYPE safe_cont = ASN1_TYPE_EMPTY;
738 int result;
739 int enc = 0, dum = 1;
740 char null;
741
742 if (pkcs12 == NULL) {
743 gnutls_assert();
744 return GNUTLS_E_INVALID_REQUEST;
745 }
746
747 /* Step 1. Check if the pkcs12 structure is empty. In that
748 * case generate an empty PFX.
749 */
750 result =
751 asn1_read_value(pkcs12->pkcs12, "authSafe.content", &null,
752 &dum);
753 if (result == ASN1_VALUE_NOT_FOUND) {
754 result = create_empty_pfx(pkcs12->pkcs12);
755 if (result < 0) {
756 gnutls_assert();
757 return result;
758 }
759 }
760
761 /* Step 2. decode the authenticatedSafe.
762 */
763 result = _decode_pkcs12_auth_safe(pkcs12->pkcs12, &c2, NULL);
764 if (result < 0) {
765 gnutls_assert();
766 return result;
767 }
768
769 /* Step 3. Encode the bag elements into a SafeContents
770 * structure.
771 */
772 result = _pkcs12_encode_safe_contents(bag, &safe_cont, &enc);
773 if (result < 0) {
774 gnutls_assert();
775 return result;
776 }
777
778 /* Step 4. Insert the encoded SafeContents into the AuthenticatedSafe
779 * structure.
780 */
781 result = asn1_write_value(c2, "", "NEW", 1);
782 if (result != ASN1_SUCCESS) {
783 gnutls_assert();
784 result = _gnutls_asn2err(result);
785 goto cleanup;
786 }
787
788 if (enc)
789 result =
790 asn1_write_value(c2, "?LAST.contentType", ENC_DATA_OID,
791 1);
792 else
793 result =
794 asn1_write_value(c2, "?LAST.contentType", DATA_OID, 1);
795 if (result != ASN1_SUCCESS) {
796 gnutls_assert();
797 result = _gnutls_asn2err(result);
798 goto cleanup;
799 }
800
801 if (enc) {
802 /* Encrypted packets are written directly.
803 */
804 result =
805 asn1_write_value(c2, "?LAST.content",
806 bag->element[0].data.data,
807 bag->element[0].data.size);
808 if (result != ASN1_SUCCESS) {
809 gnutls_assert();
810 result = _gnutls_asn2err(result);
811 goto cleanup;
812 }
813 } else {
814 result =
815 _gnutls_x509_der_encode_and_copy(safe_cont, "", c2,
816 "?LAST.content", 1);
817 if (result < 0) {
818 gnutls_assert();
819 goto cleanup;
820 }
821 }
822
823 asn1_delete_structure(&safe_cont);
824
825
826 /* Step 5. Re-encode and copy the AuthenticatedSafe into the pkcs12
827 * structure.
828 */
829 result =
830 _gnutls_x509_der_encode_and_copy(c2, "", pkcs12->pkcs12,
831 "authSafe.content", 1);
832 if (result < 0) {
833 gnutls_assert();
834 goto cleanup;
835 }
836
837 asn1_delete_structure(&c2);
838
839 return 0;
840
841 cleanup:
842 asn1_delete_structure(&c2);
843 asn1_delete_structure(&safe_cont);
844 return result;
845 }
846
847 #if ENABLE_GOST
848 /*
849 * Russian differs from PKCS#12 here. It described proprietary way
850 * to obtain MAC key instead of using standard mechanism.
851 *
852 * See https://wwwold.tc26.ru/standard/rs/%D0%A0%2050.1.112-2016.pdf
853 * section 5.
854 */
855 static int
_gnutls_pkcs12_gost_string_to_key(gnutls_mac_algorithm_t algo,const uint8_t * salt,unsigned int salt_size,unsigned int iter,const char * pass,unsigned int req_keylen,uint8_t * keybuf)856 _gnutls_pkcs12_gost_string_to_key(gnutls_mac_algorithm_t algo,
857 const uint8_t * salt,
858 unsigned int salt_size, unsigned int iter,
859 const char *pass, unsigned int req_keylen,
860 uint8_t * keybuf)
861 {
862 uint8_t temp[96];
863 size_t temp_len = sizeof(temp);
864 gnutls_datum_t key;
865 gnutls_datum_t _salt;
866 int ret;
867
868 if (iter == 0)
869 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
870
871 key.data = (void *)pass;
872 key.size = pass ? strlen(pass) : 0;
873
874 _salt.data = (void *)salt;
875 _salt.size = salt_size;
876
877 ret = gnutls_pbkdf2(algo, &key, &_salt, iter, temp, temp_len);
878 if (ret < 0)
879 return gnutls_assert_val(ret);
880
881 memcpy(keybuf, temp + temp_len - req_keylen, req_keylen);
882
883 return 0;
884 }
885 #endif
886
887 /**
888 * gnutls_pkcs12_generate_mac2:
889 * @pkcs12: A pkcs12 type
890 * @mac: the MAC algorithm to use
891 * @pass: The password for the MAC
892 *
893 * This function will generate a MAC for the PKCS12 structure.
894 *
895 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
896 * negative error value.
897 **/
gnutls_pkcs12_generate_mac2(gnutls_pkcs12_t pkcs12,gnutls_mac_algorithm_t mac,const char * pass)898 int gnutls_pkcs12_generate_mac2(gnutls_pkcs12_t pkcs12, gnutls_mac_algorithm_t mac, const char *pass)
899 {
900 uint8_t salt[8], key[MAX_HASH_SIZE];
901 int result;
902 const int iter = 10*1024;
903 mac_hd_st td1;
904 gnutls_datum_t tmp = { NULL, 0 };
905 unsigned mac_size, key_len;
906 uint8_t mac_out[MAX_HASH_SIZE];
907 const mac_entry_st *me = mac_to_entry(mac);
908
909 if (pkcs12 == NULL || me == NULL)
910 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
911
912 if (me->oid == NULL)
913 return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
914
915 mac_size = _gnutls_mac_get_algo_len(me);
916 key_len = mac_size;
917
918 /* Generate the salt.
919 */
920 result = gnutls_rnd(GNUTLS_RND_NONCE, salt, sizeof(salt));
921 if (result < 0) {
922 gnutls_assert();
923 return result;
924 }
925
926 /* Write the salt into the structure.
927 */
928 result =
929 asn1_write_value(pkcs12->pkcs12, "macData.macSalt", salt,
930 sizeof(salt));
931 if (result != ASN1_SUCCESS) {
932 gnutls_assert();
933 result = _gnutls_asn2err(result);
934 goto cleanup;
935 }
936
937 /* write the iterations
938 */
939
940 if (iter > 1) {
941 result =
942 _gnutls_x509_write_uint32(pkcs12->pkcs12,
943 "macData.iterations", iter);
944 if (result < 0) {
945 gnutls_assert();
946 goto cleanup;
947 }
948 }
949
950 /* Generate the key.
951 */
952 #if ENABLE_GOST
953 if (me->id == GNUTLS_MAC_GOSTR_94 ||
954 me->id == GNUTLS_MAC_STREEBOG_256 ||
955 me->id == GNUTLS_MAC_STREEBOG_512) {
956 key_len = 32;
957 result = _gnutls_pkcs12_gost_string_to_key(me->id,
958 salt,
959 sizeof(salt),
960 iter,
961 pass,
962 key_len,
963 key);
964 } else
965 #endif
966 result = _gnutls_pkcs12_string_to_key(me, 3 /*MAC*/,
967 salt, sizeof(salt),
968 iter, pass,
969 mac_size, key);
970 if (result < 0) {
971 gnutls_assert();
972 goto cleanup;
973 }
974
975 /* Get the data to be MACed
976 */
977 result = _decode_pkcs12_auth_safe(pkcs12->pkcs12, NULL, &tmp);
978 if (result < 0) {
979 gnutls_assert();
980 goto cleanup;
981 }
982
983 /* MAC the data
984 */
985 result = _gnutls_mac_init(&td1, me,
986 key, key_len);
987 if (result < 0) {
988 gnutls_assert();
989 goto cleanup;
990 }
991
992 _gnutls_mac(&td1, tmp.data, tmp.size);
993 _gnutls_free_datum(&tmp);
994
995 _gnutls_mac_deinit(&td1, mac_out);
996
997
998 result =
999 asn1_write_value(pkcs12->pkcs12, "macData.mac.digest", mac_out,
1000 mac_size);
1001 if (result != ASN1_SUCCESS) {
1002 gnutls_assert();
1003 result = _gnutls_asn2err(result);
1004 goto cleanup;
1005 }
1006
1007 result =
1008 asn1_write_value(pkcs12->pkcs12,
1009 "macData.mac.digestAlgorithm.parameters",
1010 NULL, 0);
1011 if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND) {
1012 gnutls_assert();
1013 result = _gnutls_asn2err(result);
1014 goto cleanup;
1015 }
1016
1017 result =
1018 asn1_write_value(pkcs12->pkcs12,
1019 "macData.mac.digestAlgorithm.algorithm",
1020 me->oid, 1);
1021 if (result != ASN1_SUCCESS) {
1022 gnutls_assert();
1023 result = _gnutls_asn2err(result);
1024 goto cleanup;
1025 }
1026
1027 return 0;
1028
1029 cleanup:
1030 _gnutls_free_datum(&tmp);
1031 return result;
1032 }
1033
1034 /**
1035 * gnutls_pkcs12_generate_mac:
1036 * @pkcs12: A pkcs12 type
1037 * @pass: The password for the MAC
1038 *
1039 * This function will generate a MAC for the PKCS12 structure.
1040 *
1041 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1042 * negative error value.
1043 **/
gnutls_pkcs12_generate_mac(gnutls_pkcs12_t pkcs12,const char * pass)1044 int gnutls_pkcs12_generate_mac(gnutls_pkcs12_t pkcs12, const char *pass)
1045 {
1046 return gnutls_pkcs12_generate_mac2(pkcs12, GNUTLS_MAC_SHA1, pass);
1047 }
1048
1049 /**
1050 * gnutls_pkcs12_verify_mac:
1051 * @pkcs12: should contain a gnutls_pkcs12_t type
1052 * @pass: The password for the MAC
1053 *
1054 * This function will verify the MAC for the PKCS12 structure.
1055 *
1056 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1057 * negative error value.
1058 **/
gnutls_pkcs12_verify_mac(gnutls_pkcs12_t pkcs12,const char * pass)1059 int gnutls_pkcs12_verify_mac(gnutls_pkcs12_t pkcs12, const char *pass)
1060 {
1061 uint8_t key[MAX_HASH_SIZE];
1062 char oid[MAX_OID_SIZE];
1063 int result;
1064 unsigned int iter;
1065 int len;
1066 mac_hd_st td1;
1067 gnutls_datum_t tmp = { NULL, 0 }, salt = {
1068 NULL, 0};
1069 uint8_t mac_output[MAX_HASH_SIZE];
1070 uint8_t mac_output_orig[MAX_HASH_SIZE];
1071 gnutls_mac_algorithm_t algo;
1072 unsigned mac_len, key_len;
1073 const mac_entry_st *entry;
1074 #if ENABLE_GOST
1075 int gost_retry = 0;
1076 #endif
1077
1078 if (pkcs12 == NULL) {
1079 gnutls_assert();
1080 return GNUTLS_E_INVALID_REQUEST;
1081 }
1082
1083 /* read the iterations
1084 */
1085 result =
1086 _gnutls_x509_read_uint(pkcs12->pkcs12, "macData.iterations",
1087 &iter);
1088 if (result < 0) {
1089 iter = 1; /* the default */
1090 }
1091
1092 len = sizeof(oid);
1093 result =
1094 asn1_read_value(pkcs12->pkcs12, "macData.mac.digestAlgorithm.algorithm",
1095 oid, &len);
1096 if (result != ASN1_SUCCESS) {
1097 gnutls_assert();
1098 return _gnutls_asn2err(result);
1099 }
1100
1101 algo = DIG_TO_MAC(gnutls_oid_to_digest(oid));
1102 if (algo == GNUTLS_MAC_UNKNOWN) {
1103 unknown_mac:
1104 gnutls_assert();
1105 return GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
1106 }
1107
1108 entry = mac_to_entry(algo);
1109 if (entry == NULL)
1110 goto unknown_mac;
1111
1112 mac_len = _gnutls_mac_get_algo_len(entry);
1113 key_len = mac_len;
1114
1115 /* Read the salt from the structure.
1116 */
1117 result =
1118 _gnutls_x509_read_null_value(pkcs12->pkcs12, "macData.macSalt",
1119 &salt);
1120 if (result < 0) {
1121 gnutls_assert();
1122 goto cleanup;
1123 }
1124
1125 /* Generate the key.
1126 */
1127 result = _gnutls_pkcs12_string_to_key(entry, 3 /*MAC*/,
1128 salt.data, salt.size,
1129 iter, pass,
1130 key_len, key);
1131 if (result < 0) {
1132 gnutls_assert();
1133 goto cleanup;
1134 }
1135
1136 /* Get the data to be MACed
1137 */
1138 result = _decode_pkcs12_auth_safe(pkcs12->pkcs12, NULL, &tmp);
1139 if (result < 0) {
1140 gnutls_assert();
1141 goto cleanup;
1142 }
1143
1144 #if ENABLE_GOST
1145 /* GOST PKCS#12 files use either PKCS#12 scheme or proprietary
1146 * HMAC-based scheme to generate MAC key. */
1147 pkcs12_try_gost:
1148 #endif
1149
1150 /* MAC the data
1151 */
1152 result = _gnutls_mac_init(&td1, entry, key, key_len);
1153 if (result < 0) {
1154 gnutls_assert();
1155 goto cleanup;
1156 }
1157
1158 _gnutls_mac(&td1, tmp.data, tmp.size);
1159
1160 _gnutls_mac_deinit(&td1, mac_output);
1161
1162 len = sizeof(mac_output_orig);
1163 result =
1164 asn1_read_value(pkcs12->pkcs12, "macData.mac.digest",
1165 mac_output_orig, &len);
1166 if (result != ASN1_SUCCESS) {
1167 gnutls_assert();
1168 result = _gnutls_asn2err(result);
1169 goto cleanup;
1170 }
1171
1172 if ((unsigned)len != mac_len ||
1173 memcmp(mac_output_orig, mac_output, len) != 0) {
1174
1175 #if ENABLE_GOST
1176 /* It is possible that GOST files use proprietary
1177 * key generation scheme */
1178 if (!gost_retry &&
1179 (algo == GNUTLS_MAC_GOSTR_94 ||
1180 algo == GNUTLS_MAC_STREEBOG_256 ||
1181 algo == GNUTLS_MAC_STREEBOG_512)) {
1182 gost_retry = 1;
1183 key_len = 32;
1184 result = _gnutls_pkcs12_gost_string_to_key(algo,
1185 salt.data,
1186 salt.size,
1187 iter,
1188 pass,
1189 key_len,
1190 key);
1191 if (result < 0) {
1192 gnutls_assert();
1193 goto cleanup;
1194 }
1195
1196 goto pkcs12_try_gost;
1197 }
1198 #endif
1199
1200 gnutls_assert();
1201 result = GNUTLS_E_MAC_VERIFY_FAILED;
1202 goto cleanup;
1203 }
1204
1205 result = 0;
1206 cleanup:
1207 _gnutls_free_datum(&tmp);
1208 _gnutls_free_datum(&salt);
1209 return result;
1210 }
1211
1212
1213 static int
write_attributes(gnutls_pkcs12_bag_t bag,int elem,ASN1_TYPE c2,const char * where)1214 write_attributes(gnutls_pkcs12_bag_t bag, int elem,
1215 ASN1_TYPE c2, const char *where)
1216 {
1217 int result;
1218 char root[128];
1219
1220 /* If the bag attributes are empty, then write
1221 * nothing to the attribute field.
1222 */
1223 if (bag->element[elem].friendly_name == NULL &&
1224 bag->element[elem].local_key_id.data == NULL) {
1225 /* no attributes
1226 */
1227 result = asn1_write_value(c2, where, NULL, 0);
1228 if (result != ASN1_SUCCESS) {
1229 gnutls_assert();
1230 return _gnutls_asn2err(result);
1231 }
1232
1233 return 0;
1234 }
1235
1236 if (bag->element[elem].local_key_id.data != NULL) {
1237
1238 /* Add a new Attribute
1239 */
1240 result = asn1_write_value(c2, where, "NEW", 1);
1241 if (result != ASN1_SUCCESS) {
1242 gnutls_assert();
1243 return _gnutls_asn2err(result);
1244 }
1245
1246 _gnutls_str_cpy(root, sizeof(root), where);
1247 _gnutls_str_cat(root, sizeof(root), ".?LAST");
1248
1249 result =
1250 _gnutls_x509_encode_and_write_attribute(KEY_ID_OID, c2,
1251 root,
1252 bag->element
1253 [elem].
1254 local_key_id.data,
1255 bag->element
1256 [elem].
1257 local_key_id.size,
1258 1);
1259 if (result < 0) {
1260 gnutls_assert();
1261 return result;
1262 }
1263 }
1264
1265 if (bag->element[elem].friendly_name != NULL) {
1266 uint8_t *name;
1267 int size, i;
1268 const char *p;
1269
1270 /* Add a new Attribute
1271 */
1272 result = asn1_write_value(c2, where, "NEW", 1);
1273 if (result != ASN1_SUCCESS) {
1274 gnutls_assert();
1275 return _gnutls_asn2err(result);
1276 }
1277
1278 /* convert name to BMPString
1279 */
1280 size = strlen(bag->element[elem].friendly_name) * 2;
1281 name = gnutls_malloc(size);
1282
1283 if (name == NULL) {
1284 gnutls_assert();
1285 return GNUTLS_E_MEMORY_ERROR;
1286 }
1287
1288 p = bag->element[elem].friendly_name;
1289 for (i = 0; i < size; i += 2) {
1290 name[i] = 0;
1291 name[i + 1] = *p;
1292 p++;
1293 }
1294
1295 _gnutls_str_cpy(root, sizeof(root), where);
1296 _gnutls_str_cat(root, sizeof(root), ".?LAST");
1297
1298 result =
1299 _gnutls_x509_encode_and_write_attribute
1300 (FRIENDLY_NAME_OID, c2, root, name, size, 1);
1301
1302 gnutls_free(name);
1303
1304 if (result < 0) {
1305 gnutls_assert();
1306 return result;
1307 }
1308 }
1309
1310 return 0;
1311 }
1312
1313
1314 /* Encodes the bag into a SafeContents structure, and puts the output in
1315 * the given datum. Enc is set to non-zero if the data are encrypted;
1316 */
1317 int
_pkcs12_encode_safe_contents(gnutls_pkcs12_bag_t bag,ASN1_TYPE * contents,int * enc)1318 _pkcs12_encode_safe_contents(gnutls_pkcs12_bag_t bag, ASN1_TYPE * contents,
1319 int *enc)
1320 {
1321 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1322 int result;
1323 unsigned i;
1324 const char *oid;
1325
1326 if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED && enc) {
1327 *enc = 1;
1328 return 0; /* ENCRYPTED BAG, do nothing. */
1329 } else if (enc)
1330 *enc = 0;
1331
1332 /* Step 1. Create the SEQUENCE.
1333 */
1334
1335 if ((result = asn1_create_element
1336 (_gnutls_get_pkix(), "PKIX1.pkcs-12-SafeContents",
1337 &c2)) != ASN1_SUCCESS) {
1338 gnutls_assert();
1339 result = _gnutls_asn2err(result);
1340 goto cleanup;
1341 }
1342
1343 for (i = 0; i < bag->bag_elements; i++) {
1344
1345 oid = bag_to_oid(bag->element[i].type);
1346 if (oid == NULL) {
1347 gnutls_assert();
1348 continue;
1349 }
1350
1351 result = asn1_write_value(c2, "", "NEW", 1);
1352 if (result != ASN1_SUCCESS) {
1353 gnutls_assert();
1354 result = _gnutls_asn2err(result);
1355 goto cleanup;
1356 }
1357
1358 /* Copy the bag type.
1359 */
1360 result = asn1_write_value(c2, "?LAST.bagId", oid, 1);
1361 if (result != ASN1_SUCCESS) {
1362 gnutls_assert();
1363 result = _gnutls_asn2err(result);
1364 goto cleanup;
1365 }
1366
1367 /* Set empty attributes
1368 */
1369 result =
1370 write_attributes(bag, i, c2, "?LAST.bagAttributes");
1371 if (result < 0) {
1372 gnutls_assert();
1373 goto cleanup;
1374 }
1375
1376
1377 /* Copy the Bag Value
1378 */
1379
1380 if (bag->element[i].type == GNUTLS_BAG_CERTIFICATE ||
1381 bag->element[i].type == GNUTLS_BAG_SECRET ||
1382 bag->element[i].type == GNUTLS_BAG_CRL) {
1383 gnutls_datum_t tmp;
1384
1385 /* in that case encode it to a CertBag or
1386 * a CrlBag.
1387 */
1388
1389 result =
1390 _pkcs12_encode_crt_bag(bag->element[i].type,
1391 &bag->element[i].data,
1392 &tmp);
1393
1394 if (result < 0) {
1395 gnutls_assert();
1396 goto cleanup;
1397 }
1398
1399 result =
1400 _gnutls_x509_write_value(c2, "?LAST.bagValue",
1401 &tmp);
1402
1403 _gnutls_free_datum(&tmp);
1404
1405 } else {
1406
1407 result =
1408 _gnutls_x509_write_value(c2, "?LAST.bagValue",
1409 &bag->element[i].
1410 data);
1411 }
1412
1413 if (result < 0) {
1414 gnutls_assert();
1415 goto cleanup;
1416 }
1417
1418 }
1419
1420 /* Encode the data and copy them into the datum
1421 */
1422 *contents = c2;
1423
1424 return 0;
1425
1426 cleanup:
1427 if (c2)
1428 asn1_delete_structure(&c2);
1429 return result;
1430
1431 }
1432
1433 /* Checks if the extra_certs contain certificates that may form a chain
1434 * with the first certificate in chain (it is expected that chain_len==1)
1435 * and appends those in the chain.
1436 */
make_chain(gnutls_x509_crt_t ** chain,unsigned int * chain_len,gnutls_x509_crt_t ** extra_certs,unsigned int * extra_certs_len,unsigned int flags)1437 static int make_chain(gnutls_x509_crt_t ** chain, unsigned int *chain_len,
1438 gnutls_x509_crt_t ** extra_certs,
1439 unsigned int *extra_certs_len, unsigned int flags)
1440 {
1441 unsigned int i;
1442
1443 if (*chain_len != 1)
1444 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1445
1446 i = 0;
1447 while (i < *extra_certs_len) {
1448 /* if it is an issuer but not a self-signed one */
1449 if (gnutls_x509_crt_check_issuer
1450 ((*chain)[*chain_len - 1], (*extra_certs)[i]) != 0) {
1451 if (!(flags & GNUTLS_PKCS12_SP_INCLUDE_SELF_SIGNED)
1452 &&
1453 gnutls_x509_crt_check_issuer((*extra_certs)[i],
1454 (*extra_certs)[i])
1455 != 0)
1456 goto skip;
1457
1458 *chain =
1459 gnutls_realloc_fast(*chain,
1460 sizeof((*chain)[0]) *
1461 ++(*chain_len));
1462 if (*chain == NULL) {
1463 gnutls_assert();
1464 return GNUTLS_E_MEMORY_ERROR;
1465 }
1466 (*chain)[*chain_len - 1] = (*extra_certs)[i];
1467
1468 (*extra_certs)[i] =
1469 (*extra_certs)[*extra_certs_len - 1];
1470 (*extra_certs_len)--;
1471
1472 i = 0;
1473 continue;
1474 }
1475
1476 skip:
1477 i++;
1478 }
1479 return 0;
1480 }
1481
1482 /**
1483 * gnutls_pkcs12_simple_parse:
1484 * @p12: A pkcs12 type
1485 * @password: optional password used to decrypt the structure, bags and keys.
1486 * @key: a structure to store the parsed private key.
1487 * @chain: the corresponding to key certificate chain (may be %NULL)
1488 * @chain_len: will be updated with the number of additional (may be %NULL)
1489 * @extra_certs: optional pointer to receive an array of additional
1490 * certificates found in the PKCS12 structure (may be %NULL).
1491 * @extra_certs_len: will be updated with the number of additional
1492 * certs (may be %NULL).
1493 * @crl: an optional structure to store the parsed CRL (may be %NULL).
1494 * @flags: should be zero or one of GNUTLS_PKCS12_SP_*
1495 *
1496 * This function parses a PKCS12 structure in @pkcs12 and extracts the
1497 * private key, the corresponding certificate chain, any additional
1498 * certificates and a CRL. The structures in @key, @chain @crl, and @extra_certs
1499 * must not be initialized.
1500 *
1501 * The @extra_certs and @extra_certs_len parameters are optional
1502 * and both may be set to %NULL. If either is non-%NULL, then both must
1503 * be set. The value for @extra_certs is allocated
1504 * using gnutls_malloc().
1505 *
1506 * Encrypted PKCS12 bags and PKCS8 private keys are supported, but
1507 * only with password based security and the same password for all
1508 * operations.
1509 *
1510 * Note that a PKCS12 structure may contain many keys and/or certificates,
1511 * and there is no way to identify which key/certificate pair you want.
1512 * For this reason this function is useful for PKCS12 files that contain
1513 * only one key/certificate pair and/or one CRL.
1514 *
1515 * If the provided structure has encrypted fields but no password
1516 * is provided then this function returns %GNUTLS_E_DECRYPTION_FAILED.
1517 *
1518 * Note that normally the chain constructed does not include self signed
1519 * certificates, to comply with TLS' requirements. If, however, the flag
1520 * %GNUTLS_PKCS12_SP_INCLUDE_SELF_SIGNED is specified then
1521 * self signed certificates will be included in the chain.
1522 *
1523 * Prior to using this function the PKCS #12 structure integrity must
1524 * be verified using gnutls_pkcs12_verify_mac().
1525 *
1526 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1527 * negative error value.
1528 *
1529 * Since: 3.1.0
1530 **/
1531 int
gnutls_pkcs12_simple_parse(gnutls_pkcs12_t p12,const char * password,gnutls_x509_privkey_t * key,gnutls_x509_crt_t ** chain,unsigned int * chain_len,gnutls_x509_crt_t ** extra_certs,unsigned int * extra_certs_len,gnutls_x509_crl_t * crl,unsigned int flags)1532 gnutls_pkcs12_simple_parse(gnutls_pkcs12_t p12,
1533 const char *password,
1534 gnutls_x509_privkey_t * key,
1535 gnutls_x509_crt_t ** chain,
1536 unsigned int *chain_len,
1537 gnutls_x509_crt_t ** extra_certs,
1538 unsigned int *extra_certs_len,
1539 gnutls_x509_crl_t * crl, unsigned int flags)
1540 {
1541 gnutls_pkcs12_bag_t bag = NULL;
1542 gnutls_x509_crt_t *_extra_certs = NULL;
1543 unsigned int _extra_certs_len = 0;
1544 gnutls_x509_crt_t *_chain = NULL;
1545 unsigned int _chain_len = 0;
1546 int idx = 0;
1547 int ret;
1548 size_t cert_id_size = 0;
1549 size_t key_id_size = 0;
1550 uint8_t cert_id[20];
1551 uint8_t key_id[20];
1552 int privkey_ok = 0;
1553 unsigned int i;
1554 int elements_in_bag;
1555
1556 *key = NULL;
1557
1558 if (crl)
1559 *crl = NULL;
1560
1561 /* find the first private key */
1562 for (;;) {
1563
1564 ret = gnutls_pkcs12_bag_init(&bag);
1565 if (ret < 0) {
1566 bag = NULL;
1567 gnutls_assert();
1568 goto done;
1569 }
1570
1571 ret = gnutls_pkcs12_get_bag(p12, idx, bag);
1572 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1573 gnutls_pkcs12_bag_deinit(bag);
1574 bag = NULL;
1575 break;
1576 }
1577 if (ret < 0) {
1578 gnutls_assert();
1579 goto done;
1580 }
1581
1582 ret = gnutls_pkcs12_bag_get_type(bag, 0);
1583 if (ret < 0) {
1584 gnutls_assert();
1585 goto done;
1586 }
1587
1588 if (ret == GNUTLS_BAG_ENCRYPTED) {
1589 if (password == NULL) {
1590 ret =
1591 gnutls_assert_val
1592 (GNUTLS_E_DECRYPTION_FAILED);
1593 goto done;
1594 }
1595
1596 ret = gnutls_pkcs12_bag_decrypt(bag, password);
1597 if (ret < 0) {
1598 gnutls_assert();
1599 goto done;
1600 }
1601 }
1602
1603 elements_in_bag = gnutls_pkcs12_bag_get_count(bag);
1604 if (elements_in_bag < 0) {
1605 gnutls_assert();
1606 goto done;
1607 }
1608
1609 for (i = 0; i < (unsigned)elements_in_bag; i++) {
1610 int type;
1611 gnutls_datum_t data;
1612
1613 type = gnutls_pkcs12_bag_get_type(bag, i);
1614 if (type < 0) {
1615 gnutls_assert();
1616 goto done;
1617 }
1618
1619 ret = gnutls_pkcs12_bag_get_data(bag, i, &data);
1620 if (ret < 0) {
1621 gnutls_assert();
1622 goto done;
1623 }
1624
1625 switch (type) {
1626 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
1627 if (password == NULL) {
1628 ret =
1629 gnutls_assert_val
1630 (GNUTLS_E_DECRYPTION_FAILED);
1631 goto done;
1632 }
1633
1634 FALLTHROUGH;
1635 case GNUTLS_BAG_PKCS8_KEY:
1636 if (*key != NULL) { /* too simple to continue */
1637 gnutls_assert();
1638 break;
1639 }
1640
1641 ret = gnutls_x509_privkey_init(key);
1642 if (ret < 0) {
1643 gnutls_assert();
1644 goto done;
1645 }
1646
1647 ret = gnutls_x509_privkey_import_pkcs8
1648 (*key, &data, GNUTLS_X509_FMT_DER,
1649 password,
1650 type ==
1651 GNUTLS_BAG_PKCS8_KEY ?
1652 GNUTLS_PKCS_PLAIN : 0);
1653 if (ret < 0) {
1654 gnutls_assert();
1655 goto done;
1656 }
1657
1658 key_id_size = sizeof(key_id);
1659 ret =
1660 gnutls_x509_privkey_get_key_id(*key, 0,
1661 key_id,
1662 &key_id_size);
1663 if (ret < 0) {
1664 gnutls_assert();
1665 goto done;
1666 }
1667
1668 privkey_ok = 1; /* break */
1669 break;
1670 default:
1671 break;
1672 }
1673 }
1674
1675 idx++;
1676 gnutls_pkcs12_bag_deinit(bag);
1677 bag = NULL;
1678
1679 if (privkey_ok != 0) /* private key was found */
1680 break;
1681 }
1682
1683 if (privkey_ok == 0) { /* no private key */
1684 gnutls_assert();
1685 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1686 }
1687
1688 /* now find the corresponding certificate
1689 */
1690 idx = 0;
1691 bag = NULL;
1692 for (;;) {
1693 ret = gnutls_pkcs12_bag_init(&bag);
1694 if (ret < 0) {
1695 bag = NULL;
1696 gnutls_assert();
1697 goto done;
1698 }
1699
1700 ret = gnutls_pkcs12_get_bag(p12, idx, bag);
1701 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1702 gnutls_pkcs12_bag_deinit(bag);
1703 bag = NULL;
1704 break;
1705 }
1706 if (ret < 0) {
1707 gnutls_assert();
1708 goto done;
1709 }
1710
1711 ret = gnutls_pkcs12_bag_get_type(bag, 0);
1712 if (ret < 0) {
1713 gnutls_assert();
1714 goto done;
1715 }
1716
1717 if (ret == GNUTLS_BAG_ENCRYPTED) {
1718 ret = gnutls_pkcs12_bag_decrypt(bag, password);
1719 if (ret < 0) {
1720 gnutls_assert();
1721 goto done;
1722 }
1723 }
1724
1725 elements_in_bag = gnutls_pkcs12_bag_get_count(bag);
1726 if (elements_in_bag < 0) {
1727 gnutls_assert();
1728 goto done;
1729 }
1730
1731 for (i = 0; i < (unsigned)elements_in_bag; i++) {
1732 int type;
1733 gnutls_datum_t data;
1734 gnutls_x509_crt_t this_cert;
1735
1736 type = gnutls_pkcs12_bag_get_type(bag, i);
1737 if (type < 0) {
1738 gnutls_assert();
1739 goto done;
1740 }
1741
1742 ret = gnutls_pkcs12_bag_get_data(bag, i, &data);
1743 if (ret < 0) {
1744 gnutls_assert();
1745 goto done;
1746 }
1747
1748 switch (type) {
1749 case GNUTLS_BAG_CERTIFICATE:
1750 ret = gnutls_x509_crt_init(&this_cert);
1751 if (ret < 0) {
1752 gnutls_assert();
1753 goto done;
1754 }
1755
1756 ret =
1757 gnutls_x509_crt_import(this_cert,
1758 &data,
1759 GNUTLS_X509_FMT_DER);
1760 if (ret < 0) {
1761 gnutls_assert();
1762 gnutls_x509_crt_deinit(this_cert);
1763 this_cert = NULL;
1764 goto done;
1765 }
1766
1767 /* check if the key id match */
1768 cert_id_size = sizeof(cert_id);
1769 ret =
1770 gnutls_x509_crt_get_key_id(this_cert,
1771 0, cert_id,
1772 &cert_id_size);
1773 if (ret < 0) {
1774 gnutls_assert();
1775 gnutls_x509_crt_deinit(this_cert);
1776 this_cert = NULL;
1777 goto done;
1778 }
1779
1780 if (memcmp(cert_id, key_id, cert_id_size) != 0) { /* they don't match - skip the certificate */
1781 _extra_certs =
1782 gnutls_realloc_fast
1783 (_extra_certs,
1784 sizeof(_extra_certs
1785 [0]) *
1786 ++_extra_certs_len);
1787 if (!_extra_certs) {
1788 gnutls_assert();
1789 ret =
1790 GNUTLS_E_MEMORY_ERROR;
1791 goto done;
1792 }
1793 _extra_certs
1794 [_extra_certs_len -
1795 1] = this_cert;
1796 this_cert = NULL;
1797 } else {
1798 if (chain && _chain_len == 0) {
1799 _chain =
1800 gnutls_malloc(sizeof
1801 (_chain
1802 [0]) *
1803 (++_chain_len));
1804 if (!_chain) {
1805 gnutls_assert();
1806 ret =
1807 GNUTLS_E_MEMORY_ERROR;
1808 goto done;
1809 }
1810 _chain[_chain_len - 1] =
1811 this_cert;
1812 this_cert = NULL;
1813 } else {
1814 gnutls_x509_crt_deinit
1815 (this_cert);
1816 this_cert = NULL;
1817 }
1818 }
1819 break;
1820
1821 case GNUTLS_BAG_CRL:
1822 if (crl == NULL || *crl != NULL) {
1823 gnutls_assert();
1824 break;
1825 }
1826
1827 ret = gnutls_x509_crl_init(crl);
1828 if (ret < 0) {
1829 gnutls_assert();
1830 goto done;
1831 }
1832
1833 ret =
1834 gnutls_x509_crl_import(*crl, &data,
1835 GNUTLS_X509_FMT_DER);
1836 if (ret < 0) {
1837 gnutls_assert();
1838 gnutls_x509_crl_deinit(*crl);
1839 *crl = NULL;
1840 goto done;
1841 }
1842 break;
1843
1844 case GNUTLS_BAG_ENCRYPTED:
1845 /* XXX Bother to recurse one level down? Unlikely to
1846 use the same password anyway. */
1847 case GNUTLS_BAG_EMPTY:
1848 default:
1849 break;
1850 }
1851 }
1852
1853 idx++;
1854 gnutls_pkcs12_bag_deinit(bag);
1855 bag = NULL;
1856 }
1857
1858 if (chain != NULL) {
1859 if (_chain_len != 1) {
1860 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1861 goto done;
1862 }
1863
1864 ret =
1865 make_chain(&_chain, &_chain_len, &_extra_certs,
1866 &_extra_certs_len, flags);
1867 if (ret < 0) {
1868 gnutls_assert();
1869 goto done;
1870 }
1871 }
1872
1873 ret = 0;
1874
1875 done:
1876 if (bag)
1877 gnutls_pkcs12_bag_deinit(bag);
1878
1879 if (ret < 0) {
1880 if (*key) {
1881 gnutls_x509_privkey_deinit(*key);
1882 *key = NULL;
1883 }
1884 if (crl != NULL && *crl != NULL) {
1885 gnutls_x509_crl_deinit(*crl);
1886 *crl = NULL;
1887 }
1888 if (_extra_certs_len && _extra_certs != NULL) {
1889 for (i = 0; i < _extra_certs_len; i++)
1890 gnutls_x509_crt_deinit(_extra_certs[i]);
1891 gnutls_free(_extra_certs);
1892 }
1893 if (_chain_len && _chain != NULL) {
1894 for (i = 0; i < _chain_len; i++)
1895 gnutls_x509_crt_deinit(_chain[i]);
1896 gnutls_free(_chain);
1897 }
1898
1899 return ret;
1900 }
1901
1902 if (extra_certs && _extra_certs_len > 0) {
1903 *extra_certs = _extra_certs;
1904 *extra_certs_len = _extra_certs_len;
1905 } else {
1906 if (extra_certs) {
1907 *extra_certs = NULL;
1908 *extra_certs_len = 0;
1909 }
1910 for (i = 0; i < _extra_certs_len; i++)
1911 gnutls_x509_crt_deinit(_extra_certs[i]);
1912 gnutls_free(_extra_certs);
1913 }
1914
1915 if (chain != NULL) {
1916 *chain = _chain;
1917 *chain_len = _chain_len;
1918 }
1919
1920 return ret;
1921 }
1922
1923
1924 /**
1925 * gnutls_pkcs12_mac_info:
1926 * @pkcs12: A pkcs12 type
1927 * @mac: the MAC algorithm used as %gnutls_mac_algorithm_t
1928 * @salt: the salt used for string to key (if non-NULL then @salt_size initially holds its size)
1929 * @salt_size: string to key salt size
1930 * @iter_count: string to key iteration count
1931 * @oid: if non-NULL it will contain an allocated null-terminated variable with the OID
1932 *
1933 * This function will provide information on the MAC algorithm used
1934 * in a PKCS #12 structure. If the structure algorithms
1935 * are unknown the code %GNUTLS_E_UNKNOWN_HASH_ALGORITHM will be returned,
1936 * and only @oid, will be set. That is, @oid will be set on structures
1937 * with a MAC whether supported or not. It must be deinitialized using gnutls_free().
1938 * The other variables are only set on supported structures.
1939 *
1940 * Returns: %GNUTLS_E_INVALID_REQUEST if the provided structure doesn't contain a MAC,
1941 * %GNUTLS_E_UNKNOWN_HASH_ALGORITHM if the structure's MAC isn't supported, or
1942 * another negative error code in case of a failure. Zero on success.
1943 **/
1944 int
gnutls_pkcs12_mac_info(gnutls_pkcs12_t pkcs12,unsigned int * mac,void * salt,unsigned int * salt_size,unsigned int * iter_count,char ** oid)1945 gnutls_pkcs12_mac_info(gnutls_pkcs12_t pkcs12, unsigned int *mac,
1946 void *salt, unsigned int *salt_size, unsigned int *iter_count, char **oid)
1947 {
1948 int ret;
1949 gnutls_datum_t tmp = { NULL, 0 }, dsalt = {
1950 NULL, 0};
1951 gnutls_mac_algorithm_t algo;
1952
1953 if (oid)
1954 *oid = NULL;
1955
1956 if (pkcs12 == NULL) {
1957 gnutls_assert();
1958 return GNUTLS_E_INVALID_REQUEST;
1959 }
1960
1961 ret =
1962 _gnutls_x509_read_value(pkcs12->pkcs12, "macData.mac.digestAlgorithm.algorithm",
1963 &tmp);
1964 if (ret < 0) {
1965 gnutls_assert();
1966 return GNUTLS_E_INVALID_REQUEST;
1967 }
1968
1969 if (oid) {
1970 *oid = (char*)tmp.data;
1971 }
1972
1973 algo = DIG_TO_MAC(gnutls_oid_to_digest((char*)tmp.data));
1974 if (algo == GNUTLS_MAC_UNKNOWN || mac_to_entry(algo) == NULL) {
1975 gnutls_assert();
1976 return GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
1977 }
1978
1979 if (oid) {
1980 tmp.data = NULL;
1981 }
1982
1983 if (mac) {
1984 *mac = algo;
1985 }
1986
1987 if (iter_count) {
1988 ret =
1989 _gnutls_x509_read_uint(pkcs12->pkcs12, "macData.iterations",
1990 iter_count);
1991 if (ret < 0) {
1992 *iter_count = 1; /* the default */
1993 }
1994 }
1995
1996 if (salt) {
1997 /* Read the salt from the structure.
1998 */
1999 ret =
2000 _gnutls_x509_read_null_value(pkcs12->pkcs12, "macData.macSalt",
2001 &dsalt);
2002 if (ret < 0) {
2003 gnutls_assert();
2004 goto cleanup;
2005 }
2006
2007 if (*salt_size >= (unsigned)dsalt.size) {
2008 *salt_size = dsalt.size;
2009 if (dsalt.size > 0)
2010 memcpy(salt, dsalt.data, dsalt.size);
2011 } else {
2012 *salt_size = dsalt.size;
2013 ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
2014 goto cleanup;
2015 }
2016 }
2017
2018 ret = 0;
2019 cleanup:
2020 _gnutls_free_datum(&tmp);
2021 _gnutls_free_datum(&dsalt);
2022 return ret;
2023
2024 }
2025
2026