gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, master, updated. gnutls_2_99_2-7-g911d1b1


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_2_99_2-7-g911d1b1
Date: Fri, 27 May 2011 21:55:37 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=911d1b16482cbe53c0c47db7c08c3c2749731c43

The branch, master has been updated
       via  911d1b16482cbe53c0c47db7c08c3c2749731c43 (commit)
      from  5281029f727f18186ee15f0e1021eead09d4f2c5 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 911d1b16482cbe53c0c47db7c08c3c2749731c43
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri May 27 23:53:38 2011 +0200

    Added ECDHE-PSK ciphersuites for TLS (RFC 5489).

-----------------------------------------------------------------------

Summary of changes:
 NEWS                            |    8 ++
 lib/algorithms/ciphersuites.c   |   38 ++++++++++
 lib/algorithms/kx.c             |    7 ++-
 lib/auth/anon.c                 |    6 +-
 lib/auth/anon_ecdh.c            |    3 +-
 lib/auth/dh_common.c            |   36 ++--------
 lib/auth/dh_common.h            |    7 +-
 lib/auth/dhe.c                  |    9 ++-
 lib/auth/dhe_psk.c              |  145 +++++++++++++++++++++++++++++++++++++--
 lib/auth/ecdh_common.c          |   55 ++++++++++++---
 lib/auth/ecdh_common.h          |   19 ++++-
 lib/gnutls_state.c              |    3 +-
 lib/includes/gnutls/gnutls.h.in |    2 +
 13 files changed, 272 insertions(+), 66 deletions(-)

diff --git a/NEWS b/NEWS
index b3edf68..86abf15 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,14 @@ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005,
               2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 See the end for copying conditions.
 
+* Version 2.99.3 (unreleased)
+
+** libgnutls: Added ECDHE-PSK ciphersuites for TLS (RFC 5489).
+
+** API and ABI modifications:
+GNUTLS_KX_ECDHE_PSK: New key exchange method
+
+
 * Version 2.99.2 (released 2011-05-26)
 
 ** libgnutls: Added Elliptic curve support. This is not
diff --git a/lib/algorithms/ciphersuites.c b/lib/algorithms/ciphersuites.c
index 09b115d..e834e16 100644
--- a/lib/algorithms/ciphersuites.c
+++ b/lib/algorithms/ciphersuites.c
@@ -216,6 +216,15 @@ typedef struct
 #define GNUTLS_ECDHE_ECDSA_AES_128_GCM_SHA256   {0xC0,0x2B}
 #define GNUTLS_ECDHE_RSA_AES_128_GCM_SHA256     {0xC0,0x2F}
 
+/* ECC with PSK */
+#define GNUTLS_ECDHE_PSK_3DES_EDE_CBC_SHA { 0xC0, 0x34 }
+#define GNUTLS_ECDHE_PSK_AES_128_CBC_SHA { 0xC0, 0x35 }
+#define GNUTLS_ECDHE_PSK_AES_256_CBC_SHA { 0xC0, 0x36 }
+#define GNUTLS_ECDHE_PSK_AES_128_CBC_SHA256 { 0xC0, 0x37 }
+#define GNUTLS_ECDHE_PSK_AES_256_CBC_SHA384 { 0xC0, 0x38 }
+#define GNUTLS_ECDHE_PSK_NULL_SHA256 { 0xC0, 0x3A }
+#define GNUTLS_ECDHE_PSK_NULL_SHA384 { 0xC0, 0x3B }
+
 #define CIPHER_SUITES_COUNT 
(sizeof(cs_algorithms)/sizeof(gnutls_cipher_suite_entry)-1)
 
 /* FIXME: what we don't handle here is TLS 1.2 requirement
@@ -581,6 +590,35 @@ static const gnutls_cipher_suite_entry cs_algorithms[] = {
                              GNUTLS_CIPHER_AES_128_GCM, GNUTLS_KX_ECDHE_RSA,
                              GNUTLS_MAC_AEAD, GNUTLS_TLS1_2,
                              GNUTLS_VERSION_MAX, 1),
+  /* ECC - PSK */
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_PSK_3DES_EDE_CBC_SHA,
+                             GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_ECDHE_PSK,
+                             GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_PSK_AES_128_CBC_SHA,
+                             GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ECDHE_PSK,
+                             GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_PSK_AES_256_CBC_SHA,
+                             GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_ECDHE_PSK,
+                             GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_PSK_AES_128_CBC_SHA256,
+                             GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ECDHE_PSK,
+                             GNUTLS_MAC_SHA256, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_PSK_AES_256_CBC_SHA384,
+                             GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ECDHE_PSK,
+                             GNUTLS_MAC_SHA384, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_PSK_NULL_SHA256,
+                             GNUTLS_CIPHER_NULL, GNUTLS_KX_ECDHE_PSK,
+                             GNUTLS_MAC_SHA256, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_PSK_NULL_SHA384,
+                             GNUTLS_CIPHER_NULL, GNUTLS_KX_ECDHE_PSK,
+                             GNUTLS_MAC_SHA384, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
   {0, {{0, 0}}, 0, 0, 0, 0, 0, 0}
 };
 
diff --git a/lib/algorithms/kx.c b/lib/algorithms/kx.c
index 36a5647..f3e2196 100644
--- a/lib/algorithms/kx.c
+++ b/lib/algorithms/kx.c
@@ -32,6 +32,7 @@ extern mod_auth_st rsa_auth_struct;
 extern mod_auth_st rsa_export_auth_struct;
 extern mod_auth_st dhe_rsa_auth_struct;
 extern mod_auth_st ecdhe_rsa_auth_struct;
+extern mod_auth_st ecdhe_psk_auth_struct;
 extern mod_auth_st ecdhe_ecdsa_auth_struct;
 extern mod_auth_st dhe_dss_auth_struct;
 extern mod_auth_st anon_auth_struct;
@@ -66,6 +67,7 @@ static const gnutls_cred_map cred_mappings[] = {
   {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_ECDHE_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},
@@ -98,8 +100,8 @@ static const gnutls_kx_algo_entry _gnutls_kx_algorithms[] = {
   {"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},
-  {"ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, &ecdhe_rsa_auth_struct, 1, 0},
-  {"ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, &ecdhe_ecdsa_auth_struct, 1, 0},
+  {"ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, &ecdhe_rsa_auth_struct, 0, 0},
+  {"ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, &ecdhe_ecdsa_auth_struct, 0, 0},
   {"DHE-DSS", GNUTLS_KX_DHE_DSS, &dhe_dss_auth_struct, 1, 0},
 
 #ifdef ENABLE_SRP
@@ -111,6 +113,7 @@ static const gnutls_kx_algo_entry _gnutls_kx_algorithms[] = 
{
   {"PSK", GNUTLS_KX_PSK, &psk_auth_struct, 0, 0},
   {"DHE-PSK", GNUTLS_KX_DHE_PSK, &dhe_psk_auth_struct,
    1 /* needs DHE params */ , 0},
+  {"ECDHE-PSK", GNUTLS_KX_ECDHE_PSK, &ecdhe_psk_auth_struct, 0 , 0},
 #endif
   {0, 0, 0, 0, 0}
 };
diff --git a/lib/auth/anon.c b/lib/auth/anon.c
index ef3b910..691b5d6 100644
--- a/lib/auth/anon.c
+++ b/lib/auth/anon.c
@@ -101,7 +101,7 @@ gen_anon_server_kx (gnutls_session_t session, 
gnutls_buffer_st* data)
 
   _gnutls_dh_set_group (session, g, p);
 
-  ret = _gnutls_dh_common_print_server_kx (session, g, p, data, 0);
+  ret = _gnutls_dh_common_print_server_kx (session, g, p, data);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -141,7 +141,7 @@ proc_anon_client_kx (gnutls_session_t session, opaque * 
data,
   p = mpis[0];
   g = mpis[1];
 
-  ret = _gnutls_proc_dh_common_client_kx (session, data, _data_size, g, p);
+  ret = _gnutls_proc_dh_common_client_kx (session, data, _data_size, g, p, 
NULL);
 
   return ret;
 
@@ -163,7 +163,7 @@ proc_anon_server_kx (gnutls_session_t session, opaque * 
data,
       return ret;
     }
 
-  ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size, 0);
+  ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size);
   if (ret < 0)
     {
       gnutls_assert ();
diff --git a/lib/auth/anon_ecdh.c b/lib/auth/anon_ecdh.c
index e87f80c..8506a55 100644
--- a/lib/auth/anon_ecdh.c
+++ b/lib/auth/anon_ecdh.c
@@ -109,7 +109,8 @@ proc_anon_ecdh_client_kx (gnutls_session_t session, opaque 
* data,
       return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
     }
 
-  return _gnutls_proc_ecdh_common_client_kx (session, data, _data_size, 
_gnutls_session_ecc_curve_get(session));
+  return _gnutls_proc_ecdh_common_client_kx (session, data, _data_size, 
+                                             
_gnutls_session_ecc_curve_get(session), NULL);
 }
 
 int
diff --git a/lib/auth/dh_common.c b/lib/auth/dh_common.c
index 5b8aab3..a0fb9c4 100644
--- a/lib/auth/dh_common.c
+++ b/lib/auth/dh_common.c
@@ -55,7 +55,8 @@ _gnutls_free_dh_info (dh_info_st * dh)
 int
 _gnutls_proc_dh_common_client_kx (gnutls_session_t session,
                                   opaque * data, size_t _data_size,
-                                  bigint_t g, bigint_t p)
+                                  bigint_t g, bigint_t p,
+                                  gnutls_datum_t* psk_key)
 {
   uint16_t n_Y;
   size_t _n_Y;
@@ -89,9 +90,7 @@ _gnutls_proc_dh_common_client_kx (gnutls_session_t session,
   _gnutls_mpi_release (&session->key->dh_secret);
 
 
-  if (_gnutls_cipher_suite_get_kx_algo
-      (&session->security_parameters.current_cipher_suite)
-      != GNUTLS_KX_DHE_PSK)
+  if (psk_key == NULL)
     {
       ret = _gnutls_mpi_dprint (session->key->KEY, &session->key->key);
     }
@@ -105,7 +104,7 @@ _gnutls_proc_dh_common_client_kx (gnutls_session_t session,
           return ret;
         }
 
-      ret = _gnutls_set_psk_session_key (session, NULL, &tmp_dh_key);
+      ret = _gnutls_set_psk_session_key (session, psk_key, &tmp_dh_key);
       _gnutls_free_datum (&tmp_dh_key);
 
     }
@@ -205,26 +204,18 @@ error:
 /* Returns the bytes parsed */
 int
 _gnutls_proc_dh_common_server_kx (gnutls_session_t session,
-                                  opaque * data, size_t _data_size, int psk)
+                                  opaque * data, size_t _data_size)
 {
   uint16_t n_Y, n_g, n_p;
   size_t _n_Y, _n_g, _n_p;
   uint8_t *data_p;
   uint8_t *data_g;
   uint8_t *data_Y;
-  int i, bits, psk_size, ret;
+  int i, bits, ret;
   ssize_t data_size = _data_size;
 
   i = 0;
 
-  if (psk != 0)
-    {
-      DECR_LEN (data_size, 2);
-      psk_size = _gnutls_read_uint16 (&data[i]);
-      DECR_LEN (data_size, psk_size);
-      i += 2 + psk_size;
-    }
-
   DECR_LEN (data_size, 2);
   n_p = _gnutls_read_uint16 (&data[i]);
   i += 2;
@@ -290,8 +281,6 @@ _gnutls_proc_dh_common_server_kx (gnutls_session_t session,
   _gnutls_dh_set_peer_public (session, session->key->client_Y);
 
   ret = n_Y + n_p + n_g + 6;
-  if (psk != 0)
-    ret += 2;
 
   return ret;
 }
@@ -300,8 +289,7 @@ _gnutls_proc_dh_common_server_kx (gnutls_session_t session,
  * be inserted */
 int
 _gnutls_dh_common_print_server_kx (gnutls_session_t session,
-                                   bigint_t g, bigint_t p, gnutls_buffer_st* 
data,
-                                   int psk)
+                                   bigint_t g, bigint_t p, gnutls_buffer_st* 
data)
 {
   bigint_t x, X;
   int ret;
@@ -316,16 +304,6 @@ _gnutls_dh_common_print_server_kx (gnutls_session_t 
session,
   session->key->dh_secret = x;
   _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
 
-  if (psk != 0)
-    {
-      ret = _gnutls_buffer_append_prefix(data, 16, 0);
-      if (ret < 0)
-        {
-          ret = gnutls_assert_val(ret);
-          goto cleanup;
-        }
-    }
-
   ret = _gnutls_buffer_append_mpi(data, 16, p, 0);
   if (ret < 0)
     {
diff --git a/lib/auth/dh_common.h b/lib/auth/dh_common.h
index 9c528f1..2ad459b 100644
--- a/lib/auth/dh_common.h
+++ b/lib/auth/dh_common.h
@@ -42,10 +42,11 @@ int _gnutls_gen_dh_common_client_kx_int (gnutls_session_t, 
gnutls_buffer_st*, gn
 int _gnutls_gen_dh_common_client_kx (gnutls_session_t, gnutls_buffer_st*);
 int _gnutls_proc_dh_common_client_kx (gnutls_session_t session,
                                       opaque * data, size_t _data_size,
-                                      bigint_t p, bigint_t g);
+                                      bigint_t p, bigint_t g,
+                                      gnutls_datum_t* psk_key);
 int _gnutls_dh_common_print_server_kx (gnutls_session_t, bigint_t g,
-                                       bigint_t p, gnutls_buffer_st* data, int 
psk);
+                                       bigint_t p, gnutls_buffer_st* data);
 int _gnutls_proc_dh_common_server_kx (gnutls_session_t session, opaque * data,
-                                      size_t _data_size, int psk);
+                                      size_t _data_size);
 
 #endif
diff --git a/lib/auth/dhe.c b/lib/auth/dhe.c
index c43c9df..422ce59 100644
--- a/lib/auth/dhe.c
+++ b/lib/auth/dhe.c
@@ -170,7 +170,7 @@ gen_dhe_server_kx (gnutls_session_t session, 
gnutls_buffer_st* data)
 
       _gnutls_dh_set_group (session, g, p);
 
-      ret = _gnutls_dh_common_print_server_kx (session, g, p, data, 0);
+      ret = _gnutls_dh_common_print_server_kx (session, g, p, data);
     }
   else
     {
@@ -273,7 +273,7 @@ proc_dhe_server_kx (gnutls_session_t session, opaque * data,
     }
 
   if (!_gnutls_session_is_ecc (session))
-    ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size, 0);
+    ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size);
   else
     ret = _gnutls_proc_ecdh_common_server_kx (session, data, _data_size);
 
@@ -367,10 +367,11 @@ proc_dhe_client_kx (gnutls_session_t session, opaque * 
data,
       p = mpis[0];
       g = mpis[1];
 
-      ret = _gnutls_proc_dh_common_client_kx (session, data, _data_size, g, p);
+      ret = _gnutls_proc_dh_common_client_kx (session, data, _data_size, g, p, 
NULL);
     }
   else
-    ret = _gnutls_proc_ecdh_common_client_kx (session, data, _data_size, 
_gnutls_session_ecc_curve_get(session));
+    ret = _gnutls_proc_ecdh_common_client_kx (session, data, _data_size, 
+                                              
_gnutls_session_ecc_curve_get(session), NULL);
 
   return ret;
 
diff --git a/lib/auth/dhe_psk.c b/lib/auth/dhe_psk.c
index c73631f..d39b6dc 100644
--- a/lib/auth/dhe_psk.c
+++ b/lib/auth/dhe_psk.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2005, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
  *
  * Author: Nikos Mavrogiannopoulos
  *
@@ -30,6 +30,9 @@
 
 #ifdef ENABLE_PSK
 
+/* Contains PSK code for DHE and ECDHE
+ */
+
 #include "gnutls_auth.h"
 #include "gnutls_errors.h"
 #include "gnutls_dh.h"
@@ -38,12 +41,17 @@
 #include "gnutls_mpi.h"
 #include <gnutls_state.h>
 #include <auth/dh_common.h>
+#include <auth/ecdh_common.h>
 #include <gnutls_datum.h>
+#include <auth/psk_passwd.h>
 
 static int gen_psk_server_kx (gnutls_session_t, gnutls_buffer_st*);
 static int gen_psk_client_kx (gnutls_session_t, gnutls_buffer_st*);
 static int proc_psk_client_kx (gnutls_session_t, opaque *, size_t);
 static int proc_psk_server_kx (gnutls_session_t, opaque *, size_t);
+static int gen_ecdhe_psk_server_kx (gnutls_session_t session, 
gnutls_buffer_st* data);
+static int proc_ecdhe_psk_client_kx (gnutls_session_t session, opaque * data,
+                                     size_t _data_size);
 
 const mod_auth_st dhe_psk_auth_struct = {
   "DHE PSK",
@@ -62,6 +70,23 @@ const mod_auth_st dhe_psk_auth_struct = {
   NULL
 };
 
+const mod_auth_st ecdhe_psk_auth_struct = {
+  "ECDHE PSK",
+  NULL,
+  NULL,
+  gen_ecdhe_psk_server_kx,
+  gen_psk_client_kx,
+  NULL,
+  NULL,
+
+  NULL,
+  NULL,                         /* certificate */
+  proc_psk_server_kx,
+  proc_ecdhe_psk_client_kx,
+  NULL,
+  NULL
+};
+
 static int
 gen_psk_client_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
@@ -87,7 +112,11 @@ gen_psk_client_kx (gnutls_session_t session, 
gnutls_buffer_st* data)
     }
 
   /* The PSK key is set in there */
-  ret = _gnutls_gen_dh_common_client_kx_int (session, data, &key);
+  if (!_gnutls_session_is_ecc (session))
+    ret = _gnutls_gen_dh_common_client_kx_int (session, data, &key);
+  else
+    ret = _gnutls_gen_ecdh_common_client_kx_int (session, data, &key);
+
   if (ret < 0)
     {
       gnutls_assert ();
@@ -146,12 +175,39 @@ gen_psk_server_kx (gnutls_session_t session, 
gnutls_buffer_st* data)
 
   _gnutls_dh_set_group (session, g, p);
 
-  ret = _gnutls_dh_common_print_server_kx (session, g, p, data, 1);
+  ret = _gnutls_buffer_append_prefix(data, 16, 0);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
+
+  ret = _gnutls_dh_common_print_server_kx (session, g, p, data);
   if (ret < 0)
+    gnutls_assert ();
+
+  return ret;
+}
+
+static int
+gen_ecdhe_psk_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
+{
+  int ret;
+
+  if ((ret =
+       _gnutls_auth_info_set (session, GNUTLS_CRD_PSK,
+                              sizeof (psk_auth_info_st), 1)) < 0)
     {
       gnutls_assert ();
+      return ret;
     }
 
+  ret = _gnutls_buffer_append_prefix(data, 16, 0);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
+
+  ret = _gnutls_ecdh_common_print_server_kx (session, data, 
+                                             
_gnutls_session_ecc_curve_get(session));
+  if (ret < 0)
+    gnutls_assert ();
+
   return ret;
 }
 
@@ -164,6 +220,7 @@ proc_psk_client_kx (gnutls_session_t session, opaque * data,
   bigint_t p, g;
   gnutls_dh_params_t dh_params;
   const bigint_t *mpis;
+  gnutls_datum_t psk_key;
   gnutls_psk_server_credentials_t cred;
   psk_auth_info_t info;
   gnutls_datum_t username;
@@ -221,9 +278,74 @@ proc_psk_client_kx (gnutls_session_t session, opaque * 
data,
   /* Adjust the data */
   data += username.size + 2;
 
-  ret = _gnutls_proc_dh_common_client_kx (session, data, data_size, g, p);
+  ret = _gnutls_psk_pwd_find_entry(session, info->username, &psk_key);
+  if (ret < 0) 
+    return gnutls_assert_val(ret);
 
-  return ret;
+  return _gnutls_proc_dh_common_client_kx (session, data, data_size, 
+                                          g, p, &psk_key);
+
+}
+
+static int
+proc_ecdhe_psk_client_kx (gnutls_session_t session, opaque * data,
+                    size_t _data_size)
+{
+  int ret;
+  gnutls_psk_server_credentials_t cred;
+  gnutls_datum_t psk_key;
+  psk_auth_info_t info;
+  gnutls_datum_t username;
+  ssize_t data_size = _data_size;
+
+  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;
+    }
+
+  if ((ret =
+       _gnutls_auth_info_set (session, GNUTLS_CRD_PSK,
+                              sizeof (psk_auth_info_st), 1)) < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  DECR_LEN (data_size, 2);
+  username.size = _gnutls_read_uint16 (&data[0]);
+
+  DECR_LEN (data_size, username.size);
+
+  username.data = &data[2];
+
+  /* copy the username to the auth info structures
+   */
+  info = _gnutls_get_auth_info (session);
+
+  if (username.size > MAX_USERNAME_SIZE)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_ILLEGAL_SRP_USERNAME;
+    }
+
+  memcpy (info->username, username.data, username.size);
+  info->username[username.size] = 0;
+
+  /* Adjust the data */
+  data += username.size + 2;
+
+  /* should never fail. It will always return a key even if it is
+   * a random one */
+  ret = _gnutls_psk_pwd_find_entry(session, info->username, &psk_key);
+  if (ret < 0) 
+    return gnutls_assert_val(ret);
+
+  return _gnutls_proc_ecdh_common_client_kx(session, data, data_size, 
+    _gnutls_session_ecc_curve_get(session), &psk_key);
 
 }
 
@@ -232,7 +354,8 @@ proc_psk_server_kx (gnutls_session_t session, opaque * data,
                     size_t _data_size)
 {
 
-  int ret;
+  int ret, psk_size;
+  ssize_t data_size = _data_size;
 
   /* set auth_info */
   if ((ret =
@@ -243,7 +366,15 @@ proc_psk_server_kx (gnutls_session_t session, opaque * 
data,
       return ret;
     }
 
-  ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size, 1);
+  DECR_LEN (data_size, 2);
+  psk_size = _gnutls_read_uint16 (data);
+  DECR_LEN (data_size, psk_size);
+  data += 2 + psk_size;
+
+  if (!_gnutls_session_is_ecc (session))
+    ret = _gnutls_proc_dh_common_server_kx (session, data, data_size);
+  else
+    ret = _gnutls_proc_ecdh_common_server_kx (session, data, data_size);
   if (ret < 0)
     {
       gnutls_assert ();
diff --git a/lib/auth/ecdh_common.c b/lib/auth/ecdh_common.c
index f04526a..cebd4ff 100644
--- a/lib/auth/ecdh_common.c
+++ b/lib/auth/ecdh_common.c
@@ -43,7 +43,7 @@
 #include <auth/psk.h>
 #include <gnutls_pk.h>
 
-static int calc_ecdh_key( gnutls_session_t session)
+static int calc_ecdh_key( gnutls_session_t session, gnutls_datum_t * psk_key)
 {
 gnutls_pk_params_st pub;
 int ret;
@@ -61,21 +61,43 @@ int ret;
   
   _gnutls_mpi_set_ui(pub.params[7], 1);
   
-  ret = _gnutls_pk_derive(GNUTLS_PK_ECC, &session->key->key, 
&session->key->ecdh_params, &pub);
-  
-  _gnutls_mpi_release(&pub.params[7]);
+  if (psk_key == NULL)
+    ret = _gnutls_pk_derive(GNUTLS_PK_ECC, &session->key->key, 
&session->key->ecdh_params, &pub);
+  else
+    {
+      gnutls_datum_t tmp_dh_key;
+
+      ret = _gnutls_pk_derive(GNUTLS_PK_ECC, &tmp_dh_key, 
&session->key->ecdh_params, &pub);
+      if (ret < 0)
+        {
+          ret = gnutls_assert_val(ret);
+          goto cleanup;
+        }
+
+      ret = _gnutls_set_psk_session_key (session, psk_key, &tmp_dh_key);
+      _gnutls_free_datum (&tmp_dh_key);
+    }
   
   if (ret < 0)
-    return gnutls_assert_val(ret);
+    {
+      ret = gnutls_assert_val(ret);
+      goto cleanup;
+    }
     
-  return 0;
+  ret = 0;
+
+cleanup:
+  _gnutls_mpi_release(&pub.params[7]);
+  return ret;
+
 }
 
 
 int
 _gnutls_proc_ecdh_common_client_kx (gnutls_session_t session,
-                                  opaque * data, size_t _data_size,
-                                  gnutls_ecc_curve_t curve)
+                                    opaque * data, size_t _data_size,
+                                    gnutls_ecc_curve_t curve,
+                                    gnutls_datum_t *psk_key)
 {
   ssize_t data_size = _data_size;
   int ret, i = 0;
@@ -94,7 +116,7 @@ _gnutls_proc_ecdh_common_client_kx (gnutls_session_t session,
     return gnutls_assert_val(ret);
 
   /* generate pre-shared key */
-  ret = calc_ecdh_key(session);
+  ret = calc_ecdh_key(session, psk_key);
   if (ret < 0)
     return gnutls_assert_val(ret);
 
@@ -102,7 +124,16 @@ _gnutls_proc_ecdh_common_client_kx (gnutls_session_t 
session,
 }
 
 int
-_gnutls_gen_ecdh_common_client_kx (gnutls_session_t session, gnutls_buffer_st* 
data)
+_gnutls_gen_ecdh_common_client_kx (gnutls_session_t session, 
+                                   gnutls_buffer_st* data)
+{
+  return _gnutls_gen_ecdh_common_client_kx_int(session, data, NULL);
+}
+
+int
+_gnutls_gen_ecdh_common_client_kx_int (gnutls_session_t session, 
+                                   gnutls_buffer_st* data, 
+                                   gnutls_datum_t * psk_key)
 {
   int ret;
   gnutls_datum_t out;
@@ -124,9 +155,9 @@ _gnutls_gen_ecdh_common_client_kx (gnutls_session_t 
session, gnutls_buffer_st* d
   
   if (ret < 0)
     return gnutls_assert_val(ret);
-    
+
   /* generate pre-shared key */
-  ret = calc_ecdh_key(session);
+  ret = calc_ecdh_key(session, psk_key);
   if (ret < 0)
     return gnutls_assert_val(ret);
 
diff --git a/lib/auth/ecdh_common.h b/lib/auth/ecdh_common.h
index 9b7a92b..a945fed 100644
--- a/lib/auth/ecdh_common.h
+++ b/lib/auth/ecdh_common.h
@@ -27,10 +27,21 @@
 
 #include <gnutls_auth.h>
 
-int _gnutls_gen_ecdh_common_client_kx (gnutls_session_t, gnutls_buffer_st*);
-int _gnutls_proc_ecdh_common_client_kx (gnutls_session_t session,
-                                      opaque * data, size_t _data_size,
-                                      gnutls_ecc_curve_t curve);
+int
+_gnutls_gen_ecdh_common_client_kx (gnutls_session_t session, 
+                                   gnutls_buffer_st* data);
+
+int
+_gnutls_gen_ecdh_common_client_kx_int (gnutls_session_t session, 
+                                   gnutls_buffer_st* data, 
+                                   gnutls_datum_t * psk_key);
+
+int
+_gnutls_proc_ecdh_common_client_kx (gnutls_session_t session,
+                                    opaque * data, size_t _data_size,
+                                    gnutls_ecc_curve_t curve,
+                                    gnutls_datum_t *psk_key);
+
 int _gnutls_ecdh_common_print_server_kx (gnutls_session_t, gnutls_buffer_st* 
data,
                                          gnutls_ecc_curve_t curve);
 int _gnutls_proc_ecdh_common_server_kx (gnutls_session_t session, opaque * 
data,
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index 3f15f08..a8be185 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -1194,7 +1194,8 @@ _gnutls_session_is_ecc (gnutls_session_t session)
   kx =
     _gnutls_cipher_suite_get_kx_algo (&session->
                                       
security_parameters.current_cipher_suite);
-  if (kx == GNUTLS_KX_ECDHE_RSA || kx == GNUTLS_KX_ECDHE_ECDSA || kx == 
GNUTLS_KX_ANON_ECDH)
+  if (kx == GNUTLS_KX_ECDHE_RSA || kx == GNUTLS_KX_ECDHE_ECDSA  ||
+    kx == GNUTLS_KX_ANON_ECDH || kx == GNUTLS_KX_ECDHE_PSK)
     return 1;
 
   return 0;
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index a44205b..9375f6a 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -138,6 +138,7 @@ extern "C"
    * @GNUTLS_KX_SRP_DSS: SRP-DSS key-exchange algorithm.
    * @GNUTLS_KX_PSK: PSK key-exchange algorithm.
    * @GNUTLS_KX_DHE_PSK: DHE-PSK key-exchange algorithm.
+   * @GNUTLS_KX_ECDHE_PSK: ECDHE-PSK key-exchange algorithm.
    *
    * Enumeration of different key exchange algorithms.
    */
@@ -157,6 +158,7 @@ extern "C"
     GNUTLS_KX_ANON_ECDH = 11,
     GNUTLS_KX_ECDHE_RSA = 12,
     GNUTLS_KX_ECDHE_ECDSA = 13,
+    GNUTLS_KX_ECDHE_PSK = 14,
   } gnutls_kx_algorithm_t;
 
   /**


hooks/post-receive
-- 
GNU gnutls



reply via email to

[Prev in Thread] Current Thread [Next in Thread]