|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* Copyright (C) 2018 Free Software Foundation, Inc.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Author: Ander Juaristi
|
|
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 "stek.h"
|
|
Packit Service |
4684c1 |
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
|
Packit Service |
4684c1 |
#include <valgrind/memcheck.h>
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define NAME_POS (0)
|
|
Packit Service |
4684c1 |
#define KEY_POS (TICKET_KEY_NAME_SIZE)
|
|
Packit Service |
4684c1 |
#define MAC_SECRET_POS (TICKET_KEY_NAME_SIZE+TICKET_CIPHER_KEY_SIZE)
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int totp_sha3(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
uint64_t t,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t *secret,
|
|
Packit Service |
4684c1 |
uint8_t out[TICKET_MASTER_KEY_SIZE])
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int retval;
|
|
Packit Service |
4684c1 |
uint8_t t_be[8];
|
|
Packit Service |
4684c1 |
digest_hd_st hd;
|
|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* We choose SHA3-512 because it outputs 64 bytes,
|
|
Packit Service |
4684c1 |
* just the same length as the ticket key.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
const gnutls_digest_algorithm_t algo = GNUTLS_DIG_SHA3_512;
|
|
Packit Service |
4684c1 |
#if TICKET_MASTER_KEY_SIZE != 64
|
|
Packit Service |
4684c1 |
#error "TICKET_MASTER_KEY_SIZE must be 64 bytes"
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (unlikely(secret == NULL))
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if ((retval = _gnutls_hash_init(&hd, hash_to_entry(algo))) < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(retval);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_write_uint64(t, t_be);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if ((retval = _gnutls_hash(&hd, t_be, sizeof(t_be))) < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(retval);
|
|
Packit Service |
4684c1 |
if ((retval = _gnutls_hash(&hd, secret->data, secret->size)) < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(retval);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_hash_deinit(&hd, out);
|
|
Packit Service |
4684c1 |
return GNUTLS_E_SUCCESS;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static uint64_t T(gnutls_session_t session, time_t t)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
uint64_t numeral = t;
|
|
Packit Service |
4684c1 |
unsigned int x = session->internals.expire_time * STEK_ROTATION_PERIOD_PRODUCT;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (numeral <= 0)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return (numeral / x);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int64_t totp_next(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
time_t t;
|
|
Packit Service |
4684c1 |
uint64_t result;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
t = gnutls_time(NULL);
|
|
Packit Service |
4684c1 |
if (unlikely(t == (time_t) -1))
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
result = T(session, t);
|
|
Packit Service |
4684c1 |
if (result == 0)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (result == session->key.totp.last_result)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return result;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int64_t totp_previous(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
uint64_t result;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->key.totp.last_result == 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
|
|
Packit Service |
4684c1 |
if (!session->key.totp.was_rotated)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
result = session->key.totp.last_result - 1;
|
|
Packit Service |
4684c1 |
if (result == 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return result;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void call_rotation_callback(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
uint8_t key[TICKET_MASTER_KEY_SIZE], uint64_t t)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_datum_t prev_key, new_key;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->key.totp.cb) {
|
|
Packit Service |
4684c1 |
new_key.data = key;
|
|
Packit Service |
4684c1 |
new_key.size = TICKET_MASTER_KEY_SIZE;
|
|
Packit Service |
4684c1 |
prev_key.data = session->key.session_ticket_key;
|
|
Packit Service |
4684c1 |
prev_key.size = TICKET_MASTER_KEY_SIZE;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session->key.totp.cb(&prev_key, &new_key, t);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int rotate(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int64_t t;
|
|
Packit Service |
4684c1 |
gnutls_datum_t secret;
|
|
Packit Service |
4684c1 |
uint8_t key[TICKET_MASTER_KEY_SIZE];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Do we need to calculate new totp? */
|
|
Packit Service |
4684c1 |
t = totp_next(session);
|
|
Packit Service |
4684c1 |
if (t > 0) {
|
|
Packit Service |
4684c1 |
secret.data = session->key.initial_stek;
|
|
Packit Service |
4684c1 |
secret.size = TICKET_MASTER_KEY_SIZE;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Generate next key */
|
|
Packit Service |
4684c1 |
if (totp_sha3(session, t, &secret, key) < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Replace old key with new one, and call callback if provided */
|
|
Packit Service |
4684c1 |
call_rotation_callback(session, key, t);
|
|
Packit Service |
4684c1 |
session->key.totp.last_result = t;
|
|
Packit Service |
4684c1 |
memcpy(session->key.session_ticket_key, key, sizeof(key));
|
|
Packit Service |
4684c1 |
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
|
Packit Service |
4684c1 |
if (RUNNING_ON_VALGRIND)
|
|
Packit Service |
4684c1 |
VALGRIND_MAKE_MEM_DEFINED(session->key.session_ticket_key,
|
|
Packit Service |
4684c1 |
TICKET_MASTER_KEY_SIZE);
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session->key.totp.was_rotated = 1;
|
|
Packit Service |
4684c1 |
} else if (t < 0) {
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(t);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return GNUTLS_E_SUCCESS;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int rotate_back_and_peek(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
uint8_t key[TICKET_MASTER_KEY_SIZE])
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int64_t t;
|
|
Packit Service |
4684c1 |
gnutls_datum_t secret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Get the previous TOTP */
|
|
Packit Service |
4684c1 |
t = totp_previous(session);
|
|
Packit Service |
4684c1 |
if (t < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(t);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
secret.data = session->key.initial_stek;
|
|
Packit Service |
4684c1 |
secret.size = TICKET_MASTER_KEY_SIZE;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (totp_sha3(session, t, &secret, key) < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* _gnutls_get_session_ticket_encryption_key:
|
|
Packit Service |
4684c1 |
* @key_name: an empty datum that will receive the key name part of the STEK
|
|
Packit Service |
4684c1 |
* @mac_key: an empty datum that will receive the MAC key part of the STEK
|
|
Packit Service |
4684c1 |
* @enc_key: an empty datum that will receive the encryption key part of the STEK
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Get the currently active session ticket encryption key (STEK).
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* The STEK is a 64-byte blob which is further divided in three parts,
|
|
Packit Service |
4684c1 |
* and this function requires the caller to supply three separate datums for each one.
|
|
Packit Service |
4684c1 |
* Though the caller might omit one or more of those if not interested in that part of the STEK.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* These are the three parts the STEK is divided in:
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* - Key name: 16 bytes
|
|
Packit Service |
4684c1 |
* - Encryption key: 32 bytes
|
|
Packit Service |
4684c1 |
* - MAC key: 16 bytes
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will transparently rotate the key, if the time has come for that,
|
|
Packit Service |
4684c1 |
* before returning it to the caller.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
int _gnutls_get_session_ticket_encryption_key(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
gnutls_datum_t *key_name,
|
|
Packit Service |
4684c1 |
gnutls_datum_t *mac_key,
|
|
Packit Service |
4684c1 |
gnutls_datum_t *enc_key)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int retval;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (unlikely(session == NULL)) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_INTERNAL_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if ((retval = rotate(session)) < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(retval);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Copy key parts to user-supplied datums (if provided) */
|
|
Packit Service |
4684c1 |
if (key_name) {
|
|
Packit Service |
4684c1 |
key_name->data = &session->key.session_ticket_key[NAME_POS];
|
|
Packit Service |
4684c1 |
key_name->size = TICKET_KEY_NAME_SIZE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
if (mac_key) {
|
|
Packit Service |
4684c1 |
mac_key->data = &session->key.session_ticket_key[MAC_SECRET_POS];
|
|
Packit Service |
4684c1 |
mac_key->size = TICKET_MAC_SECRET_SIZE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
if (enc_key) {
|
|
Packit Service |
4684c1 |
enc_key->data = &session->key.session_ticket_key[KEY_POS];
|
|
Packit Service |
4684c1 |
enc_key->size = TICKET_CIPHER_KEY_SIZE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return retval;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* _gnutls_get_session_ticket_decryption_key:
|
|
Packit Service |
4684c1 |
* @ticket_data: the bytes of a session ticket that must be decrypted
|
|
Packit Service |
4684c1 |
* @key_name: an empty datum that will receive the key name part of the STEK
|
|
Packit Service |
4684c1 |
* @mac_key: an empty datum that will receive the MAC key part of the STEK
|
|
Packit Service |
4684c1 |
* @enc_key: an empty datum that will receive the encryption key part of the STEK
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Get the key (STEK) the given session ticket was encrypted with.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* As with its encryption counterpart (%_gnutls_get_session_ticket_encryption_key),
|
|
Packit Service |
4684c1 |
* this function will also transparently rotate
|
|
Packit Service |
4684c1 |
* the currently active STEK if time has come for that, and it also requires the different
|
|
Packit Service |
4684c1 |
* parts of the STEK to be obtained in different datums.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or a negative error code, such as
|
|
Packit Service |
4684c1 |
* %GNUTLS_E_REQUSTED_DATA_NOT_AVAILABLE if no key could be found for the supplied ticket.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
int _gnutls_get_session_ticket_decryption_key(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t *ticket_data,
|
|
Packit Service |
4684c1 |
gnutls_datum_t *key_name,
|
|
Packit Service |
4684c1 |
gnutls_datum_t *mac_key,
|
|
Packit Service |
4684c1 |
gnutls_datum_t *enc_key)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int retval;
|
|
Packit Service |
4684c1 |
gnutls_datum_t key = {
|
|
Packit Service |
4684c1 |
.data = session->key.session_ticket_key,
|
|
Packit Service |
4684c1 |
.size = TICKET_MASTER_KEY_SIZE
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (unlikely(session == NULL || ticket_data == NULL || ticket_data->data == NULL))
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ticket_data->size < TICKET_KEY_NAME_SIZE)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if ((retval = rotate(session)) < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(retval);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* Is current key valid?
|
|
Packit Service |
4684c1 |
* We compare the first 16 bytes --> The key_name field.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if (memcmp(ticket_data->data,
|
|
Packit Service |
4684c1 |
&key.data[NAME_POS],
|
|
Packit Service |
4684c1 |
TICKET_KEY_NAME_SIZE) == 0)
|
|
Packit Service |
4684c1 |
goto key_found;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
key.size = TICKET_MASTER_KEY_SIZE;
|
|
Packit Service |
4684c1 |
key.data = session->key.previous_ticket_key;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* Current key is not valid.
|
|
Packit Service |
4684c1 |
* Compute previous key and see if that matches.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if ((retval = rotate_back_and_peek(session, key.data)) < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(retval);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (memcmp(ticket_data->data,
|
|
Packit Service |
4684c1 |
&key.data[NAME_POS],
|
|
Packit Service |
4684c1 |
TICKET_KEY_NAME_SIZE) == 0)
|
|
Packit Service |
4684c1 |
goto key_found;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
key_found:
|
|
Packit Service |
4684c1 |
if (key_name) {
|
|
Packit Service |
4684c1 |
key_name->data = &key.data[NAME_POS];
|
|
Packit Service |
4684c1 |
key_name->size = TICKET_KEY_NAME_SIZE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
if (mac_key) {
|
|
Packit Service |
4684c1 |
mac_key->data = &key.data[MAC_SECRET_POS];
|
|
Packit Service |
4684c1 |
mac_key->size = TICKET_MAC_SECRET_SIZE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
if (enc_key) {
|
|
Packit Service |
4684c1 |
enc_key->data = &key.data[KEY_POS];
|
|
Packit Service |
4684c1 |
enc_key->size = TICKET_CIPHER_KEY_SIZE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return GNUTLS_E_SUCCESS;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* _gnutls_initialize_session_ticket_key_rotation:
|
|
Packit Service |
4684c1 |
* @key: Initial session ticket key
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Initialize the session ticket key rotation.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will not enable session ticket keys on the server side. That is done
|
|
Packit Service |
4684c1 |
* with the gnutls_session_ticket_enable_server() function. This function just initializes
|
|
Packit Service |
4684c1 |
* the internal state to support periodical rotation of the session ticket encryption key.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: %GNUTLS_E_SUCCESS (0) on success, or %GNUTLS_E_INVALID_REQUEST on error.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
int _gnutls_initialize_session_ticket_key_rotation(gnutls_session_t session, const gnutls_datum_t *key)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (unlikely(session == NULL || key == NULL))
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (unlikely(session->key.totp.last_result != 0))
|
|
Packit Service |
4684c1 |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memcpy(session->key.initial_stek, key->data, key->size);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session->key.totp.was_rotated = 0;
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* _gnutls_set_session_ticket_key_rotation_callback:
|
|
Packit Service |
4684c1 |
* @cb: the callback function
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Set a callback function that will be invoked every time the session ticket key
|
|
Packit Service |
4684c1 |
* is rotated.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* The function will take as arguments the previous key, the new key and the time
|
|
Packit Service |
4684c1 |
* step value that caused the key to rotate.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
void _gnutls_set_session_ticket_key_rotation_callback(gnutls_session_t session, gnutls_stek_rotation_callback_t cb)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (session)
|
|
Packit Service |
4684c1 |
session->key.totp.cb = cb;
|
|
Packit Service |
4684c1 |
}
|