summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-07-13 09:44:28 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-09-11 15:51:53 +0200
commit9e848e7bc752e785b68327805b9ebddee531c634 (patch)
tree2cf7591900d199b7f01a98b2773a539edaa25d39
parentacdba5bbc3501045e499bcc72f4fac96a8f0eed9 (diff)
downloadgnutls-9e848e7bc752e785b68327805b9ebddee531c634.tar.gz
Added support for post handshake auth extension
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--lib/ext/Makefile.am3
-rw-r--r--lib/ext/post_handshake.c87
-rw-r--r--lib/ext/post_handshake.h30
-rw-r--r--lib/extensions.c2
-rw-r--r--lib/gnutls_int.h4
-rw-r--r--lib/session_pack.c6
6 files changed, 131 insertions, 1 deletions
diff --git a/lib/ext/Makefile.am b/lib/ext/Makefile.am
index 8d75f9fd41..a97f204dce 100644
--- a/lib/ext/Makefile.am
+++ b/lib/ext/Makefile.am
@@ -41,7 +41,8 @@ libgnutls_ext_la_SOURCES = max_record.c \
session_ticket.c srp.c ecc.c ecc.h heartbeat.c heartbeat.h \
status_request.h status_request.c dumbfw.c dumbfw.h \
ext_master_secret.c ext_master_secret.h etm.h etm.c \
- supported_versions.c supported_versions.h
+ supported_versions.c supported_versions.h \
+ post_handshake.c post_handshake.h
if ENABLE_ALPN
libgnutls_ext_la_SOURCES += alpn.c alpn.h
diff --git a/lib/ext/post_handshake.c b/lib/ext/post_handshake.c
new file mode 100644
index 0000000000..04d1cb0d4a
--- /dev/null
+++ b/lib/ext/post_handshake.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/* This file contains the code for the Post-Handshake TLS 1.3 extension.
+ */
+
+#include "gnutls_int.h"
+#include "errors.h"
+#include "num.h"
+#include <extensions.h>
+#include <ext/post_handshake.h>
+#include "auth/cert.h"
+
+static int _gnutls_post_handshake_recv_params(gnutls_session_t session,
+ const uint8_t * data,
+ size_t data_size);
+static int _gnutls_post_handshake_send_params(gnutls_session_t session,
+ gnutls_buffer_st * extdata);
+
+const extension_entry_st ext_mod_post_handshake = {
+ .name = "Post Handshake Auth",
+ .type = GNUTLS_EXTENSION_POST_HANDSHAKE,
+ .parse_type = GNUTLS_EXT_TLS,
+
+ .recv_func = _gnutls_post_handshake_recv_params,
+ .send_func = _gnutls_post_handshake_send_params,
+ .pack_func = NULL,
+ .unpack_func = NULL,
+ .deinit_func = NULL,
+ .cannot_be_overriden = 1
+};
+
+static int
+_gnutls_post_handshake_recv_params(gnutls_session_t session,
+ const uint8_t * data, size_t _data_size)
+{
+ if (session->security_parameters.entity == GNUTLS_SERVER) {
+ session->security_parameters.post_handshake_auth = 1;
+ }
+
+ return 0;
+}
+
+/* returns data_size or a negative number on failure
+ */
+static int
+_gnutls_post_handshake_send_params(gnutls_session_t session,
+ gnutls_buffer_st * extdata)
+{
+ gnutls_certificate_credentials_t cred;
+
+ if (session->security_parameters.entity != GNUTLS_CLIENT) {
+ /* not sent on server side */
+ return 0;
+ }
+
+ cred = (gnutls_certificate_credentials_t)
+ _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE);
+ if (cred == NULL) /* no certificate authentication */
+ return gnutls_assert_val(0);
+
+ if (cred->ncerts || cred->get_cert_callback2 || cred->get_cert_callback)
+ return GNUTLS_E_INT_RET_0;
+ else
+ return 0;
+}
+
+
diff --git a/lib/ext/post_handshake.h b/lib/ext/post_handshake.h
new file mode 100644
index 0000000000..4f48930521
--- /dev/null
+++ b/lib/ext/post_handshake.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef EXT_POST_HANDSHAKE_H
+#define EXT_POST_HANDSHAKE_H
+
+#include <extensions.h>
+
+extern const extension_entry_st ext_mod_post_handshake;
+
+#endif
diff --git a/lib/extensions.c b/lib/extensions.c
index 1f835b497a..3dcfb30e2d 100644
--- a/lib/extensions.c
+++ b/lib/extensions.c
@@ -41,6 +41,7 @@
#include <ext/status_request.h>
#include <ext/ext_master_secret.h>
#include <ext/supported_versions.h>
+#include <ext/post_handshake.h>
#include <ext/srtp.h>
#include <ext/alpn.h>
#include <ext/dumbfw.h>
@@ -57,6 +58,7 @@ static extension_entry_st const *extfunc[MAX_EXT_TYPES+1] = {
&ext_mod_max_record_size,
&ext_mod_ext_master_secret,
&ext_mod_supported_versions,
+ &ext_mod_post_handshake,
&ext_mod_etm,
#ifdef ENABLE_OCSP
&ext_mod_status_request,
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 7a7880b9b4..03f5104f5b 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -286,6 +286,7 @@ typedef enum extensions_t {
GNUTLS_EXTENSION_EXT_MASTER_SECRET = 23,
GNUTLS_EXTENSION_SESSION_TICKET = 35,
GNUTLS_EXTENSION_SUPPORTED_VERSIONS = 43,
+ GNUTLS_EXTENSION_POST_HANDSHAKE = 49,
GNUTLS_EXTENSION_SAFE_RENEGOTIATION = 65281 /* aka: 0xff01 */
} extensions_t;
@@ -590,6 +591,9 @@ typedef struct {
uint8_t session_id_size;
time_t timestamp;
+ /* whether client has agreed in post handshake auth - only set on server side */
+ uint8_t post_handshake_auth;
+
/* The send size is the one requested by the programmer.
* The recv size is the one negotiated with the peer.
*/
diff --git a/lib/session_pack.c b/lib/session_pack.c
index 3bcff851d3..211307c6e7 100644
--- a/lib/session_pack.c
+++ b/lib/session_pack.c
@@ -773,6 +773,8 @@ pack_security_parameters(gnutls_session_t session, gnutls_buffer_st * ps)
BUFFER_APPEND_NUM(ps, 0);
}
+ BUFFER_APPEND_NUM(ps, session->security_parameters.post_handshake_auth);
+
BUFFER_APPEND_NUM(ps,
session->security_parameters.server_sign_algo);
BUFFER_APPEND_NUM(ps,
@@ -860,6 +862,8 @@ unpack_security_parameters(gnutls_session_t session, gnutls_buffer_st * ps)
session->internals.resumed_security_parameters.grp = _gnutls_id_to_group(ret);
/* it can be null */
+ BUFFER_POP_NUM(ps, session->security_parameters.post_handshake_auth);
+
BUFFER_POP_NUM(ps,
session->internals.resumed_security_parameters.
server_sign_algo);
@@ -975,6 +979,8 @@ gnutls_session_set_premaster(gnutls_session_t session, unsigned int entity,
session->internals.resumed_security_parameters.grp = 0;
+ session->internals.resumed_security_parameters.post_handshake_auth = 0;
+
session->internals.premaster_set = 1;
return 0;