]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Callback function is being called in both PSK-DHE and PSK.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 9 Feb 2011 19:48:04 +0000 (20:48 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 9 Feb 2011 19:48:04 +0000 (20:48 +0100)
Using the callback function will not overwrite the credentials,
which were wrongly being overwritten using the retrieved username/key.
The credentials structure is now accessed for reading only, as it
should have been.

lib/auth_dh_common.c
lib/auth_dh_common.h
lib/auth_dhe_psk.c
lib/auth_psk.c
lib/auth_psk.h

index f0198b252454892665b3772782d295a2638424fb..5bf7e92551416fe1f37f090e857f646e5dc60c84 100644 (file)
@@ -105,7 +105,7 @@ _gnutls_proc_dh_common_client_kx (gnutls_session_t session,
           return ret;
         }
 
-      ret = _gnutls_set_psk_session_key (session, &tmp_dh_key);
+      ret = _gnutls_set_psk_session_key (session, NULL, &tmp_dh_key);
       _gnutls_free_datum (&tmp_dh_key);
 
     }
@@ -120,8 +120,13 @@ _gnutls_proc_dh_common_client_kx (gnutls_session_t session,
   return 0;
 }
 
+int _gnutls_gen_dh_common_client_kx (gnutls_session_t session, gnutls_buffer_st* data)
+{
+  return _gnutls_gen_dh_common_client_kx_int(session, data, NULL);
+}
+
 int
-_gnutls_gen_dh_common_client_kx (gnutls_session_t session, gnutls_buffer_st* data)
+_gnutls_gen_dh_common_client_kx_int (gnutls_session_t session, gnutls_buffer_st* data, gnutls_datum_t* pskkey)
 {
   bigint_t x = NULL, X = NULL;
   int ret;
@@ -170,6 +175,7 @@ _gnutls_gen_dh_common_client_kx (gnutls_session_t session, gnutls_buffer_st* dat
   else                          /* In DHE_PSK the key is set differently */
     {
       gnutls_datum_t tmp_dh_key;
+
       ret = _gnutls_mpi_dprint (session->key->KEY, &tmp_dh_key);
       if (ret < 0)
         {
@@ -177,9 +183,8 @@ _gnutls_gen_dh_common_client_kx (gnutls_session_t session, gnutls_buffer_st* dat
           goto error;
         }
 
-      ret = _gnutls_set_psk_session_key (session, &tmp_dh_key);
+      ret = _gnutls_set_psk_session_key (session, pskkey, &tmp_dh_key);
       _gnutls_free_datum (&tmp_dh_key);
-
     }
 
   _gnutls_mpi_release (&session->key->KEY);
index ccfe5c000e0a8c30f16a572c93bac9da54b0db67..9c528f10814c0d1b6882fb09b5b37a2d8ea40ef2 100644 (file)
@@ -38,6 +38,7 @@ typedef struct
 } dh_info_st;
 
 void _gnutls_free_dh_info (dh_info_st * dh);
+int _gnutls_gen_dh_common_client_kx_int (gnutls_session_t, gnutls_buffer_st*, gnutls_datum_t *pskkey);
 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,
index 78991827f0017db2c690b805ebcffc2c7fb753e7..6d698c45632dd995bb0a883fa695040ce4ae46c8 100644 (file)
@@ -65,38 +65,43 @@ const mod_auth_st dhe_psk_auth_struct = {
 static int
 gen_psk_client_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
-  int ret;
+  int ret, free;
   gnutls_psk_client_credentials_t cred;
+  gnutls_datum_t username, key;
 
   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;
-    }
+    return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
 
-  if (cred->username.data == NULL || cred->key.data == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
-    }
-
-  ret = _gnutls_buffer_append_data_prefix(data, 16, cred->username.data, cred->username.size);
+  ret = _gnutls_find_psk_key( session, cred, &username, &key, &free);
   if (ret < 0)
     return gnutls_assert_val(ret);
 
+  ret = _gnutls_buffer_append_data_prefix(data, 16, username.data, username.size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
 
   /* The PSK key is set in there */
-  ret = _gnutls_gen_dh_common_client_kx (session, data);
+  ret = _gnutls_gen_dh_common_client_kx_int (session, data, &key);
   if (ret < 0)
     {
       gnutls_assert ();
-      return ret;
+      goto cleanup;
     }
 
-  return data->length;
+  ret = data->length;
+
+cleanup:
+  if (free)
+    _gnutls_free_datum(&username);
+    _gnutls_free_datum(&key);
+
+  return ret;
 
 }
 
index c272bba3ff67bb7854fe16082f9984b2d53022e4..17d9403e9c9e408368c458ac9e38d48b6ffcc9f1 100644 (file)
@@ -65,30 +65,14 @@ const mod_auth_st psk_auth_struct = {
  */
 int
 _gnutls_set_psk_session_key (gnutls_session_t session,
-                             gnutls_datum_t * dh_secret)
+    gnutls_datum_t * ppsk /* key */,
+    gnutls_datum_t * dh_secret)
 {
   gnutls_datum_t pwd_psk = { NULL, 0 };
-  gnutls_datum_t *ppsk;
   size_t dh_secret_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
+  if (session->security_parameters.entity == GNUTLS_SERVER)
     {                           /* SERVER side */
       psk_auth_info_t info;
 
@@ -142,6 +126,41 @@ error:
   return ret;
 }
 
+/* returns the username and they key for the PSK session.
+ * Free is non zero if they have to be freed.
+ */
+int _gnutls_find_psk_key( gnutls_session_t session, gnutls_psk_client_credentials_t cred, 
+  gnutls_datum_t * username, gnutls_datum* key, int* free)
+{
+char* user_p;
+int ret;
+
+   *free = 0;
+
+  if (cred->username.data != NULL && cred->key.data != NULL)
+    {
+      username->data = cred->username.data;
+      username->size = cred->username.size;
+      key->data = cred->key.data;
+      key->size = cred->key.size;
+    }
+  else if (cred->get_function != NULL)
+    {
+      ret = cred->get_function (session, &user_p, key);
+      if (ret)
+        return gnutls_assert_val(ret);
+      
+      username->data = user_p;
+      username->size = strlen(user_p);
+      
+      *free = 1;
+    }
+  else
+    return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+  
+  return 0;
+}
+
 
 /* Generates the PSK client key exchange
  *
@@ -156,7 +175,9 @@ error:
 int
 _gnutls_gen_psk_client_kx (gnutls_session_t session, gnutls_buffer_st* data)
 {
-  int ret;
+  int ret, free;
+  gnutls_datum_t username;
+  gnutls_datum_t key;
   gnutls_psk_client_credentials_t cred;
 
   cred = (gnutls_psk_client_credentials_t)
@@ -168,50 +189,31 @@ _gnutls_gen_psk_client_kx (gnutls_session_t session, gnutls_buffer_st* data)
       return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
     }
 
-  if (cred->username.data == NULL && cred->key.data == NULL &&
-      cred->get_function != NULL)
-    {
-      char *username;
-      gnutls_datum_t key;
-
-      ret = cred->get_function (session, &username, &key);
-      if (ret)
-        {
-          gnutls_assert ();
-          return ret;
-        }
-
-      ret = _gnutls_set_datum (&cred->username, username, strlen (username));
-      gnutls_free (username);
-      if (ret < 0)
-        {
-          gnutls_assert ();
-          _gnutls_free_datum (&key);
-          return ret;
-        }
+  ret = _gnutls_find_psk_key( session, cred, &username, &key, &free);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
 
-      ret = _gnutls_set_datum (&cred->key, key.data, key.size);
-      _gnutls_free_datum (&key);
-      if (ret < 0)
-        {
-          gnutls_assert ();
-          return GNUTLS_E_MEMORY_ERROR;
-        }
-    }
-  else if (cred->username.data == NULL || cred->key.data == NULL)
+  ret = _gnutls_set_psk_session_key (session, &key, NULL);
+  if (ret < 0)
     {
-      gnutls_assert ();
-      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
+      gnutls_assert();
+      goto cleanup;
     }
-
-  ret = _gnutls_set_psk_session_key (session, NULL);
+  
+  ret = _gnutls_buffer_append_data_prefix(data, 16, username.data, username.size);
   if (ret < 0)
     {
-      gnutls_assert ();
-      return ret;
+      gnutls_assert();
     }
 
-  return _gnutls_buffer_append_data_prefix(data, 16, cred->username.data, cred->username.size);
+cleanup:
+  if (free) 
+    {
+      gnutls_free(username.data);
+      gnutls_free(key.data);
+    }
+  
+  return ret;
 }
 
 
@@ -265,7 +267,7 @@ _gnutls_proc_psk_client_kx (gnutls_session_t session, opaque * data,
   memcpy (info->username, username.data, username.size);
   info->username[username.size] = 0;
 
-  ret = _gnutls_set_psk_session_key (session, NULL);
+  ret = _gnutls_set_psk_session_key (session, NULL, NULL);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -328,10 +330,10 @@ _gnutls_proc_psk_server_kx (gnutls_session_t session, opaque * data,
   ssize_t data_size = _data_size;
   int ret;
   gnutls_datum_t hint;
-  gnutls_psk_server_credentials_t cred;
+  gnutls_psk_client_credentials_t cred;
   psk_auth_info_t info;
 
-  cred = (gnutls_psk_server_credentials_t)
+  cred = (gnutls_psk_client_credentials_t)
     _gnutls_get_cred (session->key, GNUTLS_CRD_PSK, NULL);
 
   if (cred == NULL)
@@ -368,7 +370,7 @@ _gnutls_proc_psk_server_kx (gnutls_session_t session, opaque * data,
   memcpy (info->hint, hint.data, hint.size);
   info->hint[hint.size] = 0;
 
-  ret = _gnutls_set_psk_session_key (session, NULL);
+  ret = _gnutls_set_psk_session_key (session, &cred->key, NULL);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -381,4 +383,4 @@ error:
   return ret;
 }
 
-#endif /* ENABLE_SRP */
+#endif /* ENABLE_PSK */
index c79da6b79f78c56b485f2e7aef957f12058c3357..40e88f1481eed5fe3c6461ebf966651971c806ca 100644 (file)
@@ -68,7 +68,11 @@ typedef struct psk_auth_info_st
 typedef struct psk_auth_info_st psk_auth_info_st;
 
 int
-_gnutls_set_psk_session_key (gnutls_session_t session, gnutls_datum_t * psk2);
+_gnutls_set_psk_session_key (gnutls_session_t session, gnutls_datum_t* key, gnutls_datum_t * psk2);
+
+int _gnutls_find_psk_key( gnutls_session_t session, gnutls_psk_client_credentials_t cred, 
+  gnutls_datum_t * username, gnutls_datum* key, int* free);
+
 #else
 #define _gnutls_set_psk_session_key(x,y) GNUTLS_E_INTERNAL_ERROR
 #endif /* ENABLE_PSK */