summaryrefslogtreecommitdiff
path: root/lib/handshake-tls13.c
diff options
context:
space:
mode:
authorAnder Juaristi <a@juaristi.eus>2018-03-22 08:59:56 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2018-04-06 13:28:55 +0200
commit921cee23b4c7ee5d4e4537431e7fb1e9411be2d6 (patch)
tree3b1b423ea33220f41c49d7d5322fd505c4dfb55d /lib/handshake-tls13.c
parenta046665a384a728253ad94122dfcbd25a52478c2 (diff)
downloadgnutls-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.c42
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);