summaryrefslogtreecommitdiff
path: root/lib/handshake.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/handshake.c')
-rw-r--r--lib/handshake.c172
1 files changed, 27 insertions, 145 deletions
diff --git a/lib/handshake.c b/lib/handshake.c
index da0f41cc05..45210254d2 100644
--- a/lib/handshake.c
+++ b/lib/handshake.c
@@ -34,6 +34,7 @@
#include "mbuffers.h"
#include "kx.h"
#include "handshake.h"
+#include "handshake-msg.h"
#include "num.h"
#include "hash_int.h"
#include "db.h"
@@ -87,17 +88,6 @@ handshake_hash_buffer_empty(gnutls_session_t session)
}
static int
-handshake_hash_add_recvd(gnutls_session_t session,
- gnutls_handshake_description_t recv_type,
- uint8_t * header, uint16_t header_size,
- uint8_t * dataptr, uint32_t datalen);
-
-static int
-handshake_hash_add_sent(gnutls_session_t session,
- gnutls_handshake_description_t type,
- uint8_t * dataptr, uint32_t datalen);
-
-static int
recv_hello_verify_request(gnutls_session_t session,
uint8_t * data, int datalen);
@@ -756,11 +746,13 @@ int _gnutls_send_finished(gnutls_session_t session, int again)
ret =
_gnutls_send_handshake(session, bufel,
- GNUTLS_HANDSHAKE_FINISHED);
+ GNUTLS_HANDSHAKE_FINISHED,
+ NULL);
} else {
ret =
_gnutls_send_handshake(session, NULL,
- GNUTLS_HANDSHAKE_FINISHED);
+ GNUTLS_HANDSHAKE_FINISHED,
+ NULL);
}
return ret;
@@ -1005,7 +997,7 @@ _gnutls_send_empty_handshake(gnutls_session_t session,
} else
bufel = NULL;
- return _gnutls_send_handshake(session, bufel, type);
+ return _gnutls_send_handshake(session, bufel, type, NULL);
}
inline
@@ -1034,12 +1026,12 @@ inline
*/
int
_gnutls_send_handshake(gnutls_session_t session, mbuffer_st * bufel,
- gnutls_handshake_description_t type)
+ gnutls_handshake_description_t type,
+ struct handshake_msg_st *hs)
{
- int ret;
+ int pos = 0, ret;
uint8_t *data;
uint32_t datasize, i_datasize;
- int pos = 0;
if (bufel == NULL) {
/* we are resuming a previously interrupted
@@ -1047,7 +1039,6 @@ _gnutls_send_handshake(gnutls_session_t session, mbuffer_st * bufel,
*/
ret = _gnutls_handshake_io_write_flush(session);
return ret;
-
}
/* first run */
@@ -1081,16 +1072,23 @@ _gnutls_send_handshake(gnutls_session_t session, mbuffer_st * bufel,
session, _gnutls_handshake2str(type),
(long) datasize);
- /* Here we keep the handshake messages in order to hash them...
- */
- if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
- if ((ret =
- handshake_hash_add_sent(session, type, data,
- datasize)) < 0) {
- gnutls_assert();
+ if (hs) {
+ /*
+ * Use the given handshake buffer context
+ * to append handshake data to the buffer
+ */
+ ret = _gnutls_handshake_msg_commit_from_mbuffer(session, hs,
+ bufel,
+ 0, _mbuffer_get_uhead_size(bufel));
+ if (ret < 0) {
+ gnutls_assert_val(ret);
_mbuffer_xfree(&bufel);
return ret;
}
+ } else {
+ /* Just append the whole thing to the handshake buffer */
+ ret = _gnutls_handshake_hash_add_sent(session, type, data, datasize);
+ }
ret = call_hook_func(session, type, GNUTLS_HOOK_PRE, 0,
_mbuffer_get_udata_ptr(bufel), _mbuffer_get_udata_size(bufel));
@@ -1144,122 +1142,6 @@ _gnutls_send_handshake(gnutls_session_t session, mbuffer_st * bufel,
return ret;
}
-#define CHECK_SIZE(ll) \
- if ((session->internals.max_handshake_data_buffer_size > 0) && \
- (((ll) + session->internals.handshake_hash_buffer.length) > \
- session->internals.max_handshake_data_buffer_size)) { \
- _gnutls_debug_log("Handshake buffer length is %u (max: %u)\n", (unsigned)((ll) + session->internals.handshake_hash_buffer.length), (unsigned)session->internals.max_handshake_data_buffer_size); \
- return gnutls_assert_val(GNUTLS_E_HANDSHAKE_TOO_LARGE); \
- }
-
-/* This function add the handshake headers and the
- * handshake data to the handshake hash buffers. Needed
- * for the finished messages calculations.
- */
-static int
-handshake_hash_add_recvd(gnutls_session_t session,
- gnutls_handshake_description_t recv_type,
- uint8_t * header, uint16_t header_size,
- uint8_t * dataptr, uint32_t datalen)
-{
- int ret;
- const version_entry_st *vers = get_version(session);
-
- if (unlikely(vers == NULL))
- return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
-
- if ((vers->id != GNUTLS_DTLS0_9 &&
- recv_type == GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST) ||
- recv_type == GNUTLS_HANDSHAKE_HELLO_REQUEST)
- return 0;
-
- CHECK_SIZE(header_size + datalen);
-
- session->internals.handshake_hash_buffer_prev_len =
- session->internals.handshake_hash_buffer.length;
-
- if (vers->id != GNUTLS_DTLS0_9) {
- ret =
- _gnutls_buffer_append_data(&session->internals.
- handshake_hash_buffer,
- header, header_size);
- if (ret < 0)
- return gnutls_assert_val(ret);
- }
- if (datalen > 0) {
- ret =
- _gnutls_buffer_append_data(&session->internals.
- handshake_hash_buffer,
- dataptr, datalen);
- if (ret < 0)
- return gnutls_assert_val(ret);
- }
-
- /* save the size until client KX. That is because the TLS
- * session hash is calculated up to this message.
- */
- if (recv_type == GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE)
- session->internals.handshake_hash_buffer_client_kx_len =
- session->internals.handshake_hash_buffer.length;
- if (recv_type == GNUTLS_HANDSHAKE_FINISHED && session->security_parameters.entity == GNUTLS_CLIENT)
- session->internals.handshake_hash_buffer_server_finished_len =
- session->internals.handshake_hash_buffer.length;
-
- return 0;
-}
-
-/* This function will store the handshake message we sent.
- */
-static int
-handshake_hash_add_sent(gnutls_session_t session,
- gnutls_handshake_description_t type,
- uint8_t * dataptr, uint32_t datalen)
-{
- int ret;
- const version_entry_st *vers = get_version(session);
-
- if (unlikely(vers == NULL))
- return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
-
- /* We don't check for GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST because it
- * is not sent via that channel.
- */
- if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST) {
- CHECK_SIZE(datalen);
-
- if (vers->id == GNUTLS_DTLS0_9) {
- /* Old DTLS doesn't include the header in the MAC */
- if (datalen < 12) {
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
- }
- dataptr += 12;
- datalen -= 12;
-
- if (datalen == 0)
- return 0;
- }
-
- ret =
- _gnutls_buffer_append_data(&session->internals.
- handshake_hash_buffer,
- dataptr, datalen);
- if (ret < 0)
- return gnutls_assert_val(ret);
-
- if (type == GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE)
- session->internals.handshake_hash_buffer_client_kx_len =
- session->internals.handshake_hash_buffer.length;
- if (type == GNUTLS_HANDSHAKE_FINISHED && session->security_parameters.entity == GNUTLS_SERVER)
- session->internals.handshake_hash_buffer_server_finished_len =
- session->internals.handshake_hash_buffer.length;
-
- return 0;
- }
-
- return 0;
-}
-
/* This function will receive handshake messages of the given types,
* and will pass the message to the right place in order to be processed.
* E.g. for the SERVER_HELLO message (if it is expected), it will be
@@ -1292,7 +1174,7 @@ _gnutls_recv_handshake(gnutls_session_t session,
goto cleanup;
}
- ret = handshake_hash_add_recvd(session, hsk.htype,
+ ret = _gnutls_handshake_hash_add_recvd(session, hsk.htype,
hsk.header, hsk.header_size,
hsk.data.data,
hsk.data.length);
@@ -1876,7 +1758,7 @@ static int send_client_hello(gnutls_session_t session, int again)
return
_gnutls_send_handshake(session, bufel,
- GNUTLS_HANDSHAKE_CLIENT_HELLO);
+ GNUTLS_HANDSHAKE_CLIENT_HELLO, NULL);
cleanup:
_gnutls_buffer_clear(&extdata);
@@ -1992,7 +1874,7 @@ static int send_server_hello(gnutls_session_t session, int again)
ret =
_gnutls_send_handshake(session, bufel,
- GNUTLS_HANDSHAKE_SERVER_HELLO);
+ GNUTLS_HANDSHAKE_SERVER_HELLO, NULL);
fail:
_gnutls_buffer_clear(&buf);
@@ -2178,7 +2060,7 @@ static int _gnutls_send_supplemental(gnutls_session_t session, int again)
}
return _gnutls_send_handshake(session, bufel,
- GNUTLS_HANDSHAKE_SUPPLEMENTAL);
+ GNUTLS_HANDSHAKE_SUPPLEMENTAL, NULL);
}
static int _gnutls_recv_supplemental(gnutls_session_t session)