summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-06-19 08:52:01 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-06-19 08:52:01 +0000
commitd8b7191de9df39cd78a2c4e5f5c7e6be000e0401 (patch)
tree104e7aad5e32267ab863dae50f3488f5e28141dc
parent669edad5e2e0a92411d721064e68e9c8698dd386 (diff)
downloadgnutls-d8b7191de9df39cd78a2c4e5f5c7e6be000e0401.tar.gz
fixes in session resuming..
-rw-r--r--NEWS1
-rw-r--r--doc/TODO1
-rw-r--r--lib/auth_rsa.c12
-rw-r--r--lib/debug.c40
-rw-r--r--lib/debug.h3
-rw-r--r--lib/gnutls.h.in2
-rw-r--r--lib/gnutls_cipher.c14
-rw-r--r--lib/gnutls_handshake.c547
-rw-r--r--lib/gnutls_int.h8
-rw-r--r--lib/gnutls_kx.c98
-rw-r--r--lib/gnutls_kx.h1
-rw-r--r--lib/gnutls_record.c55
-rw-r--r--lib/gnutls_session.c2
-rw-r--r--lib/gnutls_v2_compat.c3
-rw-r--r--src/serv.c41
15 files changed, 478 insertions, 350 deletions
diff --git a/NEWS b/NEWS
index a8a899a4cb..02de73833a 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ Version 0.1.4
- Added RSA Ciphersuites (server side only).
- Fixes in SSL 2.0 client hello parsing.
- Added ASN.1 and DER parsers.
+- Bugfixes in session resuming
Version 0.1.3 (01/06/2001)
- Updated API (and the way it is documented - we use inline documentation)
diff --git a/doc/TODO b/doc/TODO
index 07af4063cb..b73be9d6eb 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -8,4 +8,3 @@
only one parse of the der structures.
* Create global variables that hold read/write and initialize
the ASN.1 parser's structures.
-* Fix session resuming
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c
index 04a4b4941c..5259359980 100644
--- a/lib/auth_rsa.c
+++ b/lib/auth_rsa.c
@@ -74,8 +74,8 @@ int _gnutls_calc_rsa_signature( GNUTLS_KEY key, const opaque* data, int data_siz
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
}
- gnutls_hash( td, key->client_random, 32);
- gnutls_hash( td, key->server_random, 32);
+ gnutls_hash( td, key->client_random, TLS_RANDOM_SIZE);
+ gnutls_hash( td, key->server_random, TLS_RANDOM_SIZE);
gnutls_hash( td, data, data_size);
md5 = gnutls_hash_deinit(td);
@@ -92,8 +92,8 @@ int _gnutls_calc_rsa_signature( GNUTLS_KEY key, const opaque* data, int data_siz
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
}
- gnutls_hash( td, key->client_random, 32);
- gnutls_hash( td, key->server_random, 32);
+ gnutls_hash( td, key->client_random, TLS_RANDOM_SIZE);
+ gnutls_hash( td, key->server_random, TLS_RANDOM_SIZE);
gnutls_hash( td, data, data_size);
sha = gnutls_hash_deinit(td);
@@ -388,7 +388,7 @@ int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data)
return pdatasize;
}
-#define RANDOMIZE_X(x) x.size=48; x.data=gnutls_malloc(x.size); \
+#define RANDOMIZE_X(x) x.size=TLS_MASTER_SIZE; x.data=gnutls_malloc(x.size); \
if (x.data==NULL) return GNUTLS_E_MEMORY_ERROR; \
if (_gnutls_get_random( key->key.data, key->key.size, GNUTLS_WEAK_RANDOM) < 0) { \
return GNUTLS_E_MEMORY_ERROR; \
@@ -419,7 +419,7 @@ int proc_rsa_client_kx( GNUTLS_KEY key, opaque* data, int data_size) {
RANDOMIZE_X(key->key);
} else {
ret = 0;
- if (plaintext.size != 48) { /* WOW */
+ if (plaintext.size != TLS_MASTER_SIZE) { /* WOW */
RANDOMIZE_X(key->key);
} else {
if (key->version.major != plaintext.data[0]) ret = GNUTLS_E_DECRYPTION_FAILED;
diff --git a/lib/debug.c b/lib/debug.c
index 2c61d408bd..98b39f5fea 100644
--- a/lib/debug.c
+++ b/lib/debug.c
@@ -77,46 +77,6 @@ void _gnutls_print_state(GNUTLS_STATE state)
}
-void _gnutls_print_TLSCompressed(GNUTLSCompressed * compressed)
-{
- fprintf(stderr, "TLSCompressed packet:\n");
- fprintf(stderr, "type: %d\n", compressed->type);
- fprintf(stderr, "version: %d,%d\n", compressed->version.major,
- compressed->version.minor);
- fprintf(stderr, "length: %d\n", compressed->length);
- fprintf(stderr, "fragment: %s\n",
- _gnutls_bin2hex(compressed->fragment, compressed->length));
- fprintf(stderr, "\n");
-}
-
-
-void _gnutls_print_TLSPlaintext(GNUTLSPlaintext * plaintext)
-{
- fprintf(stderr, "TLSPlaintext packet:\n");
- fprintf(stderr, "type: %d\n", plaintext->type);
- fprintf(stderr, "version: %d,%d\n", plaintext->version.major,
- plaintext->version.minor);
- fprintf(stderr, "length: %d\n", plaintext->length);
- fprintf(stderr, "fragment: %s\n",
- _gnutls_bin2hex(plaintext->fragment, plaintext->length));
- fprintf(stderr, "\n");
-}
-
-
-void _gnutls_print_TLSCiphertext(GNUTLSCiphertext * ciphertext)
-{
-
- fprintf(stderr, "TLSCiphertext packet:\n");
- fprintf(stderr, "type: %d\n", ciphertext->type);
- fprintf(stderr, "version: %d,%d\n", ciphertext->version.major,
- ciphertext->version.minor);
- fprintf(stderr, "length: %d\n", ciphertext->length);
-
- fprintf(stderr, "fragment: %s\n",
- _gnutls_bin2hex(ciphertext->fragment, ciphertext->length));
- fprintf(stderr, "\n");
-}
-
char* _gnutls_alert2str( int alert) {
static char str[512];
diff --git a/lib/debug.h b/lib/debug.h
index b793c1a106..85ad14b261 100644
--- a/lib/debug.h
+++ b/lib/debug.h
@@ -20,9 +20,6 @@
#ifdef DEBUG
void _gnutls_print_state(GNUTLS_STATE state);
-void _gnutls_print_TLSCompressed(GNUTLSCompressed * compressed);
-void _gnutls_print_TLSPlaintext(GNUTLSPlaintext * plaintext);
-void _gnutls_print_TLSCiphertext( GNUTLSCiphertext *);
char * _gnutls_bin2hex(const unsigned char *old, const size_t oldlen);
void _gnutls_dump_mpi(char* prefix,MPI a);
char* _gnutls_packet2str( int packet);
diff --git a/lib/gnutls.h.in b/lib/gnutls.h.in
index 80a5e61748..9283d26f0f 100644
--- a/lib/gnutls.h.in
+++ b/lib/gnutls.h.in
@@ -56,6 +56,8 @@ typedef struct {
int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end);
int gnutls_deinit(GNUTLS_STATE state);
int gnutls_bye(SOCKET cd, GNUTLS_STATE state);
+int gnutls_bye_nowait(SOCKET cd, GNUTLS_STATE state);
+
int gnutls_handshake(SOCKET cd, GNUTLS_STATE state);
int gnutls_check_pending(GNUTLS_STATE state);
int gnutls_rehandshake(SOCKET cd, GNUTLS_STATE state);
diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c
index 942bff194a..41b451d2c0 100644
--- a/lib/gnutls_cipher.c
+++ b/lib/gnutls_cipher.c
@@ -30,6 +30,7 @@
#include "gnutls_random.h"
#include "gnutls_num.h"
#include "gnutls_datum.h"
+#include "gnutls_kx.h"
int _gnutls_encrypt(GNUTLS_STATE state, const char *data, size_t data_size,
uint8 ** ciphertext, ContentType type)
@@ -186,7 +187,7 @@ int _gnutls_set_mac(GNUTLS_STATE state, MACAlgorithm algo)
*/
int _gnutls_connection_state_init(GNUTLS_STATE state)
{
- int rc, mac_size;
+ int rc, mac_size, ret;
uint64zero(&state->connection_state.write_sequence_number);
uint64zero(&state->connection_state.read_sequence_number);
@@ -225,19 +226,20 @@ int _gnutls_connection_state_init(GNUTLS_STATE state)
/* clear the resumed security parameters */
memset( &state->gnutls_internals.resumed_security_parameters, 0, sizeof(SecurityParameters));
-#ifdef HARD_DEBUG
- fprintf(stderr, "Master Secret: %s\n", _gnutls_bin2hex(state->security_parameters.master_secret, 48));
-#endif
}
/* Setup the keys since we have the master secret
*/
- _gnutls_set_keys(state);
+ if ( (ret=_gnutls_generate_master(state)) < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ _gnutls_set_keys(state);
#ifdef DEBUG
fprintf(stderr, "Cipher Suite: %s\n",
_gnutls_cipher_suite_get_name(state->
- security_parameters.current_suite));
+ security_parameters.current_cipher_suite));
#endif
if (state->connection_state.write_mac_secret!=NULL)
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 957bd009f1..f268270941 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -46,18 +46,63 @@
#define TRUE 1
#define FALSE 0
-static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data, int datalen);
-int _gnutls_SelectCompMethod(GNUTLS_STATE state, CompressionMethod * ret, opaque * data, int datalen);
+static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data,
+ int datalen);
+int _gnutls_SelectCompMethod(GNUTLS_STATE state, CompressionMethod * ret,
+ opaque * data, int datalen);
-void _gnutls_set_server_random( GNUTLS_STATE state, uint8* random) {
- memcpy( state->security_parameters.server_random, random, TLS_RANDOM_SIZE);
- if (state->gnutls_key!=NULL)
- memcpy( state->gnutls_key->server_random, random, TLS_RANDOM_SIZE);
+/* this will keep as less data to security_parameters.
+ */
+static void resume_copy_required_values(GNUTLS_STATE state) {
+ /* get the new random values */
+ memcpy(state->gnutls_internals.resumed_security_parameters.
+ server_random,
+ state->security_parameters.server_random,
+ TLS_RANDOM_SIZE);
+ memcpy(state->gnutls_internals.resumed_security_parameters.
+ client_random,
+ state->security_parameters.client_random,
+ TLS_RANDOM_SIZE);
+
+ /* keep the ciphersuite and compression
+ * That is because the client must see these in our
+ * hello message.
+ */
+ memcpy(state->security_parameters.current_cipher_suite.
+ CipherSuite,
+ state->gnutls_internals.resumed_security_parameters.
+ current_cipher_suite.CipherSuite, 2);
+ state->gnutls_internals.compression_method =
+ state->gnutls_internals.resumed_security_parameters.
+ compression_algorithm;
+
+ memcpy(state->security_parameters.session_id,
+ state->gnutls_internals.resumed_security_parameters.
+ session_id, sizeof(state->security_parameters.session_id));
+ state->security_parameters.session_id_size =
+ state->gnutls_internals.resumed_security_parameters.
+ session_id_size;
+
+
+ return;
}
-void _gnutls_set_client_random( GNUTLS_STATE state, uint8* random) {
- memcpy( state->security_parameters.client_random, random, TLS_RANDOM_SIZE);
- if (state->gnutls_key!=NULL)
- memcpy( state->gnutls_key->client_random, random, TLS_RANDOM_SIZE);
+
+void _gnutls_set_server_random(GNUTLS_STATE state, uint8 * random)
+{
+ memcpy(state->security_parameters.server_random, random,
+ TLS_RANDOM_SIZE);
+ if (state->gnutls_key != NULL)
+ memcpy(state->gnutls_key->server_random, random,
+ TLS_RANDOM_SIZE);
+}
+
+void _gnutls_set_client_random(GNUTLS_STATE state, uint8 * random)
+{
+ memcpy(state->security_parameters.client_random, random,
+ TLS_RANDOM_SIZE);
+ if (state->gnutls_key != NULL)
+ memcpy(state->gnutls_key->client_random, random,
+ TLS_RANDOM_SIZE);
}
/* Calculate The SSL3 Finished message */
@@ -157,19 +202,21 @@ void *_gnutls_finished(GNUTLS_STATE state, int type, int skip)
/* this function will produce TLS_RANDOM_SIZE bytes of random data
* and put it to dst.
*/
-int _gnutls_create_random( opaque* dst) {
-uint32 tim;
-opaque rand[TLS_RANDOM_SIZE-4];
+int _gnutls_create_random(opaque * dst)
+{
+ uint32 tim;
+ opaque rand[TLS_RANDOM_SIZE - 4];
tim = time(NULL);
/* generate server random value */
- WRITEuint32( tim, dst);
+ WRITEuint32(tim, dst);
- if (_gnutls_get_random(rand, TLS_RANDOM_SIZE-4, GNUTLS_STRONG_RANDOM) < 0) {
+ if (_gnutls_get_random
+ (rand, TLS_RANDOM_SIZE - 4, GNUTLS_STRONG_RANDOM) < 0) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
}
- memcpy( &dst[4], rand, 28);
+ memcpy(&dst[4], rand, 28);
return 0;
}
@@ -194,7 +241,7 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
int err;
opaque random[TLS_RANDOM_SIZE];
- if (state->gnutls_internals.v2_hello!=0) { /* version 2.0 */
+ if (state->gnutls_internals.v2_hello != 0) { /* version 2.0 */
return _gnutls_read_client_hello_v2(state, data, datalen);
}
@@ -218,11 +265,11 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
pos += 2;
DECR_LEN(len, TLS_RANDOM_SIZE);
- _gnutls_set_client_random( state, &data[pos]);
+ _gnutls_set_client_random(state, &data[pos]);
pos += TLS_RANDOM_SIZE;
- _gnutls_create_random( random);
- _gnutls_set_server_random( state, random);
+ _gnutls_create_random(random);
+ _gnutls_set_server_random(state, random);
state->security_parameters.timestamp = time(NULL);
@@ -234,7 +281,7 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
gnutls_assert();
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
-
+
DECR_LEN(len, session_id_len);
ret =
_gnutls_server_restore_session(state, &data[pos],
@@ -242,24 +289,7 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
pos += session_id_len;
if (ret == 0) { /* resumed! */
- /* get the new random values */
- memcpy(state->gnutls_internals.resumed_security_parameters.
- server_random,
- state->security_parameters.server_random, TLS_RANDOM_SIZE);
- memcpy(state->gnutls_internals.resumed_security_parameters.
- client_random,
- state->security_parameters.client_random, TLS_RANDOM_SIZE);
-
- /* keep the ciphersuite and compression
- * That is because the client must see these in our
- * hello message.
- */
- memcpy( state->security_parameters.current_cipher_suite.CipherSuite,
- state->gnutls_internals.resumed_security_parameters.current_cipher_suite.CipherSuite,
- 2);
- state->gnutls_internals.compression_method =
- state->gnutls_internals.resumed_security_parameters.compression_algorithm;
-
+ resume_copy_required_values(state);
state->gnutls_internals.resumed = RESUME_TRUE;
return 0;
@@ -273,7 +303,7 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
}
/* Select a ciphersuite */
DECR_LEN(len, 2);
- sizeOfSuites = READuint16( &data[pos]);
+ sizeOfSuites = READuint16(&data[pos]);
pos += 2;
DECR_LEN(len, sizeOfSuites);
@@ -321,10 +351,12 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
DECR_LEN(len, z);
ret = _gnutls_SelectCompMethod(state, &state->
- gnutls_internals.compression_method,
- &data[pos], z);
-#ifdef HARD_DEBUG
- fprintf(stderr, "Selected Compression Method: %s\n", gnutls_compression_get_name(state->gnutls_internals.compression_method));
+ gnutls_internals.compression_method,
+ &data[pos], z);
+#ifdef HANDSHAKE_DEBUG
+ fprintf(stderr, "Selected Compression Method: %s\n",
+ gnutls_compression_get_name(state->gnutls_internals.
+ compression_method));
#endif
pos += z;
@@ -444,7 +476,7 @@ static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data,
GNUTLS_CipherSuite *ciphers;
x = _gnutls_supported_ciphersuites(state, &ciphers);
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
fprintf(stderr, "Requested cipher suites: \n");
for (j = 0; j < datalen; j += 2)
fprintf(stderr, "\t%s\n",
@@ -462,7 +494,7 @@ static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data,
for (i = 0; i < x; i++) {
if (memcmp(ciphers[i].CipherSuite, &data[j], 2) ==
0) {
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
fprintf(stderr, "Selected cipher suite: ");
fprintf(stderr, "%s\n",
_gnutls_cipher_suite_get_name(*
@@ -486,7 +518,7 @@ static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data,
/* This selects the best supported compression method from the ones provided */
int _gnutls_SelectCompMethod(GNUTLS_STATE state, CompressionMethod * ret,
- opaque * data, int datalen)
+ opaque * data, int datalen)
{
int x, i, j;
uint8 *ciphers;
@@ -497,7 +529,8 @@ int _gnutls_SelectCompMethod(GNUTLS_STATE state, CompressionMethod * ret,
for (j = 0; j < datalen; j++) {
for (i = 0; i < x; i++) {
if (ciphers[i] == data[j]) {
- *ret = _gnutls_compression_get_id(ciphers[i]);
+ *ret =
+ _gnutls_compression_get_id(ciphers[i]);
gnutls_free(ciphers);
return 0;
}
@@ -527,8 +560,8 @@ int _gnutls_send_handshake(SOCKET cd, GNUTLS_STATE state, void *i_data,
data = gnutls_malloc(i_datasize);
memcpy(&data[pos++], &type, 1);
- WRITEuint24( datasize, &data[pos]);
- pos+=3;
+ WRITEuint24(datasize, &data[pos]);
+ pos += 3;
if (i_datasize > 4)
memcpy(&data[pos], i_data, i_datasize - 4);
@@ -563,41 +596,51 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
{
int ret;
uint32 length32 = 0, sum = 0;
- uint8 *dataptr=NULL; /* for realloc */
+ uint8 *dataptr = NULL; /* for realloc */
int handshake_headers = HANDSHAKE_HEADERS_SIZE;
HandshakeType recv_type;
if (type == GNUTLS_CERTIFICATE) {
/* If the ciphersuite does not support certificate just quit */
if (state->security_parameters.entity == GNUTLS_CLIENT) {
- if (_gnutls_kx_server_certificate( _gnutls_cipher_suite_get_kx_algo( state->security_parameters.current_cipher_suite) ) == 0)
+ if (_gnutls_kx_server_certificate
+ (_gnutls_cipher_suite_get_kx_algo
+ (state->security_parameters.
+ current_cipher_suite)) == 0)
return 0;
} else { /* server */
- if (_gnutls_kx_client_certificate( _gnutls_cipher_suite_get_kx_algo( state->security_parameters.current_cipher_suite) ) == 0)
+ if (_gnutls_kx_client_certificate
+ (_gnutls_cipher_suite_get_kx_algo
+ (state->security_parameters.
+ current_cipher_suite)) == 0)
return 0;
}
}
dataptr = gnutls_malloc(HANDSHAKE_HEADERS_SIZE);
-
+
ret =
- _gnutls_Recv_int(cd, state, GNUTLS_HANDSHAKE, dataptr, SSL2_HEADERS);
+ _gnutls_Recv_int(cd, state, GNUTLS_HANDSHAKE, dataptr,
+ SSL2_HEADERS);
if (ret < 0) {
gnutls_assert();
gnutls_free(dataptr);
return ret;
}
- if (ret!=SSL2_HEADERS) {
+ if (ret != SSL2_HEADERS) {
gnutls_assert();
gnutls_free(dataptr);
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
- if ( state->gnutls_internals.v2_hello == 0 || type != GNUTLS_CLIENT_HELLO) {
+ if (state->gnutls_internals.v2_hello == 0
+ || type != GNUTLS_CLIENT_HELLO) {
ret =
- _gnutls_Recv_int(cd, state, GNUTLS_HANDSHAKE, &dataptr[SSL2_HEADERS],
- HANDSHAKE_HEADERS_SIZE-SSL2_HEADERS);
+ _gnutls_Recv_int(cd, state, GNUTLS_HANDSHAKE,
+ &dataptr[SSL2_HEADERS],
+ HANDSHAKE_HEADERS_SIZE -
+ SSL2_HEADERS);
if (ret < 0) {
gnutls_assert();
gnutls_free(dataptr);
@@ -610,14 +653,14 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
}
recv_type = dataptr[0];
-
+
if (recv_type != type) {
gnutls_assert();
gnutls_free(dataptr);
return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
}
-
- length32 = READuint24( &dataptr[1]);
+
+ length32 = READuint24(&dataptr[1]);
#ifdef HANDSHAKE_DEBUG
fprintf(stderr, "Handshake: %s was received [%ld bytes]\n",
@@ -626,31 +669,31 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
#endif
- } else { /* v2 hello */
- length32 = state->gnutls_internals.v2_hello - SSL2_HEADERS; /* we've read the first byte */
-
- handshake_headers = SSL2_HEADERS; /* we've already read one byte */
+ } else { /* v2 hello */
+ length32 = state->gnutls_internals.v2_hello - SSL2_HEADERS; /* we've read the first byte */
+
+ handshake_headers = SSL2_HEADERS; /* we've already read one byte */
recv_type = dataptr[0];
#ifdef HANDSHAKE_DEBUG
- fprintf(stderr, "Handshake: %s(v2) was received [%ld bytes]\n",
+ fprintf(stderr,
+ "Handshake: %s(v2) was received [%ld bytes]\n",
_gnutls_handshake2str(recv_type),
length32 + handshake_headers);
#endif
- if (recv_type != GNUTLS_CLIENT_HELLO) { /* it should be one or nothing */
+ if (recv_type != GNUTLS_CLIENT_HELLO) { /* it should be one or nothing */
gnutls_assert();
return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
}
}
- dataptr =
- gnutls_realloc(dataptr, length32 + handshake_headers);
+ dataptr = gnutls_realloc(dataptr, length32 + handshake_headers);
if (length32 > 0 && data != NULL)
*data = gnutls_malloc(length32);
if (datalen != NULL)
- *datalen = length32;
+ *datalen = length32;
sum = handshake_headers;
do {
@@ -659,7 +702,7 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
&dataptr[sum], length32);
sum += ret;
} while (((sum - handshake_headers) < length32) && (ret > 0));
-
+
if (ret < 0) {
gnutls_assert();
gnutls_free(dataptr);
@@ -671,9 +714,10 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
memcpy(*data, &dataptr[handshake_headers], length32);
/* here we buffer the handshake messages - needed at Finished message */
-
- if (recv_type!=GNUTLS_HELLO_REQUEST)
- gnutls_insertHashDataBuffer(state, dataptr, length32 + handshake_headers);
+
+ if (recv_type != GNUTLS_HELLO_REQUEST)
+ gnutls_insertHashDataBuffer(state, dataptr,
+ length32 + handshake_headers);
switch (recv_type) {
case GNUTLS_CLIENT_HELLO:
@@ -703,7 +747,7 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
ret = length32;
break;
case GNUTLS_CERTIFICATE_REQUEST:
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
fprintf(stderr, "Requested Client Certificate!\n");
#endif
/* FIXME: just ignore that message for the time being
@@ -734,14 +778,14 @@ int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data,
**/
int gnutls_rehandshake(SOCKET cd, GNUTLS_STATE state)
{
-int ret;
+ int ret;
/* only server sends that handshake packet */
if (state->security_parameters.entity == GNUTLS_CLIENT)
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
ret = _gnutls_send_handshake(cd, state, NULL, 0,
- GNUTLS_HELLO_REQUEST);
+ GNUTLS_HELLO_REQUEST);
if (ret < 0) {
gnutls_assert();
@@ -764,7 +808,7 @@ int _gnutls_send_client_certificate(SOCKET cd, GNUTLS_STATE state)
/* we do not have that functionality yet */
state->gnutls_internals.certificate_verify_needed = 0;
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
fprintf(stderr, "Sending Client Certificate\n");
#endif
@@ -778,7 +822,8 @@ int _gnutls_send_client_certificate(SOCKET cd, GNUTLS_STATE state)
return ret;
}
-static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datalen)
+static int _gnutls_read_server_hello(GNUTLS_STATE state, char *data,
+ int datalen)
{
uint8 session_id_len = 0, z;
int pos = 0;
@@ -809,7 +854,7 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
pos += 2;
DECR_LEN(len, TLS_RANDOM_SIZE);
- _gnutls_set_server_random( state, &data[pos]);
+ _gnutls_set_server_random(state, &data[pos]);
pos += TLS_RANDOM_SIZE;
DECR_LEN(len, 1);
@@ -822,7 +867,7 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
DECR_LEN(len, session_id_len);
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
fprintf(stderr, "SessionID length: %d\n", session_id_len);
fprintf(stderr, "SessionID: %s\n",
_gnutls_bin2hex(&data[pos], session_id_len));
@@ -852,9 +897,9 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
session_id_len;
memcpy(state->security_parameters.session_id,
&data[pos], session_id_len);
- }
- pos += session_id_len;
- DECR_LEN(len, 2);
+ }
+ pos += session_id_len;
+ DECR_LEN(len, 2);
memcpy(cipher_suite.CipherSuite, &data[pos], 2);
pos += 2;
@@ -873,15 +918,15 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
}
memcpy(state->security_parameters.
- current_cipher_suite.CipherSuite,
- cipher_suite.CipherSuite, 2);
+ current_cipher_suite.CipherSuite,
+ cipher_suite.CipherSuite, 2);
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
fprintf(stderr, "Selected cipher suite: ");
fprintf(stderr, "%s\n",
_gnutls_cipher_suite_get_name(state->
- security_parameters.
- current_cipher_suite));
+ security_parameters.
+ current_cipher_suite));
#endif
/* check if the credentials (username, public key etc. are ok - actually check if they exist)
@@ -905,8 +950,8 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
(cipher_suite));
if (state->gnutls_internals.auth_struct == NULL) {
#ifdef DEBUG
- fprintf(stderr,
- "Cannot find the appropriate handler for the KX algorithm\n");
+ fprintf(stderr,
+ "Cannot find the appropriate handler for the KX algorithm\n");
#endif
gnutls_assert();
return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
@@ -933,7 +978,7 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
}
state->gnutls_internals.compression_method =
- _gnutls_compression_get_id( compression_method);
+ _gnutls_compression_get_id(compression_method);
gnutls_free(cipher_suites);
gnutls_free(compression_methods);
@@ -943,11 +988,12 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale
gnutls_assert();
return ret;
}
-
+
return ret;
}
-int _gnutls_send_hello(SOCKET cd, GNUTLS_STATE state)
+
+static int _gnutls_send_client_hello(SOCKET cd, GNUTLS_STATE state)
{
char *data = NULL;
opaque *extdata;
@@ -960,140 +1006,168 @@ int _gnutls_send_hello(SOCKET cd, GNUTLS_STATE state)
uint16 x;
opaque random[TLS_RANDOM_SIZE];
- if (state->security_parameters.entity == GNUTLS_CLIENT) {
- opaque * SessionID = state->gnutls_internals.resumed_security_parameters.session_id;
- uint8 session_id_len = state->gnutls_internals.resumed_security_parameters.session_id_size;
-
- if (SessionID==NULL) session_id_len = 0;
-
- datalen = 2 + 4 + (session_id_len + 1) + 28 + 3;
- /* 2 for version, 4 for unix time, 28 for random bytes 2 for cipher suite's
- * size and 1 for compression method's size
- */
- data = gnutls_malloc(datalen);
+ opaque *SessionID =
+ state->gnutls_internals.resumed_security_parameters.session_id;
+ uint8 session_id_len =
+ state->gnutls_internals.resumed_security_parameters.
+ session_id_size;
+
+ if (SessionID == NULL)
+ session_id_len = 0;
- data[pos++] =
- _gnutls_version_get_major(state->connection_state.
- version);
- data[pos++] =
- _gnutls_version_get_minor(state->connection_state.
- version);
+ datalen = 2 + 4 + (session_id_len + 1) + 28 + 3;
+ /* 2 for version, 4 for unix time, 28 for random bytes 2 for cipher suite's
+ * size and 1 for compression method's size
+ */
+ data = gnutls_malloc(datalen);
- _gnutls_create_random( random);
- _gnutls_set_client_random( state, random);
-
- state->security_parameters.timestamp = time(0);
+ data[pos++] =
+ _gnutls_version_get_major(state->connection_state.version);
+ data[pos++] =
+ _gnutls_version_get_minor(state->connection_state.version);
- memcpy(&data[pos],
- state->security_parameters.client_random, TLS_RANDOM_SIZE);
- pos += TLS_RANDOM_SIZE;
+ _gnutls_create_random(random);
+ _gnutls_set_client_random(state, random);
- memcpy(&data[pos++], &session_id_len, 1);
+ state->security_parameters.timestamp = time(0);
- if (session_id_len > 0) {
- memcpy(&data[pos], SessionID, session_id_len);
- }
- pos += session_id_len;
+ memcpy(&data[pos],
+ state->security_parameters.client_random, TLS_RANDOM_SIZE);
+ pos += TLS_RANDOM_SIZE;
- x = _gnutls_supported_ciphersuites_sorted(state,
- &cipher_suites);
- x *= sizeof(uint16); /* in order to get bytes */
+ memcpy(&data[pos++], &session_id_len, 1);
- WRITEuint16( x, &data[pos]);
- pos += sizeof(uint16);
+ if (session_id_len > 0) {
+ memcpy(&data[pos], SessionID, session_id_len);
+ }
+ pos += session_id_len;
- datalen += x;
- data = gnutls_realloc(data, datalen);
+ x = _gnutls_supported_ciphersuites_sorted(state, &cipher_suites);
+ x *= sizeof(uint16); /* in order to get bytes */
- for (i = 0; i < x / 2; i++) {
- memcpy(&data[pos], cipher_suites[i].CipherSuite,
- 2);
- pos += 2;
- }
- gnutls_free(cipher_suites);
+ WRITEuint16(x, &data[pos]);
+ pos += sizeof(uint16);
+
+ datalen += x;
+ data = gnutls_realloc(data, datalen);
+
+ for (i = 0; i < x / 2; i++) {
+ memcpy(&data[pos], cipher_suites[i].CipherSuite, 2);
+ pos += 2;
+ }
+ gnutls_free(cipher_suites);
+
+ z = _gnutls_supported_compression_methods
+ (state, &compression_methods);
+
+ memcpy(&data[pos++], &z, 1); /* put the number of compression methods */
- z = _gnutls_supported_compression_methods
- (state, &compression_methods);
+ datalen += z;
+ data = gnutls_realloc(data, datalen);
+
+ for (i = 0; i < z; i++) {
+ memcpy(&data[pos++], &compression_methods[i], 1);
+ }
- memcpy(&data[pos++], &z, 1); /* put the number of compression methods */
+ gnutls_free(compression_methods);
- datalen += z;
+ extdatalen = _gnutls_gen_extensions(state, &extdata);
+ if (extdatalen > 0) {
+ datalen += extdatalen;
data = gnutls_realloc(data, datalen);
+ memcpy(&data[pos], extdata, extdatalen);
+ gnutls_free(extdata);
+ }
- for (i = 0; i < z; i++) {
- memcpy(&data[pos++], &compression_methods[i], 1);
- }
+ ret =
+ _gnutls_send_handshake(cd, state, data, datalen,
+ GNUTLS_CLIENT_HELLO);
+ gnutls_free(data);
- gnutls_free(compression_methods);
- extdatalen = _gnutls_gen_extensions(state, &extdata);
- if (extdatalen > 0) {
- datalen += extdatalen;
- data = gnutls_realloc(data, datalen);
- memcpy(&data[pos], extdata, extdatalen);
- gnutls_free(extdata);
- }
- ret =
- _gnutls_send_handshake(cd, state, data, datalen,
- GNUTLS_CLIENT_HELLO);
- gnutls_free(data);
+ return ret;
+}
+static int _gnutls_send_server_hello(SOCKET cd, GNUTLS_STATE state)
+{
+ char *data = NULL;
+ opaque *extdata;
+ int extdatalen;
+ int pos = 0;
+ int datalen, ret = 0;
+ uint8 comp;
+ opaque *SessionID = state->security_parameters.session_id;
+ uint8 session_id_len = state->security_parameters.session_id_size;
- } else { /* SERVER */
- uint8 comp;
- opaque * SessionID = state->security_parameters.session_id;
- uint8 session_id_len = state->security_parameters.session_id_size;
-
- if (SessionID==NULL) session_id_len = 0;
-
- datalen = 2 + session_id_len + 1 + TLS_RANDOM_SIZE;
- data = gnutls_malloc(datalen);
-
- data[pos++] =
- _gnutls_version_get_major(state->connection_state.
- version);
- data[pos++] =
- _gnutls_version_get_minor(state->connection_state.
- version);
-
- memcpy(&data[pos],
- state->security_parameters.server_random, TLS_RANDOM_SIZE);
- pos += TLS_RANDOM_SIZE;
-
- memcpy(&data[pos++], &session_id_len, sizeof(uint8));
- if (session_id_len > 0) {
- memcpy(&data[pos], SessionID, session_id_len);
- }
- pos += session_id_len;
+ if (SessionID == NULL)
+ session_id_len = 0;
- datalen += 2;
- data = gnutls_realloc(data, datalen);
-
- memcpy(&data[pos],
- state->security_parameters.
- current_cipher_suite.CipherSuite, 2);
- pos += 2;
+ datalen = 2 + session_id_len + 1 + TLS_RANDOM_SIZE;
+ data = gnutls_malloc(datalen);
+
+ data[pos++] =
+ _gnutls_version_get_major(state->connection_state.version);
+ data[pos++] =
+ _gnutls_version_get_minor(state->connection_state.version);
+
+ memcpy(&data[pos],
+ state->security_parameters.server_random, TLS_RANDOM_SIZE);
+ pos += TLS_RANDOM_SIZE;
+
+ data[pos++] = session_id_len;
+ if (session_id_len > 0) {
+ memcpy(&data[pos], SessionID, session_id_len);
+ }
+ pos += session_id_len;
+
+#ifdef HANDSHAKE_DEBUG
+ fprintf(stderr, "Handshake: SessionID: %s\n",
+ _gnutls_bin2hex(SessionID, session_id_len));
+#endif
+
+ datalen += 2;
+ data = gnutls_realloc(data, datalen);
+
+ memcpy(&data[pos],
+ state->security_parameters.
+ current_cipher_suite.CipherSuite, 2);
+ pos += 2;
+
+ datalen += 1;
+ data = gnutls_realloc(data, datalen);
- datalen += 1;
+ comp =
+ (uint8) _gnutls_compression_get_num(state->gnutls_internals.
+ compression_method);
+ memcpy(&data[pos++], &comp, 1);
+
+ extdatalen = _gnutls_gen_extensions(state, &extdata);
+ if (extdatalen > 0) {
+ datalen += extdatalen;
data = gnutls_realloc(data, datalen);
-
- comp = (uint8) _gnutls_compression_get_num(state->gnutls_internals.compression_method);
- memcpy(&data[pos++], &comp, 1);
-
- extdatalen = _gnutls_gen_extensions(state, &extdata);
- if (extdatalen > 0) {
- datalen += extdatalen;
- data = gnutls_realloc(data, datalen);
- memcpy(&data[pos], extdata, extdatalen);
- gnutls_free(extdata);
- }
+ memcpy(&data[pos], extdata, extdatalen);
+ gnutls_free(extdata);
+ }
- ret =
- _gnutls_send_handshake(cd, state, data, datalen,
- GNUTLS_SERVER_HELLO);
- gnutls_free(data);
+ ret =
+ _gnutls_send_handshake(cd, state, data, datalen,
+ GNUTLS_SERVER_HELLO);
+ gnutls_free(data);
+
+
+ return ret;
+}
+
+int _gnutls_send_hello(SOCKET cd, GNUTLS_STATE state)
+{
+ int ret;
+
+ if (state->security_parameters.entity == GNUTLS_CLIENT) {
+ ret = _gnutls_send_client_hello(cd, state);
+ } else { /* SERVER */
+ ret = _gnutls_send_server_hello(cd, state);
}
return ret;
@@ -1103,14 +1177,15 @@ int _gnutls_send_hello(SOCKET cd, GNUTLS_STATE state)
* hello message is expected. It uses the security_parameters.current_cipher_suite
* and gnutls_internals.compression_method.
*/
-int _gnutls_recv_hello(SOCKET cd, GNUTLS_STATE state, char *data, int datalen)
+int _gnutls_recv_hello(SOCKET cd, GNUTLS_STATE state, char *data,
+ int datalen)
{
-int ret;
+ int ret;
if (state->security_parameters.entity == GNUTLS_CLIENT) {
ret = _gnutls_read_server_hello(state, data, datalen);
if (ret < 0) {
- _gnutls_send_alert( cd, state, GNUTLS_FATAL, GNUTLS_HANDSHAKE_FAILURE); /* send handshake failure */
+ _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_HANDSHAKE_FAILURE); /* send handshake failure */
gnutls_assert();
return ret;
}
@@ -1118,7 +1193,7 @@ int ret;
ret = _gnutls_read_client_hello(state, data, datalen);
if (ret < 0) {
- _gnutls_send_alert( cd, state, GNUTLS_FATAL, GNUTLS_HANDSHAKE_FAILURE); /* send handshake failure */
+ _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_HANDSHAKE_FAILURE); /* send handshake failure */
gnutls_assert();
return ret;
}
@@ -1141,7 +1216,7 @@ int _gnutls_recv_certificate(SOCKET cd, GNUTLS_STATE state, char *data,
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
- sizeOfCert = READuint24( &data[pos]);
+ sizeOfCert = READuint24(&data[pos]);
pos += 3;
if (sizeOfCert > MAX24) {
@@ -1217,7 +1292,7 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
int ret;
if (state->security_parameters.entity == GNUTLS_CLIENT) {
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
if (state->gnutls_internals.resumed_security_parameters.
session_id_size > 0)
fprintf(stderr, "Ask to resume: %s\n",
@@ -1228,8 +1303,7 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
resumed_security_parameters.
session_id_size));
#endif
- ret =
- _gnutls_send_hello(cd, state);
+ ret = _gnutls_send_hello(cd, state);
if (ret < 0) {
ERR("send hello", ret);
gnutls_clearHashDataBuffer(state);
@@ -1269,8 +1343,7 @@ int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state)
return ret;
}
- ret =
- _gnutls_send_hello(cd, state);
+ ret = _gnutls_send_hello(cd, state);
if (ret < 0) {
ERR("send hello", ret);
gnutls_assert();
@@ -1339,7 +1412,6 @@ static int _gnutls_send_handshake_final(SOCKET cd, GNUTLS_STATE state,
ret = _gnutls_send_change_cipher_spec(cd, state);
if (ret < 0) {
ERR("send ChangeCipherSpec", ret);
- gnutls_clearHashDataBuffer(state);
return ret;
}
@@ -1348,7 +1420,6 @@ static int _gnutls_send_handshake_final(SOCKET cd, GNUTLS_STATE state,
ret = _gnutls_connection_state_init(state);
if (ret < 0) {
gnutls_assert();
- gnutls_clearHashDataBuffer(state);
return ret;
}
}
@@ -1357,7 +1428,6 @@ static int _gnutls_send_handshake_final(SOCKET cd, GNUTLS_STATE state,
ret = _gnutls_send_finished(cd, state);
if (ret < 0) {
ERR("send Finished", ret);
- gnutls_clearHashDataBuffer(state);
return ret;
}
return ret;
@@ -1375,7 +1445,6 @@ static int _gnutls_recv_handshake_final(SOCKET cd, GNUTLS_STATE state,
NULL, 0, 0);
if (ret < 0) {
ERR("recv ChangeCipherSpec", ret);
- gnutls_clearHashDataBuffer(state);
return ret;
}
@@ -1384,7 +1453,6 @@ static int _gnutls_recv_handshake_final(SOCKET cd, GNUTLS_STATE state,
ret = _gnutls_connection_state_init(state);
if (ret < 0) {
gnutls_assert();
- gnutls_clearHashDataBuffer(state);
return ret;
}
}
@@ -1392,7 +1460,6 @@ static int _gnutls_recv_handshake_final(SOCKET cd, GNUTLS_STATE state,
ret = _gnutls_recv_finished(cd, state);
if (ret < 0) {
ERR("recv finished", ret);
- gnutls_clearHashDataBuffer(state);
return ret;
}
return ret;
@@ -1534,7 +1601,9 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
gnutls_assert();
gnutls_clearHashDataBuffer(state);
/* for srp */
- if (state->security_parameters.kx_algorithm==GNUTLS_KX_SRP) return GNUTLS_E_AUTH_FAILED;
+ if (state->security_parameters.kx_algorithm ==
+ GNUTLS_KX_SRP)
+ return GNUTLS_E_AUTH_FAILED;
return ret;
}
@@ -1558,7 +1627,9 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
gnutls_assert();
gnutls_clearHashDataBuffer(state);
/* in srp failure here - means authentication error */
- if (state->security_parameters.kx_algorithm==GNUTLS_KX_SRP) return GNUTLS_E_AUTH_FAILED;
+ if (state->security_parameters.kx_algorithm ==
+ GNUTLS_KX_SRP)
+ return GNUTLS_E_AUTH_FAILED;
return ret;
}
}
@@ -1577,7 +1648,8 @@ int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state)
int _gnutls_generate_session_id(char *session_id, uint8 * len)
{
opaque rand[TLS_RANDOM_SIZE];
- if (_gnutls_get_random(rand, TLS_RANDOM_SIZE, GNUTLS_WEAK_RANDOM) < 0) {
+ if (_gnutls_get_random(rand, TLS_RANDOM_SIZE, GNUTLS_WEAK_RANDOM) <
+ 0) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
}
@@ -1585,45 +1657,50 @@ int _gnutls_generate_session_id(char *session_id, uint8 * len)
memcpy(session_id, rand, TLS_RANDOM_SIZE);
*len = TLS_RANDOM_SIZE;
-#ifdef HARD_DEBUG
+#ifdef HANDSHAKE_DEBUG
fprintf(stderr, "Generated SessionID: %s\n",
_gnutls_bin2hex(session_id, TLS_RANDOM_SIZE));
#endif
return 0;
}
+
#define RENEGOTIATE
-int _gnutls_recv_hello_request(SOCKET cd, GNUTLS_STATE state, void* data, uint32 data_size) {
+int _gnutls_recv_hello_request(SOCKET cd, GNUTLS_STATE state, void *data,
+ uint32 data_size)
+{
#ifndef RENEGOTIATE
-int ret;
+ int ret;
/* only client should receive that */
if (state->security_parameters.entity == GNUTLS_SERVER)
return GNUTLS_E_UNEXPECTED_PACKET;
/* just return an alert that we don't like that */
- ret = _gnutls_send_alert( cd, state, GNUTLS_WARNING, GNUTLS_NO_RENEGOTIATION);
+ ret =
+ _gnutls_send_alert(cd, state, GNUTLS_WARNING,
+ GNUTLS_NO_RENEGOTIATION);
if (ret < 0) {
gnutls_assert();
return ret;
}
return 0;
-#else /* this does not seem to work - yet */
-uint8 type;
+#else /* this does not seem to work - yet */
+ uint8 type;
if (state->security_parameters.entity == GNUTLS_SERVER) {
gnutls_assert();
return GNUTLS_E_UNEXPECTED_PACKET;
}
-
+
if (data_size < 1) {
gnutls_assert();
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
-
- type = ((uint8*)data)[0];
- if (type==GNUTLS_HELLO_REQUEST)
- return gnutls_handshake( cd, state);
+
+ type = ((uint8 *) data)[0];
+ if (type == GNUTLS_HELLO_REQUEST)
+ return gnutls_handshake(cd, state);
else {
gnutls_assert();
return GNUTLS_E_UNEXPECTED_PACKET;
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 487cd44ece..0b81352850 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -27,10 +27,11 @@
#define READ_DEBUG
#define WRITE_DEBUG
#define BUFFERS_DEBUG
-#define HANDSHAKE_DEBUG
+*/#define HANDSHAKE_DEBUG
+/*#define RECORD_DEBUG
#define HARD_DEBUG
-#define DEBUG
*/
+#define DEBUG
#define SOCKET int
#define LIST ...
@@ -41,6 +42,7 @@
#define TLS_RANDOM_SIZE 32
#define TLS_MAX_SESSION_ID_SIZE 32
+#define TLS_MASTER_SIZE 48
/* the default for TCP */
#define DEFAULT_LOWAT 1
@@ -207,7 +209,7 @@ typedef struct {
uint8 key_size;
uint8 key_material_length;
uint8 hash_size;
- opaque master_secret[48];
+ opaque master_secret[TLS_MASTER_SIZE];
opaque client_random[TLS_RANDOM_SIZE];
opaque server_random[TLS_RANDOM_SIZE];
opaque session_id[TLS_MAX_SESSION_ID_SIZE];
diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c
index b31dfacfc6..261ece77d1 100644
--- a/lib/gnutls_kx.c
+++ b/lib/gnutls_kx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000 Nikos Mavroyanopoulos
+ * Copyright (C) 2000,2001 Nikos Mavroyanopoulos
*
* This file is part of GNUTLS.
*
@@ -29,52 +29,105 @@
#include "gnutls_gcry.h"
#define MASTER_SECRET "master secret"
+static int generate_normal_master( GNUTLS_STATE state);
+static int generate_resumed_master( GNUTLS_STATE state);
+int _gnutls_generate_master( GNUTLS_STATE state) {
+ if (state->gnutls_internals.resumed==RESUME_FALSE)
+ return generate_normal_master(state);
+ return 0;
+}
-static int generate_master( GNUTLS_STATE state) {
+static int generate_normal_master( GNUTLS_STATE state) {
int premaster_size;
#ifdef HARD_DEBUG
int i;
#endif
opaque* premaster, *master;
int ret = 0;
-char random[64];
+char random[2*TLS_RANDOM_SIZE];
- memmove(random, state->security_parameters.client_random, 32);
- memmove(&random[32], state->security_parameters.server_random, 32);
+ memmove(random, state->security_parameters.client_random, TLS_RANDOM_SIZE);
+ memmove(&random[TLS_RANDOM_SIZE], state->security_parameters.server_random, TLS_RANDOM_SIZE);
/* generate premaster */
premaster_size = state->gnutls_key->key.size;
premaster = state->gnutls_key->key.data;
#ifdef HARD_DEBUG
- fprintf(stderr, "PREMASTER SECRET: ");
- for (i=0;i<premaster_size;i++) fprintf(stderr, "%x",premaster[i]);
- fprintf(stderr, "\n");
+ fprintf(stderr, "PREMASTER SECRET[%d]: %s\n", premaster_size, _gnutls_bin2hex(premaster, premaster_size));
+ fprintf(stderr, "CLIENT RANDOM[%d]: %s\n", 32, _gnutls_bin2hex(state->security_parameters.client_random,32));
+ fprintf(stderr, "SERVER RANDOM[%d]: %s\n", 32, _gnutls_bin2hex(state->security_parameters.server_random,32));
#endif
if (_gnutls_version_ssl3(state->connection_state.version) == 0) {
master =
gnutls_ssl3_generate_random( premaster, premaster_size,
- random, 64, 48);
+ random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE);
} else {
master =
gnutls_PRF( premaster, premaster_size,
MASTER_SECRET, strlen(MASTER_SECRET),
- random, 64, 48);
+ random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE);
}
secure_free(premaster);
state->gnutls_key->key.size = 0;
state->gnutls_key->key.data = NULL;
+ if (master==NULL) return GNUTLS_E_MEMORY_ERROR;
+
#ifdef HARD_DEBUG
- fprintf(stderr, "MASTER SECRET: %s\n", _gnutls_bin2hex(master, 48));
+ fprintf(stderr, "MASTER SECRET: %s\n", _gnutls_bin2hex(master, TLS_MASTER_SIZE));
#endif
- memmove(state->security_parameters.master_secret, master, 48);
+ memmove(state->security_parameters.master_secret, master, TLS_MASTER_SIZE);
secure_free(master);
return ret;
+}
+
+static int generate_resumed_master( GNUTLS_STATE state) {
+int premaster_size;
+#ifdef HARD_DEBUG
+int i;
+#endif
+opaque* premaster, *master;
+int ret = 0;
+char random[2*TLS_RANDOM_SIZE];
+
+ memmove(random, state->security_parameters.client_random, TLS_RANDOM_SIZE);
+ memmove(&random[TLS_RANDOM_SIZE], state->security_parameters.server_random, TLS_RANDOM_SIZE);
+
+ /* generate premaster */
+ premaster_size = sizeof(state->security_parameters.master_secret);
+ premaster = state->security_parameters.master_secret;
+
+#ifdef HARD_DEBUG
+ fprintf(stderr, "RESUME...\n");
+ fprintf(stderr, "PREMASTER SECRET[%d]: %s\n", premaster_size, _gnutls_bin2hex(premaster, premaster_size));
+ fprintf(stderr, "CLIENT RANDOM[%d]: %s\n", 32, _gnutls_bin2hex(state->security_parameters.client_random,32));
+ fprintf(stderr, "SERVER RANDOM[%d]: %s\n", 32, _gnutls_bin2hex(state->security_parameters.server_random,32));
+#endif
+
+ if (_gnutls_version_ssl3(state->connection_state.version) == 0) {
+ master =
+ gnutls_ssl3_generate_random( premaster, premaster_size,
+ random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE);
+
+ } else {
+ master =
+ gnutls_PRF( premaster, premaster_size,
+ MASTER_SECRET, strlen(MASTER_SECRET),
+ random, 2*TLS_RANDOM_SIZE, TLS_MASTER_SIZE);
+ }
+
+#ifdef HARD_DEBUG
+ fprintf(stderr, "MASTER SECRET: %s\n", _gnutls_bin2hex(master, TLS_MASTER_SIZE));
+#endif
+ if (master==NULL) return GNUTLS_E_MEMORY_ERROR;
+ memmove(state->security_parameters.master_secret, master, TLS_MASTER_SIZE);
+ secure_free(master);
+ return ret;
}
/* This is called when we want to receive the key exchange message of the
@@ -142,11 +195,6 @@ int _gnutls_send_server_kx_message2(SOCKET cd, GNUTLS_STATE state)
return ret;
}
- ret = generate_master( state);
- if (ret<0) {
- gnutls_assert();
- return ret;
- }
}
return data_size;
}
@@ -187,12 +235,6 @@ int _gnutls_send_client_kx_message(SOCKET cd, GNUTLS_STATE state)
return ret;
}
- ret = generate_master( state);
- if (ret<0) {
- gnutls_assert();
- return ret;
- }
-
return ret;
}
@@ -326,11 +368,6 @@ int _gnutls_recv_server_kx_message2(SOCKET cd, GNUTLS_STATE state)
if (ret < 0)
return ret;
- ret = generate_master( state);
- if (ret<0) {
- gnutls_assert();
- return ret;
- }
}
return ret;
}
@@ -368,11 +405,6 @@ int _gnutls_recv_client_kx_message(SOCKET cd, GNUTLS_STATE state)
if (ret < 0)
return ret;
- ret = generate_master( state);
- if (ret<0) {
- gnutls_assert();
- return ret;
- }
}
return ret;
diff --git a/lib/gnutls_kx.h b/lib/gnutls_kx.h
index 6408832a35..68ab4a3b9e 100644
--- a/lib/gnutls_kx.h
+++ b/lib/gnutls_kx.h
@@ -28,3 +28,4 @@ int _gnutls_recv_client_kx_message(int cd, GNUTLS_STATE state);
int _gnutls_recv_client_kx_message0(int cd, GNUTLS_STATE state);
int _gnutls_send_client_certificate_verify(int cd, GNUTLS_STATE state);
int _gnutls_send_certificate(int cd, GNUTLS_STATE state);
+int _gnutls_generate_master( GNUTLS_STATE state);
diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c
index cea9ce1e25..91e0b02d89 100644
--- a/lib/gnutls_record.c
+++ b/lib/gnutls_record.c
@@ -34,6 +34,7 @@
#include "gnutls_auth_int.h"
#include "gnutls_num.h"
#include "gnutls_record.h"
+
#ifdef HAVE_ERRNO_H
# include <errno.h>
#endif
@@ -189,6 +190,7 @@ int gnutls_deinit(GNUTLS_STATE state)
GNUTLS_FREE(state->gnutls_internals.db_name);
+ memset( state, 0, sizeof(GNUTLS_STATE_INT));
GNUTLS_FREE(state);
return 0;
}
@@ -356,25 +358,33 @@ int _gnutls_set_keys(GNUTLS_STATE state)
int hash_size;
int IV_size;
int key_size;
-
+ int block_size;
+
hash_size = state->security_parameters.hash_size;
IV_size = state->security_parameters.IV_size;
key_size = state->security_parameters.key_material_length;
memmove(random, state->security_parameters.server_random, TLS_RANDOM_SIZE);
- memmove(&random[TLS_RANDOM_SIZE], state->security_parameters.client_random, 32);
+ memmove(&random[TLS_RANDOM_SIZE], state->security_parameters.client_random, TLS_RANDOM_SIZE);
+
+ block_size = 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);
+ key_block = gnutls_ssl3_generate_random( state->security_parameters.master_secret, TLS_MASTER_SIZE, random, 2*TLS_RANDOM_SIZE,
+ block_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);
+ gnutls_PRF( state->security_parameters.master_secret, TLS_MASTER_SIZE,
+ keyexp, strlen(keyexp), random, 2*TLS_RANDOM_SIZE,
+ block_size);
}
if (key_block==NULL) return GNUTLS_E_MEMORY_ERROR;
+#ifdef HARD_DEBUG
+ fprintf(stderr, "KEY BLOCK[%d]: %s\n",block_size, _gnutls_bin2hex(key_block, block_size));
+#endif
+
if (hash_size>0) {
state->cipher_specs.client_write_mac_secret = secure_malloc(hash_size);
if (state->cipher_specs.client_write_mac_secret==NULL)
@@ -451,6 +461,27 @@ int gnutls_bye(SOCKET cd, GNUTLS_STATE state)
return ret;
}
+/**
+ * gnutls_bye_nowait - This function terminates the current TLS/SSL connection.
+ * @cd: is a connection descriptor.
+ * @state: is a &GNUTLS_STATE structure.
+ *
+ * Terminates the current TLS/SSL connection. The connection should
+ * have been initiated using gnutls_handshake() or similar function.
+ * This function does not wait for the other peer to close the TLS
+ * connection.
+ **/
+int gnutls_bye_nowait(SOCKET cd, GNUTLS_STATE state)
+{
+ int ret;
+
+ ret = _gnutls_send_alert(cd, state, GNUTLS_WARNING, GNUTLS_CLOSE_NOTIFY);
+
+ state->gnutls_internals.valid_connection = VALID_FALSE;
+
+ return ret;
+}
+
int gnutls_close_nowait(SOCKET cd, GNUTLS_STATE state)
{
int ret;
@@ -496,7 +527,7 @@ ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, const v
headers[1]=_gnutls_version_get_major(state->connection_state.version);
headers[2]=_gnutls_version_get_minor(state->connection_state.version);
-#ifdef HARD_DEBUG
+#ifdef RECORD_DEBUG
fprintf(stderr, "Record: Sending Packet[%d] %s(%d) with length: %d\n",
(int) uint64touint32(&state->connection_state.write_sequence_number), _gnutls_packet2str(type), type, sizeofdata);
#endif
@@ -523,7 +554,7 @@ ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, const v
gnutls_assert();
return GNUTLS_E_UNABLE_SEND_DATA;
}
-#ifdef HARD_DEBUG
+#ifdef RECORD_DEBUG
fprintf(stderr, "Record: Sended Packet[%d] %s(%d) with length: %d\n",
(int) uint64touint32(&state->connection_state.write_sequence_number), _gnutls_packet2str(type), type, cipher_size);
#endif
@@ -592,7 +623,7 @@ ssize_t _gnutls_send_change_cipher_spec(SOCKET cd, GNUTLS_STATE state)
headers[2] = _gnutls_version_get_minor(state->connection_state.version);
#ifdef HANDSHAKE_DEBUG
- fprintf(stderr, "ChangeCipherSpec was sent\n");
+ fprintf(stderr, "Record: ChangeCipherSpec was sent\n");
#endif
WRITEuint16( 1, &headers[3]);
@@ -722,7 +753,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, char *d
}
-#ifdef HARD_DEBUG
+#ifdef RECORD_DEBUG
fprintf(stderr, "Record: Expected Packet[%d] %s(%d) with length: %d\n",
(int) uint64touint32(&state->connection_state.read_sequence_number), _gnutls_packet2str(type), type, sizeofdata);
fprintf(stderr, "Record: Received Packet[%d] %s(%d) with length: %d\n",
@@ -795,7 +826,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, char *d
}
if (type == GNUTLS_CHANGE_CIPHER_SPEC && recv_type == GNUTLS_CHANGE_CIPHER_SPEC) {
-#ifdef HARD_DEBUG
+#ifdef RECORD_DEBUG
fprintf(stderr, "Record: ChangeCipherSpec Packet was received\n");
#endif
gnutls_free(ciphertext);
@@ -826,7 +857,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, char *d
return tmplen;
}
-#ifdef HARD_DEBUG
+#ifdef RECORD_DEBUG
fprintf(stderr, "Record: Decrypted Packet[%d] %s(%d) with length: %d\n",
(int) uint64touint32(&state->connection_state.read_sequence_number), _gnutls_packet2str(recv_type), recv_type, tmplen);
#endif
diff --git a/lib/gnutls_session.c b/lib/gnutls_session.c
index 548e0dadc3..58db045728 100644
--- a/lib/gnutls_session.c
+++ b/lib/gnutls_session.c
@@ -86,7 +86,7 @@ int gnutls_get_current_session_id( GNUTLS_STATE state, void* session, int *sessi
*
* Sets all session parameters - in order to support resuming
* session must be the one returned by gnutls_get_current_session();
- * This function should be called before gnutls_handshake_begin() or gnutls_handshake().
+ * This function should be called before gnutls_handshake().
* Keep in mind that session resuming is advisory. The server may
* choose not to resume the session, thus a full handshake will be
* performed.
diff --git a/lib/gnutls_v2_compat.c b/lib/gnutls_v2_compat.c
index 7192d3d60e..f441baee8c 100644
--- a/lib/gnutls_v2_compat.c
+++ b/lib/gnutls_v2_compat.c
@@ -207,9 +207,6 @@ int _gnutls_read_client_hello_v2(GNUTLS_STATE state, opaque * data,
DECR_LEN(len, challenge);
memset( random, 0, TLS_RANDOM_SIZE);
- /* Well, I think that this is not what TLS 1.0 defines,
- * but with this, we are compatible with netscape browser!
- */
memcpy( &random[TLS_RANDOM_SIZE-challenge], &data[pos], challenge);
_gnutls_set_client_random( state, random);
diff --git a/src/serv.c b/src/serv.c
index 7225a31b3b..24091ac960 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -138,6 +138,15 @@ void print_info(GNUTLS_STATE state)
const SRP_AUTH_INFO *srp_info;
const ANON_AUTH_INFO *dh_info;
char *tmp;
+ unsigned char sesid[32];
+ int sesid_size, i;
+
+ /* print session_id specific data */
+ gnutls_get_current_session_id( state, sesid, &sesid_size);
+ printf("\n- Session ID: ");
+ for(i=0;i<sesid_size;i++)
+ printf("%.2X", sesid[i]);
+ printf("\n");
/* print srp specific data */
if (gnutls_get_current_kx(state) == GNUTLS_KX_SRP) {
@@ -177,13 +186,24 @@ void print_info(GNUTLS_STATE state)
}
+/* Creates html with the current state information.
+ */
#define tmp2 &http_buffer[strlen(http_buffer)]
void peer_print_info(int cd, GNUTLS_STATE state)
{
const SRP_AUTH_INFO *srp_info;
const ANON_AUTH_INFO *dh_info;
char *tmp;
+ unsigned char sesid[32];
+ int sesid_size, i;
+ /* print session_id */
+ gnutls_get_current_session_id( state, sesid, &sesid_size);
+ sprintf(tmp2, "\n<p>Session ID: <i>");
+ for(i=0;i<sesid_size;i++)
+ sprintf(tmp2, "%.2X", sesid[i]);
+ sprintf(tmp2, "</i></p>\n");
+
/* print srp specific data */
if (gnutls_get_current_kx(state) == GNUTLS_KX_SRP) {
srp_info = gnutls_get_auth_info(state);
@@ -231,23 +251,29 @@ void peer_print_info(int cd, GNUTLS_STATE state)
return;
}
+/* actually something like readline.
+ * if rnl!=1 then reads an http request in the form REQ\n\n
+ */
int read_request(int cd, GNUTLS_STATE state, char *data, int data_size, int rnl)
{
- /* rnl is the requested new lines. Eg. return if 3 newlines
- * were given
- */
int n, rc, nl = 0;
- char c, *ptr;
+ char c, *ptr, p1=0, p2=0;
ptr = data;
for (n = 1; n < data_size; n++) {
if ((rc = gnutls_read(cd, state, &c, 1)) == 1) {
+
*ptr++ = c;
- if (c == '\n') {
+ if (c == '\n' && rnl==1) break;
+
+ if (c=='\n' && p1=='\r' && p2=='\n') {
nl++;
- if (nl == rnl)
+ if (nl == 1)
break;
}
+ p2 = p1;
+ p1 = c;
+
} else if (rc == 0) {
if (n == 1)
return 0;
@@ -257,6 +283,7 @@ int read_request(int cd, GNUTLS_STATE state, char *data, int data_size, int rnl)
return rc;
}
}
+fprintf(stderr, "\n");
*ptr = 0;
return n;
}
@@ -384,7 +411,7 @@ int main(int argc, char **argv)
}
}
printf("\n");
- gnutls_bye(sd, state);
+ gnutls_bye_nowait(sd, state);
close(sd);
gnutls_deinit(state);
}