* card-common.h (struct p15_private_s): Forward declaration. Add
authorWerner Koch <wk@gnupg.org>
Fri, 16 Aug 2002 10:33:31 +0000 (10:33 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 16 Aug 2002 10:33:31 +0000 (10:33 +0000)
it to card_ctx_s.
* card.c (card_close): Make sure private data is released.
* card-p15.c (p15_release_private_data): New.
(init_private_data): New to work around an OpenSC weirdness.
(p15_enum_keypairs): Do an OpenSC get_objects only once.

scd/ChangeLog
scd/Makefile.am
scd/card-common.h
scd/card-p15.c
scd/card.c

index e0cfda8..32ed893 100644 (file)
@@ -1,3 +1,12 @@
+2002-08-16  Werner Koch  <wk@gnupg.org>
+
+       * card-common.h (struct p15_private_s): Forward declaration.  Add
+       it to card_ctx_s.
+       * card.c (card_close): Make sure private data is released.
+       * card-p15.c (p15_release_private_data): New.
+       (init_private_data): New to work around an OpenSC weirdness.
+       (p15_enum_keypairs): Do an OpenSC get_objects only once.
+
 2002-08-09  Werner Koch  <wk@gnupg.org>
 
        * card.c (card_get_serial_and_stamp): Use the tokeinfo serial
index b306a3a..8812d1b 100644 (file)
@@ -23,8 +23,8 @@ INCLUDES = -I../intl -DLOCALEDIR=\"$(localedir)\"
 
 bin_PROGRAMS = scdaemon
 
-AM_CPPFLAGS = -I$(top_srcdir)/common $(LIBOPENSC_CFLAGS) $(LIBGCRYPT_CFLAGS) \
-             $(LIBKSBA_CFLAGS)
+AM_CPPFLAGS = -I$(top_srcdir)/common $(OPENSC_CFLAGS) $(LIBGCRYPT_CFLAGS) \
+             $(KSBA_CFLAGS)
 LDFLAGS = @LDFLAGS@ 
 
 scdaemon_SOURCES = \
@@ -33,12 +33,9 @@ scdaemon_SOURCES = \
        card-common.h \
        card-p15.c card-dinsig.c
 
-# fixme: We added -lpcslite because the opensc config script can't cope with 
-# a static only libopensc.
 scdaemon_LDADD = ../jnlib/libjnlib.a ../assuan/libassuan.a  \
                ../common/libcommon.a \
-               $(LIBOPENSC_LIBS) $(LIBGCRYPT_LIBS) $(LIBKSBA_LIBS) \
-               -lpcsclite -lpthread
+               $(OPENSC_LIBS) $(LIBGCRYPT_LIBS) $(KSBA_LIBS) 
 
 
 
index 1c912b7..62b9a87 100644 (file)
 #ifndef CARD_COMMON_H
 #define CARD_COMMON_H
 
+/* Declaration of private data structure used by card-p15.c */
+struct p15private_s;
+
 
 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 */
+  struct p15private_s *p15priv;   /* private data used by card-p15.c */
 
   struct {
     int initialized;  /* the card has been initialied and the function
@@ -57,7 +61,8 @@ struct card_ctx_s {
 int map_sc_err (int rc);
 int card_help_get_keygrip (KsbaCert cert, unsigned char *array);
 
-
+/*-- card-15.c --*/
+void p15_release_private_data (CARD card);
 
 /* constructors */
 void card_p15_bind (CARD card);
index 6248ddf..c075816 100644 (file)
 #include "card-common.h"
 
 
+struct p15private_s {
+  int n_prkey_rsa_objs;
+  struct sc_pkcs15_object *prkey_rsa_objs[32];
+};
+
+
+/* Allocate private data. */
+static int 
+init_private_data (CARD card)
+{
+  struct p15private_s *priv;
+  int rc;
+
+  if (card->p15priv)
+    return 0; /* already done. */
+
+  priv = xtrycalloc (1, sizeof *priv);
+  if (!priv)
+    return GNUPG_Out_Of_Core;
+
+  /* OpenSC (0.7.0) is a bit strange in that the get_objects functions
+     tries to be a bit too clever and implicitly does an enumeration
+     which eventually leads to the fact that every call to this
+     fucntion returns one more macthing object.  The old code in
+     p15_enum_keypairs assume that it would alwyas return the same
+     numer of objects and used this to figure out what the last object
+     enumerated is.  We now do an enum_objects just once and keep it
+     in the private data. */
+  rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_PRKEY_RSA, 
+                              priv->prkey_rsa_objs,
+                              DIM (priv->prkey_rsa_objs));
+  if (rc < 0) 
+    {
+      log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
+      xfree (priv);
+      return GNUPG_Card_Error;
+    }
+  priv->n_prkey_rsa_objs = rc;
+  card->p15priv = priv;
+  return 0;
+}
+
+
+/* Release private data used in this module. */
+void
+p15_release_private_data (CARD card)
+{
+  if (!card->p15priv)
+    return;
+  xfree (card->p15priv);
+  card->p15priv = NULL;
+}
+
+
+
 /* See card.c for interface description */
 static int
 p15_enum_keypairs (CARD card, int idx,
@@ -39,25 +94,23 @@ p15_enum_keypairs (CARD card, int idx,
 {
   int rc;
   KsbaError krc;
-  struct sc_pkcs15_object *objs[32], *tmpobj;
+  struct p15private_s *priv;
+  struct sc_pkcs15_object *tmpobj;
   int nobjs;
   struct sc_pkcs15_prkey_info *pinfo;
   struct sc_pkcs15_cert_info *certinfo;
   struct sc_pkcs15_cert      *certder;
   KsbaCert cert;
 
-  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 = init_private_data (card);
+  if (rc) 
+      return rc;
+  priv = card->p15priv;
+  nobjs = priv->n_prkey_rsa_objs;
   rc = 0;
   if (idx >= nobjs)
     return -1;
-  pinfo = objs[idx]->data;
+  pinfo = priv->prkey_rsa_objs[idx]->data;
   
   /* now we need to read the certificate so that we can calculate the
      keygrip */
index 9c22867..34812b8 100644 (file)
@@ -162,6 +162,8 @@ card_close (CARD card)
           sc_pkcs15_unbind (card->p15card);
           card->p15card = NULL;
         }
+      if (card->p15priv)
+        p15_release_private_data (card);
       if (card->scard)
         {
           sc_unlock (card->scard);