summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2000-12-06 20:21:47 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2000-12-06 20:21:47 +0000
commit41a568c52fb71c692ed086b36404adfb70153bb5 (patch)
tree1ab5ecad81979b2edb953ee9b92f5880001495ed
parentda7248019a054f11eb633592f8f7bd9251b195e3 (diff)
downloadgnutls-41a568c52fb71c692ed086b36404adfb70153bb5.tar.gz
A lot of fixes for SSL3
-rw-r--r--lib/gnutls.c15
-rw-r--r--lib/gnutls.h2
-rw-r--r--lib/gnutls_algorithms.c6
-rw-r--r--lib/gnutls_buffers.c81
-rw-r--r--lib/gnutls_buffers.h5
-rw-r--r--lib/gnutls_cipher.c29
-rw-r--r--lib/gnutls_cipher_int.c7
-rw-r--r--lib/gnutls_handshake.c265
-rw-r--r--lib/gnutls_hash_int.c35
-rw-r--r--lib/gnutls_hash_int.h4
-rw-r--r--lib/gnutls_int.h13
-rw-r--r--lib/gnutls_kx.c37
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