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.c82
1 files changed, 80 insertions, 2 deletions
diff --git a/lib/ext/pre_shared_key.c b/lib/ext/pre_shared_key.c
index 771092fa9c..436a426a87 100644
--- a/lib/ext/pre_shared_key.c
+++ b/lib/ext/pre_shared_key.c
@@ -24,6 +24,7 @@
#include "gnutls_int.h"
#include "auth/psk.h"
#include "handshake.h"
+#include "kx.h"
#include "secrets.h"
#include "tls13/anti_replay.h"
#include "tls13/psk_ext_parser.h"
@@ -189,6 +190,70 @@ error:
}
static int
+generate_early_secrets(gnutls_session_t session,
+ const mac_entry_st *prf)
+{
+ int ret;
+
+ ret = _tls13_derive_secret2(prf, EARLY_TRAFFIC_LABEL, sizeof(EARLY_TRAFFIC_LABEL)-1,
+ session->internals.handshake_hash_buffer.data,
+ session->internals.handshake_hash_buffer_client_hello_len,
+ session->key.proto.tls13.temp_secret,
+ session->key.proto.tls13.e_ckey);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ _gnutls_nss_keylog_write(session, "CLIENT_EARLY_TRAFFIC_SECRET",
+ session->key.proto.tls13.e_ckey,
+ prf->output_size);
+
+ ret = _tls13_derive_secret2(prf, EARLY_EXPORTER_MASTER_LABEL, sizeof(EARLY_EXPORTER_MASTER_LABEL)-1,
+ session->internals.handshake_hash_buffer.data,
+ session->internals.handshake_hash_buffer_client_hello_len,
+ session->key.proto.tls13.temp_secret,
+ session->key.proto.tls13.ap_expkey);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ _gnutls_nss_keylog_write(session, "EARLY_EXPORTER_SECRET",
+ session->key.proto.tls13.ap_expkey,
+ prf->output_size);
+
+ return 0;
+}
+
+/* Calculate TLS 1.3 Early Secret and the derived secrets from the
+ * selected PSK. */
+int
+_gnutls_generate_early_secrets_for_psk(gnutls_session_t session)
+{
+ const uint8_t *psk;
+ size_t psk_size;
+ const mac_entry_st *prf;
+ int ret;
+
+ psk = session->key.binders[0].psk.data;
+ psk_size = session->key.binders[0].psk.size;
+ prf = session->key.binders[0].prf;
+
+ if (unlikely(psk_size == 0))
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ ret = _tls13_init_secret2(prf, psk, psk_size,
+ session->key.proto.tls13.temp_secret);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ session->key.proto.tls13.temp_secret_size = prf->output_size;
+
+ ret = generate_early_secrets(session, session->key.binders[0].prf);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ return 0;
+}
+
+static int
client_send_params(gnutls_session_t session,
gnutls_buffer_t extdata,
const gnutls_psk_client_credentials_t cred)
@@ -651,6 +716,12 @@ static int server_recv_params(gnutls_session_t session,
session->key.binders[0].prf = prf;
session->key.binders[0].resumption = resuming;
+ ret = _gnutls_generate_early_secrets_for_psk(session);
+ if (ret < 0) {
+ gnutls_assert();
+ goto fail;
+ }
+
return 0;
fail:
@@ -742,6 +813,7 @@ static int _gnutls_psk_recv_params(gnutls_session_t session,
unsigned i;
gnutls_psk_server_credentials_t pskcred;
const version_entry_st *vers = get_version(session);
+ int ret;
if (!vers || !vers->tls13_sem)
return 0;
@@ -759,9 +831,15 @@ static int _gnutls_psk_recv_params(gnutls_session_t session,
_gnutls_handshake_log("EXT[%p]: selected PSK mode\n", session);
}
- /* ensure that selected binder is set on (our) index zero */
- if (i != 0)
+ /* different PSK is selected, than the one we calculated early secrets */
+ if (i != 0) {
+ /* ensure that selected binder is set on (our) index zero */
swap_binders(session);
+
+ ret = _gnutls_generate_early_secrets_for_psk(session);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ }
session->internals.hsk_flags |= HSK_PSK_SELECTED;
}
}