[PATCH] Switch to the Nettle 3 API

David Michael <[email protected]> Mon, 20 Jul 2015 12:00:29 -0400
Newsgroups gmane.network.lsh.bugs
Message-ID <[email protected]>
---
Hi,

I tried to update the Nettle DSA function calls so LSH can be built with
Nettle 3.  The main issue seemed to be that DSA's x and y variables were
removed from structs and use mpz_t types now.

The following patch against the master branch just switches to the new
API and requires Nettle 3 (as did e.g. GnuTLS) instead of trying to keep
compatiblity with both APIs.

Can something like this be applied to the LSH repo to support Nettle 3?

Thanks.

David


 configure.ac     |   4 +-
 spki/verify.c    |  26 +++++++-----
 src/crypto.c     |   2 +-
 src/dsa.c        | 120 ++++++++++++++++++++++++++++---------------------------
 src/lsh-keygen.c |  54 ++++++++++++++-----------
 5 files changed, 111 insertions(+), 95 deletions(-)

diff --git a/configure.ac b/configure.ac
index a42d4ad..b12c37e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -422,9 +422,9 @@ AC_CHECK_LIB(gmp, __gmpz_getlimbn,,
 
 LSH_RPATH_FIX
 
-AC_CHECK_LIB(hogweed, nettle_dsa_sha1_sign, [true],
+AC_CHECK_LIB(hogweed, nettle_dsa_params_init, [true],
     [AC_MSG_ERROR(
-    [Nettle library not found; needs version 2.2 or later. See http://www.lysator.liu.se/~nisse/nettle/.])], [-lnettle -lgmp])
+    [Nettle library not found; needs version 3.0 or later. See http://www.lysator.liu.se/~nisse/nettle/.])], [-lnettle -lgmp])
 
 LSH_RPATH_FIX
 
diff --git a/spki/verify.c b/spki/verify.c
index 6f16a9d..0984ca7 100644
--- a/spki/verify.c
+++ b/spki/verify.c
@@ -70,22 +70,25 @@ spki_verify_dsa_sha1(const uint8_t *digest,
 		     struct spki_iterator *key,
 		     struct spki_iterator *signature)
 {
-  struct dsa_public_key dsa;
+  struct dsa_params dsa;
   struct dsa_signature rs;
+  mpz_t pub;
   int res;
 
-  dsa_public_key_init(&dsa);
+  dsa_params_init(&dsa);
   dsa_signature_init(&rs);
+  mpz_init(pub);
 
-  res = (dsa_keypair_from_sexp_alist(&dsa, NULL,
+  res = (dsa_keypair_from_sexp_alist(&dsa, pub, NULL,
 				     DSA_SHA1_KEYSIZE_LIMIT,
 				     DSA_SHA1_Q_BITS, &key->sexp)
 	 && spki_parse_end(key)
 	 && dsa_signature_from_sexp(&rs, &signature->sexp, DSA_SHA1_Q_BITS)
-	 && dsa_sha1_verify_digest(&dsa, digest, &rs));
+	 && dsa_verify(&dsa, pub, SHA1_DIGEST_SIZE, digest, &rs));
 
+  mpz_clear(pub);
   dsa_signature_clear(&rs);
-  dsa_public_key_clear(&dsa);
+  dsa_params_clear(&dsa);
 
   return res;    
 }
@@ -95,23 +98,26 @@ spki_verify_dsa_sha256(const uint8_t *digest,
 		       struct spki_iterator *key,
 		       struct spki_iterator *signature)
 {
-  struct dsa_public_key dsa;
+  struct dsa_params dsa;
   struct dsa_signature rs;
+  mpz_t pub;
   int res;
 
-  dsa_public_key_init(&dsa);
+  dsa_params_init(&dsa);
   dsa_signature_init(&rs);
+  mpz_init(pub);
 
-  res = (dsa_keypair_from_sexp_alist(&dsa, NULL,
+  res = (dsa_keypair_from_sexp_alist(&dsa, pub, NULL,
 				     DSA_SHA256_KEYSIZE_LIMIT,
 				     DSA_SHA256_Q_BITS, &key->sexp)
 	 && spki_parse_end(key)
 	 && dsa_signature_from_sexp(&rs, &signature->sexp,
 				    DSA_SHA256_Q_BITS)
-	 && dsa_sha256_verify_digest(&dsa, digest, &rs));
+	 && dsa_verify(&dsa, pub, SHA256_DIGEST_SIZE, digest, &rs));
 
+  mpz_clear(pub);
   dsa_signature_clear(&rs);
-  dsa_public_key_clear(&dsa);
+  dsa_params_clear(&dsa);
 
   return res;    
 }
diff --git a/src/crypto.c b/src/crypto.c
index c9aef66..6a7c774 100644
--- a/src/crypto.c
+++ b/src/crypto.c
@@ -366,7 +366,7 @@ make_cast128_cbc_instance(struct crypto_algorithm *algorithm, int mode,
 			? do_cast128_encrypt
 			: do_cast128_decrypt);
 
-  cast128_set_key(&self->ctx.ctx, algorithm->key_size, key);
+  cast5_set_key(&self->ctx.ctx, algorithm->key_size, key);
   CBC_SET_IV(&self->ctx, iv);
 
   return(&self->super);
diff --git a/src/dsa.c b/src/dsa.c
index 230698d..21e0c6c 100644
--- a/src/dsa.c
+++ b/src/dsa.c
@@ -64,8 +64,8 @@
      (name dsa_verifier)
      (super verifier)
      (vars
-       (key indirect-special "struct dsa_public_key"
-            #f dsa_public_key_clear)))
+       (params indirect-special "struct dsa_params" #f dsa_params_clear)
+       (public bignum)))
 */
 
 /* GABA:
@@ -74,8 +74,7 @@
      (super signer)
      (vars
        (verifier object dsa_verifier)
-       (key indirect-special "struct dsa_private_key"
-            #f dsa_private_key_clear)))
+       (private bignum)))
 */
 
 static int
@@ -148,8 +147,8 @@ do_dsa_verify(struct verifier *c, int algorithm,
 
   sha1_init(&hash);
   sha1_update(&hash, length, msg);
-  
-  res = dsa_sha1_verify(&self->key, &hash, &sv);
+
+  res = dsa_verify(&self->params, self->public, SHA1_DIGEST_SIZE, &hash, &sv);
  fail:
 
   dsa_signature_clear(&sv);
@@ -164,8 +163,8 @@ do_dsa_public_key(struct verifier *s)
   CAST(dsa_verifier, self, s);
   return ssh_format("%a%n%n%n%n",
 		    ATOM_SSH_DSS,
-		    self->key.p, self->key.q,
-		    self->key.g, self->key.y);
+		    self->params.p, self->params.q,
+		    self->params.g, self->public);
 }
 
 /* FIXME: Should maybe switch to the name "dsa-sha1". Not sure what we
@@ -179,16 +178,17 @@ do_dsa_public_spki_key(struct verifier *s, int transport)
   return lsh_string_format_sexp(transport,
 				"(%0s(%0s(%0s%b)(%0s%b)(%0s%b)(%0s%b)))",
 				"public-key",  "dsa",
-				"p", self->key.p,
-				"q", self->key.q,
-				"g", self->key.g,
-				"y", self->key.y);
+				"p", self->params.p,
+				"q", self->params.q,
+				"g", self->params.g,
+				"y", self->public);
 }
 
 static void
 init_dsa_verifier(struct dsa_verifier *self)
 {
-  dsa_public_key_init(&self->key);
+  dsa_params_init(&self->params);
+  mpz_init(self->public);
 
   self->super.verify = do_dsa_verify;
   self->super.public_spki_key = do_dsa_public_spki_key;
@@ -204,18 +204,18 @@ parse_ssh_dss_public(struct simple_buffer *buffer)
   NEW(dsa_verifier, res);
   init_dsa_verifier(res);
 
-  if (parse_bignum(buffer, res->key.p, DSA_SHA1_MAX_OCTETS)
-      && (mpz_sgn(res->key.p) == 1)
-      && parse_bignum(buffer, res->key.q, DSA_SHA1_Q_OCTETS)
-      && (mpz_sgn(res->key.q) == 1)
-      && mpz_sizeinbase(res->key.q, 2) == DSA_SHA1_Q_BITS
-      && (mpz_cmp(res->key.q, res->key.p) < 0) /* q < p */ 
-      && parse_bignum(buffer, res->key.g, DSA_SHA1_MAX_OCTETS)
-      && (mpz_sgn(res->key.g) == 1)
-      && (mpz_cmp(res->key.g, res->key.p) < 0) /* g < p */ 
-      && parse_bignum(buffer, res->key.y, DSA_SHA1_MAX_OCTETS) 
-      && (mpz_sgn(res->key.y) == 1)
-      && (mpz_cmp(res->key.y, res->key.p) < 0) /* y < p */
+  if (parse_bignum(buffer, res->params.p, DSA_SHA1_MAX_OCTETS)
+      && (mpz_sgn(res->params.p) == 1)
+      && parse_bignum(buffer, res->params.q, DSA_SHA1_Q_OCTETS)
+      && (mpz_sgn(res->params.q) == 1)
+      && mpz_sizeinbase(res->params.q, 2) == DSA_SHA1_Q_BITS
+      && (mpz_cmp(res->params.q, res->params.p) < 0) /* q < p */
+      && parse_bignum(buffer, res->params.g, DSA_SHA1_MAX_OCTETS)
+      && (mpz_sgn(res->params.g) == 1)
+      && (mpz_cmp(res->params.g, res->params.p) < 0) /* g < p */
+      && parse_bignum(buffer, res->public, DSA_SHA1_MAX_OCTETS)
+      && (mpz_sgn(res->public) == 1)
+      && (mpz_cmp(res->public, res->params.p) < 0) /* y < p */
       && parse_eod(buffer))
     
     return &res->super;
@@ -257,8 +257,8 @@ do_dsa_sign(struct signer *c,
   sha1_init(&hash);
   sha1_update(&hash, msg_length, msg);
 
-  if (dsa_sha1_sign(&self->verifier->key, &self->key,
-		NULL, lsh_random, &hash, &sv))
+  if (dsa_sign(&self->verifier->params, self->private,
+	       NULL, lsh_random, SHA1_DIGEST_SIZE, &hash, &sv))
     /* Build signature */
     switch (algorithm)
       {
@@ -310,7 +310,7 @@ make_dsa_verifier(struct signature_algorithm *self UNUSED,
   NEW(dsa_verifier, res);
   init_dsa_verifier(res);
 
-  if (dsa_keypair_from_sexp_alist(&res->key, NULL,
+  if (dsa_keypair_from_sexp_alist(&res->params, res->public, NULL,
 				  DSA_SHA1_MAX_BITS, DSA_SHA1_Q_BITS,
 				  i))
     return &res->super;
@@ -327,10 +327,11 @@ make_dsa_signer(struct signature_algorithm *self UNUSED,
   NEW(dsa_signer, res);
 
   init_dsa_verifier(verifier);
-  
-  dsa_private_key_init(&res->key);
 
-  if (dsa_keypair_from_sexp_alist(&verifier->key, &res->key,
+  mpz_init(res->private);
+
+  if (dsa_keypair_from_sexp_alist(&verifier->params,
+				  verifier->public, res->private,
 				  DSA_SHA1_MAX_BITS, DSA_SHA1_Q_BITS,
 				  i))
     {
@@ -411,8 +412,9 @@ do_dsa_sha256_verify(struct verifier *c, int algorithm,
 
   sha256_init(&hash);
   sha256_update(&hash, length, msg);
-  
-  res = dsa_sha256_verify(&self->key, &hash, &sv);
+
+  res = dsa_verify(&self->params, self->public,
+		   SHA256_DIGEST_SIZE, &hash, &sv);
  fail:
 
   dsa_signature_clear(&sv);
@@ -427,8 +429,8 @@ do_dsa_sha256_public_key(struct verifier *s)
   CAST(dsa_verifier, self, s);
   return ssh_format("%a%n%n%n%n",
 		    ATOM_SSH_DSA,
-		    self->key.p, self->key.q,
-		    self->key.g, self->key.y);
+		    self->params.p, self->params.q,
+		    self->params.g, self->public);
 }
 
 static struct lsh_string *
@@ -439,16 +441,17 @@ do_dsa_sha256_public_spki_key(struct verifier *s, int transport)
   return lsh_string_format_sexp(transport,
 				"(%0s(%0s(%0s%b)(%0s%b)(%0s%b)(%0s%b)))",
 				"public-key",  "dsa-sha256",
-				"p", self->key.p,
-				"q", self->key.q,
-				"g", self->key.g,
-				"y", self->key.y);
+				"p", self->params.p,
+				"q", self->params.q,
+				"g", self->params.g,
+				"y", self->public);
 }
 
 static void
 init_dsa_sha256_verifier(struct dsa_verifier *self)
 {
-  dsa_public_key_init(&self->key);
+  dsa_params_init(&self->params);
+  mpz_init(self->public);
 
   self->super.verify = do_dsa_sha256_verify;
   self->super.public_spki_key = do_dsa_sha256_public_spki_key;
@@ -464,18 +467,18 @@ parse_ssh_dsa_sha256_public(struct simple_buffer *buffer)
   NEW(dsa_verifier, res);
   init_dsa_verifier(res);
 
-  if (parse_bignum(buffer, res->key.p, DSA_SHA256_MAX_OCTETS)
-      && (mpz_sgn(res->key.p) == 1)
-      && parse_bignum(buffer, res->key.q, DSA_SHA256_Q_OCTETS)
-      && (mpz_sgn(res->key.q) == 1)
-      && mpz_sizeinbase(res->key.q, 2) == DSA_SHA256_Q_BITS
-      && (mpz_cmp(res->key.q, res->key.p) < 0) /* q < p */ 
-      && parse_bignum(buffer, res->key.g, DSA_SHA256_MAX_OCTETS)
-      && (mpz_sgn(res->key.g) == 1)
-      && (mpz_cmp(res->key.g, res->key.p) < 0) /* g < p */ 
-      && parse_bignum(buffer, res->key.y, DSA_SHA256_MAX_OCTETS) 
-      && (mpz_sgn(res->key.y) == 1)
-      && (mpz_cmp(res->key.y, res->key.p) < 0) /* y < p */
+  if (parse_bignum(buffer, res->params.p, DSA_SHA256_MAX_OCTETS)
+      && (mpz_sgn(res->params.p) == 1)
+      && parse_bignum(buffer, res->params.q, DSA_SHA256_Q_OCTETS)
+      && (mpz_sgn(res->params.q) == 1)
+      && mpz_sizeinbase(res->params.q, 2) == DSA_SHA256_Q_BITS
+      && (mpz_cmp(res->params.q, res->params.p) < 0) /* q < p */
+      && parse_bignum(buffer, res->params.g, DSA_SHA256_MAX_OCTETS)
+      && (mpz_sgn(res->params.g) == 1)
+      && (mpz_cmp(res->params.g, res->params.p) < 0) /* g < p */
+      && parse_bignum(buffer, res->public, DSA_SHA256_MAX_OCTETS)
+      && (mpz_sgn(res->public) == 1)
+      && (mpz_cmp(res->public, res->params.p) < 0) /* y < p */
       && parse_eod(buffer))
     
     return &res->super;
@@ -507,8 +510,8 @@ do_dsa_sha256_sign(struct signer *c,
   sha256_init(&hash);
   sha256_update(&hash, msg_length, msg);
 
-  if (dsa_sha256_sign(&self->verifier->key, &self->key,
-		      NULL, lsh_random, &hash, &sv))
+  if (dsa_sign(&self->verifier->params, self->private,
+	       NULL, lsh_random, SHA256_DIGEST_SIZE, &hash, &sv))
     /* Build signature */
     switch (algorithm)
       {
@@ -554,7 +557,7 @@ make_dsa_sha256_verifier(struct signature_algorithm *self UNUSED,
   NEW(dsa_verifier, res);
   init_dsa_sha256_verifier(res);
 
-  if (dsa_keypair_from_sexp_alist(&res->key, NULL,
+  if (dsa_keypair_from_sexp_alist(&res->params, res->public, NULL,
 				  DSA_SHA256_MAX_BITS, DSA_SHA256_Q_BITS,
 				  i))
     return &res->super;
@@ -571,10 +574,11 @@ make_dsa_sha256_signer(struct signature_algorithm *self UNUSED,
   NEW(dsa_signer, res);
 
   init_dsa_verifier(verifier);
-  
-  dsa_private_key_init(&res->key);
 
-  if (dsa_keypair_from_sexp_alist(&verifier->key, &res->key,
+  mpz_init(&res->private);
+
+  if (dsa_keypair_from_sexp_alist(&verifier->params,
+				  verifier->public, res->private,
 				  DSA_SHA256_MAX_BITS, DSA_SHA256_Q_BITS,
 				  i))
     {
diff --git a/src/lsh-keygen.c b/src/lsh-keygen.c
index a82663c..274a536 100644
--- a/src/lsh-keygen.c
+++ b/src/lsh-keygen.c
@@ -476,54 +476,60 @@ progress(void *ctx UNUSED, int c)
 static struct lsh_string *
 dsa_sha1_generate_key(unsigned bits)
 {
-  struct dsa_public_key public;
-  struct dsa_private_key private;
+  struct dsa_params params;
+  mpz_t public;
+  mpz_t private;
   struct lsh_string *key = NULL;
 
-  dsa_public_key_init(&public);
-  dsa_private_key_init(&private);
+  dsa_params_init(&params);
+  mpz_init(public);
+  mpz_init(private);
 
-  if (dsa_generate_keypair(&public, &private,
-			   NULL, lsh_random,
-			   NULL, progress,
-			   bits, 160))
+  if (dsa_generate_params(&params,
+			  NULL, lsh_random,
+			  NULL, progress,
+			  bits, 160))
     {
+      dsa_generate_keypair(&params, public, private, NULL, lsh_random);
       key =
 	lsh_string_format_sexp(0,
 			       "(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))",
-			       public.p, public.q, public.g, public.y,
-			       private.x);
+			       params.p, params.q, params.g, public, private);
     }
 
-  dsa_public_key_clear(&public);
-  dsa_private_key_clear(&private);
+  dsa_params_clear(&params);
+  mpz_clear(public);
+  mpz_clear(private);
   return key;
 }
 
 static struct lsh_string *
 dsa_sha256_generate_key(unsigned bits)
 {
-  struct dsa_public_key public;
-  struct dsa_private_key private;
+  struct dsa_params params;
+  mpz_t public;
+  mpz_t private;
   struct lsh_string *key = NULL;
 
-  dsa_public_key_init(&public);
-  dsa_private_key_init(&private);
+  dsa_params_init(&params);
+  mpz_init(public);
+  mpz_init(private);
 
-  if (dsa_generate_keypair(&public, &private,
-			   NULL, lsh_random,
-			   NULL, progress,
-			   bits, 256))
+  if (dsa_generate_params(&params,
+			  NULL, lsh_random,
+			  NULL, progress,
+			  bits, 256))
     {
+      dsa_generate_keypair(&params, public, private, NULL, lsh_random);
       key =
 	lsh_string_format_sexp(0,
 			       "(private-key(dsa-sha256(p%b)(q%b)(g%b)(y%b)(x%b)))",
-			       public.p, public.q, public.g, public.y,
-			       private.x);
+			       params.p, params.q, params.g, public, private);
     }
 
-  dsa_public_key_clear(&public);
-  dsa_private_key_clear(&private);
+  dsa_params_clear(&params);
+  mpz_clear(public);
+  mpz_clear(private);
   return key;
 }
 
-- 
2.1.0