Bug fixes and ssh support for the BELPIC.
authorWerner Koch <wk@gnupg.org>
Fri, 9 Sep 2005 11:18:08 +0000 (11:18 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 9 Sep 2005 11:18:08 +0000 (11:18 +0000)
15 files changed:
NEWS
agent/ChangeLog
agent/command-ssh.c
agent/minip12.c
po/de.po
scd/ChangeLog
scd/app-openpgp.c
scd/app-p15.c
scd/ccid-driver.c
scd/ccid-driver.h
scd/iso7816.c
scd/iso7816.h
scd/pcsc-wrapper.c
sm/ChangeLog
sm/export.c

diff --git a/NEWS b/NEWS
index 75410e8..acc7c25 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,10 @@
 Noteworthy changes in version 1.9.19
 -------------------------------------------------
 
- * The Belgian eID card is now supported.
+ * The Belgian eID card is now supported for signatures and ssh.
 
+ * Fixed bug in --export-secret-key-p12 so that certificates are again
+   included.
 
 Noteworthy changes in version 1.9.18 (2005-08-01)
 -------------------------------------------------
index adb7b1b..83e1fe8 100644 (file)
@@ -1,3 +1,17 @@
+2005-09-09  Werner Koch  <wk@g10code.com>
+
+       * minip12.c (p12_build): Oops, array needs to be larger for the
+       certificate.
+
+       * command-ssh.c (card_key_available): Let the card handler decide
+       whether the card is supported here.  Also get a short serial
+       number to return from the card handler.
+
+2005-09-08  Werner Koch  <wk@g10code.com>
+
+       * minip12.c (build_cert_bag): Use a non constructed object.
+       i.e. 0x80 and not 0xa0.
+
 2005-08-16  Werner Koch  <wk@g10code.com>
 
        * gpg-agent.c (main): Use a default file name for --write-env-file.
index 642bcbb..b8f0d20 100644 (file)
@@ -1583,13 +1583,13 @@ key_secret_to_public (gcry_sexp_t *key_public,
 /* Check whether a smartcard is available and whether it has a usable
    key.  Store a copy of that key at R_PK and return 0.  If no key is
    available store NULL at R_PK and return an error code.  If CARDSN
-   is no NULL, a string with the serial number of the card will be
+   is not NULL, a string with the serial number of the card will be
    a malloced and stored there. */
 static gpg_error_t
 card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
 {
   gpg_error_t err;
-  char *appname;
+  char *authkeyid;
   char *serialno = NULL;
   unsigned char *pkbuf;
   size_t pkbuflen;
@@ -1602,7 +1602,7 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
 
   /* First see whether a card is available and whether the application
      is supported.  */
-  err = agent_card_getattr (ctrl, "APPTYPE", &appname);
+  err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
   if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED )
     {
       /* Ask for the serial number to reset the card.  */
@@ -1615,40 +1615,33 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
           return err;
         }
       log_info (_("detected card with S/N: %s\n"), serialno);
-      err = agent_card_getattr (ctrl, "APPTYPE", &appname);
+      err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
     }
   if (err)
     {
-      log_error (_("error getting application type of card: %s\n"),
+      log_error (_("error getting default authentication keyID of card: %s\n"),
                  gpg_strerror (err));
       xfree (serialno);
       return err;
     }
-  if (strcmp (appname, "OPENPGP"))
-    {
-      log_info (_("card application `%s' is not supported\n"), appname);
-      xfree (appname);
-      xfree (serialno);
-      return gpg_error (GPG_ERR_NOT_SUPPORTED);
-    }
-  xfree (appname);
-  appname = NULL;
 
   /* Get the S/N if we don't have it yet.  Use the fast getattr method.  */
   if (!serialno && (err = agent_card_getattr (ctrl, "SERIALNO", &serialno)) )
     {
       log_error (_("error getting serial number of card: %s\n"),
                  gpg_strerror (err));
+      xfree (authkeyid);
       return err;
     }
 
   /* Read the public key.  */
-  err = agent_card_readkey (ctrl, "OPENPGP.3", &pkbuf);
+  err = agent_card_readkey (ctrl, authkeyid, &pkbuf);
   if (err)
     {
       if (opt.verbose)
         log_info (_("no suitable card key found: %s\n"), gpg_strerror (err));
       xfree (serialno);
+      xfree (authkeyid);
       return err;
     }
 
@@ -1660,6 +1653,7 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
                  gpg_strerror (err));
       xfree (pkbuf);
       xfree (serialno);
+      xfree (authkeyid);
       return err;
     }
 
@@ -1671,6 +1665,7 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
       xfree (pkbuf);
       gcry_sexp_release (s_pk);
       xfree (serialno);
+      xfree (authkeyid);
       return err;
     }
 
@@ -1680,13 +1675,14 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
       unsigned char *shadow_info;
       unsigned char *tmp;
       
-      shadow_info = make_shadow_info (serialno, "OPENPGP.3");
+      shadow_info = make_shadow_info (serialno, authkeyid);
       if (!shadow_info)
         {
           err = gpg_error_from_errno (errno);
           xfree (pkbuf);
           gcry_sexp_release (s_pk);
           xfree (serialno);
+          xfree (authkeyid);
           return err;
         }
       err = agent_shadow_key (pkbuf, shadow_info, &tmp);
@@ -1697,6 +1693,7 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
           xfree (pkbuf);
           gcry_sexp_release (s_pk);
           xfree (serialno);
+          xfree (authkeyid);
           return err;
         }
       xfree (pkbuf);
@@ -1711,18 +1708,23 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
           xfree (pkbuf);
           gcry_sexp_release (s_pk);
           xfree (serialno);
+          xfree (authkeyid);
           return err;
         }
     }
 
   if (cardsn)
     {
-      size_t snlen = strlen (serialno);
+      char *dispsn;
 
-      if (snlen == 32
-          && !memcmp (serialno, "D27600012401", 12)) /* OpenPGP card. */
-        *cardsn = xtryasprintf ("cardno:%.12s", serialno+16);
-      else /* Something is wrong: Print all. */
+      /* If the card handler is able to return a short serialnumber,
+         use that one, else use the complete serialno. */
+      if (!agent_card_getattr (ctrl, "$DISPSERIALNO", &dispsn))
+        {
+          *cardsn = xtryasprintf ("cardno:%s", dispsn);
+          xfree (dispsn);
+        }
+      else
         *cardsn = xtryasprintf ("cardno:%s", serialno);
       if (!*cardsn)
         {
@@ -1730,12 +1732,14 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
           xfree (pkbuf);
           gcry_sexp_release (s_pk);
           xfree (serialno);
+          xfree (authkeyid);
           return err;
         }
     }
 
   xfree (pkbuf);
   xfree (serialno);
+  xfree (authkeyid);
   *r_pk = s_pk;
   return 0;
 }
index 0300439..ea9f9b1 100644 (file)
@@ -1409,7 +1409,7 @@ build_cert_bag (unsigned char *buffer, size_t buflen, char *salt,
   p += DIM (oid_encryptedData); 
 
   /* 2. Store a [0] tag. */
-  p = store_tag_length (p, 0xa0, len[2]);
+  p = store_tag_length (p, 0x80, len[2]);
 
   /* 3. Store a sequence. */
   p = store_tag_length (p, TAG_SEQUENCE, len[3]);
@@ -1553,7 +1553,7 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
   unsigned char *buffer;
   size_t n, buflen;
   char salt[8];
-  struct buffer_s seqlist[2];
+  struct buffer_s seqlist[3];
   int seqlistidx = 0;
 
   n = buflen = 0; /* (avoid compiler warning). */
index 69606fa..11f2c8a 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnupg2 1.9.18\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"POT-Creation-Date: 2005-09-06 20:01+0200\n"
+"POT-Creation-Date: 2005-09-09 12:47+0200\n"
 "PO-Revision-Date: 2005-08-02 17:02+0200\n"
 "Last-Translator: Werner Koch <wk@gnupg.org>\n"
 "Language-Team: de\n"
@@ -605,52 +605,52 @@ msgstr "Der Fingerprint kann nicht gespeichert werden: %s\n"
 msgid "failed to store the creation date: %s\n"
 msgstr "Das Erzeugungsdatum kann nicht gespeichert werden: %s\n"
 
-#: scd/app-openpgp.c:978
+#: scd/app-openpgp.c:1003
 #, c-format
 msgid "reading public key failed: %s\n"
 msgstr "Fehler beim Lesen des öffentlichen Schlüssels: %s\n"
 
-#: scd/app-openpgp.c:986 scd/app-openpgp.c:1917
+#: scd/app-openpgp.c:1011 scd/app-openpgp.c:1942
 msgid "response does not contain the public key data\n"
 msgstr "Die Antwort enthält keine Public Key Daten\n"
 
-#: scd/app-openpgp.c:994 scd/app-openpgp.c:1925
+#: scd/app-openpgp.c:1019 scd/app-openpgp.c:1950
 msgid "response does not contain the RSA modulus\n"
 msgstr "Die Antwort enthält keinen RSA Modulus\n"
 
-#: scd/app-openpgp.c:1003 scd/app-openpgp.c:1935
+#: scd/app-openpgp.c:1028 scd/app-openpgp.c:1960
 msgid "response does not contain the RSA public exponent\n"
 msgstr "Die Antwort enthält keinen öffenlichen RSA Exponent\n"
 
-#: scd/app-openpgp.c:1266 scd/app-openpgp.c:1354 scd/app-openpgp.c:2157
+#: scd/app-openpgp.c:1291 scd/app-openpgp.c:1379 scd/app-openpgp.c:2182
 #, c-format
 msgid "PIN callback returned error: %s\n"
 msgstr "Fehler vom PIN \"callback\": %s\n"
 
-#: scd/app-openpgp.c:1272 scd/app-openpgp.c:1360 scd/app-openpgp.c:2163
+#: scd/app-openpgp.c:1297 scd/app-openpgp.c:1385 scd/app-openpgp.c:2188
 #, c-format
 msgid "PIN for CHV%d is too short; minimum length is %d\n"
 msgstr "Die PIN für den CHV%d ist zu kurz; Mindestlänge ist %d\n"
 
-#: scd/app-openpgp.c:1281 scd/app-openpgp.c:1295 scd/app-openpgp.c:1370
-#: scd/app-openpgp.c:2172 scd/app-openpgp.c:2186
+#: scd/app-openpgp.c:1306 scd/app-openpgp.c:1320 scd/app-openpgp.c:1395
+#: scd/app-openpgp.c:2197 scd/app-openpgp.c:2211
 #, c-format
 msgid "verify CHV%d failed: %s\n"
 msgstr "Prüfen von CHV%d fehlgeschlagen: %s\n"
 
-#: scd/app-openpgp.c:1318
+#: scd/app-openpgp.c:1343
 msgid "access to admin commands is not configured\n"
 msgstr "Zugriff auf Admin Kommandos ist nicht konfiguriert\n"
 
-#: scd/app-openpgp.c:1333 scd/app-openpgp.c:2392
+#: scd/app-openpgp.c:1358 scd/app-openpgp.c:2417
 msgid "error retrieving CHV status from card\n"
 msgstr "Fehler beim Holen des CHV Status von der Karte\n"
 
-#: scd/app-openpgp.c:1339 scd/app-openpgp.c:2401
+#: scd/app-openpgp.c:1364 scd/app-openpgp.c:2426
 msgid "card is permanently locked!\n"
 msgstr "Die Karte ist dauerhaft gesperrt!\n"
 
-#: scd/app-openpgp.c:1344
+#: scd/app-openpgp.c:1369
 #, c-format
 msgid "%d Admin PIN attempts remaining before card is permanently locked\n"
 msgstr ""
@@ -659,105 +659,105 @@ msgstr ""
 #. TRANSLATORS: Do not translate the "|A|" prefix but
 #. keep it at the start of the string.  We need this elsewhere
 #. to get some infos on the string.
-#: scd/app-openpgp.c:1351
+#: scd/app-openpgp.c:1376
 msgid "|A|Admin PIN"
 msgstr "|A|Admin PIN"
 
 #. TRANSLATORS: Do not translate the "|*|" prefixes but
 #. keep it at the start of the string.  We need this elsewhere
 #. to get some infos on the string.
-#: scd/app-openpgp.c:1500
+#: scd/app-openpgp.c:1525
 msgid "|AN|New Admin PIN"
 msgstr "|AN|Neue Admin PIN"
 
-#: scd/app-openpgp.c:1500
+#: scd/app-openpgp.c:1525
 msgid "|N|New PIN"
 msgstr "|N|Neue PIN"
 
-#: scd/app-openpgp.c:1504
+#: scd/app-openpgp.c:1529
 #, c-format
 msgid "error getting new PIN: %s\n"
 msgstr "Fehler beim Holen der neuen PIN: %s\n"
 
-#: scd/app-openpgp.c:1554 scd/app-openpgp.c:2003
+#: scd/app-openpgp.c:1579 scd/app-openpgp.c:2028
 msgid "error reading application data\n"
 msgstr "Fehler beim Lesen der Anwendungsdaten\n"
 
-#: scd/app-openpgp.c:1560 scd/app-openpgp.c:2010
+#: scd/app-openpgp.c:1585 scd/app-openpgp.c:2035
 msgid "error reading fingerprint DO\n"
 msgstr "Fehler beim Lesen des Fingerabdruck Datenobjekts\n"
 
-#: scd/app-openpgp.c:1570
+#: scd/app-openpgp.c:1595
 msgid "key already exists\n"
 msgstr "Schlüssel existiert bereits\n"
 
-#: scd/app-openpgp.c:1574
+#: scd/app-openpgp.c:1599
 msgid "existing key will be replaced\n"
 msgstr "Existierender Schlüssel wird ersetzt\n"
 
-#: scd/app-openpgp.c:1576
+#: scd/app-openpgp.c:1601
 msgid "generating new key\n"
 msgstr "Neuer Schlüssel wird erzeugt\n"
 
-#: scd/app-openpgp.c:1743
+#: scd/app-openpgp.c:1768
 msgid "creation timestamp missing\n"
 msgstr "Erzeugungsdatum fehlt\n"
 
-#: scd/app-openpgp.c:1750
+#: scd/app-openpgp.c:1775
 #, c-format
 msgid "RSA modulus missing or not of size %d bits\n"
 msgstr "Der RSA Modulus fehlt oder ist nicht %d Bits lang\n"
 
-#: scd/app-openpgp.c:1757
+#: scd/app-openpgp.c:1782
 #, c-format
 msgid "RSA public exponent missing or larger than %d bits\n"
 msgstr "Der öffentliche RSA Exponent fehlt oder ist länger als %d Bits\n"
 
-#: scd/app-openpgp.c:1765 scd/app-openpgp.c:1772
+#: scd/app-openpgp.c:1790 scd/app-openpgp.c:1797
 #, c-format
 msgid "RSA prime %s missing or not of size %d bits\n"
 msgstr "Die RSA Primzahl %s fehlt oder ist nicht %d Bits lang\n"
 
-#: scd/app-openpgp.c:1835
+#: scd/app-openpgp.c:1860
 #, c-format
 msgid "failed to store the key: %s\n"
 msgstr "Fehler beim Speichern des Schlüssels: %s\n"
 
-#: scd/app-openpgp.c:1894
+#: scd/app-openpgp.c:1919
 msgid "please wait while key is being generated ...\n"
 msgstr "Bitte warten bis der Schlüssel erzeugt wurde ...\n"
 
-#: scd/app-openpgp.c:1908
+#: scd/app-openpgp.c:1933
 msgid "generating key failed\n"
 msgstr "Fehler beim Erzeugen des Schlüssels\n"
 
-#: scd/app-openpgp.c:1911
+#: scd/app-openpgp.c:1936
 #, c-format
 msgid "key generation completed (%d seconds)\n"
 msgstr "Schlüsselerzeugung vollendet (%d Sekunden)\n"
 
-#: scd/app-openpgp.c:1968
+#: scd/app-openpgp.c:1993
 msgid "invalid structure of OpenPGP card (DO 0x93)\n"
 msgstr "Ungültige Struktur der OpenPGP Karte (DO 0x93)\n"
 
-#: scd/app-openpgp.c:2137
+#: scd/app-openpgp.c:2162
 #, c-format
 msgid "signatures created so far: %lu\n"
 msgstr "Anzahl bereits erzeugter Signaturen: %lu\n"
 
-#: scd/app-openpgp.c:2145
+#: scd/app-openpgp.c:2170
 #, c-format
 msgid "||Please enter the PIN%%0A[sigs done: %lu]"
 msgstr "||Bitte geben Sie die PIN ein%%0A[Sigs bisher: %lu]"
 
-#: scd/app-openpgp.c:2406
+#: scd/app-openpgp.c:2431
 msgid ""
 "verification of Admin PIN is currently prohibited through this command\n"
 msgstr ""
 "Die Überprüfung der Admin PIN is momentan durch ein Kommando verboten "
 "worden\n"
 
-#: scd/app-openpgp.c:2477 scd/app-openpgp.c:2487
+#: scd/app-openpgp.c:2502 scd/app-openpgp.c:2512
 #, c-format
 msgid "can't access %s - invalid OpenPGP card?\n"
 msgstr "Zugriff auf %s nicht möglich - ungültige OpenPGP Karte?\n"
index df22c6b..2076700 100644 (file)
@@ -1,3 +1,15 @@
+2005-09-09  Werner Koch  <wk@g10code.com>
+
+       * pcsc-wrapper.c (main): Removed bogus free.
+
+       * app-p15.c (do_auth): New.
+       (do_getattr): New attribs $AUTHKEYID and $DISPSERIALNO.
+       * app-openpgp.c (do_getattr): Ditto.
+
+2005-09-08  Werner Koch  <wk@g10code.com>
+
+       * app-openpgp.c (do_getattr): New key $AUTHKEYID.
+
 2005-09-06  Werner Koch  <wk@g10code.com>
 
        * app-p15.c (do_sign): Tweaked for BELPIC cards.
@@ -8,7 +20,7 @@
 
        * iso7816.c (iso7816_select_path): New.
        * app-p15.c (select_ef_by_path): Allow for direct path selection.
-       (app_select_p15): Try using the beigian variant of pkcs#15.
+       (app_select_p15): Try using the Belgian variant of pkcs#15.
        (read_home_df): New.
        (read_ef_odf): Generalized.
        (read_ef_tokeninfo): New.
index bd56fb9..5625c72 100644 (file)
@@ -696,6 +696,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
     { "PRIVATE-DO-2", 0x0102 },
     { "PRIVATE-DO-3", 0x0103 },
     { "PRIVATE-DO-4", 0x0104 },
+    { "$AUTHKEYID",   0x0000, -3 },
+    { "$DISPSERIALNO",0x0000, -4 },
     { NULL, 0 }
   };
   int idx, i, rc;
@@ -742,6 +744,29 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
       send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0);
       return 0;
     }
+  if (table[idx].special == -3)
+    {
+      char const tmp[] = "OPENPGP.3";
+      send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0);
+      return 0;
+    }
+  if (table[idx].special == -4)
+    {
+      char *serial;
+      time_t stamp;
+    
+      if (!app_get_serial_and_stamp (app, &serial, &stamp))
+        {
+          if (strlen (serial) > 16+12)
+            {
+              send_status_info (ctrl, table[idx].name, serial+16, 12, NULL, 0);
+              xfree (serial);
+              return 0;
+            }
+          xfree (serial);
+        }
+      return gpg_error (GPG_ERR_INV_NAME); 
+    }
 
   relptr = get_one_do (app, table[idx].tag, &value, &valuelen, &rc);
   if (relptr)
@@ -2203,7 +2228,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
    fingerprint delimited by a slash.  Optionally the id OPENPGP.3 may
    be given.
 
-   Note that this fucntion may return the error code
+   Note that this function may return the error code
    GPG_ERR_WRONG_CARD to indicate that the card currently present does
    not match the one required for the requested action (e.g. the
    serial number does not match). */
index bf3c4dc..739a9ef 100644 (file)
@@ -2629,7 +2629,6 @@ readcert_by_cdf (app_t app, cdf_object_t cdf,
 }
 
 
-
 /* Handler for the READCERT command.
 
    Read the certificate with id CERTID (as returned by learn_status in
@@ -2653,6 +2652,95 @@ do_readcert (app_t app, const char *certid,
 }
 
 
+
+/* Implement the GETATTR command.  This is similar to the LEARN
+   command but returns just one value via the status interface. */
+static gpg_error_t 
+do_getattr (app_t app, ctrl_t ctrl, const char *name)
+{
+  gpg_error_t err;
+  int i;
+
+  if (!strcmp (name, "$AUTHKEYID"))
+    {
+      char *buf, *p;
+      prkdf_object_t prkdf;
+
+      /* We return the ID of the first private keycapable of
+         signing. */
+      for (prkdf = app->app_local->private_key_info; prkdf;
+           prkdf = prkdf->next)
+        if (prkdf->usageflags.sign)
+          break;
+      if (prkdf)
+        {
+          buf = xtrymalloc (9 + prkdf->objidlen*2 + 1);
+          if (!buf)
+            return gpg_error_from_errno (errno);
+          p = stpcpy (buf, "P15");
+          if (app->app_local->home_df)
+            {
+              sprintf (p, "-%04hX", (app->app_local->home_df & 0xffff));
+              p += 5;
+            }
+          p = stpcpy (p, ".");
+          for (i=0; i < prkdf->objidlen; i++)
+            {
+              sprintf (p, "%02X", prkdf->objid[i]);
+              p += 2;
+            }
+
+          send_status_info (ctrl, name, buf, strlen (buf), NULL, 0);
+          xfree (buf);
+          return 0;
+        }
+    }
+  else if (!strcmp (name, "$DISPSERIALNO"))
+    {
+      /* For certain cards we return special IDs.  There is no
+         general rule for it so we need to decide case by case. */
+      if (app->app_local->card_type == CARD_TYPE_BELPIC)
+        {
+          /* The eID card has a card number printed on the fron matter
+             which seems to be a good indication. */
+          unsigned char *buffer;
+          const unsigned char *p;
+          size_t buflen, n;
+          unsigned short path[] = { 0x3F00, 0xDF01, 0x4031 };
+
+          err = select_ef_by_path (app, path, DIM(path) );
+          if (!err)
+            err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen);
+          if (err)
+            {
+              log_error ("error accessing EF(ID): %s\n", gpg_strerror (err));
+              return err;
+            }
+
+          p = find_tlv (buffer, buflen, 1, &n);
+          if (p && n == 12)
+            {
+              char tmp[12+2+1];
+              memcpy (tmp, p, 3);
+              tmp[3] = '-';
+              memcpy (tmp+4, p+3, 7);
+              tmp[11] = '-';
+              memcpy (tmp+12, p+10, 2);
+              tmp[14] = 0;
+              send_status_info (ctrl, name, tmp, strlen (tmp), NULL, 0);
+              xfree (buffer);
+              return 0;
+            }
+          xfree (buffer);
+        }
+
+    }
+  return gpg_error (GPG_ERR_INV_NAME); 
+}
+
+
+
+
 /* Micardo cards require special treatment. This is a helper for the
    crypto functions to manage the security environment.  We expect that
    the key file has already been selected. FID is the one of the
@@ -3086,6 +3174,38 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
 }
 
 
+/* Handler for the PKAUTH command. 
+
+   This is basically the same as the PKSIGN command but we firstcheck
+   that the requested key is suitable for authentication; that is, it
+   must match the criteria used for the attribute $AUTHKEYID.  See
+   do_sign for calling conventions; there is no HASHALGO, though. */
+static gpg_error_t 
+do_auth (app_t app, const char *keyidstr, 
+         gpg_error_t (*pincb)(void*, const char *, char **),
+         void *pincb_arg,
+         const void *indata, size_t indatalen,
+         unsigned char **outdata, size_t *outdatalen )
+{
+  gpg_error_t err;
+  prkdf_object_t prkdf;
+
+  if (!keyidstr || !*keyidstr)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = prkdf_object_from_keyidstr (app, keyidstr, &prkdf);
+  if (err)
+    return err;
+  if (!prkdf->usageflags.sign)
+    {
+      log_error ("key %s may not be used for authentication\n", keyidstr);
+      return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
+    }
+  return do_sign (app, keyidstr, GCRY_MD_SHA1, pincb, pincb_arg, 
+                  indata, indatalen, outdata, outdatalen);
+}
+
+
 \f
 /* Assume that EF(DIR) has been selected.  Read its content and figure
    out the home EF of pkcs#15.  Return that home DF or 0 if not found
@@ -3270,11 +3390,11 @@ app_select_p15 (app_t app)
       app->fnc.deinit = do_deinit;
       app->fnc.learn_status = do_learn_status;
       app->fnc.readcert = do_readcert;
-      app->fnc.getattr = NULL;
+      app->fnc.getattr = do_getattr;
       app->fnc.setattr = NULL;
       app->fnc.genkey = NULL;
       app->fnc.sign = do_sign;
-      app->fnc.auth = NULL;
+      app->fnc.auth = do_auth;
       app->fnc.decipher = NULL;
       app->fnc.change_pin = NULL;
       app->fnc.check_pin = NULL;
@@ -3286,5 +3406,3 @@ app_select_p15 (app_t app)
 
   return rc;
 }
-
-
index 096a681..f82d93b 100644 (file)
@@ -16,7 +16,8 @@
  *
  * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
  *
  * ALTERNATIVELY, this file may be distributed under the terms of the
  * following license, in which case the provisions of this license are
index 82feed5..1b9ac2f 100644 (file)
@@ -15,7 +15,8 @@
  *
  * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
  *
  * ALTERNATIVELY, this file may be distributed under the terms of the
  * following license, in which case the provisions of this license are
index 4849062..5b98532 100644 (file)
@@ -15,7 +15,8 @@
  *
  * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
  *
  * $Id$
  */
index 828fabb..04c7ae6 100644 (file)
@@ -15,7 +15,8 @@
  *
  * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
  *
  * $Id$
  */
index f149e78..23e8442 100644 (file)
@@ -819,7 +819,6 @@ main (int argc, char **argv)
           fprintf (stderr, PGM ": invalid request 0x%02X\n", c);
           exit (1);
         }
-      free (argbuffer);
     }
   return 0;
 }
index a76f586..41cf7bd 100644 (file)
@@ -1,3 +1,9 @@
+2005-09-08  Werner Koch  <wk@g10code.com>
+
+       * export.c (popen_protect_tool): Add option --have-cert.  We
+       probably lost this option with 1.9.14 due to restructuring of
+       export.c.
+
 2005-07-21  Werner Koch  <wk@g10code.com>
 
        * gpgsm.c (main): New options --no-log-file and --debug-none.
index b4450b2..f9d6dac 100644 (file)
@@ -520,6 +520,7 @@ popen_protect_tool (const char *pgmname,
   argv[i++] = "--homedir";
   argv[i++] = opt.homedir;
   argv[i++] = "--p12-export";
+  argv[i++] = "--have-cert";
   argv[i++] = "--prompt";
   argv[i++] = prompt?prompt:"";
   argv[i++] = "--enable-status-msg";