Doc fixes, moved some fizmes to TODO, fixed minor bugs.
authorWerner Koch <wk@gnupg.org>
Mon, 18 Mar 2002 09:30:35 +0000 (09:30 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 18 Mar 2002 09:30:35 +0000 (09:30 +0000)
14 files changed:
agent/ChangeLog
agent/cache.c
agent/learncard.c
agent/trustlist.c
scd/ChangeLog
scd/Makefile.am
scd/card.c
scd/command.c
scd/scdaemon.h
sm/base64.c
sm/call-agent.c
sm/certcheck.c
sm/decrypt.c
sm/gpgsm.c

index cbc05b1..fbc7ed9 100644 (file)
@@ -1,3 +1,8 @@
+2002-03-11  Werner Koch  <wk@gnupg.org>
+
+       * learncard.c (kpinfo_cb): Remove the content restrictions from
+       the keyID.
+
 2002-03-06  Werner Koch  <wk@gnupg.org>
 
        * learncard.c: New.
index 58cec42..445c4c5 100644 (file)
@@ -213,7 +213,7 @@ agent_get_cache (const char *key)
     log_debug ("agent_get_cache `%s'...\n", key);
   housekeeping ();
 
-  /* FIXME: Returning pointers is not thread safe - add a referencense
+  /* FIXME: Returning pointers is not thread safe - add a reference
      counter */
   for (r=thecache; r; r = r->next, count++)
     {
index 4cd1cb8..fe3e9ef 100644 (file)
@@ -84,7 +84,7 @@ kpinfo_cb (void *opaque, const char *line)
       p++;
     }
   else if ((p - item->hexgrip) != 40 || !spacep (p))
-    { /* not a 20 byte hex keygrip or now followed by a space */
+    { /* not a 20 byte hex keygrip or not followed by a space */
       parm->error = GNUPG_Invalid_Response;
       xfree (item);
       return;
@@ -93,9 +93,9 @@ kpinfo_cb (void *opaque, const char *line)
   while (spacep (p))
     p++;
   item->id = p;
-  for (; hexdigitp (p) || *p == '.'; p++)
-    ;
-  if (!(spacep (p) || !*p))
+  while (*p && !spacep (p))
+    p++;
+  if (p == item->id)
     { /* invalid ID string */
       parm->error = GNUPG_Invalid_Response;
       xfree (item);
index 15208ce..d3b8b6d 100644 (file)
@@ -29,7 +29,7 @@
 #include <sys/stat.h>
 
 #include "agent.h"
-#include "../assuan/assuan.h" /* fixme: nned a way to avoid assuna
+#include "../assuan/assuan.h" /* fixme: need a way to avoid assuan
                                  calls here */
 
 static const char headerblurb[] =
index 74ea5ed..399c6f5 100644 (file)
@@ -1,3 +1,9 @@
+2002-03-10  Werner Koch  <wk@gnupg.org>
+
+       * card-p15.c, card-dinsig.c, card-common.h: New.
+       * card.c: Factored most code out to the new modules, so that we
+       can better support different types of card applications.
+
 2002-01-26  Werner Koch  <wk@gnupg.org>
 
        * scdaemon.c scdaemon.h, command.c: New. Based on the code from
index 5379d51..c280b6d 100644 (file)
@@ -26,7 +26,8 @@ LDFLAGS = @LDFLAGS@
 
 scdaemon_SOURCES = \
        scdaemon.c scdaemon.h \
-       command.c card.c
+       command.c card.c \
+       card-p15.c card-dinsig.c
 
 
 scdaemon_LDADD = ../jnlib/libjnlib.a ../assuan/libassuan.a  \
index e7640ff..e59f88b 100644 (file)
 #include <ksba.h>
 
 #include "scdaemon.h"
-
-
-
-struct card_ctx_s {
-  int reader;   /* used reader */
-  struct sc_context *ctx;
-  struct sc_card *scard;
-  struct sc_pkcs15_card *p15card; /* only if there is a pkcs15 application */
-  
-};
+#include "card-common.h"
 
 /* Map the SC error codes to the GNUPG ones */
-static int
+int
 map_sc_err (int rc)
 {
   switch (rc)
@@ -84,9 +75,40 @@ map_sc_err (int rc)
   return rc;
 }
 
+/* Get the keygrip from CERT, return 0 on success */
+int
+card_help_get_keygrip (KsbaCert cert, unsigned char *array)
+{
+  GCRY_SEXP s_pkey;
+  int rc;
+  KsbaSexp p;
+  size_t n;
+  
+  p = ksba_cert_get_public_key (cert);
+  if (!p)
+    return -1; /* oops */
+  n = gcry_sexp_canon_len (p, 0, NULL, NULL);
+  if (!n)
+    return -1; /* libksba did not return a proper S-expression */
+  rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n);
+  xfree (p);
+  if (rc)
+    return -1; /* can't parse that S-expression */
+  array = gcry_pk_get_keygrip (s_pkey, array);
+  gcry_sexp_release (s_pkey);
+  if (!array)
+    return -1; /* failed to calculate the keygrip */
+  return 0;
+}
+
+
+
+
+
 
+\f
 /* Create a new context for the card and figures out some basic
-   information of the card.  Detects whether a PKCS_15 application is
+   information of the card.  Detects whgether a PKCS_15 application is
    stored.
 
    Common errors: GNUPG_Card_Not_Present */
@@ -114,7 +136,11 @@ card_open (CARD *rcard)
       rc = GNUPG_Card_Error;
     }
   card->ctx->error_file = log_get_stream ();
-  card->ctx->debug_file = log_get_stream ();
+  if (opt.debug)
+    {
+       card->ctx->debug = 1;
+       card->ctx->debug_file = log_get_stream ();
+    }
   if (sc_detect_card_presence (card->ctx->reader[card->reader], 0) != 1)
     {
       rc = GNUPG_Card_Not_Present;
@@ -142,16 +168,6 @@ card_open (CARD *rcard)
       goto leave;
     }
 
-  rc = sc_pkcs15_bind (card->scard, &card->p15card);
-  if (rc == SC_ERROR_PKCS15_APP_NOT_FOUND)
-    rc = 0; /* okay */
-  else if (rc)
-    {
-      log_error ("binding of existing PKCS-15 failed in reader %d: %s\n",
-                 card->reader, sc_strerror (rc));
-      rc = map_sc_err (rc);
-      goto leave;
-    }
     
  leave:
   if (rc)
@@ -188,6 +204,8 @@ card_close (CARD card)
     }      
 }
 
+
+
 /* 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.
@@ -195,22 +213,95 @@ card_close (CARD card)
    is mandatory for a PKCS_15 application and an error will be
    returned if this value is not availbale.  For non-PKCS-15 cards a
    serial number is constructed by other means. Caller must free
-   SERIAL unless the fucntion returns an error. */
+   SERIAL unless the function returns an error. */
 int 
 card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp)
 {
   char *s;
+  int rc;
 
   if (!card || !serial || !stamp)
     return GNUPG_Invalid_Value;
 
   *serial = NULL;
   *stamp = 0; /* not available */
+
+  if (!card->fnc.initialized)
+    {
+      card->fnc.initialized = 1;
+      /* The first use of this card tries to figure out the type of the card 
+         and sets up the function pointers. */
+      rc = sc_pkcs15_bind (card->scard, &card->p15card);
+      if (rc)
+        {
+          if (rc != SC_ERROR_PKCS15_APP_NOT_FOUND)
+            log_error ("binding of existing PKCS-15 failed in reader %d: %s\n",
+                       card->reader, sc_strerror (rc));
+          card->p15card = NULL;
+          rc = 0;
+        }
+      if (card->p15card)
+        card_p15_bind (card);
+      else
+        card_dinsig_bind (card);
+      card->fnc.initialized = 1;
+    }
+      
+
   if (!card->p15card)
     { /* fixme: construct a serial number */
-      /* We should lookup the iso 7812-1 and 8583-3 - argh ISO practice is
-         suppressing innovation - IETF rules! */
-      return GNUPG_No_PKCS15_App;
+      /* We should lookup the iso 7812-1 and 8583-3 - argh ISO
+         practice is suppressing innovation - IETF rules!  Anyway,
+         we try to get the serialnumber from the 2F00 GDO file. */
+      struct sc_path path;
+      struct sc_file *file;
+      unsigned char buf[12];
+      int i;
+
+      sc_format_path ("3F002F02", &path);
+      rc = sc_select_file (card->scard, &path, &file);
+      if (rc) 
+        {
+          log_error ("sc_select_file failed: %s\n", sc_strerror (rc));
+          return GNUPG_Card_Error;
+        }
+      if (file->type != SC_FILE_TYPE_WORKING_EF
+          || file->ef_structure != SC_FILE_EF_TRANSPARENT)
+        {
+          log_error ("wrong type or structure of GDO file\n");
+          sc_file_free (file);
+          return GNUPG_Card_Error;
+        }
+      if (file->size != 12)
+        { /* FIXME: Use a real parser */
+          log_error ("unsupported size of GDO file\n");
+          sc_file_free (file);
+          return GNUPG_Card_Error;
+        }
+      
+      rc = sc_read_binary (card->scard, 0, buf, DIM (buf), 0);
+      sc_file_free (file);
+      if (rc < 0) 
+        {
+          log_error ("error reading GDO file: %s\n", sc_strerror (rc));
+          return GNUPG_Card_Error;
+        }
+      if (rc != file->size)
+        {
+          log_error ("short read on GDO file\n");
+          return GNUPG_Card_Error;
+        }
+      if (buf[0] != 0x5a || buf[1] != 10)
+        {
+          log_error ("invalid structure of GDO file\n");
+          return GNUPG_Card_Error;
+        }
+      *serial = s = xtrymalloc (21);
+      if (!*serial)
+        return GNUPG_Out_Of_Core;
+      for (i=0; i < 10; i++, s += 2)
+        sprintf (s, "%02X", buf[2+i]);
+      return 0;
     }
   s = card->p15card->serial_number;
   if (!s || !hexdigitp (s) )
@@ -222,41 +313,12 @@ card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp)
 }
 
 
-\f
-/* Get the keygrip from CERT, return 0 on success */
-static int
-get_keygrip (KsbaCert cert, unsigned char *array)
-{
-  GCRY_SEXP s_pkey;
-  int rc;
-  KsbaSexp p;
-  size_t n;
-  
-  p = ksba_cert_get_public_key (cert);
-  if (!p)
-    return -1; /* oops */
-  n = gcry_sexp_canon_len (p, 0, NULL, NULL);
-  if (!n)
-    return -1; /* libksba did not return a proper S-expression */
-  rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n);
-  xfree (p);
-  if (rc)
-    return -1; /* can't parse that S-expression */
-  array = gcry_pk_get_keygrip (s_pkey, array);
-  gcry_sexp_release (s_pkey);
-  if (!array)
-    return -1; /* failed to calculate the keygrip */
-  return 0;
-}
-
-
-
 /* Enumerate all keypairs on the card and return the Keygrip as well
    as the internal identification of the key.  KEYGRIP must be a
    caller provided buffer with a size of 20 bytes which will receive
    the KEYGRIP of the keypair.  If KEYID is not NULL, it returns the
-   ID field of the key in allocated memory, NKEYID will then receive
-   the length of it.  The function returns -1 when all keys have been
+   ID field of the key in allocated memory; this is a string without
+   spaces.  The function returns -1 when all keys have been
    enumerated.  Note that the error GNUPG_Missing_Certificate may be
    returned if there is just the private key but no public key (ie.e a
    certificate) available.  Applications might want to continue
@@ -264,129 +326,29 @@ get_keygrip (KsbaCert cert, unsigned char *array)
 int
 card_enum_keypairs (CARD card, int idx,
                     unsigned char *keygrip,
-                    unsigned char **keyid, size_t *nkeyid)
+                    char **keyid)
 {
   int rc;
-  KsbaError krc;
-  struct sc_pkcs15_object *objs[32], *tmpobj;
-  int nobjs;
-  struct sc_pkcs15_prkey_info *pinfo;
-  struct sc_pkcs15_cert_info *certinfo;
-  struct sc_pkcs15_cert      *certder;
-  KsbaCert cert;
 
   if (keyid)
     *keyid = NULL;
-  if (nkeyid)
-    *nkeyid = 0;
 
-  if (!card || !keygrip || !card->p15card)
+  if (!card || !keygrip)
     return GNUPG_Invalid_Value;
   if (idx < 0)
     return GNUPG_Invalid_Index;
-       
-  rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_PRKEY_RSA, 
-                              objs, DIM (objs));
-  if (rc < 0) 
-    {
-      log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
-      return GNUPG_Card_Error;
-    }
-  nobjs = rc;
-  rc = 0;
-  if (idx >= nobjs)
-    return -1;
-  pinfo = objs[idx]->data;
-  
-  /* now we need to read the certificate so that we can calculate the
-     keygrip */
-  rc = sc_pkcs15_find_cert_by_id (card->p15card, &pinfo->id, &tmpobj);
-  if (rc)
-    {
-      log_info ("certificate for private key %d not found: %s\n",
-                idx, sc_strerror (rc));
-      /* but we should return the ID anyway */
-      if (keyid)
-        {
-          *keyid = xtrymalloc (pinfo->id.len);
-          if (!*keyid)
-            return GNUPG_Out_Of_Core;
-          memcpy (*keyid, pinfo->id.value, pinfo->id.len);
-        }
-      if (nkeyid)
-        *nkeyid = pinfo->id.len;
-      return GNUPG_Missing_Certificate;
-    }
-  certinfo = tmpobj->data;
-  rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
-  if (rc)
-    {
-      log_info ("failed to read certificate for private key %d: %s\n",
-                idx, sc_strerror (rc));
-      return GNUPG_Card_Error;
-    }
-
-  cert = ksba_cert_new ();
-  if (!cert)
-    {
-      sc_pkcs15_free_certificate (certder);
-      return GNUPG_Out_Of_Core;
-    }
-  krc = ksba_cert_init_from_mem (cert, certder->data, certder->data_len);
-  sc_pkcs15_free_certificate (certder);
-  if (krc)
-    {
-      log_error ("failed to parse the certificate for private key %d: %s\n",
-                 idx, ksba_strerror (krc));
-      ksba_cert_release (cert);
-      return GNUPG_Card_Error;
-    }
-  if (get_keygrip (cert, keygrip))
-    {
-      log_error ("failed to calculate the keygrip of private key %d\n", idx);
-      ksba_cert_release (cert);
-      return GNUPG_Card_Error;
-    }      
-  ksba_cert_release (cert);
-
-  /* return the iD */
-  if (keyid)
-    {
-      *keyid = xtrymalloc (pinfo->id.len);
-      if (!*keyid)
-        return GNUPG_Out_Of_Core;
-      memcpy (*keyid, pinfo->id.value, pinfo->id.len);
-    }
-  if (nkeyid)
-    *nkeyid = pinfo->id.len;
-  
-  return 0;
+  if (!card->fnc.initialized)
+    return GNUPG_Card_Not_Initialized;
+  if (!card->fnc.enum_keypairs)
+    return GNUPG_Unsupported_Operation;
+  rc = card->fnc.enum_keypairs (card, idx, keygrip, keyid);
+  if (opt.verbose)
+    log_info ("card operation enum_keypairs result: %s\n",
+              gnupg_strerror (rc));
+  return rc;
 }
 
 
-\f
-static int
-idstr_to_id (const char *idstr, struct sc_pkcs15_id *id)
-{
-  const char *s;
-  int n;
-
-  /* For now we only support the standard DF */
-  if (strncmp (idstr, "3F005015.", 9) ) 
-    return GNUPG_Invalid_Id;
-  for (s=idstr+9, n=0; hexdigitp (s); s++, n++)
-    ;
-  if (*s || (n&1))
-    return GNUPG_Invalid_Id; /* invalid or odd number of digits */
-  n /= 2;
-  if (!n || n > SC_PKCS15_MAX_ID_SIZE)
-    return GNUPG_Invalid_Id; /* empty or too large */
-  for (s=idstr+9, n=0; *s; s += 2, n++)
-    id->value[n] = xtoi_2 (s);
-  id->len = n;
-  return 0;
-}
-
 /* Read the certificate identified by CERTIDSTR which is the
    hexadecimal encoded ID of the certificate, prefixed with the string
    "3F005015.". The certificate is return in DER encoded form in CERT
@@ -395,148 +357,45 @@ int
 card_read_cert (CARD card, const char *certidstr,
                 unsigned char **cert, size_t *ncert)
 {
-  struct sc_pkcs15_object *tmpobj;
-  struct sc_pkcs15_id certid;
-  struct sc_pkcs15_cert_info *certinfo;
-  struct sc_pkcs15_cert      *certder;
   int rc;
 
-  if (!card || !certidstr || !card->p15card || !cert || !ncert)
+  if (!card || !certidstr || !cert || !ncert)
     return GNUPG_Invalid_Value;
-
-  rc = idstr_to_id (certidstr, &certid);
-  if (rc)
-    return rc;
-
-  rc = sc_pkcs15_find_cert_by_id (card->p15card, &certid, &tmpobj);
-  if (rc)
-    {
-      log_info ("certificate '%s' not found: %s\n", 
-                certidstr, sc_strerror (rc));
-      return -1;
-    }
-  certinfo = tmpobj->data;
-  rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder);
-  if (rc)
-    {
-      log_info ("failed to read certificate '%s': %s\n",
-                certidstr, sc_strerror (rc));
-      return GNUPG_Card_Error;
-    }
-
-  *cert = xtrymalloc (certder->data_len);
-  if (!*cert)
-    {
-      sc_pkcs15_free_certificate (certder);
-      return GNUPG_Out_Of_Core;
-    }
-  memcpy (*cert, certder->data, certder->data_len);
-  *ncert = certder->data_len;
-  sc_pkcs15_free_certificate (certder);
-  return 0;
+  if (!card->fnc.initialized)
+    return GNUPG_Card_Not_Initialized;
+  if (!card->fnc.read_cert)
+    return GNUPG_Unsupported_Operation;
+  rc = card->fnc.read_cert (card, certidstr, cert, ncert);
+  if (opt.verbose)
+    log_info ("card operation read_cert result: %s\n", gnupg_strerror (rc));
+  return rc;
 }
 
 
-\f
 /* 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 
-card_create_signature (CARD card, 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 )
+card_sign (CARD card, 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 )
 {
-  unsigned int cryptflags = 0;
-  struct sc_pkcs15_id keyid;
-  struct sc_pkcs15_prkey_info *key;
-  struct sc_pkcs15_pin_info *pin;
-  struct sc_pkcs15_object *keyobj, *pinobj;
-  char *pinvalue;
   int rc;
-  unsigned char *outbuf = NULL;
-  size_t outbuflen;
 
-  if (!card || !card->p15card || !indata || !indatalen
-      || !outdata || !outdatalen || !pincb)
+  if (!card || !indata || !indatalen || !outdata || !outdatalen || !pincb)
     return GNUPG_Invalid_Value;
-  
-  if (hashalgo != GCRY_MD_SHA1)
-    return GNUPG_Unsupported_Algorithm;
-
-  rc = idstr_to_id (keyidstr, &keyid);
-  if (rc)
-    return rc;
-
-  rc = sc_pkcs15_find_prkey_by_id (card->p15card, &keyid, &keyobj);
-  if (rc < 0)
-    {
-      log_error ("private key not found: %s\n", sc_strerror(rc));
-      rc = GNUPG_No_Secret_Key;
-      goto leave;
-    }
-  rc = 0;
-  key = keyobj->data;
-
-  rc = sc_pkcs15_find_pin_by_auth_id (card->p15card,
-                                      &keyobj->auth_id, &pinobj);
-  if (rc)
-    {
-      log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc));
-      rc = GNUPG_Bad_PIN_Method;
-      goto leave;
-    }
-  pin = pinobj->data;
-
-  /* Fixme: pack this into a verification loop */
-  /* Fixme: we might want to pass pin->min_length and 
-     pin->stored_length */
-  rc = pincb (pincb_arg, pinobj->label, &pinvalue);
-  if (rc)
-    {
-      log_info ("PIN callback returned error: %s\n", gnupg_strerror (rc));
-      goto leave;
-    }
-
-  rc = sc_pkcs15_verify_pin (card->p15card, pin,
-                             pinvalue, strlen (pinvalue));
-  xfree (pinvalue);
-  if (rc)
-    {
-      log_info ("PIN verification failed: %s\n", sc_strerror (rc));
-      rc = GNUPG_Bad_PIN;
-      goto leave;
-    }
-
-/*    cryptflags |= SC_PKCS15_HASH_SHA1; */
-/*    cryptflags |= SC_PKCS15_PAD_PKCS1_V1_5; */
-
-  outbuflen = 1024; 
-  outbuf = xtrymalloc (outbuflen);
-  if (!outbuf)
-    return GNUPG_Out_Of_Core;
-  
-  rc = sc_pkcs15_compute_signature (card->p15card, key,
-                                    cryptflags,
-                                    indata, indatalen,
-                                    outbuf, outbuflen );
-  if (rc < 0)
-    {
-      log_error ("failed to create signature: %s\n", sc_strerror (rc));
-      rc = GNUPG_Card_Error;
-    }
-  else
-    {
-      *outdatalen = rc;
-      *outdata = outbuf;
-      outbuf = NULL;
-      rc = 0;
-    }
-
-
-leave:
-  xfree (outbuf);
+  if (!card->fnc.initialized)
+    return GNUPG_Card_Not_Initialized;
+  if (!card->fnc.sign)
+    return GNUPG_Unsupported_Operation;
+  rc =  card->fnc.sign (card, keyidstr, hashalgo,
+                        pincb, pincb_arg,
+                        indata, indatalen,
+                        outdata, outdatalen);
+  if (opt.verbose)
+    log_info ("card operation sign result: %s\n", gnupg_strerror (rc));
   return rc;
 }
 
@@ -551,93 +410,19 @@ card_decipher (CARD card, const char *keyidstr,
                const void *indata, size_t indatalen,
                void **outdata, size_t *outdatalen )
 {
-  struct sc_pkcs15_id keyid;
-  struct sc_pkcs15_prkey_info *key;
-  struct sc_pkcs15_pin_info *pin;
-  struct sc_pkcs15_object *keyobj, *pinobj;
-  char *pinvalue;
   int rc;
-  unsigned char *outbuf = NULL;
-  size_t outbuflen;
 
-  if (!card || !card->p15card || !indata || !indatalen
-      || !outdata || !outdatalen || !pincb)
+  if (!card || !indata || !indatalen || !outdata || !outdatalen || !pincb)
     return GNUPG_Invalid_Value;
-  
-  rc = idstr_to_id (keyidstr, &keyid);
-  if (rc)
-    return rc;
-
-  rc = sc_pkcs15_find_prkey_by_id (card->p15card, &keyid, &keyobj);
-  if (rc < 0)
-    {
-      log_error ("private key not found: %s\n", sc_strerror(rc));
-      rc = GNUPG_No_Secret_Key;
-      goto leave;
-    }
-  rc = 0;
-  key = keyobj->data;
-
-  rc = sc_pkcs15_find_pin_by_auth_id (card->p15card,
-                                      &keyobj->auth_id, &pinobj);
-  if (rc)
-    {
-      log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc));
-      rc = GNUPG_Bad_PIN_Method;
-      goto leave;
-    }
-  pin = pinobj->data;
-
-  /* Fixme: pack this into a verification loop */
-  /* Fixme: we might want to pass pin->min_length and 
-     pin->stored_length */
-  rc = pincb (pincb_arg, pinobj->label, &pinvalue);
-  if (rc)
-    {
-      log_info ("PIN callback returned error: %s\n", gnupg_strerror (rc));
-      goto leave;
-    }
-
-  rc = sc_pkcs15_verify_pin (card->p15card, pin,
-                             pinvalue, strlen (pinvalue));
-  xfree (pinvalue);
-  if (rc)
-    {
-      log_info ("PIN verification failed: %s\n", sc_strerror (rc));
-      rc = GNUPG_Bad_PIN;
-      goto leave;
-    }
-
-  outbuflen = indatalen < 256? 256 : indatalen; 
-  outbuf = xtrymalloc (outbuflen);
-  if (!outbuf)
-    return GNUPG_Out_Of_Core;
-
-  /* OpenSC does not yet support decryption for cryptflex cards */  
-/*    rc = sc_pkcs15_decipher (card->p15card, key, */
-/*                             indata, indatalen, */
-/*                             outbuf, outbuflen); */
-  rc = sc_pkcs15_compute_signature (card->p15card, key,
-                                    0,
-                                    indata, indatalen,
-                                    outbuf, outbuflen );
-  if (rc < 0)
-    {
-      log_error ("failed to decipger the data: %s\n", sc_strerror (rc));
-      rc = GNUPG_Card_Error;
-    }
-  else
-    {
-      *outdatalen = rc;
-      *outdata = outbuf;
-      outbuf = NULL;
-      rc = 0;
-    }
-
-
-leave:
-  xfree (outbuf);
+  if (!card->fnc.initialized)
+    return GNUPG_Card_Not_Initialized;
+  if (!card->fnc.decipher)
+    return GNUPG_Unsupported_Operation;
+  rc =  card->fnc.decipher (card, keyidstr,
+                            pincb, pincb_arg,
+                            indata, indatalen,
+                            outdata, outdatalen);
+  if (opt.verbose)
+    log_info ("card operation decipher result: %s\n", gnupg_strerror (rc));
   return rc;
 }
-
-
index 5186a2f..8f005a3 100644 (file)
@@ -212,12 +212,10 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
   for (idx=0; !rc; idx++)
     {
       unsigned char keygrip[20];
-      unsigned char *keyid;
-      size_t nkeyid;
+      char *keyid;
       int no_cert = 0;
 
-      rc = card_enum_keypairs (ctrl->card_ctx, idx, 
-                               keygrip, &keyid, &nkeyid);
+      rc = card_enum_keypairs (ctrl->card_ctx, idx, keygrip, &keyid);
       if (rc == GNUPG_Missing_Certificate && keyid)
         {
           /* this does happen with an incomplete personalized
@@ -232,7 +230,7 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
         {
           char *buf, *p;
 
-          buf = p = xtrymalloc (40+1+9+2*nkeyid+1);
+          buf = p = xtrymalloc (40 + 1 + strlen (keyid) + 1);
           if (!buf)
             rc = GNUPG_Out_Of_Core;
           else
@@ -247,11 +245,7 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
                     sprintf (p, "%02X", keygrip[i]);
                 }
               *p++ = ' ';
-              /* fixme: we need to get the pkcs-15 DF from the card function */
-              p = stpcpy (p, "3F005015.");
-              for (i=0; i < nkeyid; i++, p += 2)
-                sprintf (p, "%02X", keyid[i]);
-              *p = 0;
+              strcpy (p, keyid);
               assuan_write_status (ctx, "KEYPAIRINFO", buf);
               xfree (buf);
             }
@@ -440,14 +434,14 @@ cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
   if ((rc = open_card (ctrl)))
     return rc;
 
-  rc = card_create_signature (ctrl->card_ctx,
-                              line, GCRY_MD_SHA1,
-                              pin_cb, ctx,
-                              ctrl->in_data.value, ctrl->in_data.valuelen,
-                              &outdata, &outdatalen);
+  rc = card_sign (ctrl->card_ctx,
+                  line, GCRY_MD_SHA1,
+                  pin_cb, ctx,
+                  ctrl->in_data.value, ctrl->in_data.valuelen,
+                  &outdata, &outdatalen);
   if (rc)
     {
-      log_error ("card_create_signature failed: %s\n", gnupg_strerror (rc));
+      log_error ("card_sign failed: %s\n", gnupg_strerror (rc));
     }
   else
     {
index bd604b4..9c8af5d 100644 (file)
@@ -83,15 +83,15 @@ void card_close (CARD card);
 int card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp);
 int card_enum_keypairs (CARD card, int idx,
                         unsigned char *keygrip,
-                        unsigned char **keyid, size_t *nkeyid);
+                        char **keyid);
 int card_read_cert (CARD card, const char *certidstr,
                     unsigned char **cert, size_t *ncert);
-int card_create_signature (CARD card,
-                           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 card_sign (CARD card,
+               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 card_decipher (CARD card, const char *keyidstr,
                    int (pincb)(void*, const char *, char **),
                    void *pincb_arg,
index e7a1ae9..f70615e 100644 (file)
@@ -178,7 +178,7 @@ base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
           if (c == '\n')
             {
               parm->have_lf = 1;
-              /* FIXME: we need to skip overlong lines while detecting
+              /* Fixme: we need to skip overlong lines while detecting
                  the dashed lines */
               break;
             }
index 7065ab8..a7e7a31 100644 (file)
@@ -553,7 +553,7 @@ learn_cb (void *opaque, const void *buffer, size_t length)
     }
 
 
-  /* FIXME: this shoudl go inot import.c */
+  /* FIXME: this should go into import.c */
   cert = ksba_cert_new ();
   if (!cert)
     {
index 07f2d35..612a3d2 100644 (file)
@@ -256,10 +256,6 @@ gpgsm_create_cms_signature (KsbaCert cert, GCRY_MD_HD md, int mdalgo,
                            gcry_md_get_algo_dlen (mdalgo), mdalgo,
                            r_sigval, &siglen);
   xfree (grip);
-  /* FIXME: we should check that the returned S-Exp is valid fits int
-     siglen.  It ould probably be a good idea to scan and print it
-     again to make this sure and be sure that we have canoncical
-     encoding */
   return rc;
 }
 
index c9da002..4e513a2 100644 (file)
@@ -82,7 +82,7 @@ prepare_decryption (const char *hexkeygrip, KsbaConstSexp enc_val,
   /* FIXME: Actually the leading zero is required but due to the way
      we encode the output in libgcrypt as an MPI we are not able to
      encode that leading zero.  However, when using a Smartcard we are
-     doing it the rightway and therefore we have skip the zero.  This
+     doing it the rightway and therefore we have to skip the zero.  This
      should be fixed in gpg-agent of course. */
   if (!seskey[n])
     n++;
index 142e170..f0fa98f 100644 (file)
@@ -580,7 +580,7 @@ main ( int argc, char **argv)
   struct server_control_s ctrl;
   CERTLIST recplist = NULL;
 
-  /* fixme: trap_unaligned ();*/
+  /* trap_unaligned ();*/
   set_strusage (my_strusage);
   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
   /* Please note that we may running SUID(ROOT), so be very CAREFUL
@@ -1048,7 +1048,7 @@ main ( int argc, char **argv)
     case aSign: /* sign the given file */
       /* FIXME: we can only do detached sigs for now and we don't
          handle --output yet. We should also allow to concatenate
-         multiple files for signins because that is what gpg does.*/
+         multiple files for signing because that is what gpg does.*/
       if (!argc)
         gpgsm_sign (&ctrl, 0, 1, stdout); /* create from stdin */
       else if (argc == 1)