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_1-78-g9125af3


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_2_99_1-78-g9125af3
Date: Sun, 22 May 2011 17:39:59 +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=9125af3d1d8c2a706c4486362e1b0334e4708f56

The branch, master has been updated
       via  9125af3d1d8c2a706c4486362e1b0334e4708f56 (commit)
       via  69dfdb821df5f26eea7c264a612d0e3d46da3ad5 (commit)
      from  c25fca6ffc04baabc9df3ef2bc09c859bb905f8b (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 9125af3d1d8c2a706c4486362e1b0334e4708f56
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun May 22 19:39:56 2011 +0200

    updated

commit 69dfdb821df5f26eea7c264a612d0e3d46da3ad5
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun May 22 19:36:28 2011 +0200

    Added support for verifying server certificates with ECDSA.

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

Summary of changes:
 .gitignore                      |    2 +
 lib/algorithms/ciphersuites.c   |   25 ++++++-
 lib/algorithms/kx.c             |    3 +
 lib/auth/cert.c                 |    9 ++-
 lib/auth/dhe.c                  |   17 ++++
 lib/gnutls_pk.c                 |   28 -------
 lib/gnutls_pk.h                 |    3 -
 lib/gnutls_pubkey.c             |    4 +-
 lib/gnutls_sig.c                |    3 +-
 lib/gnutls_state.c              |    2 +-
 lib/includes/gnutls/gnutls.h.in |    2 +
 lib/nettle/ecc_sign_hash.c      |   31 ++++----
 lib/nettle/pk.c                 |  154 ++++++++++++++++++++++++++++++++-------
 lib/nettle/rnd.c                |    9 --
 lib/nettle/rnd.h                |    2 -
 lib/x509/common.h               |    2 +-
 lib/x509/verify.c               |   37 ++++++----
 17 files changed, 223 insertions(+), 110 deletions(-)
 delete mode 100644 lib/nettle/rnd.h

diff --git a/.gitignore b/.gitignore
index d0fc83e..e00238b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -453,3 +453,5 @@ lib/auth/libgnutls_auth.la
 tests/cipher-test
 tests/suite/x509paths/X509tests
 tests/x509cert
+src/benchmark-cipher
+src/benchmark-tls
diff --git a/lib/algorithms/ciphersuites.c b/lib/algorithms/ciphersuites.c
index 6b7f4eb..a765cb9 100644
--- a/lib/algorithms/ciphersuites.c
+++ b/lib/algorithms/ciphersuites.c
@@ -202,8 +202,13 @@ typedef struct
 #define GNUTLS_ECDHE_RSA_AES_128_CBC_SHA { 0xC0, 0x13 }
 #define GNUTLS_ECDHE_RSA_AES_256_CBC_SHA { 0xC0, 0x14 }
 
+/* ECC-ECDSA */
+#define GNUTLS_ECDHE_ECDSA_NULL_SHA           { 0xC0, 0x06 }
+#define GNUTLS_ECDHE_ECDSA_3DES_EDE_CBC_SHA   { 0xC0, 0x08 }
+#define GNUTLS_ECDHE_ECDSA_AES_128_CBC_SHA    { 0xC0, 0x09 }
+#define GNUTLS_ECDHE_ECDSA_AES_256_CBC_SHA    { 0xC0, 0x0A }
 
-#define CIPHER_SUITES_COUNT 
sizeof(cs_algorithms)/sizeof(gnutls_cipher_suite_entry)-1
+#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
  * that each ciphersuite has it's own PRF algorithm. Now we
@@ -533,7 +538,23 @@ static const gnutls_cipher_suite_entry cs_algorithms[] = {
                              GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_ECDHE_RSA,
                              GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
                              GNUTLS_VERSION_MAX, 1),
-  {0, {{0, 0}}, 0, 0, 0, 0, 0, 0}
+  /* ECDHE-ECDSA */
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_ECDSA_NULL_SHA,
+                             GNUTLS_CIPHER_NULL, GNUTLS_KX_ECDHE_ECDSA,
+                             GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_ECDSA_3DES_EDE_CBC_SHA,
+                             GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_ECDHE_ECDSA,
+                             GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_ECDSA_AES_128_CBC_SHA,
+                             GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ECDHE_ECDSA,
+                             GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
+  GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ECDHE_ECDSA_AES_256_CBC_SHA,
+                             GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_ECDHE_ECDSA,
+                             GNUTLS_MAC_SHA1, GNUTLS_TLS1_0,
+                             GNUTLS_VERSION_MAX, 1),
 };
 
 #define GNUTLS_CIPHER_SUITE_LOOP(b) \
diff --git a/lib/algorithms/kx.c b/lib/algorithms/kx.c
index c9d2cfb..36a5647 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_ecdsa_auth_struct;
 extern mod_auth_st dhe_dss_auth_struct;
 extern mod_auth_st anon_auth_struct;
 extern mod_auth_st anon_ecdh_auth_struct;
@@ -60,6 +61,7 @@ static const gnutls_cred_map cred_mappings[] = {
   {GNUTLS_KX_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
   {GNUTLS_KX_RSA_EXPORT, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
   {GNUTLS_KX_ECDHE_RSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
+  {GNUTLS_KX_ECDHE_ECDSA, GNUTLS_CRD_CERTIFICATE, GNUTLS_CRD_CERTIFICATE},
   {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},
@@ -97,6 +99,7 @@ static const gnutls_kx_algo_entry _gnutls_kx_algorithms[] = {
    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},
   {"DHE-DSS", GNUTLS_KX_DHE_DSS, &dhe_dss_auth_struct, 1, 0},
 
 #ifdef ENABLE_SRP
diff --git a/lib/auth/cert.c b/lib/auth/cert.c
index deb9451..40edd79 100644
--- a/lib/auth/cert.c
+++ b/lib/auth/cert.c
@@ -1417,7 +1417,7 @@ _gnutls_proc_cert_server_certificate (gnutls_session_t 
session,
 
 #define MAX_SIGN_ALGOS 2
 typedef enum CertificateSigType
-{ RSA_SIGN = 1, DSA_SIGN
+{ RSA_SIGN = 1, DSA_SIGN=2, ECDSA_SIGN=64
 } CertificateSigType;
 
 /* Checks if we support the given signature algorithm 
@@ -1433,6 +1433,8 @@ _gnutls_check_supported_sign_algo (CertificateSigType 
algo)
       return GNUTLS_PK_RSA;
     case DSA_SIGN:
       return GNUTLS_PK_DSA;
+    case ECDSA_SIGN:
+      return GNUTLS_PK_ECC;
     }
 
   return -1;
@@ -1701,7 +1703,7 @@ _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t 
session,
   return 0;
 }
 
-#define CERTTYPE_SIZE 3
+#define CERTTYPE_SIZE 4
 int
 _gnutls_gen_cert_server_cert_req (gnutls_session_t session, gnutls_buffer_st * 
data)
 {
@@ -1737,7 +1739,8 @@ _gnutls_gen_cert_server_cert_req (gnutls_session_t 
session, gnutls_buffer_st * d
 
   tmp_data[0] = CERTTYPE_SIZE - 1;
   tmp_data[1] = RSA_SIGN;
-  tmp_data[2] = DSA_SIGN;          /* only these for now */
+  tmp_data[2] = DSA_SIGN;
+  tmp_data[3] = ECDSA_SIGN;          /* only these for now */
 
   ret = _gnutls_buffer_append_data( data, tmp_data, CERTTYPE_SIZE);
   if (ret < 0)
diff --git a/lib/auth/dhe.c b/lib/auth/dhe.c
index fe78b70..c43c9df 100644
--- a/lib/auth/dhe.c
+++ b/lib/auth/dhe.c
@@ -46,6 +46,23 @@ static int gen_dhe_server_kx (gnutls_session_t, 
gnutls_buffer_st*);
 static int proc_dhe_server_kx (gnutls_session_t, opaque *, size_t);
 static int proc_dhe_client_kx (gnutls_session_t, opaque *, size_t);
 
+const mod_auth_st ecdhe_ecdsa_auth_struct = {
+  "ECDHE_ECDSA",
+  _gnutls_gen_cert_server_certificate,
+  _gnutls_gen_cert_client_certificate,
+  gen_dhe_server_kx,
+  _gnutls_gen_ecdh_common_client_kx,   /* This is the only different */
+  _gnutls_gen_cert_client_cert_vrfy,
+  _gnutls_gen_cert_server_cert_req,
+
+  _gnutls_proc_cert_server_certificate,
+  _gnutls_proc_cert_client_certificate,
+  proc_dhe_server_kx,
+  proc_dhe_client_kx,
+  _gnutls_proc_cert_client_cert_vrfy,
+  _gnutls_proc_cert_cert_req
+};
+
 const mod_auth_st ecdhe_rsa_auth_struct = {
   "ECDHE_RSA",
   _gnutls_gen_cert_server_certificate,
diff --git a/lib/gnutls_pk.c b/lib/gnutls_pk.c
index 358cef4..e7cd6f9 100644
--- a/lib/gnutls_pk.c
+++ b/lib/gnutls_pk.c
@@ -474,34 +474,6 @@ _gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, 
bigint_t * r,
   return 0;
 }
 
-/* params is p, q, g, y in that order
- */
-int
-_gnutls_dsa_verify (const gnutls_datum_t * vdata,
-                    const gnutls_datum_t * sig_value,
-                    gnutls_pk_params_st* params)
-{
-
-  int ret;
-
-  if (vdata->size < 20)
-    { /* SHA1 or better only */
-      gnutls_assert ();
-      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
-    }
-
-  /* decrypt signature */
-  ret = _gnutls_pk_verify (GNUTLS_PK_DSA, vdata, sig_value, params);
-
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      return ret;
-    }
-
-  return 0;                     /* ok */
-}
-
 /* some generic pk functions */
 
 int _gnutls_pk_params_copy (gnutls_pk_params_st * dst, const 
gnutls_pk_params_st * src)
diff --git a/lib/gnutls_pk.h b/lib/gnutls_pk.h
index 1cdcf86..8b6359e 100644
--- a/lib/gnutls_pk.h
+++ b/lib/gnutls_pk.h
@@ -62,9 +62,6 @@ int _gnutls_rsa_verify (const gnutls_datum_t * vdata,
                         const gnutls_datum_t * ciphertext, 
                         gnutls_pk_params_st*,
                         int btype);
-int _gnutls_dsa_verify (const gnutls_datum_t * vdata,
-                        const gnutls_datum_t * sig_value,
-                        gnutls_pk_params_st* params);
 
 int
 _gnutls_encode_ber_rs (gnutls_datum_t * sig_value, bigint_t r, bigint_t s);
diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c
index e3e8fad..7769b78 100644
--- a/lib/gnutls_pubkey.c
+++ b/lib/gnutls_pubkey.c
@@ -1197,9 +1197,9 @@ gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key,
 int _gnutls_pubkey_compatible_with_sig(gnutls_pubkey_t pubkey, 
gnutls_protocol_t ver, 
   gnutls_sign_algorithm_t sign)
 {
-  if (pubkey->pk_algorithm == GNUTLS_PK_DSA)
+  if (pubkey->pk_algorithm == GNUTLS_PK_DSA || pubkey->pk_algorithm == 
GNUTLS_PK_ECC)
     { /* override */
-      int hash_algo = _gnutls_dsa_q_to_hash (pubkey->params.params[1]);
+      int hash_algo = _gnutls_dsa_q_to_hash (pubkey->pk_algorithm, 
&pubkey->params);
 
       /* DSA keys over 1024 bits cannot be used with TLS 1.x, x<2 */
       if (!_gnutls_version_has_selectable_sighash (ver))
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index 1f2ac23..6e7cb10 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -289,6 +289,7 @@ verify_tls_hash (gnutls_protocol_t ver, gnutls_pcert_st* 
cert,
 
       break;
     case GNUTLS_PK_DSA:
+    case GNUTLS_PK_ECC:
 
       vdata.data = &hash_concat->data[sha1pos];
       vdata.size = hash_concat->size - sha1pos;
@@ -756,7 +757,7 @@ pk_hash_data (gnutls_pk_algorithm_t pk, 
gnutls_digest_algorithm_t hash,
     case GNUTLS_PK_RSA:
       break;
     case GNUTLS_PK_DSA:
-      if (params && hash != _gnutls_dsa_q_to_hash (params->params[1]))
+      if (params && hash != _gnutls_dsa_q_to_hash (pk, params))
         {
           gnutls_assert ();
           return GNUTLS_E_INVALID_REQUEST;
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index 0a4ee1d..3f15f08 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -1194,7 +1194,7 @@ _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_ANON_ECDH)
+  if (kx == GNUTLS_KX_ECDHE_RSA || kx == GNUTLS_KX_ECDHE_ECDSA || kx == 
GNUTLS_KX_ANON_ECDH)
     return 1;
 
   return 0;
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 58e53cd..2659918 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -129,6 +129,7 @@ extern "C"
    * @GNUTLS_KX_DHE_DSS: DHE-DSS key-exchange algorithm.
    * @GNUTLS_KX_DHE_RSA: DHE-RSA key-exchange algorithm.
    * @GNUTLS_KX_ECDHE_RSA: ECDHE-RSA key-exchange algorithm.
+   * @GNUTLS_KX_ECDHE_ECDSA: ECDHE-ECDSA key-exchange algorithm.
    * @GNUTLS_KX_ANON_DH: Anon-DH key-exchange algorithm.
    * @GNUTLS_KX_ANON_ECDH: Anon-ECDH key-exchange algorithm.
    * @GNUTLS_KX_SRP: SRP key-exchange algorithm.
@@ -155,6 +156,7 @@ extern "C"
     GNUTLS_KX_DHE_PSK = 10,
     GNUTLS_KX_ANON_ECDH = 11,
     GNUTLS_KX_ECDHE_RSA = 12,
+    GNUTLS_KX_ECDHE_ECDSA = 13,
   } gnutls_kx_algorithm_t;
 
   /**
diff --git a/lib/nettle/ecc_sign_hash.c b/lib/nettle/ecc_sign_hash.c
index 158949f..4111610 100644
--- a/lib/nettle/ecc_sign_hash.c
+++ b/lib/nettle/ecc_sign_hash.c
@@ -26,7 +26,7 @@
   Sign a message digest
   @param in        The message digest to sign
   @param inlen     The length of the digest
-  @param signature The destination for the signature
+  @param sign      The destination for the signature
   @param prng      An active PRNG state
   @param wprng     The index of the PRNG you wish to use
   @param key       A private ECC key
@@ -34,15 +34,15 @@
 */
 int
 ecc_sign_hash (const unsigned char *in, unsigned long inlen,
-               struct dsa_signature *signature,
+               struct dsa_signature *sig,
                void *random_ctx, nettle_random_func random, ecc_key * key)
 {
   ecc_key pubkey;
-  mpz_t r, s, e;
+  mpz_t e;
   int err;
 
   assert (in != NULL);
-  assert (signature != NULL);
+  assert (sig != NULL);
   assert (key != NULL);
 
   /* is this a private key? */
@@ -53,7 +53,7 @@ ecc_sign_hash (const unsigned char *in, unsigned long inlen,
 
   /* get the hash and load it as a bignum into 'e' */
   /* init the bignums */
-  if ((err = mp_init_multi (&r, &s, &e, NULL)) != 0)
+  if ((err = mp_init_multi (&e, NULL)) != 0)
     {
       return err;
     }
@@ -74,9 +74,9 @@ ecc_sign_hash (const unsigned char *in, unsigned long inlen,
         }
 
       /* find r = x1 mod n */
-      mpz_mod (r, pubkey.pubkey.x, pubkey.order);
+      mpz_mod (sig->r, pubkey.pubkey.x, pubkey.order);
 
-      if (mpz_cmp_ui (r, 0) == 0)
+      if (mpz_cmp_ui (sig->r, 0) == 0)
         {
           ecc_free (&pubkey);
         }
@@ -86,24 +86,21 @@ ecc_sign_hash (const unsigned char *in, unsigned long inlen,
           mpz_invert (pubkey.k, pubkey.k, pubkey.order);
 
           /* mulmod */
-          mpz_mul (s, key->k, r);
-          mpz_mod (s, s, pubkey.order);
-          mpz_add (s, e, s);
-          mpz_mod (s, s, pubkey.order);
+          mpz_mul (sig->s, key->k, sig->r);
+          mpz_mod (sig->s, sig->s, pubkey.order);
+          mpz_add (sig->s, e, sig->s);
+          mpz_mod (sig->s, sig->s, pubkey.order);
 
-          mpz_mul (s, s, pubkey.k);
-          mpz_mod (s, s, pubkey.order);
+          mpz_mul (sig->s, sig->s, pubkey.k);
+          mpz_mod (sig->s, sig->s, pubkey.order);
           ecc_free (&pubkey);
-          if (mpz_cmp_ui (s, 0) != 0)
+          if (mpz_cmp_ui (sig->s, 0) != 0)
             {
               break;
             }
         }
     }
 
-  memcpy (&signature->r, &r, sizeof (signature->r));
-  memcpy (&signature->s, &s, sizeof (signature->s));
-
 errnokey:
   mp_clear_multi (&e, NULL);
   return err;
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index c9acf64..cfa5285 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -41,7 +41,6 @@
 #include <nettle/rsa.h>
 #include <random.h>
 #include <gnutls/crypto.h>
-#include "rnd.h"
 #include "ecc.h"
 
 #define TOMPZ(x) (*((mpz_t*)(x)))
@@ -84,6 +83,37 @@ _rsa_params_to_privkey (const gnutls_pk_params_st * 
pk_params,
 
 }
 
+static void 
+_ecc_params_to_privkey(const gnutls_pk_params_st * pk_params,
+                       ecc_key * priv)
+{
+        priv->type = PK_PRIVATE;
+        memcpy(&priv->prime, pk_params->params[0], sizeof(mpz_t));
+        memcpy(&priv->order, pk_params->params[1], sizeof(mpz_t));
+        memcpy(&priv->A, pk_params->params[2], sizeof(mpz_t));
+        memcpy(&priv->Gx, pk_params->params[3], sizeof(mpz_t));
+        memcpy(&priv->Gy, pk_params->params[4], sizeof(mpz_t));
+        memcpy(&priv->pubkey.x, pk_params->params[5], sizeof(mpz_t));
+        memcpy(&priv->pubkey.y, pk_params->params[6], sizeof(mpz_t));
+        memcpy(&priv->k, pk_params->params[7], sizeof(mpz_t));
+        mpz_init_set_ui(priv->pubkey.z, 1);
+}
+
+static void 
+_ecc_params_to_pubkey(const gnutls_pk_params_st * pk_params,
+                       ecc_key * pub)
+{
+        pub->type = PK_PUBLIC;
+        memcpy(&pub->prime, pk_params->params[0], sizeof(mpz_t));
+        memcpy(&pub->order, pk_params->params[1], sizeof(mpz_t));
+        memcpy(&pub->A, pk_params->params[2], sizeof(mpz_t));
+        memcpy(&pub->Gx, pk_params->params[3], sizeof(mpz_t));
+        memcpy(&pub->Gy, pk_params->params[4], sizeof(mpz_t));
+        memcpy(&pub->pubkey.x, pk_params->params[5], sizeof(mpz_t));
+        memcpy(&pub->pubkey.y, pk_params->params[6], sizeof(mpz_t));
+        mpz_init_set_ui(pub->pubkey.z, 1);
+}
+
 static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t algo, gnutls_datum_t * 
out,
                                   const gnutls_pk_params_st * priv,
                                   const gnutls_pk_params_st * pub)
@@ -101,26 +131,8 @@ static int _wrap_nettle_pk_derive(gnutls_pk_algorithm_t 
algo, gnutls_datum_t * o
         if (is_supported_curve(curve) == 0)
           return gnutls_assert_val(GNUTLS_E_ECC_NO_SUPPORTED_CURVES);
 
-        ecc_pub.type = PK_PUBLIC;
-        memcpy(&ecc_pub.prime, pub->params[0], sizeof(mpz_t));
-        memcpy(&ecc_pub.order, pub->params[1], sizeof(mpz_t));
-        memcpy(&ecc_pub.A, pub->params[2], sizeof(mpz_t));
-        memcpy(&ecc_pub.Gx, pub->params[3], sizeof(mpz_t));
-        memcpy(&ecc_pub.Gy, pub->params[4], sizeof(mpz_t));
-        memcpy(&ecc_pub.pubkey.x, pub->params[5], sizeof(mpz_t));
-        memcpy(&ecc_pub.pubkey.y, pub->params[6], sizeof(mpz_t));
-        mpz_init_set_ui(ecc_pub.pubkey.z, 1);
-
-        ecc_priv.type = PK_PRIVATE;
-        memcpy(&ecc_priv.prime, priv->params[0], sizeof(mpz_t));
-        memcpy(&ecc_priv.order, priv->params[1], sizeof(mpz_t));
-        memcpy(&ecc_priv.A, priv->params[2], sizeof(mpz_t));
-        memcpy(&ecc_priv.Gx, priv->params[3], sizeof(mpz_t));
-        memcpy(&ecc_priv.Gy, priv->params[4], sizeof(mpz_t));
-        memcpy(&ecc_priv.pubkey.x, priv->params[5], sizeof(mpz_t));
-        memcpy(&ecc_priv.pubkey.y, priv->params[6], sizeof(mpz_t));
-        memcpy(&ecc_priv.k, priv->params[7], sizeof(mpz_t));
-        mpz_init_set_ui(ecc_pub.pubkey.z, 1);
+        _ecc_params_to_pubkey(pub, &ecc_pub);
+        _ecc_params_to_privkey(priv, &ecc_priv);
 
         sz = ECC_BUF_SIZE;
         out->data = gnutls_malloc(sz);
@@ -337,7 +349,47 @@ _wrap_nettle_pk_sign (gnutls_pk_algorithm_t algo,
 
   switch (algo)
     {
+    case GNUTLS_PK_ECC: /* we do ECDSA */
+      {
+        ecc_key priv;
+        struct dsa_signature sig;
+        int hash_len;
+
+        _ecc_params_to_privkey(pk_params, &priv);
 
+        dsa_signature_init (&sig);
+
+        hash = _gnutls_dsa_q_to_hash (algo, pk_params);
+        hash_len = _gnutls_hash_get_algo_len (hash);
+        if (hash_len > vdata->size)
+          {
+            gnutls_assert ();
+            _gnutls_debug_log("Asked to sign %d bytes with hash %s\n", 
vdata->size, gnutls_mac_get_name(hash));
+            ret = GNUTLS_E_PK_SIGN_FAILED;
+            goto ecdsa_fail;
+          }
+
+        ret = ecc_sign_hash(vdata->data, vdata->size, 
+                            &sig, NULL, rnd_func, &priv);
+        if (ret != 0)
+          {
+            gnutls_assert ();
+            ret = GNUTLS_E_PK_SIGN_FAILED;
+            goto ecdsa_fail;
+          }
+
+        ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s);
+
+      ecdsa_fail:
+        dsa_signature_clear (&sig);
+
+        if (ret < 0)
+          {
+            gnutls_assert ();
+            goto cleanup;
+          }
+        break;
+      }
     case GNUTLS_PK_DSA:
       {
         struct dsa_public_key pub;
@@ -352,7 +404,7 @@ _wrap_nettle_pk_sign (gnutls_pk_algorithm_t algo,
 
         dsa_signature_init (&sig);
 
-        hash = _gnutls_dsa_q_to_hash (pub.q);
+        hash = _gnutls_dsa_q_to_hash (algo, pk_params);
         hash_len = _gnutls_hash_get_algo_len (hash);
         if (hash_len > vdata->size)
           {
@@ -481,6 +533,50 @@ _wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo,
 
   switch (algo)
     {
+    case GNUTLS_PK_ECC: /* ECDSA */
+      {
+        ecc_key pub;
+        struct dsa_signature sig;
+        int stat;
+
+        ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]);
+        if (ret < 0)
+          {
+            gnutls_assert ();
+            goto cleanup;
+          }
+
+        _ecc_params_to_pubkey(pk_params, &pub);
+        memcpy (&sig.r, tmp[0], sizeof (sig.r));
+        memcpy (&sig.s, tmp[1], sizeof (sig.s));
+
+        hash = _gnutls_dsa_q_to_hash (algo, pk_params);
+        if (vdata->size != _gnutls_hash_get_algo_len (hash))
+          {
+            gnutls_assert ();
+            
+            if (vdata->size != 20)
+              {
+                ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
+                goto ecdsa_fail;
+              }
+            else hash = GNUTLS_DIG_SHA1;
+          }
+
+        ret = ecc_verify_hash(&sig, vdata->data, vdata->size, &stat, &pub);
+        if (ret != 0 || stat != 1)
+          {
+            gnutls_assert();
+            ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
+          }
+        else
+          ret = 0;
+
+      ecdsa_fail:
+        _gnutls_mpi_release (&tmp[0]);
+        _gnutls_mpi_release (&tmp[1]);
+        break;
+      }
     case GNUTLS_PK_DSA:
       {
         struct dsa_public_key pub;
@@ -497,13 +593,17 @@ _wrap_nettle_pk_verify (gnutls_pk_algorithm_t algo,
         memcpy (&sig.r, tmp[0], sizeof (sig.r));
         memcpy (&sig.s, tmp[1], sizeof (sig.s));
 
-        hash = _gnutls_dsa_q_to_hash (pub.q);
-
+        hash = _gnutls_dsa_q_to_hash (algo, pk_params);
         if (vdata->size != _gnutls_hash_get_algo_len (hash))
           {
             gnutls_assert ();
-            ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
-            goto dsa_fail;
+            
+            if (vdata->size != 20)
+              {
+                ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
+                goto dsa_fail;
+              }
+            else hash = GNUTLS_DIG_SHA1;
           }
 
         ret = _dsa_verify (&pub, vdata->size, vdata->data, &sig);
@@ -698,7 +798,7 @@ rsa_fail:
         tls_ecc_set.Gy = st->Gy;
         tls_ecc_set.A = st->A;
 
-        ret = ecc_make_key(NULL, _int_random_func, &key, &tls_ecc_set);
+        ret = ecc_make_key(NULL, rnd_func, &key, &tls_ecc_set);
         if (ret != 0)
           return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
 
diff --git a/lib/nettle/rnd.c b/lib/nettle/rnd.c
index b503e10..d9f3488 100644
--- a/lib/nettle/rnd.c
+++ b/lib/nettle/rnd.c
@@ -33,7 +33,6 @@
 #include <gnutls_errors.h>
 #include <gnutls_num.h>
 #include <nettle/yarrow.h>
-#include "rnd.h"
 
 #define SOURCES 2
 
@@ -467,14 +466,6 @@ wrap_nettle_rnd (void *_ctx, int level, void *data, size_t 
datasize)
   return 0;
 }
 
-/* internal function to provide to nettle functions that
- * require a nettle_random_func().
- */
-void _int_random_func(void *ctx, unsigned length, uint8_t *dst)
-{
-  wrap_nettle_rnd(ctx, 0, dst, length);
-}
-
 int crypto_rnd_prio = INT_MAX;
 
 gnutls_crypto_rnd_st _gnutls_rnd_ops = {
diff --git a/lib/nettle/rnd.h b/lib/nettle/rnd.h
deleted file mode 100644
index 5deefd3..0000000
--- a/lib/nettle/rnd.h
+++ /dev/null
@@ -1,2 +0,0 @@
-void _int_random_func(void *ctx,
-                                unsigned length, uint8_t *dst);
diff --git a/lib/x509/common.h b/lib/x509/common.h
index 86e6b8d..b025162 100644
--- a/lib/x509/common.h
+++ b/lib/x509/common.h
@@ -140,7 +140,7 @@ 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);
+gnutls_digest_algorithm_t _gnutls_dsa_q_to_hash (gnutls_pk_algorithm_t algo, 
const gnutls_pk_params_st* params);
 
 int _gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root,
                           gnutls_pk_params_st * params);
diff --git a/lib/x509/verify.c b/lib/x509/verify.c
index 747405f..d2653c5 100644
--- a/lib/x509/verify.c
+++ b/lib/x509/verify.c
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
- * Software Foundation, Inc.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
+ * Free Software Foundation, Inc.
  *
  * Author: Nikos Mavrogiannopoulos
  *
@@ -824,12 +824,13 @@ _pkcs1_rsa_verify_sig (const gnutls_datum_t * text,
   return 0;
 }
 
-/* Hashes input data and verifies a DSA signature.
+/* Hashes input data and verifies a signature.
  */
 static int
-dsa_verify_sig (const gnutls_datum_t * text,
+verify_sig (const gnutls_datum_t * text,
                 const gnutls_datum_t * hash,
                 const gnutls_datum_t * signature,
+                gnutls_pk_algorithm_t pk,
                 gnutls_pk_params_st* params)
 {
   int ret;
@@ -838,21 +839,24 @@ dsa_verify_sig (const gnutls_datum_t * text,
   digest_hd_st hd;
   gnutls_digest_algorithm_t algo;
 
-  algo = _gnutls_dsa_q_to_hash (params->params[1]);
+  algo = _gnutls_dsa_q_to_hash (pk, params);
   if (hash)
     {
       /* SHA1 or better allowed */
       if (!hash->data || hash->size != _gnutls_hash_get_algo_len(algo))
         {
           gnutls_assert();
-          _gnutls_debug_log("Hash size (%d) does not correspond to hash %s", 
(int)hash->size, gnutls_mac_get_name(algo));
-          return GNUTLS_E_INVALID_REQUEST;
+          _gnutls_debug_log("Hash size (%d) does not correspond to hash %s. 
Assuming SHA-1.\n", (int)hash->size, gnutls_mac_get_name(algo));
+          algo = GNUTLS_DIG_SHA1;
+          
+          if (hash->size != 20)
+            return gnutls_assert_val(GNUTLS_E_PK_SIG_VERIFY_FAILED);
         }
+
       digest = *hash;
     }
   else
     {
-
       ret = _gnutls_hash_init (&hd, algo);
       if (ret < 0)
         {
@@ -867,7 +871,7 @@ dsa_verify_sig (const gnutls_datum_t * text,
       digest.size = _gnutls_hash_get_algo_len(algo);
     }
 
-  ret = _gnutls_dsa_verify (&digest, signature, params);
+  ret = _gnutls_pk_verify (pk, &digest, signature, params);
 
   return ret;
 }
@@ -897,9 +901,9 @@ pubkey_verify_sig (const gnutls_datum_t * tbs,
       return 1;
       break;
 
+    case GNUTLS_PK_ECC:
     case GNUTLS_PK_DSA:
-      if (dsa_verify_sig
-          (tbs, hash, signature, issuer_params) != 0)
+      if (verify_sig(tbs, hash, signature, pk, issuer_params) != 0)
         {
           gnutls_assert ();
           return GNUTLS_E_PK_SIG_VERIFY_FAILED;
@@ -915,9 +919,14 @@ pubkey_verify_sig (const gnutls_datum_t * tbs,
 }
 
 gnutls_digest_algorithm_t
-_gnutls_dsa_q_to_hash (bigint_t q)
+_gnutls_dsa_q_to_hash (gnutls_pk_algorithm_t algo, const gnutls_pk_params_st* 
params)
 {
-  int bits = _gnutls_mpi_get_nbits (q);
+  int bits = 0;
+  
+  if (algo == GNUTLS_PK_DSA)
+    bits = _gnutls_mpi_get_nbits (params->params[1]);
+  else if (algo == GNUTLS_PK_ECC)
+    bits = gnutls_ecc_curve_get_size(params->flags)*8;
 
   if (bits <= 160)
     {
@@ -953,7 +962,7 @@ _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * 
hash,
     case GNUTLS_PK_DSA:
 
       if (hash)
-        *hash = _gnutls_dsa_q_to_hash (issuer_params->params[1]);
+        *hash = _gnutls_dsa_q_to_hash (GNUTLS_PK_DSA, issuer_params);
 
       ret = 0;
       break;


hooks/post-receive
-- 
GNU gnutls



reply via email to

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