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>
29 #include <gnutls_datum.h>
30 #include <gnutls_global.h>
31 #include <gnutls_errors.h>
32 #include <gnutls_num.h>
39 /* Decodes the PKCS #12 auth_safe, and returns the allocated raw data,
40 * which holds them. Returns an ASN1_TYPE of authenticatedSafe.
43 _decode_pkcs12_auth_safe (ASN1_TYPE pkcs12
, ASN1_TYPE
* authen_safe
,
46 char oid
[MAX_OID_SIZE
];
47 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
48 gnutls_datum_t auth_safe
= { NULL
, 0 };
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
)
57 return _gnutls_asn2err (result
);
60 if (strcmp (oid
, DATA_OID
) != 0)
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
71 _gnutls_x509_read_string (pkcs12
, "authSafe.content", &auth_safe
, RV_OCTET_STRING
);
78 /* Step 2. Extract the authenticatedSafe.
81 if ((result
= asn1_create_element
82 (_gnutls_get_pkix (), "PKIX1.pkcs-12-AuthenticatedSafe",
83 &c2
)) != ASN1_SUCCESS
)
86 result
= _gnutls_asn2err (result
);
90 result
= asn1_der_decoding (&c2
, auth_safe
.data
, auth_safe
.size
, error_str
);
91 if (result
!= ASN1_SUCCESS
)
94 _gnutls_debug_log ("DER error: %s\n", error_str
);
95 result
= _gnutls_asn2err (result
);
101 _gnutls_free_datum (&auth_safe
);
105 raw
->data
= auth_safe
.data
;
106 raw
->size
= auth_safe
.size
;
112 asn1_delete_structure (&c2
);
118 asn1_delete_structure (&c2
);
119 _gnutls_free_datum (&auth_safe
);
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
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
));
141 int result
= asn1_create_element (_gnutls_get_pkix (),
144 if (result
!= ASN1_SUCCESS
)
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.
162 gnutls_pkcs12_deinit (gnutls_pkcs12_t 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
;
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
,
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
);
233 _gnutls_free_datum (&_data
);
239 _gnutls_free_datum (&_data
);
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
258 * If the structure is PEM encoded, it will have a header
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
)
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
292 * Returns: In case of failure a negative error code will be
293 * returned, and 0 on success.
298 gnutls_pkcs12_export2 (gnutls_pkcs12_t pkcs12
,
299 gnutls_x509_crt_fmt_t format
, gnutls_datum_t
*out
)
304 return GNUTLS_E_INVALID_REQUEST
;
307 return _gnutls_x509_export_int2 (pkcs12
->pkcs12
, format
, PEM_PKCS12
, out
);
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
;
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
;
340 case GNUTLS_BAG_SECRET
:
347 ucs2_to_ascii (char *data
, int size
)
351 for (i
= 0; i
< size
/ 2; i
++)
354 if (isascii (data
[j
]))
355 data
[i
] = data
[i
* 2 + 1];
364 /* Decodes the SafeContents, and puts the output in
368 _pkcs12_decode_safe_contents (const gnutls_datum_t
* content
,
369 gnutls_pkcs12_bag_t bag
)
371 char oid
[MAX_OID_SIZE
], root
[ASN1_MAX_NAME_SIZE
];
372 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
375 gnutls_datum_t attr_val
;
377 int count
= 0, i
, attributes
, j
;
379 /* Step 1. Extract the SEQUENCE.
382 if ((result
= asn1_create_element
383 (_gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
384 &c2
)) != ASN1_SUCCESS
)
387 result
= _gnutls_asn2err (result
);
391 result
= asn1_der_decoding (&c2
, content
->data
, content
->size
, NULL
);
392 if (result
!= ASN1_SUCCESS
)
395 result
= _gnutls_asn2err (result
);
399 /* Count the number of bags
401 result
= asn1_number_of_elements (c2
, "", &count
);
402 if (result
!= ASN1_SUCCESS
)
405 result
= _gnutls_asn2err (result
);
409 bag
->bag_elements
= MIN (MAX_BAG_ELEMENTS
, count
);
411 for (i
= 0; i
< bag
->bag_elements
; i
++)
414 snprintf (root
, sizeof (root
), "?%u.bagId", i
+ 1);
417 result
= asn1_read_value (c2
, root
, oid
, &len
);
418 if (result
!= ASN1_SUCCESS
)
421 result
= _gnutls_asn2err (result
);
427 bag_type
= oid2bag (oid
);
435 /* Read the Bag Value
438 snprintf (root
, sizeof (root
), "?%u.bagValue", i
+ 1);
440 result
= _gnutls_x509_read_value (c2
, root
, &bag
->element
[i
].data
);
447 if (bag_type
== GNUTLS_BAG_CERTIFICATE
|| bag_type
== GNUTLS_BAG_CRL
448 || bag_type
== GNUTLS_BAG_SECRET
)
450 gnutls_datum_t tmp
= bag
->element
[i
].data
;
453 _pkcs12_decode_crt_bag (bag_type
, &tmp
, &bag
->element
[i
].data
);
460 _gnutls_free_datum (&tmp
);
463 /* read the bag attributes
465 snprintf (root
, sizeof (root
), "?%u.bagAttributes", i
+ 1);
467 result
= asn1_number_of_elements (c2
, root
, &attributes
);
468 if (result
!= ASN1_SUCCESS
&& result
!= ASN1_ELEMENT_NOT_FOUND
)
471 result
= _gnutls_asn2err (result
);
478 if (result
!= ASN1_ELEMENT_NOT_FOUND
)
479 for (j
= 0; j
< attributes
; j
++)
482 snprintf (root
, sizeof (root
), "?%u.bagAttributes.?%u", i
+ 1,
486 _gnutls_x509_decode_and_read_attribute (c2
, root
, oid
,
487 sizeof (oid
), &attr_val
,
493 continue; /* continue in case we find some known attributes */
496 if (strcmp (oid
, KEY_ID_OID
) == 0)
499 _gnutls_x509_decode_string (NULL
, attr_val
.data
, attr_val
.size
, &t
);
500 _gnutls_free_datum (&attr_val
);
505 ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid
);
509 attr_val
.data
= t
.data
;
510 attr_val
.size
= t
.size
;
512 bag
->element
[i
].local_key_id
= attr_val
;
514 else if (strcmp (oid
, FRIENDLY_NAME_OID
) == 0)
517 _gnutls_x509_decode_string ("BMPString",
518 attr_val
.data
, attr_val
.size
, &t
);
519 _gnutls_free_datum (&attr_val
);
524 ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid
);
528 attr_val
.data
= t
.data
;
529 attr_val
.size
= t
.size
;
531 bag
->element
[i
].friendly_name
=
532 ucs2_to_ascii ((char*)attr_val
.data
, attr_val
.size
);
536 _gnutls_free_datum (&attr_val
);
538 ("Unknown PKCS12 Bag Attribute OID '%s'\n", oid
);
543 bag
->element
[i
].type
= bag_type
;
547 asn1_delete_structure (&c2
);
554 asn1_delete_structure (&c2
);
561 _parse_safe_contents (ASN1_TYPE sc
, const char *sc_name
,
562 gnutls_pkcs12_bag_t bag
)
564 gnutls_datum_t content
= { NULL
, 0 };
567 /* Step 1. Extract the content.
570 result
= _gnutls_x509_read_string (sc
, sc_name
, &content
, RV_OCTET_STRING
);
577 result
= _pkcs12_decode_safe_contents (&content
, bag
);
584 _gnutls_free_datum (&content
);
589 _gnutls_free_datum (&content
);
595 * gnutls_pkcs12_get_bag:
596 * @pkcs12: should contain a gnutls_pkcs12_t structure
597 * @indx: contains the index of the bag to extract
598 * @bag: An initialized bag, where the contents of the bag will be copied
600 * This function will return a Bag from the PKCS12 structure.
602 * After the last Bag has been read
603 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
605 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
606 * negative error value.
609 gnutls_pkcs12_get_bag (gnutls_pkcs12_t pkcs12
,
610 int indx
, gnutls_pkcs12_bag_t bag
)
612 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
614 char root2
[ASN1_MAX_NAME_SIZE
];
615 char oid
[MAX_OID_SIZE
];
620 return GNUTLS_E_INVALID_REQUEST
;
623 /* Step 1. decode the data.
625 result
= _decode_pkcs12_auth_safe (pkcs12
->pkcs12
, &c2
, NULL
);
632 /* Step 2. Parse the AuthenticatedSafe
635 snprintf (root2
, sizeof (root2
), "?%u.contentType", indx
+ 1);
637 len
= sizeof (oid
) - 1;
638 result
= asn1_read_value (c2
, root2
, oid
, &len
);
640 if (result
== ASN1_ELEMENT_NOT_FOUND
)
642 result
= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
646 if (result
!= ASN1_SUCCESS
)
649 result
= _gnutls_asn2err (result
);
656 snprintf (root2
, sizeof (root2
), "?%u.content", indx
+ 1);
658 if (strcmp (oid
, DATA_OID
) == 0)
660 result
= _parse_safe_contents (c2
, root2
, bag
);
664 /* ENC_DATA_OID needs decryption */
666 bag
->element
[0].type
= GNUTLS_BAG_ENCRYPTED
;
667 bag
->bag_elements
= 1;
669 result
= _gnutls_x509_read_value (c2
, root2
, &bag
->element
[0].data
);
680 asn1_delete_structure (&c2
);
684 /* Creates an empty PFX structure for the PKCS12 structure.
687 create_empty_pfx (ASN1_TYPE pkcs12
)
691 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
695 result
= asn1_write_value (pkcs12
, "version", &three
, 1);
696 if (result
!= ASN1_SUCCESS
)
699 result
= _gnutls_asn2err (result
);
703 /* Write the content type of the data
705 result
= asn1_write_value (pkcs12
, "authSafe.contentType", DATA_OID
, 1);
706 if (result
!= ASN1_SUCCESS
)
709 result
= _gnutls_asn2err (result
);
713 /* Check if the authenticatedSafe content is empty, and encode a
714 * null one in that case.
717 if ((result
= asn1_create_element
718 (_gnutls_get_pkix (), "PKIX1.pkcs-12-AuthenticatedSafe",
719 &c2
)) != ASN1_SUCCESS
)
722 result
= _gnutls_asn2err (result
);
727 _gnutls_x509_der_encode_and_copy (c2
, "", pkcs12
, "authSafe.content", 1);
733 asn1_delete_structure (&c2
);
738 asn1_delete_structure (&c2
);
744 * gnutls_pkcs12_set_bag:
745 * @pkcs12: should contain a gnutls_pkcs12_t structure
746 * @bag: An initialized bag
748 * This function will insert a Bag into the PKCS12 structure.
750 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
751 * negative error value.
754 gnutls_pkcs12_set_bag (gnutls_pkcs12_t pkcs12
, gnutls_pkcs12_bag_t bag
)
756 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
757 ASN1_TYPE safe_cont
= ASN1_TYPE_EMPTY
;
759 int enc
= 0, dum
= 1;
765 return GNUTLS_E_INVALID_REQUEST
;
768 /* Step 1. Check if the pkcs12 structure is empty. In that
769 * case generate an empty PFX.
771 result
= asn1_read_value (pkcs12
->pkcs12
, "authSafe.content", &null
, &dum
);
772 if (result
== ASN1_VALUE_NOT_FOUND
)
774 result
= create_empty_pfx (pkcs12
->pkcs12
);
782 /* Step 2. decode the authenticatedSafe.
784 result
= _decode_pkcs12_auth_safe (pkcs12
->pkcs12
, &c2
, NULL
);
791 /* Step 3. Encode the bag elements into a SafeContents
794 result
= _pkcs12_encode_safe_contents (bag
, &safe_cont
, &enc
);
801 /* Step 4. Insert the encoded SafeContents into the AuthenticatedSafe
804 result
= asn1_write_value (c2
, "", "NEW", 1);
805 if (result
!= ASN1_SUCCESS
)
808 result
= _gnutls_asn2err (result
);
813 result
= asn1_write_value (c2
, "?LAST.contentType", ENC_DATA_OID
, 1);
815 result
= asn1_write_value (c2
, "?LAST.contentType", DATA_OID
, 1);
816 if (result
!= ASN1_SUCCESS
)
819 result
= _gnutls_asn2err (result
);
825 /* Encrypted packets are written directly.
828 asn1_write_value (c2
, "?LAST.content",
829 bag
->element
[0].data
.data
,
830 bag
->element
[0].data
.size
);
831 if (result
!= ASN1_SUCCESS
)
834 result
= _gnutls_asn2err (result
);
841 _gnutls_x509_der_encode_and_copy (safe_cont
, "", c2
,
850 asn1_delete_structure (&safe_cont
);
853 /* Step 5. Reencode and copy the AuthenticatedSafe into the pkcs12
857 _gnutls_x509_der_encode_and_copy (c2
, "", pkcs12
->pkcs12
,
858 "authSafe.content", 1);
865 asn1_delete_structure (&c2
);
870 asn1_delete_structure (&c2
);
871 asn1_delete_structure (&safe_cont
);
876 * gnutls_pkcs12_generate_mac:
877 * @pkcs12: should contain a gnutls_pkcs12_t structure
878 * @pass: The password for the MAC
880 * This function will generate a MAC for the PKCS12 structure.
882 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
883 * negative error value.
886 gnutls_pkcs12_generate_mac (gnutls_pkcs12_t pkcs12
, const char *pass
)
888 uint8_t salt
[8], key
[20];
892 gnutls_datum_t tmp
= { NULL
, 0 };
898 return GNUTLS_E_INVALID_REQUEST
;
901 /* Generate the salt.
903 result
= _gnutls_rnd (GNUTLS_RND_NONCE
, salt
, sizeof (salt
));
910 /* Write the salt into the structure.
913 asn1_write_value (pkcs12
->pkcs12
, "macData.macSalt", salt
, sizeof (salt
));
914 if (result
!= ASN1_SUCCESS
)
917 result
= _gnutls_asn2err (result
);
921 /* write the iterations
927 _gnutls_x509_write_uint32 (pkcs12
->pkcs12
, "macData.iterations",
938 result
= _gnutls_pkcs12_string_to_key (3 /*MAC*/, salt
, sizeof (salt
),
939 iter
, pass
, sizeof (key
), key
);
946 /* Get the data to be MACed
948 result
= _decode_pkcs12_auth_safe (pkcs12
->pkcs12
, NULL
, &tmp
);
957 result
= _gnutls_hmac_init (&td1
, GNUTLS_MAC_SHA1
, key
, sizeof (key
));
964 _gnutls_hmac (&td1
, tmp
.data
, tmp
.size
);
965 _gnutls_free_datum (&tmp
);
967 _gnutls_hmac_deinit (&td1
, sha_mac
);
971 asn1_write_value (pkcs12
->pkcs12
, "macData.mac.digest", sha_mac
,
973 if (result
!= ASN1_SUCCESS
)
976 result
= _gnutls_asn2err (result
);
981 asn1_write_value (pkcs12
->pkcs12
,
982 "macData.mac.digestAlgorithm.parameters", NULL
, 0);
983 if (result
!= ASN1_SUCCESS
)
986 result
= _gnutls_asn2err (result
);
991 asn1_write_value (pkcs12
->pkcs12
,
992 "macData.mac.digestAlgorithm.algorithm", HASH_OID_SHA1
,
994 if (result
!= ASN1_SUCCESS
)
997 result
= _gnutls_asn2err (result
);
1004 _gnutls_free_datum (&tmp
);
1009 * gnutls_pkcs12_verify_mac:
1010 * @pkcs12: should contain a gnutls_pkcs12_t structure
1011 * @pass: The password for the MAC
1013 * This function will verify the MAC for the PKCS12 structure.
1015 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1016 * negative error value.
1019 gnutls_pkcs12_verify_mac (gnutls_pkcs12_t pkcs12
, const char *pass
)
1026 gnutls_datum_t tmp
= { NULL
, 0 }, salt
=
1029 uint8_t sha_mac
[20];
1030 uint8_t sha_mac_orig
[20];
1035 return GNUTLS_E_INVALID_REQUEST
;
1038 /* read the iterations
1042 _gnutls_x509_read_uint (pkcs12
->pkcs12
, "macData.iterations", &iter
);
1045 iter
= 1; /* the default */
1049 /* Read the salt from the structure.
1052 _gnutls_x509_read_value (pkcs12
->pkcs12
, "macData.macSalt", &salt
);
1053 if (result
!= ASN1_SUCCESS
)
1056 result
= _gnutls_asn2err (result
);
1060 /* Generate the key.
1062 result
= _gnutls_pkcs12_string_to_key (3 /*MAC*/, salt
.data
, salt
.size
,
1063 iter
, pass
, sizeof (key
), key
);
1070 _gnutls_free_datum (&salt
);
1072 /* Get the data to be MACed
1074 result
= _decode_pkcs12_auth_safe (pkcs12
->pkcs12
, NULL
, &tmp
);
1083 result
= _gnutls_hmac_init (&td1
, GNUTLS_MAC_SHA1
, key
, sizeof (key
));
1090 _gnutls_hmac (&td1
, tmp
.data
, tmp
.size
);
1091 _gnutls_free_datum (&tmp
);
1093 _gnutls_hmac_deinit (&td1
, sha_mac
);
1095 len
= sizeof (sha_mac_orig
);
1097 asn1_read_value (pkcs12
->pkcs12
, "macData.mac.digest", sha_mac_orig
,
1099 if (result
!= ASN1_SUCCESS
)
1102 result
= _gnutls_asn2err (result
);
1106 if (memcmp (sha_mac_orig
, sha_mac
, sizeof (sha_mac
)) != 0)
1109 return GNUTLS_E_MAC_VERIFY_FAILED
;
1115 _gnutls_free_datum (&tmp
);
1116 _gnutls_free_datum (&salt
);
1122 write_attributes (gnutls_pkcs12_bag_t bag
, int elem
,
1123 ASN1_TYPE c2
, const char *where
)
1128 /* If the bag attributes are empty, then write
1129 * nothing to the attribute field.
1131 if (bag
->element
[elem
].friendly_name
== NULL
&&
1132 bag
->element
[elem
].local_key_id
.data
== NULL
)
1136 result
= asn1_write_value (c2
, where
, NULL
, 0);
1137 if (result
!= ASN1_SUCCESS
)
1140 return _gnutls_asn2err (result
);
1146 if (bag
->element
[elem
].local_key_id
.data
!= NULL
)
1149 /* Add a new Attribute
1151 result
= asn1_write_value (c2
, where
, "NEW", 1);
1152 if (result
!= ASN1_SUCCESS
)
1155 return _gnutls_asn2err (result
);
1158 _gnutls_str_cpy (root
, sizeof (root
), where
);
1159 _gnutls_str_cat (root
, sizeof (root
), ".?LAST");
1162 _gnutls_x509_encode_and_write_attribute (KEY_ID_OID
, c2
, root
,
1164 element
[elem
].local_key_id
.
1167 element
[elem
].local_key_id
.
1176 if (bag
->element
[elem
].friendly_name
!= NULL
)
1182 /* Add a new Attribute
1184 result
= asn1_write_value (c2
, where
, "NEW", 1);
1185 if (result
!= ASN1_SUCCESS
)
1188 return _gnutls_asn2err (result
);
1191 /* convert name to BMPString
1193 size
= strlen (bag
->element
[elem
].friendly_name
) * 2;
1194 name
= gnutls_malloc (size
);
1199 return GNUTLS_E_MEMORY_ERROR
;
1202 p
= bag
->element
[elem
].friendly_name
;
1203 for (i
= 0; i
< size
; i
+= 2)
1210 _gnutls_str_cpy (root
, sizeof (root
), where
);
1211 _gnutls_str_cat (root
, sizeof (root
), ".?LAST");
1214 _gnutls_x509_encode_and_write_attribute (FRIENDLY_NAME_OID
, c2
,
1215 root
, name
, size
, 1);
1230 /* Encodes the bag into a SafeContents structure, and puts the output in
1231 * the given datum. Enc is set to non-zero if the data are encrypted;
1234 _pkcs12_encode_safe_contents (gnutls_pkcs12_bag_t bag
, ASN1_TYPE
* contents
,
1237 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
1242 if (bag
->element
[0].type
== GNUTLS_BAG_ENCRYPTED
&& enc
)
1245 return 0; /* ENCRYPTED BAG, do nothing. */
1250 /* Step 1. Create the SEQUENCE.
1253 if ((result
= asn1_create_element
1254 (_gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
1255 &c2
)) != ASN1_SUCCESS
)
1258 result
= _gnutls_asn2err (result
);
1262 for (i
= 0; i
< bag
->bag_elements
; i
++)
1265 oid
= bag_to_oid (bag
->element
[i
].type
);
1272 result
= asn1_write_value (c2
, "", "NEW", 1);
1273 if (result
!= ASN1_SUCCESS
)
1276 result
= _gnutls_asn2err (result
);
1280 /* Copy the bag type.
1282 result
= asn1_write_value (c2
, "?LAST.bagId", oid
, 1);
1283 if (result
!= ASN1_SUCCESS
)
1286 result
= _gnutls_asn2err (result
);
1290 /* Set empty attributes
1292 result
= write_attributes (bag
, i
, c2
, "?LAST.bagAttributes");
1300 /* Copy the Bag Value
1303 if (bag
->element
[i
].type
== GNUTLS_BAG_CERTIFICATE
||
1304 bag
->element
[i
].type
== GNUTLS_BAG_SECRET
||
1305 bag
->element
[i
].type
== GNUTLS_BAG_CRL
)
1309 /* in that case encode it to a CertBag or
1314 _pkcs12_encode_crt_bag (bag
->element
[i
].type
,
1315 &bag
->element
[i
].data
, &tmp
);
1323 result
= _gnutls_x509_write_value (c2
, "?LAST.bagValue", &tmp
, 0);
1325 _gnutls_free_datum (&tmp
);
1331 result
= _gnutls_x509_write_value (c2
, "?LAST.bagValue",
1332 &bag
->element
[i
].data
, 0);
1343 /* Encode the data and copy them into the datum
1351 asn1_delete_structure (&c2
);
1356 /* Checks if the extra_certs contain certificates that may form a chain
1357 * with the first certificate in chain (it is expected that chain_len==1)
1358 * and appends those in the chain.
1360 static int make_chain(gnutls_x509_crt_t
**chain
, unsigned int *chain_len
,
1361 gnutls_x509_crt_t
**extra_certs
, unsigned int *extra_certs_len
,
1366 if (*chain_len
!= 1)
1367 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST
);
1370 while(i
<*extra_certs_len
)
1372 /* if it is an issuer but not a self-signed one */
1373 if (gnutls_x509_crt_check_issuer((*chain
)[*chain_len
- 1], (*extra_certs
)[i
]) != 0)
1375 if (!(flags
& GNUTLS_PKCS12_SP_INCLUDE_SELF_SIGNED
) &&
1376 gnutls_x509_crt_check_issuer((*extra_certs
)[i
], (*extra_certs
)[i
]) != 0)
1379 *chain
= gnutls_realloc (*chain
, sizeof((*chain
)[0]) *
1384 return GNUTLS_E_MEMORY_ERROR
;
1386 (*chain
)[*chain_len
- 1] = (*extra_certs
)[i
];
1388 (*extra_certs
)[i
] = (*extra_certs
)[*extra_certs_len
-1];
1389 (*extra_certs_len
)--;
1402 * gnutls_pkcs12_simple_parse:
1403 * @p12: the PKCS#12 blob.
1404 * @password: optional password used to decrypt PKCS#12 blob, bags and keys.
1405 * @key: a structure to store the parsed private key.
1406 * @chain: the corresponding to key certificate chain
1407 * @chain_len: will be updated with the number of additional
1408 * @extra_certs: optional pointer to receive an array of additional
1409 * certificates found in the PKCS#12 blob.
1410 * @extra_certs_len: will be updated with the number of additional
1412 * @crl: an optional structure to store the parsed CRL.
1413 * @flags: should be zero or one of GNUTLS_PKCS12_SP_*
1415 * This function parses a PKCS#12 blob in @p12blob and extracts the
1416 * private key, the corresponding certificate chain, and any additional
1417 * certificates and a CRL.
1419 * The @extra_certs_ret and @extra_certs_ret_len parameters are optional
1420 * and both may be set to %NULL. If either is non-%NULL, then both must
1423 * Encrypted PKCS#12 bags and PKCS#8 private keys are supported. However,
1424 * only password based security, and the same password for all
1425 * operations, are supported.
1427 * PKCS#12 file may contain many keys and/or certificates, and there
1428 * is no way to identify which key/certificate pair you want. You
1429 * should make sure the PKCS#12 file only contain one key/certificate
1430 * pair and/or one CRL.
1432 * It is believed that the limitations of this function is acceptable
1433 * for most usage, and that any more flexibility would introduce
1434 * complexity that would make it harder to use this functionality at
1437 * If the provided structure has encrypted fields but no password
1438 * is provided then this function returns %GNUTLS_E_DECRYPTION_FAILED.
1440 * Note that normally the chain constructed does not include self signed
1441 * certificates, to comply with TLS' requirements. If, however, the flag
1442 * %GNUTLS_PKCS12_SP_INCLUDE_SELF_SIGNED is specified then
1443 * self signed certificates will be included in the chain.
1445 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1446 * negative error value.
1451 gnutls_pkcs12_simple_parse (gnutls_pkcs12_t p12
,
1452 const char *password
,
1453 gnutls_x509_privkey_t
* key
,
1454 gnutls_x509_crt_t
** chain
,
1455 unsigned int * chain_len
,
1456 gnutls_x509_crt_t
** extra_certs
,
1457 unsigned int * extra_certs_len
,
1458 gnutls_x509_crl_t
* crl
,
1461 gnutls_pkcs12_bag_t bag
= NULL
;
1462 gnutls_x509_crt_t
*_extra_certs
= NULL
;
1463 unsigned int _extra_certs_len
= 0;
1464 gnutls_x509_crt_t
*_chain
= NULL
;
1465 unsigned int _chain_len
= 0;
1468 size_t cert_id_size
= 0;
1469 size_t key_id_size
= 0;
1470 uint8_t cert_id
[20];
1480 /* find the first private key */
1483 int elements_in_bag
;
1486 ret
= gnutls_pkcs12_bag_init (&bag
);
1494 ret
= gnutls_pkcs12_get_bag (p12
, idx
, bag
);
1495 if (ret
== GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
)
1503 ret
= gnutls_pkcs12_bag_get_type (bag
, 0);
1510 if (ret
== GNUTLS_BAG_ENCRYPTED
)
1512 if (password
== NULL
)
1514 ret
= gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED
);
1518 ret
= gnutls_pkcs12_bag_decrypt (bag
, password
);
1526 elements_in_bag
= gnutls_pkcs12_bag_get_count (bag
);
1527 if (elements_in_bag
< 0)
1533 for (i
= 0; i
< elements_in_bag
; i
++)
1536 gnutls_datum_t data
;
1538 type
= gnutls_pkcs12_bag_get_type (bag
, i
);
1545 ret
= gnutls_pkcs12_bag_get_data (bag
, i
, &data
);
1554 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
:
1555 if (password
== NULL
)
1557 ret
= gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED
);
1561 case GNUTLS_BAG_PKCS8_KEY
:
1562 if (*key
!= NULL
) /* too simple to continue */
1568 ret
= gnutls_x509_privkey_init (key
);
1575 ret
= gnutls_x509_privkey_import_pkcs8
1576 (*key
, &data
, GNUTLS_X509_FMT_DER
, password
,
1577 type
== GNUTLS_BAG_PKCS8_KEY
? GNUTLS_PKCS_PLAIN
: 0);
1581 gnutls_x509_privkey_deinit (*key
);
1585 key_id_size
= sizeof (key_id
);
1587 gnutls_x509_privkey_get_key_id (*key
, 0, key_id
,
1592 gnutls_x509_privkey_deinit (*key
);
1596 privkey_ok
= 1; /* break */
1604 gnutls_pkcs12_bag_deinit (bag
);
1606 if (privkey_ok
!= 0) /* private key was found */
1610 if (privkey_ok
== 0) /* no private key */
1613 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1616 /* now find the corresponding certificate
1622 int elements_in_bag
;
1625 ret
= gnutls_pkcs12_bag_init (&bag
);
1633 ret
= gnutls_pkcs12_get_bag (p12
, idx
, bag
);
1634 if (ret
== GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
)
1642 ret
= gnutls_pkcs12_bag_get_type (bag
, 0);
1649 if (ret
== GNUTLS_BAG_ENCRYPTED
)
1651 ret
= gnutls_pkcs12_bag_decrypt (bag
, password
);
1659 elements_in_bag
= gnutls_pkcs12_bag_get_count (bag
);
1660 if (elements_in_bag
< 0)
1666 for (i
= 0; i
< elements_in_bag
; i
++)
1669 gnutls_datum_t data
;
1670 gnutls_x509_crt_t this_cert
;
1672 type
= gnutls_pkcs12_bag_get_type (bag
, i
);
1679 ret
= gnutls_pkcs12_bag_get_data (bag
, i
, &data
);
1688 case GNUTLS_BAG_CERTIFICATE
:
1689 ret
= gnutls_x509_crt_init (&this_cert
);
1697 gnutls_x509_crt_import (this_cert
, &data
, GNUTLS_X509_FMT_DER
);
1701 gnutls_x509_crt_deinit (this_cert
);
1705 /* check if the key id match */
1706 cert_id_size
= sizeof (cert_id
);
1708 gnutls_x509_crt_get_key_id (this_cert
, 0, cert_id
, &cert_id_size
);
1712 gnutls_x509_crt_deinit (this_cert
);
1716 if (memcmp (cert_id
, key_id
, cert_id_size
) != 0)
1717 { /* they don't match - skip the certificate */
1720 _extra_certs
= gnutls_realloc (_extra_certs
,
1721 sizeof(_extra_certs
[0]) *
1722 ++_extra_certs_len
);
1726 ret
= GNUTLS_E_MEMORY_ERROR
;
1729 _extra_certs
[_extra_certs_len
- 1] = this_cert
;
1734 gnutls_x509_crt_deinit (this_cert
);
1739 if (_chain_len
== 0)
1741 _chain
= gnutls_malloc (sizeof(_chain
[0]) * (++_chain_len
));
1745 ret
= GNUTLS_E_MEMORY_ERROR
;
1748 _chain
[_chain_len
- 1] = this_cert
;
1753 gnutls_x509_crt_deinit (this_cert
);
1758 case GNUTLS_BAG_CRL
:
1759 if (crl
== NULL
|| *crl
!= NULL
)
1765 ret
= gnutls_x509_crl_init (crl
);
1772 ret
= gnutls_x509_crl_import (*crl
, &data
, GNUTLS_X509_FMT_DER
);
1776 gnutls_x509_crl_deinit (*crl
);
1781 case GNUTLS_BAG_ENCRYPTED
:
1782 /* XXX Bother to recurse one level down? Unlikely to
1783 use the same password anyway. */
1784 case GNUTLS_BAG_EMPTY
:
1791 gnutls_pkcs12_bag_deinit (bag
);
1794 if (_chain_len
!= 1)
1796 ret
= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1800 ret
= make_chain(&_chain
, &_chain_len
, &_extra_certs
, &_extra_certs_len
, flags
);
1811 gnutls_pkcs12_bag_deinit (bag
);
1816 gnutls_x509_privkey_deinit(*key
);
1817 if (_extra_certs_len
&& _extra_certs
!= NULL
)
1819 for (i
= 0; i
< _extra_certs_len
; i
++)
1820 gnutls_x509_crt_deinit(_extra_certs
[i
]);
1821 gnutls_free(_extra_certs
);
1823 if (_chain_len
&& _chain
!= NULL
)
1825 for (i
= 0; i
< _chain_len
; i
++)
1826 gnutls_x509_crt_deinit(_chain
[i
]);
1827 gnutls_free(_chain
);
1833 if (extra_certs
&& _extra_certs_len
> 0)
1835 *extra_certs
= _extra_certs
;
1836 *extra_certs_len
= _extra_certs_len
;
1842 *extra_certs
= NULL
;
1843 *extra_certs_len
= 0;
1845 for (i
= 0; i
< _extra_certs_len
; i
++)
1846 gnutls_x509_crt_deinit(_extra_certs
[i
]);
1847 gnutls_free(_extra_certs
);
1851 *chain_len
= _chain_len
;