summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2002-03-03 00:06:33 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2002-03-03 00:06:33 +0000
commit638b172abbc1163c1bacf7d8a5aa13d94c7109d0 (patch)
treef501317ef2ff2ebe976ff9aff32ffba3056b121e
parentb0ba633b9a3d85c9b1168826c2f7bc065e59498a (diff)
downloadgnutls-638b172abbc1163c1bacf7d8a5aa13d94c7109d0.tar.gz
Changed behaviour in rehandshake procedure. Now can use rehandshake with
a different authentication method (ie. perform anonymous authentication, and after that perform a certificate authentication, or srp).
-rw-r--r--lib/auth_cert.c8
-rw-r--r--lib/gnutls_auth.c26
-rw-r--r--lib/gnutls_handshake.c4
-rw-r--r--lib/gnutls_int.h6
-rw-r--r--lib/gnutls_state.c35
-rw-r--r--lib/gnutls_state.h1
6 files changed, 59 insertions, 21 deletions
diff --git a/lib/auth_cert.c b/lib/auth_cert.c
index 8920d81fc3..95d0af7363 100644
--- a/lib/auth_cert.c
+++ b/lib/auth_cert.c
@@ -812,10 +812,6 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data,
}
- /* keep the PK algorithm */
- state->gnutls_internals.peer_pk_algorithm =
- peer_certificate_list[0].subject_pk_algorithm;
-
if ((ret =
_gnutls_copy_certificate_auth_info(info,
peer_certificate_list,
@@ -966,10 +962,6 @@ int _gnutls_proc_openpgp_server_certificate(GNUTLS_STATE state,
}
gnutls_free_datum( &akey);
- /* keep the PK algorithm */
- state->gnutls_internals.peer_pk_algorithm =
- peer_certificate_list[0].subject_pk_algorithm;
-
if ((ret =
_gnutls_copy_certificate_auth_info(info,
peer_certificate_list,
diff --git a/lib/gnutls_auth.c b/lib/gnutls_auth.c
index 1bc1eb26c6..567a8066d8 100644
--- a/lib/gnutls_auth.c
+++ b/lib/gnutls_auth.c
@@ -233,6 +233,9 @@ void _gnutls_free_auth_info( GNUTLS_STATE state) {
}
+/* This function will set the auth info structure in the gnutls_key
+ * structure.
+ */
int _gnutls_auth_info_set( GNUTLS_STATE state, CredType type, int size) {
if ( state->gnutls_key->auth_info == NULL) {
state->gnutls_key->auth_info = gnutls_calloc( 1, size);
@@ -242,7 +245,9 @@ int _gnutls_auth_info_set( GNUTLS_STATE state, CredType type, int size) {
}
state->gnutls_key->auth_info_type = type;
state->gnutls_key->auth_info_size = size;
- } else
+ } else {
+#if 0
+ /* 20020303: This is the old behaviour */
/* If the credentials for the current authentication scheme,
* are not the one we want to set, then it's an error.
* This may happen if a rehandshake is performed an the
@@ -253,6 +258,25 @@ int _gnutls_auth_info_set( GNUTLS_STATE state, CredType type, int size) {
gnutls_assert();
return GNUTLS_E_INVALID_REQUEST;
}
+#endif
+ /* The new behaviour: Here we reallocate the auth info structure
+ * in order to be able to negotiate different authentication
+ * types. Ie. perform an auth_anon and then authenticate again using a
+ * certificate (in order to prevent revealing the certificate's contents,
+ * to passive eavesdropers.
+ */
+ if ( gnutls_auth_get_type( state) != state->gnutls_key->auth_info_type) {
+ state->gnutls_key->auth_info = gnutls_realloc_fast(
+ state->gnutls_key->auth_info, size);
+ if (state->gnutls_key->auth_info == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ memset( state->gnutls_key->auth_info, 0, size);
+ state->gnutls_key->auth_info_type = type;
+ state->gnutls_key->auth_info_size = size;
+ }
+ }
return 0;
}
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 4251412e52..f5ce9e7537 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -337,7 +337,6 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
/* Parse the extensions (if any)
*/
if (ver >= GNUTLS_TLS1) {
- gnutls_assert();
ret = _gnutls_parse_extensions(state, &data[pos], len); /* len is the rest of the parsed length */
if (ret < 0) {
gnutls_assert();
@@ -1290,7 +1289,6 @@ static int _gnutls_read_server_hello(GNUTLS_STATE state, char *data,
/* Parse extensions.
*/
if (version >= GNUTLS_TLS1) {
- gnutls_assert();
ret = _gnutls_parse_extensions(state, &data[pos], len); /* len is the rest of the parsed length */
if (ret < 0) {
gnutls_assert();
@@ -1554,7 +1552,6 @@ static int _gnutls_send_client_hello(GNUTLS_STATE state, int again)
/* Generate and copy TLS extensions.
*/
if (hver >= GNUTLS_TLS1) {
- gnutls_assert();
extdatalen = _gnutls_gen_extensions(state, &extdata);
if (extdatalen > 0) {
datalen += extdatalen;
@@ -1861,6 +1858,7 @@ int gnutls_handshake(GNUTLS_STATE state)
STATE = STATE0;
_gnutls_handshake_io_buffer_clear(state);
+ _gnutls_handshake_internal_state_clear(state);
return 0;
}
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 2eaf78b831..c1c2325233 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -483,9 +483,6 @@ typedef struct {
* supports it.
*/
int send_cert_req;
- int peer_pk_algorithm;
- /* holds the username got in the srp tls extension
- */
/* this is a callback function to call if no appropriate
* client certificates were found.
@@ -546,6 +543,9 @@ typedef struct {
/* This holds the default version that our first
* record packet will have. */
GNUTLS_Version default_record_version;
+
+ /* If you add anything here, check _gnutls_handshake_internal_state_clear().
+ */
} GNUTLS_INTERNALS;
struct GNUTLS_STATE_INT {
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index 5873f18183..d0d674a1a9 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -110,6 +110,32 @@ int i;
return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
}
+/* This function will clear all the variables in gnutls_internals
+ * structure within the state, which depend on the current handshake.
+ * This is used to allow further handshakes.
+ */
+void _gnutls_handshake_internal_state_clear( GNUTLS_STATE state) {
+ state->gnutls_internals.pgp_fingerprint = 0;
+ state->gnutls_internals.extensions_sent_size = 0;
+
+ /* by default no selected certificate */
+ state->gnutls_internals.selected_cert_index = -1;
+ state->gnutls_internals.proposed_record_size = DEFAULT_MAX_RECORD_SIZE;
+ state->gnutls_internals.send_cert_req;
+ state->gnutls_internals.adv_version_major = 0;
+ state->gnutls_internals.adv_version_minor = 0;
+ state->gnutls_internals.v2_hello = 0;
+ memset( &state->gnutls_internals.handshake_header_buffer, 0,
+ sizeof(HANDSHAKE_HEADER_BUFFER));
+ state->gnutls_internals.adv_version_minor = 0;
+ state->gnutls_internals.adv_version_minor = 0;
+
+ state->gnutls_internals.resumed = RESUME_FALSE;
+ state->gnutls_internals.resumable = RESUME_TRUE;
+
+}
+
+
#define _gnutls_free(x) if(x!=NULL) gnutls_free(x)
/**
* gnutls_init - This function initializes the state to null (null encryption etc...).
@@ -144,7 +170,6 @@ int default_protocol_list[] = { GNUTLS_TLS1, 0 };
(*state)->security_parameters.read_compression_algorithm = GNUTLS_COMP_NULL;
(*state)->security_parameters.write_compression_algorithm = GNUTLS_COMP_NULL;
- (*state)->gnutls_internals.resumable = RESUME_TRUE;
gnutls_protocol_set_priority( *state, default_protocol_list); /* default */
@@ -154,8 +179,6 @@ int default_protocol_list[] = { GNUTLS_TLS1, 0 };
return GNUTLS_E_MEMORY_ERROR;
}
- (*state)->gnutls_internals.resumed = RESUME_FALSE;
-
(*state)->gnutls_internals.expire_time = DEFAULT_EXPIRE_TIME; /* one hour default */
gnutls_dh_set_prime_bits( (*state), MIN_BITS);
@@ -173,15 +196,14 @@ int default_protocol_list[] = { GNUTLS_TLS1, 0 };
/* set the default maximum record size for TLS
*/
(*state)->security_parameters.max_record_size = DEFAULT_MAX_RECORD_SIZE;
- (*state)->gnutls_internals.proposed_record_size = DEFAULT_MAX_RECORD_SIZE;
- /* by default no selected certificate */
- (*state)->gnutls_internals.selected_cert_index = -1;
/* everything else not initialized here is initialized
* as NULL or 0. This is why calloc is used.
*/
+ _gnutls_handshake_internal_state_clear( *state);
+
return 0;
}
@@ -377,3 +399,4 @@ void _gnutls_record_set_default_version(GNUTLS_STATE state, GNUTLS_Version versi
{
state->gnutls_internals.default_record_version = version;
}
+
diff --git a/lib/gnutls_state.h b/lib/gnutls_state.h
index c7803cf20e..929a85d68f 100644
--- a/lib/gnutls_state.h
+++ b/lib/gnutls_state.h
@@ -22,6 +22,7 @@ int _gnutls_dh_set_secret_bits( GNUTLS_STATE state, int bits);
int _gnutls_dh_set_prime_bits( GNUTLS_STATE state, int bits);
int _gnutls_dh_get_prime_bits( GNUTLS_STATE state);
void gnutls_dh_set_prime_bits( GNUTLS_STATE state, int bits);
+void _gnutls_handshake_internal_state_clear( GNUTLS_STATE);
int _gnutls_openpgp_send_fingerprint( GNUTLS_STATE state);