gnutls_certificate_verify_peers2() checks ocsp status response if available.
[gnutls.git] / lib / gnutls_x509.c
blob1d7128b3c2328cfbf0d0b7a163d3c4a163717036
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 <gnutls/ocsp.h>
42 #include "x509/common.h"
43 #include "x509/x509_int.h"
44 #include <gnutls_str_array.h>
45 #include "read-file.h"
46 #ifdef _WIN32
47 # include <wincrypt.h>
48 #endif
51 * some x509 certificate parsing functions.
54 /* Check if the number of bits of the key in the certificate
55 * is unacceptable.
57 inline static int
58 check_bits (gnutls_session_t session, gnutls_x509_crt_t crt, unsigned int max_bits)
60 int ret, pk;
61 unsigned int bits;
63 ret = gnutls_x509_crt_get_pk_algorithm (crt, &bits);
64 if (ret < 0)
66 gnutls_assert ();
67 return ret;
69 pk = ret;
71 if (bits > max_bits && max_bits > 0)
73 gnutls_assert ();
74 return GNUTLS_E_CONSTRAINT_ERROR;
77 if (gnutls_pk_bits_to_sec_param(pk, bits) == GNUTLS_SEC_PARAM_INSECURE)
79 gnutls_assert();
80 _gnutls_audit_log(session, "The security level of the certificate (%s: %u) is weak\n", gnutls_pk_get_name(pk), bits);
81 if (session->internals.priorities.allow_weak_keys == 0)
82 return gnutls_assert_val(GNUTLS_E_CERTIFICATE_ERROR);
85 return 0;
88 /* three days */
89 #define MAX_OCSP_VALIDITY_SECS (3*60*60*24)
91 /* Returns:
92 * -1: certificate is revoked
93 * 1: certificate is ok
94 * 0: dunno
96 static int
97 check_ocsp_response (gnutls_session_t session, gnutls_x509_crt_t cert,
98 gnutls_x509_crt_t issuer,
99 gnutls_datum_t *data)
101 gnutls_ocsp_resp_t resp;
102 int ret;
103 unsigned int status, cert_status;
104 time_t rtime, vtime, ntime, now;
106 now = gnutls_time(0);
108 ret = gnutls_ocsp_resp_init (&resp);
109 if (ret < 0)
110 return gnutls_assert_val(0);
112 ret = gnutls_ocsp_resp_import (resp, data);
113 if (ret < 0)
114 return gnutls_assert_val(0);
116 ret = gnutls_ocsp_resp_check_crt(resp, 0, cert);
117 if (ret < 0)
119 _gnutls_audit_log (session, "Got OCSP response on an unrelated certificate (ignoring)\n");
120 ret = 0;
121 goto cleanup;
124 ret = gnutls_ocsp_resp_verify_direct( resp, issuer, &status, 0);
125 if (ret < 0)
126 return gnutls_assert_val(0);
128 /* do not consider revocation data if response was not verified */
129 if (status != 0)
131 ret = gnutls_assert_val(0);
132 goto cleanup;
135 ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL,
136 &cert_status, &vtime, &ntime, &rtime, NULL);
137 if (ret < 0)
139 ret = gnutls_assert_val(0);
140 goto cleanup;
143 if (cert_status == GNUTLS_OCSP_CERT_REVOKED)
145 _gnutls_audit_log(session, "The certificate was revoked via OCSP\n");
146 ret = gnutls_assert_val(-1);
147 goto cleanup;
150 if (ntime == -1)
152 if (now - vtime > MAX_OCSP_VALIDITY_SECS)
154 _gnutls_audit_log(session, "The OCSP response is old\n");
157 else
159 /* there is a newer OCSP answer, don't trust this one */
160 if (ntime < now)
162 _gnutls_audit_log(session, "There is a newer OCSP response but was not provided by the server\n");
166 ret = 1;
167 cleanup:
168 gnutls_ocsp_resp_deinit (resp);
170 return ret;
174 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) { \
175 if (peer_certificate_list[x]) \
176 gnutls_x509_crt_deinit(peer_certificate_list[x]); \
178 gnutls_free( peer_certificate_list)
181 * _gnutls_x509_cert_verify_peers - return the peer's certificate status
182 * @session: is a gnutls session
184 * This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.).
185 * The return value (status) should be one of the gnutls_certificate_status_t enumerated elements.
186 * However you must also check the peer's name in order to check if the verified certificate belongs to the
187 * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
190 _gnutls_x509_cert_verify_peers (gnutls_session_t session,
191 unsigned int *status)
193 cert_auth_info_t info;
194 gnutls_certificate_credentials_t cred;
195 gnutls_x509_crt_t *peer_certificate_list;
196 gnutls_datum_t resp;
197 int peer_certificate_list_size, i, x, ret;
198 gnutls_x509_crt_t issuer;
199 unsigned int ocsp_status = 0;
201 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
203 info = _gnutls_get_auth_info (session);
204 if (info == NULL)
206 gnutls_assert ();
207 return GNUTLS_E_INVALID_REQUEST;
210 cred = (gnutls_certificate_credentials_t)
211 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
212 if (cred == NULL)
214 gnutls_assert ();
215 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
218 if (info->raw_certificate_list == NULL || info->ncerts == 0)
219 return GNUTLS_E_NO_CERTIFICATE_FOUND;
221 if (info->ncerts > cred->verify_depth && cred->verify_depth > 0)
223 gnutls_assert ();
224 return GNUTLS_E_CONSTRAINT_ERROR;
227 /* generate a list of gnutls_certs based on the auth info
228 * raw certs.
230 peer_certificate_list_size = info->ncerts;
231 peer_certificate_list =
232 gnutls_calloc (peer_certificate_list_size, sizeof (gnutls_x509_crt_t));
233 if (peer_certificate_list == NULL)
235 gnutls_assert ();
236 return GNUTLS_E_MEMORY_ERROR;
239 for (i = 0; i < peer_certificate_list_size; i++)
241 ret = gnutls_x509_crt_init (&peer_certificate_list[i]);
242 if (ret < 0)
244 gnutls_assert ();
245 CLEAR_CERTS;
246 return ret;
249 ret =
250 gnutls_x509_crt_import (peer_certificate_list[i],
251 &info->raw_certificate_list[i],
252 GNUTLS_X509_FMT_DER);
253 if (ret < 0)
255 gnutls_assert ();
256 CLEAR_CERTS;
257 return ret;
260 ret = check_bits (session, peer_certificate_list[i], cred->verify_bits);
261 if (ret < 0)
263 gnutls_assert ();
264 CLEAR_CERTS;
265 return ret;
270 /* Use the OCSP extension if any */
271 ret = gnutls_ocsp_status_request_get(session, &resp);
272 if (ret < 0)
273 goto skip_ocsp;
275 if (peer_certificate_list_size > 1)
276 issuer = peer_certificate_list[1];
277 else
279 ret = gnutls_x509_trust_list_get_issuer(cred->tlist, peer_certificate_list[0],
280 &issuer, 0);
281 if (ret < 0)
283 goto skip_ocsp;
287 ret = check_ocsp_response(session, peer_certificate_list[0], issuer, &resp);
288 if (ret < 0) /* revoked */
289 ocsp_status |= GNUTLS_CERT_REVOKED;
291 skip_ocsp:
292 /* Verify certificate
294 ret = gnutls_x509_trust_list_verify_crt (cred->tlist, peer_certificate_list,
295 peer_certificate_list_size,
296 cred->verify_flags | session->internals.
297 priorities.additional_verify_flags,
298 status, NULL);
300 CLEAR_CERTS;
302 if (ret < 0)
304 gnutls_assert ();
305 return ret;
308 *status |= ocsp_status;
310 return 0;
314 * Read certificates and private keys, from files, memory etc.
318 /* Returns the name of the certificate of a null name
320 static int get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t *names)
322 size_t max_size;
323 int i, ret = 0, ret2;
324 char name[MAX_CN];
326 for (i = 0; !(ret < 0); i++)
328 max_size = sizeof(name);
330 ret = gnutls_x509_crt_get_subject_alt_name(crt, i, name, &max_size, NULL);
331 if (ret == GNUTLS_SAN_DNSNAME)
333 ret2 = _gnutls_str_array_append(names, name, max_size);
334 if (ret2 < 0)
336 _gnutls_str_array_clear(names);
337 return gnutls_assert_val(ret2);
342 max_size = sizeof(name);
343 ret = gnutls_x509_crt_get_dn_by_oid (crt, OID_X520_COMMON_NAME, 0, 0, name, &max_size);
344 if (ret >= 0)
346 ret = _gnutls_str_array_append(names, name, max_size);
347 if (ret < 0)
349 _gnutls_str_array_clear(names);
350 return gnutls_assert_val(ret);
354 return 0;
357 static int get_x509_name_raw(gnutls_datum_t *raw, gnutls_x509_crt_fmt_t type, gnutls_str_array_t *names)
359 int ret;
360 gnutls_x509_crt_t crt;
362 ret = gnutls_x509_crt_init (&crt);
363 if (ret < 0)
365 gnutls_assert ();
366 return ret;
369 ret = gnutls_x509_crt_import (crt, raw, type);
370 if (ret < 0)
372 gnutls_assert ();
373 gnutls_x509_crt_deinit (crt);
374 return ret;
377 ret = get_x509_name(crt, names);
378 gnutls_x509_crt_deinit (crt);
379 return ret;
382 /* Reads a DER encoded certificate list from memory and stores it to a
383 * gnutls_cert structure. Returns the number of certificates parsed.
385 static int
386 parse_der_cert_mem (gnutls_certificate_credentials_t res,
387 const void *input_cert, int input_cert_size)
389 gnutls_datum_t tmp;
390 gnutls_x509_crt_t crt;
391 gnutls_pcert_st *ccert;
392 int ret;
393 gnutls_str_array_t names;
395 _gnutls_str_array_init(&names);
397 ccert = gnutls_malloc (sizeof (*ccert));
398 if (ccert == NULL)
400 gnutls_assert ();
401 return GNUTLS_E_MEMORY_ERROR;
404 ret = gnutls_x509_crt_init (&crt);
405 if (ret < 0)
407 gnutls_assert ();
408 goto cleanup;
411 tmp.data = (uint8_t *) input_cert;
412 tmp.size = input_cert_size;
414 ret = gnutls_x509_crt_import (crt, &tmp, GNUTLS_X509_FMT_DER);
415 if (ret < 0)
417 gnutls_assert ();
418 gnutls_x509_crt_deinit (crt);
419 goto cleanup;
422 ret = get_x509_name(crt, &names);
423 if (ret < 0)
425 gnutls_assert();
426 gnutls_x509_crt_deinit (crt);
427 goto cleanup;
430 ret = gnutls_pcert_import_x509 (ccert, crt, 0);
431 gnutls_x509_crt_deinit (crt);
433 if (ret < 0)
435 gnutls_assert ();
436 goto cleanup;
439 ret = certificate_credential_append_crt_list (res, names, ccert, 1);
440 if (ret < 0)
442 gnutls_assert ();
443 goto cleanup;
446 return ret;
448 cleanup:
449 _gnutls_str_array_clear(&names);
450 gnutls_free (ccert);
451 return ret;
454 /* Reads a base64 encoded certificate list from memory and stores it to
455 * a gnutls_cert structure. Returns the number of certificate parsed.
457 static int
458 parse_pem_cert_mem (gnutls_certificate_credentials_t res,
459 const char *input_cert, int input_cert_size)
461 int size;
462 const char *ptr;
463 gnutls_datum_t tmp;
464 int ret, count, i;
465 gnutls_pcert_st *certs = NULL;
466 gnutls_str_array_t names;
468 _gnutls_str_array_init(&names);
470 /* move to the certificate
472 ptr = memmem (input_cert, input_cert_size,
473 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
474 if (ptr == NULL)
475 ptr = memmem (input_cert, input_cert_size,
476 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
478 if (ptr == NULL)
480 gnutls_assert ();
481 return GNUTLS_E_BASE64_DECODING_ERROR;
483 size = input_cert_size - (ptr - input_cert);
485 count = 0;
489 certs = gnutls_realloc_fast (certs, (count + 1) * sizeof (gnutls_pcert_st));
491 if (certs == NULL)
493 gnutls_assert ();
494 ret = GNUTLS_E_MEMORY_ERROR;
495 goto cleanup;
498 tmp.data = (void*)ptr;
499 tmp.size = size;
501 if (count == 0)
503 ret = get_x509_name_raw(&tmp, GNUTLS_X509_FMT_PEM, &names);
504 if (ret < 0)
506 gnutls_assert();
507 goto cleanup;
511 ret = gnutls_pcert_import_x509_raw (&certs[count], &tmp, GNUTLS_X509_FMT_PEM, 0);
512 if (ret < 0)
514 gnutls_assert ();
515 goto cleanup;
518 /* now we move ptr after the pem header
520 ptr++;
521 /* find the next certificate (if any)
523 size = input_cert_size - (ptr - input_cert);
525 if (size > 0)
527 char *ptr3;
529 ptr3 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
530 if (ptr3 == NULL)
531 ptr3 = memmem (ptr, size, PEM_CERT_SEP2,
532 sizeof (PEM_CERT_SEP2) - 1);
534 ptr = ptr3;
536 else
537 ptr = NULL;
539 count++;
542 while (ptr != NULL);
544 ret = certificate_credential_append_crt_list (res, names, certs, count);
545 if (ret < 0)
547 gnutls_assert ();
548 goto cleanup;
551 return count;
553 cleanup:
554 _gnutls_str_array_clear(&names);
555 for (i=0;i<count;i++)
556 gnutls_pcert_deinit(&certs[i]);
557 gnutls_free(certs);
558 return ret;
563 /* Reads a DER or PEM certificate from memory
565 static int
566 read_cert_mem (gnutls_certificate_credentials_t res, const void *cert,
567 int cert_size, gnutls_x509_crt_fmt_t type)
569 int ret;
571 if (type == GNUTLS_X509_FMT_DER)
572 ret = parse_der_cert_mem (res, cert, cert_size);
573 else
574 ret = parse_pem_cert_mem (res, cert, cert_size);
576 if (ret < 0)
578 gnutls_assert ();
579 return ret;
582 return ret;
585 /* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory. Type
586 * indicates the certificate format. KEY can be NULL, to indicate
587 * that GnuTLS doesn't know the private key.
589 static int
590 read_key_mem (gnutls_certificate_credentials_t res,
591 const void *key, int key_size, gnutls_x509_crt_fmt_t type)
593 int ret;
594 gnutls_datum_t tmp;
595 gnutls_privkey_t privkey;
597 if (key)
599 tmp.data = (uint8_t *) key;
600 tmp.size = key_size;
602 ret = gnutls_privkey_init(&privkey);
603 if (ret < 0)
605 gnutls_assert ();
606 return ret;
609 if (res->pin.cb)
610 gnutls_privkey_set_pin_function(privkey, res->pin.cb, res->pin.data);
612 ret = gnutls_privkey_import_x509_raw (privkey, &tmp, type, NULL, 0);
613 if (ret < 0)
615 gnutls_assert ();
616 return ret;
619 ret = certificate_credentials_append_pkey (res, privkey);
620 if (ret < 0)
622 gnutls_assert ();
623 gnutls_privkey_deinit (privkey);
624 return ret;
628 else
630 gnutls_assert ();
631 return GNUTLS_E_INVALID_REQUEST;
635 return 0;
639 /* Reads a private key from a token.
641 static int
642 read_key_url (gnutls_certificate_credentials_t res, const char *url)
644 int ret;
645 gnutls_privkey_t pkey = NULL;
647 /* allocate space for the pkey list
649 ret = gnutls_privkey_init (&pkey);
650 if (ret < 0)
652 gnutls_assert ();
653 return ret;
656 if (res->pin.cb)
657 gnutls_privkey_set_pin_function(pkey, res->pin.cb, res->pin.data);
659 ret = gnutls_privkey_import_url (pkey, url, 0);
660 if (ret < 0)
662 gnutls_assert ();
663 goto cleanup;
666 ret = certificate_credentials_append_pkey (res, pkey);
667 if (ret < 0)
669 gnutls_assert ();
670 goto cleanup;
673 return 0;
675 cleanup:
676 if (pkey)
677 gnutls_privkey_deinit (pkey);
679 return ret;
682 #ifdef ENABLE_PKCS11
683 /* Reads a private key from a token.
685 static int
686 read_cas_url (gnutls_certificate_credentials_t res, const char *url)
688 int ret;
689 gnutls_x509_crt_t *xcrt_list = NULL;
690 gnutls_pkcs11_obj_t *pcrt_list = NULL;
691 unsigned int pcrt_list_size = 0;
693 /* FIXME: should we use login? */
694 ret =
695 gnutls_pkcs11_obj_list_import_url (NULL, &pcrt_list_size, url,
696 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
697 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
699 gnutls_assert ();
700 return ret;
703 if (pcrt_list_size == 0)
705 gnutls_assert ();
706 return 0;
709 pcrt_list = gnutls_malloc (sizeof (*pcrt_list) * pcrt_list_size);
710 if (pcrt_list == NULL)
712 gnutls_assert ();
713 return GNUTLS_E_MEMORY_ERROR;
716 ret =
717 gnutls_pkcs11_obj_list_import_url (pcrt_list, &pcrt_list_size, url,
718 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
719 if (ret < 0)
721 gnutls_assert ();
722 goto cleanup;
725 xcrt_list = gnutls_malloc (sizeof (*xcrt_list) * pcrt_list_size);
726 if (xcrt_list == NULL)
728 gnutls_assert ();
729 ret = GNUTLS_E_MEMORY_ERROR;
730 goto cleanup;
733 ret =
734 gnutls_x509_crt_list_import_pkcs11 (xcrt_list, pcrt_list_size, pcrt_list,
736 if (ret < 0)
738 gnutls_assert ();
739 goto cleanup;
742 ret = gnutls_x509_trust_list_add_cas(res->tlist, xcrt_list, pcrt_list_size, 0);
743 if (ret < 0)
745 gnutls_assert();
746 goto cleanup;
749 cleanup:
750 gnutls_free (xcrt_list);
751 gnutls_free (pcrt_list);
753 return ret;
758 /* Reads a certificate key from a token.
760 static int
761 read_cert_url (gnutls_certificate_credentials_t res, const char *url)
763 int ret;
764 gnutls_x509_crt_t crt;
765 gnutls_pcert_st *ccert;
766 gnutls_str_array_t names;
768 _gnutls_str_array_init(&names);
770 ccert = gnutls_malloc (sizeof (*ccert));
771 if (ccert == NULL)
773 gnutls_assert ();
774 return GNUTLS_E_MEMORY_ERROR;
777 ret = gnutls_x509_crt_init (&crt);
778 if (ret < 0)
780 gnutls_assert ();
781 goto cleanup;
784 if (res->pin.cb)
785 gnutls_x509_crt_set_pin_function(crt, res->pin.cb, res->pin.data);
787 ret = gnutls_x509_crt_import_pkcs11_url (crt, url, 0);
788 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
789 ret =
790 gnutls_x509_crt_import_pkcs11_url (crt, url,
791 GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
793 if (ret < 0)
795 gnutls_assert ();
796 gnutls_x509_crt_deinit (crt);
797 goto cleanup;
800 ret = get_x509_name(crt, &names);
801 if (ret < 0)
803 gnutls_assert ();
804 gnutls_x509_crt_deinit (crt);
805 goto cleanup;
808 ret = gnutls_pcert_import_x509 (ccert, crt, 0);
809 gnutls_x509_crt_deinit (crt);
811 if (ret < 0)
813 gnutls_assert ();
814 goto cleanup;
817 ret = certificate_credential_append_crt_list (res, names, ccert, 1);
818 if (ret < 0)
820 gnutls_assert ();
821 goto cleanup;
824 return 0;
826 cleanup:
827 _gnutls_str_array_clear(&names);
828 gnutls_free (ccert);
829 return ret;
831 #endif
833 /* Reads a certificate file
835 static int
836 read_cert_file (gnutls_certificate_credentials_t res,
837 const char *certfile, gnutls_x509_crt_fmt_t type)
839 int ret;
840 size_t size;
841 char *data;
843 #ifdef ENABLE_PKCS11
844 if (strncmp (certfile, "pkcs11:", 7) == 0)
846 return read_cert_url (res, certfile);
848 #endif /* ENABLE_PKCS11 */
850 data = read_binary_file (certfile, &size);
852 if (data == NULL)
854 gnutls_assert ();
855 return GNUTLS_E_FILE_ERROR;
858 ret = read_cert_mem (res, data, size, type);
859 free (data);
861 return ret;
867 /* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
868 * stores it).
870 static int
871 read_key_file (gnutls_certificate_credentials_t res,
872 const char *keyfile, gnutls_x509_crt_fmt_t type)
874 int ret;
875 size_t size;
876 char *data;
878 if (gnutls_url_is_supported(keyfile))
880 return read_key_url (res, keyfile);
883 data = read_binary_file (keyfile, &size);
885 if (data == NULL)
887 gnutls_assert ();
888 return GNUTLS_E_FILE_ERROR;
891 ret = read_key_mem (res, data, size, type);
892 free (data);
894 return ret;
898 * gnutls_certificate_set_x509_key_mem:
899 * @res: is a #gnutls_certificate_credentials_t structure.
900 * @cert: contains a certificate list (path) for the specified private key
901 * @key: is the private key, or %NULL
902 * @type: is PEM or DER
904 * This function sets a certificate/private key pair in the
905 * gnutls_certificate_credentials_t structure. This function may be called
906 * more than once, in case multiple keys/certificates exist for the
907 * server.
909 * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
910 * is supported. This means that certificates intended for signing cannot
911 * be used for ciphersuites that require encryption.
913 * If the certificate and the private key are given in PEM encoding
914 * then the strings that hold their values must be null terminated.
916 * The @key may be %NULL if you are using a sign callback, see
917 * gnutls_sign_callback_set().
919 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
922 gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t res,
923 const gnutls_datum_t * cert,
924 const gnutls_datum_t * key,
925 gnutls_x509_crt_fmt_t type)
927 int ret;
929 /* this should be first
931 if ((ret = read_key_mem (res, key ? key->data : NULL,
932 key ? key->size : 0, type)) < 0)
933 return ret;
935 if ((ret = read_cert_mem (res, cert->data, cert->size, type)) < 0)
936 return ret;
938 res->ncerts++;
940 if (key && (ret = _gnutls_check_key_cert_match (res)) < 0)
942 gnutls_assert ();
943 return ret;
946 return 0;
949 static int check_if_sorted(gnutls_pcert_st * crt, int nr)
951 gnutls_x509_crt_t x509;
952 char prev_dn[MAX_DN];
953 char dn[MAX_DN];
954 size_t prev_dn_size, dn_size;
955 int i, ret;
957 /* check if the X.509 list is ordered */
958 if (nr > 1 && crt[0].type == GNUTLS_CRT_X509)
961 for (i=0;i<nr;i++)
963 ret = gnutls_x509_crt_init(&x509);
964 if (ret < 0)
965 return gnutls_assert_val(ret);
967 ret = gnutls_x509_crt_import(x509, &crt[i].cert, GNUTLS_X509_FMT_DER);
968 if (ret < 0)
970 ret = gnutls_assert_val(ret);
971 goto cleanup;
974 if (i>0)
976 dn_size = sizeof(dn);
977 ret = gnutls_x509_crt_get_dn(x509, dn, &dn_size);
978 if (ret < 0)
980 ret = gnutls_assert_val(ret);
981 goto cleanup;
984 if (dn_size != prev_dn_size || memcmp(dn, prev_dn, dn_size) != 0)
986 ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
987 goto cleanup;
991 prev_dn_size = sizeof(prev_dn);
992 ret = gnutls_x509_crt_get_issuer_dn(x509, prev_dn, &prev_dn_size);
993 if (ret < 0)
995 ret = gnutls_assert_val(ret);
996 goto cleanup;
999 gnutls_x509_crt_deinit(x509);
1003 return 0;
1005 cleanup:
1006 gnutls_x509_crt_deinit(x509);
1007 return ret;
1011 certificate_credential_append_crt_list (gnutls_certificate_credentials_t res,
1012 gnutls_str_array_t names, gnutls_pcert_st * crt, int nr)
1014 int ret;
1016 ret = check_if_sorted(crt, nr);
1017 if (ret < 0)
1018 return gnutls_assert_val(ret);
1020 res->certs = gnutls_realloc_fast (res->certs,
1021 (1 + res->ncerts) *
1022 sizeof (certs_st));
1023 if (res->certs == NULL)
1025 gnutls_assert ();
1026 return GNUTLS_E_MEMORY_ERROR;
1029 res->certs[res->ncerts].cert_list = crt;
1030 res->certs[res->ncerts].cert_list_length = nr;
1031 res->certs[res->ncerts].names = names;
1033 return 0;
1038 certificate_credentials_append_pkey (gnutls_certificate_credentials_t res,
1039 gnutls_privkey_t pkey)
1041 res->pkey = gnutls_realloc_fast (res->pkey,
1042 (1 + res->ncerts) *
1043 sizeof (gnutls_privkey_t));
1044 if (res->pkey == NULL)
1046 gnutls_assert ();
1047 return GNUTLS_E_MEMORY_ERROR;
1049 res->pkey[res->ncerts] = pkey;
1050 return 0;
1055 * gnutls_certificate_set_x509_key:
1056 * @res: is a #gnutls_certificate_credentials_t structure.
1057 * @cert_list: contains a certificate list (path) for the specified private key
1058 * @cert_list_size: holds the size of the certificate list
1059 * @key: is a #gnutls_x509_privkey_t key
1061 * This function sets a certificate/private key pair in the
1062 * gnutls_certificate_credentials_t structure. This function may be
1063 * called more than once, in case multiple keys/certificates exist for
1064 * the server. For clients that wants to send more than their own end
1065 * entity certificate (e.g., also an intermediate CA cert) then put
1066 * the certificate chain in @cert_list.
1068 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1070 * Since: 2.4.0
1073 gnutls_certificate_set_x509_key (gnutls_certificate_credentials_t res,
1074 gnutls_x509_crt_t * cert_list,
1075 int cert_list_size,
1076 gnutls_x509_privkey_t key)
1078 int ret, i;
1079 gnutls_privkey_t pkey;
1080 gnutls_pcert_st *pcerts = NULL;
1081 gnutls_str_array_t names;
1083 _gnutls_str_array_init(&names);
1085 /* this should be first
1087 ret = gnutls_privkey_init (&pkey);
1088 if (ret < 0)
1090 gnutls_assert ();
1091 return ret;
1094 if (res->pin.cb)
1095 gnutls_privkey_set_pin_function(pkey, res->pin.cb, res->pin.data);
1097 ret = gnutls_privkey_import_x509 (pkey, key, GNUTLS_PRIVKEY_IMPORT_COPY);
1098 if (ret < 0)
1100 gnutls_assert ();
1101 return ret;
1104 ret = certificate_credentials_append_pkey (res, pkey);
1105 if (ret < 0)
1107 gnutls_assert ();
1108 return ret;
1111 /* load certificates */
1112 pcerts = gnutls_malloc (sizeof (gnutls_pcert_st) * cert_list_size);
1113 if (pcerts == NULL)
1115 gnutls_assert ();
1116 return GNUTLS_E_MEMORY_ERROR;
1119 ret = get_x509_name(cert_list[0], &names);
1120 if (ret < 0)
1121 return gnutls_assert_val(ret);
1123 for (i = 0; i < cert_list_size; i++)
1125 ret = gnutls_pcert_import_x509 (&pcerts[i], cert_list[i], 0);
1126 if (ret < 0)
1128 gnutls_assert ();
1129 goto cleanup;
1133 ret = certificate_credential_append_crt_list (res, names, pcerts, cert_list_size);
1134 if (ret < 0)
1136 gnutls_assert ();
1137 goto cleanup;
1140 res->ncerts++;
1142 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1144 gnutls_assert ();
1145 return ret;
1148 return 0;
1150 cleanup:
1151 _gnutls_str_array_clear(&names);
1152 return ret;
1156 * gnutls_certificate_set_key:
1157 * @res: is a #gnutls_certificate_credentials_t structure.
1158 * @names: is an array of DNS name of the certificate (NULL if none)
1159 * @names_size: holds the size of the names list
1160 * @pcert_list: contains a certificate list (path) for the specified private key
1161 * @pcert_list_size: holds the size of the certificate list
1162 * @key: is a #gnutls_privkey_t key
1164 * This function sets a certificate/private key pair in the
1165 * gnutls_certificate_credentials_t structure. This function may be
1166 * called more than once, in case multiple keys/certificates exist for
1167 * the server. For clients that wants to send more than its own end
1168 * entity certificate (e.g., also an intermediate CA cert) then put
1169 * the certificate chain in @pcert_list. The @pcert_list and @key will
1170 * become part of the credentials structure and must not
1171 * be deallocated. They will be automatically deallocated when @res
1172 * is deinitialized.
1174 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1176 * Since: 3.0
1179 gnutls_certificate_set_key (gnutls_certificate_credentials_t res,
1180 const char** names,
1181 int names_size,
1182 gnutls_pcert_st * pcert_list,
1183 int pcert_list_size,
1184 gnutls_privkey_t key)
1186 int ret, i;
1187 gnutls_str_array_t str_names;
1189 _gnutls_str_array_init(&str_names);
1191 if (names != NULL && names_size > 0)
1193 for (i=0;i<names_size;i++)
1195 ret = _gnutls_str_array_append(&str_names, names[i], strlen(names[i]));
1196 if (ret < 0)
1198 ret = gnutls_assert_val(ret);
1199 goto cleanup;
1204 if (res->pin.cb)
1205 gnutls_privkey_set_pin_function(key, res->pin.cb, res->pin.data);
1207 ret = certificate_credentials_append_pkey (res, key);
1208 if (ret < 0)
1210 gnutls_assert ();
1211 goto cleanup;
1214 ret = certificate_credential_append_crt_list (res, str_names, pcert_list, pcert_list_size);
1215 if (ret < 0)
1217 gnutls_assert ();
1218 goto cleanup;
1221 res->ncerts++;
1223 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1225 gnutls_assert ();
1226 return ret;
1229 return 0;
1231 cleanup:
1232 _gnutls_str_array_clear(&str_names);
1233 return ret;
1237 * gnutls_certificate_set_x509_key_file:
1238 * @res: is a #gnutls_certificate_credentials_t structure.
1239 * @certfile: is a file that containing the certificate list (path) for
1240 * the specified private key, in PKCS7 format, or a list of certificates
1241 * @keyfile: is a file that contains the private key
1242 * @type: is PEM or DER
1244 * This function sets a certificate/private key pair in the
1245 * gnutls_certificate_credentials_t structure. This function may be
1246 * called more than once, in case multiple keys/certificates exist for
1247 * the server. For clients that need to send more than its own end
1248 * entity certificate, e.g., also an intermediate CA cert, then the
1249 * @certfile must contain the ordered certificate chain.
1251 * This function can also accept URLs at @keyfile and @certfile. In that case it
1252 * will import the private key and certificate indicated by the URLs. Note
1253 * that the supported URLs are the ones indicated by gnutls_url_is_supported().
1255 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1258 gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t res,
1259 const char *certfile,
1260 const char *keyfile,
1261 gnutls_x509_crt_fmt_t type)
1263 int ret;
1265 /* this should be first
1267 if ((ret = read_key_file (res, keyfile, type)) < 0)
1268 return ret;
1270 if ((ret = read_cert_file (res, certfile, type)) < 0)
1271 return ret;
1273 res->ncerts++;
1275 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1277 gnutls_assert ();
1278 return ret;
1281 return 0;
1284 static int
1285 add_new_crt_to_rdn_seq (gnutls_certificate_credentials_t res, gnutls_x509_crt_t* crts,
1286 unsigned int crt_size)
1288 gnutls_datum_t tmp;
1289 int ret;
1290 size_t newsize;
1291 unsigned char *newdata, *p;
1292 unsigned i;
1294 /* Add DN of the last added CAs to the RDN sequence
1295 * This will be sent to clients when a certificate
1296 * request message is sent.
1299 /* FIXME: in case of a client it is not needed
1300 * to do that. This would save time and memory.
1301 * However we don't have that information available
1302 * here.
1303 * Further, this function is now much more efficient,
1304 * so optimizing that is less important.
1307 for (i = 0; i < crt_size; i++)
1309 if ((ret = gnutls_x509_crt_get_raw_dn (crts[i], &tmp)) < 0)
1311 gnutls_assert ();
1312 return ret;
1315 newsize = res->x509_rdn_sequence.size + 2 + tmp.size;
1316 if (newsize < res->x509_rdn_sequence.size)
1318 gnutls_assert ();
1319 _gnutls_free_datum (&tmp);
1320 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1323 newdata = gnutls_realloc (res->x509_rdn_sequence.data, newsize);
1324 if (newdata == NULL)
1326 gnutls_assert ();
1327 _gnutls_free_datum (&tmp);
1328 return GNUTLS_E_MEMORY_ERROR;
1331 p = newdata + res->x509_rdn_sequence.size;
1332 _gnutls_write_uint16 (tmp.size, p);
1333 if (tmp.data != NULL)
1334 memcpy (p+2, tmp.data, tmp.size);
1336 _gnutls_free_datum (&tmp);
1338 res->x509_rdn_sequence.size = newsize;
1339 res->x509_rdn_sequence.data = newdata;
1342 return 0;
1345 /* Returns 0 if it's ok to use the gnutls_kx_algorithm_t with this
1346 * certificate (uses the KeyUsage field).
1349 _gnutls_check_key_usage (const gnutls_pcert_st* cert, gnutls_kx_algorithm_t alg)
1351 unsigned int key_usage = 0;
1352 int encipher_type;
1354 if (cert == NULL)
1356 gnutls_assert ();
1357 return GNUTLS_E_INTERNAL_ERROR;
1360 if (_gnutls_map_kx_get_cred (alg, 1) == GNUTLS_CRD_CERTIFICATE ||
1361 _gnutls_map_kx_get_cred (alg, 0) == GNUTLS_CRD_CERTIFICATE)
1364 gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
1366 encipher_type = _gnutls_kx_encipher_type (alg);
1368 if (key_usage != 0 && encipher_type != CIPHER_IGN)
1370 /* If key_usage has been set in the certificate
1373 if (encipher_type == CIPHER_ENCRYPT)
1375 /* If the key exchange method requires an encipher
1376 * type algorithm, and key's usage does not permit
1377 * encipherment, then fail.
1379 if (!(key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT))
1381 gnutls_assert ();
1382 return GNUTLS_E_KEY_USAGE_VIOLATION;
1386 if (encipher_type == CIPHER_SIGN)
1388 /* The same as above, but for sign only keys
1390 if (!(key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE))
1392 gnutls_assert ();
1393 return GNUTLS_E_KEY_USAGE_VIOLATION;
1398 return 0;
1401 static int
1402 parse_pem_ca_mem (gnutls_certificate_credentials_t res,
1403 const uint8_t * input_cert, int input_cert_size)
1405 gnutls_x509_crt_t *x509_cert_list;
1406 unsigned int x509_ncerts;
1407 gnutls_datum_t tmp;
1408 int ret;
1410 tmp.data = (void*)input_cert;
1411 tmp.size = input_cert_size;
1413 ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp,
1414 GNUTLS_X509_FMT_PEM, 0);
1415 if (ret < 0)
1417 gnutls_assert();
1418 return ret;
1421 if ((ret = add_new_crt_to_rdn_seq (res, x509_cert_list, x509_ncerts)) < 0)
1423 gnutls_assert();
1424 goto cleanup;
1427 ret = gnutls_x509_trust_list_add_cas(res->tlist, x509_cert_list, x509_ncerts, 0);
1428 if (ret < 0)
1430 gnutls_assert();
1431 goto cleanup;
1434 cleanup:
1435 gnutls_free(x509_cert_list);
1436 return ret;
1439 /* Reads a DER encoded certificate list from memory and stores it to a
1440 * gnutls_cert structure. Returns the number of certificates parsed.
1442 static int
1443 parse_der_ca_mem (gnutls_certificate_credentials_t res,
1444 const void *input_cert, int input_cert_size)
1446 gnutls_x509_crt_t crt;
1447 gnutls_datum_t tmp;
1448 int ret;
1450 tmp.data = (void*)input_cert;
1451 tmp.size = input_cert_size;
1453 ret = gnutls_x509_crt_init( &crt);
1454 if (ret < 0)
1456 gnutls_assert();
1457 return ret;
1460 ret = gnutls_x509_crt_import( crt, &tmp, GNUTLS_X509_FMT_DER);
1461 if (ret < 0)
1463 gnutls_assert();
1464 goto cleanup;
1467 if ((ret = add_new_crt_to_rdn_seq (res, &crt, 1)) < 0)
1469 gnutls_assert();
1470 goto cleanup;
1473 ret = gnutls_x509_trust_list_add_cas(res->tlist, &crt, 1, 0);
1474 if (ret < 0)
1476 gnutls_assert();
1477 goto cleanup;
1480 return ret;
1482 cleanup:
1483 gnutls_x509_crt_deinit(crt);
1484 return ret;
1488 * gnutls_certificate_set_x509_trust_mem:
1489 * @res: is a #gnutls_certificate_credentials_t structure.
1490 * @ca: is a list of trusted CAs or a DER certificate
1491 * @type: is DER or PEM
1493 * This function adds the trusted CAs in order to verify client or
1494 * server certificates. In case of a client this is not required to be
1495 * called if the certificates are not verified using
1496 * gnutls_certificate_verify_peers2(). This function may be called
1497 * multiple times.
1499 * In case of a server the CAs set here will be sent to the client if
1500 * a certificate request is sent. This can be disabled using
1501 * gnutls_certificate_send_x509_rdn_sequence().
1503 * Returns: the number of certificates processed or a negative error code
1504 * on error.
1507 gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t res,
1508 const gnutls_datum_t * ca,
1509 gnutls_x509_crt_fmt_t type)
1511 int ret;
1513 if (type == GNUTLS_X509_FMT_DER)
1514 ret = parse_der_ca_mem (res,
1515 ca->data, ca->size);
1516 else
1517 ret = parse_pem_ca_mem (res,
1518 ca->data, ca->size);
1520 if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
1521 return 0;
1523 return ret;
1527 * gnutls_certificate_set_x509_trust:
1528 * @res: is a #gnutls_certificate_credentials_t structure.
1529 * @ca_list: is a list of trusted CAs
1530 * @ca_list_size: holds the size of the CA list
1532 * This function adds the trusted CAs in order to verify client
1533 * or server certificates. In case of a client this is not required
1534 * to be called if the certificates are not verified using
1535 * gnutls_certificate_verify_peers2().
1536 * This function may be called multiple times.
1538 * In case of a server the CAs set here will be sent to the client if
1539 * a certificate request is sent. This can be disabled using
1540 * gnutls_certificate_send_x509_rdn_sequence().
1542 * Returns: the number of certificates processed or a negative error code
1543 * on error.
1545 * Since: 2.4.0
1548 gnutls_certificate_set_x509_trust (gnutls_certificate_credentials_t res,
1549 gnutls_x509_crt_t * ca_list,
1550 int ca_list_size)
1552 int ret, i, j;
1553 gnutls_x509_crt_t new_list[ca_list_size];
1555 for (i = 0; i < ca_list_size; i++)
1557 ret = gnutls_x509_crt_init (&new_list[i]);
1558 if (ret < 0)
1560 gnutls_assert ();
1561 goto cleanup;
1564 ret = _gnutls_x509_crt_cpy (new_list[i], ca_list[i]);
1565 if (ret < 0)
1567 gnutls_assert ();
1568 goto cleanup;
1572 if ((ret = add_new_crt_to_rdn_seq (res, new_list, ca_list_size)) < 0)
1574 gnutls_assert();
1575 goto cleanup;
1578 ret = gnutls_x509_trust_list_add_cas(res->tlist, new_list, ca_list_size, 0);
1579 if (ret < 0)
1581 gnutls_assert ();
1582 goto cleanup;
1585 return ret;
1587 cleanup:
1588 for (j=0;j<i;i++)
1589 gnutls_x509_crt_deinit(new_list[j]);
1591 return ret;
1596 * gnutls_certificate_set_x509_trust_file:
1597 * @cred: is a #gnutls_certificate_credentials_t structure.
1598 * @cafile: is a file containing the list of trusted CAs (DER or PEM list)
1599 * @type: is PEM or DER
1601 * This function adds the trusted CAs in order to verify client or
1602 * server certificates. In case of a client this is not required to
1603 * be called if the certificates are not verified using
1604 * gnutls_certificate_verify_peers2(). This function may be called
1605 * multiple times.
1607 * In case of a server the names of the CAs set here will be sent to
1608 * the client if a certificate request is sent. This can be disabled
1609 * using gnutls_certificate_send_x509_rdn_sequence().
1611 * This function can also accept URLs. In that case it
1612 * will import all certificates that are marked as trusted. Note
1613 * that the supported URLs are the ones indicated by gnutls_url_is_supported().
1615 * Returns: number of certificates processed, or a negative error code on
1616 * error.
1619 gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t cred,
1620 const char *cafile,
1621 gnutls_x509_crt_fmt_t type)
1623 int ret;
1624 gnutls_datum_t cas;
1625 size_t size;
1627 #ifdef ENABLE_PKCS11
1628 if (strncmp (cafile, "pkcs11:", 7) == 0)
1630 return read_cas_url (cred, cafile);
1632 #endif
1634 cas.data = (void*)read_binary_file (cafile, &size);
1635 if (cas.data == NULL)
1637 gnutls_assert ();
1638 return GNUTLS_E_FILE_ERROR;
1641 cas.size = size;
1643 ret = gnutls_certificate_set_x509_trust_mem(cred, &cas, type);
1645 free (cas.data);
1647 if (ret < 0)
1649 gnutls_assert ();
1650 return ret;
1653 return ret;
1657 * gnutls_certificate_set_x509_system_trust:
1658 * @cred: is a #gnutls_certificate_credentials_t structure.
1660 * This function adds the system's default trusted CAs in order to
1661 * verify client or server certificates.
1663 * In the case the system is currently unsupported %GNUTLS_E_UNIMPLEMENTED_FEATURE
1664 * is returned.
1666 * Returns: the number of certificates processed or a negative error code
1667 * on error.
1669 * Since: 3.0
1672 gnutls_certificate_set_x509_system_trust (gnutls_certificate_credentials_t cred)
1674 return gnutls_x509_trust_list_add_system_trust(cred->tlist, 0, 0);
1677 static int
1678 parse_pem_crl_mem (gnutls_x509_trust_list_t tlist,
1679 const char * input_crl, unsigned int input_crl_size)
1681 gnutls_x509_crl_t *x509_crl_list;
1682 unsigned int x509_ncrls;
1683 gnutls_datum_t tmp;
1684 int ret;
1686 tmp.data = (void*)input_crl;
1687 tmp.size = input_crl_size;
1689 ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp,
1690 GNUTLS_X509_FMT_PEM, 0);
1691 if (ret < 0)
1693 gnutls_assert();
1694 return ret;
1697 ret = gnutls_x509_trust_list_add_crls(tlist, x509_crl_list, x509_ncrls, 0, 0);
1698 if (ret < 0)
1700 gnutls_assert();
1701 goto cleanup;
1704 cleanup:
1705 gnutls_free(x509_crl_list);
1706 return ret;
1709 /* Reads a DER encoded certificate list from memory and stores it to a
1710 * gnutls_cert structure. Returns the number of certificates parsed.
1712 static int
1713 parse_der_crl_mem (gnutls_x509_trust_list_t tlist,
1714 const void *input_crl, unsigned int input_crl_size)
1716 gnutls_x509_crl_t crl;
1717 gnutls_datum_t tmp;
1718 int ret;
1720 tmp.data = (void*)input_crl;
1721 tmp.size = input_crl_size;
1723 ret = gnutls_x509_crl_init( &crl);
1724 if (ret < 0)
1726 gnutls_assert();
1727 return ret;
1730 ret = gnutls_x509_crl_import( crl, &tmp, GNUTLS_X509_FMT_DER);
1731 if (ret < 0)
1733 gnutls_assert();
1734 goto cleanup;
1737 ret = gnutls_x509_trust_list_add_crls(tlist, &crl, 1, 0, 0);
1738 if (ret < 0)
1740 gnutls_assert();
1741 goto cleanup;
1744 return ret;
1746 cleanup:
1747 gnutls_x509_crl_deinit(crl);
1748 return ret;
1753 /* Reads a DER or PEM CRL from memory
1755 static int
1756 read_crl_mem (gnutls_certificate_credentials_t res, const void *crl,
1757 int crl_size, gnutls_x509_crt_fmt_t type)
1759 int ret;
1761 if (type == GNUTLS_X509_FMT_DER)
1762 ret = parse_der_crl_mem (res->tlist, crl, crl_size);
1763 else
1764 ret = parse_pem_crl_mem (res->tlist, crl, crl_size);
1766 if (ret < 0)
1768 gnutls_assert ();
1771 return ret;
1775 * gnutls_certificate_set_x509_crl_mem:
1776 * @res: is a #gnutls_certificate_credentials_t structure.
1777 * @CRL: is a list of trusted CRLs. They should have been verified before.
1778 * @type: is DER or PEM
1780 * This function adds the trusted CRLs in order to verify client or
1781 * server certificates. In case of a client this is not required to
1782 * be called if the certificates are not verified using
1783 * gnutls_certificate_verify_peers2(). This function may be called
1784 * multiple times.
1786 * Returns: number of CRLs processed, or a negative error code on error.
1789 gnutls_certificate_set_x509_crl_mem (gnutls_certificate_credentials_t res,
1790 const gnutls_datum_t * CRL,
1791 gnutls_x509_crt_fmt_t type)
1793 return read_crl_mem (res, CRL->data, CRL->size, type);
1797 * gnutls_certificate_set_x509_crl:
1798 * @res: is a #gnutls_certificate_credentials_t structure.
1799 * @crl_list: is a list of trusted CRLs. They should have been verified before.
1800 * @crl_list_size: holds the size of the crl_list
1802 * This function adds the trusted CRLs in order to verify client or
1803 * server certificates. In case of a client this is not required to
1804 * be called if the certificates are not verified using
1805 * gnutls_certificate_verify_peers2(). This function may be called
1806 * multiple times.
1808 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1810 * Since: 2.4.0
1813 gnutls_certificate_set_x509_crl (gnutls_certificate_credentials_t res,
1814 gnutls_x509_crl_t * crl_list,
1815 int crl_list_size)
1817 int ret, i, j;
1818 gnutls_x509_crl_t new_crl[crl_list_size];
1820 for (i = 0; i < crl_list_size; i++)
1822 ret = gnutls_x509_crl_init (&new_crl[i]);
1823 if (ret < 0)
1825 gnutls_assert ();
1826 goto cleanup;
1829 ret = _gnutls_x509_crl_cpy (new_crl[i], crl_list[i]);
1830 if (ret < 0)
1832 gnutls_assert ();
1833 goto cleanup;
1837 ret = gnutls_x509_trust_list_add_crls(res->tlist, new_crl, crl_list_size, 0, 0);
1838 if (ret < 0)
1840 gnutls_assert ();
1841 goto cleanup;
1844 return ret;
1846 cleanup:
1847 for (j=0;j<i;j++)
1848 gnutls_x509_crl_deinit(new_crl[j]);
1850 return ret;
1854 * gnutls_certificate_set_x509_crl_file:
1855 * @res: is a #gnutls_certificate_credentials_t structure.
1856 * @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
1857 * @type: is PEM or DER
1859 * This function adds the trusted CRLs in order to verify client or server
1860 * certificates. In case of a client this is not required
1861 * to be called if the certificates are not verified using
1862 * gnutls_certificate_verify_peers2().
1863 * This function may be called multiple times.
1865 * Returns: number of CRLs processed or a negative error code on error.
1868 gnutls_certificate_set_x509_crl_file (gnutls_certificate_credentials_t res,
1869 const char *crlfile,
1870 gnutls_x509_crt_fmt_t type)
1872 int ret;
1873 size_t size;
1874 char *data = (void*)read_binary_file (crlfile, &size);
1876 if (data == NULL)
1878 gnutls_assert ();
1879 return GNUTLS_E_FILE_ERROR;
1882 if (type == GNUTLS_X509_FMT_DER)
1883 ret = parse_der_crl_mem (res->tlist, data, size);
1884 else
1885 ret = parse_pem_crl_mem (res->tlist, data, size);
1887 free (data);
1889 if (ret < 0)
1891 gnutls_assert ();
1892 return ret;
1895 return ret;
1898 #include <gnutls/pkcs12.h>
1902 * gnutls_certificate_set_x509_simple_pkcs12_file:
1903 * @res: is a #gnutls_certificate_credentials_t structure.
1904 * @pkcs12file: filename of file containing PKCS#12 blob.
1905 * @type: is PEM or DER of the @pkcs12file.
1906 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
1908 * This function sets a certificate/private key pair and/or a CRL in
1909 * the gnutls_certificate_credentials_t structure. This function may
1910 * be called more than once (in case multiple keys/certificates exist
1911 * for the server).
1913 * PKCS#12 files with a MAC, encrypted bags and PKCS #8
1914 * private keys are supported. However,
1915 * only password based security, and the same password for all
1916 * operations, are supported.
1918 * PKCS#12 file may contain many keys and/or certificates, and there
1919 * is no way to identify which key/certificate pair you want. You
1920 * should make sure the PKCS#12 file only contain one key/certificate
1921 * pair and/or one CRL.
1923 * It is believed that the limitations of this function is acceptable
1924 * for most usage, and that any more flexibility would introduce
1925 * complexity that would make it harder to use this functionality at
1926 * all.
1928 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1931 gnutls_certificate_set_x509_simple_pkcs12_file
1932 (gnutls_certificate_credentials_t res, const char *pkcs12file,
1933 gnutls_x509_crt_fmt_t type, const char *password)
1935 gnutls_datum_t p12blob;
1936 size_t size;
1937 int ret;
1939 p12blob.data = (void*)read_binary_file (pkcs12file, &size);
1940 p12blob.size = (unsigned int) size;
1941 if (p12blob.data == NULL)
1943 gnutls_assert ();
1944 return GNUTLS_E_FILE_ERROR;
1947 ret =
1948 gnutls_certificate_set_x509_simple_pkcs12_mem (res, &p12blob, type,
1949 password);
1950 free (p12blob.data);
1952 return ret;
1956 * gnutls_certificate_set_x509_simple_pkcs12_mem:
1957 * @res: is a #gnutls_certificate_credentials_t structure.
1958 * @p12blob: the PKCS#12 blob.
1959 * @type: is PEM or DER of the @pkcs12file.
1960 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
1962 * This function sets a certificate/private key pair and/or a CRL in
1963 * the gnutls_certificate_credentials_t structure. This function may
1964 * be called more than once (in case multiple keys/certificates exist
1965 * for the server).
1967 * Encrypted PKCS#12 bags and PKCS#8 private keys are supported. However,
1968 * only password based security, and the same password for all
1969 * operations, are supported.
1971 * PKCS#12 file may contain many keys and/or certificates, and there
1972 * is no way to identify which key/certificate pair you want. You
1973 * should make sure the PKCS#12 file only contain one key/certificate
1974 * pair and/or one CRL.
1976 * It is believed that the limitations of this function is acceptable
1977 * for most usage, and that any more flexibility would introduce
1978 * complexity that would make it harder to use this functionality at
1979 * all.
1981 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1983 * Since: 2.8.0
1986 gnutls_certificate_set_x509_simple_pkcs12_mem
1987 (gnutls_certificate_credentials_t res, const gnutls_datum_t * p12blob,
1988 gnutls_x509_crt_fmt_t type, const char *password)
1990 gnutls_pkcs12_t p12;
1991 gnutls_x509_privkey_t key = NULL;
1992 gnutls_x509_crt_t *chain = NULL;
1993 gnutls_x509_crl_t crl = NULL;
1994 unsigned int chain_size = 0, i;
1995 int ret;
1997 ret = gnutls_pkcs12_init (&p12);
1998 if (ret < 0)
2000 gnutls_assert ();
2001 return ret;
2004 ret = gnutls_pkcs12_import (p12, p12blob, type, 0);
2005 if (ret < 0)
2007 gnutls_assert ();
2008 gnutls_pkcs12_deinit (p12);
2009 return ret;
2012 if (password)
2014 ret = gnutls_pkcs12_verify_mac (p12, password);
2015 if (ret < 0)
2017 gnutls_assert ();
2018 gnutls_pkcs12_deinit (p12);
2019 return ret;
2023 ret = gnutls_pkcs12_simple_parse (p12, password, &key, &chain, &chain_size,
2024 NULL, NULL, &crl, 0);
2025 gnutls_pkcs12_deinit (p12);
2026 if (ret < 0)
2028 gnutls_assert ();
2029 return ret;
2032 if (key && chain)
2034 ret = gnutls_certificate_set_x509_key (res, chain, chain_size, key);
2035 if (ret < 0)
2037 gnutls_assert ();
2038 goto done;
2041 else
2043 gnutls_assert();
2044 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2045 goto done;
2048 if (crl)
2050 ret = gnutls_certificate_set_x509_crl (res, &crl, 1);
2051 if (ret < 0)
2053 gnutls_assert ();
2054 goto done;
2058 ret = 0;
2060 done:
2061 if (chain)
2063 for (i=0;i<chain_size;i++)
2064 gnutls_x509_crt_deinit (chain[i]);
2065 gnutls_free(chain);
2067 if (key)
2068 gnutls_x509_privkey_deinit (key);
2069 if (crl)
2070 gnutls_x509_crl_deinit (crl);
2072 return ret;
2078 * gnutls_certificate_free_crls:
2079 * @sc: is a #gnutls_certificate_credentials_t structure.
2081 * This function will delete all the CRLs associated
2082 * with the given credentials.
2084 void
2085 gnutls_certificate_free_crls (gnutls_certificate_credentials_t sc)
2087 /* do nothing for now */
2088 return;
2092 * gnutls_certificate_credentials_t:
2093 * @cred: is a #gnutls_certificate_credentials_t structure.
2094 * @fn: A PIN callback
2095 * @userdata: Data to be passed in the callback
2097 * This function will set a callback function to be used when
2098 * required to access a protected object. This function overrides any other
2099 * global PIN functions.
2101 * Note that this function must be called right after initialization
2102 * to have effect.
2104 * Since: 3.1.0
2106 void gnutls_certificate_set_pin_function (gnutls_certificate_credentials_t cred,
2107 gnutls_pin_callback_t fn, void *userdata)
2109 cred->pin.cb = fn;
2110 cred->pin.data = userdata;