diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2005-11-15 17:35:02 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2005-11-15 17:35:02 +0000 |
commit | 28742fa959f05142f2659f73a5ea1260175179a7 (patch) | |
tree | b29435e31924e409e58bf034cf30092e5e39cf2e | |
parent | dea22989089a7c2de01a606a9e6ed60caee2742f (diff) | |
download | gnutls-28742fa959f05142f2659f73a5ea1260175179a7.tar.gz |
added DHE-PSK ciphersuites and some cleanups.
36 files changed, 939 insertions, 228 deletions
@@ -5,6 +5,9 @@ See the end for copying conditions. * Version 1.3.1 (unreleased) +** Support for DHE-PSK cipher suites has been added. + + * Version 1.3.0 (2005-11-15) ** Support for TLS Pre-Shared Key (TLS-PSK) ciphersuites have been added. diff --git a/includes/gnutls/gnutls.h.in b/includes/gnutls/gnutls.h.in index b08f10b98d..b10eec05ed 100644 --- a/includes/gnutls/gnutls.h.in +++ b/includes/gnutls/gnutls.h.in @@ -79,7 +79,7 @@ typedef enum gnutls_cipher_algorithm { GNUTLS_CIPHER_NULL = 1, typedef enum { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP, GNUTLS_KX_RSA_EXPORT, GNUTLS_KX_SRP_RSA, GNUTLS_KX_SRP_DSS, - GNUTLS_KX_PSK + GNUTLS_KX_PSK, GNUTLS_KX_DHE_PSK } gnutls_kx_algorithm_t; typedef enum { GNUTLS_PARAMS_RSA_EXPORT=1, @@ -633,6 +633,7 @@ void gnutls_psk_set_client_credentials_function( gnutls_psk_client_credentials_t int gnutls_hex_encode( const gnutls_datum_t *data, char* result, size_t* result_size); int gnutls_hex_decode( const gnutls_datum_t *hex_data, char* result, size_t* result_size); +void gnutls_psk_set_server_dh_params( gnutls_psk_server_credentials_t res, gnutls_dh_params_t dh_params); #ifndef GNUTLS_UI_H @@ -770,22 +771,25 @@ int gnutls_hex_decode( const gnutls_datum_t *hex_data, char* result, size_t* res #define GNUTLS_KEY_ENCIPHER_ONLY 1 #define GNUTLS_KEY_DECIPHER_ONLY 32768 - typedef struct gnutls_params_st { +typedef struct gnutls_params_st { gnutls_params_type_t type; union params { gnutls_dh_params_t dh; gnutls_rsa_params_t rsa_export; } params; int deinit; - } gnutls_params_st; +} gnutls_params_st; - typedef int gnutls_params_function(gnutls_session_t, gnutls_params_type_t, +typedef int gnutls_params_function(gnutls_session_t, gnutls_params_type_t, gnutls_params_st *); - void +void gnutls_certificate_set_params_function(gnutls_certificate_credentials_t res, gnutls_params_function * func); - void gnutls_anon_set_params_function(gnutls_anon_server_credentials_t res, +void gnutls_anon_set_params_function(gnutls_anon_server_credentials_t res, + gnutls_params_function * func); + +void gnutls_psk_set_params_function(gnutls_psk_server_credentials_t res, gnutls_params_function * func); diff --git a/lib/Makefile.am b/lib/Makefile.am index 997fd5fc58..1af672e3b6 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -54,7 +54,7 @@ lib_LTLIBRARIES = libgnutls.la SRP_COBJECTS = ext_srp.c gnutls_srp.c auth_srp.c auth_srp_passwd.c \ auth_srp_sb64.c auth_srp_rsa.c -PSK_COBJECTS = auth_psk.c auth_psk_passwd.c gnutls_psk.c +PSK_COBJECTS = auth_psk.c auth_psk_passwd.c gnutls_psk.c auth_dhe_psk.c COBJECTS = gnutls_record.c gnutls_compress.c debug.c gnutls_cipher.c \ gnutls_buffers.c gnutls_handshake.c gnutls_num.c \ diff --git a/lib/auth_anon.c b/lib/auth_anon.c index c94da0ffb1..e08fdf33f6 100644 --- a/lib/auth_anon.c +++ b/lib/auth_anon.c @@ -78,8 +78,8 @@ gen_anon_server_kx (gnutls_session_t session, opaque ** data) return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } - dh_params = _gnutls_anon_get_dh_params (cred, session); - mpis = _gnutls_get_dh_params (dh_params); + dh_params = _gnutls_get_dh_params (cred->dh_params, cred->params_func, session); + mpis = _gnutls_dh_params_to_mpi (dh_params); if (mpis == NULL) { gnutls_assert (); @@ -130,8 +130,8 @@ proc_anon_client_kx (gnutls_session_t session, opaque * data, return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } - dh_params = _gnutls_anon_get_dh_params (cred, session); - mpis = _gnutls_get_dh_params (dh_params); + dh_params = _gnutls_get_dh_params (cred->dh_params, cred->params_func, session); + mpis = _gnutls_dh_params_to_mpi (dh_params); if (mpis == NULL) { gnutls_assert (); diff --git a/lib/auth_anon.h b/lib/auth_anon.h index 1f7ae397ae..39bd13d10d 100644 --- a/lib/auth_anon.h +++ b/lib/auth_anon.h @@ -51,6 +51,3 @@ typedef anon_client_auth_info_t anon_auth_info_t; typedef struct anon_client_auth_info_st anon_client_auth_info_st; typedef anon_client_auth_info_st anon_server_auth_info_st; -gnutls_dh_params_t _gnutls_anon_get_dh_params (const - gnutls_anon_server_credentials_t - sc, gnutls_session_t session); diff --git a/lib/auth_cert.h b/lib/auth_cert.h index dadd2d7d7e..810bbfdcc4 100644 --- a/lib/auth_cert.h +++ b/lib/auth_cert.h @@ -150,10 +150,5 @@ void _gnutls_selected_certs_set (gnutls_session_t session, gnutls_rsa_params_t _gnutls_certificate_get_rsa_params (const gnutls_certificate_credentials_t sc, gnutls_session_t); -gnutls_dh_params_t _gnutls_certificate_get_dh_params (const - gnutls_certificate_credentials_t - sc, - gnutls_session_t - session); #endif diff --git a/lib/auth_dh_common.c b/lib/auth_dh_common.c index a56f9a9890..a3578e6dea 100644 --- a/lib/auth_dh_common.c +++ b/lib/auth_dh_common.c @@ -38,6 +38,8 @@ #include <gnutls_extra.h> #include <gnutls_state.h> #include <auth_dh_common.h> +#include <gnutls_algorithms.h> +#include <auth_psk.h> /* Frees the dh_info_st structure. */ @@ -86,7 +88,29 @@ _gnutls_proc_dh_common_client_kx (gnutls_session_t session, _gnutls_mpi_release (&session->key->client_Y); _gnutls_mpi_release (&session->key->dh_secret); - ret = _gnutls_generate_session_key (session->key); + + if (_gnutls_cipher_suite_get_kx_algo + (&session->security_parameters.current_cipher_suite) + != GNUTLS_KX_DHE_PSK) + { + ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY); + } + else /* In DHE_PSK the key is set differently */ + { + gnutls_datum tmp_dh_key; + ret = _gnutls_mpi_dprint (&tmp_dh_key, session->key->KEY); + if (ret < 0) + { + _gnutls_free_datum (&tmp_dh_key); + gnutls_assert (); + return ret; + } + + ret = _gnutls_set_psk_session_key (session, &tmp_dh_key); + _gnutls_free_datum (&tmp_dh_key); + + } + _gnutls_mpi_release (&session->key->KEY); if (ret < 0) @@ -149,7 +173,28 @@ _gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque ** data) _gnutls_mpi_release (&session->key->client_p); _gnutls_mpi_release (&session->key->client_g); - ret = _gnutls_generate_session_key (session->key); + if (_gnutls_cipher_suite_get_kx_algo + (&session->security_parameters.current_cipher_suite) + != GNUTLS_KX_DHE_PSK) + { + ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY); + } + else /* In DHE_PSK the key is set differently */ + { + gnutls_datum tmp_dh_key; + ret = _gnutls_mpi_dprint (&tmp_dh_key, session->key->KEY); + if (ret < 0) + { + _gnutls_free_datum (&tmp_dh_key); + gnutls_assert (); + goto error; + } + + ret = _gnutls_set_psk_session_key (session, &tmp_dh_key); + _gnutls_free_datum (&tmp_dh_key); + + } + _gnutls_mpi_release (&session->key->KEY); if (ret < 0) diff --git a/lib/auth_dhe.c b/lib/auth_dhe.c index f3952a3e3a..4af25eee90 100644 --- a/lib/auth_dhe.c +++ b/lib/auth_dhe.c @@ -112,8 +112,8 @@ gen_dhe_server_kx (gnutls_session_t session, opaque ** data) return ret; } - dh_params = _gnutls_certificate_get_dh_params (cred, session); - mpis = _gnutls_get_dh_params (dh_params); + dh_params = _gnutls_get_dh_params (cred->dh_params, cred->params_func, session); + mpis = _gnutls_dh_params_to_mpi (dh_params); if (mpis == NULL) { gnutls_assert (); @@ -257,8 +257,8 @@ proc_dhe_client_kx (gnutls_session_t session, opaque * data, return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } - dh_params = _gnutls_certificate_get_dh_params (cred, session); - mpis = _gnutls_get_dh_params (dh_params); + dh_params = _gnutls_get_dh_params (cred->dh_params, cred->params_func, session); + mpis = _gnutls_dh_params_to_mpi (dh_params); if (mpis == NULL) { gnutls_assert (); diff --git a/lib/auth_dhe_psk.c b/lib/auth_dhe_psk.c new file mode 100644 index 0000000000..772ac86edb --- /dev/null +++ b/lib/auth_dhe_psk.c @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation + * + * Author: Nikos Mavroyanopoulos + * + * This file is part of GNUTLS. + * + * The GNUTLS library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA + * + */ + +/* This file contains the Anonymous Diffie Hellman key exchange part of + * the anonymous authentication. The functions here are used in the + * handshake. + */ + +#include <gnutls_int.h> + +#ifdef ENABLE_PSK + +#include "gnutls_auth_int.h" +#include "gnutls_errors.h" +#include "gnutls_dh.h" +#include "auth_psk.h" +#include "gnutls_num.h" +#include "gnutls_mpi.h" +#include <gnutls_state.h> +#include <auth_dh_common.h> + +static int gen_psk_server_kx (gnutls_session_t, opaque **); +static int proc_psk_client_kx (gnutls_session_t, opaque *, size_t); +static int proc_psk_server_kx (gnutls_session_t, opaque *, size_t); + +const mod_auth_st dhe_psk_auth_struct = { + "DHE PSK", + NULL, + NULL, + gen_psk_server_kx, + _gnutls_gen_dh_common_client_kx, /* this can be shared */ + NULL, + NULL, + + NULL, + NULL, /* certificate */ + proc_psk_server_kx, + proc_psk_client_kx, + NULL, + NULL +}; + +static int +gen_psk_server_kx (gnutls_session_t session, opaque ** data) +{ + mpi_t g, p; + const mpi_t *mpis; + int ret; + gnutls_dh_params_t dh_params; + gnutls_psk_server_credentials_t cred; + + cred = (gnutls_psk_server_credentials_t) + _gnutls_get_cred (session->key, GNUTLS_CRD_PSK, NULL); + if (cred == NULL) + { + gnutls_assert (); + return GNUTLS_E_INSUFFICIENT_CREDENTIALS; + } + + dh_params = _gnutls_get_dh_params (cred->dh_params, cred->params_func, session); + mpis = _gnutls_dh_params_to_mpi (dh_params); + if (mpis == NULL) + { + gnutls_assert (); + return GNUTLS_E_NO_TEMPORARY_DH_PARAMS; + } + + p = mpis[0]; + g = mpis[1]; + + if ((ret = + _gnutls_auth_info_set (session, GNUTLS_CRD_PSK, + sizeof (psk_server_auth_info_st), 1)) < 0) + { + gnutls_assert (); + return ret; + } + + _gnutls_dh_set_group (session, g, p); + + ret = _gnutls_dh_common_print_server_kx (session, g, p, data); + if (ret < 0) + { + gnutls_assert (); + } + + return ret; +} + + +static int +proc_psk_client_kx (gnutls_session_t session, opaque * data, + size_t _data_size) +{ + gnutls_psk_server_credentials_t cred; + int bits; + int ret; + mpi_t p, g; + gnutls_dh_params_t dh_params; + const mpi_t *mpis; + + bits = _gnutls_dh_get_allowed_prime_bits (session); + + cred = (gnutls_psk_server_credentials_t) + _gnutls_get_cred (session->key, GNUTLS_CRD_PSK, NULL); + if (cred == NULL) + { + gnutls_assert (); + return GNUTLS_E_INSUFFICIENT_CREDENTIALS; + } + + dh_params = _gnutls_get_dh_params (cred->dh_params, cred->params_func, session); + mpis = _gnutls_dh_params_to_mpi (dh_params); + if (mpis == NULL) + { + gnutls_assert (); + return GNUTLS_E_NO_TEMPORARY_DH_PARAMS; + } + + p = mpis[0]; + g = mpis[1]; + + ret = _gnutls_proc_dh_common_client_kx (session, data, _data_size, g, p); + + return ret; + +} + +int +proc_psk_server_kx (gnutls_session_t session, opaque * data, + size_t _data_size) +{ + + int ret; + + /* set auth_info */ + if ((ret = + _gnutls_auth_info_set (session, GNUTLS_CRD_PSK, + sizeof (psk_client_auth_info_st), 1)) < 0) + { + gnutls_assert (); + return ret; + } + + ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + return 0; +} + +#endif /* ENABLE_PSK */ diff --git a/lib/auth_psk.c b/lib/auth_psk.c index dd4bf39b06..e6a0de92ef 100644 --- a/lib/auth_psk.c +++ b/lib/auth_psk.c @@ -59,17 +59,62 @@ const mod_auth_st psk_auth_struct = { /* Set the PSK premaster secret. */ -static int -set_psk_session_key (gnutls_session_t session, gnutls_datum * psk) +int +_gnutls_set_psk_session_key (gnutls_session_t session, gnutls_datum * psk2) { + gnutls_datum psk = { NULL, 0 }; + gnutls_datum *ppsk; + size_t psk2_size; + int ret; + + if (session->security_parameters.entity == GNUTLS_CLIENT) + { + gnutls_psk_client_credentials_t cred; + + cred = (gnutls_psk_client_credentials_t) + _gnutls_get_cred (session->key, GNUTLS_CRD_PSK, NULL); + + if (cred == NULL) + { + gnutls_assert (); + return GNUTLS_E_INSUFFICIENT_CREDENTIALS; + } + + ppsk = &cred->key; + + } + else + { /* SERVER side */ + psk_server_auth_info_t info; + + info = _gnutls_get_auth_info (session); + + /* find the key of this username + */ + ret = _gnutls_psk_pwd_find_entry (session, info->username, &psk); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + ppsk = &psk; + } + + + if (psk2 == NULL) + psk2_size = ppsk->size; + else + psk2_size = psk2->size; + /* set the session key */ - session->key->key.size = 4 + psk->size + psk->size; + session->key->key.size = 4 + psk2_size + ppsk->size; session->key->key.data = gnutls_malloc (session->key->key.size); if (session->key->key.data == NULL) { gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; + ret = GNUTLS_E_MEMORY_ERROR; + goto error; } /* format of the premaster secret: @@ -78,11 +123,19 @@ set_psk_session_key (gnutls_session_t session, gnutls_datum * psk) * (uint16) psk_size * the psk */ - _gnutls_write_uint16 (psk->size, session->key->key.data); - memset (&session->key->key.data[2], 0, psk->size); - _gnutls_write_datum16 (&session->key->key.data[psk->size + 2], *psk); - - return 0; + _gnutls_write_uint16 (psk2_size, session->key->key.data); + if (psk2 == NULL) + memset (&session->key->key.data[2], 0, psk2_size); + else + memcpy (&session->key->key.data[2], psk2->data, psk2->size); + + _gnutls_write_datum16 (&session->key->key.data[psk2_size + 2], *ppsk); + + ret = 0; + + error: + _gnutls_free_datum( &psk); + return ret; } @@ -101,7 +154,6 @@ _gnutls_gen_psk_client_kx (gnutls_session_t session, opaque ** data) { int ret; gnutls_psk_client_credentials_t cred; - gnutls_datum *psk; cred = (gnutls_psk_client_credentials_t) _gnutls_get_cred (session->key, GNUTLS_CRD_PSK, NULL); @@ -112,15 +164,13 @@ _gnutls_gen_psk_client_kx (gnutls_session_t session, opaque ** data) return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } - psk = &cred->key; - - if (cred->username.data == NULL || psk == NULL) + if (cred->username.data == NULL || cred->key.data == NULL) { gnutls_assert (); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } - ret = set_psk_session_key (session, psk); + ret = _gnutls_set_psk_session_key (session, NULL); if (ret < 0) { gnutls_assert (); @@ -149,11 +199,10 @@ _gnutls_proc_psk_client_kx (gnutls_session_t session, opaque * data, ssize_t data_size = _data_size; int ret; gnutls_datum username; - gnutls_psk_client_credentials_t cred; - gnutls_datum psk; + gnutls_psk_server_credentials_t cred; psk_server_auth_info_t info; - cred = (gnutls_psk_client_credentials_t) + cred = (gnutls_psk_server_credentials_t) _gnutls_get_cred (session->key, GNUTLS_CRD_PSK, NULL); if (cred == NULL) @@ -191,26 +240,16 @@ _gnutls_proc_psk_client_kx (gnutls_session_t session, opaque * data, memcpy (info->username, username.data, username.size); info->username[username.size] = 0; - /* find the key of this username - */ - ret = _gnutls_psk_pwd_find_entry (session, info->username, &psk); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - - ret = set_psk_session_key (session, &psk); + ret = _gnutls_set_psk_session_key (session, NULL); if (ret < 0) { gnutls_assert (); goto error; } - return 0; + ret = 0; error: - _gnutls_free_datum (&psk); return ret; } diff --git a/lib/auth_psk.h b/lib/auth_psk.h index 432515eb08..bd558da804 100644 --- a/lib/auth_psk.h +++ b/lib/auth_psk.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation + * Copyright (C) 2005 Free Software Foundation * * Author: Nikos Mavroyanopoulos * @@ -26,6 +26,7 @@ # define AUTH_PSK_H #include <gnutls_auth.h> +#include <auth_dh_common.h> typedef struct gnutls_psk_client_credentials_st { @@ -41,6 +42,13 @@ typedef struct gnutls_psk_server_credentials_st * password files. */ gnutls_psk_server_credentials_function *pwd_callback; + + /* For DHE_PSK */ + gnutls_dh_params_t dh_params; + /* this callback is used to retrieve the DH or RSA + * parameters. + */ + gnutls_params_function *params_func; } psk_server_cred_st; /* these structures should not use allocated data */ @@ -50,10 +58,20 @@ typedef struct psk_server_auth_info_st } *psk_server_auth_info_t; +typedef struct psk_client_auth_info_st +{ + dh_info_st dh; +} *psk_client_auth_info_t; + #ifdef ENABLE_PSK typedef struct psk_server_auth_info_st psk_server_auth_info_st; +typedef struct psk_client_auth_info_st psk_client_auth_info_st; +int +_gnutls_set_psk_session_key (gnutls_session_t session, gnutls_datum * psk2); +#else +# define _gnutls_set_psk_session_key(x,y) GNUTLS_E_INTERNAL_ERROR #endif /* ENABLE_PSK */ #endif diff --git a/lib/auth_rsa_export.c b/lib/auth_rsa_export.c index 8f240eac54..f56842fd78 100644 --- a/lib/auth_rsa_export.c +++ b/lib/auth_rsa_export.c @@ -108,7 +108,7 @@ gen_rsa_export_server_kx (gnutls_session_t session, opaque ** data) } rsa_params = _gnutls_certificate_get_rsa_params (cred, session); - rsa_mpis = _gnutls_get_rsa_params (rsa_params); + rsa_mpis = _gnutls_rsa_params_to_mpi (rsa_params); if (rsa_mpis == NULL) { gnutls_assert (); diff --git a/lib/auth_srp.c b/lib/auth_srp.c index d6c0264147..0efadd16a9 100644 --- a/lib/auth_srp.c +++ b/lib/auth_srp.c @@ -335,7 +335,7 @@ _gnutls_gen_srp_client_kx (gnutls_session_t session, opaque ** data) _gnutls_mpi_release (&session->key->u); _gnutls_mpi_release (&B); - ret = _gnutls_generate_session_key (session->key); + ret = _gnutls_mpi_dprint( &session->key->key, session->key->KEY); _gnutls_mpi_release (&S); if (ret < 0) @@ -431,7 +431,7 @@ _gnutls_proc_srp_client_kx (gnutls_session_t session, opaque * data, _gnutls_mpi_release (&session->key->u); _gnutls_mpi_release (&B); - ret = _gnutls_generate_session_key (session->key); + ret = _gnutls_mpi_dprint( &session->key->key, session->key->KEY); _gnutls_mpi_release (&S); if (ret < 0) diff --git a/lib/auth_srp_sb64.c b/lib/auth_srp_sb64.c index ae7513e536..578a66817d 100644 --- a/lib/auth_srp_sb64.c +++ b/lib/auth_srp_sb64.c @@ -330,7 +330,7 @@ gnutls_srp_base64_encode (const gnutls_datum_t * data, char *result, if (size < 0) return size; - if (result == NULL || *result_size < size) + if (result == NULL || *result_size < (size_t)size) { gnutls_free (ret); *result_size = size; @@ -408,7 +408,7 @@ gnutls_srp_base64_decode (const gnutls_datum_t * b64_data, char *result, if (size < 0) return size; - if (result == NULL || *result_size < size) + if (result == NULL || *result_size < (size_t)size) { gnutls_free (ret); *result_size = size; diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c index 8ffe12d1b9..24fd9e2b72 100644 --- a/lib/gnutls_algorithms.c +++ b/lib/gnutls_algorithms.c @@ -47,6 +47,7 @@ static const gnutls_cred_map cred_mappings[] = { {GNUTLS_KX_DHE_DSS, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE}, {GNUTLS_KX_DHE_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE}, {GNUTLS_KX_PSK, GNUTLS_CRD_PSK, GNUTLS_CRD_PSK}, + {GNUTLS_KX_DHE_PSK, GNUTLS_CRD_PSK, GNUTLS_CRD_PSK}, {GNUTLS_KX_SRP, GNUTLS_CRD_SRP, GNUTLS_CRD_SRP}, {GNUTLS_KX_SRP_RSA, GNUTLS_CRD_SRP, GNUTLS_CRD_CERTIFICATE}, {GNUTLS_KX_SRP_DSS, GNUTLS_CRD_SRP, GNUTLS_CRD_CERTIFICATE}, @@ -229,11 +230,12 @@ extern mod_auth_st dhe_dss_auth_struct; extern mod_auth_st anon_auth_struct; extern mod_auth_st srp_auth_struct; extern mod_auth_st psk_auth_struct; +extern mod_auth_st dhe_psk_auth_struct; extern mod_auth_st srp_rsa_auth_struct; extern mod_auth_st srp_dss_auth_struct; -#define MAX_KX_ALGOS 10 +#define MAX_KX_ALGOS 16 const int _gnutls_kx_algorithms_size = MAX_KX_ALGOS; gnutls_kx_algo_entry _gnutls_kx_algorithms[MAX_KX_ALGOS] = { @@ -241,7 +243,7 @@ gnutls_kx_algo_entry _gnutls_kx_algorithms[MAX_KX_ALGOS] = { {"Anon DH", GNUTLS_KX_ANON_DH, &anon_auth_struct, 1, 0}, #endif {"RSA", GNUTLS_KX_RSA, &rsa_auth_struct, 0, 0}, - {"RSA EXPORT", GNUTLS_KX_RSA_EXPORT, &rsa_export_auth_struct, 0, 1}, + {"RSA EXPORT", GNUTLS_KX_RSA_EXPORT, &rsa_export_auth_struct, 0, 1 /* needs RSA params */}, {"DHE RSA", GNUTLS_KX_DHE_RSA, &dhe_rsa_auth_struct, 1, 0}, {"DHE DSS", GNUTLS_KX_DHE_DSS, &dhe_dss_auth_struct, 1, 0}, @@ -252,6 +254,7 @@ gnutls_kx_algo_entry _gnutls_kx_algorithms[MAX_KX_ALGOS] = { #endif #ifdef ENABLE_PSK {"PSK", GNUTLS_KX_PSK, &psk_auth_struct, 0, 0}, + {"DHE PSK", GNUTLS_KX_DHE_PSK, &dhe_psk_auth_struct, 1 /* needs DHE params */, 0}, #endif /* other algorithms are appended here by gnutls-extra * initialization function. @@ -308,6 +311,12 @@ typedef struct #define GNUTLS_PSK_SHA_AES_128_CBC_SHA1 { 0x00, 0x8C } #define GNUTLS_PSK_SHA_AES_256_CBC_SHA1 { 0x00, 0x8D } +#define GNUTLS_DHE_PSK_SHA_ARCFOUR_SHA1 { 0x00, 0x8E } +#define GNUTLS_DHE_PSK_SHA_3DES_EDE_CBC_SHA1 { 0x00, 0x8F } +#define GNUTLS_DHE_PSK_SHA_AES_128_CBC_SHA1 { 0x00, 0x90 } +#define GNUTLS_DHE_PSK_SHA_AES_256_CBC_SHA1 { 0x00, 0x91 } + + /* SRP (not in TLS 1.0) * draft-ietf-tls-srp-02: */ @@ -394,6 +403,20 @@ static const gnutls_cipher_suite_entry cs_algorithms[] = { GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_PSK, GNUTLS_MAC_SHA1, GNUTLS_TLS1), + /* DHE-PSK */ + GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_ARCFOUR_SHA1, + GNUTLS_CIPHER_ARCFOUR, GNUTLS_KX_DHE_PSK, + GNUTLS_MAC_SHA1, GNUTLS_TLS1), + GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_3DES_EDE_CBC_SHA1, + GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_PSK, + GNUTLS_MAC_SHA1, GNUTLS_TLS1), + GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_AES_128_CBC_SHA1, + GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_PSK, + GNUTLS_MAC_SHA1, GNUTLS_TLS1), + GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_AES_256_CBC_SHA1, + GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_PSK, + GNUTLS_MAC_SHA1, GNUTLS_TLS1), + /* SRP */ GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_3DES_EDE_CBC_SHA1, GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP, diff --git a/lib/gnutls_anon_cred.c b/lib/gnutls_anon_cred.c index 0261a7683b..22695e701e 100644 --- a/lib/gnutls_anon_cred.c +++ b/lib/gnutls_anon_cred.c @@ -49,41 +49,6 @@ gnutls_anon_free_server_credentials (gnutls_anon_server_credentials_t sc) gnutls_free (sc); } -/*- - * _gnutls_anon_get_dh_params - Returns the DH parameters pointer - * @sc: is an #gnutls_certificate_credentials_t structure. - * - * This function will return the dh parameters pointer. - * - -*/ -gnutls_dh_params_t -_gnutls_anon_get_dh_params (const - gnutls_anon_server_credentials_t - sc, gnutls_session_t session) -{ - gnutls_params_st params; - int ret; - - if (session->internals.params.anon_dh_params) - return session->internals.params.anon_dh_params; - - if (sc->dh_params) - { - session->internals.params.anon_dh_params = sc->dh_params; - } - else if (sc->params_func) - { - ret = sc->params_func (session, GNUTLS_PARAMS_DH, ¶ms); - if (ret == 0 && params.type == GNUTLS_PARAMS_DH) - { - session->internals.params.anon_dh_params = params.params.dh; - session->internals.params.free_anon_dh_params = params.deinit; - } - } - - return session->internals.params.anon_dh_params; -} - /** * gnutls_anon_allocate_server_credentials - Used to allocate an gnutls_anon_server_credentials_t structure * @sc: is a pointer to an #gnutls_anon_server_credentials_t structure. @@ -137,4 +102,40 @@ gnutls_anon_allocate_client_credentials (gnutls_anon_client_credentials_t * return 0; } +/** + * gnutls_anon_set_server_dh_params - This function will set the DH parameters for a server to use + * @res: is a gnutls_anon_server_credentials_t structure + * @dh_params: is a structure that holds diffie hellman parameters. + * + * This function will set the diffie hellman parameters for an anonymous + * server to use. These parameters will be used in Anonymous Diffie Hellman + * cipher suites. + * + **/ +void +gnutls_anon_set_server_dh_params (gnutls_anon_server_credentials_t res, + gnutls_dh_params_t dh_params) +{ + res->dh_params = dh_params; +} + +/** + * gnutls_anon_set_params_function - This function will set the DH parameters callback + * @res: is a gnutls_certificate_credentials_t structure + * @func: is the function to be called + * + * This function will set a callback in order for the server to get the + * diffie hellman parameters for anonymous authentication. The callback should + * return zero on success. + * + **/ +void +gnutls_anon_set_params_function (gnutls_anon_server_credentials_t res, + gnutls_params_function * func) +{ + res->params_func = func; +} + + + #endif diff --git a/lib/gnutls_auth.c b/lib/gnutls_auth.c index 8d36be1660..926c754b1f 100644 --- a/lib/gnutls_auth.c +++ b/lib/gnutls_auth.c @@ -410,22 +410,3 @@ _gnutls_auth_info_set (gnutls_session_t session, return 0; } -/* this function will copy an mpi_t key to - * opaque data. - */ -int -_gnutls_generate_session_key (gnutls_key_st key) -{ - size_t tmp; - - _gnutls_mpi_print (NULL, &tmp, key->KEY); - key->key.data = gnutls_secure_malloc (tmp); - if (key->key.data == NULL) - { - return GNUTLS_E_MEMORY_ERROR; - } - _gnutls_mpi_print (key->key.data, &tmp, key->KEY); - - key->key.size = tmp; - return 0; -} diff --git a/lib/gnutls_auth_int.h b/lib/gnutls_auth_int.h index acb5de4afb..157398bed7 100644 --- a/lib/gnutls_auth_int.h +++ b/lib/gnutls_auth_int.h @@ -26,7 +26,6 @@ const void *_gnutls_get_cred (gnutls_key_st key, gnutls_credentials_type_t kx, int *err); const void *_gnutls_get_kx_cred (gnutls_session_t session, gnutls_kx_algorithm_t algo, int *err); -int _gnutls_generate_session_key (gnutls_key_st key); void *_gnutls_get_auth_info (gnutls_session_t session); int _gnutls_auth_info_set (gnutls_session_t session, gnutls_credentials_type_t type, int size, diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index c95a02180f..517bd9157c 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -132,45 +132,6 @@ gnutls_certificate_free_ca_names (gnutls_certificate_credentials_t sc) } /*- - * _gnutls_certificate_get_dh_params - Returns the DH parameters pointer - * @sc: is an #gnutls_certificate_credentials_t structure. - * - * This function will return the dh parameters pointer. This will read the - * credentials structure, and cache the output to the session, so later - * calls would not examine the credentials (or call a callback). - * - -*/ -gnutls_dh_params_t -_gnutls_certificate_get_dh_params (const - gnutls_certificate_credentials_t sc, - gnutls_session_t session) -{ - gnutls_params_st params; - int ret; - - if (session->internals.params.cert_dh_params) - { - return session->internals.params.cert_dh_params; - } - - if (sc->dh_params) - { - session->internals.params.cert_dh_params = sc->dh_params; - } - else if (sc->params_func) - { - ret = sc->params_func (session, GNUTLS_PARAMS_DH, ¶ms); - if (ret == 0 && params.type == GNUTLS_PARAMS_DH) - { - session->internals.params.cert_dh_params = params.params.dh; - session->internals.params.free_cert_dh_params = params.deinit; - } - } - - return session->internals.params.cert_dh_params; -} - -/*- * _gnutls_certificate_get_rsa_params - Returns the RSA parameters pointer * @sc: is an #gnutls_certificate_credentials_t structure. * diff --git a/lib/gnutls_dh.c b/lib/gnutls_dh.c index 5eae3c2366..76c851ecfe 100644 --- a/lib/gnutls_dh.c +++ b/lib/gnutls_dh.c @@ -122,3 +122,40 @@ gnutls_calc_dh_key (mpi_t f, mpi_t x, mpi_t prime) _gnutls_mpi_powm (k, f, x, prime); return k; } + +/*- + * _gnutls_get_dh_params - Returns the DH parameters pointer + * @dh_params: is an DH parameters structure, or NULL. + * @func: is a callback function to receive the parameters or NULL. + * @session: a gnutls session. + * + * This function will return the dh parameters pointer. + * + -*/ +gnutls_dh_params_t +_gnutls_get_dh_params (gnutls_dh_params_t dh_params, gnutls_params_function* func, + gnutls_session_t session) +{ + gnutls_params_st params; + int ret; + + /* if cached return the cached */ + if (session->internals.params.dh_params) + return session->internals.params.dh_params; + + if (dh_params) + { + session->internals.params.dh_params = dh_params; + } + else if (func) + { + ret = func (session, GNUTLS_PARAMS_DH, ¶ms); + if (ret == 0 && params.type == GNUTLS_PARAMS_DH) + { + session->internals.params.dh_params = params.params.dh; + session->internals.params.free_dh_params = params.deinit; + } + } + + return session->internals.params.dh_params; +} diff --git a/lib/gnutls_dh.h b/lib/gnutls_dh.h index bbae902478..e27e8f0f7a 100644 --- a/lib/gnutls_dh.h +++ b/lib/gnutls_dh.h @@ -22,7 +22,16 @@ * */ -const mpi_t *_gnutls_get_dh_params (gnutls_dh_params_t); +#ifndef GNUTLS_DH_H +# define GNUTLS_DH_H + +const mpi_t *_gnutls_dh_params_to_mpi (gnutls_dh_params_t); mpi_t gnutls_calc_dh_secret (mpi_t * ret_x, mpi_t g, mpi_t prime); mpi_t gnutls_calc_dh_key (mpi_t f, mpi_t x, mpi_t prime); int _gnutls_dh_generate_prime (mpi_t * ret_g, mpi_t * ret_n, uint bits); + +gnutls_dh_params_t +_gnutls_get_dh_params (gnutls_dh_params_t dh_params, gnutls_params_function* func, + gnutls_session_t session); + +#endif diff --git a/lib/gnutls_dh_primes.c b/lib/gnutls_dh_primes.c index ff383e1f3d..d9289a66a3 100644 --- a/lib/gnutls_dh_primes.c +++ b/lib/gnutls_dh_primes.c @@ -35,7 +35,7 @@ /* returns the prime and the generator of DH params. */ const mpi_t * -_gnutls_get_dh_params (gnutls_dh_params_t dh_primes) +_gnutls_dh_params_to_mpi (gnutls_dh_params_t dh_primes) { if (dh_primes == NULL || dh_primes->params[1] == NULL || dh_primes->params[0] == NULL) diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 4331fb136b..4ee8e44336 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -49,6 +49,7 @@ #include <ext_srp.h> #include <gnutls_rsa_export.h> /* for gnutls_get_rsa_params() */ #include <auth_anon.h> /* for gnutls_anon_server_credentials_t */ +#include <auth_psk.h> /* for gnutls_psk_server_credentials_t */ #include <gc.h> #ifdef HANDSHAKE_DEBUG @@ -2592,7 +2593,7 @@ check_server_params (gnutls_session_t session, if (x509_cred != NULL) { - dh_params = _gnutls_certificate_get_dh_params (x509_cred, session); + dh_params = _gnutls_get_dh_params (x509_cred->dh_params, x509_cred->params_func, session); rsa_params = _gnutls_certificate_get_rsa_params (x509_cred, session); } @@ -2623,7 +2624,20 @@ check_server_params (gnutls_session_t session, if (anon_cred != NULL) { - dh_params = _gnutls_anon_get_dh_params (anon_cred, session); + dh_params = _gnutls_get_dh_params (anon_cred->dh_params, anon_cred->params_func, session); + } +#endif +#ifdef ENABLE_PSK + } + else if (cred_type == GNUTLS_CRD_PSK) + { + gnutls_psk_server_credentials_t psk_cred = + (gnutls_psk_server_credentials_t) _gnutls_get_cred (session->key, + cred_type, NULL); + + if (psk_cred != NULL) + { + dh_params = _gnutls_get_dh_params (psk_cred->dh_params, psk_cred->params_func, session); } #endif } @@ -2637,15 +2651,19 @@ check_server_params (gnutls_session_t session, if (_gnutls_kx_needs_rsa_params (kx) != 0) { /* needs rsa params. */ - if (_gnutls_get_rsa_params (rsa_params) == NULL) + if (_gnutls_rsa_params_to_mpi (rsa_params) == NULL) { + gnutls_assert(); return 1; + } } if (_gnutls_kx_needs_dh_params (kx) != 0) { /* needs DH params. */ - if (_gnutls_get_dh_params (dh_params) == NULL) + if (_gnutls_dh_params_to_mpi (dh_params) == NULL) { + gnutls_assert(); return 1; + } } return 0; diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 654aafacd9..1380242434 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -364,10 +364,8 @@ typedef struct gnutls_dh_params_int typedef struct { - gnutls_dh_params_t anon_dh_params; - int free_anon_dh_params; - gnutls_dh_params_t cert_dh_params; - int free_cert_dh_params; + gnutls_dh_params_t dh_params; + int free_dh_params; gnutls_rsa_params_t rsa_params; int free_rsa_params; } internal_params_st; diff --git a/lib/gnutls_mpi.c b/lib/gnutls_mpi.c index d0fcd5da1d..5385f795e8 100644 --- a/lib/gnutls_mpi.c +++ b/lib/gnutls_mpi.c @@ -159,6 +159,35 @@ _gnutls_mpi_dprint_lz (gnutls_datum_t * dest, const mpi_t a) return GNUTLS_E_MPI_PRINT_FAILED; } +int +_gnutls_mpi_dprint(gnutls_datum_t * dest, const mpi_t a) +{ + int ret; + opaque *buf = NULL; + size_t bytes = 0; + + if (dest == NULL || a == NULL) + return GNUTLS_E_INVALID_REQUEST; + + gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &bytes, a); + + if (bytes != 0) + buf = gnutls_malloc (bytes); + if (buf == NULL) + return GNUTLS_E_MEMORY_ERROR; + + ret = gcry_mpi_print (GCRYMPI_FMT_USG, buf, bytes, &bytes, a); + if (!ret) + { + dest->data = buf; + dest->size = bytes; + return 0; + } + + gnutls_free (buf); + return GNUTLS_E_MPI_PRINT_FAILED; +} + /* this function reads an integer * from asn1 structs. Combines the read and mpi_scan diff --git a/lib/gnutls_mpi.h b/lib/gnutls_mpi.h index 2efde82d2d..8d83aaba9d 100644 --- a/lib/gnutls_mpi.h +++ b/lib/gnutls_mpi.h @@ -72,6 +72,6 @@ int _gnutls_mpi_print (void *buffer, size_t * nbytes, const mpi_t a); int _gnutls_mpi_print_lz (void *buffer, size_t * nbytes, const mpi_t a); int _gnutls_mpi_dprint_lz (gnutls_datum_t * dest, const mpi_t a); -#define _gnutls_mpi_dprint _gnutls_mpi_dprint_lz +int _gnutls_mpi_dprint(gnutls_datum_t * dest, const mpi_t a); #endif diff --git a/lib/gnutls_psk.c b/lib/gnutls_psk.c index 1dab4f72e5..080edb0f99 100644 --- a/lib/gnutls_psk.c +++ b/lib/gnutls_psk.c @@ -357,5 +357,38 @@ gnutls_hex_encode (const gnutls_datum_t * data, char *result, return 0; } +/** + * gnutls_psk_set_server_dh_params - This function will set the DH parameters for a server to use + * @res: is a gnutls_psk_server_credentials_t structure + * @dh_params: is a structure that holds diffie hellman parameters. + * + * This function will set the diffie hellman parameters for an anonymous + * server to use. These parameters will be used in Diffie Hellman with PSK + * cipher suites. + * + **/ +void +gnutls_psk_set_server_dh_params (gnutls_psk_server_credentials_t res, + gnutls_dh_params_t dh_params) +{ + res->dh_params = dh_params; +} + +/** + * gnutls_psk_set_params_function - This function will set the DH parameters callback + * @res: is a gnutls_certificate_credentials_t structure + * @func: is the function to be called + * + * This function will set a callback in order for the server to get the + * diffie hellman parameters for PSK authentication. The callback should + * return zero on success. + * + **/ +void +gnutls_psk_set_params_function (gnutls_psk_server_credentials_t res, + gnutls_params_function * func) +{ + res->params_func = func; +} #endif /* ENABLE_PSK */ diff --git a/lib/gnutls_rsa_export.c b/lib/gnutls_rsa_export.c index 7121ee6d74..8344fe99ab 100644 --- a/lib/gnutls_rsa_export.c +++ b/lib/gnutls_rsa_export.c @@ -45,7 +45,7 @@ * We only support limited key sizes. */ const mpi_t * -_gnutls_get_rsa_params (gnutls_rsa_params_t rsa_params) +_gnutls_rsa_params_to_mpi (gnutls_rsa_params_t rsa_params) { if (rsa_params == NULL) { diff --git a/lib/gnutls_rsa_export.h b/lib/gnutls_rsa_export.h index 932852d11a..1a825de245 100644 --- a/lib/gnutls_rsa_export.h +++ b/lib/gnutls_rsa_export.h @@ -22,6 +22,6 @@ * */ -const mpi_t *_gnutls_get_rsa_params (gnutls_rsa_params_t); +const mpi_t *_gnutls_rsa_params_to_mpi (gnutls_rsa_params_t); int _gnutls_peers_cert_less_512 (gnutls_session_t session); int _gnutls_rsa_generate_params (mpi_t * resarr, int *resarr_len, int bits); diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index b8c258de9d..b7039c0851 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -174,11 +174,8 @@ _gnutls_session_cert_type_supported (gnutls_session_t session, inline static void deinit_internal_params (gnutls_session_t session) { - if (session->internals.params.free_anon_dh_params) - gnutls_dh_params_deinit (session->internals.params.anon_dh_params); - - if (session->internals.params.free_cert_dh_params) - gnutls_dh_params_deinit (session->internals.params.cert_dh_params); + if (session->internals.params.free_dh_params) + gnutls_dh_params_deinit (session->internals.params.dh_params); if (session->internals.params.free_rsa_params) gnutls_rsa_params_deinit (session->internals.params.rsa_params); diff --git a/lib/gnutls_ui.c b/lib/gnutls_ui.c index ec2a007dfd..2a03586588 100644 --- a/lib/gnutls_ui.c +++ b/lib/gnutls_ui.c @@ -22,7 +22,7 @@ * */ -/* This file was intended to contains functions to be exported in the +/* This file contains certificate authentication functions to be exported in the * API and did not fit elsewhere. */ @@ -511,22 +511,6 @@ gnutls_fingerprint (gnutls_digest_algorithm_t algo, return 0; } -/** - * gnutls_anon_set_server_dh_params - This function will set the DH parameters for a server to use - * @res: is a gnutls_anon_server_credentials_t structure - * @dh_params: is a structure that holds diffie hellman parameters. - * - * This function will set the diffie hellman parameters for an anonymous - * server to use. These parameters will be used in Anonymous Diffie Hellman - * cipher suites. - * - **/ -void -gnutls_anon_set_server_dh_params (gnutls_anon_server_credentials_t res, - gnutls_dh_params_t dh_params) -{ - res->dh_params = dh_params; -} /** * gnutls_certificate_set_dh_params - This function will set the DH parameters for a server to use @@ -565,23 +549,6 @@ gnutls_certificate_set_params_function (gnutls_certificate_credentials_t res, res->params_func = func; } -/** - * gnutls_anon_set_params_function - This function will set the DH parameters callback - * @res: is a gnutls_certificate_credentials_t structure - * @func: is the function to be called - * - * This function will set a callback in order for the server to get the - * diffie hellman parameters for anonymous authentication. The callback should - * return zero on success. - * - **/ -void -gnutls_anon_set_params_function (gnutls_anon_server_credentials_t res, - gnutls_params_function * func) -{ - res->params_func = func; -} - /** * gnutls_certificate_set_verify_flags - This function will set the flags to be used at certificate verification diff --git a/src/common.c b/src/common.c index 261a769314..4acccf3ff1 100644 --- a/src/common.c +++ b/src/common.c @@ -615,6 +615,7 @@ print_list (void) printf (", RSA-EXPORT"); printf (", DHE-DSS"); printf (", DHE-RSA"); + printf (", DHE-PSK"); printf (", PSK"); printf (", SRP"); printf (", SRP-RSA"); @@ -753,6 +754,8 @@ parse_kx (char **kx, int nkx, int *kx_priority) kx_priority[j++] = GNUTLS_KX_RSA; else if (strcasecmp (kx[i], "PSK") == 0) kx_priority[j++] = GNUTLS_KX_PSK; + else if (strcasecmp (kx[i], "DHE-PSK") == 0) + kx_priority[j++] = GNUTLS_KX_DHE_PSK; else if (strcasecmp (kx[i], "RSA-EXPORT") == 0) kx_priority[j++] = GNUTLS_KX_RSA_EXPORT; else if (strncasecmp (kx[i], "DHE-RSA", 7) == 0) diff --git a/src/serv.c b/src/serv.c index 1f0d79dcf2..2af99355cc 100644 --- a/src/serv.c +++ b/src/serv.c @@ -805,6 +805,8 @@ main (int argc, char **argv) fprintf (stderr, "Error while setting PSK parameters\n"); GERR (ret); } + + gnutls_psk_set_params_function (psk_cred, get_params); } #endif diff --git a/tests/Makefile.am b/tests/Makefile.am index e997178c20..ab21e593e4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -30,7 +30,7 @@ EXTRA_DIST = client.p12 noclient.p12 unclient.p12 openssl_LDADD = $(LDADD) ../libextra/libgnutls-openssl.la -ctests = simple anonself pskself openssl gc +ctests = simple anonself pskself openssl gc dhepskself TESTS = pkcs12_neon $(ctests) check_PROGRAMS = $(ctests) dist_check_SCRIPTS = pkcs12_neon diff --git a/tests/dhepskself.c b/tests/dhepskself.c new file mode 100644 index 0000000000..fff760179e --- /dev/null +++ b/tests/dhepskself.c @@ -0,0 +1,395 @@ +/* + * Copyright (C) 2004, 2005 Free Software Foundation + * + * 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 2 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. */ + +#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 "utils.h" + +/* A very basic TLS client, with PSK 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); +} + +/* Connects to the peer and returns a socket + * descriptor. + */ +int +tcp_connect (void) +{ + const char *PORT = "5556"; + const char *SERVER = "127.0.0.1"; + int err, sd; + struct sockaddr_in sa; + + /* connects to server + */ + sd = socket (AF_INET, SOCK_STREAM, 0); + + memset (&sa, '\0', sizeof (sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons (atoi (PORT)); + inet_pton (AF_INET, SERVER, &sa.sin_addr); + + err = connect (sd, (struct sockaddr *) &sa, sizeof (sa)); + if (err < 0) + { + fprintf (stderr, "Connect error\n"); + exit (1); + } + + return sd; +} + +/* closes the given socket descriptor. + */ +void +tcp_close (int sd) +{ + shutdown (sd, SHUT_RDWR); /* no more receptions */ + close (sd); +} + +void +client (void) +{ + int ret, sd, ii; + gnutls_session_t session; + char buffer[MAX_BUF + 1]; + gnutls_psk_client_credentials_t pskcred; + /* Need to enable anonymous KX specifically. */ + const int kx_prio[] = { GNUTLS_KX_DHE_PSK, 0 }; + const gnutls_datum_t key = { "DEADBEEF", 8 }; + + gnutls_global_init (); + + gnutls_global_set_log_function (tls_log_func); +// gnutls_global_set_log_level (99); + + gnutls_psk_allocate_client_credentials (&pskcred); + gnutls_psk_set_client_credentials (pskcred, "test", &key, + GNUTLS_PSK_KEY_HEX); + + /* 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_PSK, pskcred); + + /* 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) + { + fail ("client: Handshake failed\n"); + gnutls_perror (ret); + goto end; + } + else + { + success ("client: Handshake was completed\n"); + } + + gnutls_record_send (session, MSG, strlen (MSG)); + + ret = gnutls_record_recv (session, buffer, MAX_BUF); + if (ret == 0) + { + 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_psk_free_client_credentials (pskcred); + + gnutls_global_deinit (); +} + +/* This is a sample TLS 1.0 echo server, for PSK authentication. + */ + +#define SA struct sockaddr +#define MAX_BUF 1024 +#define PORT 5556 /* listen to 5556 port */ +#define DH_BITS 1024 + +/* These are global */ +gnutls_psk_server_credentials_t server_pskcred; + +gnutls_session_t +initialize_tls_session (void) +{ + gnutls_session_t session; + const int kx_prio[] = { GNUTLS_KX_DHE_PSK, 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_PSK, server_pskcred); + + return session; +} + +static gnutls_dh_params_t dh_params; + +static int +generate_dh_params (void) +{ + + /* 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); + gnutls_dh_params_generate2 (dh_params, DH_BITS); + + return 0; +} + +static int +pskfunc (gnutls_session_t session, const char *username, gnutls_datum_t * key) +{ + printf ("psk: username %s\n", username); + key->data = gnutls_malloc (4); + key->data[0] = 0xDE; + key->data[1] = 0xAD; + key->data[2] = 0xBE; + key->data[3] = 0xEF; + key->size = 4; + return 0; +} + +int err, listen_sd, i; +int sd, ret; +struct sockaddr_in sa_serv; +struct sockaddr_in sa_cli; +int client_len; +char topbuf[512]; +gnutls_session_t session; +char buffer[MAX_BUF + 1]; +int optval = 1; + +void +server_start (void) +{ + /* this must be called once in the program + */ + gnutls_global_init (); + + gnutls_global_set_log_function (tls_log_func); +// gnutls_global_set_log_level (99); + + generate_dh_params(); + + gnutls_psk_allocate_server_credentials (&server_pskcred); + gnutls_psk_set_server_credentials_function (server_pskcred, pskfunc); + gnutls_psk_set_server_dh_params( server_pskcred, dh_params); + + success ("Launched, generating DH parameters...\n"); + + /* 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, &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; + } + + success ("server: ready. Listening to port '%d'.\n", PORT); +} + +void +server (void) +{ + client_len = sizeof (sa_cli); + + session = initialize_tls_session (); + + sd = accept (listen_sd, (SA *) & sa_cli, &client_len); + + 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); + ret = gnutls_handshake (session); + if (ret < 0) + { + close (sd); + gnutls_deinit (session); + fail ("server: Handshake has failed (%s)\n\n", gnutls_strerror (ret)); + return; + } + success ("server: Handshake was completed\n"); + + /* see the Getting peer's information example */ + /* print_info(session); */ + + i = 0; + for (;;) + { + bzero (buffer, MAX_BUF + 1); + ret = gnutls_record_recv (session, buffer, MAX_BUF); + + if (ret == 0) + { + success ("server: Peer has closed the GNUTLS connection\n"); + break; + } + else if (ret < 0) + { + 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_psk_free_server_credentials (server_pskcred); + + gnutls_global_deinit (); + + 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 (); +} diff --git a/tests/pskself.c b/tests/pskself.c index 27d2f95a19..91bf176e44 100644 --- a/tests/pskself.c +++ b/tests/pskself.c @@ -194,28 +194,9 @@ initialize_tls_session (void) gnutls_credentials_set (session, GNUTLS_CRD_PSK, server_pskcred); - gnutls_dh_set_prime_bits (session, DH_BITS); - return session; } -static gnutls_dh_params_t dh_params; - -static int -generate_dh_params (void) -{ - - /* 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); - gnutls_dh_params_generate2 (dh_params, DH_BITS); - - return 0; -} - static int pskfunc (gnutls_session_t session, const char *username, gnutls_datum_t * key) { |