]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Use correct hashing algorithms for DSA with q over 160 bits.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Tue, 25 May 2010 12:22:35 +0000 (14:22 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Tue, 25 May 2010 12:37:28 +0000 (14:37 +0200)
lib/x509/common.h
lib/x509/privkey.c
lib/x509/sign.c
lib/x509/verify.c

index 46b9fcd9cadc95026152812fd71d1ab632b67417..a2a94fea548eff10fff1cd0cceeb03fc9340e8c8 100644 (file)
@@ -128,4 +128,6 @@ int _gnutls_x509_get_signed_data (ASN1_TYPE src, const char *src_name,
 int _gnutls_x509_get_signature (ASN1_TYPE src, const char *src_name,
                                gnutls_datum_t * signature);
 
+gnutls_digest_algorithm_t _gnutls_dsa_q_to_hash(bigint_t q);
+
 #endif
index ce50da2a9e1283b81c0c6c75bea89c41d7228c0c..f49380478b34eb06c0d86c8baf909613c17c6fd6 100644 (file)
@@ -1468,7 +1468,7 @@ cleanup:
 /**
  * gnutls_x509_privkey_sign_data:
  * @key: Holds the key
- * @digest: should be MD5 or SHA1
+ * @digest: should be MD5 or SHAx. May be ignored.
  * @flags: should be 0 for now
  * @data: holds the data to be signed
  * @signature: will contain the signature
index 1c5739fa267768a4fa7dfa0ce884c2bf49409e87..e74c48f00e160bd7c734a78f72523cfb810f8664 100644 (file)
@@ -180,8 +180,9 @@ dsa_sign (const gnutls_datum_t * text,
   opaque _digest[MAX_HASH_SIZE];
   digest_hd_st hd;
   gnutls_datum_t digest;
+  gnutls_digest_algorithm_t hash = _gnutls_dsa_q_to_hash(params[1]);
 
-  ret = _gnutls_hash_init (&hd, GNUTLS_MAC_SHA1);
+  ret = _gnutls_hash_init (&hd, hash);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -192,7 +193,7 @@ dsa_sign (const gnutls_datum_t * text,
   _gnutls_hash_deinit (&hd, _digest);
 
   digest.data = _digest;
-  digest.size = 20;
+  digest.size = _gnutls_hash_get_algo_len(hash);
 
   if ((ret =
        _gnutls_sign (GNUTLS_PK_DSA, params, params_len, &digest,
index 33aef9461e569e42d5a4991a84fdc010f2b48c11..8ef697b16dafe2b4bba1a6cf4f3a38ea6f569a6f 100644 (file)
@@ -839,6 +839,19 @@ verify_sig (const gnutls_datum_t * tbs,
     }
 }
 
+gnutls_digest_algorithm_t _gnutls_dsa_q_to_hash(bigint_t q)
+{
+  int bits = _gnutls_mpi_get_nbits(q);
+
+  if (bits <= 160) {
+    return GNUTLS_DIG_SHA1;
+  } else if (bits <= 224) {
+    return GNUTLS_DIG_SHA224;
+  } else {
+    return GNUTLS_DIG_SHA256;
+  }
+}
+
 int
 _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
                               const gnutls_datum_t * signature,
@@ -851,38 +864,37 @@ _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
   int digest_size;
   int ret, i;
 
+  issuer_params_size = MAX_PUBLIC_PARAMS_SIZE;
+  ret =
+    _gnutls_x509_crt_get_mpis (issuer, issuer_params,
+                                  &issuer_params_size);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
   switch (gnutls_x509_crt_get_pk_algorithm (issuer, NULL))
     {
     case GNUTLS_PK_DSA:
+      
       if (hash)
-       *hash = GNUTLS_MAC_SHA1;
-      return 0;
+       *hash = _gnutls_dsa_q_to_hash(issuer_params[1]);
+
+      ret = 0;
+      break;
 
     case GNUTLS_PK_RSA:
-      issuer_params_size = MAX_PUBLIC_PARAMS_SIZE;
-      ret =
-       _gnutls_x509_crt_get_mpis (issuer, issuer_params,
-                                  &issuer_params_size);
-      if (ret < 0)
-       {
-         gnutls_assert ();
-         return ret;
-       }
 
       ret =
        _gnutls_pkcs1_rsa_decrypt (&decrypted, signature,
                                   issuer_params, issuer_params_size, 1);
 
-      /* release allocated mpis */
-      for (i = 0; i < issuer_params_size; i++)
-       {
-         _gnutls_mpi_release (&issuer_params[i]);
-       }
 
       if (ret < 0)
        {
          gnutls_assert ();
-         return ret;
+         goto cleanup;
        }
 
       digest_size = sizeof (digest);
@@ -892,22 +904,34 @@ _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
        {
          gnutls_assert ();
          _gnutls_free_datum (&decrypted);
-         return ret;
+         goto cleanup;
        }
 
       _gnutls_free_datum (&decrypted);
       if (digest_size != _gnutls_hash_get_algo_len (*hash))
        {
          gnutls_assert ();
-         return GNUTLS_E_ASN1_GENERIC_ERROR;
+         ret = GNUTLS_E_ASN1_GENERIC_ERROR;
+         goto cleanup;
        }
 
-      return 0;
+      ret = 0;
+      break;
 
     default:
       gnutls_assert ();
-      return GNUTLS_E_INTERNAL_ERROR;
+      ret = GNUTLS_E_INTERNAL_ERROR;
+    }
+
+cleanup:
+    /* release allocated mpis */
+  for (i = 0; i < issuer_params_size; i++)
+    {
+      _gnutls_mpi_release (&issuer_params[i]);
     }
+
+  return ret;
+
 }
 
 /* verifies if the certificate is properly signed.