|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* Copyright (C) 2000-2016 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 |
#include "gnutls_int.h"
|
|
Packit Service |
4684c1 |
#include "errors.h"
|
|
Packit Service |
4684c1 |
#include "debug.h"
|
|
Packit Service |
4684c1 |
#include <session_pack.h>
|
|
Packit Service |
4684c1 |
#include <datum.h>
|
|
Packit Service |
4684c1 |
#include "buffers.h"
|
|
Packit Service |
4684c1 |
#include "state.h"
|
|
Packit Service |
4684c1 |
#include "ext/cert_types.h"
|
|
Packit Service |
4684c1 |
#include <minmax.h>
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_session_get_data:
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
* @session_data: is a pointer to space to hold the session.
|
|
Packit Service |
4684c1 |
* @session_data_size: is the session_data's size, or it will be set by the function.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns all session parameters needed to be stored to support resumption,
|
|
Packit Service |
4684c1 |
* in a pre-allocated buffer.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* See gnutls_session_get_data2() for more information.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
|
|
Packit Service |
4684c1 |
* an error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_session_get_data(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
void *session_data, size_t * session_data_size)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_datum_t psession;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_session_get_data2(session, &psession);
|
|
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 |
if (psession.size > *session_data_size) {
|
|
Packit Service |
4684c1 |
*session_data_size = psession.size;
|
|
Packit Service |
4684c1 |
ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
|
|
Packit Service |
4684c1 |
goto error;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
*session_data_size = psession.size;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session_data != NULL)
|
|
Packit Service |
4684c1 |
memcpy(session_data, psession.data, psession.size);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
error:
|
|
Packit Service |
4684c1 |
_gnutls_free_datum(&psession);
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define EMPTY_DATA "\x00\x00\x00\x00"
|
|
Packit Service |
4684c1 |
#define EMPTY_DATA_SIZE 4
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_session_get_data2:
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
* @data: is a pointer to a datum that will hold the session.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns necessary parameters to support resumption. The client
|
|
Packit Service |
4684c1 |
* should call this function and store the returned session data. A session
|
|
Packit Service |
4684c1 |
* can be resumed later by calling gnutls_session_set_data() with the returned
|
|
Packit Service |
4684c1 |
* data. Note that under TLS 1.3, it is recommended for clients to use
|
|
Packit Service |
4684c1 |
* session parameters only once, to prevent passive-observers from correlating
|
|
Packit Service |
4684c1 |
* the different connections.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* The returned @data are allocated and must be released using gnutls_free().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will fail if called prior to handshake completion. In
|
|
Packit Service |
4684c1 |
* case of false start TLS, the handshake completes only after data have
|
|
Packit Service |
4684c1 |
* been successfully received from the peer.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Under TLS1.3 session resumption is possible only after a session ticket
|
|
Packit Service |
4684c1 |
* is received by the client. To ensure that such a ticket has been received use
|
|
Packit Service |
4684c1 |
* gnutls_session_get_flags() and check for flag %GNUTLS_SFLAGS_SESSION_TICKET;
|
|
Packit Service |
4684c1 |
* if this flag is not set, this function will wait for a new ticket within
|
|
Packit Service |
4684c1 |
* an estimated rountrip, and if not received will return dummy data which
|
|
Packit Service |
4684c1 |
* cannot lead to resumption.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* To get notified when new tickets are received by the server
|
|
Packit Service |
4684c1 |
* use gnutls_handshake_set_hook_function() to wait for %GNUTLS_HANDSHAKE_NEW_SESSION_TICKET
|
|
Packit Service |
4684c1 |
* messages. Each call of gnutls_session_get_data2() after a ticket is
|
|
Packit Service |
4684c1 |
* received, will return session resumption data corresponding to the last
|
|
Packit Service |
4684c1 |
* received ticket.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Note that this function under TLS1.3 requires a callback to be set with
|
|
Packit Service |
4684c1 |
* gnutls_transport_set_pull_timeout_function() for successful operation. There
|
|
Packit Service |
4684c1 |
* was a bug before 3.6.10 which could make this function fail if that callback
|
|
Packit Service |
4684c1 |
* was not set. On later versions if not set, the function will return a successful
|
|
Packit Service |
4684c1 |
* error code, but will return dummy data that cannot lead to a resumption.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
|
|
Packit Service |
4684c1 |
* an error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_session_get_data2(gnutls_session_t session, gnutls_datum_t *data)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
const version_entry_st *vers = get_version(session);
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (data == NULL || vers == NULL) {
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (vers->tls13_sem && !(session->internals.hsk_flags & HSK_TICKET_RECEIVED)) {
|
|
Packit Service |
4684c1 |
unsigned ertt = session->internals.ertt;
|
|
Packit Service |
4684c1 |
/* use our estimation of round-trip + some time for the server to calculate
|
|
Packit Service |
4684c1 |
* the value(s). */
|
|
Packit Service |
4684c1 |
ertt += 60;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* we cannot use a read with timeout if the caller has not set
|
|
Packit Service |
4684c1 |
* a callback with gnutls_transport_set_pull_timeout_function() */
|
|
Packit Service |
4684c1 |
if (NO_TIMEOUT_FUNC_SET(session) || (session->internals.flags & GNUTLS_NONBLOCK)) {
|
|
Packit Service |
4684c1 |
if (!(session->internals.flags & GNUTLS_NONBLOCK))
|
|
Packit Service |
4684c1 |
_gnutls_debug_log("TLS1.3 works efficiently if a callback with gnutls_transport_set_pull_timeout_function() is set\n");
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
/* wait for a message with timeout */
|
|
Packit Service |
4684c1 |
ret = _gnutls_recv_in_buffers(session, GNUTLS_APPLICATION_DATA, -1, ertt);
|
|
Packit Service |
4684c1 |
if (ret < 0 && (gnutls_error_is_fatal(ret) && ret != GNUTLS_E_TIMEDOUT)) {
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (!(session->internals.hsk_flags & HSK_TICKET_RECEIVED)) {
|
|
Packit Service |
4684c1 |
ret = _gnutls_set_datum(data, EMPTY_DATA, EMPTY_DATA_SIZE);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else if (!vers->tls13_sem) {
|
|
Packit Service |
4684c1 |
/* under TLS1.3 we want to pack the latest ticket, while that's
|
|
Packit Service |
4684c1 |
* not the case in TLS1.2 or earlier. */
|
|
Packit Service |
4684c1 |
if (gnutls_session_is_resumed(session) && session->internals.resumption_data.data) {
|
|
Packit Service |
4684c1 |
ret = _gnutls_set_datum(data, session->internals.resumption_data.data, session->internals.resumption_data.size);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.resumable == RESUME_FALSE)
|
|
Packit Service |
4684c1 |
return GNUTLS_E_INVALID_SESSION;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_session_pack(session, data);
|
|
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 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_session_get_id:
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
* @session_id: is a pointer to space to hold the session id.
|
|
Packit Service |
4684c1 |
* @session_id_size: initially should contain the maximum @session_id size and will be updated.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns the TLS session identifier. The session ID is selected by the
|
|
Packit Service |
4684c1 |
* server, and in older versions of TLS was a unique identifier shared
|
|
Packit Service |
4684c1 |
* between client and server which was persistent across resumption.
|
|
Packit Service |
4684c1 |
* In the latest version of TLS (1.3) or TLS with session tickets, the
|
|
Packit Service |
4684c1 |
* notion of session identifiers is undefined and cannot be relied for uniquely
|
|
Packit Service |
4684c1 |
* identifying sessions across client and server.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* In client side this function returns the identifier returned by the
|
|
Packit Service |
4684c1 |
* server, and cannot be assumed to have any relation to session resumption.
|
|
Packit Service |
4684c1 |
* In server side this function is guaranteed to return a persistent
|
|
Packit Service |
4684c1 |
* identifier of the session since GnuTLS 3.6.4, which may not necessarily
|
|
Packit Service |
4684c1 |
* map into the TLS session ID value. Prior to that version the value
|
|
Packit Service |
4684c1 |
* could only be considered a persistent identifier, under TLS1.2 or earlier
|
|
Packit Service |
4684c1 |
* and when no session tickets were in use.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* The session identifier value returned is always less than
|
|
Packit Service |
4684c1 |
* %GNUTLS_MAX_SESSION_ID_SIZE.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
|
|
Packit Service |
4684c1 |
* an error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_session_get_id(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
void *session_id, size_t * session_id_size)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
size_t given_session_id_size = *session_id_size;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
*session_id_size = session->security_parameters.session_id_size;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* just return the session size */
|
|
Packit Service |
4684c1 |
if (session_id == NULL) {
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (given_session_id_size <
|
|
Packit Service |
4684c1 |
session->security_parameters.session_id_size) {
|
|
Packit Service |
4684c1 |
return GNUTLS_E_SHORT_MEMORY_BUFFER;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memcpy(session_id, &session->security_parameters.session_id,
|
|
Packit Service |
4684c1 |
*session_id_size);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_session_get_id2:
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
* @session_id: will point to the session ID.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns the TLS session identifier. The session ID is selected by the
|
|
Packit Service |
4684c1 |
* server, and in older versions of TLS was a unique identifier shared
|
|
Packit Service |
4684c1 |
* between client and server which was persistent across resumption.
|
|
Packit Service |
4684c1 |
* In the latest version of TLS (1.3) or TLS 1.2 with session tickets, the
|
|
Packit Service |
4684c1 |
* notion of session identifiers is undefined and cannot be relied for uniquely
|
|
Packit Service |
4684c1 |
* identifying sessions across client and server.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* In client side this function returns the identifier returned by the
|
|
Packit Service |
4684c1 |
* server, and cannot be assumed to have any relation to session resumption.
|
|
Packit Service |
4684c1 |
* In server side this function is guaranteed to return a persistent
|
|
Packit Service |
4684c1 |
* identifier of the session since GnuTLS 3.6.4, which may not necessarily
|
|
Packit Service |
4684c1 |
* map into the TLS session ID value. Prior to that version the value
|
|
Packit Service |
4684c1 |
* could only be considered a persistent identifier, under TLS1.2 or earlier
|
|
Packit Service |
4684c1 |
* and when no session tickets were in use.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* The session identifier value returned is always less than
|
|
Packit Service |
4684c1 |
* %GNUTLS_MAX_SESSION_ID_SIZE and should be treated as constant.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
|
|
Packit Service |
4684c1 |
* an error code is returned.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.1.4
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_session_get_id2(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
gnutls_datum_t * session_id)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
session_id->size = session->security_parameters.session_id_size;
|
|
Packit Service |
4684c1 |
session_id->data = session->security_parameters.session_id;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_session_set_data:
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
* @session_data: is a pointer to space to hold the session.
|
|
Packit Service |
4684c1 |
* @session_data_size: is the session's size
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Sets all session parameters, in order to resume a previously
|
|
Packit Service |
4684c1 |
* established session. The session data given must be the one
|
|
Packit Service |
4684c1 |
* returned by gnutls_session_get_data(). This function should be
|
|
Packit Service |
4684c1 |
* called before gnutls_handshake().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Keep in mind that session resuming is advisory. The server may
|
|
Packit Service |
4684c1 |
* choose not to resume the session, thus a full handshake will be
|
|
Packit Service |
4684c1 |
* performed.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
|
|
Packit Service |
4684c1 |
* an error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_session_set_data(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
const void *session_data, size_t session_data_size)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
gnutls_datum_t psession;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
psession.data = (uint8_t *) session_data;
|
|
Packit Service |
4684c1 |
psession.size = session_data_size;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session_data == NULL || session_data_size == 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* under TLS1.3 we always return some data on resumption when there
|
|
Packit Service |
4684c1 |
* is no ticket in order to keep compatibility with existing apps */
|
|
Packit Service |
4684c1 |
if (session_data_size == EMPTY_DATA_SIZE &&
|
|
Packit Service |
4684c1 |
memcmp(session_data, EMPTY_DATA, EMPTY_DATA_SIZE) == 0) {
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_session_unpack(session, &psession);
|
|
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 |
session->internals.resumption_requested = 1;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.resumption_data.data != NULL)
|
|
Packit Service |
4684c1 |
gnutls_free(session->internals.resumption_data.data);
|
|
Packit Service |
4684c1 |
ret = _gnutls_set_datum(&session->internals.resumption_data, session_data, session_data_size);
|
|
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 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_session_force_valid:
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Clears the invalid flag in a session. That means
|
|
Packit Service |
4684c1 |
* that sessions were corrupt or invalid data were received
|
|
Packit Service |
4684c1 |
* can be re-used. Use only when debugging or experimenting
|
|
Packit Service |
4684c1 |
* with the TLS protocol. Should not be used in typical
|
|
Packit Service |
4684c1 |
* applications.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
void gnutls_session_force_valid(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
session->internals.invalid_connection = 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define DESC_SIZE 96
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_session_get_desc:
|
|
Packit Service |
4684c1 |
* @session: is a gnutls session
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function returns a string describing the current session.
|
|
Packit Service |
4684c1 |
* The string is null terminated and allocated using gnutls_malloc().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* If initial negotiation is not complete when this function is called,
|
|
Packit Service |
4684c1 |
* %NULL will be returned.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: a description of the protocols and algorithms in the current session.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.1.10
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
char *gnutls_session_get_desc(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_kx_algorithm_t kx;
|
|
Packit Service |
4684c1 |
const char *kx_str, *sign_str;
|
|
Packit Service |
4684c1 |
gnutls_certificate_type_t ctype_client, ctype_server;
|
|
Packit Service |
4684c1 |
char kx_name[64] = "";
|
|
Packit Service |
4684c1 |
char proto_name[32];
|
|
Packit Service |
4684c1 |
char _group_name[24];
|
|
Packit Service |
4684c1 |
const char *group_name = NULL;
|
|
Packit Service |
4684c1 |
int dh_bits = 0;
|
|
Packit Service |
4684c1 |
unsigned mac_id;
|
|
Packit Service |
4684c1 |
unsigned sign_algo;
|
|
Packit Service |
4684c1 |
char *desc;
|
|
Packit Service |
4684c1 |
const struct gnutls_group_entry_st *group = get_group(session);
|
|
Packit Service |
4684c1 |
const version_entry_st *ver = get_version(session);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.initial_negotiation_completed == 0)
|
|
Packit Service |
4684c1 |
return NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
kx = session->security_parameters.cs->kx_algorithm;
|
|
Packit Service |
4684c1 |
if (group)
|
|
Packit Service |
4684c1 |
group_name = group->name;
|
|
Packit Service |
4684c1 |
#if defined(ENABLE_DHE) || defined(ENABLE_ANON)
|
|
Packit Service |
4684c1 |
if (group_name == NULL && _gnutls_kx_is_dhe(kx)) {
|
|
Packit Service |
4684c1 |
dh_bits = gnutls_dh_get_prime_bits(session);
|
|
Packit Service |
4684c1 |
if (dh_bits > 0)
|
|
Packit Service |
4684c1 |
snprintf(_group_name, sizeof(_group_name), "CUSTOM%u", dh_bits);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
snprintf(_group_name, sizeof(_group_name), "CUSTOM");
|
|
Packit Service |
4684c1 |
group_name = _group_name;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Key exchange - Signature algorithm */
|
|
Packit Service |
4684c1 |
/* DHE-3072 - RSA-PSS-2048 */
|
|
Packit Service |
4684c1 |
/* ECDHE-SECP256R1 - ECDSA-SECP256R1 */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
sign_algo = gnutls_sign_algorithm_get(session);
|
|
Packit Service |
4684c1 |
sign_str = gnutls_sign_get_name(sign_algo);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (kx == 0 && ver->tls13_sem) { /* TLS 1.3 */
|
|
Packit Service |
4684c1 |
if (session->internals.hsk_flags & HSK_PSK_SELECTED) {
|
|
Packit Service |
4684c1 |
if (group) {
|
|
Packit Service |
4684c1 |
if (group->pk == GNUTLS_PK_DH)
|
|
Packit Service |
4684c1 |
snprintf(kx_name, sizeof(kx_name), "(DHE-PSK-%s)",
|
|
Packit Service |
4684c1 |
group_name);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
snprintf(kx_name, sizeof(kx_name), "(ECDHE-PSK-%s)",
|
|
Packit Service |
4684c1 |
group_name);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
snprintf(kx_name, sizeof(kx_name), "(PSK)");
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else if (group && sign_str) {
|
|
Packit Service |
4684c1 |
if (group->curve)
|
|
Packit Service |
4684c1 |
snprintf(kx_name, sizeof(kx_name), "(ECDHE-%s)-(%s)",
|
|
Packit Service |
4684c1 |
group_name, sign_str);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
snprintf(kx_name, sizeof(kx_name), "(DHE-%s)-(%s)",
|
|
Packit Service |
4684c1 |
group_name, sign_str);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
kx_str = gnutls_kx_get_name(kx);
|
|
Packit Service |
4684c1 |
if (kx_str == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return NULL;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if ((kx == GNUTLS_KX_ECDHE_ECDSA || kx == GNUTLS_KX_ECDHE_RSA ||
|
|
Packit Service |
4684c1 |
kx == GNUTLS_KX_ECDHE_PSK) && group_name) {
|
|
Packit Service |
4684c1 |
if (sign_str)
|
|
Packit Service |
4684c1 |
snprintf(kx_name, sizeof(kx_name), "(ECDHE-%s)-(%s)",
|
|
Packit Service |
4684c1 |
group_name, sign_str);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
snprintf(kx_name, sizeof(kx_name), "(ECDHE-%s)",
|
|
Packit Service |
4684c1 |
group_name);
|
|
Packit Service |
4684c1 |
} else if ((kx == GNUTLS_KX_DHE_DSS || kx == GNUTLS_KX_DHE_RSA ||
|
|
Packit Service |
4684c1 |
kx == GNUTLS_KX_DHE_PSK) && group_name) {
|
|
Packit Service |
4684c1 |
if (sign_str)
|
|
Packit Service |
4684c1 |
snprintf(kx_name, sizeof(kx_name), "(DHE-%s)-(%s)", group_name, sign_str);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
snprintf(kx_name, sizeof(kx_name), "(DHE-%s)", group_name);
|
|
Packit Service |
4684c1 |
} else if (kx == GNUTLS_KX_RSA) {
|
|
Packit Service |
4684c1 |
/* Possible enhancement: include the certificate bits */
|
|
Packit Service |
4684c1 |
snprintf(kx_name, sizeof(kx_name), "(RSA)");
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
snprintf(kx_name, sizeof(kx_name), "(%s)",
|
|
Packit Service |
4684c1 |
kx_str);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (are_alternative_cert_types_allowed(session)) {
|
|
Packit Service |
4684c1 |
// Get certificate types
|
|
Packit Service |
4684c1 |
ctype_client = get_certificate_type(session, GNUTLS_CTYPE_CLIENT);
|
|
Packit Service |
4684c1 |
ctype_server = get_certificate_type(session, GNUTLS_CTYPE_SERVER);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ctype_client == ctype_server) {
|
|
Packit Service |
4684c1 |
// print proto version, client/server cert type
|
|
Packit Service |
4684c1 |
snprintf(proto_name, sizeof(proto_name), "%s-%s",
|
|
Packit Service |
4684c1 |
gnutls_protocol_get_name(get_num_version(session)),
|
|
Packit Service |
4684c1 |
gnutls_certificate_type_get_name(ctype_client));
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
// print proto version, client cert type, server cert type
|
|
Packit Service |
4684c1 |
snprintf(proto_name, sizeof(proto_name), "%s-%s-%s",
|
|
Packit Service |
4684c1 |
gnutls_protocol_get_name(get_num_version(session)),
|
|
Packit Service |
4684c1 |
gnutls_certificate_type_get_name(ctype_client),
|
|
Packit Service |
4684c1 |
gnutls_certificate_type_get_name(ctype_server));
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else { // Assumed default certificate type (X.509)
|
|
Packit Service |
4684c1 |
snprintf(proto_name, sizeof(proto_name), "%s",
|
|
Packit Service |
4684c1 |
gnutls_protocol_get_name(get_num_version(session)));
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
desc = gnutls_malloc(DESC_SIZE);
|
|
Packit Service |
4684c1 |
if (desc == NULL)
|
|
Packit Service |
4684c1 |
return NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
mac_id = gnutls_mac_get(session);
|
|
Packit Service |
4684c1 |
if (mac_id == GNUTLS_MAC_AEAD) { /* no need to print */
|
|
Packit Service |
4684c1 |
snprintf(desc, DESC_SIZE,
|
|
Packit Service |
4684c1 |
"(%s)-%s-(%s)",
|
|
Packit Service |
4684c1 |
proto_name,
|
|
Packit Service |
4684c1 |
kx_name,
|
|
Packit Service |
4684c1 |
gnutls_cipher_get_name(gnutls_cipher_get(session)));
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
snprintf(desc, DESC_SIZE,
|
|
Packit Service |
4684c1 |
"(%s)-%s-(%s)-(%s)",
|
|
Packit Service |
4684c1 |
proto_name,
|
|
Packit Service |
4684c1 |
kx_name,
|
|
Packit Service |
4684c1 |
gnutls_cipher_get_name(gnutls_cipher_get(session)),
|
|
Packit Service |
4684c1 |
gnutls_mac_get_name(mac_id));
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return desc;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_session_set_id:
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
* @sid: the session identifier
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function sets the session ID to be used in a client hello.
|
|
Packit Service |
4684c1 |
* This is a function intended for exceptional uses. Do not use this
|
|
Packit Service |
4684c1 |
* function unless you are implementing a custom protocol.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* To set session resumption parameters use gnutls_session_set_data() instead.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
|
|
Packit Service |
4684c1 |
* an error code is returned.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.2.1
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_session_set_id(gnutls_session_t session, const gnutls_datum_t * sid)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (session->security_parameters.entity == GNUTLS_SERVER ||
|
|
Packit Service |
4684c1 |
sid->size > GNUTLS_MAX_SESSION_ID_SIZE)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memset(&session->internals.resumed_security_parameters, 0,
|
|
Packit Service |
4684c1 |
sizeof(session->internals.resumed_security_parameters));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session->internals.resumed_security_parameters.session_id_size =
|
|
Packit Service |
4684c1 |
sid->size;
|
|
Packit Service |
4684c1 |
memcpy(session->internals.resumed_security_parameters.session_id,
|
|
Packit Service |
4684c1 |
sid->data, sid->size);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|