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.c3652
1 files changed, 1842 insertions, 1810 deletions
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 150e1864d6..9dc66a99dd 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -47,8 +47,8 @@
#include <gnutls_alert.h>
#include <gnutls_state.h>
#include <ext_srp.h>
-#include <gnutls_rsa_export.h> /* for gnutls_get_rsa_params() */
-#include <auth_anon.h> /* for gnutls_anon_server_credentials */
+#include <gnutls_rsa_export.h> /* for gnutls_get_rsa_params() */
+#include <auth_anon.h> /* for gnutls_anon_server_credentials */
#ifdef HANDSHAKE_DEBUG
#define ERR(x, y) _gnutls_handshake_log( "HSK[%x]: %s (%d)\n", session, x,y)
@@ -60,19 +60,19 @@
#define FALSE 0
int _gnutls_server_select_comp_method(gnutls_session session,
- opaque * data, int datalen);
+ opaque * data, int datalen);
/* Clears the handshake hash buffers and handles.
*/
inline static
-void _gnutls_handshake_hash_buffers_clear( gnutls_session session)
+void _gnutls_handshake_hash_buffers_clear(gnutls_session session)
{
- _gnutls_hash_deinit( session->internals.handshake_mac_handle_md5, NULL);
- _gnutls_hash_deinit( session->internals.handshake_mac_handle_sha, NULL);
- session->internals.handshake_mac_handle_md5 = NULL;
- session->internals.handshake_mac_handle_sha = NULL;
- _gnutls_handshake_buffer_clear( session);
+ _gnutls_hash_deinit(session->internals.handshake_mac_handle_md5, NULL);
+ _gnutls_hash_deinit(session->internals.handshake_mac_handle_sha, NULL);
+ session->internals.handshake_mac_handle_md5 = NULL;
+ session->internals.handshake_mac_handle_sha = NULL;
+ _gnutls_handshake_buffer_clear(session);
}
/* this will copy the required values for resuming to
@@ -81,55 +81,57 @@ void _gnutls_handshake_hash_buffers_clear( gnutls_session session)
*/
static void resume_copy_required_values(gnutls_session session)
{
- /* get the new random values */
- memcpy(session->internals.resumed_security_parameters.
- server_random,
- session->security_parameters.server_random, TLS_RANDOM_SIZE);
- memcpy(session->internals.resumed_security_parameters.
- client_random,
- session->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(session->security_parameters.current_cipher_suite.
- suite,
- session->internals.resumed_security_parameters.
- current_cipher_suite.suite, 2);
-
- session->internals.compression_method =
- session->internals.resumed_security_parameters.read_compression_algorithm;
- /* or write_compression_algorithm
- * they are the same
- */
-
- session->security_parameters.entity =
- session->internals.resumed_security_parameters.entity;
-
- _gnutls_set_current_version( session, session->internals.resumed_security_parameters.version);
-
- session->security_parameters.cert_type =
- session->internals.resumed_security_parameters.cert_type;
-
- memcpy(session->security_parameters.session_id,
- session->internals.resumed_security_parameters.
- session_id, sizeof(session->security_parameters.session_id));
- session->security_parameters.session_id_size =
- session->internals.resumed_security_parameters.
- session_id_size;
+ /* get the new random values */
+ memcpy(session->internals.resumed_security_parameters.
+ server_random,
+ session->security_parameters.server_random, TLS_RANDOM_SIZE);
+ memcpy(session->internals.resumed_security_parameters.
+ client_random,
+ session->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(session->security_parameters.current_cipher_suite.
+ suite,
+ session->internals.resumed_security_parameters.
+ current_cipher_suite.suite, 2);
+
+ session->internals.compression_method =
+ session->internals.resumed_security_parameters.
+ read_compression_algorithm;
+ /* or write_compression_algorithm
+ * they are the same
+ */
+
+ session->security_parameters.entity =
+ session->internals.resumed_security_parameters.entity;
+
+ _gnutls_set_current_version(session,
+ session->internals.
+ resumed_security_parameters.version);
+
+ session->security_parameters.cert_type =
+ session->internals.resumed_security_parameters.cert_type;
+
+ memcpy(session->security_parameters.session_id,
+ session->internals.resumed_security_parameters.
+ session_id, sizeof(session->security_parameters.session_id));
+ session->security_parameters.session_id_size =
+ session->internals.resumed_security_parameters.session_id_size;
}
void _gnutls_set_server_random(gnutls_session session, uint8 * random)
{
- memcpy(session->security_parameters.server_random, random,
- TLS_RANDOM_SIZE);
+ memcpy(session->security_parameters.server_random, random,
+ TLS_RANDOM_SIZE);
}
void _gnutls_set_client_random(gnutls_session session, uint8 * random)
{
- memcpy(session->security_parameters.client_random, random,
- TLS_RANDOM_SIZE);
+ memcpy(session->security_parameters.client_random, random,
+ TLS_RANDOM_SIZE);
}
/* Calculate The SSL3 Finished message
@@ -137,39 +139,46 @@ void _gnutls_set_client_random(gnutls_session session, uint8 * random)
#define SSL3_CLIENT_MSG "CLNT"
#define SSL3_SERVER_MSG "SRVR"
#define SSL_MSG_LEN 4
-static int _gnutls_ssl3_finished(gnutls_session session, int type, opaque * ret)
+static int _gnutls_ssl3_finished(gnutls_session session, int type,
+ opaque * ret)
{
- const int siz = SSL_MSG_LEN;
- mac_hd_t td_md5;
- mac_hd_t td_sha;
- const char *mesg;
-
- td_md5 = _gnutls_hash_copy( session->internals.handshake_mac_handle_md5);
- if (td_md5 == NULL) {
- gnutls_assert();
- return GNUTLS_E_HASH_FAILED;
- }
-
- td_sha = _gnutls_hash_copy( session->internals.handshake_mac_handle_sha);
- if (td_sha == NULL) {
- gnutls_assert();
- _gnutls_hash_deinit( td_md5, NULL);
- return GNUTLS_E_HASH_FAILED;
- }
-
- if (type == GNUTLS_SERVER) {
- mesg = SSL3_SERVER_MSG;
- } else {
- mesg = SSL3_CLIENT_MSG;
- }
-
- _gnutls_hash(td_md5, mesg, siz);
- _gnutls_hash(td_sha, mesg, siz);
-
- _gnutls_mac_deinit_ssl3_handshake(td_md5, ret, session->security_parameters.master_secret, TLS_MASTER_SIZE);
- _gnutls_mac_deinit_ssl3_handshake(td_sha, &ret[16], session->security_parameters.master_secret, TLS_MASTER_SIZE);
+ const int siz = SSL_MSG_LEN;
+ mac_hd_t td_md5;
+ mac_hd_t td_sha;
+ const char *mesg;
+
+ td_md5 =
+ _gnutls_hash_copy(session->internals.handshake_mac_handle_md5);
+ if (td_md5 == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_HASH_FAILED;
+ }
- return 0;
+ td_sha =
+ _gnutls_hash_copy(session->internals.handshake_mac_handle_sha);
+ if (td_sha == NULL) {
+ gnutls_assert();
+ _gnutls_hash_deinit(td_md5, NULL);
+ return GNUTLS_E_HASH_FAILED;
+ }
+
+ if (type == GNUTLS_SERVER) {
+ mesg = SSL3_SERVER_MSG;
+ } else {
+ mesg = SSL3_CLIENT_MSG;
+ }
+
+ _gnutls_hash(td_md5, mesg, siz);
+ _gnutls_hash(td_sha, mesg, siz);
+
+ _gnutls_mac_deinit_ssl3_handshake(td_md5, ret,
+ session->security_parameters.
+ master_secret, TLS_MASTER_SIZE);
+ _gnutls_mac_deinit_ssl3_handshake(td_sha, &ret[16],
+ session->security_parameters.
+ master_secret, TLS_MASTER_SIZE);
+
+ return 0;
}
/* Hash the handshake messages as required by TLS 1.0
@@ -179,39 +188,40 @@ static int _gnutls_ssl3_finished(gnutls_session session, int type, opaque * ret)
#define TLS_MSG_LEN 15
int _gnutls_finished(gnutls_session session, int type, void *ret)
{
- const int siz = TLS_MSG_LEN;
- opaque concat[36];
- const char *mesg;
- mac_hd_t td_md5;
- mac_hd_t td_sha;
+ const int siz = TLS_MSG_LEN;
+ opaque concat[36];
+ const char *mesg;
+ mac_hd_t td_md5;
+ mac_hd_t td_sha;
- td_md5 = _gnutls_hash_copy( session->internals.handshake_mac_handle_md5);
- if (td_md5 == NULL) {
- gnutls_assert();
- return GNUTLS_E_HASH_FAILED;
- }
+ td_md5 =
+ _gnutls_hash_copy(session->internals.handshake_mac_handle_md5);
+ if (td_md5 == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_HASH_FAILED;
+ }
- td_sha = _gnutls_hash_copy( session->internals.handshake_mac_handle_sha);
- if (td_sha == NULL) {
- gnutls_assert();
- _gnutls_hash_deinit( td_md5, NULL);
- return GNUTLS_E_HASH_FAILED;
- }
+ td_sha =
+ _gnutls_hash_copy(session->internals.handshake_mac_handle_sha);
+ if (td_sha == NULL) {
+ gnutls_assert();
+ _gnutls_hash_deinit(td_md5, NULL);
+ return GNUTLS_E_HASH_FAILED;
+ }
- _gnutls_hash_deinit(td_md5, concat);
- _gnutls_hash_deinit(td_sha, &concat[16]);
+ _gnutls_hash_deinit(td_md5, concat);
+ _gnutls_hash_deinit(td_sha, &concat[16]);
- if (type == GNUTLS_SERVER) {
- mesg = SERVER_MSG;
- } else {
- mesg = CLIENT_MSG;
- }
+ if (type == GNUTLS_SERVER) {
+ mesg = SERVER_MSG;
+ } else {
+ mesg = CLIENT_MSG;
+ }
- return _gnutls_PRF(session->security_parameters.master_secret,
- TLS_MASTER_SIZE, mesg, siz, concat, 36,
- 12, ret);
+ return _gnutls_PRF(session->security_parameters.master_secret,
+ TLS_MASTER_SIZE, mesg, siz, concat, 36, 12, ret);
}
/* this function will produce TLS_RANDOM_SIZE==32 bytes of random data
@@ -219,24 +229,24 @@ int _gnutls_finished(gnutls_session session, int type, void *ret)
*/
int _gnutls_tls_create_random(opaque * dst)
{
- uint32 tim;
+ uint32 tim;
- /* Use weak random numbers for the most of the
- * buffer except for the first 4 that are the
- * system's time.
- */
+ /* Use weak random numbers for the most of the
+ * buffer except for the first 4 that are the
+ * system's time.
+ */
- tim = time(NULL);
- /* generate server random value */
- _gnutls_write_uint32(tim, dst);
+ tim = time(NULL);
+ /* generate server random value */
+ _gnutls_write_uint32(tim, dst);
- if (_gnutls_get_random
- (&dst[4], TLS_RANDOM_SIZE - 4, GNUTLS_WEAK_RANDOM) < 0) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
+ if (_gnutls_get_random
+ (&dst[4], TLS_RANDOM_SIZE - 4, GNUTLS_WEAK_RANDOM) < 0) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
- return 0;
+ return 0;
}
@@ -248,154 +258,159 @@ int _gnutls_tls_create_random(opaque * dst)
int _gnutls_read_client_hello(gnutls_session session, opaque * data,
int datalen)
{
- uint8 session_id_len, z;
- int pos = 0, ret;
- uint16 suite_size;
- gnutls_protocol_version version;
- int len = datalen;
- opaque random[TLS_RANDOM_SIZE], *suite_ptr;
- gnutls_protocol_version ver;
-
- if (session->internals.v2_hello != 0) { /* version 2.0 */
- return _gnutls_read_client_hello_v2(session, data, datalen);
- }
- DECR_LEN(len, 2);
-
- _gnutls_handshake_log("HSK[%x]: Client's version: %d.%d\n", session, data[pos], data[pos + 1]);
-
- version = _gnutls_version_get(data[pos], data[pos + 1]);
- set_adv_version(session, data[pos], data[pos + 1]);
- pos += 2;
-
- /* if we do not support that version */
- if (_gnutls_version_is_supported(session, version) == 0) {
- /* If he requested something we do not support
- * then we send him the highest we support.
- */
- ver = _gnutls_version_max(session);
- if (ver==GNUTLS_VERSION_UNKNOWN) {
- /* this check is not really needed.
- */
- gnutls_assert();
- return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
- }
- } else {
- ver = version;
- }
-
- _gnutls_set_current_version(session, ver);
-
- /* Read client random value.
- */
- DECR_LEN(len, TLS_RANDOM_SIZE);
- _gnutls_set_client_random(session, &data[pos]);
- pos += TLS_RANDOM_SIZE;
-
- _gnutls_tls_create_random(random);
- _gnutls_set_server_random(session, random);
-
- session->security_parameters.timestamp = time(NULL);
-
- DECR_LEN(len, 1);
- session_id_len = data[pos++];
-
- /* RESUME SESSION
+ uint8 session_id_len, z;
+ int pos = 0, ret;
+ uint16 suite_size;
+ gnutls_protocol_version version;
+ int len = datalen;
+ opaque random[TLS_RANDOM_SIZE], *suite_ptr;
+ gnutls_protocol_version ver;
+
+ if (session->internals.v2_hello != 0) { /* version 2.0 */
+ return _gnutls_read_client_hello_v2(session, data, datalen);
+ }
+ DECR_LEN(len, 2);
+
+ _gnutls_handshake_log("HSK[%x]: Client's version: %d.%d\n", session,
+ data[pos], data[pos + 1]);
+
+ version = _gnutls_version_get(data[pos], data[pos + 1]);
+ set_adv_version(session, data[pos], data[pos + 1]);
+ pos += 2;
+
+ /* if we do not support that version */
+ if (_gnutls_version_is_supported(session, version) == 0) {
+ /* If he requested something we do not support
+ * then we send him the highest we support.
*/
- if (session_id_len > TLS_MAX_SESSION_ID_SIZE) {
- gnutls_assert();
- return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ ver = _gnutls_version_max(session);
+ if (ver == GNUTLS_VERSION_UNKNOWN) {
+ /* this check is not really needed.
+ */
+ gnutls_assert();
+ return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
}
- DECR_LEN(len, session_id_len);
- ret = _gnutls_server_restore_session(session, &data[pos], session_id_len);
- pos += session_id_len;
+ } else {
+ ver = version;
+ }
- if (ret == 0) { /* resumed! */
- resume_copy_required_values(session);
- session->internals.resumed = RESUME_TRUE;
- return 0;
- } else {
- _gnutls_generate_session_id(session->security_parameters.
- session_id,
- &session->security_parameters.
- session_id_size);
+ _gnutls_set_current_version(session, ver);
- session->internals.resumed = RESUME_FALSE;
- }
+ /* Read client random value.
+ */
+ DECR_LEN(len, TLS_RANDOM_SIZE);
+ _gnutls_set_client_random(session, &data[pos]);
+ pos += TLS_RANDOM_SIZE;
- /* Remember ciphersuites for later
- */
- DECR_LEN(len, 2);
- suite_size = _gnutls_read_uint16(&data[pos]);
- pos += 2;
+ _gnutls_tls_create_random(random);
+ _gnutls_set_server_random(session, random);
- DECR_LEN(len, suite_size);
- suite_ptr = &data[pos];
- pos += suite_size;
+ session->security_parameters.timestamp = time(NULL);
- /* Select an appropriate compression method
- */
- DECR_LEN(len, 1);
- z = data[pos++]; /* z is the number of compression methods */
+ DECR_LEN(len, 1);
+ session_id_len = data[pos++];
- DECR_LEN(len, z);
- ret = _gnutls_server_select_comp_method(session, &data[pos], z);
- pos += z;
+ /* RESUME SESSION
+ */
+ if (session_id_len > TLS_MAX_SESSION_ID_SIZE) {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ }
+ DECR_LEN(len, session_id_len);
+ ret =
+ _gnutls_server_restore_session(session, &data[pos],
+ session_id_len);
+ pos += session_id_len;
+
+ if (ret == 0) { /* resumed! */
+ resume_copy_required_values(session);
+ session->internals.resumed = RESUME_TRUE;
+ return 0;
+ } else {
+ _gnutls_generate_session_id(session->security_parameters.
+ session_id,
+ &session->security_parameters.
+ session_id_size);
+
+ session->internals.resumed = RESUME_FALSE;
+ }
+
+ /* Remember ciphersuites for later
+ */
+ DECR_LEN(len, 2);
+ suite_size = _gnutls_read_uint16(&data[pos]);
+ pos += 2;
+
+ DECR_LEN(len, suite_size);
+ suite_ptr = &data[pos];
+ pos += suite_size;
+
+ /* Select an appropriate compression method
+ */
+ DECR_LEN(len, 1);
+ z = 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;
+ }
+ /* Parse the extensions (if any)
+ */
+ if (ver >= GNUTLS_TLS1) {
+ ret = _gnutls_parse_extensions(session, &data[pos], len); /* len is the rest of the parsed length */
if (ret < 0) {
- gnutls_assert();
- return ret;
- }
-
- /* Parse the extensions (if any)
- */
- if (ver >= GNUTLS_TLS1) {
- ret = _gnutls_parse_extensions(session, &data[pos], len); /* len is the rest of the parsed length */
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
- }
-
- /* select an appropriate cipher suite
- */
- ret = _gnutls_server_select_suite(session, suite_ptr, suite_size);
- if (ret < 0) {
- gnutls_assert();
- return ret;
+ gnutls_assert();
+ return ret;
}
+ }
- return 0;
+ /* select an appropriate cipher suite
+ */
+ ret = _gnutls_server_select_suite(session, suite_ptr, suite_size);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ return 0;
}
/* here we hash all pending data.
*/
-inline static int
-_gnutls_handshake_hash_pending( gnutls_session session) {
-size_t siz;
-int ret;
-opaque * data;
-
- if (session->internals.handshake_mac_handle_sha==NULL ||
- session->internals.handshake_mac_handle_md5==NULL) {
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
- }
+inline static int _gnutls_handshake_hash_pending(gnutls_session session)
+{
+ size_t siz;
+ int ret;
+ opaque *data;
- /* We check if there are pending data to hash.
- */
- if ((ret=_gnutls_handshake_buffer_get_ptr(session, &data, &siz)) < 0) {
- gnutls_assert();
- return ret;
- }
+ if (session->internals.handshake_mac_handle_sha == NULL ||
+ session->internals.handshake_mac_handle_md5 == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
- if (siz > 0) {
- _gnutls_hash( session->internals.handshake_mac_handle_sha, data, siz);
- _gnutls_hash( session->internals.handshake_mac_handle_md5, data, siz);
- }
-
- _gnutls_handshake_buffer_empty( session);
-
- return 0;
+ /* We check if there are pending data to hash.
+ */
+ if ((ret = _gnutls_handshake_buffer_get_ptr(session, &data, &siz)) < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ if (siz > 0) {
+ _gnutls_hash(session->internals.handshake_mac_handle_sha, data,
+ siz);
+ _gnutls_hash(session->internals.handshake_mac_handle_md5, data,
+ siz);
+ }
+
+ _gnutls_handshake_buffer_empty(session);
+
+ return 0;
}
@@ -405,48 +420,46 @@ opaque * data;
*/
int _gnutls_send_finished(gnutls_session session, int again)
{
- uint8 data[36];
- int ret;
- int data_size = 0;
+ uint8 data[36];
+ int ret;
+ int data_size = 0;
- if (again == 0) {
-
- /* This is needed in order to hash all the required
- * messages.
- */
- if ((ret=_gnutls_handshake_hash_pending(session)) < 0) {
- gnutls_assert();
- return ret;
- }
+ if (again == 0) {
- if (gnutls_protocol_get_version( session) == GNUTLS_SSL3) {
- ret =
- _gnutls_ssl3_finished(session,
- session->
- security_parameters.
- entity, data);
- data_size = 36;
- } else { /* TLS 1.0 */
- ret =
- _gnutls_finished(session,
- session->security_parameters.
- entity, data);
- data_size = 12;
- }
+ /* This is needed in order to hash all the required
+ * messages.
+ */
+ if ((ret = _gnutls_handshake_hash_pending(session)) < 0) {
+ gnutls_assert();
+ return ret;
+ }
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
+ if (gnutls_protocol_get_version(session) == GNUTLS_SSL3) {
+ ret =
+ _gnutls_ssl3_finished(session,
+ session->
+ security_parameters.entity, data);
+ data_size = 36;
+ } else { /* TLS 1.0 */
+ ret =
+ _gnutls_finished(session,
+ session->security_parameters.
+ entity, data);
+ data_size = 12;
+ }
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
}
- ret =
- _gnutls_send_handshake(session, data, data_size,
- GNUTLS_FINISHED);
+ }
- return ret;
+ ret =
+ _gnutls_send_handshake(session, data, data_size, GNUTLS_FINISHED);
+
+ return ret;
}
/* This is to be called after sending our finished message. If everything
@@ -454,245 +467,256 @@ int _gnutls_send_finished(gnutls_session session, int again)
*/
int _gnutls_recv_finished(gnutls_session session)
{
- uint8 data[36], *vrfy;
- int data_size;
- int ret;
- int vrfysize;
-
- ret =
- _gnutls_recv_handshake(session, &vrfy, &vrfysize,
- GNUTLS_FINISHED, MANDATORY_PACKET);
- if (ret < 0) {
- ERR("recv finished int", ret);
- gnutls_assert();
- return ret;
- }
+ uint8 data[36], *vrfy;
+ int data_size;
+ int ret;
+ int vrfysize;
+
+ ret =
+ _gnutls_recv_handshake(session, &vrfy, &vrfysize,
+ GNUTLS_FINISHED, MANDATORY_PACKET);
+ if (ret < 0) {
+ ERR("recv finished int", ret);
+ gnutls_assert();
+ return ret;
+ }
- if ( gnutls_protocol_get_version( session) == GNUTLS_SSL3) {
- data_size = 36;
- } else {
- data_size = 12;
- }
+ if (gnutls_protocol_get_version(session) == GNUTLS_SSL3) {
+ data_size = 36;
+ } else {
+ data_size = 12;
+ }
- if (vrfysize != data_size) {
- gnutls_assert();
- gnutls_free(vrfy);
- return GNUTLS_E_ERROR_IN_FINISHED_PACKET;
- }
-
- if (gnutls_protocol_get_version( session) == GNUTLS_SSL3) {
- ret =
- _gnutls_ssl3_finished(session,
- (session->security_parameters.
- entity + 1) % 2, data);
- } else { /* TLS 1.0 */
- ret =
- _gnutls_finished(session,
- (session->security_parameters.entity +
- 1) % 2, data);
- }
+ if (vrfysize != data_size) {
+ gnutls_assert();
+ gnutls_free(vrfy);
+ return GNUTLS_E_ERROR_IN_FINISHED_PACKET;
+ }
- if (ret < 0) {
- gnutls_assert();
- gnutls_free(vrfy);
- return ret;
- }
+ if (gnutls_protocol_get_version(session) == GNUTLS_SSL3) {
+ ret =
+ _gnutls_ssl3_finished(session,
+ (session->security_parameters.
+ entity + 1) % 2, data);
+ } else { /* TLS 1.0 */
+ ret =
+ _gnutls_finished(session,
+ (session->security_parameters.entity +
+ 1) % 2, data);
+ }
- if (memcmp(vrfy, data, data_size) != 0) {
- gnutls_assert();
- ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET;
- }
+ if (ret < 0) {
+ gnutls_assert();
gnutls_free(vrfy);
-
return ret;
+ }
+
+ if (memcmp(vrfy, data, data_size) != 0) {
+ gnutls_assert();
+ ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET;
+ }
+ gnutls_free(vrfy);
+
+ return ret;
}
/* returns PK_RSA if the given cipher suite list only supports,
* RSA algorithms, PK_DSA if DSS, and PK_ANY for both or PK_NONE for none.
*/
-static int _gnutls_server_find_pk_algos_in_ciphersuites( const opaque* data, int datalen)
+static int _gnutls_server_find_pk_algos_in_ciphersuites(const opaque *
+ data, int datalen)
{
-int j;
-gnutls_pk_algorithm algo=GNUTLS_PK_NONE, prev_algo = 0;
-gnutls_kx_algorithm kx;
-cipher_suite_st cs;
+ int j;
+ gnutls_pk_algorithm algo = GNUTLS_PK_NONE, prev_algo = 0;
+ gnutls_kx_algorithm kx;
+ cipher_suite_st cs;
- if (datalen % 2 != 0) {
- gnutls_assert();
- return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
- }
+ if (datalen % 2 != 0) {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ }
- for (j = 0; j < datalen; j += 2) {
- memcpy( &cs.suite, &data[j], 2);
- kx = _gnutls_cipher_suite_get_kx_algo( &cs);
-
- if ( _gnutls_map_kx_get_cred( kx, 1) == GNUTLS_CRD_CERTIFICATE) {
- algo = _gnutls_map_pk_get_pk( kx);
-
- if (algo!=prev_algo && prev_algo!=0) return GNUTLS_PK_ANY;
- prev_algo = algo;
- }
+ for (j = 0; j < datalen; j += 2) {
+ memcpy(&cs.suite, &data[j], 2);
+ kx = _gnutls_cipher_suite_get_kx_algo(&cs);
+
+ if (_gnutls_map_kx_get_cred(kx, 1) == GNUTLS_CRD_CERTIFICATE) {
+ algo = _gnutls_map_pk_get_pk(kx);
+
+ if (algo != prev_algo && prev_algo != 0)
+ return GNUTLS_PK_ANY;
+ prev_algo = algo;
}
+ }
- return algo;
+ return algo;
}
/* This selects the best supported ciphersuite from the given ones. Then
* it adds the suite to the session and performs some checks.
*/
-int _gnutls_server_select_suite(gnutls_session session, opaque *data, int datalen)
+int _gnutls_server_select_suite(gnutls_session session, opaque * data,
+ int datalen)
{
- int x, i, j;
- cipher_suite_st *ciphers, cs;
- int retval, err;
- gnutls_pk_algorithm pk_algo; /* will hold the pk algorithms
- * supported by the peer.
- */
+ int x, i, j;
+ cipher_suite_st *ciphers, cs;
+ int retval, err;
+ gnutls_pk_algorithm pk_algo; /* will hold the pk algorithms
+ * supported by the peer.
+ */
- pk_algo = _gnutls_server_find_pk_algos_in_ciphersuites( data, datalen);
-
- x = _gnutls_supported_ciphersuites(session, &ciphers);
- if (x < 0) { /* the case x==0 is handled within the function. */
- gnutls_assert();
- return x;
- }
-
- /* Here we remove any ciphersuite that does not conform
- * the certificate requested, or to the
- * authentication requested (e.g. SRP).
- */
- x = _gnutls_remove_unwanted_ciphersuites(session, &ciphers, x, pk_algo);
- if (x<=0) {
- gnutls_assert();
- gnutls_free(ciphers);
- if (x<0) return x;
- else return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
- }
-
- /* Data length should be zero mod 2 since
- * every ciphersuite is 2 bytes. (this check is needed
- * see below).
- */
- if (datalen % 2 != 0) {
- gnutls_assert();
- return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
- }
+ pk_algo = _gnutls_server_find_pk_algos_in_ciphersuites(data, datalen);
+ x = _gnutls_supported_ciphersuites(session, &ciphers);
+ if (x < 0) { /* the case x==0 is handled within the function. */
+ gnutls_assert();
+ return x;
+ }
+
+ /* Here we remove any ciphersuite that does not conform
+ * the certificate requested, or to the
+ * authentication requested (e.g. SRP).
+ */
+ x = _gnutls_remove_unwanted_ciphersuites(session, &ciphers, x,
+ pk_algo);
+ if (x <= 0) {
+ gnutls_assert();
+ gnutls_free(ciphers);
+ if (x < 0)
+ return x;
+ else
+ return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
+ }
+
+ /* Data length should be zero mod 2 since
+ * every ciphersuite is 2 bytes. (this check is needed
+ * see below).
+ */
+ if (datalen % 2 != 0) {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ }
#ifdef HANDSHAKE_DEBUG
- _gnutls_handshake_log("HSK[%x]: Requested cipher suites: \n", session);
- for (j = 0; j < datalen; j += 2) {
- memcpy( &cs.suite, &data[j], 2);
- _gnutls_handshake_log("\t%s\n",
- _gnutls_cipher_suite_get_name(&cs));
- }
- _gnutls_handshake_log("HSK[%x]: Supported cipher suites: \n", session);
- for (j = 0; j < x; j++)
- _gnutls_handshake_log("\t%s\n",
- _gnutls_cipher_suite_get_name(&ciphers[j]));
+ _gnutls_handshake_log("HSK[%x]: Requested cipher suites: \n", session);
+ for (j = 0; j < datalen; j += 2) {
+ memcpy(&cs.suite, &data[j], 2);
+ _gnutls_handshake_log("\t%s\n",
+ _gnutls_cipher_suite_get_name(&cs));
+ }
+ _gnutls_handshake_log("HSK[%x]: Supported cipher suites: \n", session);
+ for (j = 0; j < x; j++)
+ _gnutls_handshake_log("\t%s\n",
+ _gnutls_cipher_suite_get_name(&ciphers[j]));
#endif
- memset(session->security_parameters.current_cipher_suite.suite, '\0', 2);
-
- retval = GNUTLS_E_UNKNOWN_CIPHER_SUITE;
-
- for (j = 0; j < datalen; j += 2) {
- for (i = 0; i < x; i++) {
- if (memcmp(ciphers[i].suite, &data[j], 2) ==
- 0) {
- memcpy( &cs.suite, &data[j], 2);
-
- _gnutls_handshake_log("HSK[%x]: Selected cipher suite: %s\n",
- session, _gnutls_cipher_suite_get_name(&cs));
- memcpy(session->security_parameters.current_cipher_suite.suite, ciphers[i].suite, 2);
- retval = 0;
- goto finish;
- }
- }
- }
-
- finish:
- gnutls_free(ciphers);
-
- if (retval != 0) {
- gnutls_assert();
- return retval;
- }
-
- /* check if the credentials (username, public key etc.) are ok
- */
- if (_gnutls_get_kx_cred
- (session, _gnutls_cipher_suite_get_kx_algo(&session->security_parameters.
- current_cipher_suite),
- &err) == NULL && err != 0) {
- gnutls_assert();
- return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
- }
+ memset(session->security_parameters.current_cipher_suite.suite, '\0',
+ 2);
+ retval = GNUTLS_E_UNKNOWN_CIPHER_SUITE;
- /* set the mod_auth_st to the appropriate struct
- * according to the KX algorithm. This is needed since all the
- * handshake functions are read from there;
- */
- session->internals.auth_struct =
- _gnutls_kx_auth_struct(_gnutls_cipher_suite_get_kx_algo
- (&session->security_parameters.
- current_cipher_suite));
- if (session->internals.auth_struct == NULL) {
+ for (j = 0; j < datalen; j += 2) {
+ for (i = 0; i < x; i++) {
+ if (memcmp(ciphers[i].suite, &data[j], 2) == 0) {
+ memcpy(&cs.suite, &data[j], 2);
_gnutls_handshake_log
- ("HSK[%x]: Cannot find the appropriate handler for the KX algorithm\n", session);
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
+ ("HSK[%x]: Selected cipher suite: %s\n", session,
+ _gnutls_cipher_suite_get_name(&cs));
+ memcpy(session->security_parameters.current_cipher_suite.
+ suite, ciphers[i].suite, 2);
+ retval = 0;
+ goto finish;
+ }
}
+ }
- return 0;
+ finish:
+ gnutls_free(ciphers);
+
+ if (retval != 0) {
+ gnutls_assert();
+ return retval;
+ }
+
+ /* check if the credentials (username, public key etc.) are ok
+ */
+ if (_gnutls_get_kx_cred
+ (session,
+ _gnutls_cipher_suite_get_kx_algo(&session->security_parameters.
+ current_cipher_suite),
+ &err) == NULL && err != 0) {
+ gnutls_assert();
+ return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
+ }
+
+
+ /* set the mod_auth_st to the appropriate struct
+ * according to the KX algorithm. This is needed since all the
+ * handshake functions are read from there;
+ */
+ session->internals.auth_struct =
+ _gnutls_kx_auth_struct(_gnutls_cipher_suite_get_kx_algo
+ (&session->security_parameters.
+ current_cipher_suite));
+ if (session->internals.auth_struct == NULL) {
+
+ _gnutls_handshake_log
+ ("HSK[%x]: Cannot find the appropriate handler for the KX algorithm\n",
+ session);
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+
+ return 0;
}
/* This selects the best supported compression method from the ones provided
*/
-int _gnutls_server_select_comp_method(gnutls_session session, opaque * data,
- int datalen)
+int _gnutls_server_select_comp_method(gnutls_session session,
+ opaque * data, int datalen)
{
- int x, i, j;
- uint8 *comps;
+ int x, i, j;
+ uint8 *comps;
- x = _gnutls_supported_compression_methods(session, &comps);
- if (x < 0) {
- gnutls_assert();
- return x;
- }
+ x = _gnutls_supported_compression_methods(session, &comps);
+ if (x < 0) {
+ gnutls_assert();
+ return x;
+ }
- memset( &session->internals.compression_method, 0, sizeof(gnutls_compression_method));
+ memset(&session->internals.compression_method, 0,
+ sizeof(gnutls_compression_method));
- for (j = 0; j < datalen; j++) {
- for (i = 0; i < x; i++) {
- if (comps[i] == data[j]) {
- gnutls_compression_method method =
- _gnutls_compression_get_id(comps[i]);
+ for (j = 0; j < datalen; j++) {
+ for (i = 0; i < x; i++) {
+ if (comps[i] == data[j]) {
+ gnutls_compression_method method =
+ _gnutls_compression_get_id(comps[i]);
- session->internals.compression_method = method;
- gnutls_free(comps);
+ session->internals.compression_method = method;
+ gnutls_free(comps);
- _gnutls_handshake_log("HSK[%x]: Selected Compression Method: %s\n",
- session, gnutls_compression_get_name(session->internals.
- compression_method));
+ _gnutls_handshake_log
+ ("HSK[%x]: Selected Compression Method: %s\n", session,
+ gnutls_compression_get_name(session->internals.
+ compression_method));
- return 0;
- }
- }
+ return 0;
+ }
}
+ }
- /* we were not able to find a compatible compression
- * algorithm
- */
- gnutls_free(comps);
- gnutls_assert();
- return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
+ /* we were not able to find a compatible compression
+ * algorithm
+ */
+ gnutls_free(comps);
+ gnutls_assert();
+ return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
}
@@ -701,39 +725,43 @@ int _gnutls_server_select_comp_method(gnutls_session session, opaque * data,
* GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, then it must be called again
* (until it returns ok), with NULL parameters.
*/
-int _gnutls_send_empty_handshake(gnutls_session session, HandshakeType type,
- int again)
+int _gnutls_send_empty_handshake(gnutls_session session,
+ HandshakeType type, int again)
{
- opaque data = 0;
- opaque *ptr;
+ opaque data = 0;
+ opaque *ptr;
- if (again == 0)
- ptr = &data;
- else
- ptr = NULL;
+ if (again == 0)
+ ptr = &data;
+ else
+ ptr = NULL;
- return _gnutls_send_handshake(session, ptr, 0, type);
+ return _gnutls_send_handshake(session, ptr, 0, type);
}
/* This function will hash the handshake message we sent.
*/
static
-int _gnutls_handshake_hash_add_sent( gnutls_session session, HandshakeType type,
- opaque* dataptr, uint32 datalen) {
-int ret;
+int _gnutls_handshake_hash_add_sent(gnutls_session session,
+ HandshakeType type, opaque * dataptr,
+ uint32 datalen)
+{
+ int ret;
- if ( (ret=_gnutls_handshake_hash_pending( session)) < 0) {
- gnutls_assert();
- return ret;
- }
+ if ((ret = _gnutls_handshake_hash_pending(session)) < 0) {
+ gnutls_assert();
+ return ret;
+ }
- if ( type != GNUTLS_HELLO_REQUEST) {
- _gnutls_hash( session->internals.handshake_mac_handle_sha, dataptr, datalen);
- _gnutls_hash( session->internals.handshake_mac_handle_md5, dataptr, datalen);
- }
+ if (type != GNUTLS_HELLO_REQUEST) {
+ _gnutls_hash(session->internals.handshake_mac_handle_sha, dataptr,
+ datalen);
+ _gnutls_hash(session->internals.handshake_mac_handle_md5, dataptr,
+ datalen);
+ }
- return 0;
+ return 0;
}
@@ -745,62 +773,64 @@ int ret;
int _gnutls_send_handshake(gnutls_session session, void *i_data,
uint32 i_datasize, HandshakeType type)
{
- int ret;
- uint8 *data;
- uint32 datasize;
- int pos = 0;
-
- if (i_data == NULL && i_datasize == 0) {
- /* we are resuming a previously interrupted
- * send.
- */
- ret = _gnutls_handshake_io_write_flush(session);
- return ret;
+ int ret;
+ uint8 *data;
+ uint32 datasize;
+ int pos = 0;
+
+ if (i_data == NULL && i_datasize == 0) {
+ /* we are resuming a previously interrupted
+ * send.
+ */
+ ret = _gnutls_handshake_io_write_flush(session);
+ return ret;
- }
+ }
- if (i_data == NULL && i_datasize > 0) {
- gnutls_assert();
- return GNUTLS_E_INVALID_REQUEST;
- }
+ if (i_data == NULL && i_datasize > 0) {
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
- /* first run */
- datasize = i_datasize + HANDSHAKE_HEADER_SIZE;
- data = gnutls_alloca(datasize);
- if (data == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
+ /* first run */
+ datasize = i_datasize + HANDSHAKE_HEADER_SIZE;
+ data = gnutls_alloca(datasize);
+ if (data == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
- data[pos++] = (uint8) type;
- _gnutls_write_uint24(i_datasize, &data[pos]);
- pos += 3;
+ data[pos++] = (uint8) type;
+ _gnutls_write_uint24(i_datasize, &data[pos]);
+ pos += 3;
- if (i_datasize > 0)
- memcpy(&data[pos], i_data, i_datasize);
+ if (i_datasize > 0)
+ memcpy(&data[pos], i_data, i_datasize);
- _gnutls_handshake_log("HSK[%x]: %s was send [%ld bytes]\n",
- session, _gnutls_handshake2str(type), datasize);
+ _gnutls_handshake_log("HSK[%x]: %s was send [%ld bytes]\n",
+ session, _gnutls_handshake2str(type), datasize);
- /* Here we keep the handshake messages in order to hash them...
- */
- if ( type != GNUTLS_HELLO_REQUEST)
- if ( (ret= _gnutls_handshake_hash_add_sent( session, type, data, datasize)) < 0) {
- gnutls_assert();
- gnutls_afree(data);
- return ret;
- }
+ /* Here we keep the handshake messages in order to hash them...
+ */
+ if (type != GNUTLS_HELLO_REQUEST)
+ if ((ret =
+ _gnutls_handshake_hash_add_sent(session, type, data,
+ datasize)) < 0) {
+ gnutls_assert();
+ gnutls_afree(data);
+ return ret;
+ }
- session->internals.last_handshake_out = type;
+ session->internals.last_handshake_out = type;
- ret =
- _gnutls_handshake_io_send_int(session, GNUTLS_HANDSHAKE, type,
- data, datasize);
+ ret =
+ _gnutls_handshake_io_send_int(session, GNUTLS_HANDSHAKE, type,
+ data, datasize);
- gnutls_afree(data);
+ gnutls_afree(data);
- return ret;
+ return ret;
}
/* This function will read the handshake header and return it to the caller. If the
@@ -814,127 +844,117 @@ static int _gnutls_recv_handshake_header(gnutls_session session,
HandshakeType type,
HandshakeType * recv_type)
{
- int ret;
- uint32 length32 = 0;
- uint8 *dataptr = NULL; /* for realloc */
- size_t handshake_header_size = HANDSHAKE_HEADER_SIZE;
-
- /* if we have data into the buffer then return them, do not read the next packet.
- * In order to return we need a full TLS handshake header, or in case of a version 2
- * packet, then we return the first byte.
- */
- if (session->internals.handshake_header_buffer.header_size ==
- handshake_header_size || (session->internals.v2_hello != 0
- && type == GNUTLS_CLIENT_HELLO
- && session->internals.
- handshake_header_buffer.
- packet_length > 0)) {
-
- *recv_type =
- session->internals.handshake_header_buffer.
- recv_type;
-
- return session->internals.handshake_header_buffer.
- packet_length;
- }
-
- /* Note: SSL2_HEADERS == 1 */
+ int ret;
+ uint32 length32 = 0;
+ uint8 *dataptr = NULL; /* for realloc */
+ size_t handshake_header_size = HANDSHAKE_HEADER_SIZE;
+
+ /* if we have data into the buffer then return them, do not read the next packet.
+ * In order to return we need a full TLS handshake header, or in case of a version 2
+ * packet, then we return the first byte.
+ */
+ if (session->internals.handshake_header_buffer.header_size ==
+ handshake_header_size || (session->internals.v2_hello != 0
+ && type == GNUTLS_CLIENT_HELLO
+ && session->internals.
+ handshake_header_buffer.
+ packet_length > 0)) {
+
+ *recv_type = session->internals.handshake_header_buffer.recv_type;
+
+ return session->internals.handshake_header_buffer.packet_length;
+ }
+
+ /* Note: SSL2_HEADERS == 1 */
+
+ dataptr = session->internals.handshake_header_buffer.header;
+
+ /* If we haven't already read the handshake headers.
+ */
+ if (session->internals.handshake_header_buffer.header_size <
+ SSL2_HEADERS) {
+ ret =
+ _gnutls_handshake_io_recv_int(session, GNUTLS_HANDSHAKE,
+ type, dataptr, SSL2_HEADERS);
- dataptr = session->internals.handshake_header_buffer.header;
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
- /* If we haven't already read the handshake headers.
+ /* The case ret==0 is caught here.
*/
- if (session->internals.handshake_header_buffer.header_size <
- SSL2_HEADERS) {
- ret =
- _gnutls_handshake_io_recv_int(session, GNUTLS_HANDSHAKE,
- type, dataptr,
- SSL2_HEADERS);
-
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
-
- /* The case ret==0 is caught here.
- */
- if (ret != SSL2_HEADERS) {
- gnutls_assert();
- return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
- }
- session->internals.handshake_header_buffer.
- header_size = SSL2_HEADERS;
+ if (ret != SSL2_HEADERS) {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
+ session->internals.handshake_header_buffer.
+ header_size = SSL2_HEADERS;
+ }
- if (session->internals.v2_hello == 0
- || type != GNUTLS_CLIENT_HELLO) {
- ret =
- _gnutls_handshake_io_recv_int(session, GNUTLS_HANDSHAKE,
- type,
- &dataptr[session->
- internals.
- handshake_header_buffer.
- header_size],
- HANDSHAKE_HEADER_SIZE -
- session->internals.
- handshake_header_buffer.
- header_size);
- if (ret <= 0) {
- gnutls_assert();
- return (ret <
- 0) ? ret :
- GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
- }
- if ((size_t)ret !=
- HANDSHAKE_HEADER_SIZE -
- session->internals.handshake_header_buffer.
- header_size) {
- gnutls_assert();
- return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
- }
- *recv_type = dataptr[0];
-
- /* we do not use DECR_LEN because we know
- * that the packet has enough data.
- */
- length32 = _gnutls_read_uint24(&dataptr[1]);
- handshake_header_size = HANDSHAKE_HEADER_SIZE;
+ if (session->internals.v2_hello == 0 || type != GNUTLS_CLIENT_HELLO) {
+ ret =
+ _gnutls_handshake_io_recv_int(session, GNUTLS_HANDSHAKE,
+ type,
+ &dataptr[session->
+ internals.
+ handshake_header_buffer.
+ header_size],
+ HANDSHAKE_HEADER_SIZE -
+ session->internals.
+ handshake_header_buffer.
+ header_size);
+ if (ret <= 0) {
+ gnutls_assert();
+ return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ }
+ if ((size_t) ret !=
+ HANDSHAKE_HEADER_SIZE -
+ session->internals.handshake_header_buffer.header_size) {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ }
+ *recv_type = dataptr[0];
+
+ /* we do not use DECR_LEN because we know
+ * that the packet has enough data.
+ */
+ length32 = _gnutls_read_uint24(&dataptr[1]);
+ handshake_header_size = HANDSHAKE_HEADER_SIZE;
- _gnutls_handshake_log("HSK[%x]: %s was received [%ld bytes]\n",
- session, _gnutls_handshake2str(dataptr[0]),
- length32 + HANDSHAKE_HEADER_SIZE);
+ _gnutls_handshake_log("HSK[%x]: %s was received [%ld bytes]\n",
+ session, _gnutls_handshake2str(dataptr[0]),
+ length32 + HANDSHAKE_HEADER_SIZE);
- } else { /* v2 hello */
- length32 = session->internals.v2_hello - SSL2_HEADERS; /* we've read the first byte */
+ } else { /* v2 hello */
+ length32 = session->internals.v2_hello - SSL2_HEADERS; /* we've read the first byte */
- handshake_header_size = SSL2_HEADERS; /* we've already read one byte */
+ handshake_header_size = SSL2_HEADERS; /* we've already read one byte */
- *recv_type = dataptr[0];
+ *recv_type = dataptr[0];
- _gnutls_handshake_log("HSK[%x]: %s(v2) was received [%ld bytes]\n",
- session, _gnutls_handshake2str(*recv_type),
- length32 + handshake_header_size);
+ _gnutls_handshake_log("HSK[%x]: %s(v2) was received [%ld bytes]\n",
+ session, _gnutls_handshake2str(*recv_type),
+ length32 + handshake_header_size);
- if (*recv_type != GNUTLS_CLIENT_HELLO) { /* it should be one or nothing */
- gnutls_assert();
- return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
- }
+ if (*recv_type != GNUTLS_CLIENT_HELLO) { /* it should be one or nothing */
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
}
+ }
- /* put the packet into the buffer */
- session->internals.handshake_header_buffer.header_size =
- handshake_header_size;
- session->internals.handshake_header_buffer.packet_length =
- length32;
- session->internals.handshake_header_buffer.recv_type =
- *recv_type;
+ /* put the packet into the buffer */
+ session->internals.handshake_header_buffer.header_size =
+ handshake_header_size;
+ session->internals.handshake_header_buffer.packet_length = length32;
+ session->internals.handshake_header_buffer.recv_type = *recv_type;
- if (*recv_type != type) {
- gnutls_assert();
- return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
- }
+ if (*recv_type != type) {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
+ }
- return length32;
+ return length32;
}
#define _gnutls_handshake_header_buffer_clear( session) session->internals.handshake_header_buffer.header_size = 0
@@ -945,40 +965,43 @@ static int _gnutls_recv_handshake_header(gnutls_session session,
* handshake data.
*/
static
-int _gnutls_handshake_hash_add_recvd( gnutls_session session, HandshakeType recv_type,
- opaque* header, uint16 header_size, opaque* dataptr, uint32 datalen) {
-int ret;
+int _gnutls_handshake_hash_add_recvd(gnutls_session session,
+ HandshakeType recv_type,
+ opaque * header, uint16 header_size,
+ opaque * dataptr, uint32 datalen)
+{
+ int ret;
- /* The idea here is to hash the previous message we received,
- * and add the one we just received into the handshake_hash_buffer.
- */
-
- if ( (ret=_gnutls_handshake_hash_pending( session)) < 0) {
- gnutls_assert();
- return ret;
+ /* The idea here is to hash the previous message we received,
+ * and add the one we just received into the handshake_hash_buffer.
+ */
+
+ if ((ret = _gnutls_handshake_hash_pending(session)) < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ /* here we buffer the handshake messages - needed at Finished message */
+ if (recv_type != GNUTLS_HELLO_REQUEST) {
+
+ if ((ret =
+ _gnutls_handshake_buffer_put(session,
+ header, header_size)) < 0) {
+ gnutls_assert();
+ return ret;
}
-
- /* here we buffer the handshake messages - needed at Finished message */
- if ( recv_type != GNUTLS_HELLO_REQUEST) {
-
- if ((ret =
- _gnutls_handshake_buffer_put(session,
- header, header_size)) < 0) {
- gnutls_assert();
- return ret;
- }
- if ( datalen > 0) {
- if ((ret =
- _gnutls_handshake_buffer_put(session, dataptr,
- datalen)) < 0) {
- gnutls_assert();
- return ret;
- }
- }
+ if (datalen > 0) {
+ if ((ret =
+ _gnutls_handshake_buffer_put(session, dataptr,
+ datalen)) < 0) {
+ gnutls_assert();
+ return ret;
+ }
}
+ }
- return 0;
+ return 0;
}
@@ -991,118 +1014,121 @@ int _gnutls_recv_handshake(gnutls_session session, uint8 ** data,
int *datalen, HandshakeType type,
Optional optional)
{
- int ret;
- uint32 length32 = 0;
- opaque *dataptr = NULL;
- HandshakeType recv_type;
-
- ret = _gnutls_recv_handshake_header(session, type, &recv_type);
- if (ret < 0) {
+ int ret;
+ uint32 length32 = 0;
+ opaque *dataptr = NULL;
+ HandshakeType recv_type;
- /* 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_SERVER_HELLO)
- {
- gnutls_assert();
- return GNUTLS_E_INT_HANDSHAKE_AGAIN;
- }
-
- if (ret == GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET
- && optional == OPTIONAL_PACKET) {
- if (datalen != NULL)
- *datalen = 0;
- if (data != NULL)
- *data = NULL;
- return 0; /* ok just ignore the packet */
- }
-
- return ret;
- }
+ ret = _gnutls_recv_handshake_header(session, type, &recv_type);
+ if (ret < 0) {
- session->internals.last_handshake_in = recv_type;
-
- length32 = ret;
-
- if (length32 > 0)
- dataptr = gnutls_malloc(length32);
- else if (recv_type != GNUTLS_SERVER_HELLO_DONE) {
- gnutls_assert();
- return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ /* 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_SERVER_HELLO) {
+ gnutls_assert();
+ return GNUTLS_E_INT_HANDSHAKE_AGAIN;
}
- if (dataptr == NULL && length32 > 0) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
+ if (ret == GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET
+ && optional == OPTIONAL_PACKET) {
+ if (datalen != NULL)
+ *datalen = 0;
+ if (data != NULL)
+ *data = NULL;
+ return 0; /* ok just ignore the packet */
}
- if (datalen != NULL)
- *datalen = length32;
-
- if (length32 > 0) {
- ret =
- _gnutls_handshake_io_recv_int(session, GNUTLS_HANDSHAKE,
- type, dataptr, length32);
- if (ret <= 0) {
- gnutls_assert();
- gnutls_free(dataptr);
- return (ret ==
- 0) ? GNUTLS_E_UNEXPECTED_PACKET_LENGTH :
- ret;
- }
- }
+ return ret;
+ }
- if (data != NULL && length32 > 0)
- *data = dataptr;
+ session->internals.last_handshake_in = recv_type;
+ length32 = ret;
- ret = _gnutls_handshake_hash_add_recvd( session, recv_type,
- session->internals.handshake_header_buffer.header,
- session->internals.handshake_header_buffer.header_size,
- dataptr, length32);
- if (ret < 0) {
- gnutls_assert();
- _gnutls_handshake_header_buffer_clear(session);
- return ret;
- }
+ if (length32 > 0)
+ dataptr = gnutls_malloc(length32);
+ else if (recv_type != GNUTLS_SERVER_HELLO_DONE) {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ }
- /* If we fail before this then we will reuse the handshake header
- * have have received above. if we get here the we clear the handshake
- * header we received.
- */
- _gnutls_handshake_header_buffer_clear(session);
+ if (dataptr == NULL && length32 > 0) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
- switch (recv_type) {
- case GNUTLS_CLIENT_HELLO:
- case GNUTLS_SERVER_HELLO:
- ret = _gnutls_recv_hello(session, dataptr, length32);
- /* dataptr is freed because the caller does not
- * need it */
- gnutls_free(dataptr);
- if (data!=NULL) *data = NULL;
- break;
- case GNUTLS_SERVER_HELLO_DONE:
- if (length32==0) ret = 0;
- else ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
- break;
- case GNUTLS_CERTIFICATE_PKT:
- case GNUTLS_FINISHED:
- case GNUTLS_SERVER_KEY_EXCHANGE:
- case GNUTLS_CLIENT_KEY_EXCHANGE:
- case GNUTLS_CERTIFICATE_REQUEST:
- case GNUTLS_CERTIFICATE_VERIFY:
- ret = length32;
- break;
- default:
- gnutls_assert();
- gnutls_free(dataptr);
- if (data!=NULL) *data = NULL;
- ret = GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
- }
+ if (datalen != NULL)
+ *datalen = length32;
+ if (length32 > 0) {
+ ret =
+ _gnutls_handshake_io_recv_int(session, GNUTLS_HANDSHAKE,
+ type, dataptr, length32);
+ if (ret <= 0) {
+ gnutls_assert();
+ gnutls_free(dataptr);
+ return (ret == 0) ? GNUTLS_E_UNEXPECTED_PACKET_LENGTH : ret;
+ }
+ }
+
+ if (data != NULL && length32 > 0)
+ *data = dataptr;
+
+
+ ret = _gnutls_handshake_hash_add_recvd(session, recv_type,
+ session->internals.
+ handshake_header_buffer.header,
+ session->internals.
+ handshake_header_buffer.
+ header_size, dataptr, length32);
+ if (ret < 0) {
+ gnutls_assert();
+ _gnutls_handshake_header_buffer_clear(session);
return ret;
+ }
+
+ /* If we fail before this then we will reuse the handshake header
+ * have have received above. if we get here the we clear the handshake
+ * header we received.
+ */
+ _gnutls_handshake_header_buffer_clear(session);
+
+ switch (recv_type) {
+ case GNUTLS_CLIENT_HELLO:
+ case GNUTLS_SERVER_HELLO:
+ ret = _gnutls_recv_hello(session, dataptr, length32);
+ /* dataptr is freed because the caller does not
+ * need it */
+ gnutls_free(dataptr);
+ if (data != NULL)
+ *data = NULL;
+ break;
+ case GNUTLS_SERVER_HELLO_DONE:
+ if (length32 == 0)
+ ret = 0;
+ else
+ ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ break;
+ case GNUTLS_CERTIFICATE_PKT:
+ case GNUTLS_FINISHED:
+ case GNUTLS_SERVER_KEY_EXCHANGE:
+ case GNUTLS_CLIENT_KEY_EXCHANGE:
+ case GNUTLS_CERTIFICATE_REQUEST:
+ case GNUTLS_CERTIFICATE_VERIFY:
+ ret = length32;
+ break;
+ default:
+ gnutls_assert();
+ gnutls_free(dataptr);
+ if (data != NULL)
+ *data = NULL;
+ ret = GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
+ }
+
+ return ret;
}
/* This function checks if the given cipher suite is supported, and sets it
@@ -1111,72 +1137,75 @@ int _gnutls_recv_handshake(gnutls_session session, uint8 ** data,
static int _gnutls_client_set_ciphersuite(gnutls_session session,
opaque suite[2])
{
- uint8 z;
- cipher_suite_st *cipher_suites;
- int cipher_suite_num;
- int i, err;
-
- z = 1;
- cipher_suite_num = _gnutls_supported_ciphersuites(session, &cipher_suites);
- if (cipher_suite_num < 0) {
- gnutls_assert();
- return cipher_suite_num;
- }
-
- for (i = 0; i < cipher_suite_num; i++) {
- if (memcmp(&cipher_suites[i], suite, 2) == 0) {
- z = 0; break;
- }
- }
-
- gnutls_free(cipher_suites);
+ uint8 z;
+ cipher_suite_st *cipher_suites;
+ int cipher_suite_num;
+ int i, err;
+
+ z = 1;
+ cipher_suite_num =
+ _gnutls_supported_ciphersuites(session, &cipher_suites);
+ if (cipher_suite_num < 0) {
+ gnutls_assert();
+ return cipher_suite_num;
+ }
- if (z != 0) {
- gnutls_assert();
- return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
+ for (i = 0; i < cipher_suite_num; i++) {
+ if (memcmp(&cipher_suites[i], suite, 2) == 0) {
+ z = 0;
+ break;
}
+ }
- memcpy(session->security_parameters.
- current_cipher_suite.suite, suite, 2);
-
- _gnutls_handshake_log("HSK[%x]: Selected cipher suite: %s\n", session,
- _gnutls_cipher_suite_get_name(&session->
- security_parameters.
- current_cipher_suite));
+ gnutls_free(cipher_suites);
-
- /* check if the credentials (username, public key etc.) are ok.
- * Actually checks if they exist.
- */
- if (_gnutls_get_kx_cred
- (session, _gnutls_cipher_suite_get_kx_algo(&session->
- security_parameters.
- current_cipher_suite),
- &err) == NULL && err != 0) {
- gnutls_assert();
- return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
- }
+ if (z != 0) {
+ gnutls_assert();
+ return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
+ }
+
+ memcpy(session->security_parameters.
+ current_cipher_suite.suite, suite, 2);
+
+ _gnutls_handshake_log("HSK[%x]: Selected cipher suite: %s\n", session,
+ _gnutls_cipher_suite_get_name(&session->
+ security_parameters.
+ current_cipher_suite));
+
+
+ /* check if the credentials (username, public key etc.) are ok.
+ * Actually checks if they exist.
+ */
+ if (_gnutls_get_kx_cred
+ (session, _gnutls_cipher_suite_get_kx_algo(&session->
+ security_parameters.
+ current_cipher_suite),
+ &err) == NULL && err != 0) {
+ gnutls_assert();
+ return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
+ }
- /* set the mod_auth_st to the appropriate struct
- * according to the KX algorithm. This is needed since all the
- * handshake functions are read from there;
- */
- session->internals.auth_struct =
- _gnutls_kx_auth_struct(_gnutls_cipher_suite_get_kx_algo
- (&session->security_parameters.
- current_cipher_suite));
+ /* set the mod_auth_st to the appropriate struct
+ * according to the KX algorithm. This is needed since all the
+ * handshake functions are read from there;
+ */
+ session->internals.auth_struct =
+ _gnutls_kx_auth_struct(_gnutls_cipher_suite_get_kx_algo
+ (&session->security_parameters.
+ current_cipher_suite));
- if (session->internals.auth_struct == NULL) {
+ if (session->internals.auth_struct == NULL) {
- _gnutls_handshake_log
- ("HSK[%x]: Cannot find the appropriate handler for the KX algorithm\n", session);
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
- }
+ _gnutls_handshake_log
+ ("HSK[%x]: Cannot find the appropriate handler for the KX algorithm\n",
+ session);
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
- return 0;
+ return 0;
}
/* This function sets the given comp method to the session.
@@ -1184,35 +1213,36 @@ static int _gnutls_client_set_ciphersuite(gnutls_session session,
static int _gnutls_client_set_comp_method(gnutls_session session,
opaque comp_method)
{
- int comp_methods_num;
- uint8 *compression_methods;
- int i;
+ int comp_methods_num;
+ uint8 *compression_methods;
+ int i;
- comp_methods_num = _gnutls_supported_compression_methods(session,
- &compression_methods);
- if ( comp_methods_num < 0) {
- gnutls_assert();
- return comp_methods_num;
- }
-
- for (i = 0; i < comp_methods_num; i++) {
- if (compression_methods[i] == comp_method) {
- comp_methods_num = 0; break;
- }
+ comp_methods_num = _gnutls_supported_compression_methods(session,
+ &compression_methods);
+ if (comp_methods_num < 0) {
+ gnutls_assert();
+ return comp_methods_num;
+ }
+
+ for (i = 0; i < comp_methods_num; i++) {
+ if (compression_methods[i] == comp_method) {
+ comp_methods_num = 0;
+ break;
}
+ }
- gnutls_free(compression_methods);
+ gnutls_free(compression_methods);
- if (comp_methods_num != 0) {
- gnutls_assert();
- return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
- }
+ if (comp_methods_num != 0) {
+ gnutls_assert();
+ return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
+ }
- session->internals.compression_method =
- _gnutls_compression_get_id(comp_method);
+ session->internals.compression_method =
+ _gnutls_compression_get_id(comp_method);
- return 0;
+ return 0;
}
/* This function returns 0 if we are resuming a session or -1 otherwise.
@@ -1223,40 +1253,41 @@ static int _gnutls_client_check_if_resuming(gnutls_session session,
opaque * session_id,
int session_id_len)
{
-opaque buf[2*TLS_MAX_SESSION_ID_SIZE+1];
+ opaque buf[2 * TLS_MAX_SESSION_ID_SIZE + 1];
+
+ _gnutls_handshake_log("HSK[%x]: SessionID length: %d\n", session,
+ session_id_len);
+ _gnutls_handshake_log("HSK[%x]: SessionID: %s\n", session,
+ _gnutls_bin2hex(session_id, session_id_len, buf,
+ sizeof(buf)));
+
+ if ((session->internals.resumed_security_parameters.
+ session_id_size > 0)
+ && memcmp(session_id,
+ session->internals.
+ resumed_security_parameters.session_id,
+ session_id_len) == 0) {
+ /* resume session */
+ memcpy(session->internals.
+ resumed_security_parameters.server_random,
+ session->security_parameters.server_random,
+ TLS_RANDOM_SIZE);
+ memcpy(session->internals.
+ resumed_security_parameters.client_random,
+ session->security_parameters.client_random,
+ TLS_RANDOM_SIZE);
+ session->internals.resumed = RESUME_TRUE; /* we are resuming */
- _gnutls_handshake_log("HSK[%x]: SessionID length: %d\n", session, session_id_len);
- _gnutls_handshake_log("HSK[%x]: SessionID: %s\n", session,
- _gnutls_bin2hex(session_id, session_id_len, buf, sizeof(buf)));
-
- if ((session->internals.resumed_security_parameters.
- session_id_size > 0)
- && memcmp(session_id,
- session->internals.
- resumed_security_parameters.session_id,
- session_id_len) == 0) {
- /* resume session */
- memcpy(session->internals.
- resumed_security_parameters.server_random,
- session->security_parameters.server_random,
- TLS_RANDOM_SIZE);
- memcpy(session->internals.
- resumed_security_parameters.client_random,
- session->security_parameters.client_random,
- TLS_RANDOM_SIZE);
- session->internals.resumed = RESUME_TRUE; /* we are resuming */
+ return 0;
+ } else {
+ /* keep the new session id */
+ session->internals.resumed = RESUME_FALSE; /* we are not resuming */
+ session->security_parameters.session_id_size = session_id_len;
+ memcpy(session->security_parameters.session_id,
+ session_id, session_id_len);
- return 0;
- } else {
- /* keep the new session id */
- session->internals.resumed = RESUME_FALSE; /* we are not resuming */
- session->security_parameters.session_id_size =
- session_id_len;
- memcpy(session->security_parameters.session_id,
- session_id, session_id_len);
-
- return -1;
- }
+ return -1;
+ }
}
@@ -1264,94 +1295,94 @@ opaque buf[2*TLS_MAX_SESSION_ID_SIZE+1];
* This function also restores resumed parameters if we are resuming a
* session.
*/
-static int _gnutls_read_server_hello(gnutls_session session, opaque *data,
+static int _gnutls_read_server_hello(gnutls_session session, opaque * data,
int datalen)
{
- uint8 session_id_len = 0;
- int pos = 0;
- int ret = 0;
- gnutls_protocol_version version;
- int len = datalen;
+ uint8 session_id_len = 0;
+ int pos = 0;
+ int ret = 0;
+ gnutls_protocol_version version;
+ int len = datalen;
- if (datalen < 38) {
- gnutls_assert();
- return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
- }
+ if (datalen < 38) {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ }
- _gnutls_handshake_log("HSK[%x]: Server's version: %d.%d\n",
- session, data[pos], data[pos + 1]);
+ _gnutls_handshake_log("HSK[%x]: Server's version: %d.%d\n",
+ session, data[pos], data[pos + 1]);
- DECR_LEN(len, 2);
- version = _gnutls_version_get(data[pos], data[pos + 1]);
- if (_gnutls_version_is_supported(session, version) == 0) {
- gnutls_assert();
- return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
- } else {
- _gnutls_set_current_version(session, version);
- }
+ DECR_LEN(len, 2);
+ version = _gnutls_version_get(data[pos], data[pos + 1]);
+ if (_gnutls_version_is_supported(session, version) == 0) {
+ gnutls_assert();
+ return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
+ } else {
+ _gnutls_set_current_version(session, version);
+ }
- pos += 2;
+ pos += 2;
- DECR_LEN(len, TLS_RANDOM_SIZE);
- _gnutls_set_server_random(session, &data[pos]);
- pos += TLS_RANDOM_SIZE;
+ DECR_LEN(len, TLS_RANDOM_SIZE);
+ _gnutls_set_server_random(session, &data[pos]);
+ pos += TLS_RANDOM_SIZE;
- /* Read session ID
- */
- DECR_LEN(len, 1);
- session_id_len = data[pos++];
+ /* Read session ID
+ */
+ DECR_LEN(len, 1);
+ session_id_len = data[pos++];
- if (len < session_id_len) {
- gnutls_assert();
- return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
- }
- DECR_LEN(len, session_id_len);
+ if (len < session_id_len) {
+ gnutls_assert();
+ return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
+ }
+ DECR_LEN(len, session_id_len);
- /* check if we are resuming and set the appropriate
- * values;
- */
- if (_gnutls_client_check_if_resuming
- (session, &data[pos], session_id_len) == 0)
- return 0;
- pos += session_id_len;
+ /* check if we are resuming and set the appropriate
+ * values;
+ */
+ if (_gnutls_client_check_if_resuming
+ (session, &data[pos], session_id_len) == 0)
+ return 0;
+ pos += session_id_len;
- /* Check if the given cipher suite is supported and copy
- * it to the session.
- */
+ /* Check if the given cipher suite is supported and copy
+ * it to the session.
+ */
- DECR_LEN(len, 2);
- ret = _gnutls_client_set_ciphersuite(session, &data[pos]);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
- pos += 2;
+ DECR_LEN(len, 2);
+ ret = _gnutls_client_set_ciphersuite(session, &data[pos]);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ pos += 2;
- /* move to compression
- */
- DECR_LEN(len, 1);
+ /* move to compression
+ */
+ DECR_LEN(len, 1);
- ret = _gnutls_client_set_comp_method(session, data[pos++]);
- if (ret < 0) {
- gnutls_assert();
- return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
- }
+ ret = _gnutls_client_set_comp_method(session, data[pos++]);
+ if (ret < 0) {
+ gnutls_assert();
+ return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
+ }
- /* Parse extensions.
- */
- if (version >= GNUTLS_TLS1) {
- ret = _gnutls_parse_extensions(session, &data[pos], len); /* len is the rest of the parsed length */
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
+ /* Parse extensions.
+ */
+ if (version >= GNUTLS_TLS1) {
+ ret = _gnutls_parse_extensions(session, &data[pos], len); /* len is the rest of the parsed length */
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
}
- return ret;
+ }
+ return ret;
}
@@ -1359,63 +1390,64 @@ static int _gnutls_read_server_hello(gnutls_session session, opaque *data,
* Needed in client hello messages. Returns the new data length.
*/
static int _gnutls_copy_ciphersuites(gnutls_session session,
- opaque * ret_data, size_t ret_data_size)
+ opaque * ret_data,
+ size_t ret_data_size)
{
- int ret, i;
- cipher_suite_st *cipher_suites;
- uint16 cipher_num;
- int datalen, pos;
+ int ret, i;
+ cipher_suite_st *cipher_suites;
+ uint16 cipher_num;
+ int datalen, pos;
- ret = _gnutls_supported_ciphersuites_sorted(session, &cipher_suites);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
+ ret = _gnutls_supported_ciphersuites_sorted(session, &cipher_suites);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ /* Here we remove any ciphersuite that does not conform
+ * the certificate requested, or to the
+ * authentication requested (eg SRP).
+ */
+ ret =
+ _gnutls_remove_unwanted_ciphersuites(session, &cipher_suites,
+ ret, -1);
+ if (ret < 0) {
+ gnutls_assert();
+ gnutls_free(cipher_suites);
+ return ret;
+ }
- /* Here we remove any ciphersuite that does not conform
- * the certificate requested, or to the
- * authentication requested (eg SRP).
- */
- ret =
- _gnutls_remove_unwanted_ciphersuites(session, &cipher_suites,
- ret, -1);
- if (ret < 0) {
- gnutls_assert();
- gnutls_free(cipher_suites);
- return ret;
- }
+ /* If no cipher suites were enabled.
+ */
+ if (ret == 0) {
+ gnutls_assert();
+ gnutls_free(cipher_suites);
+ return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
+ }
- /* If no cipher suites were enabled.
- */
- if (ret == 0) {
- gnutls_assert();
- gnutls_free(cipher_suites);
- return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
- }
+ cipher_num = ret;
- cipher_num = ret;
-
- cipher_num *= sizeof(uint16); /* in order to get bytes */
-
- datalen = pos = 0;
+ cipher_num *= sizeof(uint16); /* in order to get bytes */
- datalen += sizeof(uint16) + cipher_num;
+ datalen = pos = 0;
- if ((size_t)datalen > ret_data_size) {
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
- }
-
- _gnutls_write_uint16(cipher_num, ret_data);
- pos += 2;
+ datalen += sizeof(uint16) + cipher_num;
- for (i = 0; i < (cipher_num / 2); i++) {
- memcpy( &ret_data[pos], cipher_suites[i].suite, 2);
- pos += 2;
- }
- gnutls_free(cipher_suites);
+ if ((size_t) datalen > ret_data_size) {
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+
+ _gnutls_write_uint16(cipher_num, ret_data);
+ pos += 2;
+
+ for (i = 0; i < (cipher_num / 2); i++) {
+ memcpy(&ret_data[pos], cipher_suites[i].suite, 2);
+ pos += 2;
+ }
+ gnutls_free(cipher_suites);
- return datalen;
+ return datalen;
}
@@ -1423,39 +1455,40 @@ static int _gnutls_copy_ciphersuites(gnutls_session session,
* Needed in hello messages. Returns the new data length.
*/
static int _gnutls_copy_comp_methods(gnutls_session session,
- opaque * ret_data, size_t ret_data_size)
+ opaque * ret_data,
+ size_t ret_data_size)
{
- int ret, i;
- uint8 *compression_methods, comp_num;
- int datalen, pos;
-
- ret =
- _gnutls_supported_compression_methods(session,
- &compression_methods);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
+ int ret, i;
+ uint8 *compression_methods, comp_num;
+ int datalen, pos;
+
+ ret =
+ _gnutls_supported_compression_methods(session,
+ &compression_methods);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
- comp_num = ret;
+ comp_num = ret;
- datalen = pos = 0;
- datalen += comp_num + 1;
+ datalen = pos = 0;
+ datalen += comp_num + 1;
- if ((size_t)datalen > ret_data_size) {
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
- }
+ if ((size_t) datalen > ret_data_size) {
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
- ret_data[pos++] = comp_num; /* put the number of compression methods */
+ ret_data[pos++] = comp_num; /* put the number of compression methods */
- for (i = 0; i < comp_num; i++) {
- ret_data[pos++] = compression_methods[i];
- }
+ for (i = 0; i < comp_num; i++) {
+ ret_data[pos++] = compression_methods[i];
+ }
- gnutls_free(compression_methods);
+ gnutls_free(compression_methods);
- return datalen;
+ return datalen;
}
/* This should be sufficient by now. It should hold all the extensions
@@ -1467,312 +1500,313 @@ static int _gnutls_copy_comp_methods(gnutls_session session,
*/
static int _gnutls_send_client_hello(gnutls_session session, int again)
{
- opaque *data = NULL;
- int extdatalen;
- int pos = 0;
- int datalen = 0, ret = 0;
- opaque random[TLS_RANDOM_SIZE];
- gnutls_protocol_version hver;
- opaque extdata[MAX_EXT_DATA_LENGTH];
-
- opaque *SessionID =
- session->internals.resumed_security_parameters.session_id;
- uint8 session_id_len =
- session->internals.resumed_security_parameters.
- session_id_size;
-
- if (SessionID == NULL) session_id_len = 0;
- else if (session_id_len == 0) SessionID = NULL;
-
- if (again == 0) {
-
- datalen = 2 + (session_id_len + 1) + TLS_RANDOM_SIZE;
- /* 2 for version, (4 for unix time + 28 for random bytes==TLS_RANDOM_SIZE)
- */
-
- data = gnutls_malloc(datalen);
- if (data == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
+ opaque *data = NULL;
+ int extdatalen;
+ int pos = 0;
+ int datalen = 0, ret = 0;
+ opaque random[TLS_RANDOM_SIZE];
+ gnutls_protocol_version hver;
+ opaque extdata[MAX_EXT_DATA_LENGTH];
+
+ opaque *SessionID =
+ session->internals.resumed_security_parameters.session_id;
+ uint8 session_id_len =
+ session->internals.resumed_security_parameters.session_id_size;
+
+ if (SessionID == NULL)
+ session_id_len = 0;
+ else if (session_id_len == 0)
+ SessionID = NULL;
+
+ if (again == 0) {
+
+ datalen = 2 + (session_id_len + 1) + TLS_RANDOM_SIZE;
+ /* 2 for version, (4 for unix time + 28 for random bytes==TLS_RANDOM_SIZE)
+ */
- /* if we are resuming a session then we set the
- * version number to the previously established.
- */
- if (SessionID == NULL)
- hver = _gnutls_version_max(session);
- else { /* we are resuming a session */
- hver =
- session->internals.
- resumed_security_parameters.version;
- }
+ data = gnutls_malloc(datalen);
+ if (data == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
- if (hver == GNUTLS_VERSION_UNKNOWN || hver == 0) {
- gnutls_assert();
- gnutls_free(data);
- return GNUTLS_E_INTERNAL_ERROR;
- }
+ /* if we are resuming a session then we set the
+ * version number to the previously established.
+ */
+ if (SessionID == NULL)
+ hver = _gnutls_version_max(session);
+ else { /* we are resuming a session */
+ hver = session->internals.resumed_security_parameters.version;
+ }
- data[pos++] = _gnutls_version_get_major(hver);
- data[pos++] = _gnutls_version_get_minor(hver);
-
- /* Set the version we advertized as maximum
- * (RSA uses it).
- */
- _gnutls_set_adv_version( session, hver);
-
- /* Some old implementations do not interoperate if we send a
- * different version in the record layer.
- * It seems they prefer to read the record's version
- * as the one we actually requested.
- * The proper behaviour is to use the one in the client hello
- * handshake packet and ignore the one in the packet's record
- * header.
- */
- _gnutls_set_current_version(session, hver);
-
- /* In order to know when this session was initiated.
- */
- session->security_parameters.timestamp = time(NULL);
-
- /* Generate random data
- */
- _gnutls_tls_create_random(random);
- _gnutls_set_client_random(session, random);
-
- memcpy(&data[pos], random, TLS_RANDOM_SIZE);
- pos += TLS_RANDOM_SIZE;
-
- /* Copy the Session ID
- */
- data[pos++] = session_id_len;
-
- if (session_id_len > 0) {
- memcpy(&data[pos], SessionID, session_id_len);
- pos += session_id_len;
- }
+ if (hver == GNUTLS_VERSION_UNKNOWN || hver == 0) {
+ gnutls_assert();
+ gnutls_free(data);
+ return GNUTLS_E_INTERNAL_ERROR;
+ }
+ data[pos++] = _gnutls_version_get_major(hver);
+ data[pos++] = _gnutls_version_get_minor(hver);
- /* Copy the ciphersuites.
- */
- extdatalen = _gnutls_copy_ciphersuites(session, extdata, sizeof(extdata));
- if (extdatalen > 0) {
- datalen += extdatalen;
- data = gnutls_realloc_fast(data, datalen);
- if (data == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- memcpy(&data[pos], extdata, extdatalen);
- pos += extdatalen;
-
- } else {
- if (extdatalen == 0)
- extdatalen = GNUTLS_E_INTERNAL_ERROR;
- gnutls_free(data);
- gnutls_assert();
- return extdatalen;
- }
+ /* Set the version we advertized as maximum
+ * (RSA uses it).
+ */
+ _gnutls_set_adv_version(session, hver);
+
+ /* Some old implementations do not interoperate if we send a
+ * different version in the record layer.
+ * It seems they prefer to read the record's version
+ * as the one we actually requested.
+ * The proper behaviour is to use the one in the client hello
+ * handshake packet and ignore the one in the packet's record
+ * header.
+ */
+ _gnutls_set_current_version(session, hver);
+
+ /* In order to know when this session was initiated.
+ */
+ session->security_parameters.timestamp = time(NULL);
+ /* Generate random data
+ */
+ _gnutls_tls_create_random(random);
+ _gnutls_set_client_random(session, random);
- /* Copy the compression methods.
- */
- extdatalen = _gnutls_copy_comp_methods(session, extdata, sizeof(extdata));
- if (extdatalen > 0) {
- datalen += extdatalen;
- data = gnutls_realloc_fast(data, datalen);
- if (data == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- memcpy(&data[pos], extdata, extdatalen);
- pos += extdatalen;
-
- } else {
- if (extdatalen == 0)
- extdatalen = GNUTLS_E_INTERNAL_ERROR;
- gnutls_free(data);
- gnutls_assert();
- return extdatalen;
- }
+ memcpy(&data[pos], random, TLS_RANDOM_SIZE);
+ pos += TLS_RANDOM_SIZE;
+
+ /* Copy the Session ID
+ */
+ data[pos++] = session_id_len;
+
+ if (session_id_len > 0) {
+ memcpy(&data[pos], SessionID, session_id_len);
+ pos += session_id_len;
+ }
+
+
+ /* Copy the ciphersuites.
+ */
+ extdatalen =
+ _gnutls_copy_ciphersuites(session, extdata, sizeof(extdata));
+ if (extdatalen > 0) {
+ datalen += extdatalen;
+ data = gnutls_realloc_fast(data, datalen);
+ if (data == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ memcpy(&data[pos], extdata, extdatalen);
+ pos += extdatalen;
+
+ } else {
+ if (extdatalen == 0)
+ extdatalen = GNUTLS_E_INTERNAL_ERROR;
+ gnutls_free(data);
+ gnutls_assert();
+ return extdatalen;
+ }
+
+
+ /* Copy the compression methods.
+ */
+ extdatalen =
+ _gnutls_copy_comp_methods(session, extdata, sizeof(extdata));
+ if (extdatalen > 0) {
+ datalen += extdatalen;
+ data = gnutls_realloc_fast(data, datalen);
+ if (data == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
- /* Generate and copy TLS extensions.
- */
- if (hver >= GNUTLS_TLS1) {
- extdatalen = _gnutls_gen_extensions(session, extdata, sizeof(extdata));
-
- if (extdatalen > 0) {
- datalen += extdatalen;
- data = gnutls_realloc_fast(data, datalen);
- if (data == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- memcpy(&data[pos], extdata, extdatalen);
- } else if (extdatalen < 0) {
- gnutls_assert();
- gnutls_free(data);
- return extdatalen;
- }
+ memcpy(&data[pos], extdata, extdatalen);
+ pos += extdatalen;
+
+ } else {
+ if (extdatalen == 0)
+ extdatalen = GNUTLS_E_INTERNAL_ERROR;
+ gnutls_free(data);
+ gnutls_assert();
+ return extdatalen;
+ }
+
+ /* Generate and copy TLS extensions.
+ */
+ if (hver >= GNUTLS_TLS1) {
+ extdatalen =
+ _gnutls_gen_extensions(session, extdata, sizeof(extdata));
+
+ if (extdatalen > 0) {
+ datalen += extdatalen;
+ data = gnutls_realloc_fast(data, datalen);
+ if (data == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
}
+
+ memcpy(&data[pos], extdata, extdatalen);
+ } else if (extdatalen < 0) {
+ gnutls_assert();
+ gnutls_free(data);
+ return extdatalen;
+ }
}
+ }
- ret =
- _gnutls_send_handshake(session, data, datalen,
- GNUTLS_CLIENT_HELLO);
- gnutls_free(data);
+ ret =
+ _gnutls_send_handshake(session, data, datalen,
+ GNUTLS_CLIENT_HELLO);
+ gnutls_free(data);
- return ret;
+ return ret;
}
static int _gnutls_send_server_hello(gnutls_session session, int again)
{
- opaque *data = NULL;
- opaque extdata[MAX_EXT_DATA_LENGTH];
- int extdatalen;
- int pos = 0;
- int datalen, ret = 0;
- uint8 comp;
- opaque *SessionID = session->security_parameters.session_id;
- uint8 session_id_len = session->security_parameters.session_id_size;
- opaque buf[2*TLS_MAX_SESSION_ID_SIZE+1];
+ opaque *data = NULL;
+ opaque extdata[MAX_EXT_DATA_LENGTH];
+ int extdatalen;
+ int pos = 0;
+ int datalen, ret = 0;
+ uint8 comp;
+ opaque *SessionID = session->security_parameters.session_id;
+ uint8 session_id_len = session->security_parameters.session_id_size;
+ opaque buf[2 * TLS_MAX_SESSION_ID_SIZE + 1];
+
+ if (SessionID == NULL)
+ session_id_len = 0;
+
+ datalen = 0;
+
+ if (IS_SRP_KX
+ (_gnutls_cipher_suite_get_kx_algo
+ (&session->security_parameters.current_cipher_suite))) {
+ /* While resuming we cannot check the username extension since it is
+ * not available at this point. It will be copied on connection
+ * state activation.
+ */
+ if (session->internals.resumed == RESUME_FALSE &&
+ 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.
+ */
+ gnutls_assert();
+ ret = gnutls_alert_send(session, GNUTLS_AL_WARNING,
+ GNUTLS_A_MISSING_SRP_USERNAME);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
- if (SessionID == NULL)
- session_id_len = 0;
-
- datalen = 0;
-
- if (IS_SRP_KX(
- _gnutls_cipher_suite_get_kx_algo(
- &session->security_parameters.current_cipher_suite)))
- {
- /* While resuming we cannot check the username extension since it is
- * not available at this point. It will be copied on connection
- * state activation.
- */
- if (session->internals.resumed == RESUME_FALSE &&
- 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.
- */
- gnutls_assert();
- ret = gnutls_alert_send( session, GNUTLS_AL_WARNING,
- GNUTLS_A_MISSING_SRP_USERNAME);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
-
- return GNUTLS_E_INT_HANDSHAKE_AGAIN;
- }
+ return GNUTLS_E_INT_HANDSHAKE_AGAIN;
}
+ }
- if (again == 0) {
- datalen = 2 + session_id_len + 1 + TLS_RANDOM_SIZE + 3;
- extdatalen = _gnutls_gen_extensions(session, extdata, sizeof(extdata));
+ if (again == 0) {
+ datalen = 2 + session_id_len + 1 + TLS_RANDOM_SIZE + 3;
+ extdatalen =
+ _gnutls_gen_extensions(session, extdata, sizeof(extdata));
- if (extdatalen < 0) {
- gnutls_assert();
- return extdatalen;
- }
+ if (extdatalen < 0) {
+ gnutls_assert();
+ return extdatalen;
+ }
- data = gnutls_alloca(datalen + extdatalen);
- if (data == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
+ data = gnutls_alloca(datalen + extdatalen);
+ if (data == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
- data[pos++] =
- _gnutls_version_get_major(session->security_parameters.
- version);
- data[pos++] =
- _gnutls_version_get_minor(session->security_parameters.
- version);
-
- memcpy(&data[pos],
- session->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;
+ data[pos++] =
+ _gnutls_version_get_major(session->security_parameters.
+ version);
+ data[pos++] =
+ _gnutls_version_get_minor(session->security_parameters.
+ version);
+
+ memcpy(&data[pos],
+ session->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;
- _gnutls_handshake_log("HSK[%x]: SessionID: %s\n", session,
- _gnutls_bin2hex(SessionID, session_id_len, buf, sizeof(buf)));
+ _gnutls_handshake_log("HSK[%x]: SessionID: %s\n", session,
+ _gnutls_bin2hex(SessionID, session_id_len,
+ buf, sizeof(buf)));
- memcpy(&data[pos],
- session->security_parameters.
- current_cipher_suite.suite, 2);
- pos += 2;
+ memcpy(&data[pos],
+ session->security_parameters.current_cipher_suite.suite, 2);
+ pos += 2;
- comp =
- (uint8) _gnutls_compression_get_num(session->
- internals.
- compression_method);
- data[pos++] = comp;
+ comp =
+ (uint8) _gnutls_compression_get_num(session->
+ internals.
+ compression_method);
+ data[pos++] = comp;
- if (extdatalen > 0) {
- datalen += extdatalen;
+ if (extdatalen > 0) {
+ datalen += extdatalen;
- memcpy(&data[pos], extdata, extdatalen);
- }
+ memcpy(&data[pos], extdata, extdatalen);
}
+ }
- ret =
- _gnutls_send_handshake(session, data, datalen,
- GNUTLS_SERVER_HELLO);
- gnutls_afree(data);
+ ret =
+ _gnutls_send_handshake(session, data, datalen,
+ GNUTLS_SERVER_HELLO);
+ gnutls_afree(data);
- return ret;
+ return ret;
}
int _gnutls_send_hello(gnutls_session session, int again)
{
- int ret;
+ int ret;
- if (session->security_parameters.entity == GNUTLS_CLIENT) {
- ret = _gnutls_send_client_hello(session, again);
+ if (session->security_parameters.entity == GNUTLS_CLIENT) {
+ ret = _gnutls_send_client_hello(session, again);
- } else { /* SERVER */
- ret = _gnutls_send_server_hello(session, again);
- }
+ } else { /* SERVER */
+ ret = _gnutls_send_server_hello(session, again);
+ }
- return ret;
+ return ret;
}
/* RECEIVE A HELLO MESSAGE. This should be called from gnutls_recv_handshake_int only if a
* hello message is expected. It uses the security_parameters.current_cipher_suite
* and internals.compression_method.
*/
-int _gnutls_recv_hello(gnutls_session session, opaque *data, int datalen)
+int _gnutls_recv_hello(gnutls_session session, opaque * data, int datalen)
{
- int ret;
+ int ret;
- if (session->security_parameters.entity == GNUTLS_CLIENT) {
- ret = _gnutls_read_server_hello(session, data, datalen);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
- } else { /* Server side reading a client hello */
+ if (session->security_parameters.entity == GNUTLS_CLIENT) {
+ ret = _gnutls_read_server_hello(session, data, datalen);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ } else { /* Server side reading a client hello */
- ret = _gnutls_read_client_hello(session, data, datalen);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
+ ret = _gnutls_read_client_hello(session, data, datalen);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
}
+ }
- return ret;
+ return ret;
}
/* The packets in gnutls_handshake (it's more broad than original TLS handshake)
@@ -1821,64 +1855,67 @@ int _gnutls_recv_hello(gnutls_session session, opaque *data, int datalen)
**/
int gnutls_rehandshake(gnutls_session session)
{
- int ret;
+ int ret;
- /* only server sends that handshake packet */
- if (session->security_parameters.entity == GNUTLS_CLIENT)
- return GNUTLS_E_INVALID_REQUEST;
+ /* only server sends that handshake packet */
+ if (session->security_parameters.entity == GNUTLS_CLIENT)
+ return GNUTLS_E_INVALID_REQUEST;
- ret =
- _gnutls_send_empty_handshake(session, GNUTLS_HELLO_REQUEST,
- AGAIN(STATE50));
- STATE = STATE50;
+ ret =
+ _gnutls_send_empty_handshake(session, GNUTLS_HELLO_REQUEST,
+ AGAIN(STATE50));
+ STATE = STATE50;
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
- STATE = STATE0;
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ STATE = STATE0;
- return 0;
+ return 0;
}
-inline
-static int _gnutls_abort_handshake( gnutls_session session, int ret)
+inline static int _gnutls_abort_handshake(gnutls_session session, int ret)
{
- if ( ((ret==GNUTLS_E_WARNING_ALERT_RECEIVED) &&
- ( gnutls_alert_get(session) == GNUTLS_A_NO_RENEGOTIATION))
- || ret==GNUTLS_E_GOT_APPLICATION_DATA)
- return 0;
+ if (((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) &&
+ (gnutls_alert_get(session) == GNUTLS_A_NO_RENEGOTIATION))
+ || ret == GNUTLS_E_GOT_APPLICATION_DATA)
+ return 0;
- /* this doesn't matter */
- return GNUTLS_E_INTERNAL_ERROR;
+ /* this doesn't matter */
+ return GNUTLS_E_INTERNAL_ERROR;
}
/* This function initialized the handshake hash session.
* required for finished messages.
*/
-inline
-static int _gnutls_handshake_hash_init( gnutls_session session) {
+inline static int _gnutls_handshake_hash_init(gnutls_session session)
+{
- if ( session->internals.handshake_mac_handle_md5==NULL) {
- session->internals.handshake_mac_handle_md5 = _gnutls_hash_init( GNUTLS_MAC_MD5);
+ if (session->internals.handshake_mac_handle_md5 == NULL) {
+ session->internals.handshake_mac_handle_md5 =
+ _gnutls_hash_init(GNUTLS_MAC_MD5);
- if (session->internals.handshake_mac_handle_md5==GNUTLS_HASH_FAILED) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
+ if (session->internals.handshake_mac_handle_md5 ==
+ GNUTLS_HASH_FAILED) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
}
+ }
- if ( session->internals.handshake_mac_handle_sha==NULL) {
- session->internals.handshake_mac_handle_sha = _gnutls_hash_init( GNUTLS_MAC_SHA);
- if (session->internals.handshake_mac_handle_sha==GNUTLS_HASH_FAILED) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
+ if (session->internals.handshake_mac_handle_sha == NULL) {
+ session->internals.handshake_mac_handle_sha =
+ _gnutls_hash_init(GNUTLS_MAC_SHA);
+ if (session->internals.handshake_mac_handle_sha ==
+ GNUTLS_HASH_FAILED) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
}
+ }
- return 0;
-}
+ return 0;
+}
/**
* gnutls_handshake - This is the main function in the handshake protocol.
@@ -1906,43 +1943,43 @@ static int _gnutls_handshake_hash_init( gnutls_session session) {
**/
int gnutls_handshake(gnutls_session session)
{
- int ret;
+ int ret;
- if ( (ret=_gnutls_handshake_hash_init( session)) < 0) {
- gnutls_assert();
- return ret;
- }
+ if ((ret = _gnutls_handshake_hash_init(session)) < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ if (session->security_parameters.entity == GNUTLS_CLIENT) {
+ ret = _gnutls_handshake_client(session);
+ } else {
+ ret = _gnutls_handshake_server(session);
+ }
+ if (ret < 0) {
+ /* In the case of a rehandshake abort
+ * we should reset the handshake's internal state.
+ */
+ if (_gnutls_abort_handshake(session, ret) == 0)
+ STATE = STATE0;
- if (session->security_parameters.entity == GNUTLS_CLIENT) {
- ret = _gnutls_handshake_client(session);
- } else {
- ret = _gnutls_handshake_server(session);
- }
- if (ret < 0) {
- /* In the case of a rehandshake abort
- * we should reset the handshake's internal state.
- */
- if (_gnutls_abort_handshake( session, ret) == 0)
- STATE = STATE0;
+ return ret;
+ }
- return ret;
- }
-
- ret = _gnutls_handshake_common(session);
+ ret = _gnutls_handshake_common(session);
- if (ret < 0) {
- if (_gnutls_abort_handshake( session, ret) == 0)
- STATE = STATE0;
-
- return ret;
- }
-
- STATE = STATE0;
+ if (ret < 0) {
+ if (_gnutls_abort_handshake(session, ret) == 0)
+ STATE = STATE0;
- _gnutls_handshake_io_buffer_clear(session);
- _gnutls_handshake_internal_state_clear(session);
+ return ret;
+ }
- return 0;
+ STATE = STATE0;
+
+ _gnutls_handshake_io_buffer_clear(session);
+ _gnutls_handshake_internal_state_clear(session);
+
+ return 0;
}
/* Here if GNUTLS_E_INT_HANDSHAKE_AGAIN is received we go to
@@ -1975,162 +2012,154 @@ int gnutls_handshake(gnutls_session session)
*/
int _gnutls_handshake_client(gnutls_session session)
{
- int ret = 0;
+ int ret = 0;
#ifdef HANDSHAKE_DEBUG
- char buf[64];
-
- if (session->internals.resumed_security_parameters.
- session_id_size > 0)
- _gnutls_handshake_log("HSK[%x]: Ask to resume: %s\n", session,
- _gnutls_bin2hex(session->internals.
- resumed_security_parameters.
- session_id,
- session->internals.
- resumed_security_parameters.
- session_id_size, buf, sizeof(buf)));
+ char buf[64];
+
+ if (session->internals.resumed_security_parameters.session_id_size > 0)
+ _gnutls_handshake_log("HSK[%x]: Ask to resume: %s\n", session,
+ _gnutls_bin2hex(session->internals.
+ resumed_security_parameters.
+ session_id,
+ session->internals.
+ resumed_security_parameters.
+ session_id_size, buf,
+ sizeof(buf)));
#endif
- restart:
-
- switch (STATE) {
- case STATE0:
- case STATE1:
- ret = _gnutls_send_hello(session, AGAIN(STATE1));
- STATE = STATE1;
- IMED_RET("send hello", ret);
-
- case STATE2:
- /* receive the server hello */
- ret =
- _gnutls_recv_handshake(session, NULL, NULL,
- GNUTLS_SERVER_HELLO,
- MANDATORY_PACKET);
- STATE = STATE2;
- IMED_RET("recv hello", ret);
-
- case STATE3:
- /* RECV CERTIFICATE */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
- ret = _gnutls_recv_server_certificate(session);
- STATE = STATE3;
- IMED_RET("recv server certificate", ret);
-
- case STATE4:
- /* receive the server key exchange */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
- ret = _gnutls_recv_server_kx_message(session);
- STATE = STATE4;
- IMED_RET("recv server kx message", ret);
-
- case STATE5:
- /* receive the server certificate request - if any
- */
-
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
- ret =
- _gnutls_recv_server_certificate_request(session);
- STATE = STATE5;
- IMED_RET("recv server certificate request message", ret);
-
- case STATE6:
- /* receive the server hello done */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
- ret =
- _gnutls_recv_handshake(session, NULL, NULL,
- GNUTLS_SERVER_HELLO_DONE,
- MANDATORY_PACKET);
- STATE = STATE6;
- IMED_RET("recv server hello done", ret);
-
- case STATE7:
- /* send our certificate - if any and if requested
- */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
- ret =
- _gnutls_send_client_certificate(session,
- AGAIN(STATE7));
- STATE = STATE7;
- IMED_RET("send client certificate", ret);
-
- case STATE8:
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
- ret =
- _gnutls_send_client_kx_message(session,
- AGAIN(STATE8));
- STATE = STATE8;
- IMED_RET("send client kx", ret);
-
- case STATE9:
- /* send client certificate verify */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
- ret =
- _gnutls_send_client_certificate_verify(session,
- AGAIN
- (STATE9));
- STATE = STATE9;
- IMED_RET("send client certificate verify", ret);
-
- STATE = STATE0;
- default:
- break;
- }
+ restart:
+ switch (STATE) {
+ case STATE0:
+ case STATE1:
+ ret = _gnutls_send_hello(session, AGAIN(STATE1));
+ STATE = STATE1;
+ IMED_RET("send hello", ret);
- return 0;
+ case STATE2:
+ /* receive the server hello */
+ ret =
+ _gnutls_recv_handshake(session, NULL, NULL,
+ GNUTLS_SERVER_HELLO, MANDATORY_PACKET);
+ STATE = STATE2;
+ IMED_RET("recv hello", ret);
+
+ case STATE3:
+ /* RECV CERTIFICATE */
+ if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ ret = _gnutls_recv_server_certificate(session);
+ STATE = STATE3;
+ IMED_RET("recv server certificate", ret);
+
+ case STATE4:
+ /* receive the server key exchange */
+ if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ ret = _gnutls_recv_server_kx_message(session);
+ STATE = STATE4;
+ IMED_RET("recv server kx message", ret);
+
+ case STATE5:
+ /* receive the server certificate request - if any
+ */
+
+ if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ ret = _gnutls_recv_server_certificate_request(session);
+ STATE = STATE5;
+ IMED_RET("recv server certificate request message", ret);
+
+ case STATE6:
+ /* receive the server hello done */
+ if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ ret =
+ _gnutls_recv_handshake(session, NULL, NULL,
+ GNUTLS_SERVER_HELLO_DONE,
+ MANDATORY_PACKET);
+ STATE = STATE6;
+ IMED_RET("recv server hello done", ret);
+
+ case STATE7:
+ /* send our certificate - if any and if requested
+ */
+ if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ ret = _gnutls_send_client_certificate(session, AGAIN(STATE7));
+ STATE = STATE7;
+ IMED_RET("send client certificate", ret);
+
+ case STATE8:
+ if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ ret = _gnutls_send_client_kx_message(session, AGAIN(STATE8));
+ STATE = STATE8;
+ IMED_RET("send client kx", ret);
+
+ case STATE9:
+ /* send client certificate verify */
+ if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ ret =
+ _gnutls_send_client_certificate_verify(session,
+ AGAIN(STATE9));
+ STATE = STATE9;
+ IMED_RET("send client certificate verify", ret);
+
+ STATE = STATE0;
+ default:
+ break;
+ }
+
+
+ return 0;
}
/* This function sends the final handshake packets and initializes connection
*/
static int _gnutls_send_handshake_final(gnutls_session session, int init)
{
- int ret = 0;
-
- /* Send the CHANGE CIPHER SPEC PACKET */
-
- switch (STATE) {
- case STATE0:
- case STATE20:
- ret =
- _gnutls_send_change_cipher_spec(session, AGAIN(STATE20));
- STATE = STATE20;
- if (ret < 0) {
- ERR("send ChangeCipherSpec", ret);
- gnutls_assert();
- return ret;
- }
+ int ret = 0;
- /* Initialize the connection session (start encryption) - in case of client
- */
- if (init == TRUE) {
- ret = _gnutls_connection_state_init(session);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
- }
+ /* Send the CHANGE CIPHER SPEC PACKET */
- ret = _gnutls_write_connection_state_init(session);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
+ switch (STATE) {
+ case STATE0:
+ case STATE20:
+ ret = _gnutls_send_change_cipher_spec(session, AGAIN(STATE20));
+ STATE = STATE20;
+ if (ret < 0) {
+ ERR("send ChangeCipherSpec", ret);
+ gnutls_assert();
+ return ret;
+ }
- case STATE21:
- /* send the finished message */
- ret = _gnutls_send_finished(session, AGAIN(STATE21));
- STATE = STATE21;
- if (ret < 0) {
- ERR("send Finished", ret);
- gnutls_assert();
- return ret;
- }
+ /* Initialize the connection session (start encryption) - in case of client
+ */
+ if (init == TRUE) {
+ ret = _gnutls_connection_state_init(session);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ }
- STATE = STATE0;
- default:
- break;
+ ret = _gnutls_write_connection_state_init(session);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
}
- return 0;
+ case STATE21:
+ /* send the finished message */
+ ret = _gnutls_send_finished(session, AGAIN(STATE21));
+ STATE = STATE21;
+ if (ret < 0) {
+ ERR("send Finished", ret);
+ gnutls_assert();
+ return ret;
+ }
+
+ STATE = STATE0;
+ default:
+ break;
+ }
+
+ return 0;
}
/* This function receives the final handshake packets
@@ -2139,54 +2168,52 @@ static int _gnutls_send_handshake_final(gnutls_session session, int init)
*/
static int _gnutls_recv_handshake_final(gnutls_session session, int init)
{
- int ret = 0;
- uint8 ch;
-
- switch (STATE) {
- case STATE0:
- case STATE30:
- ret =
- _gnutls_recv_int(session, GNUTLS_CHANGE_CIPHER_SPEC, -1,
- &ch, 1);
- STATE = STATE30;
- if (ret <= 0) {
- ERR("recv ChangeCipherSpec", ret);
- gnutls_assert();
- return (ret <
- 0) ? ret :
- GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
- }
+ int ret = 0;
+ uint8 ch;
- /* Initialize the connection session (start encryption) - in case of server */
- if (init == TRUE) {
- ret = _gnutls_connection_state_init(session);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
- }
+ switch (STATE) {
+ case STATE0:
+ case STATE30:
+ ret =
+ _gnutls_recv_int(session, GNUTLS_CHANGE_CIPHER_SPEC, -1,
+ &ch, 1);
+ STATE = STATE30;
+ if (ret <= 0) {
+ ERR("recv ChangeCipherSpec", ret);
+ gnutls_assert();
+ return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+ }
+
+ /* Initialize the connection session (start encryption) - in case of server */
+ if (init == TRUE) {
+ ret = _gnutls_connection_state_init(session);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ }
- ret = _gnutls_read_connection_state_init(session);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
+ ret = _gnutls_read_connection_state_init(session);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
- case STATE31:
- ret = _gnutls_recv_finished(session);
- STATE = STATE31;
- if (ret < 0) {
- ERR("recv finished", ret);
- gnutls_assert();
- return ret;
- }
- STATE = STATE0;
- default:
- break;
+ case STATE31:
+ ret = _gnutls_recv_finished(session);
+ STATE = STATE31;
+ if (ret < 0) {
+ ERR("recv finished", ret);
+ gnutls_assert();
+ return ret;
}
+ STATE = STATE0;
+ default:
+ break;
+ }
- return 0;
+ return 0;
}
/*
@@ -2196,236 +2223,231 @@ static int _gnutls_recv_handshake_final(gnutls_session session, int init)
int _gnutls_handshake_server(gnutls_session session)
{
- int ret = 0;
-
- restart:
-
- switch (STATE) {
- case STATE0:
- case STATE1:
- ret =
- _gnutls_recv_handshake(session, NULL, NULL,
- GNUTLS_CLIENT_HELLO,
- MANDATORY_PACKET);
- STATE = STATE1;
- IMED_RET("recv hello", ret);
-
- case STATE2:
- ret = _gnutls_send_hello(session, AGAIN(STATE2));
- STATE = STATE2;
- IMED_RET("send hello", ret);
-
- /* SEND CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */
- case STATE3:
- /* NOTE: these should not be send if we are resuming */
-
- if (session->internals.resumed == RESUME_FALSE)
- ret =
- _gnutls_send_server_certificate(session,
- AGAIN(STATE3));
- STATE = STATE3;
- IMED_RET("send server certificate", ret);
-
- case STATE4:
- /* send server key exchange (A) */
- if (session->internals.resumed == RESUME_FALSE)
- ret =
- _gnutls_send_server_kx_message(session,
- AGAIN(STATE4));
- STATE = STATE4;
- IMED_RET("send server kx", ret);
-
- case STATE5:
- /* Send certificate request - if requested to */
- if (session->internals.resumed == RESUME_FALSE)
- ret =
- _gnutls_send_server_certificate_request(session,
- AGAIN
- (STATE5));
- STATE = STATE5;
- IMED_RET("send server cert request", ret);
-
- case STATE6:
- /* send the server hello done */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
- ret =
- _gnutls_send_empty_handshake(session,
- GNUTLS_SERVER_HELLO_DONE,
- AGAIN(STATE6));
- STATE = STATE6;
- IMED_RET("send server hello done", ret);
-
-
- /* RECV CERTIFICATE + KEYEXCHANGE + CERTIFICATE_VERIFY */
- case STATE7:
- /* receive the client certificate message */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
- ret = _gnutls_recv_client_certificate(session);
- STATE = STATE7;
- IMED_RET("recv client certificate", ret);
-
- case STATE8:
- /* receive the client key exchange message */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
- ret = _gnutls_recv_client_kx_message(session);
- STATE = STATE8;
- IMED_RET("recv client kx", ret);
-
- case STATE9:
- /* receive the client certificate verify message */
- if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
- ret =
- _gnutls_recv_client_certificate_verify_message
- (session);
- STATE = STATE9;
- IMED_RET("recv client certificate verify", ret);
-
- STATE = STATE0; /* finished thus clear session */
- default:
- break;
- }
+ int ret = 0;
- return 0;
+ restart:
+
+ switch (STATE) {
+ case STATE0:
+ case STATE1:
+ ret =
+ _gnutls_recv_handshake(session, NULL, NULL,
+ GNUTLS_CLIENT_HELLO, MANDATORY_PACKET);
+ STATE = STATE1;
+ IMED_RET("recv hello", ret);
+
+ case STATE2:
+ ret = _gnutls_send_hello(session, AGAIN(STATE2));
+ STATE = STATE2;
+ IMED_RET("send hello", ret);
+
+ /* SEND CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */
+ case STATE3:
+ /* NOTE: these should not be send if we are resuming */
+
+ if (session->internals.resumed == RESUME_FALSE)
+ ret = _gnutls_send_server_certificate(session, AGAIN(STATE3));
+ STATE = STATE3;
+ IMED_RET("send server certificate", ret);
+
+ case STATE4:
+ /* send server key exchange (A) */
+ if (session->internals.resumed == RESUME_FALSE)
+ ret = _gnutls_send_server_kx_message(session, AGAIN(STATE4));
+ STATE = STATE4;
+ IMED_RET("send server kx", ret);
+
+ case STATE5:
+ /* Send certificate request - if requested to */
+ if (session->internals.resumed == RESUME_FALSE)
+ ret =
+ _gnutls_send_server_certificate_request(session,
+ AGAIN(STATE5));
+ STATE = STATE5;
+ IMED_RET("send server cert request", ret);
+
+ case STATE6:
+ /* send the server hello done */
+ if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ ret =
+ _gnutls_send_empty_handshake(session,
+ GNUTLS_SERVER_HELLO_DONE,
+ AGAIN(STATE6));
+ STATE = STATE6;
+ IMED_RET("send server hello done", ret);
+
+
+ /* RECV CERTIFICATE + KEYEXCHANGE + CERTIFICATE_VERIFY */
+ case STATE7:
+ /* receive the client certificate message */
+ if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ ret = _gnutls_recv_client_certificate(session);
+ STATE = STATE7;
+ IMED_RET("recv client certificate", ret);
+
+ case STATE8:
+ /* receive the client key exchange message */
+ if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ ret = _gnutls_recv_client_kx_message(session);
+ STATE = STATE8;
+ IMED_RET("recv client kx", ret);
+
+ case STATE9:
+ /* receive the client certificate verify message */
+ if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
+ ret = _gnutls_recv_client_certificate_verify_message(session);
+ STATE = STATE9;
+ IMED_RET("recv client certificate verify", ret);
+
+ STATE = STATE0; /* finished thus clear session */
+ default:
+ break;
+ }
+
+ return 0;
}
int _gnutls_handshake_common(gnutls_session session)
{
- int ret = 0;
+ int ret = 0;
- restart:
+ restart:
- /* send and recv the change cipher spec and finished messages */
- if ((session->internals.resumed == RESUME_TRUE
- && session->security_parameters.entity == GNUTLS_CLIENT)
- || (session->internals.resumed == RESUME_FALSE
- && session->security_parameters.entity == GNUTLS_SERVER)) {
- /* if we are a client resuming - or we are a server not resuming */
+ /* send and recv the change cipher spec and finished messages */
+ if ((session->internals.resumed == RESUME_TRUE
+ && session->security_parameters.entity == GNUTLS_CLIENT)
+ || (session->internals.resumed == RESUME_FALSE
+ && session->security_parameters.entity == GNUTLS_SERVER)) {
+ /* if we are a client resuming - or we are a server not resuming */
- ret = _gnutls_recv_handshake_final(session, TRUE);
- IMED_RET("recv handshake final", ret);
+ ret = _gnutls_recv_handshake_final(session, TRUE);
+ IMED_RET("recv handshake final", ret);
- ret = _gnutls_send_handshake_final(session, FALSE);
- IMED_RET("send handshake final", ret);
- } else { /* if we are a client not resuming - or we are a server resuming */
+ ret = _gnutls_send_handshake_final(session, FALSE);
+ IMED_RET("send handshake final", ret);
+ } else { /* if we are a client not resuming - or we are a server resuming */
- ret = _gnutls_send_handshake_final(session, TRUE);
- IMED_RET("send handshake final 2", ret);
+ ret = _gnutls_send_handshake_final(session, TRUE);
+ IMED_RET("send handshake final 2", ret);
- ret = _gnutls_recv_handshake_final(session, FALSE);
- IMED_RET("recv handshake final 2", ret);
- }
+ ret = _gnutls_recv_handshake_final(session, FALSE);
+ IMED_RET("recv handshake final 2", ret);
+ }
- if (session->security_parameters.entity == GNUTLS_SERVER) {
- /* in order to support session resuming */
- _gnutls_server_register_current_session(session);
- }
+ if (session->security_parameters.entity == GNUTLS_SERVER) {
+ /* in order to support session resuming */
+ _gnutls_server_register_current_session(session);
+ }
- /* clear handshake buffer */
- _gnutls_handshake_hash_buffers_clear(session);
- return ret;
+ /* clear handshake buffer */
+ _gnutls_handshake_hash_buffers_clear(session);
+ return ret;
}
-int _gnutls_generate_session_id(opaque *session_id, uint8 * len)
+int _gnutls_generate_session_id(opaque * session_id, uint8 * len)
{
- *len = TLS_MAX_SESSION_ID_SIZE;
+ *len = TLS_MAX_SESSION_ID_SIZE;
- if (_gnutls_get_random(session_id, *len, GNUTLS_WEAK_RANDOM) <
- 0) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
+ if (_gnutls_get_random(session_id, *len, GNUTLS_WEAK_RANDOM) < 0) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
- return 0;
+ return 0;
}
int _gnutls_recv_hello_request(gnutls_session session, void *data,
uint32 data_size)
{
- uint8 type;
+ uint8 type;
- if (session->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_E_REHANDSHAKE;
- else {
- gnutls_assert();
- return GNUTLS_E_UNEXPECTED_PACKET;
- }
+ if (session->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_E_REHANDSHAKE;
+ else {
+ gnutls_assert();
+ return GNUTLS_E_UNEXPECTED_PACKET;
+ }
}
/* Returns 1 if the given KX has not the corresponding parameters
* (DH or RSA) set up. Otherwise returns 0.
*/
-inline static int check_server_params( gnutls_session session, gnutls_kx_algorithm kx,
- gnutls_kx_algorithm* alg, int alg_size)
+inline static int check_server_params(gnutls_session session,
+ gnutls_kx_algorithm kx,
+ gnutls_kx_algorithm * alg,
+ int alg_size)
{
- int cred_type;
- const gnutls_certificate_credentials x509_cred;
- const gnutls_anon_server_credentials anon_cred;
- gnutls_dh_params dh_params = NULL;
- gnutls_rsa_params rsa_params = NULL;
- int j, remove;
-
- cred_type = _gnutls_map_kx_get_cred( kx, 1);
-
- if (cred_type == GNUTLS_CRD_CERTIFICATE) {
- x509_cred =
- _gnutls_get_cred(session->key, cred_type, NULL);
-
- if (x509_cred != NULL) {
- dh_params = _gnutls_certificate_get_dh_params(x509_cred, session);
- rsa_params = _gnutls_certificate_get_rsa_params(x509_cred, session);
- }
+ int cred_type;
+ const gnutls_certificate_credentials x509_cred;
+ const gnutls_anon_server_credentials anon_cred;
+ gnutls_dh_params dh_params = NULL;
+ gnutls_rsa_params rsa_params = NULL;
+ int j, remove;
- /* Check also if the certificate supports the
- * KX method.
- */
- remove = 1;
- for (j = 0; j < alg_size; j++) {
- if (alg[j] == kx) {
- remove = 0;
- break;
- }
- }
-
- if (remove == 1) return 1;
+ cred_type = _gnutls_map_kx_get_cred(kx, 1);
-#ifdef ENABLE_ANON
- } else if ( cred_type == GNUTLS_CRD_ANON) {
- anon_cred =
- _gnutls_get_cred(session->key, cred_type, NULL);
-
- if (anon_cred != NULL) {
- dh_params = _gnutls_anon_get_dh_params(anon_cred, session);
- }
-#endif
- } else return 0; /* no need for params */
+ if (cred_type == GNUTLS_CRD_CERTIFICATE) {
+ x509_cred = _gnutls_get_cred(session->key, cred_type, NULL);
+ if (x509_cred != NULL) {
+ dh_params =
+ _gnutls_certificate_get_dh_params(x509_cred, session);
+ rsa_params =
+ _gnutls_certificate_get_rsa_params(x509_cred, session);
+ }
- /* If the key exchange method needs RSA or DH params,
- * but they are not set then remove it.
+ /* Check also if the certificate supports the
+ * KX method.
*/
- if (_gnutls_kx_needs_rsa_params( kx) != 0) {
- /* needs rsa params. */
- if (_gnutls_get_rsa_params( rsa_params)==NULL)
- return 1;
- }
-
- if (_gnutls_kx_needs_dh_params( kx) != 0) {
- /* needs DH params. */
- if (_gnutls_get_dh_params( dh_params)==NULL)
- return 1;
+ remove = 1;
+ for (j = 0; j < alg_size; j++) {
+ if (alg[j] == kx) {
+ remove = 0;
+ break;
+ }
}
- return 0;
+ if (remove == 1)
+ return 1;
+
+#ifdef ENABLE_ANON
+ } else if (cred_type == GNUTLS_CRD_ANON) {
+ anon_cred = _gnutls_get_cred(session->key, cred_type, NULL);
+
+ if (anon_cred != NULL) {
+ dh_params = _gnutls_anon_get_dh_params(anon_cred, session);
+ }
+#endif
+ } else
+ return 0; /* no need for params */
+
+
+ /* If the key exchange method needs RSA or DH params,
+ * but they are not set then remove it.
+ */
+ if (_gnutls_kx_needs_rsa_params(kx) != 0) {
+ /* needs rsa params. */
+ if (_gnutls_get_rsa_params(rsa_params) == NULL)
+ return 1;
+ }
+
+ if (_gnutls_kx_needs_dh_params(kx) != 0) {
+ /* needs DH params. */
+ if (_gnutls_get_dh_params(dh_params) == NULL)
+ return 1;
+ }
+
+ return 0;
}
/* This function will remove algorithms that are not supported by
@@ -2437,103 +2459,107 @@ inline static int check_server_params( gnutls_session session, gnutls_kx_algorit
*/
int _gnutls_remove_unwanted_ciphersuites(gnutls_session session,
cipher_suite_st **
- cipherSuites, int numCipherSuites,
- gnutls_pk_algorithm requested_pk_algo)
+ cipherSuites, int numCipherSuites,
+ gnutls_pk_algorithm
+ requested_pk_algo)
{
- int ret = 0;
- cipher_suite_st *newSuite, cs;
- int newSuiteSize = 0, i, remove;
- const gnutls_certificate_credentials x509_cred;
- gnutls_kx_algorithm kx;
- int server = session->security_parameters.entity==GNUTLS_SERVER?1:0;
- gnutls_kx_algorithm *alg;
- int alg_size;
-
- /* if we should use a specific certificate,
- * we should remove all algorithms that are not supported
- * by that certificate and are on the same authentication
- * method (CERTIFICATE).
- */
+ int ret = 0;
+ cipher_suite_st *newSuite, cs;
+ int newSuiteSize = 0, i, remove;
+ const gnutls_certificate_credentials x509_cred;
+ gnutls_kx_algorithm kx;
+ int server =
+ session->security_parameters.entity == GNUTLS_SERVER ? 1 : 0;
+ gnutls_kx_algorithm *alg;
+ int alg_size;
+
+ /* if we should use a specific certificate,
+ * we should remove all algorithms that are not supported
+ * by that certificate and are on the same authentication
+ * method (CERTIFICATE).
+ */
+
+ x509_cred =
+ _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, NULL);
+
+ /* if x509_cred==NULL we should remove all X509 ciphersuites
+ */
+
+ if (session->security_parameters.entity == GNUTLS_SERVER
+ && x509_cred != NULL) {
+ ret = _gnutls_server_select_cert(session, requested_pk_algo);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+ }
- x509_cred =
- _gnutls_get_cred(session->key, GNUTLS_CRD_CERTIFICATE, NULL);
+ /* get all the key exchange algorithms that are
+ * supported by the X509 certificate parameters.
+ */
+ if ((ret =
+ _gnutls_selected_cert_supported_kx(session, &alg,
+ &alg_size)) < 0) {
+ gnutls_assert();
+ return ret;
+ }
- /* if x509_cred==NULL we should remove all X509 ciphersuites
+ newSuite = gnutls_malloc(numCipherSuites * sizeof(cipher_suite_st));
+ if (newSuite == NULL) {
+ gnutls_assert();
+ gnutls_free(alg);
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ /* now removes ciphersuites based on the KX algorithm
+ */
+ for (i = 0; i < numCipherSuites; i++) {
+ /* finds the key exchange algorithm in
+ * the ciphersuite
*/
+ kx = _gnutls_cipher_suite_get_kx_algo(&(*cipherSuites)[i]);
+ remove = 0;
- if (session->security_parameters.entity == GNUTLS_SERVER && x509_cred != NULL) {
- ret = _gnutls_server_select_cert(session, requested_pk_algo);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
- }
-
- /* get all the key exchange algorithms that are
- * supported by the X509 certificate parameters.
+ /* if it is defined but had no credentials
*/
- if ((ret =
- _gnutls_selected_cert_supported_kx(session, &alg,
- &alg_size)) < 0) {
- gnutls_assert();
- return ret;
- }
+ if (_gnutls_get_kx_cred(session, kx, NULL) == NULL) {
+ remove = 1;
+ } else {
+ remove = 0;
- newSuite =
- gnutls_malloc(numCipherSuites * sizeof(cipher_suite_st));
- if (newSuite == NULL) {
- gnutls_assert();
- gnutls_free(alg);
- return GNUTLS_E_MEMORY_ERROR;
+ if (server)
+ remove = check_server_params(session, kx, alg, alg_size);
}
- /* now removes ciphersuites based on the KX algorithm
- */
- for (i = 0; i < numCipherSuites; i++) {
- /* finds the key exchange algorithm in
- * the ciphersuite
- */
- kx = _gnutls_cipher_suite_get_kx_algo(&(*cipherSuites)[i]);
- remove = 0;
- /* if it is defined but had no credentials
- */
- if (_gnutls_get_kx_cred(session, kx, NULL) == NULL) {
- remove = 1;
- } else {
- remove = 0;
- if (server)
- remove = check_server_params( session, kx, alg, alg_size);
- }
-
-
-
- memcpy( &cs.suite, &(*cipherSuites)[i].suite, 2);
+ memcpy(&cs.suite, &(*cipherSuites)[i].suite, 2);
- if (remove == 0) {
+ if (remove == 0) {
- _gnutls_handshake_log("HSK[%x]: Keeping ciphersuite: %s\n", session,
- _gnutls_cipher_suite_get_name(&cs));
+ _gnutls_handshake_log("HSK[%x]: Keeping ciphersuite: %s\n",
+ session,
+ _gnutls_cipher_suite_get_name(&cs));
- memcpy(newSuite[newSuiteSize].suite,
- (*cipherSuites)[i].suite, 2);
- newSuiteSize++;
- } else {
- _gnutls_handshake_log("HSK[%x]: Removing ciphersuite: %s\n", session,
- _gnutls_cipher_suite_get_name(&cs));
+ memcpy(newSuite[newSuiteSize].suite,
+ (*cipherSuites)[i].suite, 2);
+ newSuiteSize++;
+ } else {
+ _gnutls_handshake_log("HSK[%x]: Removing ciphersuite: %s\n",
+ session,
+ _gnutls_cipher_suite_get_name(&cs));
- }
}
+ }
- gnutls_free(alg);
- gnutls_free(*cipherSuites);
- *cipherSuites = newSuite;
+ gnutls_free(alg);
+ gnutls_free(*cipherSuites);
+ *cipherSuites = newSuite;
- ret = newSuiteSize;
+ ret = newSuiteSize;
- return ret;
+ return ret;
}
@@ -2548,18 +2574,23 @@ int _gnutls_remove_unwanted_ciphersuites(gnutls_session session,
* to set an upper limit.
*
**/
-void gnutls_handshake_set_max_packet_length(gnutls_session session, int max)
+void gnutls_handshake_set_max_packet_length(gnutls_session session,
+ int max)
{
- session->internals.max_handshake_data_buffer_size = max;
+ session->internals.max_handshake_data_buffer_size = max;
}
-void _gnutls_set_adv_version( gnutls_session session, gnutls_protocol_version ver) {
- set_adv_version( session, _gnutls_version_get_major(ver), _gnutls_version_get_minor(ver));
+void _gnutls_set_adv_version(gnutls_session session,
+ gnutls_protocol_version ver)
+{
+ set_adv_version(session, _gnutls_version_get_major(ver),
+ _gnutls_version_get_minor(ver));
}
-gnutls_protocol_version _gnutls_get_adv_version( gnutls_session session) {
- return _gnutls_version_get( _gnutls_get_adv_version_major( session),
- _gnutls_get_adv_version_minor( session));
+gnutls_protocol_version _gnutls_get_adv_version(gnutls_session session)
+{
+ return _gnutls_version_get(_gnutls_get_adv_version_major(session),
+ _gnutls_get_adv_version_minor(session));
}
/**
@@ -2572,9 +2603,10 @@ gnutls_protocol_version _gnutls_get_adv_version( gnutls_session session) {
*
* Check gnutls.h for the available handshake descriptions.
**/
-gnutls_handshake_description gnutls_handshake_get_last_in( gnutls_session session)
+gnutls_handshake_description gnutls_handshake_get_last_in(gnutls_session
+ session)
{
- return session->internals.last_handshake_in;
+ return session->internals.last_handshake_in;
}
/**
@@ -2588,8 +2620,8 @@ gnutls_handshake_description gnutls_handshake_get_last_in( gnutls_session sessio
* Check gnutls.h for the available handshake descriptions.
*
**/
-gnutls_handshake_description gnutls_handshake_get_last_out( gnutls_session session)
+gnutls_handshake_description gnutls_handshake_get_last_out(gnutls_session
+ session)
{
- return session->internals.last_handshake_out;
+ return session->internals.last_handshake_out;
}
-