|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* Copyright (C) 2001-2012 Free Software Foundation, Inc.
|
|
Packit Service |
4684c1 |
* Copyright (C) 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 "errors.h"
|
|
Packit Service |
4684c1 |
#include "auth.h"
|
|
Packit Service |
4684c1 |
#include "auth.h"
|
|
Packit Service |
4684c1 |
#include "algorithms.h"
|
|
Packit Service |
4684c1 |
#include <auth/cert.h>
|
|
Packit Service |
4684c1 |
#include <auth/psk.h>
|
|
Packit Service |
4684c1 |
#include <auth/anon.h>
|
|
Packit Service |
4684c1 |
#include <datum.h>
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* The functions here are used in order for authentication algorithms
|
|
Packit Service |
4684c1 |
* to be able to retrieve the needed credentials eg public and private
|
|
Packit Service |
4684c1 |
* key etc.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_credentials_clear:
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Clears all the credentials previously set in this session.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
void gnutls_credentials_clear(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (session->key.cred) { /* beginning of the list */
|
|
Packit Service |
4684c1 |
auth_cred_st *ccred, *ncred;
|
|
Packit Service |
4684c1 |
ccred = session->key.cred;
|
|
Packit Service |
4684c1 |
while (ccred != NULL) {
|
|
Packit Service |
4684c1 |
ncred = ccred->next;
|
|
Packit Service |
4684c1 |
gnutls_free(ccred);
|
|
Packit Service |
4684c1 |
ccred = ncred;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
session->key.cred = NULL;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* This creates a linked list of the form:
|
|
Packit Service |
4684c1 |
* { algorithm, credentials, pointer to next }
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_credentials_set:
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
* @type: is the type of the credentials
|
|
Packit Service |
4684c1 |
* @cred: the credentials to set
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Sets the needed credentials for the specified type. E.g. username,
|
|
Packit Service |
4684c1 |
* password - or public and private keys etc. The @cred parameter is
|
|
Packit Service |
4684c1 |
* a structure that depends on the specified type and on the current
|
|
Packit Service |
4684c1 |
* session (client or server).
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* In order to minimize memory usage, and share credentials between
|
|
Packit Service |
4684c1 |
* several threads gnutls keeps a pointer to cred, and not the whole
|
|
Packit Service |
4684c1 |
* cred structure. Thus you will have to keep the structure allocated
|
|
Packit Service |
4684c1 |
* until you call gnutls_deinit().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* For %GNUTLS_CRD_ANON, @cred should be
|
|
Packit Service |
4684c1 |
* #gnutls_anon_client_credentials_t in case of a client. In case of
|
|
Packit Service |
4684c1 |
* a server it should be #gnutls_anon_server_credentials_t.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* For %GNUTLS_CRD_SRP, @cred should be #gnutls_srp_client_credentials_t
|
|
Packit Service |
4684c1 |
* in case of a client, and #gnutls_srp_server_credentials_t, in case
|
|
Packit Service |
4684c1 |
* of a server.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* For %GNUTLS_CRD_CERTIFICATE, @cred should be
|
|
Packit Service |
4684c1 |
* #gnutls_certificate_credentials_t.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
|
|
Packit Service |
4684c1 |
* otherwise a negative error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_credentials_set(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
gnutls_credentials_type_t type, void *cred)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
auth_cred_st *ccred = NULL, *pcred = NULL;
|
|
Packit Service |
4684c1 |
int exists = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->key.cred == NULL) { /* beginning of the list */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session->key.cred = gnutls_malloc(sizeof(auth_cred_st));
|
|
Packit Service |
4684c1 |
if (session->key.cred == NULL)
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* copy credentials locally */
|
|
Packit Service |
4684c1 |
session->key.cred->credentials = cred;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session->key.cred->next = NULL;
|
|
Packit Service |
4684c1 |
session->key.cred->algorithm = type;
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
ccred = session->key.cred;
|
|
Packit Service |
4684c1 |
while (ccred != NULL) {
|
|
Packit Service |
4684c1 |
if (ccred->algorithm == type) {
|
|
Packit Service |
4684c1 |
exists = 1;
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
pcred = ccred;
|
|
Packit Service |
4684c1 |
ccred = ccred->next;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
/* After this, pcred is not null.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (exists == 0) { /* new entry */
|
|
Packit Service |
4684c1 |
pcred->next = gnutls_malloc(sizeof(auth_cred_st));
|
|
Packit Service |
4684c1 |
if (pcred->next == NULL)
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ccred = pcred->next;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* copy credentials locally */
|
|
Packit Service |
4684c1 |
ccred->credentials = cred;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ccred->next = NULL;
|
|
Packit Service |
4684c1 |
ccred->algorithm = type;
|
|
Packit Service |
4684c1 |
} else { /* modify existing entry */
|
|
Packit Service |
4684c1 |
ccred->credentials = cred;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* sanity tests */
|
|
Packit Service |
4684c1 |
if (type == GNUTLS_CRD_CERTIFICATE) {
|
|
Packit Service |
4684c1 |
gnutls_certificate_credentials_t c = cred;
|
|
Packit Service |
4684c1 |
unsigned i;
|
|
Packit Service |
4684c1 |
bool allow_tls13 = 0;
|
|
Packit Service |
4684c1 |
unsigned key_usage;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (c != NULL && c->ncerts != 0) {
|
|
Packit Service |
4684c1 |
for (i = 0; i < c->ncerts; i++) {
|
|
Packit Service |
4684c1 |
key_usage = get_key_usage(session, c->certs[i].cert_list[0].pubkey);
|
|
Packit Service |
4684c1 |
if (key_usage == 0 || (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)) {
|
|
Packit Service |
4684c1 |
allow_tls13 = 1;
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->security_parameters.entity == GNUTLS_SERVER &&
|
|
Packit Service |
4684c1 |
!c->tls13_ok)
|
|
Packit Service |
4684c1 |
allow_tls13 = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (!allow_tls13) {
|
|
Packit Service |
4684c1 |
/* to prevent the server random indicate TLS1.3 support */
|
|
Packit Service |
4684c1 |
session->internals.flags |= INT_FLAG_NO_TLS13;
|
|
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 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_credentials_get:
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
* @type: is the type of the credentials to return
|
|
Packit Service |
4684c1 |
* @cred: will contain the credentials.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns the previously provided credentials structures.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* For %GNUTLS_CRD_ANON, @cred will be
|
|
Packit Service |
4684c1 |
* #gnutls_anon_client_credentials_t in case of a client. In case of
|
|
Packit Service |
4684c1 |
* a server it should be #gnutls_anon_server_credentials_t.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* For %GNUTLS_CRD_SRP, @cred will be #gnutls_srp_client_credentials_t
|
|
Packit Service |
4684c1 |
* in case of a client, and #gnutls_srp_server_credentials_t, in case
|
|
Packit Service |
4684c1 |
* of a server.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* For %GNUTLS_CRD_CERTIFICATE, @cred will be
|
|
Packit Service |
4684c1 |
* #gnutls_certificate_credentials_t.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
|
|
Packit Service |
4684c1 |
* otherwise a negative error code is returned.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.3.3
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_credentials_get(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
gnutls_credentials_type_t type, void **cred)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
const void *_cred;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_cred = _gnutls_get_cred(session, type);
|
|
Packit Service |
4684c1 |
if (_cred == NULL)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (cred)
|
|
Packit Service |
4684c1 |
*cred = (void*)_cred;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_auth_get_type:
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns type of credentials for the current authentication schema.
|
|
Packit Service |
4684c1 |
* The returned information is to be used to distinguish the function used
|
|
Packit Service |
4684c1 |
* to access authentication data.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Eg. for CERTIFICATE ciphersuites (key exchange algorithms:
|
|
Packit Service |
4684c1 |
* %GNUTLS_KX_RSA, %GNUTLS_KX_DHE_RSA), the same function are to be
|
|
Packit Service |
4684c1 |
* used to access the authentication data.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Note that on resumed sessions, this function returns the schema
|
|
Packit Service |
4684c1 |
* used in the original session authentication.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: The type of credentials for the current authentication
|
|
Packit Service |
4684c1 |
* schema, a #gnutls_credentials_type_t type.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
gnutls_credentials_type_t gnutls_auth_get_type(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (session->security_parameters.entity == GNUTLS_SERVER)
|
|
Packit Service |
4684c1 |
return gnutls_auth_client_get_type(session);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
return gnutls_auth_server_get_type(session);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_auth_server_get_type:
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns the type of credentials that were used for server authentication.
|
|
Packit Service |
4684c1 |
* The returned information is to be used to distinguish the function used
|
|
Packit Service |
4684c1 |
* to access authentication data.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Note that on resumed sessions, this function returns the schema
|
|
Packit Service |
4684c1 |
* used in the original session authentication.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: The type of credentials for the server authentication
|
|
Packit Service |
4684c1 |
* schema, a #gnutls_credentials_type_t type.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
gnutls_credentials_type_t
|
|
Packit Service |
4684c1 |
gnutls_auth_server_get_type(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return session->security_parameters.server_auth_type;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_auth_client_get_type:
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns the type of credentials that were used for client authentication.
|
|
Packit Service |
4684c1 |
* The returned information is to be used to distinguish the function used
|
|
Packit Service |
4684c1 |
* to access authentication data.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Note that on resumed sessions, this function returns the schema
|
|
Packit Service |
4684c1 |
* used in the original session authentication.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: The type of credentials for the client authentication
|
|
Packit Service |
4684c1 |
* schema, a #gnutls_credentials_type_t type.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
gnutls_credentials_type_t
|
|
Packit Service |
4684c1 |
gnutls_auth_client_get_type(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return session->security_parameters.client_auth_type;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* This returns a pointer to the linked list. Don't
|
|
Packit Service |
4684c1 |
* free that!!!
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
const void *_gnutls_get_kx_cred(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
gnutls_kx_algorithm_t algo)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int server =
|
|
Packit Service |
4684c1 |
session->security_parameters.entity == GNUTLS_SERVER ? 1 : 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return _gnutls_get_cred(session,
|
|
Packit Service |
4684c1 |
_gnutls_map_kx_get_cred(algo, server));
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
const void *_gnutls_get_cred(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
gnutls_credentials_type_t type)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
auth_cred_st *ccred;
|
|
Packit Service |
4684c1 |
gnutls_key_st *key = &session->key;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ccred = key->cred;
|
|
Packit Service |
4684c1 |
while (ccred != NULL) {
|
|
Packit Service |
4684c1 |
if (ccred->algorithm == type) {
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
ccred = ccred->next;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
if (ccred == NULL)
|
|
Packit Service |
4684c1 |
return NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return ccred->credentials;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/*-
|
|
Packit Service |
4684c1 |
* _gnutls_free_auth_info - Frees the auth info structure
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function frees the auth info structure and sets it to
|
|
Packit Service |
4684c1 |
* null. It must be called since some structures contain malloced
|
|
Packit Service |
4684c1 |
* elements.
|
|
Packit Service |
4684c1 |
-*/
|
|
Packit Service |
4684c1 |
void _gnutls_free_auth_info(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
dh_info_st *dh_info;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
switch (session->key.auth_info_type) {
|
|
Packit Service |
4684c1 |
case GNUTLS_CRD_SRP:
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
#ifdef ENABLE_ANON
|
|
Packit Service |
4684c1 |
case GNUTLS_CRD_ANON:
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
anon_auth_info_t info =
|
|
Packit Service |
4684c1 |
_gnutls_get_auth_info(session, GNUTLS_CRD_ANON);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (info == NULL)
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
dh_info = &info->dh;
|
|
Packit Service |
4684c1 |
_gnutls_free_dh_info(dh_info);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
case GNUTLS_CRD_PSK:
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
psk_auth_info_t info =
|
|
Packit Service |
4684c1 |
_gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (info == NULL)
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#ifdef ENABLE_DHE
|
|
Packit Service |
4684c1 |
dh_info = &info->dh;
|
|
Packit Service |
4684c1 |
_gnutls_free_dh_info(dh_info);
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
case GNUTLS_CRD_CERTIFICATE:
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
unsigned int i;
|
|
Packit Service |
4684c1 |
cert_auth_info_t info =
|
|
Packit Service |
4684c1 |
_gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (info == NULL)
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
dh_info = &info->dh;
|
|
Packit Service |
4684c1 |
for (i = 0; i < info->ncerts; i++) {
|
|
Packit Service |
4684c1 |
_gnutls_free_datum(&info->raw_certificate_list[i]);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
for (i = 0; i < info->nocsp; i++) {
|
|
Packit Service |
4684c1 |
_gnutls_free_datum(&info->raw_ocsp_list[i]);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_free(info->raw_certificate_list);
|
|
Packit Service |
4684c1 |
gnutls_free(info->raw_ocsp_list);
|
|
Packit Service |
4684c1 |
info->ncerts = 0;
|
|
Packit Service |
4684c1 |
info->nocsp = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#ifdef ENABLE_DHE
|
|
Packit Service |
4684c1 |
_gnutls_free_dh_info(dh_info);
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
default:
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_free(session->key.auth_info);
|
|
Packit Service |
4684c1 |
session->key.auth_info_size = 0;
|
|
Packit Service |
4684c1 |
session->key.auth_info_type = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* This function will create the auth info structure in the key
|
|
Packit Service |
4684c1 |
* structure if needed.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* If allow change is !=0 then this will allow changing the auth
|
|
Packit Service |
4684c1 |
* info structure to a different type.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
_gnutls_auth_info_init(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
gnutls_credentials_type_t type, int size,
|
|
Packit Service |
4684c1 |
int allow_change)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (session->key.auth_info == NULL) {
|
|
Packit Service |
4684c1 |
session->key.auth_info = gnutls_calloc(1, size);
|
|
Packit Service |
4684c1 |
if (session->key.auth_info == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
session->key.auth_info_type = type;
|
|
Packit Service |
4684c1 |
session->key.auth_info_size = size;
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
if (allow_change == 0) {
|
|
Packit Service |
4684c1 |
/* If the credentials for the current authentication scheme,
|
|
Packit Service |
4684c1 |
* are not the one we want to set, then it's an error.
|
|
Packit Service |
4684c1 |
* This may happen if a rehandshake is performed an the
|
|
Packit Service |
4684c1 |
* ciphersuite which is negotiated has different authentication
|
|
Packit Service |
4684c1 |
* schema.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if (type != session->key.auth_info_type) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
/* The new behaviour: Here we reallocate the auth info structure
|
|
Packit Service |
4684c1 |
* in order to be able to negotiate different authentication
|
|
Packit Service |
4684c1 |
* types. Ie. perform an auth_anon and then authenticate again using a
|
|
Packit Service |
4684c1 |
* certificate (in order to prevent revealing the certificate's contents,
|
|
Packit Service |
4684c1 |
* to passive eavesdropers.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if (type != session->key.auth_info_type) {
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_free_auth_info(session);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session->key.auth_info = calloc(1, size);
|
|
Packit Service |
4684c1 |
if (session->key.auth_info == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session->key.auth_info_type = type;
|
|
Packit Service |
4684c1 |
session->key.auth_info_size = size;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|