Imported Upstream version 2.0.31 upstream/2.0.31
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 9 Feb 2021 06:59:52 +0000 (15:59 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 9 Feb 2021 06:59:52 +0000 (15:59 +0900)
56 files changed:
AUTHORS
NEWS
README
configure.ac
doc/gpg.texi
g10/build-packet.c
g10/card-util.c
g10/gpg.c
g10/gpgv.c
g10/keygen.c
g10/mainproc.c
g10/options.h
g10/parse-packet.c
g10/sig-check.c
g10/tdbio.c
g10/trustdb.c
po/be.po
po/ca.po
po/cs.po
po/da.po
po/de.po
po/el.po
po/eo.po
po/es.po
po/et.po
po/fi.po
po/fr.po
po/gl.po
po/hu.po
po/id.po
po/it.po
po/ja.po
po/nb.po
po/nl.po
po/pl.po
po/pt.po
po/pt_BR.po
po/ro.po
po/ru.po
po/sk.po
po/sv.po
po/tr.po
po/uk.po
po/zh_CN.po
po/zh_TW.po
scd/Makefile.am
scd/apdu.c
scd/apdu.h
scd/app-openpgp.c
scd/app.c
scd/ccid-driver.c
scd/command.c
scd/iso7816.c
scd/iso7816.h
scd/scdaemon.c
sm/gpgsm.c

diff --git a/AUTHORS b/AUTHORS
index 9b57c16..7e97c85 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -3,6 +3,7 @@ Homepage: https://www.gnupg.org
 Maintainer: Werner Koch <wk@gnupg.org>
 Bug reports: http://bugs.gnupg.org
 Security related bug reports: <security@gnupg.org>
+End-of-life: 2017-12-31
 License: GPLv3+
 
 GnuPG is free software.  See the files COPYING for copying conditions.
diff --git a/NEWS b/NEWS
index 75ed1b3..cdf2352 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,11 @@
+Noteworthy changes in version 2.0.31 (2017-12-29)
+-------------------------------------------------
+
+ This 2.0 branch has reached end-of-life.  Please upgrade to 2.2.
+
+ * Minor changes collected over the last 21 months
+
+
 Noteworthy changes in version 2.0.30 (2016-03-31)
 -------------------------------------------------
 
diff --git a/README b/README
index a031c5e..087f7ac 100644 (file)
--- a/README
+++ b/README
@@ -6,6 +6,10 @@
    Copyright 1998-2015 Free Software Foundation, Inc.
 
 
+NOTE: This branch is not anymore supported.
+      Please upgrade to version 2.2
+
+
 INTRODUCTION
 ============
 
index e5b8baf..0041bec 100644 (file)
@@ -26,7 +26,7 @@ min_automake_version="1.14"
 # (git tag -s gnupg-2.n.m) and run "./autogen.sh --force".  Please
 # bump the version number immediately *after* the release and do
 # another commit and push so that the git magic is able to work.
-m4_define([mym4_version], [2.0.30])
+m4_define([mym4_version], [2.0.31])
 
 # Below is m4 magic to extract and compute the git revision number,
 # the decimalized short revision number, a beta version string and a
index ee31d75..cde27a5 100644 (file)
@@ -2448,20 +2448,6 @@ be given in C syntax (e.g. 0x0042).
 @opindex debug-all
 Set all useful debugging flags.
 
-@ifset gpgone
-@item --debug-ccid-driver
-@opindex debug-ccid-driver
-Enable debug output from the included CCID driver for smartcards.
-Note that this option is only available on some system.
-@end ifset
-
-@item --faked-system-time @var{epoch}
-@opindex faked-system-time
-This option is only useful for testing; it sets the system time back or
-forth to @var{epoch} which is the number of seconds elapsed since the year
-1970.  Alternatively @var{epoch} may be given as a full ISO time string
-(e.g. "20070924T154812").
-
 @item --enable-progress-filter
 @opindex enable-progress-filter
 Enable certain PROGRESS status outputs. This option allows frontends
@@ -2518,9 +2504,9 @@ protected by the signature.
 @opindex emit-version
 Force inclusion of the version string in ASCII armored output.  If
 given once only the name of the program and the major number is
-emitted (default), given twice the minor is also emitted, given triple
+emitted, given twice the minor is also emitted, given triple
 the micro is added, and given quad an operating system identification
-is also emitted.  @option{--no-emit-version} disables the version
+is also emitted.  @option{--no-emit-version} (default) disables the version
 line.
 
 @item --sig-notation @code{name=value}
index 5cc03cf..d7f2291 100644 (file)
@@ -233,12 +233,17 @@ do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
 
     if( uid->attrib_data )
       {
-       write_header(out, ctb, uid->attrib_len);
+        /* We need to take special care of a user ID with a length of 0:
+         * Without forcing HDRLEN to 2 in this case an indeterminate length
+         * packet would be written which is not allowed.  Note that we are
+         * always called with a CTB indicating an old packet header format,
+         * so that forcing a 2 octet header works.  */
+       write_header2 (out, ctb, uid->attrib_len, (uid->attrib_len? 0 : 2));
        rc = iobuf_write( out, uid->attrib_data, uid->attrib_len );
       }
     else
       {
-        write_header2( out, ctb, uid->len, 2 );
+        write_header2 (out, ctb, uid->len, 2);
        rc = iobuf_write( out, uid->name, uid->len );
       }
     return rc;
index 2198cb2..745ba1d 100644 (file)
@@ -729,28 +729,18 @@ fetch_url(void)
     log_error("error retrieving URL from card: %s\n",gpg_strerror(rc));
   else
     {
-      struct keyserver_spec *spec=NULL;
-
       rc=agent_scd_getattr("KEY-FPR",&info);
       if(rc)
        log_error("error retrieving key fingerprint from card: %s\n",
                  gpg_strerror(rc));
       else if (info.pubkey_url && *info.pubkey_url)
-       {
-         spec=parse_keyserver_uri(info.pubkey_url,1,NULL,0);
-         if(spec && info.fpr1valid)
-           {
-             /* This is not perfectly right.  Currently, all card
-                fingerprints are 20 digits, but what about
-                fingerprints for a future v5 key?  We should get the
-                length from somewhere lower in the code.  In any
-                event, the fpr/keyid is not meaningful for straight
-                HTTP fetches, but using it allows the card to point
-                to HKP and LDAP servers as well. */
-             rc=keyserver_import_fprint(info.fpr1,20,spec);
-             free_keyserver_spec(spec);
-           }
-       }
+        {
+          strlist_t sl = NULL;
+
+          add_to_strlist (&sl, info.pubkey_url);
+          rc = keyserver_fetch (sl);
+          free_strlist (sl);
+        }
       else if (info.fpr1valid)
        {
           rc = keyserver_import_fprint (info.fpr1, 20, opt.keyserver);
index 97975fb..a757fe3 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -2018,7 +2018,7 @@ main (int argc, char **argv)
     opt.def_cert_expire="0";
     set_homedir ( default_homedir () );
     opt.passphrase_repeat=1;
-    opt.emit_version = 1; /* Limit to the major number.  */
+    opt.emit_version = 0;
 
     opt.list_options   |= LIST_SHOW_UID_VALIDITY;
     opt.verify_options |= LIST_SHOW_UID_VALIDITY;
@@ -4130,7 +4130,6 @@ main (int argc, char **argv)
         break;
 
       case aListPackets:
-       opt.list_packets=2;
       default:
        if( argc > 1 )
            wrong_args(_("[filename]"));
@@ -4157,8 +4156,8 @@ main (int argc, char **argv)
                }
            }
            if( cmd == aListPackets ) {
-               set_packet_list_mode(1);
                opt.list_packets=1;
+               set_packet_list_mode(1);
            }
            rc = proc_packets(NULL, a );
            if( rc )
index b700f17..3b48a0e 100644 (file)
@@ -163,6 +163,8 @@ main( int argc, char **argv )
   opt.pgp2_workarounds = 1;
   opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE;
   opt.trust_model = TM_ALWAYS;
+  opt.no_sig_cache = 1;
+  opt.flags.require_cross_cert = 1;
   opt.batch = 1;
 
   opt.homedir = default_homedir ();
index 560480d..1ad39bf 100644 (file)
@@ -1802,8 +1802,8 @@ ask_keysize (int algo, unsigned int primary_keysize)
   int for_subkey = !!primary_keysize;
   int autocomp = 0;
 
-  if(opt.expert)
-    min=512;
+  if(opt.expert && algo == PUBKEY_ALGO_DSA)
+    min=768;
   else
     min=1024;
 
index 17d40de..8c2d2e1 100644 (file)
@@ -1292,7 +1292,7 @@ do_proc_packets( CTX c, IOBUF a )
             /* stop processing when an invalid packet has been encountered
              * but don't do so when we are doing a --list-packets. */
            if (gpg_err_code (rc) == GPG_ERR_INV_PACKET
-                && opt.list_packets != 2 )
+                && opt.list_packets == 0 )
                break;
            continue;
        }
index cc8718e..b02c0d9 100644 (file)
@@ -62,7 +62,7 @@ struct
   int fingerprint; /* list fingerprints */
   int list_sigs;   /* list signatures */
   int no_armor;
-  int list_packets; /* list-packets mode: 1=normal, 2=invoked by command*/
+  int list_packets; /* Option --list-packets active.  */
   int def_cipher_algo;
   int force_v3_sigs;
   int force_v4_certs;
index c925e94..1030204 100644 (file)
@@ -207,7 +207,7 @@ set_packet_list_mode( int mode )
        whether using log_stream() would be better.  Perhaps we should
        enable the list mdoe only with a special option. */
     if (!listfp)
-        listfp = opt.list_packets == 2 ? stdout : stderr;
+        listfp = opt.list_packets ? stdout : stderr;
     return old;
 }
 
index fc5e1fa..7178d06 100644 (file)
@@ -82,9 +82,9 @@ signature_check2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate,
       }
     else if( get_pubkey( pk, sig->keyid ) )
        rc = G10ERR_NO_PUBKEY;
-    else if(!pk->is_valid && !pk->is_primary)
+    else if(!pk->is_valid)
         rc=G10ERR_BAD_PUBKEY; /* you cannot have a good sig from an
-                                invalid subkey */
+                                invalid key */
     else
       {
         if(r_expiredate)
index 5c2fdd1..725c3c2 100644 (file)
@@ -92,6 +92,7 @@ static int  db_fd = -1;
 static int in_transaction;
 
 static void open_db(void);
+static void create_hashtable (TRUSTREC *vr, int type);
 
 static int
 take_write_lock (void)
@@ -471,6 +472,10 @@ create_version_record (void)
   rc = tdbio_write_record( &rec );
   if( !rc )
     tdbio_sync();
+
+  if (!rc)
+    create_hashtable (&rec, 0);
+
   return rc;
 }
 
@@ -763,8 +768,6 @@ get_trusthashrec(void)
        if( rc )
            log_fatal( _("%s: error reading version record: %s\n"),
                                            db_name, g10_errstr(rc) );
-       if( !vr.r.ver.trusthashtbl )
-           create_hashtable( &vr, 0 );
 
        trusthashtbl = vr.r.ver.trusthashtbl;
     }
index c9c8891..bc90161 100644 (file)
@@ -1823,6 +1823,10 @@ clean_key(KBNODE keyblock,int noisy,int self_only,
 /* Returns a sanitized copy of the regexp (which might be "", but not
    NULL). */
 #ifndef DISABLE_REGEX
+/* Operator charactors except '.' and backslash.
+   See regex(7) on BSD.  */
+#define REGEXP_OPERATOR_CHARS "^[$()|*+?{"
+
 static char *
 sanitize_regexp(const char *old)
 {
@@ -1862,7 +1866,7 @@ sanitize_regexp(const char *old)
     {
       if(!escaped && old[start]=='\\')
        escaped=1;
-      else if(!escaped && old[start]!='.')
+      else if (!escaped && strchr (REGEXP_OPERATOR_CHARS, old[start]))
        new[idx++]='\\';
       else
        escaped=0;
index 606b297..d79654f 100644 (file)
--- a/po/be.po
+++ b/po/be.po
@@ -4899,14 +4899,14 @@ msgstr ""
 msgid "trustdb transaction too large\n"
 msgstr ""
 
-#, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "немагчыма адкрыць %s: %s\n"
-
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr ""
 
+#, fuzzy, c-format
+msgid "can't access `%s': %s\n"
+msgstr "немагчыма адкрыць %s: %s\n"
+
 #, c-format
 msgid "%s: failed to create version record: %s"
 msgstr ""
index 86eb364..23ad588 100644 (file)
--- a/po/ca.po
+++ b/po/ca.po
@@ -5378,16 +5378,16 @@ msgstr ""
 msgid "trustdb transaction too large\n"
 msgstr "la transacció de la base de dades de confiança és massa gran\n"
 
+#, c-format
+msgid "%s: directory does not exist!\n"
+msgstr "%s: el directori no existeix!\n"
+
 # No em passe! ;)  ivb
 #, fuzzy, c-format
 msgid "can't access `%s': %s\n"
 msgstr "no s'ha pogut tancar «%s»: %s\n"
 
 #, c-format
-msgid "%s: directory does not exist!\n"
-msgstr "%s: el directori no existeix!\n"
-
-#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: no s'ha pogut crear un registre de versió: %s"
 
index 0aaabcb..e2bba98 100644 (file)
--- a/po/cs.po
+++ b/po/cs.po
@@ -5040,14 +5040,14 @@ msgid "trustdb transaction too large\n"
 msgstr "transakce s databází důvěry je příliš dlouhá\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "nemohu otevřít „%s“: %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: adresář neexistuje!\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "nemohu otevřít „%s“: %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: nepodařilo se vytvořit záznam verze: %s"
 
index 06d9ab0..f5a934b 100644 (file)
--- a/po/da.po
+++ b/po/da.po
@@ -5024,14 +5024,14 @@ msgid "trustdb transaction too large\n"
 msgstr "transaktion for trustdb er for stor\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "kan ikke tilgå »%s«: %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: mappe findes ikke!\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "kan ikke tilgå »%s«: %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: kunne ikke oprette versionspost: %s"
 
index 839868b..9d8c33d 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -893,7 +893,7 @@ msgid "Data decryption succeeded"
 msgstr "Entschlüsselung der Daten erfolgreich"
 
 msgid "Encryption algorithm supported"
-msgstr "Verschlüsselungsverfahren %d%s wird nicht unterstützt"
+msgstr "Verschlüsselungsverfahren wird unterstützt"
 
 msgid "Data verification succeeded"
 msgstr "Prüfung der Signatur erfolgreich"
@@ -3167,8 +3167,7 @@ msgstr "Der folgende Schlüssel wurde am %s von %s Schlüssel %s widerrufen\n"
 
 #, c-format
 msgid "This key may be revoked by %s key %s"
-msgstr ""
-"Dieser Schlüssel könnte durch %s mit Schlüssel %s  widerrufen worden sein"
+msgstr "Dieser Schlüssel kann von %s-Schlüssel %s widerrufen werden"
 
 msgid "(sensitive)"
 msgstr "(empfindlich)"
@@ -5125,14 +5124,14 @@ msgid "trustdb transaction too large\n"
 msgstr "trustdb Transaktion zu groß\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "kann aus `%s' nicht zugreifen: %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: Verzeichnis existiert nicht!\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "kann aus `%s' nicht zugreifen: %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: Fehler beim Erzeugen des Versionsatzes: %s"
 
index b55f03a..92ee086 100644 (file)
--- a/po/el.po
+++ b/po/el.po
@@ -5254,14 +5254,14 @@ msgstr "trustdb rec %lu: 
 msgid "trustdb transaction too large\n"
 msgstr "ðïëý ìåãÜëç óõíáëëáãÞ trustdb\n"
 
-#, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "áäõíáìßá êëåéóßìáôïò ôïõ `%s': %s\n"
-
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: ï öÜêåëïò äåí õðÜñ÷åé!\n"
 
+#, fuzzy, c-format
+msgid "can't access `%s': %s\n"
+msgstr "áäõíáìßá êëåéóßìáôïò ôïõ `%s': %s\n"
+
 #, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: áðïôõ÷ßá äçìéïõñãßáò ìéáò åããñáöÞò Ýêäïóçò: %s"
index 8fc95a9..911274d 100644 (file)
--- a/po/eo.po
+++ b/po/eo.po
@@ -5209,14 +5209,14 @@ msgstr "fido-datenaro loko %lu: skribo malsukcesis (n=%d): %s\n"
 msgid "trustdb transaction too large\n"
 msgstr "fido-datenaro-transakcio tro granda\n"
 
-#, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "ne povas fermi '%s': %s\n"
-
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: dosierujo ne ekzistas!\n"
 
+#, fuzzy, c-format
+msgid "can't access `%s': %s\n"
+msgstr "ne povas fermi '%s': %s\n"
+
 #, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: malsukcesis krei versiregistron: %s"
index 33330d2..a5278bd 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -5045,14 +5045,14 @@ msgid "trustdb transaction too large\n"
 msgstr "transacción en la base de datos de confianza demasiado grande\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "no se puede acceder a `%s': %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: ¡el directorio no existe!\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "no se puede acceder a `%s': %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: fallo en la creación del registro de versión: %s"
 
index d18984e..1aaeebe 100644 (file)
--- a/po/et.po
+++ b/po/et.po
@@ -5176,14 +5176,14 @@ msgstr "trustdb rec %lu: write failed (n=%d): %s\n"
 msgid "trustdb transaction too large\n"
 msgstr "trustdb transaktsioon on liiga suur\n"
 
-#, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "`%s' ei õnnestu sulgeda: %s\n"
-
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: kataloogi ei ole!\n"
 
+#, fuzzy, c-format
+msgid "can't access `%s': %s\n"
+msgstr "`%s' ei õnnestu sulgeda: %s\n"
+
 #, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: versioonikirje loomine ei õnnestu: %s"
index 85e042e..d3f5d42 100644 (file)
--- a/po/fi.po
+++ b/po/fi.po
@@ -5240,14 +5240,14 @@ msgstr "trustdb rec %lu: kirjoittaminen epäonnistuin (n=%d): %s\n"
 msgid "trustdb transaction too large\n"
 msgstr "trustdb-tapahtuma on liian suuri\n"
 
-#, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "tiedostoa \"%s\" ei voi sulkea: %s\n"
-
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: hakemistoa ei ole olemassa!\n"
 
+#, fuzzy, c-format
+msgid "can't access `%s': %s\n"
+msgstr "tiedostoa \"%s\" ei voi sulkea: %s\n"
+
 #, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: versiotietueen luonti epäonnistui: %s"
index b0775c9..88ac4ac 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -5162,14 +5162,14 @@ msgid "trustdb transaction too large\n"
 msgstr "transaction de base de confiance trop grande\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "impossible d'accéder à « %s » : %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s : le répertoire n'existe pas.\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "impossible d'accéder à « %s » : %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s : impossible de créer un enregistrement de version : %s"
 
index f675ea7..40ac351 100644 (file)
--- a/po/gl.po
+++ b/po/gl.po
@@ -5243,14 +5243,14 @@ msgstr ""
 msgid "trustdb transaction too large\n"
 msgstr "transacción da base de datos de confianza demasiado grande\n"
 
-#, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "non se pode pechar `%s': %s\n"
-
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: ¡o directorio non existe!\n"
 
+#, fuzzy, c-format
+msgid "can't access `%s': %s\n"
+msgstr "non se pode pechar `%s': %s\n"
+
 #, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: non se puido crea-lo rexistro de versión: %s"
index a43f640..6469bf3 100644 (file)
--- a/po/hu.po
+++ b/po/hu.po
@@ -5207,14 +5207,14 @@ msgstr "Bizalmi adatb
 msgid "trustdb transaction too large\n"
 msgstr "Bizalmi adatbázis tranzakciója túl nagy.\n"
 
-#, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "Nem tudom bezárni a(z) \"%s\" állományt: %s.\n"
-
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: Könyvtár nem létezik!\n"
 
+#, fuzzy, c-format
+msgid "can't access `%s': %s\n"
+msgstr "Nem tudom bezárni a(z) \"%s\" állományt: %s.\n"
+
 #, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: Nem sikerült verziórekordot létrehoznom: %s"
index 5238a4b..f3ba6b5 100644 (file)
--- a/po/id.po
+++ b/po/id.po
@@ -5205,14 +5205,14 @@ msgstr "trustdb rec %lu: write failed (n=%d): %s\n"
 msgid "trustdb transaction too large\n"
 msgstr "transaksi trustdb terlalu besar\n"
 
-#, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "tidak dapat menutup `%s': %s\n"
-
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: direktori tidak ada!\n"
 
+#, fuzzy, c-format
+msgid "can't access `%s': %s\n"
+msgstr "tidak dapat menutup `%s': %s\n"
+
 #, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: gagal membuat catatan versi: %s"
index 0612633..a1728a4 100644 (file)
--- a/po/it.po
+++ b/po/it.po
@@ -5245,14 +5245,14 @@ msgstr "trustdb rec %lu: scrittura fallita (n=%d): %s\n"
 msgid "trustdb transaction too large\n"
 msgstr "transazione del trustdb troppo grande\n"
 
-#, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "impossibile chiudere `%s': %s\n"
-
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: la directory non esiste!\n"
 
+#, fuzzy, c-format
+msgid "can't access `%s': %s\n"
+msgstr "impossibile chiudere `%s': %s\n"
+
 #, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: creazione del record della versione fallita: %s"
index 4dc35ec..23176f9 100644 (file)
--- a/po/ja.po
+++ b/po/ja.po
@@ -7,9 +7,9 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: GNU gnupg 2.0.29\n"
+"Project-Id-Version: GNU gnupg 2.0.30\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2015-09-15 15:14+0900\n"
+"PO-Revision-Date: 2017-12-18 14:34+0900\n"
 "Last-Translator: NIIBE Yutaka <gniibe@fsij.org>\n"
 "Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
 "Language: ja\n"
@@ -3504,10 +3504,10 @@ msgid "invalid value\n"
 msgstr "無効な値\n"
 
 msgid "Key does not expire at all\n"
-msgstr "%sは無期限です\n"
+msgstr "は無期限です\n"
 
 msgid "Signature does not expire at all\n"
-msgstr "%署名は無期限です\n"
+msgstr "署名は無期限です\n"
 
 #, c-format
 msgid "Key expires at %s\n"
@@ -4911,14 +4911,14 @@ msgid "trustdb transaction too large\n"
 msgstr "信用データベースのトランザクションが大きすぎます\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "「%s」にアクセスできません: %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: ディレクトリがありません!\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "「%s」にアクセスできません: %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: バージョン・レコードの作成に失敗しました: %s"
 
index f7a3a1b..a25f25e 100644 (file)
--- a/po/nb.po
+++ b/po/nb.po
@@ -4979,14 +4979,14 @@ msgid "trustdb transaction too large\n"
 msgstr ""
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "kan ikke aksere «%s»: %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr ""
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "kan ikke aksere «%s»: %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr ""
 
index 56fcd2a..03fdaf1 100644 (file)
--- a/po/nl.po
+++ b/po/nl.po
@@ -30,7 +30,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnupg 2.0.28\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2015-06-07 16:56+0200\n"
+"PO-Revision-Date: 2017-12-19 12:28+0100\n"
 "Last-Translator: Frans Spiesschaert <Frans.Spiesschaert@yucom.be>\n"
 "Language-Team: Debian Dutch l10n Team <debian-l10n-dutch@lists.debian.org>\n"
 "Language: nl\n"
@@ -5201,14 +5201,14 @@ msgid "trustdb transaction too large\n"
 msgstr "betrouwbaarheidsdatabank (trustdb): transactie is te groot\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "krijg geen toegang tot `%s': %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: map bestaat niet!\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "krijg geen toegang tot `%s': %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: het registreren van de versie is mislukt: %s"
 
@@ -6501,7 +6501,7 @@ msgid "keybox `%s' created\n"
 msgstr "sleuteldoosje `%s' is aangemaakt\n"
 
 msgid "failed to get the fingerprint\n"
-msgstr "opvragen van de vingerafdruk is mislukt: %s\n"
+msgstr "opvragen van de vingerafdruk is mislukt\n"
 
 #, c-format
 msgid "problem looking for existing certificate: %s\n"
index 331510c..5198a7c 100644 (file)
--- a/po/pl.po
+++ b/po/pl.po
@@ -5062,14 +5062,14 @@ msgid "trustdb transaction too large\n"
 msgstr "zbyt duże zlecenie dla bazy zaufania\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "nie można dostać się do ,,%s'': %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: katalog nie istnieje!\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "nie można dostać się do ,,%s'': %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: stworzenie zapisu o wersji nie powiodło się: %s"
 
index d51a531..851d056 100644 (file)
--- a/po/pt.po
+++ b/po/pt.po
@@ -5207,14 +5207,14 @@ msgstr "base de dados de confian
 msgid "trustdb transaction too large\n"
 msgstr "transação de base de dados de confiança muito grande\n"
 
-#, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "impossível fechar `%s': %s\n"
-
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: diretoria inexistente!\n"
 
+#, fuzzy, c-format
+msgid "can't access `%s': %s\n"
+msgstr "impossível fechar `%s': %s\n"
+
 #, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: falha ao criar registo de versão: %s"
index f74ef0f..98d43df 100644 (file)
@@ -5217,14 +5217,14 @@ msgstr "banco de dados de confiabilidade rec %lu: escrita falhou (n=%d): %s\n"
 msgid "trustdb transaction too large\n"
 msgstr "transação de banco de dados de confiabilidade muito grande\n"
 
-#, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "impossível abrir `%s': %s\n"
-
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: diretório inexistente!\n"
 
+#, fuzzy, c-format
+msgid "can't access `%s': %s\n"
+msgstr "impossível abrir `%s': %s\n"
+
 #, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: falha ao criar registro de versão: %s"
index be90de5..fb3fed7 100644 (file)
--- a/po/ro.po
+++ b/po/ro.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnupg 1.4.2rc1\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"PO-Revision-Date: 2005-05-31 22:00-0500\n"
+"PO-Revision-Date: 2017-12-19 12:30+0100\n"
 "Last-Translator: Laurentiu Buzdugan <lbuz@rolix.org>\n"
 "Language-Team: Romanian <translation-team-ro@lists.sourceforge.net>\n"
 "Language: ro\n"
@@ -2720,6 +2720,7 @@ msgstr ""
 msgid "User ID \"%s\" is revoked."
 msgstr "ID utilizator \"%s\" a fost revocat."
 
+#, fuzzy
 msgid "Are you sure you still want to sign it? (y/N) "
 msgstr "Sunteþi sigur(ã) cã doriþi sã ºtergeþi permanent \"%s\"? (d/N)"
 
@@ -5119,14 +5120,14 @@ msgid "trustdb transaction too large\n"
 msgstr "tranzacþia trustdb prea mare\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "nu pot accesa `%s': %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: directorul nu existã!\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "nu pot accesa `%s': %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: am eºuat sã creez înregistrare versiune: %s"
 
index a5156be..5f23ded 100644 (file)
--- a/po/ru.po
+++ b/po/ru.po
@@ -4998,14 +4998,14 @@ msgid "trustdb transaction too large\n"
 msgstr "слишком большая транзакция таблицы доверия\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "нет доступа к `%s': %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: каталог не существует!\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "нет доступа к `%s': %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: сбой создания записи о версии: %s"
 
index 9d5feb9..53f88e0 100644 (file)
--- a/po/sk.po
+++ b/po/sk.po
@@ -4604,6 +4604,7 @@ msgstr "\"%s\" nie je s
 msgid "Is this photo correct (y/N/q)? "
 msgstr "Je táto fotografia správna (a/N/u)? "
 
+#, fuzzy
 msgid "unable to display photo ID!\n"
 msgstr "nemo¾no nastavi» exec-path na %s\n"
 
@@ -5223,14 +5224,14 @@ msgstr "z
 msgid "trustdb transaction too large\n"
 msgstr "transakcia s databázou dôvery je príli¹ dlhá\n"
 
-#, fuzzy, c-format
-msgid "can't access `%s': %s\n"
-msgstr "nemô¾em zavrie» `%s': %s\n"
-
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: adresár neexistuje!\n"
 
+#, fuzzy, c-format
+msgid "can't access `%s': %s\n"
+msgstr "nemô¾em zavrie» `%s': %s\n"
+
 #, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: nepodarilo sa vytvori» záznam verzie: %s"
index 0817012..130d9ce 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -5154,14 +5154,14 @@ msgid "trustdb transaction too large\n"
 msgstr "tillitsdatabastransaktion för stor\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "kan inte komma åt \"%s\": %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: katalogen finns inte!\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "kan inte komma åt \"%s\": %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: misslyckades med att skapa versionspost: %s"
 
index eb8af01..61124d6 100644 (file)
--- a/po/tr.po
+++ b/po/tr.po
@@ -5089,14 +5089,14 @@ msgid "trustdb transaction too large\n"
 msgstr "güvence veritabanı işlemi çok uzun\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "'%s' erişilemiyor: %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: dizin yok!\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "'%s' erişilemiyor: %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: sürüm kaydı oluşturmada başarısız: %s"
 
index 1ad8d81..798146b 100644 (file)
--- a/po/uk.po
+++ b/po/uk.po
@@ -5100,14 +5100,14 @@ msgid "trustdb transaction too large\n"
 msgstr "занадто велика операція trustdb\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "немає доступу до «%s»: %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: каталогу не існує!\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "немає доступу до «%s»: %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: не вдалося створити запис щодо версії: %s"
 
index 20f44b9..ff9f770 100644 (file)
@@ -4958,14 +4958,14 @@ msgid "trustdb transaction too large\n"
 msgstr "信任度数据库处理量过大\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "无法存取‘%s’:%s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s:目录不存在!\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "无法存取‘%s’:%s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s:建立版本记录失败:%s"
 
index c1319a0..4dcea6c 100644 (file)
@@ -4885,14 +4885,14 @@ msgid "trustdb transaction too large\n"
 msgstr "信任資料庫更動量過大\n"
 
 #, c-format
-msgid "can't access `%s': %s\n"
-msgstr "無法存取 `%s': %s\n"
-
-#, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: 目錄不存在!\n"
 
 #, c-format
+msgid "can't access `%s': %s\n"
+msgstr "無法存取 `%s': %s\n"
+
+#, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: 建立版本記錄失敗: %s"
 
index e883180..aa370fa 100644 (file)
@@ -25,7 +25,7 @@ endif
 
 EXTRA_DIST = ChangeLog-2011 scdaemon-w32info.rc
 
-AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common
+AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common -I$(top_srcdir)/include
 
 include $(top_srcdir)/am/cmacros.am
 
index 30e5ef9..97bce79 100644 (file)
@@ -98,7 +98,6 @@ struct reader_table_s {
   int (*connect_card)(int);
   int (*disconnect_card)(int);
   int (*close_reader)(int);
-  int (*shutdown_reader)(int);
   int (*reset_reader)(int);
   int (*get_status_reader)(int, unsigned int *);
   int (*send_apdu_reader)(int,unsigned char *,size_t,
@@ -432,7 +431,6 @@ new_reader_slot (void)
   reader_table[reader].connect_card = NULL;
   reader_table[reader].disconnect_card = NULL;
   reader_table[reader].close_reader = NULL;
-  reader_table[reader].shutdown_reader = NULL;
   reader_table[reader].reset_reader = NULL;
   reader_table[reader].get_status_reader = NULL;
   reader_table[reader].send_apdu_reader = NULL;
@@ -1857,8 +1855,12 @@ pcsc_vendor_specific_init (int slot)
       reader_table[slot].is_spr532 = 1;
       reader_table[slot].pinpad_varlen_supported = 1;
     }
-  else if (vendor == 0x046a && product == 0x003e) /* Cherry ST-2xxx */
+  else if (vendor == 0x046a)
     {
+      /* Cherry ST-2xxx (product == 0x003e) supports TPDU level
+       * exchange.  Other products which only support short APDU level
+       * exchange only work with shorter keys like RSA 1024.
+       */
       reader_table[slot].pcsc.pinmax = 15;
       reader_table[slot].pinpad_varlen_supported = 1;
     }
@@ -2437,14 +2439,6 @@ close_ccid_reader (int slot)
 
 
 static int
-shutdown_ccid_reader (int slot)
-{
-  ccid_shutdown_reader (reader_table[slot].ccid.handle);
-  return 0;
-}
-
-
-static int
 reset_ccid_reader (int slot)
 {
   int err;
@@ -2609,7 +2603,6 @@ open_ccid_reader (const char *portstr)
     }
 
   reader_table[slot].close_reader = close_ccid_reader;
-  reader_table[slot].shutdown_reader = shutdown_ccid_reader;
   reader_table[slot].reset_reader = reset_ccid_reader;
   reader_table[slot].get_status_reader = get_status_ccid;
   reader_table[slot].send_apdu_reader = send_apdu_ccid;
@@ -3178,24 +3171,6 @@ apdu_prepare_exit (void)
 }
 
 
-/* Shutdown a reader; that is basically the same as a close but keeps
-   the handle ready for later use. A apdu_reset_reader or apdu_connect
-   should be used to get it active again. */
-int
-apdu_shutdown_reader (int slot)
-{
-  int sw;
-
-  if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
-    return SW_HOST_NO_DRIVER;
-  sw = apdu_disconnect (slot);
-  if (sw)
-    return sw;
-  if (reader_table[slot].shutdown_reader)
-    return reader_table[slot].shutdown_reader (slot);
-  return SW_HOST_NOT_SUPPORTED;
-}
-
 /* Enumerate all readers and return information on whether this reader
    is in use.  The caller should start with SLOT set to 0 and
    increment it with each call until an error is returned. */
@@ -3216,8 +3191,8 @@ apdu_enum_reader (int slot, int *used)
 int
 apdu_connect (int slot)
 {
-  int sw;
-  unsigned int status;
+  int sw = 0;
+  unsigned int status = 0;
 
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
     return SW_HOST_NO_DRIVER;
@@ -3234,15 +3209,15 @@ apdu_connect (int slot)
           unlock_slot (slot);
         }
     }
-  else
-    sw = 0;
 
   /* We need to call apdu_get_status_internal, so that the last-status
      machinery gets setup properly even if a card is inserted while
      scdaemon is fired up and apdu_get_status has not yet been called.
      Without that we would force a reset of the card with the next
      call to apdu_get_status.  */
-  apdu_get_status_internal (slot, 1, 1, &status, NULL);
+  if (!sw)
+    sw = apdu_get_status_internal (slot, 1, 1, &status, NULL);
+
   if (sw)
     ;
   else if (!(status & APDU_CARD_PRESENT))
@@ -3673,8 +3648,9 @@ send_le (int slot, int class, int ins, int p0, int p1,
 
   if (use_extended_length && (le > 256 || le < 0))
     {
-      result_buffer_size = le < 0? 4096 : le;
-      result_buffer = xtrymalloc (result_buffer_size + 10);
+      /* Two more bytes are needed for status bytes.  */
+      result_buffer_size = le < 0? 4096 : (le + 2);
+      result_buffer = xtrymalloc (result_buffer_size);
       if (!result_buffer)
         {
           xfree (apdu_buffer);
index 1524f99..ac16ea1 100644 (file)
@@ -92,7 +92,6 @@ int apdu_open_remote_reader (const char *portstr,
                              void *writefnc_value,
                              void (*closefnc) (void *opaque),
                              void *closefnc_value);
-int apdu_shutdown_reader (int slot);
 int apdu_close_reader (int slot);
 void apdu_prepare_exit (void);
 int apdu_enum_reader (int slot, int *used);
index 2e7a9fc..5983aba 100644 (file)
@@ -66,7 +66,8 @@
 #include "iso7816.h"
 #include "app-common.h"
 #include "tlv.h"
-#include "../include/host2net.h"
+#include "host2net.h"
+#include "cipher.h"
 
 
 /* A table describing the DOs of the card.  */
@@ -181,8 +182,6 @@ struct app_local_s {
     unsigned int sm_aes128:1;          /* Use AES-128 for SM.  */
     unsigned int max_certlen_3:16;
     unsigned int max_get_challenge:16; /* Maximum size for get_challenge.  */
-    unsigned int max_cmd_data:16;      /* Maximum data size for a command.  */
-    unsigned int max_rsp_data:16;      /* Maximum size of a response.  */
   } extcap;
 
   /* Flags used to control the application.  */
@@ -299,7 +298,7 @@ get_cached_data (app_t app, int tag,
     }
 
   if (try_extlen && app->app_local->cardcap.ext_lc_le)
-    exmode = app->app_local->extcap.max_rsp_data;
+    exmode = app->app_local->extcap.max_certlen_3;
   else
     exmode = 0;
 
@@ -429,10 +428,7 @@ get_one_do (app_t app, int tag, unsigned char **result, size_t *nbytes,
 
   if (app->card_version > 0x0100 && data_objects[i].get_immediate_in_v11)
     {
-      if (data_objects[i].try_extlen && app->app_local->cardcap.ext_lc_le)
-        exmode = app->app_local->extcap.max_rsp_data;
-      else
-        exmode = 0;
+      exmode = 0;
       rc = iso7816_get_data (app->slot, exmode, tag, &buffer, &buflen);
       if (rc)
         {
@@ -854,6 +850,7 @@ send_key_attr (ctrl_t ctrl, app_t app, const char *keyword, int number)
   assert (number >=0 && number < DIM(app->app_local->keyattr));
 
   /* We only support RSA thus the algo identifier is fixed to 1.  */
+  /* Note that PUBKEY_ALGO_RSA == 1 */
   snprintf (buffer, sizeof buffer, "%d 1 %u %u %d",
             number+1,
             app->app_local->keyattr[number].n_bits,
@@ -863,6 +860,22 @@ send_key_attr (ctrl_t ctrl, app_t app, const char *keyword, int number)
 }
 
 
+#define RSA_SMALL_SIZE_KEY 1952
+#define RSA_SMALL_SIZE_OP  2048
+
+static int
+determine_rsa_response (app_t app, int keyno)
+{
+  int size;
+
+  size = 2 + 3 /* header */
+    + 4 /* tag+len */ + app->app_local->keyattr[keyno].n_bits/8
+    + 2 /* tag+len */ + app->app_local->keyattr[keyno].e_bits/8;
+
+  return size;
+}
+
+
 /* Implement the GETATTR command.  This is similar to the LEARN
    command but returns just one value via the status interface. */
 static gpg_error_t
@@ -940,7 +953,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
                 app->app_local->extcap.max_certlen_3,
                 app->app_local->extcap.algo_attr_change,
                 (app->app_local->extcap.sm_supported
-                 ? (app->app_local->extcap.sm_aes128? 7 : 2)
+                 ? (app->app_local->extcap.sm_aes128? CIPHER_ALGO_AES : CIPHER_ALGO_3DES)
                  : 0));
       send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0);
       return 0;
@@ -1160,7 +1173,7 @@ retrieve_key_material (FILE *fp, const char *hexkeyid,
    the APP handle.  On error that field gets cleared.  If we already
    know about the public key we will just return.  Note that this does
    not mean a key is available; this is soley indicated by the
-   presence of the app->app_local->pk[KEYNO-1].key field.
+   presence of the app->app_local->pk[KEYNO].key field.
 
    Note that GnuPG 1.x does not need this and it would be too time
    consuming to send it just for the fun of it. However, given that we
@@ -1179,9 +1192,8 @@ get_public_key (app_t app, int keyno)
   char *keybuf = NULL;
   char *keybuf_p;
 
-  if (keyno < 1 || keyno > 3)
+  if (keyno < 0 || keyno > 2)
     return gpg_error (GPG_ERR_INV_ID);
-  keyno--;
 
   /* Already cached? */
   if (app->app_local->pk[keyno].read_done)
@@ -1198,10 +1210,11 @@ get_public_key (app_t app, int keyno)
       int exmode, le_value;
 
       /* We may simply read the public key out of these cards.  */
-      if (app->app_local->cardcap.ext_lc_le)
+      if (app->app_local->cardcap.ext_lc_le
+          && app->app_local->keyattr[keyno].n_bits > RSA_SMALL_SIZE_KEY)
         {
           exmode = 1;    /* Use extended length.  */
-          le_value = app->app_local->extcap.max_rsp_data;
+          le_value = determine_rsa_response (app, keyno);
         }
       else
         {
@@ -1209,12 +1222,10 @@ get_public_key (app_t app, int keyno)
           le_value = 256; /* Use legacy value. */
         }
 
-      err = iso7816_read_public_key
-        (app->slot, exmode,
-         (const unsigned char*)(keyno == 0? "\xB6" :
-                                keyno == 1? "\xB8" : "\xA4"), 2,
-         le_value,
-         &buffer, &buflen);
+      err = iso7816_read_public_key (app->slot, exmode,
+                                     (keyno == 0? "\xB6" :
+                                      keyno == 1? "\xB8" : "\xA4"),
+                                     2, le_value, &buffer, &buflen);
       if (err)
         {
           log_error (_("reading public key failed: %s\n"), gpg_strerror (err));
@@ -1361,17 +1372,18 @@ get_public_key (app_t app, int keyno)
   xfree (buffer);
   xfree (mbuf);
   xfree (ebuf);
-  return 0;
+  return err;
 }
 #endif /* GNUPG_MAJOR_VERSION > 1 */
 
 
 
-/* Send the KEYPAIRINFO back. KEYNO needs to be in the range [1,3].
+/* Send the KEYPAIRINFO back. KEY needs to be in the range [1,3].
    This is used by the LEARN command. */
 static gpg_error_t
-send_keypair_info (app_t app, ctrl_t ctrl, int keyno)
+send_keypair_info (app_t app, ctrl_t ctrl, int key)
 {
+  int keyno = key - 1;
   gpg_error_t err = 0;
   /* Note that GnuPG 1.x does not need this and it would be too time
      consuming to send it just for the fun of it. */
@@ -1384,19 +1396,19 @@ send_keypair_info (app_t app, ctrl_t ctrl, int keyno)
   if (err)
     goto leave;
 
-  assert (keyno >= 1 && keyno <= 3);
-  if (!app->app_local->pk[keyno-1].key)
+  assert (keyno >= 0 && keyno <= 2);
+  if (!app->app_local->pk[keyno].key)
     goto leave; /* No such key - ignore. */
 
-  err = keygrip_from_canon_sexp (app->app_local->pk[keyno-1].key,
-                                 app->app_local->pk[keyno-1].keylen,
+  err = keygrip_from_canon_sexp (app->app_local->pk[keyno].key,
+                                 app->app_local->pk[keyno].keylen,
                                  grip);
   if (err)
     goto leave;
 
   bin2hex (grip, 20, gripstr);
 
-  sprintf (idbuf, "OPENPGP.%d", keyno);
+  sprintf (idbuf, "OPENPGP.%d", keyno+1);
   send_status_info (ctrl, "KEYPAIRINFO",
                     gripstr, 40,
                     idbuf, strlen (idbuf),
@@ -1459,11 +1471,11 @@ do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
   unsigned char *buf;
 
   if (!strcmp (keyid, "OPENPGP.1"))
-    keyno = 1;
+    keyno = 0;
   else if (!strcmp (keyid, "OPENPGP.2"))
-    keyno = 2;
+    keyno = 1;
   else if (!strcmp (keyid, "OPENPGP.3"))
-    keyno = 3;
+    keyno = 2;
   else
     return gpg_error (GPG_ERR_INV_ID);
 
@@ -1471,10 +1483,10 @@ do_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
   if (err)
     return err;
 
-  buf = app->app_local->pk[keyno-1].key;
+  buf = app->app_local->pk[keyno].key;
   if (!buf)
     return gpg_error (GPG_ERR_NO_PUBKEY);
-  *pklen = app->app_local->pk[keyno-1].keylen;;
+  *pklen = app->app_local->pk[keyno].keylen;;
   *pk = xtrymalloc (*pklen);
   if (!*pk)
     {
@@ -2543,7 +2555,7 @@ change_keyattr (app_t app, int keyno, unsigned int nbits,
   relptr = get_one_do (app, 0xC1+keyno, &buffer, &buflen, NULL);
   if (!relptr)
     return gpg_error (GPG_ERR_CARD);
-  if (buflen < 6 || buffer[0] != 1)
+  if (buflen < 6 || buffer[0] != PUBKEY_ALGO_RSA)
     {
       /* Attriutes too short or not an RSA key.  */
       xfree (relptr);
@@ -2608,14 +2620,18 @@ change_keyattr_from_string (app_t app,
      happen.  */
   if (sscanf (string, " --force %d %d %u", &keyno, &algo, &nbits) != 3)
     err = gpg_error (GPG_ERR_INV_DATA);
-  else if (keyno < 1 || keyno > 3)
-    err = gpg_error (GPG_ERR_INV_ID);
-  else if (algo != 1)
-    err = gpg_error (GPG_ERR_PUBKEY_ALGO); /* Not RSA.  */
-  else if (nbits < 1024)
-    err = gpg_error (GPG_ERR_TOO_SHORT);
-  else
-    err = change_keyattr (app, keyno-1, nbits, pincb, pincb_arg);
+  keyno = keyno - 1;
+  if (!err)
+    {
+      if (keyno < 0 || keyno > 2)
+        err = gpg_error (GPG_ERR_INV_ID);
+      else if (algo != PUBKEY_ALGO_RSA)
+        err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+      else if (nbits < 1024)
+        err = gpg_error (GPG_ERR_TOO_SHORT);
+      else
+        err = change_keyattr (app, keyno, nbits, pincb, pincb_arg);
+    }
 
   xfree (string);
   return err;
@@ -2993,23 +3009,22 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
            gpg_error_t (*pincb)(void*, const char *, char **),
            void *pincb_arg)
 {
-  int rc;
+  gpg_error_t err;
   char numbuf[30];
   unsigned char fprbuf[20];
   const unsigned char *keydata, *m, *e;
   unsigned char *buffer = NULL;
   size_t buflen, keydatalen, mlen, elen;
-  time_t created_at;
-  int keyno = atoi (keynostr);
+  u32 created_at;
+  int keyno = atoi (keynostr) - 1;
   int force = (flags & 1);
   time_t start_at;
   int exmode;
   int le_value;
   unsigned int keybits;
 
-  if (keyno < 1 || keyno > 3)
+  if (keyno < 0 || keyno > 2)
     return gpg_error (GPG_ERR_INV_ID);
-  keyno--;
 
   /* We flush the cache to increase the traffic before a key
      generation.  This _might_ help a card to gather more entropy. */
@@ -3022,9 +3037,9 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
   app->app_local->pk[keyno].read_done = 0;
 
   /* Check whether a key already exists.  */
-  rc = does_key_exist (app, keyno, 1, force);
-  if (rc)
-    return rc;
+  err = does_key_exist (app, keyno, 1, force);
+  if (err)
+    return err;
 
   /* Because we send the key parameter back via status lines we need
      to put a limit on the max. allowed keysize.  2048 bit will
@@ -3035,16 +3050,15 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
     return gpg_error (GPG_ERR_TOO_LARGE);
 
   /* Prepare for key generation by verifying the Admin PIN.  */
-  rc = verify_chv3 (app, pincb, pincb_arg);
-  if (rc)
+  err = verify_chv3 (app, pincb, pincb_arg);
+  if (err)
     goto leave;
 
-  /* Test whether we will need extended length mode.  (1900 is an
-     arbitrary length which for sure fits into a short apdu.)  */
-  if (app->app_local->cardcap.ext_lc_le && keybits > 1900)
+  /* Test whether we will need extended length mode.  */
+  if (app->app_local->cardcap.ext_lc_le && keybits > RSA_SMALL_SIZE_KEY)
     {
       exmode = 1;    /* Use extended length w/o a limit.  */
-      le_value = app->app_local->extcap.max_rsp_data;
+      le_value = determine_rsa_response (app, keyno);
       /* No need to check le_value because it comes from a 16 bit
          value and thus can't create an overflow on a 32 bit
          system.  */
@@ -3057,17 +3071,13 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
 
   log_info (_("please wait while key is being generated ...\n"));
   start_at = time (NULL);
-  rc = iso7816_generate_keypair
-/* # warning key generation temporary replaced by reading an existing key. */
-/*   rc = iso7816_read_public_key */
-    (app->slot, exmode,
-     (const unsigned char*)(keyno == 0? "\xB6" :
-                            keyno == 1? "\xB8" : "\xA4"), 2,
-     le_value,
-     &buffer, &buflen);
-  if (rc)
+  err = iso7816_generate_keypair (app->slot, exmode,
+                                  (keyno == 0? "\xB6" :
+                                   keyno == 1? "\xB8" : "\xA4"),
+                                  2, le_value, &buffer, &buflen);
+  if (err)
     {
-      rc = gpg_error (GPG_ERR_CARD);
+      err = gpg_error (GPG_ERR_CARD);
       log_error (_("generating key failed\n"));
       goto leave;
     }
@@ -3077,7 +3087,7 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
   keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen);
   if (!keydata)
     {
-      rc = gpg_error (GPG_ERR_CARD);
+      err = gpg_error (GPG_ERR_CARD);
       log_error (_("response does not contain the public key data\n"));
       goto leave;
     }
@@ -3085,7 +3095,7 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
   m = find_tlv (keydata, keydatalen, 0x0081, &mlen);
   if (!m)
     {
-      rc = gpg_error (GPG_ERR_CARD);
+      err = gpg_error (GPG_ERR_CARD);
       log_error (_("response does not contain the RSA modulus\n"));
       goto leave;
     }
@@ -3095,28 +3105,28 @@ do_genkey (app_t app, ctrl_t ctrl,  const char *keynostr, unsigned int flags,
   e = find_tlv (keydata, keydatalen, 0x0082, &elen);
   if (!e)
     {
-      rc = gpg_error (GPG_ERR_CARD);
+      err = gpg_error (GPG_ERR_CARD);
       log_error (_("response does not contain the RSA public exponent\n"));
       goto leave;
     }
   /* log_printhex ("RSA e:", e, elen); */
   send_key_data (ctrl, "e", e, elen);
 
-  created_at = createtime? createtime : gnupg_get_time ();
-  sprintf (numbuf, "%lu", (unsigned long)created_at);
+  created_at = (u32)(createtime? createtime : gnupg_get_time ());
+  sprintf (numbuf, "%u", created_at);
   send_status_info (ctrl, "KEY-CREATED-AT",
                     numbuf, (size_t)strlen(numbuf), NULL, 0);
 
-  rc = store_fpr (app, keyno, (u32)created_at,
+  err = store_fpr (app, keyno, (u32)created_at,
                   m, mlen, e, elen, fprbuf, app->card_version);
-  if (rc)
+  if (err)
     goto leave;
   send_fpr_if_not_null (ctrl, "KEY-FPR", -1, fprbuf);
 
 
  leave:
   xfree (buffer);
-  return rc;
+  return err;
 }
 
 
@@ -3159,7 +3169,7 @@ compare_fingerprint (app_t app, int keyno, unsigned char *sha1fpr)
   size_t buflen, n;
   int rc, i;
 
-  assert (keyno >= 1 && keyno <= 3);
+  assert (keyno >= 0 && keyno <= 2);
 
   rc = get_cached_data (app, 0x006E, &buffer, &buflen, 0, 0);
   if (rc)
@@ -3174,7 +3184,7 @@ compare_fingerprint (app_t app, int keyno, unsigned char *sha1fpr)
       log_error (_("error reading fingerprint DO\n"));
       return gpg_error (GPG_ERR_GENERAL);
     }
-  fpr += (keyno-1)*20;
+  fpr += keyno*20;
   for (i=0; i < 20; i++)
     if (sha1fpr[i] != fpr[i])
       {
@@ -3193,7 +3203,7 @@ compare_fingerprint (app_t app, int keyno, unsigned char *sha1fpr)
    gpg has not been updated.  If there is no fingerprint we assume
    that this is okay. */
 static gpg_error_t
-check_against_given_fingerprint (app_t app, const char *fpr, int keyno)
+check_against_given_fingerprint (app_t app, const char *fpr, int key)
 {
   unsigned char tmp[20];
   const char *s;
@@ -3210,7 +3220,7 @@ check_against_given_fingerprint (app_t app, const char *fpr, int keyno)
 
   for (s=fpr, n=0; n < 20; s += 2, n++)
         tmp[n] = xtoi_2 (s);
-  return compare_fingerprint (app, keyno, tmp);
+  return compare_fingerprint (app, key-1, tmp);
 }
 
 
@@ -3407,10 +3417,11 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
     }
 
 
-  if (app->app_local->cardcap.ext_lc_le)
+  if (app->app_local->cardcap.ext_lc_le
+      && app->app_local->keyattr[0].n_bits > RSA_SMALL_SIZE_OP)
     {
       exmode = 1;    /* Use extended length.  */
-      le_value = app->app_local->extcap.max_rsp_data;
+      le_value = app->app_local->keyattr[0].n_bits / 8;
     }
   else
     {
@@ -3492,10 +3503,11 @@ do_auth (app_t app, const char *keyidstr,
     {
       int exmode, le_value;
 
-      if (app->app_local->cardcap.ext_lc_le)
+      if (app->app_local->cardcap.ext_lc_le
+          && app->app_local->keyattr[2].n_bits > RSA_SMALL_SIZE_OP)
         {
           exmode = 1;    /* Use extended length.  */
-          le_value = app->app_local->extcap.max_rsp_data;
+          le_value = app->app_local->keyattr[2].n_bits / 8;
         }
       else
         {
@@ -3608,10 +3620,12 @@ do_decipher (app_t app, const char *keyidstr,
           padind = -1; /* Already padded.  */
         }
 
-      if (app->app_local->cardcap.ext_lc_le && indatalen > 254 )
+      if (app->app_local->cardcap.ext_lc_le
+          && (indatalen > 254
+              || app->app_local->keyattr[1].n_bits > RSA_SMALL_SIZE_OP))
         {
           exmode = 1;    /* Extended length w/o a limit.  */
-          le_value = app->app_local->extcap.max_rsp_data;
+          le_value = app->app_local->keyattr[1].n_bits / 8;
         }
       else if (app->app_local->cardcap.cmd_chaining && indatalen > 254)
         {
@@ -3743,8 +3757,6 @@ show_caps (struct app_local_s *s)
   if (s->extcap.sm_supported)
     log_printf (" (%s)", s->extcap.sm_aes128? "AES-128":"3DES");
   log_info ("Max-Cert3-Len ..: %u\n", s->extcap.max_certlen_3);
-  log_info ("Max-Cmd-Data ...: %u\n", s->extcap.max_cmd_data);
-  log_info ("Max-Rsp-Data ...: %u\n", s->extcap.max_rsp_data);
   log_info ("Cmd-Chaining ...: %s\n", s->cardcap.cmd_chaining?"yes":"no");
   log_info ("Ext-Lc-Le ......: %s\n", s->cardcap.ext_lc_le?"yes":"no");
   log_info ("Status Indicator: %02X\n", s->status_indicator);
@@ -3833,7 +3845,7 @@ parse_algorithm_attribute (app_t app, int keyno)
 
   if (opt.verbose)
     log_info ("Key-Attr-%s ..: ", desc[keyno]);
-  if (*buffer == 1 && (buflen == 5 || buflen == 6))
+  if (*buffer == PUBKEY_ALGO_RSA && (buflen == 5 || buflen == 6))
     {
       app->app_local->keyattr[keyno].n_bits = (buffer[1]<<8 | buffer[2]);
       app->app_local->keyattr[keyno].e_bits = (buffer[3]<<8 | buffer[4]);
@@ -3972,8 +3984,6 @@ app_select_openpgp (app_t app)
           app->app_local->extcap.max_get_challenge
                                                = (buffer[2] << 8 | buffer[3]);
           app->app_local->extcap.max_certlen_3 = (buffer[4] << 8 | buffer[5]);
-          app->app_local->extcap.max_cmd_data  = (buffer[6] << 8 | buffer[7]);
-          app->app_local->extcap.max_rsp_data  = (buffer[8] << 8 | buffer[9]);
         }
       xfree (relptr);
 
index 0f36409..24ed5b0 100644 (file)
--- a/scd/app.c
+++ b/scd/app.c
@@ -183,8 +183,12 @@ application_notify_card_reset (int slot)
   /* Release the APP, as it's not reusable any more.  */
   if (lock_table[slot].app)
     {
+      if (lock_table[slot].app->ref_count)
+        log_bug ("trying to release active context\n");
+
       deallocate_app (lock_table[slot].app);
       lock_table[slot].app = NULL;
+      log_debug ("application has been released\n");
     }
 
   unlock_reader (slot);
index 8f9c1bd..07e884c 100644 (file)
@@ -1013,7 +1013,7 @@ parse_ccid_descriptor (ccid_driver_t handle,
       handle->max_ifsd = 48;
     }
 
-  if (handle->id_vendor == VENDOR_GEMPC && handle->id_product == GEMPC_CT30)
+  if (handle->id_vendor == VENDOR_GEMPC)
     {
       DEBUGOUT ("enabling product quirk: disable non-null NAD\n");
       handle->nonnull_nad = 0;
@@ -1744,79 +1744,6 @@ do_close_reader (ccid_driver_t handle)
 }
 
 
-/* Reset a reader on HANDLE.  This is useful in case a reader has been
-   plugged of and inserted at a different port.  By resetting the
-   handle, the same reader will be get used.  Note, that on error the
-   handle won't get released.
-
-   This does not return an ATR, so ccid_get_atr should be called right
-   after this one.
-*/
-int
-ccid_shutdown_reader (ccid_driver_t handle)
-{
-  int rc = 0;
-  struct usb_device *dev = NULL;
-  usb_dev_handle *idev = NULL;
-  unsigned char *ifcdesc_extra = NULL;
-  size_t ifcdesc_extra_len;
-  int ifc_no, ep_bulk_out, ep_bulk_in, ep_intr;
-
-  if (!handle || !handle->rid)
-    return CCID_DRIVER_ERR_INV_VALUE;
-
-  do_close_reader (handle);
-
-  if (scan_or_find_devices (-1, handle->rid, NULL, &dev,
-                            &ifcdesc_extra, &ifcdesc_extra_len,
-                            &ifc_no, &ep_bulk_out, &ep_bulk_in, &ep_intr,
-                            &idev, NULL) || !idev)
-    {
-      DEBUGOUT_1 ("no CCID reader with ID %s\n", handle->rid);
-      return CCID_DRIVER_ERR_NO_READER;
-    }
-
-  if (idev)
-    {
-      handle->idev = idev;
-      handle->ifc_no = ifc_no;
-      handle->ep_bulk_out = ep_bulk_out;
-      handle->ep_bulk_in = ep_bulk_in;
-      handle->ep_intr = ep_intr;
-
-      if (parse_ccid_descriptor (handle, ifcdesc_extra, ifcdesc_extra_len))
-        {
-          DEBUGOUT ("device not supported\n");
-          rc = CCID_DRIVER_ERR_NO_READER;
-          goto leave;
-        }
-
-      rc = usb_claim_interface (idev, ifc_no);
-      if (rc)
-        {
-          DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc);
-          rc = CCID_DRIVER_ERR_CARD_IO_ERROR;
-          goto leave;
-        }
-    }
-
- leave:
-  free (ifcdesc_extra);
-  if (rc)
-    {
-      if (handle->idev)
-        usb_close (handle->idev);
-      handle->idev = NULL;
-      if (handle->dev_fd != -1)
-        close (handle->dev_fd);
-      handle->dev_fd = -1;
-    }
-
-  return rc;
-
-}
-
-
 int
 ccid_set_progress_cb (ccid_driver_t handle,
                       void (*cb)(void *, const char *, int, int, int),
@@ -1878,6 +1805,11 @@ writen (int fd, const void *buf, size_t nbytes)
   return 0;
 }
 
+#if defined(ENXIO) && !defined(LIBUSB_PATH_MAX) && defined(__GNU_LIBRARY__)
+#define LIBUSB_ERRNO_NO_SUCH_DEVICE ENXIO       /* libusb-compat */
+#elif defined(ENODEV)
+#define LIBUSB_ERRNO_NO_SUCH_DEVICE ENODEV      /* Original libusb */
+#endif
 
 /* Write a MSG of length MSGLEN to the designated bulk out endpoint.
    Returns 0 on success. */
@@ -1952,26 +1884,26 @@ bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen,
                            5000 /* ms timeout */);
       if (rc == msglen)
         return 0;
-#ifdef ENODEV
-      if (rc == -(ENODEV))
+#ifdef LIBUSB_ERRNO_NO_SUCH_DEVICE
+      if (rc == -(LIBUSB_ERRNO_NO_SUCH_DEVICE))
         {
           /* The Linux libusb returns a negative error value.  Catch
              the most important one.  */
-          errno = ENODEV;
+          errno = LIBUSB_ERRNO_NO_SUCH_DEVICE;
           rc = -1;
         }
-#endif /*ENODEV*/
+#endif /*LIBUSB_ERRNO_NO_SUCH_DEVICE*/
 
       if (rc == -1)
         {
           DEBUGOUT_1 ("usb_bulk_write error: %s\n", strerror (errno));
-#ifdef ENODEV
-          if (errno == ENODEV)
+#ifdef LIBUSB_ERRNO_NO_SUCH_DEVICE
+          if (errno == LIBUSB_ERRNO_NO_SUCH_DEVICE)
             {
               handle->enodev_seen = 1;
               return CCID_DRIVER_ERR_NO_READER;
             }
-#endif /*ENODEV*/
+#endif /*LIBUSB_ERRNO_NO_SUCH_DEVICE*/
         }
       else
         DEBUGOUT_1 ("usb_bulk_write failed: %d\n", rc);
index b26bd68..2c43a3a 100644 (file)
@@ -118,10 +118,6 @@ struct server_local_s
      continue operation. */
   int card_removed;
 
-  /* Flag indicating that the application context needs to be released
-     at the next opportunity.  */
-  int app_ctx_marked_for_release;
-
   /* A disconnect command has been sent.  */
   int disconnect_allowed;
 
@@ -185,14 +181,29 @@ update_card_removed (int slot, int value)
     return;
 
   for (sl=session_list; sl; sl = sl->next_session)
-    if (sl->ctrl_backlink
-        && sl->ctrl_backlink->reader_slot == slot)
-      {
-        sl->card_removed = value;
-      }
+    {
+      ctrl_t ctrl = sl->ctrl_backlink;
+
+      if (ctrl && ctrl->reader_slot == slot)
+        {
+          sl->card_removed = value;
+          if (value)
+            {
+              struct app_ctx_s *app = ctrl->app_ctx;
+              ctrl->app_ctx = NULL;
+              release_application (app);
+            }
+        }
+    }
+
   /* Let the card application layer know about the removal.  */
   if (value)
-    application_notify_card_reset (slot);
+    {
+      log_debug ("Removal of a card: %d\n", slot);
+      apdu_close_reader (slot);
+      application_notify_card_reset (slot);
+      slot_table[slot].slot = -1;
+    }
 }
 
 
@@ -283,27 +294,36 @@ static void
 do_reset (ctrl_t ctrl, int send_reset)
 {
   int slot = ctrl->reader_slot;
+  struct app_ctx_s *app = ctrl->app_ctx;
 
   if (!(slot == -1 || (slot >= 0 && slot < DIM(slot_table))))
     BUG ();
 
-  /* If there is an active application, release it.  Tell all other
-     sessions using the same application to release the
-     application.  */
-  if (ctrl->app_ctx)
+  /* If there is an active application, release it. */
+  if (app)
     {
-      release_application (ctrl->app_ctx);
       ctrl->app_ctx = NULL;
-      if (send_reset)
+      release_application (app);
+    }
+
+  /* Release the same application which is used by other sessions.  */
+  if (send_reset)
+    {
+      struct server_local_s *sl;
+
+      for (sl=session_list; sl; sl = sl->next_session)
         {
-          struct server_local_s *sl;
+          ctrl_t c = sl->ctrl_backlink;
 
-          for (sl=session_list; sl; sl = sl->next_session)
-            if (sl->ctrl_backlink
-                && sl->ctrl_backlink->reader_slot == slot)
-              {
-                sl->app_ctx_marked_for_release = 1;
-              }
+          if (c && c != ctrl && c->reader_slot == slot)
+            {
+              struct app_ctx_s *app0 = c->app_ctx;
+              if (app0)
+                {
+                  c->app_ctx = NULL;
+                  release_application (app0);
+                }
+            }
         }
     }
 
@@ -443,16 +463,6 @@ open_card (ctrl_t ctrl, const char *apptype)
   if ( IS_LOCKED (ctrl) )
     return gpg_error (GPG_ERR_LOCKED);
 
-  /* If the application has been marked for release do it now.  We
-     can't do it immediately in do_reset because the application may
-     still be in use.  */
-  if (ctrl->server_local->app_ctx_marked_for_release)
-    {
-      ctrl->server_local->app_ctx_marked_for_release = 0;
-      release_application (ctrl->app_ctx);
-      ctrl->app_ctx = NULL;
-    }
-
   /* If we are already initialized for one specific application we
      need to check that the client didn't requested a specific
      application different from the one in use before we continue. */
@@ -482,8 +492,8 @@ open_card (ctrl_t ctrl, const char *apptype)
           else if (sw == SW_HOST_CARD_INACTIVE)
             err = gpg_error (GPG_ERR_CARD_RESET);
           else
-            err = gpg_error (GPG_ERR_CARD);
-       }
+            err = gpg_error (GPG_ERR_ENODEV);
+        }
       else
         err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
     }
@@ -1744,13 +1754,14 @@ static gpg_error_t
 cmd_restart (assuan_context_t ctx, char *line)
 {
   ctrl_t ctrl = assuan_get_pointer (ctx);
+  struct app_ctx_s *app = ctrl->app_ctx;
 
   (void)line;
 
-  if (ctrl->app_ctx)
+  if (app)
     {
-      release_application (ctrl->app_ctx);
       ctrl->app_ctx = NULL;
+      release_application (app);
     }
   if (locked_session && ctrl->server_local == locked_session)
     {
@@ -2007,10 +2018,7 @@ scd_command_handler (ctrl_t ctrl, int fd)
 
   /* We open the reader right at startup so that the ticker is able to
      update the status file. */
-  if (ctrl->reader_slot == -1)
-    {
-      ctrl->reader_slot = get_reader_slot ();
-    }
+  ctrl->reader_slot = get_reader_slot ();
 
   /* Command processing loop. */
   for (;;)
@@ -2095,7 +2103,8 @@ send_status_info (ctrl_t ctrl, const char *keyword, ...)
         }
       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
         {
-          if (*value < ' ' || *value == '+')
+          if (*value == '+' || *value == '\"' || *value == '%'
+              || *value < ' ')
             {
               sprintf (p, "%%%02X", *value);
               p += 3;
@@ -2228,9 +2237,7 @@ update_reader_status_file (int set_card_removed_flag)
       if (sw_apdu == SW_HOST_NO_READER)
         {
           /* Most likely the _reader_ has been unplugged.  */
-         application_notify_card_reset (ss->slot);
          apdu_close_reader (ss->slot);
-         ss->valid = 0;
           status = 0;
           changed = ss->changed;
         }
@@ -2310,7 +2317,7 @@ update_reader_status_file (int set_card_removed_flag)
 
           /* Set the card removed flag for all current sessions.  */
           if (ss->any && ss->status == 0 && set_card_removed_flag)
-            update_card_removed (idx, 1);
+            update_card_removed (ss->slot, 1);
 
           ss->any = 1;
 
index 2a9aa53..f22626f 100644 (file)
@@ -603,9 +603,8 @@ iso7816_internal_authenticate (int slot, int extended_mode,
    returned.  In that case a value of -1 uses a large default
    (e.g. 4096 bytes), a value larger 256 used that value.  */
 static gpg_error_t
-do_generate_keypair (int slot, int extended_mode, int readonly,
-                     const unsigned char *data, size_t datalen,
-                     int le, 
+do_generate_keypair (int slot, int extended_mode, int read_only,
+                     const char *data, size_t datalen, int le,
                      unsigned char **result, size_t *resultlen)
 {
   int sw;
@@ -616,8 +615,8 @@ do_generate_keypair (int slot, int extended_mode, int readonly,
   *resultlen = 0;
 
   sw = apdu_send_le (slot, extended_mode,
-                     0x00, CMD_GENERATE_KEYPAIR, readonly? 0x81:0x80, 0,
-                     datalen, (const char*)data,
+                     0x00, CMD_GENERATE_KEYPAIR, read_only? 0x81:0x80, 0,
+                     datalen, data,
                      le >= 0 && le < 256? 256:le,
                      result, resultlen);
   if (sw != SW_SUCCESS)
@@ -635,8 +634,8 @@ do_generate_keypair (int slot, int extended_mode, int readonly,
 
 gpg_error_t
 iso7816_generate_keypair (int slot, int extended_mode,
-                          const unsigned char *data, size_t datalen,
-                          int le, 
+                          const char *data, size_t datalen,
+                          int le,
                           unsigned char **result, size_t *resultlen)
 {
   return do_generate_keypair (slot, extended_mode, 0,
@@ -646,8 +645,8 @@ iso7816_generate_keypair (int slot, int extended_mode,
 
 gpg_error_t
 iso7816_read_public_key (int slot, int extended_mode,
-                         const unsigned char *data, size_t datalen,
-                         int le, 
+                         const char *data, size_t datalen,
+                         int le,
                          unsigned char **result, size_t *resultlen)
 {
   return do_generate_keypair (slot, extended_mode, 1,
index 4354c72..05fea65 100644 (file)
@@ -100,11 +100,11 @@ gpg_error_t iso7816_internal_authenticate (int slot, int extended_mode,
                                    int le,
                                    unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_generate_keypair (int slot, int extended_mode,
-                                    const unsigned char *data, size_t datalen,
+                                    const char *data, size_t datalen,
                                     int le,
                                     unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_read_public_key (int slot, int extended_mode,
-                                    const unsigned char *data, size_t datalen,
+                                    const char *data, size_t datalen,
                                     int le,
                                     unsigned char **result, size_t *resultlen);
 gpg_error_t iso7816_get_challenge (int slot,
index e133ddc..89b4e0e 100644 (file)
@@ -150,6 +150,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oDisableApplication, "disable-application", "@"),
   ARGPARSE_s_n (oEnablePinpadVarlen, "enable-pinpad-varlen",
                 N_("use variable length input for pinpad")),
+  ARGPARSE_s_s (oHomedir,    "homedir",      "@"),
 
   ARGPARSE_end ()
 };
index ef01a5c..ebb7ed1 100644 (file)
@@ -1489,6 +1489,8 @@ main ( int argc, char **argv)
   else if (!strcmp (opt.def_cipher_algoid, "AES")
            || !strcmp (opt.def_cipher_algoid, "AES128"))
     opt.def_cipher_algoid = "2.16.840.1.101.3.4.1.2";
+  else if (!strcmp (opt.def_cipher_algoid, "AES192") )
+    opt.def_cipher_algoid = "2.16.840.1.101.3.4.1.22";
   else if (!strcmp (opt.def_cipher_algoid, "AES256") )
     opt.def_cipher_algoid = "2.16.840.1.101.3.4.1.42";
   else if (!strcmp (opt.def_cipher_algoid, "SERPENT")
@@ -1496,7 +1498,7 @@ main ( int argc, char **argv)
     opt.def_cipher_algoid = "1.3.6.1.4.1.11591.13.2.2";
   else if (!strcmp (opt.def_cipher_algoid, "SERPENT192") )
     opt.def_cipher_algoid = "1.3.6.1.4.1.11591.13.2.22";
-  else if (!strcmp (opt.def_cipher_algoid, "SERPENT192") )
+  else if (!strcmp (opt.def_cipher_algoid, "SERPENT256") )
     opt.def_cipher_algoid = "1.3.6.1.4.1.11591.13.2.42";
   else if (!strcmp (opt.def_cipher_algoid, "SEED") )
     opt.def_cipher_algoid = "1.2.410.200004.1.4";