diff options
author | Ander Juaristi <a@juaristi.eus> | 2018-03-22 08:59:56 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-04-06 13:28:55 +0200 |
commit | 921cee23b4c7ee5d4e4537431e7fb1e9411be2d6 (patch) | |
tree | 3b1b423ea33220f41c49d7d5322fd505c4dfb55d /lib/handshake-tls13.c | |
parent | a046665a384a728253ad94122dfcbd25a52478c2 (diff) | |
download | gnutls-921cee23b4c7ee5d4e4537431e7fb1e9411be2d6.tar.gz |
Added support for out-of-band Pre-shared keys under TLS1.3
That adds support for pre-shared keys with and without Diffie-Hellman
key exchange. That's a modified version of initial Ander's patch.
Resolves #414
Resolves #125
Signed-off-by: Ander Juaristi <a@juaristi.eus>
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.org>
Diffstat (limited to 'lib/handshake-tls13.c')
-rw-r--r-- | lib/handshake-tls13.c | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/lib/handshake-tls13.c b/lib/handshake-tls13.c index edb6e80574..de14cf106e 100644 --- a/lib/handshake-tls13.c +++ b/lib/handshake-tls13.c @@ -204,14 +204,46 @@ static int generate_ap_traffic_keys(gnutls_session_t session) static int generate_hs_traffic_keys(gnutls_session_t session) { int ret; + unsigned null_key = 0; - if (unlikely(session->key.key.size == 0 || session->key.proto.tls13.temp_secret_size == 0)) + if (unlikely(session->key.proto.tls13.temp_secret_size == 0)) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); - ret = _tls13_update_secret(session, session->key.key.data, session->key.key.size); - if (ret < 0) { - gnutls_assert(); - return ret; + if ((session->security_parameters.entity == GNUTLS_CLIENT && + !(session->internals.hsk_flags & HSK_KEY_SHARE_RECEIVED)) || + (session->security_parameters.entity == GNUTLS_SERVER && + !(session->internals.hsk_flags & HSK_KEY_SHARE_SENT))) { + + if ((session->internals.hsk_flags & HSK_PSK_SELECTED) && + (session->internals.hsk_flags & HSK_PSK_KE_MODE_PSK)) { + null_key = 1; + } + } + + if (null_key) { + uint8_t digest[MAX_HASH_SIZE]; + unsigned digest_size; + + if (unlikely(session->security_parameters.prf == NULL)) + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + + digest_size = session->security_parameters.prf->output_size; + memset(digest, 0, digest_size); + + ret = _tls13_update_secret(session, digest, digest_size); + if (ret < 0) { + gnutls_assert(); + return ret; + } + } else { + if (unlikely(session->key.key.size == 0)) + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + + ret = _tls13_update_secret(session, session->key.key.data, session->key.key.size); + if (ret < 0) { + gnutls_assert(); + return ret; + } } ret = _tls13_connection_state_init(session, STAGE_HS); |