diff options
-rw-r--r-- | lib/gnutls.c | 15 | ||||
-rw-r--r-- | lib/gnutls.h | 2 | ||||
-rw-r--r-- | lib/gnutls_algorithms.c | 6 | ||||
-rw-r--r-- | lib/gnutls_buffers.c | 81 | ||||
-rw-r--r-- | lib/gnutls_buffers.h | 5 | ||||
-rw-r--r-- | lib/gnutls_cipher.c | 29 | ||||
-rw-r--r-- | lib/gnutls_cipher_int.c | 7 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 265 | ||||
-rw-r--r-- | lib/gnutls_hash_int.c | 35 | ||||
-rw-r--r-- | lib/gnutls_hash_int.h | 4 | ||||
-rw-r--r-- | lib/gnutls_int.h | 13 | ||||
-rw-r--r-- | lib/gnutls_kx.c | 37 |
12 files changed, 354 insertions, 145 deletions
diff --git a/lib/gnutls.c b/lib/gnutls.c index f9fdf359ea..77bd7ee17f 100644 --- a/lib/gnutls.c +++ b/lib/gnutls.c @@ -76,6 +76,10 @@ int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end) (*state)->cipher_specs.client_write_key = NULL; (*state)->gnutls_internals.buffer = NULL; + /* SSL3 stuff */ + (*state)->gnutls_internals.client_hash_buffer = NULL; + (*state)->gnutls_internals.server_hash_buffer = NULL; + (*state)->gnutls_internals.buffer_handshake = NULL; (*state)->gnutls_internals.client_md_md5 = NULL; (*state)->gnutls_internals.client_md_sha1 = NULL; @@ -275,9 +279,14 @@ int _gnutls_set_keys(GNUTLS_STATE state) memmove(random, state->security_parameters.server_random, 32); memmove(&random[32], state->security_parameters.client_random, 32); - key_block = - gnutls_PRF( state->security_parameters.master_secret, 48, - keyexp, strlen(keyexp), random, 64, 2 * hash_size + 2 * key_size + 2 * IV_size); + if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3 */ + key_block = gnutls_ssl3_generate_random( state->security_parameters.master_secret, 48, random, 64, + 2 * hash_size + 2 * key_size + 2 * IV_size); + } else { /* TLS 1.0 */ + key_block = + gnutls_PRF( state->security_parameters.master_secret, 48, + keyexp, strlen(keyexp), random, 64, 2 * hash_size + 2 * key_size + 2 * IV_size); + } state->cipher_specs.client_write_mac_secret = secure_malloc(hash_size); memmove(state->cipher_specs.client_write_mac_secret, &key_block[0], hash_size); diff --git a/lib/gnutls.h b/lib/gnutls.h index 1594344903..92233502aa 100644 --- a/lib/gnutls.h +++ b/lib/gnutls.h @@ -20,7 +20,7 @@ enum ContentType { GNUTLS_APPLICATION_DATA=23 }; typedef enum ContentType ContentType; -enum BulkCipherAlgorithm { GNUTLS_NULL, GNUTLS_ARCFOUR=1, GNUTLS_DES=3, GNUTLS_3DES = 4, GNUTLS_RIJNDAEL }; +enum BulkCipherAlgorithm { GNUTLS_NULL, GNUTLS_ARCFOUR=1, GNUTLS_3DES = 4, GNUTLS_RIJNDAEL }; typedef enum BulkCipherAlgorithm BulkCipherAlgorithm; enum KXAlgorithm { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_DH_DSS, GNUTLS_KX_DH_RSA, GNUTLS_KX_ANON_DH }; typedef enum KXAlgorithm KXAlgorithm; diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c index fbc64e7b9c..a7945be77f 100644 --- a/lib/gnutls_algorithms.c +++ b/lib/gnutls_algorithms.c @@ -64,7 +64,6 @@ static gnutls_cipher_entry algorithms[] = { GNUTLS_CIPHER_ENTRY(GNUTLS_3DES, 8, 24, 1, 8), GNUTLS_CIPHER_ENTRY(GNUTLS_RIJNDAEL, 16, 16, 1, 16), #ifdef USE_MCRYPT - GNUTLS_CIPHER_ENTRY(GNUTLS_DES, 8, 8, 1, 8), GNUTLS_CIPHER_ENTRY(GNUTLS_ARCFOUR, 1, 16, 0, 0,), #else GNUTLS_CIPHER_ENTRY(GNUTLS_ARCFOUR, 1, 16, 0, 0), @@ -181,17 +180,12 @@ static gnutls_cipher_suite_entry cs_algorithms[] = { GNUTLS_CIPHER_SUITE_ENTRY(GNUTLS_DH_anon_WITH_ARCFOUR_MD5, GNUTLS_ARCFOUR, GNUTLS_KX_ANON_DH, GNUTLS_MAC_MD5), GNUTLS_CIPHER_SUITE_ENTRY(GNUTLS_DH_anon_WITH_3DES_EDE_CBC_SHA, GNUTLS_3DES, GNUTLS_KX_ANON_DH, GNUTLS_MAC_SHA), GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, GNUTLS_3DES, GNUTLS_KX_DH_DSS, GNUTLS_MAC_SHA), - GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DH_DSS_WITH_DES_CBC_SHA, GNUTLS_DES, GNUTLS_KX_DH_DSS, GNUTLS_MAC_SHA), GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, GNUTLS_3DES, GNUTLS_KX_DH_RSA, GNUTLS_MAC_SHA), - GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DH_RSA_WITH_DES_CBC_SHA, GNUTLS_DES, GNUTLS_KX_DH_RSA, GNUTLS_MAC_SHA), GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,GNUTLS_3DES, GNUTLS_KX_DHE_DSS, GNUTLS_MAC_SHA), GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,GNUTLS_3DES, GNUTLS_KX_DHE_RSA, GNUTLS_MAC_SHA), - GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DHE_DSS_WITH_DES_CBC_SHA, GNUTLS_DES, GNUTLS_KX_DHE_DSS, GNUTLS_MAC_SHA), - GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DHE_RSA_WITH_DES_CBC_SHA, GNUTLS_DES, GNUTLS_KX_DHE_RSA, GNUTLS_MAC_SHA), GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_RSA_WITH_ARCFOUR_SHA, GNUTLS_ARCFOUR, GNUTLS_KX_RSA, GNUTLS_MAC_SHA), GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_RSA_WITH_ARCFOUR_MD5, GNUTLS_ARCFOUR, GNUTLS_KX_RSA, GNUTLS_MAC_MD5), GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_RSA_WITH_3DES_EDE_CBC_SHA, GNUTLS_3DES, GNUTLS_KX_RSA, GNUTLS_MAC_SHA), - GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_RSA_WITH_DES_CBC_SHA, GNUTLS_DES, GNUTLS_KX_RSA, GNUTLS_MAC_SHA), GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_RSA_WITH_RIJNDAEL_128_CBC_SHA, GNUTLS_RIJNDAEL, GNUTLS_KX_RSA, GNUTLS_MAC_SHA), GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DH_DSS_WITH_RIJNDAEL_128_CBC_SHA, GNUTLS_RIJNDAEL, GNUTLS_KX_DH_DSS, GNUTLS_MAC_SHA), GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DH_RSA_WITH_RIJNDAEL_128_CBC_SHA, GNUTLS_RIJNDAEL, GNUTLS_KX_DH_RSA, GNUTLS_MAC_SHA), diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index 92b85ab897..840de05439 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -226,3 +226,84 @@ ssize_t _gnutls_Recv_int(int fd, GNUTLS_STATE state, ContentType type, void *ipt return (sizeOfPtr - left); } + +int gnutls_insertHashDataBuffer( int type, GNUTLS_STATE state, char *data, int length) +{ + int old_buffer; + + if (type==GNUTLS_SERVER) { + old_buffer = state->gnutls_internals.server_hash_bufferSize; + + state->gnutls_internals.server_hash_bufferSize += length; +#ifdef HARD_DEBUG + fprintf(stderr, "Inserted %d bytes of SSL3 Server Hash Data(%d) into buffer\n", length, type); +#endif + state->gnutls_internals.server_hash_buffer = + gnutls_realloc(state->gnutls_internals.server_hash_buffer, + state->gnutls_internals.server_hash_bufferSize); + memmove(&state->gnutls_internals.server_hash_buffer[old_buffer], data, length); + + } else { /* GNUTLS_CLIENT */ + old_buffer = state->gnutls_internals.client_hash_bufferSize; + + state->gnutls_internals.client_hash_bufferSize += length; +#ifdef HARD_DEBUG + fprintf(stderr, "Inserted %d bytes of SSL3 Client Hash Data(%d) into buffer\n", length, type); +#endif + state->gnutls_internals.client_hash_buffer = + gnutls_realloc(state->gnutls_internals.client_hash_buffer, + state->gnutls_internals.client_hash_bufferSize); + memmove(&state->gnutls_internals.client_hash_buffer[old_buffer], data, length); + } + return 0; +} + +int gnutls_getHashDataBufferSize( int type, GNUTLS_STATE state) +{ + if (type==GNUTLS_SERVER) { + return state->gnutls_internals.server_hash_bufferSize; + } else { + return state->gnutls_internals.client_hash_bufferSize; + } +} + +int gnutls_getHashDataFromBuffer(int type, GNUTLS_STATE state, char *data, int length) +{ + if (type==GNUTLS_SERVER) { + if (length > state->gnutls_internals.server_hash_bufferSize) { + length = state->gnutls_internals.server_hash_bufferSize; + } +#ifdef HARD_DEBUG + fprintf(stderr, "Read %d bytes of SSL3 Server Hash Data(%d) from buffer\n", length, type); +#endif + state->gnutls_internals.server_hash_bufferSize -= length; + memmove(data, state->gnutls_internals.server_hash_buffer, length); + /* overwrite buffer */ + memmove(state->gnutls_internals.server_hash_buffer, + &state->gnutls_internals.server_hash_buffer[length], + state->gnutls_internals.server_hash_bufferSize); + state->gnutls_internals.server_hash_buffer = + gnutls_realloc(state->gnutls_internals.server_hash_buffer, + state->gnutls_internals.server_hash_bufferSize); + + return length; + } else { /* CLIENT */ + if (length > state->gnutls_internals.client_hash_bufferSize) { + length = state->gnutls_internals.client_hash_bufferSize; + } +#ifdef HARD_DEBUG + fprintf(stderr, "Read %d bytes of SSL3 Client Hash Data(%d) from buffer\n", length, type); +#endif + state->gnutls_internals.client_hash_bufferSize -= length; + memmove(data, state->gnutls_internals.client_hash_buffer, length); + /* overwrite buffer */ + memmove(state->gnutls_internals.client_hash_buffer, + &state->gnutls_internals.client_hash_buffer[length], + state->gnutls_internals.client_hash_bufferSize); + state->gnutls_internals.client_hash_buffer = + gnutls_realloc(state->gnutls_internals.client_hash_buffer, + state->gnutls_internals.client_hash_bufferSize); + + return length; + } +} diff --git a/lib/gnutls_buffers.h b/lib/gnutls_buffers.h index 8401c4f979..22b24b4530 100644 --- a/lib/gnutls_buffers.h +++ b/lib/gnutls_buffers.h @@ -5,3 +5,8 @@ ssize_t Read(int fd, void *iptr, size_t n); ssize_t Write(int fd, const void *iptr, size_t n); ssize_t _gnutls_Recv_int(int fd, GNUTLS_STATE state, ContentType type, void *iptr, size_t sizeOfPtr); ssize_t _gnutls_Send_int(int fd, GNUTLS_STATE state, ContentType type, void *, size_t); + +/* used in SSL3 */ +int gnutls_getHashDataFromBuffer(int type, GNUTLS_STATE state, char *data, int length); +int gnutls_getHashDataBufferSize(int type, GNUTLS_STATE state); +int gnutls_insertHashDataBuffer(int type, GNUTLS_STATE state, char *data, int length); diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c index 1a5bcd0992..dd713ac93f 100644 --- a/lib/gnutls_cipher.c +++ b/lib/gnutls_cipher.c @@ -413,7 +413,7 @@ int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state, *cipher = gnutls_malloc(sizeof(GNUTLSCiphertext)); ciphertext = *cipher; - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3.0 */ td = gnutls_hash_init_ssl3(state->security_parameters. mac_algorithm, @@ -448,11 +448,17 @@ int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state, if (td != GNUTLS_MAC_FAILED) { /* actually when the algorithm in not the NULL one */ gnutls_hmac(td, &seq_num, 8); gnutls_hmac(td, &compressed->type, 1); - gnutls_hmac(td, &compressed->version.major, 1); - gnutls_hmac(td, &compressed->version.minor, 1); + if (_gnutls_version_ssl3(state->connection_state.version) != 0) { /* TLS 1.0 only */ + gnutls_hmac(td, &compressed->version.major, 1); + gnutls_hmac(td, &compressed->version.minor, 1); + } gnutls_hmac(td, &c_length, 2); gnutls_hmac(td, compressed->fragment, compressed->length); - MAC = gnutls_hmac_deinit(td); + if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3.0 */ + MAC = gnutls_hash_deinit_ssl3(td); + } else { + MAC = gnutls_hmac_deinit(td); + } } switch (state->security_parameters.cipher_type) { case CIPHER_STREAM: @@ -478,8 +484,7 @@ int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state, rand = gcry_random_bytes(1, GCRY_WEAK_RANDOM); /* make rand a multiple of blocksize */ - if (_gnutls_version_ssl3(state->connection_state.version) - == 0) { + if (_gnutls_version_ssl3(state->connection_state.version) == 0) { rand[0] = 0; } else { rand[0] = @@ -638,11 +643,17 @@ int _gnutls_TLSCiphertext2TLSCompressed(GNUTLS_STATE state, if (td != GNUTLS_MAC_FAILED) { gnutls_hmac(td, &seq_num, 8); gnutls_hmac(td, &compressed->type, 1); - gnutls_hmac(td, &compressed->version.major, 1); - gnutls_hmac(td, &compressed->version.minor, 1); + if (_gnutls_version_ssl3(state->connection_state.version) != 0) { /* TLS 1.0 only */ + gnutls_hmac(td, &compressed->version.major, 1); + gnutls_hmac(td, &compressed->version.minor, 1); + } gnutls_hmac(td, &c_length, 2); gnutls_hmac(td, data, compressed->length); - MAC = gnutls_hmac_deinit(td); + if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3.0 */ + MAC = gnutls_hash_deinit_ssl3(td); + } else { + MAC = gnutls_hmac_deinit(td); + } } /* HMAC was not the same. */ if (memcmp diff --git a/lib/gnutls_cipher_int.c b/lib/gnutls_cipher_int.c index 5063f3573f..d5cc0705ca 100644 --- a/lib/gnutls_cipher_int.c +++ b/lib/gnutls_cipher_int.c @@ -31,13 +31,6 @@ GNUTLS_CIPHER_HANDLE ret; case GNUTLS_NULL: ret = GNUTLS_CIPHER_FAILED; break; - case GNUTLS_DES: -#ifdef USE_MCRYPT - ret = mcrypt_module_open( "des", NULL, "cbc", NULL); -#else - ret = GNUTLS_CIPHER_FAILED; -#endif - break; case GNUTLS_RIJNDAEL: #ifdef USE_MCRYPT ret = mcrypt_module_open( "rijndael-128", NULL, "cbc", NULL); diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 215fba392b..62c866ee41 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -48,47 +48,101 @@ */ #define SERVER_MSG "server finished" #define CLIENT_MSG "client finished" +#define SSL3_CLIENT_MSG "CLNT" +#define SSL3_SERVER_MSG "SRVR" int _gnutls_send_finished(int cd, GNUTLS_STATE state) { uint8 *data; uint8 concat[36]; /* md5+sha1 */ int ret; - - - memset(concat, 0, 36); + GNUTLS_MAC_HANDLE td; /* for SSL3 */ + GNUTLS_MAC_HANDLE td2; + int data_size; if (state->security_parameters.entity == GNUTLS_CLIENT) { /* we are a CLIENT */ - memmove(concat, state->gnutls_internals.client_md_md5, 16); - memmove(&concat[16], - state->gnutls_internals.client_md_sha1, 20); - - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3 */ + /* Calculate The SSL3 Finished */ + td = gnutls_hash_init_ssl3( GNUTLS_MAC_MD5, state->security_parameters.master_secret, 48); + td2 = gnutls_hash_init_ssl3( GNUTLS_MAC_SHA, state->security_parameters.master_secret, 48); + + ret = gnutls_getHashDataBufferSize( GNUTLS_CLIENT, state); + data = gnutls_malloc( ret); + + gnutls_getHashDataFromBuffer( GNUTLS_CLIENT, state, data, ret); + + gnutls_hash(td, data, ret); + gnutls_hash(td2, data, ret); + + gnutls_free(data); + gnutls_hash(td, SSL3_CLIENT_MSG, strlen(SSL3_CLIENT_MSG)); + data = gnutls_hash_deinit_ssl3(td); + memcpy( concat, data, 16); + gnutls_free(data); + + gnutls_hash(td2, SSL3_CLIENT_MSG, strlen(SSL3_CLIENT_MSG)); + data = gnutls_hash_deinit_ssl3(td2); + + memcpy( &concat[16], data, 20); + gnutls_free(data); + + data_size = 36; data = concat; } else { + memmove(concat, state->gnutls_internals.client_md_md5, 16); + memmove(&concat[16], + state->gnutls_internals.client_md_sha1, 20); + data = gnutls_PRF( state->security_parameters.master_secret, 48, CLIENT_MSG, strlen(CLIENT_MSG), concat, 36, 12); + data_size = 12; } } else { /* server */ - memmove(concat, state->gnutls_internals.server_md_md5, 16); - memmove(&concat[16], - state->gnutls_internals.server_md_sha1, 20); - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + /* Calculate The SSL3 Finished */ + td = gnutls_hash_init_ssl3( GNUTLS_MAC_MD5, state->security_parameters.master_secret, 48); + td2 = gnutls_hash_init_ssl3( GNUTLS_MAC_SHA, state->security_parameters.master_secret, 48); + + ret = gnutls_getHashDataBufferSize( GNUTLS_SERVER, state); + data = gnutls_malloc( ret); + + gnutls_getHashDataFromBuffer( GNUTLS_SERVER, state, data, ret); + + gnutls_hash(td, data, ret); + gnutls_hash(td2, data, ret); + + gnutls_free(data); + gnutls_hash(td, SSL3_SERVER_MSG, strlen(SSL3_SERVER_MSG)); + data = gnutls_hash_deinit_ssl3(td); + memcpy( concat, data, 16); + gnutls_free(data); + + gnutls_hash(td2, SSL3_SERVER_MSG, strlen(SSL3_SERVER_MSG)); + data = gnutls_hash_deinit_ssl3(td2); + + memcpy( &concat[16], data, 20); + gnutls_free(data); + + data_size = 36; data = concat; - } else { + } else { /* TLS 1 - Using PRF */ + memmove(concat, state->gnutls_internals.server_md_md5, 16); + memmove(&concat[16], + state->gnutls_internals.server_md_sha1, 20); + data = gnutls_PRF( state->security_parameters.master_secret, 48, SERVER_MSG, strlen(SERVER_MSG), concat, 36, 12); + data_size = 12; + } } - ret = _gnutls_send_handshake(cd, state, data, 12, GNUTLS_FINISHED); - if (_gnutls_version_ssl3(state->connection_state.version) != 0) { + ret = _gnutls_send_handshake(cd, state, data, data_size, GNUTLS_FINISHED); + if (_gnutls_version_ssl3(state->connection_state.version) != 0) gnutls_free(data); - } return ret; } @@ -99,9 +153,12 @@ int _gnutls_send_finished(int cd, GNUTLS_STATE state) int _gnutls_recv_finished(int cd, GNUTLS_STATE state) { uint8 *data, *vrfy; + int data_size; uint8 concat[36]; /* md5+sha1 */ int ret; int vrfysize; + GNUTLS_MAC_HANDLE td; /* SSL3 */ + GNUTLS_MAC_HANDLE td2; ret = 0; @@ -110,32 +167,89 @@ int _gnutls_recv_finished(int cd, GNUTLS_STATE state) ERR("recv finished int", ret); return ret; } - if (vrfysize != 12) { + + if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + data_size=36; + } else { + data_size=12; + } + + if (vrfysize != data_size) { gnutls_assert(); return GNUTLS_E_ERROR_IN_FINISHED_PACKET; } if (state->security_parameters.entity == GNUTLS_CLIENT) { - memmove(concat, state->gnutls_internals.server_md_md5, 16); - memmove(&concat[16], - state->gnutls_internals.server_md_sha1, 20); - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + /* Calculate The SSL3 Finished */ + td = gnutls_hash_init_ssl3( GNUTLS_MAC_MD5, state->security_parameters.master_secret, 48); + td2 = gnutls_hash_init_ssl3( GNUTLS_MAC_SHA, state->security_parameters.master_secret, 48); + + ret = gnutls_getHashDataBufferSize( GNUTLS_SERVER, state); + data = gnutls_malloc( ret); + + gnutls_getHashDataFromBuffer( GNUTLS_SERVER, state, data, ret); + + gnutls_hash(td, data, ret); + gnutls_hash(td2, data, ret); + + gnutls_free(data); + gnutls_hash(td, SSL3_SERVER_MSG, strlen(SSL3_SERVER_MSG)); + data = gnutls_hash_deinit_ssl3(td); + memcpy( concat, data, 16); + gnutls_free(data); + + gnutls_hash(td2, SSL3_SERVER_MSG, strlen(SSL3_SERVER_MSG)); + data = gnutls_hash_deinit_ssl3(td2); + + memcpy( &concat[16], data, 20); + gnutls_free(data); + + data_size = 36; data = concat; } else { + memmove(concat, state->gnutls_internals.server_md_md5, 16); + memmove(&concat[16], + state->gnutls_internals.server_md_sha1, 20); + data = gnutls_PRF( state->security_parameters.master_secret, 48, SERVER_MSG, strlen(SERVER_MSG), concat, 36, 12); } } else { /* server */ - memmove(concat, state->gnutls_internals.client_md_md5, 16); - memmove(&concat[16], + if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + /* Calculate The SSL3 Finished */ + td = gnutls_hash_init_ssl3( GNUTLS_MAC_MD5, state->security_parameters.master_secret, 48); + td2 = gnutls_hash_init_ssl3( GNUTLS_MAC_SHA, state->security_parameters.master_secret, 48); + + ret = gnutls_getHashDataBufferSize( GNUTLS_CLIENT, state); + data = gnutls_malloc( ret); + + gnutls_getHashDataFromBuffer( GNUTLS_CLIENT, state, data, ret); + + gnutls_hash(td, data, ret); + gnutls_hash(td2, data, ret); + gnutls_free(data); + + gnutls_hash(td, SSL3_CLIENT_MSG, strlen(SSL3_CLIENT_MSG)); + data = gnutls_hash_deinit_ssl3(td); + memcpy( concat, data, 16); + gnutls_free(data); + + gnutls_hash(td2, SSL3_CLIENT_MSG, strlen(SSL3_CLIENT_MSG)); + data = gnutls_hash_deinit_ssl3(td2); + + memcpy( &concat[16], data, 20); + gnutls_free(data); + + data_size = 36; + data = concat; + } else { /* TLS 1.0 */ + memmove(concat, state->gnutls_internals.client_md_md5, 16); + memmove(&concat[16], state->gnutls_internals.client_md_sha1, 20); - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { - data = concat; - } else { data = gnutls_PRF( state->security_parameters.master_secret, 48, CLIENT_MSG, strlen(CLIENT_MSG), concat, @@ -143,12 +257,13 @@ int _gnutls_recv_finished(int cd, GNUTLS_STATE state) } } - if (memcmp(vrfy, data, 12) != 0) { + if (memcmp(vrfy, data, data_size) != 0) { gnutls_assert(); ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET; } - gnutls_free(data); + if (_gnutls_version_ssl3(state->connection_state.version) != 0) + gnutls_free(data); gnutls_free(vrfy); return ret; @@ -250,16 +365,24 @@ int _gnutls_send_handshake(int cd, GNUTLS_STATE state, void *i_data, memmove(&data[pos], i_data, i_datasize - 4); if (state->gnutls_internals.client_hash == HASH_TRUE) { - gnutls_hash(state->gnutls_internals.client_td_md5, data, - i_datasize); - gnutls_hash(state->gnutls_internals.client_td_sha1, data, - i_datasize); + if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + gnutls_insertHashDataBuffer( GNUTLS_CLIENT, state, data, i_datasize); + } else { /* TLS 1 */ + gnutls_hash(state->gnutls_internals.client_td_md5, data, + i_datasize); + gnutls_hash(state->gnutls_internals.client_td_sha1, data, + i_datasize); + } } if (state->gnutls_internals.server_hash == HASH_TRUE) { - gnutls_hash(state->gnutls_internals.server_td_md5, data, - i_datasize); - gnutls_hash(state->gnutls_internals.server_td_sha1, data, - i_datasize); + if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + gnutls_insertHashDataBuffer( GNUTLS_SERVER, state, data, i_datasize); + } else { /* TLS 1 */ + gnutls_hash(state->gnutls_internals.server_td_md5, data, + i_datasize); + gnutls_hash(state->gnutls_internals.server_td_sha1, data, + i_datasize); + } } #ifdef HARD_DEBUG @@ -355,17 +478,25 @@ int _gnutls_recv_handshake(int cd, GNUTLS_STATE state, uint8 **data, /* here we do the hashing work needed at finished messages */ if (state->gnutls_internals.client_hash == HASH_TRUE) { - gnutls_hash(state->gnutls_internals.client_td_md5, dataptr, - length32 + 4); - gnutls_hash(state->gnutls_internals.client_td_sha1, dataptr, - length32 + 4); + if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + gnutls_insertHashDataBuffer( GNUTLS_CLIENT, state, dataptr, length32+4); + } else { /* TLS 1 */ + gnutls_hash(state->gnutls_internals.client_td_md5, dataptr, + length32 + 4); + gnutls_hash(state->gnutls_internals.client_td_sha1, dataptr, + length32 + 4); + } } if (state->gnutls_internals.server_hash == HASH_TRUE) { - gnutls_hash(state->gnutls_internals.server_td_md5, dataptr, - length32 + 4); - gnutls_hash(state->gnutls_internals.server_td_sha1, dataptr, - length32 + 4); + if (_gnutls_version_ssl3(state->connection_state.version) == 0) { + gnutls_insertHashDataBuffer( GNUTLS_SERVER, state, dataptr, length32+4); + } else { /* TLS 1 */ + gnutls_hash(state->gnutls_internals.server_td_md5, dataptr, + length32 + 4); + gnutls_hash(state->gnutls_internals.server_td_sha1, dataptr, + length32 + 4); + } } @@ -806,13 +937,7 @@ int gnutls_handshake(int cd, GNUTLS_STATE state) /* These are in order to hash the messages transmitted and received. * (needed by the protocol) */ - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { -/* FIXME!!! we need to keep the messages and hash them - later! */ -// state->gnutls_internals.client_td_md5 = gnutls_hash_init_ssl3(GNUTLS_MAC_MD5); -// state->gnutls_internals.client_td_sha1 = gnutls_hash_init_ssl3(GNUTLS_MAC_SHA); -// state->gnutls_internals.server_td_md5 = gnutls_hash_init_ssl3(GNUTLS_MAC_MD5); -// state->gnutls_internals.server_td_sha1 = gnutls_hash_init_ssl3(GNUTLS_MAC_SHA); - } else { + if (_gnutls_version_ssl3(state->connection_state.version) != 0) { /* TLS */ state->gnutls_internals.client_td_md5 = gnutls_hash_init(GNUTLS_MAC_MD5); state->gnutls_internals.client_td_sha1 = gnutls_hash_init(GNUTLS_MAC_SHA); state->gnutls_internals.server_td_md5 = gnutls_hash_init(GNUTLS_MAC_MD5); @@ -917,17 +1042,12 @@ int gnutls_handshake(int cd, GNUTLS_STATE state) ERR("send ChangeCipherSpec", ret); return ret; } - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { - state->gnutls_internals.client_md_md5 = - gnutls_hash_deinit_ssl3(state->gnutls_internals.client_td_md5); - state->gnutls_internals.client_md_sha1 = - gnutls_hash_deinit_ssl3(state->gnutls_internals.client_td_sha1); - } else { - state->gnutls_internals.client_md_md5 = - gnutls_hash_deinit(state->gnutls_internals.client_td_md5); - state->gnutls_internals.client_md_sha1 = - gnutls_hash_deinit(state->gnutls_internals.client_td_sha1); - } + if (_gnutls_version_ssl3(state->connection_state.version) != 0) { /* TLS1 */ + state->gnutls_internals.client_md_md5 = + gnutls_hash_deinit(state->gnutls_internals.client_td_md5); + state->gnutls_internals.client_md_sha1 = + gnutls_hash_deinit(state->gnutls_internals.client_td_sha1); + } /* Initialize the connection state (start encryption) */ ret = _gnutls_connection_state_init(state); @@ -954,12 +1074,7 @@ int gnutls_handshake(int cd, GNUTLS_STATE state) return ret; } - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { - state->gnutls_internals.server_md_md5 = - gnutls_hash_deinit_ssl3(state->gnutls_internals.server_td_md5); - state->gnutls_internals.server_md_sha1 = - gnutls_hash_deinit_ssl3(state->gnutls_internals.server_td_sha1); - } else { + if (_gnutls_version_ssl3(state->connection_state.version) != 0) { /* TLS1 */ state->gnutls_internals.server_md_md5 = gnutls_hash_deinit(state->gnutls_internals.server_td_md5); state->gnutls_internals.server_md_sha1 = @@ -1054,12 +1169,7 @@ int gnutls_handshake(int cd, GNUTLS_STATE state) ret = _gnutls_connection_state_init(state); if (ret<0) return ret; - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { - state->gnutls_internals.client_md_md5 = - gnutls_hash_deinit_ssl3(state->gnutls_internals.client_td_md5); - state->gnutls_internals.client_md_sha1 = - gnutls_hash_deinit_ssl3(state->gnutls_internals.client_td_sha1); - } else { + if (_gnutls_version_ssl3(state->connection_state.version) != 0) { /* TLS 1.0 */ state->gnutls_internals.client_md_md5 = gnutls_hash_deinit(state->gnutls_internals.client_td_md5); state->gnutls_internals.client_md_sha1 = @@ -1081,12 +1191,7 @@ int gnutls_handshake(int cd, GNUTLS_STATE state) return ret; } - if (_gnutls_version_ssl3(state->connection_state.version) == 0) { - state->gnutls_internals.server_md_md5 = - gnutls_hash_deinit_ssl3(state->gnutls_internals.server_td_md5); - state->gnutls_internals.server_md_sha1 = - gnutls_hash_deinit_ssl3(state->gnutls_internals.server_td_sha1); - } else { + if (_gnutls_version_ssl3(state->connection_state.version) != 0) { /* TLS 1.0 */ state->gnutls_internals.server_md_md5 = gnutls_hash_deinit(state->gnutls_internals.server_td_md5); state->gnutls_internals.server_md_sha1 = diff --git a/lib/gnutls_hash_int.c b/lib/gnutls_hash_int.c index 9b10c010c0..89be1699fa 100644 --- a/lib/gnutls_hash_int.c +++ b/lib/gnutls_hash_int.c @@ -125,7 +125,7 @@ void *gnutls_hash_deinit(GNUTLS_MAC_HANDLE handle) } -GNUTLS_MAC_HANDLE gnutls_hmac_init(MACAlgorithm algorithm, char *key, +GNUTLS_MAC_HANDLE gnutls_hmac_init(MACAlgorithm algorithm, void *key, int keylen) { GNUTLS_MAC_HANDLE ret = @@ -232,11 +232,11 @@ void *gnutls_hmac_deinit(GNUTLS_MAC_HANDLE handle) return ret; } -GNUTLS_MAC_HANDLE gnutls_hash_init_ssl3(MACAlgorithm algorithm, char *key, +GNUTLS_MAC_HANDLE gnutls_hash_init_ssl3(MACAlgorithm algorithm, void *key, int keylen) { GNUTLS_MAC_HANDLE ret; - char *ipad; + char ipad[48]; char *digest; int padsize; @@ -251,7 +251,6 @@ GNUTLS_MAC_HANDLE gnutls_hash_init_ssl3(MACAlgorithm algorithm, char *key, padsize = 0; } if (padsize>0) { - ipad = gnutls_malloc(padsize); memset(ipad, 0x36, padsize); } ret = gnutls_hash_init(algorithm); @@ -259,10 +258,9 @@ GNUTLS_MAC_HANDLE gnutls_hash_init_ssl3(MACAlgorithm algorithm, char *key, ret->key = key; ret->keysize = keylen; - if (keylen>0) gnutls_hash(ret, key, keylen); + if (keylen > 0) gnutls_hash(ret, key, keylen); gnutls_hash(ret, ipad, padsize); } - if (padsize>0) gnutls_free(ipad); return ret; } @@ -271,8 +269,9 @@ void *gnutls_hash_deinit_ssl3(GNUTLS_MAC_HANDLE handle) { void *ret=NULL; GNUTLS_MAC_HANDLE td; - char *opad; + char opad[48]; int padsize; + int block; switch (handle->algorithm) { case GNUTLS_MAC_MD5: @@ -285,22 +284,20 @@ void *gnutls_hash_deinit_ssl3(GNUTLS_MAC_HANDLE handle) padsize=0; } if (padsize>0) { - opad = gnutls_malloc(padsize); memset(opad, 0x5C, padsize); } td = gnutls_hash_init(handle->algorithm); if (td!=GNUTLS_MAC_FAILED) { - if (handle->keysize) gnutls_hash(td, handle->key, handle->keysize); + if (handle->keysize > 0) gnutls_hash(td, handle->key, handle->keysize); gnutls_hash(td, opad, padsize); - gnutls_free(opad); - + block = gnutls_hmac_get_algo_len(handle->algorithm); ret = gnutls_hash_deinit(handle); /* get the previous hash */ - gnutls_hash(td, ret, gnutls_hmac_get_algo_len(handle->algorithm)); + gnutls_hash(td, ret, block); gnutls_free(ret); - ret = gnutls_hash_deinit(handle); + ret = gnutls_hash_deinit(td); } return ret; } @@ -335,7 +332,6 @@ static void *ssl3_md5(int i, char *secret, int secret_len, char *random, digest = ssl3_sha(i, secret, secret_len, random, random_len); - gnutls_hash(td, secret, secret_len); gnutls_hash(td, digest, gnutls_hash_get_algo_len(GNUTLS_MAC_SHA)); gnutls_free(digest); @@ -348,18 +344,21 @@ void *gnutls_ssl3_generate_random(void *secret, int secret_len, void *random, { int size = 0, i = 0; char *digest; - char *ret = gnutls_malloc(bytes); - int block = gnutls_hash_get_algo_len(GNUTLS_MAC_SHA); + char *ret = secure_malloc(bytes); + int block = gnutls_hash_get_algo_len(GNUTLS_MAC_MD5); while (size < bytes) { + digest = ssl3_md5(i, secret, secret_len, random, random_len); - size += block; + memmove(&ret[size - block], digest, - size > bytes ? (block - bytes % block) : block); + size > bytes ? (block - (bytes % block)) : block); + gnutls_free(digest); i++; } + return ret; } diff --git a/lib/gnutls_hash_int.h b/lib/gnutls_hash_int.h index 27f7589a45..a95e3942bb 100644 --- a/lib/gnutls_hash_int.h +++ b/lib/gnutls_hash_int.h @@ -27,12 +27,12 @@ typedef GNUTLS_MAC_HANDLE_INT* GNUTLS_MAC_HANDLE; #define GNUTLS_HASH_FAILED NULL #define GNUTLS_MAC_FAILED NULL -GNUTLS_MAC_HANDLE gnutls_hmac_init( MACAlgorithm algorithm, char* key, int keylen); +GNUTLS_MAC_HANDLE gnutls_hmac_init( MACAlgorithm algorithm, void* key, int keylen); int gnutls_hmac_get_algo_len(MACAlgorithm algorithm); int gnutls_hmac(GNUTLS_MAC_HANDLE handle, void* text, int textlen); void* gnutls_hmac_deinit( GNUTLS_MAC_HANDLE handle); -GNUTLS_MAC_HANDLE gnutls_hash_init_ssl3( MACAlgorithm algorithm, char* key, int keylen); +GNUTLS_MAC_HANDLE gnutls_hash_init_ssl3( MACAlgorithm algorithm, void* key, int keylen); void* gnutls_hash_deinit_ssl3( GNUTLS_MAC_HANDLE handle); GNUTLS_MAC_HANDLE gnutls_hash_init(MACAlgorithm algorithm); diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index f42c4ebe4f..2d532d90f1 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -2,7 +2,7 @@ #define GNUTLS_INT_H -#define HARD_DEBUG +//#define HARD_DEBUG //#define READ_DEBUG //#define WRITE_DEBUG #define DEBUG @@ -82,7 +82,7 @@ typedef struct { /* STATE */ enum ConnectionEnd { GNUTLS_SERVER, GNUTLS_CLIENT }; -enum BulkCipherAlgorithm { GNUTLS_NULL, GNUTLS_ARCFOUR=1, GNUTLS_DES=3, GNUTLS_3DES = 4, GNUTLS_RIJNDAEL }; +enum BulkCipherAlgorithm { GNUTLS_NULL, GNUTLS_ARCFOUR=1, GNUTLS_3DES = 4, GNUTLS_RIJNDAEL }; enum KXAlgorithm { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_DH_DSS, GNUTLS_KX_DH_RSA, GNUTLS_KX_ANON_DH }; enum KeyExchangeAlgorithm { GNUTLS_RSA, GNUTLS_DIFFIE_HELLMAN }; enum CipherType { CIPHER_STREAM, CIPHER_BLOCK }; @@ -178,6 +178,10 @@ typedef struct { typedef struct { char* buffer; uint32 bufferSize; + char* client_hash_buffer; /* used in SSL3 */ + uint32 client_hash_bufferSize; /* used in SSL3 */ + char* server_hash_buffer; /* used in SSL3 */ + uint32 server_hash_bufferSize; /* used in SSL3 */ char* buffer_handshake; uint32 bufferSize_handshake; ResumableSession resumable; /* TRUE or FALSE */ @@ -205,9 +209,8 @@ typedef struct { int certificate_requested; /* non zero if client certificate was requested */ int certificate_verify_needed; /* non zero if we should expect for certificate verify */ BulkCipherAlgorithm_Priority BulkCipherAlgorithmPriority; - MACAlgorithm_Priority MACAlgorithmPriority; - KXAlgorithm_Priority KXAlgorithmPriority; - + MACAlgorithm_Priority MACAlgorithmPriority; + KXAlgorithm_Priority KXAlgorithmPriority; } GNUTLS_INTERNALS; typedef struct { diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c index 1f16e973b5..6bc0977a23 100644 --- a/lib/gnutls_kx.c +++ b/lib/gnutls_kx.c @@ -207,14 +207,14 @@ int _gnutls_send_client_kx_message(int cd, GNUTLS_STATE state) } if (_gnutls_version_ssl3(state->connection_state.version) == 0) { - master = - gnutls_ssl3_generate_random( premaster, premaster_size, - random, 64, 48); + master = + gnutls_ssl3_generate_random( premaster, premaster_size, + random, 64, 48); } else { - master = - gnutls_PRF( premaster, premaster_size, - MASTER_SECRET, strlen(MASTER_SECRET), random, 64, - 48); + master = + gnutls_PRF( premaster, premaster_size, + MASTER_SECRET, strlen(MASTER_SECRET), random, 64, + 48); } secure_free(premaster); #ifdef HARD_DEBUG @@ -379,6 +379,7 @@ int _gnutls_recv_client_kx_message(int cd, GNUTLS_STATE state) uint16 n_Y; size_t _n_Y; uint8 *data; + int i; int datasize; int ret = 0; uint8 *premaster = NULL; @@ -454,16 +455,24 @@ int _gnutls_recv_client_kx_message(int cd, GNUTLS_STATE state) } } +#ifdef HARD_DEBUG + fprintf(stderr, "PREMASTER SECRET: "); + for (i=0;i<premaster_size;i++) fprintf(stderr, "%x",premaster[i]); + fprintf(stderr, "\n"); +#endif + if (_gnutls_version_ssl3(state->connection_state.version) == 0) { - master = - gnutls_ssl3_generate_random( premaster, premaster_size, - random, 64, 48); secure_free(premaster); + master = + gnutls_ssl3_generate_random( premaster, premaster_size, + random, 64, 48); + } else { - master = - gnutls_PRF( premaster, premaster_size, - MASTER_SECRET, strlen(MASTER_SECRET), - random, 64, 48); secure_free(premaster); + master = + gnutls_PRF( premaster, premaster_size, + MASTER_SECRET, strlen(MASTER_SECRET), + random, 64, 48); } + secure_free(premaster); #ifdef HARD_DEBUG fprintf(stderr, "master secret: %s\n", _gnutls_bin2hex(master, 48)); #endif |