2004-09-25 Moritz Schulte <moritz@g10code.com>
authorMoritz Schulte <mo@g10code.com>
Sun, 26 Sep 2004 21:48:13 +0000 (21:48 +0000)
committerMoritz Schulte <mo@g10code.com>
Sun, 26 Sep 2004 21:48:13 +0000 (21:48 +0000)
* agent.h: Declare: agent_pksign_do.
(struct server_control_s): New member: raw_value.

* pksign.c (do_encode_md): New argument: raw_value; support
generation of raw (non-pkcs1) data objects; adjust callers.
(agent_pksign_do): New function, based on code ripped
out from agent_pksign.
(agent_pksign): Use agent_pksign_do.

* command.c (start_command_handler): Set ctrl.digest.raw_value.

agent/ChangeLog
agent/agent.h
agent/command.c
agent/pksign.c

index 470c701..0323086 100644 (file)
@@ -1,3 +1,16 @@
+2004-09-25  Moritz Schulte  <moritz@g10code.com>
+       
+       * agent.h: Declare: agent_pksign_do.
+       (struct server_control_s): New member: raw_value.
+       
+       * pksign.c (do_encode_md): New argument: raw_value; support
+       generation of raw (non-pkcs1) data objects; adjust callers.
+       (agent_pksign_do): New function, based on code ripped
+       out from agent_pksign.
+       (agent_pksign): Use agent_pksign_do.
+
+       * command.c (start_command_handler): Set ctrl.digest.raw_value.
+       
 2004-09-09  Werner Koch  <wk@g10code.de>
 
        * gpg-agent.c (check_for_running_agent): New.
index 89fc428..8112c25 100644 (file)
@@ -95,6 +95,7 @@ struct server_control_s {
     int algo;
     unsigned char value[MAX_DIGEST_LEN];
     int valuelen;
+    int raw_value: 1;
   } digest;
   char keygrip[20];
   int have_keygrip;
@@ -159,6 +160,8 @@ void agent_unlock_cache_entry (void **cache_id);
 
 
 /*-- pksign.c --*/
+int agent_pksign_do (CTRL ctrl, const char *desc_text,
+                    gcry_sexp_t *signature_sexp, int ignore_cache);
 int agent_pksign (ctrl_t ctrl, const char *desc_text,
                   FILE *outfp, int ignore_cache);
 
index 1d1ae97..02bbf34 100644 (file)
@@ -854,6 +854,7 @@ start_command_handler (int listen_fd, int fd)
   ctrl.server_local->assuan_ctx = ctx;
   ctrl.server_local->message_fd = -1;
   ctrl.server_local->use_cache_for_signing = 1;
+  ctrl.digest.raw_value = 0;
 
   if (DBG_ASSUAN)
     assuan_set_log_stream (ctx, log_get_stream ());
index acde660..11e9648 100644 (file)
 
 
 static int
-do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash)
+do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash,
+             int raw_value)
 {
   gcry_sexp_t hash;
-  const char *s;
-  char tmp[16+1];
-  int i, rc;
+  int rc;
 
-  s = gcry_md_algo_name (algo);
-  if (s && strlen (s) < 16)
+  if (! raw_value)
+    {
+      const char *s;
+      char tmp[16+1];
+      int i;
+      
+      s = gcry_md_algo_name (algo);
+      if (s && strlen (s) < 16)
+       {
+         for (i=0; i < strlen (s); i++)
+           tmp[i] = tolower (s[i]);
+         tmp[i] = '\0';   
+       }
+
+      rc = gcry_sexp_build (&hash, NULL,
+                           "(data (flags pkcs1) (hash %s %b))",
+                           tmp, mdlen, md);
+    }
+  else
     {
-      for (i=0; i < strlen (s); i++)
-        tmp[i] = tolower (s[i]);
-      tmp[i] = '\0';   
+      gcry_mpi_t mpi;
+      
+      rc = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, md, mdlen, NULL);
+      if (! rc)
+       {
+         rc = gcry_sexp_build (&hash, NULL,
+                               "(data (flags raw) (value %m))",
+                               mpi);
+         gcry_mpi_release (mpi);
+       }
+         
     }
-  rc = gcry_sexp_build (&hash, NULL,
-                        "(data (flags pkcs1) (hash %s %b))",
-                        tmp,
-                        mdlen, md);
+  
   *r_hash = hash;
   return rc;   
 }
 
 
-/* SIGN whatever information we have accumulated in CTRL and write it
-   back to OUTFP. */
+/* SIGN whatever information we have accumulated in CTRL and return
+   the signature S-Expression. */
 int
-agent_pksign (CTRL ctrl, const char *desc_text, FILE *outfp, int ignore_cache) 
+agent_pksign_do (CTRL ctrl, const char *desc_text,
+                gcry_sexp_t *signature_sexp, int ignore_cache)
 {
-  gcry_sexp_t s_skey = NULL, s_hash = NULL, s_sig = NULL;
+  gcry_sexp_t s_skey = NULL, s_sig = NULL;
   unsigned char *shadow_info = NULL;
-  int rc;
-  char *buf = NULL;
-  size_t len;
+  unsigned int rc = 0;         /* FIXME: gpg-error? */
 
-  if (!ctrl->have_keygrip)
+  if (! ctrl->have_keygrip)
     return gpg_error (GPG_ERR_NO_SECKEY);
 
   rc = agent_key_from_file (ctrl, desc_text, ctrl->keygrip,
@@ -77,32 +97,47 @@ agent_pksign (CTRL ctrl, const char *desc_text, FILE *outfp, int ignore_cache)
       goto leave;
     }
 
-  if (!s_skey)
-    { /* divert operation to the smartcard */
-      unsigned char *sigbuf;
+  if (! s_skey)
+    {
+      /* divert operation to the smartcard */
+
+      unsigned char *buf = NULL;
+      size_t len = 0;
 
       rc = divert_pksign (ctrl, 
                           ctrl->digest.value, 
                           ctrl->digest.valuelen,
                           ctrl->digest.algo,
-                          shadow_info, &sigbuf);
+                          shadow_info, &buf);
       if (rc)
         {
           log_error ("smartcard signing failed: %s\n", gpg_strerror (rc));
           goto leave;
         }
-      len = gcry_sexp_canon_len (sigbuf, 0, NULL, NULL);
+      len = gcry_sexp_canon_len (buf, 0, NULL, NULL);
       assert (len);
-      buf = sigbuf;
+
+      rc = gcry_sexp_sscan (&s_sig, NULL, buf, len);
+      xfree (buf);
+      if (rc)
+       {
+         log_error ("failed to convert sigbuf returned by divert_pksign "
+                    "into S-Exp: %s", gpg_strerror (rc));
+         goto leave;
+       }
     }
   else
-    { /* no smartcard, but a private key */
+    {
+      /* no smartcard, but a private key */
+
+      gcry_sexp_t s_hash = NULL;
 
       /* put the hash into a sexp */
       rc = do_encode_md (ctrl->digest.value,
                          ctrl->digest.valuelen,
                          ctrl->digest.algo,
-                         &s_hash);
+                         &s_hash,
+                        ctrl->digest.raw_value);
       if (rc)
         goto leave;
 
@@ -114,6 +149,7 @@ agent_pksign (CTRL ctrl, const char *desc_text, FILE *outfp, int ignore_cache)
 
       /* sign */
       rc = gcry_pk_sign (&s_sig, s_hash, s_skey);
+      gcry_sexp_release (s_hash);
       if (rc)
         {
           log_error ("signing failed: %s\n", gpg_strerror (rc));
@@ -125,26 +161,46 @@ agent_pksign (CTRL ctrl, const char *desc_text, FILE *outfp, int ignore_cache)
           log_debug ("result: ");
           gcry_sexp_dump (s_sig);
         }
-
-      len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, NULL, 0);
-      assert (len);
-      buf = xmalloc (len);
-      len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, buf, len);
-      assert (len);
     }
 
+ leave:
+
+  *signature_sexp = s_sig;
+
+  gcry_sexp_release (s_skey);
+  xfree (shadow_info);
+
+  return rc;
+}
+
+/* SIGN whatever information we have accumulated in CTRL and write it
+   back to OUTFP. */
+int
+agent_pksign (CTRL ctrl, const char *desc_text, FILE *outfp, int ignore_cache) 
+{
+  gcry_sexp_t s_sig = NULL;
+  char *buf = NULL;
+  size_t len = 0;
+  int rc = 0;
+
+  rc = agent_pksign_do (ctrl, desc_text, &s_sig, ignore_cache);
+  if (rc)
+    goto leave;
+
+  len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, NULL, 0);
+  assert (len);
+  buf = xmalloc (len);
+  len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, buf, len);
+  assert (len);
+
   /* FIXME: we must make sure that no buffering takes place or we are
      in full control of the buffer memory (easy to do) - should go
      into assuan. */
   fwrite (buf, 1, len, outfp);
 
  leave:
-  gcry_sexp_release (s_skey);
-  gcry_sexp_release (s_hash);
   gcry_sexp_release (s_sig);
   xfree (buf);
-  xfree (shadow_info);
+
   return rc;
 }
-
-