summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--includes/gnutls/gnutls.h.in16
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/auth_anon.c8
-rw-r--r--lib/auth_anon.h3
-rw-r--r--lib/auth_cert.h5
-rw-r--r--lib/auth_dh_common.c49
-rw-r--r--lib/auth_dhe.c8
-rw-r--r--lib/auth_dhe_psk.c176
-rw-r--r--lib/auth_psk.c97
-rw-r--r--lib/auth_psk.h20
-rw-r--r--lib/auth_rsa_export.c2
-rw-r--r--lib/auth_srp.c4
-rw-r--r--lib/auth_srp_sb64.c4
-rw-r--r--lib/gnutls_algorithms.c27
-rw-r--r--lib/gnutls_anon_cred.c71
-rw-r--r--lib/gnutls_auth.c19
-rw-r--r--lib/gnutls_auth_int.h1
-rw-r--r--lib/gnutls_cert.c39
-rw-r--r--lib/gnutls_dh.c37
-rw-r--r--lib/gnutls_dh.h11
-rw-r--r--lib/gnutls_dh_primes.c2
-rw-r--r--lib/gnutls_handshake.c26
-rw-r--r--lib/gnutls_int.h6
-rw-r--r--lib/gnutls_mpi.c29
-rw-r--r--lib/gnutls_mpi.h2
-rw-r--r--lib/gnutls_psk.c33
-rw-r--r--lib/gnutls_rsa_export.c2
-rw-r--r--lib/gnutls_rsa_export.h2
-rw-r--r--lib/gnutls_state.c7
-rw-r--r--lib/gnutls_ui.c35
-rw-r--r--src/common.c3
-rw-r--r--src/serv.c2
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/dhepskself.c395
-rw-r--r--tests/pskself.c19
36 files changed, 939 insertions, 228 deletions
diff --git a/NEWS b/NEWS
index cb6f581e7a..3538e29dbc 100644
--- a/NEWS
+++ b/NEWS
@@ -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, &params);
- 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, &params);
- 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, &params);
+ 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)
{