|
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 |
}
|