diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-02-06 16:54:40 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-02-06 22:06:24 +0100 |
commit | 255743fe481668e05746bbe49d1f362cb0ee60f8 (patch) | |
tree | 4be7525c13a26e4ff5831ad4562115cac48a83eb | |
parent | 069f5e2f4e584d302d850eaf7207f8274d478b13 (diff) | |
download | gnutls-255743fe481668e05746bbe49d1f362cb0ee60f8.tar.gz |
Removed inner application extension.
-rw-r--r-- | NEWS | 41 | ||||
-rw-r--r-- | doc/Makefile.am | 17 | ||||
-rw-r--r-- | doc/cha-functions.texi | 2 | ||||
-rw-r--r-- | doc/cha-gtls-app.texi | 9 | ||||
-rw-r--r-- | doc/examples/Makefile.am | 1 | ||||
-rw-r--r-- | doc/examples/ex-client-tlsia.c | 161 | ||||
-rw-r--r-- | lib/gnutls_kx.c | 4 | ||||
-rw-r--r-- | libextra/Makefile.am | 5 | ||||
-rw-r--r-- | libextra/ext_inner_application.c | 266 | ||||
-rw-r--r-- | libextra/ext_inner_application.h | 64 | ||||
-rw-r--r-- | libextra/gnutls_extra.c | 7 | ||||
-rw-r--r-- | libextra/gnutls_ia.c | 1004 | ||||
-rw-r--r-- | libextra/libgnutls-extra.map | 20 | ||||
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rw-r--r-- | tests/tlsia.c | 586 |
15 files changed, 38 insertions, 2152 deletions
@@ -3,7 +3,10 @@ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. See the end for copying conditions. -* Version 2.11.7 (unreleased) +* Version 2.99.0 (unreleased) + +** libgnutls-extra: Inner application extension was removed. +It was never standardized nor published as an RFC. ** libgnutls: Added new certificate verification functions, that can provide more details and are more efficient. Check @@ -16,6 +19,36 @@ gnutls_x509_trust_list_*. using the --verify option. Combined with --load-ca-certificate it can verify a certificate chain against a list of certificates. +** API and ABI modifications: +gnutls_ext_register: REMOVED +gnutls_certificate_get_x509_crls: REMOVED +gnutls_certificate_get_x509_cas: REMOVED +gnutls_session_get_server_random: REMOVED +gnutls_session_get_client_random: REMOVED +gnutls_session_get_master_secret: REMOVED +gnutls_ia_allocate_client_credentials: REMOVED +gnutls_ia_allocate_server_credentials: REMOVED +gnutls_ia_enable: REMOVED +gnutls_ia_endphase_send: REMOVED +gnutls_ia_extract_inner_secret: REMOVED +gnutls_ia_free_client_credentials: REMOVED +gnutls_ia_free_server_credentials: REMOVED +gnutls_ia_generate_challenge: REMOVED +gnutls_ia_get_client_avp_ptr: REMOVED +gnutls_ia_get_server_avp_ptr: REMOVED +gnutls_ia_handshake: REMOVED +gnutls_ia_handshake_p: REMOVED +gnutls_ia_permute_inner_secret: REMOVED +gnutls_ia_recv: REMOVED +gnutls_ia_send: REMOVED +gnutls_ia_set_client_avp_function: REMOVED +gnutls_ia_set_client_avp_ptr: REMOVED +gnutls_ia_set_server_avp_function: REMOVED +gnutls_ia_set_server_avp_ptr: REMOVED +gnutls_ia_verify_endphase: REMOVED + +* Version 2.11.7 + ** libgnutls: The deprecated gnutls_x509_privkey_sign_hash() was replaced by gnutls_privkey_sign_hash2(). @@ -79,12 +112,6 @@ gnutls_openpgp_privkey_sign_hash: DEPRECATED (use: gnutls_privkey_sign_hash2) gnutls_pkcs11_privkey_sign_hash: REMOVED (was added in 2.11.0) gnutls_pkcs11_privkey_decrypt_data: REMOVED (was added in 2.11.0) gnutls_privkey_sign_hash: REMOVED (was added in 2.11.0) -gnutls_ext_register: REMOVED -gnutls_certificate_get_x509_crls: REMOVED -gnutls_certificate_get_x509_cas: REMOVED -gnutls_session_get_server_random: REMOVED -gnutls_session_get_client_random: REMOVED -gnutls_session_get_master_secret: REMOVED * Version 2.11.6 (released 2010-12-06) diff --git a/doc/Makefile.am b/doc/Makefile.am index ec1a5dbefa..f1b1002a8b 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -40,7 +40,7 @@ gnutls_TEXINFOS = gnutls.texi fdl-1.3.texi lgpl-2.1.texi gpl-3.0.texi \ gnutls_TEXINFOS += examples/ex-client1.c examples/ex-client2.c \ examples/ex-session-info.c examples/ex-verify.c \ examples/ex-cert-select.c examples/ex-client-resume.c \ - examples/ex-client-srp.c examples/ex-client-tlsia.c \ + examples/ex-client-srp.c \ examples/ex-rfc2818.c examples/ex-serv1.c \ examples/ex-serv-anon.c \ examples/ex-serv-pgp.c examples/ex-serv-srp.c \ @@ -100,9 +100,9 @@ MAINTAINERCLEANFILES = # Generated texinfos. -gnutls_TEXINFOS += gnutls-api.texi extra-api.texi ia-api.texi \ +gnutls_TEXINFOS += gnutls-api.texi extra-api.texi \ x509-api.texi pgp-api.texi -MAINTAINERCLEANFILES += gnutls-api.texi extra-api.texi ia-api.texi \ +MAINTAINERCLEANFILES += gnutls-api.texi extra-api.texi \ x509-api.texi pgp-api.texi gnutls-api.texi: $(srcdir)/../lib/*.c @@ -149,17 +149,6 @@ extra-api.texi: $(srcdir)/../libextra/gnutls_extra.c rm -f $@-tmp mv -f $@-tmp2 $@ -ia-api.texi: $(srcdir)/../libextra/gnutls_ia.c - echo "" > $@-tmp - for i in $^; do \ - echo -n "Creating documentation for file $$i... " && \ - $(srcdir)/scripts/gdoc -texinfo $$i >> $@-tmp && \ - echo "ok"; \ - done - $(srcdir)/scripts/sort2.pl < $@-tmp > $@-tmp2 - rm -f $@-tmp - mv -f $@-tmp2 $@ - # Generated texinfos. gnutls_TEXINFOS += error_codes.texi algorithms.texi diff --git a/doc/cha-functions.texi b/doc/cha-functions.texi index f73bc571e9..d0260ba395 100644 --- a/doc/cha-functions.texi +++ b/doc/cha-functions.texi @@ -105,8 +105,6 @@ The control flow in a typical server is similar to the above, use @code{gnutls_ia_client_credentials_t}, and replace the call to the client functions with the corresponding server functions. -@include ia-api.texi - @node Error codes and descriptions @section Error Codes and Descriptions @anchor{Error Codes} diff --git a/doc/cha-gtls-app.texi b/doc/cha-gtls-app.texi index 16a5da1475..3f907e205c 100644 --- a/doc/cha-gtls-app.texi +++ b/doc/cha-gtls-app.texi @@ -182,7 +182,6 @@ implemented by another example. * Client using a PKCS #11 token with TLS:: * Client with Resume capability example:: * Simple client example with SRP authentication:: -* Simple client example with TLS/IA support:: * Simple client example in C++:: * Helper function for TCP connections:: @end menu @@ -286,14 +285,6 @@ itself using a certificate, and in that case it has to be verified. @verbatiminclude examples/ex-client-srp.c -@node Simple client example with TLS/IA support -@subsection Simple Client Example with @acronym{TLS/IA} Support - -The following client is a simple client which uses the -@acronym{TLS/IA} extension to authenticate with the server. - -@verbatiminclude examples/ex-client-tlsia.c - @node Simple client example in C++ @subsection Simple Client Example using the C++ API diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am index 9a19409c7f..ef9d1d6f56 100644 --- a/doc/examples/Makefile.am +++ b/doc/examples/Makefile.am @@ -56,7 +56,6 @@ endif if ENABLE_ANON noinst_PROGRAMS += ex-client1 ex-serv-anon -noinst_PROGRAMS += ex-client-tlsia endif if ENABLE_OPENPGP diff --git a/doc/examples/ex-client-tlsia.c b/doc/examples/ex-client-tlsia.c deleted file mode 100644 index 99d36402af..0000000000 --- a/doc/examples/ex-client-tlsia.c +++ /dev/null @@ -1,161 +0,0 @@ -/* This example code is placed in the public domain. */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <arpa/inet.h> -#include <unistd.h> -#include <gnutls/gnutls.h> -#include <gnutls/extra.h> - -/* A basic TLS client, with anonymous authentication and TLS/IA handshake. - */ - -#define MAX_BUF 1024 -#define MSG "GET / HTTP/1.0\r\n\r\n" - -extern int tcp_connect (void); -extern void tcp_close (int sd); - -static int -client_avp (gnutls_session_t session, void *ptr, - const char *last, size_t lastlen, char **new, size_t * newlen) -{ - - if (last) - printf ("- received %d bytes AVP: `%.*s'\n", - (int) lastlen, (int) lastlen, last); - else - printf ("- new application phase\n"); - - *new = gnutls_strdup ("client avp"); - if (!*new) - return -1; - *newlen = strlen (*new); - - printf ("- sending %d bytes AVP: `%s'\n", (int) *newlen, *new); - - gnutls_ia_permute_inner_secret (session, 3, "foo"); - - return 0; - -} - -int -main (void) -{ - int ret, sd, ii; - gnutls_session_t session; - char buffer[MAX_BUF + 1]; - gnutls_anon_client_credentials_t anoncred; - gnutls_ia_client_credentials_t iacred; - /* Need to enable anonymous KX specifically. */ - - gnutls_global_init (); - - gnutls_anon_allocate_client_credentials (&anoncred); - gnutls_ia_allocate_client_credentials (&iacred); - - /* Set TLS/IA stuff - */ - gnutls_ia_set_client_avp_function (iacred, client_avp); - - /* Initialize TLS session - */ - gnutls_init (&session, GNUTLS_CLIENT); - - /* Use default priorities */ - gnutls_priority_set_direct (session, "NORMAL:+ANON-DH", NULL); - - /* put the anonymous and TLS/IA credentials to the current session - */ - gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred); - gnutls_credentials_set (session, GNUTLS_CRD_IA, iacred); - - /* connect to the peer - */ - sd = tcp_connect (); - - gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd); - - /* Perform the TLS handshake - */ - ret = gnutls_handshake (session); - - if (ret < 0) - { - fprintf (stderr, "*** Handshake failed\n"); - gnutls_perror (ret); - goto end; - } - else - { - printf ("- Handshake was completed\n"); - } - - if (!gnutls_ia_handshake_p (session)) - { - fprintf (stderr, "*** TLS/IA not negotiated...\n"); - goto end; - } - else - { - printf ("- Starting TLS/IA handshake...\n"); - - ret = gnutls_ia_handshake (session); - - if (ret < 0) - { - fprintf (stderr, "*** TLS/IA handshake failed\n"); - gnutls_perror (ret); - goto end; - } - else - { - printf ("- TLS/IA Handshake was completed\n"); - } - } - - - gnutls_record_send (session, MSG, strlen (MSG)); - - ret = gnutls_record_recv (session, buffer, MAX_BUF); - if (ret == 0) - { - printf ("- Peer has closed the TLS connection\n"); - goto end; - } - else if (ret < 0) - { - fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret)); - goto end; - } - - printf ("- Received %d bytes: ", ret); - for (ii = 0; ii < ret; ii++) - { - fputc (buffer[ii], stdout); - } - fputs ("\n", stdout); - - gnutls_bye (session, GNUTLS_SHUT_RDWR); - -end: - - tcp_close (sd); - - gnutls_deinit (session); - - gnutls_ia_free_client_credentials (iacred); - gnutls_anon_free_client_credentials (anoncred); - - gnutls_global_deinit (); - - return 0; -} diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c index e24292c0bf..99be1f4635 100644 --- a/lib/gnutls_kx.c +++ b/lib/gnutls_kx.c @@ -39,7 +39,6 @@ #include <gnutls_datum.h> #include <gnutls_rsa_export.h> #include <gnutls_mbuffers.h> -#include "../libextra/ext_inner_application.h" /* isn't this too much? */ /* This is a temporary function to be used before the generate_* internal API is changed to use mbuffers. For now we don't avoid the @@ -140,9 +139,6 @@ generate_normal_master (gnutls_session_t session, int keep_premaster) session->security_parameters.master_secret); } - /* TLS/IA inner secret is derived from the master secret. */ - _gnutls_ia_derive_inner_secret (session); - if (!keep_premaster) _gnutls_free_datum (&PREMASTER); diff --git a/libextra/Makefile.am b/libextra/Makefile.am index fd95a9e95f..665d0ec51f 100644 --- a/libextra/Makefile.am +++ b/libextra/Makefile.am @@ -84,11 +84,6 @@ endif libgnutls_extra_la_LIBADD = $(LIBSOCKET) libgnutls_extra_la_LDFLAGS = -no-undefined -# TLS/IA - -libgnutls_extra_la_SOURCES += \ - ext_inner_application.h ext_inner_application.c gnutls_ia.c - # Rest if HAVE_LD_OUTPUT_DEF diff --git a/libextra/ext_inner_application.c b/libextra/ext_inner_application.c deleted file mode 100644 index 329e4ec9a7..0000000000 --- a/libextra/ext_inner_application.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2008, 2010 Free Software Foundation, Inc. - * - * Author: Simon Josefsson - * - * This file is part of GnuTLS-EXTRA. - * - * GnuTLS-extra is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * GnuTLS-extra 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - * <http://www.gnu.org/licenses/>. - * - */ - -#include "gnutls_int.h" -#include "gnutls_auth.h" -#include "gnutls_errors.h" -#include "gnutls_num.h" -#include "ext_inner_application.h" -#include <gnutls/extra.h> - -#define NO 0 -#define YES 1 - -static int _gnutls_inner_application_recv_params (gnutls_session_t session, - const opaque * data, - size_t data_size); -static int _gnutls_inner_application_send_params (gnutls_session_t session, - opaque * data, size_t); -static int ia_unpack (gnutls_buffer_st * ps, extension_priv_data_t * _priv); -static int ia_pack (extension_priv_data_t _priv, gnutls_buffer_st * ps); -static void ia_deinit_data (extension_priv_data_t priv); - -extension_entry_st ext_mod_ia = { - .name = "INNER APPLICATION", - .type = GNUTLS_EXTENSION_INNER_APPLICATION, - .parse_type = GNUTLS_EXT_TLS, - - .recv_func = _gnutls_inner_application_recv_params, - .send_func = _gnutls_inner_application_send_params, - .pack_func = ia_pack, - .unpack_func = ia_unpack, - .deinit_func = ia_deinit_data, -}; - -static int -_gnutls_inner_application_recv_params (gnutls_session_t session, - const opaque * data, size_t data_size) -{ - extension_priv_data_t epriv; - ia_ext_st *priv; - int ret; - - if (data_size != 1) - { - gnutls_assert (); - return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; - } - - ret = - _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_INNER_APPLICATION, - &epriv); - if (ret < 0) - { - priv = gnutls_calloc (1, sizeof (*priv)); - if (priv == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - epriv.ptr = priv; - _gnutls_ext_set_session_data (session, - GNUTLS_EXTENSION_INNER_APPLICATION, - epriv); - } - else - priv = epriv.ptr; - - priv->flags |= IA_PEER_ENABLE; - priv->flags &= ~IA_PEER_ALLOW_SKIP; - - switch ((unsigned char) *data) - { - case NO: /* Peer's ia_on_resume == no */ - priv->flags |= IA_PEER_ALLOW_SKIP; - break; - - case YES: - break; - - default: - gnutls_assert (); - } - - - return 0; -} - - -/* returns data_size or a negative number on failure - */ -static int -_gnutls_inner_application_send_params (gnutls_session_t session, - opaque * data, size_t data_size) -{ - extension_priv_data_t epriv; - ia_ext_st *priv = NULL; - int ret; - - ret = - _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_INNER_APPLICATION, - &epriv); - if (ret < 0) - { - priv = gnutls_calloc (1, sizeof (*priv)); - if (priv == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - epriv.ptr = priv; - _gnutls_ext_set_session_data (session, - GNUTLS_EXTENSION_INNER_APPLICATION, - epriv); - } - else - priv = epriv.ptr; - - /* Set ext->gnutls_ia_enable depending on whether we have a TLS/IA - credential in the session. */ - - if (session->security_parameters.entity == GNUTLS_CLIENT) - { - gnutls_ia_client_credentials_t cred = (gnutls_ia_client_credentials_t) - _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL); - - if (cred) - priv->flags |= IA_ENABLE; - } - else /* SERVER */ - { - gnutls_ia_server_credentials_t cred; - - cred = (gnutls_ia_server_credentials_t) - _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL); - - if (cred) - priv->flags |= IA_PEER_ENABLE; - } - - /* If we don't want gnutls_ia locally, or we are a server and the - * client doesn't want it, don't advertise TLS/IA support at all, as - * required. */ - - if (!(priv->flags & IA_ENABLE)) - return 0; - - if (session->security_parameters.entity == GNUTLS_SERVER && - !(priv->flags & IA_PEER_ENABLE)) - return 0; - - /* We'll advertise. Check if there's room in the hello buffer. */ - - if (data_size < 1) - { - gnutls_assert (); - return GNUTLS_E_SHORT_MEMORY_BUFFER; - } - - /* default: require new application phase */ - - *data = YES; - - if (session->security_parameters.entity == GNUTLS_CLIENT) - { - - /* Client: value follows local setting */ - - if (priv->flags & IA_ALLOW_SKIP) - *data = NO; - } - else - { - - /* Server: value follows local setting and client's setting, but only - * if we are resuming. - * - * XXX Can server test for resumption at this stage? - * - * Ai! It seems that read_client_hello only calls parse_extensions if - * we're NOT resuming! That would make us automatically violate the IA - * draft; if we're resuming, we must first learn what the client wants - * -- IA or no IA -- and then prepare our response. Right now we'll - * always skip IA on resumption, because recv_ext isn't even called - * to record the peer's support for IA at all. Simon? */ - - if ((priv->flags & IA_ALLOW_SKIP) && - (priv->flags & IA_PEER_ALLOW_SKIP) && - session->internals.resumed == RESUME_TRUE) - *data = NO; - } - - return 1; -} - -static void -ia_deinit_data (extension_priv_data_t priv) -{ - gnutls_free (priv.ptr); -} - -static int -ia_pack (extension_priv_data_t epriv, gnutls_buffer_st * ps) -{ - ia_ext_st *priv = epriv.ptr; - int ret; - - BUFFER_APPEND_NUM (ps, priv->flags); - BUFFER_APPEND_PFX (ps, priv->inner_secret, GNUTLS_MASTER_SIZE); - - return 0; -} - -static int -ia_unpack (gnutls_buffer_st * ps, extension_priv_data_t * _priv) -{ - ia_ext_st *priv; - int size, ret; - extension_priv_data_t epriv; - - priv = gnutls_calloc (1, sizeof (*priv)); - if (priv == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - BUFFER_POP_NUM (ps, priv->flags); - BUFFER_POP_NUM (ps, size); - if (size != GNUTLS_MASTER_SIZE) - { - gnutls_assert (); - return GNUTLS_E_PARSING_ERROR; - } - BUFFER_POP (ps, priv->inner_secret, GNUTLS_MASTER_SIZE); - - epriv.ptr = priv; - *_priv = epriv; - - return 0; - -error: - gnutls_free (priv); - return ret; -} diff --git a/libextra/ext_inner_application.h b/libextra/ext_inner_application.h deleted file mode 100644 index a137c08c2d..0000000000 --- a/libextra/ext_inner_application.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2005, 2008, 2010 Free Software Foundation, Inc. - * - * Author: Simon Josefsson - * - * This file is part of GnuTLS-EXTRA. - * - * GnuTLS-extra is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * GnuTLS-extra 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - * <http://www.gnu.org/licenses/>. - * - */ - -#ifndef EXT_IA_H -#define EXT_IA_H - -#include <gnutls_extensions.h> - -#define IA_PEER_ENABLE (1 << 1) -#define IA_PEER_ALLOW_SKIP (1 << 2) -#define IA_ENABLE (1 << 3) -#define IA_ALLOW_SKIP (1 << 4) - -extension_entry_st ext_mod_ia; - -typedef struct -{ - unsigned int flags; - /* For TLS/IA. XXX: Move to IA credential? */ - opaque inner_secret[GNUTLS_MASTER_SIZE]; -} ia_ext_st; - -inline static void -_gnutls_ia_derive_inner_secret (gnutls_session_t session) -{ - extension_priv_data_t epriv; - ia_ext_st *priv; - int ret; - - ret = - _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_INNER_APPLICATION, - &epriv); - if (ret < 0) - { - return; - } - priv = epriv.ptr; - - memcpy (priv->inner_secret, - session->security_parameters.master_secret, GNUTLS_MASTER_SIZE); - -} - -#endif diff --git a/libextra/gnutls_extra.c b/libextra/gnutls_extra.c index e890fbf43f..4887053baf 100644 --- a/libextra/gnutls_extra.c +++ b/libextra/gnutls_extra.c @@ -25,7 +25,6 @@ #include <gnutls_errors.h> #include <gnutls_extensions.h> #include <gnutls_algorithms.h> -#include <ext_inner_application.h> #ifdef HAVE_GCRYPT #include <gcrypt.h> @@ -110,8 +109,6 @@ static int _gnutls_init_extra = 0; int gnutls_global_init_extra (void) { - int ret; - /* If the version of libgnutls != version of * libextra, then do not initialize the library. * This is because it may break things. @@ -126,10 +123,6 @@ gnutls_global_init_extra (void) if (_gnutls_init_extra != 1) return 0; - ret = _gnutls_ext_register (&ext_mod_ia); - if (ret != GNUTLS_E_SUCCESS) - return ret; - /* Initialize the LZO library */ #ifdef USE_LZO diff --git a/libextra/gnutls_ia.c b/libextra/gnutls_ia.c deleted file mode 100644 index e692bde43f..0000000000 --- a/libextra/gnutls_ia.c +++ /dev/null @@ -1,1004 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2008, 2009, 2010 Free Software Foundation, - * Inc. - * - * Author: Simon Josefsson - * - * This file is part of GnuTLS-EXTRA. - * - * GnuTLS-extra is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GnuTLS-extra 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "gnutls_int.h" -#include "gnutls_record.h" -#include "gnutls_errors.h" -#include "gnutls_num.h" -#include "gnutls_state.h" -#include <gnutls/extra.h> -#include <ext_inner_application.h> - -#define CHECKSUM_SIZE 12 - -struct gnutls_ia_client_credentials_st -{ - gnutls_ia_avp_func avp_func; - void *avp_ptr; -}; - -struct gnutls_ia_server_credentials_st -{ - gnutls_ia_avp_func avp_func; - void *avp_ptr; -}; - -static const char server_finished_label[] = "server phase finished"; -static const char client_finished_label[] = "client phase finished"; -static const char inner_permutation_label[] = "inner secret permutation"; -static const char challenge_label[] = "inner application challenge"; - -/* - * The TLS/IA packet is the InnerApplication token, described as - * follows in draft-funk-tls-inner-application-extension-01.txt: - * - * enum { - * application_payload(0), intermediate_phase_finished(1), - * final_phase_finished(2), (255) - * } InnerApplicationType; - * - * struct { - * InnerApplicationType msg_type; - * uint24 length; - * select (InnerApplicationType) { - * case application_payload: ApplicationPayload; - * case intermediate_phase_finished: IntermediatePhaseFinished; - * case final_phase_finished: FinalPhaseFinished; - * } body; - * } InnerApplication; - * - */ - -/* Send TLS/IA data. If data==NULL && sizeofdata==NULL, then the last - send was interrupted for some reason, and then we try to send it - again. Returns the number of bytes sent, or an error code. If - this return E_AGAIN and E_INTERRUPTED, call this function again - with data==NULL&&sizeofdata=0NULL until it returns successfully. */ -static ssize_t -_gnutls_send_inner_application (gnutls_session_t session, - gnutls_ia_apptype_t msg_type, - const char *data, size_t sizeofdata) -{ - opaque *p = NULL; - size_t plen = 0; - ssize_t len; - - if (data != NULL) - { - plen = sizeofdata + 4; - p = gnutls_malloc (plen); - if (!p) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - *(unsigned char *) p = (unsigned char) (msg_type & 0xFF); - _gnutls_write_uint24 (sizeofdata, p + 1); - memcpy (p + 4, data, sizeofdata); - } - - len = - _gnutls_send_int (session, GNUTLS_INNER_APPLICATION, -1, - EPOCH_WRITE_CURRENT, p, plen, MBUFFER_FLUSH); - - if (p) - gnutls_free (p); - - return len; -} - -/* Receive TLS/IA data. Store received TLS/IA message type in - *MSG_TYPE, and the data in DATA of max SIZEOFDATA size. Return the - number of bytes read, or an error code. */ -static ssize_t -_gnutls_recv_inner_application (gnutls_session_t session, - gnutls_ia_apptype_t * msg_type, - opaque * data, size_t sizeofdata) -{ - ssize_t len; - uint32_t len24; - opaque pkt[4]; - - len = _gnutls_recv_int (session, GNUTLS_INNER_APPLICATION, -1, pkt, 4); - if (len != 4) - { - gnutls_assert (); - return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; - } - - *msg_type = pkt[0]; - len24 = _gnutls_read_uint24 (&pkt[1]); - - if (*msg_type != GNUTLS_IA_APPLICATION_PAYLOAD && len24 != CHECKSUM_SIZE) - { - gnutls_assert (); - return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; - } - - if (sizeofdata < len24) - { - /* XXX push back pkt to IA buffer? */ - gnutls_assert (); - return GNUTLS_E_SHORT_MEMORY_BUFFER; - } - - if (len24 > 0) - { - uint32_t tmplen = len24; - - len24 = _gnutls_recv_int (session, GNUTLS_INNER_APPLICATION, -1, - data, tmplen); - if (len24 != tmplen) - { - gnutls_assert (); - /* XXX Correct? */ - return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; - } - } - - return len24; -} - -/* Apply the TLS PRF using the TLS/IA inner secret as keying material, - where the seed is the client random concatenated with the server - random concatenated EXTRA of EXTRA_SIZE length (which can be NULL/0 - respectively). LABEL and LABEL_SIZE is used as the label. The - result is placed in pre-allocated OUT of OUTSIZE length. */ -static int -_gnutls_ia_prf (gnutls_session_t session, - size_t label_size, - const char *label, - size_t extra_size, - const char *extra, size_t outsize, opaque * out) -{ - int ret; - opaque *seed; - size_t seedsize = 2 * GNUTLS_RANDOM_SIZE + extra_size; - extension_priv_data_t epriv; - ia_ext_st *priv; - - ret = - _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_INNER_APPLICATION, - &epriv); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - priv = epriv.ptr; - - seed = gnutls_malloc (seedsize); - if (!seed) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - memcpy (seed, session->security_parameters.server_random, - GNUTLS_RANDOM_SIZE); - memcpy (seed + GNUTLS_RANDOM_SIZE, - session->security_parameters.client_random, GNUTLS_RANDOM_SIZE); - memcpy (seed + 2 * GNUTLS_RANDOM_SIZE, extra, extra_size); - - ret = _gnutls_PRF (session, priv->inner_secret, - GNUTLS_MASTER_SIZE, - label, label_size, seed, seedsize, outsize, out); - - gnutls_free (seed); - - return ret; -} - -/** - * gnutls_ia_permute_inner_secret: - * @session: is a #gnutls_session_t structure. - * @session_keys_size: Size of generated session keys (0 if none). - * @session_keys: Generated session keys, used to permute inner secret - * (NULL if none). - * - * Permute the inner secret using the generated session keys. - * - * This can be called in the TLS/IA AVP callback to mix any generated - * session keys with the TLS/IA inner secret. - * - * Return value: Return zero on success, or a negative error code. - **/ -int -gnutls_ia_permute_inner_secret (gnutls_session_t session, - size_t session_keys_size, - const char *session_keys) -{ - extension_priv_data_t epriv; - ia_ext_st *priv; - int ret; - - ret = - _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_INNER_APPLICATION, - &epriv); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - priv = epriv.ptr; - - return _gnutls_ia_prf (session, - sizeof (inner_permutation_label) - 1, - inner_permutation_label, - session_keys_size, - session_keys, - GNUTLS_RANDOM_SIZE, priv->inner_secret); -} - -/** - * gnutls_ia_generate_challenge: - * @session: is a #gnutls_session_t structure. - * @buffer_size: size of output buffer. - * @buffer: pre-allocated buffer to contain @buffer_size bytes of output. - * - * Generate an application challenge that the client cannot control or - * predict, based on the TLS/IA inner secret. - * - * Return value: Returns 0 on success, or an negative error code. - **/ -int -gnutls_ia_generate_challenge (gnutls_session_t session, - size_t buffer_size, char *buffer) -{ - return _gnutls_ia_prf (session, - sizeof (challenge_label) - 1, - challenge_label, 0, NULL, buffer_size, buffer); -} - -/** - * gnutls_ia_extract_inner_secret: - * @session: is a #gnutls_session_t structure. - * @buffer: pre-allocated buffer to hold 48 bytes of inner secret. - * - * Copy the 48 bytes large inner secret into the specified buffer - * - * This function is typically used after the TLS/IA handshake has - * concluded. The TLS/IA inner secret can be used as input to a PRF - * to derive session keys. Do not use the inner secret directly as a - * session key, because for a resumed session that does not include an - * application phase, the inner secret will be identical to the inner - * secret in the original session. It is important to include, for - * example, the client and server randomness when deriving a sesssion - * key from the inner secret. - **/ -void -gnutls_ia_extract_inner_secret (gnutls_session_t session, char *buffer) -{ - extension_priv_data_t epriv; - ia_ext_st *priv; - int ret; - - ret = - _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_INNER_APPLICATION, - &epriv); - if (ret < 0) - { - gnutls_assert (); - return; - } - priv = epriv.ptr; - - memcpy (buffer, priv->inner_secret, GNUTLS_MASTER_SIZE); -} - -/** - * gnutls_ia_endphase_send: - * @session: is a #gnutls_session_t structure. - * @final_p: Set iff this should signal the final phase. - * - * Send a TLS/IA end phase message. - * - * In the client, this should only be used to acknowledge an end phase - * message sent by the server. - * - * In the server, this can be called instead of gnutls_ia_send() if - * the server wishes to end an application phase. - * - * Return value: Return 0 on success, or an error code. - **/ -int -gnutls_ia_endphase_send (gnutls_session_t session, int final_p) -{ - opaque local_checksum[CHECKSUM_SIZE]; - int client = session->security_parameters.entity == GNUTLS_CLIENT; - const char *label = client ? client_finished_label : server_finished_label; - int size_of_label = client ? sizeof (client_finished_label) : - sizeof (server_finished_label); - ssize_t len; - int ret; - extension_priv_data_t epriv; - ia_ext_st *priv; - - ret = - _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_INNER_APPLICATION, - &epriv); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - priv = epriv.ptr; - - ret = _gnutls_PRF (session, priv->inner_secret, - GNUTLS_MASTER_SIZE, label, size_of_label - 1, - /* XXX specification unclear on seed. */ - "", 0, CHECKSUM_SIZE, local_checksum); - if (ret < 0) - return ret; - - len = _gnutls_send_inner_application - (session, - final_p ? GNUTLS_IA_FINAL_PHASE_FINISHED : - GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED, local_checksum, CHECKSUM_SIZE); - - /* XXX Instead of calling this function over and over...? - * while (len == GNUTLS_E_AGAIN || len == GNUTLS_E_INTERRUPTED) - * len = _gnutls_io_write_flush(session); - */ - - if (len < 0) - { - gnutls_assert (); - return len; - } - - return 0; -} - -/** - * gnutls_ia_verify_endphase: - * @session: is a #gnutls_session_t structure. - * @checksum: 12-byte checksum data, received from gnutls_ia_recv(). - * - * Verify TLS/IA end phase checksum data. If verification fails, the - * %GNUTLS_A_INNER_APPLICATION_VERIFICATION alert is sent to the other - * sie. - * - * This function is called when gnutls_ia_recv() return - * %GNUTLS_E_WARNING_IA_IPHF_RECEIVED or - * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED. - * - * Return value: Return 0 on successful verification, or an error - * code. If the checksum verification of the end phase message fails, - * %GNUTLS_E_IA_VERIFY_FAILED is returned. - **/ -int -gnutls_ia_verify_endphase (gnutls_session_t session, const char *checksum) -{ - char local_checksum[CHECKSUM_SIZE]; - int client = session->security_parameters.entity == GNUTLS_CLIENT; - const char *label = client ? server_finished_label : client_finished_label; - int size_of_label = client ? sizeof (server_finished_label) : - sizeof (client_finished_label); - int ret; - extension_priv_data_t epriv; - ia_ext_st *priv; - - ret = - _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_INNER_APPLICATION, - &epriv); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - priv = epriv.ptr; - - ret = _gnutls_PRF (session, priv->inner_secret, - GNUTLS_MASTER_SIZE, - label, size_of_label - 1, - "", 0, CHECKSUM_SIZE, local_checksum); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - - if (memcmp (local_checksum, checksum, CHECKSUM_SIZE) != 0) - { - ret = gnutls_alert_send (session, GNUTLS_AL_FATAL, - GNUTLS_A_INNER_APPLICATION_VERIFICATION); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - - return GNUTLS_E_IA_VERIFY_FAILED; - } - - return 0; -} - -/** - * gnutls_ia_send: - * @session: is a #gnutls_session_t structure. - * @data: contains the data to send - * @sizeofdata: is the length of the data - * - * Send TLS/IA application payload data. This function has the - * similar semantics with send(). The only difference is that it - * accepts a GnuTLS session, and uses different error codes. - * - * The TLS/IA protocol is synchronous, so you cannot send more than - * one packet at a time. The client always send the first packet. - * - * To finish an application phase in the server, use - * gnutls_ia_endphase_send(). The client cannot end an application - * phase unilaterally; rather, a client is required to respond with an - * endphase of its own if gnutls_ia_recv indicates that the server has - * sent one. - * - * If the EINTR is returned by the internal push function (the default - * is send()} then %GNUTLS_E_INTERRUPTED will be returned. If - * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must call - * this function again, with the same parameters; alternatively you - * could provide a %NULL pointer for data, and 0 for size. - * - * Returns: The number of bytes sent, or a negative error code. - **/ -ssize_t -gnutls_ia_send (gnutls_session_t session, const char *data, size_t sizeofdata) -{ - ssize_t len; - - len = _gnutls_send_inner_application (session, - GNUTLS_IA_APPLICATION_PAYLOAD, - data, sizeofdata); - - return len; -} - -/** - * gnutls_ia_recv: - * @session: is a #gnutls_session_t structure. - * @data: the buffer that the data will be read into, must hold >= 12 bytes. - * @sizeofdata: the number of requested bytes, must be >= 12. - * - * Receive TLS/IA data. This function has the similar semantics with - * recv(). The only difference is that it accepts a GnuTLS session, - * and uses different error codes. - * - * If the server attempt to finish an application phase, this function - * will return %GNUTLS_E_WARNING_IA_IPHF_RECEIVED or - * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED. The caller should then invoke - * gnutls_ia_verify_endphase(), and if it runs the client side, also - * send an endphase message of its own using gnutls_ia_endphase_send. - * - * If EINTR is returned by the internal push function (the default is - * @code{recv()}) then GNUTLS_E_INTERRUPTED will be returned. If - * GNUTLS_E_INTERRUPTED or GNUTLS_E_AGAIN is returned, you must call - * this function again, with the same parameters; alternatively you - * could provide a NULL pointer for data, and 0 for size. - * - * Returns: The number of bytes received. A negative error code is - * returned in case of an error. The - * %GNUTLS_E_WARNING_IA_IPHF_RECEIVED and - * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED errors are returned when an - * application phase finished message has been sent by the server. - **/ -ssize_t -gnutls_ia_recv (gnutls_session_t session, char *data, size_t sizeofdata) -{ - gnutls_ia_apptype_t msg_type = 0; - ssize_t len; - - len = _gnutls_recv_inner_application (session, &msg_type, data, sizeofdata); - - if (msg_type == GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED) - return GNUTLS_E_WARNING_IA_IPHF_RECEIVED; - else if (msg_type == GNUTLS_IA_FINAL_PHASE_FINISHED) - return GNUTLS_E_WARNING_IA_FPHF_RECEIVED; - - return len; -} - -/* XXX rewrite the following two functions as state machines, to - handle EAGAIN/EINTERRUPTED? just add more problems to callers, - though. */ - -static int -_gnutls_ia_client_handshake (gnutls_session_t session) -{ - char *buf = NULL; - size_t buflen = 0; - char tmp[1024]; /* XXX */ - ssize_t len; - int ret; - const struct gnutls_ia_client_credentials_st *cred = - _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL); - - if (cred == NULL) - return GNUTLS_E_INTERNAL_ERROR; - - while (1) - { - char *avp; - size_t avplen; - - ret = cred->avp_func (session, cred->avp_ptr, - buf, buflen, &avp, &avplen); - if (ret) - { - int tmpret; - tmpret = gnutls_alert_send (session, GNUTLS_AL_FATAL, - GNUTLS_A_INNER_APPLICATION_FAILURE); - if (tmpret < 0) - gnutls_assert (); - return ret; - } - - len = gnutls_ia_send (session, avp, avplen); - gnutls_free (avp); - if (len < 0) - return len; - - len = gnutls_ia_recv (session, tmp, sizeof (tmp)); - if (len == GNUTLS_E_WARNING_IA_IPHF_RECEIVED || - len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED) - { - ret = gnutls_ia_verify_endphase (session, tmp); - if (ret < 0) - return ret; - - ret = gnutls_ia_endphase_send - (session, len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED); - if (ret < 0) - return ret; - } - - if (len == GNUTLS_E_WARNING_IA_IPHF_RECEIVED) - { - buf = NULL; - buflen = 0; - continue; - } - else if (len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED) - break; - - if (len < 0) - return len; - - buflen = len; - buf = tmp; - } - - return 0; -} - -static int -_gnutls_ia_server_handshake (gnutls_session_t session) -{ - gnutls_ia_apptype_t msg_type; - ssize_t len; - char buf[1024]; - int ret; - const struct gnutls_ia_server_credentials_st *cred = - _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL); - - if (cred == NULL) - return GNUTLS_E_INTERNAL_ERROR; - - do - { - char *avp; - size_t avplen; - - len = gnutls_ia_recv (session, buf, sizeof (buf)); - if (len == GNUTLS_E_WARNING_IA_IPHF_RECEIVED || - len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED) - { - ret = gnutls_ia_verify_endphase (session, buf); - if (ret < 0) - return ret; - } - - if (len == GNUTLS_E_WARNING_IA_IPHF_RECEIVED) - continue; - else if (len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED) - break; - - if (len < 0) - return len; - - avp = NULL; - avplen = 0; - - ret = cred->avp_func (session, cred->avp_ptr, buf, len, &avp, &avplen); - if (ret < 0) - { - int tmpret; - tmpret = gnutls_alert_send (session, GNUTLS_AL_FATAL, - GNUTLS_A_INNER_APPLICATION_FAILURE); - if (tmpret < 0) - gnutls_assert (); - return ret; - } - - msg_type = ret; - - if (msg_type != GNUTLS_IA_APPLICATION_PAYLOAD) - { - ret = gnutls_ia_endphase_send (session, msg_type == - GNUTLS_IA_FINAL_PHASE_FINISHED); - if (ret < 0) - return ret; - } - else - { - len = gnutls_ia_send (session, avp, avplen); - gnutls_free (avp); - if (len < 0) - return len; - } - } - while (1); - - return 0; -} - -/** - * gnutls_ia_handshake_p: - * @session: is a #gnutls_session_t structure. - * - * Predicate to be used after gnutls_handshake() to decide whether to - * invoke gnutls_ia_handshake(). Usable by both clients and servers. - * - * Return value: non-zero if TLS/IA handshake is expected, zero - * otherwise. - **/ -int -gnutls_ia_handshake_p (gnutls_session_t session) -{ - extension_priv_data_t epriv; - ia_ext_st *priv; - int ret; - - ret = - _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_SERVER_NAME, - &epriv); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - priv = epriv.ptr; - - /* Either local side or peer doesn't do TLS/IA: don't do IA */ - - if (!(priv->flags & IA_ENABLE) || !(priv->flags & IA_PEER_ENABLE)) - return 0; - - /* Not resuming or we don't allow skipping on resumption locally: do IA */ - - if (!(priv->flags & IA_ALLOW_SKIP) || !gnutls_session_is_resumed (session)) - return 1; - - /* If we're resuming and we and the peer both allow skipping on resumption: - * don't do IA */ - - return !(priv->flags & IA_PEER_ALLOW_SKIP); -} - - -/** - * gnutls_ia_handshake: - * @session: is a #gnutls_session_t structure. - * - * Perform a TLS/IA handshake. This should be called after - * gnutls_handshake() iff gnutls_ia_handshake_p(). - * - * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned, - * otherwise an error code is returned. - **/ -int -gnutls_ia_handshake (gnutls_session_t session) -{ - int ret; - - if (session->security_parameters.entity == GNUTLS_CLIENT) - ret = _gnutls_ia_client_handshake (session); - else - ret = _gnutls_ia_server_handshake (session); - - return ret; -} - -/** - * gnutls_ia_allocate_client_credentials: - * @sc: is a pointer to a #gnutls_ia_server_credentials_t structure. - * - * This structure is complex enough to manipulate directly thus this - * helper function is provided in order to allocate it. - * - * Adding this credential to a session will enable TLS/IA, and will - * require an Application Phase after the TLS handshake (if the server - * support TLS/IA). Use gnutls_ia_enable() to toggle the TLS/IA mode. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise - * an error code is returned. - **/ -int -gnutls_ia_allocate_client_credentials (gnutls_ia_client_credentials_t * sc) -{ - *sc = gnutls_calloc (1, sizeof (**sc)); - - if (*sc == NULL) - return GNUTLS_E_MEMORY_ERROR; - - return 0; -} - -/** - * gnutls_ia_free_client_credentials: - * @sc: is a #gnutls_ia_client_credentials_t structure. - * - * This structure is complex enough to manipulate directly thus this - * helper function is provided in order to free (deallocate) it. - * - **/ -void -gnutls_ia_free_client_credentials (gnutls_ia_client_credentials_t sc) -{ - gnutls_free (sc); -} - -/** - * gnutls_ia_set_client_avp_function: - * @cred: is a #gnutls_ia_client_credentials_t structure. - * @avp_func: is the callback function - * - * Set the TLS/IA AVP callback handler used for the session. - * - * The AVP callback is called to process AVPs received from the - * server, and to get a new AVP to send to the server. - * - * The callback's function form is: - * int (*avp_func) (gnutls_session_t session, void *ptr, - * const char *last, size_t lastlen, - * char **next, size_t *nextlen); - * - * The @session parameter is the #gnutls_session_t structure - * corresponding to the current session. The @ptr parameter is the - * application hook pointer, set through - * gnutls_ia_set_client_avp_ptr(). The AVP received from the server - * is present in @last of @lastlen size, which will be %NULL on the - * first invocation. The newly allocated output AVP to send to the - * server should be placed in *@next of *@nextlen size. - * - * The callback may invoke gnutls_ia_permute_inner_secret() to mix any - * generated session keys with the TLS/IA inner secret. - * - * Return 0 (%GNUTLS_IA_APPLICATION_PAYLOAD) on success, or a negative - * error code to abort the TLS/IA handshake. - * - * Note that the callback must use allocate the @next parameter using - * gnutls_malloc(), because it is released via gnutls_free() by the - * TLS/IA handshake function. - * - **/ -void -gnutls_ia_set_client_avp_function (gnutls_ia_client_credentials_t cred, - gnutls_ia_avp_func avp_func) -{ - cred->avp_func = avp_func; -} - -/** - * gnutls_ia_set_client_avp_ptr: - * @cred: is a #gnutls_ia_client_credentials_t structure. - * @ptr: is the pointer - * - * Sets the pointer that will be provided to the TLS/IA callback - * function as the first argument. - **/ -void -gnutls_ia_set_client_avp_ptr (gnutls_ia_client_credentials_t cred, void *ptr) -{ - cred->avp_ptr = ptr; -} - -/** - * gnutls_ia_get_client_avp_ptr: - * @cred: is a #gnutls_ia_client_credentials_t structure. - * - * Returns the pointer that will be provided to the TLS/IA callback - * function as the first argument. - * - * Returns: The client callback data pointer. - **/ -void * -gnutls_ia_get_client_avp_ptr (gnutls_ia_client_credentials_t cred) -{ - return cred->avp_ptr; -} - -/** - * gnutls_ia_allocate_server_credentials: - * @sc: is a pointer to a #gnutls_ia_server_credentials_t structure. - * - * This structure is complex enough to manipulate directly thus this - * helper function is provided in order to allocate it. - * - * Adding this credential to a session will enable TLS/IA, and will - * require an Application Phase after the TLS handshake (if the client - * support TLS/IA). Use gnutls_ia_enable() to toggle the TLS/IA mode. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise - * an error code is returned. - **/ -int -gnutls_ia_allocate_server_credentials (gnutls_ia_server_credentials_t * sc) -{ - *sc = gnutls_calloc (1, sizeof (**sc)); - - if (*sc == NULL) - return GNUTLS_E_MEMORY_ERROR; - - return 0; -} - -/** - * gnutls_ia_free_server_credentials: - * @sc: is a #gnutls_ia_server_credentials_t structure. - * - * This structure is complex enough to manipulate directly thus this - * helper function is provided in order to free (deallocate) it. - * - **/ -void -gnutls_ia_free_server_credentials (gnutls_ia_server_credentials_t sc) -{ - gnutls_free (sc); -} - -/** - * gnutls_ia_set_server_credentials_function: - * @cred: is a #gnutls_ia_server_credentials_t structure. - * @func: is the callback function - * - * Set the TLS/IA AVP callback handler used for the session. - * - * The callback's function form is: - * int (*avp_func) (gnutls_session_t session, void *ptr, - * const char *last, size_t lastlen, - * char **next, size_t *nextlen); - * - * The @session parameter is the #gnutls_session_t structure - * corresponding to the current session. The @ptr parameter is the - * application hook pointer, set through - * gnutls_ia_set_server_avp_ptr(). The AVP received from the client - * is present in @last of @lastlen size. The newly allocated output - * AVP to send to the client should be placed in *@next of *@nextlen - * size. - * - * The AVP callback is called to process incoming AVPs from the - * client, and to get a new AVP to send to the client. It can also be - * used to instruct the TLS/IA handshake to do go into the - * Intermediate or Final phases. It return a negative error code, or - * a #gnutls_ia_apptype_t message type. - * - * The callback may invoke gnutls_ia_permute_inner_secret() to mix any - * generated session keys with the TLS/IA inner secret. - * - * Specifically, return %GNUTLS_IA_APPLICATION_PAYLOAD (0) to send - * another AVP to the client, return - * %GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED (1) to indicate that an - * IntermediatePhaseFinished message should be sent, and return - * %GNUTLS_IA_FINAL_PHASE_FINISHED (2) to indicate that an - * FinalPhaseFinished message should be sent. In the last two cases, - * the contents of the @next and @nextlen parameter is not used. - * - * Note that the callback must use allocate the @next parameter using - * gnutls_malloc(), because it is released via gnutls_free() by the - * TLS/IA handshake function. - **/ -void -gnutls_ia_set_server_avp_function (gnutls_ia_server_credentials_t cred, - gnutls_ia_avp_func avp_func) -{ - cred->avp_func = avp_func; -} - -/** - * gnutls_ia_set_server_avp_ptr: - * @cred: is a #gnutls_ia_client_credentials_t structure. - * @ptr: is the pointer - * - * Sets the pointer that will be provided to the TLS/IA callback - * function as the first argument. - **/ -void -gnutls_ia_set_server_avp_ptr (gnutls_ia_server_credentials_t cred, void *ptr) -{ - cred->avp_ptr = ptr; -} - -/** - * gnutls_ia_get_server_avp_ptr: - * @cred: is a #gnutls_ia_client_credentials_t structure. - * - * Returns the pointer that will be provided to the TLS/IA callback - * function as the first argument. - * - * Returns: The server callback data pointer. - **/ -void * -gnutls_ia_get_server_avp_ptr (gnutls_ia_server_credentials_t cred) -{ - return cred->avp_ptr; -} - -/** - * gnutls_ia_enable: - * @session: is a #gnutls_session_t structure. - * @allow_skip_on_resume: non-zero if local party allows to skip the - * TLS/IA application phases for a resumed session. - * - * Specify whether we must advertise support for the TLS/IA extension - * during the handshake. - * - * At the client side, we always advertise TLS/IA if gnutls_ia_enable - * was called before the handshake; at the server side, we also - * require that the client has advertised that it wants to run TLS/IA - * before including the advertisement, as required by the protocol. - * - * Similarly, at the client side we always advertise that we allow - * TLS/IA to be skipped for resumed sessions if @allow_skip_on_resume - * is non-zero; at the server side, we also require that the session - * is indeed resumable and that the client has also advertised that it - * allows TLS/IA to be skipped for resumed sessions. - * - * After the TLS handshake, call gnutls_ia_handshake_p() to find out - * whether both parties agreed to do a TLS/IA handshake, before - * calling gnutls_ia_handshake() or one of the lower level gnutls_ia_* - * functions. - **/ -void -gnutls_ia_enable (gnutls_session_t session, int allow_skip_on_resume) -{ - extension_priv_data_t epriv; - ia_ext_st *priv; - - priv = gnutls_calloc (1, sizeof (*priv)); - if (priv == NULL) - { - gnutls_assert (); - return; - } - - epriv.ptr = priv; - - priv->flags |= IA_ENABLE; - if (allow_skip_on_resume) - priv->flags |= IA_ALLOW_SKIP; - - _gnutls_ext_set_session_data (session, GNUTLS_EXTENSION_INNER_APPLICATION, - epriv); - -} diff --git a/libextra/libgnutls-extra.map b/libextra/libgnutls-extra.map index a24e09f140..746b8219ac 100644 --- a/libextra/libgnutls-extra.map +++ b/libextra/libgnutls-extra.map @@ -26,26 +26,6 @@ GNUTLS_1_4 global: gnutls_extra_check_version; gnutls_global_init_extra; - gnutls_ia_allocate_client_credentials; - gnutls_ia_allocate_server_credentials; - gnutls_ia_enable; - gnutls_ia_endphase_send; - gnutls_ia_extract_inner_secret; - gnutls_ia_free_client_credentials; - gnutls_ia_free_server_credentials; - gnutls_ia_generate_challenge; - gnutls_ia_get_client_avp_ptr; - gnutls_ia_get_server_avp_ptr; - gnutls_ia_handshake; - gnutls_ia_handshake_p; - gnutls_ia_permute_inner_secret; - gnutls_ia_recv; - gnutls_ia_send; - gnutls_ia_set_client_avp_function; - gnutls_ia_set_client_avp_ptr; - gnutls_ia_set_server_avp_function; - gnutls_ia_set_server_avp_ptr; - gnutls_ia_verify_endphase; gnutls_register_md5_handler; local: diff --git a/tests/Makefile.am b/tests/Makefile.am index 1f10d23944..b8adcfd94e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -74,13 +74,12 @@ endif if HAVE_FORK ctests += x509self x509dn anonself pskself dhepskself \ - tlsia resume setcredcrash + resume setcredcrash if ENABLE_OPENPGP ctests += openpgpself endif -tlsia_LDADD = ../libextra/libgnutls-extra.la $(LDADD) $(LTLIBREADLINE) endif check_PROGRAMS = $(ctests) diff --git a/tests/tlsia.c b/tests/tlsia.c deleted file mode 100644 index b63bc296e4..0000000000 --- a/tests/tlsia.c +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010 Free Software - * Foundation, Inc. - * - * Author: Simon Josefsson - * - * This file is part of GnuTLS. - * - * GnuTLS is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuTLS 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GnuTLS; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -/* Parts copied from GnuTLS example programs. */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/wait.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <unistd.h> -#include <gnutls/gnutls.h> -#include <gnutls/extra.h> - -#include "utils.h" - -#include "tcp.c" - -#include <readline.h> - -/* A very basic TLS client, with anonymous authentication. - */ - -#define MAX_BUF 1024 -#define MSG "Hello TLS" - -static void -tls_log_func (int level, const char *str) -{ - fprintf (stderr, "<%d>| %s", level, str); -} - -static int -client_avp (gnutls_session_t session, void *ptr, - const char *last, size_t lastlen, char **new, size_t * newlen) -{ - static int iter = 0; - const char *p; - - if (debug) - { - if (last) - printf ("client: received %d bytes AVP: `%.*s'\n", - (int) lastlen, (int) lastlen, last); - else - printf ("client: new application phase\n"); - } - - switch (iter) - { - case 0: - p = "client's first AVP, next will be empty"; - break; - - case 1: - p = ""; - break; - - case 2: - p = "client avp"; - break; - - default: - p = "final client AVP, we'll restart next"; - iter = -1; - break; - } - - iter++; - - if (debug) - p = readline ("Client TLS/IA AVP: "); - - *new = gnutls_strdup (p); - if (!*new) - return -1; - *newlen = strlen (*new); - - if (debug) - printf ("client: sending %d bytes AVP: `%s'\n", (int) *newlen, *new); - - gnutls_ia_permute_inner_secret (session, 3, "foo"); - - return 0; -} - -static void -client (void) -{ - int ret, sd, ii; - gnutls_session_t session; - char buffer[MAX_BUF + 1]; - gnutls_anon_client_credentials_t anoncred; - gnutls_ia_client_credentials_t iacred; - /* Need to enable anonymous KX specifically. */ - const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 }; - - ret = gnutls_global_init (); - gnutls_global_set_log_function (tls_log_func); - if (debug) - gnutls_global_set_log_level (2); - - if (ret) - fail ("global_init: %d\n", ret); - ret = gnutls_global_init_extra (); - if (ret) - fail ("global_init_extra: %d\n", ret); - - gnutls_anon_allocate_client_credentials (&anoncred); - gnutls_ia_allocate_client_credentials (&iacred); - - /* Initialize TLS session - */ - gnutls_init (&session, GNUTLS_CLIENT); - - /* Use default priorities */ - gnutls_set_default_priority (session); - gnutls_kx_set_priority (session, kx_prio); - - /* put the anonymous credentials to the current session - */ - gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred); - gnutls_credentials_set (session, GNUTLS_CRD_IA, iacred); - - /* connect to the peer - */ - sd = tcp_connect (); - - gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd); - - /* Enable TLS/IA. */ - gnutls_ia_set_client_avp_function (iacred, client_avp); - - /* Perform the TLS handshake - */ - ret = gnutls_handshake (session); - - if (ret < 0) - { - fail ("client: Handshake failed\n"); - gnutls_perror (ret); - goto end; - } - else - { - if (debug) - success ("client: Handshake was completed\n"); - } - - /* - To test TLS/IA alert's (the server will print that a fatal alert - was received): - gnutls_alert_send(session, GNUTLS_AL_FATAL, - GNUTLS_A_INNER_APPLICATION_FAILURE); - */ - - if (!gnutls_ia_handshake_p (session)) - fail ("client: No TLS/IA negotiation\n"); - else - { - if (debug) - success ("client: TLS/IA handshake\n"); - - ret = gnutls_ia_handshake (session); - - if (ret < 0) - { - fail ("client: TLS/IA handshake failed\n"); - gnutls_perror (ret); - goto end; - } - else - { - if (debug) - success ("client: TLS/IA Handshake was completed\n"); - } - } - - gnutls_record_send (session, MSG, strlen (MSG)); - - ret = gnutls_record_recv (session, buffer, MAX_BUF); - if (ret == 0) - { - if (debug) - success ("client: Peer has closed the TLS connection\n"); - goto end; - } - else if (ret < 0) - { - fail ("client: Error: %s\n", gnutls_strerror (ret)); - goto end; - } - - if (debug) - { - printf ("- Received %d bytes: ", ret); - for (ii = 0; ii < ret; ii++) - { - fputc (buffer[ii], stdout); - } - fputs ("\n", stdout); - } - - gnutls_bye (session, GNUTLS_SHUT_RDWR); - -end: - - tcp_close (sd); - - gnutls_deinit (session); - - gnutls_ia_free_client_credentials (iacred); - - gnutls_anon_free_client_credentials (anoncred); - - gnutls_global_deinit (); -} - -/* This is a sample TLS 1.0 echo server, for anonymous authentication only. - */ - -#define SA struct sockaddr -#define MAX_BUF 1024 -#define PORT 5556 /* listen to 5556 port */ -#define DH_BITS 1024 - -/* These are global */ -gnutls_anon_server_credentials_t anoncred; -gnutls_ia_server_credentials_t iacred; - -static gnutls_session_t -initialize_tls_session (void) -{ - gnutls_session_t session; - const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 }; - - gnutls_init (&session, GNUTLS_SERVER); - - /* avoid calling all the priority functions, since the defaults - * are adequate. - */ - gnutls_set_default_priority (session); - gnutls_kx_set_priority (session, kx_prio); - - gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred); - - gnutls_dh_set_prime_bits (session, DH_BITS); - - return session; -} - -static gnutls_dh_params_t dh_params; - -static int -generate_dh_params (void) -{ - const gnutls_datum_t p3 = { (char *) pkcs3, strlen (pkcs3) }; - /* Generate Diffie-Hellman parameters - for use with DHE - * kx algorithms. These should be discarded and regenerated - * once a day, once a week or once a month. Depending on the - * security requirements. - */ - gnutls_dh_params_init (&dh_params); - return gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM); -} - -int err, listen_sd, i; -int sd, ret; -struct sockaddr_in sa_serv; -struct sockaddr_in sa_cli; -socklen_t client_len; -char topbuf[512]; -gnutls_session_t session; -char buffer[MAX_BUF + 1]; -int optval = 1; - -static int -server_avp (gnutls_session_t session, void *ptr, - const char *last, size_t lastlen, char **new, size_t * newlen) -{ - static int iter = 0; - const char *p; - - if (last && debug) - printf ("server: received %d bytes AVP: `%.*s'\n", - (int) lastlen, (int) lastlen, last); - - gnutls_ia_permute_inner_secret (session, 3, "foo"); - - switch (iter) - { - case 0: - p = "first server AVP"; - break; - - case 1: - p = "second server AVP, next will be empty, then a intermediate finish"; - break; - - case 2: - p = ""; - break; - - case 3: - p = "1"; - break; - - case 4: - p = "server avp, after intermediate finish, next another intermediate"; - break; - - case 5: - p = "1"; - break; - - case 6: - p = "server avp, next will be the finish phase"; - break; - - default: - p = "2"; - break; - } - - iter++; - - if (debug) - p = readline ("Server TLS/IA AVP (type '1' to sync, '2' to finish): "); - - if (!p) - return -1; - - if (strcmp (p, "1") == 0) - { - if (debug) - success ("server: Sending IntermediatePhaseFinished...\n"); - return 1; - } - - if (strcmp (p, "2") == 0) - { - if (debug) - success ("server: Sending FinalPhaseFinished...\n"); - return 2; - } - - *new = gnutls_strdup (p); - if (!*new) - return -1; - *newlen = strlen (*new); - - if (debug) - printf ("server: sending %d bytes AVP: `%s'\n", (int) *newlen, *new); - - return 0; -} - -static void -server_start (void) -{ - /* Socket operations - */ - listen_sd = socket (AF_INET, SOCK_STREAM, 0); - if (err == -1) - { - perror ("socket"); - fail ("server: socket failed\n"); - return; - } - - memset (&sa_serv, '\0', sizeof (sa_serv)); - sa_serv.sin_family = AF_INET; - sa_serv.sin_addr.s_addr = INADDR_ANY; - sa_serv.sin_port = htons (PORT); /* Server Port number */ - - setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval, - sizeof (int)); - - err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv)); - if (err == -1) - { - perror ("bind"); - fail ("server: bind failed\n"); - return; - } - - err = listen (listen_sd, 1024); - if (err == -1) - { - perror ("listen"); - fail ("server: listen failed\n"); - return; - } - - if (debug) - success ("server: ready. Listening to port '%d'\n", PORT); -} - -static void -server (void) -{ - /* this must be called once in the program - */ - ret = gnutls_global_init (); - if (ret) - fail ("global_init: %d\n", ret); - ret = gnutls_global_init_extra (); - if (ret) - fail ("global_init_extra: %d\n", ret); - - gnutls_global_set_log_function (tls_log_func); - if (debug) - gnutls_global_set_log_level (2); - - gnutls_anon_allocate_server_credentials (&anoncred); - gnutls_ia_allocate_server_credentials (&iacred); - - if (debug) - success ("Launched, generating DH parameters...\n"); - - generate_dh_params (); - - gnutls_anon_set_server_dh_params (anoncred, dh_params); - - client_len = sizeof (sa_cli); - - session = initialize_tls_session (); - - sd = accept (listen_sd, (SA *) & sa_cli, &client_len); - - if (debug) - success ("server: connection from %s, port %d\n", - inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf, - sizeof (topbuf)), ntohs (sa_cli.sin_port)); - - gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd); - - /* Enable TLS/IA. */ - gnutls_credentials_set (session, GNUTLS_CRD_IA, iacred); - gnutls_ia_set_server_avp_function (iacred, server_avp); - - ret = gnutls_handshake (session); - if (ret < 0) - { - close (sd); - gnutls_deinit (session); - fail ("server: Handshake has failed (%s)\n\n", gnutls_strerror (ret)); - return; - } - if (debug) - success ("server: Handshake was completed\n"); - - if (!gnutls_ia_handshake_p (session)) - fail ("server: No TLS/IA negotiation\n"); - else - { - if (debug) - success ("server: TLS/IA handshake\n"); - - ret = gnutls_ia_handshake (session); - - if (ret < 0) - { - fail ("server: TLS/IA handshake failed\n"); - gnutls_perror (ret); - return; - } - else - { - if (debug) - success ("server: TLS/IA Handshake was completed\n"); - } - } - - /* see the Getting peer's information example */ - /* print_info(session); */ - - i = 0; - for (;;) - { - memset (buffer, 0, MAX_BUF + 1); - ret = gnutls_record_recv (session, buffer, MAX_BUF); - - if (ret == 0) - { - if (debug) - success ("server: Peer has closed the GnuTLS connection\n"); - break; - } - else if (ret < 0) - { - if (ret == GNUTLS_E_FATAL_ALERT_RECEIVED) - { - gnutls_alert_description_t alert; - const char *err; - alert = gnutls_alert_get (session); - err = gnutls_alert_get_name (alert); - if (err) - printf ("Fatal alert: %s\n", err); - } - - fail ("server: Received corrupted data(%d). Closing...\n", ret); - break; - } - else if (ret > 0) - { - /* echo data back to the client - */ - gnutls_record_send (session, buffer, strlen (buffer)); - } - } - /* do not wait for the peer to close the connection. - */ - gnutls_bye (session, GNUTLS_SHUT_WR); - - close (sd); - gnutls_deinit (session); - - close (listen_sd); - - gnutls_ia_free_server_credentials (iacred); - - gnutls_anon_free_server_credentials (anoncred); - - gnutls_dh_params_deinit (dh_params); - - gnutls_global_deinit (); - - if (debug) - success ("server: finished\n"); -} - -void -doit (void) -{ - pid_t child; - - server_start (); - if (error_count) - return; - - child = fork (); - if (child < 0) - { - perror ("fork"); - fail ("fork"); - return; - } - - if (child) - { - int status; - /* parent */ - server (); - wait (&status); - } - else - client (); -} |