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_value (pkcs12
, "authSafe.content", &auth_safe
, 1);
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
)
212 result
= _gnutls_fbase64_decode (PEM_PKCS12
, data
->data
, data
->size
,
218 result
= GNUTLS_E_INTERNAL_ERROR
;
230 asn1_der_decoding (&pkcs12
->pkcs12
, _data
.data
, _data
.size
, error_str
);
231 if (result
!= ASN1_SUCCESS
)
233 result
= _gnutls_asn2err (result
);
234 _gnutls_debug_log ("DER error: %s\n", error_str
);
240 _gnutls_free_datum (&_data
);
246 _gnutls_free_datum (&_data
);
252 * gnutls_pkcs12_export:
253 * @pkcs12: Holds the pkcs12 structure
254 * @format: the format of output params. One of PEM or DER.
255 * @output_data: will contain a structure PEM or DER encoded
256 * @output_data_size: holds the size of output_data (and will be
257 * replaced by the actual size of parameters)
259 * This function will export the pkcs12 structure to DER or PEM format.
261 * If the buffer provided is not long enough to hold the output, then
262 * *output_data_size will be updated and GNUTLS_E_SHORT_MEMORY_BUFFER
265 * If the structure is PEM encoded, it will have a header
268 * Returns: In case of failure a negative error code will be
269 * returned, and 0 on success.
272 gnutls_pkcs12_export (gnutls_pkcs12_t pkcs12
,
273 gnutls_x509_crt_fmt_t format
, void *output_data
,
274 size_t * output_data_size
)
279 return GNUTLS_E_INVALID_REQUEST
;
282 return _gnutls_x509_export_int (pkcs12
->pkcs12
, format
, PEM_PKCS12
,
283 output_data
, output_data_size
);
287 oid2bag (const char *oid
)
289 if (strcmp (oid
, BAG_PKCS8_KEY
) == 0)
290 return GNUTLS_BAG_PKCS8_KEY
;
291 if (strcmp (oid
, BAG_PKCS8_ENCRYPTED_KEY
) == 0)
292 return GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
;
293 if (strcmp (oid
, BAG_CERTIFICATE
) == 0)
294 return GNUTLS_BAG_CERTIFICATE
;
295 if (strcmp (oid
, BAG_CRL
) == 0)
296 return GNUTLS_BAG_CRL
;
297 if (strcmp (oid
, BAG_SECRET
) == 0)
298 return GNUTLS_BAG_SECRET
;
300 return GNUTLS_BAG_UNKNOWN
;
308 case GNUTLS_BAG_PKCS8_KEY
:
309 return BAG_PKCS8_KEY
;
310 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
:
311 return BAG_PKCS8_ENCRYPTED_KEY
;
312 case GNUTLS_BAG_CERTIFICATE
:
313 return BAG_CERTIFICATE
;
316 case GNUTLS_BAG_SECRET
:
323 ucs2_to_ascii (char *data
, int size
)
327 for (i
= 0; i
< size
/ 2; i
++)
330 if (isascii (data
[j
]))
331 data
[i
] = data
[i
* 2 + 1];
340 /* Decodes the SafeContents, and puts the output in
344 _pkcs12_decode_safe_contents (const gnutls_datum_t
* content
,
345 gnutls_pkcs12_bag_t bag
)
347 char oid
[MAX_OID_SIZE
], root
[ASN1_MAX_NAME_SIZE
];
348 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
351 gnutls_datum_t attr_val
;
352 int count
= 0, i
, attributes
, j
;
355 /* Step 1. Extract the SEQUENCE.
358 if ((result
= asn1_create_element
359 (_gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
360 &c2
)) != ASN1_SUCCESS
)
363 result
= _gnutls_asn2err (result
);
367 result
= asn1_der_decoding (&c2
, content
->data
, content
->size
, NULL
);
368 if (result
!= ASN1_SUCCESS
)
371 result
= _gnutls_asn2err (result
);
375 /* Count the number of bags
377 result
= asn1_number_of_elements (c2
, "", &count
);
378 if (result
!= ASN1_SUCCESS
)
381 result
= _gnutls_asn2err (result
);
385 bag
->bag_elements
= MIN (MAX_BAG_ELEMENTS
, count
);
387 for (i
= 0; i
< bag
->bag_elements
; i
++)
390 snprintf (root
, sizeof (root
), "?%u.bagId", i
+ 1);
393 result
= asn1_read_value (c2
, root
, oid
, &len
);
394 if (result
!= ASN1_SUCCESS
)
397 result
= _gnutls_asn2err (result
);
403 bag_type
= oid2bag (oid
);
411 /* Read the Bag Value
414 snprintf (root
, sizeof (root
), "?%u.bagValue", i
+ 1);
416 result
= _gnutls_x509_read_value (c2
, root
, &bag
->element
[i
].data
, 0);
423 if (bag_type
== GNUTLS_BAG_CERTIFICATE
|| bag_type
== GNUTLS_BAG_CRL
424 || bag_type
== GNUTLS_BAG_SECRET
)
426 gnutls_datum_t tmp
= bag
->element
[i
].data
;
429 _pkcs12_decode_crt_bag (bag_type
, &tmp
, &bag
->element
[i
].data
);
436 _gnutls_free_datum (&tmp
);
439 /* read the bag attributes
441 snprintf (root
, sizeof (root
), "?%u.bagAttributes", i
+ 1);
443 result
= asn1_number_of_elements (c2
, root
, &attributes
);
444 if (result
!= ASN1_SUCCESS
&& result
!= ASN1_ELEMENT_NOT_FOUND
)
447 result
= _gnutls_asn2err (result
);
454 if (result
!= ASN1_ELEMENT_NOT_FOUND
)
455 for (j
= 0; j
< attributes
; j
++)
458 snprintf (root
, sizeof (root
), "?%u.bagAttributes.?%u", i
+ 1,
462 _gnutls_x509_decode_and_read_attribute (c2
, root
, oid
,
463 sizeof (oid
), &attr_val
,
469 continue; /* continue in case we find some known attributes */
472 if (strcmp (oid
, KEY_ID_OID
) == 0)
474 size
= attr_val
.size
;
477 _gnutls_x509_decode_octet_string (NULL
, attr_val
.data
, size
,
478 attr_val
.data
, &size
);
479 attr_val
.size
= size
;
482 _gnutls_free_datum (&attr_val
);
485 ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid
);
488 bag
->element
[i
].local_key_id
= attr_val
;
490 else if (strcmp (oid
, FRIENDLY_NAME_OID
) == 0)
492 size
= attr_val
.size
;
494 _gnutls_x509_decode_octet_string ("BMPString",
496 attr_val
.data
, &size
);
497 attr_val
.size
= size
;
500 _gnutls_free_datum (&attr_val
);
503 ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid
);
506 bag
->element
[i
].friendly_name
=
507 ucs2_to_ascii ((char*)attr_val
.data
, attr_val
.size
);
511 _gnutls_free_datum (&attr_val
);
513 ("Unknown PKCS12 Bag Attribute OID '%s'\n", oid
);
518 bag
->element
[i
].type
= bag_type
;
522 asn1_delete_structure (&c2
);
529 asn1_delete_structure (&c2
);
536 _parse_safe_contents (ASN1_TYPE sc
, const char *sc_name
,
537 gnutls_pkcs12_bag_t bag
)
539 gnutls_datum_t content
= { NULL
, 0 };
542 /* Step 1. Extract the content.
545 result
= _gnutls_x509_read_value (sc
, sc_name
, &content
, 1);
552 result
= _pkcs12_decode_safe_contents (&content
, bag
);
559 _gnutls_free_datum (&content
);
564 _gnutls_free_datum (&content
);
570 * gnutls_pkcs12_get_bag:
571 * @pkcs12: should contain a gnutls_pkcs12_t structure
572 * @indx: contains the index of the bag to extract
573 * @bag: An initialized bag, where the contents of the bag will be copied
575 * This function will return a Bag from the PKCS12 structure.
577 * After the last Bag has been read
578 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
580 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
581 * negative error value.
584 gnutls_pkcs12_get_bag (gnutls_pkcs12_t pkcs12
,
585 int indx
, gnutls_pkcs12_bag_t bag
)
587 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
589 char root2
[ASN1_MAX_NAME_SIZE
];
590 char oid
[MAX_OID_SIZE
];
595 return GNUTLS_E_INVALID_REQUEST
;
598 /* Step 1. decode the data.
600 result
= _decode_pkcs12_auth_safe (pkcs12
->pkcs12
, &c2
, NULL
);
607 /* Step 2. Parse the AuthenticatedSafe
610 snprintf (root2
, sizeof (root2
), "?%u.contentType", indx
+ 1);
612 len
= sizeof (oid
) - 1;
613 result
= asn1_read_value (c2
, root2
, oid
, &len
);
615 if (result
== ASN1_ELEMENT_NOT_FOUND
)
617 result
= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
621 if (result
!= ASN1_SUCCESS
)
624 result
= _gnutls_asn2err (result
);
631 snprintf (root2
, sizeof (root2
), "?%u.content", indx
+ 1);
633 if (strcmp (oid
, DATA_OID
) == 0)
635 result
= _parse_safe_contents (c2
, root2
, bag
);
639 /* ENC_DATA_OID needs decryption */
641 bag
->element
[0].type
= GNUTLS_BAG_ENCRYPTED
;
642 bag
->bag_elements
= 1;
644 result
= _gnutls_x509_read_value (c2
, root2
, &bag
->element
[0].data
, 0);
655 asn1_delete_structure (&c2
);
659 /* Creates an empty PFX structure for the PKCS12 structure.
662 create_empty_pfx (ASN1_TYPE pkcs12
)
666 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
670 result
= asn1_write_value (pkcs12
, "version", &three
, 1);
671 if (result
!= ASN1_SUCCESS
)
674 result
= _gnutls_asn2err (result
);
678 /* Write the content type of the data
680 result
= asn1_write_value (pkcs12
, "authSafe.contentType", DATA_OID
, 1);
681 if (result
!= ASN1_SUCCESS
)
684 result
= _gnutls_asn2err (result
);
688 /* Check if the authenticatedSafe content is empty, and encode a
689 * null one in that case.
692 if ((result
= asn1_create_element
693 (_gnutls_get_pkix (), "PKIX1.pkcs-12-AuthenticatedSafe",
694 &c2
)) != ASN1_SUCCESS
)
697 result
= _gnutls_asn2err (result
);
702 _gnutls_x509_der_encode_and_copy (c2
, "", pkcs12
, "authSafe.content", 1);
708 asn1_delete_structure (&c2
);
713 asn1_delete_structure (&c2
);
719 * gnutls_pkcs12_set_bag:
720 * @pkcs12: should contain a gnutls_pkcs12_t structure
721 * @bag: An initialized bag
723 * This function will insert a Bag into the PKCS12 structure.
725 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
726 * negative error value.
729 gnutls_pkcs12_set_bag (gnutls_pkcs12_t pkcs12
, gnutls_pkcs12_bag_t bag
)
731 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
732 ASN1_TYPE safe_cont
= ASN1_TYPE_EMPTY
;
734 int enc
= 0, dum
= 1;
740 return GNUTLS_E_INVALID_REQUEST
;
743 /* Step 1. Check if the pkcs12 structure is empty. In that
744 * case generate an empty PFX.
746 result
= asn1_read_value (pkcs12
->pkcs12
, "authSafe.content", &null
, &dum
);
747 if (result
== ASN1_VALUE_NOT_FOUND
)
749 result
= create_empty_pfx (pkcs12
->pkcs12
);
757 /* Step 2. decode the authenticatedSafe.
759 result
= _decode_pkcs12_auth_safe (pkcs12
->pkcs12
, &c2
, NULL
);
766 /* Step 3. Encode the bag elements into a SafeContents
769 result
= _pkcs12_encode_safe_contents (bag
, &safe_cont
, &enc
);
776 /* Step 4. Insert the encoded SafeContents into the AuthenticatedSafe
779 result
= asn1_write_value (c2
, "", "NEW", 1);
780 if (result
!= ASN1_SUCCESS
)
783 result
= _gnutls_asn2err (result
);
788 result
= asn1_write_value (c2
, "?LAST.contentType", ENC_DATA_OID
, 1);
790 result
= asn1_write_value (c2
, "?LAST.contentType", DATA_OID
, 1);
791 if (result
!= ASN1_SUCCESS
)
794 result
= _gnutls_asn2err (result
);
800 /* Encrypted packets are written directly.
803 asn1_write_value (c2
, "?LAST.content",
804 bag
->element
[0].data
.data
,
805 bag
->element
[0].data
.size
);
806 if (result
!= ASN1_SUCCESS
)
809 result
= _gnutls_asn2err (result
);
816 _gnutls_x509_der_encode_and_copy (safe_cont
, "", c2
,
825 asn1_delete_structure (&safe_cont
);
828 /* Step 5. Reencode and copy the AuthenticatedSafe into the pkcs12
832 _gnutls_x509_der_encode_and_copy (c2
, "", pkcs12
->pkcs12
,
833 "authSafe.content", 1);
840 asn1_delete_structure (&c2
);
845 asn1_delete_structure (&c2
);
846 asn1_delete_structure (&safe_cont
);
851 * gnutls_pkcs12_generate_mac:
852 * @pkcs12: should contain a gnutls_pkcs12_t structure
853 * @pass: The password for the MAC
855 * This function will generate a MAC for the PKCS12 structure.
857 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
858 * negative error value.
861 gnutls_pkcs12_generate_mac (gnutls_pkcs12_t pkcs12
, const char *pass
)
863 uint8_t salt
[8], key
[20];
867 gnutls_datum_t tmp
= { NULL
, 0 };
873 return GNUTLS_E_INVALID_REQUEST
;
876 /* Generate the salt.
878 result
= _gnutls_rnd (GNUTLS_RND_NONCE
, salt
, sizeof (salt
));
885 /* Write the salt into the structure.
888 asn1_write_value (pkcs12
->pkcs12
, "macData.macSalt", salt
, sizeof (salt
));
889 if (result
!= ASN1_SUCCESS
)
892 result
= _gnutls_asn2err (result
);
896 /* write the iterations
902 _gnutls_x509_write_uint32 (pkcs12
->pkcs12
, "macData.iterations",
913 result
= _gnutls_pkcs12_string_to_key (3 /*MAC*/, salt
, sizeof (salt
),
914 iter
, pass
, sizeof (key
), key
);
921 /* Get the data to be MACed
923 result
= _decode_pkcs12_auth_safe (pkcs12
->pkcs12
, NULL
, &tmp
);
932 result
= _gnutls_hmac_init (&td1
, GNUTLS_MAC_SHA1
, key
, sizeof (key
));
939 _gnutls_hmac (&td1
, tmp
.data
, tmp
.size
);
940 _gnutls_free_datum (&tmp
);
942 _gnutls_hmac_deinit (&td1
, sha_mac
);
946 asn1_write_value (pkcs12
->pkcs12
, "macData.mac.digest", sha_mac
,
948 if (result
!= ASN1_SUCCESS
)
951 result
= _gnutls_asn2err (result
);
956 asn1_write_value (pkcs12
->pkcs12
,
957 "macData.mac.digestAlgorithm.parameters", NULL
, 0);
958 if (result
!= ASN1_SUCCESS
)
961 result
= _gnutls_asn2err (result
);
966 asn1_write_value (pkcs12
->pkcs12
,
967 "macData.mac.digestAlgorithm.algorithm", HASH_OID_SHA1
,
969 if (result
!= ASN1_SUCCESS
)
972 result
= _gnutls_asn2err (result
);
979 _gnutls_free_datum (&tmp
);
984 * gnutls_pkcs12_verify_mac:
985 * @pkcs12: should contain a gnutls_pkcs12_t structure
986 * @pass: The password for the MAC
988 * This function will verify the MAC for the PKCS12 structure.
990 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
991 * negative error value.
994 gnutls_pkcs12_verify_mac (gnutls_pkcs12_t pkcs12
, const char *pass
)
1001 gnutls_datum_t tmp
= { NULL
, 0 }, salt
=
1004 uint8_t sha_mac
[20];
1005 uint8_t sha_mac_orig
[20];
1010 return GNUTLS_E_INVALID_REQUEST
;
1013 /* read the iterations
1017 _gnutls_x509_read_uint (pkcs12
->pkcs12
, "macData.iterations", &iter
);
1020 iter
= 1; /* the default */
1024 /* Read the salt from the structure.
1027 _gnutls_x509_read_value (pkcs12
->pkcs12
, "macData.macSalt", &salt
, 0);
1028 if (result
!= ASN1_SUCCESS
)
1031 result
= _gnutls_asn2err (result
);
1035 /* Generate the key.
1037 result
= _gnutls_pkcs12_string_to_key (3 /*MAC*/, salt
.data
, salt
.size
,
1038 iter
, pass
, sizeof (key
), key
);
1045 _gnutls_free_datum (&salt
);
1047 /* Get the data to be MACed
1049 result
= _decode_pkcs12_auth_safe (pkcs12
->pkcs12
, NULL
, &tmp
);
1058 result
= _gnutls_hmac_init (&td1
, GNUTLS_MAC_SHA1
, key
, sizeof (key
));
1065 _gnutls_hmac (&td1
, tmp
.data
, tmp
.size
);
1066 _gnutls_free_datum (&tmp
);
1068 _gnutls_hmac_deinit (&td1
, sha_mac
);
1070 len
= sizeof (sha_mac_orig
);
1072 asn1_read_value (pkcs12
->pkcs12
, "macData.mac.digest", sha_mac_orig
,
1074 if (result
!= ASN1_SUCCESS
)
1077 result
= _gnutls_asn2err (result
);
1081 if (memcmp (sha_mac_orig
, sha_mac
, sizeof (sha_mac
)) != 0)
1084 return GNUTLS_E_MAC_VERIFY_FAILED
;
1090 _gnutls_free_datum (&tmp
);
1091 _gnutls_free_datum (&salt
);
1097 write_attributes (gnutls_pkcs12_bag_t bag
, int elem
,
1098 ASN1_TYPE c2
, const char *where
)
1103 /* If the bag attributes are empty, then write
1104 * nothing to the attribute field.
1106 if (bag
->element
[elem
].friendly_name
== NULL
&&
1107 bag
->element
[elem
].local_key_id
.data
== NULL
)
1111 result
= asn1_write_value (c2
, where
, NULL
, 0);
1112 if (result
!= ASN1_SUCCESS
)
1115 return _gnutls_asn2err (result
);
1121 if (bag
->element
[elem
].local_key_id
.data
!= NULL
)
1124 /* Add a new Attribute
1126 result
= asn1_write_value (c2
, where
, "NEW", 1);
1127 if (result
!= ASN1_SUCCESS
)
1130 return _gnutls_asn2err (result
);
1133 _gnutls_str_cpy (root
, sizeof (root
), where
);
1134 _gnutls_str_cat (root
, sizeof (root
), ".?LAST");
1137 _gnutls_x509_encode_and_write_attribute (KEY_ID_OID
, c2
, root
,
1139 element
[elem
].local_key_id
.
1142 element
[elem
].local_key_id
.
1151 if (bag
->element
[elem
].friendly_name
!= NULL
)
1157 /* Add a new Attribute
1159 result
= asn1_write_value (c2
, where
, "NEW", 1);
1160 if (result
!= ASN1_SUCCESS
)
1163 return _gnutls_asn2err (result
);
1166 /* convert name to BMPString
1168 size
= strlen (bag
->element
[elem
].friendly_name
) * 2;
1169 name
= gnutls_malloc (size
);
1174 return GNUTLS_E_MEMORY_ERROR
;
1177 p
= bag
->element
[elem
].friendly_name
;
1178 for (i
= 0; i
< size
; i
+= 2)
1185 _gnutls_str_cpy (root
, sizeof (root
), where
);
1186 _gnutls_str_cat (root
, sizeof (root
), ".?LAST");
1189 _gnutls_x509_encode_and_write_attribute (FRIENDLY_NAME_OID
, c2
,
1190 root
, name
, size
, 1);
1205 /* Encodes the bag into a SafeContents structure, and puts the output in
1206 * the given datum. Enc is set to non (0) if the data are encrypted;
1209 _pkcs12_encode_safe_contents (gnutls_pkcs12_bag_t bag
, ASN1_TYPE
* contents
,
1212 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
1217 if (bag
->element
[0].type
== GNUTLS_BAG_ENCRYPTED
&& enc
)
1220 return 0; /* ENCRYPTED BAG, do nothing. */
1225 /* Step 1. Create the SEQUENCE.
1228 if ((result
= asn1_create_element
1229 (_gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
1230 &c2
)) != ASN1_SUCCESS
)
1233 result
= _gnutls_asn2err (result
);
1237 for (i
= 0; i
< bag
->bag_elements
; i
++)
1240 oid
= bag_to_oid (bag
->element
[i
].type
);
1247 result
= asn1_write_value (c2
, "", "NEW", 1);
1248 if (result
!= ASN1_SUCCESS
)
1251 result
= _gnutls_asn2err (result
);
1255 /* Copy the bag type.
1257 result
= asn1_write_value (c2
, "?LAST.bagId", oid
, 1);
1258 if (result
!= ASN1_SUCCESS
)
1261 result
= _gnutls_asn2err (result
);
1265 /* Set empty attributes
1267 result
= write_attributes (bag
, i
, c2
, "?LAST.bagAttributes");
1275 /* Copy the Bag Value
1278 if (bag
->element
[i
].type
== GNUTLS_BAG_CERTIFICATE
||
1279 bag
->element
[i
].type
== GNUTLS_BAG_SECRET
||
1280 bag
->element
[i
].type
== GNUTLS_BAG_CRL
)
1284 /* in that case encode it to a CertBag or
1289 _pkcs12_encode_crt_bag (bag
->element
[i
].type
,
1290 &bag
->element
[i
].data
, &tmp
);
1298 result
= _gnutls_x509_write_value (c2
, "?LAST.bagValue", &tmp
, 0);
1300 _gnutls_free_datum (&tmp
);
1306 result
= _gnutls_x509_write_value (c2
, "?LAST.bagValue",
1307 &bag
->element
[i
].data
, 0);
1318 /* Encode the data and copy them into the datum
1326 asn1_delete_structure (&c2
);
1331 /* Checks if the extra_certs contain certificates that may form a chain
1332 * with the first certificate in chain (it is expected that chain_len==1)
1333 * and appends those in the chain.
1335 static int make_chain(gnutls_x509_crt_t
**chain
, unsigned int *chain_len
,
1336 gnutls_x509_crt_t
**extra_certs
, unsigned int *extra_certs_len
)
1340 if (*chain_len
!= 1)
1341 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST
);
1344 while(i
<*extra_certs_len
)
1346 /* if it is an issuer but not a self-signed one */
1347 if (gnutls_x509_crt_check_issuer((*chain
)[*chain_len
- 1], (*extra_certs
)[i
]) != 0 &&
1348 gnutls_x509_crt_check_issuer((*extra_certs
)[i
], (*extra_certs
)[i
]) == 0)
1350 *chain
= gnutls_realloc (*chain
, sizeof((*chain
)[0]) *
1355 return GNUTLS_E_MEMORY_ERROR
;
1357 (*chain
)[*chain_len
- 1] = (*extra_certs
)[i
];
1359 (*extra_certs
)[i
] = (*extra_certs
)[*extra_certs_len
-1];
1360 (*extra_certs_len
)--;
1371 * gnutls_pkcs12_simple_parse:
1372 * @p12: the PKCS#12 blob.
1373 * @password: optional password used to decrypt PKCS#12 blob, bags and keys.
1374 * @key: a structure to store the parsed private key.
1375 * @chain: the corresponding to key certificate chain
1376 * @chain_len: will be updated with the number of additional
1377 * @extra_certs: optional pointer to receive an array of additional
1378 * certificates found in the PKCS#12 blob.
1379 * @extra_certs_len: will be updated with the number of additional
1381 * @crl: an optional structure to store the parsed CRL.
1382 * @flags: should be zero
1384 * This function parses a PKCS#12 blob in @p12blob and extracts the
1385 * private key, the corresponding certificate chain, and any additional
1386 * certificates and a CRL.
1388 * The @extra_certs_ret and @extra_certs_ret_len parameters are optional
1389 * and both may be set to %NULL. If either is non-%NULL, then both must
1392 * MAC:ed PKCS#12 files are supported. Encrypted PKCS#12 bags are
1393 * supported. Encrypted PKCS#8 private keys are supported. However,
1394 * only password based security, and the same password for all
1395 * operations, are supported.
1397 * The private keys may be RSA PKCS#1 or DSA private keys encoded in
1400 * PKCS#12 file may contain many keys and/or certificates, and there
1401 * is no way to identify which key/certificate pair you want. You
1402 * should make sure the PKCS#12 file only contain one key/certificate
1403 * pair and/or one CRL.
1405 * It is believed that the limitations of this function is acceptable
1406 * for most usage, and that any more flexibility would introduce
1407 * complexity that would make it harder to use this functionality at
1410 * If the provided structure has encrypted fields but no password
1411 * is provided then this function returns %GNUTLS_E_DECRYPTION_FAILED.
1413 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1414 * negative error value.
1419 gnutls_pkcs12_simple_parse (gnutls_pkcs12_t p12
,
1420 const char *password
,
1421 gnutls_x509_privkey_t
* key
,
1422 gnutls_x509_crt_t
** chain
,
1423 unsigned int * chain_len
,
1424 gnutls_x509_crt_t
** extra_certs
,
1425 unsigned int * extra_certs_len
,
1426 gnutls_x509_crl_t
* crl
,
1429 gnutls_pkcs12_bag_t bag
= NULL
;
1430 gnutls_x509_crt_t
*_extra_certs
= NULL
;
1431 unsigned int _extra_certs_len
= 0;
1432 gnutls_x509_crt_t
*_chain
= NULL
;
1433 unsigned int _chain_len
= 0;
1436 size_t cert_id_size
= 0;
1437 size_t key_id_size
= 0;
1438 uint8_t cert_id
[20];
1448 /* find the first private key */
1451 int elements_in_bag
;
1454 ret
= gnutls_pkcs12_bag_init (&bag
);
1462 ret
= gnutls_pkcs12_get_bag (p12
, idx
, bag
);
1463 if (ret
== GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
)
1471 ret
= gnutls_pkcs12_bag_get_type (bag
, 0);
1478 if (ret
== GNUTLS_BAG_ENCRYPTED
)
1480 if (password
== NULL
)
1482 ret
= gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED
);
1486 ret
= gnutls_pkcs12_bag_decrypt (bag
, password
);
1494 elements_in_bag
= gnutls_pkcs12_bag_get_count (bag
);
1495 if (elements_in_bag
< 0)
1501 for (i
= 0; i
< elements_in_bag
; i
++)
1504 gnutls_datum_t data
;
1506 type
= gnutls_pkcs12_bag_get_type (bag
, i
);
1513 ret
= gnutls_pkcs12_bag_get_data (bag
, i
, &data
);
1522 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
:
1523 if (password
== NULL
)
1525 ret
= gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED
);
1529 case GNUTLS_BAG_PKCS8_KEY
:
1530 if (*key
!= NULL
) /* too simple to continue */
1536 ret
= gnutls_x509_privkey_init (key
);
1543 ret
= gnutls_x509_privkey_import_pkcs8
1544 (*key
, &data
, GNUTLS_X509_FMT_DER
, password
,
1545 type
== GNUTLS_BAG_PKCS8_KEY
? GNUTLS_PKCS_PLAIN
: 0);
1549 gnutls_x509_privkey_deinit (*key
);
1553 key_id_size
= sizeof (key_id
);
1555 gnutls_x509_privkey_get_key_id (*key
, 0, key_id
,
1560 gnutls_x509_privkey_deinit (*key
);
1564 privkey_ok
= 1; /* break */
1572 gnutls_pkcs12_bag_deinit (bag
);
1574 if (privkey_ok
!= 0) /* private key was found */
1578 if (privkey_ok
== 0) /* no private key */
1581 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1584 /* now find the corresponding certificate
1590 int elements_in_bag
;
1593 ret
= gnutls_pkcs12_bag_init (&bag
);
1601 ret
= gnutls_pkcs12_get_bag (p12
, idx
, bag
);
1602 if (ret
== GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
)
1610 ret
= gnutls_pkcs12_bag_get_type (bag
, 0);
1617 if (ret
== GNUTLS_BAG_ENCRYPTED
)
1619 ret
= gnutls_pkcs12_bag_decrypt (bag
, password
);
1627 elements_in_bag
= gnutls_pkcs12_bag_get_count (bag
);
1628 if (elements_in_bag
< 0)
1634 for (i
= 0; i
< elements_in_bag
; i
++)
1637 gnutls_datum_t data
;
1638 gnutls_x509_crt_t this_cert
;
1640 type
= gnutls_pkcs12_bag_get_type (bag
, i
);
1647 ret
= gnutls_pkcs12_bag_get_data (bag
, i
, &data
);
1656 case GNUTLS_BAG_CERTIFICATE
:
1657 ret
= gnutls_x509_crt_init (&this_cert
);
1665 gnutls_x509_crt_import (this_cert
, &data
, GNUTLS_X509_FMT_DER
);
1669 gnutls_x509_crt_deinit (this_cert
);
1673 /* check if the key id match */
1674 cert_id_size
= sizeof (cert_id
);
1676 gnutls_x509_crt_get_key_id (this_cert
, 0, cert_id
, &cert_id_size
);
1680 gnutls_x509_crt_deinit (this_cert
);
1684 if (memcmp (cert_id
, key_id
, cert_id_size
) != 0)
1685 { /* they don't match - skip the certificate */
1688 _extra_certs
= gnutls_realloc (_extra_certs
,
1689 sizeof(_extra_certs
[0]) *
1690 ++_extra_certs_len
);
1694 ret
= GNUTLS_E_MEMORY_ERROR
;
1697 _extra_certs
[_extra_certs_len
- 1] = this_cert
;
1702 gnutls_x509_crt_deinit (this_cert
);
1707 if (_chain_len
== 0)
1709 _chain
= gnutls_malloc (sizeof(_chain
[0]) * (++_chain_len
));
1713 ret
= GNUTLS_E_MEMORY_ERROR
;
1716 _chain
[_chain_len
- 1] = this_cert
;
1721 gnutls_x509_crt_deinit (this_cert
);
1726 case GNUTLS_BAG_CRL
:
1727 if (crl
== NULL
|| *crl
!= NULL
)
1733 ret
= gnutls_x509_crl_init (crl
);
1740 ret
= gnutls_x509_crl_import (*crl
, &data
, GNUTLS_X509_FMT_DER
);
1744 gnutls_x509_crl_deinit (*crl
);
1749 case GNUTLS_BAG_ENCRYPTED
:
1750 /* XXX Bother to recurse one level down? Unlikely to
1751 use the same password anyway. */
1752 case GNUTLS_BAG_EMPTY
:
1759 gnutls_pkcs12_bag_deinit (bag
);
1762 if (_chain_len
!= 1)
1764 ret
= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1768 ret
= make_chain(&_chain
, &_chain_len
, &_extra_certs
, &_extra_certs_len
);
1779 gnutls_pkcs12_bag_deinit (bag
);
1784 gnutls_x509_privkey_deinit(*key
);
1785 if (_extra_certs_len
&& _extra_certs
!= NULL
)
1787 for (i
= 0; i
< _extra_certs_len
; i
++)
1788 gnutls_x509_crt_deinit(_extra_certs
[i
]);
1789 gnutls_free(_extra_certs
);
1791 if (_chain_len
&& chain
!= NULL
)
1793 for (i
= 0; i
< _chain_len
; i
++)
1794 gnutls_x509_crt_deinit(_chain
[i
]);
1795 gnutls_free(_chain
);
1801 if (extra_certs
&& _extra_certs_len
> 0)
1803 *extra_certs
= _extra_certs
;
1804 *extra_certs_len
= _extra_certs_len
;
1810 *extra_certs
= NULL
;
1811 *extra_certs_len
= 0;
1813 for (i
= 0; i
< _extra_certs_len
; i
++)
1814 gnutls_x509_crt_deinit(_extra_certs
[i
]);
1815 gnutls_free(_extra_certs
);
1819 *chain_len
= _chain_len
;