summaryrefslogtreecommitdiff
path: root/lib/gnutls_handshake.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gnutls_handshake.c')
-rw-r--r--lib/gnutls_handshake.c96
1 files changed, 40 insertions, 56 deletions
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index f8d2724ff3..753bfe2d14 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -282,12 +282,12 @@ int
_gnutls_read_client_hello (gnutls_session_t session, opaque * data,
int datalen)
{
- uint8_t session_id_len, z;
+ uint8_t session_id_len;
int pos = 0, ret;
- uint16_t suite_size;
+ uint16_t suite_size, comp_size;
gnutls_protocol_t version;
int len = datalen;
- opaque rnd[TLS_RANDOM_SIZE], *suite_ptr;
+ opaque rnd[TLS_RANDOM_SIZE], *suite_ptr, *comp_ptr;
gnutls_protocol_t ver;
if (session->internals.v2_hello != 0)
@@ -376,20 +376,14 @@ _gnutls_read_client_hello (gnutls_session_t session, opaque * data,
suite_ptr = &data[pos];
pos += suite_size;
- /* Select an appropriate compression method
+ /* Point to the compression methods
*/
DECR_LEN (len, 1);
- z = data[pos++]; /* z is the number of compression methods */
+ comp_size = data[pos++]; /* z is the number of compression methods */
- DECR_LEN (len, z);
- ret = _gnutls_server_select_comp_method (session, &data[pos], z);
- pos += z;
-
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
+ DECR_LEN (len, comp_size);
+ comp_ptr = &data[pos];
+ pos += comp_size;
/* Parse the extensions (if any)
*/
@@ -403,6 +397,16 @@ _gnutls_read_client_hello (gnutls_session_t session, opaque * data,
}
}
+ if (session->internals.user_hello_func != NULL)
+ {
+ ret = session->internals.user_hello_func( session);
+ if (ret < 0)
+ {
+ gnutls_assert();
+ return ret;
+ }
+ }
+
/* select an appropriate cipher suite
*/
ret = _gnutls_server_select_suite (session, suite_ptr, suite_size);
@@ -412,6 +416,14 @@ _gnutls_read_client_hello (gnutls_session_t session, opaque * data,
return ret;
}
+ /* select appropriate compression method */
+ ret = _gnutls_server_select_comp_method (session, comp_ptr, comp_size);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+
return 0;
}
@@ -1115,17 +1127,6 @@ _gnutls_recv_handshake (gnutls_session_t session, uint8_t ** data,
if (ret < 0)
{
- /* In SRP when expecting the server hello we may receive
- * an alert instead. Do as the draft demands.
- */
- if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED &&
- gnutls_alert_get (session) == GNUTLS_A_MISSING_SRP_USERNAME &&
- type == GNUTLS_HANDSHAKE_SERVER_HELLO)
- {
- gnutls_assert ();
- return GNUTLS_E_INT_HANDSHAKE_AGAIN;
- }
-
if (ret == GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET
&& optional == OPTIONAL_PACKET)
{
@@ -1839,19 +1840,19 @@ _gnutls_send_server_hello (gnutls_session_t session, int again)
session->security_parameters.extensions.srp_username[0] == 0)
{
/* The peer didn't send a valid SRP extension with the
- * SRP username. The draft requires that we send an
- * alert and start the handshake again.
+ * SRP username. The draft requires that we send a fatal
+ * alert and abort.
*/
gnutls_assert ();
- ret = gnutls_alert_send (session, GNUTLS_AL_WARNING,
- GNUTLS_A_MISSING_SRP_USERNAME);
+ ret = gnutls_alert_send (session, GNUTLS_AL_FATAL,
+ GNUTLS_A_UNKNOWN_PSK_IDENTITY);
if (ret < 0)
{
gnutls_assert ();
return ret;
}
- return GNUTLS_E_INT_HANDSHAKE_AGAIN;
+ return GNUTLS_E_ILLEGAL_SRP_USERNAME;
}
}
#endif
@@ -2217,21 +2218,8 @@ gnutls_handshake (gnutls_session_t session)
return 0;
}
-/* Here if GNUTLS_E_INT_HANDSHAKE_AGAIN is received we go to
- * restart. This works because this error code may only be
- * received on the first 2 handshake packets. If for some reason
- * this changes we should return GNUTLS_E_AGAIN.
- */
#define IMED_RET( str, ret) do { \
if (ret < 0) { \
- if (ret == GNUTLS_E_INT_HANDSHAKE_AGAIN && \
- session->internals.handshake_restarted == 1) \
- ret = GNUTLS_E_INTERNAL_ERROR; \
- if (ret == GNUTLS_E_INT_HANDSHAKE_AGAIN) { \
- STATE = STATE0; \
- session->internals.handshake_restarted = 1; \
- goto restart; \
- } \
if (gnutls_error_is_fatal(ret)==0) return ret; \
gnutls_assert(); \
ERR( str, ret); \
@@ -2263,7 +2251,6 @@ _gnutls_handshake_client (gnutls_session_t session)
session_id_size, buf,
sizeof (buf)));
#endif
-restart:
switch (STATE)
{
@@ -2491,8 +2478,6 @@ _gnutls_handshake_server (gnutls_session_t session)
{
int ret = 0;
-restart:
-
switch (STATE)
{
case STATE0:
@@ -2594,8 +2579,6 @@ _gnutls_handshake_common (gnutls_session_t session)
{
int ret = 0;
-restart:
-
/* send and recv the change cipher spec and finished messages */
if ((session->internals.resumed == RESUME_TRUE
&& session->security_parameters.entity == GNUTLS_CLIENT)
@@ -2801,11 +2784,11 @@ _gnutls_remove_unwanted_ciphersuites (gnutls_session_t session,
int ret = 0;
cipher_suite_st *newSuite, cs;
int newSuiteSize = 0, i;
- gnutls_certificate_credentials_t x509_cred;
+ gnutls_certificate_credentials_t cert_cred;
gnutls_kx_algorithm_t kx;
int server = session->security_parameters.entity == GNUTLS_SERVER ? 1 : 0;
- gnutls_kx_algorithm_t *alg;
- int alg_size;
+ gnutls_kx_algorithm_t *alg = NULL;
+ int alg_size = 0;
/* if we should use a specific certificate,
* we should remove all algorithms that are not supported
@@ -2813,22 +2796,23 @@ _gnutls_remove_unwanted_ciphersuites (gnutls_session_t session,
* method (CERTIFICATE).
*/
- x509_cred =
+ cert_cred =
(gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
GNUTLS_CRD_CERTIFICATE,
NULL);
- /* if x509_cred==NULL we should remove all X509 ciphersuites
+ /* If there are certificate credentials, find an appropriate certificate
+ * or disable them;
*/
-
if (session->security_parameters.entity == GNUTLS_SERVER
- && x509_cred != NULL)
+ && cert_cred != NULL)
{
ret = _gnutls_server_select_cert (session, requested_pk_algo);
if (ret < 0)
{
gnutls_assert ();
- return ret;
+ _gnutls_x509_log("Could not find an appropriate certificate: %s\n", gnutls_strerror(ret));
+ cert_cred = NULL;
}
}