summaryrefslogtreecommitdiffstats
path: root/scd/card-p15.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2002-08-16 12:33:31 +0200
committerWerner Koch <wk@gnupg.org>2002-08-16 12:33:31 +0200
commitfd2f1c8aa3190d55cb16fd6d2aab994447ab3bf8 (patch)
treed88d5f3480e5c6856a8a8c1947de91b4a9d06176 /scd/card-p15.c
parentRemoved a leftover conflict indicator. (diff)
downloadgnupg2-fd2f1c8aa3190d55cb16fd6d2aab994447ab3bf8.tar.xz
gnupg2-fd2f1c8aa3190d55cb16fd6d2aab994447ab3bf8.zip
* 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.
Diffstat (limited to 'scd/card-p15.c')
-rw-r--r--scd/card-p15.c73
1 files changed, 63 insertions, 10 deletions
diff --git a/scd/card-p15.c b/scd/card-p15.c
index 6248ddfe2..c0758161f 100644
--- a/scd/card-p15.c
+++ b/scd/card-p15.c
@@ -32,6 +32,61 @@
#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 */