diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/debug.c | 1 | ||||
-rw-r--r-- | lib/defines.h | 1 | ||||
-rw-r--r-- | lib/gnutls.c | 1 | ||||
-rw-r--r-- | lib/gnutls_algorithms.c | 1 | ||||
-rw-r--r-- | lib/gnutls_buffers.c | 1 | ||||
-rw-r--r-- | lib/gnutls_cipher.c | 1 | ||||
-rw-r--r-- | lib/gnutls_compress.c | 1 | ||||
-rw-r--r-- | lib/gnutls_dh.c | 78 | ||||
-rw-r--r-- | lib/gnutls_dh.h | 7 | ||||
-rw-r--r-- | lib/gnutls_errors.c | 2 | ||||
-rw-r--r-- | lib/gnutls_errors.h | 3 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 350 | ||||
-rw-r--r-- | lib/gnutls_int.h | 9 | ||||
-rw-r--r-- | lib/gnutls_num.c | 1 | ||||
-rw-r--r-- | lib/gnutls_plaintext.c | 1 |
15 files changed, 413 insertions, 45 deletions
diff --git a/lib/debug.c b/lib/debug.c index 9343de237d..a696e1f8ea 100644 --- a/lib/debug.c +++ b/lib/debug.c @@ -1,7 +1,6 @@ #include <stdio.h> #include <stdlib.h> #include <defines.h> -#include <mhash.h> #include "gnutls_int.h" #include "gnutls_errors.h" diff --git a/lib/defines.h b/lib/defines.h index 546aaed186..ef88347691 100644 --- a/lib/defines.h +++ b/lib/defines.h @@ -26,7 +26,6 @@ # include <unistd.h> #endif -#include <gcrypt.h> #if SIZEOF_UNSIGNED_LONG_INT == 8 typedef unsigned long int uint64; diff --git a/lib/gnutls.c b/lib/gnutls.c index d1cbd209a3..7113d2e5f7 100644 --- a/lib/gnutls.c +++ b/lib/gnutls.c @@ -1,5 +1,4 @@ #include <defines.h> -#include <mhash.h> #include "gnutls_int.h" #include "gnutls_errors.h" #include "debug.h" diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c index 549afb483f..487c353afa 100644 --- a/lib/gnutls_algorithms.c +++ b/lib/gnutls_algorithms.c @@ -1,5 +1,4 @@ #include <defines.h> -#include <mhash.h> #include "gnutls_int.h" #include "gnutls_algorithms.h" diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index 9b8b3fd6f1..334a54e986 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -1,5 +1,4 @@ #include <defines.h> -#include <mhash.h> #include "gnutls_int.h" #include "gnutls_errors.h" diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c index 904b316efe..c514e11c43 100644 --- a/lib/gnutls_cipher.c +++ b/lib/gnutls_cipher.c @@ -1,5 +1,4 @@ #include <defines.h> -#include <mhash.h> #include "gnutls_int.h" #include "gnutls_errors.h" #include "gnutls_compress.h" diff --git a/lib/gnutls_compress.c b/lib/gnutls_compress.c index fa0d2bb11b..9938da3b5e 100644 --- a/lib/gnutls_compress.c +++ b/lib/gnutls_compress.c @@ -1,5 +1,4 @@ #include <defines.h> -#include <mhash.h> #include "gnutls_int.h" #include "gnutls_compress.h" #include "gnutls_errors.h" diff --git a/lib/gnutls_dh.c b/lib/gnutls_dh.c index a593b1a669..f7718dff40 100644 --- a/lib/gnutls_dh.c +++ b/lib/gnutls_dh.c @@ -1,5 +1,7 @@ #include <defines.h> -#include <gcrypt.h> +#include <gnutls_int.h> + +/* Taken from gsti */ static const uint8 diffie_hellman_group1_prime[130] = { 0x04, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, @@ -15,23 +17,27 @@ static const uint8 diffie_hellman_group1_prime[130] = { 0x04, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; #if 0 - --Example-- - you: X = g^x mod p; + --Example-- + you: X = g^x mod p; peer: Y = g^y mod p; - g = mpi_set_ui( NULL, 2 ); + your_key = Y^x mod p; + his_key = X^y mod p; + /* generate our secret and the public value for it */ - X = calc_dh_secret( &x ); + X = _gnutls_calc_dh_secret( &x ); /* now we can calculate the shared secret */ - key = calc_dh_key( Y, x ); + key = _gnutls_calc_dh_key( Y, x); mpi_release( x ); + mpi_release( g ); #endif /**************** * Choose a random value x and calculate e = g^x mod p. * Return: e and if ret_x is not NULL x. + * It also returns g and p. */ -MPI calc_dh_secret( MPI *ret_x ) +MPI _gnutls_calc_dh_secret( MPI *ret_x ) { MPI e, g, x, prime; size_t n = sizeof diffie_hellman_group1_prime; @@ -53,24 +59,72 @@ MPI calc_dh_secret( MPI *ret_x ) *ret_x = x; else mpi_release(x); - mpi_release(g); - mpi_release(prime); + mpi_release(g); + mpi_release(prime); return e; } +MPI __gnutls_calc_dh_secret( MPI *ret_x, MPI g, MPI prime ) +{ + MPI e, x; + + x = mpi_new( 200 ); /* FIXME: allocate in secure memory */ + gcry_mpi_randomize( x, 200, GCRY_STRONG_RANDOM ); + /* fixme: set high bit of x and select a larger one */ + + e = mpi_new(1024); + mpi_powm( e, g, x, prime ); + + if( ret_x ) + *ret_x = x; + else + mpi_release(x); + return e; +} -MPI calc_dh_key( MPI f, MPI x ) +/* returns g and p */ +MPI _gnutls_get_dh_params( MPI *ret_p ) { - MPI k, prime; + MPI g, prime; size_t n = sizeof diffie_hellman_group1_prime; - if( gcry_mpi_scan( &prime, GCRYMPI_FMT_STD, + if( gcry_mpi_scan( &prime, GCRYMPI_FMT_STD, diffie_hellman_group1_prime, &n ) ) abort(); + g = mpi_set_ui( NULL, 2 ); + + if( ret_p ) + *ret_p = prime; + else + mpi_release(prime); + return g; +} + + +MPI _gnutls_calc_dh_key( MPI f, MPI x ) +{ + MPI k, prime; + size_t n = sizeof diffie_hellman_group1_prime; + k = mpi_new( 1024 ); /* FIXME: allocate in secure memory */ + if( gcry_mpi_scan( &prime, GCRYMPI_FMT_STD, + diffie_hellman_group1_prime, &n ) ) + abort(); + /*dump_mpi(stderr, "prime=", prime );*/ + mpi_powm( k, f, x, prime ); mpi_release(prime); return k; } +MPI __gnutls_calc_dh_key( MPI f, MPI x, MPI prime ) +{ + MPI k; + + k = mpi_new( 1024 ); /* FIXME: allocate in secure memory */ + + mpi_powm( k, f, x, prime ); + return k; +} + diff --git a/lib/gnutls_dh.h b/lib/gnutls_dh.h index bdd5d74ece..67e4810329 100644 --- a/lib/gnutls_dh.h +++ b/lib/gnutls_dh.h @@ -1,2 +1,5 @@ -MPI calc_dh_secret( MPI *ret_x ); -MPI calc_dh_key( MPI f, MPI x ); +MPI _gnutls_calc_dh_secret( MPI *ret_x ); +MPI _gnutls_get_dh_params(MPI *ret_p); +MPI _gnutls_calc_dh_key( MPI f, MPI x ); +MPI __gnutls_calc_dh_secret( MPI *ret_x, MPI g, MPI prime ); +MPI __gnutls_calc_dh_key( MPI f, MPI x, MPI prime ); diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index b571eb7adf..ae7abe4c96 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -21,6 +21,8 @@ int gnutls_is_fatal_error( int error) { case GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET: case GNUTLS_E_CLOSURE_ALERT_RECEIVED: case GNUTLS_E_ERROR_IN_FINISHED_PACKET: + case GNUTLS_E_UNIMPLEMENTED_FEATURE: + case GNUTLS_E_UNKNOWN_KX_ALGORITHM: return 1; case GNUTLS_E_WARNING_ALERT_RECEIVED: return 0; diff --git a/lib/gnutls_errors.h b/lib/gnutls_errors.h index 7a251a27b9..28ba61a564 100644 --- a/lib/gnutls_errors.h +++ b/lib/gnutls_errors.h @@ -17,3 +17,6 @@ #define GNUTLS_E_CLOSURE_ALERT_RECEIVED -17 #define GNUTLS_E_ERROR_IN_FINISHED_PACKET -18 #define GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET -19 +#define GNUTLS_E_UNKNOWN_KX_ALGORITHM -20 + +#define GNUTLS_E_UNIMPLEMENTED_FEATURE -50 diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 57e31d5582..35af059d7a 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -1,7 +1,7 @@ #include <defines.h> -#include <mhash.h> #include "gnutls_int.h" #include "gnutls_errors.h" +#include "gnutls_dh.h" #include "debug.h" #include "gnutls_algorithms.h" #include "gnutls_compress.h" @@ -21,33 +21,280 @@ #define HASH_FALSE 0 -int _gnutls_send_kx_message(int cd, GNUTLS_STATE state) +int _gnutls_send_server_kx_message(int cd, GNUTLS_STATE state) { KX_Algorithm algorithm; + MPI x, Y, g, p; + int n_Y, n_g, n_p; + uint16 _n_Y, _n_g, _n_p; + uint8 data[1536]; /* 3*512 */ + uint8 *data_p; + uint8 *data_g; + uint8 *data_Y; + int ret=0; + + + n_Y = n_g = n_p = 512 - 2; algorithm = - _gnutls_cipher_suite_get_kx_algo(state->gnutls_internals. - current_cipher_suite. - CipherSuite); + _gnutls_cipher_suite_get_kx_algo(state-> + gnutls_internals.current_cipher_suite); /* Do key exchange only if the algorithm permits it */ if (_gnutls_kx_algo_server_key_exchange(algorithm) != 0) { - if (_gnutls_kx_algo_DH_public_value != 0) { - data[0] = GNUTLS_DIFFIE_HELLMAN; + if ( _gnutls_cipher_suite_get_kx_algo(state->gnutls_internals.current_cipher_suite) == KX_ANON_DH) { + Y = _gnutls_calc_dh_secret(&x); + state->gnutls_internals.dh_secret = x; + g = _gnutls_get_dh_params(&p); + + + data_p = &data[0]; + gcry_mpi_print(GCRYMPI_FMT_STD, &data_p[2], + &n_p, p); + + _n_p = n_p; +#ifndef WORDS_BIGENDIAN + _n_p = byteswap16(_n_p); + memmove(data_p, &_n_p, 2); +#else + memmove(data_p, &_n_p, 2); +#endif + + + data_g = &data_p[2+n_p]; + gcry_mpi_print(GCRYMPI_FMT_STD, &data_g[2], + &n_g, g); + _n_g = n_g; +#ifndef WORDS_BIGENDIAN + + _n_g = byteswap16(_n_g); + memmove(data_g, &_n_g, 2); +#else + memmove(data_g, &_n_g, 2); +#endif + + data_Y = &data_g[2+n_g]; + gcry_mpi_print(GCRYMPI_FMT_STD, &data_Y[2], + &n_Y, Y); + _n_Y = n_Y; +#ifndef WORDS_BIGENDIAN + _n_Y = byteswap16(_n_Y); + memmove(data_Y, &_n_Y, 2); +#else + memmove(data_Y, &_n_Y, 2); +#endif + + + ret = + _gnutls_send_handshake(cd, state, data, + n_p + n_g + n_Y + 6, + GNUTLS_SERVER_KEY_EXCHANGE); } else { - data[0] = GNUTLS_RSA; + ret = GNUTLS_E_UNKNOWN_KX_ALGORITHM; } - g = mpi_set_ui(NULL, 2); - E = calc_dh_secret(&y); + } + + return ret; + +} + +int _gnutls_send_client_kx_message(int cd, GNUTLS_STATE state) +{ + KX_Algorithm algorithm; + MPI x, X; + int n_X; + uint16 _n_X; + uint8 data[1536]; /* 3*512 */ + int ret=0; + uint8 premaster[1500]; + int premaster_size = sizeof(premaster); + svoid* master; + char* random = gnutls_malloc(64); + + memmove( random, state->security_parameters.client_random, 32); + memmove( &random[32], state->security_parameters.server_random, 32); + + n_X = 1530; + + algorithm = + _gnutls_cipher_suite_get_kx_algo(state-> + gnutls_internals.current_cipher_suite); + + if ( _gnutls_cipher_suite_get_kx_algo(state->gnutls_internals.current_cipher_suite) == KX_ANON_DH) { + + data[0] = 1; /* extern */ + + X = __gnutls_calc_dh_secret(&x, state->gnutls_internals.client_g, state->gnutls_internals.client_p); + gcry_mpi_print(GCRYMPI_FMT_STD, &data[3], + &n_X, X); + + + _n_X = n_X; +#ifndef WORDS_BIGENDIAN + _n_X = byteswap16(_n_X); + memmove(&data[1], &_n_X, 2); +#else + memmove(&data[1], &_n_X, 2); +#endif + + ret = + _gnutls_send_handshake(cd, state, data, + n_X + 3, + GNUTLS_CLIENT_KEY_EXCHANGE); + + /* calculate the key after sending the message */ + state->gnutls_internals.KEY = __gnutls_calc_dh_key( state->gnutls_internals.client_Y, x, state->gnutls_internals.client_p); + gcry_mpi_print(GCRYMPI_FMT_STD, premaster, + &premaster_size, state->gnutls_internals.KEY); + fprintf(stderr, "premaster: %s || %d\n", bin2hex(premaster, premaster_size), premaster_size); + + } else { + ret = GNUTLS_E_UNKNOWN_KX_ALGORITHM; } - return 0; + master = gnutls_PRF( premaster, premaster_size, "master secret", strlen("master secret"), + random, 64 ,48); + memmove( state->security_parameters.master_secret, master, 48); + secure_free(master); + gnutls_free(random); + + return ret; + +} + +int _gnutls_recv_server_kx_message(int cd, GNUTLS_STATE state) +{ + KX_Algorithm algorithm; + uint16 n_Y, n_g, n_p; + int _n_Y, _n_g, _n_p; + uint8 data[15000]; + uint8 *data_p; + uint8 *data_g; + uint8 *data_Y; + int ret=0, i=0; + + n_Y = n_g = n_p = 512 - 2; + + algorithm = + _gnutls_cipher_suite_get_kx_algo(state-> + gnutls_internals.current_cipher_suite); + + /* Do key exchange only if the algorithm permits it */ + if (_gnutls_kx_algo_server_key_exchange(algorithm) != 0) { + + if ( _gnutls_cipher_suite_get_kx_algo(state->gnutls_internals.current_cipher_suite) == KX_ANON_DH) { + + state->gnutls_internals.next_handshake_type = GNUTLS_SERVER_KEY_EXCHANGE; + ret = gnutls_recv_int(cd, state, GNUTLS_HANDSHAKE, data, 15000); + state->gnutls_internals.next_handshake_type = GNUTLS_NONE; + + + memmove( &n_p, &data[i], 2); + i+=2; +#ifndef WORDS_BIGENDIAN + n_p = byteswap16(n_p); +#endif + data_p = &data[i]; + i+=n_p; + + memmove( &n_g, &data[i], 2); +#ifndef WORDS_BIGENDIAN + n_g = byteswap16(n_g); +#endif + i+=2; + data_g = &data[i]; + i+=n_g; + + memmove( &n_Y, &data[i], 2); + i+=2; +#ifndef WORDS_BIGENDIAN + n_Y = byteswap16(n_Y); +#endif + i+=n_Y; + data_Y = &data[i]; + + _n_Y = n_Y; + _n_g = n_g; + _n_p = n_p; + + gcry_mpi_scan( &state->gnutls_internals.client_Y, GCRYMPI_FMT_STD, data_Y, &_n_Y); + gcry_mpi_scan( &state->gnutls_internals.client_g, GCRYMPI_FMT_STD, data_g, &_n_g); + gcry_mpi_scan( &state->gnutls_internals.client_p, GCRYMPI_FMT_STD, data_p, &_n_p); + } else { + ret = GNUTLS_E_UNKNOWN_KX_ALGORITHM; + } + } + + return ret; + +} + +int _gnutls_recv_client_kx_message(int cd, GNUTLS_STATE state) +{ + KX_Algorithm algorithm; + uint16 n_Y; + int _n_Y; + uint8 data[1000]; + int ret=0; + uint8 premaster[1500]; + int premaster_size = sizeof(premaster); + svoid* master; + char* random = gnutls_malloc(64); + + memmove( random, state->security_parameters.client_random, 32); + memmove( &random[32], state->security_parameters.server_random, 32); + + n_Y = 1000 - 3; + + algorithm = + _gnutls_cipher_suite_get_kx_algo(state-> + gnutls_internals.current_cipher_suite); + + /* Do key exchange only if the algorithm permits it */ + if (_gnutls_kx_algo_server_key_exchange(algorithm) != 0) { + + if ( _gnutls_cipher_suite_get_kx_algo(state->gnutls_internals.current_cipher_suite) == KX_ANON_DH) { + + state->gnutls_internals.next_handshake_type = GNUTLS_CLIENT_KEY_EXCHANGE; + ret = gnutls_recv_int(cd, state, GNUTLS_HANDSHAKE, data, 15000); + state->gnutls_internals.next_handshake_type = GNUTLS_NONE; + + if ( data[0] != 1) return GNUTLS_E_UNIMPLEMENTED_FEATURE; + + memmove( &n_Y, &data[1], 2); +#ifndef WORDS_BIGENDIAN + n_Y = byteswap16(n_Y); +#endif + + _n_Y = n_Y; + + gcry_mpi_scan( &state->gnutls_internals.client_Y, GCRYMPI_FMT_STD, &data[3], &_n_Y); + state->gnutls_internals.KEY = _gnutls_calc_dh_key( state->gnutls_internals.client_Y, state->gnutls_internals.dh_secret); + + gcry_mpi_print(GCRYMPI_FMT_STD, premaster, + &premaster_size, state->gnutls_internals.KEY); + fprintf(stderr, "premaster: %s\n", bin2hex(premaster, premaster_size)); + } else { + ret = GNUTLS_E_UNKNOWN_KX_ALGORITHM; + } + } + + master = gnutls_PRF( premaster, premaster_size, "master secret", strlen("master secret"), + random, 64 ,48); + memmove( state->security_parameters.master_secret, master, 48); + secure_free(master); + gnutls_free(random); + + + return ret; } + + #define SERVER_MSG "server finished" #define CLIENT_MSG "client finished" int _gnutls_send_finished(int cd, GNUTLS_STATE state) @@ -202,8 +449,8 @@ int _gnutls_supported_ciphersuites(GNUTLS_CipherSuite ** ciphers) for (i = 0; i < count; i++) { - - (*ciphers)[i].CipherSuite[0] = + + (*ciphers)[i].CipherSuite[0] = cipher_suite_algorithms[i].suite.CipherSuite[0]; (*ciphers)[i].CipherSuite[1] = cipher_suite_algorithms[i].suite.CipherSuite[1]; @@ -248,6 +495,7 @@ int _gnutls_send_handshake(int cd, GNUTLS_STATE state, void *i_data, i_datasize += 4; data = gnutls_malloc(i_datasize); + memmove(&data[pos++], &type, 1); memmove(&data[pos++], &length.pint[0], 1); memmove(&data[pos++], &length.pint[1], 1); @@ -311,6 +559,7 @@ int _gnutls_recv_handshake_int(int cd, GNUTLS_STATE state, void *data, } ret = GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET; + switch (dataptr[0]) { case GNUTLS_CLIENT_HELLO: case GNUTLS_SERVER_HELLO: @@ -328,6 +577,18 @@ int _gnutls_recv_handshake_int(int cd, GNUTLS_STATE state, void *data, memmove(output_data, &dataptr[4], length32); ret = length32; break; + case GNUTLS_SERVER_KEY_EXCHANGE: + if (output_datasize > length32) + output_datasize = length32; + memmove(output_data, &dataptr[4], length32); + ret = length32; + break; + case GNUTLS_CLIENT_KEY_EXCHANGE: + if (output_datasize > length32) + output_datasize = length32; + memmove(output_data, &dataptr[4], length32); + ret = length32; + break; } return ret; @@ -459,8 +720,8 @@ int _gnutls_send_hello(int cd, GNUTLS_STATE state, opaque * SessionID, datalen += 2; data = gnutls_realloc(data, datalen); memmove(&data[pos], - &state->gnutls_internals.current_cipher_suite. - CipherSuite, 2); + &state->gnutls_internals. + current_cipher_suite.CipherSuite, 2); pos += 2; datalen += 1; @@ -539,8 +800,9 @@ int _gnutls_recv_hello(int cd, GNUTLS_STATE state, char *data, int datalen, } if (z != 0) return GNUTLS_E_UNKNOWN_CIPHER_TYPE; - memmove(state->gnutls_internals.current_cipher_suite. - CipherSuite, cipher_suite.CipherSuite, 2); + memmove(state->gnutls_internals. + current_cipher_suite.CipherSuite, + cipher_suite.CipherSuite, 2); z = 1; memmove(&compression_method, &data[pos++], 1); @@ -592,13 +854,15 @@ int _gnutls_recv_hello(int cd, GNUTLS_STATE state, char *data, int datalen, #ifndef WORDS_BIGENDIAN sizeOfSuites = byteswap16(sizeOfSuites); #endif - SelectSuite(state->gnutls_internals.current_cipher_suite. - CipherSuite, &data[pos], sizeOfSuites); + SelectSuite(state->gnutls_internals. + current_cipher_suite.CipherSuite, &data[pos], + sizeOfSuites); pos += sizeOfSuites; memmove(&z, &data[pos++], 1); - SelectCompMethod(&state->gnutls_internals. - compression_method, &data[pos], z); + SelectCompMethod(&state-> + gnutls_internals.compression_method, + &data[pos], z); } @@ -645,6 +909,18 @@ int gnutls_handshake(int cd, GNUTLS_STATE state) /* RECV CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */ + /* receive the server key exchange */ + HASH(client_hash); + HASH(server_hash); + ret = _gnutls_recv_server_kx_message(cd, state); + NOT_HASH(client_hash); + NOT_HASH(server_hash); + if (ret < 0) { + ERR("recv server hello done", ret); + return ret; + } + + /* receive the server hello done */ HASH(client_hash); HASH(server_hash); @@ -660,6 +936,17 @@ int gnutls_handshake(int cd, GNUTLS_STATE state) /* SEND CERTIFICATE + KEYEXCHANGE + CERTIFICATE_VERIFY */ + HASH(client_hash); + HASH(server_hash); + ret = _gnutls_send_client_kx_message(cd, state); + NOT_HASH(client_hash); + NOT_HASH(server_hash); + if (ret < 0) { + ERR("send client kx", ret); + return ret; + } + + /* Send the CHANGE CIPHER SPEC PACKET */ ret = _gnutls_send_change_cipher_spec(cd, state); if (ret < 0) { @@ -744,7 +1031,15 @@ int gnutls_handshake(int cd, GNUTLS_STATE state) gnutls_free(session_id); /* SEND CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */ - + HASH(client_hash); + HASH(server_hash); + ret = _gnutls_send_server_kx_message(cd, state); + NOT_HASH(client_hash); + NOT_HASH(server_hash); + if (ret < 0) { + ERR("send server kx", ret); + return ret; + } /* send the server hello done */ HASH(client_hash); @@ -760,6 +1055,17 @@ int gnutls_handshake(int cd, GNUTLS_STATE state) } /* RECV CERTIFICATE + KEYEXCHANGE + CERTIFICATE_VERIFY */ + + HASH(client_hash); + HASH(server_hash); + ret = _gnutls_recv_client_kx_message(cd, state); + NOT_HASH(client_hash); + NOT_HASH(server_hash); + if (ret < 0) { + ERR("recv client kx", ret); + return ret; + } + /* Initialize the connection state (start encryption) */ diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 93ea7b292a..e409f3083d 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -1,3 +1,6 @@ +#include <gcrypt.h> +#include <mhash.h> + #define DEBUG #define svoid void /* for functions that allocate using secure_free */ @@ -150,6 +153,12 @@ typedef struct { void* server_md_sha1; int server_hash; int client_hash; + /* For DH KX */ + MPI KEY; + MPI client_Y; + MPI client_g; + MPI client_p; + MPI dh_secret; } GNUTLS_INTERNALS; typedef struct { diff --git a/lib/gnutls_num.c b/lib/gnutls_num.c index 4374d32ecb..141d43c266 100644 --- a/lib/gnutls_num.c +++ b/lib/gnutls_num.c @@ -1,5 +1,4 @@ #include <defines.h> -#include <mhash.h> #include <gnutls_int.h> uint32 uint24touint32( uint24 num) { diff --git a/lib/gnutls_plaintext.c b/lib/gnutls_plaintext.c index b57ad97911..5a82106de1 100644 --- a/lib/gnutls_plaintext.c +++ b/lib/gnutls_plaintext.c @@ -1,5 +1,4 @@ #include <defines.h> -#include <mhash.h> #include "gnutls_int.h" #include "gnutls_errors.h" |