Use windows trusted certificate store.
[gnutls.git] / lib / gnutls_x509.c
blob71e0d696c514e1422ae5bea92d98f39b6daaaa90
1 /*
2 * Copyright (C) 2002-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #include <gnutls_int.h>
24 #include "gnutls_auth.h"
25 #include "gnutls_errors.h"
26 #include <auth/cert.h>
27 #include "gnutls_dh.h"
28 #include "gnutls_num.h"
29 #include "gnutls_datum.h"
30 #include <gnutls_pk.h>
31 #include <algorithms.h>
32 #include <gnutls_global.h>
33 #include <gnutls_record.h>
34 #include <gnutls_sig.h>
35 #include <gnutls_state.h>
36 #include <gnutls_pk.h>
37 #include <gnutls_str.h>
38 #include <debug.h>
39 #include <x509_b64.h>
40 #include <gnutls_x509.h>
41 #include "x509/common.h"
42 #include "x509/x509_int.h"
43 #include <gnutls_str_array.h>
44 #include "read-file.h"
47 * some x509 certificate parsing functions.
50 /* Check if the number of bits of the key in the certificate
51 * is unacceptable.
53 inline static int
54 check_bits (gnutls_x509_crt_t crt, unsigned int max_bits)
56 int ret;
57 unsigned int bits;
59 ret = gnutls_x509_crt_get_pk_algorithm (crt, &bits);
60 if (ret < 0)
62 gnutls_assert ();
63 return ret;
66 if (bits > max_bits && max_bits > 0)
68 gnutls_assert ();
69 return GNUTLS_E_CONSTRAINT_ERROR;
72 return 0;
76 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) { \
77 if (peer_certificate_list[x]) \
78 gnutls_x509_crt_deinit(peer_certificate_list[x]); \
79 } \
80 gnutls_free( peer_certificate_list)
82 /*-
83 * _gnutls_x509_cert_verify_peers - return the peer's certificate status
84 * @session: is a gnutls session
86 * This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.).
87 * The return value (status) should be one of the gnutls_certificate_status_t enumerated elements.
88 * However you must also check the peer's name in order to check if the verified certificate belongs to the
89 * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
90 -*/
91 int
92 _gnutls_x509_cert_verify_peers (gnutls_session_t session,
93 unsigned int *status)
95 cert_auth_info_t info;
96 gnutls_certificate_credentials_t cred;
97 gnutls_x509_crt_t *peer_certificate_list;
98 int peer_certificate_list_size, i, x, ret;
100 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
102 info = _gnutls_get_auth_info (session);
103 if (info == NULL)
105 gnutls_assert ();
106 return GNUTLS_E_INVALID_REQUEST;
109 cred = (gnutls_certificate_credentials_t)
110 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
111 if (cred == NULL)
113 gnutls_assert ();
114 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
117 if (info->raw_certificate_list == NULL || info->ncerts == 0)
118 return GNUTLS_E_NO_CERTIFICATE_FOUND;
120 if (info->ncerts > cred->verify_depth && cred->verify_depth > 0)
122 gnutls_assert ();
123 return GNUTLS_E_CONSTRAINT_ERROR;
126 /* generate a list of gnutls_certs based on the auth info
127 * raw certs.
129 peer_certificate_list_size = info->ncerts;
130 peer_certificate_list =
131 gnutls_calloc (peer_certificate_list_size, sizeof (gnutls_x509_crt_t));
132 if (peer_certificate_list == NULL)
134 gnutls_assert ();
135 return GNUTLS_E_MEMORY_ERROR;
138 for (i = 0; i < peer_certificate_list_size; i++)
140 ret = gnutls_x509_crt_init (&peer_certificate_list[i]);
141 if (ret < 0)
143 gnutls_assert ();
144 CLEAR_CERTS;
145 return ret;
148 ret =
149 gnutls_x509_crt_import (peer_certificate_list[i],
150 &info->raw_certificate_list[i],
151 GNUTLS_X509_FMT_DER);
152 if (ret < 0)
154 gnutls_assert ();
155 CLEAR_CERTS;
156 return ret;
159 ret = check_bits (peer_certificate_list[i], cred->verify_bits);
160 if (ret < 0)
162 gnutls_assert ();
163 CLEAR_CERTS;
164 return ret;
169 /* Verify certificate
172 ret = gnutls_x509_trust_list_verify_crt (cred->tlist, peer_certificate_list,
173 peer_certificate_list_size,
174 cred->verify_flags | session->internals.
175 priorities.additional_verify_flags,
176 status, NULL);
178 CLEAR_CERTS;
180 if (ret < 0)
182 gnutls_assert ();
183 return ret;
186 return 0;
190 * Read certificates and private keys, from files, memory etc.
193 /* returns error if the certificate has different algorithm than
194 * the given key parameters.
196 static int
197 _gnutls_check_key_cert_match (gnutls_certificate_credentials_t res)
199 int pk = gnutls_pubkey_get_pk_algorithm(res->certs[res->ncerts-1].cert_list[0].pubkey, NULL);
201 if (gnutls_privkey_get_pk_algorithm (res->pkey[res->ncerts - 1], NULL) !=
204 gnutls_assert ();
205 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
208 return 0;
211 /* Returns the name of the certificate of a null name
213 static int get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t *names)
215 size_t max_size;
216 int i, ret = 0, ret2;
217 char name[MAX_CN];
219 for (i = 0; !(ret < 0); i++)
221 max_size = sizeof(name);
223 ret = gnutls_x509_crt_get_subject_alt_name(crt, i, name, &max_size, NULL);
224 if (ret == GNUTLS_SAN_DNSNAME)
226 ret2 = _gnutls_str_array_append(names, name, max_size);
227 if (ret2 < 0)
229 _gnutls_str_array_clear(names);
230 return gnutls_assert_val(ret2);
235 max_size = sizeof(name);
236 ret = gnutls_x509_crt_get_dn_by_oid (crt, OID_X520_COMMON_NAME, 0, 0, name, &max_size);
237 if (ret >= 0)
239 ret = _gnutls_str_array_append(names, name, max_size);
240 if (ret < 0)
242 _gnutls_str_array_clear(names);
243 return gnutls_assert_val(ret);
247 return 0;
250 static int get_x509_name_raw(gnutls_datum_t *raw, gnutls_x509_crt_fmt_t type, gnutls_str_array_t *names)
252 int ret;
253 gnutls_x509_crt_t crt;
255 ret = gnutls_x509_crt_init (&crt);
256 if (ret < 0)
258 gnutls_assert ();
259 return ret;
262 ret = gnutls_x509_crt_import (crt, raw, type);
263 if (ret < 0)
265 gnutls_assert ();
266 gnutls_x509_crt_deinit (crt);
267 return ret;
270 ret = get_x509_name(crt, names);
271 gnutls_x509_crt_deinit (crt);
272 return ret;
275 /* Reads a DER encoded certificate list from memory and stores it to a
276 * gnutls_cert structure. Returns the number of certificates parsed.
278 static int
279 parse_der_cert_mem (gnutls_certificate_credentials_t res,
280 const void *input_cert, int input_cert_size)
282 gnutls_datum_t tmp;
283 gnutls_x509_crt_t crt;
284 gnutls_pcert_st *ccert;
285 int ret;
286 gnutls_str_array_t names;
288 _gnutls_str_array_init(&names);
290 ccert = gnutls_malloc (sizeof (*ccert));
291 if (ccert == NULL)
293 gnutls_assert ();
294 return GNUTLS_E_MEMORY_ERROR;
297 ret = gnutls_x509_crt_init (&crt);
298 if (ret < 0)
300 gnutls_assert ();
301 goto cleanup;
304 tmp.data = (uint8_t *) input_cert;
305 tmp.size = input_cert_size;
307 ret = gnutls_x509_crt_import (crt, &tmp, GNUTLS_X509_FMT_DER);
308 if (ret < 0)
310 gnutls_assert ();
311 gnutls_x509_crt_deinit (crt);
312 goto cleanup;
315 ret = get_x509_name(crt, &names);
316 if (ret < 0)
318 gnutls_assert();
319 gnutls_x509_crt_deinit (crt);
320 goto cleanup;
323 ret = gnutls_pcert_import_x509 (ccert, crt, 0);
324 gnutls_x509_crt_deinit (crt);
326 if (ret < 0)
328 gnutls_assert ();
329 goto cleanup;
332 ret = certificate_credential_append_crt_list (res, names, ccert, 1);
333 if (ret < 0)
335 gnutls_assert ();
336 goto cleanup;
339 return ret;
341 cleanup:
342 _gnutls_str_array_clear(&names);
343 gnutls_free (ccert);
344 return ret;
347 /* Reads a base64 encoded certificate list from memory and stores it to
348 * a gnutls_cert structure. Returns the number of certificate parsed.
350 static int
351 parse_pem_cert_mem (gnutls_certificate_credentials_t res,
352 const char *input_cert, int input_cert_size)
354 int size;
355 const char *ptr;
356 gnutls_datum_t tmp;
357 int ret, count, i;
358 gnutls_pcert_st *certs = NULL;
359 gnutls_str_array_t names;
361 _gnutls_str_array_init(&names);
363 /* move to the certificate
365 ptr = memmem (input_cert, input_cert_size,
366 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
367 if (ptr == NULL)
368 ptr = memmem (input_cert, input_cert_size,
369 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
371 if (ptr == NULL)
373 gnutls_assert ();
374 return GNUTLS_E_BASE64_DECODING_ERROR;
376 size = input_cert_size - (ptr - input_cert);
378 count = 0;
382 certs = gnutls_realloc_fast (certs, (count + 1) * sizeof (gnutls_pcert_st));
384 if (certs == NULL)
386 gnutls_assert ();
387 ret = GNUTLS_E_MEMORY_ERROR;
388 goto cleanup;
391 tmp.data = (void*)ptr;
392 tmp.size = size;
394 if (count == 0)
396 ret = get_x509_name_raw(&tmp, GNUTLS_X509_FMT_PEM, &names);
397 if (ret < 0)
399 gnutls_assert();
400 goto cleanup;
404 ret = gnutls_pcert_import_x509_raw (&certs[count], &tmp, GNUTLS_X509_FMT_PEM, 0);
405 if (ret < 0)
407 gnutls_assert ();
408 goto cleanup;
411 /* now we move ptr after the pem header
413 ptr++;
414 /* find the next certificate (if any)
416 size = input_cert_size - (ptr - input_cert);
418 if (size > 0)
420 char *ptr3;
422 ptr3 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
423 if (ptr3 == NULL)
424 ptr3 = memmem (ptr, size, PEM_CERT_SEP2,
425 sizeof (PEM_CERT_SEP2) - 1);
427 ptr = ptr3;
429 else
430 ptr = NULL;
432 count++;
435 while (ptr != NULL);
437 ret = certificate_credential_append_crt_list (res, names, certs, count);
438 if (ret < 0)
440 gnutls_assert ();
441 goto cleanup;
444 return count;
446 cleanup:
447 _gnutls_str_array_clear(&names);
448 for (i=0;i<count;i++)
449 gnutls_pcert_deinit(&certs[i]);
450 gnutls_free(certs);
451 return ret;
456 /* Reads a DER or PEM certificate from memory
458 static int
459 read_cert_mem (gnutls_certificate_credentials_t res, const void *cert,
460 int cert_size, gnutls_x509_crt_fmt_t type)
462 int ret;
464 if (type == GNUTLS_X509_FMT_DER)
465 ret = parse_der_cert_mem (res, cert, cert_size);
466 else
467 ret = parse_pem_cert_mem (res, cert, cert_size);
469 if (ret < 0)
471 gnutls_assert ();
472 return ret;
475 return ret;
478 static int
479 _gnutls_x509_raw_privkey_to_privkey (gnutls_privkey_t * privkey,
480 const gnutls_datum_t * raw_key,
481 gnutls_x509_crt_fmt_t type)
483 gnutls_x509_privkey_t tmpkey;
484 int ret;
486 ret = gnutls_x509_privkey_init (&tmpkey);
487 if (ret < 0)
489 gnutls_assert ();
490 return ret;
493 ret = gnutls_x509_privkey_import (tmpkey, raw_key, type);
494 if (ret < 0)
496 gnutls_assert ();
497 gnutls_x509_privkey_deinit (tmpkey);
498 return ret;
501 ret = gnutls_privkey_init (privkey);
502 if (ret < 0)
504 gnutls_assert ();
505 gnutls_x509_privkey_deinit (tmpkey);
506 return ret;
509 ret =
510 gnutls_privkey_import_x509 (*privkey, tmpkey,
511 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
512 if (ret < 0)
514 gnutls_assert ();
515 gnutls_x509_privkey_deinit (tmpkey);
516 gnutls_privkey_deinit (*privkey);
517 return ret;
520 return 0;
523 /* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory. Type
524 * indicates the certificate format. KEY can be NULL, to indicate
525 * that GnuTLS doesn't know the private key.
527 static int
528 read_key_mem (gnutls_certificate_credentials_t res,
529 const void *key, int key_size, gnutls_x509_crt_fmt_t type)
531 int ret;
532 gnutls_datum_t tmp;
533 gnutls_privkey_t privkey;
535 if (key)
537 tmp.data = (uint8_t *) key;
538 tmp.size = key_size;
540 ret = _gnutls_x509_raw_privkey_to_privkey (&privkey, &tmp, type);
541 if (ret < 0)
543 gnutls_assert ();
544 return ret;
547 ret = certificate_credentials_append_pkey (res, privkey);
548 if (ret < 0)
550 gnutls_assert ();
551 gnutls_privkey_deinit (privkey);
552 return ret;
556 else
558 gnutls_assert ();
559 return GNUTLS_E_INVALID_REQUEST;
563 return 0;
566 #ifdef ENABLE_PKCS11
567 /* Reads a private key from a token.
569 static int
570 read_key_url (gnutls_certificate_credentials_t res, const char *url)
572 int ret;
573 gnutls_pkcs11_privkey_t key1 = NULL;
574 gnutls_privkey_t pkey = NULL;
576 /* allocate space for the pkey list
579 ret = gnutls_pkcs11_privkey_init (&key1);
580 if (ret < 0)
582 gnutls_assert ();
583 return ret;
586 ret = gnutls_pkcs11_privkey_import_url (key1, url, 0);
587 if (ret < 0)
589 gnutls_assert ();
590 goto cleanup;
593 ret = gnutls_privkey_init (&pkey);
594 if (ret < 0)
596 gnutls_assert ();
597 goto cleanup;
600 ret =
601 gnutls_privkey_import_pkcs11 (pkey, key1,
602 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
603 if (ret < 0)
605 gnutls_assert ();
606 goto cleanup;
609 ret = certificate_credentials_append_pkey (res, pkey);
610 if (ret < 0)
612 gnutls_assert ();
613 goto cleanup;
616 return 0;
618 cleanup:
619 if (pkey)
620 gnutls_privkey_deinit (pkey);
622 if (key1)
623 gnutls_pkcs11_privkey_deinit (key1);
625 return ret;
628 /* Reads a private key from a token.
630 static int
631 read_cas_url (gnutls_certificate_credentials_t res, const char *url)
633 int ret;
634 gnutls_x509_crt_t *xcrt_list = NULL;
635 gnutls_pkcs11_obj_t *pcrt_list = NULL;
636 unsigned int pcrt_list_size = 0;
638 /* FIXME: should we use login? */
639 ret =
640 gnutls_pkcs11_obj_list_import_url (NULL, &pcrt_list_size, url,
641 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
642 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
644 gnutls_assert ();
645 return ret;
648 if (pcrt_list_size == 0)
650 gnutls_assert ();
651 return 0;
654 pcrt_list = gnutls_malloc (sizeof (*pcrt_list) * pcrt_list_size);
655 if (pcrt_list == NULL)
657 gnutls_assert ();
658 return GNUTLS_E_MEMORY_ERROR;
661 ret =
662 gnutls_pkcs11_obj_list_import_url (pcrt_list, &pcrt_list_size, url,
663 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
664 if (ret < 0)
666 gnutls_assert ();
667 goto cleanup;
670 xcrt_list = gnutls_malloc (sizeof (*xcrt_list) * pcrt_list_size);
671 if (xcrt_list == NULL)
673 gnutls_assert ();
674 ret = GNUTLS_E_MEMORY_ERROR;
675 goto cleanup;
678 ret =
679 gnutls_x509_crt_list_import_pkcs11 (xcrt_list, pcrt_list_size, pcrt_list,
681 if (xcrt_list == NULL)
683 gnutls_assert ();
684 ret = GNUTLS_E_MEMORY_ERROR;
685 goto cleanup;
688 ret = gnutls_x509_trust_list_add_cas(res->tlist, xcrt_list, pcrt_list_size, 0);
689 if (ret < 0)
691 gnutls_assert();
692 goto cleanup;
695 cleanup:
696 gnutls_free (xcrt_list);
697 gnutls_free (pcrt_list);
699 return ret;
704 /* Reads a private key from a token.
706 static int
707 read_cert_url (gnutls_certificate_credentials_t res, const char *url)
709 int ret;
710 gnutls_x509_crt_t crt;
711 gnutls_pcert_st *ccert;
712 gnutls_str_array_t names;
714 _gnutls_str_array_init(&names);
716 ccert = gnutls_malloc (sizeof (*ccert));
717 if (ccert == NULL)
719 gnutls_assert ();
720 return GNUTLS_E_MEMORY_ERROR;
723 ret = gnutls_x509_crt_init (&crt);
724 if (ret < 0)
726 gnutls_assert ();
727 goto cleanup;
730 ret = gnutls_x509_crt_import_pkcs11_url (crt, url, 0);
731 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
732 ret =
733 gnutls_x509_crt_import_pkcs11_url (crt, url,
734 GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
736 if (ret < 0)
738 gnutls_assert ();
739 gnutls_x509_crt_deinit (crt);
740 goto cleanup;
743 ret = get_x509_name(crt, &names);
744 if (ret < 0)
746 gnutls_assert ();
747 gnutls_x509_crt_deinit (crt);
748 goto cleanup;
751 ret = gnutls_pcert_import_x509 (ccert, crt, 0);
752 gnutls_x509_crt_deinit (crt);
754 if (ret < 0)
756 gnutls_assert ();
757 goto cleanup;
760 ret = certificate_credential_append_crt_list (res, names, ccert, 1);
761 if (ret < 0)
763 gnutls_assert ();
764 goto cleanup;
767 return 0;
769 cleanup:
770 _gnutls_str_array_clear(&names);
771 gnutls_free (ccert);
772 return ret;
774 #endif
776 /* Reads a certificate file
778 static int
779 read_cert_file (gnutls_certificate_credentials_t res,
780 const char *certfile, gnutls_x509_crt_fmt_t type)
782 int ret;
783 size_t size;
784 char *data;
786 #ifdef ENABLE_PKCS11
787 if (strncmp (certfile, "pkcs11:", 7) == 0)
789 return read_cert_url (res, certfile);
791 #endif /* ENABLE_PKCS11 */
793 data = read_binary_file (certfile, &size);
795 if (data == NULL)
797 gnutls_assert ();
798 return GNUTLS_E_FILE_ERROR;
801 ret = read_cert_mem (res, data, size, type);
802 free (data);
804 return ret;
810 /* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
811 * stores it).
813 static int
814 read_key_file (gnutls_certificate_credentials_t res,
815 const char *keyfile, gnutls_x509_crt_fmt_t type)
817 int ret;
818 size_t size;
819 char *data;
821 #ifdef ENABLE_PKCS11
822 if (strncmp (keyfile, "pkcs11:", 7) == 0)
824 return read_key_url (res, keyfile);
826 #endif /* ENABLE_PKCS11 */
828 data = read_binary_file (keyfile, &size);
830 if (data == NULL)
832 gnutls_assert ();
833 return GNUTLS_E_FILE_ERROR;
836 ret = read_key_mem (res, data, size, type);
837 free (data);
839 return ret;
843 * gnutls_certificate_set_x509_key_mem:
844 * @res: is a #gnutls_certificate_credentials_t structure.
845 * @cert: contains a certificate list (path) for the specified private key
846 * @key: is the private key, or %NULL
847 * @type: is PEM or DER
849 * This function sets a certificate/private key pair in the
850 * gnutls_certificate_credentials_t structure. This function may be called
851 * more than once, in case multiple keys/certificates exist for the
852 * server.
854 * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
855 * is supported. This means that certificates intended for signing cannot
856 * be used for ciphersuites that require encryption.
858 * If the certificate and the private key are given in PEM encoding
859 * then the strings that hold their values must be null terminated.
861 * The @key may be %NULL if you are using a sign callback, see
862 * gnutls_sign_callback_set().
864 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
867 gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t res,
868 const gnutls_datum_t * cert,
869 const gnutls_datum_t * key,
870 gnutls_x509_crt_fmt_t type)
872 int ret;
874 /* this should be first
876 if ((ret = read_key_mem (res, key ? key->data : NULL,
877 key ? key->size : 0, type)) < 0)
878 return ret;
880 if ((ret = read_cert_mem (res, cert->data, cert->size, type)) < 0)
881 return ret;
883 res->ncerts++;
885 if (key && (ret = _gnutls_check_key_cert_match (res)) < 0)
887 gnutls_assert ();
888 return ret;
891 return 0;
894 static int check_if_sorted(gnutls_pcert_st * crt, int nr)
896 gnutls_x509_crt_t x509;
897 char prev_dn[MAX_DN];
898 char dn[MAX_DN];
899 size_t prev_dn_size, dn_size;
900 int i, ret;
902 /* check if the X.509 list is ordered */
903 if (nr > 1 && crt[0].type == GNUTLS_CRT_X509)
906 for (i=0;i<nr;i++)
908 ret = gnutls_x509_crt_init(&x509);
909 if (ret < 0)
910 return gnutls_assert_val(ret);
912 ret = gnutls_x509_crt_import(x509, &crt[i].cert, GNUTLS_X509_FMT_DER);
913 if (ret < 0)
915 ret = gnutls_assert_val(ret);
916 goto cleanup;
919 if (i>0)
921 dn_size = sizeof(dn);
922 ret = gnutls_x509_crt_get_dn(x509, dn, &dn_size);
923 if (ret < 0)
925 ret = gnutls_assert_val(ret);
926 goto cleanup;
929 if (dn_size != prev_dn_size || memcmp(dn, prev_dn, dn_size) != 0)
931 ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
932 goto cleanup;
936 prev_dn_size = sizeof(prev_dn);
937 ret = gnutls_x509_crt_get_issuer_dn(x509, prev_dn, &prev_dn_size);
938 if (ret < 0)
940 ret = gnutls_assert_val(ret);
941 goto cleanup;
944 gnutls_x509_crt_deinit(x509);
948 return 0;
950 cleanup:
951 gnutls_x509_crt_deinit(x509);
952 return ret;
956 certificate_credential_append_crt_list (gnutls_certificate_credentials_t res,
957 gnutls_str_array_t names, gnutls_pcert_st * crt, int nr)
959 int ret;
961 ret = check_if_sorted(crt, nr);
962 if (ret < 0)
963 return gnutls_assert_val(ret);
965 res->certs = gnutls_realloc_fast (res->certs,
966 (1 + res->ncerts) *
967 sizeof (certs_st));
968 if (res->certs == NULL)
970 gnutls_assert ();
971 return GNUTLS_E_MEMORY_ERROR;
974 res->certs[res->ncerts].cert_list = crt;
975 res->certs[res->ncerts].cert_list_length = nr;
976 res->certs[res->ncerts].names = names;
978 return 0;
983 certificate_credentials_append_pkey (gnutls_certificate_credentials_t res,
984 gnutls_privkey_t pkey)
986 res->pkey = gnutls_realloc_fast (res->pkey,
987 (1 + res->ncerts) *
988 sizeof (gnutls_privkey_t));
989 if (res->pkey == NULL)
991 gnutls_assert ();
992 return GNUTLS_E_MEMORY_ERROR;
994 res->pkey[res->ncerts] = pkey;
995 return 0;
1000 * gnutls_certificate_set_x509_key:
1001 * @res: is a #gnutls_certificate_credentials_t structure.
1002 * @cert_list: contains a certificate list (path) for the specified private key
1003 * @cert_list_size: holds the size of the certificate list
1004 * @key: is a gnutls_x509_privkey_t key
1006 * This function sets a certificate/private key pair in the
1007 * gnutls_certificate_credentials_t structure. This function may be
1008 * called more than once, in case multiple keys/certificates exist for
1009 * the server. For clients that wants to send more than its own end
1010 * entity certificate (e.g., also an intermediate CA cert) then put
1011 * the certificate chain in @cert_list.
1015 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1017 * Since: 2.4.0
1020 gnutls_certificate_set_x509_key (gnutls_certificate_credentials_t res,
1021 gnutls_x509_crt_t * cert_list,
1022 int cert_list_size,
1023 gnutls_x509_privkey_t key)
1025 int ret, i;
1026 gnutls_privkey_t pkey;
1027 gnutls_pcert_st *pcerts = NULL;
1028 gnutls_str_array_t names;
1030 _gnutls_str_array_init(&names);
1032 /* this should be first
1034 ret = gnutls_privkey_init (&pkey);
1035 if (ret < 0)
1037 gnutls_assert ();
1038 return ret;
1041 ret = gnutls_privkey_import_x509 (pkey, key, GNUTLS_PRIVKEY_IMPORT_COPY);
1042 if (ret < 0)
1044 gnutls_assert ();
1045 return ret;
1048 ret = certificate_credentials_append_pkey (res, pkey);
1049 if (ret < 0)
1051 gnutls_assert ();
1052 return ret;
1055 /* load certificates */
1056 pcerts = gnutls_malloc (sizeof (gnutls_pcert_st) * cert_list_size);
1057 if (pcerts == NULL)
1059 gnutls_assert ();
1060 return GNUTLS_E_MEMORY_ERROR;
1063 ret = get_x509_name(cert_list[0], &names);
1064 if (ret < 0)
1065 return gnutls_assert_val(ret);
1067 for (i = 0; i < cert_list_size; i++)
1069 ret = gnutls_pcert_import_x509 (&pcerts[i], cert_list[i], 0);
1070 if (ret < 0)
1072 gnutls_assert ();
1073 goto cleanup;
1077 ret = certificate_credential_append_crt_list (res, names, pcerts, cert_list_size);
1078 if (ret < 0)
1080 gnutls_assert ();
1081 goto cleanup;
1084 res->ncerts++;
1086 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1088 gnutls_assert ();
1089 return ret;
1092 return 0;
1094 cleanup:
1095 _gnutls_str_array_clear(&names);
1096 return ret;
1100 * gnutls_certificate_set_key:
1101 * @res: is a #gnutls_certificate_credentials_t structure.
1102 * @names: is an array of DNS name of the certificate (NULL if none)
1103 * @names_size: holds the size of the names list
1104 * @pcert_list: contains a certificate list (path) for the specified private key
1105 * @pcert_list_size: holds the size of the certificate list
1106 * @key: is a gnutls_x509_privkey_t key
1108 * This function sets a certificate/private key pair in the
1109 * gnutls_certificate_credentials_t structure. This function may be
1110 * called more than once, in case multiple keys/certificates exist for
1111 * the server. For clients that wants to send more than its own end
1112 * entity certificate (e.g., also an intermediate CA cert) then put
1113 * the certificate chain in @pcert_list. The @pcert_list and @key will
1114 * become part of the credentials structure and must not
1115 * be deallocated. They will be automatically deallocated when
1116 * @res is deinitialized.
1118 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1120 * Since: 3.0
1123 gnutls_certificate_set_key (gnutls_certificate_credentials_t res,
1124 const char** names,
1125 int names_size,
1126 gnutls_pcert_st * pcert_list,
1127 int pcert_list_size,
1128 gnutls_privkey_t key)
1130 int ret, i;
1131 gnutls_str_array_t str_names;
1133 _gnutls_str_array_init(&str_names);
1135 if (names != NULL && names_size > 0)
1137 for (i=0;i<names_size;i++)
1139 ret = _gnutls_str_array_append(&str_names, names[i], strlen(names[i]));
1140 if (ret < 0)
1142 ret = gnutls_assert_val(ret);
1143 goto cleanup;
1148 ret = certificate_credentials_append_pkey (res, key);
1149 if (ret < 0)
1151 gnutls_assert ();
1152 goto cleanup;
1155 ret = certificate_credential_append_crt_list (res, str_names, pcert_list, pcert_list_size);
1156 if (ret < 0)
1158 gnutls_assert ();
1159 goto cleanup;
1162 res->ncerts++;
1164 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1166 gnutls_assert ();
1167 return ret;
1170 return 0;
1172 cleanup:
1173 _gnutls_str_array_clear(&str_names);
1174 return ret;
1178 * gnutls_certificate_set_x509_key_file:
1179 * @res: is a #gnutls_certificate_credentials_t structure.
1180 * @certfile: is a file that containing the certificate list (path) for
1181 * the specified private key, in PKCS7 format, or a list of certificates
1182 * @keyfile: is a file that contains the private key
1183 * @type: is PEM or DER
1185 * This function sets a certificate/private key pair in the
1186 * gnutls_certificate_credentials_t structure. This function may be
1187 * called more than once, in case multiple keys/certificates exist for
1188 * the server. For clients that need to send more than its own end
1189 * entity certificate, e.g., also an intermediate CA cert, then the
1190 * @certfile must contain the ordered certificate chain.
1192 * This function can also accept PKCS #11 URLs at @keyfile and @certfile. In that case it
1193 * will import the private key and certificate indicated by the URLs.
1195 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1198 gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t res,
1199 const char *certfile,
1200 const char *keyfile,
1201 gnutls_x509_crt_fmt_t type)
1203 int ret;
1205 /* this should be first
1207 if ((ret = read_key_file (res, keyfile, type)) < 0)
1208 return ret;
1210 if ((ret = read_cert_file (res, certfile, type)) < 0)
1211 return ret;
1213 res->ncerts++;
1215 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1217 gnutls_assert ();
1218 return ret;
1221 return 0;
1224 static int
1225 add_new_crt_to_rdn_seq (gnutls_certificate_credentials_t res, gnutls_x509_crt_t* crts,
1226 unsigned int crt_size)
1228 gnutls_datum_t tmp;
1229 int ret;
1230 size_t newsize;
1231 unsigned char *newdata;
1232 unsigned i;
1234 /* Add DN of the last added CAs to the RDN sequence
1235 * This will be sent to clients when a certificate
1236 * request message is sent.
1239 /* FIXME: in case of a client it is not needed
1240 * to do that. This would save time and memory.
1241 * However we don't have that information available
1242 * here.
1243 * Further, this function is now much more efficient,
1244 * so optimizing that is less important.
1247 for (i = 0; i < crt_size; i++)
1249 if ((ret = gnutls_x509_crt_get_raw_dn (crts[i], &tmp)) < 0)
1251 gnutls_assert ();
1252 return ret;
1255 newsize = res->x509_rdn_sequence.size + 2 + tmp.size;
1256 if (newsize < res->x509_rdn_sequence.size)
1258 gnutls_assert ();
1259 _gnutls_free_datum (&tmp);
1260 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1263 newdata = gnutls_realloc (res->x509_rdn_sequence.data, newsize);
1264 if (newdata == NULL)
1266 gnutls_assert ();
1267 _gnutls_free_datum (&tmp);
1268 return GNUTLS_E_MEMORY_ERROR;
1271 _gnutls_write_datum16 (newdata + res->x509_rdn_sequence.size, tmp);
1272 _gnutls_free_datum (&tmp);
1274 res->x509_rdn_sequence.size = newsize;
1275 res->x509_rdn_sequence.data = newdata;
1278 return 0;
1281 /* Returns 0 if it's ok to use the gnutls_kx_algorithm_t with this
1282 * certificate (uses the KeyUsage field).
1285 _gnutls_check_key_usage (const gnutls_pcert_st* cert, gnutls_kx_algorithm_t alg)
1287 unsigned int key_usage = 0;
1288 int encipher_type;
1290 if (cert == NULL)
1292 gnutls_assert ();
1293 return GNUTLS_E_INTERNAL_ERROR;
1296 if (_gnutls_map_kx_get_cred (alg, 1) == GNUTLS_CRD_CERTIFICATE ||
1297 _gnutls_map_kx_get_cred (alg, 0) == GNUTLS_CRD_CERTIFICATE)
1300 gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
1302 encipher_type = _gnutls_kx_encipher_type (alg);
1304 if (key_usage != 0 && encipher_type != CIPHER_IGN)
1306 /* If key_usage has been set in the certificate
1309 if (encipher_type == CIPHER_ENCRYPT)
1311 /* If the key exchange method requires an encipher
1312 * type algorithm, and key's usage does not permit
1313 * encipherment, then fail.
1315 if (!(key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT))
1317 gnutls_assert ();
1318 return GNUTLS_E_KEY_USAGE_VIOLATION;
1322 if (encipher_type == CIPHER_SIGN)
1324 /* The same as above, but for sign only keys
1326 if (!(key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE))
1328 gnutls_assert ();
1329 return GNUTLS_E_KEY_USAGE_VIOLATION;
1334 return 0;
1337 static int
1338 parse_pem_ca_mem (gnutls_certificate_credentials_t res,
1339 const uint8_t * input_cert, int input_cert_size)
1341 gnutls_x509_crt_t *x509_cert_list;
1342 unsigned int x509_ncerts;
1343 gnutls_datum_t tmp;
1344 int ret;
1346 tmp.data = (void*)input_cert;
1347 tmp.size = input_cert_size;
1349 ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp,
1350 GNUTLS_X509_FMT_PEM, 0);
1351 if (ret < 0)
1353 gnutls_assert();
1354 return ret;
1357 if ((ret = add_new_crt_to_rdn_seq (res, x509_cert_list, x509_ncerts)) < 0)
1359 gnutls_assert();
1360 goto cleanup;
1363 ret = gnutls_x509_trust_list_add_cas(res->tlist, x509_cert_list, x509_ncerts, 0);
1364 if (ret < 0)
1366 gnutls_assert();
1367 goto cleanup;
1370 cleanup:
1371 gnutls_free(x509_cert_list);
1372 return ret;
1375 /* Reads a DER encoded certificate list from memory and stores it to a
1376 * gnutls_cert structure. Returns the number of certificates parsed.
1378 static int
1379 parse_der_ca_mem (gnutls_certificate_credentials_t res,
1380 const void *input_cert, int input_cert_size)
1382 gnutls_x509_crt_t crt;
1383 gnutls_datum_t tmp;
1384 int ret;
1386 tmp.data = (void*)input_cert;
1387 tmp.size = input_cert_size;
1389 ret = gnutls_x509_crt_init( &crt);
1390 if (ret < 0)
1392 gnutls_assert();
1393 return ret;
1396 ret = gnutls_x509_crt_import( crt, &tmp, GNUTLS_X509_FMT_DER);
1397 if (ret < 0)
1399 gnutls_assert();
1400 goto cleanup;
1403 if ((ret = add_new_crt_to_rdn_seq (res, &crt, 1)) < 0)
1405 gnutls_assert();
1406 goto cleanup;
1409 ret = gnutls_x509_trust_list_add_cas(res->tlist, &crt, 1, 0);
1410 if (ret < 0)
1412 gnutls_assert();
1413 goto cleanup;
1416 return ret;
1418 cleanup:
1419 gnutls_x509_crt_deinit(crt);
1420 return ret;
1424 * gnutls_certificate_set_x509_trust_mem:
1425 * @res: is a #gnutls_certificate_credentials_t structure.
1426 * @ca: is a list of trusted CAs or a DER certificate
1427 * @type: is DER or PEM
1429 * This function adds the trusted CAs in order to verify client or
1430 * server certificates. In case of a client this is not required to be
1431 * called if the certificates are not verified using
1432 * gnutls_certificate_verify_peers2(). This function may be called
1433 * multiple times.
1435 * In case of a server the CAs set here will be sent to the client if
1436 * a certificate request is sent. This can be disabled using
1437 * gnutls_certificate_send_x509_rdn_sequence().
1439 * Returns: the number of certificates processed or a negative error code
1440 * on error.
1443 gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t res,
1444 const gnutls_datum_t * ca,
1445 gnutls_x509_crt_fmt_t type)
1447 int ret;
1449 if (type == GNUTLS_X509_FMT_DER)
1450 ret = parse_der_ca_mem (res,
1451 ca->data, ca->size);
1452 else
1453 ret = parse_pem_ca_mem (res,
1454 ca->data, ca->size);
1456 if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
1457 return 0;
1459 return ret;
1463 * gnutls_certificate_set_x509_trust:
1464 * @res: is a #gnutls_certificate_credentials_t structure.
1465 * @ca_list: is a list of trusted CAs
1466 * @ca_list_size: holds the size of the CA list
1468 * This function adds the trusted CAs in order to verify client
1469 * or server certificates. In case of a client this is not required
1470 * to be called if the certificates are not verified using
1471 * gnutls_certificate_verify_peers2().
1472 * This function may be called multiple times.
1474 * In case of a server the CAs set here will be sent to the client if
1475 * a certificate request is sent. This can be disabled using
1476 * gnutls_certificate_send_x509_rdn_sequence().
1478 * Returns: the number of certificates processed or a negative error code
1479 * on error.
1481 * Since: 2.4.0
1484 gnutls_certificate_set_x509_trust (gnutls_certificate_credentials_t res,
1485 gnutls_x509_crt_t * ca_list,
1486 int ca_list_size)
1488 int ret, i, j;
1489 gnutls_x509_crt_t new_list[ca_list_size];
1491 for (i = 0; i < ca_list_size; i++)
1493 ret = gnutls_x509_crt_init (&new_list[i]);
1494 if (ret < 0)
1496 gnutls_assert ();
1497 goto cleanup;
1500 ret = _gnutls_x509_crt_cpy (new_list[i], ca_list[i]);
1501 if (ret < 0)
1503 gnutls_assert ();
1504 goto cleanup;
1508 if ((ret = add_new_crt_to_rdn_seq (res, new_list, ca_list_size)) < 0)
1510 gnutls_assert();
1511 goto cleanup;
1514 ret = gnutls_x509_trust_list_add_cas(res->tlist, new_list, ca_list_size, 0);
1515 if (ret < 0)
1517 gnutls_assert ();
1518 goto cleanup;
1521 return ret;
1523 cleanup:
1524 for (j=0;j<i;i++)
1525 gnutls_x509_crt_deinit(new_list[j]);
1527 return ret;
1532 * gnutls_certificate_set_x509_trust_file:
1533 * @cred: is a #gnutls_certificate_credentials_t structure.
1534 * @cafile: is a file containing the list of trusted CAs (DER or PEM list)
1535 * @type: is PEM or DER
1537 * This function adds the trusted CAs in order to verify client or
1538 * server certificates. In case of a client this is not required to
1539 * be called if the certificates are not verified using
1540 * gnutls_certificate_verify_peers2(). This function may be called
1541 * multiple times.
1543 * In case of a server the names of the CAs set here will be sent to
1544 * the client if a certificate request is sent. This can be disabled
1545 * using gnutls_certificate_send_x509_rdn_sequence().
1547 * This function can also accept PKCS #11 URLs. In that case it
1548 * will import all certificates that are marked as trusted.
1550 * Returns: number of certificates processed, or a negative error code on
1551 * error.
1554 gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t cred,
1555 const char *cafile,
1556 gnutls_x509_crt_fmt_t type)
1558 int ret;
1559 gnutls_datum_t cas;
1560 size_t size;
1562 #ifdef ENABLE_PKCS11
1563 if (strncmp (cafile, "pkcs11:", 7) == 0)
1565 return read_cas_url (cred, cafile);
1567 #endif
1569 cas.data = (void*)read_binary_file (cafile, &size);
1570 if (cas.data == NULL)
1572 gnutls_assert ();
1573 return GNUTLS_E_FILE_ERROR;
1576 cas.size = size;
1578 ret = gnutls_certificate_set_x509_trust_mem(cred, &cas, type);
1580 free (cas.data);
1582 if (ret < 0)
1584 gnutls_assert ();
1585 return ret;
1588 return ret;
1591 #ifdef _WIN32
1592 static int
1593 set_x509_system_trust_file (gnutls_certificate_credentials_t cred)
1595 HCERTSTORE store = CertOpenSystemStore(0, "CA");
1596 const CERT_CONTEXT *cert;
1597 const CRL_CONTEXT *crl;
1598 gnutls_datum_t data;
1599 int ret = 0;
1600 unsigned int i;
1602 for (i=0;i<2;i++)
1605 if (i==0) store = CertOpenSystemStore(0, "ROOT");
1606 else store = CertOpenSystemStore(0, "CA");
1608 if (store == NULL) return GNUTLS_E_FILE_ERROR;
1610 cert = CertEnumCertificatesInStore(store, NULL);
1611 crl = CertEnumCRLsInStore(store, NULL);
1613 while(cert != NULL)
1615 if (cert->dwCertEncodingType == X509_ASN_ENCODING)
1617 data.data = cert->pbCertEncoded;
1618 data.size = cert->cbCertEncoded;
1619 if (gnutls_certificate_set_x509_trust_mem (cred, &data, GNUTLS_X509_FMT_DER) > 0)
1620 ret++;
1622 cert = CertEnumCertificatesInStore(store, cert);
1625 while(crl != NULL)
1627 if (crl->dwCertEncodingType == X509_ASN_ENCODING)
1629 data.data = crl->pbCrlEncoded;
1630 data.size = crl->cbCrlEncoded;
1632 gnutls_certificate_set_x509_crl_mem(cred, &data, GNUTLS_X509_FMT_DER);
1634 crl = CertEnumCRLsInStore(store, crl);
1636 CertCloseStore(store, 0);
1639 return ret;
1641 #elif defined(DEFAULT_TRUST_STORE_FILE)
1642 static int
1643 set_x509_system_trust_file (gnutls_certificate_credentials_t cred)
1645 int ret, r;
1646 gnutls_datum_t cas;
1647 size_t size;
1649 cas.data = (void*)read_binary_file (DEFAULT_TRUST_STORE_FILE, &size);
1650 if (cas.data == NULL)
1652 gnutls_assert ();
1653 return GNUTLS_E_FILE_ERROR;
1656 cas.size = size;
1658 ret = gnutls_certificate_set_x509_trust_mem(cred, &cas, GNUTLS_X509_FMT_PEM);
1660 free (cas.data);
1662 if (ret < 0)
1664 gnutls_assert ();
1665 return ret;
1668 r = ret;
1670 #ifdef DEFAULT_CRL_FILE
1671 cas.data = (void*)read_binary_file (DEFAULT_CRL_FILE, &size);
1672 if (cas.data == NULL)
1674 gnutls_assert ();
1675 return r;
1678 cas.size = size;
1680 ret = gnutls_certificate_set_x509_crl_mem(cred, &cas, GNUTLS_X509_FMT_PEM);
1682 free (cas.data);
1684 if (ret < 0)
1686 gnutls_assert ();
1687 return ret;
1689 #endif
1691 return r;
1693 #endif
1696 * gnutls_certificate_set_x509_system_trust:
1697 * @cred: is a #gnutls_certificate_credentials_t structure.
1699 * This function adds the system's default trusted CAs in order to
1700 * verify client or server certificates.
1702 * In the case the system is currently unsupported %GNUTLS_E_UNIMPLEMENTED_FEATURE
1703 * is returned.
1705 * Returns: the number of certificates processed or a negative error code
1706 * on error.
1708 * Since: 3.0
1711 gnutls_certificate_set_x509_system_trust (gnutls_certificate_credentials_t cred)
1713 #if !defined(_WIN32) && !defined(DEFAULT_TRUST_STORE_PKCS11) && !defined(DEFAULT_TRUST_STORE_FILE)
1714 int r = GNUTLS_E_UNIMPLEMENTED_FEATURE;
1715 #else
1716 int ret, r = 0;
1717 #endif
1719 #if defined(ENABLE_PKCS11) && defined(DEFAULT_TRUST_STORE_PKCS11)
1720 ret = read_cas_url (cred, DEFAULT_TRUST_STORE_PKCS11);
1721 if (ret > 0)
1722 r += ret;
1723 #endif
1725 #ifdef DEFAULT_TRUST_STORE_FILE
1726 ret = set_x509_system_trust_file(cred);
1727 if (ret > 0)
1728 r += ret;
1729 #endif
1731 return r;
1734 static int
1735 parse_pem_crl_mem (gnutls_x509_trust_list_t tlist,
1736 const char * input_crl, unsigned int input_crl_size)
1738 gnutls_x509_crl_t *x509_crl_list;
1739 unsigned int x509_ncrls;
1740 gnutls_datum_t tmp;
1741 int ret;
1743 tmp.data = (void*)input_crl;
1744 tmp.size = input_crl_size;
1746 ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp,
1747 GNUTLS_X509_FMT_PEM, 0);
1748 if (ret < 0)
1750 gnutls_assert();
1751 return ret;
1754 ret = gnutls_x509_trust_list_add_crls(tlist, x509_crl_list, x509_ncrls, 0, 0);
1755 if (ret < 0)
1757 gnutls_assert();
1758 goto cleanup;
1761 cleanup:
1762 gnutls_free(x509_crl_list);
1763 return ret;
1766 /* Reads a DER encoded certificate list from memory and stores it to a
1767 * gnutls_cert structure. Returns the number of certificates parsed.
1769 static int
1770 parse_der_crl_mem (gnutls_x509_trust_list_t tlist,
1771 const void *input_crl, unsigned int input_crl_size)
1773 gnutls_x509_crl_t crl;
1774 gnutls_datum_t tmp;
1775 int ret;
1777 tmp.data = (void*)input_crl;
1778 tmp.size = input_crl_size;
1780 ret = gnutls_x509_crl_init( &crl);
1781 if (ret < 0)
1783 gnutls_assert();
1784 return ret;
1787 ret = gnutls_x509_crl_import( crl, &tmp, GNUTLS_X509_FMT_DER);
1788 if (ret < 0)
1790 gnutls_assert();
1791 goto cleanup;
1794 ret = gnutls_x509_trust_list_add_crls(tlist, &crl, 1, 0, 0);
1795 if (ret < 0)
1797 gnutls_assert();
1798 goto cleanup;
1801 return ret;
1803 cleanup:
1804 gnutls_x509_crl_deinit(crl);
1805 return ret;
1810 /* Reads a DER or PEM CRL from memory
1812 static int
1813 read_crl_mem (gnutls_certificate_credentials_t res, const void *crl,
1814 int crl_size, gnutls_x509_crt_fmt_t type)
1816 int ret;
1818 if (type == GNUTLS_X509_FMT_DER)
1819 ret = parse_der_crl_mem (res->tlist, crl, crl_size);
1820 else
1821 ret = parse_pem_crl_mem (res->tlist, crl, crl_size);
1823 if (ret < 0)
1825 gnutls_assert ();
1828 return ret;
1832 * gnutls_certificate_set_x509_crl_mem:
1833 * @res: is a #gnutls_certificate_credentials_t structure.
1834 * @CRL: is a list of trusted CRLs. They should have been verified before.
1835 * @type: is DER or PEM
1837 * This function adds the trusted CRLs in order to verify client or
1838 * server certificates. In case of a client this is not required to
1839 * be called if the certificates are not verified using
1840 * gnutls_certificate_verify_peers2(). This function may be called
1841 * multiple times.
1843 * Returns: number of CRLs processed, or a negative error code on error.
1846 gnutls_certificate_set_x509_crl_mem (gnutls_certificate_credentials_t res,
1847 const gnutls_datum_t * CRL,
1848 gnutls_x509_crt_fmt_t type)
1850 return read_crl_mem (res, CRL->data, CRL->size, type);
1854 * gnutls_certificate_set_x509_crl:
1855 * @res: is a #gnutls_certificate_credentials_t structure.
1856 * @crl_list: is a list of trusted CRLs. They should have been verified before.
1857 * @crl_list_size: holds the size of the crl_list
1859 * This function adds the trusted CRLs in order to verify client or
1860 * server certificates. In case of a client this is not required to
1861 * be called if the certificates are not verified using
1862 * gnutls_certificate_verify_peers2(). This function may be called
1863 * multiple times.
1865 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1867 * Since: 2.4.0
1870 gnutls_certificate_set_x509_crl (gnutls_certificate_credentials_t res,
1871 gnutls_x509_crl_t * crl_list,
1872 int crl_list_size)
1874 int ret, i, j;
1875 gnutls_x509_crl_t new_crl[crl_list_size];
1877 for (i = 0; i < crl_list_size; i++)
1879 ret = gnutls_x509_crl_init (&new_crl[i]);
1880 if (ret < 0)
1882 gnutls_assert ();
1883 goto cleanup;
1886 ret = _gnutls_x509_crl_cpy (new_crl[i], crl_list[i]);
1887 if (ret < 0)
1889 gnutls_assert ();
1890 goto cleanup;
1894 ret = gnutls_x509_trust_list_add_crls(res->tlist, new_crl, crl_list_size, 0, 0);
1895 if (ret < 0)
1897 gnutls_assert ();
1898 goto cleanup;
1901 return ret;
1903 cleanup:
1904 for (j=0;j<i;j++)
1905 gnutls_x509_crl_deinit(new_crl[j]);
1907 return ret;
1911 * gnutls_certificate_set_x509_crl_file:
1912 * @res: is a #gnutls_certificate_credentials_t structure.
1913 * @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
1914 * @type: is PEM or DER
1916 * This function adds the trusted CRLs in order to verify client or server
1917 * certificates. In case of a client this is not required
1918 * to be called if the certificates are not verified using
1919 * gnutls_certificate_verify_peers2().
1920 * This function may be called multiple times.
1922 * Returns: number of CRLs processed or a negative error code on error.
1925 gnutls_certificate_set_x509_crl_file (gnutls_certificate_credentials_t res,
1926 const char *crlfile,
1927 gnutls_x509_crt_fmt_t type)
1929 int ret;
1930 size_t size;
1931 char *data = (void*)read_binary_file (crlfile, &size);
1933 if (data == NULL)
1935 gnutls_assert ();
1936 return GNUTLS_E_FILE_ERROR;
1939 if (type == GNUTLS_X509_FMT_DER)
1940 ret = parse_der_crl_mem (res->tlist, data, size);
1941 else
1942 ret = parse_pem_crl_mem (res->tlist, data, size);
1944 free (data);
1946 if (ret < 0)
1948 gnutls_assert ();
1949 return ret;
1952 return ret;
1955 #include <gnutls/pkcs12.h>
1957 static int
1958 parse_pkcs12 (gnutls_certificate_credentials_t res,
1959 gnutls_pkcs12_t p12,
1960 const char *password,
1961 gnutls_x509_privkey_t * key,
1962 gnutls_x509_crt_t * cert, gnutls_x509_crl_t * crl)
1964 gnutls_pkcs12_bag_t bag = NULL;
1965 int idx = 0;
1966 int ret;
1967 size_t cert_id_size = 0;
1968 size_t key_id_size = 0;
1969 uint8_t cert_id[20];
1970 uint8_t key_id[20];
1971 int privkey_ok = 0;
1973 *cert = NULL;
1974 *key = NULL;
1975 *crl = NULL;
1977 /* find the first private key */
1978 for (;;)
1980 int elements_in_bag;
1981 int i;
1983 ret = gnutls_pkcs12_bag_init (&bag);
1984 if (ret < 0)
1986 bag = NULL;
1987 gnutls_assert ();
1988 goto done;
1991 ret = gnutls_pkcs12_get_bag (p12, idx, bag);
1992 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1993 break;
1994 if (ret < 0)
1996 gnutls_assert ();
1997 goto done;
2000 ret = gnutls_pkcs12_bag_get_type (bag, 0);
2001 if (ret < 0)
2003 gnutls_assert ();
2004 goto done;
2007 if (ret == GNUTLS_BAG_ENCRYPTED)
2009 ret = gnutls_pkcs12_bag_decrypt (bag, password);
2010 if (ret < 0)
2012 gnutls_assert ();
2013 goto done;
2017 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
2018 if (elements_in_bag < 0)
2020 gnutls_assert ();
2021 goto done;
2024 for (i = 0; i < elements_in_bag; i++)
2026 int type;
2027 gnutls_datum_t data;
2029 type = gnutls_pkcs12_bag_get_type (bag, i);
2030 if (type < 0)
2032 gnutls_assert ();
2033 goto done;
2036 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
2037 if (ret < 0)
2039 gnutls_assert ();
2040 goto done;
2043 switch (type)
2045 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
2046 case GNUTLS_BAG_PKCS8_KEY:
2047 if (*key != NULL) /* too simple to continue */
2049 gnutls_assert ();
2050 break;
2053 ret = gnutls_x509_privkey_init (key);
2054 if (ret < 0)
2056 gnutls_assert ();
2057 goto done;
2060 ret = gnutls_x509_privkey_import_pkcs8
2061 (*key, &data, GNUTLS_X509_FMT_DER, password,
2062 type == GNUTLS_BAG_PKCS8_KEY ? GNUTLS_PKCS_PLAIN : 0);
2063 if (ret < 0)
2065 gnutls_assert ();
2066 gnutls_x509_privkey_deinit (*key);
2067 goto done;
2070 key_id_size = sizeof (key_id);
2071 ret =
2072 gnutls_x509_privkey_get_key_id (*key, 0, key_id,
2073 &key_id_size);
2074 if (ret < 0)
2076 gnutls_assert ();
2077 gnutls_x509_privkey_deinit (*key);
2078 goto done;
2081 privkey_ok = 1; /* break */
2082 break;
2083 default:
2084 break;
2088 idx++;
2089 gnutls_pkcs12_bag_deinit (bag);
2091 if (privkey_ok != 0) /* private key was found */
2092 break;
2095 if (privkey_ok == 0) /* no private key */
2097 gnutls_assert ();
2098 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2101 /* now find the corresponding certificate
2103 idx = 0;
2104 bag = NULL;
2105 for (;;)
2107 int elements_in_bag;
2108 int i;
2110 ret = gnutls_pkcs12_bag_init (&bag);
2111 if (ret < 0)
2113 bag = NULL;
2114 gnutls_assert ();
2115 goto done;
2118 ret = gnutls_pkcs12_get_bag (p12, idx, bag);
2119 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
2120 break;
2121 if (ret < 0)
2123 gnutls_assert ();
2124 goto done;
2127 ret = gnutls_pkcs12_bag_get_type (bag, 0);
2128 if (ret < 0)
2130 gnutls_assert ();
2131 goto done;
2134 if (ret == GNUTLS_BAG_ENCRYPTED)
2136 ret = gnutls_pkcs12_bag_decrypt (bag, password);
2137 if (ret < 0)
2139 gnutls_assert ();
2140 goto done;
2144 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
2145 if (elements_in_bag < 0)
2147 gnutls_assert ();
2148 goto done;
2151 for (i = 0; i < elements_in_bag; i++)
2153 int type;
2154 gnutls_datum_t data;
2156 type = gnutls_pkcs12_bag_get_type (bag, i);
2157 if (type < 0)
2159 gnutls_assert ();
2160 goto done;
2163 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
2164 if (ret < 0)
2166 gnutls_assert ();
2167 goto done;
2170 switch (type)
2172 case GNUTLS_BAG_CERTIFICATE:
2173 if (*cert != NULL) /* no need to set it again */
2175 gnutls_assert ();
2176 break;
2179 ret = gnutls_x509_crt_init (cert);
2180 if (ret < 0)
2182 gnutls_assert ();
2183 goto done;
2186 ret =
2187 gnutls_x509_crt_import (*cert, &data, GNUTLS_X509_FMT_DER);
2188 if (ret < 0)
2190 gnutls_assert ();
2191 gnutls_x509_crt_deinit (*cert);
2192 goto done;
2195 /* check if the key id match */
2196 cert_id_size = sizeof (cert_id);
2197 ret =
2198 gnutls_x509_crt_get_key_id (*cert, 0, cert_id, &cert_id_size);
2199 if (ret < 0)
2201 gnutls_assert ();
2202 gnutls_x509_crt_deinit (*cert);
2203 goto done;
2206 if (memcmp (cert_id, key_id, cert_id_size) != 0)
2207 { /* they don't match - skip the certificate */
2208 gnutls_x509_crt_deinit (*cert);
2209 *cert = NULL;
2211 break;
2213 case GNUTLS_BAG_CRL:
2214 if (*crl != NULL)
2216 gnutls_assert ();
2217 break;
2220 ret = gnutls_x509_crl_init (crl);
2221 if (ret < 0)
2223 gnutls_assert ();
2224 goto done;
2227 ret = gnutls_x509_crl_import (*crl, &data, GNUTLS_X509_FMT_DER);
2228 if (ret < 0)
2230 gnutls_assert ();
2231 gnutls_x509_crl_deinit (*crl);
2232 goto done;
2234 break;
2236 case GNUTLS_BAG_ENCRYPTED:
2237 /* XXX Bother to recurse one level down? Unlikely to
2238 use the same password anyway. */
2239 case GNUTLS_BAG_EMPTY:
2240 default:
2241 break;
2245 idx++;
2246 gnutls_pkcs12_bag_deinit (bag);
2249 ret = 0;
2251 done:
2252 if (bag)
2253 gnutls_pkcs12_bag_deinit (bag);
2255 return ret;
2259 * gnutls_certificate_set_x509_simple_pkcs12_file:
2260 * @res: is a #gnutls_certificate_credentials_t structure.
2261 * @pkcs12file: filename of file containing PKCS#12 blob.
2262 * @type: is PEM or DER of the @pkcs12file.
2263 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
2265 * This function sets a certificate/private key pair and/or a CRL in
2266 * the gnutls_certificate_credentials_t structure. This function may
2267 * be called more than once (in case multiple keys/certificates exist
2268 * for the server).
2270 * PKCS#12 files with a MAC, encrypted bags and PKCS #8
2271 * private keys are supported. However,
2272 * only password based security, and the same password for all
2273 * operations, are supported.
2275 * PKCS#12 file may contain many keys and/or certificates, and there
2276 * is no way to identify which key/certificate pair you want. You
2277 * should make sure the PKCS#12 file only contain one key/certificate
2278 * pair and/or one CRL.
2280 * It is believed that the limitations of this function is acceptable
2281 * for most usage, and that any more flexibility would introduce
2282 * complexity that would make it harder to use this functionality at
2283 * all.
2285 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
2288 gnutls_certificate_set_x509_simple_pkcs12_file
2289 (gnutls_certificate_credentials_t res, const char *pkcs12file,
2290 gnutls_x509_crt_fmt_t type, const char *password)
2292 gnutls_datum_t p12blob;
2293 size_t size;
2294 int ret;
2296 p12blob.data = (void*)read_binary_file (pkcs12file, &size);
2297 p12blob.size = (unsigned int) size;
2298 if (p12blob.data == NULL)
2300 gnutls_assert ();
2301 return GNUTLS_E_FILE_ERROR;
2304 ret =
2305 gnutls_certificate_set_x509_simple_pkcs12_mem (res, &p12blob, type,
2306 password);
2307 free (p12blob.data);
2309 return ret;
2313 * gnutls_certificate_set_x509_simple_pkcs12_mem:
2314 * @res: is a #gnutls_certificate_credentials_t structure.
2315 * @p12blob: the PKCS#12 blob.
2316 * @type: is PEM or DER of the @pkcs12file.
2317 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
2319 * This function sets a certificate/private key pair and/or a CRL in
2320 * the gnutls_certificate_credentials_t structure. This function may
2321 * be called more than once (in case multiple keys/certificates exist
2322 * for the server).
2324 * MAC:ed PKCS#12 files are supported. Encrypted PKCS#12 bags are
2325 * supported. Encrypted PKCS#8 private keys are supported. However,
2326 * only password based security, and the same password for all
2327 * operations, are supported.
2329 * PKCS#12 file may contain many keys and/or certificates, and there
2330 * is no way to identify which key/certificate pair you want. You
2331 * should make sure the PKCS#12 file only contain one key/certificate
2332 * pair and/or one CRL.
2334 * It is believed that the limitations of this function is acceptable
2335 * for most usage, and that any more flexibility would introduce
2336 * complexity that would make it harder to use this functionality at
2337 * all.
2339 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
2341 * Since: 2.8.0
2344 gnutls_certificate_set_x509_simple_pkcs12_mem
2345 (gnutls_certificate_credentials_t res, const gnutls_datum_t * p12blob,
2346 gnutls_x509_crt_fmt_t type, const char *password)
2348 gnutls_pkcs12_t p12;
2349 gnutls_x509_privkey_t key = NULL;
2350 gnutls_x509_crt_t cert = NULL;
2351 gnutls_x509_crl_t crl = NULL;
2352 int ret;
2354 ret = gnutls_pkcs12_init (&p12);
2355 if (ret < 0)
2357 gnutls_assert ();
2358 return ret;
2361 ret = gnutls_pkcs12_import (p12, p12blob, type, 0);
2362 if (ret < 0)
2364 gnutls_assert ();
2365 gnutls_pkcs12_deinit (p12);
2366 return ret;
2369 if (password)
2371 ret = gnutls_pkcs12_verify_mac (p12, password);
2372 if (ret < 0)
2374 gnutls_assert ();
2375 gnutls_pkcs12_deinit (p12);
2376 return ret;
2380 ret = parse_pkcs12 (res, p12, password, &key, &cert, &crl);
2381 gnutls_pkcs12_deinit (p12);
2382 if (ret < 0)
2384 gnutls_assert ();
2385 return ret;
2388 if (key && cert)
2390 ret = gnutls_certificate_set_x509_key (res, &cert, 1, key);
2391 if (ret < 0)
2393 gnutls_assert ();
2394 goto done;
2398 if (crl)
2400 ret = gnutls_certificate_set_x509_crl (res, &crl, 1);
2401 if (ret < 0)
2403 gnutls_assert ();
2404 goto done;
2408 ret = 0;
2410 done:
2411 if (cert)
2412 gnutls_x509_crt_deinit (cert);
2413 if (key)
2414 gnutls_x509_privkey_deinit (key);
2415 if (crl)
2416 gnutls_x509_crl_deinit (crl);
2418 return ret;
2424 * gnutls_certificate_free_crls:
2425 * @sc: is a #gnutls_certificate_credentials_t structure.
2427 * This function will delete all the CRLs associated
2428 * with the given credentials.
2430 void
2431 gnutls_certificate_free_crls (gnutls_certificate_credentials_t sc)
2433 /* do nothing for now */
2434 return;