diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-07-13 09:44:28 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-09-25 07:46:59 +0200 |
commit | f6756b694b419ae5b5053856cf873245749273fc (patch) | |
tree | 156f80f7b6cdf17f1f6bf58f3b08ced4ea7a6bac | |
parent | 777ff7139079403cc54b6fc786a978862e3f0e80 (diff) | |
download | gnutls-f6756b694b419ae5b5053856cf873245749273fc.tar.gz |
Added support for post handshake auth extension
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r-- | lib/ext/Makefile.am | 3 | ||||
-rw-r--r-- | lib/ext/post_handshake.c | 87 | ||||
-rw-r--r-- | lib/ext/post_handshake.h | 30 | ||||
-rw-r--r-- | lib/extensions.c | 2 | ||||
-rw-r--r-- | lib/gnutls_int.h | 4 | ||||
-rw-r--r-- | lib/session_pack.c | 6 |
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 25f44d04fd..d20601a831 100644 --- a/lib/session_pack.c +++ b/lib/session_pack.c @@ -772,6 +772,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, @@ -859,6 +861,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); @@ -974,6 +978,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; |