summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--devel/libgnutls-latest-x86_64.abi2
-rw-r--r--devel/symbols.last3
-rw-r--r--doc/Makefile.am4
-rw-r--r--doc/manpages/Makefile.am2
-rw-r--r--lib/includes/gnutls/gnutls.h.in5
-rw-r--r--lib/libgnutls.map9
-rw-r--r--lib/state.c67
-rw-r--r--tests/tls13-early-data.c33
9 files changed, 128 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 16ee97fb87..86e33edd58 100644
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,10 @@ See the end for copying conditions.
GNUTLS_NO_IMPLICIT_INIT to reflect the purpose (#1178). The former is now
deprecated and will be removed in the future releases.
+** API and ABI modifications:
+gnutls_early_cipher_get: Added
+gnutls_early_prf_hash_get: Added
+
* Version 3.7.1 (released 2021-03-10)
** libgnutls: Fixed potential use-after-free in sending "key_share"
diff --git a/devel/libgnutls-latest-x86_64.abi b/devel/libgnutls-latest-x86_64.abi
index ca32cbac7d..97a0184242 100644
--- a/devel/libgnutls-latest-x86_64.abi
+++ b/devel/libgnutls-latest-x86_64.abi
@@ -257,6 +257,8 @@
<elf-symbol name='gnutls_dtls_set_data_mtu' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_dtls_set_mtu' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_dtls_set_timeouts' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='gnutls_early_cipher_get' version='GNUTLS_3_7_2' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ <elf-symbol name='gnutls_early_prf_hash_get' version='GNUTLS_3_7_2' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_ecc_curve_get' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_ecc_curve_get_id' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='gnutls_ecc_curve_get_name' version='GNUTLS_3_4' is-default-version='yes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
diff --git a/devel/symbols.last b/devel/symbols.last
index a3482d25a6..963287687b 100644
--- a/devel/symbols.last
+++ b/devel/symbols.last
@@ -12,6 +12,7 @@ GNUTLS_3_6_6@GNUTLS_3_6_6
GNUTLS_3_6_8@GNUTLS_3_6_8
GNUTLS_3_6_9@GNUTLS_3_6_9
GNUTLS_3_7_0@GNUTLS_3_7_0
+GNUTLS_3_7_2@GNUTLS_3_7_2
_gnutls_global_init_skip@GNUTLS_3_4
gnutls_aead_cipher_decrypt@GNUTLS_3_4
gnutls_aead_cipher_decryptv2@GNUTLS_3_6_10
@@ -203,6 +204,8 @@ gnutls_dtls_prestate_set@GNUTLS_3_4
gnutls_dtls_set_data_mtu@GNUTLS_3_4
gnutls_dtls_set_mtu@GNUTLS_3_4
gnutls_dtls_set_timeouts@GNUTLS_3_4
+gnutls_early_cipher_get@GNUTLS_3_7_2
+gnutls_early_prf_hash_get@GNUTLS_3_7_2
gnutls_ecc_curve_get@GNUTLS_3_4
gnutls_ecc_curve_get_id@GNUTLS_3_4
gnutls_ecc_curve_get_name@GNUTLS_3_4
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 5301db7d88..562a85fa87 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -992,6 +992,10 @@ FUNCS += functions/gnutls_dtls_set_mtu
FUNCS += functions/gnutls_dtls_set_mtu.short
FUNCS += functions/gnutls_dtls_set_timeouts
FUNCS += functions/gnutls_dtls_set_timeouts.short
+FUNCS += functions/gnutls_early_cipher_get
+FUNCS += functions/gnutls_early_cipher_get.short
+FUNCS += functions/gnutls_early_prf_hash_get
+FUNCS += functions/gnutls_early_prf_hash_get.short
FUNCS += functions/gnutls_ecc_curve_get
FUNCS += functions/gnutls_ecc_curve_get.short
FUNCS += functions/gnutls_ecc_curve_get_id
diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
index 0cfec06b7a..cee5a9644a 100644
--- a/doc/manpages/Makefile.am
+++ b/doc/manpages/Makefile.am
@@ -298,6 +298,8 @@ APIMANS += gnutls_dtls_prestate_set.3
APIMANS += gnutls_dtls_set_data_mtu.3
APIMANS += gnutls_dtls_set_mtu.3
APIMANS += gnutls_dtls_set_timeouts.3
+APIMANS += gnutls_early_cipher_get.3
+APIMANS += gnutls_early_prf_hash_get.3
APIMANS += gnutls_ecc_curve_get.3
APIMANS += gnutls_ecc_curve_get_id.3
APIMANS += gnutls_ecc_curve_get_name.3
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index ca01fc9bdc..d69b29b443 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -1299,14 +1299,17 @@ gnutls_group_t gnutls_group_get(gnutls_session_t session);
/* get information on the current session */
gnutls_cipher_algorithm_t gnutls_cipher_get(gnutls_session_t session);
+gnutls_cipher_algorithm_t gnutls_early_cipher_get(gnutls_session_t session);
gnutls_kx_algorithm_t gnutls_kx_get(gnutls_session_t session);
gnutls_mac_algorithm_t gnutls_mac_get(gnutls_session_t session);
gnutls_digest_algorithm_t gnutls_prf_hash_get(const gnutls_session_t session);
+gnutls_digest_algorithm_t
+gnutls_early_prf_hash_get(const gnutls_session_t session);
gnutls_certificate_type_t
gnutls_certificate_type_get(gnutls_session_t session);
gnutls_certificate_type_t
gnutls_certificate_type_get2(gnutls_session_t session,
- gnutls_ctype_target_t target);
+ gnutls_ctype_target_t target);
int gnutls_sign_algorithm_get(gnutls_session_t session);
int gnutls_sign_algorithm_get_client(gnutls_session_t session);
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 0a4575f3fc..e6a19865b8 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -1346,6 +1346,15 @@ GNUTLS_3_7_0
*;
} GNUTLS_3_4;
+GNUTLS_3_7_2
+{
+ global:
+ gnutls_early_cipher_get;
+ gnutls_early_prf_hash_get;
+ local:
+ *;
+} GNUTLS_3_6_13;
+
GNUTLS_FIPS140_3_4 {
global:
gnutls_cipher_self_test;
diff --git a/lib/state.c b/lib/state.c
index 5836f81f21..f42c6ae6db 100644
--- a/lib/state.c
+++ b/lib/state.c
@@ -92,6 +92,40 @@ gnutls_cipher_algorithm_t gnutls_cipher_get(gnutls_session_t session)
}
/**
+ * gnutls_early_cipher_get:
+ * @session: is a #gnutls_session_t type.
+ *
+ * Get the cipher algorithm used for encrypting early data.
+ *
+ * Returns: the cipher used for early data, a
+ * #gnutls_cipher_algorithm_t type.
+ *
+ * Since: 3.7.2
+ **/
+gnutls_cipher_algorithm_t gnutls_early_cipher_get(gnutls_session_t session)
+{
+ const cipher_entry_st *ce;
+
+ if (!(session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT)) {
+ return gnutls_assert_val(GNUTLS_CIPHER_UNKNOWN);
+ }
+
+ if (unlikely(session->internals.
+ resumed_security_parameters.cs == NULL)) {
+ return gnutls_assert_val(GNUTLS_CIPHER_UNKNOWN);
+ }
+
+ ce = cipher_to_entry(session->internals.
+ resumed_security_parameters.
+ cs->block_algorithm);
+ if (unlikely(ce == NULL)) {
+ return gnutls_assert_val(GNUTLS_CIPHER_UNKNOWN);
+ }
+
+ return ce->id;
+}
+
+/**
* gnutls_certificate_type_get:
* @session: is a #gnutls_session_t type.
*
@@ -259,6 +293,39 @@ gnutls_prf_hash_get(const gnutls_session_t session)
return (gnutls_digest_algorithm_t)session->security_parameters.prf->id;
}
+/**
+ * gnutls_early_prf_hash_get:
+ * @session: is a #gnutls_session_t type.
+ *
+ * Get the hash algorithm used as a PRF to derive keys for encrypting
+ * early data in TLS 1.3.
+ *
+ * Returns: the hash algorithm used for early data, a
+ * #gnutls_digest_algorithm_t value.
+ *
+ * Since: 3.7.2
+ **/
+gnutls_digest_algorithm_t
+gnutls_early_prf_hash_get(const gnutls_session_t session)
+{
+ if (!(session->internals.hsk_flags & HSK_EARLY_DATA_IN_FLIGHT)) {
+ return gnutls_assert_val(GNUTLS_DIG_UNKNOWN);
+ }
+
+ if (unlikely(session->internals.
+ resumed_security_parameters.prf == NULL)) {
+ return gnutls_assert_val(GNUTLS_DIG_UNKNOWN);
+ }
+
+ if (unlikely(session->internals.
+ resumed_security_parameters.prf->id >= GNUTLS_MAC_AEAD)) {
+ return gnutls_assert_val(GNUTLS_DIG_UNKNOWN);
+ }
+
+ return (gnutls_digest_algorithm_t)session->internals.
+ resumed_security_parameters.prf->id;
+}
+
void reset_binders(gnutls_session_t session)
{
_gnutls_free_temp_key_datum(&session->key.binders[0].psk);
diff --git a/tests/tls13-early-data.c b/tests/tls13-early-data.c
index d26973e498..381ecbdb97 100644
--- a/tests/tls13-early-data.c
+++ b/tests/tls13-early-data.c
@@ -368,6 +368,25 @@ secret_callback(gnutls_session_t session,
if (level == GNUTLS_ENCRYPTION_LEVEL_EARLY) {
fail("early secret is set on initial connection\n");
}
+ } else {
+ if (level == GNUTLS_ENCRYPTION_LEVEL_EARLY) {
+ gnutls_cipher_algorithm_t cipher_algo;
+ gnutls_digest_algorithm_t digest_algo;
+
+ cipher_algo = gnutls_early_cipher_get(session);
+ if (cipher_algo != GNUTLS_CIPHER_AES_128_GCM) {
+ fail("unexpected cipher used for early data: %s != %s\n",
+ gnutls_cipher_get_name(cipher_algo),
+ gnutls_cipher_get_name(GNUTLS_CIPHER_AES_128_GCM));
+ }
+
+ digest_algo = gnutls_early_prf_hash_get(session);
+ if (digest_algo != GNUTLS_DIG_SHA256) {
+ fail("unexpected PRF hash used for early data: %s != %s\n",
+ gnutls_digest_get_name(digest_algo),
+ gnutls_digest_get_name(GNUTLS_DIG_SHA256));
+ }
+ }
}
if (secret_size > MAX_SECRET_SIZE) {
@@ -475,6 +494,13 @@ client(int sds[], const struct fixture *fixture)
&fixture->client_secrets[t]);
}
+ ret = gnutls_cipher_get(session);
+ if ((t == 0 && ret != GNUTLS_CIPHER_AES_128_GCM) ||
+ (t > 0 && ret != GNUTLS_CIPHER_CHACHA20_POLY1305)) {
+ fail("negotiated unexpected cipher: %s\n",
+ gnutls_cipher_get_name(ret));
+ }
+
if (t == 0) {
/* get the session data size */
ret =
@@ -664,6 +690,13 @@ server(int sds[], const struct fixture *fixture)
goto skip_early_data;
}
+ ret = gnutls_cipher_get(session);
+ if ((t == 0 && ret != GNUTLS_CIPHER_AES_128_GCM) ||
+ (t > 0 && ret != GNUTLS_CIPHER_CHACHA20_POLY1305)) {
+ fail("negotiated unexpected cipher: %s\n",
+ gnutls_cipher_get_name(ret));
+ }
+
#if TRACE == TRACE_SERVER
print_secrets(stderr, "server", fixture->name, t,
callback_data.secrets,