scd: ECDSA sign support

NIIBE Yutaka gniibe at fsij.org
Fri Mar 8 07:48:31 CET 2013


Here is another patch for GnuPG in the smartcard ECDSA support series.
(There will be one more: support writekey for ECDSA.)

This patch is to support ECDSA signing.

This patch is made so that the change can be minimum.  But it shows
we would need to change the protocol between GPG-agent and SCDaemon.

Currently, it's only for RSA and it supports multiple hash algorithms.
GPG-agent encodes the hash algorithm block and prepend it to the data.

For ECDSA, hash algorithm is implicitly determined by its key size,
and we don't prepend the hash algorithm block.  Thus, we just drop
off the block added by GPG-agent.

In the current implementation, do_sign checks hash algorithm.  It remove
off the hash algorithm block and put it again.  I think that this check
is not needed at SCDaemon.

If it is OK to remove the checking of hash algorithm by SCDaemon, I'd
like to remove it, and also remove adding the hash algorithm block for
ECDSA by GPG-daemon.

I'd like to change the code, step by step.  I'll commit this change if
there are no objections at first.  Then, in the next step, I will
change the protocol (we won't prepend hash algorithm block for ECDSA).
I mean, change agent/divert-scd.c and scd/app-openpgp.c.


diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 8d507c4..1df35b2 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -3416,14 +3416,23 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
       memcpy (data + sizeof b ## _prefix, indata, indatalen); \
     }
 
-  X(SHA1,   sha1,   1)
-  else X(RMD160, rmd160, 1)
-  else X(SHA224, sha224, app->app_local->extcap.is_v2)
-  else X(SHA256, sha256, app->app_local->extcap.is_v2)
-  else X(SHA384, sha384, app->app_local->extcap.is_v2)
-  else X(SHA512, sha512, app->app_local->extcap.is_v2)
+  if (use_auth
+      || app->app_local->keyattr[use_auth? 2: 0].key_type == KEY_TYPE_RSA)
+    {
+      X(SHA1,   sha1,   1)
+      else X(RMD160, rmd160, 1)
+      else X(SHA224, sha224, app->app_local->extcap.is_v2)
+      else X(SHA256, sha256, app->app_local->extcap.is_v2)
+      else X(SHA384, sha384, app->app_local->extcap.is_v2)
+      else X(SHA512, sha512, app->app_local->extcap.is_v2)
+      else
+        return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
+    }
   else
-    return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
+    {
+      datalen = indatalen;
+      memcpy (data, indata, indatalen);
+    }
 #undef X
 
   /* Redirect to the AUTH command if asked to. */
@@ -3515,6 +3524,14 @@ do_auth (app_t app, const char *keyidstr,
   if (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
+      && (indatalen == 51 || indatalen == 67 || indatalen == 83)
+    {
+      const char *p = (const char *)indata + 19;
+      indata = p;
+      indatalen -= 19;
+    }
+
   /* Check whether an OpenPGP card of any version has been requested. */
   if (!strcmp (keyidstr, "OPENPGP.3"))
     ;
-- 





More information about the Gnupg-devel mailing list