Use the new asn1_read_node_value()
[gnutls.git] / lib / x509 / pkcs12_bag.c
blob38d01e9c73a52994d756ae26a430f75a5b2d8fa5
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 Bag packet parsing.
26 #include <gnutls_int.h>
28 #include <gnutls_datum.h>
29 #include <gnutls_global.h>
30 #include <gnutls_errors.h>
31 #include <common.h>
32 #include "x509_int.h"
34 /**
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.
44 **/
45 int
46 gnutls_pkcs12_bag_init (gnutls_pkcs12_bag_t * bag)
48 *bag = gnutls_calloc (1, sizeof (gnutls_pkcs12_bag_int));
50 if (*bag)
52 return 0; /* success */
54 return GNUTLS_E_MEMORY_ERROR;
57 static inline void
58 _pkcs12_bag_free_data (gnutls_pkcs12_bag_t bag)
60 int i;
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;
74 /**
75 * gnutls_pkcs12_bag_deinit:
76 * @bag: The structure to be initialized
78 * This function will deinitialize a PKCS12 Bag structure.
79 **/
80 void
81 gnutls_pkcs12_bag_deinit (gnutls_pkcs12_bag_t bag)
83 if (!bag)
84 return;
86 _pkcs12_bag_free_data (bag);
88 gnutls_free (bag);
91 /**
92 * gnutls_pkcs12_bag_get_type:
93 * @bag: The bag
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.
99 **/
100 gnutls_pkcs12_bag_type_t
101 gnutls_pkcs12_bag_get_type (gnutls_pkcs12_bag_t bag, int indx)
103 if (bag == NULL)
105 gnutls_assert ();
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:
116 * @bag: The bag
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
121 * error.
124 gnutls_pkcs12_bag_get_count (gnutls_pkcs12_bag_t bag)
126 if (bag == NULL)
128 gnutls_assert ();
129 return GNUTLS_E_INVALID_REQUEST;
132 return bag->bag_elements;
136 * gnutls_pkcs12_bag_get_data:
137 * @bag: The bag
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
143 * is deleted.
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)
152 if (bag == NULL)
154 gnutls_assert ();
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;
164 return 0;
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)
175 int ret;
176 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
178 switch (type)
180 case GNUTLS_BAG_CERTIFICATE:
181 if ((ret = asn1_create_element (_gnutls_get_pkix (),
182 "PKIX1.pkcs-12-CertBag",
183 &c2)) != ASN1_SUCCESS)
185 gnutls_assert ();
186 ret = _gnutls_asn2err (ret);
187 goto cleanup;
190 ret = asn1_der_decoding (&c2, in->data, in->size, NULL);
191 if (ret != ASN1_SUCCESS)
193 gnutls_assert ();
194 ret = _gnutls_asn2err (ret);
195 goto cleanup;
198 ret = _gnutls_x509_read_value (c2, "certValue", out, 1);
199 if (ret < 0)
201 gnutls_assert ();
202 goto cleanup;
204 break;
206 case GNUTLS_BAG_CRL:
207 if ((ret = asn1_create_element (_gnutls_get_pkix (),
208 "PKIX1.pkcs-12-CRLBag",
209 &c2)) != ASN1_SUCCESS)
211 gnutls_assert ();
212 ret = _gnutls_asn2err (ret);
213 goto cleanup;
216 ret = asn1_der_decoding (&c2, in->data, in->size, NULL);
217 if (ret != ASN1_SUCCESS)
219 gnutls_assert ();
220 ret = _gnutls_asn2err (ret);
221 goto cleanup;
224 ret = _gnutls_x509_read_value (c2, "crlValue", out, 1);
225 if (ret < 0)
227 gnutls_assert ();
228 goto cleanup;
230 break;
232 case GNUTLS_BAG_SECRET:
233 if ((ret = asn1_create_element (_gnutls_get_pkix (),
234 "PKIX1.pkcs-12-SecretBag",
235 &c2)) != ASN1_SUCCESS)
237 gnutls_assert ();
238 ret = _gnutls_asn2err (ret);
239 goto cleanup;
242 ret = asn1_der_decoding (&c2, in->data, in->size, NULL);
243 if (ret != ASN1_SUCCESS)
245 gnutls_assert ();
246 ret = _gnutls_asn2err (ret);
247 goto cleanup;
250 ret = _gnutls_x509_read_value (c2, "secretValue", out, 1);
251 if (ret < 0)
253 gnutls_assert ();
254 goto cleanup;
256 break;
258 default:
259 gnutls_assert ();
260 asn1_delete_structure (&c2);
261 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
264 asn1_delete_structure (&c2);
266 return 0;
269 cleanup:
271 asn1_delete_structure (&c2);
272 return ret;
277 _pkcs12_encode_crt_bag (gnutls_pkcs12_bag_type_t type,
278 const gnutls_datum_t * raw, gnutls_datum_t * out)
280 int ret;
281 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
283 switch (type)
285 case GNUTLS_BAG_CERTIFICATE:
286 if ((ret = asn1_create_element (_gnutls_get_pkix (),
287 "PKIX1.pkcs-12-CertBag",
288 &c2)) != ASN1_SUCCESS)
290 gnutls_assert ();
291 ret = _gnutls_asn2err (ret);
292 goto cleanup;
295 ret = asn1_write_value (c2, "certId", X509_CERT_OID, 1);
296 if (ret != ASN1_SUCCESS)
298 gnutls_assert ();
299 ret = _gnutls_asn2err (ret);
300 goto cleanup;
303 ret = _gnutls_x509_write_value (c2, "certValue", raw, 1);
304 if (ret < 0)
306 gnutls_assert ();
307 goto cleanup;
309 break;
311 case GNUTLS_BAG_CRL:
312 if ((ret = asn1_create_element (_gnutls_get_pkix (),
313 "PKIX1.pkcs-12-CRLBag",
314 &c2)) != ASN1_SUCCESS)
316 gnutls_assert ();
317 ret = _gnutls_asn2err (ret);
318 goto cleanup;
321 ret = asn1_write_value (c2, "crlId", X509_CRL_OID, 1);
322 if (ret != ASN1_SUCCESS)
324 gnutls_assert ();
325 ret = _gnutls_asn2err (ret);
326 goto cleanup;
329 ret = _gnutls_x509_write_value (c2, "crlValue", raw, 1);
330 if (ret < 0)
332 gnutls_assert ();
333 goto cleanup;
335 break;
337 case GNUTLS_BAG_SECRET:
338 if ((ret = asn1_create_element (_gnutls_get_pkix (),
339 "PKIX1.pkcs-12-SecretBag",
340 &c2)) != ASN1_SUCCESS)
342 gnutls_assert ();
343 ret = _gnutls_asn2err (ret);
344 goto cleanup;
347 ret = asn1_write_value (c2, "secretTypeId", RANDOM_NONCE_OID, 1);
348 if (ret != ASN1_SUCCESS)
350 gnutls_assert ();
351 ret = _gnutls_asn2err (ret);
352 goto cleanup;
355 ret = _gnutls_x509_write_value (c2, "secretValue", raw, 1);
356 if (ret < 0)
358 gnutls_assert ();
359 goto cleanup;
361 break;
363 default:
364 gnutls_assert ();
365 asn1_delete_structure (&c2);
366 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
369 ret = _gnutls_x509_der_encode (c2, "", out, 0);
371 if (ret < 0)
373 gnutls_assert ();
374 goto cleanup;
377 asn1_delete_structure (&c2);
379 return 0;
382 cleanup:
384 asn1_delete_structure (&c2);
385 return ret;
390 * gnutls_pkcs12_bag_set_data:
391 * @bag: The bag
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
396 * the bag.
398 * Returns: the index of the added bag on success, or a negative
399 * value on error.
402 gnutls_pkcs12_bag_set_data (gnutls_pkcs12_bag_t bag,
403 gnutls_pkcs12_bag_type_t type,
404 const gnutls_datum_t * data)
406 int ret;
407 if (bag == NULL)
409 gnutls_assert ();
410 return GNUTLS_E_INVALID_REQUEST;
413 if (bag->bag_elements == MAX_BAG_ELEMENTS - 1)
415 gnutls_assert ();
416 /* bag is full */
417 return GNUTLS_E_MEMORY_ERROR;
420 if (bag->bag_elements == 1)
422 /* A bag with a key or an encrypted bag, must have
423 * only one element.
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)
430 gnutls_assert ();
431 return GNUTLS_E_INVALID_REQUEST;
435 ret =
436 _gnutls_set_datum (&bag->element[bag->bag_elements].data,
437 data->data, data->size);
439 if (ret < 0)
441 gnutls_assert ();
442 return ret;
445 bag->element[bag->bag_elements].type = type;
447 bag->bag_elements++;
449 return bag->bag_elements - 1;
453 * gnutls_pkcs12_bag_set_crt:
454 * @bag: The bag
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
461 * value on failure.
464 gnutls_pkcs12_bag_set_crt (gnutls_pkcs12_bag_t bag, gnutls_x509_crt_t crt)
466 int ret;
467 gnutls_datum_t data;
469 if (bag == NULL)
471 gnutls_assert ();
472 return GNUTLS_E_INVALID_REQUEST;
475 ret = _gnutls_x509_der_encode (crt->cert, "", &data, 0);
476 if (ret < 0)
478 gnutls_assert ();
479 return ret;
482 ret = gnutls_pkcs12_bag_set_data (bag, GNUTLS_BAG_CERTIFICATE, &data);
484 _gnutls_free_datum (&data);
486 return ret;
490 * gnutls_pkcs12_bag_set_crl:
491 * @bag: The bag
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
498 * on failure.
501 gnutls_pkcs12_bag_set_crl (gnutls_pkcs12_bag_t bag, gnutls_x509_crl_t crl)
503 int ret;
504 gnutls_datum_t data;
507 if (bag == NULL)
509 gnutls_assert ();
510 return GNUTLS_E_INVALID_REQUEST;
513 ret = _gnutls_x509_der_encode (crl->crl, "", &data, 0);
514 if (ret < 0)
516 gnutls_assert ();
517 return ret;
520 ret = gnutls_pkcs12_bag_set_data (bag, GNUTLS_BAG_CRL, &data);
522 _gnutls_free_datum (&data);
524 return ret;
528 * gnutls_pkcs12_bag_set_key_id:
529 * @bag: The bag
530 * @indx: The bag's element to add the id
531 * @id: 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)
545 int ret;
548 if (bag == NULL)
550 gnutls_assert ();
551 return GNUTLS_E_INVALID_REQUEST;
554 if (indx > bag->bag_elements - 1)
556 gnutls_assert ();
557 return GNUTLS_E_INVALID_REQUEST;
560 ret = _gnutls_set_datum (&bag->element[indx].local_key_id,
561 id->data, id->size);
563 if (ret < 0)
565 gnutls_assert ();
566 return ret;
569 return 0;
573 * gnutls_pkcs12_bag_get_key_id:
574 * @bag: The bag
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,
587 gnutls_datum_t * id)
589 if (bag == NULL)
591 gnutls_assert ();
592 return GNUTLS_E_INVALID_REQUEST;
595 if (indx > bag->bag_elements - 1)
597 gnutls_assert ();
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;
604 return 0;
608 * gnutls_pkcs12_bag_get_friendly_name:
609 * @bag: The bag
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,
622 char **name)
624 if (bag == NULL)
626 gnutls_assert ();
627 return GNUTLS_E_INVALID_REQUEST;
630 if (indx > bag->bag_elements - 1)
632 gnutls_assert ();
633 return GNUTLS_E_INVALID_REQUEST;
636 *name = bag->element[indx].friendly_name;
638 return 0;
643 * gnutls_pkcs12_bag_set_friendly_name:
644 * @bag: The bag
645 * @indx: The bag's element to add the id
646 * @name: the name
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,
658 const char *name)
660 if (bag == NULL)
662 gnutls_assert ();
663 return GNUTLS_E_INVALID_REQUEST;
666 if (indx > bag->bag_elements - 1)
668 gnutls_assert ();
669 return GNUTLS_E_INVALID_REQUEST;
672 bag->element[indx].friendly_name = gnutls_strdup (name);
674 if (name == NULL)
676 gnutls_assert ();
677 return GNUTLS_E_MEMORY_ERROR;
680 return 0;
685 * gnutls_pkcs12_bag_decrypt:
686 * @bag: The bag
687 * @pass: The password used for encryption, must be ASCII.
689 * This function will decrypt the given encrypted bag and return 0 on
690 * success.
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)
698 int ret;
699 gnutls_datum_t dec;
701 if (bag == NULL)
703 gnutls_assert ();
704 return GNUTLS_E_INVALID_REQUEST;
707 if (bag->element[0].type != GNUTLS_BAG_ENCRYPTED)
709 gnutls_assert ();
710 return GNUTLS_E_INVALID_REQUEST;
713 ret = _gnutls_pkcs7_decrypt_data (&bag->element[0].data, pass, &dec);
715 if (ret < 0)
717 gnutls_assert ();
718 return ret;
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);
731 if (ret < 0)
733 gnutls_assert ();
734 return ret;
737 return 0;
741 * gnutls_pkcs12_bag_encrypt:
742 * @bag: The bag
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,
753 unsigned int flags)
755 int ret;
756 ASN1_TYPE safe_cont = ASN1_TYPE_EMPTY;
757 gnutls_datum_t der = { NULL, 0 };
758 gnutls_datum_t enc = { NULL, 0 };
759 schema_id id;
761 if (bag == NULL)
763 gnutls_assert ();
764 return GNUTLS_E_INVALID_REQUEST;
767 if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED)
769 gnutls_assert ();
770 return GNUTLS_E_INVALID_REQUEST;
773 /* Encode the whole bag to a safe contents
774 * structure.
776 ret = _pkcs12_encode_safe_contents (bag, &safe_cont, NULL);
777 if (ret < 0)
779 gnutls_assert ();
780 return ret;
783 /* DER encode the SafeContents.
785 ret = _gnutls_x509_der_encode (safe_cont, "", &der, 0);
787 asn1_delete_structure (&safe_cont);
789 if (ret < 0)
791 gnutls_assert ();
792 return ret;
795 if (flags & GNUTLS_PKCS_PLAIN)
797 gnutls_assert ();
798 return GNUTLS_E_INVALID_REQUEST;
801 id = _gnutls_pkcs_flags_to_schema (flags);
803 /* Now encrypt them.
805 ret = _gnutls_pkcs7_encrypt_data (id, &der, pass, &enc);
807 _gnutls_free_datum (&der);
809 if (ret < 0)
811 gnutls_assert ();
812 return ret;
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;
826 return 0;