[PATCH gnupg] sm: Support generation of card-based ed25519 CSR.

Damien Goutte-Gattat dgouttegattat at incenp.org
Sun Feb 17 18:40:51 CET 2019


Hi,

On Thu, 14 Feb 2019 23:19:52 +0000, Damien Goutte-Gattat wrote:
> > (1) There are three cases; RSA, ECDSA, and EdDSA.  It's good that we
> >     can support all.
>
> Agreed. I have another patch in the works to add support for EdDSA.

Here is the patch to add EdDSA support when generating a CSR from a
token-based key.

What is still missing for this to work is support from Libksba, which
currently generates both an incorrect SPKI and an incorrect signature
value for EdDSA-based CSRs.


-- >8 --
Subject: sm: Support generation of card-based ed25519 CSR.

* sm/call-agent.c (gpgsm_scd_pksign): Allow SHA512. Create proper
S-expression for EdDSA signature.
* sm/certreqgen.c (create_request): Force use of SHA512 when
using a ed25519 key.
* sm/misc.c (transform_sigval): Insert OID for ed25519.

GnuPG-bug-id: 4013
Signed-off-by: Damien Goutte-Gattat <dgouttegattat at incenp.org>
---
 sm/call-agent.c |  7 +++++++
 sm/certreqgen.c |  6 ++++--
 sm/misc.c       | 10 ++++++++--
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/sm/call-agent.c b/sm/call-agent.c
index 6ac715fab..4f2b83f56 100644
--- a/sm/call-agent.c
+++ b/sm/call-agent.c
@@ -354,6 +354,7 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
     case GCRY_MD_RMD160:hashopt = "--hash=rmd160"; break;
     case GCRY_MD_MD5:   hashopt = "--hash=md5"; break;
     case GCRY_MD_SHA256:hashopt = "--hash=sha256"; break;
+    case GCRY_MD_SHA512:hashopt = "--hash=sha512"; break;
     default:
       return gpg_error (GPG_ERR_DIGEST_ALGO);
     }
@@ -417,6 +418,12 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
                             sigbuflen/2, sigbuf + sigbuflen/2);
       break;
 
+    case GCRY_PK_EDDSA:
+      rc = gcry_sexp_build (&sig, NULL, "(sig-val(eddsa(r%b)(s%b)))",
+                            sigbuflen/2, sigbuf,
+                            sigbuflen/2, sigbuf + sigbuflen/2);
+      break;
+
     default:
       rc = gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
       break;
diff --git a/sm/certreqgen.c b/sm/certreqgen.c
index 1d610c1bb..01fba30f5 100644
--- a/sm/certreqgen.c
+++ b/sm/certreqgen.c
@@ -807,8 +807,10 @@ create_request (ctrl_t ctrl,
   if (err)
     return err;
 
-  string = get_parameter_value (para, pHASHALGO, 0);
-  if (string)
+  len = gcry_sexp_canon_len (public, 0, NULL, NULL);
+  if (get_pk_algo_from_canon_sexp (public, len) == GCRY_PK_EDDSA)
+    mdalgo = GCRY_MD_SHA512;
+  else if ((string = get_parameter_value (para, pHASHALGO, 0)))
     mdalgo = gcry_md_map_name (string);
   else
     mdalgo = GCRY_MD_SHA256;
diff --git a/sm/misc.c b/sm/misc.c
index 9bf528513..4672f269e 100644
--- a/sm/misc.c
+++ b/sm/misc.c
@@ -146,6 +146,8 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
     pkalgo = GCRY_PK_RSA;
   else if (toklen == 5 && !memcmp ("ecdsa", tok, 5))
     pkalgo = GCRY_PK_ECC;
+  else if (toklen == 5 && !memcmp ("eddsa", tok, 5))
+    pkalgo = GCRY_PK_EDDSA;
   else
     return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
 
@@ -170,7 +172,7 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
                   mpi = &rsa_s;
                   mpi_len = &rsa_s_len;
                 }
-              else if (pkalgo == GCRY_PK_ECC)
+              else if (pkalgo == GCRY_PK_ECC || pkalgo == GCRY_PK_EDDSA)
                 {
                   mpi = &ecc_s;
                   mpi_len = &ecc_s_len;
@@ -236,6 +238,10 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
       oid = "1.2.840.10045.4.3.4"; /* ecdsa-with-sha512 */
       break;
 
+    case GCRY_MD_SHA512 | (GCRY_PK_EDDSA << 8):
+      oid = "1.3.101.112"; /* ed25519 */
+      break;
+
     default:
       return gpg_error (GPG_ERR_DIGEST_ALGO);
     }
@@ -245,7 +251,7 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
   else if (pkalgo == GCRY_PK_RSA)
     err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(s%b)))", oid,
                            (int)rsa_s_len, rsa_s);
-  else if (pkalgo == GCRY_PK_ECC)
+  else if (pkalgo == GCRY_PK_ECC || pkalgo == GCRY_PK_EDDSA)
     err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(r%b)(s%b)))", oid,
                            (int)ecc_r_len, ecc_r, (int)ecc_s_len, ecc_s);
   if (err)
-- 
2.14.5




More information about the Gnupg-devel mailing list