[git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-380-g3132bd9

by NIIBE Yutaka cvs at cvs.gnupg.org
Wed Apr 9 02:31:34 CEST 2014


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 "The GNU Privacy Guard".

The branch, master has been updated
       via  3132bd90dc8db9c7fd19ba201918e95891306dc5 (commit)
      from  db85feceaf43ebd6d44421bb14fcb60495804ae0 (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 3132bd90dc8db9c7fd19ba201918e95891306dc5
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Wed Apr 9 09:30:19 2014 +0900

    scd: EdDSA support.
    
    * scd/app-openpgp.c (KEY_TYPE_EDDSA, CURVE_ED25519): New.
    (struct app_local_s): Add eddsa.
    (get_algo_byte, store_fpr): Support KEY_TYPE_EDDSA.
    (get_ecc_key_parameters, get_curve_name): Support CURVE_ED25519.
    (send_key_attr, get_public_key): Support KEY_TYPE_EDDSA.
    (build_ecc_privkey_template): Rename as it supports both of
    ECDSA and EdDSA.
    (ecc_writekey): Rename.  Support CURVE_ED25519, too.
    (do_writekey): Follow the change of ecc_writekey.
    (do_auth): Support KEY_TYPE_EDDSA.
    (parse_ecc_curve): Support CURVE_ED25519.  Bug fix for other curves.
    (parse_algorithm_attribute): Bug fix for ECDH.  Support EdDSA.

diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index b1599fb..fff097a 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -122,6 +122,7 @@ typedef enum
   {
     KEY_TYPE_ECDH,
     KEY_TYPE_ECDSA,
+    KEY_TYPE_EDDSA,
     KEY_TYPE_RSA,
   }
 key_type_t;
@@ -146,7 +147,8 @@ enum
     CURVE_NIST_P384,
     CURVE_NIST_P521,
     CURVE_SEC_P256K1,
-    CURVE_UNKOWN,
+    CURVE_ED25519,
+    CURVE_UNKNOWN,
   };
 
 
@@ -237,6 +239,9 @@ struct app_local_s {
       } ecdsa;
       struct {
         int curve;
+      } eddsa;
+      struct {
+        int curve;
         int hashalgo;
         int cipheralgo;
       } ecdh;
@@ -746,6 +751,8 @@ get_algo_byte (key_type_t key_type)
     return 19;
   else if (key_type == KEY_TYPE_ECDH)
     return 18;
+  else if (key_type == KEY_TYPE_EDDSA)
+    return 105;                 /* (experimental) */
   else
     return 1;  /* RSA */
 }
@@ -770,7 +777,8 @@ store_fpr (app_t app, int keynumber, u32 timestamp,
   int i;
 
   n = 6;    /* key packet version, 4-byte timestamps, and algorithm */
-  if (key_type == KEY_TYPE_RSA || key_type == KEY_TYPE_ECDSA)
+  if (key_type == KEY_TYPE_RSA || key_type == KEY_TYPE_ECDSA
+      || key_type == KEY_TYPE_EDDSA)
     argc = 2;
   else if (key_type == KEY_TYPE_ECDH)
     argc = 3;
@@ -935,11 +943,21 @@ get_ecc_key_parameters (int curve, int *r_n_bits, const char **r_curve_oid)
       *r_n_bits = 521;
       *r_curve_oid = "1.3.132.0.35";
     }
-  else
+  else if (curve == CURVE_SEC_P256K1)
     {
       *r_n_bits = 256;
       *r_curve_oid = "1.3.132.0.10";
     }
+  else if (curve == CURVE_ED25519)
+    {
+      *r_n_bits = 255;
+      *r_curve_oid = "1.3.6.1.4.1.11591.15.1";
+    }
+  else
+    {
+      *r_n_bits = 0;
+      *r_curve_oid = "1.3.6.1.4.1.11591.2.12242973"; /* gnu.gnupg.badoid */
+    }
 }
 
 static void
@@ -973,6 +991,13 @@ send_key_attr (ctrl_t ctrl, app_t app, const char *keyword, int number)
                 app->app_local->keyattr[number].ecdh.hashalgo,
                 app->app_local->keyattr[number].ecdh.cipheralgo);
     }
+  else if (app->app_local->keyattr[number].key_type == KEY_TYPE_EDDSA)
+    {
+      get_ecc_key_parameters (app->app_local->keyattr[number].eddsa.curve,
+                              &n_bits, &curve_oid);
+      snprintf (buffer, sizeof buffer, "%d 105 %u %s",
+                number+1, n_bits, curve_oid);
+    }
   else
     snprintf (buffer, sizeof buffer, "0 0 UNKNOWN");
 
@@ -1282,8 +1307,12 @@ get_curve_name (int curve)
     return "NIST P-384";
   else if (curve == CURVE_NIST_P521)
     return "NIST P-521";
-  else
+  else if (curve == CURVE_SEC_P256K1)
     return "secp256k1";
+  else if (curve == CURVE_ED25519)
+    return "Ed25519";
+  else
+    return "unknown";
 }
 
 
@@ -1455,7 +1484,8 @@ get_public_key (app_t app, int keyno)
       goto leave;
     }
   /* Prepend numbers with a 0 if needed.  */
-  if (mlen && (*m & 0x80))
+  if (app->app_local->keyattr[keyno].key_type != KEY_TYPE_EDDSA
+      && mlen && (*m & 0x80))
     {
       *mbuf = 0;
       memcpy (mbuf+1, m, mlen);
@@ -1521,6 +1551,29 @@ get_public_key (app_t app, int keyno)
       gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keybuf, len);
       gcry_sexp_release (s_pkey);
     }
+  else if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_EDDSA)
+    {
+      const char *curve_name
+        = get_curve_name (app->app_local->keyattr[keyno].eddsa.curve);
+
+      err = gcry_sexp_build (&s_pkey, NULL,
+                             "(public-key(ecc(curve%s)(flags eddsa)(q%b)))",
+                             curve_name, mlen, mbuf);
+      if (err)
+        goto leave;
+
+      len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
+
+      keybuf = xtrymalloc (len);
+      if (!keybuf)
+        {
+          gcry_sexp_release (s_pkey);
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+      gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keybuf, len);
+      gcry_sexp_release (s_pkey);
+    }
   else
     {
       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
@@ -2695,9 +2748,9 @@ build_privkey_template (app_t app, int keyno,
 }
 
 static gpg_error_t
-build_ecdsa_privkey_template (app_t app, int keyno,
-                              const unsigned char *ecc_d, size_t ecc_d_len,
-                              unsigned char **result, size_t *resultlen)
+build_ecc_privkey_template (app_t app, int keyno,
+                            const unsigned char *ecc_d, size_t ecc_d_len,
+                            unsigned char **result, size_t *resultlen)
 {
   unsigned char privkey[2];
   size_t privkey_len;
@@ -3189,9 +3242,9 @@ ecdh_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
 
 
 static gpg_error_t
-ecdsa_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
-                void *pincb_arg, int keyno,
-                const unsigned char *buf, size_t buflen, int depth)
+ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
+              void *pincb_arg, int keyno,
+              const unsigned char *buf, size_t buflen, int depth)
 {
   gpg_error_t err;
   const unsigned char *tok;
@@ -3204,10 +3257,14 @@ ecdsa_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
   size_t template_len;
   unsigned char fprbuf[20];
   u32 created_at = 0;
-  int curve = CURVE_UNKOWN;
-
-  /* (private-key(ecdsa(curve%s)(q%m)(d%m))): curve = "1.2.840.10045.3.1.7" */
-  /* (private-key(ecc(curve%s)(q%m)(d%m))): curve = "secp256k1" */
+  int curve = CURVE_UNKNOWN;
+
+  /* (private-key(ecdsa(curve%s)(q%m)(d%m))(created-at%d)):
+     curve = "1.2.840.10045.3.1.7" */
+  /* (private-key(ecc(curve%s)(q%m)(d%m))(created-at%d)):
+     curve = "secp256k1" */
+  /* (private-key(ecc(curve%s)(flags eddsa)(q%m)(d%m))(created-at%d)):
+      curve = "Ed25519" */
   last_depth1 = depth;
   while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
          && depth && depth >= last_depth1)
@@ -3229,33 +3286,34 @@ ecdsa_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
             curve = CURVE_NIST_P256;
           else if (tok && toklen == 9 && !memcmp (tok, "secp256k1", 9))
             curve = CURVE_SEC_P256K1;
+          else if (tok && toklen == 7 && !memcmp (tok, "Ed25519", 7))
+            curve = CURVE_ED25519;
         }
       else if (tok && toklen == 1)
         {
-          const unsigned char **mpi;
-          size_t *mpi_len;
+          const unsigned char **buf2;
+          size_t *buf2len;
 
           switch (*tok)
             {
-            case 'q': mpi = &ecc_q; mpi_len = &ecc_q_len; break;
-            case 'd': mpi = &ecc_d; mpi_len = &ecc_d_len; break;
-            default: mpi = NULL;  mpi_len = NULL; break;
+            case 'q': buf2 = &ecc_q; buf2len = &ecc_q_len; break;
+            case 'd': buf2 = &ecc_d; buf2len = &ecc_d_len; break;
+            default: buf2 = NULL;  buf2len = NULL; break;
             }
-          if (mpi && *mpi)
+          if (buf2 && *buf2)
             {
               err = gpg_error (GPG_ERR_DUP_VALUE);
               goto leave;
             }
           if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
             goto leave;
-          if (tok && mpi)
-            {
-              /* Strip off leading zero bytes and save. */
-              for (;toklen && !*tok; toklen--, tok++)
-                ;
-              *mpi = tok;
-              *mpi_len = toklen;
-            }
+          if (tok && buf2 && curve != CURVE_ED25519)
+            /* It's MPI.  Strip off leading zero bytes and save. */
+            for (;toklen && !*tok; toklen--, tok++)
+              ;
+
+          *buf2 = tok;
+          *buf2len = toklen;
         }
       /* Skip until end of list. */
       last_depth2 = depth;
@@ -3322,9 +3380,9 @@ ecdsa_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
          the OpenPGP card specs version 2.0.  */
       int exmode;
 
-      err = build_ecdsa_privkey_template (app, keyno,
-                                          ecc_d, ecc_d_len,
-                                          &template, &template_len);
+      err = build_ecc_privkey_template (app, keyno,
+                                        ecc_d, ecc_d_len,
+                                        &template, &template_len);
       if (err)
         goto leave;
 
@@ -3353,11 +3411,14 @@ ecdsa_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **),
     }
 
   err = store_fpr (app, keyno, created_at, fprbuf, app->card_version,
-                   KEY_TYPE_ECDSA,
-                   curve == CURVE_NIST_P256?
+                   curve == CURVE_ED25519 ? KEY_TYPE_EDDSA : KEY_TYPE_ECDSA,
+                   curve == CURVE_ED25519 ?
+                   "\x09\x2b\x06\x01\x04\x01\xda\x47\x0f\x01"
+                   : curve == CURVE_NIST_P256 ?
                    "\x08\x2a\x86\x48\xce\x3d\x03\x01\x07"
                    : "\05\x2b\x81\x04\x00\x0a",
-                   curve == CURVE_NIST_P256? 9 : 6,
+                   curve == CURVE_ED25519 ? 10
+                   : curve == CURVE_NIST_P256? 9 : 6,
                    ecc_q, ecc_q_len);
   if (err)
     goto leave;
@@ -3435,7 +3496,7 @@ do_writekey (app_t app, ctrl_t ctrl,
   else if ((tok && toklen == 3 && memcmp ("ecc", tok, toklen) == 0
             && (keyno == 0 || keyno == 2))
            || (tok && toklen == 5 && memcmp ("ecdsa", tok, toklen) == 0))
-    ecdsa_writekey (app, pincb, pincb_arg, keyno, buf, buflen, depth);
+    ecc_writekey (app, pincb, pincb_arg, keyno, buf, buflen, depth);
   else if ((tok && toklen == 3 && memcmp ("ecc", tok, toklen) == 0
             && keyno == 1)
            || (tok && toklen == 4 && memcmp ("ecdh", tok, toklen) == 0))
@@ -3922,7 +3983,8 @@ do_auth (app_t app, const char *keyidstr,
 
   if (!keyidstr || !*keyidstr)
     return gpg_error (GPG_ERR_INV_VALUE);
-  if (indatalen > 101) /* For a 2048 bit key. */
+  if (app->app_local->keyattr[2].key_type == KEY_TYPE_RSA
+      && indatalen > 101) /* For a 2048 bit key. */
     return gpg_error (GPG_ERR_INV_VALUE);
 
   if (app->app_local->keyattr[2].key_type == KEY_TYPE_ECDSA
@@ -3932,6 +3994,12 @@ do_auth (app_t app, const char *keyidstr,
       indata = p;
       indatalen -= 19;
     }
+  else if (app->app_local->keyattr[2].key_type == KEY_TYPE_EDDSA)
+    {
+      const char *p = (const char *)indata + 15;
+      indata = p;
+      indatalen -= 15;
+    }
 
   /* Check whether an OpenPGP card of any version has been requested. */
   if (!strcmp (keyidstr, "OPENPGP.3"))
@@ -4308,14 +4376,18 @@ parse_ecc_curve (const unsigned char *buffer, size_t buflen)
 {
   int curve;
 
-  if (buflen == 6 && buffer[5] == 0x22)
+  if (buflen == 5 && buffer[5] == 0x22)
     curve = CURVE_NIST_P384;
-  else if (buflen == 6 && buffer[5] == 0x23)
+  else if (buflen == 5 && buffer[5] == 0x23)
     curve = CURVE_NIST_P521;
-  else if (buflen == 9)
+  else if (buflen == 8)
     curve = CURVE_NIST_P256;
-  else
+  else if (buflen == 5 && buffer[5] == 0x0a)
     curve = CURVE_SEC_P256K1;
+  else if (buflen == 9)
+    curve = CURVE_ED25519;
+  else
+    curve = CURVE_UNKNOWN;
 
   return curve;
 }
@@ -4384,10 +4456,16 @@ parse_algorithm_attribute (app_t app, int keyno)
   else if (*buffer == 18 && buflen == 11) /* ECDH */
     {
       app->app_local->keyattr[keyno].key_type = KEY_TYPE_ECDH;
-      app->app_local->keyattr[keyno].ecdh.curve
-        = parse_ecc_curve (buffer + 1, buflen - 1);
       app->app_local->keyattr[keyno].ecdh.hashalgo = buffer[1];
       app->app_local->keyattr[keyno].ecdh.cipheralgo = buffer[2];
+      app->app_local->keyattr[keyno].ecdh.curve
+        = parse_ecc_curve (buffer + 3, buflen - 3);
+    }
+  else if (*buffer == 105) /* EdDSA (experimental) */
+    {
+      app->app_local->keyattr[keyno].key_type = KEY_TYPE_EDDSA;
+      app->app_local->keyattr[keyno].eddsa.curve
+        = parse_ecc_curve (buffer + 1, buflen - 1);
     }
   else if (opt.verbose)
     log_printhex ("", buffer, buflen);

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

Summary of changes:
 scd/app-openpgp.c |  164 +++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 121 insertions(+), 43 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list