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.
+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)
-------------------------------------------------
Copyright 1998-2015 Free Software Foundation, Inc.
+NOTE: This branch is not anymore supported.
+ Please upgrade to version 2.2
+
+
INTRODUCTION
============
# (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
@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
@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}
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;
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);
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;
break;
case aListPackets:
- opt.list_packets=2;
default:
if( argc > 1 )
wrong_args(_("[filename]"));
}
}
if( cmd == aListPackets ) {
- set_packet_list_mode(1);
opt.list_packets=1;
+ set_packet_list_mode(1);
}
rc = proc_packets(NULL, a );
if( rc )
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 ();
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;
/* 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;
}
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;
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;
}
}
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)
static int in_transaction;
static void open_db(void);
+static void create_hashtable (TRUSTREC *vr, int type);
static int
take_write_lock (void)
rc = tdbio_write_record( &rec );
if( !rc )
tdbio_sync();
+
+ if (!rc)
+ create_hashtable (&rec, 0);
+
return rc;
}
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;
}
/* 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)
{
{
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;
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 ""
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"
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"
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"
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"
#, 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)"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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"
#
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"
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"
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"
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 ""
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"
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"
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"
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"
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"
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"
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"
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)"
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"
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"
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"
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"
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"
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"
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"
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"
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"
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
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,
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;
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;
}
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;
}
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;
}
-/* 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. */
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;
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))
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);
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);
#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. */
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. */
}
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;
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)
{
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,
}
+#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
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;
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
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)
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
{
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));
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. */
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),
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);
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)
{
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);
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;
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. */
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
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. */
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;
}
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;
}
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;
}
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;
}
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)
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])
{
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;
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);
}
}
- 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
{
{
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
{
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)
{
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);
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]);
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);
/* 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);
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;
}
-/* 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),
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. */
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);
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;
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;
+ }
}
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);
+ }
+ }
}
}
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. */
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);
}
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)
{
/* 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 (;;)
}
for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
{
- if (*value < ' ' || *value == '+')
+ if (*value == '+' || *value == '\"' || *value == '%'
+ || *value < ' ')
{
sprintf (p, "%%%02X", *value);
p += 3;
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;
}
/* 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;
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;
*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)
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,
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,
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,
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 ()
};
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")
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";