summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2022-08-29 07:47:13 +0000
committerDaiki Ueno <ueno@gnu.org>2022-08-29 07:47:13 +0000
commitf3b1543fb13b607996652c1c1dadda2ccbeb8c02 (patch)
tree2f8a1bdf3c9b00bae6f488028895c05948e951f7
parentbc7f67c46736486426ba1bd22a52a67bd58beee5 (diff)
parent25beb4af246870b1f6c7e024aaf054ef18c9d8cf (diff)
downloadgnutls-f3b1543fb13b607996652c1c1dadda2ccbeb8c02.tar.gz
Merge branch 'wip/dueno/cb-fixes' into 'master'
doc: mention GNUTLS_CB_TLS_EXPORTER Closes #1391 See merge request gnutls/gnutls!1636
-rw-r--r--NEWS7
-rw-r--r--doc/cha-bib.texi4
-rw-r--r--doc/cha-gtls-app.texi9
-rw-r--r--doc/latex/gnutls.bib14
-rw-r--r--lib/state.c17
-rw-r--r--src/common.c65
6 files changed, 93 insertions, 23 deletions
diff --git a/NEWS b/NEWS
index f12a06defd..4595555829 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,13 @@ See the end for copying conditions.
1536, and 1792 bits), in addition to any modulus sizes larger than
2048 bits, according to SP800-131A rev2.
+** libgnutls: gnutls_session_channel_binding performs additional checks when
+ GNUTLS_CB_TLS_EXPORTER is requested. According to RFC9622 4.2, the
+ "tls-exporter" channel binding is only usable when the handshake is
+ bound to a unique master secret (i.e., either TLS 1.3 or extended
+ master secret extension is negotiated). Otherwise the function now
+ returns error.
+
* Version 3.7.7 (released 2022-07-28)
** libgnutls: Fixed double free during verification of pkcs7 signatures.
diff --git a/doc/cha-bib.texi b/doc/cha-bib.texi
index 4df5e98f90..20dab0a99f 100644
--- a/doc/cha-bib.texi
+++ b/doc/cha-bib.texi
@@ -275,4 +275,8 @@ Computer Science No. 1465 (Rafael Hirschfeld, ed.), February 1998),
pages 178--183, available from
@url{https://people.csail.mit.edu/rivest/Rivest-CanWeEliminateCertificateRevocationLists.pdf}.
+@item @anchor{RFC9266}[RFC9266]
+S. Whited, "Channel Bindings for TLS 1.3",
+July 2022, available from @url{https://www.ietf.org/rfc/rfc9266.txt}.
+
@end table
diff --git a/doc/cha-gtls-app.texi b/doc/cha-gtls-app.texi
index bd4447822b..56ca472ecd 100644
--- a/doc/cha-gtls-app.texi
+++ b/doc/cha-gtls-app.texi
@@ -2201,9 +2201,12 @@ background and discussion see @xcite{RFC5056}.
In @acronym{GnuTLS} you can extract a channel binding using the
@funcref{gnutls_session_channel_binding} function. Currently only the
-type @code{GNUTLS_CB_TLS_UNIQUE} is supported, which corresponds to
-the @code{tls-unique} channel binding for TLS defined in
-@xcite{RFC5929}.
+following types are supported:
+
+@itemize
+@item @code{GNUTLS_CB_TLS_UNIQUE}: corresponds to the @code{tls-unique} channel binding for TLS defined in @xcite{RFC5929}
+@item @code{GNUTLS_CB_TLS_EXPORTER}: corresponds to the @code{tls-exporter} channel binding for TLS defined in @xcite{RFC9266}
+@end itemize
The following example describes how to print the channel binding data.
Note that it must be run after a successful TLS handshake.
diff --git a/doc/latex/gnutls.bib b/doc/latex/gnutls.bib
index a30f079f3d..ee9dea0d4f 100644
--- a/doc/latex/gnutls.bib
+++ b/doc/latex/gnutls.bib
@@ -538,3 +538,17 @@
url="https://www.ietf.org/rfc/rfc4418.txt",
}
+@misc{rfc9266,
+ series = {Request for Comments},
+ number = 9266,
+ howpublished = {RFC 9266},
+ publisher = {RFC Editor},
+ doi = {10.17487/RFC9266},
+ url = {https://www.rfc-editor.org/info/rfc9266},
+ author = {Sam Whited},
+ title = {{Channel Bindings for TLS 1.3}},
+ pagetotal = 7,
+ year = 2022,
+ month = jul,
+ abstract = {This document defines a channel binding type, tls-exporter, that is compatible with TLS 1.3 in accordance with RFC 5056, "On the Use of Channel Bindings to Secure Channels". Furthermore, it updates the default channel binding to the new binding for versions of TLS greater than 1.2. This document updates RFCs 5801, 5802, 5929, and 7677.},
+} \ No newline at end of file
diff --git a/lib/state.c b/lib/state.c
index ee72646128..9e16d99300 100644
--- a/lib/state.c
+++ b/lib/state.c
@@ -1369,7 +1369,7 @@ gnutls_session_channel_binding(gnutls_session_t session,
if (cbtype == GNUTLS_CB_TLS_UNIQUE) {
const version_entry_st *ver = get_version(session);
if (unlikely(ver == NULL || ver->tls13_sem))
- return GNUTLS_E_INVALID_REQUEST;
+ return GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE;
cb->size = session->internals.cb_tls_unique_len;
cb->data = gnutls_malloc(cb->size);
@@ -1461,6 +1461,21 @@ gnutls_session_channel_binding(gnutls_session_t session,
#define EXPORTER_CTX_DATA ""
#define EXPORTER_CTX_LEN 0
+ const version_entry_st *ver = get_version(session);
+ if (unlikely(ver == NULL)) {
+ return GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE;
+ }
+
+ /* "tls-exporter" channel binding is defined only when
+ * the TLS handshake results in unique master secrets,
+ * i.e., either TLS 1.3, or TLS 1.2 with extended
+ * master secret negotiated.
+ */
+ if (!ver->tls13_sem &&
+ gnutls_session_ext_master_secret_status(session) == 0) {
+ return GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE;
+ }
+
cb->size = 32;
cb->data = gnutls_malloc(cb->size);
if (cb->data == NULL)
diff --git a/src/common.c b/src/common.c
index 827157424b..6d2056f95e 100644
--- a/src/common.c
+++ b/src/common.c
@@ -442,6 +442,51 @@ static void print_ecdh_info(gnutls_session_t session, const char *str, int print
}
+struct channel_binding_request {
+ gnutls_channel_binding_t type;
+ const char *name;
+};
+
+static void print_channel_bindings(gnutls_session_t session, int print)
+{
+ static const struct channel_binding_request requests[] = {
+ { GNUTLS_CB_TLS_UNIQUE, "tls-unique" },
+ { GNUTLS_CB_TLS_SERVER_END_POINT, "tls-server-end-point" },
+ { GNUTLS_CB_TLS_EXPORTER, "tls-exporter" }
+ };
+ size_t i;
+
+ if (!print) {
+ return;
+ }
+
+ log_msg(stdout, "- Channel bindings\n");
+ for (i = 0; i < sizeof(requests) / sizeof(requests[0]); i++) {
+ gnutls_datum_t cb;
+ int rc;
+
+ rc = gnutls_session_channel_binding(session,
+ requests[i].type,
+ &cb);
+ if (rc == GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE) {
+ log_msg(stdout, " - '%s': not available\n",
+ requests[i].name);
+ } else if (rc < 0) {
+ fprintf(stderr, " - '%s': error: %s\n",
+ requests[i].name, gnutls_strerror(rc));
+ } else {
+ size_t j;
+
+ log_msg(stdout, " - '%s': ",
+ requests[i].name);
+ for (j = 0; j < cb.size; j++)
+ log_msg(stdout, "%02x", cb.data[j]);
+ log_msg(stdout, "\n");
+ gnutls_free(cb.data);
+ }
+ }
+}
+
int print_info(gnutls_session_t session, int verbose, int flags)
{
const char *tmp;
@@ -599,25 +644,7 @@ int print_info(gnutls_session_t session, int verbose, int flags)
log_msg(stdout, "- Application protocol: %.*s\n", p.size, p.data);
#endif
- if (verbose) {
- gnutls_datum_t cb;
-
- rc = gnutls_session_channel_binding(session,
- GNUTLS_CB_TLS_EXPORTER,
- &cb);
- if (rc)
- fprintf(stderr, "Channel binding error: %s\n",
- gnutls_strerror(rc));
- else {
- size_t i;
-
- log_msg(stdout, "- Channel binding 'tls-exporter': ");
- for (i = 0; i < cb.size; i++)
- log_msg(stdout, "%02x", cb.data[i]);
- log_msg(stdout, "\n");
- gnutls_free(cb.data);
- }
- }
+ print_channel_bindings(session, verbose);
fflush(stdout);