benchmark time was increased.
[gnutls.git] / lib / gnutls_x509.c
blob3806a76a68f592119263f3f959bf90d883db6460
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 #ifdef _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_session_t session, gnutls_x509_crt_t crt, unsigned int max_bits)
59 int ret, pk;
60 unsigned int bits;
62 ret = gnutls_x509_crt_get_pk_algorithm (crt, &bits);
63 if (ret < 0)
65 gnutls_assert ();
66 return ret;
68 pk = ret;
70 if (bits > max_bits && max_bits > 0)
72 gnutls_assert ();
73 return GNUTLS_E_CONSTRAINT_ERROR;
76 if (gnutls_pk_bits_to_sec_param(pk, bits) == GNUTLS_SEC_PARAM_INSECURE)
78 gnutls_assert();
79 _gnutls_audit_log(session, "The security level of the certificate (%s: %u) is weak\n", gnutls_pk_get_name(pk), bits);
80 if (session->internals.priorities.allow_weak_keys == 0)
81 return gnutls_assert_val(GNUTLS_E_CERTIFICATE_ERROR);
84 return 0;
88 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) { \
89 if (peer_certificate_list[x]) \
90 gnutls_x509_crt_deinit(peer_certificate_list[x]); \
91 } \
92 gnutls_free( peer_certificate_list)
94 /*-
95 * _gnutls_x509_cert_verify_peers - return the peer's certificate status
96 * @session: is a gnutls session
98 * This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.).
99 * The return value (status) should be one of the gnutls_certificate_status_t enumerated elements.
100 * However you must also check the peer's name in order to check if the verified certificate belongs to the
101 * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
104 _gnutls_x509_cert_verify_peers (gnutls_session_t session,
105 unsigned int *status)
107 cert_auth_info_t info;
108 gnutls_certificate_credentials_t cred;
109 gnutls_x509_crt_t *peer_certificate_list;
110 int peer_certificate_list_size, i, x, ret;
112 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
114 info = _gnutls_get_auth_info (session);
115 if (info == NULL)
117 gnutls_assert ();
118 return GNUTLS_E_INVALID_REQUEST;
121 cred = (gnutls_certificate_credentials_t)
122 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
123 if (cred == NULL)
125 gnutls_assert ();
126 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
129 if (info->raw_certificate_list == NULL || info->ncerts == 0)
130 return GNUTLS_E_NO_CERTIFICATE_FOUND;
132 if (info->ncerts > cred->verify_depth && cred->verify_depth > 0)
134 gnutls_assert ();
135 return GNUTLS_E_CONSTRAINT_ERROR;
138 /* generate a list of gnutls_certs based on the auth info
139 * raw certs.
141 peer_certificate_list_size = info->ncerts;
142 peer_certificate_list =
143 gnutls_calloc (peer_certificate_list_size, sizeof (gnutls_x509_crt_t));
144 if (peer_certificate_list == NULL)
146 gnutls_assert ();
147 return GNUTLS_E_MEMORY_ERROR;
150 for (i = 0; i < peer_certificate_list_size; i++)
152 ret = gnutls_x509_crt_init (&peer_certificate_list[i]);
153 if (ret < 0)
155 gnutls_assert ();
156 CLEAR_CERTS;
157 return ret;
160 ret =
161 gnutls_x509_crt_import (peer_certificate_list[i],
162 &info->raw_certificate_list[i],
163 GNUTLS_X509_FMT_DER);
164 if (ret < 0)
166 gnutls_assert ();
167 CLEAR_CERTS;
168 return ret;
171 ret = check_bits (session, peer_certificate_list[i], cred->verify_bits);
172 if (ret < 0)
174 gnutls_assert ();
175 CLEAR_CERTS;
176 return ret;
181 /* Verify certificate
184 ret = gnutls_x509_trust_list_verify_crt (cred->tlist, peer_certificate_list,
185 peer_certificate_list_size,
186 cred->verify_flags | session->internals.
187 priorities.additional_verify_flags,
188 status, NULL);
190 CLEAR_CERTS;
192 if (ret < 0)
194 gnutls_assert ();
195 return ret;
198 return 0;
202 * Read certificates and private keys, from files, memory etc.
206 /* Returns the name of the certificate of a null name
208 static int get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t *names)
210 size_t max_size;
211 int i, ret = 0, ret2;
212 char name[MAX_CN];
214 for (i = 0; !(ret < 0); i++)
216 max_size = sizeof(name);
218 ret = gnutls_x509_crt_get_subject_alt_name(crt, i, name, &max_size, NULL);
219 if (ret == GNUTLS_SAN_DNSNAME)
221 ret2 = _gnutls_str_array_append(names, name, max_size);
222 if (ret2 < 0)
224 _gnutls_str_array_clear(names);
225 return gnutls_assert_val(ret2);
230 max_size = sizeof(name);
231 ret = gnutls_x509_crt_get_dn_by_oid (crt, OID_X520_COMMON_NAME, 0, 0, name, &max_size);
232 if (ret >= 0)
234 ret = _gnutls_str_array_append(names, name, max_size);
235 if (ret < 0)
237 _gnutls_str_array_clear(names);
238 return gnutls_assert_val(ret);
242 return 0;
245 static int get_x509_name_raw(gnutls_datum_t *raw, gnutls_x509_crt_fmt_t type, gnutls_str_array_t *names)
247 int ret;
248 gnutls_x509_crt_t crt;
250 ret = gnutls_x509_crt_init (&crt);
251 if (ret < 0)
253 gnutls_assert ();
254 return ret;
257 ret = gnutls_x509_crt_import (crt, raw, type);
258 if (ret < 0)
260 gnutls_assert ();
261 gnutls_x509_crt_deinit (crt);
262 return ret;
265 ret = get_x509_name(crt, names);
266 gnutls_x509_crt_deinit (crt);
267 return ret;
270 /* Reads a DER encoded certificate list from memory and stores it to a
271 * gnutls_cert structure. Returns the number of certificates parsed.
273 static int
274 parse_der_cert_mem (gnutls_certificate_credentials_t res,
275 const void *input_cert, int input_cert_size)
277 gnutls_datum_t tmp;
278 gnutls_x509_crt_t crt;
279 gnutls_pcert_st *ccert;
280 int ret;
281 gnutls_str_array_t names;
283 _gnutls_str_array_init(&names);
285 ccert = gnutls_malloc (sizeof (*ccert));
286 if (ccert == NULL)
288 gnutls_assert ();
289 return GNUTLS_E_MEMORY_ERROR;
292 ret = gnutls_x509_crt_init (&crt);
293 if (ret < 0)
295 gnutls_assert ();
296 goto cleanup;
299 tmp.data = (uint8_t *) input_cert;
300 tmp.size = input_cert_size;
302 ret = gnutls_x509_crt_import (crt, &tmp, GNUTLS_X509_FMT_DER);
303 if (ret < 0)
305 gnutls_assert ();
306 gnutls_x509_crt_deinit (crt);
307 goto cleanup;
310 ret = get_x509_name(crt, &names);
311 if (ret < 0)
313 gnutls_assert();
314 gnutls_x509_crt_deinit (crt);
315 goto cleanup;
318 ret = gnutls_pcert_import_x509 (ccert, crt, 0);
319 gnutls_x509_crt_deinit (crt);
321 if (ret < 0)
323 gnutls_assert ();
324 goto cleanup;
327 ret = certificate_credential_append_crt_list (res, names, ccert, 1);
328 if (ret < 0)
330 gnutls_assert ();
331 goto cleanup;
334 return ret;
336 cleanup:
337 _gnutls_str_array_clear(&names);
338 gnutls_free (ccert);
339 return ret;
342 /* Reads a base64 encoded certificate list from memory and stores it to
343 * a gnutls_cert structure. Returns the number of certificate parsed.
345 static int
346 parse_pem_cert_mem (gnutls_certificate_credentials_t res,
347 const char *input_cert, int input_cert_size)
349 int size;
350 const char *ptr;
351 gnutls_datum_t tmp;
352 int ret, count, i;
353 gnutls_pcert_st *certs = NULL;
354 gnutls_str_array_t names;
356 _gnutls_str_array_init(&names);
358 /* move to the certificate
360 ptr = memmem (input_cert, input_cert_size,
361 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
362 if (ptr == NULL)
363 ptr = memmem (input_cert, input_cert_size,
364 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
366 if (ptr == NULL)
368 gnutls_assert ();
369 return GNUTLS_E_BASE64_DECODING_ERROR;
371 size = input_cert_size - (ptr - input_cert);
373 count = 0;
377 certs = gnutls_realloc_fast (certs, (count + 1) * sizeof (gnutls_pcert_st));
379 if (certs == NULL)
381 gnutls_assert ();
382 ret = GNUTLS_E_MEMORY_ERROR;
383 goto cleanup;
386 tmp.data = (void*)ptr;
387 tmp.size = size;
389 if (count == 0)
391 ret = get_x509_name_raw(&tmp, GNUTLS_X509_FMT_PEM, &names);
392 if (ret < 0)
394 gnutls_assert();
395 goto cleanup;
399 ret = gnutls_pcert_import_x509_raw (&certs[count], &tmp, GNUTLS_X509_FMT_PEM, 0);
400 if (ret < 0)
402 gnutls_assert ();
403 goto cleanup;
406 /* now we move ptr after the pem header
408 ptr++;
409 /* find the next certificate (if any)
411 size = input_cert_size - (ptr - input_cert);
413 if (size > 0)
415 char *ptr3;
417 ptr3 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
418 if (ptr3 == NULL)
419 ptr3 = memmem (ptr, size, PEM_CERT_SEP2,
420 sizeof (PEM_CERT_SEP2) - 1);
422 ptr = ptr3;
424 else
425 ptr = NULL;
427 count++;
430 while (ptr != NULL);
432 ret = certificate_credential_append_crt_list (res, names, certs, count);
433 if (ret < 0)
435 gnutls_assert ();
436 goto cleanup;
439 return count;
441 cleanup:
442 _gnutls_str_array_clear(&names);
443 for (i=0;i<count;i++)
444 gnutls_pcert_deinit(&certs[i]);
445 gnutls_free(certs);
446 return ret;
451 /* Reads a DER or PEM certificate from memory
453 static int
454 read_cert_mem (gnutls_certificate_credentials_t res, const void *cert,
455 int cert_size, gnutls_x509_crt_fmt_t type)
457 int ret;
459 if (type == GNUTLS_X509_FMT_DER)
460 ret = parse_der_cert_mem (res, cert, cert_size);
461 else
462 ret = parse_pem_cert_mem (res, cert, cert_size);
464 if (ret < 0)
466 gnutls_assert ();
467 return ret;
470 return ret;
473 /* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory. Type
474 * indicates the certificate format. KEY can be NULL, to indicate
475 * that GnuTLS doesn't know the private key.
477 static int
478 read_key_mem (gnutls_certificate_credentials_t res,
479 const void *key, int key_size, gnutls_x509_crt_fmt_t type)
481 int ret;
482 gnutls_datum_t tmp;
483 gnutls_privkey_t privkey;
485 if (key)
487 tmp.data = (uint8_t *) key;
488 tmp.size = key_size;
490 ret = gnutls_privkey_init(&privkey);
491 if (ret < 0)
493 gnutls_assert ();
494 return ret;
497 if (res->pin.cb)
498 gnutls_privkey_set_pin_function(privkey, res->pin.cb, res->pin.data);
500 ret = gnutls_privkey_import_x509_raw (privkey, &tmp, type, NULL, 0);
501 if (ret < 0)
503 gnutls_assert ();
504 return ret;
507 ret = certificate_credentials_append_pkey (res, privkey);
508 if (ret < 0)
510 gnutls_assert ();
511 gnutls_privkey_deinit (privkey);
512 return ret;
516 else
518 gnutls_assert ();
519 return GNUTLS_E_INVALID_REQUEST;
523 return 0;
527 /* Reads a private key from a token.
529 static int
530 read_key_url (gnutls_certificate_credentials_t res, const char *url)
532 int ret;
533 gnutls_privkey_t pkey = NULL;
535 /* allocate space for the pkey list
537 ret = gnutls_privkey_init (&pkey);
538 if (ret < 0)
540 gnutls_assert ();
541 return ret;
544 if (res->pin.cb)
545 gnutls_privkey_set_pin_function(pkey, res->pin.cb, res->pin.data);
547 ret = gnutls_privkey_import_url (pkey, url, 0);
548 if (ret < 0)
550 gnutls_assert ();
551 goto cleanup;
554 ret = certificate_credentials_append_pkey (res, pkey);
555 if (ret < 0)
557 gnutls_assert ();
558 goto cleanup;
561 return 0;
563 cleanup:
564 if (pkey)
565 gnutls_privkey_deinit (pkey);
567 return ret;
570 #ifdef ENABLE_PKCS11
571 /* Reads a private key from a token.
573 static int
574 read_cas_url (gnutls_certificate_credentials_t res, const char *url)
576 int ret;
577 gnutls_x509_crt_t *xcrt_list = NULL;
578 gnutls_pkcs11_obj_t *pcrt_list = NULL;
579 unsigned int pcrt_list_size = 0;
581 /* FIXME: should we use login? */
582 ret =
583 gnutls_pkcs11_obj_list_import_url (NULL, &pcrt_list_size, url,
584 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
585 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
587 gnutls_assert ();
588 return ret;
591 if (pcrt_list_size == 0)
593 gnutls_assert ();
594 return 0;
597 pcrt_list = gnutls_malloc (sizeof (*pcrt_list) * pcrt_list_size);
598 if (pcrt_list == NULL)
600 gnutls_assert ();
601 return GNUTLS_E_MEMORY_ERROR;
604 ret =
605 gnutls_pkcs11_obj_list_import_url (pcrt_list, &pcrt_list_size, url,
606 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
607 if (ret < 0)
609 gnutls_assert ();
610 goto cleanup;
613 xcrt_list = gnutls_malloc (sizeof (*xcrt_list) * pcrt_list_size);
614 if (xcrt_list == NULL)
616 gnutls_assert ();
617 ret = GNUTLS_E_MEMORY_ERROR;
618 goto cleanup;
621 ret =
622 gnutls_x509_crt_list_import_pkcs11 (xcrt_list, pcrt_list_size, pcrt_list,
624 if (ret < 0)
626 gnutls_assert ();
627 goto cleanup;
630 ret = gnutls_x509_trust_list_add_cas(res->tlist, xcrt_list, pcrt_list_size, 0);
631 if (ret < 0)
633 gnutls_assert();
634 goto cleanup;
637 cleanup:
638 gnutls_free (xcrt_list);
639 gnutls_free (pcrt_list);
641 return ret;
646 /* Reads a certificate key from a token.
648 static int
649 read_cert_url (gnutls_certificate_credentials_t res, const char *url)
651 int ret;
652 gnutls_x509_crt_t crt;
653 gnutls_pcert_st *ccert;
654 gnutls_str_array_t names;
656 _gnutls_str_array_init(&names);
658 ccert = gnutls_malloc (sizeof (*ccert));
659 if (ccert == NULL)
661 gnutls_assert ();
662 return GNUTLS_E_MEMORY_ERROR;
665 ret = gnutls_x509_crt_init (&crt);
666 if (ret < 0)
668 gnutls_assert ();
669 goto cleanup;
672 if (res->pin.cb)
673 gnutls_x509_crt_set_pin_function(crt, res->pin.cb, res->pin.data);
675 ret = gnutls_x509_crt_import_pkcs11_url (crt, url, 0);
676 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
677 ret =
678 gnutls_x509_crt_import_pkcs11_url (crt, url,
679 GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
681 if (ret < 0)
683 gnutls_assert ();
684 gnutls_x509_crt_deinit (crt);
685 goto cleanup;
688 ret = get_x509_name(crt, &names);
689 if (ret < 0)
691 gnutls_assert ();
692 gnutls_x509_crt_deinit (crt);
693 goto cleanup;
696 ret = gnutls_pcert_import_x509 (ccert, crt, 0);
697 gnutls_x509_crt_deinit (crt);
699 if (ret < 0)
701 gnutls_assert ();
702 goto cleanup;
705 ret = certificate_credential_append_crt_list (res, names, ccert, 1);
706 if (ret < 0)
708 gnutls_assert ();
709 goto cleanup;
712 return 0;
714 cleanup:
715 _gnutls_str_array_clear(&names);
716 gnutls_free (ccert);
717 return ret;
719 #endif
721 /* Reads a certificate file
723 static int
724 read_cert_file (gnutls_certificate_credentials_t res,
725 const char *certfile, gnutls_x509_crt_fmt_t type)
727 int ret;
728 size_t size;
729 char *data;
731 #ifdef ENABLE_PKCS11
732 if (strncmp (certfile, "pkcs11:", 7) == 0)
734 return read_cert_url (res, certfile);
736 #endif /* ENABLE_PKCS11 */
738 data = read_binary_file (certfile, &size);
740 if (data == NULL)
742 gnutls_assert ();
743 return GNUTLS_E_FILE_ERROR;
746 ret = read_cert_mem (res, data, size, type);
747 free (data);
749 return ret;
755 /* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
756 * stores it).
758 static int
759 read_key_file (gnutls_certificate_credentials_t res,
760 const char *keyfile, gnutls_x509_crt_fmt_t type)
762 int ret;
763 size_t size;
764 char *data;
766 if (gnutls_url_is_supported(keyfile))
768 return read_key_url (res, keyfile);
771 data = read_binary_file (keyfile, &size);
773 if (data == NULL)
775 gnutls_assert ();
776 return GNUTLS_E_FILE_ERROR;
779 ret = read_key_mem (res, data, size, type);
780 free (data);
782 return ret;
786 * gnutls_certificate_set_x509_key_mem:
787 * @res: is a #gnutls_certificate_credentials_t structure.
788 * @cert: contains a certificate list (path) for the specified private key
789 * @key: is the private key, or %NULL
790 * @type: is PEM or DER
792 * This function sets a certificate/private key pair in the
793 * gnutls_certificate_credentials_t structure. This function may be called
794 * more than once, in case multiple keys/certificates exist for the
795 * server.
797 * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
798 * is supported. This means that certificates intended for signing cannot
799 * be used for ciphersuites that require encryption.
801 * If the certificate and the private key are given in PEM encoding
802 * then the strings that hold their values must be null terminated.
804 * The @key may be %NULL if you are using a sign callback, see
805 * gnutls_sign_callback_set().
807 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
810 gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t res,
811 const gnutls_datum_t * cert,
812 const gnutls_datum_t * key,
813 gnutls_x509_crt_fmt_t type)
815 int ret;
817 /* this should be first
819 if ((ret = read_key_mem (res, key ? key->data : NULL,
820 key ? key->size : 0, type)) < 0)
821 return ret;
823 if ((ret = read_cert_mem (res, cert->data, cert->size, type)) < 0)
824 return ret;
826 res->ncerts++;
828 if (key && (ret = _gnutls_check_key_cert_match (res)) < 0)
830 gnutls_assert ();
831 return ret;
834 return 0;
837 static int check_if_sorted(gnutls_pcert_st * crt, int nr)
839 gnutls_x509_crt_t x509;
840 char prev_dn[MAX_DN];
841 char dn[MAX_DN];
842 size_t prev_dn_size, dn_size;
843 int i, ret;
845 /* check if the X.509 list is ordered */
846 if (nr > 1 && crt[0].type == GNUTLS_CRT_X509)
849 for (i=0;i<nr;i++)
851 ret = gnutls_x509_crt_init(&x509);
852 if (ret < 0)
853 return gnutls_assert_val(ret);
855 ret = gnutls_x509_crt_import(x509, &crt[i].cert, GNUTLS_X509_FMT_DER);
856 if (ret < 0)
858 ret = gnutls_assert_val(ret);
859 goto cleanup;
862 if (i>0)
864 dn_size = sizeof(dn);
865 ret = gnutls_x509_crt_get_dn(x509, dn, &dn_size);
866 if (ret < 0)
868 ret = gnutls_assert_val(ret);
869 goto cleanup;
872 if (dn_size != prev_dn_size || memcmp(dn, prev_dn, dn_size) != 0)
874 ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
875 goto cleanup;
879 prev_dn_size = sizeof(prev_dn);
880 ret = gnutls_x509_crt_get_issuer_dn(x509, prev_dn, &prev_dn_size);
881 if (ret < 0)
883 ret = gnutls_assert_val(ret);
884 goto cleanup;
887 gnutls_x509_crt_deinit(x509);
891 return 0;
893 cleanup:
894 gnutls_x509_crt_deinit(x509);
895 return ret;
899 certificate_credential_append_crt_list (gnutls_certificate_credentials_t res,
900 gnutls_str_array_t names, gnutls_pcert_st * crt, int nr)
902 int ret;
904 ret = check_if_sorted(crt, nr);
905 if (ret < 0)
906 return gnutls_assert_val(ret);
908 res->certs = gnutls_realloc_fast (res->certs,
909 (1 + res->ncerts) *
910 sizeof (certs_st));
911 if (res->certs == NULL)
913 gnutls_assert ();
914 return GNUTLS_E_MEMORY_ERROR;
917 res->certs[res->ncerts].cert_list = crt;
918 res->certs[res->ncerts].cert_list_length = nr;
919 res->certs[res->ncerts].names = names;
921 return 0;
926 certificate_credentials_append_pkey (gnutls_certificate_credentials_t res,
927 gnutls_privkey_t pkey)
929 res->pkey = gnutls_realloc_fast (res->pkey,
930 (1 + res->ncerts) *
931 sizeof (gnutls_privkey_t));
932 if (res->pkey == NULL)
934 gnutls_assert ();
935 return GNUTLS_E_MEMORY_ERROR;
937 res->pkey[res->ncerts] = pkey;
938 return 0;
943 * gnutls_certificate_set_x509_key:
944 * @res: is a #gnutls_certificate_credentials_t structure.
945 * @cert_list: contains a certificate list (path) for the specified private key
946 * @cert_list_size: holds the size of the certificate list
947 * @key: is a #gnutls_x509_privkey_t key
949 * This function sets a certificate/private key pair in the
950 * gnutls_certificate_credentials_t structure. This function may be
951 * called more than once, in case multiple keys/certificates exist for
952 * the server. For clients that wants to send more than their own end
953 * entity certificate (e.g., also an intermediate CA cert) then put
954 * the certificate chain in @cert_list.
956 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
958 * Since: 2.4.0
961 gnutls_certificate_set_x509_key (gnutls_certificate_credentials_t res,
962 gnutls_x509_crt_t * cert_list,
963 int cert_list_size,
964 gnutls_x509_privkey_t key)
966 int ret, i;
967 gnutls_privkey_t pkey;
968 gnutls_pcert_st *pcerts = NULL;
969 gnutls_str_array_t names;
971 _gnutls_str_array_init(&names);
973 /* this should be first
975 ret = gnutls_privkey_init (&pkey);
976 if (ret < 0)
978 gnutls_assert ();
979 return ret;
982 if (res->pin.cb)
983 gnutls_privkey_set_pin_function(pkey, res->pin.cb, res->pin.data);
985 ret = gnutls_privkey_import_x509 (pkey, key, GNUTLS_PRIVKEY_IMPORT_COPY);
986 if (ret < 0)
988 gnutls_assert ();
989 return ret;
992 ret = certificate_credentials_append_pkey (res, pkey);
993 if (ret < 0)
995 gnutls_assert ();
996 return ret;
999 /* load certificates */
1000 pcerts = gnutls_malloc (sizeof (gnutls_pcert_st) * cert_list_size);
1001 if (pcerts == NULL)
1003 gnutls_assert ();
1004 return GNUTLS_E_MEMORY_ERROR;
1007 ret = get_x509_name(cert_list[0], &names);
1008 if (ret < 0)
1009 return gnutls_assert_val(ret);
1011 for (i = 0; i < cert_list_size; i++)
1013 ret = gnutls_pcert_import_x509 (&pcerts[i], cert_list[i], 0);
1014 if (ret < 0)
1016 gnutls_assert ();
1017 goto cleanup;
1021 ret = certificate_credential_append_crt_list (res, names, pcerts, cert_list_size);
1022 if (ret < 0)
1024 gnutls_assert ();
1025 goto cleanup;
1028 res->ncerts++;
1030 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1032 gnutls_assert ();
1033 return ret;
1036 return 0;
1038 cleanup:
1039 _gnutls_str_array_clear(&names);
1040 return ret;
1044 * gnutls_certificate_set_key:
1045 * @res: is a #gnutls_certificate_credentials_t structure.
1046 * @names: is an array of DNS name of the certificate (NULL if none)
1047 * @names_size: holds the size of the names list
1048 * @pcert_list: contains a certificate list (path) for the specified private key
1049 * @pcert_list_size: holds the size of the certificate list
1050 * @key: is a #gnutls_privkey_t key
1052 * This function sets a certificate/private key pair in the
1053 * gnutls_certificate_credentials_t structure. This function may be
1054 * called more than once, in case multiple keys/certificates exist for
1055 * the server. For clients that wants to send more than its own end
1056 * entity certificate (e.g., also an intermediate CA cert) then put
1057 * the certificate chain in @pcert_list. The @pcert_list and @key will
1058 * become part of the credentials structure and must not
1059 * be deallocated. They will be automatically deallocated when @res
1060 * is deinitialized.
1062 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1064 * Since: 3.0
1067 gnutls_certificate_set_key (gnutls_certificate_credentials_t res,
1068 const char** names,
1069 int names_size,
1070 gnutls_pcert_st * pcert_list,
1071 int pcert_list_size,
1072 gnutls_privkey_t key)
1074 int ret, i;
1075 gnutls_str_array_t str_names;
1077 _gnutls_str_array_init(&str_names);
1079 if (names != NULL && names_size > 0)
1081 for (i=0;i<names_size;i++)
1083 ret = _gnutls_str_array_append(&str_names, names[i], strlen(names[i]));
1084 if (ret < 0)
1086 ret = gnutls_assert_val(ret);
1087 goto cleanup;
1092 if (res->pin.cb)
1093 gnutls_privkey_set_pin_function(key, res->pin.cb, res->pin.data);
1095 ret = certificate_credentials_append_pkey (res, key);
1096 if (ret < 0)
1098 gnutls_assert ();
1099 goto cleanup;
1102 ret = certificate_credential_append_crt_list (res, str_names, pcert_list, pcert_list_size);
1103 if (ret < 0)
1105 gnutls_assert ();
1106 goto cleanup;
1109 res->ncerts++;
1111 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1113 gnutls_assert ();
1114 return ret;
1117 return 0;
1119 cleanup:
1120 _gnutls_str_array_clear(&str_names);
1121 return ret;
1125 * gnutls_certificate_set_x509_key_file:
1126 * @res: is a #gnutls_certificate_credentials_t structure.
1127 * @certfile: is a file that containing the certificate list (path) for
1128 * the specified private key, in PKCS7 format, or a list of certificates
1129 * @keyfile: is a file that contains the private key
1130 * @type: is PEM or DER
1132 * This function sets a certificate/private key pair in the
1133 * gnutls_certificate_credentials_t structure. This function may be
1134 * called more than once, in case multiple keys/certificates exist for
1135 * the server. For clients that need to send more than its own end
1136 * entity certificate, e.g., also an intermediate CA cert, then the
1137 * @certfile must contain the ordered certificate chain.
1139 * This function can also accept URLs at @keyfile and @certfile. In that case it
1140 * will import the private key and certificate indicated by the URLs. Note
1141 * that the supported URLs are the ones indicated by gnutls_url_is_supported().
1143 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1146 gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t res,
1147 const char *certfile,
1148 const char *keyfile,
1149 gnutls_x509_crt_fmt_t type)
1151 int ret;
1153 /* this should be first
1155 if ((ret = read_key_file (res, keyfile, type)) < 0)
1156 return ret;
1158 if ((ret = read_cert_file (res, certfile, type)) < 0)
1159 return ret;
1161 res->ncerts++;
1163 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1165 gnutls_assert ();
1166 return ret;
1169 return 0;
1172 static int
1173 add_new_crt_to_rdn_seq (gnutls_certificate_credentials_t res, gnutls_x509_crt_t* crts,
1174 unsigned int crt_size)
1176 gnutls_datum_t tmp;
1177 int ret;
1178 size_t newsize;
1179 unsigned char *newdata;
1180 unsigned i;
1182 /* Add DN of the last added CAs to the RDN sequence
1183 * This will be sent to clients when a certificate
1184 * request message is sent.
1187 /* FIXME: in case of a client it is not needed
1188 * to do that. This would save time and memory.
1189 * However we don't have that information available
1190 * here.
1191 * Further, this function is now much more efficient,
1192 * so optimizing that is less important.
1195 for (i = 0; i < crt_size; i++)
1197 if ((ret = gnutls_x509_crt_get_raw_dn (crts[i], &tmp)) < 0)
1199 gnutls_assert ();
1200 return ret;
1203 newsize = res->x509_rdn_sequence.size + 2 + tmp.size;
1204 if (newsize < res->x509_rdn_sequence.size)
1206 gnutls_assert ();
1207 _gnutls_free_datum (&tmp);
1208 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1211 newdata = gnutls_realloc (res->x509_rdn_sequence.data, newsize);
1212 if (newdata == NULL)
1214 gnutls_assert ();
1215 _gnutls_free_datum (&tmp);
1216 return GNUTLS_E_MEMORY_ERROR;
1219 _gnutls_write_datum16 (newdata + res->x509_rdn_sequence.size, tmp);
1220 _gnutls_free_datum (&tmp);
1222 res->x509_rdn_sequence.size = newsize;
1223 res->x509_rdn_sequence.data = newdata;
1226 return 0;
1229 /* Returns 0 if it's ok to use the gnutls_kx_algorithm_t with this
1230 * certificate (uses the KeyUsage field).
1233 _gnutls_check_key_usage (const gnutls_pcert_st* cert, gnutls_kx_algorithm_t alg)
1235 unsigned int key_usage = 0;
1236 int encipher_type;
1238 if (cert == NULL)
1240 gnutls_assert ();
1241 return GNUTLS_E_INTERNAL_ERROR;
1244 if (_gnutls_map_kx_get_cred (alg, 1) == GNUTLS_CRD_CERTIFICATE ||
1245 _gnutls_map_kx_get_cred (alg, 0) == GNUTLS_CRD_CERTIFICATE)
1248 gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
1250 encipher_type = _gnutls_kx_encipher_type (alg);
1252 if (key_usage != 0 && encipher_type != CIPHER_IGN)
1254 /* If key_usage has been set in the certificate
1257 if (encipher_type == CIPHER_ENCRYPT)
1259 /* If the key exchange method requires an encipher
1260 * type algorithm, and key's usage does not permit
1261 * encipherment, then fail.
1263 if (!(key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT))
1265 gnutls_assert ();
1266 return GNUTLS_E_KEY_USAGE_VIOLATION;
1270 if (encipher_type == CIPHER_SIGN)
1272 /* The same as above, but for sign only keys
1274 if (!(key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE))
1276 gnutls_assert ();
1277 return GNUTLS_E_KEY_USAGE_VIOLATION;
1282 return 0;
1285 static int
1286 parse_pem_ca_mem (gnutls_certificate_credentials_t res,
1287 const uint8_t * input_cert, int input_cert_size)
1289 gnutls_x509_crt_t *x509_cert_list;
1290 unsigned int x509_ncerts;
1291 gnutls_datum_t tmp;
1292 int ret;
1294 tmp.data = (void*)input_cert;
1295 tmp.size = input_cert_size;
1297 ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp,
1298 GNUTLS_X509_FMT_PEM, 0);
1299 if (ret < 0)
1301 gnutls_assert();
1302 return ret;
1305 if ((ret = add_new_crt_to_rdn_seq (res, x509_cert_list, x509_ncerts)) < 0)
1307 gnutls_assert();
1308 goto cleanup;
1311 ret = gnutls_x509_trust_list_add_cas(res->tlist, x509_cert_list, x509_ncerts, 0);
1312 if (ret < 0)
1314 gnutls_assert();
1315 goto cleanup;
1318 cleanup:
1319 gnutls_free(x509_cert_list);
1320 return ret;
1323 /* Reads a DER encoded certificate list from memory and stores it to a
1324 * gnutls_cert structure. Returns the number of certificates parsed.
1326 static int
1327 parse_der_ca_mem (gnutls_certificate_credentials_t res,
1328 const void *input_cert, int input_cert_size)
1330 gnutls_x509_crt_t crt;
1331 gnutls_datum_t tmp;
1332 int ret;
1334 tmp.data = (void*)input_cert;
1335 tmp.size = input_cert_size;
1337 ret = gnutls_x509_crt_init( &crt);
1338 if (ret < 0)
1340 gnutls_assert();
1341 return ret;
1344 ret = gnutls_x509_crt_import( crt, &tmp, GNUTLS_X509_FMT_DER);
1345 if (ret < 0)
1347 gnutls_assert();
1348 goto cleanup;
1351 if ((ret = add_new_crt_to_rdn_seq (res, &crt, 1)) < 0)
1353 gnutls_assert();
1354 goto cleanup;
1357 ret = gnutls_x509_trust_list_add_cas(res->tlist, &crt, 1, 0);
1358 if (ret < 0)
1360 gnutls_assert();
1361 goto cleanup;
1364 return ret;
1366 cleanup:
1367 gnutls_x509_crt_deinit(crt);
1368 return ret;
1372 * gnutls_certificate_set_x509_trust_mem:
1373 * @res: is a #gnutls_certificate_credentials_t structure.
1374 * @ca: is a list of trusted CAs or a DER certificate
1375 * @type: is DER or PEM
1377 * This function adds the trusted CAs in order to verify client or
1378 * server certificates. In case of a client this is not required to be
1379 * called if the certificates are not verified using
1380 * gnutls_certificate_verify_peers2(). This function may be called
1381 * multiple times.
1383 * In case of a server the CAs set here will be sent to the client if
1384 * a certificate request is sent. This can be disabled using
1385 * gnutls_certificate_send_x509_rdn_sequence().
1387 * Returns: the number of certificates processed or a negative error code
1388 * on error.
1391 gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t res,
1392 const gnutls_datum_t * ca,
1393 gnutls_x509_crt_fmt_t type)
1395 int ret;
1397 if (type == GNUTLS_X509_FMT_DER)
1398 ret = parse_der_ca_mem (res,
1399 ca->data, ca->size);
1400 else
1401 ret = parse_pem_ca_mem (res,
1402 ca->data, ca->size);
1404 if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
1405 return 0;
1407 return ret;
1411 * gnutls_certificate_set_x509_trust:
1412 * @res: is a #gnutls_certificate_credentials_t structure.
1413 * @ca_list: is a list of trusted CAs
1414 * @ca_list_size: holds the size of the CA list
1416 * This function adds the trusted CAs in order to verify client
1417 * or server certificates. In case of a client this is not required
1418 * to be called if the certificates are not verified using
1419 * gnutls_certificate_verify_peers2().
1420 * This function may be called multiple times.
1422 * In case of a server the CAs set here will be sent to the client if
1423 * a certificate request is sent. This can be disabled using
1424 * gnutls_certificate_send_x509_rdn_sequence().
1426 * Returns: the number of certificates processed or a negative error code
1427 * on error.
1429 * Since: 2.4.0
1432 gnutls_certificate_set_x509_trust (gnutls_certificate_credentials_t res,
1433 gnutls_x509_crt_t * ca_list,
1434 int ca_list_size)
1436 int ret, i, j;
1437 gnutls_x509_crt_t new_list[ca_list_size];
1439 for (i = 0; i < ca_list_size; i++)
1441 ret = gnutls_x509_crt_init (&new_list[i]);
1442 if (ret < 0)
1444 gnutls_assert ();
1445 goto cleanup;
1448 ret = _gnutls_x509_crt_cpy (new_list[i], ca_list[i]);
1449 if (ret < 0)
1451 gnutls_assert ();
1452 goto cleanup;
1456 if ((ret = add_new_crt_to_rdn_seq (res, new_list, ca_list_size)) < 0)
1458 gnutls_assert();
1459 goto cleanup;
1462 ret = gnutls_x509_trust_list_add_cas(res->tlist, new_list, ca_list_size, 0);
1463 if (ret < 0)
1465 gnutls_assert ();
1466 goto cleanup;
1469 return ret;
1471 cleanup:
1472 for (j=0;j<i;i++)
1473 gnutls_x509_crt_deinit(new_list[j]);
1475 return ret;
1480 * gnutls_certificate_set_x509_trust_file:
1481 * @cred: is a #gnutls_certificate_credentials_t structure.
1482 * @cafile: is a file containing the list of trusted CAs (DER or PEM list)
1483 * @type: is PEM or DER
1485 * This function adds the trusted CAs in order to verify client or
1486 * server certificates. In case of a client this is not required to
1487 * be called if the certificates are not verified using
1488 * gnutls_certificate_verify_peers2(). This function may be called
1489 * multiple times.
1491 * In case of a server the names of the CAs set here will be sent to
1492 * the client if a certificate request is sent. This can be disabled
1493 * using gnutls_certificate_send_x509_rdn_sequence().
1495 * This function can also accept URLs. In that case it
1496 * will import all certificates that are marked as trusted. Note
1497 * that the supported URLs are the ones indicated by gnutls_url_is_supported().
1499 * Returns: number of certificates processed, or a negative error code on
1500 * error.
1503 gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t cred,
1504 const char *cafile,
1505 gnutls_x509_crt_fmt_t type)
1507 int ret;
1508 gnutls_datum_t cas;
1509 size_t size;
1511 #ifdef ENABLE_PKCS11
1512 if (strncmp (cafile, "pkcs11:", 7) == 0)
1514 return read_cas_url (cred, cafile);
1516 #endif
1518 cas.data = (void*)read_binary_file (cafile, &size);
1519 if (cas.data == NULL)
1521 gnutls_assert ();
1522 return GNUTLS_E_FILE_ERROR;
1525 cas.size = size;
1527 ret = gnutls_certificate_set_x509_trust_mem(cred, &cas, type);
1529 free (cas.data);
1531 if (ret < 0)
1533 gnutls_assert ();
1534 return ret;
1537 return ret;
1541 * gnutls_certificate_set_x509_system_trust:
1542 * @cred: is a #gnutls_certificate_credentials_t structure.
1544 * This function adds the system's default trusted CAs in order to
1545 * verify client or server certificates.
1547 * In the case the system is currently unsupported %GNUTLS_E_UNIMPLEMENTED_FEATURE
1548 * is returned.
1550 * Returns: the number of certificates processed or a negative error code
1551 * on error.
1553 * Since: 3.0
1556 gnutls_certificate_set_x509_system_trust (gnutls_certificate_credentials_t cred)
1558 return gnutls_x509_trust_list_add_system_trust(cred->tlist, 0, 0);
1561 static int
1562 parse_pem_crl_mem (gnutls_x509_trust_list_t tlist,
1563 const char * input_crl, unsigned int input_crl_size)
1565 gnutls_x509_crl_t *x509_crl_list;
1566 unsigned int x509_ncrls;
1567 gnutls_datum_t tmp;
1568 int ret;
1570 tmp.data = (void*)input_crl;
1571 tmp.size = input_crl_size;
1573 ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp,
1574 GNUTLS_X509_FMT_PEM, 0);
1575 if (ret < 0)
1577 gnutls_assert();
1578 return ret;
1581 ret = gnutls_x509_trust_list_add_crls(tlist, x509_crl_list, x509_ncrls, 0, 0);
1582 if (ret < 0)
1584 gnutls_assert();
1585 goto cleanup;
1588 cleanup:
1589 gnutls_free(x509_crl_list);
1590 return ret;
1593 /* Reads a DER encoded certificate list from memory and stores it to a
1594 * gnutls_cert structure. Returns the number of certificates parsed.
1596 static int
1597 parse_der_crl_mem (gnutls_x509_trust_list_t tlist,
1598 const void *input_crl, unsigned int input_crl_size)
1600 gnutls_x509_crl_t crl;
1601 gnutls_datum_t tmp;
1602 int ret;
1604 tmp.data = (void*)input_crl;
1605 tmp.size = input_crl_size;
1607 ret = gnutls_x509_crl_init( &crl);
1608 if (ret < 0)
1610 gnutls_assert();
1611 return ret;
1614 ret = gnutls_x509_crl_import( crl, &tmp, GNUTLS_X509_FMT_DER);
1615 if (ret < 0)
1617 gnutls_assert();
1618 goto cleanup;
1621 ret = gnutls_x509_trust_list_add_crls(tlist, &crl, 1, 0, 0);
1622 if (ret < 0)
1624 gnutls_assert();
1625 goto cleanup;
1628 return ret;
1630 cleanup:
1631 gnutls_x509_crl_deinit(crl);
1632 return ret;
1637 /* Reads a DER or PEM CRL from memory
1639 static int
1640 read_crl_mem (gnutls_certificate_credentials_t res, const void *crl,
1641 int crl_size, gnutls_x509_crt_fmt_t type)
1643 int ret;
1645 if (type == GNUTLS_X509_FMT_DER)
1646 ret = parse_der_crl_mem (res->tlist, crl, crl_size);
1647 else
1648 ret = parse_pem_crl_mem (res->tlist, crl, crl_size);
1650 if (ret < 0)
1652 gnutls_assert ();
1655 return ret;
1659 * gnutls_certificate_set_x509_crl_mem:
1660 * @res: is a #gnutls_certificate_credentials_t structure.
1661 * @CRL: is a list of trusted CRLs. They should have been verified before.
1662 * @type: is DER or PEM
1664 * This function adds the trusted CRLs in order to verify client or
1665 * server certificates. In case of a client this is not required to
1666 * be called if the certificates are not verified using
1667 * gnutls_certificate_verify_peers2(). This function may be called
1668 * multiple times.
1670 * Returns: number of CRLs processed, or a negative error code on error.
1673 gnutls_certificate_set_x509_crl_mem (gnutls_certificate_credentials_t res,
1674 const gnutls_datum_t * CRL,
1675 gnutls_x509_crt_fmt_t type)
1677 return read_crl_mem (res, CRL->data, CRL->size, type);
1681 * gnutls_certificate_set_x509_crl:
1682 * @res: is a #gnutls_certificate_credentials_t structure.
1683 * @crl_list: is a list of trusted CRLs. They should have been verified before.
1684 * @crl_list_size: holds the size of the crl_list
1686 * This function adds the trusted CRLs in order to verify client or
1687 * server certificates. In case of a client this is not required to
1688 * be called if the certificates are not verified using
1689 * gnutls_certificate_verify_peers2(). This function may be called
1690 * multiple times.
1692 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1694 * Since: 2.4.0
1697 gnutls_certificate_set_x509_crl (gnutls_certificate_credentials_t res,
1698 gnutls_x509_crl_t * crl_list,
1699 int crl_list_size)
1701 int ret, i, j;
1702 gnutls_x509_crl_t new_crl[crl_list_size];
1704 for (i = 0; i < crl_list_size; i++)
1706 ret = gnutls_x509_crl_init (&new_crl[i]);
1707 if (ret < 0)
1709 gnutls_assert ();
1710 goto cleanup;
1713 ret = _gnutls_x509_crl_cpy (new_crl[i], crl_list[i]);
1714 if (ret < 0)
1716 gnutls_assert ();
1717 goto cleanup;
1721 ret = gnutls_x509_trust_list_add_crls(res->tlist, new_crl, crl_list_size, 0, 0);
1722 if (ret < 0)
1724 gnutls_assert ();
1725 goto cleanup;
1728 return ret;
1730 cleanup:
1731 for (j=0;j<i;j++)
1732 gnutls_x509_crl_deinit(new_crl[j]);
1734 return ret;
1738 * gnutls_certificate_set_x509_crl_file:
1739 * @res: is a #gnutls_certificate_credentials_t structure.
1740 * @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
1741 * @type: is PEM or DER
1743 * This function adds the trusted CRLs in order to verify client or server
1744 * certificates. In case of a client this is not required
1745 * to be called if the certificates are not verified using
1746 * gnutls_certificate_verify_peers2().
1747 * This function may be called multiple times.
1749 * Returns: number of CRLs processed or a negative error code on error.
1752 gnutls_certificate_set_x509_crl_file (gnutls_certificate_credentials_t res,
1753 const char *crlfile,
1754 gnutls_x509_crt_fmt_t type)
1756 int ret;
1757 size_t size;
1758 char *data = (void*)read_binary_file (crlfile, &size);
1760 if (data == NULL)
1762 gnutls_assert ();
1763 return GNUTLS_E_FILE_ERROR;
1766 if (type == GNUTLS_X509_FMT_DER)
1767 ret = parse_der_crl_mem (res->tlist, data, size);
1768 else
1769 ret = parse_pem_crl_mem (res->tlist, data, size);
1771 free (data);
1773 if (ret < 0)
1775 gnutls_assert ();
1776 return ret;
1779 return ret;
1782 #include <gnutls/pkcs12.h>
1786 * gnutls_certificate_set_x509_simple_pkcs12_file:
1787 * @res: is a #gnutls_certificate_credentials_t structure.
1788 * @pkcs12file: filename of file containing PKCS#12 blob.
1789 * @type: is PEM or DER of the @pkcs12file.
1790 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
1792 * This function sets a certificate/private key pair and/or a CRL in
1793 * the gnutls_certificate_credentials_t structure. This function may
1794 * be called more than once (in case multiple keys/certificates exist
1795 * for the server).
1797 * PKCS#12 files with a MAC, encrypted bags and PKCS #8
1798 * private keys are supported. However,
1799 * only password based security, and the same password for all
1800 * operations, are supported.
1802 * PKCS#12 file may contain many keys and/or certificates, and there
1803 * is no way to identify which key/certificate pair you want. You
1804 * should make sure the PKCS#12 file only contain one key/certificate
1805 * pair and/or one CRL.
1807 * It is believed that the limitations of this function is acceptable
1808 * for most usage, and that any more flexibility would introduce
1809 * complexity that would make it harder to use this functionality at
1810 * all.
1812 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1815 gnutls_certificate_set_x509_simple_pkcs12_file
1816 (gnutls_certificate_credentials_t res, const char *pkcs12file,
1817 gnutls_x509_crt_fmt_t type, const char *password)
1819 gnutls_datum_t p12blob;
1820 size_t size;
1821 int ret;
1823 p12blob.data = (void*)read_binary_file (pkcs12file, &size);
1824 p12blob.size = (unsigned int) size;
1825 if (p12blob.data == NULL)
1827 gnutls_assert ();
1828 return GNUTLS_E_FILE_ERROR;
1831 ret =
1832 gnutls_certificate_set_x509_simple_pkcs12_mem (res, &p12blob, type,
1833 password);
1834 free (p12blob.data);
1836 return ret;
1840 * gnutls_certificate_set_x509_simple_pkcs12_mem:
1841 * @res: is a #gnutls_certificate_credentials_t structure.
1842 * @p12blob: the PKCS#12 blob.
1843 * @type: is PEM or DER of the @pkcs12file.
1844 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
1846 * This function sets a certificate/private key pair and/or a CRL in
1847 * the gnutls_certificate_credentials_t structure. This function may
1848 * be called more than once (in case multiple keys/certificates exist
1849 * for the server).
1851 * Encrypted PKCS#12 bags and PKCS#8 private keys are supported. However,
1852 * only password based security, and the same password for all
1853 * operations, are supported.
1855 * PKCS#12 file may contain many keys and/or certificates, and there
1856 * is no way to identify which key/certificate pair you want. You
1857 * should make sure the PKCS#12 file only contain one key/certificate
1858 * pair and/or one CRL.
1860 * It is believed that the limitations of this function is acceptable
1861 * for most usage, and that any more flexibility would introduce
1862 * complexity that would make it harder to use this functionality at
1863 * all.
1865 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1867 * Since: 2.8.0
1870 gnutls_certificate_set_x509_simple_pkcs12_mem
1871 (gnutls_certificate_credentials_t res, const gnutls_datum_t * p12blob,
1872 gnutls_x509_crt_fmt_t type, const char *password)
1874 gnutls_pkcs12_t p12;
1875 gnutls_x509_privkey_t key = NULL;
1876 gnutls_x509_crt_t *chain = NULL;
1877 gnutls_x509_crl_t crl = NULL;
1878 unsigned int chain_size = 0, i;
1879 int ret;
1881 ret = gnutls_pkcs12_init (&p12);
1882 if (ret < 0)
1884 gnutls_assert ();
1885 return ret;
1888 ret = gnutls_pkcs12_import (p12, p12blob, type, 0);
1889 if (ret < 0)
1891 gnutls_assert ();
1892 gnutls_pkcs12_deinit (p12);
1893 return ret;
1896 if (password)
1898 ret = gnutls_pkcs12_verify_mac (p12, password);
1899 if (ret < 0)
1901 gnutls_assert ();
1902 gnutls_pkcs12_deinit (p12);
1903 return ret;
1907 ret = gnutls_pkcs12_simple_parse (p12, password, &key, &chain, &chain_size,
1908 NULL, NULL, &crl, 0);
1909 gnutls_pkcs12_deinit (p12);
1910 if (ret < 0)
1912 gnutls_assert ();
1913 return ret;
1916 if (key && chain)
1918 ret = gnutls_certificate_set_x509_key (res, chain, chain_size, key);
1919 if (ret < 0)
1921 gnutls_assert ();
1922 goto done;
1925 else
1927 gnutls_assert();
1928 ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1929 goto done;
1932 if (crl)
1934 ret = gnutls_certificate_set_x509_crl (res, &crl, 1);
1935 if (ret < 0)
1937 gnutls_assert ();
1938 goto done;
1942 ret = 0;
1944 done:
1945 if (chain)
1947 for (i=0;i<chain_size;i++)
1948 gnutls_x509_crt_deinit (chain[i]);
1949 gnutls_free(chain);
1951 if (key)
1952 gnutls_x509_privkey_deinit (key);
1953 if (crl)
1954 gnutls_x509_crl_deinit (crl);
1956 return ret;
1962 * gnutls_certificate_free_crls:
1963 * @sc: is a #gnutls_certificate_credentials_t structure.
1965 * This function will delete all the CRLs associated
1966 * with the given credentials.
1968 void
1969 gnutls_certificate_free_crls (gnutls_certificate_credentials_t sc)
1971 /* do nothing for now */
1972 return;
1976 * gnutls_certificate_credentials_t:
1977 * @cred: is a #gnutls_certificate_credentials_t structure.
1978 * @fn: A PIN callback
1979 * @userdata: Data to be passed in the callback
1981 * This function will set a callback function to be used when
1982 * required to access a protected object. This function overrides any other
1983 * global PIN functions.
1985 * Note that this function must be called right after initialization
1986 * to have effect.
1988 * Since: 3.1.0
1990 void gnutls_certificate_set_pin_function (gnutls_certificate_credentials_t cred,
1991 gnutls_pin_callback_t fn, void *userdata)
1993 cred->pin.cb = fn;
1994 cred->pin.data = userdata;