summaryrefslogtreecommitdiff
path: root/lib/ext/pre_shared_key.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ext/pre_shared_key.c')
-rw-r--r--lib/ext/pre_shared_key.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/lib/ext/pre_shared_key.c b/lib/ext/pre_shared_key.c
index 0d3468c40d..0fa7df2d27 100644
--- a/lib/ext/pre_shared_key.c
+++ b/lib/ext/pre_shared_key.c
@@ -58,20 +58,31 @@ compute_binder_key(const mac_entry_st *prf,
}
static int
-compute_psk_binder(unsigned entity,
+compute_psk_binder(gnutls_session_t session,
const mac_entry_st *prf, unsigned binders_length, unsigned hash_size,
int exts_length, int ext_offset,
const gnutls_datum_t *psk, const gnutls_datum_t *client_hello,
void *out)
{
int ret;
- unsigned extensions_len_pos;
+ unsigned client_hello_pos, extensions_len_pos;
gnutls_buffer_st handshake_buf;
uint8_t binder_key[MAX_HASH_SIZE];
_gnutls_buffer_init(&handshake_buf);
- if (entity == GNUTLS_CLIENT) {
+ if (session->security_parameters.entity == GNUTLS_CLIENT) {
+ if (session->internals.hsk_flags & HSK_HRR_RECEIVED) {
+ ret = gnutls_buffer_append_data(&handshake_buf,
+ (const void *) session->internals.handshake_hash_buffer.data,
+ session->internals.handshake_hash_buffer.length);
+ if (ret < 0) {
+ gnutls_assert();
+ goto error;
+ }
+ }
+
+ client_hello_pos = handshake_buf.length;
ret = gnutls_buffer_append_data(&handshake_buf,
(const void *) client_hello->data,
client_hello->size);
@@ -81,23 +92,40 @@ compute_psk_binder(unsigned entity,
}
/* This is a ClientHello message */
- handshake_buf.data[0] = GNUTLS_HANDSHAKE_CLIENT_HELLO;
+ handshake_buf.data[client_hello_pos] = GNUTLS_HANDSHAKE_CLIENT_HELLO;
/*
* At this point we have not yet added the binders to the ClientHello,
* but we have to overwrite the size field, pretending as if binders
* of the correct length were present.
*/
- _gnutls_write_uint24(handshake_buf.length + binders_length - 2, &handshake_buf.data[1]);
- _gnutls_write_uint16(handshake_buf.length + binders_length - ext_offset,
- &handshake_buf.data[ext_offset]);
+ _gnutls_write_uint24(handshake_buf.length - client_hello_pos + binders_length - 2, &handshake_buf.data[client_hello_pos + 1]);
+ _gnutls_write_uint16(handshake_buf.length - client_hello_pos + binders_length - ext_offset,
+ &handshake_buf.data[client_hello_pos + ext_offset]);
- extensions_len_pos = handshake_buf.length - exts_length - 2;
+ extensions_len_pos = handshake_buf.length - client_hello_pos - exts_length - 2;
_gnutls_write_uint16(exts_length + binders_length + 2,
- &handshake_buf.data[extensions_len_pos]);
+ &handshake_buf.data[client_hello_pos + extensions_len_pos]);
} else {
- if (unlikely(client_hello->size <= binders_length))
- return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
+ if (session->internals.hsk_flags & HSK_HRR_SENT) {
+ if (unlikely(session->internals.handshake_hash_buffer.length <= client_hello->size)) {
+ ret = gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
+ goto error;
+ }
+
+ ret = gnutls_buffer_append_data(&handshake_buf,
+ (const void *) session->internals.handshake_hash_buffer.data,
+ session->internals.handshake_hash_buffer.length - client_hello->size);
+ if (ret < 0) {
+ gnutls_assert();
+ goto error;
+ }
+ }
+
+ if (unlikely(client_hello->size <= binders_length)) {
+ ret = gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
+ goto error;
+ }
ret = gnutls_buffer_append_data(&handshake_buf,
(const void *) client_hello->data,
@@ -194,7 +222,7 @@ client_send_params(gnutls_session_t session,
client_hello.data = extdata->data+sizeof(mbuffer_st);
client_hello.size = extdata->length-sizeof(mbuffer_st);
- ret = compute_psk_binder(GNUTLS_CLIENT, prf,
+ ret = compute_psk_binder(session, prf,
hash_size+1, hash_size, extdata->length-pos,
ext_offset, &key, &client_hello,
binder_value);
@@ -314,7 +342,7 @@ static int server_recv_params(gnutls_session_t session,
/* Compute the binder value for this PSK */
prf = pskcred->binder_algo;
hash_size = prf->output_size;
- ret = compute_psk_binder(GNUTLS_SERVER, prf, psk_parser.binder_len+2, hash_size, 0, 0,
+ ret = compute_psk_binder(session, prf, psk_parser.binder_len+2, hash_size, 0, 0,
&key, &full_client_hello,
binder_value);
if (ret < 0) {