* scdaemon.c: Include i18n.h.
authorWerner Koch <wk@gnupg.org>
Fri, 16 Aug 2002 14:23:40 +0000 (14:23 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 16 Aug 2002 14:23:40 +0000 (14:23 +0000)
* 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_enum_certs): New.
* 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.
(p15_enum_certs): New.
(card_p15_bind): Bind new function.
* command.c (cmd_learn): Return information about the certificates.

scd/ChangeLog
scd/card-common.h
scd/card-p15.c
scd/card.c
scd/command.c
scd/scdaemon.c
scd/scdaemon.h

index 32ed893..da3cdb4 100644 (file)
@@ -1,11 +1,17 @@
 2002-08-16  Werner Koch  <wk@gnupg.org>
 
+       * scdaemon.c: Include i18n.h.
+
        * 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_enum_certs): New.
        * 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.
+       (p15_enum_certs): New.
+       (card_p15_bind): Bind new function.
+       * command.c (cmd_learn): Return information about the certificates.
 
 2002-08-09  Werner Koch  <wk@gnupg.org>
 
index 62b9a87..50014ce 100644 (file)
@@ -40,6 +40,7 @@ struct card_ctx_s {
 
     int (*enum_keypairs) (CARD card, int idx,
                           unsigned char *keygrip, char **keyid);
+    int (*enum_certs) (CARD card, int idx, char **certid, int *certtype);
     int (*read_cert) (CARD card, const char *certidstr,
                       unsigned char **cert, size_t *ncert);
     int (*sign) (CARD card,
index c075816..25502a6 100644 (file)
@@ -35,6 +35,8 @@
 struct p15private_s {
   int n_prkey_rsa_objs;
   struct sc_pkcs15_object *prkey_rsa_objs[32];
+  int n_cert_objs;
+  struct sc_pkcs15_object *cert_objs[32];
 };
 
 
@@ -70,6 +72,19 @@ init_private_data (CARD card)
       return GNUPG_Card_Error;
     }
   priv->n_prkey_rsa_objs = rc;
+
+  /* Read all certificate objects. */
+  rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_CERT_X509, 
+                              priv->cert_objs,
+                              DIM (priv->cert_objs));
+  if (rc < 0) 
+    {
+      log_error ("private keys enumeration failed: %s\n", sc_strerror (rc));
+      xfree (priv);
+      return GNUPG_Card_Error;
+    }
+  priv->n_cert_objs = rc;
+
   card->p15priv = priv;
   return 0;
 }
@@ -174,6 +189,57 @@ p15_enum_keypairs (CARD card, int idx,
   return rc;
 }
 
+/* See card.c for interface description */
+static int
+p15_enum_certs (CARD card, int idx, char **certid, int *type)
+{
+  int rc;
+  struct p15private_s *priv;
+  struct sc_pkcs15_object *obj;
+  struct sc_pkcs15_cert_info *cinfo;
+  int nobjs;
+
+  rc = init_private_data (card);
+  if (rc) 
+      return rc;
+  priv = card->p15priv;
+  nobjs = priv->n_cert_objs;
+  rc = 0;
+  if (idx >= nobjs)
+    return -1;
+  obj =  priv->cert_objs[idx];
+  cinfo = obj->data;
+  
+  if (certid)
+    {
+      char *p;
+      int i;
+
+      *certid = p = xtrymalloc (9+cinfo->id.len*2+1);
+      if (!*certid)
+        return GNUPG_Out_Of_Core;
+      p = stpcpy (p, "P15-5015.");
+      for (i=0; i < cinfo->id.len; i++, p += 2)
+        sprintf (p, "%02X", cinfo->id.value[i]);
+      *p = 0;
+    }
+  if (type)
+    {
+      if (!obj->df)
+        *type = 0; /* unknown */
+      else if (obj->df->type == SC_PKCS15_CDF)
+        *type = 100;
+      else if (obj->df->type == SC_PKCS15_CDF_TRUSTED)
+        *type = 101;
+      else if (obj->df->type == SC_PKCS15_CDF_USEFUL)
+        *type = 102;
+      else 
+        *type = 0; /* error -> unknown */
+    }
+  
+  return rc;
+}
+
 
 \f
 static int
@@ -425,6 +491,7 @@ void
 card_p15_bind (CARD card)
 {
   card->fnc.enum_keypairs = p15_enum_keypairs;
+  card->fnc.enum_certs    = p15_enum_certs;
   card->fnc.read_cert     = p15_read_cert;
   card->fnc.sign          = p15_sign;
   card->fnc.decipher      = p15_decipher;
index 34812b8..9e0f060 100644 (file)
@@ -428,6 +428,39 @@ card_enum_keypairs (CARD card, int idx,
 }
 
 
+/* Enumerate all trusted certificates available on the card, return
+   their ID in CERT and the type in CERTTYPE.  Types of certificates
+   are:
+      0   := Unknown
+      100 := Regular X.509 cert
+      101 := Trusted X.509 cert
+      102 := Useful X.509 cert
+ */
+int
+card_enum_certs (CARD card, int idx, char **certid, int *certtype)
+{
+  int rc;
+
+  if (certid)
+    *certid = NULL;
+
+  if (!card)
+    return GNUPG_Invalid_Value;
+  if (idx < 0)
+    return GNUPG_Invalid_Index;
+  if (!card->fnc.initialized)
+    return GNUPG_Card_Not_Initialized;
+  if (!card->fnc.enum_certs)
+    return GNUPG_Unsupported_Operation;
+  rc = card->fnc.enum_certs (card, idx, certid, certtype);
+  if (opt.verbose)
+    log_info ("card operation enum_certs result: %s\n",
+              gnupg_strerror (rc));
+  return rc;
+}
+
+
+
 /* 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
index 9e0ddc5..aa410a6 100644 (file)
@@ -151,7 +151,17 @@ cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
      S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>
 
    If there is no certificate yet stored on the card a single "X" is
-   returned as the keygrip.
+   returned as the keygrip.  In addition to the keypair info, information
+   about all certificates stored on the card is also returned:
+
+     S CERTINFO <certtype> <hexstring_with_id>
+
+   Where CERTINFO 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
+
 
 */
 static int
@@ -209,6 +219,34 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
     free (serial_and_stamp);
   }
 
+  /* Return information about the certificates. */
+  for (idx=0; !rc; idx++)
+    {
+      char *certid;
+      int certtype;
+
+      rc = card_enum_certs (ctrl->card_ctx, idx, &certid, &certtype);
+      if (!rc)
+        {
+          char *buf;
+
+          buf = xtrymalloc (40 + 1 + strlen (certid) + 1);
+          if (!buf)
+            rc = GNUPG_Out_Of_Core;
+          else
+            {
+              sprintf (buf, "%d %s", certtype, certid);
+              assuan_write_status (ctx, "CERTINFO", buf);
+              xfree (buf);
+            }
+        }
+      xfree (certid);
+    }
+  if (rc == -1)
+    rc = 0;
+
+
+  /* Return information about the keys. */
   for (idx=0; !rc; idx++)
     {
       unsigned char keygrip[20];
index 29256d8..6001faf 100644 (file)
 #include "scdaemon.h"
 #include "../assuan/assuan.h" /* malloc hooks */
 
+#include "i18n.h"
 #include "sysutils.h"
 
 
-#define N_(a) a
-#define _(a) a
-
 
 enum cmd_and_opt_values 
 { aNull = 0,
index 97bf93d..9fbf891 100644 (file)
@@ -85,6 +85,7 @@ int card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp);
 int card_enum_keypairs (CARD card, int idx,
                         unsigned char *keygrip,
                         char **keyid);
+int card_enum_certs (CARD card, int idx, char **certid, int *certtype);
 int card_read_cert (CARD card, const char *certidstr,
                     unsigned char **cert, size_t *ncert);
 int card_sign (CARD card,