From e3b2389b5fbb3550c25615ed0b84ab5e4e255f4b Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Wed, 21 Aug 2002 15:04:52 +0000 Subject: Added the first exportable ciphersuite (TLS_RSA_WITH_RC4_EXPORT_MD5). This one only works in servers that have certificates of 512 bits length. --- lib/gnutls.h.in.in | 3 +- lib/gnutls_constate.c | 586 ++++++++++++++++++++++++++++++------------------- lib/gnutls_handshake.c | 3 +- lib/gnutls_hash_int.c | 30 +++ lib/gnutls_hash_int.h | 2 + lib/gnutls_int.h | 3 +- lib/gnutls_state.c | 28 +-- 7 files changed, 402 insertions(+), 253 deletions(-) diff --git a/lib/gnutls.h.in.in b/lib/gnutls.h.in.in index 7e50ae2745..af00cb4935 100644 --- a/lib/gnutls.h.in.in +++ b/lib/gnutls.h.in.in @@ -42,8 +42,7 @@ typedef enum GNUTLS_BulkCipherAlgorithm { GNUTLS_CIPHER_NULL=1, } GNUTLS_BulkCipherAlgorithm; typedef enum GNUTLS_KXAlgorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS, - GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP, - GNUTLS_KX_RSA_EXPORT + GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP } GNUTLS_KXAlgorithm; typedef enum GNUTLS_CredType { GNUTLS_CRD_CERTIFICATE=1, GNUTLS_CRD_ANON, GNUTLS_CRD_SRP } GNUTLS_CredType; diff --git a/lib/gnutls_constate.c b/lib/gnutls_constate.c index 5811dc0cea..9d02e19c0c 100644 --- a/lib/gnutls_constate.c +++ b/lib/gnutls_constate.c @@ -33,16 +33,16 @@ #include 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; #define EXPORT_FINAL_KEY_SIZE 16 @@ -51,167 +51,212 @@ static const int servwrite_length = sizeof(servwrite) - 1; * This function creates the keys and stores them into pending state. * (state->cipher_specs) */ -int _gnutls_set_keys(GNUTLS_STATE state, int hash_size, int IV_size, int key_size, int export_flag) +int _gnutls_set_keys(GNUTLS_STATE state, int hash_size, int IV_size, + int key_size, int export_flag) { opaque *key_block; - char random[2*TLS_RANDOM_SIZE]; + char random[2 * TLS_RANDOM_SIZE]; + char rrandom[2 * TLS_RANDOM_SIZE]; int pos, ret; int block_size; - - if (state->cipher_specs.generated_keys!=0) { + + if (state->cipher_specs.generated_keys != 0) { /* keys have already been generated. * reset generated_keys and exit normally. */ - state->cipher_specs.generated_keys=0; - return 0; + state->cipher_specs.generated_keys = 0; + return 0; } block_size = 2 * hash_size + 2 * key_size; - if (export_flag == 0) block_size += 2 * IV_size; + if (export_flag == 0) + block_size += 2 * IV_size; - key_block = gnutls_secure_malloc( block_size); - if (key_block==NULL) { + key_block = gnutls_secure_malloc(block_size); + if (key_block == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } - - memcpy(random, state->security_parameters.server_random, TLS_RANDOM_SIZE); - memcpy(&random[TLS_RANDOM_SIZE], state->security_parameters.client_random, TLS_RANDOM_SIZE); - - if ( state->security_parameters.version == GNUTLS_SSL3) { /* SSL 3 */ - ret = _gnutls_ssl3_generate_random( state->security_parameters.master_secret, TLS_MASTER_SIZE, random, 2*TLS_RANDOM_SIZE, - block_size, key_block); - } else { /* TLS 1.0 */ + + memcpy(random, state->security_parameters.server_random, + TLS_RANDOM_SIZE); + memcpy(&random[TLS_RANDOM_SIZE], + state->security_parameters.client_random, TLS_RANDOM_SIZE); + + memcpy(rrandom, state->security_parameters.client_random, + TLS_RANDOM_SIZE); + memcpy(&rrandom[TLS_RANDOM_SIZE], + state->security_parameters.server_random, TLS_RANDOM_SIZE); + + if (state->security_parameters.version == GNUTLS_SSL3) { /* SSL 3 */ ret = - _gnutls_PRF( state->security_parameters.master_secret, TLS_MASTER_SIZE, - keyexp, keyexp_length, random, 2*TLS_RANDOM_SIZE, - block_size, key_block); + _gnutls_ssl3_generate_random(state-> + security_parameters. + master_secret, + TLS_MASTER_SIZE, random, + 2 * TLS_RANDOM_SIZE, + block_size, key_block); + } else { /* TLS 1.0 */ + ret = + _gnutls_PRF(state->security_parameters.master_secret, + TLS_MASTER_SIZE, keyexp, keyexp_length, + random, 2 * TLS_RANDOM_SIZE, block_size, + key_block); } - - if (ret<0) { + + if (ret < 0) { gnutls_assert(); gnutls_free(key_block); return ret; } - - _gnutls_hard_log( "INT: KEY BLOCK[%d]: %s\n",block_size, _gnutls_bin2hex(key_block, block_size)); + + _gnutls_hard_log("INT: KEY BLOCK[%d]: %s\n", block_size, + _gnutls_bin2hex(key_block, block_size)); pos = 0; if (hash_size > 0) { - if (gnutls_sset_datum( &state->cipher_specs.client_write_mac_secret, &key_block[pos], hash_size) < 0 ) { + if (gnutls_sset_datum + (&state->cipher_specs.client_write_mac_secret, + &key_block[pos], hash_size) < 0) { gnutls_free(key_block); return GNUTLS_E_MEMORY_ERROR; } - pos+=hash_size; + pos += hash_size; - if (gnutls_sset_datum( &state->cipher_specs.server_write_mac_secret, &key_block[pos], hash_size) < 0 ) { + if (gnutls_sset_datum + (&state->cipher_specs.server_write_mac_secret, + &key_block[pos], hash_size) < 0) { gnutls_free(key_block); return GNUTLS_E_MEMORY_ERROR; } - pos+=hash_size; + pos += hash_size; } - + if (key_size > 0) { - opaque * client_write_key, *server_write_key; + opaque *client_write_key, *server_write_key; int client_write_key_size, server_write_key_size; int free_keys = 0; - if (export_flag==0) { + if (export_flag == 0) { 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; - } else { /* export */ + } else { /* export */ free_keys = 1; - client_write_key = gnutls_secure_malloc( EXPORT_FINAL_KEY_SIZE); + client_write_key = + gnutls_secure_malloc(EXPORT_FINAL_KEY_SIZE); if (client_write_key == NULL) { gnutls_assert(); gnutls_free(key_block); return GNUTLS_E_MEMORY_ERROR; } - server_write_key = gnutls_secure_malloc( EXPORT_FINAL_KEY_SIZE); + server_write_key = + gnutls_secure_malloc(EXPORT_FINAL_KEY_SIZE); if (server_write_key == NULL) { gnutls_assert(); gnutls_free(key_block); - gnutls_free( client_write_key); + gnutls_free(client_write_key); return GNUTLS_E_MEMORY_ERROR; } - + /* generate the final keys */ - /* SSL3: check */ - if ( state->security_parameters.version == GNUTLS_SSL3) { /* SSL 3 */ - ret = _gnutls_ssl3_generate_random( &key_block[pos], key_size, - random, 2*TLS_RANDOM_SIZE, EXPORT_FINAL_KEY_SIZE, - client_write_key); - } else { /* TLS 1.0 */ + if (state->security_parameters.version == GNUTLS_SSL3) { /* SSL 3 */ ret = - _gnutls_PRF( &key_block[pos], key_size, - cliwrite, cliwrite_length, random, 2*TLS_RANDOM_SIZE, - EXPORT_FINAL_KEY_SIZE, client_write_key); + _gnutls_ssl3_hash_md5(&key_block[pos], + key_size, rrandom, + 2 * TLS_RANDOM_SIZE, + EXPORT_FINAL_KEY_SIZE, + client_write_key); + + } else { /* TLS 1.0 */ + ret = + _gnutls_PRF(&key_block[pos], key_size, + cliwrite, cliwrite_length, + rrandom, + 2 * TLS_RANDOM_SIZE, + EXPORT_FINAL_KEY_SIZE, + client_write_key); } - if (ret<0) { + if (ret < 0) { gnutls_assert(); gnutls_free(key_block); - gnutls_free( server_write_key); - gnutls_free( client_write_key); + gnutls_free(server_write_key); + gnutls_free(client_write_key); return ret; } - + client_write_key_size = EXPORT_FINAL_KEY_SIZE; pos += key_size; - if ( state->security_parameters.version == GNUTLS_SSL3) { /* SSL 3 */ - ret = _gnutls_ssl3_generate_random( &key_block[pos], key_size, - random, 2*TLS_RANDOM_SIZE, EXPORT_FINAL_KEY_SIZE, - server_write_key); - } else { /* TLS 1.0 */ + if (state->security_parameters.version == GNUTLS_SSL3) { /* SSL 3 */ + ret = + _gnutls_ssl3_hash_md5(&key_block + [pos], key_size, + random, 2 * TLS_RANDOM_SIZE, + EXPORT_FINAL_KEY_SIZE, + server_write_key); + } else { /* TLS 1.0 */ ret = - _gnutls_PRF( &key_block[pos], key_size, - servwrite, servwrite_length, random, 2*TLS_RANDOM_SIZE, - EXPORT_FINAL_KEY_SIZE, server_write_key); + _gnutls_PRF(&key_block[pos], key_size, + servwrite, servwrite_length, + rrandom, 2 * TLS_RANDOM_SIZE, + EXPORT_FINAL_KEY_SIZE, + server_write_key); } - if (ret<0) { + if (ret < 0) { gnutls_assert(); gnutls_free(key_block); - gnutls_free( server_write_key); - gnutls_free( client_write_key); + gnutls_free(server_write_key); + gnutls_free(client_write_key); return ret; } - + server_write_key_size = EXPORT_FINAL_KEY_SIZE; pos += key_size; - } - if (gnutls_sset_datum( &state->cipher_specs.client_write_key, - client_write_key, client_write_key_size) < 0 ) { + + if (gnutls_sset_datum + (&state->cipher_specs.client_write_key, + client_write_key, client_write_key_size) < 0) { gnutls_free(key_block); - gnutls_free( server_write_key); - gnutls_free( client_write_key); + gnutls_free(server_write_key); + gnutls_free(client_write_key); return GNUTLS_E_MEMORY_ERROR; } - - if (gnutls_sset_datum( &state->cipher_specs.server_write_key, - server_write_key, server_write_key_size) < 0 ) { + _gnutls_hard_log("INT: CLIENT WRITE KEY [%d]: %s\n", + client_write_key_size, + _gnutls_bin2hex(client_write_key, + client_write_key_size)); + + if (gnutls_sset_datum + (&state->cipher_specs.server_write_key, + server_write_key, server_write_key_size) < 0) { gnutls_free(key_block); - gnutls_free( server_write_key); - gnutls_free( client_write_key); + gnutls_free(server_write_key); + gnutls_free(client_write_key); return 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)); + if (free_keys != 0) { - gnutls_free( server_write_key); - gnutls_free( client_write_key); + gnutls_free(server_write_key); + gnutls_free(client_write_key); } } @@ -219,19 +264,24 @@ int _gnutls_set_keys(GNUTLS_STATE state, int hash_size, int IV_size, int key_siz /* IV generation in export and non export ciphers. */ if (IV_size > 0 && export_flag == 0) { - if (gnutls_sset_datum( &state->cipher_specs.client_write_IV, &key_block[pos], IV_size) < 0 ) { + if (gnutls_sset_datum + (&state->cipher_specs.client_write_IV, &key_block[pos], + IV_size) < 0) { gnutls_free(key_block); return GNUTLS_E_MEMORY_ERROR; } - pos+=IV_size; - - if (gnutls_sset_datum( &state->cipher_specs.server_write_IV, &key_block[pos], IV_size) < 0 ) { + pos += IV_size; + + if (gnutls_sset_datum + (&state->cipher_specs.server_write_IV, &key_block[pos], + IV_size) < 0) { gnutls_free(key_block); return GNUTLS_E_MEMORY_ERROR; } - pos+=IV_size; + pos += IV_size; + } else if (IV_size > 0 && export_flag != 0) { - opaque *iv_block = gnutls_alloca( IV_size * 2); + opaque *iv_block = gnutls_alloca(IV_size * 2); if (iv_block == NULL) { gnutls_assert(); @@ -239,34 +289,52 @@ int _gnutls_set_keys(GNUTLS_STATE state, int hash_size, int IV_size, int key_siz return GNUTLS_E_MEMORY_ERROR; } - /* SSL3: check */ - if ( state->security_parameters.version == GNUTLS_SSL3) { /* SSL 3 */ - ret = _gnutls_ssl3_generate_random( "", 0, random, 2*TLS_RANDOM_SIZE, - IV_size*2, iv_block); - } else { /* TLS 1.0 */ + if (state->security_parameters.version == GNUTLS_SSL3) { /* SSL 3 */ + ret = + _gnutls_ssl3_hash_md5( "", 0, + rrandom, TLS_RANDOM_SIZE*2, + IV_size, iv_block); + + if (ret < 0) { + gnutls_assert(); + gnutls_free(key_block); + return ret; + } + ret = - _gnutls_PRF( "", 0, - ivblock, ivblock_length, random, 2*TLS_RANDOM_SIZE, - IV_size*2, iv_block); + _gnutls_ssl3_hash_md5( "", 0, random, + TLS_RANDOM_SIZE*2, + IV_size, &iv_block[IV_size]); + + } else { /* TLS 1.0 */ + ret = + _gnutls_PRF("", 0, + ivblock, ivblock_length, rrandom, + 2 * TLS_RANDOM_SIZE, IV_size * 2, + iv_block); } - if (ret<0) { + if (ret < 0) { gnutls_assert(); gnutls_free(key_block); return ret; } - if (gnutls_sset_datum( &state->cipher_specs.client_write_IV, iv_block, IV_size) < 0 ) { + if (gnutls_sset_datum + (&state->cipher_specs.client_write_IV, iv_block, + IV_size) < 0) { gnutls_free(key_block); return GNUTLS_E_MEMORY_ERROR; } - - if (gnutls_sset_datum( &state->cipher_specs.server_write_IV, &iv_block[IV_size], IV_size) < 0 ) { + + if (gnutls_sset_datum + (&state->cipher_specs.server_write_IV, + &iv_block[IV_size], IV_size) < 0) { gnutls_free(key_block); return GNUTLS_E_MEMORY_ERROR; } } - + gnutls_free(key_block); state->cipher_specs.generated_keys = 1; @@ -281,16 +349,17 @@ int _gnutls_set_read_keys(GNUTLS_STATE state) int key_size, export_flag; BulkCipherAlgorithm algo; MACAlgorithm mac_algo; - + mac_algo = state->security_parameters.read_mac_algorithm; algo = state->security_parameters.read_bulk_cipher_algorithm; - hash_size = _gnutls_mac_get_digest_size( mac_algo); - IV_size = _gnutls_cipher_get_iv_size( algo); - key_size = gnutls_cipher_get_key_size( algo); - export_flag = _gnutls_cipher_get_export_flag( algo); + hash_size = _gnutls_mac_get_digest_size(mac_algo); + IV_size = _gnutls_cipher_get_iv_size(algo); + key_size = gnutls_cipher_get_key_size(algo); + export_flag = _gnutls_cipher_get_export_flag(algo); - return _gnutls_set_keys( state, hash_size, IV_size, key_size, export_flag); + return _gnutls_set_keys(state, hash_size, IV_size, key_size, + export_flag); } int _gnutls_set_write_keys(GNUTLS_STATE state) @@ -300,16 +369,17 @@ int _gnutls_set_write_keys(GNUTLS_STATE state) int key_size, export_flag; BulkCipherAlgorithm algo; MACAlgorithm mac_algo; - + mac_algo = state->security_parameters.write_mac_algorithm; algo = state->security_parameters.write_bulk_cipher_algorithm; - hash_size = _gnutls_mac_get_digest_size( mac_algo); - IV_size = _gnutls_cipher_get_iv_size( algo); - key_size = gnutls_cipher_get_key_size( algo); - export_flag = _gnutls_cipher_get_export_flag( algo); + hash_size = _gnutls_mac_get_digest_size(mac_algo); + IV_size = _gnutls_cipher_get_iv_size(algo); + key_size = gnutls_cipher_get_key_size(algo); + export_flag = _gnutls_cipher_get_export_flag(algo); - return _gnutls_set_keys( state, hash_size, IV_size, key_size, export_flag); + return _gnutls_set_keys(state, hash_size, IV_size, key_size, + export_flag); } #define CPY_COMMON dst->entity = src->entity; \ @@ -325,21 +395,27 @@ int _gnutls_set_write_keys(GNUTLS_STATE state) dst->max_record_send_size = src->max_record_send_size; \ dst->version = src->version; \ memcpy( &dst->extensions, &src->extensions, sizeof(TLSExtensions)); - -static void _gnutls_cpy_read_security_parameters( SecurityParameters * dst, SecurityParameters* src) { - CPY_COMMON; + +static void _gnutls_cpy_read_security_parameters(SecurityParameters * dst, + SecurityParameters * src) +{ + CPY_COMMON; dst->read_bulk_cipher_algorithm = src->read_bulk_cipher_algorithm; dst->read_mac_algorithm = src->read_mac_algorithm; dst->read_compression_algorithm = src->read_compression_algorithm; } -static void _gnutls_cpy_write_security_parameters( SecurityParameters * dst, SecurityParameters* src) { +static void _gnutls_cpy_write_security_parameters(SecurityParameters * dst, + SecurityParameters * src) +{ CPY_COMMON; - - dst->write_bulk_cipher_algorithm = src->write_bulk_cipher_algorithm; + + dst->write_bulk_cipher_algorithm = + src->write_bulk_cipher_algorithm; dst->write_mac_algorithm = src->write_mac_algorithm; - dst->write_compression_algorithm = src->write_compression_algorithm; + dst->write_compression_algorithm = + src->write_compression_algorithm; } /* Sets the current connection state to conform with the @@ -354,7 +430,7 @@ int _gnutls_connection_state_init(GNUTLS_STATE state) /* Setup the master secret */ - if ( (ret = _gnutls_generate_master(state)) < 0) { + if ((ret = _gnutls_generate_master(state)) < 0) { gnutls_assert(); return ret; } @@ -367,83 +443,93 @@ int _gnutls_connection_state_init(GNUTLS_STATE state) /* Initializes the read connection state * (read encrypted data) */ -int _gnutls_read_connection_state_init(GNUTLS_STATE state) { -int mac_size; -int rc; +int _gnutls_read_connection_state_init(GNUTLS_STATE state) +{ + int mac_size; + int rc; _gnutls_uint64zero(&state->connection_state.read_sequence_number); /* Update internals from CipherSuite selected. * If we are resuming just copy the connection state */ - if (state->gnutls_internals.resumed==RESUME_FALSE) { - rc = - _gnutls_set_read_cipher(state, - _gnutls_cipher_suite_get_cipher_algo - (state->security_parameters.current_cipher_suite)); + if (state->gnutls_internals.resumed == RESUME_FALSE) { + rc = _gnutls_set_read_cipher(state, + _gnutls_cipher_suite_get_cipher_algo + (state->security_parameters. + current_cipher_suite)); if (rc < 0) return rc; - rc = - _gnutls_set_read_mac(state, - _gnutls_cipher_suite_get_mac_algo - (state->security_parameters.current_cipher_suite)); + rc = _gnutls_set_read_mac(state, + _gnutls_cipher_suite_get_mac_algo + (state->security_parameters. + current_cipher_suite)); if (rc < 0) return rc; - rc = - _gnutls_set_kx(state, - _gnutls_cipher_suite_get_kx_algo - (state->security_parameters.current_cipher_suite)); + rc = _gnutls_set_kx(state, + _gnutls_cipher_suite_get_kx_algo + (state->security_parameters. + current_cipher_suite)); if (rc < 0) return rc; - rc = - _gnutls_set_read_compression(state, - state->gnutls_internals.compression_method); + rc = _gnutls_set_read_compression(state, + state->gnutls_internals. + compression_method); if (rc < 0) return rc; - } else { /* RESUME_TRUE */ - _gnutls_cpy_read_security_parameters( &state->security_parameters, &state->gnutls_internals.resumed_security_parameters); + } else { /* RESUME_TRUE */ + _gnutls_cpy_read_security_parameters(&state-> + security_parameters, + &state-> + gnutls_internals. + resumed_security_parameters); } rc = _gnutls_set_read_keys(state); if (rc < 0) return rc; - - _gnutls_handshake_log( "HSK: Cipher Suite: %s\n", - _gnutls_cipher_suite_get_name(state-> - security_parameters.current_cipher_suite)); - if (_gnutls_compression_is_ok(state->security_parameters.read_compression_algorithm) != 0) { + _gnutls_handshake_log("HSK: Cipher Suite: %s\n", + _gnutls_cipher_suite_get_name(state-> + security_parameters. + current_cipher_suite)); + + if (_gnutls_compression_is_ok + (state->security_parameters.read_compression_algorithm) != 0) { gnutls_assert(); return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM; } - if (_gnutls_mac_is_ok(state->security_parameters.read_mac_algorithm) != 0) { + if (_gnutls_mac_is_ok + (state->security_parameters.read_mac_algorithm) != 0) { gnutls_assert(); return GNUTLS_E_UNKNOWN_MAC_ALGORITHM; } /* Free all the previous keys/ states etc. */ - if ( state->connection_state.read_mac_secret.data != NULL) - gnutls_sfree_datum( &state->connection_state.read_mac_secret); + if (state->connection_state.read_mac_secret.data != NULL) + gnutls_sfree_datum(&state->connection_state. + read_mac_secret); if (state->connection_state.read_cipher_state != NULL) _gnutls_cipher_deinit(state->connection_state. - read_cipher_state); + read_cipher_state); if (state->connection_state.read_compression_state != NULL) _gnutls_comp_deinit(state->connection_state. - read_compression_state, 1); + read_compression_state, 1); mac_size = _gnutls_mac_get_digest_size(state->security_parameters. - read_mac_algorithm); + read_mac_algorithm); - _gnutls_handshake_log( "HSK: Initializing internal [read] cipher states\n"); + _gnutls_handshake_log + ("HSK: Initializing internal [read] cipher states\n"); switch (state->security_parameters.entity) { case GNUTLS_SERVER: @@ -451,13 +537,15 @@ int rc; */ state->connection_state.read_cipher_state = _gnutls_cipher_init(state->security_parameters. - read_bulk_cipher_algorithm, - state->cipher_specs.client_write_key, - state->cipher_specs.client_write_IV); + read_bulk_cipher_algorithm, + state->cipher_specs. + client_write_key, + state->cipher_specs. + client_write_IV); if (state->connection_state.read_cipher_state == GNUTLS_CIPHER_FAILED - && state->security_parameters.read_bulk_cipher_algorithm != - GNUTLS_CIPHER_NULL) { + && state->security_parameters. + read_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL) { gnutls_assert(); return GNUTLS_E_UNKNOWN_CIPHER; } @@ -466,9 +554,12 @@ int rc; * state. */ if (mac_size > 0) { - gnutls_sset_datum( &state->connection_state.read_mac_secret, - state->cipher_specs.client_write_mac_secret.data, - state->cipher_specs.client_write_mac_secret.size); + gnutls_sset_datum(&state->connection_state. + read_mac_secret, + state->cipher_specs. + client_write_mac_secret.data, + state->cipher_specs. + client_write_mac_secret.size); } @@ -477,15 +568,16 @@ int rc; case GNUTLS_CLIENT: state->connection_state.read_cipher_state = _gnutls_cipher_init(state->security_parameters. - read_bulk_cipher_algorithm, - state->cipher_specs. - server_write_key, - state->cipher_specs.server_write_IV); - + read_bulk_cipher_algorithm, + state->cipher_specs. + server_write_key, + state->cipher_specs. + server_write_IV); + if (state->connection_state.read_cipher_state == GNUTLS_CIPHER_FAILED - && state->security_parameters.read_bulk_cipher_algorithm != - GNUTLS_CIPHER_NULL) { + && state->security_parameters. + read_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL) { gnutls_assert(); return GNUTLS_E_UNKNOWN_CIPHER; } @@ -494,21 +586,24 @@ int rc; /* copy mac secret to connection state */ if (mac_size > 0) { - gnutls_sset_datum( &state->connection_state.read_mac_secret, - state->cipher_specs.server_write_mac_secret.data, - state->cipher_specs.server_write_mac_secret.size); + gnutls_sset_datum(&state->connection_state. + read_mac_secret, + state->cipher_specs. + server_write_mac_secret.data, + state->cipher_specs. + server_write_mac_secret.size); } break; - default: /* this check is useless */ + default: /* this check is useless */ gnutls_assert(); return GNUTLS_E_UNKNOWN_ERROR; } state->connection_state.read_compression_state = _gnutls_comp_init(state->security_parameters. - read_compression_algorithm, 1); + read_compression_algorithm, 1); if (state->connection_state.read_compression_state == GNUTLS_COMP_FAILED) { @@ -524,59 +619,68 @@ int rc; /* Initializes the write connection state * (write encrypted data) */ -int _gnutls_write_connection_state_init(GNUTLS_STATE state) { -int mac_size; -int rc; +int _gnutls_write_connection_state_init(GNUTLS_STATE state) +{ + int mac_size; + int rc; _gnutls_uint64zero(&state->connection_state.write_sequence_number); /* Update internals from CipherSuite selected. * If we are resuming just copy the connection state */ - if (state->gnutls_internals.resumed==RESUME_FALSE) { - rc = - _gnutls_set_write_cipher(state, - _gnutls_cipher_suite_get_cipher_algo - (state->security_parameters.current_cipher_suite)); + if (state->gnutls_internals.resumed == RESUME_FALSE) { + rc = _gnutls_set_write_cipher(state, + _gnutls_cipher_suite_get_cipher_algo + (state->security_parameters. + current_cipher_suite)); if (rc < 0) return rc; - rc = - _gnutls_set_write_mac(state, - _gnutls_cipher_suite_get_mac_algo - (state->security_parameters.current_cipher_suite)); + rc = _gnutls_set_write_mac(state, + _gnutls_cipher_suite_get_mac_algo + (state->security_parameters. + current_cipher_suite)); if (rc < 0) return rc; - rc = - _gnutls_set_kx(state, - _gnutls_cipher_suite_get_kx_algo - (state->security_parameters.current_cipher_suite)); + rc = _gnutls_set_kx(state, + _gnutls_cipher_suite_get_kx_algo + (state->security_parameters. + current_cipher_suite)); if (rc < 0) return rc; - rc = - _gnutls_set_write_compression(state, - state->gnutls_internals.compression_method); + rc = _gnutls_set_write_compression(state, + state->gnutls_internals. + compression_method); if (rc < 0) return rc; - } else { /* RESUME_TRUE */ - _gnutls_cpy_write_security_parameters( &state->security_parameters, &state->gnutls_internals.resumed_security_parameters); + } else { /* RESUME_TRUE */ + _gnutls_cpy_write_security_parameters(&state-> + security_parameters, + &state-> + gnutls_internals. + resumed_security_parameters); } - + rc = _gnutls_set_write_keys(state); if (rc < 0) return rc; - _gnutls_handshake_log( "HSK: Cipher Suite: %s\n", - _gnutls_cipher_suite_get_name(state-> - security_parameters.current_cipher_suite)); + _gnutls_handshake_log("HSK: Cipher Suite: %s\n", + _gnutls_cipher_suite_get_name(state-> + security_parameters. + current_cipher_suite)); - if (_gnutls_compression_is_ok(state->security_parameters.write_compression_algorithm) != 0) { + if (_gnutls_compression_is_ok + (state->security_parameters.write_compression_algorithm) != + 0) { gnutls_assert(); return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM; } - if (_gnutls_mac_is_ok(state->security_parameters.write_mac_algorithm) != 0) { + if (_gnutls_mac_is_ok + (state->security_parameters.write_mac_algorithm) != 0) { gnutls_assert(); return GNUTLS_E_UNKNOWN_MAC_ALGORITHM; } @@ -586,33 +690,40 @@ int rc; /* Free all the previous keys/ states etc. */ if (state->connection_state.write_mac_secret.data != NULL) - gnutls_sfree_datum( &state->connection_state.write_mac_secret); + gnutls_sfree_datum(&state->connection_state. + write_mac_secret); if (state->connection_state.write_cipher_state != NULL) _gnutls_cipher_deinit(state->connection_state. - write_cipher_state); + write_cipher_state); if (state->connection_state.write_compression_state != NULL) _gnutls_comp_deinit(state->connection_state. - write_compression_state, 0); + write_compression_state, 0); mac_size = _gnutls_mac_get_digest_size(state->security_parameters. write_mac_algorithm); - _gnutls_handshake_log( "HSK: Initializing internal [write] cipher states\n"); + _gnutls_handshake_log + ("HSK: Initializing internal [write] cipher states\n"); switch (state->security_parameters.entity) { case GNUTLS_SERVER: /* initialize cipher state */ state->connection_state.write_cipher_state = - _gnutls_cipher_init(state->security_parameters.write_bulk_cipher_algorithm, - state->cipher_specs.server_write_key, - state->cipher_specs.server_write_IV); + _gnutls_cipher_init(state->security_parameters. + write_bulk_cipher_algorithm, + state->cipher_specs. + server_write_key, + state->cipher_specs. + server_write_IV); - if (state->connection_state.write_cipher_state == GNUTLS_CIPHER_FAILED - && state->security_parameters.write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL) { + if (state->connection_state.write_cipher_state == + GNUTLS_CIPHER_FAILED + && state->security_parameters. + write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL) { gnutls_assert(); return GNUTLS_E_UNKNOWN_CIPHER; } @@ -622,9 +733,12 @@ int rc; * state. */ if (mac_size > 0) { - gnutls_sset_datum( &state->connection_state.write_mac_secret, - state->cipher_specs.server_write_mac_secret.data, - state->cipher_specs.server_write_mac_secret.size); + gnutls_sset_datum(&state->connection_state. + write_mac_secret, + state->cipher_specs. + server_write_mac_secret.data, + state->cipher_specs. + server_write_mac_secret.size); } @@ -634,14 +748,16 @@ int rc; case GNUTLS_CLIENT: state->connection_state.write_cipher_state = _gnutls_cipher_init(state->security_parameters. - write_bulk_cipher_algorithm, - state->cipher_specs.client_write_key, - state->cipher_specs.client_write_IV); + write_bulk_cipher_algorithm, + state->cipher_specs. + client_write_key, + state->cipher_specs. + client_write_IV); if (state->connection_state.write_cipher_state == GNUTLS_CIPHER_FAILED - && state->security_parameters.write_bulk_cipher_algorithm != - GNUTLS_CIPHER_NULL) { + && state->security_parameters. + write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL) { gnutls_assert(); return GNUTLS_E_UNKNOWN_CIPHER; } @@ -649,9 +765,12 @@ int rc; /* copy mac secret to connection state */ if (mac_size > 0) { - gnutls_sset_datum( &state->connection_state.write_mac_secret, - state->cipher_specs.client_write_mac_secret.data, - state->cipher_specs.client_write_mac_secret.size); + gnutls_sset_datum(&state->connection_state. + write_mac_secret, + state->cipher_specs. + client_write_mac_secret.data, + state->cipher_specs. + client_write_mac_secret.size); } break; @@ -663,9 +782,11 @@ int rc; state->connection_state.write_compression_state = - _gnutls_comp_init(state->security_parameters.write_compression_algorithm, 0); + _gnutls_comp_init(state->security_parameters. + write_compression_algorithm, 0); - if (state->connection_state.write_compression_state == GNUTLS_COMP_FAILED) { + if (state->connection_state.write_compression_state == + GNUTLS_COMP_FAILED) { gnutls_assert(); return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM; } @@ -684,7 +805,8 @@ int _gnutls_set_read_cipher(GNUTLS_STATE state, BulkCipherAlgorithm algo) return GNUTLS_E_UNWANTED_ALGORITHM; } - state->security_parameters.read_bulk_cipher_algorithm = algo; + state->security_parameters.read_bulk_cipher_algorithm = + algo; } else { gnutls_assert(); @@ -704,7 +826,8 @@ int _gnutls_set_write_cipher(GNUTLS_STATE state, BulkCipherAlgorithm algo) return GNUTLS_E_UNWANTED_ALGORITHM; } - state->security_parameters.write_bulk_cipher_algorithm = algo; + state->security_parameters.write_bulk_cipher_algorithm = + algo; } else { gnutls_assert(); @@ -718,11 +841,13 @@ int _gnutls_set_write_cipher(GNUTLS_STATE state, BulkCipherAlgorithm algo) /* Sets the specified algorithm into pending compression state */ -int _gnutls_set_read_compression(GNUTLS_STATE state, CompressionMethod algo) +int _gnutls_set_read_compression(GNUTLS_STATE state, + CompressionMethod algo) { - if (_gnutls_compression_is_ok(algo)==0) { - state->security_parameters.read_compression_algorithm = algo; + if (_gnutls_compression_is_ok(algo) == 0) { + state->security_parameters.read_compression_algorithm = + algo; } else { gnutls_assert(); return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM; @@ -731,11 +856,13 @@ int _gnutls_set_read_compression(GNUTLS_STATE state, CompressionMethod algo) } -int _gnutls_set_write_compression(GNUTLS_STATE state, CompressionMethod algo) +int _gnutls_set_write_compression(GNUTLS_STATE state, + CompressionMethod algo) { - if (_gnutls_compression_is_ok(algo)==0) { - state->security_parameters.write_compression_algorithm = algo; + if (_gnutls_compression_is_ok(algo) == 0) { + state->security_parameters.write_compression_algorithm = + algo; } else { gnutls_assert(); return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM; @@ -803,4 +930,3 @@ int _gnutls_set_write_mac(GNUTLS_STATE state, MACAlgorithm algo) return 0; } - diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index f07a7cb93c..56257d5fe2 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -1340,7 +1340,6 @@ static int _gnutls_copy_ciphersuites(GNUTLS_STATE state, return GNUTLS_E_INSUFICIENT_CRED; } - cipher_num = ret; cipher_num *= sizeof(uint16); /* in order to get bytes */ @@ -1358,7 +1357,7 @@ static int _gnutls_copy_ciphersuites(GNUTLS_STATE state, _gnutls_write_uint16(cipher_num, *ret_data); pos += 2; - for (i = 0; i < (cipher_num / 2) - 1; i++) { + for (i = 0; i < (cipher_num / 2); i++) { memcpy( &(*ret_data)[pos], cipher_suites[i].CipherSuite, 2); pos += 2; } diff --git a/lib/gnutls_hash_int.c b/lib/gnutls_hash_int.c index 51eb9b985c..4d772e0ae8 100644 --- a/lib/gnutls_hash_int.c +++ b/lib/gnutls_hash_int.c @@ -99,6 +99,7 @@ int _gnutls_hash_get_algo_len(MACAlgorithm algorithm) int _gnutls_hash(GNUTLS_HASH_HANDLE handle, const void *text, int textlen) { + if (textlen > 0) #ifdef USE_MHASH mhash(handle->handle, text, textlen); #else @@ -452,6 +453,35 @@ static int ssl3_md5(int i, char *secret, int secret_len, char *random, return 0; } +int _gnutls_ssl3_hash_md5(void *first, int first_len, + void *second, int second_len, int ret_len, opaque* ret) +{ + opaque digest[MAX_HASH_SIZE]; + GNUTLS_MAC_HANDLE td; + int block = _gnutls_hash_get_algo_len(GNUTLS_MAC_MD5); + + td = _gnutls_hash_init(GNUTLS_MAC_MD5); + if (td == NULL) { + gnutls_assert(); + return GNUTLS_E_HASH_FAILED; + } + + _gnutls_hash(td, first, first_len); + _gnutls_hash(td, second, second_len); + + _gnutls_hash_deinit(td, digest); + + if ( block > ret_len) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + memcpy( ret, digest, ret_len); + + return 0; + +} + int _gnutls_ssl3_generate_random(void *secret, int secret_len, void *random, int random_len, int bytes, opaque* ret) { diff --git a/lib/gnutls_hash_int.h b/lib/gnutls_hash_int.h index 9804f51802..7607cdb0be 100644 --- a/lib/gnutls_hash_int.h +++ b/lib/gnutls_hash_int.h @@ -59,6 +59,8 @@ int _gnutls_hash(GNUTLS_HASH_HANDLE handle, const void* text, int textlen); void _gnutls_hash_deinit(GNUTLS_HASH_HANDLE handle, void* digest); int _gnutls_ssl3_generate_random(void *secret, int secret_len, void *random, int random_len, int bytes, opaque* ret); +int _gnutls_ssl3_hash_md5(void *first, int first_len, + void *second, int second_len, int ret_len, opaque* ret); void _gnutls_mac_deinit_ssl3_handshake(GNUTLS_MAC_HANDLE handle, void* digest, opaque* key, uint32 key_size); diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 82ae8beaca..ef66490695 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -165,8 +165,7 @@ typedef enum Extensions { GNUTLS_EXTENSION_MAX_RECORD_SIZE=1, GNUTLS_EXTENSION_S } Extensions; typedef enum KXAlgorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS, - GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP, - GNUTLS_KX_RSA_EXPORT + GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP } KXAlgorithm; #define GNUTLS_KXAlgorithm KXAlgorithm diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index 60d2382485..09dbcd7b52 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -534,8 +534,9 @@ static int _gnutls_P_hash( MACAlgorithm algorithm, const opaque * secret, int se { GNUTLS_MAC_HANDLE td2; - int i = 0, times, how, blocksize, A_size; + int i, times, how, blocksize, A_size; opaque final[20], Atmp[MAX_SEED_SIZE]; + int output_bytes; if (seed_size > MAX_SEED_SIZE || total_bytes<=0) { gnutls_assert(); @@ -543,16 +544,19 @@ static int _gnutls_P_hash( MACAlgorithm algorithm, const opaque * secret, int se } blocksize = _gnutls_hmac_get_algo_len(algorithm); + + output_bytes = 0; do { - i += blocksize; - } while (i < total_bytes); + output_bytes += blocksize; + } while (output_bytes < total_bytes); /* calculate A(0) */ memcpy( Atmp, seed, seed_size); A_size = seed_size; - times = i / blocksize; + times = output_bytes / blocksize; + for (i = 0; i < times; i++) { td2 = _gnutls_hmac_init(algorithm, secret, secret_size); @@ -579,24 +583,14 @@ static int _gnutls_P_hash( MACAlgorithm algorithm, const opaque * secret, int se return 0; } -/* Function that xor's buffers using the maximum word size supported - * by the system. It should be faster. - only if one / and % are much faster - * than the whole xor operation. +/* Xor's two buffers and puts the output in the first one. */ inline static -void _gnutls_xor(void* _o1, void* _o2, int _length) { -unsigned long int* o1 = _o1; -unsigned long int* o2 = _o2; -int i, length = _length/sizeof(unsigned long int); -int modlen = _length%sizeof(unsigned long int); - +void _gnutls_xor(opaque* o1, opaque* o2, int length) { +int i; for (i = 0; i < length; i++) { o1[i] ^= o2[i]; } - i*=sizeof(unsigned long int); - for (;i