diff options
Diffstat (limited to 'lib/handshake.c')
-rw-r--r-- | lib/handshake.c | 172 |
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) |