Blame lib/auto-verify.c

Packit Service 4684c1
/*
Packit Service 4684c1
 * Copyright (C) 2015 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 "errors.h"
Packit Service 4684c1
#include <auth/cert.h>
Packit Service 4684c1
#include <gnutls/gnutls.h>
Packit Service 4684c1
Packit Service 4684c1
/* This file implements the client certificate auto verification functionality.
Packit Service 4684c1
 */
Packit Service 4684c1
Packit Service 4684c1
/* The actual verification callback. */
Packit Service 4684c1
static int auto_verify_cb(gnutls_session_t session)
Packit Service 4684c1
{
Packit Service 4684c1
	unsigned int status;
Packit Service 4684c1
	int ret;
Packit Service 4684c1
Packit Service 4684c1
	if (session->internals.vc_elements == 0) {
Packit Service 4684c1
		ret = gnutls_certificate_verify_peers2(session, &status);
Packit Service 4684c1
	} else {
Packit Service 4684c1
		ret = gnutls_certificate_verify_peers(session, session->internals.vc_data,
Packit Service 4684c1
						      session->internals.vc_elements, &status);
Packit Service 4684c1
	}
Packit Service 4684c1
	if (ret < 0) {
Packit Service 4684c1
		return gnutls_assert_val(GNUTLS_E_CERTIFICATE_ERROR);
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	session->internals.vc_status = status;
Packit Service 4684c1
Packit Service 4684c1
	if (status != 0)	/* Certificate is not trusted */
Packit Service 4684c1
		return gnutls_assert_val(GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR);
Packit Service 4684c1
Packit Service 4684c1
	/* notify gnutls to continue handshake normally */
Packit Service 4684c1
	return 0;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_session_set_verify_cert:
Packit Service 4684c1
 * @session: is a gnutls session
Packit Service 4684c1
 * @hostname: is the expected name of the peer; may be %NULL
Packit Service 4684c1
 * @flags: flags for certificate verification -- #gnutls_certificate_verify_flags
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function instructs GnuTLS to verify the peer's certificate
Packit Service 4684c1
 * using the provided hostname. If the verification fails the handshake
Packit Service 4684c1
 * will also fail with %GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR. In that
Packit Service 4684c1
 * case the verification result can be obtained using gnutls_session_get_verify_cert_status().
Packit Service 4684c1
 *
Packit Service 4684c1
 * The @hostname pointer provided must remain valid for the lifetime
Packit Service 4684c1
 * of the session. More precisely it should be available during any subsequent
Packit Service 4684c1
 * handshakes. If no hostname is provided, no hostname verification
Packit Service 4684c1
 * will be performed. For a more advanced verification function check
Packit Service 4684c1
 * gnutls_session_set_verify_cert2().
Packit Service 4684c1
 *
Packit Service 4684c1
 * If @flags is provided which contain a profile, this function should be
Packit Service 4684c1
 * called after any session priority setting functions.
Packit Service 4684c1
 *
Packit Service 4684c1
 * The gnutls_session_set_verify_cert() function is intended to be used by TLS
Packit Service 4684c1
 * clients to verify the server's certificate.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 3.4.6
Packit Service 4684c1
 **/
Packit Service 4684c1
void gnutls_session_set_verify_cert(gnutls_session_t session,
Packit Service 4684c1
				     const char *hostname, unsigned flags)
Packit Service 4684c1
{
Packit Service 4684c1
	if (hostname) {
Packit Service 4684c1
		session->internals.vc_sdata.type = GNUTLS_DT_DNS_HOSTNAME;
Packit Service 4684c1
		session->internals.vc_sdata.data = (void*)hostname;
Packit Service 4684c1
		session->internals.vc_sdata.size = 0;
Packit Service 4684c1
		session->internals.vc_elements = 1;
Packit Service 4684c1
		session->internals.vc_data = &session->internals.vc_sdata;
Packit Service 4684c1
	} else {
Packit Service 4684c1
		session->internals.vc_elements = 0;
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	if (flags) {
Packit Service 4684c1
		ADD_PROFILE_VFLAGS(session, flags);
Packit Service 4684c1
	}
Packit Service 4684c1
Packit Service 4684c1
	gnutls_session_set_verify_function(session, auto_verify_cb);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_session_set_verify_cert2:
Packit Service 4684c1
 * @session: is a gnutls session
Packit Service 4684c1
 * @data: an array of typed data
Packit Service 4684c1
 * @elements: the number of data elements
Packit Service 4684c1
 * @flags: flags for certificate verification -- #gnutls_certificate_verify_flags
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function instructs GnuTLS to verify the peer's certificate
Packit Service 4684c1
 * using the provided typed data information. If the verification fails the handshake
Packit Service 4684c1
 * will also fail with %GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR. In that
Packit Service 4684c1
 * case the verification result can be obtained using gnutls_session_get_verify_cert_status().
Packit Service 4684c1
 *
Packit Service 4684c1
 * The acceptable typed data are the same as in gnutls_certificate_verify_peers(),
Packit Service 4684c1
 * and once set must remain valid for the lifetime of the session. More precisely
Packit Service 4684c1
 * they should be available during any subsequent handshakes.
Packit Service 4684c1
 *
Packit Service 4684c1
 * If @flags is provided which contain a profile, this function should be
Packit Service 4684c1
 * called after any session priority setting functions.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 3.4.6
Packit Service 4684c1
 **/
Packit Service 4684c1
void gnutls_session_set_verify_cert2(gnutls_session_t session,
Packit Service 4684c1
				     gnutls_typed_vdata_st * data,
Packit Service 4684c1
				     unsigned elements,
Packit Service 4684c1
				     unsigned flags)
Packit Service 4684c1
{
Packit Service 4684c1
	session->internals.vc_data = data;
Packit Service 4684c1
	session->internals.vc_elements = elements;
Packit Service 4684c1
Packit Service 4684c1
	if (flags)
Packit Service 4684c1
		session->internals.additional_verify_flags |= flags;
Packit Service 4684c1
Packit Service 4684c1
	gnutls_session_set_verify_function(session, auto_verify_cb);
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/**
Packit Service 4684c1
 * gnutls_session_get_verify_cert_status:
Packit Service 4684c1
 * @session: is a gnutls session
Packit Service 4684c1
 *
Packit Service 4684c1
 * This function returns the status of the verification when initiated
Packit Service 4684c1
 * via auto-verification, i.e., by gnutls_session_set_verify_cert2() or
Packit Service 4684c1
 * gnutls_session_set_verify_cert(). If no certificate verification
Packit Service 4684c1
 * was occurred then the return value would be set to ((unsigned int)-1).
Packit Service 4684c1
 *
Packit Service 4684c1
 * The certificate verification status is the same as in gnutls_certificate_verify_peers().
Packit Service 4684c1
 *
Packit Service 4684c1
 * Returns: the certificate verification status.
Packit Service 4684c1
 *
Packit Service 4684c1
 * Since: 3.4.6
Packit Service 4684c1
 **/
Packit Service 4684c1
unsigned int gnutls_session_get_verify_cert_status(gnutls_session_t session)
Packit Service 4684c1
{
Packit Service 4684c1
	return session->internals.vc_status;
Packit Service 4684c1
}