|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* Copyright (C) 2000-2012 Free Software Foundation, 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 |
/* This file contains functions which are wrappers for the key exchange
|
|
Packit Service |
4684c1 |
* part of TLS. They are called by the handshake functions (gnutls_handshake)
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include "gnutls_int.h"
|
|
Packit Service |
4684c1 |
#include "handshake.h"
|
|
Packit Service |
4684c1 |
#include "kx.h"
|
|
Packit Service |
4684c1 |
#include "dh.h"
|
|
Packit Service |
4684c1 |
#include "errors.h"
|
|
Packit Service |
4684c1 |
#include "algorithms.h"
|
|
Packit Service |
4684c1 |
#include "debug.h"
|
|
Packit Service |
4684c1 |
#include "locks.h"
|
|
Packit Service |
4684c1 |
#include "mpi.h"
|
|
Packit Service |
4684c1 |
#include <state.h>
|
|
Packit Service |
4684c1 |
#include <datum.h>
|
|
Packit Service |
4684c1 |
#include <mbuffers.h>
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* This file contains important thing for the TLS handshake procedure.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define MASTER_SECRET "master secret"
|
|
Packit Service |
4684c1 |
#define MASTER_SECRET_SIZE (sizeof(MASTER_SECRET)-1)
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define EXT_MASTER_SECRET "extended master secret"
|
|
Packit Service |
4684c1 |
#define EXT_MASTER_SECRET_SIZE (sizeof(EXT_MASTER_SECRET)-1)
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
GNUTLS_STATIC_MUTEX(keylog_mutex);
|
|
Packit Service |
4684c1 |
static FILE *keylog;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int generate_normal_master(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
gnutls_datum_t *, int);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int _gnutls_generate_master(gnutls_session_t session, int keep_premaster)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (session->internals.resumed == RESUME_FALSE)
|
|
Packit Service |
4684c1 |
return generate_normal_master(session, &session->key.key,
|
|
Packit Service |
4684c1 |
keep_premaster);
|
|
Packit Service |
4684c1 |
else if (session->internals.premaster_set) {
|
|
Packit Service |
4684c1 |
gnutls_datum_t premaster;
|
|
Packit Service |
4684c1 |
premaster.size =
|
|
Packit Service |
4684c1 |
sizeof(session->internals.resumed_security_parameters.
|
|
Packit Service |
4684c1 |
master_secret);
|
|
Packit Service |
4684c1 |
premaster.data =
|
|
Packit Service |
4684c1 |
session->internals.resumed_security_parameters.
|
|
Packit Service |
4684c1 |
master_secret;
|
|
Packit Service |
4684c1 |
return generate_normal_master(session, &premaster, 1);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_session_get_keylog_function:
|
|
Packit Service |
4684c1 |
* @session: is #gnutls_session_t type
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will return the callback function set using
|
|
Packit Service |
4684c1 |
* gnutls_session_set_keylog_function().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: The function set or %NULL otherwise.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.6.13
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
gnutls_keylog_func
|
|
Packit Service |
4684c1 |
gnutls_session_get_keylog_function(const gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return session->internals.keylog_func;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_session_set_keylog_function:
|
|
Packit Service |
4684c1 |
* @session: is #gnutls_session_t type
|
|
Packit Service |
4684c1 |
* @func: is the function to be called
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will set a callback to be called when a new secret is
|
|
Packit Service |
4684c1 |
* derived and installed during handshake.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.6.13
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
void
|
|
Packit Service |
4684c1 |
gnutls_session_set_keylog_function(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
gnutls_keylog_func func)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
session->internals.keylog_func = func;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
_gnutls_call_keylog_func(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
const char *label,
|
|
Packit Service |
4684c1 |
const uint8_t *data,
|
|
Packit Service |
4684c1 |
unsigned size)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (session->internals.keylog_func) {
|
|
Packit Service |
4684c1 |
gnutls_datum_t secret = {(void*)data, size};
|
|
Packit Service |
4684c1 |
return session->internals.keylog_func(session, label, &secret);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
_gnutls_nss_keylog_func(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
const char *label,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t *secret)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
/* ignore subsequent traffic secrets that are calculated from
|
|
Packit Service |
4684c1 |
* the previous traffic secret
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if (!session->internals.handshake_in_progress)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_nss_keylog_write(session, label, secret->data, secret->size);
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void _gnutls_nss_keylog_write(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
const char *label,
|
|
Packit Service |
4684c1 |
const uint8_t *secret, size_t secret_size)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
static const char *keylogfile = NULL;
|
|
Packit Service |
4684c1 |
static unsigned checked_env = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (!checked_env) {
|
|
Packit Service |
4684c1 |
checked_env = 1;
|
|
Packit Service |
4684c1 |
keylogfile = secure_getenv("SSLKEYLOGFILE");
|
|
Packit Service |
4684c1 |
if (keylogfile != NULL)
|
|
Packit Service |
4684c1 |
keylog = fopen(keylogfile, "ae");
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (keylog) {
|
|
Packit Service |
4684c1 |
char client_random_hex[2*GNUTLS_RANDOM_SIZE+1];
|
|
Packit Service |
4684c1 |
char secret_hex[2*MAX_HASH_SIZE+1];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
GNUTLS_STATIC_MUTEX_LOCK(keylog_mutex);
|
|
Packit Service |
4684c1 |
fprintf(keylog, "%s %s %s\n",
|
|
Packit Service |
4684c1 |
label,
|
|
Packit Service |
4684c1 |
_gnutls_bin2hex(session->security_parameters.
|
|
Packit Service |
4684c1 |
client_random, GNUTLS_RANDOM_SIZE,
|
|
Packit Service |
4684c1 |
client_random_hex,
|
|
Packit Service |
4684c1 |
sizeof(client_random_hex), NULL),
|
|
Packit Service |
4684c1 |
_gnutls_bin2hex(secret, secret_size,
|
|
Packit Service |
4684c1 |
secret_hex, sizeof(secret_hex), NULL));
|
|
Packit Service |
4684c1 |
fflush(keylog);
|
|
Packit Service |
4684c1 |
GNUTLS_STATIC_MUTEX_UNLOCK(keylog_mutex);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void _gnutls_nss_keylog_deinit(void)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (keylog) {
|
|
Packit Service |
4684c1 |
fclose(keylog);
|
|
Packit Service |
4684c1 |
keylog = NULL;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* here we generate the TLS Master secret.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
generate_normal_master(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
gnutls_datum_t * premaster, int keep_premaster)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
char buf[512];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_hard_log("INT: PREMASTER SECRET[%d]: %s\n",
|
|
Packit Service |
4684c1 |
premaster->size, _gnutls_bin2hex(premaster->data,
|
|
Packit Service |
4684c1 |
premaster->size,
|
|
Packit Service |
4684c1 |
buf, sizeof(buf),
|
|
Packit Service |
4684c1 |
NULL));
|
|
Packit Service |
4684c1 |
_gnutls_hard_log("INT: CLIENT RANDOM[%d]: %s\n", 32,
|
|
Packit Service |
4684c1 |
_gnutls_bin2hex(session->security_parameters.
|
|
Packit Service |
4684c1 |
client_random, 32, buf,
|
|
Packit Service |
4684c1 |
sizeof(buf), NULL));
|
|
Packit Service |
4684c1 |
_gnutls_hard_log("INT: SERVER RANDOM[%d]: %s\n", 32,
|
|
Packit Service |
4684c1 |
_gnutls_bin2hex(session->security_parameters.
|
|
Packit Service |
4684c1 |
server_random, 32, buf,
|
|
Packit Service |
4684c1 |
sizeof(buf), NULL));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->security_parameters.ext_master_secret == 0) {
|
|
Packit Service |
4684c1 |
uint8_t rnd[2 * GNUTLS_RANDOM_SIZE + 1];
|
|
Packit Service |
4684c1 |
memcpy(rnd, session->security_parameters.client_random,
|
|
Packit Service |
4684c1 |
GNUTLS_RANDOM_SIZE);
|
|
Packit Service |
4684c1 |
memcpy(&rnd[GNUTLS_RANDOM_SIZE],
|
|
Packit Service |
4684c1 |
session->security_parameters.server_random,
|
|
Packit Service |
4684c1 |
GNUTLS_RANDOM_SIZE);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#ifdef ENABLE_SSL3
|
|
Packit Service |
4684c1 |
if (get_num_version(session) == GNUTLS_SSL3) {
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_ssl3_generate_random(premaster->data,
|
|
Packit Service |
4684c1 |
premaster->size, rnd,
|
|
Packit Service |
4684c1 |
2 * GNUTLS_RANDOM_SIZE,
|
|
Packit Service |
4684c1 |
GNUTLS_MASTER_SIZE,
|
|
Packit Service |
4684c1 |
session->security_parameters.
|
|
Packit Service |
4684c1 |
master_secret);
|
|
Packit Service |
4684c1 |
} else
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_PRF(session, premaster->data, premaster->size,
|
|
Packit Service |
4684c1 |
MASTER_SECRET, MASTER_SECRET_SIZE,
|
|
Packit Service |
4684c1 |
rnd, 2 * GNUTLS_RANDOM_SIZE,
|
|
Packit Service |
4684c1 |
GNUTLS_MASTER_SIZE,
|
|
Packit Service |
4684c1 |
session->security_parameters.
|
|
Packit Service |
4684c1 |
master_secret);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
gnutls_datum_t shash = {NULL, 0};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* draft-ietf-tls-session-hash-02 */
|
|
Packit Service |
4684c1 |
ret = _gnutls_handshake_get_session_hash(session, &shash);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
#ifdef ENABLE_SSL3
|
|
Packit Service |
4684c1 |
if (get_num_version(session) == GNUTLS_SSL3)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_PRF(session, premaster->data, premaster->size,
|
|
Packit Service |
4684c1 |
EXT_MASTER_SECRET, EXT_MASTER_SECRET_SIZE,
|
|
Packit Service |
4684c1 |
shash.data, shash.size,
|
|
Packit Service |
4684c1 |
GNUTLS_MASTER_SIZE,
|
|
Packit Service |
4684c1 |
session->security_parameters.
|
|
Packit Service |
4684c1 |
master_secret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_free(shash.data);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (!keep_premaster)
|
|
Packit Service |
4684c1 |
_gnutls_free_temp_key_datum(premaster);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_call_keylog_func(session, "CLIENT_RANDOM",
|
|
Packit Service |
4684c1 |
session->security_parameters.master_secret,
|
|
Packit Service |
4684c1 |
GNUTLS_MASTER_SIZE);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_hard_log("INT: MASTER SECRET[%d]: %s\n",
|
|
Packit Service |
4684c1 |
GNUTLS_MASTER_SIZE,
|
|
Packit Service |
4684c1 |
_gnutls_bin2hex(session->security_parameters.
|
|
Packit Service |
4684c1 |
master_secret, GNUTLS_MASTER_SIZE,
|
|
Packit Service |
4684c1 |
buf, sizeof(buf), NULL));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* This is called when we want to receive the key exchange message of the
|
|
Packit Service |
4684c1 |
* server. It does nothing if this type of message is not required
|
|
Packit Service |
4684c1 |
* by the selected ciphersuite.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
int _gnutls_send_server_kx_message(gnutls_session_t session, int again)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st buf;
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
mbuffer_st *bufel = NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.auth_struct->gnutls_generate_server_kx ==
|
|
Packit Service |
4684c1 |
NULL)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (again == 0) {
|
|
Packit Service |
4684c1 |
ret = _gnutls_buffer_init_handshake_mbuffer(&buf;;
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_generate_server_kx(session, &buf;;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret == GNUTLS_E_INT_RET_0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = 0;
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
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 |
bufel = _gnutls_buffer_to_mbuffer(&buf;;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&buf;;
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* This function sends a certificate request message to the
|
|
Packit Service |
4684c1 |
* client.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
int _gnutls_send_server_crt_request(gnutls_session_t session, int again)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st buf;
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
mbuffer_st *bufel = NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_generate_server_crt_request == NULL)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.send_cert_req <= 0)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (again == 0) {
|
|
Packit Service |
4684c1 |
ret = _gnutls_buffer_init_handshake_mbuffer(&buf;;
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_generate_server_crt_request(session, &buf;;
|
|
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 |
bufel = _gnutls_buffer_to_mbuffer(&buf;;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&buf;;
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* This is the function for the client to send the key
|
|
Packit Service |
4684c1 |
* exchange message
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
int _gnutls_send_client_kx_message(gnutls_session_t session, int again)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st buf;
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
mbuffer_st *bufel = NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.auth_struct->gnutls_generate_client_kx ==
|
|
Packit Service |
4684c1 |
NULL)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (again == 0) {
|
|
Packit Service |
4684c1 |
ret = _gnutls_buffer_init_handshake_mbuffer(&buf;;
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_generate_client_kx(session, &buf;;
|
|
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 |
bufel = _gnutls_buffer_to_mbuffer(&buf;;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&buf;;
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* This is the function for the client to send the certificate
|
|
Packit Service |
4684c1 |
* verify message
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
_gnutls_send_client_certificate_verify(gnutls_session_t session, int again)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st buf;
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
mbuffer_st *bufel = NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* This is a packet that is only sent by the client
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if (session->security_parameters.entity == GNUTLS_SERVER)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* if certificate verify is not needed just exit
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if (!(session->internals.hsk_flags & HSK_CRT_ASKED))
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_generate_client_crt_vrfy == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return 0; /* this algorithm does not support cli_crt_vrfy
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (again == 0) {
|
|
Packit Service |
4684c1 |
ret = _gnutls_buffer_init_handshake_mbuffer(&buf;;
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_generate_client_crt_vrfy(session, &buf;;
|
|
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 (ret == 0)
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
bufel = _gnutls_buffer_to_mbuffer(&buf;;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&buf;;
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* This is called when we want send our certificate
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
int _gnutls_send_client_certificate(gnutls_session_t session, int again)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st buf;
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
mbuffer_st *bufel = NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (!(session->internals.hsk_flags & HSK_CRT_ASKED))
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_generate_client_certificate == NULL)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (again == 0) {
|
|
Packit Service |
4684c1 |
ret = _gnutls_buffer_init_handshake_mbuffer(&buf;;
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#ifdef ENABLE_SSL3
|
|
Packit Service |
4684c1 |
if (get_num_version(session) != GNUTLS_SSL3 ||
|
|
Packit Service |
4684c1 |
session->internals.selected_cert_list_length > 0)
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
/* TLS 1.x or SSL 3.0 with a valid certificate
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_generate_client_certificate(session,
|
|
Packit Service |
4684c1 |
&buf;;
|
|
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 |
|
|
Packit Service |
4684c1 |
bufel = _gnutls_buffer_to_mbuffer(&buf;;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#ifdef ENABLE_SSL3
|
|
Packit Service |
4684c1 |
/* In the SSL 3.0 protocol we need to send a
|
|
Packit Service |
4684c1 |
* no certificate alert instead of an
|
|
Packit Service |
4684c1 |
* empty certificate.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if (get_num_version(session) == GNUTLS_SSL3 &&
|
|
Packit Service |
4684c1 |
session->internals.selected_cert_list_length == 0) {
|
|
Packit Service |
4684c1 |
_mbuffer_xfree(&bufel);
|
|
Packit Service |
4684c1 |
return
|
|
Packit Service |
4684c1 |
gnutls_alert_send(session, GNUTLS_AL_WARNING,
|
|
Packit Service |
4684c1 |
GNUTLS_A_SSL3_NO_CERTIFICATE);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
} else /* TLS 1.0 or SSL 3.0 with a valid certificate
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&buf;;
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* This is called when we want send our certificate
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
int _gnutls_send_server_certificate(gnutls_session_t session, int again)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st buf;
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
mbuffer_st *bufel = NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_generate_server_certificate == NULL)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (again == 0) {
|
|
Packit Service |
4684c1 |
ret = _gnutls_buffer_init_handshake_mbuffer(&buf;;
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_generate_server_certificate(session, &buf;;
|
|
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 |
bufel = _gnutls_buffer_to_mbuffer(&buf;;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&buf;;
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int _gnutls_recv_server_kx_message(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st buf;
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
unsigned int optflag = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.auth_struct->gnutls_process_server_kx !=
|
|
Packit Service |
4684c1 |
NULL) {
|
|
Packit Service |
4684c1 |
/* Server key exchange packet is optional for PSK. */
|
|
Packit Service |
4684c1 |
if (_gnutls_session_is_psk(session))
|
|
Packit Service |
4684c1 |
optflag = 1;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_recv_handshake(session,
|
|
Packit Service |
4684c1 |
GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE,
|
|
Packit Service |
4684c1 |
optflag, &buf;;
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_process_server_kx(session, buf.data,
|
|
Packit Service |
4684c1 |
buf.length);
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&buf;;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int _gnutls_recv_server_crt_request(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st buf;
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_process_server_crt_request != NULL) {
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_recv_handshake(session,
|
|
Packit Service |
4684c1 |
GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST,
|
|
Packit Service |
4684c1 |
1, &buf;;
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret == 0 && buf.length == 0) {
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&buf;;
|
|
Packit Service |
4684c1 |
return 0; /* ignored */
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_process_server_crt_request(session, buf.data,
|
|
Packit Service |
4684c1 |
buf.length);
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&buf;;
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int _gnutls_recv_client_kx_message(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st buf;
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Do key exchange only if the algorithm permits it */
|
|
Packit Service |
4684c1 |
if (session->internals.auth_struct->gnutls_process_client_kx !=
|
|
Packit Service |
4684c1 |
NULL) {
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_recv_handshake(session,
|
|
Packit Service |
4684c1 |
GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE,
|
|
Packit Service |
4684c1 |
0, &buf;;
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_process_client_kx(session, buf.data,
|
|
Packit Service |
4684c1 |
buf.length);
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&buf;;
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int _gnutls_recv_client_certificate(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st buf;
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
int optional;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_process_client_certificate == NULL)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* if we have not requested a certificate then just return
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if (session->internals.send_cert_req == 0) {
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.send_cert_req == GNUTLS_CERT_REQUIRE)
|
|
Packit Service |
4684c1 |
optional = 0;
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
optional = 1;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_recv_handshake(session,
|
|
Packit Service |
4684c1 |
GNUTLS_HANDSHAKE_CERTIFICATE_PKT,
|
|
Packit Service |
4684c1 |
optional, &buf;;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
/* Handle the case of old SSL3 clients who send
|
|
Packit Service |
4684c1 |
* a warning alert instead of an empty certificate to indicate
|
|
Packit Service |
4684c1 |
* no certificate.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
#ifdef ENABLE_SSL3
|
|
Packit Service |
4684c1 |
if (optional != 0 &&
|
|
Packit Service |
4684c1 |
ret == GNUTLS_E_WARNING_ALERT_RECEIVED &&
|
|
Packit Service |
4684c1 |
get_num_version(session) == GNUTLS_SSL3 &&
|
|
Packit Service |
4684c1 |
gnutls_alert_get(session) ==
|
|
Packit Service |
4684c1 |
GNUTLS_A_SSL3_NO_CERTIFICATE) {
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* SSL3 does not send an empty certificate,
|
|
Packit Service |
4684c1 |
* but this alert. So we just ignore it.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* certificate was required
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED
|
|
Packit Service |
4684c1 |
|| ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
|
|
Packit Service |
4684c1 |
&& optional == 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_NO_CERTIFICATE_FOUND;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret == 0 && buf.length == 0 && optional != 0) {
|
|
Packit Service |
4684c1 |
/* Client has not sent the certificate message.
|
|
Packit Service |
4684c1 |
* well I'm not sure we should accept this
|
|
Packit Service |
4684c1 |
* behaviour.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = 0;
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_process_client_certificate(session, buf.data,
|
|
Packit Service |
4684c1 |
buf.length);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret < 0 && ret != GNUTLS_E_NO_CERTIFICATE_FOUND) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* ok we should expect a certificate verify message now
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND && optional != 0)
|
|
Packit Service |
4684c1 |
ret = 0;
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
session->internals.hsk_flags |= HSK_CRT_VRFY_EXPECTED;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&buf;;
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int _gnutls_recv_server_certificate(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st buf;
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_process_server_certificate != NULL) {
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_recv_handshake(session,
|
|
Packit Service |
4684c1 |
GNUTLS_HANDSHAKE_CERTIFICATE_PKT,
|
|
Packit Service |
4684c1 |
0, &buf;;
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_process_server_certificate(session, buf.data,
|
|
Packit Service |
4684c1 |
buf.length);
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&buf;;
|
|
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 |
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Recv the client certificate verify. This packet may not
|
|
Packit Service |
4684c1 |
* arrive if the peer did not send us a certificate.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
_gnutls_recv_client_certificate_verify_message(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_buffer_st buf;
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_process_client_crt_vrfy == NULL)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.send_cert_req == 0 ||
|
|
Packit Service |
4684c1 |
(!(session->internals.hsk_flags & HSK_CRT_VRFY_EXPECTED))) {
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_recv_handshake(session,
|
|
Packit Service |
4684c1 |
GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY,
|
|
Packit Service |
4684c1 |
1, &buf;;
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret == 0 && buf.length == 0
|
|
Packit Service |
4684c1 |
&& session->internals.send_cert_req == GNUTLS_CERT_REQUIRE) {
|
|
Packit Service |
4684c1 |
/* certificate was required */
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
ret = GNUTLS_E_NO_CERTIFICATE_FOUND;
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
session->internals.auth_struct->
|
|
Packit Service |
4684c1 |
gnutls_process_client_crt_vrfy(session, buf.data, buf.length);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
_gnutls_buffer_clear(&buf;;
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|