<elf-symbol name='gnutls_handshake_set_private_extensions' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_handshake_set_random' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_handshake_set_read_function' version='GNUTLS_3_7_0' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='gnutls_handshake_set_secret_function' version='GNUTLS_3_7_0' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_handshake_set_timeout' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_handshake_write' version='GNUTLS_3_7_0' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_hash' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
gnutls_free(params);
}
+static int
+_gnutls_call_secret_func(gnutls_session_t session,
+ hs_stage_t stage,
+ bool for_read, bool for_write)
+{
+ const mac_entry_st *prf = NULL;
+ gnutls_record_encryption_level_t level;
+ void *secret_read = NULL, *secret_write = NULL;
+
+ if (session->internals.h_secret_func == NULL)
+ return 0;
+
+ switch (stage) {
+ case STAGE_EARLY:
+ prf = session->key.binders[0].prf;
+ level = GNUTLS_ENCRYPTION_LEVEL_EARLY;
+ if (for_read) {
+ if (unlikely(session->security_parameters.entity == GNUTLS_CLIENT))
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+ secret_read = session->key.proto.tls13.e_ckey;
+ }
+ break;
+ case STAGE_HS:
+ prf = session->security_parameters.prf;
+ level = GNUTLS_ENCRYPTION_LEVEL_HANDSHAKE;
+ if (for_read)
+ secret_read = session->security_parameters.
+ entity == GNUTLS_CLIENT ?
+ session->key.proto.tls13.hs_skey :
+ session->key.proto.tls13.hs_ckey;
+ if (for_write)
+ secret_write = session->security_parameters.
+ entity == GNUTLS_CLIENT ?
+ session->key.proto.tls13.hs_ckey :
+ session->key.proto.tls13.hs_skey;
+ break;
+ case STAGE_APP:
+ case STAGE_UPD_OURS:
+ case STAGE_UPD_PEERS:
+ prf = session->security_parameters.prf;
+ level = GNUTLS_ENCRYPTION_LEVEL_APPLICATION;
+ if (for_read)
+ secret_read = session->security_parameters.
+ entity == GNUTLS_CLIENT ?
+ session->key.proto.tls13.ap_skey :
+ session->key.proto.tls13.ap_ckey;
+ if (for_write)
+ secret_write = session->security_parameters.
+ entity == GNUTLS_CLIENT ?
+ session->key.proto.tls13.ap_ckey :
+ session->key.proto.tls13.ap_skey;
+ break;
+ default:
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+ }
+
+ return session->internals.h_secret_func(session, level,
+ secret_read, secret_write,
+ prf->output_size);
+}
+
int _tls13_connection_state_init(gnutls_session_t session, hs_stage_t stage)
{
const uint16_t epoch_next =
session->security_parameters.epoch_read = epoch_next;
session->security_parameters.epoch_write = epoch_next;
+ ret = _gnutls_call_secret_func(session, stage, 1, 1);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
return 0;
}
session->security_parameters.epoch_read = epoch_next;
+ ret = _gnutls_call_secret_func(session, stage, 1, 0);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
return 0;
}
session->security_parameters.epoch_write = epoch_next;
+ ret = _gnutls_call_secret_func(session, stage, 0, 1);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
return 0;
}
return 0;
}
+
+/**
+ * gnutls_handshake_set_secret_function:
+ * @session: is a #gnutls_session_t type.
+ * @func: the secret func
+ *
+ * This function will set a callback to be called when a new traffic
+ * secret is installed.
+ *
+ * Since: 3.7.0
+ */
+void
+gnutls_handshake_set_secret_function(gnutls_session_t session,
+ gnutls_handshake_secret_func func)
+{
+ session->internals.h_secret_func = func;
+}
gnutls_record_encryption_level_t level,
const void *data, size_t data_size);
+ /**
+ * gnutls_handshake_secret_func:
+ * @session: the current session
+ * @level: the encryption level
+ * @secret_read: the secret used for reading, can be %NULL if not set
+ * @secret_write: the secret used for writing, can be %NULL if not set
+ * @secret_size: the size of the secrets
+ *
+ * Function prototype for secret hooks. It is set using
+ * gnutls_handshake_set_secret_function().
+ *
+ * Returns: Non zero on error.
+ * Since: 3.7.0
+ */
+typedef int (*gnutls_handshake_secret_func) (gnutls_session_t session,
+ gnutls_record_encryption_level_t level,
+ const void *secret_read,
+ const void *secret_write,
+ size_t secret_size);
+
+void
+gnutls_handshake_set_secret_function(gnutls_session_t session,
+ gnutls_handshake_secret_func func);
+
/* FIPS140-2 related functions */
unsigned gnutls_fips140_mode_enabled(void);