2 * Copyright (C) 2003, 2004, 2005, 2008, 2009, 2010 Free Software
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
26 /* Functions that relate on PKCS12 Bag packet parsing.
29 #include <gnutls_int.h>
33 #include <gnutls_datum.h>
34 #include <gnutls_global.h>
35 #include <gnutls_errors.h>
40 * gnutls_pkcs12_bag_init:
41 * @bag: The structure to be initialized
43 * This function will initialize a PKCS12 bag structure. PKCS12 Bags
44 * usually contain private keys, lists of X.509 Certificates and X.509
45 * Certificate revocation lists.
47 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
48 * negative error value.
51 gnutls_pkcs12_bag_init (gnutls_pkcs12_bag_t * bag)
53 *bag = gnutls_calloc (1, sizeof (gnutls_pkcs12_bag_int));
57 return 0; /* success */
59 return GNUTLS_E_MEMORY_ERROR;
63 _pkcs12_bag_free_data (gnutls_pkcs12_bag_t bag)
67 for (i = 0; i < bag->bag_elements; i++)
69 _gnutls_free_datum (&bag->element[i].data);
70 _gnutls_free_datum (&bag->element[i].local_key_id);
71 gnutls_free (bag->element[i].friendly_name);
72 bag->element[i].friendly_name = NULL;
73 bag->element[i].type = 0;
80 * gnutls_pkcs12_bag_deinit:
81 * @bag: The structure to be initialized
83 * This function will deinitialize a PKCS12 Bag structure.
86 gnutls_pkcs12_bag_deinit (gnutls_pkcs12_bag_t bag)
91 _pkcs12_bag_free_data (bag);
97 * gnutls_pkcs12_bag_get_type:
99 * @indx: The element of the bag to get the type
101 * This function will return the bag's type.
103 * Returns: One of the #gnutls_pkcs12_bag_type_t enumerations.
105 gnutls_pkcs12_bag_type_t
106 gnutls_pkcs12_bag_get_type (gnutls_pkcs12_bag_t bag, int indx)
111 return GNUTLS_E_INVALID_REQUEST;
114 if (indx >= bag->bag_elements)
115 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
116 return bag->element[indx].type;
120 * gnutls_pkcs12_bag_get_count:
123 * This function will return the number of the elements withing the bag.
125 * Returns: Number of elements in bag, or an negative error code on
129 gnutls_pkcs12_bag_get_count (gnutls_pkcs12_bag_t bag)
134 return GNUTLS_E_INVALID_REQUEST;
137 return bag->bag_elements;
141 * gnutls_pkcs12_bag_get_data:
143 * @indx: The element of the bag to get the data from
144 * @data: where the bag's data will be. Should be treated as constant.
146 * This function will return the bag's data. The data is a constant
147 * that is stored into the bag. Should not be accessed after the bag
150 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
151 * negative error value.
154 gnutls_pkcs12_bag_get_data (gnutls_pkcs12_bag_t bag, int indx,
155 gnutls_datum_t * data)
160 return GNUTLS_E_INVALID_REQUEST;
163 if (indx >= bag->bag_elements)
164 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
166 data->data = bag->element[indx].data.data;
167 data->size = bag->element[indx].data.size;
172 #define X509_CERT_OID "1.2.840.113549.1.9.22.1"
173 #define X509_CRL_OID "1.2.840.113549.1.9.23.1"
174 #define RANDOM_NONCE_OID "1.2.840.113549.1.9.25.3"
177 _pkcs12_decode_crt_bag (gnutls_pkcs12_bag_type_t type,
178 const gnutls_datum_t * in, gnutls_datum_t * out)
181 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
185 case GNUTLS_BAG_CERTIFICATE:
186 if ((ret = asn1_create_element (_gnutls_get_pkix (),
187 "PKIX1.pkcs-12-CertBag",
188 &c2)) != ASN1_SUCCESS)
191 ret = _gnutls_asn2err (ret);
195 ret = asn1_der_decoding (&c2, in->data, in->size, NULL);
196 if (ret != ASN1_SUCCESS)
199 ret = _gnutls_asn2err (ret);
203 ret = _gnutls_x509_read_value (c2, "certValue", out, 1);
212 if ((ret = asn1_create_element (_gnutls_get_pkix (),
213 "PKIX1.pkcs-12-CRLBag",
214 &c2)) != ASN1_SUCCESS)
217 ret = _gnutls_asn2err (ret);
221 ret = asn1_der_decoding (&c2, in->data, in->size, NULL);
222 if (ret != ASN1_SUCCESS)
225 ret = _gnutls_asn2err (ret);
229 ret = _gnutls_x509_read_value (c2, "crlValue", out, 1);
237 case GNUTLS_BAG_SECRET:
238 if ((ret = asn1_create_element (_gnutls_get_pkix (),
239 "PKIX1.pkcs-12-SecretBag",
240 &c2)) != ASN1_SUCCESS)
243 ret = _gnutls_asn2err (ret);
247 ret = asn1_der_decoding (&c2, in->data, in->size, NULL);
248 if (ret != ASN1_SUCCESS)
251 ret = _gnutls_asn2err (ret);
255 ret = _gnutls_x509_read_value (c2, "secretValue", out, 1);
265 asn1_delete_structure (&c2);
266 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
269 asn1_delete_structure (&c2);
276 asn1_delete_structure (&c2);
282 _pkcs12_encode_crt_bag (gnutls_pkcs12_bag_type_t type,
283 const gnutls_datum_t * raw, gnutls_datum_t * out)
286 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
290 case GNUTLS_BAG_CERTIFICATE:
291 if ((ret = asn1_create_element (_gnutls_get_pkix (),
292 "PKIX1.pkcs-12-CertBag",
293 &c2)) != ASN1_SUCCESS)
296 ret = _gnutls_asn2err (ret);
300 ret = asn1_write_value (c2, "certId", X509_CERT_OID, 1);
301 if (ret != ASN1_SUCCESS)
304 ret = _gnutls_asn2err (ret);
308 ret = _gnutls_x509_write_value (c2, "certValue", raw, 1);
317 if ((ret = asn1_create_element (_gnutls_get_pkix (),
318 "PKIX1.pkcs-12-CRLBag",
319 &c2)) != ASN1_SUCCESS)
322 ret = _gnutls_asn2err (ret);
326 ret = asn1_write_value (c2, "crlId", X509_CRL_OID, 1);
327 if (ret != ASN1_SUCCESS)
330 ret = _gnutls_asn2err (ret);
334 ret = _gnutls_x509_write_value (c2, "crlValue", raw, 1);
342 case GNUTLS_BAG_SECRET:
343 if ((ret = asn1_create_element (_gnutls_get_pkix (),
344 "PKIX1.pkcs-12-SecretBag",
345 &c2)) != ASN1_SUCCESS)
348 ret = _gnutls_asn2err (ret);
352 ret = asn1_write_value (c2, "secretTypeId", RANDOM_NONCE_OID, 1);
353 if (ret != ASN1_SUCCESS)
356 ret = _gnutls_asn2err (ret);
360 ret = _gnutls_x509_write_value (c2, "secretValue", raw, 1);
370 asn1_delete_structure (&c2);
371 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
374 ret = _gnutls_x509_der_encode (c2, "", out, 0);
382 asn1_delete_structure (&c2);
389 asn1_delete_structure (&c2);
395 * gnutls_pkcs12_bag_set_data:
397 * @type: The data's type
398 * @data: the data to be copied.
400 * This function will insert the given data of the given type into
403 * Returns: the index of the added bag on success, or a negative
407 gnutls_pkcs12_bag_set_data (gnutls_pkcs12_bag_t bag,
408 gnutls_pkcs12_bag_type_t type,
409 const gnutls_datum_t * data)
415 return GNUTLS_E_INVALID_REQUEST;
418 if (bag->bag_elements == MAX_BAG_ELEMENTS - 1)
422 return GNUTLS_E_MEMORY_ERROR;
425 if (bag->bag_elements == 1)
427 /* A bag with a key or an encrypted bag, must have
431 if (bag->element[0].type == GNUTLS_BAG_PKCS8_KEY ||
432 bag->element[0].type == GNUTLS_BAG_PKCS8_ENCRYPTED_KEY ||
433 bag->element[0].type == GNUTLS_BAG_ENCRYPTED)
436 return GNUTLS_E_INVALID_REQUEST;
441 _gnutls_set_datum (&bag->element[bag->bag_elements].data,
442 data->data, data->size);
450 bag->element[bag->bag_elements].type = type;
454 return bag->bag_elements - 1;
458 * gnutls_pkcs12_bag_set_crt:
460 * @crt: the certificate to be copied.
462 * This function will insert the given certificate into the
463 * bag. This is just a wrapper over gnutls_pkcs12_bag_set_data().
465 * Returns: the index of the added bag on success, or a negative
469 gnutls_pkcs12_bag_set_crt (gnutls_pkcs12_bag_t bag, gnutls_x509_crt_t crt)
477 return GNUTLS_E_INVALID_REQUEST;
480 ret = _gnutls_x509_der_encode (crt->cert, "", &data, 0);
487 ret = gnutls_pkcs12_bag_set_data (bag, GNUTLS_BAG_CERTIFICATE, &data);
489 _gnutls_free_datum (&data);
495 * gnutls_pkcs12_bag_set_crl:
497 * @crl: the CRL to be copied.
499 * This function will insert the given CRL into the
500 * bag. This is just a wrapper over gnutls_pkcs12_bag_set_data().
502 * Returns: the index of the added bag on success, or a negative value
506 gnutls_pkcs12_bag_set_crl (gnutls_pkcs12_bag_t bag, gnutls_x509_crl_t crl)
515 return GNUTLS_E_INVALID_REQUEST;
518 ret = _gnutls_x509_der_encode (crl->crl, "", &data, 0);
525 ret = gnutls_pkcs12_bag_set_data (bag, GNUTLS_BAG_CRL, &data);
527 _gnutls_free_datum (&data);
533 * gnutls_pkcs12_bag_set_key_id:
535 * @indx: The bag's element to add the id
538 * This function will add the given key ID, to the specified, by the
539 * index, bag element. The key ID will be encoded as a 'Local key
540 * identifier' bag attribute, which is usually used to distinguish
541 * the local private key and the certificate pair.
543 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
544 * negative error value. or a negative value on error.
547 gnutls_pkcs12_bag_set_key_id (gnutls_pkcs12_bag_t bag, int indx,
548 const gnutls_datum_t * id)
556 return GNUTLS_E_INVALID_REQUEST;
559 if (indx > bag->bag_elements - 1)
562 return GNUTLS_E_INVALID_REQUEST;
565 ret = _gnutls_set_datum (&bag->element[indx].local_key_id,
578 * gnutls_pkcs12_bag_get_key_id:
580 * @indx: The bag's element to add the id
581 * @id: where the ID will be copied (to be treated as const)
583 * This function will return the key ID, of the specified bag element.
584 * The key ID is usually used to distinguish the local private key and
585 * the certificate pair.
587 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
588 * negative error value. or a negative value on error.
591 gnutls_pkcs12_bag_get_key_id (gnutls_pkcs12_bag_t bag, int indx,
597 return GNUTLS_E_INVALID_REQUEST;
600 if (indx > bag->bag_elements - 1)
603 return GNUTLS_E_INVALID_REQUEST;
606 id->data = bag->element[indx].local_key_id.data;
607 id->size = bag->element[indx].local_key_id.size;
613 * gnutls_pkcs12_bag_get_friendly_name:
615 * @indx: The bag's element to add the id
616 * @name: will hold a pointer to the name (to be treated as const)
618 * This function will return the friendly name, of the specified bag
619 * element. The key ID is usually used to distinguish the local
620 * private key and the certificate pair.
622 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
623 * negative error value. or a negative value on error.
626 gnutls_pkcs12_bag_get_friendly_name (gnutls_pkcs12_bag_t bag, int indx,
632 return GNUTLS_E_INVALID_REQUEST;
635 if (indx > bag->bag_elements - 1)
638 return GNUTLS_E_INVALID_REQUEST;
641 *name = bag->element[indx].friendly_name;
648 * gnutls_pkcs12_bag_set_friendly_name:
650 * @indx: The bag's element to add the id
653 * This function will add the given key friendly name, to the
654 * specified, by the index, bag element. The name will be encoded as
655 * a 'Friendly name' bag attribute, which is usually used to set a
656 * user name to the local private key and the certificate pair.
658 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
659 * negative error value. or a negative value on error.
662 gnutls_pkcs12_bag_set_friendly_name (gnutls_pkcs12_bag_t bag, int indx,
668 return GNUTLS_E_INVALID_REQUEST;
671 if (indx > bag->bag_elements - 1)
674 return GNUTLS_E_INVALID_REQUEST;
677 bag->element[indx].friendly_name = gnutls_strdup (name);
682 return GNUTLS_E_MEMORY_ERROR;
690 * gnutls_pkcs12_bag_decrypt:
692 * @pass: The password used for encryption, must be ASCII.
694 * This function will decrypt the given encrypted bag and return 0 on
697 * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
698 * otherwise an error code is returned.
701 gnutls_pkcs12_bag_decrypt (gnutls_pkcs12_bag_t bag, const char *pass)
709 return GNUTLS_E_INVALID_REQUEST;
712 if (bag->element[0].type != GNUTLS_BAG_ENCRYPTED)
715 return GNUTLS_E_INVALID_REQUEST;
718 ret = _gnutls_pkcs7_decrypt_data (&bag->element[0].data, pass, &dec);
726 /* decryption succeeded. Now decode the SafeContents
727 * stuff, and parse it.
730 _gnutls_free_datum (&bag->element[0].data);
732 ret = _pkcs12_decode_safe_contents (&dec, bag);
734 _gnutls_free_datum (&dec);
746 * gnutls_pkcs12_bag_encrypt:
748 * @pass: The password used for encryption, must be ASCII
749 * @flags: should be one of #gnutls_pkcs_encrypt_flags_t elements bitwise or'd
751 * This function will encrypt the given bag.
753 * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
754 * otherwise an error code is returned.
757 gnutls_pkcs12_bag_encrypt (gnutls_pkcs12_bag_t bag, const char *pass,
761 ASN1_TYPE safe_cont = ASN1_TYPE_EMPTY;
762 gnutls_datum_t der = { NULL, 0 };
763 gnutls_datum_t enc = { NULL, 0 };
769 return GNUTLS_E_INVALID_REQUEST;
772 if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED)
775 return GNUTLS_E_INVALID_REQUEST;
778 /* Encode the whole bag to a safe contents
781 ret = _pkcs12_encode_safe_contents (bag, &safe_cont, NULL);
788 /* DER encode the SafeContents.
790 ret = _gnutls_x509_der_encode (safe_cont, "", &der, 0);
792 asn1_delete_structure (&safe_cont);
800 if (flags & GNUTLS_PKCS_PLAIN)
803 return GNUTLS_E_INVALID_REQUEST;
806 id = _gnutls_pkcs_flags_to_schema (flags);
810 ret = _gnutls_pkcs7_encrypt_data (id, &der, pass, &enc);
812 _gnutls_free_datum (&der);
820 /* encryption succeeded.
823 _pkcs12_bag_free_data (bag);
825 bag->element[0].type = GNUTLS_BAG_ENCRYPTED;
826 bag->element[0].data = enc;
828 bag->bag_elements = 1;
835 #endif /* ENABLE_PKI */