documented update
[gnutls.git] / lib / gnutls_x509.c
blob130d75c351ab1a578ffa69b535d25ce8f41e9400
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"
45 #if defined _WIN32 || defined __WIN32__
46 #include <wincrypt.h>
47 #endif
50 * some x509 certificate parsing functions.
53 /* Check if the number of bits of the key in the certificate
54 * is unacceptable.
56 inline static int
57 check_bits (gnutls_x509_crt_t crt, unsigned int max_bits)
59 int ret;
60 unsigned int bits;
62 ret = gnutls_x509_crt_get_pk_algorithm (crt, &bits);
63 if (ret < 0)
65 gnutls_assert ();
66 return ret;
69 if (bits > max_bits && max_bits > 0)
71 gnutls_assert ();
72 return GNUTLS_E_CONSTRAINT_ERROR;
75 return 0;
79 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) { \
80 if (peer_certificate_list[x]) \
81 gnutls_x509_crt_deinit(peer_certificate_list[x]); \
82 } \
83 gnutls_free( peer_certificate_list)
85 /*-
86 * _gnutls_x509_cert_verify_peers - return the peer's certificate status
87 * @session: is a gnutls session
89 * This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.).
90 * The return value (status) should be one of the gnutls_certificate_status_t enumerated elements.
91 * However you must also check the peer's name in order to check if the verified certificate belongs to the
92 * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
93 -*/
94 int
95 _gnutls_x509_cert_verify_peers (gnutls_session_t session,
96 unsigned int *status)
98 cert_auth_info_t info;
99 gnutls_certificate_credentials_t cred;
100 gnutls_x509_crt_t *peer_certificate_list;
101 int peer_certificate_list_size, i, x, ret;
103 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
105 info = _gnutls_get_auth_info (session);
106 if (info == NULL)
108 gnutls_assert ();
109 return GNUTLS_E_INVALID_REQUEST;
112 cred = (gnutls_certificate_credentials_t)
113 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
114 if (cred == NULL)
116 gnutls_assert ();
117 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
120 if (info->raw_certificate_list == NULL || info->ncerts == 0)
121 return GNUTLS_E_NO_CERTIFICATE_FOUND;
123 if (info->ncerts > cred->verify_depth && cred->verify_depth > 0)
125 gnutls_assert ();
126 return GNUTLS_E_CONSTRAINT_ERROR;
129 /* generate a list of gnutls_certs based on the auth info
130 * raw certs.
132 peer_certificate_list_size = info->ncerts;
133 peer_certificate_list =
134 gnutls_calloc (peer_certificate_list_size, sizeof (gnutls_x509_crt_t));
135 if (peer_certificate_list == NULL)
137 gnutls_assert ();
138 return GNUTLS_E_MEMORY_ERROR;
141 for (i = 0; i < peer_certificate_list_size; i++)
143 ret = gnutls_x509_crt_init (&peer_certificate_list[i]);
144 if (ret < 0)
146 gnutls_assert ();
147 CLEAR_CERTS;
148 return ret;
151 ret =
152 gnutls_x509_crt_import (peer_certificate_list[i],
153 &info->raw_certificate_list[i],
154 GNUTLS_X509_FMT_DER);
155 if (ret < 0)
157 gnutls_assert ();
158 CLEAR_CERTS;
159 return ret;
162 ret = check_bits (peer_certificate_list[i], cred->verify_bits);
163 if (ret < 0)
165 gnutls_assert ();
166 CLEAR_CERTS;
167 return ret;
172 /* Verify certificate
175 ret = gnutls_x509_trust_list_verify_crt (cred->tlist, peer_certificate_list,
176 peer_certificate_list_size,
177 cred->verify_flags | session->internals.
178 priorities.additional_verify_flags,
179 status, NULL);
181 CLEAR_CERTS;
183 if (ret < 0)
185 gnutls_assert ();
186 return ret;
189 return 0;
193 * Read certificates and private keys, from files, memory etc.
196 /* returns error if the certificate has different algorithm than
197 * the given key parameters.
199 static int
200 _gnutls_check_key_cert_match (gnutls_certificate_credentials_t res)
202 int pk = gnutls_pubkey_get_pk_algorithm(res->certs[res->ncerts-1].cert_list[0].pubkey, NULL);
204 if (gnutls_privkey_get_pk_algorithm (res->pkey[res->ncerts - 1], NULL) !=
207 gnutls_assert ();
208 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
211 return 0;
214 /* Returns the name of the certificate of a null name
216 static int get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t *names)
218 size_t max_size;
219 int i, ret = 0, ret2;
220 char name[MAX_CN];
222 for (i = 0; !(ret < 0); i++)
224 max_size = sizeof(name);
226 ret = gnutls_x509_crt_get_subject_alt_name(crt, i, name, &max_size, NULL);
227 if (ret == GNUTLS_SAN_DNSNAME)
229 ret2 = _gnutls_str_array_append(names, name, max_size);
230 if (ret2 < 0)
232 _gnutls_str_array_clear(names);
233 return gnutls_assert_val(ret2);
238 max_size = sizeof(name);
239 ret = gnutls_x509_crt_get_dn_by_oid (crt, OID_X520_COMMON_NAME, 0, 0, name, &max_size);
240 if (ret >= 0)
242 ret = _gnutls_str_array_append(names, name, max_size);
243 if (ret < 0)
245 _gnutls_str_array_clear(names);
246 return gnutls_assert_val(ret);
250 return 0;
253 static int get_x509_name_raw(gnutls_datum_t *raw, gnutls_x509_crt_fmt_t type, gnutls_str_array_t *names)
255 int ret;
256 gnutls_x509_crt_t crt;
258 ret = gnutls_x509_crt_init (&crt);
259 if (ret < 0)
261 gnutls_assert ();
262 return ret;
265 ret = gnutls_x509_crt_import (crt, raw, type);
266 if (ret < 0)
268 gnutls_assert ();
269 gnutls_x509_crt_deinit (crt);
270 return ret;
273 ret = get_x509_name(crt, names);
274 gnutls_x509_crt_deinit (crt);
275 return ret;
278 /* Reads a DER encoded certificate list from memory and stores it to a
279 * gnutls_cert structure. Returns the number of certificates parsed.
281 static int
282 parse_der_cert_mem (gnutls_certificate_credentials_t res,
283 const void *input_cert, int input_cert_size)
285 gnutls_datum_t tmp;
286 gnutls_x509_crt_t crt;
287 gnutls_pcert_st *ccert;
288 int ret;
289 gnutls_str_array_t names;
291 _gnutls_str_array_init(&names);
293 ccert = gnutls_malloc (sizeof (*ccert));
294 if (ccert == NULL)
296 gnutls_assert ();
297 return GNUTLS_E_MEMORY_ERROR;
300 ret = gnutls_x509_crt_init (&crt);
301 if (ret < 0)
303 gnutls_assert ();
304 goto cleanup;
307 tmp.data = (uint8_t *) input_cert;
308 tmp.size = input_cert_size;
310 ret = gnutls_x509_crt_import (crt, &tmp, GNUTLS_X509_FMT_DER);
311 if (ret < 0)
313 gnutls_assert ();
314 gnutls_x509_crt_deinit (crt);
315 goto cleanup;
318 ret = get_x509_name(crt, &names);
319 if (ret < 0)
321 gnutls_assert();
322 gnutls_x509_crt_deinit (crt);
323 goto cleanup;
326 ret = gnutls_pcert_import_x509 (ccert, crt, 0);
327 gnutls_x509_crt_deinit (crt);
329 if (ret < 0)
331 gnutls_assert ();
332 goto cleanup;
335 ret = certificate_credential_append_crt_list (res, names, ccert, 1);
336 if (ret < 0)
338 gnutls_assert ();
339 goto cleanup;
342 return ret;
344 cleanup:
345 _gnutls_str_array_clear(&names);
346 gnutls_free (ccert);
347 return ret;
350 /* Reads a base64 encoded certificate list from memory and stores it to
351 * a gnutls_cert structure. Returns the number of certificate parsed.
353 static int
354 parse_pem_cert_mem (gnutls_certificate_credentials_t res,
355 const char *input_cert, int input_cert_size)
357 int size;
358 const char *ptr;
359 gnutls_datum_t tmp;
360 int ret, count, i;
361 gnutls_pcert_st *certs = NULL;
362 gnutls_str_array_t names;
364 _gnutls_str_array_init(&names);
366 /* move to the certificate
368 ptr = memmem (input_cert, input_cert_size,
369 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
370 if (ptr == NULL)
371 ptr = memmem (input_cert, input_cert_size,
372 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
374 if (ptr == NULL)
376 gnutls_assert ();
377 return GNUTLS_E_BASE64_DECODING_ERROR;
379 size = input_cert_size - (ptr - input_cert);
381 count = 0;
385 certs = gnutls_realloc_fast (certs, (count + 1) * sizeof (gnutls_pcert_st));
387 if (certs == NULL)
389 gnutls_assert ();
390 ret = GNUTLS_E_MEMORY_ERROR;
391 goto cleanup;
394 tmp.data = (void*)ptr;
395 tmp.size = size;
397 if (count == 0)
399 ret = get_x509_name_raw(&tmp, GNUTLS_X509_FMT_PEM, &names);
400 if (ret < 0)
402 gnutls_assert();
403 goto cleanup;
407 ret = gnutls_pcert_import_x509_raw (&certs[count], &tmp, GNUTLS_X509_FMT_PEM, 0);
408 if (ret < 0)
410 gnutls_assert ();
411 goto cleanup;
414 /* now we move ptr after the pem header
416 ptr++;
417 /* find the next certificate (if any)
419 size = input_cert_size - (ptr - input_cert);
421 if (size > 0)
423 char *ptr3;
425 ptr3 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
426 if (ptr3 == NULL)
427 ptr3 = memmem (ptr, size, PEM_CERT_SEP2,
428 sizeof (PEM_CERT_SEP2) - 1);
430 ptr = ptr3;
432 else
433 ptr = NULL;
435 count++;
438 while (ptr != NULL);
440 ret = certificate_credential_append_crt_list (res, names, certs, count);
441 if (ret < 0)
443 gnutls_assert ();
444 goto cleanup;
447 return count;
449 cleanup:
450 _gnutls_str_array_clear(&names);
451 for (i=0;i<count;i++)
452 gnutls_pcert_deinit(&certs[i]);
453 gnutls_free(certs);
454 return ret;
459 /* Reads a DER or PEM certificate from memory
461 static int
462 read_cert_mem (gnutls_certificate_credentials_t res, const void *cert,
463 int cert_size, gnutls_x509_crt_fmt_t type)
465 int ret;
467 if (type == GNUTLS_X509_FMT_DER)
468 ret = parse_der_cert_mem (res, cert, cert_size);
469 else
470 ret = parse_pem_cert_mem (res, cert, cert_size);
472 if (ret < 0)
474 gnutls_assert ();
475 return ret;
478 return ret;
481 static int
482 _gnutls_x509_raw_privkey_to_privkey (gnutls_privkey_t * privkey,
483 const gnutls_datum_t * raw_key,
484 gnutls_x509_crt_fmt_t type)
486 gnutls_x509_privkey_t tmpkey;
487 int ret;
489 ret = gnutls_x509_privkey_init (&tmpkey);
490 if (ret < 0)
492 gnutls_assert ();
493 return ret;
496 ret = gnutls_x509_privkey_import (tmpkey, raw_key, type);
497 if (ret < 0)
499 gnutls_assert ();
500 gnutls_x509_privkey_deinit (tmpkey);
501 return ret;
504 ret = gnutls_privkey_init (privkey);
505 if (ret < 0)
507 gnutls_assert ();
508 gnutls_x509_privkey_deinit (tmpkey);
509 return ret;
512 ret =
513 gnutls_privkey_import_x509 (*privkey, tmpkey,
514 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
515 if (ret < 0)
517 gnutls_assert ();
518 gnutls_x509_privkey_deinit (tmpkey);
519 gnutls_privkey_deinit (*privkey);
520 return ret;
523 return 0;
526 /* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory. Type
527 * indicates the certificate format. KEY can be NULL, to indicate
528 * that GnuTLS doesn't know the private key.
530 static int
531 read_key_mem (gnutls_certificate_credentials_t res,
532 const void *key, int key_size, gnutls_x509_crt_fmt_t type)
534 int ret;
535 gnutls_datum_t tmp;
536 gnutls_privkey_t privkey;
538 if (key)
540 tmp.data = (uint8_t *) key;
541 tmp.size = key_size;
543 ret = _gnutls_x509_raw_privkey_to_privkey (&privkey, &tmp, type);
544 if (ret < 0)
546 gnutls_assert ();
547 return ret;
550 ret = certificate_credentials_append_pkey (res, privkey);
551 if (ret < 0)
553 gnutls_assert ();
554 gnutls_privkey_deinit (privkey);
555 return ret;
559 else
561 gnutls_assert ();
562 return GNUTLS_E_INVALID_REQUEST;
566 return 0;
569 #ifdef ENABLE_PKCS11
570 /* Reads a private key from a token.
572 static int
573 read_key_url (gnutls_certificate_credentials_t res, const char *url)
575 int ret;
576 gnutls_pkcs11_privkey_t key1 = NULL;
577 gnutls_privkey_t pkey = NULL;
579 /* allocate space for the pkey list
582 ret = gnutls_pkcs11_privkey_init (&key1);
583 if (ret < 0)
585 gnutls_assert ();
586 return ret;
589 ret = gnutls_pkcs11_privkey_import_url (key1, url, 0);
590 if (ret < 0)
592 gnutls_assert ();
593 goto cleanup;
596 ret = gnutls_privkey_init (&pkey);
597 if (ret < 0)
599 gnutls_assert ();
600 goto cleanup;
603 ret =
604 gnutls_privkey_import_pkcs11 (pkey, key1,
605 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
606 if (ret < 0)
608 gnutls_assert ();
609 goto cleanup;
612 ret = certificate_credentials_append_pkey (res, pkey);
613 if (ret < 0)
615 gnutls_assert ();
616 goto cleanup;
619 return 0;
621 cleanup:
622 if (pkey)
623 gnutls_privkey_deinit (pkey);
625 if (key1)
626 gnutls_pkcs11_privkey_deinit (key1);
628 return ret;
631 /* Reads a private key from a token.
633 static int
634 read_cas_url (gnutls_certificate_credentials_t res, const char *url)
636 int ret;
637 gnutls_x509_crt_t *xcrt_list = NULL;
638 gnutls_pkcs11_obj_t *pcrt_list = NULL;
639 unsigned int pcrt_list_size = 0;
641 /* FIXME: should we use login? */
642 ret =
643 gnutls_pkcs11_obj_list_import_url (NULL, &pcrt_list_size, url,
644 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
645 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
647 gnutls_assert ();
648 return ret;
651 if (pcrt_list_size == 0)
653 gnutls_assert ();
654 return 0;
657 pcrt_list = gnutls_malloc (sizeof (*pcrt_list) * pcrt_list_size);
658 if (pcrt_list == NULL)
660 gnutls_assert ();
661 return GNUTLS_E_MEMORY_ERROR;
664 ret =
665 gnutls_pkcs11_obj_list_import_url (pcrt_list, &pcrt_list_size, url,
666 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
667 if (ret < 0)
669 gnutls_assert ();
670 goto cleanup;
673 xcrt_list = gnutls_malloc (sizeof (*xcrt_list) * pcrt_list_size);
674 if (xcrt_list == NULL)
676 gnutls_assert ();
677 ret = GNUTLS_E_MEMORY_ERROR;
678 goto cleanup;
681 ret =
682 gnutls_x509_crt_list_import_pkcs11 (xcrt_list, pcrt_list_size, pcrt_list,
684 if (xcrt_list == NULL)
686 gnutls_assert ();
687 ret = GNUTLS_E_MEMORY_ERROR;
688 goto cleanup;
691 ret = gnutls_x509_trust_list_add_cas(res->tlist, xcrt_list, pcrt_list_size, 0);
692 if (ret < 0)
694 gnutls_assert();
695 goto cleanup;
698 cleanup:
699 gnutls_free (xcrt_list);
700 gnutls_free (pcrt_list);
702 return ret;
707 /* Reads a private key from a token.
709 static int
710 read_cert_url (gnutls_certificate_credentials_t res, const char *url)
712 int ret;
713 gnutls_x509_crt_t crt;
714 gnutls_pcert_st *ccert;
715 gnutls_str_array_t names;
717 _gnutls_str_array_init(&names);
719 ccert = gnutls_malloc (sizeof (*ccert));
720 if (ccert == NULL)
722 gnutls_assert ();
723 return GNUTLS_E_MEMORY_ERROR;
726 ret = gnutls_x509_crt_init (&crt);
727 if (ret < 0)
729 gnutls_assert ();
730 goto cleanup;
733 ret = gnutls_x509_crt_import_pkcs11_url (crt, url, 0);
734 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
735 ret =
736 gnutls_x509_crt_import_pkcs11_url (crt, url,
737 GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
739 if (ret < 0)
741 gnutls_assert ();
742 gnutls_x509_crt_deinit (crt);
743 goto cleanup;
746 ret = get_x509_name(crt, &names);
747 if (ret < 0)
749 gnutls_assert ();
750 gnutls_x509_crt_deinit (crt);
751 goto cleanup;
754 ret = gnutls_pcert_import_x509 (ccert, crt, 0);
755 gnutls_x509_crt_deinit (crt);
757 if (ret < 0)
759 gnutls_assert ();
760 goto cleanup;
763 ret = certificate_credential_append_crt_list (res, names, ccert, 1);
764 if (ret < 0)
766 gnutls_assert ();
767 goto cleanup;
770 return 0;
772 cleanup:
773 _gnutls_str_array_clear(&names);
774 gnutls_free (ccert);
775 return ret;
777 #endif
779 /* Reads a certificate file
781 static int
782 read_cert_file (gnutls_certificate_credentials_t res,
783 const char *certfile, gnutls_x509_crt_fmt_t type)
785 int ret;
786 size_t size;
787 char *data;
789 #ifdef ENABLE_PKCS11
790 if (strncmp (certfile, "pkcs11:", 7) == 0)
792 return read_cert_url (res, certfile);
794 #endif /* ENABLE_PKCS11 */
796 data = read_binary_file (certfile, &size);
798 if (data == NULL)
800 gnutls_assert ();
801 return GNUTLS_E_FILE_ERROR;
804 ret = read_cert_mem (res, data, size, type);
805 free (data);
807 return ret;
813 /* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
814 * stores it).
816 static int
817 read_key_file (gnutls_certificate_credentials_t res,
818 const char *keyfile, gnutls_x509_crt_fmt_t type)
820 int ret;
821 size_t size;
822 char *data;
824 #ifdef ENABLE_PKCS11
825 if (strncmp (keyfile, "pkcs11:", 7) == 0)
827 return read_key_url (res, keyfile);
829 #endif /* ENABLE_PKCS11 */
831 data = read_binary_file (keyfile, &size);
833 if (data == NULL)
835 gnutls_assert ();
836 return GNUTLS_E_FILE_ERROR;
839 ret = read_key_mem (res, data, size, type);
840 free (data);
842 return ret;
846 * gnutls_certificate_set_x509_key_mem:
847 * @res: is a #gnutls_certificate_credentials_t structure.
848 * @cert: contains a certificate list (path) for the specified private key
849 * @key: is the private key, or %NULL
850 * @type: is PEM or DER
852 * This function sets a certificate/private key pair in the
853 * gnutls_certificate_credentials_t structure. This function may be called
854 * more than once, in case multiple keys/certificates exist for the
855 * server.
857 * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
858 * is supported. This means that certificates intended for signing cannot
859 * be used for ciphersuites that require encryption.
861 * If the certificate and the private key are given in PEM encoding
862 * then the strings that hold their values must be null terminated.
864 * The @key may be %NULL if you are using a sign callback, see
865 * gnutls_sign_callback_set().
867 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
870 gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t res,
871 const gnutls_datum_t * cert,
872 const gnutls_datum_t * key,
873 gnutls_x509_crt_fmt_t type)
875 int ret;
877 /* this should be first
879 if ((ret = read_key_mem (res, key ? key->data : NULL,
880 key ? key->size : 0, type)) < 0)
881 return ret;
883 if ((ret = read_cert_mem (res, cert->data, cert->size, type)) < 0)
884 return ret;
886 res->ncerts++;
888 if (key && (ret = _gnutls_check_key_cert_match (res)) < 0)
890 gnutls_assert ();
891 return ret;
894 return 0;
897 static int check_if_sorted(gnutls_pcert_st * crt, int nr)
899 gnutls_x509_crt_t x509;
900 char prev_dn[MAX_DN];
901 char dn[MAX_DN];
902 size_t prev_dn_size, dn_size;
903 int i, ret;
905 /* check if the X.509 list is ordered */
906 if (nr > 1 && crt[0].type == GNUTLS_CRT_X509)
909 for (i=0;i<nr;i++)
911 ret = gnutls_x509_crt_init(&x509);
912 if (ret < 0)
913 return gnutls_assert_val(ret);
915 ret = gnutls_x509_crt_import(x509, &crt[i].cert, GNUTLS_X509_FMT_DER);
916 if (ret < 0)
918 ret = gnutls_assert_val(ret);
919 goto cleanup;
922 if (i>0)
924 dn_size = sizeof(dn);
925 ret = gnutls_x509_crt_get_dn(x509, dn, &dn_size);
926 if (ret < 0)
928 ret = gnutls_assert_val(ret);
929 goto cleanup;
932 if (dn_size != prev_dn_size || memcmp(dn, prev_dn, dn_size) != 0)
934 ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
935 goto cleanup;
939 prev_dn_size = sizeof(prev_dn);
940 ret = gnutls_x509_crt_get_issuer_dn(x509, prev_dn, &prev_dn_size);
941 if (ret < 0)
943 ret = gnutls_assert_val(ret);
944 goto cleanup;
947 gnutls_x509_crt_deinit(x509);
951 return 0;
953 cleanup:
954 gnutls_x509_crt_deinit(x509);
955 return ret;
959 certificate_credential_append_crt_list (gnutls_certificate_credentials_t res,
960 gnutls_str_array_t names, gnutls_pcert_st * crt, int nr)
962 int ret;
964 ret = check_if_sorted(crt, nr);
965 if (ret < 0)
966 return gnutls_assert_val(ret);
968 res->certs = gnutls_realloc_fast (res->certs,
969 (1 + res->ncerts) *
970 sizeof (certs_st));
971 if (res->certs == NULL)
973 gnutls_assert ();
974 return GNUTLS_E_MEMORY_ERROR;
977 res->certs[res->ncerts].cert_list = crt;
978 res->certs[res->ncerts].cert_list_length = nr;
979 res->certs[res->ncerts].names = names;
981 return 0;
986 certificate_credentials_append_pkey (gnutls_certificate_credentials_t res,
987 gnutls_privkey_t pkey)
989 res->pkey = gnutls_realloc_fast (res->pkey,
990 (1 + res->ncerts) *
991 sizeof (gnutls_privkey_t));
992 if (res->pkey == NULL)
994 gnutls_assert ();
995 return GNUTLS_E_MEMORY_ERROR;
997 res->pkey[res->ncerts] = pkey;
998 return 0;
1003 * gnutls_certificate_set_x509_key:
1004 * @res: is a #gnutls_certificate_credentials_t structure.
1005 * @cert_list: contains a certificate list (path) for the specified private key
1006 * @cert_list_size: holds the size of the certificate list
1007 * @key: is a gnutls_x509_privkey_t key
1009 * This function sets a certificate/private key pair in the
1010 * gnutls_certificate_credentials_t structure. This function may be
1011 * called more than once, in case multiple keys/certificates exist for
1012 * the server. For clients that wants to send more than its own end
1013 * entity certificate (e.g., also an intermediate CA cert) then put
1014 * the certificate chain in @cert_list.
1018 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1020 * Since: 2.4.0
1023 gnutls_certificate_set_x509_key (gnutls_certificate_credentials_t res,
1024 gnutls_x509_crt_t * cert_list,
1025 int cert_list_size,
1026 gnutls_x509_privkey_t key)
1028 int ret, i;
1029 gnutls_privkey_t pkey;
1030 gnutls_pcert_st *pcerts = NULL;
1031 gnutls_str_array_t names;
1033 _gnutls_str_array_init(&names);
1035 /* this should be first
1037 ret = gnutls_privkey_init (&pkey);
1038 if (ret < 0)
1040 gnutls_assert ();
1041 return ret;
1044 ret = gnutls_privkey_import_x509 (pkey, key, GNUTLS_PRIVKEY_IMPORT_COPY);
1045 if (ret < 0)
1047 gnutls_assert ();
1048 return ret;
1051 ret = certificate_credentials_append_pkey (res, pkey);
1052 if (ret < 0)
1054 gnutls_assert ();
1055 return ret;
1058 /* load certificates */
1059 pcerts = gnutls_malloc (sizeof (gnutls_pcert_st) * cert_list_size);
1060 if (pcerts == NULL)
1062 gnutls_assert ();
1063 return GNUTLS_E_MEMORY_ERROR;
1066 ret = get_x509_name(cert_list[0], &names);
1067 if (ret < 0)
1068 return gnutls_assert_val(ret);
1070 for (i = 0; i < cert_list_size; i++)
1072 ret = gnutls_pcert_import_x509 (&pcerts[i], cert_list[i], 0);
1073 if (ret < 0)
1075 gnutls_assert ();
1076 goto cleanup;
1080 ret = certificate_credential_append_crt_list (res, names, pcerts, cert_list_size);
1081 if (ret < 0)
1083 gnutls_assert ();
1084 goto cleanup;
1087 res->ncerts++;
1089 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1091 gnutls_assert ();
1092 return ret;
1095 return 0;
1097 cleanup:
1098 _gnutls_str_array_clear(&names);
1099 return ret;
1103 * gnutls_certificate_set_key:
1104 * @res: is a #gnutls_certificate_credentials_t structure.
1105 * @names: is an array of DNS name of the certificate (NULL if none)
1106 * @names_size: holds the size of the names list
1107 * @pcert_list: contains a certificate list (path) for the specified private key
1108 * @pcert_list_size: holds the size of the certificate list
1109 * @key: is a gnutls_x509_privkey_t key
1111 * This function sets a certificate/private key pair in the
1112 * gnutls_certificate_credentials_t structure. This function may be
1113 * called more than once, in case multiple keys/certificates exist for
1114 * the server. For clients that wants to send more than its own end
1115 * entity certificate (e.g., also an intermediate CA cert) then put
1116 * the certificate chain in @pcert_list. The @pcert_list and @key will
1117 * become part of the credentials structure and must not
1118 * be deallocated. They will be automatically deallocated when
1119 * @res is deinitialized.
1121 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1123 * Since: 3.0
1126 gnutls_certificate_set_key (gnutls_certificate_credentials_t res,
1127 const char** names,
1128 int names_size,
1129 gnutls_pcert_st * pcert_list,
1130 int pcert_list_size,
1131 gnutls_privkey_t key)
1133 int ret, i;
1134 gnutls_str_array_t str_names;
1136 _gnutls_str_array_init(&str_names);
1138 if (names != NULL && names_size > 0)
1140 for (i=0;i<names_size;i++)
1142 ret = _gnutls_str_array_append(&str_names, names[i], strlen(names[i]));
1143 if (ret < 0)
1145 ret = gnutls_assert_val(ret);
1146 goto cleanup;
1151 ret = certificate_credentials_append_pkey (res, key);
1152 if (ret < 0)
1154 gnutls_assert ();
1155 goto cleanup;
1158 ret = certificate_credential_append_crt_list (res, str_names, pcert_list, pcert_list_size);
1159 if (ret < 0)
1161 gnutls_assert ();
1162 goto cleanup;
1165 res->ncerts++;
1167 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1169 gnutls_assert ();
1170 return ret;
1173 return 0;
1175 cleanup:
1176 _gnutls_str_array_clear(&str_names);
1177 return ret;
1181 * gnutls_certificate_set_x509_key_file:
1182 * @res: is a #gnutls_certificate_credentials_t structure.
1183 * @certfile: is a file that containing the certificate list (path) for
1184 * the specified private key, in PKCS7 format, or a list of certificates
1185 * @keyfile: is a file that contains the private key
1186 * @type: is PEM or DER
1188 * This function sets a certificate/private key pair in the
1189 * gnutls_certificate_credentials_t structure. This function may be
1190 * called more than once, in case multiple keys/certificates exist for
1191 * the server. For clients that need to send more than its own end
1192 * entity certificate, e.g., also an intermediate CA cert, then the
1193 * @certfile must contain the ordered certificate chain.
1195 * This function can also accept PKCS #11 URLs at @keyfile and @certfile. In that case it
1196 * will import the private key and certificate indicated by the URLs.
1198 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1201 gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t res,
1202 const char *certfile,
1203 const char *keyfile,
1204 gnutls_x509_crt_fmt_t type)
1206 int ret;
1208 /* this should be first
1210 if ((ret = read_key_file (res, keyfile, type)) < 0)
1211 return ret;
1213 if ((ret = read_cert_file (res, certfile, type)) < 0)
1214 return ret;
1216 res->ncerts++;
1218 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1220 gnutls_assert ();
1221 return ret;
1224 return 0;
1227 static int
1228 add_new_crt_to_rdn_seq (gnutls_certificate_credentials_t res, gnutls_x509_crt_t* crts,
1229 unsigned int crt_size)
1231 gnutls_datum_t tmp;
1232 int ret;
1233 size_t newsize;
1234 unsigned char *newdata;
1235 unsigned i;
1237 /* Add DN of the last added CAs to the RDN sequence
1238 * This will be sent to clients when a certificate
1239 * request message is sent.
1242 /* FIXME: in case of a client it is not needed
1243 * to do that. This would save time and memory.
1244 * However we don't have that information available
1245 * here.
1246 * Further, this function is now much more efficient,
1247 * so optimizing that is less important.
1250 for (i = 0; i < crt_size; i++)
1252 if ((ret = gnutls_x509_crt_get_raw_dn (crts[i], &tmp)) < 0)
1254 gnutls_assert ();
1255 return ret;
1258 newsize = res->x509_rdn_sequence.size + 2 + tmp.size;
1259 if (newsize < res->x509_rdn_sequence.size)
1261 gnutls_assert ();
1262 _gnutls_free_datum (&tmp);
1263 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1266 newdata = gnutls_realloc (res->x509_rdn_sequence.data, newsize);
1267 if (newdata == NULL)
1269 gnutls_assert ();
1270 _gnutls_free_datum (&tmp);
1271 return GNUTLS_E_MEMORY_ERROR;
1274 _gnutls_write_datum16 (newdata + res->x509_rdn_sequence.size, tmp);
1275 _gnutls_free_datum (&tmp);
1277 res->x509_rdn_sequence.size = newsize;
1278 res->x509_rdn_sequence.data = newdata;
1281 return 0;
1284 /* Returns 0 if it's ok to use the gnutls_kx_algorithm_t with this
1285 * certificate (uses the KeyUsage field).
1288 _gnutls_check_key_usage (const gnutls_pcert_st* cert, gnutls_kx_algorithm_t alg)
1290 unsigned int key_usage = 0;
1291 int encipher_type;
1293 if (cert == NULL)
1295 gnutls_assert ();
1296 return GNUTLS_E_INTERNAL_ERROR;
1299 if (_gnutls_map_kx_get_cred (alg, 1) == GNUTLS_CRD_CERTIFICATE ||
1300 _gnutls_map_kx_get_cred (alg, 0) == GNUTLS_CRD_CERTIFICATE)
1303 gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
1305 encipher_type = _gnutls_kx_encipher_type (alg);
1307 if (key_usage != 0 && encipher_type != CIPHER_IGN)
1309 /* If key_usage has been set in the certificate
1312 if (encipher_type == CIPHER_ENCRYPT)
1314 /* If the key exchange method requires an encipher
1315 * type algorithm, and key's usage does not permit
1316 * encipherment, then fail.
1318 if (!(key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT))
1320 gnutls_assert ();
1321 return GNUTLS_E_KEY_USAGE_VIOLATION;
1325 if (encipher_type == CIPHER_SIGN)
1327 /* The same as above, but for sign only keys
1329 if (!(key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE))
1331 gnutls_assert ();
1332 return GNUTLS_E_KEY_USAGE_VIOLATION;
1337 return 0;
1340 static int
1341 parse_pem_ca_mem (gnutls_certificate_credentials_t res,
1342 const uint8_t * input_cert, int input_cert_size)
1344 gnutls_x509_crt_t *x509_cert_list;
1345 unsigned int x509_ncerts;
1346 gnutls_datum_t tmp;
1347 int ret;
1349 tmp.data = (void*)input_cert;
1350 tmp.size = input_cert_size;
1352 ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp,
1353 GNUTLS_X509_FMT_PEM, 0);
1354 if (ret < 0)
1356 gnutls_assert();
1357 return ret;
1360 if ((ret = add_new_crt_to_rdn_seq (res, x509_cert_list, x509_ncerts)) < 0)
1362 gnutls_assert();
1363 goto cleanup;
1366 ret = gnutls_x509_trust_list_add_cas(res->tlist, x509_cert_list, x509_ncerts, 0);
1367 if (ret < 0)
1369 gnutls_assert();
1370 goto cleanup;
1373 cleanup:
1374 gnutls_free(x509_cert_list);
1375 return ret;
1378 /* Reads a DER encoded certificate list from memory and stores it to a
1379 * gnutls_cert structure. Returns the number of certificates parsed.
1381 static int
1382 parse_der_ca_mem (gnutls_certificate_credentials_t res,
1383 const void *input_cert, int input_cert_size)
1385 gnutls_x509_crt_t crt;
1386 gnutls_datum_t tmp;
1387 int ret;
1389 tmp.data = (void*)input_cert;
1390 tmp.size = input_cert_size;
1392 ret = gnutls_x509_crt_init( &crt);
1393 if (ret < 0)
1395 gnutls_assert();
1396 return ret;
1399 ret = gnutls_x509_crt_import( crt, &tmp, GNUTLS_X509_FMT_DER);
1400 if (ret < 0)
1402 gnutls_assert();
1403 goto cleanup;
1406 if ((ret = add_new_crt_to_rdn_seq (res, &crt, 1)) < 0)
1408 gnutls_assert();
1409 goto cleanup;
1412 ret = gnutls_x509_trust_list_add_cas(res->tlist, &crt, 1, 0);
1413 if (ret < 0)
1415 gnutls_assert();
1416 goto cleanup;
1419 return ret;
1421 cleanup:
1422 gnutls_x509_crt_deinit(crt);
1423 return ret;
1427 * gnutls_certificate_set_x509_trust_mem:
1428 * @res: is a #gnutls_certificate_credentials_t structure.
1429 * @ca: is a list of trusted CAs or a DER certificate
1430 * @type: is DER or PEM
1432 * This function adds the trusted CAs in order to verify client or
1433 * server certificates. In case of a client this is not required to be
1434 * called if the certificates are not verified using
1435 * gnutls_certificate_verify_peers2(). This function may be called
1436 * multiple times.
1438 * In case of a server the CAs set here will be sent to the client if
1439 * a certificate request is sent. This can be disabled using
1440 * gnutls_certificate_send_x509_rdn_sequence().
1442 * Returns: the number of certificates processed or a negative error code
1443 * on error.
1446 gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t res,
1447 const gnutls_datum_t * ca,
1448 gnutls_x509_crt_fmt_t type)
1450 int ret;
1452 if (type == GNUTLS_X509_FMT_DER)
1453 ret = parse_der_ca_mem (res,
1454 ca->data, ca->size);
1455 else
1456 ret = parse_pem_ca_mem (res,
1457 ca->data, ca->size);
1459 if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
1460 return 0;
1462 return ret;
1466 * gnutls_certificate_set_x509_trust:
1467 * @res: is a #gnutls_certificate_credentials_t structure.
1468 * @ca_list: is a list of trusted CAs
1469 * @ca_list_size: holds the size of the CA list
1471 * This function adds the trusted CAs in order to verify client
1472 * or server certificates. In case of a client this is not required
1473 * to be called if the certificates are not verified using
1474 * gnutls_certificate_verify_peers2().
1475 * This function may be called multiple times.
1477 * In case of a server the CAs set here will be sent to the client if
1478 * a certificate request is sent. This can be disabled using
1479 * gnutls_certificate_send_x509_rdn_sequence().
1481 * Returns: the number of certificates processed or a negative error code
1482 * on error.
1484 * Since: 2.4.0
1487 gnutls_certificate_set_x509_trust (gnutls_certificate_credentials_t res,
1488 gnutls_x509_crt_t * ca_list,
1489 int ca_list_size)
1491 int ret, i, j;
1492 gnutls_x509_crt_t new_list[ca_list_size];
1494 for (i = 0; i < ca_list_size; i++)
1496 ret = gnutls_x509_crt_init (&new_list[i]);
1497 if (ret < 0)
1499 gnutls_assert ();
1500 goto cleanup;
1503 ret = _gnutls_x509_crt_cpy (new_list[i], ca_list[i]);
1504 if (ret < 0)
1506 gnutls_assert ();
1507 goto cleanup;
1511 if ((ret = add_new_crt_to_rdn_seq (res, new_list, ca_list_size)) < 0)
1513 gnutls_assert();
1514 goto cleanup;
1517 ret = gnutls_x509_trust_list_add_cas(res->tlist, new_list, ca_list_size, 0);
1518 if (ret < 0)
1520 gnutls_assert ();
1521 goto cleanup;
1524 return ret;
1526 cleanup:
1527 for (j=0;j<i;i++)
1528 gnutls_x509_crt_deinit(new_list[j]);
1530 return ret;
1535 * gnutls_certificate_set_x509_trust_file:
1536 * @cred: is a #gnutls_certificate_credentials_t structure.
1537 * @cafile: is a file containing the list of trusted CAs (DER or PEM list)
1538 * @type: is PEM or DER
1540 * This function adds the trusted CAs in order to verify client or
1541 * server certificates. In case of a client this is not required to
1542 * be called if the certificates are not verified using
1543 * gnutls_certificate_verify_peers2(). This function may be called
1544 * multiple times.
1546 * In case of a server the names of the CAs set here will be sent to
1547 * the client if a certificate request is sent. This can be disabled
1548 * using gnutls_certificate_send_x509_rdn_sequence().
1550 * This function can also accept PKCS #11 URLs. In that case it
1551 * will import all certificates that are marked as trusted.
1553 * Returns: number of certificates processed, or a negative error code on
1554 * error.
1557 gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t cred,
1558 const char *cafile,
1559 gnutls_x509_crt_fmt_t type)
1561 int ret;
1562 gnutls_datum_t cas;
1563 size_t size;
1565 #ifdef ENABLE_PKCS11
1566 if (strncmp (cafile, "pkcs11:", 7) == 0)
1568 return read_cas_url (cred, cafile);
1570 #endif
1572 cas.data = (void*)read_binary_file (cafile, &size);
1573 if (cas.data == NULL)
1575 gnutls_assert ();
1576 return GNUTLS_E_FILE_ERROR;
1579 cas.size = size;
1581 ret = gnutls_certificate_set_x509_trust_mem(cred, &cas, type);
1583 free (cas.data);
1585 if (ret < 0)
1587 gnutls_assert ();
1588 return ret;
1591 return ret;
1594 #ifdef _WIN32
1595 static int
1596 set_x509_system_trust_file (gnutls_certificate_credentials_t cred)
1598 HCERTSTORE store = CertOpenSystemStore(0, "CA");
1599 const CERT_CONTEXT *cert;
1600 const CRL_CONTEXT *crl;
1601 gnutls_datum_t data;
1602 int ret = 0;
1603 unsigned int i;
1605 for (i=0;i<2;i++)
1608 if (i==0) store = CertOpenSystemStore(0, "ROOT");
1609 else store = CertOpenSystemStore(0, "CA");
1611 if (store == NULL) return GNUTLS_E_FILE_ERROR;
1613 cert = CertEnumCertificatesInStore(store, NULL);
1614 crl = CertEnumCRLsInStore(store, NULL);
1616 while(cert != NULL)
1618 if (cert->dwCertEncodingType == X509_ASN_ENCODING)
1620 data.data = cert->pbCertEncoded;
1621 data.size = cert->cbCertEncoded;
1622 if (gnutls_certificate_set_x509_trust_mem (cred, &data, GNUTLS_X509_FMT_DER) > 0)
1623 ret++;
1625 cert = CertEnumCertificatesInStore(store, cert);
1628 while(crl != NULL)
1630 if (crl->dwCertEncodingType == X509_ASN_ENCODING)
1632 data.data = crl->pbCrlEncoded;
1633 data.size = crl->cbCrlEncoded;
1635 gnutls_certificate_set_x509_crl_mem(cred, &data, GNUTLS_X509_FMT_DER);
1637 crl = CertEnumCRLsInStore(store, crl);
1639 CertCloseStore(store, 0);
1642 return ret;
1644 #elif defined(DEFAULT_TRUST_STORE_FILE)
1645 static int
1646 set_x509_system_trust_file (gnutls_certificate_credentials_t cred)
1648 int ret, r;
1649 gnutls_datum_t cas;
1650 size_t size;
1652 cas.data = (void*)read_binary_file (DEFAULT_TRUST_STORE_FILE, &size);
1653 if (cas.data == NULL)
1655 gnutls_assert ();
1656 return GNUTLS_E_FILE_ERROR;
1659 cas.size = size;
1661 ret = gnutls_certificate_set_x509_trust_mem(cred, &cas, GNUTLS_X509_FMT_PEM);
1663 free (cas.data);
1665 if (ret < 0)
1667 gnutls_assert ();
1668 return ret;
1671 r = ret;
1673 #ifdef DEFAULT_CRL_FILE
1674 cas.data = (void*)read_binary_file (DEFAULT_CRL_FILE, &size);
1675 if (cas.data == NULL)
1677 gnutls_assert ();
1678 return r;
1681 cas.size = size;
1683 ret = gnutls_certificate_set_x509_crl_mem(cred, &cas, GNUTLS_X509_FMT_PEM);
1685 free (cas.data);
1687 if (ret < 0)
1689 gnutls_assert ();
1690 return ret;
1692 #endif
1694 return r;
1696 #endif
1699 * gnutls_certificate_set_x509_system_trust:
1700 * @cred: is a #gnutls_certificate_credentials_t structure.
1702 * This function adds the system's default trusted CAs in order to
1703 * verify client or server certificates.
1705 * In the case the system is currently unsupported %GNUTLS_E_UNIMPLEMENTED_FEATURE
1706 * is returned.
1708 * Returns: the number of certificates processed or a negative error code
1709 * on error.
1711 * Since: 3.0
1714 gnutls_certificate_set_x509_system_trust (gnutls_certificate_credentials_t cred)
1716 #if !defined(_WIN32) && !defined(DEFAULT_TRUST_STORE_PKCS11) && !defined(DEFAULT_TRUST_STORE_FILE)
1717 int r = GNUTLS_E_UNIMPLEMENTED_FEATURE;
1718 #else
1719 int ret, r = 0;
1720 #endif
1722 #if defined(ENABLE_PKCS11) && defined(DEFAULT_TRUST_STORE_PKCS11)
1723 ret = read_cas_url (cred, DEFAULT_TRUST_STORE_PKCS11);
1724 if (ret > 0)
1725 r += ret;
1726 #endif
1728 #ifdef DEFAULT_TRUST_STORE_FILE
1729 ret = set_x509_system_trust_file(cred);
1730 if (ret > 0)
1731 r += ret;
1732 #endif
1734 return r;
1737 static int
1738 parse_pem_crl_mem (gnutls_x509_trust_list_t tlist,
1739 const char * input_crl, unsigned int input_crl_size)
1741 gnutls_x509_crl_t *x509_crl_list;
1742 unsigned int x509_ncrls;
1743 gnutls_datum_t tmp;
1744 int ret;
1746 tmp.data = (void*)input_crl;
1747 tmp.size = input_crl_size;
1749 ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp,
1750 GNUTLS_X509_FMT_PEM, 0);
1751 if (ret < 0)
1753 gnutls_assert();
1754 return ret;
1757 ret = gnutls_x509_trust_list_add_crls(tlist, x509_crl_list, x509_ncrls, 0, 0);
1758 if (ret < 0)
1760 gnutls_assert();
1761 goto cleanup;
1764 cleanup:
1765 gnutls_free(x509_crl_list);
1766 return ret;
1769 /* Reads a DER encoded certificate list from memory and stores it to a
1770 * gnutls_cert structure. Returns the number of certificates parsed.
1772 static int
1773 parse_der_crl_mem (gnutls_x509_trust_list_t tlist,
1774 const void *input_crl, unsigned int input_crl_size)
1776 gnutls_x509_crl_t crl;
1777 gnutls_datum_t tmp;
1778 int ret;
1780 tmp.data = (void*)input_crl;
1781 tmp.size = input_crl_size;
1783 ret = gnutls_x509_crl_init( &crl);
1784 if (ret < 0)
1786 gnutls_assert();
1787 return ret;
1790 ret = gnutls_x509_crl_import( crl, &tmp, GNUTLS_X509_FMT_DER);
1791 if (ret < 0)
1793 gnutls_assert();
1794 goto cleanup;
1797 ret = gnutls_x509_trust_list_add_crls(tlist, &crl, 1, 0, 0);
1798 if (ret < 0)
1800 gnutls_assert();
1801 goto cleanup;
1804 return ret;
1806 cleanup:
1807 gnutls_x509_crl_deinit(crl);
1808 return ret;
1813 /* Reads a DER or PEM CRL from memory
1815 static int
1816 read_crl_mem (gnutls_certificate_credentials_t res, const void *crl,
1817 int crl_size, gnutls_x509_crt_fmt_t type)
1819 int ret;
1821 if (type == GNUTLS_X509_FMT_DER)
1822 ret = parse_der_crl_mem (res->tlist, crl, crl_size);
1823 else
1824 ret = parse_pem_crl_mem (res->tlist, crl, crl_size);
1826 if (ret < 0)
1828 gnutls_assert ();
1831 return ret;
1835 * gnutls_certificate_set_x509_crl_mem:
1836 * @res: is a #gnutls_certificate_credentials_t structure.
1837 * @CRL: is a list of trusted CRLs. They should have been verified before.
1838 * @type: is DER or PEM
1840 * This function adds the trusted CRLs in order to verify client or
1841 * server certificates. In case of a client this is not required to
1842 * be called if the certificates are not verified using
1843 * gnutls_certificate_verify_peers2(). This function may be called
1844 * multiple times.
1846 * Returns: number of CRLs processed, or a negative error code on error.
1849 gnutls_certificate_set_x509_crl_mem (gnutls_certificate_credentials_t res,
1850 const gnutls_datum_t * CRL,
1851 gnutls_x509_crt_fmt_t type)
1853 return read_crl_mem (res, CRL->data, CRL->size, type);
1857 * gnutls_certificate_set_x509_crl:
1858 * @res: is a #gnutls_certificate_credentials_t structure.
1859 * @crl_list: is a list of trusted CRLs. They should have been verified before.
1860 * @crl_list_size: holds the size of the crl_list
1862 * This function adds the trusted CRLs in order to verify client or
1863 * server certificates. In case of a client this is not required to
1864 * be called if the certificates are not verified using
1865 * gnutls_certificate_verify_peers2(). This function may be called
1866 * multiple times.
1868 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1870 * Since: 2.4.0
1873 gnutls_certificate_set_x509_crl (gnutls_certificate_credentials_t res,
1874 gnutls_x509_crl_t * crl_list,
1875 int crl_list_size)
1877 int ret, i, j;
1878 gnutls_x509_crl_t new_crl[crl_list_size];
1880 for (i = 0; i < crl_list_size; i++)
1882 ret = gnutls_x509_crl_init (&new_crl[i]);
1883 if (ret < 0)
1885 gnutls_assert ();
1886 goto cleanup;
1889 ret = _gnutls_x509_crl_cpy (new_crl[i], crl_list[i]);
1890 if (ret < 0)
1892 gnutls_assert ();
1893 goto cleanup;
1897 ret = gnutls_x509_trust_list_add_crls(res->tlist, new_crl, crl_list_size, 0, 0);
1898 if (ret < 0)
1900 gnutls_assert ();
1901 goto cleanup;
1904 return ret;
1906 cleanup:
1907 for (j=0;j<i;j++)
1908 gnutls_x509_crl_deinit(new_crl[j]);
1910 return ret;
1914 * gnutls_certificate_set_x509_crl_file:
1915 * @res: is a #gnutls_certificate_credentials_t structure.
1916 * @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
1917 * @type: is PEM or DER
1919 * This function adds the trusted CRLs in order to verify client or server
1920 * certificates. In case of a client this is not required
1921 * to be called if the certificates are not verified using
1922 * gnutls_certificate_verify_peers2().
1923 * This function may be called multiple times.
1925 * Returns: number of CRLs processed or a negative error code on error.
1928 gnutls_certificate_set_x509_crl_file (gnutls_certificate_credentials_t res,
1929 const char *crlfile,
1930 gnutls_x509_crt_fmt_t type)
1932 int ret;
1933 size_t size;
1934 char *data = (void*)read_binary_file (crlfile, &size);
1936 if (data == NULL)
1938 gnutls_assert ();
1939 return GNUTLS_E_FILE_ERROR;
1942 if (type == GNUTLS_X509_FMT_DER)
1943 ret = parse_der_crl_mem (res->tlist, data, size);
1944 else
1945 ret = parse_pem_crl_mem (res->tlist, data, size);
1947 free (data);
1949 if (ret < 0)
1951 gnutls_assert ();
1952 return ret;
1955 return ret;
1958 #include <gnutls/pkcs12.h>
1960 static int
1961 parse_pkcs12 (gnutls_certificate_credentials_t res,
1962 gnutls_pkcs12_t p12,
1963 const char *password,
1964 gnutls_x509_privkey_t * key,
1965 gnutls_x509_crt_t * cert, gnutls_x509_crl_t * crl)
1967 gnutls_pkcs12_bag_t bag = NULL;
1968 int idx = 0;
1969 int ret;
1970 size_t cert_id_size = 0;
1971 size_t key_id_size = 0;
1972 uint8_t cert_id[20];
1973 uint8_t key_id[20];
1974 int privkey_ok = 0;
1976 *cert = NULL;
1977 *key = NULL;
1978 *crl = NULL;
1980 /* find the first private key */
1981 for (;;)
1983 int elements_in_bag;
1984 int i;
1986 ret = gnutls_pkcs12_bag_init (&bag);
1987 if (ret < 0)
1989 bag = NULL;
1990 gnutls_assert ();
1991 goto done;
1994 ret = gnutls_pkcs12_get_bag (p12, idx, bag);
1995 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1996 break;
1997 if (ret < 0)
1999 gnutls_assert ();
2000 goto done;
2003 ret = gnutls_pkcs12_bag_get_type (bag, 0);
2004 if (ret < 0)
2006 gnutls_assert ();
2007 goto done;
2010 if (ret == GNUTLS_BAG_ENCRYPTED)
2012 ret = gnutls_pkcs12_bag_decrypt (bag, password);
2013 if (ret < 0)
2015 gnutls_assert ();
2016 goto done;
2020 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
2021 if (elements_in_bag < 0)
2023 gnutls_assert ();
2024 goto done;
2027 for (i = 0; i < elements_in_bag; i++)
2029 int type;
2030 gnutls_datum_t data;
2032 type = gnutls_pkcs12_bag_get_type (bag, i);
2033 if (type < 0)
2035 gnutls_assert ();
2036 goto done;
2039 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
2040 if (ret < 0)
2042 gnutls_assert ();
2043 goto done;
2046 switch (type)
2048 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
2049 case GNUTLS_BAG_PKCS8_KEY:
2050 if (*key != NULL) /* too simple to continue */
2052 gnutls_assert ();
2053 break;
2056 ret = gnutls_x509_privkey_init (key);
2057 if (ret < 0)
2059 gnutls_assert ();
2060 goto done;
2063 ret = gnutls_x509_privkey_import_pkcs8
2064 (*key, &data, GNUTLS_X509_FMT_DER, password,
2065 type == GNUTLS_BAG_PKCS8_KEY ? GNUTLS_PKCS_PLAIN : 0);
2066 if (ret < 0)
2068 gnutls_assert ();
2069 gnutls_x509_privkey_deinit (*key);
2070 goto done;
2073 key_id_size = sizeof (key_id);
2074 ret =
2075 gnutls_x509_privkey_get_key_id (*key, 0, key_id,
2076 &key_id_size);
2077 if (ret < 0)
2079 gnutls_assert ();
2080 gnutls_x509_privkey_deinit (*key);
2081 goto done;
2084 privkey_ok = 1; /* break */
2085 break;
2086 default:
2087 break;
2091 idx++;
2092 gnutls_pkcs12_bag_deinit (bag);
2094 if (privkey_ok != 0) /* private key was found */
2095 break;
2098 if (privkey_ok == 0) /* no private key */
2100 gnutls_assert ();
2101 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2104 /* now find the corresponding certificate
2106 idx = 0;
2107 bag = NULL;
2108 for (;;)
2110 int elements_in_bag;
2111 int i;
2113 ret = gnutls_pkcs12_bag_init (&bag);
2114 if (ret < 0)
2116 bag = NULL;
2117 gnutls_assert ();
2118 goto done;
2121 ret = gnutls_pkcs12_get_bag (p12, idx, bag);
2122 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
2123 break;
2124 if (ret < 0)
2126 gnutls_assert ();
2127 goto done;
2130 ret = gnutls_pkcs12_bag_get_type (bag, 0);
2131 if (ret < 0)
2133 gnutls_assert ();
2134 goto done;
2137 if (ret == GNUTLS_BAG_ENCRYPTED)
2139 ret = gnutls_pkcs12_bag_decrypt (bag, password);
2140 if (ret < 0)
2142 gnutls_assert ();
2143 goto done;
2147 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
2148 if (elements_in_bag < 0)
2150 gnutls_assert ();
2151 goto done;
2154 for (i = 0; i < elements_in_bag; i++)
2156 int type;
2157 gnutls_datum_t data;
2159 type = gnutls_pkcs12_bag_get_type (bag, i);
2160 if (type < 0)
2162 gnutls_assert ();
2163 goto done;
2166 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
2167 if (ret < 0)
2169 gnutls_assert ();
2170 goto done;
2173 switch (type)
2175 case GNUTLS_BAG_CERTIFICATE:
2176 if (*cert != NULL) /* no need to set it again */
2178 gnutls_assert ();
2179 break;
2182 ret = gnutls_x509_crt_init (cert);
2183 if (ret < 0)
2185 gnutls_assert ();
2186 goto done;
2189 ret =
2190 gnutls_x509_crt_import (*cert, &data, GNUTLS_X509_FMT_DER);
2191 if (ret < 0)
2193 gnutls_assert ();
2194 gnutls_x509_crt_deinit (*cert);
2195 goto done;
2198 /* check if the key id match */
2199 cert_id_size = sizeof (cert_id);
2200 ret =
2201 gnutls_x509_crt_get_key_id (*cert, 0, cert_id, &cert_id_size);
2202 if (ret < 0)
2204 gnutls_assert ();
2205 gnutls_x509_crt_deinit (*cert);
2206 goto done;
2209 if (memcmp (cert_id, key_id, cert_id_size) != 0)
2210 { /* they don't match - skip the certificate */
2211 gnutls_x509_crt_deinit (*cert);
2212 *cert = NULL;
2214 break;
2216 case GNUTLS_BAG_CRL:
2217 if (*crl != NULL)
2219 gnutls_assert ();
2220 break;
2223 ret = gnutls_x509_crl_init (crl);
2224 if (ret < 0)
2226 gnutls_assert ();
2227 goto done;
2230 ret = gnutls_x509_crl_import (*crl, &data, GNUTLS_X509_FMT_DER);
2231 if (ret < 0)
2233 gnutls_assert ();
2234 gnutls_x509_crl_deinit (*crl);
2235 goto done;
2237 break;
2239 case GNUTLS_BAG_ENCRYPTED:
2240 /* XXX Bother to recurse one level down? Unlikely to
2241 use the same password anyway. */
2242 case GNUTLS_BAG_EMPTY:
2243 default:
2244 break;
2248 idx++;
2249 gnutls_pkcs12_bag_deinit (bag);
2252 ret = 0;
2254 done:
2255 if (bag)
2256 gnutls_pkcs12_bag_deinit (bag);
2258 return ret;
2262 * gnutls_certificate_set_x509_simple_pkcs12_file:
2263 * @res: is a #gnutls_certificate_credentials_t structure.
2264 * @pkcs12file: filename of file containing PKCS#12 blob.
2265 * @type: is PEM or DER of the @pkcs12file.
2266 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
2268 * This function sets a certificate/private key pair and/or a CRL in
2269 * the gnutls_certificate_credentials_t structure. This function may
2270 * be called more than once (in case multiple keys/certificates exist
2271 * for the server).
2273 * PKCS#12 files with a MAC, encrypted bags and PKCS #8
2274 * private keys are supported. However,
2275 * only password based security, and the same password for all
2276 * operations, are supported.
2278 * PKCS#12 file may contain many keys and/or certificates, and there
2279 * is no way to identify which key/certificate pair you want. You
2280 * should make sure the PKCS#12 file only contain one key/certificate
2281 * pair and/or one CRL.
2283 * It is believed that the limitations of this function is acceptable
2284 * for most usage, and that any more flexibility would introduce
2285 * complexity that would make it harder to use this functionality at
2286 * all.
2288 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
2291 gnutls_certificate_set_x509_simple_pkcs12_file
2292 (gnutls_certificate_credentials_t res, const char *pkcs12file,
2293 gnutls_x509_crt_fmt_t type, const char *password)
2295 gnutls_datum_t p12blob;
2296 size_t size;
2297 int ret;
2299 p12blob.data = (void*)read_binary_file (pkcs12file, &size);
2300 p12blob.size = (unsigned int) size;
2301 if (p12blob.data == NULL)
2303 gnutls_assert ();
2304 return GNUTLS_E_FILE_ERROR;
2307 ret =
2308 gnutls_certificate_set_x509_simple_pkcs12_mem (res, &p12blob, type,
2309 password);
2310 free (p12blob.data);
2312 return ret;
2316 * gnutls_certificate_set_x509_simple_pkcs12_mem:
2317 * @res: is a #gnutls_certificate_credentials_t structure.
2318 * @p12blob: the PKCS#12 blob.
2319 * @type: is PEM or DER of the @pkcs12file.
2320 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
2322 * This function sets a certificate/private key pair and/or a CRL in
2323 * the gnutls_certificate_credentials_t structure. This function may
2324 * be called more than once (in case multiple keys/certificates exist
2325 * for the server).
2327 * MAC:ed PKCS#12 files are supported. Encrypted PKCS#12 bags are
2328 * supported. Encrypted PKCS#8 private keys are supported. However,
2329 * only password based security, and the same password for all
2330 * operations, are supported.
2332 * PKCS#12 file may contain many keys and/or certificates, and there
2333 * is no way to identify which key/certificate pair you want. You
2334 * should make sure the PKCS#12 file only contain one key/certificate
2335 * pair and/or one CRL.
2337 * It is believed that the limitations of this function is acceptable
2338 * for most usage, and that any more flexibility would introduce
2339 * complexity that would make it harder to use this functionality at
2340 * all.
2342 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
2344 * Since: 2.8.0
2347 gnutls_certificate_set_x509_simple_pkcs12_mem
2348 (gnutls_certificate_credentials_t res, const gnutls_datum_t * p12blob,
2349 gnutls_x509_crt_fmt_t type, const char *password)
2351 gnutls_pkcs12_t p12;
2352 gnutls_x509_privkey_t key = NULL;
2353 gnutls_x509_crt_t cert = NULL;
2354 gnutls_x509_crl_t crl = NULL;
2355 int ret;
2357 ret = gnutls_pkcs12_init (&p12);
2358 if (ret < 0)
2360 gnutls_assert ();
2361 return ret;
2364 ret = gnutls_pkcs12_import (p12, p12blob, type, 0);
2365 if (ret < 0)
2367 gnutls_assert ();
2368 gnutls_pkcs12_deinit (p12);
2369 return ret;
2372 if (password)
2374 ret = gnutls_pkcs12_verify_mac (p12, password);
2375 if (ret < 0)
2377 gnutls_assert ();
2378 gnutls_pkcs12_deinit (p12);
2379 return ret;
2383 ret = parse_pkcs12 (res, p12, password, &key, &cert, &crl);
2384 gnutls_pkcs12_deinit (p12);
2385 if (ret < 0)
2387 gnutls_assert ();
2388 return ret;
2391 if (key && cert)
2393 ret = gnutls_certificate_set_x509_key (res, &cert, 1, key);
2394 if (ret < 0)
2396 gnutls_assert ();
2397 goto done;
2401 if (crl)
2403 ret = gnutls_certificate_set_x509_crl (res, &crl, 1);
2404 if (ret < 0)
2406 gnutls_assert ();
2407 goto done;
2411 ret = 0;
2413 done:
2414 if (cert)
2415 gnutls_x509_crt_deinit (cert);
2416 if (key)
2417 gnutls_x509_privkey_deinit (key);
2418 if (crl)
2419 gnutls_x509_crl_deinit (crl);
2421 return ret;
2427 * gnutls_certificate_free_crls:
2428 * @sc: is a #gnutls_certificate_credentials_t structure.
2430 * This function will delete all the CRLs associated
2431 * with the given credentials.
2433 void
2434 gnutls_certificate_free_crls (gnutls_certificate_credentials_t sc)
2436 /* do nothing for now */
2437 return;