[PATCH] ECC working again with new libgcrypt

NIIBE Yutaka gniibe at fsij.org
Fri Apr 25 03:41:52 CEST 2014


Here is a patch to fix ECC issues.  With this patch, it now gets
success on "make check" (specifically, ecc.test).

There are confusions about PUBKEY_ALGO, if it's (1) the value defined by
OpenPGP specification or (2) it's the value defined by libgcrypt API.

Because it gets the value by the gcry_pk_map_name function (in
convert_from_openpgp_main), it's (2).  So, it is wrong to call
map_pk_openpgp_to_gcry in do_unprotect and convert_from_openpgp_main.
(This causes mysterious result of all keys will be handled as ECDH,
as the value of PUBKEY_ALGO_ECDH equals to GCRY_PK_ECC.)

Besides, the gcry_pk_map_name function in newer libgcrypt (1.6 and later),
returns generic value, and doesn't distinguish detail.  For example,

	"ECDSA" -> GCRY_PK_ECC
	"ECDH"  -> GCRY_PK_ECC

Because of this, we can't keep distinguishing "ECDSA" and "ECDH", although
client sends specific information to agent.

And, I confirmed that the change in g10/pubkey-enc.c (swapping data[0]
and data[1]) is correct.

OK to apply?

diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c
index 4c34130..ef34463 100644
--- a/agent/cvt-openpgp.c
+++ b/agent/cvt-openpgp.c
@@ -68,21 +68,17 @@ get_keygrip (int pubkey_algo, gcry_mpi_t *pkey, unsigned char *grip)
       break;
 
     case GCRY_PK_ELG:
-    case GCRY_PK_ELG_E:
       err = gcry_sexp_build (&s_pkey, NULL,
                              "(public-key(elg(p%m)(g%m)(y%m)))",
                              pkey[0], pkey[1], pkey[2]);
       break;
 
     case GCRY_PK_RSA:
-    case GCRY_PK_RSA_E:
-    case GCRY_PK_RSA_S:
       err = gcry_sexp_build (&s_pkey, NULL,
                              "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]);
       break;
 
-    case GCRY_PK_ECDSA:
-    case GCRY_PK_ECDH:
+    case GCRY_PK_ECC:
       err = gcry_sexp_build (&s_pkey, NULL,
                              "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))",
                              pkey[0], pkey[1], pkey[2], pkey[3], pkey[4],
@@ -138,14 +134,10 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey)
                              skey[5]);
       break;
 
-    case GCRY_PK_ECDSA:
-    case GCRY_PK_ECDH:
-      /* Although our code would work with "ecc" we explicitly use
-         "ecdh" or "ecdsa" to implicitly set the key capabilities.  */
+    case GCRY_PK_ECC:
       err = gcry_sexp_build (&s_skey, NULL,
-                             "(private-key(%s(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)"
+                             "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)"
                              "(d%m)))",
-                             pubkey_algo == GCRY_PK_ECDSA?"ecdsa":"ecdh",
                              skey[0], skey[1], skey[2], skey[3], skey[4],
                              skey[5], skey[6]);
       break;
@@ -186,7 +178,6 @@ convert_transfer_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey,
       break;
 
     case GCRY_PK_ELG:
-    case GCRY_PK_ELG_E:
       err = gcry_sexp_build
         (&s_skey, NULL,
          "(protected-private-key(elg(p%m)(g%m)(y%m)"
@@ -196,8 +187,6 @@ convert_transfer_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey,
 

     case GCRY_PK_RSA:
-    case GCRY_PK_RSA_E:
-    case GCRY_PK_RSA_S:
       err = gcry_sexp_build
         (&s_skey, NULL,
          "(protected-private-key(rsa(n%m)(e%m)",
@@ -205,15 +194,11 @@ convert_transfer_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey,
          skey[0], skey[1], transfer_key );
       break;
 
-    case GCRY_PK_ECDSA:
-    case GCRY_PK_ECDH:
-      /* Although our code would work with "ecc" we explicitly use
-         "ecdh" or "ecdsa" to implicitly set the key capabilities.  */
+    case GCRY_PK_ECC:
       err = gcry_sexp_build
         (&s_skey, NULL,
-         "(protected-private-key(%s(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)"
+         "(protected-private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)"
          "(protected openpgp-native%S)))",
-         pubkey_algo == GCRY_PK_ECDSA?"ecdsa":"ecdh",
          skey[0], skey[1], skey[2], skey[3], skey[4], skey[5], transfer_key);
       break;
 
@@ -359,10 +344,6 @@ do_unprotect (const char *passphrase,
 
   *r_key = NULL;
 
-  /* Unfortunately, the OpenPGP PK algorithm numbers need to be
-     re-mapped for Libgcrypt.    */
-  pubkey_algo = map_pk_openpgp_to_gcry (pubkey_algo);
-
   err = prepare_unprotect (pubkey_algo, skey, skeysize, s2k_mode,
                            &npkey, &nskey, &skeylen);
   if (err)
@@ -864,14 +845,12 @@ convert_from_openpgp_main (ctrl_t ctrl, gcry_sexp_t s_pgp,
 
   if (unattended && !from_native)
     {
-      int pubkey_g_algo = map_pk_openpgp_to_gcry (pubkey_algo);
-
-      err = prepare_unprotect (pubkey_g_algo, skey, DIM(skey), s2k_mode,
+      err = prepare_unprotect (pubkey_algo, skey, DIM(skey), s2k_mode,
                                NULL, NULL, NULL);
       if (err)
         goto leave;
 
-      err = convert_transfer_key (&s_skey, pubkey_g_algo, skey, s_pgp);
+      err = convert_transfer_key (&s_skey, pubkey_algo, skey, s_pgp);
       if (err)
         goto leave;
     }
@@ -1195,7 +1174,7 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
   else if (!strcmp (name, "ecc"))
     {
       /* FIXME: We need to use the curve parameter.  */
-      algoname = "?"; /* Decide later by checking the usage.  */
+      algoname = "ecc"; /* Decide later by checking the usage.  */
       npkey = 6;
       nskey = 7;
       err = gcry_sexp_extract_param (list, NULL, "pabgnqd",
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index 8078cba..5319e49 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -2546,12 +2546,3 @@ check_for_running_agent (int silent, int mode)
   assuan_release (ctx);
   return 0;
 }
-
-/* TODO: it is also in misc, which is not linked with the agent */
-/* FIXME: The agent should not know about openpgp internals - weel
-   except for some stuff in cvt-openpgp.  */
-int
-map_pk_openpgp_to_gcry (int algo)
-{
-  return (algo==PUBKEY_ALGO_ECDSA ? GCRY_PK_ECDSA : (algo==PUBKEY_ALGO_ECDH ? GCRY_PK_ECDH : algo));
-}
diff --git a/g10/call-agent.c b/g10/call-agent.c
index ad578db..42cc9ea 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -1991,7 +1991,7 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
       xfree (buf);
       return gpg_error (GPG_ERR_INV_SEXP);
     }
-  len -= 11;   /* Count only the data of the second part. */
+  len -= 10;   /* Count only the data of the second part. */
   p = buf + 8; /* Skip leading parenthesis and the value tag. */
 
   n = strtoul (p, &endp, 10);
diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
index a563ec0..60f7611 100644
--- a/g10/pubkey-enc.c
+++ b/g10/pubkey-enc.c
@@ -185,7 +185,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
         err = gpg_error (GPG_ERR_BAD_MPI);
       else
         err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(s%m)(e%m)))",
-                               enc->data[0], enc->data[1]);
+                               enc->data[1], enc->data[0]);
     }
   else
     err = gpg_error (GPG_ERR_BUG);
diff --git a/tests/openpgp/ecc.test b/tests/openpgp/ecc.test
index 062a1ae..d609549 100755
--- a/tests/openpgp/ecc.test
+++ b/tests/openpgp/ecc.test
@@ -20,7 +20,7 @@ mainkeyids='BAA59D9C
             45AF2FFE'
 

-if have_pubkey_algo "ECC"; then
+if have_pubkey_algo "ECDSA"; then
   :
 else
   info "No ECC support due to an old Libgcrypt"
-- 





More information about the Gnupg-devel mailing list