Import PKCS #12 keys
[gnutls.git] / lib / x509 / pkcs12.c
blobdbaebc2eccfc5e80decf1283ab54ed45db9ced6c
1 /*
2 * Copyright (C) 2003-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* Functions that relate on PKCS12 packet parsing.
26 #include <gnutls_int.h>
27 #include <libtasn1.h>
29 #include <gnutls_datum.h>
30 #include <gnutls_global.h>
31 #include <gnutls_errors.h>
32 #include <gnutls_num.h>
33 #include <common.h>
34 #include <x509_b64.h>
35 #include "x509_int.h"
36 #include <random.h>
39 /* Decodes the PKCS #12 auth_safe, and returns the allocated raw data,
40 * which holds them. Returns an ASN1_TYPE of authenticatedSafe.
42 static int
43 _decode_pkcs12_auth_safe (ASN1_TYPE pkcs12, ASN1_TYPE * authen_safe,
44 gnutls_datum_t * raw)
46 char oid[MAX_OID_SIZE];
47 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
48 gnutls_datum_t auth_safe = { NULL, 0 };
49 int len, result;
50 char error_str[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
52 len = sizeof (oid) - 1;
53 result = asn1_read_value (pkcs12, "authSafe.contentType", oid, &len);
54 if (result != ASN1_SUCCESS)
56 gnutls_assert ();
57 return _gnutls_asn2err (result);
60 if (strcmp (oid, DATA_OID) != 0)
62 gnutls_assert ();
63 _gnutls_debug_log ("Unknown PKCS12 Content OID '%s'\n", oid);
64 return GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE;
67 /* Step 1. Read the content data
70 result =
71 _gnutls_x509_read_string (pkcs12, "authSafe.content", &auth_safe, ASN1_ETYPE_OCTET_STRING);
72 if (result < 0)
74 gnutls_assert ();
75 goto cleanup;
78 /* Step 2. Extract the authenticatedSafe.
81 if ((result = asn1_create_element
82 (_gnutls_get_pkix (), "PKIX1.pkcs-12-AuthenticatedSafe",
83 &c2)) != ASN1_SUCCESS)
85 gnutls_assert ();
86 result = _gnutls_asn2err (result);
87 goto cleanup;
90 result = asn1_der_decoding (&c2, auth_safe.data, auth_safe.size, error_str);
91 if (result != ASN1_SUCCESS)
93 gnutls_assert ();
94 _gnutls_debug_log ("DER error: %s\n", error_str);
95 result = _gnutls_asn2err (result);
96 goto cleanup;
99 if (raw == NULL)
101 _gnutls_free_datum (&auth_safe);
103 else
105 raw->data = auth_safe.data;
106 raw->size = auth_safe.size;
109 if (authen_safe)
110 *authen_safe = c2;
111 else
112 asn1_delete_structure (&c2);
114 return 0;
116 cleanup:
117 if (c2)
118 asn1_delete_structure (&c2);
119 _gnutls_free_datum (&auth_safe);
120 return result;
124 * gnutls_pkcs12_init:
125 * @pkcs12: The structure to be initialized
127 * This function will initialize a PKCS12 structure. PKCS12 structures
128 * usually contain lists of X.509 Certificates and X.509 Certificate
129 * revocation lists.
131 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
132 * negative error value.
135 gnutls_pkcs12_init (gnutls_pkcs12_t * pkcs12)
137 *pkcs12 = gnutls_calloc (1, sizeof (gnutls_pkcs12_int));
139 if (*pkcs12)
141 int result = asn1_create_element (_gnutls_get_pkix (),
142 "PKIX1.pkcs-12-PFX",
143 &(*pkcs12)->pkcs12);
144 if (result != ASN1_SUCCESS)
146 gnutls_assert ();
147 gnutls_free (*pkcs12);
148 return _gnutls_asn2err (result);
150 return 0; /* success */
152 return GNUTLS_E_MEMORY_ERROR;
156 * gnutls_pkcs12_deinit:
157 * @pkcs12: The structure to be initialized
159 * This function will deinitialize a PKCS12 structure.
161 void
162 gnutls_pkcs12_deinit (gnutls_pkcs12_t pkcs12)
164 if (!pkcs12)
165 return;
167 if (pkcs12->pkcs12)
168 asn1_delete_structure (&pkcs12->pkcs12);
170 gnutls_free (pkcs12);
174 * gnutls_pkcs12_import:
175 * @pkcs12: The structure to store the parsed PKCS12.
176 * @data: The DER or PEM encoded PKCS12.
177 * @format: One of DER or PEM
178 * @flags: an ORed sequence of gnutls_privkey_pkcs8_flags
180 * This function will convert the given DER or PEM encoded PKCS12
181 * to the native gnutls_pkcs12_t format. The output will be stored in 'pkcs12'.
183 * If the PKCS12 is PEM encoded it should have a header of "PKCS12".
185 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
186 * negative error value.
189 gnutls_pkcs12_import (gnutls_pkcs12_t pkcs12,
190 const gnutls_datum_t * data,
191 gnutls_x509_crt_fmt_t format, unsigned int flags)
193 int result = 0, need_free = 0;
194 gnutls_datum_t _data;
195 char error_str[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
197 _data.data = data->data;
198 _data.size = data->size;
200 if (pkcs12 == NULL)
202 gnutls_assert ();
203 return GNUTLS_E_INVALID_REQUEST;
206 /* If the PKCS12 is in PEM format then decode it
208 if (format == GNUTLS_X509_FMT_PEM)
210 result = _gnutls_fbase64_decode (PEM_PKCS12, data->data, data->size,
211 &_data);
213 if (result < 0)
215 gnutls_assert ();
216 return result;
219 need_free = 1;
222 result =
223 asn1_der_decoding (&pkcs12->pkcs12, _data.data, _data.size, error_str);
224 if (result != ASN1_SUCCESS)
226 result = _gnutls_asn2err (result);
227 _gnutls_debug_log ("DER error: %s\n", error_str);
228 gnutls_assert ();
229 goto cleanup;
232 if (need_free)
233 _gnutls_free_datum (&_data);
235 return 0;
237 cleanup:
238 if (need_free)
239 _gnutls_free_datum (&_data);
240 return result;
245 * gnutls_pkcs12_export:
246 * @pkcs12: Holds the pkcs12 structure
247 * @format: the format of output params. One of PEM or DER.
248 * @output_data: will contain a structure PEM or DER encoded
249 * @output_data_size: holds the size of output_data (and will be
250 * replaced by the actual size of parameters)
252 * This function will export the pkcs12 structure to DER or PEM format.
254 * If the buffer provided is not long enough to hold the output, then
255 * *output_data_size will be updated and GNUTLS_E_SHORT_MEMORY_BUFFER
256 * will be returned.
258 * If the structure is PEM encoded, it will have a header
259 * of "BEGIN PKCS12".
261 * Returns: In case of failure a negative error code will be
262 * returned, and 0 on success.
265 gnutls_pkcs12_export (gnutls_pkcs12_t pkcs12,
266 gnutls_x509_crt_fmt_t format, void *output_data,
267 size_t * output_data_size)
269 if (pkcs12 == NULL)
271 gnutls_assert ();
272 return GNUTLS_E_INVALID_REQUEST;
275 return _gnutls_x509_export_int (pkcs12->pkcs12, format, PEM_PKCS12,
276 output_data, output_data_size);
280 * gnutls_pkcs12_export2:
281 * @pkcs12: Holds the pkcs12 structure
282 * @format: the format of output params. One of PEM or DER.
283 * @out: will contain a structure PEM or DER encoded
285 * This function will export the pkcs12 structure to DER or PEM format.
287 * The output buffer is allocated using gnutls_malloc().
289 * If the structure is PEM encoded, it will have a header
290 * of "BEGIN PKCS12".
292 * Returns: In case of failure a negative error code will be
293 * returned, and 0 on success.
295 * Since: 3.1
298 gnutls_pkcs12_export2 (gnutls_pkcs12_t pkcs12,
299 gnutls_x509_crt_fmt_t format, gnutls_datum_t *out)
301 if (pkcs12 == NULL)
303 gnutls_assert ();
304 return GNUTLS_E_INVALID_REQUEST;
307 return _gnutls_x509_export_int2 (pkcs12->pkcs12, format, PEM_PKCS12, out);
310 static int
311 oid2bag (const char *oid)
313 if (strcmp (oid, BAG_PKCS8_KEY) == 0)
314 return GNUTLS_BAG_PKCS8_KEY;
315 if (strcmp (oid, BAG_PKCS8_ENCRYPTED_KEY) == 0)
316 return GNUTLS_BAG_PKCS8_ENCRYPTED_KEY;
317 if (strcmp (oid, BAG_CERTIFICATE) == 0)
318 return GNUTLS_BAG_CERTIFICATE;
319 if (strcmp (oid, BAG_CRL) == 0)
320 return GNUTLS_BAG_CRL;
321 if (strcmp (oid, BAG_SECRET) == 0)
322 return GNUTLS_BAG_SECRET;
324 return GNUTLS_BAG_UNKNOWN;
327 static const char *
328 bag_to_oid (int bag)
330 switch (bag)
332 case GNUTLS_BAG_PKCS8_KEY:
333 return BAG_PKCS8_KEY;
334 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
335 return BAG_PKCS8_ENCRYPTED_KEY;
336 case GNUTLS_BAG_CERTIFICATE:
337 return BAG_CERTIFICATE;
338 case GNUTLS_BAG_CRL:
339 return BAG_CRL;
340 case GNUTLS_BAG_SECRET:
341 return BAG_SECRET;
343 return NULL;
346 /* Decodes the SafeContents, and puts the output in
347 * the given bag.
350 _pkcs12_decode_safe_contents (const gnutls_datum_t * content,
351 gnutls_pkcs12_bag_t bag)
353 char oid[MAX_OID_SIZE], root[ASN1_MAX_NAME_SIZE];
354 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
355 int len, result;
356 int bag_type;
357 gnutls_datum_t attr_val;
358 gnutls_datum_t t;
359 int count = 0, i, attributes, j;
361 /* Step 1. Extract the SEQUENCE.
364 if ((result = asn1_create_element
365 (_gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
366 &c2)) != ASN1_SUCCESS)
368 gnutls_assert ();
369 result = _gnutls_asn2err (result);
370 goto cleanup;
373 result = asn1_der_decoding (&c2, content->data, content->size, NULL);
374 if (result != ASN1_SUCCESS)
376 gnutls_assert ();
377 result = _gnutls_asn2err (result);
378 goto cleanup;
381 /* Count the number of bags
383 result = asn1_number_of_elements (c2, "", &count);
384 if (result != ASN1_SUCCESS)
386 gnutls_assert ();
387 result = _gnutls_asn2err (result);
388 goto cleanup;
391 bag->bag_elements = MIN (MAX_BAG_ELEMENTS, count);
393 for (i = 0; i < bag->bag_elements; i++)
396 snprintf (root, sizeof (root), "?%u.bagId", i + 1);
398 len = sizeof (oid);
399 result = asn1_read_value (c2, root, oid, &len);
400 if (result != ASN1_SUCCESS)
402 gnutls_assert ();
403 result = _gnutls_asn2err (result);
404 goto cleanup;
407 /* Read the Bag type
409 bag_type = oid2bag (oid);
411 if (bag_type < 0)
413 gnutls_assert ();
414 goto cleanup;
417 /* Read the Bag Value
420 snprintf (root, sizeof (root), "?%u.bagValue", i + 1);
422 result = _gnutls_x509_read_value (c2, root, &bag->element[i].data);
423 if (result < 0)
425 gnutls_assert ();
426 goto cleanup;
429 if (bag_type == GNUTLS_BAG_CERTIFICATE || bag_type == GNUTLS_BAG_CRL
430 || bag_type == GNUTLS_BAG_SECRET)
432 gnutls_datum_t tmp = bag->element[i].data;
434 result =
435 _pkcs12_decode_crt_bag (bag_type, &tmp, &bag->element[i].data);
436 if (result < 0)
438 gnutls_assert ();
439 goto cleanup;
442 _gnutls_free_datum (&tmp);
445 /* read the bag attributes
447 snprintf (root, sizeof (root), "?%u.bagAttributes", i + 1);
449 result = asn1_number_of_elements (c2, root, &attributes);
450 if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND)
452 gnutls_assert ();
453 result = _gnutls_asn2err (result);
454 goto cleanup;
457 if (attributes < 0)
458 attributes = 1;
460 if (result != ASN1_ELEMENT_NOT_FOUND)
461 for (j = 0; j < attributes; j++)
464 snprintf (root, sizeof (root), "?%u.bagAttributes.?%u", i + 1,
465 j + 1);
467 result =
468 _gnutls_x509_decode_and_read_attribute (c2, root, oid,
469 sizeof (oid), &attr_val,
470 1, 0);
472 if (result < 0)
474 gnutls_assert ();
475 continue; /* continue in case we find some known attributes */
478 if (strcmp (oid, KEY_ID_OID) == 0)
480 result =
481 _gnutls_x509_decode_string (ASN1_ETYPE_OCTET_STRING, attr_val.data,
482 attr_val.size, &t);
483 _gnutls_free_datum (&attr_val);
484 if (result < 0)
486 gnutls_assert ();
487 _gnutls_debug_log
488 ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid);
489 continue;
492 attr_val.data = t.data;
493 attr_val.size = t.size;
495 bag->element[i].local_key_id = attr_val;
497 else if (strcmp (oid, FRIENDLY_NAME_OID) == 0)
499 result =
500 _gnutls_x509_decode_string (ASN1_ETYPE_BMP_STRING,
501 attr_val.data, attr_val.size, &t);
502 _gnutls_free_datum (&attr_val);
503 if (result < 0)
505 gnutls_assert ();
506 _gnutls_debug_log
507 ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid);
508 continue;
511 attr_val.data = t.data;
512 attr_val.size = t.size;
514 bag->element[i].friendly_name = (char*)t.data;
516 else
518 _gnutls_free_datum (&attr_val);
519 _gnutls_debug_log
520 ("Unknown PKCS12 Bag Attribute OID '%s'\n", oid);
525 bag->element[i].type = bag_type;
529 asn1_delete_structure (&c2);
532 return 0;
534 cleanup:
535 if (c2)
536 asn1_delete_structure (&c2);
537 return result;
542 static int
543 _parse_safe_contents (ASN1_TYPE sc, const char *sc_name,
544 gnutls_pkcs12_bag_t bag)
546 gnutls_datum_t content = { NULL, 0 };
547 int result;
549 /* Step 1. Extract the content.
552 result = _gnutls_x509_read_string (sc, sc_name, &content, ASN1_ETYPE_OCTET_STRING);
553 if (result < 0)
555 gnutls_assert ();
556 goto cleanup;
559 result = _pkcs12_decode_safe_contents (&content, bag);
560 if (result < 0)
562 gnutls_assert ();
563 goto cleanup;
566 _gnutls_free_datum (&content);
568 return 0;
570 cleanup:
571 _gnutls_free_datum (&content);
572 return result;
577 * gnutls_pkcs12_get_bag:
578 * @pkcs12: should contain a gnutls_pkcs12_t structure
579 * @indx: contains the index of the bag to extract
580 * @bag: An initialized bag, where the contents of the bag will be copied
582 * This function will return a Bag from the PKCS12 structure.
584 * After the last Bag has been read
585 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
587 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
588 * negative error value.
591 gnutls_pkcs12_get_bag (gnutls_pkcs12_t pkcs12,
592 int indx, gnutls_pkcs12_bag_t bag)
594 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
595 int result, len;
596 char root2[ASN1_MAX_NAME_SIZE];
597 char oid[MAX_OID_SIZE];
599 if (pkcs12 == NULL)
601 gnutls_assert ();
602 return GNUTLS_E_INVALID_REQUEST;
605 /* Step 1. decode the data.
607 result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, &c2, NULL);
608 if (result < 0)
610 gnutls_assert ();
611 return result;
614 /* Step 2. Parse the AuthenticatedSafe
617 snprintf (root2, sizeof (root2), "?%u.contentType", indx + 1);
619 len = sizeof (oid) - 1;
620 result = asn1_read_value (c2, root2, oid, &len);
622 if (result == ASN1_ELEMENT_NOT_FOUND)
624 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
625 goto cleanup;
628 if (result != ASN1_SUCCESS)
630 gnutls_assert ();
631 result = _gnutls_asn2err (result);
632 goto cleanup;
635 /* Not encrypted Bag
638 snprintf (root2, sizeof (root2), "?%u.content", indx + 1);
640 if (strcmp (oid, DATA_OID) == 0)
642 result = _parse_safe_contents (c2, root2, bag);
643 goto cleanup;
646 /* ENC_DATA_OID needs decryption */
648 bag->element[0].type = GNUTLS_BAG_ENCRYPTED;
649 bag->bag_elements = 1;
651 result = _gnutls_x509_read_value (c2, root2, &bag->element[0].data);
652 if (result < 0)
654 gnutls_assert ();
655 goto cleanup;
658 result = 0;
660 cleanup:
661 if (c2)
662 asn1_delete_structure (&c2);
663 return result;
666 /* Creates an empty PFX structure for the PKCS12 structure.
668 static int
669 create_empty_pfx (ASN1_TYPE pkcs12)
671 uint8_t three = 3;
672 int result;
673 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
675 /* Use version 3
677 result = asn1_write_value (pkcs12, "version", &three, 1);
678 if (result != ASN1_SUCCESS)
680 gnutls_assert ();
681 result = _gnutls_asn2err (result);
682 goto cleanup;
685 /* Write the content type of the data
687 result = asn1_write_value (pkcs12, "authSafe.contentType", DATA_OID, 1);
688 if (result != ASN1_SUCCESS)
690 gnutls_assert ();
691 result = _gnutls_asn2err (result);
692 goto cleanup;
695 /* Check if the authenticatedSafe content is empty, and encode a
696 * null one in that case.
699 if ((result = asn1_create_element
700 (_gnutls_get_pkix (), "PKIX1.pkcs-12-AuthenticatedSafe",
701 &c2)) != ASN1_SUCCESS)
703 gnutls_assert ();
704 result = _gnutls_asn2err (result);
705 goto cleanup;
708 result =
709 _gnutls_x509_der_encode_and_copy (c2, "", pkcs12, "authSafe.content", 1);
710 if (result < 0)
712 gnutls_assert ();
713 goto cleanup;
715 asn1_delete_structure (&c2);
717 return 0;
719 cleanup:
720 asn1_delete_structure (&c2);
721 return result;
726 * gnutls_pkcs12_set_bag:
727 * @pkcs12: should contain a gnutls_pkcs12_t structure
728 * @bag: An initialized bag
730 * This function will insert a Bag into the PKCS12 structure.
732 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
733 * negative error value.
736 gnutls_pkcs12_set_bag (gnutls_pkcs12_t pkcs12, gnutls_pkcs12_bag_t bag)
738 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
739 ASN1_TYPE safe_cont = ASN1_TYPE_EMPTY;
740 int result;
741 int enc = 0, dum = 1;
742 char null;
744 if (pkcs12 == NULL)
746 gnutls_assert ();
747 return GNUTLS_E_INVALID_REQUEST;
750 /* Step 1. Check if the pkcs12 structure is empty. In that
751 * case generate an empty PFX.
753 result = asn1_read_value (pkcs12->pkcs12, "authSafe.content", &null, &dum);
754 if (result == ASN1_VALUE_NOT_FOUND)
756 result = create_empty_pfx (pkcs12->pkcs12);
757 if (result < 0)
759 gnutls_assert ();
760 return result;
764 /* Step 2. decode the authenticatedSafe.
766 result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, &c2, NULL);
767 if (result < 0)
769 gnutls_assert ();
770 return result;
773 /* Step 3. Encode the bag elements into a SafeContents
774 * structure.
776 result = _pkcs12_encode_safe_contents (bag, &safe_cont, &enc);
777 if (result < 0)
779 gnutls_assert ();
780 return result;
783 /* Step 4. Insert the encoded SafeContents into the AuthenticatedSafe
784 * structure.
786 result = asn1_write_value (c2, "", "NEW", 1);
787 if (result != ASN1_SUCCESS)
789 gnutls_assert ();
790 result = _gnutls_asn2err (result);
791 goto cleanup;
794 if (enc)
795 result = asn1_write_value (c2, "?LAST.contentType", ENC_DATA_OID, 1);
796 else
797 result = asn1_write_value (c2, "?LAST.contentType", DATA_OID, 1);
798 if (result != ASN1_SUCCESS)
800 gnutls_assert ();
801 result = _gnutls_asn2err (result);
802 goto cleanup;
805 if (enc)
807 /* Encrypted packets are written directly.
809 result =
810 asn1_write_value (c2, "?LAST.content",
811 bag->element[0].data.data,
812 bag->element[0].data.size);
813 if (result != ASN1_SUCCESS)
815 gnutls_assert ();
816 result = _gnutls_asn2err (result);
817 goto cleanup;
820 else
822 result =
823 _gnutls_x509_der_encode_and_copy (safe_cont, "", c2,
824 "?LAST.content", 1);
825 if (result < 0)
827 gnutls_assert ();
828 goto cleanup;
832 asn1_delete_structure (&safe_cont);
835 /* Step 5. Reencode and copy the AuthenticatedSafe into the pkcs12
836 * structure.
838 result =
839 _gnutls_x509_der_encode_and_copy (c2, "", pkcs12->pkcs12,
840 "authSafe.content", 1);
841 if (result < 0)
843 gnutls_assert ();
844 goto cleanup;
847 asn1_delete_structure (&c2);
849 return 0;
851 cleanup:
852 asn1_delete_structure (&c2);
853 asn1_delete_structure (&safe_cont);
854 return result;
858 * gnutls_pkcs12_generate_mac:
859 * @pkcs12: should contain a gnutls_pkcs12_t structure
860 * @pass: The password for the MAC
862 * This function will generate a MAC for the PKCS12 structure.
864 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
865 * negative error value.
868 gnutls_pkcs12_generate_mac (gnutls_pkcs12_t pkcs12, const char *pass)
870 uint8_t salt[8], key[20];
871 int result;
872 const int iter = 1;
873 digest_hd_st td1;
874 gnutls_datum_t tmp = { NULL, 0 };
875 uint8_t sha_mac[20];
877 if (pkcs12 == NULL)
879 gnutls_assert ();
880 return GNUTLS_E_INVALID_REQUEST;
883 /* Generate the salt.
885 result = _gnutls_rnd (GNUTLS_RND_NONCE, salt, sizeof (salt));
886 if (result < 0)
888 gnutls_assert ();
889 return result;
892 /* Write the salt into the structure.
894 result =
895 asn1_write_value (pkcs12->pkcs12, "macData.macSalt", salt, sizeof (salt));
896 if (result != ASN1_SUCCESS)
898 gnutls_assert ();
899 result = _gnutls_asn2err (result);
900 goto cleanup;
903 /* write the iterations
906 if (iter > 1)
908 result =
909 _gnutls_x509_write_uint32 (pkcs12->pkcs12, "macData.iterations",
910 iter);
911 if (result < 0)
913 gnutls_assert ();
914 goto cleanup;
918 /* Generate the key.
920 result = _gnutls_pkcs12_string_to_key (3 /*MAC*/, salt, sizeof (salt),
921 iter, pass, sizeof (key), key);
922 if (result < 0)
924 gnutls_assert ();
925 goto cleanup;
928 /* Get the data to be MACed
930 result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, NULL, &tmp);
931 if (result < 0)
933 gnutls_assert ();
934 goto cleanup;
937 /* MAC the data
939 result = _gnutls_hmac_init (&td1, GNUTLS_MAC_SHA1, key, sizeof (key));
940 if (result < 0)
942 gnutls_assert ();
943 goto cleanup;
946 _gnutls_hmac (&td1, tmp.data, tmp.size);
947 _gnutls_free_datum (&tmp);
949 _gnutls_hmac_deinit (&td1, sha_mac);
952 result =
953 asn1_write_value (pkcs12->pkcs12, "macData.mac.digest", sha_mac,
954 sizeof (sha_mac));
955 if (result != ASN1_SUCCESS)
957 gnutls_assert ();
958 result = _gnutls_asn2err (result);
959 goto cleanup;
962 result =
963 asn1_write_value (pkcs12->pkcs12,
964 "macData.mac.digestAlgorithm.parameters", NULL, 0);
965 if (result != ASN1_SUCCESS)
967 gnutls_assert ();
968 result = _gnutls_asn2err (result);
969 goto cleanup;
972 result =
973 asn1_write_value (pkcs12->pkcs12,
974 "macData.mac.digestAlgorithm.algorithm", HASH_OID_SHA1,
976 if (result != ASN1_SUCCESS)
978 gnutls_assert ();
979 result = _gnutls_asn2err (result);
980 goto cleanup;
983 return 0;
985 cleanup:
986 _gnutls_free_datum (&tmp);
987 return result;
991 * gnutls_pkcs12_verify_mac:
992 * @pkcs12: should contain a gnutls_pkcs12_t structure
993 * @pass: The password for the MAC
995 * This function will verify the MAC for the PKCS12 structure.
997 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
998 * negative error value.
1001 gnutls_pkcs12_verify_mac (gnutls_pkcs12_t pkcs12, const char *pass)
1003 uint8_t key[20];
1004 int result;
1005 unsigned int iter;
1006 int len;
1007 digest_hd_st td1;
1008 gnutls_datum_t tmp = { NULL, 0 }, salt =
1010 NULL, 0};
1011 uint8_t sha_mac[20];
1012 uint8_t sha_mac_orig[20];
1014 if (pkcs12 == NULL)
1016 gnutls_assert ();
1017 return GNUTLS_E_INVALID_REQUEST;
1020 /* read the iterations
1023 result =
1024 _gnutls_x509_read_uint (pkcs12->pkcs12, "macData.iterations", &iter);
1025 if (result < 0)
1027 iter = 1; /* the default */
1031 /* Read the salt from the structure.
1033 result =
1034 _gnutls_x509_read_value (pkcs12->pkcs12, "macData.macSalt", &salt);
1035 if (result != ASN1_SUCCESS)
1037 gnutls_assert ();
1038 result = _gnutls_asn2err (result);
1039 goto cleanup;
1042 /* Generate the key.
1044 result = _gnutls_pkcs12_string_to_key (3 /*MAC*/, salt.data, salt.size,
1045 iter, pass, sizeof (key), key);
1046 if (result < 0)
1048 gnutls_assert ();
1049 goto cleanup;
1052 _gnutls_free_datum (&salt);
1054 /* Get the data to be MACed
1056 result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, NULL, &tmp);
1057 if (result < 0)
1059 gnutls_assert ();
1060 goto cleanup;
1063 /* MAC the data
1065 result = _gnutls_hmac_init (&td1, GNUTLS_MAC_SHA1, key, sizeof (key));
1066 if (result < 0)
1068 gnutls_assert ();
1069 goto cleanup;
1072 _gnutls_hmac (&td1, tmp.data, tmp.size);
1073 _gnutls_free_datum (&tmp);
1075 _gnutls_hmac_deinit (&td1, sha_mac);
1077 len = sizeof (sha_mac_orig);
1078 result =
1079 asn1_read_value (pkcs12->pkcs12, "macData.mac.digest", sha_mac_orig,
1080 &len);
1081 if (result != ASN1_SUCCESS)
1083 gnutls_assert ();
1084 result = _gnutls_asn2err (result);
1085 goto cleanup;
1088 if (memcmp (sha_mac_orig, sha_mac, sizeof (sha_mac)) != 0)
1090 gnutls_assert ();
1091 return GNUTLS_E_MAC_VERIFY_FAILED;
1094 return 0;
1096 cleanup:
1097 _gnutls_free_datum (&tmp);
1098 _gnutls_free_datum (&salt);
1099 return result;
1103 static int
1104 write_attributes (gnutls_pkcs12_bag_t bag, int elem,
1105 ASN1_TYPE c2, const char *where)
1107 int result;
1108 char root[128];
1110 /* If the bag attributes are empty, then write
1111 * nothing to the attribute field.
1113 if (bag->element[elem].friendly_name == NULL &&
1114 bag->element[elem].local_key_id.data == NULL)
1116 /* no attributes
1118 result = asn1_write_value (c2, where, NULL, 0);
1119 if (result != ASN1_SUCCESS)
1121 gnutls_assert ();
1122 return _gnutls_asn2err (result);
1125 return 0;
1128 if (bag->element[elem].local_key_id.data != NULL)
1131 /* Add a new Attribute
1133 result = asn1_write_value (c2, where, "NEW", 1);
1134 if (result != ASN1_SUCCESS)
1136 gnutls_assert ();
1137 return _gnutls_asn2err (result);
1140 _gnutls_str_cpy (root, sizeof (root), where);
1141 _gnutls_str_cat (root, sizeof (root), ".?LAST");
1143 result =
1144 _gnutls_x509_encode_and_write_attribute (KEY_ID_OID, c2, root,
1145 bag->
1146 element[elem].local_key_id.
1147 data,
1148 bag->
1149 element[elem].local_key_id.
1150 size, 1);
1151 if (result < 0)
1153 gnutls_assert ();
1154 return result;
1158 if (bag->element[elem].friendly_name != NULL)
1160 uint8_t *name;
1161 int size, i;
1162 const char *p;
1164 /* Add a new Attribute
1166 result = asn1_write_value (c2, where, "NEW", 1);
1167 if (result != ASN1_SUCCESS)
1169 gnutls_assert ();
1170 return _gnutls_asn2err (result);
1173 /* convert name to BMPString
1175 size = strlen (bag->element[elem].friendly_name) * 2;
1176 name = gnutls_malloc (size);
1178 if (name == NULL)
1180 gnutls_assert ();
1181 return GNUTLS_E_MEMORY_ERROR;
1184 p = bag->element[elem].friendly_name;
1185 for (i = 0; i < size; i += 2)
1187 name[i] = 0;
1188 name[i + 1] = *p;
1189 p++;
1192 _gnutls_str_cpy (root, sizeof (root), where);
1193 _gnutls_str_cat (root, sizeof (root), ".?LAST");
1195 result =
1196 _gnutls_x509_encode_and_write_attribute (FRIENDLY_NAME_OID, c2,
1197 root, name, size, 1);
1199 gnutls_free (name);
1201 if (result < 0)
1203 gnutls_assert ();
1204 return result;
1208 return 0;
1212 /* Encodes the bag into a SafeContents structure, and puts the output in
1213 * the given datum. Enc is set to non-zero if the data are encrypted;
1216 _pkcs12_encode_safe_contents (gnutls_pkcs12_bag_t bag, ASN1_TYPE * contents,
1217 int *enc)
1219 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1220 int result;
1221 int i;
1222 const char *oid;
1224 if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED && enc)
1226 *enc = 1;
1227 return 0; /* ENCRYPTED BAG, do nothing. */
1229 else if (enc)
1230 *enc = 0;
1232 /* Step 1. Create the SEQUENCE.
1235 if ((result = asn1_create_element
1236 (_gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
1237 &c2)) != ASN1_SUCCESS)
1239 gnutls_assert ();
1240 result = _gnutls_asn2err (result);
1241 goto cleanup;
1244 for (i = 0; i < bag->bag_elements; i++)
1247 oid = bag_to_oid (bag->element[i].type);
1248 if (oid == NULL)
1250 gnutls_assert ();
1251 continue;
1254 result = asn1_write_value (c2, "", "NEW", 1);
1255 if (result != ASN1_SUCCESS)
1257 gnutls_assert ();
1258 result = _gnutls_asn2err (result);
1259 goto cleanup;
1262 /* Copy the bag type.
1264 result = asn1_write_value (c2, "?LAST.bagId", oid, 1);
1265 if (result != ASN1_SUCCESS)
1267 gnutls_assert ();
1268 result = _gnutls_asn2err (result);
1269 goto cleanup;
1272 /* Set empty attributes
1274 result = write_attributes (bag, i, c2, "?LAST.bagAttributes");
1275 if (result < 0)
1277 gnutls_assert ();
1278 goto cleanup;
1282 /* Copy the Bag Value
1285 if (bag->element[i].type == GNUTLS_BAG_CERTIFICATE ||
1286 bag->element[i].type == GNUTLS_BAG_SECRET ||
1287 bag->element[i].type == GNUTLS_BAG_CRL)
1289 gnutls_datum_t tmp;
1291 /* in that case encode it to a CertBag or
1292 * a CrlBag.
1295 result =
1296 _pkcs12_encode_crt_bag (bag->element[i].type,
1297 &bag->element[i].data, &tmp);
1299 if (result < 0)
1301 gnutls_assert ();
1302 goto cleanup;
1305 result = _gnutls_x509_write_value (c2, "?LAST.bagValue", &tmp);
1307 _gnutls_free_datum (&tmp);
1310 else
1313 result = _gnutls_x509_write_value (c2, "?LAST.bagValue",
1314 &bag->element[i].data);
1317 if (result < 0)
1319 gnutls_assert ();
1320 goto cleanup;
1325 /* Encode the data and copy them into the datum
1327 *contents = c2;
1329 return 0;
1331 cleanup:
1332 if (c2)
1333 asn1_delete_structure (&c2);
1334 return result;
1338 /* Checks if the extra_certs contain certificates that may form a chain
1339 * with the first certificate in chain (it is expected that chain_len==1)
1340 * and appends those in the chain.
1342 static int make_chain(gnutls_x509_crt_t **chain, unsigned int *chain_len,
1343 gnutls_x509_crt_t **extra_certs, unsigned int *extra_certs_len,
1344 unsigned int flags)
1346 unsigned int i;
1348 if (*chain_len != 1)
1349 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1351 i = 0;
1352 while(i<*extra_certs_len)
1354 /* if it is an issuer but not a self-signed one */
1355 if (gnutls_x509_crt_check_issuer((*chain)[*chain_len - 1], (*extra_certs)[i]) != 0)
1357 if (!(flags & GNUTLS_PKCS12_SP_INCLUDE_SELF_SIGNED) &&
1358 gnutls_x509_crt_check_issuer((*extra_certs)[i], (*extra_certs)[i]) != 0)
1359 goto skip;
1361 *chain = gnutls_realloc (*chain, sizeof((*chain)[0]) *
1362 ++(*chain_len));
1363 if (*chain == NULL)
1365 gnutls_assert();
1366 return GNUTLS_E_MEMORY_ERROR;
1368 (*chain)[*chain_len - 1] = (*extra_certs)[i];
1370 (*extra_certs)[i] = (*extra_certs)[*extra_certs_len-1];
1371 (*extra_certs_len)--;
1373 i=0;
1374 continue;
1377 skip:
1378 i++;
1380 return 0;
1384 * gnutls_pkcs12_simple_parse:
1385 * @p12: the PKCS#12 blob.
1386 * @password: optional password used to decrypt PKCS#12 blob, bags and keys.
1387 * @key: a structure to store the parsed private key.
1388 * @chain: the corresponding to key certificate chain (may be %NULL)
1389 * @chain_len: will be updated with the number of additional (may be %NULL)
1390 * @extra_certs: optional pointer to receive an array of additional
1391 * certificates found in the PKCS#12 blob (may be %NULL).
1392 * @extra_certs_len: will be updated with the number of additional
1393 * certs (may be %NULL).
1394 * @crl: an optional structure to store the parsed CRL (may be %NULL).
1395 * @flags: should be zero or one of GNUTLS_PKCS12_SP_*
1397 * This function parses a PKCS#12 blob in @p12blob and extracts the
1398 * private key, the corresponding certificate chain, and any additional
1399 * certificates and a CRL.
1401 * The @extra_certs_ret and @extra_certs_ret_len parameters are optional
1402 * and both may be set to %NULL. If either is non-%NULL, then both must
1403 * be.
1405 * Encrypted PKCS#12 bags and PKCS#8 private keys are supported. However,
1406 * only password based security, and the same password for all
1407 * operations, are supported.
1409 * PKCS#12 file may contain many keys and/or certificates, and there
1410 * is no way to identify which key/certificate pair you want. You
1411 * should make sure the PKCS#12 file only contain one key/certificate
1412 * pair and/or one CRL.
1414 * It is believed that the limitations of this function is acceptable
1415 * for most usage, and that any more flexibility would introduce
1416 * complexity that would make it harder to use this functionality at
1417 * all.
1419 * If the provided structure has encrypted fields but no password
1420 * is provided then this function returns %GNUTLS_E_DECRYPTION_FAILED.
1422 * Note that normally the chain constructed does not include self signed
1423 * certificates, to comply with TLS' requirements. If, however, the flag
1424 * %GNUTLS_PKCS12_SP_INCLUDE_SELF_SIGNED is specified then
1425 * self signed certificates will be included in the chain.
1427 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1428 * negative error value.
1430 * Since: 3.1
1433 gnutls_pkcs12_simple_parse (gnutls_pkcs12_t p12,
1434 const char *password,
1435 gnutls_x509_privkey_t * key,
1436 gnutls_x509_crt_t ** chain,
1437 unsigned int * chain_len,
1438 gnutls_x509_crt_t ** extra_certs,
1439 unsigned int * extra_certs_len,
1440 gnutls_x509_crl_t * crl,
1441 unsigned int flags)
1443 gnutls_pkcs12_bag_t bag = NULL;
1444 gnutls_x509_crt_t *_extra_certs = NULL;
1445 unsigned int _extra_certs_len = 0;
1446 gnutls_x509_crt_t *_chain = NULL;
1447 unsigned int _chain_len = 0;
1448 int idx = 0;
1449 int ret;
1450 size_t cert_id_size = 0;
1451 size_t key_id_size = 0;
1452 uint8_t cert_id[20];
1453 uint8_t key_id[20];
1454 int privkey_ok = 0;
1455 unsigned int i;
1457 *key = NULL;
1459 if (crl)
1460 *crl = NULL;
1462 /* find the first private key */
1463 for (;;)
1465 int elements_in_bag;
1466 int i;
1468 ret = gnutls_pkcs12_bag_init (&bag);
1469 if (ret < 0)
1471 bag = NULL;
1472 gnutls_assert ();
1473 goto done;
1476 ret = gnutls_pkcs12_get_bag (p12, idx, bag);
1477 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1478 break;
1479 if (ret < 0)
1481 gnutls_assert ();
1482 goto done;
1485 ret = gnutls_pkcs12_bag_get_type (bag, 0);
1486 if (ret < 0)
1488 gnutls_assert ();
1489 goto done;
1492 if (ret == GNUTLS_BAG_ENCRYPTED)
1494 if (password == NULL)
1496 ret = gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
1497 goto done;
1500 ret = gnutls_pkcs12_bag_decrypt (bag, password);
1501 if (ret < 0)
1503 gnutls_assert ();
1504 goto done;
1508 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
1509 if (elements_in_bag < 0)
1511 gnutls_assert ();
1512 goto done;
1515 for (i = 0; i < elements_in_bag; i++)
1517 int type;
1518 gnutls_datum_t data;
1520 type = gnutls_pkcs12_bag_get_type (bag, i);
1521 if (type < 0)
1523 gnutls_assert ();
1524 goto done;
1527 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
1528 if (ret < 0)
1530 gnutls_assert ();
1531 goto done;
1534 switch (type)
1536 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
1537 if (password == NULL)
1539 ret = gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
1540 goto done;
1543 case GNUTLS_BAG_PKCS8_KEY:
1544 if (*key != NULL) /* too simple to continue */
1546 gnutls_assert ();
1547 break;
1550 ret = gnutls_x509_privkey_init (key);
1551 if (ret < 0)
1553 gnutls_assert ();
1554 goto done;
1557 ret = gnutls_x509_privkey_import_pkcs8
1558 (*key, &data, GNUTLS_X509_FMT_DER, password,
1559 type == GNUTLS_BAG_PKCS8_KEY ? GNUTLS_PKCS_PLAIN : 0);
1560 if (ret < 0)
1562 gnutls_assert ();
1563 gnutls_x509_privkey_deinit (*key);
1564 goto done;
1567 key_id_size = sizeof (key_id);
1568 ret =
1569 gnutls_x509_privkey_get_key_id (*key, 0, key_id,
1570 &key_id_size);
1571 if (ret < 0)
1573 gnutls_assert ();
1574 gnutls_x509_privkey_deinit (*key);
1575 goto done;
1578 privkey_ok = 1; /* break */
1579 break;
1580 default:
1581 break;
1585 idx++;
1586 gnutls_pkcs12_bag_deinit (bag);
1588 if (privkey_ok != 0) /* private key was found */
1589 break;
1592 if (privkey_ok == 0) /* no private key */
1594 gnutls_assert ();
1595 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1598 /* now find the corresponding certificate
1600 idx = 0;
1601 bag = NULL;
1602 for (;;)
1604 int elements_in_bag;
1605 int i;
1607 ret = gnutls_pkcs12_bag_init (&bag);
1608 if (ret < 0)
1610 bag = NULL;
1611 gnutls_assert ();
1612 goto done;
1615 ret = gnutls_pkcs12_get_bag (p12, idx, bag);
1616 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1617 break;
1618 if (ret < 0)
1620 gnutls_assert ();
1621 goto done;
1624 ret = gnutls_pkcs12_bag_get_type (bag, 0);
1625 if (ret < 0)
1627 gnutls_assert ();
1628 goto done;
1631 if (ret == GNUTLS_BAG_ENCRYPTED)
1633 ret = gnutls_pkcs12_bag_decrypt (bag, password);
1634 if (ret < 0)
1636 gnutls_assert ();
1637 goto done;
1641 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
1642 if (elements_in_bag < 0)
1644 gnutls_assert ();
1645 goto done;
1648 for (i = 0; i < elements_in_bag; i++)
1650 int type;
1651 gnutls_datum_t data;
1652 gnutls_x509_crt_t this_cert;
1654 type = gnutls_pkcs12_bag_get_type (bag, i);
1655 if (type < 0)
1657 gnutls_assert ();
1658 goto done;
1661 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
1662 if (ret < 0)
1664 gnutls_assert ();
1665 goto done;
1668 switch (type)
1670 case GNUTLS_BAG_CERTIFICATE:
1671 ret = gnutls_x509_crt_init (&this_cert);
1672 if (ret < 0)
1674 gnutls_assert ();
1675 goto done;
1678 ret =
1679 gnutls_x509_crt_import (this_cert, &data, GNUTLS_X509_FMT_DER);
1680 if (ret < 0)
1682 gnutls_assert ();
1683 gnutls_x509_crt_deinit (this_cert);
1684 goto done;
1687 /* check if the key id match */
1688 cert_id_size = sizeof (cert_id);
1689 ret =
1690 gnutls_x509_crt_get_key_id (this_cert, 0, cert_id, &cert_id_size);
1691 if (ret < 0)
1693 gnutls_assert ();
1694 gnutls_x509_crt_deinit (this_cert);
1695 goto done;
1698 if (memcmp (cert_id, key_id, cert_id_size) != 0)
1699 { /* they don't match - skip the certificate */
1700 if (extra_certs)
1702 _extra_certs = gnutls_realloc (_extra_certs,
1703 sizeof(_extra_certs[0]) *
1704 ++_extra_certs_len);
1705 if (!_extra_certs)
1707 gnutls_assert ();
1708 ret = GNUTLS_E_MEMORY_ERROR;
1709 goto done;
1711 _extra_certs[_extra_certs_len - 1] = this_cert;
1712 this_cert = NULL;
1714 else
1716 gnutls_x509_crt_deinit (this_cert);
1719 else
1721 if (chain && _chain_len == 0)
1723 _chain = gnutls_malloc (sizeof(_chain[0]) * (++_chain_len));
1724 if (!_chain)
1726 gnutls_assert ();
1727 ret = GNUTLS_E_MEMORY_ERROR;
1728 goto done;
1730 _chain[_chain_len - 1] = this_cert;
1731 this_cert = NULL;
1733 else
1735 gnutls_x509_crt_deinit (this_cert);
1738 break;
1740 case GNUTLS_BAG_CRL:
1741 if (crl == NULL || *crl != NULL)
1743 gnutls_assert ();
1744 break;
1747 ret = gnutls_x509_crl_init (crl);
1748 if (ret < 0)
1750 gnutls_assert ();
1751 goto done;
1754 ret = gnutls_x509_crl_import (*crl, &data, GNUTLS_X509_FMT_DER);
1755 if (ret < 0)
1757 gnutls_assert ();
1758 gnutls_x509_crl_deinit (*crl);
1759 goto done;
1761 break;
1763 case GNUTLS_BAG_ENCRYPTED:
1764 /* XXX Bother to recurse one level down? Unlikely to
1765 use the same password anyway. */
1766 case GNUTLS_BAG_EMPTY:
1767 default:
1768 break;
1772 idx++;
1773 gnutls_pkcs12_bag_deinit (bag);
1776 if (chain != NULL)
1778 if (_chain_len != 1)
1780 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1781 goto done;
1784 ret = make_chain(&_chain, &_chain_len, &_extra_certs, &_extra_certs_len, flags);
1785 if (ret < 0)
1787 gnutls_assert();
1788 goto done;
1792 ret = 0;
1794 done:
1795 if (bag)
1796 gnutls_pkcs12_bag_deinit (bag);
1798 if (ret < 0)
1800 if (*key)
1801 gnutls_x509_privkey_deinit(*key);
1802 if (_extra_certs_len && _extra_certs != NULL)
1804 for (i = 0; i < _extra_certs_len; i++)
1805 gnutls_x509_crt_deinit(_extra_certs[i]);
1806 gnutls_free(_extra_certs);
1808 if (_chain_len && _chain != NULL)
1810 for (i = 0; i < _chain_len; i++)
1811 gnutls_x509_crt_deinit(_chain[i]);
1812 gnutls_free(_chain);
1815 return ret;
1818 if (extra_certs && _extra_certs_len > 0)
1820 *extra_certs = _extra_certs;
1821 *extra_certs_len = _extra_certs_len;
1823 else
1825 if (extra_certs)
1827 *extra_certs = NULL;
1828 *extra_certs_len = 0;
1830 for (i = 0; i < _extra_certs_len; i++)
1831 gnutls_x509_crt_deinit(_extra_certs[i]);
1832 gnutls_free(_extra_certs);
1835 if (chain != NULL)
1837 *chain = _chain;
1838 *chain_len = _chain_len;
1841 return ret;