Blame lib/cert-cred-x509.c

Packit Service 4684c1
/*
Packit Service 4684c1
 * Copyright (C) 2002-2016 Free Software Foundation, Inc.
Packit Service 4684c1
 * Copyright (C) 2016-2017 Red Hat, Inc.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Author: Nikos Mavrogiannopoulos
Packit Service 4684c1
 *
Packit Service 4684c1
 * This file is part of GnuTLS.
Packit Service 4684c1
 *
Packit Service 4684c1
 * The GnuTLS is free software; you can redistribute it and/or
Packit Service 4684c1
 * modify it under the terms of the GNU Lesser General Public License
Packit Service 4684c1
 * as published by the Free Software Foundation; either version 2.1 of
Packit Service 4684c1
 * the License, or (at your option) any later version.
Packit Service 4684c1
 *
Packit Service 4684c1
 * This library is distributed in the hope that it will be useful, but
Packit Service 4684c1
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 4684c1
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 4684c1
 * Lesser General Public License for more details.
Packit Service 4684c1
 *
Packit Service 4684c1
 * You should have received a copy of the GNU Lesser General Public License
Packit Service 4684c1
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
Packit Service 4684c1
 *
Packit Service 4684c1
 */
Packit Service 4684c1
Packit Service 4684c1
#include "gnutls_int.h"
Packit Service 4684c1
#include "auth.h"
Packit Service 4684c1
#include "errors.h"
Packit Service 4684c1
#include <auth/cert.h>
Packit Service 4684c1
#include "dh.h"
Packit Service 4684c1
#include "num.h"
Packit Service 4684c1
#include "datum.h"
Packit Service 4684c1
#include <pk.h>
Packit Service 4684c1
#include <algorithms.h>
Packit Service 4684c1
#include <global.h>
Packit Service 4684c1
#include <record.h>
Packit Service 4684c1
#include <tls-sig.h>
Packit Service 4684c1
#include <state.h>
Packit Service 4684c1
#include <pk.h>
Packit Service 4684c1
#include "str.h"
Packit Service 4684c1
#include <debug.h>
Packit Service 4684c1
#include <x509_b64.h>
Packit Service 4684c1
#include <x509.h>
Packit Service 4684c1
#include "x509/common.h"
Packit Service 4684c1
#include "x509/x509_int.h"
Packit Service 4684c1
#include <str_array.h>
Packit Service 4684c1
#include <gnutls/x509.h>
Packit Service 4684c1
#include "read-file.h"
Packit Service 4684c1
#include "system-keys.h"
Packit Service 4684c1
#include "urls.h"
Packit Service 4684c1
#include "cert-cred.h"
Packit Service 4684c1
#ifdef _WIN32
Packit Service 4684c1
#include <wincrypt.h>
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
/*
Packit Service 4684c1
 * This file includes functions related to adding certificates and other
Packit Service 4684c1
 * related objects in a certificate credentials structure.
Packit Service 4684c1
 */
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/* Returns the name of the certificate of a null name
Packit Service 4684c1
 */
Packit Service 4684c1
int _gnutls_get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t * names)
Packit Service 4684c1
{
Packit Service 4684c1
	size_t max_size;
Packit Service 4684c1
	int i, ret = 0, ret2;
Packit Service 4684c1
	char name[MAX_CN];
Packit Service 4684c1
	unsigned have_dns_name = 0;
Packit Service 4684c1
Packit Service 4684c1
	for (i = 0; !(ret < 0); i++) {
Packit Service 4684c1
		max_size = sizeof(name);
Packit Service 4684c1
Packit Service 4684c1
		ret =
Packit Service 4684c1
		    gnutls_x509_crt_get_subject_alt_name(crt, i, name,
Packit Service 4684c1
							 &max_size, NULL);
Packit Service 4684c1
		if (ret == GNUTLS_SAN_DNSNAME) {
Packit Service 4684c1
			have_dns_name = 1;
Packit Service 4684c1
Packit Service 4684c1
			ret2 =
Packit Service 4684c1
			    _gnutls_str_array_append_idna(names, name,
Packit Service 4684c1
						  max_size);
Packit Service 4684c1
			if (ret2 < 0) {
Packit Service 4684c1
				_gnutls_str_array_clear(names);
Packit Service 4684c1
				return gnutls_assert_val(ret2);
Packit Service 4684c1
			}
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (have_dns_name == 0) {
Packit Service 4684c1
		max_size = sizeof(name);
Packit Service 4684c1
		ret =
Packit Service 4684c1
		    gnutls_x509_crt_get_dn_by_oid(crt, OID_X520_COMMON_NAME, 0, 0,
Packit Service 4684c1
						  name, &max_size);
Packit Service 4684c1
		if (ret >= 0) {
Packit Service 4684c1
			ret = _gnutls_str_array_append_idna(names, name, max_size);
Packit Service 4684c1
			if (ret < 0) {
Packit Service 4684c1
				_gnutls_str_array_clear(names);
Packit Service 4684c1
				return gnutls_assert_val(ret);
Packit Service 4684c1
			}
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	return 0;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/* Reads a DER encoded certificate list from memory and stores it to a
Packit Service 4684c1
 * gnutls_cert structure. Returns the number of certificates parsed.
Packit Service 4684c1
 */
Packit Service 4684c1
static int
Packit Service 4684c1
parse_der_cert_mem(gnutls_certificate_credentials_t res,
Packit Service 4684c1
		   gnutls_privkey_t key,
Packit Service 4684c1
		   const void *input_cert, int input_cert_size)
Packit Service 4684c1
{
Packit Service 4684c1
	gnutls_datum_t tmp;
Packit Service 4684c1
	gnutls_x509_crt_t crt;
Packit Service 4684c1
	gnutls_pcert_st *ccert;
Packit Service 4684c1
	int ret;
Packit Service 4684c1
	gnutls_str_array_t names;
Packit Service 4684c1
Packit Service 4684c1
	_gnutls_str_array_init(&names);
Packit Service 4684c1
Packit Service 4684c1
	ccert = gnutls_malloc(sizeof(*ccert));
Packit Service 4684c1
	if (ccert == NULL) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return GNUTLS_E_MEMORY_ERROR;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_x509_crt_init(&crt;;
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	tmp.data = (uint8_t *) input_cert;
Packit Service 4684c1
	tmp.size = input_cert_size;
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_x509_crt_import(crt, &tmp, GNUTLS_X509_FMT_DER);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		gnutls_x509_crt_deinit(crt);
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = _gnutls_get_x509_name(crt, &names);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		gnutls_x509_crt_deinit(crt);
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_pcert_import_x509(ccert, crt, 0);
Packit Service 4684c1
	gnutls_x509_crt_deinit(crt);
Packit Service 4684c1
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = _gnutls_certificate_credential_append_keypair(res, key, names, ccert, 1);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
Packit Service 4684c1
      cleanup:
Packit Service 4684c1
	_gnutls_str_array_clear(&names);
Packit Service 4684c1
	gnutls_free(ccert);
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/* Reads a base64 encoded certificate list from memory and stores it to
Packit Service 4684c1
 * a gnutls_cert structure. Returns the number of certificate parsed.
Packit Service 4684c1
 */
Packit Service 4684c1
static int
Packit Service 4684c1
parse_pem_cert_mem(gnutls_certificate_credentials_t res,
Packit Service 4684c1
		   gnutls_privkey_t key,
Packit Service 4684c1
		   const char *input_cert, int input_cert_size)
Packit Service 4684c1
{
Packit Service 4684c1
	int size;
Packit Service 4684c1
	const char *ptr;
Packit Service 4684c1
	gnutls_datum_t tmp;
Packit Service 4684c1
	int ret, count, i;
Packit Service 4684c1
	unsigned ncerts = 0;
Packit Service 4684c1
	gnutls_pcert_st *pcerts = NULL;
Packit Service 4684c1
	gnutls_str_array_t names;
Packit Service 4684c1
	gnutls_x509_crt_t unsorted[DEFAULT_MAX_VERIFY_DEPTH];
Packit Service 4684c1
Packit Service 4684c1
	_gnutls_str_array_init(&names);
Packit Service 4684c1
Packit Service 4684c1
	/* move to the certificate
Packit Service 4684c1
	 */
Packit Service 4684c1
	ptr = memmem(input_cert, input_cert_size,
Packit Service 4684c1
		     PEM_CERT_SEP, sizeof(PEM_CERT_SEP) - 1);
Packit Service 4684c1
	if (ptr == NULL)
Packit Service 4684c1
		ptr = memmem(input_cert, input_cert_size,
Packit Service 4684c1
			     PEM_CERT_SEP2, sizeof(PEM_CERT_SEP2) - 1);
Packit Service 4684c1
Packit Service 4684c1
	if (ptr == NULL) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return GNUTLS_E_BASE64_DECODING_ERROR;
Packit Service 4684c1
	}
Packit Service 4684c1
	size = input_cert_size - (ptr - input_cert);
Packit Service 4684c1
Packit Service 4684c1
	count = 0;
Packit Service 4684c1
Packit Service 4684c1
	do {
Packit Service 4684c1
		tmp.data = (void *) ptr;
Packit Service 4684c1
		tmp.size = size;
Packit Service 4684c1
Packit Service 4684c1
		ret = gnutls_x509_crt_init(&unsorted[count]);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			gnutls_assert();
Packit Service 4684c1
			goto cleanup;
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		ret = gnutls_x509_crt_import(unsorted[count], &tmp, GNUTLS_X509_FMT_PEM);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			gnutls_assert();
Packit Service 4684c1
			goto cleanup;
Packit Service 4684c1
		}
Packit Service 4684c1
		count++;
Packit Service 4684c1
Packit Service 4684c1
		/* now we move ptr after the pem header
Packit Service 4684c1
		 */
Packit Service 4684c1
		ptr++;
Packit Service 4684c1
		size--;
Packit Service 4684c1
Packit Service 4684c1
		/* find the next certificate (if any)
Packit Service 4684c1
		 */
Packit Service 4684c1
Packit Service 4684c1
		if (size > 0) {
Packit Service 4684c1
			char *ptr3;
Packit Service 4684c1
Packit Service 4684c1
			ptr3 =
Packit Service 4684c1
			    memmem(ptr, size, PEM_CERT_SEP,
Packit Service 4684c1
				   sizeof(PEM_CERT_SEP) - 1);
Packit Service 4684c1
			if (ptr3 == NULL)
Packit Service 4684c1
				ptr3 = memmem(ptr, size, PEM_CERT_SEP2,
Packit Service 4684c1
					      sizeof(PEM_CERT_SEP2) - 1);
Packit Service 4684c1
Packit Service 4684c1
			ptr = ptr3;
Packit Service 4684c1
			size = input_cert_size - (ptr - input_cert);
Packit Service 4684c1
		} else
Packit Service 4684c1
			ptr = NULL;
Packit Service 4684c1
Packit Service 4684c1
	}
Packit Service 4684c1
	while (ptr != NULL && count < DEFAULT_MAX_VERIFY_DEPTH);
Packit Service 4684c1
Packit Service 4684c1
	ret =
Packit Service 4684c1
	    _gnutls_get_x509_name(unsorted[0], &names);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	pcerts = gnutls_malloc(sizeof(gnutls_pcert_st) * count);
Packit Service 4684c1
	if (pcerts == NULL) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return GNUTLS_E_MEMORY_ERROR;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ncerts = count;
Packit Service 4684c1
	ret =
Packit Service 4684c1
	    gnutls_pcert_import_x509_list(pcerts, unsorted, &ncerts, GNUTLS_X509_CRT_LIST_SORT);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_free(pcerts);
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret =
Packit Service 4684c1
	    _gnutls_certificate_credential_append_keypair(res, key, names, pcerts, ncerts);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	for (i = 0; i < count; i++)
Packit Service 4684c1
		gnutls_x509_crt_deinit(unsorted[i]);
Packit Service 4684c1
Packit Service 4684c1
	return ncerts;
Packit Service 4684c1
Packit Service 4684c1
      cleanup:
Packit Service 4684c1
	_gnutls_str_array_clear(&names);
Packit Service 4684c1
	for (i = 0; i < count; i++)
Packit Service 4684c1
		gnutls_x509_crt_deinit(unsorted[i]);
Packit Service 4684c1
	if (pcerts) {
Packit Service 4684c1
		for (i = 0; i < count; i++)
Packit Service 4684c1
			gnutls_pcert_deinit(&pcerts[i]);
Packit Service 4684c1
		gnutls_free(pcerts);
Packit Service 4684c1
	}
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/* Reads a DER or PEM certificate from memory
Packit Service 4684c1
 */
Packit Service 4684c1
static int
Packit Service 4684c1
read_cert_mem(gnutls_certificate_credentials_t res,
Packit Service 4684c1
	      gnutls_privkey_t key,
Packit Service 4684c1
	      const void *cert,
Packit Service 4684c1
	      int cert_size, gnutls_x509_crt_fmt_t type)
Packit Service 4684c1
{
Packit Service 4684c1
	int ret;
Packit Service 4684c1
Packit Service 4684c1
	if (type == GNUTLS_X509_FMT_DER)
Packit Service 4684c1
		ret = parse_der_cert_mem(res, key, cert, cert_size);
Packit Service 4684c1
	else
Packit Service 4684c1
		ret = parse_pem_cert_mem(res, key, cert, cert_size);
Packit Service 4684c1
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return ret;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
static int tmp_pin_cb(void *userdata, int attempt, const char *token_url,
Packit Service 4684c1
		      const char *token_label, unsigned int flags,
Packit Service 4684c1
		      char *pin, size_t pin_max)
Packit Service 4684c1
{
Packit Service 4684c1
	const char *tmp_pin = userdata;
Packit Service 4684c1
Packit Service 4684c1
	if (attempt == 0) {
Packit Service 4684c1
		snprintf(pin, pin_max, "%s", tmp_pin);
Packit Service 4684c1
		return 0;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	return -1;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory.  Type
Packit Service 4684c1
 * indicates the certificate format.
Packit Service 4684c1
 *
Packit Service 4684c1
 * It returns the private key read in @rkey.
Packit Service 4684c1
 */
Packit Service 4684c1
int
Packit Service 4684c1
_gnutls_read_key_mem(gnutls_certificate_credentials_t res,
Packit Service 4684c1
	     const void *key, int key_size, gnutls_x509_crt_fmt_t type,
Packit Service 4684c1
	     const char *pass, unsigned int flags,
Packit Service 4684c1
	     gnutls_privkey_t *rkey)
Packit Service 4684c1
{
Packit Service 4684c1
	int ret;
Packit Service 4684c1
	gnutls_datum_t tmp;
Packit Service 4684c1
	gnutls_privkey_t privkey;
Packit Service 4684c1
Packit Service 4684c1
	if (key) {
Packit Service 4684c1
		tmp.data = (uint8_t *) key;
Packit Service 4684c1
		tmp.size = key_size;
Packit Service 4684c1
Packit Service 4684c1
		ret = gnutls_privkey_init(&privkey);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			gnutls_assert();
Packit Service 4684c1
			return ret;
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		if (res->pin.cb) {
Packit Service 4684c1
			gnutls_privkey_set_pin_function(privkey,
Packit Service 4684c1
							res->pin.cb,
Packit Service 4684c1
							res->pin.data);
Packit Service 4684c1
		} else if (pass != NULL) {
Packit Service 4684c1
			snprintf(res->pin_tmp, sizeof(res->pin_tmp), "%s",
Packit Service 4684c1
				 pass);
Packit Service 4684c1
			gnutls_privkey_set_pin_function(privkey,
Packit Service 4684c1
							tmp_pin_cb,
Packit Service 4684c1
							res->pin_tmp);
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		ret =
Packit Service 4684c1
		    gnutls_privkey_import_x509_raw(privkey, &tmp, type,
Packit Service 4684c1
						   pass, flags);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			gnutls_assert();
Packit Service 4684c1
			gnutls_privkey_deinit(privkey);
Packit Service 4684c1
			return ret;
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		*rkey = privkey;
Packit Service 4684c1
	} else {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return GNUTLS_E_INVALID_REQUEST;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	return 0;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/* Reads a private key from a token.
Packit Service 4684c1
 */
Packit Service 4684c1
static int
Packit Service 4684c1
read_key_url(gnutls_certificate_credentials_t res, const char *url, gnutls_privkey_t *rkey)
Packit Service 4684c1
{
Packit Service 4684c1
	int ret;
Packit Service 4684c1
	gnutls_privkey_t pkey = NULL;
Packit Service 4684c1
Packit Service 4684c1
	/* allocate space for the pkey list
Packit Service 4684c1
	 */
Packit Service 4684c1
	ret = gnutls_privkey_init(&pkey);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (res->pin.cb)
Packit Service 4684c1
		gnutls_privkey_set_pin_function(pkey, res->pin.cb,
Packit Service 4684c1
						res->pin.data);
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_privkey_import_url(pkey, url, 0);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	*rkey = pkey;
Packit Service 4684c1
Packit Service 4684c1
	return 0;
Packit Service 4684c1
Packit Service 4684c1
      cleanup:
Packit Service 4684c1
	if (pkey)
Packit Service 4684c1
		gnutls_privkey_deinit(pkey);
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
#define MAX_PKCS11_CERT_CHAIN 8
Packit Service 4684c1
/* Reads a certificate key from a token.
Packit Service 4684c1
 */
Packit Service 4684c1
static int
Packit Service 4684c1
read_cert_url(gnutls_certificate_credentials_t res, gnutls_privkey_t key, const char *url)
Packit Service 4684c1
{
Packit Service 4684c1
	int ret;
Packit Service 4684c1
	gnutls_x509_crt_t crt = NULL;
Packit Service 4684c1
	gnutls_pcert_st *ccert = NULL;
Packit Service 4684c1
	gnutls_str_array_t names;
Packit Service 4684c1
	gnutls_datum_t t = {NULL, 0};
Packit Service 4684c1
	unsigned i, count = 0;
Packit Service 4684c1
Packit Service 4684c1
	_gnutls_str_array_init(&names);
Packit Service 4684c1
Packit Service 4684c1
	ccert = gnutls_malloc(sizeof(*ccert)*MAX_PKCS11_CERT_CHAIN);
Packit Service 4684c1
	if (ccert == NULL) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		ret = GNUTLS_E_MEMORY_ERROR;
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_x509_crt_init(&crt;;
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (res->pin.cb)
Packit Service 4684c1
		gnutls_x509_crt_set_pin_function(crt, res->pin.cb,
Packit Service 4684c1
						 res->pin.data);
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_x509_crt_import_url(crt, url, 0);
Packit Service 4684c1
	if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
Packit Service 4684c1
		ret =
Packit Service 4684c1
		    gnutls_x509_crt_import_url(crt, url,
Packit Service 4684c1
					       GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = _gnutls_get_x509_name(crt, &names);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	/* Try to load the whole certificate chain from the PKCS #11 token */
Packit Service 4684c1
	for (i=0;i
Packit Service 4684c1
		ret = gnutls_x509_crt_check_issuer(crt, crt);
Packit Service 4684c1
		if (i > 0 && ret != 0) {
Packit Service 4684c1
			/* self signed */
Packit Service 4684c1
			break;
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		ret = gnutls_pcert_import_x509(&ccert[i], crt, 0);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			gnutls_assert();
Packit Service 4684c1
			goto cleanup;
Packit Service 4684c1
		}
Packit Service 4684c1
		count++;
Packit Service 4684c1
Packit Service 4684c1
		ret = _gnutls_get_raw_issuer(url, crt, &t, 0);
Packit Service 4684c1
		if (ret < 0)
Packit Service 4684c1
			break;
Packit Service 4684c1
Packit Service 4684c1
		gnutls_x509_crt_deinit(crt);
Packit Service 4684c1
		crt = NULL;
Packit Service 4684c1
		ret = gnutls_x509_crt_init(&crt;;
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			gnutls_assert();
Packit Service 4684c1
			goto cleanup;
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		ret = gnutls_x509_crt_import(crt, &t, GNUTLS_X509_FMT_DER);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			gnutls_assert();
Packit Service 4684c1
			goto cleanup;
Packit Service 4684c1
		}
Packit Service 4684c1
		gnutls_free(t.data);
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = _gnutls_certificate_credential_append_keypair(res, key, names, ccert, count);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (crt != NULL)
Packit Service 4684c1
		gnutls_x509_crt_deinit(crt);
Packit Service 4684c1
Packit Service 4684c1
	return 0;
Packit Service 4684c1
cleanup:
Packit Service 4684c1
	if (crt != NULL)
Packit Service 4684c1
		gnutls_x509_crt_deinit(crt);
Packit Service 4684c1
	gnutls_free(t.data);
Packit Service 4684c1
	_gnutls_str_array_clear(&names);
Packit Service 4684c1
	gnutls_free(ccert);
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/* Reads a certificate file
Packit Service 4684c1
 */
Packit Service 4684c1
static int
Packit Service 4684c1
read_cert_file(gnutls_certificate_credentials_t res,
Packit Service 4684c1
	       gnutls_privkey_t key,
Packit Service 4684c1
	       const char *certfile, gnutls_x509_crt_fmt_t type)
Packit Service 4684c1
{
Packit Service 4684c1
	int ret;
Packit Service 4684c1
	size_t size;
Packit Service 4684c1
	char *data;
Packit Service 4684c1
Packit Service 4684c1
	if (gnutls_url_is_supported(certfile)) {
Packit Service 4684c1
		return read_cert_url(res, key, certfile);
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	data = read_file(certfile, RF_BINARY, &size);
Packit Service 4684c1
Packit Service 4684c1
	if (data == NULL) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return GNUTLS_E_FILE_ERROR;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = read_cert_mem(res, key, data, size, type);
Packit Service 4684c1
	free(data);
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
Packit Service 4684c1
 * stores it).
Packit Service 4684c1
 */
Packit Service 4684c1
int
Packit Service 4684c1
_gnutls_read_key_file(gnutls_certificate_credentials_t res,
Packit Service 4684c1
	      const char *keyfile, gnutls_x509_crt_fmt_t type,
Packit Service 4684c1
	      const char *pass, unsigned int flags,
Packit Service 4684c1
	      gnutls_privkey_t *rkey)
Packit Service 4684c1
{
Packit Service 4684c1
	int ret;
Packit Service 4684c1
	size_t size;
Packit Service 4684c1
	char *data;
Packit Service 4684c1
Packit Service 4684c1
	if (_gnutls_url_is_known(keyfile)) {
Packit Service 4684c1
		if (gnutls_url_is_supported(keyfile)) {
Packit Service 4684c1
			/* if no PIN function is specified, and we have a PIN,
Packit Service 4684c1
			 * specify one */
Packit Service 4684c1
			if (pass != NULL && res->pin.cb == NULL) {
Packit Service 4684c1
				snprintf(res->pin_tmp, sizeof(res->pin_tmp), "%s", pass);
Packit Service 4684c1
				gnutls_certificate_set_pin_function(res, tmp_pin_cb, res->pin_tmp);
Packit Service 4684c1
			}
Packit Service 4684c1
Packit Service 4684c1
			return read_key_url(res, keyfile, rkey);
Packit Service 4684c1
		} else
Packit Service 4684c1
			return
Packit Service 4684c1
			    gnutls_assert_val
Packit Service 4684c1
			    (GNUTLS_E_UNIMPLEMENTED_FEATURE);
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	data = read_file(keyfile, RF_BINARY | RF_SENSITIVE, &size);
Packit Service 4684c1
Packit Service 4684c1
	if (data == NULL) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return GNUTLS_E_FILE_ERROR;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = _gnutls_read_key_mem(res, data, size, type, pass, flags, rkey);
Packit Service 4684c1
	zeroize_key(data, size);
Packit Service 4684c1
	free(data);
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_key_mem:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @cert: contains a certificate list (path) for the specified private key
Packit Service 4684c1
 * @key: is the private key, or %NULL
Packit Service 4684c1
 * @type: is PEM or DER
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function sets a certificate/private key pair in the
Packit Service 4684c1
 * gnutls_certificate_credentials_t type. This function may be called
Packit Service 4684c1
 * more than once, in case multiple keys/certificates exist for the
Packit Service 4684c1
 * server.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
Packit Service 4684c1
 * is supported. This means that certificates intended for signing cannot
Packit Service 4684c1
 * be used for ciphersuites that require encryption.
Packit Service 4684c1
 *
Packit Service 4684c1
 * If the certificate and the private key are given in PEM encoding
Packit Service 4684c1
 * then the strings that hold their values must be null terminated.
Packit Service 4684c1
 *
Packit Service 4684c1
 * The @key may be %NULL if you are using a sign callback, see
Packit Service 4684c1
 * gnutls_sign_callback_set().
Packit Service 4684c1
 *
Packit Service 4684c1
 * Note that, this function by default returns zero on success and a negative value on error.
Packit Service 4684c1
 * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
Packit Service 4684c1
 * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
Packit Service 4684c1
 *
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_set_x509_key_mem(gnutls_certificate_credentials_t res,
Packit Service 4684c1
				    const gnutls_datum_t * cert,
Packit Service 4684c1
				    const gnutls_datum_t * key,
Packit Service 4684c1
				    gnutls_x509_crt_fmt_t type)
Packit Service 4684c1
{
Packit Service 4684c1
	return gnutls_certificate_set_x509_key_mem2(res, cert, key, type,
Packit Service 4684c1
						    NULL, 0);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_key_mem2:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @cert: contains a certificate list (path) for the specified private key
Packit Service 4684c1
 * @key: is the private key, or %NULL
Packit Service 4684c1
 * @type: is PEM or DER
Packit Service 4684c1
 * @pass: is the key's password
Packit Service 4684c1
 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function sets a certificate/private key pair in the
Packit Service 4684c1
 * gnutls_certificate_credentials_t type. This function may be called
Packit Service 4684c1
 * more than once, in case multiple keys/certificates exist for the
Packit Service 4684c1
 * server.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
Packit Service 4684c1
 * is supported. This means that certificates intended for signing cannot
Packit Service 4684c1
 * be used for ciphersuites that require encryption.
Packit Service 4684c1
 *
Packit Service 4684c1
 * If the certificate and the private key are given in PEM encoding
Packit Service 4684c1
 * then the strings that hold their values must be null terminated.
Packit Service 4684c1
 *
Packit Service 4684c1
 * The @key may be %NULL if you are using a sign callback, see
Packit Service 4684c1
 * gnutls_sign_callback_set().
Packit Service 4684c1
 *
Packit Service 4684c1
 * Note that, this function by default returns zero on success and a negative value on error.
Packit Service 4684c1
 * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
Packit Service 4684c1
 * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_set_x509_key_mem2(gnutls_certificate_credentials_t res,
Packit Service 4684c1
				     const gnutls_datum_t * cert,
Packit Service 4684c1
				     const gnutls_datum_t * key,
Packit Service 4684c1
				     gnutls_x509_crt_fmt_t type,
Packit Service 4684c1
				     const char *pass, unsigned int flags)
Packit Service 4684c1
{
Packit Service 4684c1
	int ret;
Packit Service 4684c1
	gnutls_privkey_t rkey;
Packit Service 4684c1
Packit Service 4684c1
	/* this should be first
Packit Service 4684c1
	 */
Packit Service 4684c1
	if ((ret = _gnutls_read_key_mem(res, key ? key->data : NULL,
Packit Service 4684c1
				key ? key->size : 0, type, pass,
Packit Service 4684c1
				flags, &rkey)) < 0)
Packit Service 4684c1
		return ret;
Packit Service 4684c1
Packit Service 4684c1
	if ((ret = read_cert_mem(res, rkey, cert->data, cert->size, type)) < 0) {
Packit Service 4684c1
		gnutls_privkey_deinit(rkey);
Packit Service 4684c1
		return ret;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	res->ncerts++;
Packit Service 4684c1
Packit Service 4684c1
	if (key && (ret = _gnutls_check_key_cert_match(res)) < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return ret;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	CRED_RET_SUCCESS(res);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_key:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @cert_list: contains a certificate list (path) for the specified private key
Packit Service 4684c1
 * @cert_list_size: holds the size of the certificate list
Packit Service 4684c1
 * @key: is a #gnutls_x509_privkey_t key
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function sets a certificate/private key pair in the
Packit Service 4684c1
 * gnutls_certificate_credentials_t type.  This function may be
Packit Service 4684c1
 * called more than once, in case multiple keys/certificates exist for
Packit Service 4684c1
 * the server.  For clients that wants to send more than their own end
Packit Service 4684c1
 * entity certificate (e.g., also an intermediate CA cert) then put
Packit Service 4684c1
 * the certificate chain in @cert_list.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Note that the certificates and keys provided, can be safely deinitialized
Packit Service 4684c1
 * after this function is called.
Packit Service 4684c1
 *
Packit Service 4684c1
 * If that function fails to load the @res type is at an undefined state, it must
Packit Service 4684c1
 * not be reused to load other keys or certificates.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Note that, this function by default returns zero on success and a negative value on error.
Packit Service 4684c1
 * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
Packit Service 4684c1
 * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 2.4.0
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_set_x509_key(gnutls_certificate_credentials_t res,
Packit Service 4684c1
				gnutls_x509_crt_t * cert_list,
Packit Service 4684c1
				int cert_list_size,
Packit Service 4684c1
				gnutls_x509_privkey_t key)
Packit Service 4684c1
{
Packit Service 4684c1
	int ret;
Packit Service 4684c1
	gnutls_privkey_t pkey;
Packit Service 4684c1
	gnutls_pcert_st *pcerts = NULL;
Packit Service 4684c1
	gnutls_str_array_t names;
Packit Service 4684c1
Packit Service 4684c1
	_gnutls_str_array_init(&names);
Packit Service 4684c1
Packit Service 4684c1
	/* this should be first
Packit Service 4684c1
	 */
Packit Service 4684c1
	ret = gnutls_privkey_init(&pkey);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return ret;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (res->pin.cb)
Packit Service 4684c1
		gnutls_privkey_set_pin_function(pkey, res->pin.cb,
Packit Service 4684c1
						res->pin.data);
Packit Service 4684c1
Packit Service 4684c1
	ret =
Packit Service 4684c1
	    gnutls_privkey_import_x509(pkey, key,
Packit Service 4684c1
				       GNUTLS_PRIVKEY_IMPORT_COPY);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return ret;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	/* load certificates */
Packit Service 4684c1
	pcerts = gnutls_malloc(sizeof(gnutls_pcert_st) * cert_list_size);
Packit Service 4684c1
	if (pcerts == NULL) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return GNUTLS_E_MEMORY_ERROR;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = _gnutls_get_x509_name(cert_list[0], &names);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret =
Packit Service 4684c1
		gnutls_pcert_import_x509_list(pcerts, cert_list, (unsigned int*)&cert_list_size,
Packit Service 4684c1
					      GNUTLS_X509_CRT_LIST_SORT);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret =
Packit Service 4684c1
	    _gnutls_certificate_credential_append_keypair(res, pkey, names, pcerts,
Packit Service 4684c1
						   cert_list_size);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	res->ncerts++;
Packit Service 4684c1
Packit Service 4684c1
	/* after this point we do not deinitialize anything on failure to avoid
Packit Service 4684c1
	 * double freeing. We intentionally keep everything as the credentials state
Packit Service 4684c1
	 * is documented to be on undefined state. */
Packit Service 4684c1
	if ((ret = _gnutls_check_key_cert_match(res)) < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return ret;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	CRED_RET_SUCCESS(res);
Packit Service 4684c1
Packit Service 4684c1
      cleanup:
Packit Service 4684c1
	gnutls_free(pcerts);
Packit Service 4684c1
	_gnutls_str_array_clear(&names);
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_get_x509_key:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @index: The index of the key to obtain.
Packit Service 4684c1
 * @key: Location to store the key.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Obtains a X.509 private key that has been stored in @res with one of
Packit Service 4684c1
 * gnutls_certificate_set_x509_key(), gnutls_certificate_set_key(),
Packit Service 4684c1
 * gnutls_certificate_set_x509_key_file(),
Packit Service 4684c1
 * gnutls_certificate_set_x509_key_file2(),
Packit Service 4684c1
 * gnutls_certificate_set_x509_key_mem(), or
Packit Service 4684c1
 * gnutls_certificate_set_x509_key_mem2(). The returned key must be deallocated
Packit Service 4684c1
 * with gnutls_x509_privkey_deinit() when no longer needed.
Packit Service 4684c1
 *
Packit Service 4684c1
 * The @index matches the return value of gnutls_certificate_set_x509_key() and friends
Packit Service 4684c1
 * functions, when the %GNUTLS_CERTIFICATE_API_V2 flag is set.
Packit Service 4684c1
 *
Packit Service 4684c1
 * If there is no key with the given index,
Packit Service 4684c1
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned. If the key with the
Packit Service 4684c1
 * given index is not a X.509 key, %GNUTLS_E_INVALID_REQUEST is returned.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 3.4.0
Packit Service 4684c1
 */
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_get_x509_key(gnutls_certificate_credentials_t res,
Packit Service 4684c1
				unsigned index,
Packit Service 4684c1
				gnutls_x509_privkey_t *key)
Packit Service 4684c1
{
Packit Service 4684c1
	if (index >= res->ncerts) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	return gnutls_privkey_export_x509(res->certs[index].pkey, key);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_get_x509_crt:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @index: The index of the certificate list to obtain.
Packit Service 4684c1
 * @crt_list: Where to store the certificate list.
Packit Service 4684c1
 * @crt_list_size: Will hold the number of certificates.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Obtains a X.509 certificate list that has been stored in @res with one of
Packit Service 4684c1
 * gnutls_certificate_set_x509_key(), gnutls_certificate_set_key(),
Packit Service 4684c1
 * gnutls_certificate_set_x509_key_file(),
Packit Service 4684c1
 * gnutls_certificate_set_x509_key_file2(),
Packit Service 4684c1
 * gnutls_certificate_set_x509_key_mem(), or
Packit Service 4684c1
 * gnutls_certificate_set_x509_key_mem2(). Each certificate in the returned
Packit Service 4684c1
 * certificate list must be deallocated with gnutls_x509_crt_deinit(), and the
Packit Service 4684c1
 * list itself must be freed with gnutls_free().
Packit Service 4684c1
 *
Packit Service 4684c1
 * The @index matches the return value of gnutls_certificate_set_x509_key() and friends
Packit Service 4684c1
 * functions, when the %GNUTLS_CERTIFICATE_API_V2 flag is set.
Packit Service 4684c1
 *
Packit Service 4684c1
 * If there is no certificate with the given index,
Packit Service 4684c1
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned. If the certificate
Packit Service 4684c1
 * with the given index is not a X.509 certificate, %GNUTLS_E_INVALID_REQUEST
Packit Service 4684c1
 * is returned. The returned certificates must be deinitialized after
Packit Service 4684c1
 * use, and the @crt_list pointer must be freed using gnutls_free().
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 3.4.0
Packit Service 4684c1
 */
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_get_x509_crt(gnutls_certificate_credentials_t res,
Packit Service 4684c1
				unsigned index,
Packit Service 4684c1
				gnutls_x509_crt_t **crt_list,
Packit Service 4684c1
				unsigned *crt_list_size)
Packit Service 4684c1
{
Packit Service 4684c1
	int ret;
Packit Service 4684c1
	unsigned i;
Packit Service 4684c1
Packit Service 4684c1
	if (index >= res->ncerts) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	*crt_list_size = res->certs[index].cert_list_length;
Packit Service 4684c1
	*crt_list = gnutls_malloc(
Packit Service 4684c1
		res->certs[index].cert_list_length * sizeof (gnutls_x509_crt_t));
Packit Service 4684c1
	if (*crt_list == NULL) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return GNUTLS_E_MEMORY_ERROR;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	for (i = 0; i < res->certs[index].cert_list_length; ++i) {
Packit Service 4684c1
		ret = gnutls_pcert_export_x509(&res->certs[index].cert_list[i], &(*crt_list)[i]);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			while (i--)
Packit Service 4684c1
				gnutls_x509_crt_deinit((*crt_list)[i]);
Packit Service 4684c1
			gnutls_free(*crt_list);
Packit Service 4684c1
Packit Service 4684c1
			return gnutls_assert_val(ret);
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	return 0;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_trust_list:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @tlist: is a #gnutls_x509_trust_list_t type
Packit Service 4684c1
 * @flags: must be zero
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function sets a trust list in the gnutls_certificate_credentials_t type.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Note that the @tlist will become part of the credentials
Packit Service 4684c1
 * structure and must not be deallocated. It will be automatically deallocated
Packit Service 4684c1
 * when the @res structure is deinitialized.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 3.2.2
Packit Service 4684c1
 **/
Packit Service 4684c1
void
Packit Service 4684c1
gnutls_certificate_set_trust_list(gnutls_certificate_credentials_t res,
Packit Service 4684c1
				  gnutls_x509_trust_list_t tlist,
Packit Service 4684c1
				  unsigned flags)
Packit Service 4684c1
{
Packit Service 4684c1
	gnutls_x509_trust_list_deinit(res->tlist, 1);
Packit Service 4684c1
Packit Service 4684c1
	res->tlist = tlist;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_get_trust_list:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @tlist: Location where to store the trust list.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Obtains the list of trusted certificates stored in @res and writes a
Packit Service 4684c1
 * pointer to it to the location @tlist. The pointer will point to memory
Packit Service 4684c1
 * internal to @res, and must not be deinitialized. It will be automatically
Packit Service 4684c1
 * deallocated when the @res structure is deinitialized.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 3.4.0
Packit Service 4684c1
 **/
Packit Service 4684c1
void
Packit Service 4684c1
gnutls_certificate_get_trust_list(gnutls_certificate_credentials_t res,
Packit Service 4684c1
				  gnutls_x509_trust_list_t *tlist)
Packit Service 4684c1
{
Packit Service 4684c1
	*tlist = res->tlist;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_key_file:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @certfile: is a file that containing the certificate list (path) for
Packit Service 4684c1
 *   the specified private key, in PKCS7 format, or a list of certificates
Packit Service 4684c1
 * @keyfile: is a file that contains the private key
Packit Service 4684c1
 * @type: is PEM or DER
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function sets a certificate/private key pair in the
Packit Service 4684c1
 * gnutls_certificate_credentials_t type.  This function may be
Packit Service 4684c1
 * called more than once, in case multiple keys/certificates exist for
Packit Service 4684c1
 * the server.  For clients that need to send more than its own end
Packit Service 4684c1
 * entity certificate, e.g., also an intermediate CA cert, then the
Packit Service 4684c1
 * @certfile must contain the ordered certificate chain.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Note that the names in the certificate provided will be considered
Packit Service 4684c1
 * when selecting the appropriate certificate to use (in case of multiple
Packit Service 4684c1
 * certificate/key pairs).
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function can also accept URLs at @keyfile and @certfile. In that case it
Packit Service 4684c1
 * will use the private key and certificate indicated by the URLs. Note
Packit Service 4684c1
 * that the supported URLs are the ones indicated by gnutls_url_is_supported().
Packit Service 4684c1
 *
Packit Service 4684c1
 * In case the @certfile is provided as a PKCS #11 URL, then the certificate, and its
Packit Service 4684c1
 * present issuers in the token are imported (i.e., forming the required trust chain).
Packit Service 4684c1
 *
Packit Service 4684c1
 * If that function fails to load the @res structure is at an undefined state, it must
Packit Service 4684c1
 * not be reused to load other keys or certificates.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Note that, this function by default returns zero on success and a negative value on error.
Packit Service 4684c1
 * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
Packit Service 4684c1
 * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 3.1.11
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_set_x509_key_file(gnutls_certificate_credentials_t res,
Packit Service 4684c1
				     const char *certfile,
Packit Service 4684c1
				     const char *keyfile,
Packit Service 4684c1
				     gnutls_x509_crt_fmt_t type)
Packit Service 4684c1
{
Packit Service 4684c1
	return gnutls_certificate_set_x509_key_file2(res, certfile,
Packit Service 4684c1
						     keyfile, type, NULL,
Packit Service 4684c1
						     0);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_key_file2:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @certfile: is a file that containing the certificate list (path) for
Packit Service 4684c1
 *   the specified private key, in PKCS7 format, or a list of certificates
Packit Service 4684c1
 * @keyfile: is a file that contains the private key
Packit Service 4684c1
 * @type: is PEM or DER
Packit Service 4684c1
 * @pass: is the password of the key
Packit Service 4684c1
 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function sets a certificate/private key pair in the
Packit Service 4684c1
 * gnutls_certificate_credentials_t type.  This function may be
Packit Service 4684c1
 * called more than once, in case multiple keys/certificates exist for
Packit Service 4684c1
 * the server.  For clients that need to send more than its own end
Packit Service 4684c1
 * entity certificate, e.g., also an intermediate CA cert, then the
Packit Service 4684c1
 * @certfile must contain the ordered certificate chain.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Note that the names in the certificate provided will be considered
Packit Service 4684c1
 * when selecting the appropriate certificate to use (in case of multiple
Packit Service 4684c1
 * certificate/key pairs).
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function can also accept URLs at @keyfile and @certfile. In that case it
Packit Service 4684c1
 * will use the private key and certificate indicated by the URLs. Note
Packit Service 4684c1
 * that the supported URLs are the ones indicated by gnutls_url_is_supported().
Packit Service 4684c1
 * Before GnuTLS 3.4.0 when a URL was specified, the @pass part was ignored and a
Packit Service 4684c1
 * PIN callback had to be registered, this is no longer the case in current releases.
Packit Service 4684c1
 *
Packit Service 4684c1
 * In case the @certfile is provided as a PKCS #11 URL, then the certificate, and its
Packit Service 4684c1
 * present issuers in the token are imported (i.e., forming the required trust chain).
Packit Service 4684c1
 *
Packit Service 4684c1
 * If that function fails to load the @res structure is at an undefined state, it must
Packit Service 4684c1
 * not be reused to load other keys or certificates.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Note that, this function by default returns zero on success and a negative value on error.
Packit Service 4684c1
 * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
Packit Service 4684c1
 * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
Packit Service 4684c1
 *
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_set_x509_key_file2(gnutls_certificate_credentials_t res,
Packit Service 4684c1
				      const char *certfile,
Packit Service 4684c1
				      const char *keyfile,
Packit Service 4684c1
				      gnutls_x509_crt_fmt_t type,
Packit Service 4684c1
				      const char *pass, unsigned int flags)
Packit Service 4684c1
{
Packit Service 4684c1
	int ret;
Packit Service 4684c1
	gnutls_privkey_t rkey;
Packit Service 4684c1
Packit Service 4684c1
	/* this should be first
Packit Service 4684c1
	 */
Packit Service 4684c1
	if ((ret = _gnutls_read_key_file(res, keyfile, type, pass, flags, &rkey)) < 0)
Packit Service 4684c1
		return ret;
Packit Service 4684c1
Packit Service 4684c1
	if ((ret = read_cert_file(res, rkey, certfile, type)) < 0) {
Packit Service 4684c1
		gnutls_privkey_deinit(rkey);
Packit Service 4684c1
		return ret;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	res->ncerts++;
Packit Service 4684c1
Packit Service 4684c1
	if ((ret = _gnutls_check_key_cert_match(res)) < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return ret;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	CRED_RET_SUCCESS(res);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_trust_mem:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @ca: is a list of trusted CAs or a DER certificate
Packit Service 4684c1
 * @type: is DER or PEM
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function adds the trusted CAs in order to verify client or
Packit Service 4684c1
 * server certificates. In case of a client this is not required to be
Packit Service 4684c1
 * called if the certificates are not verified using
Packit Service 4684c1
 * gnutls_certificate_verify_peers2().  This function may be called
Packit Service 4684c1
 * multiple times.
Packit Service 4684c1
 *
Packit Service 4684c1
 * In case of a server the CAs set here will be sent to the client if
Packit Service 4684c1
 * a certificate request is sent. This can be disabled using
Packit Service 4684c1
 * gnutls_certificate_send_x509_rdn_sequence().
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: the number of certificates processed or a negative error code
Packit Service 4684c1
 * on error.
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_set_x509_trust_mem(gnutls_certificate_credentials_t res,
Packit Service 4684c1
				      const gnutls_datum_t * ca,
Packit Service 4684c1
				      gnutls_x509_crt_fmt_t type)
Packit Service 4684c1
{
Packit Service 4684c1
int ret;
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_x509_trust_list_add_trust_mem(res->tlist, ca, NULL,
Packit Service 4684c1
					type, GNUTLS_TL_USE_IN_TLS, 0);
Packit Service 4684c1
	if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
Packit Service 4684c1
		return 0;
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_trust:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @ca_list: is a list of trusted CAs
Packit Service 4684c1
 * @ca_list_size: holds the size of the CA list
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function adds the trusted CAs in order to verify client
Packit Service 4684c1
 * or server certificates. In case of a client this is not required
Packit Service 4684c1
 * to be called if the certificates are not verified using
Packit Service 4684c1
 * gnutls_certificate_verify_peers2().
Packit Service 4684c1
 * This function may be called multiple times.
Packit Service 4684c1
 *
Packit Service 4684c1
 * In case of a server the CAs set here will be sent to the client if
Packit Service 4684c1
 * a certificate request is sent. This can be disabled using
Packit Service 4684c1
 * gnutls_certificate_send_x509_rdn_sequence().
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: the number of certificates processed or a negative error code
Packit Service 4684c1
 * on error.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 2.4.0
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_set_x509_trust(gnutls_certificate_credentials_t res,
Packit Service 4684c1
				  gnutls_x509_crt_t * ca_list,
Packit Service 4684c1
				  int ca_list_size)
Packit Service 4684c1
{
Packit Service 4684c1
	int ret, i, j;
Packit Service 4684c1
	gnutls_x509_crt_t *new_list = gnutls_malloc(ca_list_size * sizeof(gnutls_x509_crt_t));
Packit Service 4684c1
Packit Service 4684c1
	if (!new_list)
Packit Service 4684c1
		return GNUTLS_E_MEMORY_ERROR;
Packit Service 4684c1
Packit Service 4684c1
	for (i = 0; i < ca_list_size; i++) {
Packit Service 4684c1
		ret = gnutls_x509_crt_init(&new_list[i]);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			gnutls_assert();
Packit Service 4684c1
			goto cleanup;
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		ret = _gnutls_x509_crt_cpy(new_list[i], ca_list[i]);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			gnutls_assert();
Packit Service 4684c1
			goto cleanup;
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret =
Packit Service 4684c1
	    gnutls_x509_trust_list_add_cas(res->tlist, new_list,
Packit Service 4684c1
					   ca_list_size, GNUTLS_TL_USE_IN_TLS);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	gnutls_free(new_list);
Packit Service 4684c1
	return ret;
Packit Service 4684c1
Packit Service 4684c1
      cleanup:
Packit Service 4684c1
	for (j = 0; j < i; j++)
Packit Service 4684c1
		gnutls_x509_crt_deinit(new_list[j]);
Packit Service 4684c1
	gnutls_free(new_list);
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_trust_file:
Packit Service 4684c1
 * @cred: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @cafile: is a file containing the list of trusted CAs (DER or PEM list)
Packit Service 4684c1
 * @type: is PEM or DER
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function adds the trusted CAs in order to verify client or
Packit Service 4684c1
 * server certificates. In case of a client this is not required to
Packit Service 4684c1
 * be called if the certificates are not verified using
Packit Service 4684c1
 * gnutls_certificate_verify_peers2().  This function may be called
Packit Service 4684c1
 * multiple times.
Packit Service 4684c1
 *
Packit Service 4684c1
 * In case of a server the names of the CAs set here will be sent to
Packit Service 4684c1
 * the client if a certificate request is sent. This can be disabled
Packit Service 4684c1
 * using gnutls_certificate_send_x509_rdn_sequence().
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function can also accept URLs. In that case it
Packit Service 4684c1
 * will import all certificates that are marked as trusted. Note
Packit Service 4684c1
 * that the supported URLs are the ones indicated by gnutls_url_is_supported().
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: the number of certificates processed
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_set_x509_trust_file(gnutls_certificate_credentials_t
Packit Service 4684c1
				       cred, const char *cafile,
Packit Service 4684c1
				       gnutls_x509_crt_fmt_t type)
Packit Service 4684c1
{
Packit Service 4684c1
int ret;
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_x509_trust_list_add_trust_file(cred->tlist, cafile, NULL,
Packit Service 4684c1
						type, GNUTLS_TL_USE_IN_TLS, 0);
Packit Service 4684c1
	if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
Packit Service 4684c1
		return 0;
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_trust_dir:
Packit Service 4684c1
 * @cred: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @ca_dir: is a directory containing the list of trusted CAs (DER or PEM list)
Packit Service 4684c1
 * @type: is PEM or DER
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function adds the trusted CAs present in the directory in order to
Packit Service 4684c1
 * verify client or server certificates. This function is identical
Packit Service 4684c1
 * to gnutls_certificate_set_x509_trust_file() but loads all certificates
Packit Service 4684c1
 * in a directory.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: the number of certificates processed
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 3.3.6
Packit Service 4684c1
 *
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_set_x509_trust_dir(gnutls_certificate_credentials_t cred,
Packit Service 4684c1
				      const char *ca_dir,
Packit Service 4684c1
				      gnutls_x509_crt_fmt_t type)
Packit Service 4684c1
{
Packit Service 4684c1
int ret;
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_x509_trust_list_add_trust_dir(cred->tlist, ca_dir, NULL,
Packit Service 4684c1
						type, GNUTLS_TL_USE_IN_TLS, 0);
Packit Service 4684c1
	if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
Packit Service 4684c1
		return 0;
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_system_trust:
Packit Service 4684c1
 * @cred: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function adds the system's default trusted CAs in order to
Packit Service 4684c1
 * verify client or server certificates.
Packit Service 4684c1
 *
Packit Service 4684c1
 * In the case the system is currently unsupported %GNUTLS_E_UNIMPLEMENTED_FEATURE
Packit Service 4684c1
 * is returned.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: the number of certificates processed or a negative error code
Packit Service 4684c1
 * on error.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 3.0.20
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_set_x509_system_trust(gnutls_certificate_credentials_t
Packit Service 4684c1
					 cred)
Packit Service 4684c1
{
Packit Service 4684c1
	return gnutls_x509_trust_list_add_system_trust(cred->tlist,
Packit Service 4684c1
					GNUTLS_TL_USE_IN_TLS, 0);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_crl_mem:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @CRL: is a list of trusted CRLs. They should have been verified before.
Packit Service 4684c1
 * @type: is DER or PEM
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function adds the trusted CRLs in order to verify client or
Packit Service 4684c1
 * server certificates.  In case of a client this is not required to
Packit Service 4684c1
 * be called if the certificates are not verified using
Packit Service 4684c1
 * gnutls_certificate_verify_peers2().  This function may be called
Packit Service 4684c1
 * multiple times.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: number of CRLs processed, or a negative error code on error.
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_set_x509_crl_mem(gnutls_certificate_credentials_t res,
Packit Service 4684c1
				    const gnutls_datum_t * CRL,
Packit Service 4684c1
				    gnutls_x509_crt_fmt_t type)
Packit Service 4684c1
{
Packit Service 4684c1
	unsigned flags = GNUTLS_TL_USE_IN_TLS;
Packit Service 4684c1
	int ret;
Packit Service 4684c1
Packit Service 4684c1
	if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS)
Packit Service 4684c1
		flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL;
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_x509_trust_list_add_trust_mem(res->tlist, NULL, CRL,
Packit Service 4684c1
					type, flags, 0);
Packit Service 4684c1
	if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
Packit Service 4684c1
		return 0;
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_crl:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @crl_list: is a list of trusted CRLs. They should have been verified before.
Packit Service 4684c1
 * @crl_list_size: holds the size of the crl_list
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function adds the trusted CRLs in order to verify client or
Packit Service 4684c1
 * server certificates.  In case of a client this is not required to
Packit Service 4684c1
 * be called if the certificates are not verified using
Packit Service 4684c1
 * gnutls_certificate_verify_peers2().  This function may be called
Packit Service 4684c1
 * multiple times.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: number of CRLs processed, or a negative error code on error.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 2.4.0
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_set_x509_crl(gnutls_certificate_credentials_t res,
Packit Service 4684c1
				gnutls_x509_crl_t * crl_list,
Packit Service 4684c1
				int crl_list_size)
Packit Service 4684c1
{
Packit Service 4684c1
	int ret, i, j;
Packit Service 4684c1
	gnutls_x509_crl_t *new_crl = gnutls_malloc(crl_list_size * sizeof(gnutls_x509_crl_t));
Packit Service 4684c1
	unsigned flags = GNUTLS_TL_USE_IN_TLS;
Packit Service 4684c1
Packit Service 4684c1
	if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS)
Packit Service 4684c1
		flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL;
Packit Service 4684c1
Packit Service 4684c1
	if (!new_crl)
Packit Service 4684c1
		return GNUTLS_E_MEMORY_ERROR;
Packit Service 4684c1
Packit Service 4684c1
	for (i = 0; i < crl_list_size; i++) {
Packit Service 4684c1
		ret = gnutls_x509_crl_init(&new_crl[i]);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			gnutls_assert();
Packit Service 4684c1
			goto cleanup;
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		ret = _gnutls_x509_crl_cpy(new_crl[i], crl_list[i]);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			gnutls_assert();
Packit Service 4684c1
			goto cleanup;
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret =
Packit Service 4684c1
	    gnutls_x509_trust_list_add_crls(res->tlist, new_crl,
Packit Service 4684c1
				    crl_list_size, flags, 0);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		goto cleanup;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	free(new_crl);
Packit Service 4684c1
	return ret;
Packit Service 4684c1
Packit Service 4684c1
      cleanup:
Packit Service 4684c1
	for (j = 0; j < i; j++)
Packit Service 4684c1
		gnutls_x509_crl_deinit(new_crl[j]);
Packit Service 4684c1
	free(new_crl);
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_crl_file:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
Packit Service 4684c1
 * @type: is PEM or DER
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function adds the trusted CRLs in order to verify client or server
Packit Service 4684c1
 * certificates.  In case of a client this is not required
Packit Service 4684c1
 * to be called if the certificates are not verified using
Packit Service 4684c1
 * gnutls_certificate_verify_peers2().
Packit Service 4684c1
 * This function may be called multiple times.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: number of CRLs processed or a negative error code on error.
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
gnutls_certificate_set_x509_crl_file(gnutls_certificate_credentials_t res,
Packit Service 4684c1
				     const char *crlfile,
Packit Service 4684c1
				     gnutls_x509_crt_fmt_t type)
Packit Service 4684c1
{
Packit Service 4684c1
	int ret;
Packit Service 4684c1
	unsigned flags = GNUTLS_TL_USE_IN_TLS;
Packit Service 4684c1
Packit Service 4684c1
	if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS)
Packit Service 4684c1
		flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL;
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_x509_trust_list_add_trust_file(res->tlist, NULL, crlfile,
Packit Service 4684c1
						type, flags, 0);
Packit Service 4684c1
	if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
Packit Service 4684c1
		return 0;
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
#include <gnutls/pkcs12.h>
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_simple_pkcs12_file:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @pkcs12file: filename of file containing PKCS#12 blob.
Packit Service 4684c1
 * @type: is PEM or DER of the @pkcs12file.
Packit Service 4684c1
 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function sets a certificate/private key pair and/or a CRL in
Packit Service 4684c1
 * the gnutls_certificate_credentials_t type.  This function may
Packit Service 4684c1
 * be called more than once (in case multiple keys/certificates exist
Packit Service 4684c1
 * for the server).
Packit Service 4684c1
 *
Packit Service 4684c1
 * PKCS#12 files with a MAC, encrypted bags and PKCS #8
Packit Service 4684c1
 * private keys are supported. However,
Packit Service 4684c1
 * only password based security, and the same password for all
Packit Service 4684c1
 * operations, are supported.
Packit Service 4684c1
 *
Packit Service 4684c1
 * PKCS#12 file may contain many keys and/or certificates, and this
Packit Service 4684c1
 * function will try to auto-detect based on the key ID the certificate
Packit Service 4684c1
 * and key pair to use. If the PKCS#12 file contain the issuer of
Packit Service 4684c1
 * the selected certificate, it will be appended to the certificate
Packit Service 4684c1
 * to form a chain.
Packit Service 4684c1
 *
Packit Service 4684c1
 * If more than one private keys are stored in the PKCS#12 file,
Packit Service 4684c1
 * then only one key will be read (and it is undefined which one).
Packit Service 4684c1
 *
Packit Service 4684c1
 * It is believed that the limitations of this function is acceptable
Packit Service 4684c1
 * for most usage, and that any more flexibility would introduce
Packit Service 4684c1
 * complexity that would make it harder to use this functionality at
Packit Service 4684c1
 * all.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Note that, this function by default returns zero on success and a negative value on error.
Packit Service 4684c1
 * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
Packit Service 4684c1
 * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
Packit Service 4684c1
 *
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
 gnutls_certificate_set_x509_simple_pkcs12_file
Packit Service 4684c1
    (gnutls_certificate_credentials_t res, const char *pkcs12file,
Packit Service 4684c1
     gnutls_x509_crt_fmt_t type, const char *password) {
Packit Service 4684c1
	gnutls_datum_t p12blob;
Packit Service 4684c1
	size_t size;
Packit Service 4684c1
	int ret;
Packit Service 4684c1
Packit Service 4684c1
	p12blob.data = (void *) read_file(pkcs12file, RF_BINARY | RF_SENSITIVE,
Packit Service 4684c1
					  &size);
Packit Service 4684c1
	p12blob.size = (unsigned int) size;
Packit Service 4684c1
	if (p12blob.data == NULL) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return GNUTLS_E_FILE_ERROR;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret =
Packit Service 4684c1
	    gnutls_certificate_set_x509_simple_pkcs12_mem(res, &p12blob,
Packit Service 4684c1
							  type, password);
Packit Service 4684c1
	zeroize_key(p12blob.data, p12blob.size);
Packit Service 4684c1
	free(p12blob.data);
Packit Service 4684c1
	p12blob.size = 0;
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_set_x509_simple_pkcs12_mem:
Packit Service 4684c1
 * @res: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @p12blob: the PKCS#12 blob.
Packit Service 4684c1
 * @type: is PEM or DER of the @pkcs12file.
Packit Service 4684c1
 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function sets a certificate/private key pair and/or a CRL in
Packit Service 4684c1
 * the gnutls_certificate_credentials_t type.  This function may
Packit Service 4684c1
 * be called more than once (in case multiple keys/certificates exist
Packit Service 4684c1
 * for the server).
Packit Service 4684c1
 *
Packit Service 4684c1
 * Encrypted PKCS#12 bags and PKCS#8 private keys are supported.  However,
Packit Service 4684c1
 * only password based security, and the same password for all
Packit Service 4684c1
 * operations, are supported.
Packit Service 4684c1
 *
Packit Service 4684c1
 * PKCS#12 file may contain many keys and/or certificates, and this
Packit Service 4684c1
 * function will try to auto-detect based on the key ID the certificate
Packit Service 4684c1
 * and key pair to use. If the PKCS#12 file contain the issuer of
Packit Service 4684c1
 * the selected certificate, it will be appended to the certificate
Packit Service 4684c1
 * to form a chain.
Packit Service 4684c1
 *
Packit Service 4684c1
 * If more than one private keys are stored in the PKCS#12 file,
Packit Service 4684c1
 * then only one key will be read (and it is undefined which one).
Packit Service 4684c1
 *
Packit Service 4684c1
 * It is believed that the limitations of this function is acceptable
Packit Service 4684c1
 * for most usage, and that any more flexibility would introduce
Packit Service 4684c1
 * complexity that would make it harder to use this functionality at
Packit Service 4684c1
 * all.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Note that, this function by default returns zero on success and a negative value on error.
Packit Service 4684c1
 * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
Packit Service 4684c1
 * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 2.8.0
Packit Service 4684c1
 **/
Packit Service 4684c1
int
Packit Service 4684c1
 gnutls_certificate_set_x509_simple_pkcs12_mem
Packit Service 4684c1
    (gnutls_certificate_credentials_t res, const gnutls_datum_t * p12blob,
Packit Service 4684c1
     gnutls_x509_crt_fmt_t type, const char *password) {
Packit Service 4684c1
	gnutls_pkcs12_t p12;
Packit Service 4684c1
	gnutls_x509_privkey_t key = NULL;
Packit Service 4684c1
	gnutls_x509_crt_t *chain = NULL;
Packit Service 4684c1
	gnutls_x509_crl_t crl = NULL;
Packit Service 4684c1
	unsigned int chain_size = 0, i;
Packit Service 4684c1
	int ret, idx;
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_pkcs12_init(&p12);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return ret;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret = gnutls_pkcs12_import(p12, p12blob, type, 0);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		gnutls_pkcs12_deinit(p12);
Packit Service 4684c1
		return ret;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (password) {
Packit Service 4684c1
		ret = gnutls_pkcs12_verify_mac(p12, password);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			gnutls_assert();
Packit Service 4684c1
			gnutls_pkcs12_deinit(p12);
Packit Service 4684c1
			return ret;
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	ret =
Packit Service 4684c1
	    gnutls_pkcs12_simple_parse(p12, password, &key, &chain,
Packit Service 4684c1
				       &chain_size, NULL, NULL, &crl, 0);
Packit Service 4684c1
	gnutls_pkcs12_deinit(p12);
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		return ret;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (key && chain) {
Packit Service 4684c1
		ret =
Packit Service 4684c1
		    gnutls_certificate_set_x509_key(res, chain, chain_size,
Packit Service 4684c1
						    key);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			gnutls_assert();
Packit Service 4684c1
			goto done;
Packit Service 4684c1
		}
Packit Service 4684c1
Packit Service 4684c1
		idx = ret;
Packit Service 4684c1
	} else {
Packit Service 4684c1
		gnutls_assert();
Packit Service 4684c1
		ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
Packit Service 4684c1
		goto done;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (crl) {
Packit Service 4684c1
		ret = gnutls_certificate_set_x509_crl(res, &crl, 1);
Packit Service 4684c1
		if (ret < 0) {
Packit Service 4684c1
			gnutls_assert();
Packit Service 4684c1
			goto done;
Packit Service 4684c1
		}
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (res->flags & GNUTLS_CERTIFICATE_API_V2)
Packit Service 4684c1
		ret = idx;
Packit Service 4684c1
	else
Packit Service 4684c1
		ret = 0;
Packit Service 4684c1
Packit Service 4684c1
      done:
Packit Service 4684c1
	if (chain) {
Packit Service 4684c1
		for (i = 0; i < chain_size; i++)
Packit Service 4684c1
			gnutls_x509_crt_deinit(chain[i]);
Packit Service 4684c1
		gnutls_free(chain);
Packit Service 4684c1
	}
Packit Service 4684c1
	if (key)
Packit Service 4684c1
		gnutls_x509_privkey_deinit(key);
Packit Service 4684c1
	if (crl)
Packit Service 4684c1
		gnutls_x509_crl_deinit(crl);
Packit Service 4684c1
Packit Service 4684c1
	return ret;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_free_crls:
Packit Service 4684c1
 * @sc: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function will delete all the CRLs associated
Packit Service 4684c1
 * with the given credentials.
Packit Service 4684c1
 **/
Packit Service 4684c1
void gnutls_certificate_free_crls(gnutls_certificate_credentials_t sc)
Packit Service 4684c1
{
Packit Service 4684c1
	/* do nothing for now */
Packit Service 4684c1
	return;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_certificate_credentials_t:
Packit Service 4684c1
 * @cred: is a #gnutls_certificate_credentials_t type.
Packit Service 4684c1
 * @fn: A PIN callback
Packit Service 4684c1
 * @userdata: Data to be passed in the callback
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function will set a callback function to be used when
Packit Service 4684c1
 * required to access a protected object. This function overrides any other
Packit Service 4684c1
 * global PIN functions.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Note that this function must be called right after initialization
Packit Service 4684c1
 * to have effect.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 3.1.0
Packit Service 4684c1
 **/
Packit Service 4684c1
void gnutls_certificate_set_pin_function(gnutls_certificate_credentials_t
Packit Service 4684c1
					 cred, gnutls_pin_callback_t fn,
Packit Service 4684c1
					 void *userdata)
Packit Service 4684c1
{
Packit Service 4684c1
	cred->pin.cb = fn;
Packit Service 4684c1
	cred->pin.data = userdata;
Packit Service 4684c1
}