diff options
Diffstat (limited to 'lib/gnutls_constate.c')
-rw-r--r-- | lib/gnutls_constate.c | 997 |
1 files changed, 505 insertions, 492 deletions
diff --git a/lib/gnutls_constate.c b/lib/gnutls_constate.c index a7c2d636a9..0ea7dae0ae 100644 --- a/lib/gnutls_constate.c +++ b/lib/gnutls_constate.c @@ -36,19 +36,19 @@ #include <gnutls_buffers.h> static int -_gnutls_set_kx (gnutls_session_t session, gnutls_kx_algorithm_t algo); +_gnutls_set_kx(gnutls_session_t session, gnutls_kx_algorithm_t algo); static const char keyexp[] = "key expansion"; -static const int keyexp_length = sizeof (keyexp) - 1; +static const int keyexp_length = sizeof(keyexp) - 1; static const char ivblock[] = "IV block"; -static const int ivblock_length = sizeof (ivblock) - 1; +static const int ivblock_length = sizeof(ivblock) - 1; static const char cliwrite[] = "client write key"; -static const int cliwrite_length = sizeof (cliwrite) - 1; +static const int cliwrite_length = sizeof(cliwrite) - 1; static const char servwrite[] = "server write key"; -static const int servwrite_length = sizeof (servwrite) - 1; +static const int servwrite_length = sizeof(servwrite) - 1; /* This function is to be called after handshake, when master_secret, * client_random and server_random have been initialized. @@ -56,312 +56,321 @@ static const int servwrite_length = sizeof (servwrite) - 1; * (session->cipher_specs) */ static int -_gnutls_set_keys (gnutls_session_t session, record_parameters_st * params, - int hash_size, int IV_size, int key_size) +_gnutls_set_keys(gnutls_session_t session, record_parameters_st * params, + int hash_size, int IV_size, int key_size) { - /* FIXME: This function is too long - */ - uint8_t rnd[2 * GNUTLS_RANDOM_SIZE]; - uint8_t rrnd[2 * GNUTLS_RANDOM_SIZE]; - int pos, ret; - int block_size; - char buf[65]; - /* avoid using malloc */ - uint8_t key_block[2 * MAX_HASH_SIZE + 2 * MAX_CIPHER_KEY_SIZE + - 2 * MAX_CIPHER_BLOCK_SIZE]; - record_state_st *client_write, *server_write; - - if (session->security_parameters.entity == GNUTLS_CLIENT) - { - client_write = ¶ms->write; - server_write = ¶ms->read; - } - else - { - client_write = ¶ms->read; - server_write = ¶ms->write; - } - - block_size = 2 * hash_size + 2 * key_size; - block_size += 2 * IV_size; - - memcpy (rnd, session->security_parameters.server_random, - GNUTLS_RANDOM_SIZE); - memcpy (&rnd[GNUTLS_RANDOM_SIZE], - session->security_parameters.client_random, GNUTLS_RANDOM_SIZE); - - memcpy (rrnd, session->security_parameters.client_random, - GNUTLS_RANDOM_SIZE); - memcpy (&rrnd[GNUTLS_RANDOM_SIZE], - session->security_parameters.server_random, GNUTLS_RANDOM_SIZE); - - if (get_num_version(session) == GNUTLS_SSL3) - { /* SSL 3 */ - ret = - _gnutls_ssl3_generate_random - (session->security_parameters.master_secret, GNUTLS_MASTER_SIZE, rnd, - 2 * GNUTLS_RANDOM_SIZE, block_size, key_block); - } - else - { /* TLS 1.0 */ - ret = - _gnutls_PRF (session, session->security_parameters.master_secret, - GNUTLS_MASTER_SIZE, keyexp, keyexp_length, - rnd, 2 * GNUTLS_RANDOM_SIZE, block_size, key_block); - } - - if (ret < 0) - return gnutls_assert_val (ret); - - _gnutls_hard_log ("INT: KEY BLOCK[%d]: %s\n", block_size, - _gnutls_bin2hex (key_block, block_size, buf, - sizeof (buf), NULL)); - - pos = 0; - if (hash_size > 0) - { - - if (_gnutls_set_datum - (&client_write->mac_secret, &key_block[pos], hash_size) < 0) - return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR); - - pos += hash_size; - - if (_gnutls_set_datum - (&server_write->mac_secret, &key_block[pos], hash_size) < 0) - return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR); - - pos += hash_size; - } - - if (key_size > 0) - { - uint8_t *client_write_key, *server_write_key; - int client_write_key_size, server_write_key_size; - - client_write_key = &key_block[pos]; - client_write_key_size = key_size; - - pos += key_size; - - server_write_key = &key_block[pos]; - server_write_key_size = key_size; - - pos += key_size; - - if (_gnutls_set_datum - (&client_write->key, client_write_key, client_write_key_size) < 0) - return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR); - - _gnutls_hard_log ("INT: CLIENT WRITE KEY [%d]: %s\n", - client_write_key_size, - _gnutls_bin2hex (client_write_key, - client_write_key_size, buf, - sizeof (buf), NULL)); - - if (_gnutls_set_datum - (&server_write->key, server_write_key, server_write_key_size) < 0) - return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR); - - _gnutls_hard_log ("INT: SERVER WRITE KEY [%d]: %s\n", - server_write_key_size, - _gnutls_bin2hex (server_write_key, - server_write_key_size, buf, - sizeof (buf), NULL)); - - } - - /* IV generation in export and non export ciphers. - */ - if (IV_size > 0) - { - if (_gnutls_set_datum - (&client_write->IV, &key_block[pos], IV_size) < 0) - return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR); - - pos += IV_size; - - if (_gnutls_set_datum - (&server_write->IV, &key_block[pos], IV_size) < 0) - return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR); - - } - - return 0; + /* FIXME: This function is too long + */ + uint8_t rnd[2 * GNUTLS_RANDOM_SIZE]; + uint8_t rrnd[2 * GNUTLS_RANDOM_SIZE]; + int pos, ret; + int block_size; + char buf[65]; + /* avoid using malloc */ + uint8_t key_block[2 * MAX_HASH_SIZE + 2 * MAX_CIPHER_KEY_SIZE + + 2 * MAX_CIPHER_BLOCK_SIZE]; + record_state_st *client_write, *server_write; + + if (session->security_parameters.entity == GNUTLS_CLIENT) { + client_write = ¶ms->write; + server_write = ¶ms->read; + } else { + client_write = ¶ms->read; + server_write = ¶ms->write; + } + + block_size = 2 * hash_size + 2 * key_size; + block_size += 2 * IV_size; + + memcpy(rnd, session->security_parameters.server_random, + GNUTLS_RANDOM_SIZE); + memcpy(&rnd[GNUTLS_RANDOM_SIZE], + session->security_parameters.client_random, + GNUTLS_RANDOM_SIZE); + + memcpy(rrnd, session->security_parameters.client_random, + GNUTLS_RANDOM_SIZE); + memcpy(&rrnd[GNUTLS_RANDOM_SIZE], + session->security_parameters.server_random, + GNUTLS_RANDOM_SIZE); + + if (get_num_version(session) == GNUTLS_SSL3) { /* SSL 3 */ + ret = + _gnutls_ssl3_generate_random + (session->security_parameters.master_secret, + GNUTLS_MASTER_SIZE, rnd, 2 * GNUTLS_RANDOM_SIZE, + block_size, key_block); + } else { /* TLS 1.0 */ + ret = + _gnutls_PRF(session, + session->security_parameters.master_secret, + GNUTLS_MASTER_SIZE, keyexp, keyexp_length, + rnd, 2 * GNUTLS_RANDOM_SIZE, block_size, + key_block); + } + + if (ret < 0) + return gnutls_assert_val(ret); + + _gnutls_hard_log("INT: KEY BLOCK[%d]: %s\n", block_size, + _gnutls_bin2hex(key_block, block_size, buf, + sizeof(buf), NULL)); + + pos = 0; + if (hash_size > 0) { + + if (_gnutls_set_datum + (&client_write->mac_secret, &key_block[pos], + hash_size) < 0) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + pos += hash_size; + + if (_gnutls_set_datum + (&server_write->mac_secret, &key_block[pos], + hash_size) < 0) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + pos += hash_size; + } + + if (key_size > 0) { + uint8_t *client_write_key, *server_write_key; + int client_write_key_size, server_write_key_size; + + client_write_key = &key_block[pos]; + client_write_key_size = key_size; + + pos += key_size; + + server_write_key = &key_block[pos]; + server_write_key_size = key_size; + + pos += key_size; + + if (_gnutls_set_datum + (&client_write->key, client_write_key, + client_write_key_size) < 0) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + _gnutls_hard_log("INT: CLIENT WRITE KEY [%d]: %s\n", + client_write_key_size, + _gnutls_bin2hex(client_write_key, + client_write_key_size, + buf, sizeof(buf), NULL)); + + if (_gnutls_set_datum + (&server_write->key, server_write_key, + server_write_key_size) < 0) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + _gnutls_hard_log("INT: SERVER WRITE KEY [%d]: %s\n", + server_write_key_size, + _gnutls_bin2hex(server_write_key, + server_write_key_size, + buf, sizeof(buf), NULL)); + + } + + /* IV generation in export and non export ciphers. + */ + if (IV_size > 0) { + if (_gnutls_set_datum + (&client_write->IV, &key_block[pos], IV_size) < 0) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + pos += IV_size; + + if (_gnutls_set_datum + (&server_write->IV, &key_block[pos], IV_size) < 0) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + } + + return 0; } static int -_gnutls_init_record_state (record_parameters_st * params, const version_entry_st* ver, - int read, record_state_st * state) +_gnutls_init_record_state(record_parameters_st * params, + const version_entry_st * ver, int read, + record_state_st * state) { - int ret; - gnutls_datum_t * iv = NULL; - - if (!_gnutls_version_has_explicit_iv(ver)) - { - if (_gnutls_cipher_is_block (params->cipher) != CIPHER_STREAM) - iv = &state->IV; - } - - ret = _gnutls_auth_cipher_init (&state->cipher_state, - params->cipher, &state->key, iv, - params->mac, &state->mac_secret, (ver->id==GNUTLS_SSL3)?1:0, 1-read/*1==encrypt*/); - if (ret < 0 && params->cipher->id != GNUTLS_CIPHER_NULL) - return gnutls_assert_val (ret); - - ret = - _gnutls_comp_init (&state->compression_state, params->compression_algorithm, read/*1==decompress*/); - - if (ret < 0) - return gnutls_assert_val (ret); - - return 0; + int ret; + gnutls_datum_t *iv = NULL; + + if (!_gnutls_version_has_explicit_iv(ver)) { + if (_gnutls_cipher_is_block(params->cipher) != + CIPHER_STREAM) + iv = &state->IV; + } + + ret = _gnutls_auth_cipher_init(&state->cipher_state, + params->cipher, &state->key, iv, + params->mac, &state->mac_secret, + (ver->id == GNUTLS_SSL3) ? 1 : 0, + 1 - read /*1==encrypt */ ); + if (ret < 0 && params->cipher->id != GNUTLS_CIPHER_NULL) + return gnutls_assert_val(ret); + + ret = + _gnutls_comp_init(&state->compression_state, + params->compression_algorithm, + read /*1==decompress */ ); + + if (ret < 0) + return gnutls_assert_val(ret); + + return 0; } int -_gnutls_epoch_set_cipher_suite (gnutls_session_t session, - int epoch_rel, const uint8_t suite[2]) +_gnutls_epoch_set_cipher_suite(gnutls_session_t session, + int epoch_rel, const uint8_t suite[2]) { - const cipher_entry_st * cipher_algo; - const mac_entry_st* mac_algo; - record_parameters_st *params; - int ret; + const cipher_entry_st *cipher_algo; + const mac_entry_st *mac_algo; + record_parameters_st *params; + int ret; - ret = _gnutls_epoch_get (session, epoch_rel, ¶ms); - if (ret < 0) - return gnutls_assert_val (ret); + ret = _gnutls_epoch_get(session, epoch_rel, ¶ms); + if (ret < 0) + return gnutls_assert_val(ret); - if (params->initialized - || params->cipher != NULL - || params->mac != NULL) - return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR); + if (params->initialized + || params->cipher != NULL || params->mac != NULL) + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); - cipher_algo = _gnutls_cipher_suite_get_cipher_algo (suite); - mac_algo = _gnutls_cipher_suite_get_mac_algo (suite); + cipher_algo = _gnutls_cipher_suite_get_cipher_algo(suite); + mac_algo = _gnutls_cipher_suite_get_mac_algo(suite); - if (_gnutls_cipher_is_ok (cipher_algo) == 0 - || _gnutls_mac_is_ok (mac_algo) == 0) - return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM); + if (_gnutls_cipher_is_ok(cipher_algo) == 0 + || _gnutls_mac_is_ok(mac_algo) == 0) + return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM); - if (_gnutls_cipher_priority (session, cipher_algo->id) < 0) - return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM); + if (_gnutls_cipher_priority(session, cipher_algo->id) < 0) + return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM); - if (_gnutls_mac_priority (session, mac_algo->id) < 0) - return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM); + if (_gnutls_mac_priority(session, mac_algo->id) < 0) + return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM); - params->cipher = cipher_algo; - params->mac = mac_algo; + params->cipher = cipher_algo; + params->mac = mac_algo; - return 0; + return 0; } int -_gnutls_epoch_set_compression (gnutls_session_t session, - int epoch_rel, - gnutls_compression_method_t comp_algo) +_gnutls_epoch_set_compression(gnutls_session_t session, + int epoch_rel, + gnutls_compression_method_t comp_algo) { - record_parameters_st *params; - int ret; + record_parameters_st *params; + int ret; - ret = _gnutls_epoch_get (session, epoch_rel, ¶ms); - if (ret < 0) - return gnutls_assert_val (ret); + ret = _gnutls_epoch_get(session, epoch_rel, ¶ms); + if (ret < 0) + return gnutls_assert_val(ret); - if (params->initialized - || params->compression_algorithm != GNUTLS_COMP_UNKNOWN) - return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR); + if (params->initialized + || params->compression_algorithm != GNUTLS_COMP_UNKNOWN) + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); - if (_gnutls_compression_is_ok (comp_algo) != 0) - return gnutls_assert_val (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM); + if (_gnutls_compression_is_ok(comp_algo) != 0) + return + gnutls_assert_val + (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM); - params->compression_algorithm = comp_algo; + params->compression_algorithm = comp_algo; - return 0; + return 0; } void -_gnutls_epoch_set_null_algos (gnutls_session_t session, - record_parameters_st * params) +_gnutls_epoch_set_null_algos(gnutls_session_t session, + record_parameters_st * params) { - /* This is only called on startup. We are extra paranoid about this - because it may cause unencrypted application data to go out on - the wire. */ - if (params->initialized || params->epoch != 0) - { - gnutls_assert (); - return; - } - - params->cipher = cipher_to_entry(GNUTLS_CIPHER_NULL); - params->mac = mac_to_entry(GNUTLS_MAC_NULL); - params->compression_algorithm = GNUTLS_COMP_NULL; - params->initialized = 1; + /* This is only called on startup. We are extra paranoid about this + because it may cause unencrypted application data to go out on + the wire. */ + if (params->initialized || params->epoch != 0) { + gnutls_assert(); + return; + } + + params->cipher = cipher_to_entry(GNUTLS_CIPHER_NULL); + params->mac = mac_to_entry(GNUTLS_MAC_NULL); + params->compression_algorithm = GNUTLS_COMP_NULL; + params->initialized = 1; } -int -_gnutls_epoch_set_keys (gnutls_session_t session, uint16_t epoch) +int _gnutls_epoch_set_keys(gnutls_session_t session, uint16_t epoch) { - int hash_size; - int IV_size; - int key_size; - gnutls_compression_method_t comp_algo; - record_parameters_st *params; - int ret; - const version_entry_st* ver = get_version (session); - - if (unlikely(ver == NULL)) - return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + int hash_size; + int IV_size; + int key_size; + gnutls_compression_method_t comp_algo; + record_parameters_st *params; + int ret; + const version_entry_st *ver = get_version(session); - ret = _gnutls_epoch_get (session, epoch, ¶ms); - if (ret < 0) - return gnutls_assert_val (ret); + if (unlikely(ver == NULL)) + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); - if (params->initialized) - return 0; + ret = _gnutls_epoch_get(session, epoch, ¶ms); + if (ret < 0) + return gnutls_assert_val(ret); - _gnutls_record_log - ("REC[%p]: Initializing epoch #%u\n", session, params->epoch); + if (params->initialized) + return 0; - comp_algo = params->compression_algorithm; + _gnutls_record_log + ("REC[%p]: Initializing epoch #%u\n", session, params->epoch); - if (_gnutls_cipher_is_ok (params->cipher) == 0 - || _gnutls_mac_is_ok (params->mac) == 0) - return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM); + comp_algo = params->compression_algorithm; - if (_gnutls_cipher_priority (session, params->cipher->id) < 0) - return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM); + if (_gnutls_cipher_is_ok(params->cipher) == 0 + || _gnutls_mac_is_ok(params->mac) == 0) + return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM); - if (_gnutls_mac_priority (session, params->mac->id) < 0) - return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM); + if (_gnutls_cipher_priority(session, params->cipher->id) < 0) + return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM); - if (_gnutls_compression_is_ok (comp_algo) != 0) - return gnutls_assert_val (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM); + if (_gnutls_mac_priority(session, params->mac->id) < 0) + return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM); - IV_size = _gnutls_cipher_get_implicit_iv_size (params->cipher); - key_size = _gnutls_cipher_get_key_size (params->cipher); - hash_size = _gnutls_mac_get_key_size (params->mac); + if (_gnutls_compression_is_ok(comp_algo) != 0) + return + gnutls_assert_val + (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM); - ret = _gnutls_set_keys - (session, params, hash_size, IV_size, key_size); - if (ret < 0) - return gnutls_assert_val (ret); + IV_size = _gnutls_cipher_get_implicit_iv_size(params->cipher); + key_size = _gnutls_cipher_get_key_size(params->cipher); + hash_size = _gnutls_mac_get_key_size(params->mac); - ret = _gnutls_init_record_state (params, ver, 1, ¶ms->read); - if (ret < 0) - return gnutls_assert_val (ret); - params->read.new_record_padding = session->security_parameters.new_record_padding; + ret = _gnutls_set_keys + (session, params, hash_size, IV_size, key_size); + if (ret < 0) + return gnutls_assert_val(ret); - ret = _gnutls_init_record_state (params, ver, 0, ¶ms->write); - if (ret < 0) - return gnutls_assert_val (ret); - params->write.new_record_padding = session->security_parameters.new_record_padding; + ret = _gnutls_init_record_state(params, ver, 1, ¶ms->read); + if (ret < 0) + return gnutls_assert_val(ret); + params->read.new_record_padding = + session->security_parameters.new_record_padding; - params->record_sw_size = 0; + ret = _gnutls_init_record_state(params, ver, 0, ¶ms->write); + if (ret < 0) + return gnutls_assert_val(ret); + params->write.new_record_padding = + session->security_parameters.new_record_padding; - _gnutls_record_log ("REC[%p]: Epoch #%u ready\n", session, params->epoch); + params->record_sw_size = 0; - params->initialized = 1; - return 0; + _gnutls_record_log("REC[%p]: Epoch #%u ready\n", session, + params->epoch); + + params->initialized = 1; + return 0; } @@ -379,15 +388,14 @@ _gnutls_epoch_set_keys (gnutls_session_t session, uint16_t epoch) dst->max_record_recv_size = src->max_record_recv_size; \ dst->max_record_send_size = src->max_record_send_size -static void -_gnutls_set_resumed_parameters (gnutls_session_t session) +static void _gnutls_set_resumed_parameters(gnutls_session_t session) { - security_parameters_st *src = - &session->internals.resumed_security_parameters; - security_parameters_st *dst = &session->security_parameters; + security_parameters_st *src = + &session->internals.resumed_security_parameters; + security_parameters_st *dst = &session->security_parameters; - CPY_COMMON; - dst->pversion = src->pversion; + CPY_COMMON; + dst->pversion = src->pversion; } /* Sets the current connection session to conform with the @@ -396,68 +404,64 @@ _gnutls_set_resumed_parameters (gnutls_session_t session) * secrets and random numbers to have been negotiated) * This is to be called after sending the Change Cipher Spec packet. */ -int -_gnutls_connection_state_init (gnutls_session_t session) +int _gnutls_connection_state_init(gnutls_session_t session) { - int ret; + int ret; /* Setup the master secret */ - if ((ret = _gnutls_generate_master (session, 0)) < 0) - return gnutls_assert_val (ret); + if ((ret = _gnutls_generate_master(session, 0)) < 0) + return gnutls_assert_val(ret); - return 0; + return 0; } int _gnutls_epoch_get_compression(gnutls_session_t session, int epoch) { -record_parameters_st *params; -int ret; + record_parameters_st *params; + int ret; - ret = _gnutls_epoch_get (session, epoch, ¶ms); - if (ret < 0) - return GNUTLS_COMP_UNKNOWN; + ret = _gnutls_epoch_get(session, epoch, ¶ms); + if (ret < 0) + return GNUTLS_COMP_UNKNOWN; - return params->compression_algorithm; + return params->compression_algorithm; } /* Initializes the read connection session * (read encrypted data) */ -int -_gnutls_read_connection_state_init (gnutls_session_t session) +int _gnutls_read_connection_state_init(gnutls_session_t session) { - const uint16_t epoch_next = session->security_parameters.epoch_next; - int ret; - - /* Update internals from CipherSuite selected. - * If we are resuming just copy the connection session - */ - if (session->internals.resumed == RESUME_FALSE) - { - ret = _gnutls_set_kx (session, - _gnutls_cipher_suite_get_kx_algo - (session-> - security_parameters.cipher_suite)); - if (ret < 0) - return ret; - } - else if (session->security_parameters.entity == GNUTLS_CLIENT) - _gnutls_set_resumed_parameters (session); - - ret = _gnutls_epoch_set_keys (session, epoch_next); - if (ret < 0) - return ret; - - _gnutls_handshake_log ("HSK[%p]: Cipher Suite: %s\n", - session, - _gnutls_cipher_suite_get_name - (session-> - security_parameters.cipher_suite)); - - session->security_parameters.epoch_read = epoch_next; - - return 0; + const uint16_t epoch_next = + session->security_parameters.epoch_next; + int ret; + + /* Update internals from CipherSuite selected. + * If we are resuming just copy the connection session + */ + if (session->internals.resumed == RESUME_FALSE) { + ret = _gnutls_set_kx(session, + _gnutls_cipher_suite_get_kx_algo + (session->security_parameters. + cipher_suite)); + if (ret < 0) + return ret; + } else if (session->security_parameters.entity == GNUTLS_CLIENT) + _gnutls_set_resumed_parameters(session); + + ret = _gnutls_epoch_set_keys(session, epoch_next); + if (ret < 0) + return ret; + + _gnutls_handshake_log("HSK[%p]: Cipher Suite: %s\n", + session, + _gnutls_cipher_suite_get_name + (session->security_parameters.cipher_suite)); + + session->security_parameters.epoch_read = epoch_next; + + return 0; } @@ -465,247 +469,256 @@ _gnutls_read_connection_state_init (gnutls_session_t session) /* Initializes the write connection session * (write encrypted data) */ -int -_gnutls_write_connection_state_init (gnutls_session_t session) +int _gnutls_write_connection_state_init(gnutls_session_t session) { - const uint16_t epoch_next = session->security_parameters.epoch_next; - int ret; + const uint16_t epoch_next = + session->security_parameters.epoch_next; + int ret; /* Update internals from CipherSuite selected. * If we are resuming just copy the connection session */ - if (session->internals.resumed == RESUME_FALSE) - { - ret = _gnutls_set_kx (session, - _gnutls_cipher_suite_get_kx_algo - (session-> - security_parameters.cipher_suite)); - if (ret < 0) - return ret; - } - else if (session->security_parameters.entity == GNUTLS_SERVER) - _gnutls_set_resumed_parameters (session); - - ret = _gnutls_epoch_set_keys (session, epoch_next); - if (ret < 0) - return gnutls_assert_val (ret); - - _gnutls_handshake_log ("HSK[%p]: Cipher Suite: %s\n", session, - _gnutls_cipher_suite_get_name - (session-> - security_parameters.cipher_suite)); - - _gnutls_handshake_log - ("HSK[%p]: Initializing internal [write] cipher sessions\n", session); - - session->security_parameters.epoch_write = epoch_next; - - return 0; + if (session->internals.resumed == RESUME_FALSE) { + ret = _gnutls_set_kx(session, + _gnutls_cipher_suite_get_kx_algo + (session->security_parameters. + cipher_suite)); + if (ret < 0) + return ret; + } else if (session->security_parameters.entity == GNUTLS_SERVER) + _gnutls_set_resumed_parameters(session); + + ret = _gnutls_epoch_set_keys(session, epoch_next); + if (ret < 0) + return gnutls_assert_val(ret); + + _gnutls_handshake_log("HSK[%p]: Cipher Suite: %s\n", session, + _gnutls_cipher_suite_get_name + (session->security_parameters.cipher_suite)); + + _gnutls_handshake_log + ("HSK[%p]: Initializing internal [write] cipher sessions\n", + session); + + session->security_parameters.epoch_write = epoch_next; + + return 0; } /* Sets the specified kx algorithm into pending session */ static int -_gnutls_set_kx (gnutls_session_t session, gnutls_kx_algorithm_t algo) +_gnutls_set_kx(gnutls_session_t session, gnutls_kx_algorithm_t algo) { - if (_gnutls_kx_is_ok (algo) == 0) - { - session->security_parameters.kx_algorithm = algo; - } - else - return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR); + if (_gnutls_kx_is_ok(algo) == 0) { + session->security_parameters.kx_algorithm = algo; + } else + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); - if (_gnutls_kx_priority (session, algo) < 0) - return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM); + if (_gnutls_kx_priority(session, algo) < 0) + return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM); - return 0; + return 0; } static inline int -epoch_resolve (gnutls_session_t session, - unsigned int epoch_rel, uint16_t * epoch_out) +epoch_resolve(gnutls_session_t session, + unsigned int epoch_rel, uint16_t * epoch_out) { - switch (epoch_rel) - { - case EPOCH_READ_CURRENT: - *epoch_out = session->security_parameters.epoch_read; - return 0; - - case EPOCH_WRITE_CURRENT: - *epoch_out = session->security_parameters.epoch_write; - return 0; - - case EPOCH_NEXT: - *epoch_out = session->security_parameters.epoch_next; - return 0; - - default: - if (epoch_rel > 0xffffu) - return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST); - - *epoch_out = epoch_rel; - return 0; - } + switch (epoch_rel) { + case EPOCH_READ_CURRENT: + *epoch_out = session->security_parameters.epoch_read; + return 0; + + case EPOCH_WRITE_CURRENT: + *epoch_out = session->security_parameters.epoch_write; + return 0; + + case EPOCH_NEXT: + *epoch_out = session->security_parameters.epoch_next; + return 0; + + default: + if (epoch_rel > 0xffffu) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + *epoch_out = epoch_rel; + return 0; + } } -static inline record_parameters_st ** -epoch_get_slot (gnutls_session_t session, uint16_t epoch) +static inline record_parameters_st **epoch_get_slot(gnutls_session_t + session, + uint16_t epoch) { - uint16_t epoch_index = epoch - session->security_parameters.epoch_min; - - if (epoch_index >= MAX_EPOCH_INDEX) - { - _gnutls_handshake_log("Epoch %d out of range (idx: %d, max: %d)\n", (int)epoch, (int)epoch_index, MAX_EPOCH_INDEX); - gnutls_assert (); - return NULL; - } - /* The slot may still be empty (NULL) */ - return &session->record_parameters[epoch_index]; + uint16_t epoch_index = + epoch - session->security_parameters.epoch_min; + + if (epoch_index >= MAX_EPOCH_INDEX) { + _gnutls_handshake_log + ("Epoch %d out of range (idx: %d, max: %d)\n", + (int) epoch, (int) epoch_index, MAX_EPOCH_INDEX); + gnutls_assert(); + return NULL; + } + /* The slot may still be empty (NULL) */ + return &session->record_parameters[epoch_index]; } int -_gnutls_epoch_get (gnutls_session_t session, unsigned int epoch_rel, - record_parameters_st ** params_out) +_gnutls_epoch_get(gnutls_session_t session, unsigned int epoch_rel, + record_parameters_st ** params_out) { - uint16_t epoch; - record_parameters_st **params; - int ret; + uint16_t epoch; + record_parameters_st **params; + int ret; - ret = epoch_resolve (session, epoch_rel, &epoch); - if (ret < 0) - return gnutls_assert_val (ret); + ret = epoch_resolve(session, epoch_rel, &epoch); + if (ret < 0) + return gnutls_assert_val(ret); - params = epoch_get_slot (session, epoch); - if (params == NULL || *params == NULL) - return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST); + params = epoch_get_slot(session, epoch); + if (params == NULL || *params == NULL) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - *params_out = *params; + *params_out = *params; - return 0; + return 0; } int -_gnutls_epoch_alloc (gnutls_session_t session, uint16_t epoch, - record_parameters_st ** out) +_gnutls_epoch_alloc(gnutls_session_t session, uint16_t epoch, + record_parameters_st ** out) { - record_parameters_st **slot; + record_parameters_st **slot; - _gnutls_record_log ("REC[%p]: Allocating epoch #%u\n", session, epoch); + _gnutls_record_log("REC[%p]: Allocating epoch #%u\n", session, + epoch); - slot = epoch_get_slot (session, epoch); + slot = epoch_get_slot(session, epoch); - /* If slot out of range or not empty. */ - if (slot == NULL) - return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST); + /* If slot out of range or not empty. */ + if (slot == NULL) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - if (*slot != NULL) - return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST); + if (*slot != NULL) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - *slot = gnutls_calloc (1, sizeof (record_parameters_st)); - if (*slot == NULL) - return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR); + *slot = gnutls_calloc(1, sizeof(record_parameters_st)); + if (*slot == NULL) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - (*slot)->epoch = epoch; - (*slot)->cipher = NULL; - (*slot)->mac = NULL; - (*slot)->compression_algorithm = GNUTLS_COMP_UNKNOWN; + (*slot)->epoch = epoch; + (*slot)->cipher = NULL; + (*slot)->mac = NULL; + (*slot)->compression_algorithm = GNUTLS_COMP_UNKNOWN; - if (IS_DTLS (session)) - _gnutls_write_uint16 (epoch, UINT64DATA((*slot)->write.sequence_number)); + if (IS_DTLS(session)) + _gnutls_write_uint16(epoch, + UINT64DATA((*slot)->write. + sequence_number)); - if (out != NULL) - *out = *slot; + if (out != NULL) + *out = *slot; - return 0; + return 0; } static inline int epoch_is_active(gnutls_session_t session, record_parameters_st * params) { - const security_parameters_st *sp = &session->security_parameters; - - if (params->epoch == sp->epoch_read) - return 1; - - if (params->epoch == sp->epoch_write) - return 1; - - if (params->epoch == sp->epoch_next) - return 1; - - return 0; + const security_parameters_st *sp = &session->security_parameters; + + if (params->epoch == sp->epoch_read) + return 1; + + if (params->epoch == sp->epoch_write) + return 1; + + if (params->epoch == sp->epoch_next) + return 1; + + return 0; } static inline int -epoch_alive (gnutls_session_t session, record_parameters_st * params) +epoch_alive(gnutls_session_t session, record_parameters_st * params) { - if (params->usage_cnt > 0) - return 1; + if (params->usage_cnt > 0) + return 1; - return epoch_is_active(session, params); + return epoch_is_active(session, params); } -void -_gnutls_epoch_gc (gnutls_session_t session) +void _gnutls_epoch_gc(gnutls_session_t session) { - int i, j; - unsigned int min_index = 0; - - _gnutls_record_log ("REC[%p]: Start of epoch cleanup\n", session); - - /* Free all dead cipher state */ - for (i = 0; i < MAX_EPOCH_INDEX; i++) - { - if (session->record_parameters[i] != NULL) - { - if (!epoch_is_active(session, session->record_parameters[i]) && session->record_parameters[i]->usage_cnt) - _gnutls_record_log ("REC[%p]: Note inactive epoch %d has %d users\n", session, session->record_parameters[i]->epoch, session->record_parameters[i]->usage_cnt); - if (!epoch_alive (session, session->record_parameters[i])) - { - _gnutls_epoch_free (session, session->record_parameters[i]); - session->record_parameters[i] = NULL; - } - } - } - - /* Look for contiguous NULLs at the start of the array */ - for (i = 0; i < MAX_EPOCH_INDEX && session->record_parameters[i] == NULL; - i++); - min_index = i; - - /* Pick up the slack in the epoch window. */ - for (i = 0, j = min_index; j < MAX_EPOCH_INDEX; i++, j++) - session->record_parameters[i] = session->record_parameters[j]; - - /* Set the new epoch_min */ - if (session->record_parameters[0] != NULL) - session->security_parameters.epoch_min = - session->record_parameters[0]->epoch; - - _gnutls_record_log ("REC[%p]: End of epoch cleanup\n", session); + int i, j; + unsigned int min_index = 0; + + _gnutls_record_log("REC[%p]: Start of epoch cleanup\n", session); + + /* Free all dead cipher state */ + for (i = 0; i < MAX_EPOCH_INDEX; i++) { + if (session->record_parameters[i] != NULL) { + if (!epoch_is_active + (session, session->record_parameters[i]) + && session->record_parameters[i]->usage_cnt) + _gnutls_record_log + ("REC[%p]: Note inactive epoch %d has %d users\n", + session, + session->record_parameters[i]->epoch, + session->record_parameters[i]-> + usage_cnt); + if (!epoch_alive + (session, session->record_parameters[i])) { + _gnutls_epoch_free(session, + session-> + record_parameters[i]); + session->record_parameters[i] = NULL; + } + } + } + + /* Look for contiguous NULLs at the start of the array */ + for (i = 0; + i < MAX_EPOCH_INDEX && session->record_parameters[i] == NULL; + i++); + min_index = i; + + /* Pick up the slack in the epoch window. */ + for (i = 0, j = min_index; j < MAX_EPOCH_INDEX; i++, j++) + session->record_parameters[i] = + session->record_parameters[j]; + + /* Set the new epoch_min */ + if (session->record_parameters[0] != NULL) + session->security_parameters.epoch_min = + session->record_parameters[0]->epoch; + + _gnutls_record_log("REC[%p]: End of epoch cleanup\n", session); } -static inline void -free_record_state (record_state_st * state, int d) +static inline void free_record_state(record_state_st * state, int d) { - _gnutls_free_datum (&state->mac_secret); - _gnutls_free_datum (&state->IV); - _gnutls_free_datum (&state->key); + _gnutls_free_datum(&state->mac_secret); + _gnutls_free_datum(&state->IV); + _gnutls_free_datum(&state->key); - _gnutls_auth_cipher_deinit (&state->cipher_state); + _gnutls_auth_cipher_deinit(&state->cipher_state); - if (state->compression_state.handle != NULL) - _gnutls_comp_deinit (&state->compression_state, d); + if (state->compression_state.handle != NULL) + _gnutls_comp_deinit(&state->compression_state, d); } void -_gnutls_epoch_free (gnutls_session_t session, record_parameters_st * params) +_gnutls_epoch_free(gnutls_session_t session, record_parameters_st * params) { - _gnutls_record_log ("REC[%p]: Epoch #%u freed\n", session, params->epoch); + _gnutls_record_log("REC[%p]: Epoch #%u freed\n", session, + params->epoch); - free_record_state (¶ms->read, 1); - free_record_state (¶ms->write, 0); + free_record_state(¶ms->read, 1); + free_record_state(¶ms->write, 0); - gnutls_free (params); + gnutls_free(params); } |