Remove unneeded stuff.
[gnutls.git] / lib / gnutls_x509.c
blobc86c4edd4baca29910a0de9167c93aac4d7cbdb0
1 /*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
3 * Free Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 3 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>
24 #include <gnutls_int.h>
25 #include "gnutls_auth.h"
26 #include "gnutls_errors.h"
27 #include <auth/cert.h>
28 #include "gnutls_dh.h"
29 #include "gnutls_num.h"
30 #include "gnutls_datum.h"
31 #include <gnutls_pk.h>
32 #include <algorithms.h>
33 #include <gnutls_global.h>
34 #include <gnutls_record.h>
35 #include <gnutls_sig.h>
36 #include <gnutls_state.h>
37 #include <gnutls_pk.h>
38 #include <gnutls_str.h>
39 #include <debug.h>
40 #include <x509_b64.h>
41 #include <gnutls_x509.h>
42 #include "x509/common.h"
43 #include "x509/x509_int.h"
44 #include <gnutls_str_array.h>
45 #include "read-file.h"
48 * some x509 certificate parsing functions.
51 /* Check if the number of bits of the key in the certificate
52 * is unacceptable.
54 inline static int
55 check_bits (gnutls_x509_crt_t crt, unsigned int max_bits)
57 int ret;
58 unsigned int bits;
60 ret = gnutls_x509_crt_get_pk_algorithm (crt, &bits);
61 if (ret < 0)
63 gnutls_assert ();
64 return ret;
67 if (bits > max_bits && max_bits > 0)
69 gnutls_assert ();
70 return GNUTLS_E_CONSTRAINT_ERROR;
73 return 0;
77 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) { \
78 if (peer_certificate_list[x]) \
79 gnutls_x509_crt_deinit(peer_certificate_list[x]); \
80 } \
81 gnutls_free( peer_certificate_list)
83 /*-
84 * _gnutls_x509_cert_verify_peers - return the peer's certificate status
85 * @session: is a gnutls session
87 * This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.).
88 * The return value (status) should be one of the gnutls_certificate_status_t enumerated elements.
89 * However you must also check the peer's name in order to check if the verified certificate belongs to the
90 * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
91 -*/
92 int
93 _gnutls_x509_cert_verify_peers (gnutls_session_t session,
94 unsigned int *status)
96 cert_auth_info_t info;
97 gnutls_certificate_credentials_t cred;
98 gnutls_x509_crt_t *peer_certificate_list;
99 int peer_certificate_list_size, i, x, ret;
101 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
103 info = _gnutls_get_auth_info (session);
104 if (info == NULL)
106 gnutls_assert ();
107 return GNUTLS_E_INVALID_REQUEST;
110 cred = (gnutls_certificate_credentials_t)
111 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
112 if (cred == NULL)
114 gnutls_assert ();
115 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
118 if (info->raw_certificate_list == NULL || info->ncerts == 0)
119 return GNUTLS_E_NO_CERTIFICATE_FOUND;
121 if (info->ncerts > cred->verify_depth && cred->verify_depth > 0)
123 gnutls_assert ();
124 return GNUTLS_E_CONSTRAINT_ERROR;
127 /* generate a list of gnutls_certs based on the auth info
128 * raw certs.
130 peer_certificate_list_size = info->ncerts;
131 peer_certificate_list =
132 gnutls_calloc (peer_certificate_list_size, sizeof (gnutls_x509_crt_t));
133 if (peer_certificate_list == NULL)
135 gnutls_assert ();
136 return GNUTLS_E_MEMORY_ERROR;
139 for (i = 0; i < peer_certificate_list_size; i++)
141 ret = gnutls_x509_crt_init (&peer_certificate_list[i]);
142 if (ret < 0)
144 gnutls_assert ();
145 CLEAR_CERTS;
146 return ret;
149 ret =
150 gnutls_x509_crt_import (peer_certificate_list[i],
151 &info->raw_certificate_list[i],
152 GNUTLS_X509_FMT_DER);
153 if (ret < 0)
155 gnutls_assert ();
156 CLEAR_CERTS;
157 return ret;
160 ret = check_bits (peer_certificate_list[i], cred->verify_bits);
161 if (ret < 0)
163 gnutls_assert ();
164 CLEAR_CERTS;
165 return ret;
170 /* Verify certificate
173 ret = gnutls_x509_trust_list_verify_crt (cred->tlist, peer_certificate_list,
174 peer_certificate_list_size,
175 cred->verify_flags | session->internals.
176 priorities.additional_verify_flags,
177 status, NULL);
179 CLEAR_CERTS;
181 if (ret < 0)
183 gnutls_assert ();
184 return ret;
187 return 0;
191 * Read certificates and private keys, from files, memory etc.
194 /* returns error if the certificate has different algorithm than
195 * the given key parameters.
197 static int
198 _gnutls_check_key_cert_match (gnutls_certificate_credentials_t res)
200 unsigned int pk = gnutls_pubkey_get_pk_algorithm(res->certs[res->ncerts-1].cert_list[0].pubkey, NULL);
202 if (gnutls_privkey_get_pk_algorithm (res->pkey[res->ncerts - 1], NULL) !=
205 gnutls_assert ();
206 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
209 return 0;
212 /* Returns the name of the certificate of a null name
214 static int get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t *names)
216 size_t max_size;
217 int i, ret = 0, ret2;
218 char name[MAX_CN];
220 for (i = 0; !(ret < 0); i++)
222 max_size = sizeof(name);
224 ret = gnutls_x509_crt_get_subject_alt_name(crt, i, name, &max_size, NULL);
225 if (ret == GNUTLS_SAN_DNSNAME)
227 ret2 = _gnutls_str_array_append(names, name, max_size);
228 if (ret2 < 0)
230 _gnutls_str_array_clear(names);
231 return gnutls_assert_val(ret2);
236 max_size = sizeof(name);
237 ret = gnutls_x509_crt_get_dn_by_oid (crt, OID_X520_COMMON_NAME, 0, 0, name, &max_size);
238 if (ret >= 0)
240 ret = _gnutls_str_array_append(names, name, max_size);
241 if (ret < 0)
243 _gnutls_str_array_clear(names);
244 return gnutls_assert_val(ret);
248 return 0;
251 static int get_x509_name_raw(gnutls_datum_t *raw, gnutls_x509_crt_fmt_t type, gnutls_str_array_t *names)
253 int ret;
254 gnutls_x509_crt_t crt;
256 ret = gnutls_x509_crt_init (&crt);
257 if (ret < 0)
259 gnutls_assert ();
260 return ret;
263 ret = gnutls_x509_crt_import (crt, raw, type);
264 if (ret < 0)
266 gnutls_assert ();
267 gnutls_x509_crt_deinit (crt);
268 return ret;
271 ret = get_x509_name(crt, names);
272 gnutls_x509_crt_deinit (crt);
273 return ret;
276 /* Reads a DER encoded certificate list from memory and stores it to a
277 * gnutls_cert structure. Returns the number of certificates parsed.
279 static int
280 parse_der_cert_mem (gnutls_certificate_credentials_t res,
281 const void *input_cert, int input_cert_size)
283 gnutls_datum_t tmp;
284 gnutls_x509_crt_t crt;
285 gnutls_pcert_st *ccert;
286 int ret;
287 gnutls_str_array_t names;
289 _gnutls_str_array_init(&names);
291 ccert = gnutls_malloc (sizeof (*ccert));
292 if (ccert == NULL)
294 gnutls_assert ();
295 return GNUTLS_E_MEMORY_ERROR;
298 ret = gnutls_x509_crt_init (&crt);
299 if (ret < 0)
301 gnutls_assert ();
302 goto cleanup;
305 tmp.data = (opaque *) input_cert;
306 tmp.size = input_cert_size;
308 ret = gnutls_x509_crt_import (crt, &tmp, GNUTLS_X509_FMT_DER);
309 if (ret < 0)
311 gnutls_assert ();
312 gnutls_x509_crt_deinit (crt);
313 goto cleanup;
316 ret = get_x509_name(crt, &names);
317 if (ret < 0)
319 gnutls_assert();
320 gnutls_x509_crt_deinit (crt);
321 goto cleanup;
324 ret = gnutls_pcert_import_x509 (ccert, crt, 0);
325 gnutls_x509_crt_deinit (crt);
327 if (ret < 0)
329 gnutls_assert ();
330 goto cleanup;
333 ret = certificate_credential_append_crt_list (res, names, ccert, 1);
334 if (ret < 0)
336 gnutls_assert ();
337 goto cleanup;
340 return ret;
342 cleanup:
343 _gnutls_str_array_clear(&names);
344 gnutls_free (ccert);
345 return ret;
348 /* Reads a base64 encoded certificate list from memory and stores it to
349 * a gnutls_cert structure. Returns the number of certificate parsed.
351 static int
352 parse_pem_cert_mem (gnutls_certificate_credentials_t res,
353 const char *input_cert, int input_cert_size)
355 int size;
356 const char *ptr;
357 gnutls_datum_t tmp;
358 int ret, count, i;
359 gnutls_pcert_st *certs = NULL;
360 gnutls_str_array_t names;
362 _gnutls_str_array_init(&names);
364 /* move to the certificate
366 ptr = memmem (input_cert, input_cert_size,
367 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
368 if (ptr == NULL)
369 ptr = memmem (input_cert, input_cert_size,
370 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
372 if (ptr == NULL)
374 gnutls_assert ();
375 return GNUTLS_E_BASE64_DECODING_ERROR;
377 size = input_cert_size - (ptr - input_cert);
379 count = 0;
383 certs = gnutls_realloc_fast (certs, (count + 1) * sizeof (gnutls_pcert_st));
385 if (certs == NULL)
387 gnutls_assert ();
388 ret = GNUTLS_E_MEMORY_ERROR;
389 goto cleanup;
392 tmp.data = (void*)ptr;
393 tmp.size = size;
395 if (count == 0)
397 ret = get_x509_name_raw(&tmp, GNUTLS_X509_FMT_PEM, &names);
398 if (ret < 0)
400 gnutls_assert();
401 goto cleanup;
405 ret = gnutls_pcert_import_x509_raw (&certs[count], &tmp, GNUTLS_X509_FMT_PEM, 0);
406 if (ret < 0)
408 gnutls_assert ();
409 goto cleanup;
412 /* now we move ptr after the pem header
414 ptr++;
415 /* find the next certificate (if any)
417 size = input_cert_size - (ptr - input_cert);
419 if (size > 0)
421 char *ptr3;
423 ptr3 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
424 if (ptr3 == NULL)
425 ptr3 = memmem (ptr, size, PEM_CERT_SEP2,
426 sizeof (PEM_CERT_SEP2) - 1);
428 ptr = ptr3;
430 else
431 ptr = NULL;
433 count++;
436 while (ptr != NULL);
438 ret = certificate_credential_append_crt_list (res, names, certs, count);
439 if (ret < 0)
441 gnutls_assert ();
442 goto cleanup;
445 return count;
447 cleanup:
448 _gnutls_str_array_clear(&names);
449 for (i=0;i<count;i++)
450 gnutls_pcert_deinit(&certs[i]);
451 gnutls_free(certs);
452 return ret;
457 /* Reads a DER or PEM certificate from memory
459 static int
460 read_cert_mem (gnutls_certificate_credentials_t res, const void *cert,
461 int cert_size, gnutls_x509_crt_fmt_t type)
463 int ret;
465 if (type == GNUTLS_X509_FMT_DER)
466 ret = parse_der_cert_mem (res, cert, cert_size);
467 else
468 ret = parse_pem_cert_mem (res, cert, cert_size);
470 if (ret < 0)
472 gnutls_assert ();
473 return ret;
476 return ret;
479 static int
480 _gnutls_x509_raw_privkey_to_privkey (gnutls_privkey_t * privkey,
481 const gnutls_datum_t * raw_key,
482 gnutls_x509_crt_fmt_t type)
484 gnutls_x509_privkey_t tmpkey;
485 int ret;
487 ret = gnutls_x509_privkey_init (&tmpkey);
488 if (ret < 0)
490 gnutls_assert ();
491 return ret;
494 ret = gnutls_x509_privkey_import (tmpkey, raw_key, type);
495 if (ret < 0)
497 gnutls_assert ();
498 gnutls_x509_privkey_deinit (tmpkey);
499 return ret;
502 ret = gnutls_privkey_init (privkey);
503 if (ret < 0)
505 gnutls_assert ();
506 gnutls_x509_privkey_deinit (tmpkey);
507 return ret;
510 ret =
511 gnutls_privkey_import_x509 (*privkey, tmpkey,
512 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
513 if (ret < 0)
515 gnutls_assert ();
516 gnutls_x509_privkey_deinit (tmpkey);
517 gnutls_privkey_deinit (*privkey);
518 return ret;
521 return 0;
524 /* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory. Type
525 * indicates the certificate format. KEY can be NULL, to indicate
526 * that GnuTLS doesn't know the private key.
528 static int
529 read_key_mem (gnutls_certificate_credentials_t res,
530 const void *key, int key_size, gnutls_x509_crt_fmt_t type)
532 int ret;
533 gnutls_datum_t tmp;
534 gnutls_privkey_t privkey;
536 if (key)
538 tmp.data = (opaque *) key;
539 tmp.size = key_size;
541 ret = _gnutls_x509_raw_privkey_to_privkey (&privkey, &tmp, type);
542 if (ret < 0)
544 gnutls_assert ();
545 return ret;
548 ret = certificate_credentials_append_pkey (res, privkey);
549 if (ret < 0)
551 gnutls_assert ();
552 gnutls_privkey_deinit (privkey);
553 return ret;
557 else
559 gnutls_assert ();
560 return GNUTLS_E_INVALID_REQUEST;
564 return 0;
567 #ifdef ENABLE_PKCS11
569 /* Reads a private key from a token.
571 static int
572 read_key_url (gnutls_certificate_credentials_t res, const char *url)
574 int ret;
575 gnutls_pkcs11_privkey_t key1 = NULL;
576 gnutls_privkey_t pkey = NULL;
578 /* allocate space for the pkey list
581 ret = gnutls_pkcs11_privkey_init (&key1);
582 if (ret < 0)
584 gnutls_assert ();
585 return ret;
588 ret = gnutls_pkcs11_privkey_import_url (key1, url, 0);
589 if (ret < 0)
591 gnutls_assert ();
592 goto cleanup;
595 ret = gnutls_privkey_init (&pkey);
596 if (ret < 0)
598 gnutls_assert ();
599 goto cleanup;
602 ret =
603 gnutls_privkey_import_pkcs11 (pkey, key1,
604 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
605 if (ret < 0)
607 gnutls_assert ();
608 goto cleanup;
611 ret = certificate_credentials_append_pkey (res, pkey);
612 if (ret < 0)
614 gnutls_assert ();
615 goto cleanup;
618 return 0;
620 cleanup:
621 if (pkey)
622 gnutls_privkey_deinit (pkey);
624 if (key1)
625 gnutls_pkcs11_privkey_deinit (key1);
627 return ret;
630 /* Reads a private key from a token.
632 static int
633 read_cas_url (gnutls_certificate_credentials_t res, const char *url)
635 int ret;
636 gnutls_x509_crt_t *xcrt_list = NULL;
637 gnutls_pkcs11_obj_t *pcrt_list = NULL;
638 unsigned int pcrt_list_size = 0;
640 /* FIXME: should we use login? */
641 ret =
642 gnutls_pkcs11_obj_list_import_url (NULL, &pcrt_list_size, url,
643 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
644 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
646 gnutls_assert ();
647 return ret;
650 if (pcrt_list_size == 0)
652 gnutls_assert ();
653 return 0;
656 pcrt_list = gnutls_malloc (sizeof (*pcrt_list) * pcrt_list_size);
657 if (pcrt_list == NULL)
659 gnutls_assert ();
660 return GNUTLS_E_MEMORY_ERROR;
663 ret =
664 gnutls_pkcs11_obj_list_import_url (pcrt_list, &pcrt_list_size, url,
665 GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
666 if (ret < 0)
668 gnutls_assert ();
669 goto cleanup;
672 xcrt_list = gnutls_malloc (sizeof (*xcrt_list) * pcrt_list_size);
673 if (xcrt_list == NULL)
675 gnutls_assert ();
676 ret = GNUTLS_E_MEMORY_ERROR;
677 goto cleanup;
680 ret =
681 gnutls_x509_crt_list_import_pkcs11 (xcrt_list, pcrt_list_size, pcrt_list,
683 if (xcrt_list == NULL)
685 gnutls_assert ();
686 ret = GNUTLS_E_MEMORY_ERROR;
687 goto cleanup;
690 ret = gnutls_x509_trust_list_add_cas(res->tlist, xcrt_list, pcrt_list_size, 0);
691 if (ret < 0)
693 gnutls_assert();
694 goto cleanup;
697 cleanup:
698 gnutls_free (xcrt_list);
699 gnutls_free (pcrt_list);
701 return ret;
706 /* Reads a private key from a token.
708 static int
709 read_cert_url (gnutls_certificate_credentials_t res, const char *url)
711 int ret;
712 gnutls_x509_crt_t crt;
713 gnutls_pcert_st *ccert;
714 gnutls_str_array_t names;
716 _gnutls_str_array_init(&names);
718 ccert = gnutls_malloc (sizeof (*ccert));
719 if (ccert == NULL)
721 gnutls_assert ();
722 return GNUTLS_E_MEMORY_ERROR;
725 ret = gnutls_x509_crt_init (&crt);
726 if (ret < 0)
728 gnutls_assert ();
729 goto cleanup;
732 ret = gnutls_x509_crt_import_pkcs11_url (crt, url, 0);
733 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
734 ret =
735 gnutls_x509_crt_import_pkcs11_url (crt, url,
736 GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
738 if (ret < 0)
740 gnutls_assert ();
741 gnutls_x509_crt_deinit (crt);
742 goto cleanup;
745 ret = get_x509_name(crt, &names);
746 if (ret < 0)
748 gnutls_assert ();
749 gnutls_x509_crt_deinit (crt);
750 goto cleanup;
753 ret = gnutls_pcert_import_x509 (ccert, crt, 0);
754 gnutls_x509_crt_deinit (crt);
756 if (ret < 0)
758 gnutls_assert ();
759 goto cleanup;
762 ret = certificate_credential_append_crt_list (res, names, ccert, 1);
763 if (ret < 0)
765 gnutls_assert ();
766 goto cleanup;
769 return 0;
771 cleanup:
772 _gnutls_str_array_clear(&names);
773 gnutls_free (ccert);
774 return ret;
777 #endif /* ENABLE_PKCS11 */
779 /* Reads a certificate file
781 static int
782 read_cert_file (gnutls_certificate_credentials_t res,
783 const char *certfile, gnutls_x509_crt_fmt_t type)
785 int ret;
786 size_t size;
787 char *data;
789 #ifdef ENABLE_PKCS11
790 if (strncmp (certfile, "pkcs11:", 7) == 0)
792 return read_cert_url (res, certfile);
794 #endif /* ENABLE_PKCS11 */
796 data = read_binary_file (certfile, &size);
798 if (data == NULL)
800 gnutls_assert ();
801 return GNUTLS_E_FILE_ERROR;
804 ret = read_cert_mem (res, data, size, type);
805 free (data);
807 return ret;
813 /* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
814 * stores it).
816 static int
817 read_key_file (gnutls_certificate_credentials_t res,
818 const char *keyfile, gnutls_x509_crt_fmt_t type)
820 int ret;
821 size_t size;
822 char *data;
824 #ifdef ENABLE_PKCS11
825 if (strncmp (keyfile, "pkcs11:", 7) == 0)
827 return read_key_url (res, keyfile);
829 #endif /* ENABLE_PKCS11 */
831 data = read_binary_file (keyfile, &size);
833 if (data == NULL)
835 gnutls_assert ();
836 return GNUTLS_E_FILE_ERROR;
839 ret = read_key_mem (res, data, size, type);
840 free (data);
842 return ret;
846 * gnutls_certificate_set_x509_key_mem:
847 * @res: is a #gnutls_certificate_credentials_t structure.
848 * @cert: contains a certificate list (path) for the specified private key
849 * @key: is the private key, or %NULL
850 * @type: is PEM or DER
852 * This function sets a certificate/private key pair in the
853 * gnutls_certificate_credentials_t structure. This function may be called
854 * more than once, in case multiple keys/certificates exist for the
855 * server.
857 * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
858 * is supported. This means that certificates intended for signing cannot
859 * be used for ciphersuites that require encryption.
861 * If the certificate and the private key are given in PEM encoding
862 * then the strings that hold their values must be null terminated.
864 * The @key may be %NULL if you are using a sign callback, see
865 * gnutls_sign_callback_set().
867 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
870 gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t res,
871 const gnutls_datum_t * cert,
872 const gnutls_datum_t * key,
873 gnutls_x509_crt_fmt_t type)
875 int ret;
877 /* this should be first
879 if ((ret = read_key_mem (res, key ? key->data : NULL,
880 key ? key->size : 0, type)) < 0)
881 return ret;
883 if ((ret = read_cert_mem (res, cert->data, cert->size, type)) < 0)
884 return ret;
886 res->ncerts++;
888 if (key && (ret = _gnutls_check_key_cert_match (res)) < 0)
890 gnutls_assert ();
891 return ret;
894 return 0;
897 static int check_if_sorted(gnutls_pcert_st * crt, int nr)
899 gnutls_x509_crt_t x509;
900 char prev_dn[MAX_DN];
901 char dn[MAX_DN];
902 size_t prev_dn_size, dn_size;
903 int i, ret;
905 /* check if the X.509 list is ordered */
906 if (nr > 1 && crt[0].type == GNUTLS_CRT_X509)
909 for (i=0;i<nr;i++)
911 ret = gnutls_x509_crt_init(&x509);
912 if (ret < 0)
913 return gnutls_assert_val(ret);
915 ret = gnutls_x509_crt_import(x509, &crt[i].cert, GNUTLS_X509_FMT_DER);
916 if (ret < 0)
918 ret = gnutls_assert_val(ret);
919 goto cleanup;
922 if (i>0)
924 dn_size = sizeof(dn);
925 ret = gnutls_x509_crt_get_dn(x509, dn, &dn_size);
926 if (ret < 0)
928 ret = gnutls_assert_val(ret);
929 goto cleanup;
932 if (dn_size != prev_dn_size || memcmp(dn, prev_dn, dn_size) != 0)
934 ret = gnutls_assert_val(GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
935 goto cleanup;
939 prev_dn_size = sizeof(prev_dn);
940 ret = gnutls_x509_crt_get_issuer_dn(x509, prev_dn, &prev_dn_size);
941 if (ret < 0)
943 ret = gnutls_assert_val(ret);
944 goto cleanup;
947 gnutls_x509_crt_deinit(x509);
951 return 0;
953 cleanup:
954 gnutls_x509_crt_deinit(x509);
955 return ret;
959 certificate_credential_append_crt_list (gnutls_certificate_credentials_t res,
960 gnutls_str_array_t names, gnutls_pcert_st * crt, int nr)
962 int ret;
964 ret = check_if_sorted(crt, nr);
965 if (ret < 0)
966 return gnutls_assert_val(ret);
968 res->certs = gnutls_realloc_fast (res->certs,
969 (1 + res->ncerts) *
970 sizeof (certs_st));
971 if (res->certs == NULL)
973 gnutls_assert ();
974 return GNUTLS_E_MEMORY_ERROR;
977 res->certs[res->ncerts].cert_list = crt;
978 res->certs[res->ncerts].cert_list_length = nr;
979 res->certs[res->ncerts].names = names;
981 return 0;
986 certificate_credentials_append_pkey (gnutls_certificate_credentials_t res,
987 gnutls_privkey_t pkey)
989 res->pkey = gnutls_realloc_fast (res->pkey,
990 (1 + res->ncerts) *
991 sizeof (gnutls_privkey_t));
992 if (res->pkey == NULL)
994 gnutls_assert ();
995 return GNUTLS_E_MEMORY_ERROR;
997 res->pkey[res->ncerts] = pkey;
998 return 0;
1003 * gnutls_certificate_set_x509_key:
1004 * @res: is a #gnutls_certificate_credentials_t structure.
1005 * @cert_list: contains a certificate list (path) for the specified private key
1006 * @cert_list_size: holds the size of the certificate list
1007 * @key: is a gnutls_x509_privkey_t key
1009 * This function sets a certificate/private key pair in the
1010 * gnutls_certificate_credentials_t structure. This function may be
1011 * called more than once, in case multiple keys/certificates exist for
1012 * the server. For clients that wants to send more than its own end
1013 * entity certificate (e.g., also an intermediate CA cert) then put
1014 * the certificate chain in @cert_list.
1018 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1020 * Since: 2.4.0
1023 gnutls_certificate_set_x509_key (gnutls_certificate_credentials_t res,
1024 gnutls_x509_crt_t * cert_list,
1025 int cert_list_size,
1026 gnutls_x509_privkey_t key)
1028 int ret, i;
1029 gnutls_privkey_t pkey;
1030 gnutls_pcert_st *pcerts = NULL;
1031 gnutls_str_array_t names;
1033 _gnutls_str_array_init(&names);
1035 /* this should be first
1037 ret = gnutls_privkey_init (&pkey);
1038 if (ret < 0)
1040 gnutls_assert ();
1041 return ret;
1044 ret = gnutls_privkey_import_x509 (pkey, key, GNUTLS_PRIVKEY_IMPORT_COPY);
1045 if (ret < 0)
1047 gnutls_assert ();
1048 return ret;
1051 ret = certificate_credentials_append_pkey (res, pkey);
1052 if (ret < 0)
1054 gnutls_assert ();
1055 return ret;
1058 /* load certificates */
1059 pcerts = gnutls_malloc (sizeof (gnutls_pcert_st) * cert_list_size);
1060 if (pcerts == NULL)
1062 gnutls_assert ();
1063 return GNUTLS_E_MEMORY_ERROR;
1066 ret = get_x509_name(cert_list[0], &names);
1067 if (ret < 0)
1068 return gnutls_assert_val(ret);
1070 for (i = 0; i < cert_list_size; i++)
1072 ret = gnutls_pcert_import_x509 (&pcerts[i], cert_list[i], 0);
1073 if (ret < 0)
1075 gnutls_assert ();
1076 goto cleanup;
1080 ret = certificate_credential_append_crt_list (res, names, pcerts, cert_list_size);
1081 if (ret < 0)
1083 gnutls_assert ();
1084 goto cleanup;
1087 res->ncerts++;
1089 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1091 gnutls_assert ();
1092 return ret;
1095 return 0;
1097 cleanup:
1098 _gnutls_str_array_clear(&names);
1099 return ret;
1103 * gnutls_certificate_set_key:
1104 * @res: is a #gnutls_certificate_credentials_t structure.
1105 * @names: is an array of DNS name of the certificate (NULL if none)
1106 * @names_size: holds the size of the names list
1107 * @pcert_list: contains a certificate list (path) for the specified private key
1108 * @pcert_list_size: holds the size of the certificate list
1109 * @key: is a gnutls_x509_privkey_t key
1111 * This function sets a certificate/private key pair in the
1112 * gnutls_certificate_credentials_t structure. This function may be
1113 * called more than once, in case multiple keys/certificates exist for
1114 * the server. For clients that wants to send more than its own end
1115 * entity certificate (e.g., also an intermediate CA cert) then put
1116 * the certificate chain in @pcert_list. The @pcert_list and @key will
1117 * become part of the credentials structure and must not
1118 * be deallocated. They will be automatically deallocated when
1119 * @res is deinitialized.
1121 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1123 * Since: 3.0.0
1126 gnutls_certificate_set_key (gnutls_certificate_credentials_t res,
1127 const char** names,
1128 int names_size,
1129 gnutls_pcert_st * pcert_list,
1130 int pcert_list_size,
1131 gnutls_privkey_t key)
1133 int ret, i;
1134 gnutls_str_array_t str_names;
1136 _gnutls_str_array_init(&str_names);
1138 if (names != NULL && names_size > 0)
1140 for (i=0;i<names_size;i++)
1142 ret = _gnutls_str_array_append(&str_names, names[i], strlen(names[i]));
1143 if (ret < 0)
1145 ret = gnutls_assert_val(ret);
1146 goto cleanup;
1151 ret = certificate_credentials_append_pkey (res, key);
1152 if (ret < 0)
1154 gnutls_assert ();
1155 goto cleanup;
1158 ret = certificate_credential_append_crt_list (res, str_names, pcert_list, pcert_list_size);
1159 if (ret < 0)
1161 gnutls_assert ();
1162 goto cleanup;
1165 res->ncerts++;
1167 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1169 gnutls_assert ();
1170 return ret;
1173 return 0;
1175 cleanup:
1176 _gnutls_str_array_clear(&str_names);
1177 return ret;
1181 * gnutls_certificate_set_x509_key_file:
1182 * @res: is a #gnutls_certificate_credentials_t structure.
1183 * @certfile: is a file that containing the certificate list (path) for
1184 * the specified private key, in PKCS7 format, or a list of certificates
1185 * @keyfile: is a file that contains the private key
1186 * @type: is PEM or DER
1188 * This function sets a certificate/private key pair in the
1189 * gnutls_certificate_credentials_t structure. This function may be
1190 * called more than once, in case multiple keys/certificates exist for
1191 * the server. For clients that need to send more than its own end
1192 * entity certificate, e.g., also an intermediate CA cert, then the
1193 * @certfile must contain the ordered certificate chain.
1195 * This function can also accept PKCS #11 URLs at @keyfile and @certfile. In that case it
1196 * will import the private key and certificate indicated by the URLs.
1198 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1201 gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t res,
1202 const char *certfile,
1203 const char *keyfile,
1204 gnutls_x509_crt_fmt_t type)
1206 int ret;
1208 /* this should be first
1210 if ((ret = read_key_file (res, keyfile, type)) < 0)
1211 return ret;
1213 if ((ret = read_cert_file (res, certfile, type)) < 0)
1214 return ret;
1216 res->ncerts++;
1218 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
1220 gnutls_assert ();
1221 return ret;
1224 return 0;
1227 static int
1228 add_new_crt_to_rdn_seq (gnutls_certificate_credentials_t res, gnutls_x509_crt_t* crts,
1229 unsigned int crt_size)
1231 gnutls_datum_t tmp;
1232 int ret;
1233 size_t newsize;
1234 unsigned char *newdata;
1235 unsigned i;
1237 /* Add DN of the last added CAs to the RDN sequence
1238 * This will be sent to clients when a certificate
1239 * request message is sent.
1242 /* FIXME: in case of a client it is not needed
1243 * to do that. This would save time and memory.
1244 * However we don't have that information available
1245 * here.
1246 * Further, this function is now much more efficient,
1247 * so optimizing that is less important.
1250 for (i = 0; i < crt_size; i++)
1252 if ((ret = gnutls_x509_crt_get_raw_dn (crts[i], &tmp)) < 0)
1254 gnutls_assert ();
1255 return ret;
1258 newsize = res->x509_rdn_sequence.size + 2 + tmp.size;
1259 if (newsize < res->x509_rdn_sequence.size)
1261 gnutls_assert ();
1262 _gnutls_free_datum (&tmp);
1263 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1266 newdata = gnutls_realloc (res->x509_rdn_sequence.data, newsize);
1267 if (newdata == NULL)
1269 gnutls_assert ();
1270 _gnutls_free_datum (&tmp);
1271 return GNUTLS_E_MEMORY_ERROR;
1274 _gnutls_write_datum16 (newdata + res->x509_rdn_sequence.size, tmp);
1275 _gnutls_free_datum (&tmp);
1277 res->x509_rdn_sequence.size = newsize;
1278 res->x509_rdn_sequence.data = newdata;
1281 return 0;
1284 /* Returns 0 if it's ok to use the gnutls_kx_algorithm_t with this
1285 * certificate (uses the KeyUsage field).
1288 _gnutls_check_key_usage (const gnutls_pcert_st* cert, gnutls_kx_algorithm_t alg)
1290 unsigned int key_usage = 0;
1291 int encipher_type;
1293 if (cert == NULL)
1295 gnutls_assert ();
1296 return GNUTLS_E_INTERNAL_ERROR;
1299 if (_gnutls_map_kx_get_cred (alg, 1) == GNUTLS_CRD_CERTIFICATE ||
1300 _gnutls_map_kx_get_cred (alg, 0) == GNUTLS_CRD_CERTIFICATE)
1303 gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
1305 encipher_type = _gnutls_kx_encipher_type (alg);
1307 if (key_usage != 0 && encipher_type != CIPHER_IGN)
1309 /* If key_usage has been set in the certificate
1312 if (encipher_type == CIPHER_ENCRYPT)
1314 /* If the key exchange method requires an encipher
1315 * type algorithm, and key's usage does not permit
1316 * encipherment, then fail.
1318 if (!(key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT))
1320 gnutls_assert ();
1321 return GNUTLS_E_KEY_USAGE_VIOLATION;
1325 if (encipher_type == CIPHER_SIGN)
1327 /* The same as above, but for sign only keys
1329 if (!(key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE))
1331 gnutls_assert ();
1332 return GNUTLS_E_KEY_USAGE_VIOLATION;
1337 return 0;
1340 static int
1341 parse_pem_ca_mem (gnutls_certificate_credentials_t res,
1342 const opaque * input_cert, int input_cert_size)
1344 gnutls_x509_crt_t *x509_cert_list;
1345 unsigned int x509_ncerts;
1346 gnutls_datum_t tmp;
1347 int ret;
1349 tmp.data = (void*)input_cert;
1350 tmp.size = input_cert_size;
1352 ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp,
1353 GNUTLS_X509_FMT_PEM, 0);
1354 if (ret < 0)
1356 gnutls_assert();
1357 return ret;
1360 if ((ret = add_new_crt_to_rdn_seq (res, x509_cert_list, x509_ncerts)) < 0)
1362 gnutls_assert();
1363 goto cleanup;
1366 ret = gnutls_x509_trust_list_add_cas(res->tlist, x509_cert_list, x509_ncerts, 0);
1367 if (ret < 0)
1369 gnutls_assert();
1370 goto cleanup;
1373 cleanup:
1374 gnutls_free(x509_cert_list);
1375 return ret;
1378 /* Reads a DER encoded certificate list from memory and stores it to a
1379 * gnutls_cert structure. Returns the number of certificates parsed.
1381 static int
1382 parse_der_ca_mem (gnutls_certificate_credentials_t res,
1383 const void *input_cert, int input_cert_size)
1385 gnutls_x509_crt_t crt;
1386 gnutls_datum_t tmp;
1387 int ret;
1389 tmp.data = (void*)input_cert;
1390 tmp.size = input_cert_size;
1392 ret = gnutls_x509_crt_init( &crt);
1393 if (ret < 0)
1395 gnutls_assert();
1396 return ret;
1399 ret = gnutls_x509_crt_import( crt, &tmp, GNUTLS_X509_FMT_DER);
1400 if (ret < 0)
1402 gnutls_assert();
1403 goto cleanup;
1406 if ((ret = add_new_crt_to_rdn_seq (res, &crt, 1)) < 0)
1408 gnutls_assert();
1409 goto cleanup;
1412 ret = gnutls_x509_trust_list_add_cas(res->tlist, &crt, 1, 0);
1413 if (ret < 0)
1415 gnutls_assert();
1416 goto cleanup;
1419 return ret;
1421 cleanup:
1422 gnutls_x509_crt_deinit(crt);
1423 return ret;
1427 * gnutls_certificate_set_x509_trust_mem:
1428 * @res: is a #gnutls_certificate_credentials_t structure.
1429 * @ca: is a list of trusted CAs or a DER certificate
1430 * @type: is DER or PEM
1432 * This function adds the trusted CAs in order to verify client or
1433 * server certificates. In case of a client this is not required to be
1434 * called if the certificates are not verified using
1435 * gnutls_certificate_verify_peers2(). This function may be called
1436 * multiple times.
1438 * In case of a server the CAs set here will be sent to the client if
1439 * a certificate request is sent. This can be disabled using
1440 * gnutls_certificate_send_x509_rdn_sequence().
1442 * Returns: the number of certificates processed or a negative error code
1443 * on error.
1446 gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t res,
1447 const gnutls_datum_t * ca,
1448 gnutls_x509_crt_fmt_t type)
1450 int ret;
1452 if (type == GNUTLS_X509_FMT_DER)
1453 ret = parse_der_ca_mem (res,
1454 ca->data, ca->size);
1455 else
1456 ret = parse_pem_ca_mem (res,
1457 ca->data, ca->size);
1459 if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
1460 return 0;
1462 return ret;
1466 * gnutls_certificate_set_x509_trust:
1467 * @res: is a #gnutls_certificate_credentials_t structure.
1468 * @ca_list: is a list of trusted CAs
1469 * @ca_list_size: holds the size of the CA list
1471 * This function adds the trusted CAs in order to verify client
1472 * or server certificates. In case of a client this is not required
1473 * to be called if the certificates are not verified using
1474 * gnutls_certificate_verify_peers2().
1475 * This function may be called multiple times.
1477 * In case of a server the CAs set here will be sent to the client if
1478 * a certificate request is sent. This can be disabled using
1479 * gnutls_certificate_send_x509_rdn_sequence().
1481 * Returns: the number of certificates processed or a negative error code
1482 * on error.
1484 * Since: 2.4.0
1487 gnutls_certificate_set_x509_trust (gnutls_certificate_credentials_t res,
1488 gnutls_x509_crt_t * ca_list,
1489 int ca_list_size)
1491 int ret, i, j;
1492 gnutls_x509_crt_t new_list[ca_list_size];
1494 for (i = 0; i < ca_list_size; i++)
1496 ret = gnutls_x509_crt_init (&new_list[i]);
1497 if (ret < 0)
1499 gnutls_assert ();
1500 goto cleanup;
1503 ret = _gnutls_x509_crt_cpy (new_list[i], ca_list[i]);
1504 if (ret < 0)
1506 gnutls_assert ();
1507 goto cleanup;
1511 if ((ret = add_new_crt_to_rdn_seq (res, new_list, ca_list_size)) < 0)
1513 gnutls_assert();
1514 goto cleanup;
1517 ret = gnutls_x509_trust_list_add_cas(res->tlist, new_list, ca_list_size, 0);
1518 if (ret < 0)
1520 gnutls_assert ();
1521 goto cleanup;
1524 return ret;
1526 cleanup:
1527 for (j=0;j<i;i++)
1528 gnutls_x509_crt_deinit(new_list[j]);
1530 return ret;
1535 * gnutls_certificate_set_x509_trust_file:
1536 * @cred: is a #gnutls_certificate_credentials_t structure.
1537 * @cafile: is a file containing the list of trusted CAs (DER or PEM list)
1538 * @type: is PEM or DER
1540 * This function adds the trusted CAs in order to verify client or
1541 * server certificates. In case of a client this is not required to
1542 * be called if the certificates are not verified using
1543 * gnutls_certificate_verify_peers2(). This function may be called
1544 * multiple times.
1546 * In case of a server the names of the CAs set here will be sent to
1547 * the client if a certificate request is sent. This can be disabled
1548 * using gnutls_certificate_send_x509_rdn_sequence().
1550 * This function can also accept PKCS #11 URLs. In that case it
1551 * will import all certificates that are marked as trusted.
1553 * Returns: number of certificates processed, or a negative error code on
1554 * error.
1557 gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t cred,
1558 const char *cafile,
1559 gnutls_x509_crt_fmt_t type)
1561 int ret;
1562 gnutls_datum_t cas;
1563 size_t size;
1565 #ifdef ENABLE_PKCS11
1566 if (strncmp (cafile, "pkcs11:", 7) == 0)
1568 return read_cas_url (cred, cafile);
1570 #endif
1572 cas.data = read_binary_file (cafile, &size);
1573 if (cas.data == NULL)
1575 gnutls_assert ();
1576 return GNUTLS_E_FILE_ERROR;
1579 cas.size = size;
1581 ret = gnutls_certificate_set_x509_trust_mem(cred, &cas, type);
1583 free (cas.data);
1585 if (ret < 0)
1587 gnutls_assert ();
1588 return ret;
1591 return ret;
1594 #ifdef ENABLE_PKI
1596 static int
1597 parse_pem_crl_mem (gnutls_x509_trust_list_t tlist,
1598 const opaque * input_crl, int input_crl_size)
1600 gnutls_x509_crl_t *x509_crl_list;
1601 unsigned int x509_ncrls;
1602 gnutls_datum_t tmp;
1603 int ret;
1605 tmp.data = (void*)input_crl;
1606 tmp.size = input_crl_size;
1608 ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp,
1609 GNUTLS_X509_FMT_PEM, 0);
1610 if (ret < 0)
1612 gnutls_assert();
1613 return ret;
1616 ret = gnutls_x509_trust_list_add_crls(tlist, x509_crl_list, x509_ncrls, 0, 0);
1617 if (ret < 0)
1619 gnutls_assert();
1620 goto cleanup;
1623 cleanup:
1624 gnutls_free(x509_crl_list);
1625 return ret;
1628 /* Reads a DER encoded certificate list from memory and stores it to a
1629 * gnutls_cert structure. Returns the number of certificates parsed.
1631 static int
1632 parse_der_crl_mem (gnutls_x509_trust_list_t tlist,
1633 const void *input_crl, int input_crl_size)
1635 gnutls_x509_crl_t crl;
1636 gnutls_datum_t tmp;
1637 int ret;
1639 tmp.data = (void*)input_crl;
1640 tmp.size = input_crl_size;
1642 ret = gnutls_x509_crl_init( &crl);
1643 if (ret < 0)
1645 gnutls_assert();
1646 return ret;
1649 ret = gnutls_x509_crl_import( crl, &tmp, GNUTLS_X509_FMT_DER);
1650 if (ret < 0)
1652 gnutls_assert();
1653 goto cleanup;
1656 ret = gnutls_x509_trust_list_add_crls(tlist, &crl, 1, 0, 0);
1657 if (ret < 0)
1659 gnutls_assert();
1660 goto cleanup;
1663 return ret;
1665 cleanup:
1666 gnutls_x509_crl_deinit(crl);
1667 return ret;
1672 /* Reads a DER or PEM CRL from memory
1674 static int
1675 read_crl_mem (gnutls_certificate_credentials_t res, const void *crl,
1676 int crl_size, gnutls_x509_crt_fmt_t type)
1678 int ret;
1680 if (type == GNUTLS_X509_FMT_DER)
1681 ret = parse_der_crl_mem (res->tlist, crl, crl_size);
1682 else
1683 ret = parse_pem_crl_mem (res->tlist, crl, crl_size);
1685 if (ret < 0)
1687 gnutls_assert ();
1690 return ret;
1694 * gnutls_certificate_set_x509_crl_mem:
1695 * @res: is a #gnutls_certificate_credentials_t structure.
1696 * @CRL: is a list of trusted CRLs. They should have been verified before.
1697 * @type: is DER or PEM
1699 * This function adds the trusted CRLs in order to verify client or
1700 * server certificates. In case of a client this is not required to
1701 * be called if the certificates are not verified using
1702 * gnutls_certificate_verify_peers2(). This function may be called
1703 * multiple times.
1705 * Returns: number of CRLs processed, or a negative error code on error.
1708 gnutls_certificate_set_x509_crl_mem (gnutls_certificate_credentials_t res,
1709 const gnutls_datum_t * CRL,
1710 gnutls_x509_crt_fmt_t type)
1712 return read_crl_mem (res, CRL->data, CRL->size, type);
1716 * gnutls_certificate_set_x509_crl:
1717 * @res: is a #gnutls_certificate_credentials_t structure.
1718 * @crl_list: is a list of trusted CRLs. They should have been verified before.
1719 * @crl_list_size: holds the size of the crl_list
1721 * This function adds the trusted CRLs in order to verify client or
1722 * server certificates. In case of a client this is not required to
1723 * be called if the certificates are not verified using
1724 * gnutls_certificate_verify_peers2(). This function may be called
1725 * multiple times.
1727 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
1729 * Since: 2.4.0
1732 gnutls_certificate_set_x509_crl (gnutls_certificate_credentials_t res,
1733 gnutls_x509_crl_t * crl_list,
1734 int crl_list_size)
1736 int ret, i, j;
1737 gnutls_x509_crl_t new_crl[crl_list_size];
1739 for (i = 0; i < crl_list_size; i++)
1741 ret = gnutls_x509_crl_init (&new_crl[i]);
1742 if (ret < 0)
1744 gnutls_assert ();
1745 goto cleanup;
1748 ret = _gnutls_x509_crl_cpy (new_crl[i], crl_list[i]);
1749 if (ret < 0)
1751 gnutls_assert ();
1752 goto cleanup;
1756 ret = gnutls_x509_trust_list_add_crls(res->tlist, new_crl, crl_list_size, 0, 0);
1757 if (ret < 0)
1759 gnutls_assert ();
1760 goto cleanup;
1763 return ret;
1765 cleanup:
1766 for (j=0;j<i;j++)
1767 gnutls_x509_crl_deinit(new_crl[j]);
1769 return ret;
1773 * gnutls_certificate_set_x509_crl_file:
1774 * @res: is a #gnutls_certificate_credentials_t structure.
1775 * @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
1776 * @type: is PEM or DER
1778 * This function adds the trusted CRLs in order to verify client or server
1779 * certificates. In case of a client this is not required
1780 * to be called if the certificates are not verified using
1781 * gnutls_certificate_verify_peers2().
1782 * This function may be called multiple times.
1784 * Returns: number of CRLs processed or a negative error code on error.
1787 gnutls_certificate_set_x509_crl_file (gnutls_certificate_credentials_t res,
1788 const char *crlfile,
1789 gnutls_x509_crt_fmt_t type)
1791 int ret;
1792 size_t size;
1793 char *data = read_binary_file (crlfile, &size);
1795 if (data == NULL)
1797 gnutls_assert ();
1798 return GNUTLS_E_FILE_ERROR;
1801 if (type == GNUTLS_X509_FMT_DER)
1802 ret = parse_der_crl_mem (res->tlist, data, size);
1803 else
1804 ret = parse_pem_crl_mem (res->tlist, data, size);
1806 free (data);
1808 if (ret < 0)
1810 gnutls_assert ();
1811 return ret;
1814 return ret;
1817 #include <gnutls/pkcs12.h>
1819 static int
1820 parse_pkcs12 (gnutls_certificate_credentials_t res,
1821 gnutls_pkcs12_t p12,
1822 const char *password,
1823 gnutls_x509_privkey_t * key,
1824 gnutls_x509_crt_t * cert, gnutls_x509_crl_t * crl)
1826 gnutls_pkcs12_bag_t bag = NULL;
1827 int idx = 0;
1828 int ret;
1829 size_t cert_id_size = 0;
1830 size_t key_id_size = 0;
1831 opaque cert_id[20];
1832 opaque key_id[20];
1833 int privkey_ok = 0;
1835 *cert = NULL;
1836 *key = NULL;
1837 *crl = NULL;
1839 /* find the first private key */
1840 for (;;)
1842 int elements_in_bag;
1843 int i;
1845 ret = gnutls_pkcs12_bag_init (&bag);
1846 if (ret < 0)
1848 bag = NULL;
1849 gnutls_assert ();
1850 goto done;
1853 ret = gnutls_pkcs12_get_bag (p12, idx, bag);
1854 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1855 break;
1856 if (ret < 0)
1858 gnutls_assert ();
1859 goto done;
1862 ret = gnutls_pkcs12_bag_get_type (bag, 0);
1863 if (ret < 0)
1865 gnutls_assert ();
1866 goto done;
1869 if (ret == GNUTLS_BAG_ENCRYPTED)
1871 ret = gnutls_pkcs12_bag_decrypt (bag, password);
1872 if (ret < 0)
1874 gnutls_assert ();
1875 goto done;
1879 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
1880 if (elements_in_bag < 0)
1882 gnutls_assert ();
1883 goto done;
1886 for (i = 0; i < elements_in_bag; i++)
1888 int type;
1889 gnutls_datum_t data;
1891 type = gnutls_pkcs12_bag_get_type (bag, i);
1892 if (type < 0)
1894 gnutls_assert ();
1895 goto done;
1898 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
1899 if (ret < 0)
1901 gnutls_assert ();
1902 goto done;
1905 switch (type)
1907 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
1908 case GNUTLS_BAG_PKCS8_KEY:
1909 if (*key != NULL) /* too simple to continue */
1911 gnutls_assert ();
1912 break;
1915 ret = gnutls_x509_privkey_init (key);
1916 if (ret < 0)
1918 gnutls_assert ();
1919 goto done;
1922 ret = gnutls_x509_privkey_import_pkcs8
1923 (*key, &data, GNUTLS_X509_FMT_DER, password,
1924 type == GNUTLS_BAG_PKCS8_KEY ? GNUTLS_PKCS_PLAIN : 0);
1925 if (ret < 0)
1927 gnutls_assert ();
1928 gnutls_x509_privkey_deinit (*key);
1929 goto done;
1932 key_id_size = sizeof (key_id);
1933 ret =
1934 gnutls_x509_privkey_get_key_id (*key, 0, key_id,
1935 &key_id_size);
1936 if (ret < 0)
1938 gnutls_assert ();
1939 gnutls_x509_privkey_deinit (*key);
1940 goto done;
1943 privkey_ok = 1; /* break */
1944 break;
1945 default:
1946 break;
1950 idx++;
1951 gnutls_pkcs12_bag_deinit (bag);
1953 if (privkey_ok != 0) /* private key was found */
1954 break;
1957 if (privkey_ok == 0) /* no private key */
1959 gnutls_assert ();
1960 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1963 /* now find the corresponding certificate
1965 idx = 0;
1966 bag = NULL;
1967 for (;;)
1969 int elements_in_bag;
1970 int i;
1972 ret = gnutls_pkcs12_bag_init (&bag);
1973 if (ret < 0)
1975 bag = NULL;
1976 gnutls_assert ();
1977 goto done;
1980 ret = gnutls_pkcs12_get_bag (p12, idx, bag);
1981 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1982 break;
1983 if (ret < 0)
1985 gnutls_assert ();
1986 goto done;
1989 ret = gnutls_pkcs12_bag_get_type (bag, 0);
1990 if (ret < 0)
1992 gnutls_assert ();
1993 goto done;
1996 if (ret == GNUTLS_BAG_ENCRYPTED)
1998 ret = gnutls_pkcs12_bag_decrypt (bag, password);
1999 if (ret < 0)
2001 gnutls_assert ();
2002 goto done;
2006 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
2007 if (elements_in_bag < 0)
2009 gnutls_assert ();
2010 goto done;
2013 for (i = 0; i < elements_in_bag; i++)
2015 int type;
2016 gnutls_datum_t data;
2018 type = gnutls_pkcs12_bag_get_type (bag, i);
2019 if (type < 0)
2021 gnutls_assert ();
2022 goto done;
2025 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
2026 if (ret < 0)
2028 gnutls_assert ();
2029 goto done;
2032 switch (type)
2034 case GNUTLS_BAG_CERTIFICATE:
2035 if (*cert != NULL) /* no need to set it again */
2037 gnutls_assert ();
2038 break;
2041 ret = gnutls_x509_crt_init (cert);
2042 if (ret < 0)
2044 gnutls_assert ();
2045 goto done;
2048 ret =
2049 gnutls_x509_crt_import (*cert, &data, GNUTLS_X509_FMT_DER);
2050 if (ret < 0)
2052 gnutls_assert ();
2053 gnutls_x509_crt_deinit (*cert);
2054 goto done;
2057 /* check if the key id match */
2058 cert_id_size = sizeof (cert_id);
2059 ret =
2060 gnutls_x509_crt_get_key_id (*cert, 0, cert_id, &cert_id_size);
2061 if (ret < 0)
2063 gnutls_assert ();
2064 gnutls_x509_crt_deinit (*cert);
2065 goto done;
2068 if (memcmp (cert_id, key_id, cert_id_size) != 0)
2069 { /* they don't match - skip the certificate */
2070 gnutls_x509_crt_deinit (*cert);
2071 *cert = NULL;
2073 break;
2075 case GNUTLS_BAG_CRL:
2076 if (*crl != NULL)
2078 gnutls_assert ();
2079 break;
2082 ret = gnutls_x509_crl_init (crl);
2083 if (ret < 0)
2085 gnutls_assert ();
2086 goto done;
2089 ret = gnutls_x509_crl_import (*crl, &data, GNUTLS_X509_FMT_DER);
2090 if (ret < 0)
2092 gnutls_assert ();
2093 gnutls_x509_crl_deinit (*crl);
2094 goto done;
2096 break;
2098 case GNUTLS_BAG_ENCRYPTED:
2099 /* XXX Bother to recurse one level down? Unlikely to
2100 use the same password anyway. */
2101 case GNUTLS_BAG_EMPTY:
2102 default:
2103 break;
2107 idx++;
2108 gnutls_pkcs12_bag_deinit (bag);
2111 ret = 0;
2113 done:
2114 if (bag)
2115 gnutls_pkcs12_bag_deinit (bag);
2117 return ret;
2121 * gnutls_certificate_set_x509_simple_pkcs12_file:
2122 * @res: is a #gnutls_certificate_credentials_t structure.
2123 * @pkcs12file: filename of file containing PKCS#12 blob.
2124 * @type: is PEM or DER of the @pkcs12file.
2125 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
2127 * This function sets a certificate/private key pair and/or a CRL in
2128 * the gnutls_certificate_credentials_t structure. This function may
2129 * be called more than once (in case multiple keys/certificates exist
2130 * for the server).
2132 * MAC:ed PKCS#12 files are supported. Encrypted PKCS#12 bags are
2133 * supported. Encrypted PKCS#8 private keys are supported. However,
2134 * only password based security, and the same password for all
2135 * operations, are supported.
2137 * PKCS#12 file may contain many keys and/or certificates, and there
2138 * is no way to identify which key/certificate pair you want. You
2139 * should make sure the PKCS#12 file only contain one key/certificate
2140 * pair and/or one CRL.
2142 * It is believed that the limitations of this function is acceptable
2143 * for most usage, and that any more flexibility would introduce
2144 * complexity that would make it harder to use this functionality at
2145 * all.
2147 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
2150 gnutls_certificate_set_x509_simple_pkcs12_file
2151 (gnutls_certificate_credentials_t res, const char *pkcs12file,
2152 gnutls_x509_crt_fmt_t type, const char *password)
2154 gnutls_datum_t p12blob;
2155 size_t size;
2156 int ret;
2158 p12blob.data = read_binary_file (pkcs12file, &size);
2159 p12blob.size = (unsigned int) size;
2160 if (p12blob.data == NULL)
2162 gnutls_assert ();
2163 return GNUTLS_E_FILE_ERROR;
2166 ret =
2167 gnutls_certificate_set_x509_simple_pkcs12_mem (res, &p12blob, type,
2168 password);
2169 free (p12blob.data);
2171 return ret;
2175 * gnutls_certificate_set_x509_simple_pkcs12_mem:
2176 * @res: is a #gnutls_certificate_credentials_t structure.
2177 * @p12blob: the PKCS#12 blob.
2178 * @type: is PEM or DER of the @pkcs12file.
2179 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
2181 * This function sets a certificate/private key pair and/or a CRL in
2182 * the gnutls_certificate_credentials_t structure. This function may
2183 * be called more than once (in case multiple keys/certificates exist
2184 * for the server).
2186 * MAC:ed PKCS#12 files are supported. Encrypted PKCS#12 bags are
2187 * supported. Encrypted PKCS#8 private keys are supported. However,
2188 * only password based security, and the same password for all
2189 * operations, are supported.
2191 * PKCS#12 file may contain many keys and/or certificates, and there
2192 * is no way to identify which key/certificate pair you want. You
2193 * should make sure the PKCS#12 file only contain one key/certificate
2194 * pair and/or one CRL.
2196 * It is believed that the limitations of this function is acceptable
2197 * for most usage, and that any more flexibility would introduce
2198 * complexity that would make it harder to use this functionality at
2199 * all.
2201 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
2203 * Since: 2.8.0
2206 gnutls_certificate_set_x509_simple_pkcs12_mem
2207 (gnutls_certificate_credentials_t res, const gnutls_datum_t * p12blob,
2208 gnutls_x509_crt_fmt_t type, const char *password)
2210 gnutls_pkcs12_t p12;
2211 gnutls_x509_privkey_t key = NULL;
2212 gnutls_x509_crt_t cert = NULL;
2213 gnutls_x509_crl_t crl = NULL;
2214 int ret;
2216 ret = gnutls_pkcs12_init (&p12);
2217 if (ret < 0)
2219 gnutls_assert ();
2220 return ret;
2223 ret = gnutls_pkcs12_import (p12, p12blob, type, 0);
2224 if (ret < 0)
2226 gnutls_assert ();
2227 gnutls_pkcs12_deinit (p12);
2228 return ret;
2231 if (password)
2233 ret = gnutls_pkcs12_verify_mac (p12, password);
2234 if (ret < 0)
2236 gnutls_assert ();
2237 gnutls_pkcs12_deinit (p12);
2238 return ret;
2242 ret = parse_pkcs12 (res, p12, password, &key, &cert, &crl);
2243 gnutls_pkcs12_deinit (p12);
2244 if (ret < 0)
2246 gnutls_assert ();
2247 return ret;
2250 if (key && cert)
2252 ret = gnutls_certificate_set_x509_key (res, &cert, 1, key);
2253 if (ret < 0)
2255 gnutls_assert ();
2256 goto done;
2260 if (crl)
2262 ret = gnutls_certificate_set_x509_crl (res, &crl, 1);
2263 if (ret < 0)
2265 gnutls_assert ();
2266 goto done;
2270 ret = 0;
2272 done:
2273 if (cert)
2274 gnutls_x509_crt_deinit (cert);
2275 if (key)
2276 gnutls_x509_privkey_deinit (key);
2277 if (crl)
2278 gnutls_x509_crl_deinit (crl);
2280 return ret;
2286 * gnutls_certificate_free_crls:
2287 * @sc: is a #gnutls_certificate_credentials_t structure.
2289 * This function will delete all the CRLs associated
2290 * with the given credentials.
2292 void
2293 gnutls_certificate_free_crls (gnutls_certificate_credentials_t sc)
2295 /* do nothing for now */
2296 return;
2299 #endif