|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* Copyright (C) 2001-2015 Free Software Foundation, Inc.
|
|
Packit Service |
4684c1 |
* Copyright (C) 2015 Nikos Mavrogiannopoulos
|
|
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 |
/* This file contains certificate authentication functions to be exported in the
|
|
Packit Service |
4684c1 |
* API which did not fit elsewhere.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include "gnutls_int.h"
|
|
Packit Service |
4684c1 |
#include <auth/srp_kx.h>
|
|
Packit Service |
4684c1 |
#include <auth/anon.h>
|
|
Packit Service |
4684c1 |
#include <auth/cert.h>
|
|
Packit Service |
4684c1 |
#include <auth/psk.h>
|
|
Packit Service |
4684c1 |
#include "errors.h"
|
|
Packit Service |
4684c1 |
#include <auth.h>
|
|
Packit Service |
4684c1 |
#include <state.h>
|
|
Packit Service |
4684c1 |
#include <datum.h>
|
|
Packit Service |
4684c1 |
#include <algorithms.h>
|
|
Packit Service |
4684c1 |
#include <gnutls/ocsp.h>
|
|
Packit Service |
4684c1 |
#include "x509.h"
|
|
Packit Service |
4684c1 |
#include "hello_ext.h"
|
|
Packit Service |
4684c1 |
#include "x509/ocsp.h"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_certificate_get_ours:
|
|
Packit Service |
4684c1 |
* @session: is a gnutls session
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Gets the certificate as sent to the peer in the last handshake.
|
|
Packit Service |
4684c1 |
* The certificate is in raw (DER) format. No certificate
|
|
Packit Service |
4684c1 |
* list is being returned. Only the first certificate.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function returns the certificate that was sent in the current
|
|
Packit Service |
4684c1 |
* handshake. In subsequent resumed sessions this function will return
|
|
Packit Service |
4684c1 |
* %NULL. That differs from gnutls_certificate_get_peers() which always
|
|
Packit Service |
4684c1 |
* returns the peer's certificate used in the original session.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: a pointer to a #gnutls_datum_t containing our
|
|
Packit Service |
4684c1 |
* certificate, or %NULL in case of an error or if no certificate
|
|
Packit Service |
4684c1 |
* was used.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
const gnutls_datum_t *gnutls_certificate_get_ours(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_certificate_credentials_t cred;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, NULL);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cred = (gnutls_certificate_credentials_t)
|
|
Packit Service |
4684c1 |
_gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE);
|
|
Packit Service |
4684c1 |
if (cred == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return NULL;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.selected_cert_list == NULL)
|
|
Packit Service |
4684c1 |
return NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return &session->internals.selected_cert_list[0].cert;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_certificate_get_peers:
|
|
Packit Service |
4684c1 |
* @session: is a gnutls session
|
|
Packit Service |
4684c1 |
* @list_size: is the length of the certificate list (may be %NULL)
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Get the peer's raw certificate (chain) as sent by the peer. These
|
|
Packit Service |
4684c1 |
* certificates are in raw format (DER encoded for X.509). In case of
|
|
Packit Service |
4684c1 |
* a X.509 then a certificate list may be present. The list
|
|
Packit Service |
4684c1 |
* is provided as sent by the server; the server must send as first
|
|
Packit Service |
4684c1 |
* certificate in the list its own certificate, following the
|
|
Packit Service |
4684c1 |
* issuer's certificate, then the issuer's issuer etc. However, there
|
|
Packit Service |
4684c1 |
* are servers which violate this principle and thus on certain
|
|
Packit Service |
4684c1 |
* occasions this may be an unsorted list.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* In resumed sessions, this function will return the peer's certificate
|
|
Packit Service |
4684c1 |
* list as used in the first/original session.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: a pointer to a #gnutls_datum_t containing the peer's
|
|
Packit Service |
4684c1 |
* certificates, or %NULL in case of an error or if no certificate
|
|
Packit Service |
4684c1 |
* was used.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
const gnutls_datum_t *gnutls_certificate_get_peers(gnutls_session_t
|
|
Packit Service |
4684c1 |
session,
|
|
Packit Service |
4684c1 |
unsigned int *list_size)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
cert_auth_info_t info;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, NULL);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
|
|
Packit Service |
4684c1 |
if (info == NULL)
|
|
Packit Service |
4684c1 |
return NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (list_size)
|
|
Packit Service |
4684c1 |
*list_size = info->ncerts;
|
|
Packit Service |
4684c1 |
return info->raw_certificate_list;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_certificate_client_get_request_status:
|
|
Packit Service |
4684c1 |
* @session: is a gnutls session
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Get whether client certificate was requested on the last
|
|
Packit Service |
4684c1 |
* handshake or not.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: 0 if the peer (server) did not request client
|
|
Packit Service |
4684c1 |
* authentication or 1 otherwise.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
unsigned
|
|
Packit Service |
4684c1 |
gnutls_certificate_client_get_request_status(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return (session->internals.hsk_flags & HSK_CRT_ASKED)?1:0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_certificate_set_params_function:
|
|
Packit Service |
4684c1 |
* @res: is a gnutls_certificate_credentials_t type
|
|
Packit Service |
4684c1 |
* @func: is the function to be called
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will set a callback in order for the server to get
|
|
Packit Service |
4684c1 |
* the Diffie-Hellman or RSA parameters for certificate
|
|
Packit Service |
4684c1 |
* authentication. The callback should return %GNUTLS_E_SUCCESS (0) on success.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Deprecated: This function is unnecessary and discouraged on GnuTLS 3.6.0
|
|
Packit Service |
4684c1 |
* or later. Since 3.6.0, DH parameters are negotiated
|
|
Packit Service |
4684c1 |
* following RFC7919.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
void
|
|
Packit Service |
4684c1 |
gnutls_certificate_set_params_function(gnutls_certificate_credentials_t
|
|
Packit Service |
4684c1 |
res, gnutls_params_function * func)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
res->params_func = func;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_certificate_set_flags:
|
|
Packit Service |
4684c1 |
* @res: is a gnutls_certificate_credentials_t type
|
|
Packit Service |
4684c1 |
* @flags: are the flags of #gnutls_certificate_flags type
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will set flags to tweak the operation of
|
|
Packit Service |
4684c1 |
* the credentials structure. See the #gnutls_certificate_flags enumerations
|
|
Packit Service |
4684c1 |
* for more information on the available flags.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.4.7
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
void
|
|
Packit Service |
4684c1 |
gnutls_certificate_set_flags(gnutls_certificate_credentials_t res,
|
|
Packit Service |
4684c1 |
unsigned int flags)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
res->flags = flags;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_certificate_set_verify_flags:
|
|
Packit Service |
4684c1 |
* @res: is a gnutls_certificate_credentials_t type
|
|
Packit Service |
4684c1 |
* @flags: are the flags
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will set the flags to be used for verification
|
|
Packit Service |
4684c1 |
* of certificates and override any defaults. The provided flags must be an OR of the
|
|
Packit Service |
4684c1 |
* #gnutls_certificate_verify_flags enumerations.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
void
|
|
Packit Service |
4684c1 |
gnutls_certificate_set_verify_flags(gnutls_certificate_credentials_t
|
|
Packit Service |
4684c1 |
res, unsigned int flags)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
res->verify_flags = flags;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_certificate_get_verify_flags:
|
|
Packit Service |
4684c1 |
* @res: is a gnutls_certificate_credentials_t type
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns the verification flags set with
|
|
Packit Service |
4684c1 |
* gnutls_certificate_set_verify_flags().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: The certificate verification flags used by @res.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.4.0
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
unsigned int
|
|
Packit Service |
4684c1 |
gnutls_certificate_get_verify_flags(gnutls_certificate_credentials_t res)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return res->verify_flags;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_certificate_set_verify_limits:
|
|
Packit Service |
4684c1 |
* @res: is a gnutls_certificate_credentials type
|
|
Packit Service |
4684c1 |
* @max_bits: is the number of bits of an acceptable certificate (default 8200)
|
|
Packit Service |
4684c1 |
* @max_depth: is maximum depth of the verification of a certificate chain (default 5)
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will set some upper limits for the default
|
|
Packit Service |
4684c1 |
* verification function, gnutls_certificate_verify_peers2(), to avoid
|
|
Packit Service |
4684c1 |
* denial of service attacks. You can set them to zero to disable
|
|
Packit Service |
4684c1 |
* limits.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
void
|
|
Packit Service |
4684c1 |
gnutls_certificate_set_verify_limits(gnutls_certificate_credentials_t res,
|
|
Packit Service |
4684c1 |
unsigned int max_bits,
|
|
Packit Service |
4684c1 |
unsigned int max_depth)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
res->verify_depth = max_depth;
|
|
Packit Service |
4684c1 |
res->verify_bits = max_bits;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#ifdef ENABLE_OCSP
|
|
Packit Service |
4684c1 |
/* If the certificate is revoked status will be GNUTLS_CERT_REVOKED.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns:
|
|
Packit Service |
4684c1 |
* Zero on success, a negative error code otherwise.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
check_ocsp_response(gnutls_session_t session, gnutls_x509_crt_t cert,
|
|
Packit Service |
4684c1 |
gnutls_x509_trust_list_t tl,
|
|
Packit Service |
4684c1 |
unsigned verify_flags,
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_t *cand_issuers, unsigned cand_issuers_size,
|
|
Packit Service |
4684c1 |
gnutls_datum_t * data, unsigned int *ostatus)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_ocsp_resp_t resp;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
unsigned int status, cert_status;
|
|
Packit Service |
4684c1 |
time_t rtime, vtime, ntime, now;
|
|
Packit Service |
4684c1 |
int check_failed = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
now = gnutls_time(0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_resp_init(&resp);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_resp_import(resp, data);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
_gnutls_audit_log(session,
|
|
Packit Service |
4684c1 |
"There was an error parsing the OCSP response: %s.\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
ret = gnutls_assert_val(0);
|
|
Packit Service |
4684c1 |
check_failed = 1;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_INVALID;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_resp_check_crt(resp, 0, cert);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
ret = gnutls_assert_val(0);
|
|
Packit Service |
4684c1 |
_gnutls_audit_log(session,
|
|
Packit Service |
4684c1 |
"Got OCSP response with an unrelated certificate.\n");
|
|
Packit Service |
4684c1 |
check_failed = 1;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_INVALID;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Attempt to verify against our trusted list */
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_resp_verify(resp, tl, &status, verify_flags);
|
|
Packit Service |
4684c1 |
if ((ret < 0 || status != 0) && cand_issuers_size > 0) {
|
|
Packit Service |
4684c1 |
/* Attempt to verify against the certificate list provided by the server */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_resp_verify_direct(resp, cand_issuers[0], &status, verify_flags);
|
|
Packit Service |
4684c1 |
/* if verification fails attempt to find whether any of the other
|
|
Packit Service |
4684c1 |
* bundled CAs is an issuer of the OCSP response */
|
|
Packit Service |
4684c1 |
if ((ret < 0 || status != 0) && cand_issuers_size > 1) {
|
|
Packit Service |
4684c1 |
int ret2;
|
|
Packit Service |
4684c1 |
unsigned status2, i;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
for (i=1;i
|
|
Packit Service |
4684c1 |
ret2 = gnutls_ocsp_resp_verify_direct(resp, cand_issuers[i], &status2, verify_flags);
|
|
Packit Service |
4684c1 |
if (ret2 >= 0 && status2 == 0) {
|
|
Packit Service |
4684c1 |
status = status2;
|
|
Packit Service |
4684c1 |
ret = ret2;
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
ret = gnutls_assert_val(0);
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
check_failed = 1;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_INVALID;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* do not consider revocation data if response was not verified */
|
|
Packit Service |
4684c1 |
if (status != 0) {
|
|
Packit Service |
4684c1 |
char buf[MAX_OCSP_MSG_SIZE];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_debug_log("OCSP rejection reason: %s\n",
|
|
Packit Service |
4684c1 |
_gnutls_ocsp_verify_status_to_str(status, buf));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_assert_val(0);
|
|
Packit Service |
4684c1 |
check_failed = 1;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_INVALID;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL,
|
|
Packit Service |
4684c1 |
&cert_status, &vtime, &ntime,
|
|
Packit Service |
4684c1 |
&rtime, NULL);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
_gnutls_audit_log(session,
|
|
Packit Service |
4684c1 |
"There was an error parsing the OCSP response: %s.\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror(ret));
|
|
Packit Service |
4684c1 |
ret = gnutls_assert_val(0);
|
|
Packit Service |
4684c1 |
check_failed = 1;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_INVALID;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (cert_status == GNUTLS_OCSP_CERT_REVOKED) {
|
|
Packit Service |
4684c1 |
_gnutls_audit_log(session,
|
|
Packit Service |
4684c1 |
"The certificate was revoked via OCSP\n");
|
|
Packit Service |
4684c1 |
check_failed = 1;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_INVALID;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_REVOKED;
|
|
Packit Service |
4684c1 |
ret = gnutls_assert_val(0);
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Report but do not fail on the following errors. That is
|
|
Packit Service |
4684c1 |
* because including the OCSP response in the handshake shouldn't
|
|
Packit Service |
4684c1 |
* cause more problems that not including it.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if (ntime == -1) {
|
|
Packit Service |
4684c1 |
if (now - vtime > MAX_OCSP_VALIDITY_SECS) {
|
|
Packit Service |
4684c1 |
_gnutls_audit_log(session,
|
|
Packit Service |
4684c1 |
"The OCSP response is old\n");
|
|
Packit Service |
4684c1 |
check_failed = 1;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_INVALID;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED;
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
/* there is a newer OCSP answer, don't trust this one */
|
|
Packit Service |
4684c1 |
if (ntime < now) {
|
|
Packit Service |
4684c1 |
_gnutls_audit_log(session,
|
|
Packit Service |
4684c1 |
"There is a newer OCSP response but was not provided by the server\n");
|
|
Packit Service |
4684c1 |
check_failed = 1;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_INVALID;
|
|
Packit Service |
4684c1 |
*ostatus |= GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED;
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = 0;
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
if (check_failed == 0)
|
|
Packit Service |
4684c1 |
session->internals.ocsp_check_ok = 1;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_ocsp_resp_deinit(resp);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
_gnutls_ocsp_verify_mandatory_stapling(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_t cert,
|
|
Packit Service |
4684c1 |
unsigned int * ocsp_status)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_x509_tlsfeatures_t tlsfeatures;
|
|
Packit Service |
4684c1 |
int i, ret;
|
|
Packit Service |
4684c1 |
unsigned feature;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* RFC 7633: If cert has TLS feature GNUTLS_EXTENSION_STATUS_REQUEST, stapling is mandatory.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* At this point, we know that we did not get the certificate status.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* To proceed, first check whether we have requested the certificate status
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if (!(session->internals.hsk_flags & HSK_OCSP_REQUESTED))
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_x509_tlsfeatures_init(&tlsfeatures);
|
|
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 |
/* We have requested the status, now check whether the certificate mandates a response */
|
|
Packit Service |
4684c1 |
if (gnutls_x509_crt_get_tlsfeatures(cert, tlsfeatures, 0, NULL) == 0) {
|
|
Packit Service |
4684c1 |
for (i = 0;; ++i) {
|
|
Packit Service |
4684c1 |
ret = gnutls_x509_tlsfeatures_get(tlsfeatures, i, &feature);
|
|
Packit Service |
4684c1 |
if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
}
|
|
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 |
if (feature == 5 /* TLS ID for status request */) {
|
|
Packit Service |
4684c1 |
/* We sent a status request, the certificate mandates a reply, but we did not get any. */
|
|
Packit Service |
4684c1 |
*ocsp_status |= GNUTLS_CERT_MISSING_OCSP_STATUS;
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = 0;
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
gnutls_x509_tlsfeatures_deinit(tlsfeatures);
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define CLEAR_CERTS for(x=0;x
|
|
Packit Service |
4684c1 |
if (peer_certificate_list[x]) \
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_deinit(peer_certificate_list[x]); \
|
|
Packit Service |
4684c1 |
} \
|
|
Packit Service |
4684c1 |
gnutls_free( peer_certificate_list)
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/*-
|
|
Packit Service |
4684c1 |
* _gnutls_x509_cert_verify_peers - return the peer's certificate status
|
|
Packit Service |
4684c1 |
* @session: is a gnutls session
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.).
|
|
Packit Service |
4684c1 |
* The return value (status) should be one of the gnutls_certificate_status_t enumerated elements.
|
|
Packit Service |
4684c1 |
* However you must also check the peer's name in order to check if the verified certificate belongs to the
|
|
Packit Service |
4684c1 |
* actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
|
|
Packit Service |
4684c1 |
-*/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
_gnutls_x509_cert_verify_peers(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
gnutls_typed_vdata_st * data,
|
|
Packit Service |
4684c1 |
unsigned int elements,
|
|
Packit Service |
4684c1 |
unsigned int *status)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
cert_auth_info_t info;
|
|
Packit Service |
4684c1 |
gnutls_certificate_credentials_t cred;
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_t *peer_certificate_list;
|
|
Packit Service |
4684c1 |
gnutls_datum_t resp;
|
|
Packit Service |
4684c1 |
int peer_certificate_list_size, i, x, ret;
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_t *cand_issuers;
|
|
Packit Service |
4684c1 |
unsigned cand_issuers_size;
|
|
Packit Service |
4684c1 |
unsigned int ocsp_status = 0;
|
|
Packit Service |
4684c1 |
unsigned int verify_flags;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* No OCSP check so far */
|
|
Packit Service |
4684c1 |
session->internals.ocsp_check_ok = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
|
|
Packit Service |
4684c1 |
if (info == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cred = (gnutls_certificate_credentials_t)
|
|
Packit Service |
4684c1 |
_gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE);
|
|
Packit Service |
4684c1 |
if (cred == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (info->raw_certificate_list == NULL || info->ncerts == 0)
|
|
Packit Service |
4684c1 |
return GNUTLS_E_NO_CERTIFICATE_FOUND;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (info->ncerts > cred->verify_depth && cred->verify_depth > 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_CONSTRAINT_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
verify_flags =
|
|
Packit Service |
4684c1 |
cred->verify_flags | session->internals.additional_verify_flags;
|
|
Packit Service |
4684c1 |
/* generate a list of gnutls_certs based on the auth info
|
|
Packit Service |
4684c1 |
* raw certs.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
peer_certificate_list_size = info->ncerts;
|
|
Packit Service |
4684c1 |
peer_certificate_list =
|
|
Packit Service |
4684c1 |
gnutls_calloc(peer_certificate_list_size,
|
|
Packit Service |
4684c1 |
sizeof(gnutls_x509_crt_t));
|
|
Packit Service |
4684c1 |
if (peer_certificate_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 < peer_certificate_list_size; i++) {
|
|
Packit Service |
4684c1 |
ret = gnutls_x509_crt_init(&peer_certificate_list[i]);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
CLEAR_CERTS;
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_import(peer_certificate_list[i],
|
|
Packit Service |
4684c1 |
&info->raw_certificate_list[i],
|
|
Packit Service |
4684c1 |
GNUTLS_X509_FMT_DER);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
CLEAR_CERTS;
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Use the OCSP extension if any */
|
|
Packit Service |
4684c1 |
#ifdef ENABLE_OCSP
|
|
Packit Service |
4684c1 |
if (verify_flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS)
|
|
Packit Service |
4684c1 |
goto skip_ocsp;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
for (i=0;i
|
|
Packit Service |
4684c1 |
ret = gnutls_ocsp_status_request_get2(session, i, &resp);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
ret = _gnutls_ocsp_verify_mandatory_stapling(session, peer_certificate_list[i], &ocsp_status);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
CLEAR_CERTS;
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cand_issuers = NULL;
|
|
Packit Service |
4684c1 |
cand_issuers_size = 0;
|
|
Packit Service |
4684c1 |
if (peer_certificate_list_size > i+1) {
|
|
Packit Service |
4684c1 |
cand_issuers = &peer_certificate_list[i+1];
|
|
Packit Service |
4684c1 |
cand_issuers_size = peer_certificate_list_size-i-1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
check_ocsp_response(session,
|
|
Packit Service |
4684c1 |
peer_certificate_list[i],
|
|
Packit Service |
4684c1 |
cred->tlist,
|
|
Packit Service |
4684c1 |
verify_flags, cand_issuers,
|
|
Packit Service |
4684c1 |
cand_issuers_size,
|
|
Packit Service |
4684c1 |
&resp, &ocsp_status);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
CLEAR_CERTS;
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
skip_ocsp:
|
|
Packit Service |
4684c1 |
/* Verify certificate
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_x509_trust_list_verify_crt2(cred->tlist,
|
|
Packit Service |
4684c1 |
peer_certificate_list,
|
|
Packit Service |
4684c1 |
peer_certificate_list_size,
|
|
Packit Service |
4684c1 |
data, elements,
|
|
Packit Service |
4684c1 |
verify_flags, status, NULL);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
CLEAR_CERTS;
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
CLEAR_CERTS;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
*status |= ocsp_status;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_certificate_verify_peers2:
|
|
Packit Service |
4684c1 |
* @session: is a gnutls session
|
|
Packit Service |
4684c1 |
* @status: is the output of the verification
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will verify the peer's certificate and store
|
|
Packit Service |
4684c1 |
* the status in the @status variable as a bitwise OR of gnutls_certificate_status_t
|
|
Packit Service |
4684c1 |
* values or zero if the certificate is trusted. Note that value in @status
|
|
Packit Service |
4684c1 |
* is set only when the return value of this function is success (i.e, failure
|
|
Packit Service |
4684c1 |
* to trust a certificate does not imply a negative return value).
|
|
Packit Service |
4684c1 |
* The default verification flags used by this function can be overridden
|
|
Packit Service |
4684c1 |
* using gnutls_certificate_set_verify_flags().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will take into account the stapled OCSP responses sent by the server,
|
|
Packit Service |
4684c1 |
* as well as the following X.509 certificate extensions: Name Constraints,
|
|
Packit Service |
4684c1 |
* Key Usage, and Basic Constraints (pathlen).
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Note that you must also check the peer's name in order to check if
|
|
Packit Service |
4684c1 |
* the verified certificate belongs to the actual peer, see gnutls_x509_crt_check_hostname(),
|
|
Packit Service |
4684c1 |
* or use gnutls_certificate_verify_peers3().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* To avoid denial of service attacks some
|
|
Packit Service |
4684c1 |
* default upper limits regarding the certificate key size and chain
|
|
Packit Service |
4684c1 |
* size are set. To override them use gnutls_certificate_set_verify_limits().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Note that when using raw public-keys verification will not work because there is
|
|
Packit Service |
4684c1 |
* no corresponding certificate body belonging to the raw key that can be verified. In that
|
|
Packit Service |
4684c1 |
* case this function will return %GNUTLS_E_INVALID_REQUEST.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: %GNUTLS_E_SUCCESS (0) when the validation is performed, or a negative error code otherwise.
|
|
Packit Service |
4684c1 |
* A successful error code means that the @status parameter must be checked to obtain the validation status.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_certificate_verify_peers2(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
unsigned int *status)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return gnutls_certificate_verify_peers(session, NULL, 0, status);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_certificate_verify_peers3:
|
|
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 |
* @status: is the output of the verification
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will verify the peer's certificate and store the
|
|
Packit Service |
4684c1 |
* the status in the @status variable as a bitwise OR of gnutls_certificate_status_t
|
|
Packit Service |
4684c1 |
* values or zero if the certificate is trusted. Note that value in @status
|
|
Packit Service |
4684c1 |
* is set only when the return value of this function is success (i.e, failure
|
|
Packit Service |
4684c1 |
* to trust a certificate does not imply a negative return value).
|
|
Packit Service |
4684c1 |
* The default verification flags used by this function can be overridden
|
|
Packit Service |
4684c1 |
* using gnutls_certificate_set_verify_flags(). See the documentation
|
|
Packit Service |
4684c1 |
* of gnutls_certificate_verify_peers2() for details in the verification process.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will take into account the stapled OCSP responses sent by the server,
|
|
Packit Service |
4684c1 |
* as well as the following X.509 certificate extensions: Name Constraints,
|
|
Packit Service |
4684c1 |
* Key Usage, and Basic Constraints (pathlen).
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* If the @hostname provided is non-NULL then this function will compare
|
|
Packit Service |
4684c1 |
* the hostname in the certificate against it. The comparison will follow
|
|
Packit Service |
4684c1 |
* the RFC6125 recommendations. If names do not match the
|
|
Packit Service |
4684c1 |
* %GNUTLS_CERT_UNEXPECTED_OWNER status flag will be set.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* In order to verify the purpose of the end-certificate (by checking the extended
|
|
Packit Service |
4684c1 |
* key usage), use gnutls_certificate_verify_peers().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* To avoid denial of service attacks some
|
|
Packit Service |
4684c1 |
* default upper limits regarding the certificate key size and chain
|
|
Packit Service |
4684c1 |
* size are set. To override them use gnutls_certificate_set_verify_limits().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Note that when using raw public-keys verification will not work because there is
|
|
Packit Service |
4684c1 |
* no corresponding certificate body belonging to the raw key that can be verified. In that
|
|
Packit Service |
4684c1 |
* case this function will return %GNUTLS_E_INVALID_REQUEST.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: %GNUTLS_E_SUCCESS (0) when the validation is performed, or a negative error code otherwise.
|
|
Packit Service |
4684c1 |
* A successful error code means that the @status parameter must be checked to obtain the validation status.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.1.4
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_certificate_verify_peers3(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
const char *hostname,
|
|
Packit Service |
4684c1 |
unsigned int *status)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_typed_vdata_st data;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
data.type = GNUTLS_DT_DNS_HOSTNAME;
|
|
Packit Service |
4684c1 |
data.size = 0;
|
|
Packit Service |
4684c1 |
data.data = (void*)hostname;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return gnutls_certificate_verify_peers(session, &data, 1, status);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_certificate_verify_peers:
|
|
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 |
* @status: is the output of the verification
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will verify the peer's certificate and store the
|
|
Packit Service |
4684c1 |
* the status in the @status variable as a bitwise OR of gnutls_certificate_status_t
|
|
Packit Service |
4684c1 |
* values or zero if the certificate is trusted. Note that value in @status
|
|
Packit Service |
4684c1 |
* is set only when the return value of this function is success (i.e, failure
|
|
Packit Service |
4684c1 |
* to trust a certificate does not imply a negative return value).
|
|
Packit Service |
4684c1 |
* The default verification flags used by this function can be overridden
|
|
Packit Service |
4684c1 |
* using gnutls_certificate_set_verify_flags(). See the documentation
|
|
Packit Service |
4684c1 |
* of gnutls_certificate_verify_peers2() for details in the verification process.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will take into account the stapled OCSP responses sent by the server,
|
|
Packit Service |
4684c1 |
* as well as the following X.509 certificate extensions: Name Constraints,
|
|
Packit Service |
4684c1 |
* Key Usage, and Basic Constraints (pathlen).
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* The acceptable @data types are %GNUTLS_DT_DNS_HOSTNAME, %GNUTLS_DT_RFC822NAME and %GNUTLS_DT_KEY_PURPOSE_OID.
|
|
Packit Service |
4684c1 |
* The former two accept as data a null-terminated hostname or email address, and the latter a null-terminated
|
|
Packit Service |
4684c1 |
* object identifier (e.g., %GNUTLS_KP_TLS_WWW_SERVER).
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* If a DNS hostname is provided then this function will compare
|
|
Packit Service |
4684c1 |
* the hostname in the certificate against the given. If names do not match the
|
|
Packit Service |
4684c1 |
* %GNUTLS_CERT_UNEXPECTED_OWNER status flag will be set.
|
|
Packit Service |
4684c1 |
* If a key purpose OID is provided and the end-certificate contains the extended key
|
|
Packit Service |
4684c1 |
* usage PKIX extension, it will be required to be have the provided key purpose
|
|
Packit Service |
4684c1 |
* or be marked for any purpose, otherwise verification status will have the
|
|
Packit Service |
4684c1 |
* %GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE flag set.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* To avoid denial of service attacks some
|
|
Packit Service |
4684c1 |
* default upper limits regarding the certificate key size and chain
|
|
Packit Service |
4684c1 |
* size are set. To override them use gnutls_certificate_set_verify_limits().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Note that when using raw public-keys verification will not work because there is
|
|
Packit Service |
4684c1 |
* no corresponding certificate body belonging to the raw key that can be verified. In that
|
|
Packit Service |
4684c1 |
* case this function will return %GNUTLS_E_INVALID_REQUEST.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: %GNUTLS_E_SUCCESS (0) when the validation is performed, or a negative error code otherwise.
|
|
Packit Service |
4684c1 |
* A successful error code means that the @status parameter must be checked to obtain the validation status.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.3.0
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_certificate_verify_peers(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
gnutls_typed_vdata_st * data,
|
|
Packit Service |
4684c1 |
unsigned int elements,
|
|
Packit Service |
4684c1 |
unsigned int *status)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
cert_auth_info_t info;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
|
|
Packit Service |
4684c1 |
if (info == NULL) {
|
|
Packit Service |
4684c1 |
return GNUTLS_E_NO_CERTIFICATE_FOUND;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (info->raw_certificate_list == NULL || info->ncerts == 0)
|
|
Packit Service |
4684c1 |
return GNUTLS_E_NO_CERTIFICATE_FOUND;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
switch (get_certificate_type(session, GNUTLS_CTYPE_PEERS)) {
|
|
Packit Service |
4684c1 |
case GNUTLS_CRT_X509:
|
|
Packit Service |
4684c1 |
return _gnutls_x509_cert_verify_peers(session, data, elements,
|
|
Packit Service |
4684c1 |
status);
|
|
Packit Service |
4684c1 |
default:
|
|
Packit Service |
4684c1 |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/*-
|
|
Packit Service |
4684c1 |
* _gnutls_x509_extract_certificate_activation_time - return the peer's certificate activation time
|
|
Packit Service |
4684c1 |
* @cert: should contain an X.509 DER encoded certificate
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will return the certificate's activation time in UNIX time
|
|
Packit Service |
4684c1 |
* (ie seconds since 00:00:00 UTC January 1, 1970).
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns a (time_t) -1 in case of an error.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
-*/
|
|
Packit Service |
4684c1 |
static time_t
|
|
Packit Service |
4684c1 |
_gnutls_x509_get_raw_crt_activation_time(const gnutls_datum_t * cert)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_t xcert;
|
|
Packit Service |
4684c1 |
time_t result;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
result = gnutls_x509_crt_init(&xcert);
|
|
Packit Service |
4684c1 |
if (result < 0)
|
|
Packit Service |
4684c1 |
return (time_t) - 1;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
result = gnutls_x509_crt_import(xcert, cert, GNUTLS_X509_FMT_DER);
|
|
Packit Service |
4684c1 |
if (result < 0) {
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_deinit(xcert);
|
|
Packit Service |
4684c1 |
return (time_t) - 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
result = gnutls_x509_crt_get_activation_time(xcert);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_deinit(xcert);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return result;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/*-
|
|
Packit Service |
4684c1 |
* gnutls_x509_extract_certificate_expiration_time:
|
|
Packit Service |
4684c1 |
* @cert: should contain an X.509 DER encoded certificate
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will return the certificate's expiration time in UNIX
|
|
Packit Service |
4684c1 |
* time (ie seconds since 00:00:00 UTC January 1, 1970). Returns a
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* (time_t) -1 in case of an error.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
-*/
|
|
Packit Service |
4684c1 |
static time_t
|
|
Packit Service |
4684c1 |
_gnutls_x509_get_raw_crt_expiration_time(const gnutls_datum_t * cert)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_t xcert;
|
|
Packit Service |
4684c1 |
time_t result;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
result = gnutls_x509_crt_init(&xcert);
|
|
Packit Service |
4684c1 |
if (result < 0)
|
|
Packit Service |
4684c1 |
return (time_t) - 1;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
result = gnutls_x509_crt_import(xcert, cert, GNUTLS_X509_FMT_DER);
|
|
Packit Service |
4684c1 |
if (result < 0) {
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_deinit(xcert);
|
|
Packit Service |
4684c1 |
return (time_t) - 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
result = gnutls_x509_crt_get_expiration_time(xcert);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_deinit(xcert);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return result;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_certificate_expiration_time_peers:
|
|
Packit Service |
4684c1 |
* @session: is a gnutls session
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will return the peer's certificate expiration time.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: (time_t)-1 on error.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Deprecated: gnutls_certificate_verify_peers2() now verifies expiration times.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
time_t gnutls_certificate_expiration_time_peers(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
cert_auth_info_t info;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
|
|
Packit Service |
4684c1 |
if (info == NULL) {
|
|
Packit Service |
4684c1 |
return (time_t) - 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (info->raw_certificate_list == NULL || info->ncerts == 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return (time_t) - 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
switch (get_certificate_type(session, GNUTLS_CTYPE_PEERS)) {
|
|
Packit Service |
4684c1 |
case GNUTLS_CRT_X509:
|
|
Packit Service |
4684c1 |
return
|
|
Packit Service |
4684c1 |
_gnutls_x509_get_raw_crt_expiration_time(&info->
|
|
Packit Service |
4684c1 |
raw_certificate_list[0]);
|
|
Packit Service |
4684c1 |
default:
|
|
Packit Service |
4684c1 |
return (time_t) - 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_certificate_activation_time_peers:
|
|
Packit Service |
4684c1 |
* @session: is a gnutls session
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will return the peer's certificate activation time.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: (time_t)-1 on error.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Deprecated: gnutls_certificate_verify_peers2() now verifies activation times.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
time_t gnutls_certificate_activation_time_peers(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
cert_auth_info_t info;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
|
|
Packit Service |
4684c1 |
if (info == NULL) {
|
|
Packit Service |
4684c1 |
return (time_t) - 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (info->raw_certificate_list == NULL || info->ncerts == 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return (time_t) - 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
switch (get_certificate_type(session, GNUTLS_CTYPE_PEERS)) {
|
|
Packit Service |
4684c1 |
case GNUTLS_CRT_X509:
|
|
Packit Service |
4684c1 |
return
|
|
Packit Service |
4684c1 |
_gnutls_x509_get_raw_crt_activation_time(&info->
|
|
Packit Service |
4684c1 |
raw_certificate_list[0]);
|
|
Packit Service |
4684c1 |
default:
|
|
Packit Service |
4684c1 |
return (time_t) - 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|