summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/debug.c1
-rw-r--r--lib/defines.h1
-rw-r--r--lib/gnutls.c1
-rw-r--r--lib/gnutls_algorithms.c1
-rw-r--r--lib/gnutls_buffers.c1
-rw-r--r--lib/gnutls_cipher.c1
-rw-r--r--lib/gnutls_compress.c1
-rw-r--r--lib/gnutls_dh.c78
-rw-r--r--lib/gnutls_dh.h7
-rw-r--r--lib/gnutls_errors.c2
-rw-r--r--lib/gnutls_errors.h3
-rw-r--r--lib/gnutls_handshake.c350
-rw-r--r--lib/gnutls_int.h9
-rw-r--r--lib/gnutls_num.c1
-rw-r--r--lib/gnutls_plaintext.c1
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"