]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Several updates in signature algorithms parsing and sending to avoid sending invalid...
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Tue, 8 Feb 2011 17:53:54 +0000 (18:53 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Tue, 8 Feb 2011 17:53:54 +0000 (18:53 +0100)
lib/auth_cert.c
lib/auth_dhe.c
lib/ext_signature.c
lib/gnutls_algorithms.c
lib/gnutls_algorithms.h

index 760db40566dd4b848a0411fc65327dba423e99ea..033d3d70850674a05e560353cc150696eaa3cfd8 100644 (file)
@@ -1532,7 +1532,7 @@ _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session, opaque ** data)
   gnutls_cert *apr_cert_list;
   gnutls_privkey_t apr_pkey;
   int apr_cert_list_length, size;
-  gnutls_datum_t signature;
+  gnutls_datum_t signature = { NULL, 0 };
   int total_data;
   opaque *p;
   gnutls_sign_algorithm_t sign_algo;
@@ -1584,11 +1584,17 @@ _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session, opaque ** data)
   p = *data;
   if (_gnutls_version_has_selectable_sighash (ver))
     {
-      sign_algorithm_st aid;
+      const sign_algorithm_st *aid;
       /* error checking is not needed here since we have used those algorithms */
       aid = _gnutls_sign_to_tls_aid (sign_algo);
-      p[0] = aid.hash_algorithm;
-      p[1] = aid.sign_algorithm;
+      if (aid == NULL)
+        {
+          ret = GNUTLS_E_UNKNOWN_ALGORITHM;
+          goto cleanup;
+        }
+
+      p[0] = aid->hash_algorithm;
+      p[1] = aid->sign_algorithm;
       p += 2;
     }
 
@@ -1601,6 +1607,11 @@ _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session, opaque ** data)
   _gnutls_free_datum (&signature);
 
   return total_data;
+
+cleanup:
+  _gnutls_free_datum (&signature);
+  gnutls_free(*data);
+  return ret;
 }
 
 int
index 82a8df6569f3a2d4fb2a4338d26c1c9c874f6efb..87de68489c6d32916cac154078034283f9825301 100644 (file)
@@ -89,7 +89,7 @@ gen_dhe_server_kx (gnutls_session_t session, opaque ** data)
   gnutls_cert *apr_cert_list;
   gnutls_privkey_t apr_pkey;
   int apr_cert_list_length;
-  gnutls_datum_t signature, ddata;
+  gnutls_datum_t signature = { NULL, 0 }, ddata;
   gnutls_certificate_credentials_t cred;
   gnutls_dh_params_t dh_params;
   gnutls_sign_algorithm_t sign_algo;
@@ -154,38 +154,44 @@ gen_dhe_server_kx (gnutls_session_t session, opaque ** data)
                                         &sign_algo)) < 0)
         {
           gnutls_assert ();
-          gnutls_free (*data);
-          return ret;
+          goto cleanup;
         }
     }
   else
     {
       gnutls_assert ();
-      return data_size;         /* do not put a signature - ILLEGAL! */
+      ret = data_size;         /* do not put a signature - ILLEGAL! */
+      goto cleanup;
     }
 
   *data = gnutls_realloc_fast (*data, data_size + signature.size + 4);
   if (*data == NULL)
     {
-      _gnutls_free_datum (&signature);
       gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
+      ret = GNUTLS_E_MEMORY_ERROR;
+      goto cleanup;
     }
 
   if (_gnutls_version_has_selectable_sighash (ver))
     {
-      sign_algorithm_st aid;
+      const sign_algorithm_st *aid;
 
       if (sign_algo == GNUTLS_SIGN_UNKNOWN)
         {
-          _gnutls_free_datum (&signature);
-          gnutls_assert ();
-          return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
+          ret = GNUTLS_E_UNKNOWN_ALGORITHM;
+          goto cleanup;
         }
 
       aid = _gnutls_sign_to_tls_aid (sign_algo);
-      (*data)[data_size++] = aid.hash_algorithm;
-      (*data)[data_size++] = aid.sign_algorithm;
+      if (aid == NULL)
+        {
+          gnutls_assert();
+          ret = GNUTLS_E_UNKNOWN_ALGORITHM;
+          goto cleanup;
+        }
+      
+      (*data)[data_size++] = aid->hash_algorithm;
+      (*data)[data_size++] = aid->sign_algorithm;
     }
 
   _gnutls_write_datum16 (&(*data)[data_size], signature);
@@ -194,6 +200,12 @@ gen_dhe_server_kx (gnutls_session_t session, opaque ** data)
   _gnutls_free_datum (&signature);
 
   return data_size;
+
+cleanup:
+  _gnutls_free_datum (&signature);
+  gnutls_free(*data);
+  return ret;
+
 }
 
 static int
index 6eebd39d6a61e543fde413fdf5a2a068e495f83a..af6328b758b223710ff57412d38c6ef0b96c6a44 100644 (file)
@@ -72,31 +72,41 @@ int
 _gnutls_sign_algorithm_write_params (gnutls_session_t session, opaque * data,
                                      size_t max_data_size)
 {
-  opaque *p = data;
+  opaque *p = data, *len_p;
   int len, i, j;
-  sign_algorithm_st aid;
+  const sign_algorithm_st *aid;
 
-  len = session->internals.priorities.sign_algo.algorithms * 2;
-  if (max_data_size < len + 2)
+  if (max_data_size < (session->internals.priorities.sign_algo.algorithms*2) + 2)
     {
       gnutls_assert ();
       return GNUTLS_E_SHORT_MEMORY_BUFFER;
     }
 
-  _gnutls_write_uint16 (len, p);
+  len = 0;
+  len_p = p;
+
   p += 2;
 
-  for (i = j = 0; i < len; i += 2, j++)
+  for (i = j = 0; i < session->internals.priorities.sign_algo.algorithms; i += 2, j++)
     {
       aid =
         _gnutls_sign_to_tls_aid (session->internals.priorities.
                                  sign_algo.priority[j]);
-      *p = aid.hash_algorithm;
+
+      if (aid == NULL)
+        continue;
+        
+       _gnutls_debug_log ("EXT[SIGA]: sent signature algo (%d.%d) %s\n", aid->hash_algorithm, 
+         aid->sign_algorithm, gnutls_sign_get_name(session->internals.priorities.sign_algo.priority[j]));
+      *p = aid->hash_algorithm;
       p++;
-      *p = aid.sign_algorithm;
+      *p = aid->sign_algorithm;
       p++;
-
+      len+=2;
     }
+
+  _gnutls_write_uint16 (len, len_p);
+
   return len + 2;
 }
 
@@ -127,6 +137,10 @@ _gnutls_sign_algorithm_parse_data (gnutls_session_t session,
       aid.sign_algorithm = data[i + 1];
 
       sig = _gnutls_tls_aid_to_sign (&aid);
+
+       _gnutls_debug_log ("EXT[SIGA]: rcvd signature algo (%d.%d) %s\n", aid.hash_algorithm, 
+         aid.sign_algorithm, gnutls_sign_get_name(sig));
+
       if (sig != GNUTLS_SIGN_UNKNOWN)
         {
           priv->sign_algorithms[priv->sign_algorithms_size++] = sig;
index 027bf5d99cf808eb8f6d7350b0df3474a3c866d8..cf9a314390c0409b8e2a89e3c4872cceb347796d 100644 (file)
@@ -1941,11 +1941,12 @@ struct gnutls_sign_entry
   gnutls_mac_algorithm_t mac;
   /* See RFC 5246 HashAlgorithm and SignatureAlgorithm
      for values to use in aid struct. */
-  sign_algorithm_st aid;
+  const sign_algorithm_st aid;
 };
 typedef struct gnutls_sign_entry gnutls_sign_entry;
 
 #define TLS_SIGN_AID_UNKNOWN {255, 255}
+static const sign_algorithm_st unknown_tls_aid = TLS_SIGN_AID_UNKNOWN;
 
 static const gnutls_sign_entry sign_algorithms[] = {
   {"RSA-SHA1", SIG_RSA_SHA1_OID, GNUTLS_SIGN_RSA_SHA1, GNUTLS_PK_RSA,
@@ -2147,21 +2148,31 @@ _gnutls_tls_aid_to_sign (const sign_algorithm_st * aid)
 {
   gnutls_sign_algorithm_t ret = GNUTLS_SIGN_UNKNOWN;
 
+  if (memcmp(aid, &unknown_tls_aid, sizeof(aid))==0)
+    return ret;
+
   GNUTLS_SIGN_LOOP (if (p->aid.hash_algorithm == aid->hash_algorithm
                         && p->aid.sign_algorithm == aid->sign_algorithm)
                     {
-                    ret = p->id; break;}
+                      ret = p->id; break;
+                    }
   );
 
+
   return ret;
 }
 
-sign_algorithm_st
+/* Returns NULL if a valid AID is not found
+ */
+const sign_algorithm_st*
 _gnutls_sign_to_tls_aid (gnutls_sign_algorithm_t sign)
 {
-  sign_algorithm_st ret = TLS_SIGN_AID_UNKNOWN;
+  const sign_algorithm_st * ret = NULL;
+
+  GNUTLS_SIGN_ALG_LOOP (ret = &p->aid);
 
-  GNUTLS_SIGN_ALG_LOOP (ret = p->aid);
+  if (ret != NULL && memcmp(ret, &unknown_tls_aid, sizeof(*ret))==0)
+    return NULL;
 
   return ret;
 }
index 50504f360a29440f5adbf19ea133cf5b0652dfdb..4e6b5402bb95f8f97d5ccca970434fb68ce2df61 100644 (file)
@@ -114,7 +114,7 @@ const char *_gnutls_x509_sign_to_oid (gnutls_pk_algorithm_t,
                                       gnutls_mac_algorithm_t mac);
 gnutls_sign_algorithm_t _gnutls_tls_aid_to_sign (const sign_algorithm_st *
                                                  aid);
-sign_algorithm_st _gnutls_sign_to_tls_aid (gnutls_sign_algorithm_t sign);
+const sign_algorithm_st* _gnutls_sign_to_tls_aid (gnutls_sign_algorithm_t sign);
 gnutls_mac_algorithm_t
 _gnutls_sign_get_hash_algorithm (gnutls_sign_algorithm_t);
 gnutls_pk_algorithm_t _gnutls_sign_get_pk_algorithm (gnutls_sign_algorithm_t);