Key generation and signing using the OpenPGP card does rudimentary work.
authorWerner Koch <wk@gnupg.org>
Fri, 27 Jun 2003 20:53:09 +0000 (20:53 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 27 Jun 2003 20:53:09 +0000 (20:53 +0000)
50 files changed:
agent/ChangeLog
agent/agent.h
agent/call-scd.c
agent/command.c
agent/divert-scd.c
agent/findkey.c
agent/genkey.c
agent/gpg-agent.c
agent/learncard.c
agent/minip12.c
agent/minip12.h
agent/pkdecrypt.c
agent/pksign.c
agent/protect-tool.c
agent/protect.c
common/ChangeLog
common/maperror.c
kbx/kbxutil.c
kbx/keybox-blob.c
scd/ChangeLog
scd/Makefile.am
scd/app-common.h [new file with mode: 0644]
scd/app-openpgp.c
scd/app.c [new file with mode: 0644]
scd/card.c
scd/command.c
scd/sc-investigate.c
scd/scdaemon.c
scd/scdaemon.h
sm/ChangeLog
sm/call-agent.c
sm/call-dirmngr.c
sm/certchain.c
sm/certcheck.c
sm/certdump.c
sm/certlist.c
sm/certreqgen.c
sm/decrypt.c
sm/delete.c
sm/encrypt.c
sm/export.c
sm/fingerprint.c
sm/gpgsm.c
sm/gpgsm.h
sm/import.c
sm/keydb.c
sm/keylist.c
sm/server.c
sm/sign.c
sm/verify.c

index 573a136..98d86ed 100644 (file)
@@ -1,3 +1,30 @@
+2003-06-26  Werner Koch  <wk@gnupg.org>
+
+       * call-scd.c (agent_card_serialno): Don't do a RESET anymore.
+
+2003-06-25  Werner Koch  <wk@gnupg.org>
+
+       * command.c (cmd_scd): New.
+       * call-scd.c (agent_card_scd): New.
+       * divert-scd.c (divert_generic_cmd): New
+
+       * call-scd.c (agent_card_learn): New callback args SINFO.
+       (learn_status_cb): Pass all other status lines to the sinfo
+       callback.
+       * learncard.c (release_sinfo, sinfo_cb): New.
+       (agent_handle_learn): Pass the new cb to the learn function and
+       pass the collected information back to the client's assuan
+       connection.
+
+       * gpg-agent.c (main): Moved pth_init before gcry_check_version.
+
+2003-06-24  Werner Koch  <wk@gnupg.org>
+
+       * gpg-agent.c (handle_connections): Adjusted for Pth 2.0
+
+       Adjusted for changes in the libgcrypt API. Some more fixes for the
+       libgpg-error stuff.  
+
 2003-06-04  Werner Koch  <wk@gnupg.org>
 
        Renamed error codes from INVALID to INV and removed _ERROR suffixes.
index cc4bb7a..eb4f4e3 100644 (file)
@@ -1,5 +1,5 @@
 /* agent.h - Global definitions for the agent
- *     Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ *     Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -130,8 +130,9 @@ void start_command_handler (int, int);
 /*-- findkey.c --*/
 int agent_write_private_key (const unsigned char *grip,
                              const void *buffer, size_t length, int force);
-GCRY_SEXP agent_key_from_file (CTRL ctrl, const unsigned char *grip,
-                               unsigned char **shadow_info, int ignore_cache);
+gcry_sexp_t agent_key_from_file (CTRL ctrl, const unsigned char *grip,
+                                 unsigned char **shadow_info,
+                                 int ignore_cache);
 int agent_key_available (const unsigned char *grip);
 
 /*-- query.c --*/
@@ -160,7 +161,7 @@ int agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
 /*-- genkey.c --*/
 int agent_genkey (CTRL ctrl,
                   const char *keyparam, size_t keyparmlen, FILE *outfp);
-int agent_protect_and_store (CTRL ctrl, GCRY_SEXP s_skey);
+int agent_protect_and_store (CTRL ctrl, gcry_sexp_t s_skey);
 
 /*-- protect.c --*/
 int agent_protect (const unsigned char *plainkey, const char *passphrase,
@@ -189,12 +190,17 @@ int divert_pkdecrypt (CTRL ctrl,
                       const unsigned char *cipher,
                       const unsigned char *shadow_info,
                       char **r_buf, size_t *r_len);
+int divert_generic_cmd (CTRL ctrl, const char *cmdline, void *assuan_context);
+
 
 /*-- call-scd.c --*/
 int agent_card_learn (void (*kpinfo_cb)(void*, const char *),
                       void *kpinfo_cb_arg,
                       void (*certinfo_cb)(void*, const char *),
-                      void *certinfo_cb_arg);
+                      void *certinfo_cb_arg,
+                      void (*sinfo_cb)(void*, const char *,
+                                       size_t, const char *),
+                      void *sinfo_cb_arg);
 int agent_card_serialno (char **r_serialno);
 int agent_card_pksign (const char *keyid,
                        int (*getpin_cb)(void *, const char *, char*, size_t),
@@ -208,6 +214,9 @@ int agent_card_pkdecrypt (const char *keyid,
                           char **r_buf, size_t *r_buflen);
 int agent_card_readcert (const char *id, char **r_buf, size_t *r_buflen);
 int agent_card_readkey (const char *id, unsigned char **r_buf);
+int agent_card_scd (const char *cmdline,
+                    int (*getpin_cb)(void *, const char *, char*, size_t),
+                    void *getpin_cb_arg, void *assuan_context);
 
 
 /*-- learncard.c --*/
index 30e7d6f..90d4a6c 100644 (file)
@@ -57,6 +57,8 @@ struct learn_parm_s {
   void *kpinfo_cb_arg;
   void (*certinfo_cb)(void*, const char *);
   void *certinfo_cb_arg;
+  void (*sinfo_cb)(void*, const char *, size_t, const char *);
+  void *sinfo_cb_arg;
 };
 
 struct inq_needpin_s {
@@ -245,8 +247,10 @@ learn_status_cb (void *opaque, const char *line)
     {
       log_debug ("learn_status_cb: serialno `%s'\n", line);
     }
-  else
-    log_debug ("learn_status_cb: ignoring `%.*s'\n", keywordlen, keyword);
+  else if (keywordlen && *line)
+    {
+      parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line);
+    }
   
   return 0;
 }
@@ -257,7 +261,9 @@ int
 agent_card_learn (void (*kpinfo_cb)(void*, const char *),
                   void *kpinfo_cb_arg,
                   void (*certinfo_cb)(void*, const char *),
-                  void *certinfo_cb_arg)
+                  void *certinfo_cb_arg,
+                  void (*sinfo_cb)(void*, const char *, size_t, const char *),
+                  void *sinfo_cb_arg)
 {
   int rc;
   struct learn_parm_s parm;
@@ -271,6 +277,8 @@ agent_card_learn (void (*kpinfo_cb)(void*, const char *),
   parm.kpinfo_cb_arg = kpinfo_cb_arg;
   parm.certinfo_cb = certinfo_cb;
   parm.certinfo_cb_arg = certinfo_cb_arg;
+  parm.sinfo_cb = sinfo_cb;
+  parm.sinfo_cb_arg = sinfo_cb_arg;
   rc = assuan_transact (scd_ctx, "LEARN --force",
                         NULL, NULL, NULL, NULL,
                         learn_status_cb, &parm);
@@ -329,9 +337,9 @@ agent_card_serialno (char **r_serialno)
      we can do this if we for some reason figure out that the
      operation might have failed due to a missing RESET.  Hmmm, I feel
      this is really SCdaemon's duty */
-  rc = assuan_transact (scd_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL);
-  if (rc)
-    return unlock_scd (map_assuan_err (rc));
+/*    rc = assuan_transact (scd_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); */
+/*    if (rc) */
+/*      return unlock_scd (map_assuan_err (rc)); */
 
   rc = assuan_transact (scd_ctx, "SERIALNO",
                         NULL, NULL, NULL, NULL,
@@ -592,3 +600,66 @@ agent_card_readkey (const char *id, unsigned char **r_buf)
 
 
 
+\f
+static AssuanError
+pass_status_thru (void *opaque, const char *line)
+{
+  ASSUAN_CONTEXT ctx = opaque;
+  char keyword[200];
+  int i;
+
+  for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++)
+    keyword[i] = *line;
+  keyword[i] = 0;
+  /* truncate any remaining keyword stuff. */
+  for (; *line && !spacep (line); line++)
+    ;
+  while (spacep (line))
+    line++;
+
+  assuan_write_status (ctx, keyword, line);
+  return 0;
+}
+
+static AssuanError
+pass_data_thru (void *opaque, const void *buffer, size_t length)
+{
+  ASSUAN_CONTEXT ctx = opaque;
+
+  assuan_send_data (ctx, buffer, length);
+  return 0;
+}
+
+
+/* Send the line CMDLINE with command for the SCDdaemon to it and send
+   all status messages back.  This command is used as a general quoting
+   mechanism to pass everything verbatim to SCDAEMOPN.  The PIN
+   inquirey is handled inside gpg-agent. */
+int
+agent_card_scd (const char *cmdline,
+                int (*getpin_cb)(void *, const char *, char*, size_t),
+                void *getpin_cb_arg, void *assuan_context)
+{
+  int rc;
+  struct inq_needpin_s inqparm;
+
+  rc = start_scd ();
+  if (rc)
+    return rc;
+
+  inqparm.ctx = scd_ctx;
+  inqparm.getpin_cb = getpin_cb;
+  inqparm.getpin_cb_arg = getpin_cb_arg;
+  rc = assuan_transact (scd_ctx, cmdline,
+                        pass_data_thru, assuan_context,
+                        inq_needpin, &inqparm,
+                        pass_status_thru, assuan_context);
+  if (rc)
+    {
+      return unlock_scd (map_assuan_err (rc));
+    }
+
+  return unlock_scd (0);
+}
+
+
index 594b31f..ed4ea6b 100644 (file)
@@ -549,7 +549,7 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
   CTRL ctrl = assuan_get_pointer (ctx);
   int rc;
   unsigned char grip[20];
-  GCRY_SEXP s_skey = NULL;
+  gcry_sexp_t s_skey = NULL;
   unsigned char *shadow_info = NULL;
 
   rc = parse_keygrip (ctx, line, grip);
@@ -575,6 +575,22 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
   return map_to_assuan_status (rc);
 }
 
+\f
+/* SCD <commands to pass to the scdaemon>
+  
+   This is a general quote command to redirect everything to the
+   SCDAEMON. */
+static int
+cmd_scd (ASSUAN_CONTEXT ctx, char *line)
+{
+  CTRL ctrl = assuan_get_pointer (ctx);
+  int rc;
+
+  rc = divert_generic_cmd (ctrl, line, ctx);
+
+  return map_to_assuan_status (rc);
+}
+
 
 \f
 static int
@@ -661,6 +677,7 @@ register_commands (ASSUAN_CONTEXT ctx)
     { "PASSWD",         cmd_passwd },
     { "INPUT",          NULL }, 
     { "OUTPUT",         NULL }, 
+    { "SCD",            cmd_scd },
     { NULL }
   };
   int i, rc;
index 3a0c22e..69f1844 100644 (file)
@@ -1,5 +1,5 @@
 /* divert-scd.c - divert operations to the scdaemon 
- *     Copyright (C) 2002 Free Software Foundation, Inc.
+ *     Copyright (C) 2002, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -103,7 +103,7 @@ ask_for_card (CTRL ctrl, const unsigned char *shadow_info, char **r_kid)
         }
       else
         {
-          log_error ("error accesing card: %s\n", gnupg_strerror (rc));
+          log_error ("error accesing card: %s\n", gpg_strerror (rc));
         }
 
       if (!rc)
@@ -305,3 +305,15 @@ divert_pkdecrypt (CTRL ctrl,
   xfree (kid);
   return rc;
 }
+
+
+int  
+divert_generic_cmd (CTRL ctrl, const char *cmdline, void *assuan_context)
+{
+  return agent_card_scd (cmdline, getpin_cb, ctrl, assuan_context);
+}
+
+
+
+
+
index e6c4ad7..db36cb1 100644 (file)
@@ -1,5 +1,5 @@
 /* findkey.c - locate the secret key
- *     Copyright (C) 2001,02 Free Software Foundation, Inc.
+ *     Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -204,7 +204,7 @@ unprotect (CTRL ctrl,
    an allocated S-Expression with the shadow_info part from the file.
    With IGNORE_CACHE passed as true the passphrase is not taken from
    the cache.*/
-GCRY_SEXP
+gcry_sexp_t
 agent_key_from_file (CTRL ctrl,
                      const unsigned char *grip, unsigned char **shadow_info,
                      int ignore_cache)
@@ -215,7 +215,7 @@ agent_key_from_file (CTRL ctrl,
   struct stat st;
   unsigned char *buf;
   size_t len, buflen, erroff;
-  GCRY_SEXP s_skey;
+  gcry_sexp_t s_skey;
   char hexgrip[40+4+1];
   
   if (shadow_info)
@@ -260,7 +260,7 @@ agent_key_from_file (CTRL ctrl,
   if (rc)
     {
       log_error ("failed to build S-Exp (off=%u): %s\n",
-                 (unsigned int)erroff, gcry_strerror (rc));
+                 (unsigned int)erroff, gpg_strerror (rc));
       return NULL;
     }
   len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0);
@@ -283,7 +283,7 @@ agent_key_from_file (CTRL ctrl,
       rc = unprotect (ctrl, &buf, grip, ignore_cache);
       if (rc)
         log_error ("failed to unprotect the secret key: %s\n",
-                   gnupg_strerror (rc));
+                   gpg_strerror (rc));
       break;
     case PRIVATE_KEY_SHADOWED:
       if (shadow_info)
@@ -329,7 +329,7 @@ agent_key_from_file (CTRL ctrl,
   if (rc)
     {
       log_error ("failed to build S-Exp (off=%u): %s\n",
-                 (unsigned int)erroff, gcry_strerror (rc));
+                 (unsigned int)erroff, gpg_strerror (rc));
       return NULL;
     }
 
index 28d71a6..0a0577f 100644 (file)
@@ -1,5 +1,5 @@
 /* pksign.c - Generate a keypair
- *     Copyright (C) 2002 Free Software Foundation, Inc.
+ *     Copyright (C) 2002, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -30,7 +30,7 @@
 #include "i18n.h"
 
 static int
-store_key (GCRY_SEXP private, const char *passphrase, int force)
+store_key (gcry_sexp_t private, const char *passphrase, int force)
 {
   int rc;
   char *buf;
@@ -91,7 +91,7 @@ int
 agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
               FILE *outfp) 
 {
-  GCRY_SEXP s_keyparam, s_key, s_private, s_public;
+  gcry_sexp_t s_keyparam, s_key, s_private, s_public;
   struct pin_entry_info_s *pi, *pi2;
   int rc;
   size_t len;
@@ -100,7 +100,7 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
   rc = gcry_sexp_sscan (&s_keyparam, NULL, keyparam, keyparamlen);
   if (rc)
     {
-      log_error ("failed to convert keyparam: %s\n", gcry_strerror (rc));
+      log_error ("failed to convert keyparam: %s\n", gpg_strerror (rc));
       return gpg_error (GPG_ERR_INV_DATA);
     }
 
@@ -135,7 +135,7 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
   gcry_sexp_release (s_keyparam);
   if (rc)
     {
-      log_error ("key generation failed: %s\n", gcry_strerror (rc));
+      log_error ("key generation failed: %s\n", gpg_strerror (rc));
       xfree (pi);
       return map_gcry_err (rc);
     }
@@ -204,7 +204,7 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
 \f
 /* Apply a new passpahrse to the key S_SKEY and store it. */
 int
-agent_protect_and_store (CTRL ctrl, GCRY_SEXP s_skey) 
+agent_protect_and_store (CTRL ctrl, gcry_sexp_t s_skey) 
 {
   struct pin_entry_info_s *pi, *pi2;
   int rc;
index 780dfad..b8c69fb 100644 (file)
@@ -1,5 +1,5 @@
 /* gpg-agent.c  -  The GnuPG Agent
- *     Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ *     Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 # include <pth.h>
 #endif
 
-#include <gcrypt.h>
-
 #define JNLIB_NEED_LOG_LOGV
 #include "agent.h"
-#include "../assuan/assuan.h" /* malloc hooks */
+#include <assuan.h> /* malloc hooks */
 
 #include "i18n.h"
 #include "sysutils.h"
@@ -336,6 +334,18 @@ main (int argc, char **argv )
   log_set_prefix ("gpg-agent", 1|4); 
   i18n_init ();
 
+  /* We need to initialize Pth before libgcrypt, because the libgcrypt
+     initialization done by gcry_check_version internally sets up its
+     mutex system.  Note that one must not link against pth if
+     USE_GNU_PTH is not defined. */
+#ifdef USE_GNU_PTH
+  if (!pth_init ())
+    {
+      log_error ("failed to initialize the Pth library\n");
+      exit (1);
+    }
+#endif /*USE_GNU_PTH*/
+
   /* check that the libraries are suitable.  Do it here because
      the option parsing may need services of the library */
   if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
@@ -715,12 +725,6 @@ main (int argc, char **argv )
         {
          struct sigaction sa;
 
-          if (!pth_init ())
-            {
-              log_error ("failed to initialize the Pth library\n");
-              exit (1);
-            }
-
          sa.sa_handler = SIG_IGN;
          sigemptyset (&sa.sa_mask);
          sa.sa_flags = 0;
@@ -1030,7 +1034,7 @@ handle_connections (int listen_fd)
       fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev);
       if (fd == -1)
         {
-          if (pth_event_occurred (ev))
+          if (pth_event_status (ev) == PTH_STATUS_OCCURRED)
             {
               handle_signal (signo);
               continue;
index d5c1aae..28a74f9 100644 (file)
@@ -1,5 +1,5 @@
 /* learncard.c - Handle the LEARN command
- *     Copyright (C) 2002 Free Software Foundation, Inc.
+ *     Copyright (C) 2002, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -59,6 +59,20 @@ struct certinfo_cb_parm_s {
 };
 
 
+struct sinfo_s {
+  struct sinfo_s *next;
+  char *data;       /* Points into keyword. */
+  char keyword[1];  
+};
+typedef struct sinfo_s *SINFO;  
+
+struct sinfo_cb_parm_s {
+  int error;;
+  SINFO info;
+};
+
+
+
 static void
 release_keypair_info (KEYPAIR_INFO info)
 {
@@ -81,9 +95,20 @@ release_certinfo (CERTINFO info)
     }
 }
 
+static void
+release_sinfo (SINFO info)
+{
+  while (info)
+    {
+      SINFO tmp = info->next;
+      xfree (info);
+      info = tmp;
+    }
+}
+
 
 
-/* This callback is used by agent_card_leanr and passed the content of
+/* This callback is used by agent_card_learn and passed the content of
    all KEYPAIRINFO lines.  It merely stores this data away */
 static void
 kpinfo_cb (void *opaque, const char *line)
@@ -134,7 +159,7 @@ kpinfo_cb (void *opaque, const char *line)
 }
 
 
-/* This callback is used by agent_card_leanr and passed the content of
+/* This callback is used by agent_card_learn and passed the content of
    all CERTINFO lines.  It merely stores this data away */
 static void
 certinfo_cb (void *opaque, const char *line)
@@ -173,6 +198,35 @@ certinfo_cb (void *opaque, const char *line)
 }
 
 
+/* This callback is used by agent_card_learn and passed the content of
+   all SINFO lines.  It merely stores this data away */
+static void
+sinfo_cb (void *opaque, const char *keyword, size_t keywordlen,
+          const char *data)
+{
+  struct sinfo_cb_parm_s *sparm = opaque;
+  SINFO item;
+
+  if (sparm->error)
+    return; /* no need to gather data after an error coccured */
+
+  item = xtrycalloc (1, sizeof *item + keywordlen + 1 + strlen (data));
+  if (!item)
+    {
+      sparm->error = out_of_core ();
+      return;
+    }
+  memcpy (item->keyword, keyword, keywordlen);
+  item->data = item->keyword + keywordlen;
+  *item->data = 0;
+  item->data++;
+  strcpy (item->data, data);
+  /* store it */
+  item->next = sparm->info;
+  sparm->info = item;
+}
+
+
 /* Create an S-expression with the shadow info.  */
 static unsigned char *
 make_shadow_info (const char *serialno, const char *idstring)
@@ -211,7 +265,7 @@ send_cert_back (const char *id, void *assuan_context)
   if (rc)
     {
       log_error ("error reading certificate: %s\n",
-                 gnupg_strerror (rc));
+                 gpg_strerror (rc));
       return rc;
     }
 
@@ -238,8 +292,10 @@ agent_handle_learn (void *assuan_context)
   int rc;
   struct kpinfo_cb_parm_s parm;
   struct certinfo_cb_parm_s cparm;
+  struct sinfo_cb_parm_s sparm;
   char *serialno = NULL;
   KEYPAIR_INFO item;
+  SINFO sitem;
   unsigned char grip[20];
   char *p;
   int i;
@@ -253,24 +309,35 @@ agent_handle_learn (void *assuan_context)
 
   memset (&parm, 0, sizeof parm);
   memset (&cparm, 0, sizeof cparm);
+  memset (&sparm, 0, sizeof sparm);
 
   /* Check whether a card is present and get the serial number */
   rc = agent_card_serialno (&serialno);
   if (rc)
     goto leave;
 
-  /* now gather all the availabe info */
-  rc = agent_card_learn (kpinfo_cb, &parm, certinfo_cb, &cparm);
-  if (!rc && (parm.error || cparm.error))
-    rc = parm.error? parm.error : cparm.error;
+  /* now gather all the available info */
+  rc = agent_card_learn (kpinfo_cb, &parm, certinfo_cb, &cparm,
+                         sinfo_cb, &sparm);
+  if (!rc && (parm.error || cparm.error || sparm.error))
+    rc = parm.error? parm.error : cparm.error? cparm.error : sparm.error;
   if (rc)
     {
-      log_debug ("agent_card_learn failed: %s\n", gnupg_strerror (rc));
+      log_debug ("agent_card_learn failed: %s\n", gpg_strerror (rc));
       goto leave;
     }
   
   log_info ("card has S/N: %s\n", serialno);
 
+  /* Pass on all the collected status information. */
+  if (assuan_context)
+    {
+      for (sitem = sparm.info; sitem; sitem = sitem->next)
+        {
+          assuan_write_status (assuan_context, sitem->keyword, sitem->data);
+        }
+    }
+
   /* Write out the certificates in a standard order. */
   for (i=0; certtype_list[i] != -1; i++)
     {
@@ -315,7 +382,7 @@ agent_handle_learn (void *assuan_context)
       rc = agent_card_readkey (item->id, &pubkey);
       if (rc)
         {
-          log_debug ("agent_card_readkey failed: %s\n", gnupg_strerror (rc));
+          log_debug ("agent_card_readkey failed: %s\n", gpg_strerror (rc));
           goto leave;
         }
 
@@ -333,7 +400,7 @@ agent_handle_learn (void *assuan_context)
       xfree (pubkey);
       if (rc)
         {
-          log_error ("shadowing the key failed: %s\n", gnupg_strerror (rc));
+          log_error ("shadowing the key failed: %s\n", gpg_strerror (rc));
           goto leave;
         }
       n = gcry_sexp_canon_len (shdkey, 0, NULL, NULL);
@@ -343,7 +410,7 @@ agent_handle_learn (void *assuan_context)
       xfree (shdkey);
       if (rc)
         {
-          log_error ("error writing key: %s\n", gnupg_strerror (rc));
+          log_error ("error writing key: %s\n", gpg_strerror (rc));
           goto leave;
         }
 
@@ -374,6 +441,7 @@ agent_handle_learn (void *assuan_context)
   xfree (serialno);
   release_keypair_info (parm.info);
   release_certinfo (cparm.info);
+  release_sinfo (sparm.info);
   return rc;
 }
 
index d8d4733..d86bcf0 100644 (file)
@@ -1,5 +1,5 @@
-/* minip12.c - A minilam pkcs-12 implementation.
- *     Copyright (C) 2002 Free Software Foundation, Inc.
+/* minip12.c - A minimal pkcs-12 implementation.
+ *     Copyright (C) 2002, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -211,8 +211,8 @@ string_to_key (int id, char *salt, int iter, const char *pw,
                int req_keylen, unsigned char *keybuf)
 {
   int rc, i, j;
-  GcryMDHd md;
-  GcryMPI num_b1 = NULL;
+  gcry_md_hd_t md;
+  gcry_mpi_t num_b1 = NULL;
   int pwlen;
   unsigned char hash[20], buf_b[64], buf_i[128], *p;
   size_t cur_keylen;
@@ -240,11 +240,11 @@ string_to_key (int id, char *salt, int iter, const char *pw,
 
   for (;;)
     {
-      md = gcry_md_open (GCRY_MD_SHA1, 0);
-      if (!md)
+      rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
+      if (rc)
         {
-          log_error ( "gcry_md_open failed: %s\n", gcry_strerror (-1));
-          return -1;
+          log_error ( "gcry_md_open failed: %s\n", gpg_strerror (rc));
+          return rc;
         }
       for(i=0; i < 64; i++)
         gcry_md_putc (md, id);
@@ -269,20 +269,20 @@ string_to_key (int id, char *salt, int iter, const char *pw,
       rc = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, &n);
       if (rc)
         {
-          log_error ( "gcry_mpi_scan failed: %s\n", gcry_strerror (rc));
+          log_error ( "gcry_mpi_scan failed: %s\n", gpg_strerror (rc));
           return -1;
         }
       gcry_mpi_add_ui (num_b1, num_b1, 1);
       for (i=0; i < 128; i += 64)
         {
-          GcryMPI num_ij;
+          gcry_mpi_t num_ij;
 
           n = 64;
           rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, &n);
           if (rc)
             {
               log_error ( "gcry_mpi_scan failed: %s\n",
-                       gcry_strerror (rc));
+                       gpg_strerror (rc));
               return -1;
             }
           gcry_mpi_add (num_ij, num_ij, num_b1);
@@ -292,7 +292,7 @@ string_to_key (int id, char *salt, int iter, const char *pw,
           if (rc)
             {
               log_error ( "gcry_mpi_print failed: %s\n",
-                       gcry_strerror (rc));
+                       gpg_strerror (rc));
               return -1;
             }
           gcry_mpi_release (num_ij);
@@ -302,7 +302,7 @@ string_to_key (int id, char *salt, int iter, const char *pw,
 
 
 static int 
-set_key_iv (GcryCipherHd chd, char *salt, int iter, const char *pw)
+set_key_iv (gcry_cipher_hd_t chd, char *salt, int iter, const char *pw)
 {
   unsigned char keybuf[24];
   int rc;
@@ -312,7 +312,7 @@ set_key_iv (GcryCipherHd chd, char *salt, int iter, const char *pw)
   rc = gcry_cipher_setkey (chd, keybuf, 24);
   if (rc)
     {
-      log_error ( "gcry_cipher_setkey failed: %s\n", gcry_strerror (rc));
+      log_error ( "gcry_cipher_setkey failed: %s\n", gpg_strerror (rc));
       return -1;
     }
 
@@ -321,7 +321,7 @@ set_key_iv (GcryCipherHd chd, char *salt, int iter, const char *pw)
   rc = gcry_cipher_setiv (chd, keybuf, 8);
   if (rc)
     {
-      log_error ("gcry_cipher_setiv failed: %s\n", gcry_strerror (rc));
+      log_error ("gcry_cipher_setiv failed: %s\n", gpg_strerror (rc));
       return -1;
     }
   return 0;
@@ -332,13 +332,13 @@ static void
 crypt_block (unsigned char *buffer, size_t length, char *salt, int iter,
              const char *pw, int encrypt)
 {
-  GcryCipherHd chd;
+  gcry_cipher_hd_t chd;
   int rc;
 
-  chd = gcry_cipher_open (GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
-  if (!chd)
+  rc = gcry_cipher_open (&chd, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
+  if (rc)
     {
-      log_error ( "gcry_cipher_open failed: %s\n", gcry_strerror(-1));
+      log_error ( "gcry_cipher_open failed: %s\n", gpg_strerror(-1));
       return;
     }
   if (set_key_iv (chd, salt, iter, pw))
@@ -349,7 +349,7 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, int iter,
 
   if (rc)
     {
-      log_error ( "en/de-crytion failed: %s\n", gcry_strerror (rc));
+      log_error ( "en/de-crytion failed: %s\n", gpg_strerror (rc));
       goto leave;
     }
 
@@ -414,7 +414,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
   return -1;
 }
 
-static GcryMPI *
+static gcry_mpi_t *
 parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
                 const char *pw)
 {
@@ -427,7 +427,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
   unsigned int iter;
   int len;
   unsigned char *plain = NULL;
-  GcryMPI *result = NULL;
+  gcry_mpi_t *result = NULL;
   int result_count, i;
 
   where = "start";
@@ -593,7 +593,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
           if (rc)
             {
               log_error ("error parsing key parameter: %s\n",
-                         gcry_strerror (rc));
+                         gpg_strerror (rc));
               goto bailout;
             }
           result_count++;
@@ -625,7 +625,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
    that it is only able to look for 3DES encoded enctyptedData and
    tries to extract the first private key object it finds.  In case of
    an error NULL is returned. */
-GcryMPI *
+gcry_mpi_t *
 p12_parse (const unsigned char *buffer, size_t length, const char *pw)
 {
   struct tag_info ti;
@@ -859,7 +859,7 @@ create_final (struct buffer_s *sequences, size_t *r_length)
    PW. Create a PKCS structure from it and return it as well as the
    length in R_LENGTH; return NULL in case of an error. */
 unsigned char * 
-p12_build (GcryMPI *kparms, const char *pw, size_t *r_length)
+p12_build (gcry_mpi_t *kparms, const char *pw, size_t *r_length)
 {
   int rc, i;
   size_t needed, n;
@@ -877,7 +877,7 @@ p12_build (GcryMPI *kparms, const char *pw, size_t *r_length)
       rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, &n, kparms[i]);
       if (rc)
         {
-          log_error ("error formatting parameter: %s\n", gcry_strerror (rc));
+          log_error ("error formatting parameter: %s\n", gpg_strerror (rc));
           return NULL;
         }
       needed += n;
@@ -951,7 +951,7 @@ p12_build (GcryMPI *kparms, const char *pw, size_t *r_length)
       if (rc)
         {
           log_error ("oops: error formatting parameter: %s\n",
-                     gcry_strerror (rc));
+                     gpg_strerror (rc));
           gcry_free (plain);
           return NULL;
         }
@@ -962,7 +962,7 @@ p12_build (GcryMPI *kparms, const char *pw, size_t *r_length)
       if (rc)
         {
           log_error ("oops: error storing parameter: %s\n",
-                     gcry_strerror (rc));
+                     gpg_strerror (rc));
           gcry_free (plain);
           return NULL;
         }
@@ -1131,7 +1131,7 @@ main (int argc, char **argv)
                                 NULL, result[i]);
           if (rc)
             printf ("%d: [error printing number: %s]\n",
-                    i, gcry_strerror (rc));
+                    i, gpg_strerror (rc));
           else
             {
               printf ("%d: %s\n", i, buf);
index 8573a2d..1222155 100644 (file)
@@ -1,5 +1,5 @@
 /* minip12.h - Global definitions for the minimal pkcs-12 implementation.
- *     Copyright (C) 2002 Free Software Foundation, Inc.
+ *     Copyright (C) 2002, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 
 #include <gcrypt.h>
 
-GcryMPI *p12_parse (const unsigned char *buffer, size_t length,
-                    const char *pw);
+gcry_mpi_t *p12_parse (const unsigned char *buffer, size_t length,
+                       const char *pw);
 
-unsigned char *p12_build (GcryMPI *kparms, const char *pw, size_t *r_length);
+unsigned char *p12_build (gcry_mpi_t *kparms, const char *pw,
+                          size_t *r_length);
 
 
 #endif /*MINIP12_H*/
index baa8865..543a827 100644 (file)
@@ -1,5 +1,5 @@
 /* pkdecrypt.c - public key decryption (well, acually using a secret key)
- *     Copyright (C) 2001 Free Software Foundation, Inc.
+ *     Copyright (C) 2001, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -38,7 +38,7 @@ int
 agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
                  FILE *outfp) 
 {
-  GCRY_SEXP s_skey = NULL, s_cipher = NULL, s_plain = NULL;
+  gcry_sexp_t s_skey = NULL, s_cipher = NULL, s_plain = NULL;
   unsigned char *shadow_info = NULL;
   int rc;
   char *buf = NULL;
@@ -54,7 +54,7 @@ agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
   rc = gcry_sexp_sscan (&s_cipher, NULL, ciphertext, ciphertextlen);
   if (rc)
     {
-      log_error ("failed to convert ciphertext: %s\n", gcry_strerror (rc));
+      log_error ("failed to convert ciphertext: %s\n", gpg_strerror (rc));
       rc = gpg_error (GPG_ERR_INV_DATA);
       goto leave;
     }
@@ -84,7 +84,7 @@ agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
       rc = divert_pkdecrypt (ctrl, ciphertext, shadow_info, &buf, &len );
       if (rc)
         {
-          log_error ("smartcard decryption failed: %s\n", gnupg_strerror (rc));
+          log_error ("smartcard decryption failed: %s\n", gpg_strerror (rc));
           goto leave;
         }
       /* FIXME: don't use buffering and change the protocol to return
@@ -104,7 +104,7 @@ agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
       rc = gcry_pk_decrypt (&s_plain, s_cipher, s_skey);
       if (rc)
         {
-          log_error ("decryption failed: %s\n", gcry_strerror (rc));
+          log_error ("decryption failed: %s\n", gpg_strerror (rc));
           rc = map_gcry_err (rc);
           goto leave;
         }
index 25f1238..a5f89e3 100644 (file)
@@ -1,5 +1,5 @@
 /* pksign.c - public key signing (well, acually using a secret key)
- *     Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ *     Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -33,7 +33,7 @@
 
 static int
 do_encode_md (const unsigned char *digest, size_t digestlen, int algo,
-              unsigned int nbits, GCRY_MPI *r_val)
+              unsigned int nbits, gcry_mpi_t *r_val)
 {
   int nframe = (nbits+7) / 8;
   byte *frame;
@@ -88,8 +88,8 @@ do_encode_md (const unsigned char *digest, size_t digestlen, int algo,
 int
 agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache) 
 {
-  GCRY_SEXP s_skey = NULL, s_hash = NULL, s_sig = NULL;
-  GCRY_MPI frame = NULL;
+  gcry_sexp_t s_skey = NULL, s_hash = NULL, s_sig = NULL;
+  gcry_mpi_t frame = NULL;
   unsigned char *shadow_info = NULL;
   int rc;
   char *buf = NULL;
@@ -118,7 +118,7 @@ agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache)
                           shadow_info, &sigbuf);
       if (rc)
         {
-          log_error ("smartcard signing failed: %s\n", gnupg_strerror (rc));
+          log_error ("smartcard signing failed: %s\n", gpg_strerror (rc));
           goto leave;
         }
       len = gcry_sexp_canon_len (sigbuf, 0, NULL, NULL);
@@ -149,7 +149,7 @@ agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache)
       rc = gcry_pk_sign (&s_sig, s_hash, s_skey);
       if (rc)
         {
-          log_error ("signing failed: %s\n", gcry_strerror (rc));
+          log_error ("signing failed: %s\n", gpg_strerror (rc));
           rc = map_gcry_err (rc);
           goto leave;
         }
index 20e2887..b41730c 100644 (file)
@@ -1,5 +1,5 @@
 /* protect-tool.c - A tool to test the secret key protection
- *     Copyright (C) 2002 Free Software Foundation, Inc.
+ *     Copyright (C) 2002, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -30,8 +30,6 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
-#include <gcrypt.h>
-
 #define JNLIB_NEED_LOG_LOGV
 #include "agent.h"
 #include "minip12.h"
@@ -61,12 +59,12 @@ aTest };
 
 struct rsa_secret_key_s 
   {
-    MPI n;         /* public modulus */
-    MPI e;         /* public exponent */
-    MPI d;         /* exponent */
-    MPI p;         /* prime  p. */
-    MPI q;         /* prime  q. */
-    MPI u;         /* inverse of p mod q. */
+    gcry_mpi_t n;          /* public modulus */
+    gcry_mpi_t e;          /* public exponent */
+    gcry_mpi_t d;          /* exponent */
+    gcry_mpi_t p;          /* prime  p. */
+    gcry_mpi_t q;          /* prime  q. */
+    gcry_mpi_t u;          /* inverse of p mod q. */
   };
 
 
@@ -162,7 +160,7 @@ my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
 
 
 /*  static void */
-/*  print_mpi (const char *text, GcryMPI a) */
+/*  print_mpi (const char *text, gcry_mpi_t a) */
 /*  { */
 /*    char *buf; */
 /*    void *bufaddr = &buf; */
@@ -170,7 +168,7 @@ my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
 
 /*    rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); */
 /*    if (rc) */
-/*      log_info ("%s: [error printing number: %s]\n", text, gcry_strerror (rc)); */
+/*      log_info ("%s: [error printing number: %s]\n", text, gpg_strerror (rc)); */
 /*    else */
 /*      { */
 /*        log_info ("%s: %s\n", text, buf); */
@@ -185,14 +183,14 @@ make_canonical (const char *fname, const char *buf, size_t buflen)
 {
   int rc;
   size_t erroff, len;
-  GCRY_SEXP sexp;
+  gcry_sexp_t sexp;
   unsigned char *result;
 
   rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen);
   if (rc)
     {
       log_error ("invalid S-Expression in `%s' (off=%u): %s\n",
-                 fname, (unsigned int)erroff, gcry_strerror (rc));
+                 fname, (unsigned int)erroff, gpg_strerror (rc));
       return NULL;
     }
   len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0);
@@ -209,14 +207,14 @@ make_advanced (const unsigned char *buf, size_t buflen)
 {
   int rc;
   size_t erroff, len;
-  GCRY_SEXP sexp;
+  gcry_sexp_t sexp;
   unsigned char *result;
 
   rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen);
   if (rc)
     {
       log_error ("invalid canonical S-Expression (off=%u): %s\n",
-                 (unsigned int)erroff, gcry_strerror (rc));
+                 (unsigned int)erroff, gpg_strerror (rc));
       return NULL;
     }
   len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
@@ -453,7 +451,7 @@ static void
 show_keygrip (const char *fname)
 {
   unsigned char *key;
-  GcrySexp private;
+  gcry_sexp_t private;
   unsigned char grip[20];
   int i;
   
@@ -485,10 +483,10 @@ static int
 rsa_key_check (struct rsa_secret_key_s *skey)
 {
   int err = 0;
-  MPI t = gcry_mpi_snew (0);
-  MPI t1 = gcry_mpi_snew (0);
-  MPI t2 = gcry_mpi_snew (0);
-  MPI phi = gcry_mpi_snew (0);
+  gcry_mpi_t t = gcry_mpi_snew (0);
+  gcry_mpi_t t1 = gcry_mpi_snew (0);
+  gcry_mpi_t t2 = gcry_mpi_snew (0);
+  gcry_mpi_t phi = gcry_mpi_snew (0);
 
   /* check that n == p * q */
   gcry_mpi_mul (t, skey->p, skey->q);
@@ -501,7 +499,7 @@ rsa_key_check (struct rsa_secret_key_s *skey)
   /* check that p is less than q */
   if (gcry_mpi_cmp (skey->p, skey->q) > 0)
     {
-      GcryMPI tmp;
+      gcry_mpi_t tmp;
 
       log_info ("swapping secret primes\n");
       tmp = gcry_mpi_copy (skey->p);
@@ -573,9 +571,9 @@ import_p12_file (const char *fname)
   size_t buflen, resultlen;
   int i;
   int rc;
-  GcryMPI *kparms;
+  gcry_mpi_t *kparms;
   struct rsa_secret_key_s sk;
-  GcrySexp s_key;
+  gcry_sexp_t s_key;
   unsigned char *key;
   unsigned char grip[20];
 
@@ -635,7 +633,7 @@ import_p12_file (const char *fname)
   if (rc)
     {
       log_error ("failed to created S-expression from key: %s\n",
-                 gcry_strerror (rc));
+                 gpg_strerror (rc));
       return;
     }
 
@@ -687,16 +685,16 @@ import_p12_file (const char *fname)
 
 \f
 
-static GcryMPI *
-sexp_to_kparms (GCRY_SEXP sexp)
+static gcry_mpi_t *
+sexp_to_kparms (gcry_sexp_t sexp)
 {
-  GcrySexp list, l2;
+  gcry_sexp_t list, l2;
   const char *name;
   const char *s;
   size_t n;
   int i, idx;
   const char *elems;
-  GcryMPI *array;
+  gcry_mpi_t *array;
 
   list = gcry_sexp_find_token (sexp, "private-key", 0 );
   if(!list)
@@ -747,10 +745,10 @@ sexp_to_kparms (GCRY_SEXP sexp)
 static void
 export_p12_file (const char *fname)
 {
-  GcryMPI kparms[9], *kp;
+  gcry_mpi_t kparms[9], *kp;
   unsigned char *key;
   size_t keylen;
-  GcrySexp private;
+  gcry_sexp_t private;
   struct rsa_secret_key_s sk;
   int i;
   
index b686f36..e438d53 100644 (file)
@@ -1,5 +1,6 @@
 /* protect.c - Un/Protect a secret key
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ *               2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -135,19 +136,19 @@ do_encryption (const char *protbegin, size_t protlen,
                const char *passphrase,  const unsigned char *sha1hash,
                unsigned char **result, size_t *resultlen)
 {
-  GCRY_CIPHER_HD hd;
+  gcry_cipher_hd_t hd;
   const char *modestr = "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc";
   int blklen, enclen, outlen;
   char *iv = NULL;
-  int rc = 0;
+  int rc;
   char *outbuf = NULL;
   char *p;
   int saltpos, ivpos, encpos;
 
-  hd = gcry_cipher_open (PROT_CIPHER, GCRY_CIPHER_MODE_CBC,
+  rc = gcry_cipher_open (&hd, PROT_CIPHER, GCRY_CIPHER_MODE_CBC,
                          GCRY_CIPHER_SECURE);
-  if (!hd)
-    return map_gcry_err (gcry_errno());
+  if (rc)
+    return rc;
 
 
   /* We need to work on a copy of the data because this makes it
@@ -387,7 +388,7 @@ do_decryption (const unsigned char *protected, size_t protectedlen,
 {
   int rc = 0;
   int blklen;
-  GCRY_CIPHER_HD hd;
+  gcry_cipher_hd_t hd;
   unsigned char *outbuf;
   size_t reallen;
 
@@ -395,10 +396,10 @@ do_decryption (const unsigned char *protected, size_t protectedlen,
   if (protectedlen < 4 || (protectedlen%blklen))
     return gpg_error (GPG_ERR_CORRUPTED_PROTECTION);
 
-  hd = gcry_cipher_open (PROT_CIPHER, GCRY_CIPHER_MODE_CBC,
+  rc = gcry_cipher_open (&hd, PROT_CIPHER, GCRY_CIPHER_MODE_CBC,
                          GCRY_CIPHER_SECURE);
-  if (!hd)
-    return map_gcry_err (gcry_errno());
+  if (rc)
+    return rc;
 
   outbuf = gcry_malloc_secure (protectedlen);
   if (!outbuf)
@@ -750,7 +751,8 @@ hash_passphrase (const char *passphrase, int hashalgo,
                  unsigned long s2kcount,
                  unsigned char *key, size_t keylen)
 {
-  GCRY_MD_HD md;
+  int rc;
+  gcry_md_hd_t md;
   int pass, i;
   int used = 0;
   int pwlen = strlen (passphrase);
@@ -761,9 +763,9 @@ hash_passphrase (const char *passphrase, int hashalgo,
   if ((s2kmode == 1 ||s2kmode == 3) && !s2ksalt)
     return gpg_error (GPG_ERR_INV_VALUE);
   
-  md = gcry_md_open (hashalgo, GCRY_MD_FLAG_SECURE);
-  if (!md)
-    return map_gcry_err (gcry_errno());
+  rc = gcry_md_open (&md, hashalgo, GCRY_MD_FLAG_SECURE);
+  if (rc)
+    return rc;
 
   for (pass=0; used < keylen; pass++)
     {
index ff9762b..5990d51 100644 (file)
@@ -1,3 +1,7 @@
+2003-06-25  Werner Koch  <wk@gnupg.org>
+
+       * maperror.c (map_to_assuan_status): Directly map 0 to 0.
+
 2003-06-17  Werner Koch  <wk@gnupg.org>
 
        * gettime.c (scan_isodatestr,add_days_to_timestamp,strtimevalue)
index c6a1135..13657be 100644 (file)
@@ -129,6 +129,8 @@ map_to_assuan_status (int rc)
   gpg_err_code_t   ec = gpg_err_code (rc);
   gpg_err_source_t es = gpg_err_source (rc);
 
+  if (!rc)
+    return 0;
   if (!es)
     {
       es = GPG_ERR_SOURCE_USER_4; /*  This should not happen, but we
@@ -149,3 +151,7 @@ map_to_assuan_status (int rc)
 
 
 
+
+
+
+
index b733b81..abca4fa 100644 (file)
 #include <ctype.h>
 #include <unistd.h>
 
-#include <gcrypt.h>
-
 #include "../jnlib/logging.h"
 #include "../jnlib/argparse.h"
 #include "../jnlib/stringhelp.h"
 #include "../common/i18n.h"
 #include "keybox-defs.h"
 
+#include <gcrypt.h>
+
+
 enum cmd_and_opt_values {
   aNull = 0,
   oArmor         = 'a',
index 709d5f5..5ad1d26 100644 (file)
@@ -110,6 +110,8 @@ X.509 specific are noted like [X.509: xxx]
 #include <string.h>
 #include <errno.h>
 #include <assert.h>
+
+#include "keybox-defs.h"
 #include <gcrypt.h>
 
 #ifdef KEYBOX_WITH_OPENPGP
@@ -119,7 +121,6 @@ X.509 specific are noted like [X.509: xxx]
 #include <ksba.h>
 #endif
 
-#include "keybox-defs.h"
 
 
 /* special values of the signature status */
index 6a8668b..a6407b9 100644 (file)
@@ -1,3 +1,34 @@
+2003-06-26  Werner Koch  <wk@gnupg.org>
+
+       * app-openpgp.c (find_tlv): Fixed length header parsing.
+
+       * app.c (app_genkey): New.
+       * command.c (cmd_genkey): New.
+
+2003-06-25  Werner Koch  <wk@gnupg.org>
+
+       * command.c (percent_plus_unescape): New.
+       (cmd_setattr): New.
+
+2003-06-24  Werner Koch  <wk@gnupg.org>
+
+       * command.c (send_status_info): New.
+
+       * app-openpgp.c (app_select_openpgp): Replace SLOT arg by APP arg
+       and setup the function pointers in APP on success. Changed callers.
+       * app.c: New.
+       * app-common.h: New.
+       * scdaemon.h (APP): New type to handle applications.
+       (server_control_s): Add an APP context field.
+
+       * command.c (cmd_serialno): Handle applications.
+       (cmd_pksign): Ditto.
+       (cmd_pkdecrypt): Ditto.
+       (reset_notify): Ditto.
+       (cmd_learn): For now return error for application contexts.
+       (cmd_readcert): Ditto.
+       (cmd_readkey): Ditto.
+
 2003-06-04  Werner Koch  <wk@gnupg.org>
 
        * card.c (map_sc_err): Renamed gpg_make_err to gpg_err_make.
index 55d195f..833a4cd 100644 (file)
@@ -33,6 +33,7 @@ scdaemon_SOURCES = \
        card-p15.c card-dinsig.c \
        apdu.c apdu.h \
        iso7816.c iso7816.h \
+       app.c app-common.h \
        app-openpgp.c
 
 scdaemon_LDADD = ../jnlib/libjnlib.a ../common/libcommon.a \
diff --git a/scd/app-common.h b/scd/app-common.h
new file mode 100644 (file)
index 0000000..16ee7d7
--- /dev/null
@@ -0,0 +1,90 @@
+/* app-common.h - Common declarations for all card applications
+ *     Copyright (C) 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef GNUPG_SCD_APP_COMMON_H
+#define GNUPG_SCD_APP_COMMON_H
+
+struct app_ctx_s {
+  int initialized;  /* The application has been initialied and the
+                       function pointers may be used.  Note that for
+                       unsupported operations the particular
+                       function pointer is set to NULL */
+  int slot;         /* Used reader. */
+  unsigned char *serialno; /* Serialnumber in raw form, allocated. */
+  size_t serialnolen;      /* Length in octets of serialnumber. */
+  int did_chv1;
+  int did_chv2;
+  int did_chv3;
+  struct {
+    int (*learn_status) (APP app, CTRL ctrl);
+    int (*setattr) (APP app, const char *name,
+                    int (*pincb)(void*, const char *, char **),
+                    void *pincb_arg,
+                    const unsigned char *value, size_t valuelen);
+    int (*sign) (APP app,
+                 const char *keyidstr, int hashalgo,
+                 int (pincb)(void*, const char *, char **),
+                 void *pincb_arg,
+                 const void *indata, size_t indatalen,
+                 void **outdata, size_t *outdatalen );
+    int (*decipher) (APP app, const char *keyidstr,
+                     int (pincb)(void*, const char *, char **),
+                     void *pincb_arg,
+                     const void *indata, size_t indatalen,
+                     void **outdata, size_t *outdatalen);
+    int (*genkey) (APP app, CTRL ctrl,
+                   const char *keynostr, unsigned int flags,
+                   int (*pincb)(void*, const char *, char **),
+                   void *pincb_arg);
+  } fnc;
+
+
+};
+
+/*-- app.c --*/
+APP select_application (void);
+int app_get_serial_and_stamp (APP app, char **serial, time_t *stamp);
+int app_write_learn_status (APP app, CTRL ctrl);
+int app_setattr (APP app, const char *name,
+                 int (*pincb)(void*, const char *, char **),
+                 void *pincb_arg,
+                 const unsigned char *value, size_t valuelen);
+int app_sign (APP app, const char *keyidstr, int hashalgo,
+              int (pincb)(void*, const char *, char **),
+              void *pincb_arg,
+              const void *indata, size_t indatalen,
+              void **outdata, size_t *outdatalen );
+int app_decipher (APP app, const char *keyidstr,
+                  int (pincb)(void*, const char *, char **),
+                  void *pincb_arg,
+                  const void *indata, size_t indatalen,
+                  void **outdata, size_t *outdatalen );
+int app_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
+                int (*pincb)(void*, const char *, char **),
+                void *pincb_arg);
+
+/*-- app-openpgp.c --*/
+int app_select_openpgp (APP app, unsigned char **sn, size_t *snlen);
+
+
+#endif /*GNUPG_SCD_APP_COMMON_H*/
+
+
+
index 82f0043..47bebed 100644 (file)
 #include <dlfcn.h>
 
 #include "scdaemon.h"
+#include "app-common.h"
 #include "iso7816.h"
 
+
+
 static struct {
   int tag;
   int constructed;
@@ -80,6 +83,12 @@ find_tlv (const unsigned char *buffer, size_t length,
       buffer = s;
       if (n < 2)
         return NULL; /* buffer definitely too short for tag and length. */
+      if (!*s || *s == 0xff)
+        { /* Skip optional filler between TLV objects. */
+          s++;
+          n--;
+          continue;
+        }
       composite = !!(*s & 0x20);
       if ((*s & 0x1f) == 0x1f)
         { /* more tag bytes to follow */
@@ -95,13 +104,26 @@ find_tlv (const unsigned char *buffer, size_t length,
         this_tag = s[0];
       len = s[1];
       s += 2; n -= 2;
-      if (len == 255)
-        {
+      if (len < 0x80)
+        ;
+      else if (len == 0x81)
+        { /* One byte length follows. */
+          if (!n)
+            return NULL; /* we expected 1 more bytes with the length. */
+          len = s[0];
+          s++; n--;
+        }
+      else if (len == 0x82)
+        { /* Two byte length follows. */
           if (n < 2)
             return NULL; /* we expected 2 more bytes with the length. */
           len = (s[0] << 8) | s[1];
           s += 2; n -= 2;
         }
+      else
+        return NULL; /* APDU limit is 65535, thus it does not make
+                        sense to assume longer length fields. */
+
       if (composite && nestlevel < 100)
         { /* Dive into this composite DO after checking for too deep
              nesting. */
@@ -128,7 +150,64 @@ find_tlv (const unsigned char *buffer, size_t length,
 }
 
 
+/* Get the DO identified by TAG from the card in SLOT and return a
+   buffer with its content in RESULT and NBYTES.  The return value is
+   NULL if not found or a pointer which must be used to release the
+   buffer holding value. */
+static void *
+get_one_do (int slot, int tag, unsigned char **result, size_t *nbytes)
+{
+  int rc, i;
+  unsigned char *buffer;
+  size_t buflen;
+  unsigned char *value;
+  size_t valuelen;
+
+  *result = NULL;
+  *nbytes = 0;
+  for (i=0; data_objects[i].tag && data_objects[i].tag != tag; i++)
+    ;
+
+  value = NULL;
+  rc = -1;
+  if (data_objects[i].tag && data_objects[i].get_from)
+    {
+      rc = iso7816_get_data (slot, data_objects[i].get_from,
+                             &buffer, &buflen);
+      if (!rc)
+        {
+          value = find_tlv (buffer, buflen, tag, &valuelen, 0);
+          if (!value)
+            ; /* not found */
+          else if (valuelen > buflen - (value - buffer))
+            {
+              log_error ("warning: constructed DO too short\n");
+              value = NULL;
+              xfree (buffer); buffer = NULL;
+            }
+        }
+    }
+
+  if (!value) /* Not in a constructed DO, try simple. */
+    {
+      rc = iso7816_get_data (slot, tag, &buffer, &buflen);
+      if (!rc)
+        {
+          value = buffer;
+          valuelen = buflen;
+        }
+    }
+
+  if (!rc)
+    {
+      *nbytes = valuelen;
+      *result = value;
+      return buffer;
+    }
+  return NULL;
+}
 
+#if 0 /* not used */
 static void
 dump_one_do (int slot, int tag)
 {
@@ -191,6 +270,7 @@ dump_one_do (int slot, int tag)
       xfree (buffer);
     }
 }
+#endif /*not used*/
 
 
 static void
@@ -257,15 +337,15 @@ dump_all_do (int slot)
     }
 }
 
-
+/* Note, that FPR must be at least 20 bytes. */
 static int 
 store_fpr (int slot, int keynumber, u32 timestamp,
            const unsigned char *m, size_t mlen,
-           const unsigned char *e, size_t elen)
+           const unsigned char *e, size_t elen, 
+           unsigned char *fpr)
 {
   unsigned int n;
   unsigned char *buffer, *p;
-  unsigned char fpr[20];
   int rc;
   
   n = 6 + 2 + mlen + 2 + elen;
@@ -299,45 +379,189 @@ store_fpr (int slot, int keynumber, u32 timestamp,
   return rc;
 }
 
+       
+static void
+send_fpr_if_not_null (CTRL ctrl, const char *keyword,
+                      int number, const unsigned char *fpr)
+{                      
+  int i;
+  char buf[41];
+  char numbuf[25];
+
+  for (i=0; i < 20 && !fpr[i]; i++)
+    ;
+  if (i==20)
+    return; /* All zero. */
+  for (i=0; i< 20; i++)
+    sprintf (buf+2*i, "%02X", fpr[i]);
+  if (number == -1)
+    *numbuf = 0; /* Don't print the key number */
+  else
+    sprintf (numbuf, "%d", number);
+  send_status_info (ctrl, keyword,
+                    numbuf, (size_t)strlen(numbuf),
+                    buf, (size_t)strlen (buf), NULL, 0);
+}
+
+static void
+send_key_data (CTRL ctrl, const char *name, 
+               const unsigned char *a, size_t alen)
+{
+  char *p, *buf = xmalloc (alen*2+1);
+  
+  for (p=buf; alen; a++, alen--, p += 2)
+    sprintf (p, "%02X", *a);
+
+  send_status_info (ctrl, "KEY-DATA",
+                    name, (size_t)strlen(name), 
+                    buf, (size_t)strlen (buf),
+                    NULL, 0);
+  xfree (buf);
+}
 
 
-/* Generate a new key on the card and store the fingerprint in the
-   corresponding DO.  A KEYNUMBER of 0 creates the digital signature
-   key, 1 the encryption key and 2 the authentication key.  If the key
-   already exists an error is returned unless FORCE has been set to
-   true.  Note, that the function does not return the public key; this
-   has to be done using openpgp_readkey(). */
-int
-openpgp_genkey (int slot, int keynumber, int force)
+
+static int
+do_learn_status (APP app, CTRL ctrl)
+{
+  void *relptr;
+  unsigned char *value;
+  size_t valuelen;
+  int i;
+
+  relptr = get_one_do (app->slot, 0x005B, &value, &valuelen);
+  if (relptr)
+    {
+      send_status_info (ctrl, "DISP-NAME", value, valuelen, NULL, 0);
+      xfree (relptr);
+    }
+  relptr = get_one_do (app->slot, 0x5FF0, &value, &valuelen);
+  if (relptr)
+    {
+      send_status_info (ctrl, "PUBKEY-URL", value, valuelen, NULL, 0);
+      xfree (relptr);
+    }
+
+  relptr = get_one_do (app->slot, 0x00C5, &value, &valuelen);
+  if (relptr && valuelen >= 60)
+    {
+      for (i=0; i < 3; i++)
+        send_fpr_if_not_null (ctrl, "KEY-FPR", i+1, value+i*20);
+    }
+  xfree (relptr);
+  relptr = get_one_do (app->slot, 0x00C6, &value, &valuelen);
+  if (relptr && valuelen >= 60)
+    {
+      for (i=0; i < 3; i++)
+        send_fpr_if_not_null (ctrl, "CA-FPR", i+1, value+i*20);
+    }
+  xfree (relptr);
+  return 0;
+}
+
+
+/* Handle the SETATTR operation. All arguments are already basically
+   checked. */
+static int 
+do_setattr (APP app, const char *name,
+            int (*pincb)(void*, const char *, char **),
+            void *pincb_arg,
+            const unsigned char *value, size_t valuelen)
+{
+  gpg_error_t rc;
+
+  log_debug ("app_openpgp#setattr `%s' value of length %u\n",
+             name, (unsigned int)valuelen); /* fixme: name should be
+                                               sanitized. */
+
+  if (!app->did_chv3)
+    {
+      char *pinvalue;
+
+/*        rc = pincb (pincb_arg, "Please enter the card's admin PIN (CHV3)", */
+/*                    &pinvalue); */
+      pinvalue = xstrdup ("12345678");
+      rc = 0;
+      if (rc)
+        {
+          log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
+          return rc;
+        }
+
+      rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue));
+      xfree (pinvalue);
+      if (rc)
+        {
+          log_error ("verify CHV3 failed\n");
+          rc = gpg_error (GPG_ERR_GENERAL);
+          return rc;
+        }
+      app->did_chv3 = 1;
+    }
+
+  log_debug ("setting `%s' to `%.*s'\n", name, (int)valuelen, value);
+  if (!strcmp (name, "DISP-NAME"))
+    {
+      rc = iso7816_put_data (app->slot, 0x005B, value, valuelen);
+      if (rc)
+        {
+          /* FIXME: If this fails we should *once* try again after
+          doing a verify command, so that in case of a problem with
+          tracking the verify operation we have a fallback. */
+          /* FIXME: change this when iso7816 returns correct error
+          codes. */
+          log_error ("failed to set `Name'\n");
+          rc = gpg_error (GPG_ERR_GENERAL);
+        }
+    }
+  else
+    rc = gpg_error (GPG_ERR_INV_NAME); 
+
+  return rc;
+}
+
+
+/* Handle the GENKEY command. */
+static int 
+do_genkey (APP app, CTRL ctrl,  const char *keynostr, unsigned int flags,
+          int (*pincb)(void*, const char *, char **),
+          void *pincb_arg)
 {
   int rc;
   int i;
+  char numbuf[30];
+  unsigned char fprbuf[20];
   const unsigned char *fpr;
   const unsigned char *keydata, *m, *e;
   unsigned char *buffer;
   size_t buflen, keydatalen, n, mlen, elen;
   time_t created_at;
-  
-  if (keynumber < 0 || keynumber > 2)
-    return -1; /* invalid value */
+  int keyno = atoi (keynostr);
+  int force = (flags & 1);
 
-  rc = iso7816_get_data (slot, 0x006E, &buffer, &buflen);
+  if (keyno < 1 || keyno > 3)
+    return gpg_error (GPG_ERR_INV_ID);
+  keyno--;
+
+  rc = iso7816_get_data (app->slot, 0x006E, &buffer, &buflen);
   if (rc)
     {
       log_error ("error reading application data\n");
-      return -1;
+      return gpg_error (GPG_ERR_GENERAL);
     }
   fpr = find_tlv (buffer, buflen, 0x00C5, &n, 0);
   if (!fpr || n != 60)
     {
+      rc = gpg_error (GPG_ERR_GENERAL);
       log_error ("error reading fingerprint DO\n");
       goto leave;
     }
-  fpr += 20*keynumber;
+  fpr += 20*keyno;
   for (i=0; i < 20 && !fpr[i]; i++)
     ;
   if (i!=20 && !force)
     {
+      rc = gpg_error (GPG_ERR_EEXIST);
       log_error ("key already exists\n");
       goto leave;
     }
@@ -346,8 +570,7 @@ openpgp_genkey (int slot, int keynumber, int force)
   else
     log_info ("generating new key\n");
 
-
-  rc = iso7816_verify (slot, 0x83, "12345678", 8);
+  rc = iso7816_verify (app->slot, 0x83, "12345678", 8);
   if (rc)
     {
       log_error ("verify CHV3 failed: rc=%04X\n", rc);
@@ -355,13 +578,14 @@ openpgp_genkey (int slot, int keynumber, int force)
     }
 
   xfree (buffer); buffer = NULL;
-  rc = iso7816_generate_keypair (slot, 
-                                 keynumber == 0? "\xB6" :
-                                 keynumber == 1? "\xB8" : "\xA4",
+  rc = iso7816_generate_keypair (app->slot, 
+                                 keyno == 0? "\xB6" :
+                                 keyno == 1? "\xB8" : "\xA4",
                                  2,
                                  &buffer, &buflen);
   if (rc)
     {
+      rc = gpg_error (GPG_ERR_CARD);
       log_error ("generating key failed\n");
       goto leave;
     }
@@ -372,7 +596,6 @@ openpgp_genkey (int slot, int keynumber, int force)
       goto leave;
     }
  
-
   m = find_tlv (keydata, keydatalen, 0x0081, &mlen, 0);
   if (!m)
     {
@@ -380,6 +603,8 @@ openpgp_genkey (int slot, int keynumber, int force)
       goto leave;
     }
   log_printhex ("RSA n:", m, mlen);
+  send_key_data (ctrl, "n", m, mlen);
+
   e = find_tlv (keydata, keydatalen, 0x0082, &elen, 0);
   if (!e)
     {
@@ -387,8 +612,18 @@ openpgp_genkey (int slot, int keynumber, int force)
       goto leave;
     }
   log_printhex ("RSA e:", e, elen);
+  send_key_data (ctrl, "e", e, elen);
+
   created_at = gnupg_get_time ();
-  rc = store_fpr (slot, keynumber, (u32)created_at, m, mlen, e, elen);
+  sprintf (numbuf, "%lu", (unsigned long)created_at);
+  send_status_info (ctrl, "KEY-CREATED-AT",
+                    numbuf, (size_t)strlen(numbuf), NULL, 0);
+
+  rc = store_fpr (app->slot, keyno, (u32)created_at,
+                  m, mlen, e, elen, fprbuf);
+  if (rc)
+    goto leave;
+  send_fpr_if_not_null (ctrl, "KEY-FPR", -1, fprbuf);
 
 
  leave:
@@ -397,12 +632,75 @@ openpgp_genkey (int slot, int keynumber, int force)
 }
 
 
+/* Comopute a digital signature on INDATA which is expected to be the
+   raw message digest. */
+static int 
+do_sign (APP app, const char *keyidstr, int hashalgo,
+         int (*pincb)(void*, const char *, char **),
+         void *pincb_arg,
+         const void *indata, size_t indatalen,
+         void **outdata, size_t *outdatalen )
+{
+  static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */
+  { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
+    0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
+  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 };
+  int rc;
+  unsigned char data[35];
+
+  /* We ignore KEYIDSTR, because the OpenPGP application has only one
+     signing key and no way to specify a different one. */
+  
+  if (indatalen != 20)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  if (hashalgo == GCRY_MD_SHA1)
+    memcpy (data, sha1_prefix, 15);
+  else if (hashalgo == GCRY_MD_RMD160)
+    memcpy (data, rmd160_prefix, 15);
+  else 
+    return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
+  memcpy (data+15, indata, indatalen);
+
+
+  if (!app->did_chv1)
+    {
+      char *pinvalue;
+
+/*        rc = pincb (pincb_arg, "signature PIN", &pinvalue); */
+      pinvalue = xstrdup ("123456");
+      rc = 0;
+      if (rc)
+        {
+          log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
+          return rc;
+        }
+
+      rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
+      xfree (pinvalue);
+      if (rc)
+        {
+          log_error ("verify CHV1 failed\n");
+          rc = gpg_error (GPG_ERR_GENERAL);
+          return rc;
+        }
+      app->did_chv1 = 1;
+    }
+
+  rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen);
+
+  return rc;
+}
+
+
 /* Select the OpenPGP application on the card in SLOT.  This function
-   must be used to before any other OpenPGP application functions. */
+   must be used before any other OpenPGP application functions. */
 int
-app_select_openpgp (int slot)
+app_select_openpgp (APP app, unsigned char **sn, size_t *snlen)
 {
   static char const aid[] = { 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01 };
+  int slot = app->slot;
   int rc;
   unsigned char *buffer;
   size_t buflen;
@@ -416,27 +714,31 @@ app_select_openpgp (int slot)
       if (rc)
         goto leave;
       if (opt.verbose)
-      log_info ("got AID: ");
-      log_printhex ("", buffer, buflen);
-      xfree (buffer);
+        {
+          log_info ("got AID: ");
+          log_printhex ("", buffer, buflen);
+        }
+
+      if (sn)
+        {
+          *sn = buffer;
+          *snlen = buflen;
+        }
+      else
+        xfree (buffer);
 
       dump_all_do (slot);
 
-/*        rc = iso7816_verify (slot, 0x83, "12345678", 8); */
-/*        if (rc) */
-/*          log_error ("verify CHV3 failed: rc=%04X\n", rc); */
-      
-
-/*        rc = iso7816_put_data (slot, 0x005B, "Joe Hacker", 10); */
-/*        if (rc) */
-/*          log_error ("failed to set `Name': rc=%04X\n", rc); */
-/*        else */
-/*          dump_one_do (slot, 0x005B); */
-      
-      /* fixme: associate the internal state with the slot */
-    }
+      app->fnc.learn_status = do_learn_status;
+      app->fnc.setattr = do_setattr;
+      app->fnc.genkey = do_genkey;
+      app->fnc.sign = do_sign;
+   }
 
 leave:
   return rc;
 }
 
+
+
+
diff --git a/scd/app.c b/scd/app.c
new file mode 100644 (file)
index 0000000..3688b1c
--- /dev/null
+++ b/scd/app.c
@@ -0,0 +1,208 @@
+/* app.c - Application selection.
+ *     Copyright (C) 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "scdaemon.h"
+#include "app-common.h"
+#include "apdu.h"
+
+/* The select the best fitting application and return a context.
+   Returns NULL if no application was found or no card is present. */
+APP
+select_application (void)
+{
+  int reader_port = 32768; /* First USB reader. */
+  int slot;
+  int rc;
+  APP app;
+
+  slot = apdu_open_reader (reader_port);
+  if (slot == -1)
+    {
+      log_error ("card reader not available\n");
+      return NULL;
+    }
+
+  app = xtrycalloc (1, sizeof *app);
+  if (!app)
+    {
+      rc = out_of_core ();
+      log_info ("error allocating context: %s\n", gpg_strerror (rc));
+      /*apdu_close_reader (slot);*/
+      return NULL;
+    }
+
+  app->slot = slot;
+  rc = app_select_openpgp (app, &app->serialno, &app->serialnolen);
+  if (rc)
+    {
+/*        apdu_close_reader (slot); */
+      log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
+      xfree (app);
+      return NULL;
+    }
+
+  app->initialized = 1;
+  return app;
+}
+
+
+
+/* Retrieve the serial number and the time of the last update of the
+   card.  The serial number is returned as a malloced string (hex
+   encoded) in SERIAL and the time of update is returned in STAMP.  If
+   no update time is available the returned value is 0.  Caller must
+   free SERIAL unless the function returns an error. */
+int 
+app_get_serial_and_stamp (APP app, char **serial, time_t *stamp)
+{
+  unsigned char *buf, *p;
+  int i;
+
+  if (!app || !serial || !stamp)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  *serial = NULL;
+  *stamp = 0; /* not available */
+
+  buf = xtrymalloc (app->serialnolen * 2 + 1);
+  if (!buf)
+    return gpg_error_from_errno (errno);
+  for (p=buf, i=0; i < app->serialnolen; p +=2, i++)
+    sprintf (p, "%02X", app->serialno[i]);
+  *p = 0;
+  *serial = buf;
+  return 0;
+}
+
+
+/* Write out the application specifig status lines for the LEARN
+   command. */
+int
+app_write_learn_status (APP app, CTRL ctrl)
+{
+  if (!app)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  if (!app->initialized)
+    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+  if (!app->fnc.learn_status)
+    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+  return app->fnc.learn_status (app, ctrl);
+}
+
+
+/* Perform a SETATTR operation.  */
+int 
+app_setattr (APP app, const char *name,
+             int (*pincb)(void*, const char *, char **),
+             void *pincb_arg,
+             const unsigned char *value, size_t valuelen)
+{
+  if (!app || !name || !*name || !value)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  if (!app->initialized)
+    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+  if (!app->fnc.setattr)
+    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+  return app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen);
+}
+
+/* Create the signature and return the allocated result in OUTDATA.
+   If a PIN is required the PINCB will be used to ask for the PIN; it
+   should return the PIN in an allocated buffer and put it into PIN.  */
+int 
+app_sign (APP app, const char *keyidstr, int hashalgo,
+          int (pincb)(void*, const char *, char **),
+          void *pincb_arg,
+          const void *indata, size_t indatalen,
+          void **outdata, size_t *outdatalen )
+{
+  int rc;
+
+  if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  if (!app->initialized)
+    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+  if (!app->fnc.sign)
+    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+  rc = app->fnc.sign (app, keyidstr, hashalgo,
+                      pincb, pincb_arg,
+                      indata, indatalen,
+                      outdata, outdatalen);
+  if (opt.verbose)
+    log_info ("operation sign result: %s\n", gpg_strerror (rc));
+  return rc;
+}
+
+
+/* Decrypt the data in INDATA and return the allocated result in OUTDATA.
+   If a PIN is required the PINCB will be used to ask for the PIN; it
+   should return the PIN in an allocated buffer and put it into PIN.  */
+int 
+app_decipher (APP app, const char *keyidstr,
+              int (pincb)(void*, const char *, char **),
+              void *pincb_arg,
+              const void *indata, size_t indatalen,
+              void **outdata, size_t *outdatalen )
+{
+  int rc;
+
+  if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  if (!app->initialized)
+    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+  if (!app->fnc.decipher)
+    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+  rc = app->fnc.decipher (app, keyidstr,
+                          pincb, pincb_arg,
+                          indata, indatalen,
+                          outdata, outdatalen);
+  if (opt.verbose)
+    log_info ("operation decipher result: %s\n", gpg_strerror (rc));
+  return rc;
+}
+
+
+/* Perform a SETATTR operation.  */
+int 
+app_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
+            int (*pincb)(void*, const char *, char **),
+            void *pincb_arg)
+{
+  int rc;
+
+  if (!app || !keynostr || !*keynostr || !pincb)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  if (!app->initialized)
+    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
+  if (!app->fnc.genkey)
+    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+  rc = app->fnc.genkey (app, ctrl, keynostr, flags, pincb, pincb_arg);
+  if (opt.verbose)
+    log_info ("operation genkey result: %s\n", gpg_strerror (rc));
+  return rc;
+}
+
index 574867a..e46bb9d 100644 (file)
@@ -59,7 +59,7 @@ map_sc_err (int rc)
 int
 card_help_get_keygrip (KsbaCert cert, unsigned char *array)
 {
-  GCRY_SEXP s_pkey;
+  gcry_sexp_t s_pkey;
   int rc;
   KsbaSexp p;
   size_t n;
@@ -558,3 +558,4 @@ card_decipher (CARD card, const char *keyidstr,
     log_info ("card operation decipher result: %s\n", gpg_strerror (rc));
   return rc;
 }
+
index 8267c13..9f164f2 100644 (file)
@@ -30,6 +30,7 @@
 #include <assuan.h>
 
 #include "scdaemon.h"
+#include "app-common.h"
 
 /* maximum length aloowed as a PIN; used for INQUIRE NEEDPIN */
 #define MAXLEN_PIN 100
@@ -69,6 +70,12 @@ reset_notify (ASSUAN_CONTEXT ctx)
       xfree (ctrl->in_data.value);
       ctrl->in_data.value = NULL;
     }
+  if (ctrl->app_ctx)
+    {
+      /* FIXME: close the application. */
+      xfree (ctrl->app_ctx);
+      ctrl->app_ctx = NULL;
+    }
 }
 
 
@@ -85,8 +92,14 @@ option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value)
 static AssuanError
 open_card (CTRL ctrl)
 {
-  if (!ctrl->card_ctx)
-    {
+  if (ctrl->app_ctx)
+    return 0; /* Already initialized for one specific application. */
+  if (ctrl->card_ctx)
+    return 0; /* Already initialized using a card context. */
+
+  ctrl->app_ctx = select_application ();
+  if (!ctrl->app_ctx)
+    { /* No application found - fall back to old mode. */
       int rc = card_open (&ctrl->card_ctx);
       if (rc)
         return map_to_assuan_status (rc);
@@ -95,6 +108,41 @@ open_card (CTRL ctrl)
 }
 
 
+/* Do the percent and plus/space unescaping in place and return tghe
+   length of the valid buffer. */
+static size_t
+percent_plus_unescape (unsigned char *string)
+{
+  unsigned char *p = string;
+  size_t n = 0;
+
+  while (*string)
+    {
+      if (*string == '%' && string[1] && string[2])
+        { 
+          string++;
+          *p++ = xtoi_2 (string);
+          n++;
+          string+= 2;
+        }
+      else if (*string == '+')
+        {
+          *p++ = ' ';
+          n++;
+          string++;
+        }
+      else
+        {
+          *p++ = *string++;
+          n++;
+        }
+    }
+
+  return n;
+}
+
+
+
 /* SERIALNO 
 
    Return the serial number of the card using a status reponse.  This
@@ -106,7 +154,7 @@ open_card (CTRL ctrl)
 
    Background: We want to keep the client clear of handling card
    changes between operations; i.e. the client can assume that all
-   operations are doneon the same card unless he call this function.
+   operations are done on the same card unless he call this function.
  */
 static int
 cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
@@ -120,7 +168,10 @@ cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
   if ((rc = open_card (ctrl)))
     return rc;
 
-  rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp);
+  if (ctrl->app_ctx)
+    rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
+  else
+    rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp);
   if (rc)
     return map_to_assuan_status (rc);
   rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
@@ -149,6 +200,16 @@ cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
    error message.  The response of this command is a list of status
    lines formatted as this:
 
+     S APPTYPE <apptype>
+
+   This returns the type of the application, currently the strings:
+
+       P15     = PKCS-15 structure used
+       DINSIG  = DIN SIG
+       OPENPGP = OpenPGP card
+   are implemented.  These strings are aliases for the AID
+
      S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>
 
    If there is no certificate yet stored on the card a single "X" is
@@ -157,13 +218,34 @@ cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
 
      S CERTINFO <certtype> <hexstring_with_id>
 
-   Where CERTINFO is a number indicating the type of certificate:
+   Where CERTTYPE is a number indicating the type of certificate:
       0   := Unknown
       100 := Regular X.509 cert
       101 := Trusted X.509 cert
       102 := Useful X.509 cert
 
+   For certain cards, more information will be returned:
+
+     S KEY-FPR <no> <hexstring>
 
+   For OpenPGP cards this returns the stored fingerprints of the
+   keys. This can be used check whether a key is available on the
+   card.  NO may be 1, 2 or 3.
+
+     S CA-FPR <no> <hexstring>
+
+   Similar to above, these are the fingerprints of keys assumed to be
+   ultimately trusted.
+
+     S DISP-NAME <name_of_card_holder>
+
+   The name of the card holder as stored on the card; percent
+   aescaping takes place, spaces are encoded as '+'
+
+     S PUBKEY-URL <url>
+
+   The URL to be used for locating the entire public key.
+     
 */
 static int
 cmd_learn (ASSUAN_CONTEXT ctx, char *line)
@@ -183,8 +265,11 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
     char *serial_and_stamp;
     char *serial;
     time_t stamp;
-   
-    rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp);
+
+    if (ctrl->app_ctx)
+      rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
+    else
+      rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp);
     if (rc)
       return map_to_assuan_status (rc);
     rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
@@ -221,6 +306,8 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
   }
 
   /* Return information about the certificates. */
+  if (ctrl->app_ctx)
+    rc = -1; /* This information is not yet available for applications. */
   for (idx=0; !rc; idx++)
     {
       char *certid;
@@ -248,6 +335,8 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
 
 
   /* Return information about the keys. */
+  if (ctrl->app_ctx)
+    rc = -1; /* This information is not yet available for applications. */
   for (idx=0; !rc; idx++)
     {
       unsigned char keygrip[20];
@@ -294,6 +383,9 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
   if (rc == -1)
     rc = 0;
 
+  if (!rc && ctrl->app_ctx)
+    rc = app_write_learn_status (ctrl->app_ctx, ctrl);
+
 
   return map_to_assuan_status (rc);
 }
@@ -314,6 +406,9 @@ cmd_readcert (ASSUAN_CONTEXT ctx, char *line)
   if ((rc = open_card (ctrl)))
     return rc;
 
+  if (ctrl->app_ctx)
+    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+
   rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert);
   if (rc)
     {
@@ -348,6 +443,9 @@ cmd_readkey (ASSUAN_CONTEXT ctx, char *line)
   if ((rc = open_card (ctrl)))
     return rc;
 
+  if (ctrl->app_ctx)
+    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+
   rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert);
   if (rc)
     {
@@ -480,11 +578,19 @@ cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
   keyidstr = strdup (line);
   if (!keyidstr)
     return ASSUAN_Out_Of_Core;
-  rc = card_sign (ctrl->card_ctx,
-                  keyidstr, GCRY_MD_SHA1,
-                  pin_cb, ctx,
-                  ctrl->in_data.value, ctrl->in_data.valuelen,
-                  &outdata, &outdatalen);
+  
+  if (ctrl->app_ctx)
+    rc = app_sign (ctrl->app_ctx,
+                    keyidstr, GCRY_MD_SHA1,
+                    pin_cb, ctx,
+                    ctrl->in_data.value, ctrl->in_data.valuelen,
+                    &outdata, &outdatalen);
+  else  
+    rc = card_sign (ctrl->card_ctx,
+                    keyidstr, GCRY_MD_SHA1,
+                    pin_cb, ctx,
+                    ctrl->in_data.value, ctrl->in_data.valuelen,
+                    &outdata, &outdatalen);
   free (keyidstr);
   if (rc)
     {
@@ -519,11 +625,18 @@ cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
   keyidstr = strdup (line);
   if (!keyidstr)
     return ASSUAN_Out_Of_Core;
-  rc = card_decipher (ctrl->card_ctx,
-                      keyidstr, 
-                      pin_cb, ctx,
-                      ctrl->in_data.value, ctrl->in_data.valuelen,
-                      &outdata, &outdatalen);
+  if (ctrl->app_ctx)
+    rc = app_decipher (ctrl->app_ctx,
+                        keyidstr, 
+                        pin_cb, ctx,
+                        ctrl->in_data.value, ctrl->in_data.valuelen,
+                        &outdata, &outdatalen);
+  else
+    rc = card_decipher (ctrl->card_ctx,
+                        keyidstr, 
+                        pin_cb, ctx,
+                        ctrl->in_data.value, ctrl->in_data.valuelen,
+                        &outdata, &outdatalen);
   free (keyidstr);
   if (rc)
     {
@@ -541,6 +654,99 @@ cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
 }
 
 
+/* SETATTR <name> <value> 
+
+   This command is used to store data on a a smartcard.  The allowed
+   names and values are depend on the currently selected smartcard
+   application.  NAME and VALUE must be percent and '+' escaped.
+
+   However, the curent implementation assumes that Name is not escaped;
+   this works as long as noone uses arbitrary escaping. 
+   A PIN will be requested for most NAMEs.  See the corresponding
+   setattr function of the actually used application (app-*.c) for
+   details.  */
+static int
+cmd_setattr (ASSUAN_CONTEXT ctx, char *line)
+{
+  CTRL ctrl = assuan_get_pointer (ctx);
+  int rc;
+  char *keyword;
+  int keywordlen;
+  size_t nbytes;
+
+  if ((rc = open_card (ctrl)))
+    return rc;
+
+  keyword = line;
+  for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
+    ;
+  if (*line)
+      *line++ = 0;
+  while (spacep (line))
+    line++;
+  nbytes = percent_plus_unescape (line);
+
+  rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, line, nbytes);
+
+  return map_to_assuan_status (rc);
+}
+
+/* GENKEY [--force] <no>
+
+   Generate a key on-card identified by NO, which is application
+   specific.  Return values are application specific.  For OpenPGP
+   cards 2 status lines are returned:
+
+     S KEY-FPR  <hexstring>
+     S KEY-CREATED-AT <seconds_since_epoch>
+     S KEY-DATA [p|n] <hexdata>
+     
+
+   --force is required to overwriet an already existing key.  The
+   KEY-CREATED-AT is required for further processing because it is
+   part of the hashed key material for the fingerprint.
+
+   The public part of the key can also later be retrieved using the
+   READKEY command.
+
+ */
+static int
+cmd_genkey (ASSUAN_CONTEXT ctx, char *line)
+{
+  CTRL ctrl = assuan_get_pointer (ctx);
+  int rc;
+  char *keyno;
+  int force = has_option (line, "--force");
+
+  /* Skip over options. */
+  while ( *line == '-' && line[1] == '-' )
+    {
+      while (!spacep (line))
+        line++;
+      while (spacep (line))
+        line++;
+    }
+  if (!*line)
+    return set_error (Parameter_Error, "no key number given");
+  keyno = line;
+  while (!spacep (line))
+    line++;
+  *line = 0;
+
+  if ((rc = open_card (ctrl)))
+    return rc;
+
+  if (!ctrl->app_ctx)
+    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+
+  rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0, pin_cb, ctx);
+
+  return map_to_assuan_status (rc);
+}
+
+
+
 
 \f
 /* Tell the assuan library about our commands */
@@ -560,6 +766,8 @@ register_commands (ASSUAN_CONTEXT ctx)
     { "PKDECRYPT",    cmd_pkdecrypt },
     { "INPUT",        NULL }, 
     { "OUTPUT",       NULL }, 
+    { "SETATTR",      cmd_setattr },
+    { "GENKEY",       cmd_genkey },
     { NULL }
   };
   int i, rc;
@@ -646,3 +854,51 @@ scd_command_handler (int listen_fd)
 
   assuan_deinit_server (ctx);
 }
+
+
+/* Send a line with status information via assuan and escape all given
+   buffers. The variable elements are pairs of (char *, size_t),
+   terminated with a (NULL, 0). */
+void
+send_status_info (CTRL ctrl, const char *keyword, ...)
+{
+  va_list arg_ptr;
+  const unsigned char *value;
+  size_t valuelen;
+  char buf[950], *p;
+  size_t n;
+  ASSUAN_CONTEXT ctx = ctrl->server_local->assuan_ctx;
+  
+  va_start (arg_ptr, keyword);
+
+  p = buf; 
+  n = 0;
+  while ( (value = va_arg (arg_ptr, const unsigned char *)) )
+    {
+      valuelen = va_arg (arg_ptr, size_t);
+      if (!valuelen)
+        continue; /* empty buffer */
+      if (n)
+        {
+          *p++ = ' ';
+          n++;
+        }
+      for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
+        {
+          if (*value < ' ' || *value == '+')
+            {
+              sprintf (p, "%%%02X", *value);
+              p += 3;
+            }
+          else if (*value == ' ')
+            *p++ = '+';
+          else
+            *p++ = *value;
+        }
+    }
+  *p = 0;
+  assuan_write_status (ctx, keyword, buf);
+
+  va_end (arg_ptr);
+}
+
index e6b4c4a..1100bdf 100644 (file)
 #include <string.h>
 
 #define JNLIB_NEED_LOG_LOGV
-#include <gcrypt.h>
 #include "scdaemon.h"
+#include <gcrypt.h>
 
 #include "apdu.h" /* for open_reader */
 #include "atr.h"
+#include "app-common.h"
 
 #define _(a) (a)
 
@@ -104,6 +105,9 @@ main (int argc, char **argv )
   ARGPARSE_ARGS pargs;
   int slot, rc;
   int reader_port = 32768; /* First USB reader. */
+  struct app_ctx_s appbuf;
+
+  memset (&appbuf, 0, sizeof appbuf);
 
   set_strusage (my_strusage);
   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
@@ -147,7 +151,8 @@ main (int argc, char **argv )
   if (rc)
     log_error ("can't dump ATR: %s\n", gpg_strerror (rc));
 
-  rc = app_select_openpgp (slot);
+  appbuf.slot = slot;
+  rc = app_select_openpgp (&appbuf, NULL, NULL);
   if (rc)
     log_error ("selecting openpgp failed: %s\n", gpg_strerror (rc));
   else
@@ -159,3 +164,8 @@ main (int argc, char **argv )
 
 
 
+void
+send_status_info (CTRL ctrl, const char *keyword, ...)
+{
+  /* DUMMY */
+}
index 5ab50a5..8e0ef37 100644 (file)
 #include <unistd.h>
 #include <signal.h>
 
+#define JNLIB_NEED_LOG_LOGV
+#include "scdaemon.h"
 #include <ksba.h>
 #include <gcrypt.h>
 
-#define JNLIB_NEED_LOG_LOGV
 #include <assuan.h> /* malloc hooks */
-#include "scdaemon.h"
 
 #include "i18n.h"
 #include "sysutils.h"
index 59d40e5..394a13a 100644 (file)
@@ -76,18 +76,22 @@ struct {
 
 struct server_local_s;
 struct card_ctx_s;
+struct app_ctx_s;
 
 struct server_control_s {
   struct server_local_s *server_local;
   struct card_ctx_s *card_ctx;
+  struct app_ctx_s *app_ctx;
   struct {
     unsigned char *value;  
     int valuelen;
   } in_data;  /* helper to store the value we are going to sign */
 
 };
+
 typedef struct server_control_s *CTRL;
 typedef struct card_ctx_s *CARD;
+typedef struct app_ctx_s *APP;
 
 /*-- scdaemon.c --*/
 void scd_exit (int rc);
@@ -95,6 +99,7 @@ void scd_init_default_ctrl (CTRL ctrl);
 
 /*-- command.c --*/
 void scd_command_handler (int);
+void send_status_info (CTRL ctrl, const char *keyword, ...);
 
 /*-- card.c --*/
 int card_open (CARD *rcard);
index e0ba197..20b02a1 100644 (file)
@@ -1,3 +1,14 @@
+2003-06-24  Werner Koch  <wk@gnupg.org>
+
+       * server.c (gpgsm_status_with_err_code): New.
+       * verify.c (gpgsm_verify): Use it here instead of the old
+       tokenizing version.
+
+       * verify.c (strtimestamp): Renamed to strtimestamp_r
+
+       Adjusted for changes in the libgcrypt API. Some more fixes for the
+       libgpg-error stuff.  
+
 2003-06-04  Werner Koch  <wk@gnupg.org>
 
        * call-agent.c (init_membuf,put_membuf,get_membuf): Removed.
index 31d9ba7..4d26e34 100644 (file)
 #include <unistd.h> 
 #include <time.h>
 #include <assert.h>
-#include <gcrypt.h>
 #ifdef HAVE_LOCALE_H
 #include <locale.h>
 #endif
-#include <assuan.h>
 
 #include "gpgsm.h"
+#include <gcrypt.h>
+#include <assuan.h>
 #include "i18n.h"
 #include "keydb.h" /* fixme: Move this to import.c */
+#include "../common/membuf.h"
+
 
 static ASSUAN_CONTEXT agent_ctx = NULL;
 static int force_pipe_server = 0;
@@ -54,77 +56,9 @@ struct genkey_parm_s {
 struct learn_parm_s {
   int error;
   ASSUAN_CONTEXT ctx;
-  struct membuf *data;
+  membuf_t *data;
 };
 
-struct membuf {
-  size_t len;
-  size_t size;
-  char *buf;
-  int out_of_core;
-};
-
-
-\f
-/* A simple implemnation of a dynamic buffer.  Use init_membuf() to
-   create a buffer, put_membuf to append bytes and get_membuf to
-   release and return the buffer.  Allocation errors are detected but
-   only returned at the final get_membuf(), this helps not to clutter
-   the code with out of core checks.  */
-
-static void
-init_membuf (struct membuf *mb, int initiallen)
-{
-  mb->len = 0;
-  mb->size = initiallen;
-  mb->out_of_core = 0;
-  mb->buf = xtrymalloc (initiallen);
-  if (!mb->buf)
-      mb->out_of_core = 1;
-}
-
-static void
-put_membuf (struct membuf *mb, const void *buf, size_t len)
-{
-  if (mb->out_of_core)
-    return;
-
-  if (mb->len + len >= mb->size)
-    {
-      char *p;
-      
-      mb->size += len + 1024;
-      p = xtryrealloc (mb->buf, mb->size);
-      if (!p)
-        {
-          mb->out_of_core = 1;
-          return;
-        }
-      mb->buf = p;
-    }
-  memcpy (mb->buf + mb->len, buf, len);
-  mb->len += len;
-}
-
-static void *
-get_membuf (struct membuf *mb, size_t *len)
-{
-  char *p;
-
-  if (mb->out_of_core)
-    {
-      xfree (mb->buf);
-      mb->buf = NULL;
-      return NULL;
-    }
-
-  p = mb->buf;
-  *len = mb->len;
-  mb->buf = NULL;
-  mb->out_of_core = 1; /* don't allow a reuse */
-  return p;
-}
-
 
 \f
 /* Try to connect to the agent via socket or fork it off and work by
@@ -354,7 +288,7 @@ start_agent (void)
 static AssuanError
 membuf_data_cb (void *opaque, const void *buffer, size_t length)
 {
-  struct membuf *data = opaque;
+  membuf_t *data = opaque;
 
   if (buffer)
     put_membuf (data, buffer, length);
@@ -373,7 +307,7 @@ gpgsm_agent_pksign (const char *keygrip,
 {
   int rc, i;
   char *p, line[ASSUAN_LINELENGTH];
-  struct membuf data;
+  membuf_t data;
   size_t len;
 
   *r_buf = NULL;
@@ -448,7 +382,7 @@ gpgsm_agent_pkdecrypt (const char *keygrip,
 {
   int rc;
   char line[ASSUAN_LINELENGTH];
-  struct membuf data;
+  membuf_t data;
   struct cipher_parm_s cipher_parm;
   size_t n, len;
   char *buf, *endp;
@@ -534,7 +468,7 @@ gpgsm_agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey)
 {
   int rc;
   struct genkey_parm_s gk_parm;
-  struct membuf data;
+  membuf_t data;
   size_t len;
   char *buf;
 
@@ -710,7 +644,7 @@ learn_cb (void *opaque, const void *buffer, size_t length)
       keydb_store_cert (cert, 1, NULL);
     }
   else if (rc)
-    log_error ("invalid certificate: %s\n", gnupg_strerror (rc));
+    log_error ("invalid certificate: %s\n", gpg_strerror (rc));
   else
     {
       int existed;
@@ -735,7 +669,7 @@ gpgsm_agent_learn ()
 {
   int rc;
   struct learn_parm_s learn_parm;
-  struct membuf data;
+  membuf_t data;
   size_t len;
 
   rc = start_agent ();
index 6112407..b182b24 100644 (file)
 #include <assert.h>
 #include <ctype.h>
 
+#include "gpgsm.h"
 #include <gcrypt.h>
 #include <assuan.h>
 
-#include "gpgsm.h"
 #include "i18n.h"
 
 struct membuf {
@@ -263,7 +263,7 @@ inq_certificate (void *opaque, const char *line)
       err = gpgsm_find_cert (line, &cert);
       if (err)
         {
-          log_error ("certificate not found: %s\n", gnupg_strerror (err));
+          log_error ("certificate not found: %s\n", gpg_strerror (err));
           rc = ASSUAN_Inquire_Error;
         }
       else
@@ -533,7 +533,7 @@ run_command_inq_cb (void *opaque, const char *line)
       err = gpgsm_find_cert (line, &cert);
       if (err)
         {
-          log_error ("certificate not found: %s\n", gnupg_strerror (err));
+          log_error ("certificate not found: %s\n", gpg_strerror (err));
           rc = ASSUAN_Inquire_Error;
         }
       else
index 2a2582d..6323c72 100644 (file)
 #include <time.h>
 #include <assert.h>
 
+#include "gpgsm.h"
 #include <gcrypt.h>
 #include <ksba.h>
 
-#include "gpgsm.h"
 #include "keydb.h"
 #include "i18n.h"
 
@@ -302,7 +302,7 @@ find_up (KEYDB_HANDLE kh, KsbaCert cert, const char *issuer)
         log_info (_("number of issuers matching: %d\n"), count);
       if (rc) 
         {
-          log_error ("external key lookup failed: %s\n", gnupg_strerror (rc));
+          log_error ("external key lookup failed: %s\n", gpg_strerror (rc));
           rc = -1;
         }
       else if (!count)
@@ -585,7 +585,7 @@ gpgsm_validate_chain (CTRL ctrl, KsbaCert cert, time_t *r_exptime)
           else 
             {
               log_error (_("checking the trust list failed: %s\n"),
-                         gnupg_strerror (rc));
+                         gpg_strerror (rc));
             }
           
           break;  /* okay, a self-signed certicate is an end-point */
@@ -655,8 +655,10 @@ gpgsm_validate_chain (CTRL ctrl, KsbaCert cert, time_t *r_exptime)
       rc = gpgsm_cert_use_cert_p (issuer_cert);
       if (rc)
         {
+          char numbuf[50];
+          sprintf (numbuf, "%d", rc);
           gpgsm_status2 (ctrl, STATUS_ERROR, "certcert.issuer.keyusage",
-                         gnupg_error_token (rc), NULL);
+                         numbuf, NULL);
           rc = 0;
         }
 
index 93c0bec..b837838 100644 (file)
 #include <time.h>
 #include <assert.h>
 
+#include "gpgsm.h"
 #include <gcrypt.h>
 #include <ksba.h>
 
-#include "gpgsm.h"
 #include "keydb.h"
 #include "i18n.h"
 
 
 static int
-do_encode_md (GCRY_MD_HD md, int algo,  unsigned int nbits,
-              GCRY_MPI *r_val)
+do_encode_md (gcry_md_hd_t md, int algo,  unsigned int nbits,
+              gcry_mpi_t *r_val)
 {
   int nframe = (nbits+7) / 8;
   byte *frame;
@@ -104,12 +104,12 @@ int
 gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert)
 {
   const char *algoid;
-  GCRY_MD_HD md;
+  gcry_md_hd_t md;
   int rc, algo;
-  GCRY_MPI frame;
+  gcry_mpi_t frame;
   KsbaSexp p;
   size_t n;
-  GCRY_SEXP s_sig, s_hash, s_pkey;
+  gcry_sexp_t s_sig, s_hash, s_pkey;
 
   algo = gcry_md_map_name ( (algoid=ksba_cert_get_digest_algo (cert)));
   if (!algo)
@@ -117,11 +117,11 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert)
       log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
       return gpg_error (GPG_ERR_GENERAL);
     }
-  md = gcry_md_open (algo, 0);
-  if (!md)
+  rc = gcry_md_open (&md, algo, 0);
+  if (rc)
     {
-      log_error ("md_open failed: %s\n", gcry_strerror (-1));
-      return gpg_error (GPG_ERR_GENERAL);
+      log_error ("md_open failed: %s\n", gpg_strerror (rc));
+      return rc;
     }
   if (DBG_HASHING)
     gcry_md_start_debug (md, "hash.cert");
@@ -157,9 +157,9 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert)
   ksba_free (p);
   if (rc)
     {
-      log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc));
+      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
       gcry_md_close (md);
-      return map_gcry_err (rc);
+      return rc;
     }
 
   p = ksba_cert_get_public_key (issuer_cert);
@@ -176,10 +176,10 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert)
   ksba_free (p);
   if (rc)
     {
-      log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc));
+      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
       gcry_md_close (md);
       gcry_sexp_release (s_sig);
-      return map_gcry_err (rc);
+      return rc;
     }
 
   rc = do_encode_md (md, algo, gcry_pk_get_nbits (s_pkey), &frame);
@@ -199,24 +199,24 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert)
   
   rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
   if (DBG_CRYPTO)
-      log_debug ("gcry_pk_verify: %s\n", gcry_strerror (rc));
+      log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc));
   gcry_md_close (md);
   gcry_sexp_release (s_sig);
   gcry_sexp_release (s_hash);
   gcry_sexp_release (s_pkey);
-  return map_gcry_err (rc);
+  return rc;
 }
 
 
 
 int
 gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval,
-                           GCRY_MD_HD md, int algo)
+                           gcry_md_hd_t md, int algo)
 {
   int rc;
   KsbaSexp p;
-  GCRY_MPI frame;
-  GCRY_SEXP s_sig, s_hash, s_pkey;
+  gcry_mpi_t frame;
+  gcry_sexp_t s_sig, s_hash, s_pkey;
   size_t n;
 
   n = gcry_sexp_canon_len (sigval, 0, NULL, NULL);
@@ -228,8 +228,8 @@ gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval,
   rc = gcry_sexp_sscan (&s_sig, NULL, sigval, n);
   if (rc)
     {
-      log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc));
-      return map_gcry_err (rc);
+      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
+      return rc;
     }
 
   p = ksba_cert_get_public_key (cert);
@@ -248,9 +248,9 @@ gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval,
   ksba_free (p);
   if (rc)
     {
-      log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc));
+      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
       gcry_sexp_release (s_sig);
-      return map_gcry_err (rc);
+      return rc;
     }
 
 
@@ -268,17 +268,17 @@ gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval,
   
   rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
   if (DBG_CRYPTO)
-      log_debug ("gcry_pk_verify: %s\n", gcry_strerror (rc));
+      log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc));
   gcry_sexp_release (s_sig);
   gcry_sexp_release (s_hash);
   gcry_sexp_release (s_pkey);
-  return map_gcry_err (rc);
+  return rc;
 }
 
 
 
 int
-gpgsm_create_cms_signature (KsbaCert cert, GCRY_MD_HD md, int mdalgo,
+gpgsm_create_cms_signature (KsbaCert cert, gcry_md_hd_t md, int mdalgo,
                             char **r_sigval)
 {
   int rc;
index 9afb115..703e071 100644 (file)
 #include <time.h>
 #include <assert.h>
 
+#include "gpgsm.h"
 #include <gcrypt.h>
 #include <ksba.h>
 
-#include "gpgsm.h"
 #include "keydb.h"
 #include "i18n.h"
 
index 7224625..eedc990 100644 (file)
 #include <time.h>
 #include <assert.h>
 
+#include "gpgsm.h"
 #include <gcrypt.h>
 #include <ksba.h>
 
-#include "gpgsm.h"
 #include "keydb.h"
 #include "i18n.h"
  
index 716cfcd..0dd4fdd 100644 (file)
@@ -96,10 +96,10 @@ EOF
 #include <time.h>
 #include <assert.h>
 
+#include "gpgsm.h"
 #include <gcrypt.h>
 #include <ksba.h>
 
-#include "gpgsm.h"
 #include "keydb.h"
 #include "i18n.h"
 
@@ -489,7 +489,7 @@ proc_parameters (struct para_data_s *para, struct reqgen_ctrl_s *outctrl)
     {
       r = get_parameter (para, pKEYTYPE);
       log_error ("line %d: key generation failed: %s\n",
-                 r->lnr, gnupg_strerror (rc));
+                 r->lnr, gpg_strerror (rc));
       return rc;
     }
 
@@ -508,7 +508,7 @@ create_request (struct para_data_s *para, KsbaConstSexp public,
 {
   KsbaCertreq cr;
   KsbaError err;
-  GCRY_MD_HD md;
+  gcry_md_hd_t md;
   KsbaStopReason stopreason;
   int rc = 0;
   const char *s;
@@ -517,11 +517,10 @@ create_request (struct para_data_s *para, KsbaConstSexp public,
   if (!cr)
     return gpg_error (GPG_ERR_ENOMEM);
 
-  md = gcry_md_open (GCRY_MD_SHA1, 0);
-  if (!md)
+  rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
+  if (rc)
     {
-      log_error ("md_open failed: %s\n", gcry_strerror (-1));
-      rc = map_gcry_err (gcry_errno ());
+      log_error ("md_open failed: %s\n", gpg_strerror (rc));
       goto leave;
     }
   if (DBG_HASHING)
@@ -585,7 +584,7 @@ create_request (struct para_data_s *para, KsbaConstSexp public,
         }
       if (stopreason == KSBA_SR_NEED_SIG)
         {
-          GCRY_SEXP s_pkey;
+          gcry_sexp_t s_pkey;
           size_t n;
           unsigned char grip[20], hexgrip[41];
           char *sigval;
@@ -601,8 +600,7 @@ create_request (struct para_data_s *para, KsbaConstSexp public,
           rc = gcry_sexp_sscan (&s_pkey, NULL, public, n);
           if (rc)
             {
-              log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc));
-              rc = map_gcry_err (rc);
+              log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
               goto leave;
             }
           if ( !gcry_pk_get_keygrip (s_pkey, grip) )
@@ -623,7 +621,7 @@ create_request (struct para_data_s *para, KsbaConstSexp public,
                                    &sigval, &siglen);
           if (rc)
             {
-              log_error ("signing failed: %s\n", gnupg_strerror (rc));
+              log_error ("signing failed: %s\n", gpg_strerror (rc));
               goto leave;
             }
           
@@ -671,7 +669,7 @@ gpgsm_genkey (CTRL ctrl, int in_fd, FILE *out_fp)
   rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
   if (rc)
     {
-      log_error ("can't create writer: %s\n", gnupg_strerror (rc));
+      log_error ("can't create writer: %s\n", gpg_strerror (rc));
       goto leave;
     }
 
@@ -679,14 +677,14 @@ gpgsm_genkey (CTRL ctrl, int in_fd, FILE *out_fp)
   if (rc)
     {
       log_error ("error creating certificate request: %s\n",
-                 gnupg_strerror (rc));
+                 gpg_strerror (rc));
       goto leave;
     }
 
   rc = gpgsm_finish_writer (b64writer);
   if (rc) 
     {
-      log_error ("write failed: %s\n", gnupg_strerror (rc));
+      log_error ("write failed: %s\n", gpg_strerror (rc));
       goto leave;
     }
 
index 04682f7..17483aa 100644 (file)
 #include <time.h>
 #include <assert.h>
 
+#include "gpgsm.h"
 #include <gcrypt.h>
 #include <ksba.h>
 
-#include "gpgsm.h"
 #include "keydb.h"
 #include "i18n.h"
 
@@ -38,7 +38,7 @@ struct decrypt_filter_parm_s {
   int algo;
   int mode;
   int blklen;
-  GCRY_CIPHER_HD hd;
+  gcry_cipher_hd_t hd;
   char iv[16];
   size_t ivlen;
   int any_data;  /* dod we push anything through the filter at all? */
@@ -65,7 +65,7 @@ prepare_decryption (const char *hexkeygrip, KsbaConstSexp enc_val,
                               &seskey, &seskeylen);
   if (rc)
     {
-      log_error ("error decrypting session key: %s\n", gnupg_strerror (rc));
+      log_error ("error decrypting session key: %s\n", gpg_strerror (rc));
       goto leave;
     }
 
@@ -113,17 +113,15 @@ prepare_decryption (const char *hexkeygrip, KsbaConstSexp enc_val,
   if (DBG_CRYPTO)
     log_printhex ("session key:", seskey+n, seskeylen-n);
 
-  parm->hd = gcry_cipher_open (parm->algo, parm->mode, 0);
-  if (!parm->hd)
+  rc = gcry_cipher_open (&parm->hd, parm->algo, parm->mode, 0);
+  if (rc)
     {
-      rc = gcry_errno ();
-      log_error ("error creating decryptor: %s\n", gcry_strerror (rc));
-      rc = map_gcry_err (rc);
+      log_error ("error creating decryptor: %s\n", gpg_strerror (rc));
       goto leave;
     }
                         
   rc = gcry_cipher_setkey (parm->hd, seskey+n, seskeylen-n);
-  if (rc == GCRYERR_WEAK_KEY)
+  if (gpg_err_code (rc) == GPG_ERR_WEAK_KEY)
     {
       log_info (_("WARNING: message was encrypted with "
                   "a weak key in the symmetric cipher.\n"));
@@ -131,8 +129,7 @@ prepare_decryption (const char *hexkeygrip, KsbaConstSexp enc_val,
     }
   if (rc)
     {
-      log_error("key setup failed: %s\n", gcry_strerror(rc) );
-      rc = map_gcry_err (rc);
+      log_error("key setup failed: %s\n", gpg_strerror(rc) );
       goto leave;
     }
 
@@ -277,14 +274,14 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
   rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, &reader);
   if (rc)
     {
-      log_error ("can't create reader: %s\n", gnupg_strerror (rc));
+      log_error ("can't create reader: %s\n", gpg_strerror (rc));
       goto leave;
     }
 
   rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
   if (rc)
     {
-      log_error ("can't create writer: %s\n", gnupg_strerror (rc));
+      log_error ("can't create writer: %s\n", gpg_strerror (rc));
       goto leave;
     }
 
@@ -334,8 +331,13 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
               else if (!algoid)
                 log_info (_("(this does not seem to be an encrypted"
                             " message)\n"));
-              gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.algorithm",
-                             gnupg_error_token (rc), algoid?algoid:"?", NULL);
+              {
+                char numbuf[50];
+                sprintf (numbuf, "%d", rc);
+                gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.algorithm",
+                               numbuf, algoid?algoid:"?", NULL);
+              }
+
               goto leave;
             }
           dfparm.algo = algo;
@@ -383,14 +385,14 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
                   if (rc)
                     {
                       log_error ("failed to find the certificate: %s\n",
-                                 gnupg_strerror(rc));
+                                 gpg_strerror(rc));
                       goto oops;
                     }
 
                   rc = keydb_get_cert (kh, &cert);
                   if (rc)
                     {
-                      log_error ("failed to get cert: %s\n", gnupg_strerror (rc));
+                      log_error ("failed to get cert: %s\n", gpg_strerror (rc));
                       goto oops;     
                     }
                   /* Just in case there is a problem with the own
@@ -399,8 +401,10 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
                   rc = gpgsm_cert_use_decrypt_p (cert);
                   if (rc)
                     {
+                      char numbuf[50];
+                      sprintf (numbuf, "%d", rc);
                       gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.keyusage",
-                                     gnupg_error_token (rc), NULL);
+                                     numbuf, NULL);
                       rc = 0;
                     }
 
@@ -424,7 +428,7 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
                   if (rc)
                     {
                       log_debug ("decrypting session key failed: %s\n",
-                                 gnupg_strerror (rc));
+                                 gpg_strerror (rc));
                     }
                   else
                     { /* setup the bulk decrypter */
@@ -479,7 +483,7 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
   rc = gpgsm_finish_writer (b64writer);
   if (rc) 
     {
-      log_error ("write failed: %s\n", gnupg_strerror (rc));
+      log_error ("write failed: %s\n", gpg_strerror (rc));
       goto leave;
     }
   gpgsm_status (ctrl, STATUS_DECRYPTION_OKAY, NULL);
index 5ec5b1a..53eff86 100644 (file)
 #include <time.h>
 #include <assert.h>
 
+#include "gpgsm.h"
 #include <gcrypt.h>
 #include <ksba.h>
 
-#include "gpgsm.h"
 #include "keydb.h"
 #include "i18n.h"
 
@@ -49,7 +49,7 @@ delete_one (CTRL ctrl, const char *username)
   if (rc)
     {
       log_error (_("certificate `%s' not found: %s\n"),
-                 username, gnupg_strerror (rc));
+                 username, gpg_strerror (rc));
       gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "1", NULL);
       goto leave;
     }
@@ -100,7 +100,7 @@ delete_one (CTRL ctrl, const char *username)
       if (rc == -1)
         rc = gpg_error (GPG_ERR_NO_PUBKEY);
       log_error (_("certificate `%s' not found: %s\n"),
-                 username, gnupg_strerror (rc));
+                 username, gpg_strerror (rc));
       gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "3", NULL);
       goto leave;
     }
@@ -113,7 +113,7 @@ delete_one (CTRL ctrl, const char *username)
       if (rc)
         {
           log_error ("problem re-searching certificate: %s\n",
-                     gnupg_strerror (rc));
+                     gpg_strerror (rc));
           goto leave;
         }
       
@@ -156,7 +156,7 @@ gpgsm_delete (CTRL ctrl, STRLIST names)
       if (rc)
         {
           log_error (_("deleting certificate \"%s\" failed: %s\n"),
-                     names->d, gnupg_strerror (rc) );
+                     names->d, gpg_strerror (rc) );
           return rc;
         }
     }
index 3713a7d..dfc9054 100644 (file)
 #include <time.h>
 #include <assert.h>
 
+#include "gpgsm.h"
 #include <gcrypt.h>
 #include <ksba.h>
 
-#include "gpgsm.h"
 #include "keydb.h"
 #include "i18n.h"
 
@@ -38,7 +38,7 @@
 struct dek_s {
   const char *algoid;
   int algo;
-  GCRY_CIPHER_HD chd;
+  gcry_cipher_hd_t chd;
   char key[32];
   int keylen;
   char iv[32];
@@ -89,37 +89,37 @@ init_dek (DEK dek)
       return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
     }
   
-  dek->chd = gcry_cipher_open (dek->algo, mode, GCRY_CIPHER_SECURE);
-  if (!dek->chd)
+  rc = gcry_cipher_open (&dek->chd, dek->algo, mode, GCRY_CIPHER_SECURE);
+  if (rc)
     {
-      log_error ("failed to create cipher context: %s\n", gcry_strerror (-1));
-      return gpg_error (GPG_ERR_GENERAL);
+      log_error ("failed to create cipher context: %s\n", gpg_strerror (rc));
+      return rc;
     }
   
   for (i=0; i < 8; i++)
     {
       gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
       rc = gcry_cipher_setkey (dek->chd, dek->key, dek->keylen);
-      if (rc != GCRYERR_WEAK_KEY)
+      if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY)
         break;
       log_info(_("weak key created - retrying\n") );
     }
   if (rc)
     {
-      log_error ("failed to set the key: %s\n", gcry_strerror (rc));
+      log_error ("failed to set the key: %s\n", gpg_strerror (rc));
       gcry_cipher_close (dek->chd);
       dek->chd = NULL;
-      return map_gcry_err (rc);
+      return rc;
     }
 
   gcry_randomize (dek->iv, dek->ivlen, GCRY_STRONG_RANDOM);
   rc = gcry_cipher_setiv (dek->chd, dek->iv, dek->ivlen);
   if (rc)
     {
-      log_error ("failed to set the IV: %s\n", gcry_strerror (rc));
+      log_error ("failed to set the IV: %s\n", gpg_strerror (rc));
       gcry_cipher_close (dek->chd);
       dek->chd = NULL;
-      return map_gcry_err (rc);
+      return rc;
     }
   
   return 0;
@@ -129,14 +129,14 @@ init_dek (DEK dek)
 /* Encode the session key. NBITS is the number of bits which should be
    used for packing the session key.  returns: An mpi with the session
    key (caller must free) */
-static GCRY_MPI
+static gcry_mpi_t
 encode_session_key (DEK dek, unsigned int nbits)
 {
   int nframe = (nbits+7) / 8;
   byte *p;
   byte *frame;
   int i,n;
-  MPI a;
+  gcry_mpi_t a;
 
   if (dek->keylen + 7 > nframe || !nframe)
     log_bug ("can't encode a %d bit key in a %d bits frame\n",
@@ -206,7 +206,7 @@ encode_session_key (DEK dek, unsigned int nbits)
 static int
 encrypt_dek (const DEK dek, KsbaCert cert, char **encval)
 {
-  GCRY_SEXP s_ciph, s_data, s_pkey;
+  gcry_sexp_t s_ciph, s_data, s_pkey;
   int rc;
   KsbaSexp buf;
   size_t len;
@@ -230,14 +230,14 @@ encrypt_dek (const DEK dek, KsbaCert cert, char **encval)
   xfree (buf); buf = NULL;
   if (rc)
     {
-      log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc));
-      return map_gcry_err (rc);
+      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
+      return rc;
     }
 
   /* put the encoded cleartext into a simple list */
   {
     /* fixme: actually the pkcs-1 encoding should go into libgcrypt */
-    GCRY_MPI data = encode_session_key (dek, gcry_pk_get_nbits (s_pkey));
+    gcry_mpi_t data = encode_session_key (dek, gcry_pk_get_nbits (s_pkey));
     if (!data)
       {
         gcry_mpi_release (data);
@@ -404,7 +404,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
   rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
   if (rc)
     {
-      log_error ("can't create writer: %s\n", gnupg_strerror (rc));
+      log_error ("can't create writer: %s\n", gpg_strerror (rc));
       goto leave;
     }
 
@@ -449,7 +449,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
   if (rc)
     {
       log_error ("failed to create the session key: %s\n",
-                 gnupg_strerror (rc));
+                 gpg_strerror (rc));
       goto leave;
     }
 
@@ -482,7 +482,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
       if (rc)
         {
           log_error ("encryption failed for recipient no. %d: %s\n",
-                     recpno, gnupg_strerror (rc));
+                     recpno, gpg_strerror (rc));
           goto leave;
         }
       
@@ -532,7 +532,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
   rc = gpgsm_finish_writer (b64writer);
   if (rc) 
     {
-      log_error ("write failed: %s\n", gnupg_strerror (rc));
+      log_error ("write failed: %s\n", gpg_strerror (rc));
       goto leave;
     }
   log_info ("encrypted data created\n");
index d4b0581..93a55de 100644 (file)
 #include <time.h>
 #include <assert.h>
 
+#include "gpgsm.h"
 #include <gcrypt.h>
 #include <ksba.h>
 
-#include "gpgsm.h"
 #include "keydb.h"
 
 static void print_short_info (KsbaCert cert, FILE *fp);
@@ -85,7 +85,7 @@ gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp)
           if (rc)
             {
               log_error ("key `%s' not found: %s\n",
-                         sl->d, gnupg_strerror (rc));
+                         sl->d, gpg_strerror (rc));
               rc = 0;
             }
           else
@@ -121,7 +121,7 @@ gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp)
       rc = keydb_get_cert (hd, &cert);
       if (rc) 
         {
-          log_error ("keydb_get_cert failed: %s\n", gnupg_strerror (rc));
+          log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
           goto leave;
         }
 
@@ -147,7 +147,7 @@ gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp)
           rc = gpgsm_create_writer (&b64writer, ctrl, fp, &writer);
           if (rc)
             {
-              log_error ("can't create writer: %s\n", gnupg_strerror (rc));
+              log_error ("can't create writer: %s\n", gpg_strerror (rc));
               goto leave;
             }
         }
@@ -176,7 +176,7 @@ gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp)
       cert = NULL;
     }
   if (rc && rc != -1)
-    log_error ("keydb_search failed: %s\n", gnupg_strerror (rc));
+    log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
   else if (b64writer)
     {
       rc = gpgsm_finish_writer (b64writer);
index 6e458cf..028c08a 100644 (file)
 #include <time.h>
 #include <assert.h>
 
-#include <gcrypt.h>
-#include <ksba.h>
 
 #include "gpgsm.h"
+#include <gcrypt.h>
+#include <ksba.h>
 
 /* Return the fingerprint of the certificate (we can't put this into
    libksba because we need libgcrypt support).  The caller must
@@ -45,7 +45,7 @@
 char *
 gpgsm_get_fingerprint (KsbaCert cert, int algo, char *array, int *r_len)
 {
-  GCRY_MD_HD md;
+  gcry_md_hd_t md;
   int rc, len;
   
   if (!algo)
@@ -59,10 +59,10 @@ gpgsm_get_fingerprint (KsbaCert cert, int algo, char *array, int *r_len)
   if (r_len)
     *r_len = len;
 
-  md = gcry_md_open (algo, 0);
-  if (!md)
+  rc = gcry_md_open (&md, algo, 0);
+  if (rc)
     {
-      log_error ("md_open failed: %s\n", gcry_strerror (-1));
+      log_error ("md_open failed: %s\n", gpg_strerror (rc));
       memset (array, 0xff, len); /* better return an invalid fpr than NULL */
       return array;
     }
@@ -143,7 +143,7 @@ gpgsm_get_short_fingerprint (KsbaCert cert)
 char *
 gpgsm_get_keygrip (KsbaCert cert, char *array)
 {
-  GCRY_SEXP s_pkey;
+  gcry_sexp_t s_pkey;
   int rc;
   KsbaSexp p;
   size_t n;
@@ -164,7 +164,7 @@ gpgsm_get_keygrip (KsbaCert cert, char *array)
   xfree (p);
   if (rc)
     {
-      log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc));
+      log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
       return NULL;
     }
   array = gcry_pk_get_keygrip (s_pkey, array);
index 8aebb1c..5157874 100644 (file)
 #include <unistd.h>
 #include <fcntl.h>
 
+#include "gpgsm.h"
 #include <gcrypt.h>
 #include <assuan.h> /* malloc hooks */
 
-#include "gpgsm.h"
 #include "../kbx/keybox.h" /* malloc hooks */
 #include "i18n.h"
 #include "keydb.h"
@@ -1095,7 +1095,7 @@ main ( int argc, char **argv)
       if (rc)
         {
           log_error (_("can't sign using `%s': %s\n"),
-                     sl->d, gnupg_strerror (rc));
+                     sl->d, gpg_strerror (rc));
           gpgsm_status2 (&ctrl, STATUS_INV_RECP,
                          gpg_err_code (rc) == -1?                      "1":
                          gpg_err_code (rc) == GPG_ERR_NO_PUBKEY?       "1":
@@ -1117,7 +1117,7 @@ main ( int argc, char **argv)
       if (rc)
         {
           log_error (_("can't encrypt to `%s': %s\n"),
-                     sl->d, gnupg_strerror (rc));
+                     sl->d, gpg_strerror (rc));
           gpgsm_status2 (&ctrl, STATUS_INV_RECP,
                          gpg_err_code (rc) == -1?                         "1":
                          gpg_err_code (rc) == GPG_ERR_NO_PUBKEY?          "1":
index 72abcca..f996d57 100644 (file)
@@ -152,6 +152,8 @@ void gpgsm_init_default_ctrl (struct server_control_s *ctrl);
 void gpgsm_server (void);
 void gpgsm_status (CTRL ctrl, int no, const char *text);
 void gpgsm_status2 (CTRL ctrl, int no, ...);
+void gpgsm_status_with_err_code (CTRL ctrl, int no, const char *text,
+                                 gpg_err_code_t ec);
 
 /*-- fingerprint --*/
 char *gpgsm_get_fingerprint (KsbaCert cert, int algo, char *array, int *r_len);
@@ -188,9 +190,9 @@ void gpgsm_dump_string (const char *string);
 /*-- certcheck.c --*/
 int gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert);
 int gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval,
-                               GCRY_MD_HD md, int hash_algo);
+                               gcry_md_hd_t md, int hash_algo);
 /* fixme: move create functions to another file */
-int gpgsm_create_cms_signature (KsbaCert cert, GCRY_MD_HD md, int mdalgo,
+int gpgsm_create_cms_signature (KsbaCert cert, gcry_md_hd_t md, int mdalgo,
                                 char **r_sigval);
 
 
index 12788ea..17dc3d6 100644 (file)
 #include <time.h>
 #include <assert.h>
 
+#include "gpgsm.h"
 #include <gcrypt.h>
 #include <ksba.h>
 
-#include "gpgsm.h"
 #include "keydb.h"
 #include "i18n.h"
 
index 7f8117d..fe65565 100644 (file)
@@ -231,7 +231,7 @@ keydb_add_resource (const char *url, int force, int secret)
 
  leave:
   if (rc)
-    log_error ("keyblock resource `%s': %s\n", filename, gnupg_strerror(rc));
+    log_error ("keyblock resource `%s': %s\n", filename, gpg_strerror(rc));
   else if (secret)
     any_secret = 1;
   else
@@ -1255,14 +1255,14 @@ keydb_store_cert (KsbaCert cert, int ephemeral, int *existed)
           return 0; /* okay */
         }
       log_error (_("problem looking for existing certificate: %s\n"),
-                 gnupg_strerror (rc));
+                 gpg_strerror (rc));
       return rc;
     }
 
   rc = keydb_locate_writable (kh, 0);
   if (rc)
     {
-      log_error (_("error finding writable keyDB: %s\n"), gnupg_strerror (rc));
+      log_error (_("error finding writable keyDB: %s\n"), gpg_strerror (rc));
       keydb_release (kh);
       return rc;
     }
@@ -1270,7 +1270,7 @@ keydb_store_cert (KsbaCert cert, int ephemeral, int *existed)
   rc = keydb_insert_cert (kh, cert);
   if (rc)
     {
-      log_error (_("error storing certificate: %s\n"), gnupg_strerror (rc));
+      log_error (_("error storing certificate: %s\n"), gpg_strerror (rc));
       keydb_release (kh);
       return rc;
     }
index 46a4e38..634bda2 100644 (file)
@@ -1,5 +1,5 @@
 /* keylist.c
- * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include <time.h>
 #include <assert.h>
 
+#include "gpgsm.h"
+
 #include <gcrypt.h>
 #include <ksba.h>
 
-#include "gpgsm.h"
 #include "keydb.h"
 #include "i18n.h"
 
@@ -460,7 +461,7 @@ list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
           if (rc)
             {
               log_error ("key `%s' not found: %s\n",
-                         sl->d, gnupg_strerror (rc));
+                         sl->d, gpg_strerror (rc));
               rc = 0;
             }
           else
@@ -535,7 +536,7 @@ list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
       cert = NULL;
     }
   if (rc && rc != -1)
-    log_error ("keydb_search failed: %s\n", gnupg_strerror (rc));
+    log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
   
  leave:
   ksba_cert_release (cert);
index 60f553b..dda1509 100644 (file)
@@ -991,7 +991,18 @@ gpgsm_status (CTRL ctrl, int no, const char *text)
   gpgsm_status2 (ctrl, no, text, NULL);
 }
 
+void
+gpgsm_status_with_err_code (CTRL ctrl, int no, const char *text,
+                            gpg_err_code_t ec)
+{
+  char buf[30];
 
+  sprintf (buf, "%u", (unsigned int)ec);
+  if (text)
+    gpgsm_status2 (ctrl, no, text, buf, NULL);
+  else
+    gpgsm_status2 (ctrl, no, buf, NULL);
+}
 
 #if 0
 /*
index b77c672..0afb52b 100644 (file)
--- a/sm/sign.c
+++ b/sm/sign.c
 #include <time.h>
 #include <assert.h>
 
+#include "gpgsm.h"
 #include <gcrypt.h>
 #include <ksba.h>
 
-#include "gpgsm.h"
 #include "keydb.h"
 #include "i18n.h"
 
 
 static void
-hash_data (int fd, GCRY_MD_HD md)
+hash_data (int fd, gcry_md_hd_t md)
 {
   FILE *fp;
   char buffer[4096];
@@ -61,7 +61,7 @@ hash_data (int fd, GCRY_MD_HD md)
 }
 
 static int
-hash_and_copy_data (int fd, GCRY_MD_HD md, KsbaWriter writer)
+hash_and_copy_data (int fd, gcry_md_hd_t md, KsbaWriter writer)
 {
   KsbaError err;
   FILE *fp;
@@ -203,7 +203,7 @@ get_default_signer (void)
   rc = keydb_classify_name (opt.local_user, &desc);
   if (rc)
     {
-      log_error ("failed to find default signer: %s\n", gnupg_strerror (rc));
+      log_error ("failed to find default signer: %s\n", gpg_strerror (rc));
       return NULL;
     }
 
@@ -302,7 +302,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
   KsbaCMS cms = NULL;
   KsbaStopReason stopreason;
   KEYDB_HANDLE kh = NULL;
-  GCRY_MD_HD data_md = NULL;
+  gcry_md_hd_t data_md = NULL;
   int signer;
   const char *algoid;
   int algo;
@@ -322,7 +322,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
   rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
   if (rc)
     {
-      log_error ("can't create writer: %s\n", gnupg_strerror (rc));
+      log_error ("can't create writer: %s\n", gpg_strerror (rc));
       goto leave;
     }
 
@@ -394,7 +394,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
       if (rc)
         {
           log_error ("failed to store list of certificates: %s\n",
-                     gnupg_strerror(rc));
+                     gpg_strerror(rc));
           goto leave;
         }
       /* Set the hash algorithm we are going to use */
@@ -409,11 +409,10 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
     }
   
   /* Prepare hashing (actually we are figuring out what we have set above)*/
-  data_md = gcry_md_open (0, 0);
-  if (!data_md)
+  rc = gcry_md_open (&data_md, 0, 0);
+  if (rc)
     {
-      rc = map_gcry_err (gcry_errno());
-      log_error ("md_open failed: %s\n", gcry_strerror (-1));
+      log_error ("md_open failed: %s\n", gpg_strerror (rc));
       goto leave;
     }
   if (DBG_HASHING)
@@ -524,18 +523,17 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
         }
       else if (stopreason == KSBA_SR_NEED_SIG)
         { /* calculate the signature for all signers */
-          GCRY_MD_HD md;
+          gcry_md_hd_t md;
 
           algo = GCRY_MD_SHA1;
-          md = gcry_md_open (algo, 0);
-          if (DBG_HASHING)
-            gcry_md_start_debug (md, "sign.attr");
-
-          if (!md)
+          rc = gcry_md_open (&md, algo, 0);
+          if (rc)
             {
-              log_error ("md_open failed: %s\n", gcry_strerror (-1));
+              log_error ("md_open failed: %s\n", gpg_strerror (rc));
               goto leave;
             }
+          if (DBG_HASHING)
+            gcry_md_start_debug (md, "sign.attr");
           ksba_cms_set_hash_function (cms, HASH_FNC, md);
           for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
             {
@@ -605,7 +603,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist,
   rc = gpgsm_finish_writer (b64writer);
   if (rc) 
     {
-      log_error ("write failed: %s\n", gnupg_strerror (rc));
+      log_error ("write failed: %s\n", gpg_strerror (rc));
       goto leave;
     }
 
index 569af8b..6dd4f4e 100644 (file)
 #include <time.h>
 #include <assert.h>
 
+#include "gpgsm.h"
 #include <gcrypt.h>
 #include <ksba.h>
 
-#include "gpgsm.h"
 #include "keydb.h"
 #include "i18n.h"
 
-/* fixme: Move this to jnlib */
 static char *
-strtimestamp (time_t atime)
+strtimestamp_r (time_t atime)
 {
   char *buffer = xmalloc (15);
   
@@ -59,7 +58,7 @@ strtimestamp (time_t atime)
 
 /* Hash the data for a detached signature */
 static void
-hash_data (int fd, GCRY_MD_HD md)
+hash_data (int fd, gcry_md_hd_t md)
 {
   FILE *fp;
   char buffer[4096];
@@ -102,7 +101,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
   KsbaStopReason stopreason;
   KsbaCert cert;
   KEYDB_HANDLE kh;
-  GCRY_MD_HD data_md = NULL;
+  gcry_md_hd_t data_md = NULL;
   int signer;
   const char *algoid;
   int algo;
@@ -130,7 +129,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
   rc = gpgsm_create_reader (&b64reader, ctrl, fp, &reader);
   if (rc)
     {
-      log_error ("can't create reader: %s\n", gnupg_strerror (rc));
+      log_error ("can't create reader: %s\n", gpg_strerror (rc));
       goto leave;
     }
 
@@ -139,7 +138,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
       rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
       if (rc)
         {
-          log_error ("can't create writer: %s\n", gnupg_strerror (rc));
+          log_error ("can't create writer: %s\n", gpg_strerror (rc));
           goto leave;
         }
     }
@@ -160,11 +159,10 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
       goto leave;
     }
 
-  data_md = gcry_md_open (0, 0);
-  if (!data_md)
+  rc = gcry_md_open (&data_md, 0, 0);
+  if (rc)
     {
-      rc = map_gcry_err (gcry_errno());
-      log_error ("md_open failed: %s\n", gcry_strerror (-1));
+      log_error ("md_open failed: %s\n", gpg_strerror (rc));
       goto leave;
     }
   if (DBG_HASHING)
@@ -225,7 +223,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
       rc = gpgsm_finish_writer (b64writer);
       if (rc) 
         {
-          log_error ("write failed: %s\n", gnupg_strerror (rc));
+          log_error ("write failed: %s\n", gpg_strerror (rc));
           goto leave;
         }
     }
@@ -364,7 +362,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
             }
           else
             log_error ("failed to find the certificate: %s\n",
-                       gnupg_strerror(rc));
+                       gpg_strerror(rc));
           {
             char numbuf[50];
             sprintf (numbuf, "%d", rc);
@@ -380,7 +378,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
       rc = keydb_get_cert (kh, &cert);
       if (rc)
         {
-          log_error ("failed to get cert: %s\n", gnupg_strerror (rc));
+          log_error ("failed to get cert: %s\n", gpg_strerror (rc));
           goto next_signer;
         }
 
@@ -395,7 +393,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
 
       if (msgdigest)
         { /* Signed attributes are available. */
-          GCRY_MD_HD md;
+          gcry_md_hd_t md;
           unsigned char *s;
 
           /* check that the message digest in the signed attributes
@@ -415,10 +413,10 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
               goto next_signer; 
             }
             
-          md = gcry_md_open (algo, 0);
-          if (!md)
+          rc = gcry_md_open (&md, algo, 0);
+          if (rc)
             {
-              log_error ("md_open failed: %s\n", gcry_strerror (-1));
+              log_error ("md_open failed: %s\n", gpg_strerror (rc));
               goto next_signer;
             }
           if (DBG_HASHING)
@@ -445,7 +443,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
         {
           char *fpr;
 
-          log_error ("invalid signature: %s\n", gnupg_strerror (rc));
+          log_error ("invalid signature: %s\n", gpg_strerror (rc));
           fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
           gpgsm_status (ctrl, STATUS_BADSIG, fpr);
           xfree (fpr);
@@ -454,8 +452,8 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
       rc = gpgsm_cert_use_verify_p (cert); /*(this displays an info message)*/
       if (rc)
         {
-          gpgsm_status2 (ctrl, STATUS_ERROR, "verify.keyusage",
-                         gnupg_error_token (rc), NULL);
+          gpgsm_status_with_err_code (ctrl, STATUS_ERROR, "verify.keyusage",
+                                      gpg_err_code (rc));
           rc = 0;
         }
 
@@ -474,7 +472,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
         char *buf, *fpr, *tstr;
 
         fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
-        tstr = strtimestamp (sigtime);
+        tstr = strtimestamp_r (sigtime);
         buf = xmalloc ( strlen(fpr) + strlen (tstr) + 120);
         sprintf (buf, "%s %s %lu %lu", fpr, tstr,
                  (unsigned long)sigtime, (unsigned long)keyexptime );
@@ -486,14 +484,16 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
 
       if (rc) /* of validate_chain */
         {
-          log_error ("invalid certification chain: %s\n", gnupg_strerror (rc));
+          log_error ("invalid certification chain: %s\n", gpg_strerror (rc));
           if (gpg_err_code (rc) == GPG_ERR_BAD_CERT_CHAIN
               || gpg_err_code (rc) == GPG_ERR_BAD_CERT
               || gpg_err_code (rc) == GPG_ERR_BAD_CA_CERT
               || gpg_err_code (rc) == GPG_ERR_CERT_REVOKED)
-            gpgsm_status (ctrl, STATUS_TRUST_NEVER, gnupg_error_token (rc));
+            gpgsm_status_with_err_code (ctrl, STATUS_TRUST_NEVER, NULL,
+                                        gpg_err_code (rc));
           else
-            gpgsm_status (ctrl, STATUS_TRUST_UNDEFINED, gnupg_error_token (rc));
+            gpgsm_status_with_err_code (ctrl, STATUS_TRUST_UNDEFINED, NULL, 
+                                        gpg_err_code (rc));
           goto next_signer;
         }