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 Bag packet parsing.
26 #include <gnutls_int.h>
28 #include <gnutls_datum.h>
29 #include <gnutls_global.h>
30 #include <gnutls_errors.h>
35 * gnutls_pkcs12_bag_init:
36 * @bag: The structure to be initialized
38 * This function will initialize a PKCS12 bag structure. PKCS12 Bags
39 * usually contain private keys, lists of X.509 Certificates and X.509
40 * Certificate revocation lists.
42 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
43 * negative error value.
46 gnutls_pkcs12_bag_init (gnutls_pkcs12_bag_t
* bag
)
48 *bag
= gnutls_calloc (1, sizeof (gnutls_pkcs12_bag_int
));
52 return 0; /* success */
54 return GNUTLS_E_MEMORY_ERROR
;
58 _pkcs12_bag_free_data (gnutls_pkcs12_bag_t bag
)
62 for (i
= 0; i
< bag
->bag_elements
; i
++)
64 _gnutls_free_datum (&bag
->element
[i
].data
);
65 _gnutls_free_datum (&bag
->element
[i
].local_key_id
);
66 gnutls_free (bag
->element
[i
].friendly_name
);
67 bag
->element
[i
].friendly_name
= NULL
;
68 bag
->element
[i
].type
= 0;
75 * gnutls_pkcs12_bag_deinit:
76 * @bag: The structure to be initialized
78 * This function will deinitialize a PKCS12 Bag structure.
81 gnutls_pkcs12_bag_deinit (gnutls_pkcs12_bag_t bag
)
86 _pkcs12_bag_free_data (bag
);
92 * gnutls_pkcs12_bag_get_type:
94 * @indx: The element of the bag to get the type
96 * This function will return the bag's type.
98 * Returns: One of the #gnutls_pkcs12_bag_type_t enumerations.
100 gnutls_pkcs12_bag_type_t
101 gnutls_pkcs12_bag_get_type (gnutls_pkcs12_bag_t bag
, int indx
)
106 return GNUTLS_E_INVALID_REQUEST
;
109 if (indx
>= bag
->bag_elements
)
110 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
111 return bag
->element
[indx
].type
;
115 * gnutls_pkcs12_bag_get_count:
118 * This function will return the number of the elements withing the bag.
120 * Returns: Number of elements in bag, or an negative error code on
124 gnutls_pkcs12_bag_get_count (gnutls_pkcs12_bag_t bag
)
129 return GNUTLS_E_INVALID_REQUEST
;
132 return bag
->bag_elements
;
136 * gnutls_pkcs12_bag_get_data:
138 * @indx: The element of the bag to get the data from
139 * @data: where the bag's data will be. Should be treated as constant.
141 * This function will return the bag's data. The data is a constant
142 * that is stored into the bag. Should not be accessed after the bag
145 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
146 * negative error value.
149 gnutls_pkcs12_bag_get_data (gnutls_pkcs12_bag_t bag
, int indx
,
150 gnutls_datum_t
* data
)
155 return GNUTLS_E_INVALID_REQUEST
;
158 if (indx
>= bag
->bag_elements
)
159 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
161 data
->data
= bag
->element
[indx
].data
.data
;
162 data
->size
= bag
->element
[indx
].data
.size
;
167 #define X509_CERT_OID "1.2.840.113549.1.9.22.1"
168 #define X509_CRL_OID "1.2.840.113549.1.9.23.1"
169 #define RANDOM_NONCE_OID "1.2.840.113549.1.9.25.3"
172 _pkcs12_decode_crt_bag (gnutls_pkcs12_bag_type_t type
,
173 const gnutls_datum_t
* in
, gnutls_datum_t
* out
)
176 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
180 case GNUTLS_BAG_CERTIFICATE
:
181 if ((ret
= asn1_create_element (_gnutls_get_pkix (),
182 "PKIX1.pkcs-12-CertBag",
183 &c2
)) != ASN1_SUCCESS
)
186 ret
= _gnutls_asn2err (ret
);
190 ret
= asn1_der_decoding (&c2
, in
->data
, in
->size
, NULL
);
191 if (ret
!= ASN1_SUCCESS
)
194 ret
= _gnutls_asn2err (ret
);
198 ret
= _gnutls_x509_read_string (c2
, "certValue", out
, RV_OCTET_STRING
);
207 if ((ret
= asn1_create_element (_gnutls_get_pkix (),
208 "PKIX1.pkcs-12-CRLBag",
209 &c2
)) != ASN1_SUCCESS
)
212 ret
= _gnutls_asn2err (ret
);
216 ret
= asn1_der_decoding (&c2
, in
->data
, in
->size
, NULL
);
217 if (ret
!= ASN1_SUCCESS
)
220 ret
= _gnutls_asn2err (ret
);
224 ret
= _gnutls_x509_read_string (c2
, "crlValue", out
, RV_OCTET_STRING
);
232 case GNUTLS_BAG_SECRET
:
233 if ((ret
= asn1_create_element (_gnutls_get_pkix (),
234 "PKIX1.pkcs-12-SecretBag",
235 &c2
)) != ASN1_SUCCESS
)
238 ret
= _gnutls_asn2err (ret
);
242 ret
= asn1_der_decoding (&c2
, in
->data
, in
->size
, NULL
);
243 if (ret
!= ASN1_SUCCESS
)
246 ret
= _gnutls_asn2err (ret
);
250 ret
= _gnutls_x509_read_string (c2
, "secretValue", out
, RV_OCTET_STRING
);
260 asn1_delete_structure (&c2
);
261 return GNUTLS_E_UNIMPLEMENTED_FEATURE
;
264 asn1_delete_structure (&c2
);
271 asn1_delete_structure (&c2
);
277 _pkcs12_encode_crt_bag (gnutls_pkcs12_bag_type_t type
,
278 const gnutls_datum_t
* raw
, gnutls_datum_t
* out
)
281 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
285 case GNUTLS_BAG_CERTIFICATE
:
286 if ((ret
= asn1_create_element (_gnutls_get_pkix (),
287 "PKIX1.pkcs-12-CertBag",
288 &c2
)) != ASN1_SUCCESS
)
291 ret
= _gnutls_asn2err (ret
);
295 ret
= asn1_write_value (c2
, "certId", X509_CERT_OID
, 1);
296 if (ret
!= ASN1_SUCCESS
)
299 ret
= _gnutls_asn2err (ret
);
303 ret
= _gnutls_x509_write_value (c2
, "certValue", raw
, 1);
312 if ((ret
= asn1_create_element (_gnutls_get_pkix (),
313 "PKIX1.pkcs-12-CRLBag",
314 &c2
)) != ASN1_SUCCESS
)
317 ret
= _gnutls_asn2err (ret
);
321 ret
= asn1_write_value (c2
, "crlId", X509_CRL_OID
, 1);
322 if (ret
!= ASN1_SUCCESS
)
325 ret
= _gnutls_asn2err (ret
);
329 ret
= _gnutls_x509_write_value (c2
, "crlValue", raw
, 1);
337 case GNUTLS_BAG_SECRET
:
338 if ((ret
= asn1_create_element (_gnutls_get_pkix (),
339 "PKIX1.pkcs-12-SecretBag",
340 &c2
)) != ASN1_SUCCESS
)
343 ret
= _gnutls_asn2err (ret
);
347 ret
= asn1_write_value (c2
, "secretTypeId", RANDOM_NONCE_OID
, 1);
348 if (ret
!= ASN1_SUCCESS
)
351 ret
= _gnutls_asn2err (ret
);
355 ret
= _gnutls_x509_write_value (c2
, "secretValue", raw
, 1);
365 asn1_delete_structure (&c2
);
366 return GNUTLS_E_UNIMPLEMENTED_FEATURE
;
369 ret
= _gnutls_x509_der_encode (c2
, "", out
, 0);
377 asn1_delete_structure (&c2
);
384 asn1_delete_structure (&c2
);
390 * gnutls_pkcs12_bag_set_data:
392 * @type: The data's type
393 * @data: the data to be copied.
395 * This function will insert the given data of the given type into
398 * Returns: the index of the added bag on success, or a negative
402 gnutls_pkcs12_bag_set_data (gnutls_pkcs12_bag_t bag
,
403 gnutls_pkcs12_bag_type_t type
,
404 const gnutls_datum_t
* data
)
410 return GNUTLS_E_INVALID_REQUEST
;
413 if (bag
->bag_elements
== MAX_BAG_ELEMENTS
- 1)
417 return GNUTLS_E_MEMORY_ERROR
;
420 if (bag
->bag_elements
== 1)
422 /* A bag with a key or an encrypted bag, must have
426 if (bag
->element
[0].type
== GNUTLS_BAG_PKCS8_KEY
||
427 bag
->element
[0].type
== GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
||
428 bag
->element
[0].type
== GNUTLS_BAG_ENCRYPTED
)
431 return GNUTLS_E_INVALID_REQUEST
;
436 _gnutls_set_datum (&bag
->element
[bag
->bag_elements
].data
,
437 data
->data
, data
->size
);
445 bag
->element
[bag
->bag_elements
].type
= type
;
449 return bag
->bag_elements
- 1;
453 * gnutls_pkcs12_bag_set_crt:
455 * @crt: the certificate to be copied.
457 * This function will insert the given certificate into the
458 * bag. This is just a wrapper over gnutls_pkcs12_bag_set_data().
460 * Returns: the index of the added bag on success, or a negative
464 gnutls_pkcs12_bag_set_crt (gnutls_pkcs12_bag_t bag
, gnutls_x509_crt_t crt
)
472 return GNUTLS_E_INVALID_REQUEST
;
475 ret
= _gnutls_x509_der_encode (crt
->cert
, "", &data
, 0);
482 ret
= gnutls_pkcs12_bag_set_data (bag
, GNUTLS_BAG_CERTIFICATE
, &data
);
484 _gnutls_free_datum (&data
);
490 * gnutls_pkcs12_bag_set_crl:
492 * @crl: the CRL to be copied.
494 * This function will insert the given CRL into the
495 * bag. This is just a wrapper over gnutls_pkcs12_bag_set_data().
497 * Returns: the index of the added bag on success, or a negative error code
501 gnutls_pkcs12_bag_set_crl (gnutls_pkcs12_bag_t bag
, gnutls_x509_crl_t crl
)
510 return GNUTLS_E_INVALID_REQUEST
;
513 ret
= _gnutls_x509_der_encode (crl
->crl
, "", &data
, 0);
520 ret
= gnutls_pkcs12_bag_set_data (bag
, GNUTLS_BAG_CRL
, &data
);
522 _gnutls_free_datum (&data
);
528 * gnutls_pkcs12_bag_set_key_id:
530 * @indx: The bag's element to add the id
533 * This function will add the given key ID, to the specified, by the
534 * index, bag element. The key ID will be encoded as a 'Local key
535 * identifier' bag attribute, which is usually used to distinguish
536 * the local private key and the certificate pair.
538 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
539 * negative error value. or a negative error code on error.
542 gnutls_pkcs12_bag_set_key_id (gnutls_pkcs12_bag_t bag
, int indx
,
543 const gnutls_datum_t
* id
)
551 return GNUTLS_E_INVALID_REQUEST
;
554 if (indx
> bag
->bag_elements
- 1)
557 return GNUTLS_E_INVALID_REQUEST
;
560 ret
= _gnutls_set_datum (&bag
->element
[indx
].local_key_id
,
573 * gnutls_pkcs12_bag_get_key_id:
575 * @indx: The bag's element to add the id
576 * @id: where the ID will be copied (to be treated as const)
578 * This function will return the key ID, of the specified bag element.
579 * The key ID is usually used to distinguish the local private key and
580 * the certificate pair.
582 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
583 * negative error value. or a negative error code on error.
586 gnutls_pkcs12_bag_get_key_id (gnutls_pkcs12_bag_t bag
, int indx
,
592 return GNUTLS_E_INVALID_REQUEST
;
595 if (indx
> bag
->bag_elements
- 1)
598 return GNUTLS_E_INVALID_REQUEST
;
601 id
->data
= bag
->element
[indx
].local_key_id
.data
;
602 id
->size
= bag
->element
[indx
].local_key_id
.size
;
608 * gnutls_pkcs12_bag_get_friendly_name:
610 * @indx: The bag's element to add the id
611 * @name: will hold a pointer to the name (to be treated as const)
613 * This function will return the friendly name, of the specified bag
614 * element. The key ID is usually used to distinguish the local
615 * private key and the certificate pair.
617 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
618 * negative error value. or a negative error code on error.
621 gnutls_pkcs12_bag_get_friendly_name (gnutls_pkcs12_bag_t bag
, int indx
,
627 return GNUTLS_E_INVALID_REQUEST
;
630 if (indx
> bag
->bag_elements
- 1)
633 return GNUTLS_E_INVALID_REQUEST
;
636 *name
= bag
->element
[indx
].friendly_name
;
643 * gnutls_pkcs12_bag_set_friendly_name:
645 * @indx: The bag's element to add the id
648 * This function will add the given key friendly name, to the
649 * specified, by the index, bag element. The name will be encoded as
650 * a 'Friendly name' bag attribute, which is usually used to set a
651 * user name to the local private key and the certificate pair.
653 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
654 * negative error value. or a negative error code on error.
657 gnutls_pkcs12_bag_set_friendly_name (gnutls_pkcs12_bag_t bag
, int indx
,
663 return GNUTLS_E_INVALID_REQUEST
;
666 if (indx
> bag
->bag_elements
- 1)
669 return GNUTLS_E_INVALID_REQUEST
;
672 bag
->element
[indx
].friendly_name
= gnutls_strdup (name
);
677 return GNUTLS_E_MEMORY_ERROR
;
685 * gnutls_pkcs12_bag_decrypt:
687 * @pass: The password used for encryption, must be ASCII.
689 * This function will decrypt the given encrypted bag and return 0 on
692 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
693 * otherwise a negative error code is returned.
696 gnutls_pkcs12_bag_decrypt (gnutls_pkcs12_bag_t bag
, const char *pass
)
704 return GNUTLS_E_INVALID_REQUEST
;
707 if (bag
->element
[0].type
!= GNUTLS_BAG_ENCRYPTED
)
710 return GNUTLS_E_INVALID_REQUEST
;
713 ret
= _gnutls_pkcs7_decrypt_data (&bag
->element
[0].data
, pass
, &dec
);
721 /* decryption succeeded. Now decode the SafeContents
722 * stuff, and parse it.
725 _gnutls_free_datum (&bag
->element
[0].data
);
727 ret
= _pkcs12_decode_safe_contents (&dec
, bag
);
729 _gnutls_free_datum (&dec
);
741 * gnutls_pkcs12_bag_encrypt:
743 * @pass: The password used for encryption, must be ASCII
744 * @flags: should be one of #gnutls_pkcs_encrypt_flags_t elements bitwise or'd
746 * This function will encrypt the given bag.
748 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
749 * otherwise a negative error code is returned.
752 gnutls_pkcs12_bag_encrypt (gnutls_pkcs12_bag_t bag
, const char *pass
,
756 ASN1_TYPE safe_cont
= ASN1_TYPE_EMPTY
;
757 gnutls_datum_t der
= { NULL
, 0 };
758 gnutls_datum_t enc
= { NULL
, 0 };
764 return GNUTLS_E_INVALID_REQUEST
;
767 if (bag
->element
[0].type
== GNUTLS_BAG_ENCRYPTED
)
770 return GNUTLS_E_INVALID_REQUEST
;
773 /* Encode the whole bag to a safe contents
776 ret
= _pkcs12_encode_safe_contents (bag
, &safe_cont
, NULL
);
783 /* DER encode the SafeContents.
785 ret
= _gnutls_x509_der_encode (safe_cont
, "", &der
, 0);
787 asn1_delete_structure (&safe_cont
);
795 if (flags
& GNUTLS_PKCS_PLAIN
)
798 return GNUTLS_E_INVALID_REQUEST
;
801 id
= _gnutls_pkcs_flags_to_schema (flags
);
805 ret
= _gnutls_pkcs7_encrypt_data (id
, &der
, pass
, &enc
);
807 _gnutls_free_datum (&der
);
815 /* encryption succeeded.
818 _pkcs12_bag_free_data (bag
);
820 bag
->element
[0].type
= GNUTLS_BAG_ENCRYPTED
;
821 bag
->element
[0].data
= enc
;
823 bag
->bag_elements
= 1;