gnutls-cli: Fix uninitialized variable when PKCS#11 uris in use.
[gnutls.git] / lib / gnutls_x509.c
blob6ee0549c5cdcb73a2b40f1b3ad0f7ed08d2617fb
1 /*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 * Free Software Foundation, Inc.
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,
22 * USA
26 #include <gnutls_int.h>
27 #include "gnutls_auth.h"
28 #include "gnutls_errors.h"
29 #include <gnutls_cert.h>
30 #include <auth_cert.h>
31 #include "gnutls_dh.h"
32 #include "gnutls_num.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_int.h"
47 #include "read-file.h"
51 * some x509 certificate parsing functions.
54 /* Check if the number of bits of the key in the certificate
55 * is unacceptable.
57 inline static int
58 check_bits (gnutls_x509_crt_t crt, unsigned int max_bits)
60 int ret;
61 unsigned int bits;
63 ret = gnutls_x509_crt_get_pk_algorithm (crt, &bits);
64 if (ret < 0)
66 gnutls_assert ();
67 return ret;
70 if (bits > max_bits && max_bits > 0)
72 gnutls_assert ();
73 return GNUTLS_E_CONSTRAINT_ERROR;
76 return 0;
80 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) { \
81 if (peer_certificate_list[x]) \
82 gnutls_x509_crt_deinit(peer_certificate_list[x]); \
83 } \
84 gnutls_free( peer_certificate_list)
86 /*-
87 * _gnutls_x509_cert_verify_peers - return the peer's certificate status
88 * @session: is a gnutls session
90 * This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.).
91 * The return value (status) should be one of the gnutls_certificate_status_t enumerated elements.
92 * However you must also check the peer's name in order to check if the verified certificate belongs to the
93 * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
94 -*/
95 int
96 _gnutls_x509_cert_verify_peers (gnutls_session_t session,
97 unsigned int *status)
99 cert_auth_info_t info;
100 gnutls_certificate_credentials_t cred;
101 gnutls_x509_crt_t *peer_certificate_list;
102 int peer_certificate_list_size, i, x, ret;
104 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
106 info = _gnutls_get_auth_info (session);
107 if (info == NULL)
109 gnutls_assert ();
110 return GNUTLS_E_INVALID_REQUEST;
113 cred = (gnutls_certificate_credentials_t)
114 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
115 if (cred == NULL)
117 gnutls_assert ();
118 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
121 if (info->raw_certificate_list == NULL || info->ncerts == 0)
122 return GNUTLS_E_NO_CERTIFICATE_FOUND;
124 if (info->ncerts > cred->verify_depth && cred->verify_depth > 0)
126 gnutls_assert ();
127 return GNUTLS_E_CONSTRAINT_ERROR;
130 /* generate a list of gnutls_certs based on the auth info
131 * raw certs.
133 peer_certificate_list_size = info->ncerts;
134 peer_certificate_list =
135 gnutls_calloc (peer_certificate_list_size, sizeof (gnutls_x509_crt_t));
136 if (peer_certificate_list == NULL)
138 gnutls_assert ();
139 return GNUTLS_E_MEMORY_ERROR;
142 for (i = 0; i < peer_certificate_list_size; i++)
144 ret = gnutls_x509_crt_init (&peer_certificate_list[i]);
145 if (ret < 0)
147 gnutls_assert ();
148 CLEAR_CERTS;
149 return ret;
152 ret =
153 gnutls_x509_crt_import (peer_certificate_list[i],
154 &info->raw_certificate_list[i],
155 GNUTLS_X509_FMT_DER);
156 if (ret < 0)
158 gnutls_assert ();
159 CLEAR_CERTS;
160 return ret;
163 ret = check_bits (peer_certificate_list[i], cred->verify_bits);
164 if (ret < 0)
166 gnutls_assert ();
167 CLEAR_CERTS;
168 return ret;
173 /* Verify certificate
176 ret = gnutls_x509_crt_list_verify (peer_certificate_list,
177 peer_certificate_list_size,
178 cred->x509_ca_list, cred->x509_ncas,
179 cred->x509_crl_list, cred->x509_ncrls,
180 cred->verify_flags | session->internals.
181 priorities.additional_verify_flags,
182 status);
184 CLEAR_CERTS;
186 if (ret < 0)
188 gnutls_assert ();
189 return ret;
192 return 0;
196 * Read certificates and private keys, from files, memory etc.
199 /* returns error if the certificate has different algorithm than
200 * the given key parameters.
202 static int
203 _gnutls_check_key_cert_match (gnutls_certificate_credentials_t res)
205 unsigned int pk = res->cert_list[res->ncerts - 1][0].subject_pk_algorithm;
207 if (gnutls_privkey_get_pk_algorithm (res->pkey[res->ncerts - 1], NULL) !=
210 gnutls_assert ();
211 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
214 return 0;
217 /* Reads a DER encoded certificate list from memory and stores it to a
218 * gnutls_cert structure. Returns the number of certificates parsed.
220 static int
221 parse_der_cert_mem (gnutls_certificate_credentials_t res,
222 const void *input_cert, int input_cert_size)
224 gnutls_datum_t tmp;
225 gnutls_x509_crt_t crt;
226 gnutls_cert *ccert;
227 int ret;
229 ccert = gnutls_malloc (sizeof (*ccert));
230 if (ccert == NULL)
232 gnutls_assert ();
233 return GNUTLS_E_MEMORY_ERROR;
236 ret = gnutls_x509_crt_init (&crt);
237 if (ret < 0)
239 gnutls_assert ();
240 goto cleanup;
243 tmp.data = (opaque *) input_cert;
244 tmp.size = input_cert_size;
246 ret = gnutls_x509_crt_import (crt, &tmp, GNUTLS_X509_FMT_DER);
247 if (ret < 0)
249 gnutls_assert ();
250 gnutls_x509_crt_deinit (crt);
251 goto cleanup;
254 ret = _gnutls_x509_crt_to_gcert (ccert, crt, 0);
255 gnutls_x509_crt_deinit (crt);
257 if (ret < 0)
259 gnutls_assert ();
260 goto cleanup;
263 ret = certificate_credential_append_crt_list (res, ccert, 1);
264 if (ret < 0)
266 gnutls_assert ();
267 goto cleanup;
270 return ret;
272 cleanup:
273 gnutls_free (ccert);
274 return ret;
277 /* Reads a base64 encoded certificate list from memory and stores it to
278 * a gnutls_cert structure. Returns the number of certificate parsed.
280 static int
281 parse_pem_cert_mem (gnutls_certificate_credentials_t res,
282 const char *input_cert, int input_cert_size)
284 int size, siz2;
285 const char *ptr;
286 opaque *ptr2;
287 gnutls_datum_t tmp;
288 int ret, count, i;
289 gnutls_cert *certs = NULL;
291 /* move to the certificate
293 ptr = memmem (input_cert, input_cert_size,
294 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
295 if (ptr == NULL)
296 ptr = memmem (input_cert, input_cert_size,
297 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
299 if (ptr == NULL)
301 gnutls_assert ();
302 return GNUTLS_E_BASE64_DECODING_ERROR;
304 size = input_cert_size - (ptr - input_cert);
306 count = 0;
311 siz2 = _gnutls_fbase64_decode (NULL, ptr, size, &ptr2);
312 if (siz2 < 0)
314 gnutls_assert ();
315 ret = GNUTLS_E_BASE64_DECODING_ERROR;
316 goto cleanup;
319 certs = gnutls_realloc_fast (certs, (count + 1) * sizeof (gnutls_cert));
321 if (certs == NULL)
323 gnutls_assert ();
324 ret = GNUTLS_E_MEMORY_ERROR;
325 goto cleanup;
328 tmp.data = ptr2;
329 tmp.size = siz2;
331 ret = _gnutls_x509_raw_cert_to_gcert (&certs[count], &tmp, 0);
332 if (ret < 0)
334 gnutls_assert ();
335 goto cleanup;
338 _gnutls_free_datum (&tmp); /* free ptr2 */
340 /* now we move ptr after the pem header
342 ptr++;
343 /* find the next certificate (if any)
345 size = input_cert_size - (ptr - input_cert);
347 if (size > 0)
349 char *ptr3;
351 ptr3 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
352 if (ptr3 == NULL)
353 ptr3 = memmem (ptr, size, PEM_CERT_SEP2,
354 sizeof (PEM_CERT_SEP2) - 1);
356 ptr = ptr3;
358 else
359 ptr = NULL;
361 count++;
364 while (ptr != NULL);
366 ret = certificate_credential_append_crt_list (res, certs, count);
367 if (ret < 0)
369 gnutls_assert ();
370 goto cleanup;
373 return count;
375 cleanup:
376 for (i=0;i<count;i++)
377 _gnutls_gcert_deinit(&certs[i]);
378 gnutls_free(certs);
379 return ret;
384 /* Reads a DER or PEM certificate from memory
386 static int
387 read_cert_mem (gnutls_certificate_credentials_t res, const void *cert,
388 int cert_size, gnutls_x509_crt_fmt_t type)
390 int ret;
392 if (type == GNUTLS_X509_FMT_DER)
393 ret = parse_der_cert_mem (res, cert, cert_size);
394 else
395 ret = parse_pem_cert_mem (res, cert, cert_size);
397 if (ret < 0)
399 gnutls_assert ();
400 return ret;
403 return ret;
406 static int
407 _gnutls_x509_raw_privkey_to_privkey (gnutls_privkey_t * privkey,
408 const gnutls_datum_t * raw_key,
409 gnutls_x509_crt_fmt_t type)
411 gnutls_x509_privkey_t tmpkey;
412 int ret;
414 ret = gnutls_x509_privkey_init (&tmpkey);
415 if (ret < 0)
417 gnutls_assert ();
418 return ret;
421 ret = gnutls_x509_privkey_import (tmpkey, raw_key, type);
422 if (ret < 0)
424 gnutls_assert ();
425 gnutls_x509_privkey_deinit (tmpkey);
426 return ret;
429 ret = gnutls_privkey_init (privkey);
430 if (ret < 0)
432 gnutls_assert ();
433 gnutls_x509_privkey_deinit (tmpkey);
434 return ret;
437 ret =
438 gnutls_privkey_import_x509 (*privkey, tmpkey,
439 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
440 if (ret < 0)
442 gnutls_assert ();
443 gnutls_x509_privkey_deinit (tmpkey);
444 gnutls_privkey_deinit (*privkey);
445 return ret;
448 return 0;
451 /* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory. Type
452 * indicates the certificate format. KEY can be NULL, to indicate
453 * that GnuTLS doesn't know the private key.
455 static int
456 read_key_mem (gnutls_certificate_credentials_t res,
457 const void *key, int key_size, gnutls_x509_crt_fmt_t type)
459 int ret;
460 gnutls_datum_t tmp;
461 gnutls_privkey_t privkey;
463 if (key)
465 tmp.data = (opaque *) key;
466 tmp.size = key_size;
468 ret = _gnutls_x509_raw_privkey_to_privkey (&privkey, &tmp, type);
469 if (ret < 0)
471 gnutls_assert ();
472 return ret;
475 ret = certificate_credentials_append_pkey (res, privkey);
476 if (ret < 0)
478 gnutls_assert ();
479 gnutls_privkey_deinit (privkey);
480 return ret;
484 else
486 gnutls_assert ();
487 return GNUTLS_E_INVALID_REQUEST;
491 return 0;
494 /* Reads a private key from a token.
496 static int
497 read_key_url (gnutls_certificate_credentials_t res, const char *url)
499 int ret;
500 gnutls_pkcs11_privkey_t key1 = NULL;
501 gnutls_privkey_t pkey = NULL;
503 /* allocate space for the pkey list
506 ret = gnutls_pkcs11_privkey_init (&key1);
507 if (ret < 0)
509 gnutls_assert ();
510 return ret;
513 ret = gnutls_pkcs11_privkey_import_url (key1, url, 0);
514 if (ret < 0)
516 gnutls_assert ();
517 goto cleanup;
520 ret = gnutls_privkey_init (&pkey);
521 if (ret < 0)
523 gnutls_assert ();
524 goto cleanup;
527 ret =
528 gnutls_privkey_import_pkcs11 (pkey, key1,
529 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
530 if (ret < 0)
532 gnutls_assert ();
533 goto cleanup;
536 ret = certificate_credentials_append_pkey (res, pkey);
537 if (ret < 0)
539 gnutls_assert ();
540 goto cleanup;
543 return 0;
545 cleanup:
546 if (pkey)
547 gnutls_privkey_deinit (pkey);
549 if (key1)
550 gnutls_pkcs11_privkey_deinit (key1);
552 return ret;
555 /* Reads a private key from a token.
557 static int
558 read_cas_url (gnutls_certificate_credentials_t res, const char *url)
560 int ret;
561 gnutls_x509_crt_t *xcrt_list = NULL;
562 gnutls_pkcs11_obj_t *pcrt_list = NULL;
563 unsigned int pcrt_list_size = 0;
565 /* FIXME: should we use login? */
566 ret =
567 gnutls_pkcs11_obj_list_import_url (NULL, &pcrt_list_size, url,
568 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
569 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
571 gnutls_assert ();
572 return ret;
575 if (pcrt_list_size == 0)
577 gnutls_assert ();
578 return 0;
581 pcrt_list = gnutls_malloc (sizeof (*pcrt_list) * pcrt_list_size);
582 if (pcrt_list == NULL)
584 gnutls_assert ();
585 return GNUTLS_E_MEMORY_ERROR;
588 ret =
589 gnutls_pkcs11_obj_list_import_url (pcrt_list, &pcrt_list_size, url,
590 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
591 if (ret < 0)
593 gnutls_assert ();
594 goto cleanup;
597 xcrt_list = gnutls_malloc (sizeof (*xcrt_list) * pcrt_list_size);
598 if (xcrt_list == NULL)
600 gnutls_assert ();
601 ret = GNUTLS_E_MEMORY_ERROR;
602 goto cleanup;
605 ret =
606 gnutls_x509_crt_list_import_pkcs11 (xcrt_list, pcrt_list_size, pcrt_list,
608 if (xcrt_list == NULL)
610 gnutls_assert ();
611 ret = GNUTLS_E_MEMORY_ERROR;
612 goto cleanup;
615 res->x509_ca_list = xcrt_list;
616 res->x509_ncas = pcrt_list_size;
618 gnutls_free (pcrt_list);
620 return pcrt_list_size;
622 cleanup:
623 gnutls_free (xcrt_list);
624 gnutls_free (pcrt_list);
626 return ret;
631 /* Reads a private key from a token.
633 static int
634 read_cert_url (gnutls_certificate_credentials_t res, const char *url)
636 int ret;
637 gnutls_x509_crt_t crt;
638 gnutls_cert *ccert;
640 ccert = gnutls_malloc (sizeof (*ccert));
641 if (ccert == NULL)
643 gnutls_assert ();
644 return GNUTLS_E_MEMORY_ERROR;
647 ret = gnutls_x509_crt_init (&crt);
648 if (ret < 0)
650 gnutls_assert ();
651 gnutls_free (ccert);
652 return ret;
655 ret = gnutls_x509_crt_import_pkcs11_url (crt, url, 0);
656 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
657 ret =
658 gnutls_x509_crt_import_pkcs11_url (crt, url,
659 GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
661 if (ret < 0)
663 gnutls_assert ();
664 gnutls_free (ccert);
665 gnutls_x509_crt_deinit (crt);
666 return ret;
669 ret = _gnutls_x509_crt_to_gcert (ccert, crt, 0);
670 gnutls_x509_crt_deinit (crt);
672 if (ret < 0)
674 gnutls_assert ();
675 gnutls_free (ccert);
676 return ret;
679 ret = certificate_credential_append_crt_list (res, ccert, 1);
680 if (ret < 0)
682 gnutls_assert ();
683 gnutls_free (ccert);
684 return ret;
687 return 0;
691 /* Reads a certificate file
693 static int
694 read_cert_file (gnutls_certificate_credentials_t res,
695 const char *certfile, gnutls_x509_crt_fmt_t type)
697 int ret;
698 size_t size;
699 char *data;
701 if (strncmp (certfile, "pkcs11:", 7) == 0)
703 return read_cert_url (res, certfile);
706 data = read_binary_file (certfile, &size);
708 if (data == NULL)
710 gnutls_assert ();
711 return GNUTLS_E_FILE_ERROR;
714 ret = read_cert_mem (res, data, size, type);
715 free (data);
717 return ret;
723 /* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
724 * stores it).
726 static int
727 read_key_file (gnutls_certificate_credentials_t res,
728 const char *keyfile, gnutls_x509_crt_fmt_t type)
730 int ret;
731 size_t size;
732 char *data;
734 if (strncmp (keyfile, "pkcs11:", 7) == 0)
736 return read_key_url (res, keyfile);
739 data = read_binary_file (keyfile, &size);
741 if (data == NULL)
743 gnutls_assert ();
744 return GNUTLS_E_FILE_ERROR;
747 ret = read_key_mem (res, data, size, type);
748 free (data);
750 return ret;
754 * gnutls_certificate_set_x509_key_mem:
755 * @res: is a #gnutls_certificate_credentials_t structure.
756 * @cert: contains a certificate list (path) for the specified private key
757 * @key: is the private key, or %NULL
758 * @type: is PEM or DER
760 * This function sets a certificate/private key pair in the
761 * gnutls_certificate_credentials_t structure. This function may be called
762 * more than once (in case multiple keys/certificates exist for the
763 * server).
765 * Currently are supported: RSA PKCS-1 encoded private keys,
766 * DSA private keys.
768 * DSA private keys are encoded the OpenSSL way, which is an ASN.1
769 * DER sequence of 6 INTEGERs - version, p, q, g, pub, priv.
771 * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
772 * is supported. This means that certificates intended for signing cannot
773 * be used for ciphersuites that require encryption.
775 * If the certificate and the private key are given in PEM encoding
776 * then the strings that hold their values must be null terminated.
778 * The @key may be %NULL if you are using a sign callback, see
779 * gnutls_sign_callback_set().
781 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
784 gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t res,
785 const gnutls_datum_t * cert,
786 const gnutls_datum_t * key,
787 gnutls_x509_crt_fmt_t type)
789 int ret;
791 /* this should be first
793 if ((ret = read_key_mem (res, key ? key->data : NULL,
794 key ? key->size : 0, type)) < 0)
795 return ret;
797 if ((ret = read_cert_mem (res, cert->data, cert->size, type)) < 0)
798 return ret;
800 res->ncerts++;
802 if (key && (ret = _gnutls_check_key_cert_match (res)) < 0)
804 gnutls_assert ();
805 return ret;
808 return 0;
811 static int check_if_sorted(gnutls_cert * crt, int nr)
813 gnutls_x509_crt_t x509;
814 char prev_dn[MAX_DN];
815 char dn[MAX_DN];
816 size_t prev_dn_size, dn_size;
817 int i, ret;
819 /* check if the X.509 list is ordered */
820 if (nr > 1 && crt[0].cert_type == GNUTLS_CRT_X509)
823 for (i=0;i<nr;i++)
825 ret = gnutls_x509_crt_init(&x509);
826 if (ret < 0)
827 return gnutls_assert_val(ret);
829 ret = gnutls_x509_crt_import(x509, &crt[i].raw, GNUTLS_X509_FMT_DER);
830 if (ret < 0)
832 ret = gnutls_assert_val(ret);
833 goto cleanup;
836 if (i>0)
838 dn_size = sizeof(dn);
839 ret = gnutls_x509_crt_get_dn(x509, dn, &dn_size);
840 if (ret < 0)
842 ret = gnutls_assert_val(ret);
843 goto cleanup;
846 if (dn_size != prev_dn_size || memcmp(dn, prev_dn, dn_size) != 0)
848 ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
849 goto cleanup;
853 prev_dn_size = sizeof(prev_dn);
854 ret = gnutls_x509_crt_get_issuer_dn(x509, prev_dn, &prev_dn_size);
855 if (ret < 0)
857 ret = gnutls_assert_val(ret);
858 goto cleanup;
861 gnutls_x509_crt_deinit(x509);
865 return 0;
867 cleanup:
868 gnutls_x509_crt_deinit(x509);
869 return ret;
873 certificate_credential_append_crt_list (gnutls_certificate_credentials_t res,
874 gnutls_cert * crt, int nr)
876 int ret;
878 ret = check_if_sorted(crt, nr);
879 if (ret < 0)
880 return gnutls_assert_val(ret);
882 res->cert_list = gnutls_realloc_fast (res->cert_list,
883 (1 +
884 res->ncerts) *
885 sizeof (gnutls_cert *));
886 if (res->cert_list == NULL)
888 gnutls_assert ();
889 return GNUTLS_E_MEMORY_ERROR;
892 res->cert_list_length = gnutls_realloc_fast (res->cert_list_length,
893 (1 +
894 res->ncerts) * sizeof (int));
895 if (res->cert_list_length == NULL)
897 gnutls_assert ();
898 return GNUTLS_E_MEMORY_ERROR;
901 res->cert_list[res->ncerts] = crt;
902 res->cert_list_length[res->ncerts] = nr;
904 return 0;
909 certificate_credentials_append_pkey (gnutls_certificate_credentials_t res,
910 gnutls_privkey_t pkey)
912 res->pkey = gnutls_realloc_fast (res->pkey,
913 (1 + res->ncerts) *
914 sizeof (gnutls_privkey_t));
915 if (res->pkey == NULL)
917 gnutls_assert ();
918 return GNUTLS_E_MEMORY_ERROR;
920 res->pkey[res->ncerts] = pkey;
921 return 0;
926 * gnutls_certificate_set_x509_key:
927 * @res: is a #gnutls_certificate_credentials_t structure.
928 * @cert_list: contains a certificate list (path) for the specified private key
929 * @cert_list_size: holds the size of the certificate list
930 * @key: is a gnutls_x509_privkey_t key
932 * This function sets a certificate/private key pair in the
933 * gnutls_certificate_credentials_t structure. This function may be
934 * called more than once (in case multiple keys/certificates exist for
935 * the server). For clients that wants to send more than its own end
936 * entity certificate (e.g., also an intermediate CA cert) then put
937 * the certificate chain in @cert_list.
941 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
943 * Since: 2.4.0
946 gnutls_certificate_set_x509_key (gnutls_certificate_credentials_t res,
947 gnutls_x509_crt_t * cert_list,
948 int cert_list_size,
949 gnutls_x509_privkey_t key)
951 int ret, i;
952 gnutls_privkey_t pkey;
953 gnutls_cert *pcerts = NULL;
955 /* this should be first
957 ret = gnutls_privkey_init (&pkey);
958 if (ret < 0)
960 gnutls_assert ();
961 return ret;
964 ret = gnutls_privkey_import_x509 (pkey, key, 0);
965 if (ret < 0)
967 gnutls_assert ();
968 return ret;
971 ret = certificate_credentials_append_pkey (res, pkey);
972 if (ret < 0)
974 gnutls_assert ();
975 return ret;
978 /* load certificates */
979 pcerts = gnutls_malloc (sizeof (gnutls_cert) * cert_list_size);
980 if (pcerts == NULL)
982 gnutls_assert ();
983 return GNUTLS_E_MEMORY_ERROR;
986 for (i = 0; i < cert_list_size; i++)
988 ret = _gnutls_x509_crt_to_gcert (&pcerts[i], cert_list[i], 0);
989 if (ret < 0)
991 gnutls_assert ();
992 return ret;
996 ret = certificate_credential_append_crt_list (res, pcerts, cert_list_size);
997 if (ret < 0)
999 gnutls_assert ();
1000 return ret;
1003 res->ncerts++;
1005 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1007 gnutls_assert ();
1008 return ret;
1011 return 0;
1015 * gnutls_certificate_set_x509_key_file:
1016 * @res: is a #gnutls_certificate_credentials_t structure.
1017 * @certfile: is a file that containing the certificate list (path) for
1018 * the specified private key, in PKCS7 format, or a list of certificates
1019 * @keyfile: is a file that contains the private key
1020 * @type: is PEM or DER
1022 * This function sets a certificate/private key pair in the
1023 * gnutls_certificate_credentials_t structure. This function may be
1024 * called more than once (in case multiple keys/certificates exist for
1025 * the server). For clients that wants to send more than its own end
1026 * entity certificate (e.g., also an intermediate CA cert) then put
1027 * the certificate chain in @certfile.
1029 * Currently only PKCS-1 encoded RSA and DSA private keys are accepted by
1030 * this function.
1032 * This function can also accept PKCS #11 URLs. In that case it
1033 * will import the private key and certificate indicated by the urls.
1035 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1038 gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t res,
1039 const char *certfile,
1040 const char *keyfile,
1041 gnutls_x509_crt_fmt_t type)
1043 int ret;
1045 /* this should be first
1047 if ((ret = read_key_file (res, keyfile, type)) < 0)
1048 return ret;
1050 if ((ret = read_cert_file (res, certfile, type)) < 0)
1051 return ret;
1053 res->ncerts++;
1055 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1057 gnutls_assert ();
1058 return ret;
1061 return 0;
1064 static int
1065 add_new_crt_to_rdn_seq (gnutls_certificate_credentials_t res, int new)
1067 gnutls_datum_t tmp;
1068 int ret;
1069 size_t newsize;
1070 unsigned char *newdata;
1071 unsigned i;
1073 /* Add DN of the last added CAs to the RDN sequence
1074 * This will be sent to clients when a certificate
1075 * request message is sent.
1078 /* FIXME: in case of a client it is not needed
1079 * to do that. This would save time and memory.
1080 * However we don't have that information available
1081 * here.
1082 * Further, this function is now much more efficient,
1083 * so optimizing that is less important.
1086 for (i = res->x509_ncas - new; i < res->x509_ncas; i++)
1088 if ((ret = gnutls_x509_crt_get_raw_dn (res->x509_ca_list[i], &tmp)) < 0)
1090 gnutls_assert ();
1091 return ret;
1094 newsize = res->x509_rdn_sequence.size + 2 + tmp.size;
1095 if (newsize < res->x509_rdn_sequence.size)
1097 gnutls_assert ();
1098 _gnutls_free_datum (&tmp);
1099 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1102 newdata = gnutls_realloc (res->x509_rdn_sequence.data, newsize);
1103 if (newdata == NULL)
1105 gnutls_assert ();
1106 _gnutls_free_datum (&tmp);
1107 return GNUTLS_E_MEMORY_ERROR;
1110 _gnutls_write_datum16 (newdata + res->x509_rdn_sequence.size, tmp);
1111 _gnutls_free_datum (&tmp);
1113 res->x509_rdn_sequence.size = newsize;
1114 res->x509_rdn_sequence.data = newdata;
1117 return 0;
1120 /* Returns 0 if it's ok to use the gnutls_kx_algorithm_t with this
1121 * certificate (uses the KeyUsage field).
1124 _gnutls_check_key_usage (const gnutls_cert * cert, gnutls_kx_algorithm_t alg)
1126 unsigned int key_usage = 0;
1127 int encipher_type;
1129 if (cert == NULL)
1131 gnutls_assert ();
1132 return GNUTLS_E_INTERNAL_ERROR;
1135 if (_gnutls_map_kx_get_cred (alg, 1) == GNUTLS_CRD_CERTIFICATE ||
1136 _gnutls_map_kx_get_cred (alg, 0) == GNUTLS_CRD_CERTIFICATE)
1139 key_usage = cert->key_usage;
1141 encipher_type = _gnutls_kx_encipher_type (alg);
1143 if (key_usage != 0 && encipher_type != CIPHER_IGN)
1145 /* If key_usage has been set in the certificate
1148 if (encipher_type == CIPHER_ENCRYPT)
1150 /* If the key exchange method requires an encipher
1151 * type algorithm, and key's usage does not permit
1152 * encipherment, then fail.
1154 if (!(key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT))
1156 gnutls_assert ();
1157 return GNUTLS_E_KEY_USAGE_VIOLATION;
1161 if (encipher_type == CIPHER_SIGN)
1163 /* The same as above, but for sign only keys
1165 if (!(key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE))
1167 gnutls_assert ();
1168 return GNUTLS_E_KEY_USAGE_VIOLATION;
1173 return 0;
1178 static int
1179 parse_pem_ca_mem (gnutls_x509_crt_t ** cert_list, unsigned *ncerts,
1180 const opaque * input_cert, int input_cert_size)
1182 int i, size;
1183 const opaque *ptr;
1184 gnutls_datum_t tmp;
1185 int ret, count;
1187 /* move to the certificate
1189 ptr = memmem (input_cert, input_cert_size,
1190 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
1191 if (ptr == NULL)
1192 ptr = memmem (input_cert, input_cert_size,
1193 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
1195 if (ptr == NULL)
1197 gnutls_assert ();
1198 return GNUTLS_E_BASE64_DECODING_ERROR;
1200 size = input_cert_size - (ptr - input_cert);
1202 i = *ncerts + 1;
1203 count = 0;
1208 *cert_list =
1209 (gnutls_x509_crt_t *) gnutls_realloc_fast (*cert_list,
1211 sizeof
1212 (gnutls_x509_crt_t));
1214 if (*cert_list == NULL)
1216 gnutls_assert ();
1217 return GNUTLS_E_MEMORY_ERROR;
1220 ret = gnutls_x509_crt_init (&cert_list[0][i - 1]);
1221 if (ret < 0)
1223 gnutls_assert ();
1224 return ret;
1227 tmp.data = (opaque *) ptr;
1228 tmp.size = size;
1230 ret =
1231 gnutls_x509_crt_import (cert_list[0][i - 1],
1232 &tmp, GNUTLS_X509_FMT_PEM);
1233 if (ret < 0)
1235 gnutls_assert ();
1236 return ret;
1239 /* now we move ptr after the pem header
1241 ptr++;
1242 size--;
1243 /* find the next certificate (if any)
1246 if (size > 0)
1248 char *ptr3;
1250 ptr3 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
1251 if (ptr3 == NULL)
1252 ptr3 = memmem (ptr, size,
1253 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
1255 ptr = ptr3;
1256 size = input_cert_size - (ptr - input_cert);
1258 else
1259 ptr = NULL;
1261 i++;
1262 count++;
1265 while (ptr != NULL);
1267 *ncerts = i - 1;
1269 return count;
1272 /* Reads a DER encoded certificate list from memory and stores it to a
1273 * gnutls_cert structure. Returns the number of certificates parsed.
1275 static int
1276 parse_der_ca_mem (gnutls_x509_crt_t ** cert_list, unsigned *ncerts,
1277 const void *input_cert, int input_cert_size)
1279 int i;
1280 gnutls_datum_t tmp;
1281 int ret;
1283 i = *ncerts + 1;
1285 *cert_list =
1286 (gnutls_x509_crt_t *) gnutls_realloc_fast (*cert_list,
1288 sizeof (gnutls_x509_crt_t));
1290 if (*cert_list == NULL)
1292 gnutls_assert ();
1293 return GNUTLS_E_MEMORY_ERROR;
1296 tmp.data = (opaque *) input_cert;
1297 tmp.size = input_cert_size;
1299 ret = gnutls_x509_crt_init (&cert_list[0][i - 1]);
1300 if (ret < 0)
1302 gnutls_assert ();
1303 return ret;
1306 ret =
1307 gnutls_x509_crt_import (cert_list[0][i - 1], &tmp, GNUTLS_X509_FMT_DER);
1308 if (ret < 0)
1310 gnutls_assert ();
1311 return ret;
1314 *ncerts = i;
1316 return 1; /* one certificate parsed */
1320 * gnutls_certificate_set_x509_trust_mem:
1321 * @res: is a #gnutls_certificate_credentials_t structure.
1322 * @ca: is a list of trusted CAs or a DER certificate
1323 * @type: is DER or PEM
1325 * This function adds the trusted CAs in order to verify client or
1326 * server certificates. In case of a client this is not required to be
1327 * called if the certificates are not verified using
1328 * gnutls_certificate_verify_peers2(). This function may be called
1329 * multiple times.
1331 * In case of a server the CAs set here will be sent to the client if
1332 * a certificate request is sent. This can be disabled using
1333 * gnutls_certificate_send_x509_rdn_sequence().
1335 * Returns: the number of certificates processed or a negative value
1336 * on error.
1339 gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t res,
1340 const gnutls_datum_t * ca,
1341 gnutls_x509_crt_fmt_t type)
1343 int ret, ret2;
1345 if (type == GNUTLS_X509_FMT_DER)
1346 ret = parse_der_ca_mem (&res->x509_ca_list, &res->x509_ncas,
1347 ca->data, ca->size);
1348 else
1349 ret = parse_pem_ca_mem (&res->x509_ca_list, &res->x509_ncas,
1350 ca->data, ca->size);
1352 if ((ret2 = add_new_crt_to_rdn_seq (res, ret)) < 0)
1353 return ret2;
1355 return ret;
1359 * gnutls_certificate_set_x509_trust:
1360 * @res: is a #gnutls_certificate_credentials_t structure.
1361 * @ca_list: is a list of trusted CAs
1362 * @ca_list_size: holds the size of the CA list
1364 * This function adds the trusted CAs in order to verify client
1365 * or server certificates. In case of a client this is not required
1366 * to be called if the certificates are not verified using
1367 * gnutls_certificate_verify_peers2().
1368 * This function may be called multiple times.
1370 * In case of a server the CAs set here will be sent to the client if
1371 * a certificate request is sent. This can be disabled using
1372 * gnutls_certificate_send_x509_rdn_sequence().
1374 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1376 * Since: 2.4.0
1379 gnutls_certificate_set_x509_trust (gnutls_certificate_credentials_t res,
1380 gnutls_x509_crt_t * ca_list,
1381 int ca_list_size)
1383 int ret, i, ret2;
1385 res->x509_ca_list = gnutls_realloc_fast (res->x509_ca_list,
1386 (ca_list_size +
1387 res->x509_ncas) *
1388 sizeof (gnutls_x509_crt_t));
1389 if (res->x509_ca_list == NULL)
1391 gnutls_assert ();
1392 return GNUTLS_E_MEMORY_ERROR;
1395 for (i = 0; i < ca_list_size; i++)
1397 ret = gnutls_x509_crt_init (&res->x509_ca_list[res->x509_ncas]);
1398 if (ret < 0)
1400 gnutls_assert ();
1401 return ret;
1404 ret = _gnutls_x509_crt_cpy (res->x509_ca_list[res->x509_ncas],
1405 ca_list[i]);
1406 if (ret < 0)
1408 gnutls_assert ();
1409 gnutls_x509_crt_deinit (res->x509_ca_list[res->x509_ncas]);
1410 return ret;
1412 res->x509_ncas++;
1415 if ((ret2 = add_new_crt_to_rdn_seq (res, ca_list_size)) < 0)
1416 return ret2;
1418 return 0;
1422 * gnutls_certificate_set_x509_trust_file:
1423 * @res: is a #gnutls_certificate_credentials_t structure.
1424 * @cafile: is a file containing the list of trusted CAs (DER or PEM list)
1425 * @type: is PEM or DER
1427 * This function adds the trusted CAs in order to verify client or
1428 * server certificates. In case of a client this is not required to
1429 * be called if the certificates are not verified using
1430 * gnutls_certificate_verify_peers2(). This function may be called
1431 * multiple times.
1433 * In case of a server the names of the CAs set here will be sent to
1434 * the client if a certificate request is sent. This can be disabled
1435 * using gnutls_certificate_send_x509_rdn_sequence().
1437 * This function can also accept PKCS #11 URLs. In that case it
1438 * will import all certificates that are marked as trusted.
1440 * Returns: number of certificates processed, or a negative value on
1441 * error.
1444 gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t res,
1445 const char *cafile,
1446 gnutls_x509_crt_fmt_t type)
1448 int ret, ret2;
1449 size_t size;
1450 char *data;
1452 if (strncmp (cafile, "pkcs11:", 7) == 0)
1454 return read_cas_url (res, cafile);
1457 data = read_binary_file (cafile, &size);
1458 if (data == NULL)
1460 gnutls_assert ();
1461 return GNUTLS_E_FILE_ERROR;
1464 if (type == GNUTLS_X509_FMT_DER)
1465 ret = parse_der_ca_mem (&res->x509_ca_list, &res->x509_ncas, data, size);
1466 else
1467 ret = parse_pem_ca_mem (&res->x509_ca_list, &res->x509_ncas, data, size);
1469 free (data);
1471 if (ret < 0)
1473 gnutls_assert ();
1474 return ret;
1477 if ((ret2 = add_new_crt_to_rdn_seq (res, ret)) < 0)
1478 return ret2;
1480 return ret;
1483 #ifdef ENABLE_PKI
1485 static int
1486 parse_pem_crl_mem (gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
1487 const opaque * input_crl, int input_crl_size)
1489 int size, i;
1490 const opaque *ptr;
1491 gnutls_datum_t tmp;
1492 int ret, count;
1494 /* move to the certificate
1496 ptr = memmem (input_crl, input_crl_size,
1497 PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
1498 if (ptr == NULL)
1500 gnutls_assert ();
1501 return GNUTLS_E_BASE64_DECODING_ERROR;
1504 size = input_crl_size - (ptr - input_crl);
1506 i = *ncrls + 1;
1507 count = 0;
1512 *crl_list =
1513 (gnutls_x509_crl_t *) gnutls_realloc_fast (*crl_list,
1515 sizeof
1516 (gnutls_x509_crl_t));
1518 if (*crl_list == NULL)
1520 gnutls_assert ();
1521 return GNUTLS_E_MEMORY_ERROR;
1524 ret = gnutls_x509_crl_init (&crl_list[0][i - 1]);
1525 if (ret < 0)
1527 gnutls_assert ();
1528 return ret;
1531 tmp.data = (char *) ptr;
1532 tmp.size = size;
1534 ret =
1535 gnutls_x509_crl_import (crl_list[0][i - 1],
1536 &tmp, GNUTLS_X509_FMT_PEM);
1537 if (ret < 0)
1539 gnutls_assert ();
1540 return ret;
1543 /* now we move ptr after the pem header
1545 ptr++;
1546 /* find the next certificate (if any)
1549 size = input_crl_size - (ptr - input_crl);
1551 if (size > 0)
1552 ptr = memmem (ptr, size, PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
1553 else
1554 ptr = NULL;
1555 i++;
1556 count++;
1559 while (ptr != NULL);
1561 *ncrls = i - 1;
1563 return count;
1566 /* Reads a DER encoded certificate list from memory and stores it to a
1567 * gnutls_cert structure. Returns the number of certificates parsed.
1569 static int
1570 parse_der_crl_mem (gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
1571 const void *input_crl, int input_crl_size)
1573 int i;
1574 gnutls_datum_t tmp;
1575 int ret;
1577 i = *ncrls + 1;
1579 *crl_list =
1580 (gnutls_x509_crl_t *) gnutls_realloc_fast (*crl_list,
1582 sizeof (gnutls_x509_crl_t));
1584 if (*crl_list == NULL)
1586 gnutls_assert ();
1587 return GNUTLS_E_MEMORY_ERROR;
1590 tmp.data = (opaque *) input_crl;
1591 tmp.size = input_crl_size;
1593 ret = gnutls_x509_crl_init (&crl_list[0][i - 1]);
1594 if (ret < 0)
1596 gnutls_assert ();
1597 return ret;
1600 ret =
1601 gnutls_x509_crl_import (crl_list[0][i - 1], &tmp, GNUTLS_X509_FMT_DER);
1602 if (ret < 0)
1604 gnutls_assert ();
1605 return ret;
1608 *ncrls = i;
1610 return 1; /* one certificate parsed */
1614 /* Reads a DER or PEM CRL from memory
1616 static int
1617 read_crl_mem (gnutls_certificate_credentials_t res, const void *crl,
1618 int crl_size, gnutls_x509_crt_fmt_t type)
1620 int ret;
1622 /* allocate space for the certificate to add
1624 res->x509_crl_list = gnutls_realloc_fast (res->x509_crl_list,
1625 (1 +
1626 res->x509_ncrls) *
1627 sizeof (gnutls_x509_crl_t));
1628 if (res->x509_crl_list == NULL)
1630 gnutls_assert ();
1631 return GNUTLS_E_MEMORY_ERROR;
1634 if (type == GNUTLS_X509_FMT_DER)
1635 ret = parse_der_crl_mem (&res->x509_crl_list,
1636 &res->x509_ncrls, crl, crl_size);
1637 else
1638 ret = parse_pem_crl_mem (&res->x509_crl_list,
1639 &res->x509_ncrls, crl, crl_size);
1641 if (ret < 0)
1643 gnutls_assert ();
1644 return ret;
1647 return ret;
1651 * gnutls_certificate_set_x509_crl_mem:
1652 * @res: is a #gnutls_certificate_credentials_t structure.
1653 * @CRL: is a list of trusted CRLs. They should have been verified before.
1654 * @type: is DER or PEM
1656 * This function adds the trusted CRLs in order to verify client or
1657 * server certificates. In case of a client this is not required to
1658 * be called if the certificates are not verified using
1659 * gnutls_certificate_verify_peers2(). This function may be called
1660 * multiple times.
1662 * Returns: number of CRLs processed, or a negative value on error.
1665 gnutls_certificate_set_x509_crl_mem (gnutls_certificate_credentials_t res,
1666 const gnutls_datum_t * CRL,
1667 gnutls_x509_crt_fmt_t type)
1669 int ret;
1671 if ((ret = read_crl_mem (res, CRL->data, CRL->size, type)) < 0)
1672 return ret;
1674 return ret;
1678 * gnutls_certificate_set_x509_crl:
1679 * @res: is a #gnutls_certificate_credentials_t structure.
1680 * @crl_list: is a list of trusted CRLs. They should have been verified before.
1681 * @crl_list_size: holds the size of the crl_list
1683 * This function adds the trusted CRLs in order to verify client or
1684 * server certificates. In case of a client this is not required to
1685 * be called if the certificates are not verified using
1686 * gnutls_certificate_verify_peers2(). This function may be called
1687 * multiple times.
1689 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1691 * Since: 2.4.0
1694 gnutls_certificate_set_x509_crl (gnutls_certificate_credentials_t res,
1695 gnutls_x509_crl_t * crl_list,
1696 int crl_list_size)
1698 int ret, i;
1700 res->x509_crl_list = gnutls_realloc_fast (res->x509_crl_list,
1701 (crl_list_size +
1702 res->x509_ncrls) *
1703 sizeof (gnutls_x509_crl_t));
1704 if (res->x509_crl_list == NULL)
1706 gnutls_assert ();
1707 return GNUTLS_E_MEMORY_ERROR;
1710 for (i = 0; i < crl_list_size; i++)
1712 ret = gnutls_x509_crl_init (&res->x509_crl_list[res->x509_ncrls]);
1713 if (ret < 0)
1715 gnutls_assert ();
1716 return ret;
1719 ret = _gnutls_x509_crl_cpy (res->x509_crl_list[res->x509_ncrls],
1720 crl_list[i]);
1721 if (ret < 0)
1723 gnutls_assert ();
1724 return ret;
1726 res->x509_ncrls++;
1729 return 0;
1733 * gnutls_certificate_set_x509_crl_file:
1734 * @res: is a #gnutls_certificate_credentials_t structure.
1735 * @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
1736 * @type: is PEM or DER
1738 * This function adds the trusted CRLs in order to verify client or server
1739 * certificates. In case of a client this is not required
1740 * to be called if the certificates are not verified using
1741 * gnutls_certificate_verify_peers2().
1742 * This function may be called multiple times.
1744 * Returns: number of CRLs processed or a negative value on error.
1747 gnutls_certificate_set_x509_crl_file (gnutls_certificate_credentials_t res,
1748 const char *crlfile,
1749 gnutls_x509_crt_fmt_t type)
1751 int ret;
1752 size_t size;
1753 char *data = read_binary_file (crlfile, &size);
1755 if (data == NULL)
1757 gnutls_assert ();
1758 return GNUTLS_E_FILE_ERROR;
1761 if (type == GNUTLS_X509_FMT_DER)
1762 ret = parse_der_crl_mem (&res->x509_crl_list, &res->x509_ncrls,
1763 data, size);
1764 else
1765 ret = parse_pem_crl_mem (&res->x509_crl_list, &res->x509_ncrls,
1766 data, size);
1768 free (data);
1770 if (ret < 0)
1772 gnutls_assert ();
1773 return ret;
1776 return ret;
1779 #include <gnutls/pkcs12.h>
1781 static int
1782 parse_pkcs12 (gnutls_certificate_credentials_t res,
1783 gnutls_pkcs12_t p12,
1784 const char *password,
1785 gnutls_x509_privkey_t * key,
1786 gnutls_x509_crt_t * cert, gnutls_x509_crl_t * crl)
1788 gnutls_pkcs12_bag_t bag = NULL;
1789 int idx = 0;
1790 int ret;
1791 size_t cert_id_size = 0;
1792 size_t key_id_size = 0;
1793 opaque cert_id[20];
1794 opaque key_id[20];
1795 int privkey_ok = 0;
1797 *cert = NULL;
1798 *key = NULL;
1799 *crl = NULL;
1801 /* find the first private key */
1802 for (;;)
1804 int elements_in_bag;
1805 int i;
1807 ret = gnutls_pkcs12_bag_init (&bag);
1808 if (ret < 0)
1810 bag = NULL;
1811 gnutls_assert ();
1812 goto done;
1815 ret = gnutls_pkcs12_get_bag (p12, idx, bag);
1816 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1817 break;
1818 if (ret < 0)
1820 gnutls_assert ();
1821 goto done;
1824 ret = gnutls_pkcs12_bag_get_type (bag, 0);
1825 if (ret < 0)
1827 gnutls_assert ();
1828 goto done;
1831 if (ret == GNUTLS_BAG_ENCRYPTED)
1833 ret = gnutls_pkcs12_bag_decrypt (bag, password);
1834 if (ret < 0)
1836 gnutls_assert ();
1837 goto done;
1841 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
1842 if (elements_in_bag < 0)
1844 gnutls_assert ();
1845 goto done;
1848 for (i = 0; i < elements_in_bag; i++)
1850 int type;
1851 gnutls_datum_t data;
1853 type = gnutls_pkcs12_bag_get_type (bag, i);
1854 if (type < 0)
1856 gnutls_assert ();
1857 goto done;
1860 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
1861 if (ret < 0)
1863 gnutls_assert ();
1864 goto done;
1867 switch (type)
1869 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
1870 case GNUTLS_BAG_PKCS8_KEY:
1871 if (*key != NULL) /* too simple to continue */
1873 gnutls_assert ();
1874 break;
1877 ret = gnutls_x509_privkey_init (key);
1878 if (ret < 0)
1880 gnutls_assert ();
1881 goto done;
1884 ret = gnutls_x509_privkey_import_pkcs8
1885 (*key, &data, GNUTLS_X509_FMT_DER, password,
1886 type == GNUTLS_BAG_PKCS8_KEY ? GNUTLS_PKCS_PLAIN : 0);
1887 if (ret < 0)
1889 gnutls_assert ();
1890 gnutls_x509_privkey_deinit (*key);
1891 goto done;
1894 key_id_size = sizeof (key_id);
1895 ret =
1896 gnutls_x509_privkey_get_key_id (*key, 0, key_id,
1897 &key_id_size);
1898 if (ret < 0)
1900 gnutls_assert ();
1901 gnutls_x509_privkey_deinit (*key);
1902 goto done;
1905 privkey_ok = 1; /* break */
1906 break;
1907 default:
1908 break;
1912 idx++;
1913 gnutls_pkcs12_bag_deinit (bag);
1915 if (privkey_ok != 0) /* private key was found */
1916 break;
1919 if (privkey_ok == 0) /* no private key */
1921 gnutls_assert ();
1922 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1925 /* now find the corresponding certificate
1927 idx = 0;
1928 bag = NULL;
1929 for (;;)
1931 int elements_in_bag;
1932 int i;
1934 ret = gnutls_pkcs12_bag_init (&bag);
1935 if (ret < 0)
1937 bag = NULL;
1938 gnutls_assert ();
1939 goto done;
1942 ret = gnutls_pkcs12_get_bag (p12, idx, bag);
1943 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1944 break;
1945 if (ret < 0)
1947 gnutls_assert ();
1948 goto done;
1951 ret = gnutls_pkcs12_bag_get_type (bag, 0);
1952 if (ret < 0)
1954 gnutls_assert ();
1955 goto done;
1958 if (ret == GNUTLS_BAG_ENCRYPTED)
1960 ret = gnutls_pkcs12_bag_decrypt (bag, password);
1961 if (ret < 0)
1963 gnutls_assert ();
1964 goto done;
1968 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
1969 if (elements_in_bag < 0)
1971 gnutls_assert ();
1972 goto done;
1975 for (i = 0; i < elements_in_bag; i++)
1977 int type;
1978 gnutls_datum_t data;
1980 type = gnutls_pkcs12_bag_get_type (bag, i);
1981 if (type < 0)
1983 gnutls_assert ();
1984 goto done;
1987 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
1988 if (ret < 0)
1990 gnutls_assert ();
1991 goto done;
1994 switch (type)
1996 case GNUTLS_BAG_CERTIFICATE:
1997 if (*cert != NULL) /* no need to set it again */
1999 gnutls_assert ();
2000 break;
2003 ret = gnutls_x509_crt_init (cert);
2004 if (ret < 0)
2006 gnutls_assert ();
2007 goto done;
2010 ret =
2011 gnutls_x509_crt_import (*cert, &data, GNUTLS_X509_FMT_DER);
2012 if (ret < 0)
2014 gnutls_assert ();
2015 gnutls_x509_crt_deinit (*cert);
2016 goto done;
2019 /* check if the key id match */
2020 cert_id_size = sizeof (cert_id);
2021 ret =
2022 gnutls_x509_crt_get_key_id (*cert, 0, cert_id, &cert_id_size);
2023 if (ret < 0)
2025 gnutls_assert ();
2026 gnutls_x509_crt_deinit (*cert);
2027 goto done;
2030 if (memcmp (cert_id, key_id, cert_id_size) != 0)
2031 { /* they don't match - skip the certificate */
2032 gnutls_x509_crt_deinit (*cert);
2033 *cert = NULL;
2035 break;
2037 case GNUTLS_BAG_CRL:
2038 if (*crl != NULL)
2040 gnutls_assert ();
2041 break;
2044 ret = gnutls_x509_crl_init (crl);
2045 if (ret < 0)
2047 gnutls_assert ();
2048 goto done;
2051 ret = gnutls_x509_crl_import (*crl, &data, GNUTLS_X509_FMT_DER);
2052 if (ret < 0)
2054 gnutls_assert ();
2055 gnutls_x509_crl_deinit (*crl);
2056 goto done;
2058 break;
2060 case GNUTLS_BAG_ENCRYPTED:
2061 /* XXX Bother to recurse one level down? Unlikely to
2062 use the same password anyway. */
2063 case GNUTLS_BAG_EMPTY:
2064 default:
2065 break;
2069 idx++;
2070 gnutls_pkcs12_bag_deinit (bag);
2073 ret = 0;
2075 done:
2076 if (bag)
2077 gnutls_pkcs12_bag_deinit (bag);
2079 return ret;
2083 * gnutls_certificate_set_x509_simple_pkcs12_file:
2084 * @res: is a #gnutls_certificate_credentials_t structure.
2085 * @pkcs12file: filename of file containing PKCS#12 blob.
2086 * @type: is PEM or DER of the @pkcs12file.
2087 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
2089 * This function sets a certificate/private key pair and/or a CRL in
2090 * the gnutls_certificate_credentials_t structure. This function may
2091 * be called more than once (in case multiple keys/certificates exist
2092 * for the server).
2094 * MAC:ed PKCS#12 files are supported. Encrypted PKCS#12 bags are
2095 * supported. Encrypted PKCS#8 private keys are supported. However,
2096 * only password based security, and the same password for all
2097 * operations, are supported.
2099 * The private keys may be RSA PKCS#1 or DSA private keys encoded in
2100 * the OpenSSL way.
2102 * PKCS#12 file may contain many keys and/or certificates, and there
2103 * is no way to identify which key/certificate pair you want. You
2104 * should make sure the PKCS#12 file only contain one key/certificate
2105 * pair and/or one CRL.
2107 * It is believed that the limitations of this function is acceptable
2108 * for most usage, and that any more flexibility would introduce
2109 * complexity that would make it harder to use this functionality at
2110 * all.
2112 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
2115 gnutls_certificate_set_x509_simple_pkcs12_file
2116 (gnutls_certificate_credentials_t res, const char *pkcs12file,
2117 gnutls_x509_crt_fmt_t type, const char *password)
2119 gnutls_datum_t p12blob;
2120 size_t size;
2121 int ret;
2123 p12blob.data = read_binary_file (pkcs12file, &size);
2124 p12blob.size = (unsigned int) size;
2125 if (p12blob.data == NULL)
2127 gnutls_assert ();
2128 return GNUTLS_E_FILE_ERROR;
2131 ret =
2132 gnutls_certificate_set_x509_simple_pkcs12_mem (res, &p12blob, type,
2133 password);
2134 free (p12blob.data);
2136 return ret;
2140 * gnutls_certificate_set_x509_simple_pkcs12_mem:
2141 * @res: is a #gnutls_certificate_credentials_t structure.
2142 * @p12blob: the PKCS#12 blob.
2143 * @type: is PEM or DER of the @pkcs12file.
2144 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
2146 * This function sets a certificate/private key pair and/or a CRL in
2147 * the gnutls_certificate_credentials_t structure. This function may
2148 * be called more than once (in case multiple keys/certificates exist
2149 * for the server).
2151 * MAC:ed PKCS#12 files are supported. Encrypted PKCS#12 bags are
2152 * supported. Encrypted PKCS#8 private keys are supported. However,
2153 * only password based security, and the same password for all
2154 * operations, are supported.
2156 * The private keys may be RSA PKCS#1 or DSA private keys encoded in
2157 * the OpenSSL way.
2159 * PKCS#12 file may contain many keys and/or certificates, and there
2160 * is no way to identify which key/certificate pair you want. You
2161 * should make sure the PKCS#12 file only contain one key/certificate
2162 * pair and/or one CRL.
2164 * It is believed that the limitations of this function is acceptable
2165 * for most usage, and that any more flexibility would introduce
2166 * complexity that would make it harder to use this functionality at
2167 * all.
2169 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
2171 * Since: 2.8.0
2174 gnutls_certificate_set_x509_simple_pkcs12_mem
2175 (gnutls_certificate_credentials_t res, const gnutls_datum_t * p12blob,
2176 gnutls_x509_crt_fmt_t type, const char *password)
2178 gnutls_pkcs12_t p12;
2179 gnutls_x509_privkey_t key = NULL;
2180 gnutls_x509_crt_t cert = NULL;
2181 gnutls_x509_crl_t crl = NULL;
2182 int ret;
2184 ret = gnutls_pkcs12_init (&p12);
2185 if (ret < 0)
2187 gnutls_assert ();
2188 return ret;
2191 ret = gnutls_pkcs12_import (p12, p12blob, type, 0);
2192 if (ret < 0)
2194 gnutls_assert ();
2195 gnutls_pkcs12_deinit (p12);
2196 return ret;
2199 if (password)
2201 ret = gnutls_pkcs12_verify_mac (p12, password);
2202 if (ret < 0)
2204 gnutls_assert ();
2205 gnutls_pkcs12_deinit (p12);
2206 return ret;
2210 ret = parse_pkcs12 (res, p12, password, &key, &cert, &crl);
2211 gnutls_pkcs12_deinit (p12);
2212 if (ret < 0)
2214 gnutls_assert ();
2215 return ret;
2218 if (key && cert)
2220 ret = gnutls_certificate_set_x509_key (res, &cert, 1, key);
2221 if (ret < 0)
2223 gnutls_assert ();
2224 goto done;
2228 if (crl)
2230 ret = gnutls_certificate_set_x509_crl (res, &crl, 1);
2231 if (ret < 0)
2233 gnutls_assert ();
2234 goto done;
2238 ret = 0;
2240 done:
2241 if (cert)
2242 gnutls_x509_crt_deinit (cert);
2243 if (key)
2244 gnutls_x509_privkey_deinit (key);
2245 if (crl)
2246 gnutls_x509_crl_deinit (crl);
2248 return ret;
2254 * gnutls_certificate_free_crls:
2255 * @sc: is a #gnutls_certificate_credentials_t structure.
2257 * This function will delete all the CRLs associated
2258 * with the given credentials.
2260 void
2261 gnutls_certificate_free_crls (gnutls_certificate_credentials_t sc)
2263 unsigned j;
2265 for (j = 0; j < sc->x509_ncrls; j++)
2267 gnutls_x509_crl_deinit (sc->x509_crl_list[j]);
2270 sc->x509_ncrls = 0;
2272 gnutls_free (sc->x509_crl_list);
2273 sc->x509_crl_list = NULL;
2276 #endif