Guile: Fix `x509-certificate-dn-oid' and related functions.
[gnutls.git] / lib / gnutls_x509.c
blob68e574ce0e8d749d5e6b999ce1ac14141fd4fcc6
1 /*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
4 * Author: Nikos Mavroyanopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library 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 2.1 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
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
25 #include <gnutls_int.h>
26 #include "gnutls_auth_int.h"
27 #include "gnutls_errors.h"
28 #include <gnutls_cert.h>
29 #include <auth_cert.h>
30 #include "gnutls_dh.h"
31 #include "gnutls_num.h"
32 #include "libtasn1.h"
33 #include "gnutls_datum.h"
34 #include <gnutls_pk.h>
35 #include <gnutls_algorithms.h>
36 #include <gnutls_global.h>
37 #include <gnutls_record.h>
38 #include <gnutls_sig.h>
39 #include <gnutls_state.h>
40 #include <gnutls_pk.h>
41 #include <gnutls_str.h>
42 #include <debug.h>
43 #include <x509_b64.h>
44 #include <gnutls_x509.h>
45 #include "x509/common.h"
46 #include "x509/x509.h"
47 #include "x509/verify.h"
48 #include "x509/mpi.h"
49 #include "x509/pkcs7.h"
50 #include "x509/privkey.h"
51 #include "read-file.h"
54 * some x509 certificate parsing functions.
57 /* Check if the number of bits of the key in the certificate
58 * is unacceptable.
60 inline static int
61 check_bits (gnutls_x509_crt_t crt, unsigned int max_bits)
63 int ret;
64 unsigned int bits;
66 ret = gnutls_x509_crt_get_pk_algorithm (crt, &bits);
67 if (ret < 0)
69 gnutls_assert ();
70 return ret;
73 if (bits > max_bits)
75 gnutls_assert ();
76 return GNUTLS_E_CONSTRAINT_ERROR;
79 return 0;
83 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) { \
84 if (peer_certificate_list[x]) \
85 gnutls_x509_crt_deinit(peer_certificate_list[x]); \
86 } \
87 gnutls_free( peer_certificate_list)
89 /*-
90 * _gnutls_x509_cert_verify_peers - This function returns the peer's certificate status
91 * @session: is a gnutls session
93 * This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.).
94 * The return value (status) should be one of the gnutls_certificate_status_t enumerated elements.
95 * However you must also check the peer's name in order to check if the verified certificate belongs to the
96 * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
98 -*/
99 int
100 _gnutls_x509_cert_verify_peers (gnutls_session_t session,
101 unsigned int *status)
103 cert_auth_info_t info;
104 gnutls_certificate_credentials_t cred;
105 gnutls_x509_crt_t *peer_certificate_list;
106 int peer_certificate_list_size, i, x, ret;
108 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
110 info = _gnutls_get_auth_info (session);
111 if (info == NULL)
113 gnutls_assert ();
114 return GNUTLS_E_INVALID_REQUEST;
117 cred = (gnutls_certificate_credentials_t)
118 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
119 if (cred == NULL)
121 gnutls_assert ();
122 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
125 if (info->raw_certificate_list == NULL || info->ncerts == 0)
126 return GNUTLS_E_NO_CERTIFICATE_FOUND;
128 if (info->ncerts > cred->verify_depth)
130 gnutls_assert ();
131 return GNUTLS_E_CONSTRAINT_ERROR;
134 /* generate a list of gnutls_certs based on the auth info
135 * raw certs.
137 peer_certificate_list_size = info->ncerts;
138 peer_certificate_list =
139 gnutls_calloc (1,
140 peer_certificate_list_size * sizeof (gnutls_x509_crt_t));
141 if (peer_certificate_list == NULL)
143 gnutls_assert ();
144 return GNUTLS_E_MEMORY_ERROR;
147 for (i = 0; i < peer_certificate_list_size; i++)
149 ret = gnutls_x509_crt_init (&peer_certificate_list[i]);
150 if (ret < 0)
152 gnutls_assert ();
153 CLEAR_CERTS;
154 return ret;
157 ret =
158 gnutls_x509_crt_import (peer_certificate_list[i],
159 &info->raw_certificate_list[i],
160 GNUTLS_X509_FMT_DER);
161 if (ret < 0)
163 gnutls_assert ();
164 CLEAR_CERTS;
165 return ret;
168 ret = check_bits (peer_certificate_list[i], cred->verify_bits);
169 if (ret < 0)
171 gnutls_assert ();
172 CLEAR_CERTS;
173 return ret;
178 /* Verify certificate
180 ret =
181 gnutls_x509_crt_list_verify (peer_certificate_list,
182 peer_certificate_list_size,
183 cred->x509_ca_list, cred->x509_ncas,
184 cred->x509_crl_list, cred->x509_ncrls,
185 cred->verify_flags, status);
187 CLEAR_CERTS;
189 if (ret < 0)
191 gnutls_assert ();
192 return ret;
195 return 0;
199 * Read certificates and private keys, from files, memory etc.
202 /* returns error if the certificate has different algorithm than
203 * the given key parameters.
205 static int
206 _gnutls_check_key_cert_match (gnutls_certificate_credentials_t res)
208 gnutls_datum_t cid;
209 gnutls_datum_t kid;
210 unsigned pk = res->cert_list[res->ncerts - 1][0].subject_pk_algorithm;
212 if (res->pkey[res->ncerts - 1].pk_algorithm != pk)
214 gnutls_assert ();
215 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
218 if (pk == GNUTLS_PK_RSA)
220 _gnutls_x509_write_rsa_params (res->pkey[res->ncerts - 1].params,
221 res->pkey[res->ncerts -
222 1].params_size, &kid);
225 _gnutls_x509_write_rsa_params (res->cert_list[res->ncerts - 1][0].
226 params,
227 res->cert_list[res->ncerts -
228 1][0].params_size, &cid);
230 else if (pk == GNUTLS_PK_DSA)
233 _gnutls_x509_write_dsa_params (res->pkey[res->ncerts - 1].params,
234 res->pkey[res->ncerts -
235 1].params_size, &kid);
237 _gnutls_x509_write_dsa_params (res->cert_list[res->ncerts - 1][0].
238 params,
239 res->cert_list[res->ncerts -
240 1][0].params_size, &cid);
243 if (cid.size != kid.size)
245 gnutls_assert ();
246 _gnutls_free_datum (&kid);
247 _gnutls_free_datum (&cid);
248 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
251 if (memcmp (kid.data, cid.data, kid.size) != 0)
253 gnutls_assert ();
254 _gnutls_free_datum (&kid);
255 _gnutls_free_datum (&cid);
256 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
259 _gnutls_free_datum (&kid);
260 _gnutls_free_datum (&cid);
261 return 0;
264 /* Reads a DER encoded certificate list from memory and stores it to
265 * a gnutls_cert structure. This is only called if PKCS7 read fails.
266 * returns the number of certificates parsed (1)
268 static int
269 parse_crt_mem (gnutls_cert ** cert_list, unsigned *ncerts,
270 gnutls_x509_crt_t cert)
272 int i;
273 int ret;
275 i = *ncerts + 1;
277 *cert_list =
278 (gnutls_cert *) gnutls_realloc_fast (*cert_list,
279 i * sizeof (gnutls_cert));
281 if (*cert_list == NULL)
283 gnutls_assert ();
284 return GNUTLS_E_MEMORY_ERROR;
287 ret = _gnutls_x509_crt_to_gcert (&cert_list[0][i - 1], cert, 0);
288 if (ret < 0)
290 gnutls_assert ();
291 return ret;
294 *ncerts = i;
296 return 1; /* one certificate parsed */
299 /* Reads a DER encoded certificate list from memory and stores it to
300 * a gnutls_cert structure. This is only called if PKCS7 read fails.
301 * returns the number of certificates parsed (1)
303 static int
304 parse_der_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts,
305 const void *input_cert, int input_cert_size)
307 gnutls_datum_t tmp;
308 gnutls_x509_crt_t cert;
309 int ret;
311 ret = gnutls_x509_crt_init (&cert);
312 if (ret < 0)
314 gnutls_assert ();
315 return ret;
318 tmp.data = (opaque *) input_cert;
319 tmp.size = input_cert_size;
321 ret = gnutls_x509_crt_import (cert, &tmp, GNUTLS_X509_FMT_DER);
322 if (ret < 0)
324 gnutls_assert ();
325 gnutls_x509_crt_deinit (cert);
326 return ret;
329 ret = parse_crt_mem (cert_list, ncerts, cert);
330 gnutls_x509_crt_deinit (cert);
332 return ret;
335 #define CERT_PEM 1
338 /* Reads a PKCS7 base64 encoded certificate list from memory and stores it to
339 * a gnutls_cert structure.
340 * returns the number of certificate parsed
342 static int
343 parse_pkcs7_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts, const
344 void *input_cert, int input_cert_size, int flags)
346 #ifdef ENABLE_PKI
347 int i, j, count;
348 gnutls_datum_t tmp, tmp2;
349 int ret;
350 opaque *pcert = NULL;
351 size_t pcert_size;
352 gnutls_pkcs7_t pkcs7;
354 ret = gnutls_pkcs7_init (&pkcs7);
355 if (ret < 0)
357 gnutls_assert ();
358 return ret;
361 if (flags & CERT_PEM)
362 ret = gnutls_pkcs7_import (pkcs7, &tmp, GNUTLS_X509_FMT_PEM);
363 else
364 ret = gnutls_pkcs7_import (pkcs7, &tmp, GNUTLS_X509_FMT_DER);
365 if (ret < 0)
367 /* if we failed to read the structure,
368 * then just try to decode a plain DER
369 * certificate.
371 gnutls_assert ();
372 gnutls_pkcs7_deinit (pkcs7);
373 #endif
374 return parse_der_cert_mem (cert_list, ncerts,
375 input_cert, input_cert_size);
376 #ifdef ENABLE_PKI
379 i = *ncerts + 1;
381 /* tmp now contains the decoded certificate list */
382 tmp.data = (opaque *) input_cert;
383 tmp.size = input_cert_size;
385 ret = gnutls_pkcs7_get_crt_count (pkcs7);
387 if (ret < 0)
389 gnutls_assert ();
390 gnutls_pkcs7_deinit (pkcs7);
391 return ret;
393 count = ret;
395 j = count - 1;
398 pcert_size = 0;
399 ret = gnutls_pkcs7_get_crt_raw (pkcs7, j, NULL, &pcert_size);
400 if (ret != GNUTLS_E_MEMORY_ERROR)
402 count--;
403 continue;
406 pcert = gnutls_malloc (pcert_size);
407 if (ret == GNUTLS_E_MEMORY_ERROR)
409 gnutls_assert ();
410 count--;
411 continue;
414 /* read the certificate
416 ret = gnutls_pkcs7_get_crt_raw (pkcs7, j, pcert, &pcert_size);
418 j--;
420 if (ret >= 0)
422 *cert_list =
423 (gnutls_cert *) gnutls_realloc_fast (*cert_list,
424 i * sizeof (gnutls_cert));
426 if (*cert_list == NULL)
428 gnutls_assert ();
429 gnutls_free (pcert);
430 return GNUTLS_E_MEMORY_ERROR;
433 tmp2.data = pcert;
434 tmp2.size = pcert_size;
436 ret =
437 _gnutls_x509_raw_cert_to_gcert (&cert_list[0][i - 1], &tmp2, 0);
439 if (ret < 0)
441 gnutls_assert ();
442 gnutls_pkcs7_deinit (pkcs7);
443 gnutls_free (pcert);
444 return ret;
447 i++;
450 gnutls_free (pcert);
453 while (ret >= 0 && j >= 0);
455 *ncerts = i - 1;
457 gnutls_pkcs7_deinit (pkcs7);
458 return count;
459 #endif
462 /* Reads a base64 encoded certificate list from memory and stores it to
463 * a gnutls_cert structure. Returns the number of certificate parsed.
465 static int
466 parse_pem_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts,
467 const char *input_cert, int input_cert_size)
469 int size, siz2, i;
470 const char *ptr;
471 opaque *ptr2;
472 gnutls_datum_t tmp;
473 int ret, count;
475 #ifdef ENABLE_PKI
476 if ((ptr = memmem (input_cert, input_cert_size,
477 PEM_PKCS7_SEP, sizeof (PEM_PKCS7_SEP) - 1)) != NULL)
479 size = strlen (ptr);
481 ret = parse_pkcs7_cert_mem (cert_list, ncerts, ptr, size, CERT_PEM);
483 return ret;
485 #endif
487 /* move to the certificate
489 ptr = memmem (input_cert, input_cert_size,
490 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
491 if (ptr == NULL)
492 ptr = memmem (input_cert, input_cert_size,
493 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
495 if (ptr == NULL)
497 gnutls_assert ();
498 return GNUTLS_E_BASE64_DECODING_ERROR;
500 size = input_cert_size - (ptr - input_cert);
502 i = *ncerts + 1;
503 count = 0;
508 siz2 = _gnutls_fbase64_decode (NULL, ptr, size, &ptr2);
510 if (siz2 < 0)
512 gnutls_assert ();
513 return GNUTLS_E_BASE64_DECODING_ERROR;
516 *cert_list =
517 (gnutls_cert *) gnutls_realloc_fast (*cert_list,
518 i * sizeof (gnutls_cert));
520 if (*cert_list == NULL)
522 gnutls_assert ();
523 return GNUTLS_E_MEMORY_ERROR;
526 tmp.data = ptr2;
527 tmp.size = siz2;
529 ret = _gnutls_x509_raw_cert_to_gcert (&cert_list[0][i - 1], &tmp, 0);
530 if (ret < 0)
532 gnutls_assert ();
533 return ret;
535 _gnutls_free_datum (&tmp); /* free ptr2 */
537 /* now we move ptr after the pem header
539 ptr++;
540 /* find the next certificate (if any)
542 size = input_cert_size - (ptr - input_cert);
544 if (size > 0)
546 char *ptr3;
548 ptr3 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
549 if (ptr3 == NULL)
550 ptr3 = memmem (ptr, size, PEM_CERT_SEP2,
551 sizeof (PEM_CERT_SEP2) - 1);
553 ptr = ptr3;
555 else
556 ptr = NULL;
558 i++;
559 count++;
562 while (ptr != NULL);
564 *ncerts = i - 1;
566 return count;
571 /* Reads a DER or PEM certificate from memory
573 static int
574 read_cert_mem (gnutls_certificate_credentials_t res, const void *cert,
575 int cert_size, gnutls_x509_crt_fmt_t type)
577 int ret;
579 /* allocate space for the certificate to add
581 res->cert_list = gnutls_realloc_fast (res->cert_list,
582 (1 +
583 res->ncerts) *
584 sizeof (gnutls_cert *));
585 if (res->cert_list == NULL)
587 gnutls_assert ();
588 return GNUTLS_E_MEMORY_ERROR;
591 res->cert_list_length = gnutls_realloc_fast (res->cert_list_length,
592 (1 +
593 res->ncerts) * sizeof (int));
594 if (res->cert_list_length == NULL)
596 gnutls_assert ();
597 return GNUTLS_E_MEMORY_ERROR;
600 res->cert_list[res->ncerts] = NULL; /* for realloc */
601 res->cert_list_length[res->ncerts] = 0;
603 if (type == GNUTLS_X509_FMT_DER)
604 ret = parse_pkcs7_cert_mem (&res->cert_list[res->ncerts],
605 &res->cert_list_length[res->ncerts],
606 cert, cert_size, 0);
607 else
608 ret =
609 parse_pem_cert_mem (&res->cert_list[res->ncerts],
610 &res->cert_list_length[res->ncerts], cert,
611 cert_size);
613 if (ret < 0)
615 gnutls_assert ();
616 return ret;
619 return ret;
624 _gnutls_x509_privkey_to_gkey (gnutls_privkey * dest,
625 gnutls_x509_privkey_t src)
627 int i, ret;
629 memset (dest, 0, sizeof (gnutls_privkey));
631 for (i = 0; i < src->params_size; i++)
633 dest->params[i] = _gnutls_mpi_copy (src->params[i]);
634 if (dest->params[i] == NULL)
636 gnutls_assert ();
637 ret = GNUTLS_E_MEMORY_ERROR;
638 goto cleanup;
642 dest->pk_algorithm = src->pk_algorithm;
643 dest->params_size = src->params_size;
645 return 0;
647 cleanup:
649 for (i = 0; i < src->params_size; i++)
651 _gnutls_mpi_release (&dest->params[i]);
653 return ret;
656 void
657 _gnutls_gkey_deinit (gnutls_privkey * key)
659 int i;
660 if (key == NULL)
661 return;
663 for (i = 0; i < key->params_size; i++)
665 _gnutls_mpi_release (&key->params[i]);
670 _gnutls_x509_raw_privkey_to_gkey (gnutls_privkey * privkey,
671 const gnutls_datum_t * raw_key,
672 gnutls_x509_crt_fmt_t type)
674 gnutls_x509_privkey_t tmpkey;
675 int ret;
677 ret = gnutls_x509_privkey_init (&tmpkey);
678 if (ret < 0)
680 gnutls_assert ();
681 return ret;
684 ret = gnutls_x509_privkey_import (tmpkey, raw_key, type);
685 if (ret < 0)
687 gnutls_assert ();
688 gnutls_x509_privkey_deinit (tmpkey);
689 return ret;
692 ret = _gnutls_x509_privkey_to_gkey (privkey, tmpkey);
693 if (ret < 0)
695 gnutls_assert ();
696 gnutls_x509_privkey_deinit (tmpkey);
697 return ret;
700 gnutls_x509_privkey_deinit (tmpkey);
702 return 0;
705 /* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory. Type
706 * indicates the certificate format. KEY can be NULL, to indicate
707 * that GnuTLS doesn't know the private key.
709 static int
710 read_key_mem (gnutls_certificate_credentials_t res,
711 const void *key, int key_size, gnutls_x509_crt_fmt_t type)
713 int ret;
714 gnutls_datum_t tmp;
716 /* allocate space for the pkey list
718 res->pkey =
719 gnutls_realloc_fast (res->pkey,
720 (res->ncerts + 1) * sizeof (gnutls_privkey));
721 if (res->pkey == NULL)
723 gnutls_assert ();
724 return GNUTLS_E_MEMORY_ERROR;
727 if (key)
729 tmp.data = (opaque *) key;
730 tmp.size = key_size;
732 ret =
733 _gnutls_x509_raw_privkey_to_gkey (&res->pkey[res->ncerts], &tmp, type);
734 if (ret < 0)
736 gnutls_assert ();
737 return ret;
740 else
741 memset (&res->pkey[res->ncerts], 0, sizeof (gnutls_privkey));
743 return 0;
746 /* Reads a certificate file
748 static int
749 read_cert_file (gnutls_certificate_credentials_t res,
750 const char *certfile, gnutls_x509_crt_fmt_t type)
752 int ret;
753 size_t size;
754 char *data = read_binary_file (certfile, &size);
756 if (data == NULL)
758 gnutls_assert ();
759 return GNUTLS_E_FILE_ERROR;
762 ret = read_cert_mem (res, data, size, type);
763 free (data);
765 return ret;
771 /* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
772 * stores it).
774 static int
775 read_key_file (gnutls_certificate_credentials_t res,
776 const char *keyfile, gnutls_x509_crt_fmt_t type)
778 int ret;
779 size_t size;
780 char *data = read_binary_file (keyfile, &size);
782 if (data == NULL)
784 gnutls_assert ();
785 return GNUTLS_E_FILE_ERROR;
788 ret = read_key_mem (res, data, size, type);
789 free (data);
791 return ret;
795 * gnutls_certificate_set_x509_key_mem - Used to set keys in a gnutls_certificate_credentials_t structure
796 * @res: is an #gnutls_certificate_credentials_t structure.
797 * @cert: contains a certificate list (path) for the specified private key
798 * @key: is the private key, or %NULL
799 * @type: is PEM or DER
801 * This function sets a certificate/private key pair in the
802 * gnutls_certificate_credentials_t structure. This function may be called
803 * more than once (in case multiple keys/certificates exist for the
804 * server).
806 * Currently are supported: RSA PKCS-1 encoded private keys,
807 * DSA private keys.
809 * DSA private keys are encoded the OpenSSL way, which is an ASN.1
810 * DER sequence of 6 INTEGERs - version, p, q, g, pub, priv.
812 * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
813 * is supported. This means that certificates intended for signing cannot
814 * be used for ciphersuites that require encryption.
816 * If the certificate and the private key are given in PEM encoding
817 * then the strings that hold their values must be null terminated.
819 * The @key may be %NULL if you are using a sign callback, see
820 * gnutls_sign_callback_set().
824 gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t
825 res, const gnutls_datum_t * cert,
826 const gnutls_datum_t * key,
827 gnutls_x509_crt_fmt_t type)
829 int ret;
831 /* this should be first
833 if ((ret = read_key_mem (res, key ? key->data : NULL,
834 key ? key->size : 0, type)) < 0)
835 return ret;
837 if ((ret = read_cert_mem (res, cert->data, cert->size, type)) < 0)
838 return ret;
840 res->ncerts++;
842 if (key && (ret = _gnutls_check_key_cert_match (res)) < 0)
844 gnutls_assert ();
845 return ret;
848 return 0;
852 * gnutls_certificate_set_x509_key - Used to set keys in a gnutls_certificate_credentials_t structure
853 * @res: is an #gnutls_certificate_credentials_t structure.
854 * @cert_list: contains a certificate list (path) for the specified private key
855 * @cert_list_size: holds the size of the certificate list
856 * @key: is a gnutls_x509_privkey_t key
858 * This function sets a certificate/private key pair in the
859 * gnutls_certificate_credentials_t structure. This function may be called
860 * more than once (in case multiple keys/certificates exist for the
861 * server).
865 gnutls_certificate_set_x509_key (gnutls_certificate_credentials_t res,
866 gnutls_x509_crt_t * cert_list,
867 int cert_list_size,
868 gnutls_x509_privkey_t key)
870 int ret, i;
872 /* this should be first
875 res->pkey =
876 gnutls_realloc_fast (res->pkey,
877 (res->ncerts + 1) * sizeof (gnutls_privkey));
878 if (res->pkey == NULL)
880 gnutls_assert ();
881 return GNUTLS_E_MEMORY_ERROR;
884 ret = _gnutls_x509_privkey_to_gkey (&res->pkey[res->ncerts], key);
885 if (ret < 0)
887 gnutls_assert ();
888 return ret;
891 res->cert_list = gnutls_realloc_fast (res->cert_list,
892 (1 +
893 res->ncerts) *
894 sizeof (gnutls_cert *));
895 if (res->cert_list == NULL)
897 gnutls_assert ();
898 return GNUTLS_E_MEMORY_ERROR;
901 res->cert_list_length = gnutls_realloc_fast (res->cert_list_length,
902 (1 +
903 res->ncerts) * sizeof (int));
904 if (res->cert_list_length == NULL)
906 gnutls_assert ();
907 return GNUTLS_E_MEMORY_ERROR;
910 res->cert_list[res->ncerts] = NULL; /* for realloc */
911 res->cert_list_length[res->ncerts] = 0;
914 for (i = 0; i < cert_list_size; i++)
916 ret = parse_crt_mem (&res->cert_list[res->ncerts],
917 &res->cert_list_length[res->ncerts], cert_list[i]);
918 if (ret < 0)
920 gnutls_assert ();
921 return ret;
924 res->ncerts++;
926 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
928 gnutls_assert ();
929 return ret;
932 return 0;
936 * gnutls_certificate_set_x509_key_file - Used to set keys in a gnutls_certificate_credentials_t structure
937 * @res: is an #gnutls_certificate_credentials_t structure.
938 * @CERTFILE: is a file that containing the certificate list (path) for
939 * the specified private key, in PKCS7 format, or a list of certificates
940 * @KEYFILE: is a file that contains the private key
941 * @type: is PEM or DER
943 * This function sets a certificate/private key pair in the
944 * gnutls_certificate_credentials_t structure. This function may be called
945 * more than once (in case multiple keys/certificates exist for the
946 * server).
948 * Currently only PKCS-1 encoded RSA and DSA private keys are accepted by
949 * this function.
953 gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t
954 res, const char *CERTFILE,
955 const char *KEYFILE,
956 gnutls_x509_crt_fmt_t type)
958 int ret;
960 /* this should be first
962 if ((ret = read_key_file (res, KEYFILE, type)) < 0)
963 return ret;
965 if ((ret = read_cert_file (res, CERTFILE, type)) < 0)
966 return ret;
968 res->ncerts++;
970 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
972 gnutls_assert ();
973 return ret;
976 return 0;
979 static int
980 generate_rdn_seq (gnutls_certificate_credentials_t res)
982 gnutls_datum_t tmp;
983 int ret;
984 unsigned size, i;
985 opaque *pdata;
987 /* Generate the RDN sequence
988 * This will be sent to clients when a certificate
989 * request message is sent.
992 /* FIXME: in case of a client it is not needed
993 * to do that. This would save time and memory.
994 * However we don't have that information available
995 * here.
998 size = 0;
999 for (i = 0; i < res->x509_ncas; i++)
1001 if ((ret = gnutls_x509_crt_get_raw_dn (res->x509_ca_list[i], &tmp)) < 0)
1003 gnutls_assert ();
1004 return ret;
1006 size += (2 + tmp.size);
1007 _gnutls_free_datum (&tmp);
1010 if (res->x509_rdn_sequence.data != NULL)
1011 gnutls_free (res->x509_rdn_sequence.data);
1013 res->x509_rdn_sequence.data = gnutls_malloc (size);
1014 if (res->x509_rdn_sequence.data == NULL)
1016 gnutls_assert ();
1017 return GNUTLS_E_MEMORY_ERROR;
1019 res->x509_rdn_sequence.size = size;
1021 pdata = res->x509_rdn_sequence.data;
1023 for (i = 0; i < res->x509_ncas; i++)
1025 if ((ret = gnutls_x509_crt_get_raw_dn (res->x509_ca_list[i], &tmp)) < 0)
1027 _gnutls_free_datum (&res->x509_rdn_sequence);
1028 gnutls_assert ();
1029 return ret;
1032 _gnutls_write_datum16 (pdata, tmp);
1033 pdata += (2 + tmp.size);
1034 _gnutls_free_datum (&tmp);
1037 return 0;
1043 /* Returns 0 if it's ok to use the gnutls_kx_algorithm_t with this
1044 * certificate (uses the KeyUsage field).
1047 _gnutls_check_key_usage (const gnutls_cert * cert, gnutls_kx_algorithm_t alg)
1049 unsigned int key_usage = 0;
1050 int encipher_type;
1052 if (cert == NULL)
1054 gnutls_assert ();
1055 return GNUTLS_E_INTERNAL_ERROR;
1058 if (_gnutls_map_kx_get_cred (alg, 1) == GNUTLS_CRD_CERTIFICATE ||
1059 _gnutls_map_kx_get_cred (alg, 0) == GNUTLS_CRD_CERTIFICATE)
1062 key_usage = cert->key_usage;
1064 encipher_type = _gnutls_kx_encipher_type (alg);
1066 if (key_usage != 0 && encipher_type != CIPHER_IGN)
1068 /* If key_usage has been set in the certificate
1071 if (encipher_type == CIPHER_ENCRYPT)
1073 /* If the key exchange method requires an encipher
1074 * type algorithm, and key's usage does not permit
1075 * encipherment, then fail.
1077 if (!(key_usage & KEY_KEY_ENCIPHERMENT))
1079 gnutls_assert ();
1080 return GNUTLS_E_KEY_USAGE_VIOLATION;
1084 if (encipher_type == CIPHER_SIGN)
1086 /* The same as above, but for sign only keys
1088 if (!(key_usage & KEY_DIGITAL_SIGNATURE))
1090 gnutls_assert ();
1091 return GNUTLS_E_KEY_USAGE_VIOLATION;
1096 return 0;
1101 static int
1102 parse_pem_ca_mem (gnutls_x509_crt_t ** cert_list, unsigned *ncerts,
1103 const opaque * input_cert, int input_cert_size)
1105 int i, size;
1106 const opaque *ptr;
1107 gnutls_datum_t tmp;
1108 int ret, count;
1110 /* move to the certificate
1112 ptr = memmem (input_cert, input_cert_size,
1113 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
1114 if (ptr == NULL)
1115 ptr = memmem (input_cert, input_cert_size,
1116 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
1118 if (ptr == NULL)
1120 gnutls_assert ();
1121 return GNUTLS_E_BASE64_DECODING_ERROR;
1123 size = input_cert_size - (ptr - input_cert);
1125 i = *ncerts + 1;
1126 count = 0;
1131 *cert_list =
1132 (gnutls_x509_crt_t *) gnutls_realloc_fast (*cert_list,
1134 sizeof
1135 (gnutls_x509_crt_t));
1137 if (*cert_list == NULL)
1139 gnutls_assert ();
1140 return GNUTLS_E_MEMORY_ERROR;
1143 ret = gnutls_x509_crt_init (&cert_list[0][i - 1]);
1144 if (ret < 0)
1146 gnutls_assert ();
1147 return ret;
1150 tmp.data = (opaque *) ptr;
1151 tmp.size = size;
1153 ret =
1154 gnutls_x509_crt_import (cert_list[0][i - 1],
1155 &tmp, GNUTLS_X509_FMT_PEM);
1156 if (ret < 0)
1158 gnutls_assert ();
1159 return ret;
1162 /* now we move ptr after the pem header
1164 ptr++;
1165 size--;
1166 /* find the next certificate (if any)
1169 if (size > 0)
1171 char *ptr3;
1173 ptr3 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
1174 if (ptr3 == NULL)
1175 ptr3 = memmem (ptr, size,
1176 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
1178 ptr = ptr3;
1179 size = input_cert_size - (ptr - input_cert);
1181 else
1182 ptr = NULL;
1184 i++;
1185 count++;
1188 while (ptr != NULL);
1190 *ncerts = i - 1;
1192 return count;
1195 /* Reads a DER encoded certificate list from memory and stores it to
1196 * a gnutls_cert structure. This is only called if PKCS7 read fails.
1197 * returns the number of certificates parsed (1)
1199 static int
1200 parse_der_ca_mem (gnutls_x509_crt_t ** cert_list, unsigned *ncerts,
1201 const void *input_cert, int input_cert_size)
1203 int i;
1204 gnutls_datum_t tmp;
1205 int ret;
1207 i = *ncerts + 1;
1209 *cert_list =
1210 (gnutls_x509_crt_t *) gnutls_realloc_fast (*cert_list,
1212 sizeof (gnutls_x509_crt_t));
1214 if (*cert_list == NULL)
1216 gnutls_assert ();
1217 return GNUTLS_E_MEMORY_ERROR;
1220 tmp.data = (opaque *) input_cert;
1221 tmp.size = input_cert_size;
1223 ret = gnutls_x509_crt_init (&cert_list[0][i - 1]);
1224 if (ret < 0)
1226 gnutls_assert ();
1227 return ret;
1230 ret =
1231 gnutls_x509_crt_import (cert_list[0][i - 1], &tmp, GNUTLS_X509_FMT_DER);
1232 if (ret < 0)
1234 gnutls_assert ();
1235 return ret;
1238 *ncerts = i;
1240 return 1; /* one certificate parsed */
1244 * gnutls_certificate_set_x509_trust_mem - Used to add trusted CAs in a gnutls_certificate_credentials_t structure
1245 * @res: is an #gnutls_certificate_credentials_t structure.
1246 * @ca: is a list of trusted CAs or a DER certificate
1247 * @type: is DER or PEM
1249 * This function adds the trusted CAs in order to verify client
1250 * or server certificates. In case of a client this is not required
1251 * to be called if the certificates are not verified using
1252 * gnutls_certificate_verify_peers2().
1253 * This function may be called multiple times.
1255 * In case of a server the CAs set here will be sent to the client if
1256 * a certificate request is sent. This can be disabled using
1257 * gnutls_certificate_send_x509_rdn_sequence().
1259 * Returns the number of certificates processed or a negative
1260 * value on error.
1264 gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t
1265 res, const gnutls_datum_t * ca,
1266 gnutls_x509_crt_fmt_t type)
1268 int ret, ret2;
1270 if (type == GNUTLS_X509_FMT_DER)
1271 ret = parse_der_ca_mem (&res->x509_ca_list, &res->x509_ncas,
1272 ca->data, ca->size);
1273 else
1274 ret = parse_pem_ca_mem (&res->x509_ca_list, &res->x509_ncas,
1275 ca->data, ca->size);
1277 if ((ret2 = generate_rdn_seq (res)) < 0)
1278 return ret2;
1280 return ret;
1284 * gnutls_certificate_set_x509_trust - Used to add trusted CAs in a gnutls_certificate_credentials_t structure
1285 * @res: is an #gnutls_certificate_credentials_t structure.
1286 * @ca_list: is a list of trusted CAs
1287 * @ca_list_size: holds the size of the CA list
1289 * This function adds the trusted CAs in order to verify client
1290 * or server certificates. In case of a client this is not required
1291 * to be called if the certificates are not verified using
1292 * gnutls_certificate_verify_peers2().
1293 * This function may be called multiple times.
1295 * In case of a server the CAs set here will be sent to the client if
1296 * a certificate request is sent. This can be disabled using
1297 * gnutls_certificate_send_x509_rdn_sequence().
1299 * Returns 0 on success.
1303 gnutls_certificate_set_x509_trust (gnutls_certificate_credentials_t res,
1304 gnutls_x509_crt_t * ca_list,
1305 int ca_list_size)
1307 int ret, i, ret2;
1309 res->x509_ca_list = gnutls_realloc_fast (res->x509_ca_list,
1310 (ca_list_size +
1311 res->x509_ncas) *
1312 sizeof (gnutls_x509_crt_t));
1313 if (res->x509_ca_list == NULL)
1315 gnutls_assert ();
1316 return GNUTLS_E_MEMORY_ERROR;
1319 for (i = 0; i < ca_list_size; i++)
1321 ret = gnutls_x509_crt_init (&res->x509_ca_list[ res->x509_ncas]);
1322 if (ret < 0)
1324 gnutls_assert ();
1325 return ret;
1328 ret = _gnutls_x509_crt_cpy (res->x509_ca_list[ res->x509_ncas],
1329 ca_list[i]);
1330 if (ret < 0)
1332 gnutls_assert ();
1333 gnutls_x509_crt_deinit (res->x509_ca_list[ res->x509_ncas]);
1334 return ret;
1336 res->x509_ncas++;
1339 if ((ret2 = generate_rdn_seq (res)) < 0)
1340 return ret2;
1342 return 0;
1346 * gnutls_certificate_set_x509_trust_file - Used to add trusted CAs in a gnutls_certificate_credentials_t structure
1347 * @res: is an #gnutls_certificate_credentials_t structure.
1348 * @cafile: is a file containing the list of trusted CAs (DER or PEM list)
1349 * @type: is PEM or DER
1351 * This function adds the trusted CAs in order to verify client
1352 * or server certificates. In case of a client this is not required
1353 * to be called if the certificates are not verified using
1354 * gnutls_certificate_verify_peers2().
1355 * This function may be called multiple times.
1357 * In case of a server the names of the CAs set here will be sent to the
1358 * client if a certificate request is sent. This can be disabled using
1359 * gnutls_certificate_send_x509_rdn_sequence().
1361 * Returns the number of certificates processed or a negative
1362 * value on error.
1366 gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t
1367 res, const char *cafile,
1368 gnutls_x509_crt_fmt_t type)
1370 int ret, ret2;
1371 size_t size;
1372 char *data = read_binary_file (cafile, &size);
1374 if (data == NULL)
1376 gnutls_assert ();
1377 return GNUTLS_E_FILE_ERROR;
1380 if (type == GNUTLS_X509_FMT_DER)
1381 ret = parse_der_ca_mem (&res->x509_ca_list, &res->x509_ncas,
1382 data, size);
1383 else
1384 ret = parse_pem_ca_mem (&res->x509_ca_list, &res->x509_ncas,
1385 data, size);
1387 free (data);
1389 if (ret < 0)
1391 gnutls_assert ();
1392 return ret;
1395 if ((ret2 = generate_rdn_seq (res)) < 0)
1396 return ret2;
1398 return ret;
1401 #ifdef ENABLE_PKI
1403 static int
1404 parse_pem_crl_mem (gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
1405 const opaque * input_crl, int input_crl_size)
1407 int size, i;
1408 const opaque *ptr;
1409 gnutls_datum_t tmp;
1410 int ret, count;
1412 /* move to the certificate
1414 ptr = memmem (input_crl, input_crl_size,
1415 PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
1416 if (ptr == NULL)
1418 gnutls_assert ();
1419 return GNUTLS_E_BASE64_DECODING_ERROR;
1422 size = input_crl_size - (ptr - input_crl);
1424 i = *ncrls + 1;
1425 count = 0;
1430 *crl_list =
1431 (gnutls_x509_crl_t *) gnutls_realloc_fast (*crl_list,
1433 sizeof
1434 (gnutls_x509_crl_t));
1436 if (*crl_list == NULL)
1438 gnutls_assert ();
1439 return GNUTLS_E_MEMORY_ERROR;
1442 ret = gnutls_x509_crl_init (&crl_list[0][i - 1]);
1443 if (ret < 0)
1445 gnutls_assert ();
1446 return ret;
1449 tmp.data = (char *) ptr;
1450 tmp.size = size;
1452 ret =
1453 gnutls_x509_crl_import (crl_list[0][i - 1],
1454 &tmp, GNUTLS_X509_FMT_PEM);
1455 if (ret < 0)
1457 gnutls_assert ();
1458 return ret;
1461 /* now we move ptr after the pem header
1463 ptr++;
1464 /* find the next certificate (if any)
1467 size = input_crl_size - (ptr - input_crl);
1469 if (size > 0)
1470 ptr = memmem (ptr, size, PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
1471 else
1472 ptr = NULL;
1473 i++;
1474 count++;
1477 while (ptr != NULL);
1479 *ncrls = i - 1;
1481 return count;
1484 /* Reads a DER encoded certificate list from memory and stores it to
1485 * a gnutls_cert structure. This is only called if PKCS7 read fails.
1486 * returns the number of certificates parsed (1)
1488 static int
1489 parse_der_crl_mem (gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
1490 const void *input_crl, int input_crl_size)
1492 int i;
1493 gnutls_datum_t tmp;
1494 int ret;
1496 i = *ncrls + 1;
1498 *crl_list =
1499 (gnutls_x509_crl_t *) gnutls_realloc_fast (*crl_list,
1501 sizeof (gnutls_x509_crl_t));
1503 if (*crl_list == NULL)
1505 gnutls_assert ();
1506 return GNUTLS_E_MEMORY_ERROR;
1509 tmp.data = (opaque *) input_crl;
1510 tmp.size = input_crl_size;
1512 ret = gnutls_x509_crl_init (&crl_list[0][i - 1]);
1513 if (ret < 0)
1515 gnutls_assert ();
1516 return ret;
1519 ret =
1520 gnutls_x509_crl_import (crl_list[0][i - 1], &tmp, GNUTLS_X509_FMT_DER);
1521 if (ret < 0)
1523 gnutls_assert ();
1524 return ret;
1527 *ncrls = i;
1529 return 1; /* one certificate parsed */
1533 /* Reads a DER or PEM CRL from memory
1535 static int
1536 read_crl_mem (gnutls_certificate_credentials_t res, const void *crl,
1537 int crl_size, gnutls_x509_crt_fmt_t type)
1539 int ret;
1541 /* allocate space for the certificate to add
1543 res->x509_crl_list = gnutls_realloc_fast (res->x509_crl_list,
1544 (1 +
1545 res->x509_ncrls) *
1546 sizeof (gnutls_x509_crl_t));
1547 if (res->x509_crl_list == NULL)
1549 gnutls_assert ();
1550 return GNUTLS_E_MEMORY_ERROR;
1553 if (type == GNUTLS_X509_FMT_DER)
1554 ret = parse_der_crl_mem (&res->x509_crl_list,
1555 &res->x509_ncrls, crl, crl_size);
1556 else
1557 ret = parse_pem_crl_mem (&res->x509_crl_list,
1558 &res->x509_ncrls, crl, crl_size);
1560 if (ret < 0)
1562 gnutls_assert ();
1563 return ret;
1566 return ret;
1570 * gnutls_certificate_set_x509_crl_mem - Used to add CRLs in a gnutls_certificate_credentials_t structure
1571 * @res: is an #gnutls_certificate_credentials_t structure.
1572 * @CRL: is a list of trusted CRLs. They should have been verified before.
1573 * @type: is DER or PEM
1575 * This function adds the trusted CRLs in order to verify client or server
1576 * certificates. In case of a client this is not required
1577 * to be called if the certificates are not verified using
1578 * gnutls_certificate_verify_peers2().
1579 * This function may be called multiple times.
1581 * Returns the number of CRLs processed or a negative value on error.
1585 gnutls_certificate_set_x509_crl_mem (gnutls_certificate_credentials_t
1586 res, const gnutls_datum_t * CRL,
1587 gnutls_x509_crt_fmt_t type)
1589 int ret;
1591 if ((ret = read_crl_mem (res, CRL->data, CRL->size, type)) < 0)
1592 return ret;
1594 return ret;
1598 * gnutls_certificate_set_x509_crl - Used to add CRLs in a gnutls_certificate_credentials_t structure
1599 * @res: is an #gnutls_certificate_credentials_t structure.
1600 * @crl_list: is a list of trusted CRLs. They should have been verified before.
1601 * @crl_list_size: holds the size of the crl_list
1603 * This function adds the trusted CRLs in order to verify client or server
1604 * certificates. In case of a client this is not required
1605 * to be called if the certificates are not verified using
1606 * gnutls_certificate_verify_peers2().
1607 * This function may be called multiple times.
1609 * Returns 0 on success.
1613 gnutls_certificate_set_x509_crl (gnutls_certificate_credentials_t res,
1614 gnutls_x509_crl_t * crl_list,
1615 int crl_list_size)
1617 int ret, i;
1619 res->x509_crl_list = gnutls_realloc_fast (res->x509_crl_list,
1620 (crl_list_size +
1621 res->x509_ncrls) *
1622 sizeof (gnutls_x509_crl_t));
1623 if (res->x509_crl_list == NULL)
1625 gnutls_assert ();
1626 return GNUTLS_E_MEMORY_ERROR;
1629 for (i = 0; i < crl_list_size; i++)
1631 ret = gnutls_x509_crl_init (&res->x509_crl_list[res->x509_ncrls]);
1632 if (ret < 0)
1634 gnutls_assert ();
1635 return ret;
1638 ret = _gnutls_x509_crl_cpy (res->x509_crl_list[res->x509_ncrls],
1639 crl_list[i]);
1640 if (ret < 0)
1642 gnutls_assert ();
1643 return ret;
1645 res->x509_ncrls++;
1648 return 0;
1652 * gnutls_certificate_set_x509_crl_file - Used to add CRLs in a gnutls_certificate_credentials_t structure
1653 * @res: is an #gnutls_certificate_credentials_t structure.
1654 * @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
1655 * @type: is PEM or DER
1657 * This function adds the trusted CRLs in order to verify client or server
1658 * certificates. In case of a client this is not required
1659 * to be called if the certificates are not verified using
1660 * gnutls_certificate_verify_peers2().
1661 * This function may be called multiple times.
1663 * Returns the number of CRLs processed or a negative value on error.
1667 gnutls_certificate_set_x509_crl_file (gnutls_certificate_credentials_t
1668 res, const char *crlfile,
1669 gnutls_x509_crt_fmt_t type)
1671 int ret;
1672 size_t size;
1673 char *data = read_binary_file (crlfile, &size);
1675 if (data == NULL)
1677 gnutls_assert ();
1678 return GNUTLS_E_FILE_ERROR;
1681 if (type == GNUTLS_X509_FMT_DER)
1682 ret = parse_der_crl_mem (&res->x509_crl_list, &res->x509_ncrls,
1683 data, size);
1684 else
1685 ret = parse_pem_crl_mem (&res->x509_crl_list, &res->x509_ncrls,
1686 data, size);
1688 free (data);
1690 if (ret < 0)
1692 gnutls_assert ();
1693 return ret;
1696 return ret;
1699 #include <gnutls/pkcs12.h>
1701 static int
1702 parse_pkcs12 (gnutls_certificate_credentials_t res,
1703 gnutls_pkcs12_t p12,
1704 const char *password,
1705 gnutls_x509_privkey_t * key,
1706 gnutls_x509_crt_t * cert, gnutls_x509_crl_t * crl)
1708 gnutls_pkcs12_bag_t bag = NULL;
1709 int index = 0;
1710 int ret;
1712 for (;;)
1714 int elements_in_bag;
1715 int i;
1717 ret = gnutls_pkcs12_bag_init (&bag);
1718 if (ret < 0)
1720 bag = NULL;
1721 gnutls_assert ();
1722 goto done;
1725 ret = gnutls_pkcs12_get_bag (p12, index, bag);
1726 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1727 break;
1728 if (ret < 0)
1730 gnutls_assert ();
1731 goto done;
1734 ret = gnutls_pkcs12_bag_get_type (bag, 0);
1735 if (ret < 0)
1737 gnutls_assert ();
1738 goto done;
1741 if (ret == GNUTLS_BAG_ENCRYPTED)
1743 ret = gnutls_pkcs12_bag_decrypt (bag, password);
1744 if (ret < 0)
1746 gnutls_assert ();
1747 goto done;
1751 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
1752 if (elements_in_bag < 0)
1754 gnutls_assert ();
1755 goto done;
1758 for (i = 0; i < elements_in_bag; i++)
1760 int type;
1761 gnutls_datum_t data;
1763 type = gnutls_pkcs12_bag_get_type (bag, i);
1764 if (type < 0)
1766 gnutls_assert ();
1767 goto done;
1770 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
1771 if (ret < 0)
1773 gnutls_assert ();
1774 goto done;
1777 switch (type)
1779 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
1780 case GNUTLS_BAG_PKCS8_KEY:
1781 ret = gnutls_x509_privkey_init (key);
1782 if (ret < 0)
1784 gnutls_assert ();
1785 goto done;
1788 ret = gnutls_x509_privkey_import_pkcs8
1789 (*key, &data, GNUTLS_X509_FMT_DER, password,
1790 type == GNUTLS_BAG_PKCS8_KEY ? GNUTLS_PKCS_PLAIN : 0);
1791 if (ret < 0)
1793 gnutls_assert ();
1794 goto done;
1796 break;
1798 case GNUTLS_BAG_CERTIFICATE:
1799 ret = gnutls_x509_crt_init (cert);
1800 if (ret < 0)
1802 gnutls_assert ();
1803 goto done;
1806 ret =
1807 gnutls_x509_crt_import (*cert, &data, GNUTLS_X509_FMT_DER);
1808 if (ret < 0)
1810 gnutls_assert ();
1811 goto done;
1813 break;
1815 case GNUTLS_BAG_CRL:
1816 ret = gnutls_x509_crl_init (crl);
1817 if (ret < 0)
1819 gnutls_assert ();
1820 goto done;
1823 ret = gnutls_x509_crl_import (*crl, &data, GNUTLS_X509_FMT_DER);
1824 if (ret < 0)
1826 gnutls_assert ();
1827 goto done;
1829 break;
1831 case GNUTLS_BAG_ENCRYPTED:
1832 /* XXX Bother to recurse one level down? Unlikely to
1833 use the same password anyway. */
1834 case GNUTLS_BAG_EMPTY:
1835 default:
1836 break;
1840 index++;
1841 gnutls_pkcs12_bag_deinit (bag);
1844 ret = 0;
1846 done:
1847 if (bag)
1848 gnutls_pkcs12_bag_deinit (bag);
1850 return ret;
1854 * gnutls_certificate_set_x509_simple_pkcs12_file:
1855 * @res: is an #gnutls_certificate_credentials_t structure.
1856 * @pkcs12file: filename of file containing PKCS#12 blob.
1857 * @type: is PEM or DER of the @pkcs12file.
1858 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
1860 * This function sets a certificate/private key pair and/or a CRL in
1861 * the gnutls_certificate_credentials_t structure. This function may
1862 * be called more than once (in case multiple keys/certificates exist
1863 * for the server).
1865 * MAC:ed PKCS#12 files are supported. Encrypted PKCS#12 bags are
1866 * supported. Encrypted PKCS#8 private keys are supported. However,
1867 * only password based security, and the same password for all
1868 * operations, are supported.
1870 * The private keys may be RSA PKCS#1 or DSA private keys encoded in
1871 * the OpenSSL way.
1873 * PKCS#12 file may contain many keys and/or certificates, and there
1874 * is no way to identify which key/certificate pair you want. You
1875 * should make sure the PKCS#12 file only contain one key/certificate
1876 * pair and/or one CRL.
1878 * It is believed that the limitations of this function is acceptable
1879 * for most usage, and that any more flexibility would introduce
1880 * complexity that would make it harder to use this functionality at
1881 * all.
1883 * Return value: Returns 0 on success, or an error code.
1886 gnutls_certificate_set_x509_simple_pkcs12_file
1887 (gnutls_certificate_credentials_t res, const char *pkcs12file,
1888 gnutls_x509_crt_fmt_t type, const char *password)
1890 gnutls_pkcs12_t p12;
1891 gnutls_datum_t p12blob;
1892 gnutls_x509_privkey_t key = NULL;
1893 gnutls_x509_crt_t cert = NULL;
1894 gnutls_x509_crl_t crl = NULL;
1895 int ret;
1896 size_t size;
1898 ret = gnutls_pkcs12_init (&p12);
1899 if (ret < 0)
1901 gnutls_assert ();
1902 return ret;
1905 p12blob.data = read_binary_file (pkcs12file, &size);
1906 p12blob.size = (unsigned int)size;
1907 if (p12blob.data == NULL)
1909 gnutls_assert ();
1910 gnutls_pkcs12_deinit (p12);
1911 return GNUTLS_E_FILE_ERROR;
1914 ret = gnutls_pkcs12_import (p12, &p12blob, type, 0);
1915 free (p12blob.data);
1916 if (ret < 0)
1918 gnutls_assert ();
1919 gnutls_pkcs12_deinit (p12);
1920 return ret;
1923 if (password)
1925 ret = gnutls_pkcs12_verify_mac (p12, password);
1926 if (ret < 0)
1928 gnutls_assert ();
1929 gnutls_pkcs12_deinit (p12);
1930 return ret;
1934 ret = parse_pkcs12 (res, p12, password, &key, &cert, &crl);
1935 gnutls_pkcs12_deinit (p12);
1936 if (ret < 0)
1938 gnutls_assert ();
1939 return ret;
1942 if (key && cert)
1944 ret = gnutls_certificate_set_x509_key (res, &cert, 1, key);
1945 if (ret < 0)
1947 gnutls_assert ();
1948 goto done;
1952 if (crl)
1954 ret = gnutls_certificate_set_x509_crl (res, &crl, 1);
1955 if (ret < 0)
1957 gnutls_assert ();
1958 goto done;
1962 ret = 0;
1964 done:
1965 if (cert)
1966 gnutls_x509_crt_deinit (cert);
1967 if (key)
1968 gnutls_x509_privkey_deinit (key);
1969 if (crl)
1970 gnutls_x509_crl_deinit (crl);
1972 return ret;
1977 * gnutls_certificate_free_crls - Used to free all the CRLs from a gnutls_certificate_credentials_t structure
1978 * @sc: is an #gnutls_certificate_credentials_t structure.
1980 * This function will delete all the CRLs associated
1981 * with the given credentials.
1984 void
1985 gnutls_certificate_free_crls (gnutls_certificate_credentials_t sc)
1987 unsigned j;
1989 for (j = 0; j < sc->x509_ncrls; j++)
1991 gnutls_x509_crl_deinit (sc->x509_crl_list[j]);
1994 sc->x509_ncrls = 0;
1996 gnutls_free (sc->x509_crl_list);
1997 sc->x509_crl_list = NULL;
2000 #endif