[PATCH] agent and scd: Don't prepend message digest

NIIBE Yutaka gniibe at fsij.org
Tue Mar 12 09:19:26 CET 2013


Hello,

This patch is to simplify code of GPG-Agent and SCDaemon for
signing/authentication.  Currently, we always prepend message digest
specifier and it is checked by SCDaemon.  With this patch, it will be
only prepended for RSA and not for ECDSA, and it will be not checked
by SCDaemon.

This patch changes the protocol between GPG-Agent and SCDaemon for
ECDSA signing/authentication.  It doesn't change for RSA case.

I think that removal of the check by SCDaemon is no problem.
Please correct me if I'm wrong.

I will commit this if there is no problem.


diff --git a/agent/agent.h b/agent/agent.h
index 2fd0b8b..28f69f5 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -403,7 +403,7 @@ void agent_reload_trustlist (void);
 

 /*-- divert-scd.c --*/
-int divert_pksign (ctrl_t ctrl,
+int divert_pksign (ctrl_t ctrl, int add_md,
                    const unsigned char *digest, size_t digestlen, int algo,
                    const unsigned char *shadow_info, unsigned char **r_sig,
                    size_t *r_siglen);
diff --git a/agent/divert-scd.c b/agent/divert-scd.c
index f0d8473..38fab0e 100644
--- a/agent/divert-scd.c
+++ b/agent/divert-scd.c
@@ -333,7 +333,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
 

 int
-divert_pksign (ctrl_t ctrl,
+divert_pksign (ctrl_t ctrl, int add_md,
                const unsigned char *digest, size_t digestlen, int algo,
                const unsigned char *shadow_info, unsigned char **r_sig,
                size_t *r_siglen)
@@ -360,13 +360,19 @@ divert_pksign (ctrl_t ctrl,
       unsigned char *data;
       size_t ndata;
 
-      rc = encode_md_for_card (digest, digestlen, algo, &data, &ndata);
-      if (!rc)
+      if (add_md)
         {
-          rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl,
-                                  algo, data, ndata, &sigval, &siglen);
-          xfree (data);
+          rc = encode_md_for_card (digest, digestlen, algo, &data, &ndata);
+          if (!rc)
+            {
+              rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl,
+                                      algo, data, ndata, &sigval, &siglen);
+              xfree (data);
+            }
         }
+      else
+        rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl,
+                                algo, digest, digestlen, &sigval, &siglen);
     }
 
   if (!rc)
diff --git a/agent/pksign.c b/agent/pksign.c
index 8518730..5646d1c 100644
--- a/agent/pksign.c
+++ b/agent/pksign.c
@@ -301,7 +301,7 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
       gcry_sexp_release (l);
       gcry_sexp_release (s_pkey);
 
-      rc = divert_pksign (ctrl,
+      rc = divert_pksign (ctrl, is_RSA,
                           ctrl->digest.value,
                           ctrl->digest.valuelen,
                           ctrl->digest.algo,
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 1df35b2..d2d33c3 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -3299,31 +3299,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
          const void *indata, size_t indatalen,
          unsigned char **outdata, size_t *outdatalen )
 {
-  static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */
-    { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
-      0x02, 0x01, 0x05, 0x00, 0x04, 0x14  };
-  static unsigned char sha1_prefix[15] =   /* (1.3.14.3.2.26) */
-    { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
-      0x02, 0x1a, 0x05, 0x00, 0x04, 0x14  };
-  static unsigned char sha224_prefix[19] = /* (2.16.840.1.101.3.4.2.4) */
-    { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
-      0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
-      0x1C  };
-  static unsigned char sha256_prefix[19] = /* (2.16.840.1.101.3.4.2.1) */
-    { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
-      0x00, 0x04, 0x20  };
-  static unsigned char sha384_prefix[19] = /* (2.16.840.1.101.3.4.2.2) */
-    { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
-      0x00, 0x04, 0x30  };
-  static unsigned char sha512_prefix[19] = /* (2.16.840.1.101.3.4.2.3) */
-    { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
-      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
-      0x00, 0x04, 0x40  };
   int rc;
-  unsigned char data[19+64];
-  size_t datalen;
   unsigned char tmp_sn[20]; /* Actually 16 bytes but also for the fpr. */
   const char *s;
   int n;
@@ -3335,38 +3311,6 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
   if (!keyidstr || !*keyidstr)
     return gpg_error (GPG_ERR_INV_VALUE);
 
-  /* Strip off known prefixes.  */
-#define X(a,b,c,d) \
-  if (hashalgo == GCRY_MD_ ## a                               \
-      && (d)                                                  \
-      && indatalen == sizeof b ## _prefix + (c)               \
-      && !memcmp (indata, b ## _prefix, sizeof b ## _prefix)) \
-    {                                                         \
-      indata = (const char*)indata + sizeof b ## _prefix;     \
-      indatalen -= sizeof b ## _prefix;                       \
-    }
-
-  if (indatalen == 20)
-    ;  /* Assume a plain SHA-1 or RMD160 digest has been given.  */
-  else X(SHA1,   sha1,   20, 1)
-  else X(RMD160, rmd160, 20, 1)
-  else X(SHA224, sha224, 28, app->app_local->extcap.is_v2)
-  else X(SHA256, sha256, 32, app->app_local->extcap.is_v2)
-  else X(SHA384, sha384, 48, app->app_local->extcap.is_v2)
-  else X(SHA512, sha512, 64, app->app_local->extcap.is_v2)
-  else if ((indatalen == 28 || indatalen == 32
-            || indatalen == 48 || indatalen ==64)
-           && app->app_local->extcap.is_v2)
-    ;  /* Assume a plain SHA-3 digest has been given.  */
-  else
-    {
-      log_error (_("card does not support digest algorithm %s\n"),
-                 gcry_md_algo_name (hashalgo));
-      /* Or the supplied digest length does not match an algorithm.  */
-      return gpg_error (GPG_ERR_INV_VALUE);
-    }
-#undef X
-
   /* Check whether an OpenPGP card of any version has been requested. */
   if (!strcmp (keyidstr, "OPENPGP.1"))
     ;
@@ -3406,40 +3350,11 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
   if (rc)
     return rc;
 
-  /* Concatenate prefix and digest.  */
-#define X(a,b,d) \
-  if (hashalgo == GCRY_MD_ ## a && (d) )                      \
-    {                                                         \
-      datalen = sizeof b ## _prefix + indatalen;              \
-      assert (datalen <= sizeof data);                        \
-      memcpy (data, b ## _prefix, sizeof b ## _prefix);       \
-      memcpy (data + sizeof b ## _prefix, indata, indatalen); \
-    }
-
-  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
-    {
-      datalen = indatalen;
-      memcpy (data, indata, indatalen);
-    }
-#undef X
-
   /* Redirect to the AUTH command if asked to. */
   if (use_auth)
     {
       return do_auth (app, "OPENPGP.3", pincb, pincb_arg,
-                      data, datalen,
+                      indata, indatalen,
                       outdata, outdatalen);
     }
 
@@ -3491,7 +3406,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
       exmode = 0;
       le_value = 0;
     }
-  rc = iso7816_compute_ds (app->slot, exmode, data, datalen, le_value,
+  rc = iso7816_compute_ds (app->slot, exmode, indata, indatalen, le_value,
                            outdata, outdatalen);
   return rc;
 }
@@ -3524,14 +3439,6 @@ 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