From 32118628a0f20f87791755a0a110491ad85e23ad Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 2 Nov 2011 18:29:47 +0100 Subject: [PATCH 01/68] typo fixes --- doc/gpg.texi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 715b599ec..d00e01f00 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -3202,7 +3202,7 @@ place, duplicate specification of the same filename is ignored, the last filename before a commit is used. The filename is used until a new filename is used (at commit points) and all keys are written to that file. If a new filename is given, this file is created (and -overwrites an existing one). For gnuPG versions prior to 2.1, both +overwrites an existing one). For GnuPG versions prior to 2.1, both control statements must be given. For GnuPG 2.1 and later @samp{%secring} is a no-op. @@ -3250,7 +3250,7 @@ The requested length of the generated key in bits. The default is returned by running the command @samp{gpg2 --gpgconf-list}. @item Key-Grip: @var{hexstring} -This is optional and used to generate a CSR or certificatet for an +This is optional and used to generate a CSR or certificate for an already existing key. Key-Length will be ignored when given. @item Key-Usage: @var{usage-list} From 958f29d2251a96d09439e591ea3523133930e5e9 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Sun, 6 Nov 2011 17:01:31 +0100 Subject: [PATCH 02/68] Allow creating subkeys using an existing key This works by specifying the keygrip instead of an algorithm (section number 13) and requires that the option -expert has been used. It will be easy to extend this to the primary key. --- g10/ChangeLog | 12 +++ g10/call-agent.c | 81 ++++++++++----------- g10/call-agent.h | 4 + g10/card-util.c | 6 +- g10/gpg.c | 4 +- g10/keyedit.c | 2 +- g10/keygen.c | 186 +++++++++++++++++++++++++++++++++++++++++++++-- g10/main.h | 6 +- 8 files changed, 242 insertions(+), 59 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index 4b5f2f141..892878030 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,15 @@ +2011-11-06 Werner Koch + + * card-util.c (generate_card_keys): Add arg CTRL. + + * call-agent.c (agent_readkey): New. + * keygen.c (do_create_from_keygrip): New. + (ask_algo): Add arg R_KEYGRIP and a prompt to enter it. + (generate_subkeypair): Call do_create_from_keygrip if required. + (generate_subkeypair): Add arg CTRL. Change caller. + (ask_algo): Add arg CTRL. + (generate_keypair): Ditto. + 2011-09-23 Werner Koch * gpgv.c (disable_dotlock): Rename to dotlock_disable. diff --git a/g10/call-agent.c b/g10/call-agent.c index 5a10dbdb9..445102951 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -1,6 +1,6 @@ /* call-agent.c - Divert GPG operations to the agent. * Copyright (C) 2001, 2002, 2003, 2006, 2007, 2008, 2009, - * 2010 Free Software Foundation, Inc. + * 2010, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1506,55 +1506,52 @@ agent_genkey (ctrl_t ctrl, char **cache_nonce_addr, } - -/* FIXME: Call the agent to read the public key part for a given keygrip. If +/* Call the agent to read the public key part for a given keygrip. If FROMCARD is true, the key is directly read from the current smartcard. In this case HEXKEYGRIP should be the keyID (e.g. OPENPGP.3). */ -/* int */ -/* agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip, */ -/* ksba_sexp_t *r_pubkey) */ -/* { */ -/* int rc; */ -/* membuf_t data; */ -/* size_t len; */ -/* unsigned char *buf; */ -/* char line[ASSUAN_LINELENGTH]; */ +gpg_error_t +agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip, + unsigned char **r_pubkey) +{ + gpg_error_t err; + membuf_t data; + size_t len; + unsigned char *buf; + char line[ASSUAN_LINELENGTH]; -/* *r_pubkey = NULL; */ -/* rc = start_agent (ctrl); */ -/* if (rc) */ -/* return rc; */ + *r_pubkey = NULL; + err = start_agent (ctrl, 0); + if (err) + return err; -/* rc = assuan_transact (agent_ctx, "RESET",NULL, NULL, NULL, NULL, NULL, NULL); */ -/* if (rc) */ -/* return rc; */ + err = assuan_transact (agent_ctx, "RESET",NULL, NULL, NULL, NULL, NULL, NULL); + if (err) + return err; -/* snprintf (line, DIM(line)-1, "%sREADKEY %s", */ -/* fromcard? "SCD ":"", hexkeygrip); */ -/* line[DIM(line)-1] = 0; */ + snprintf (line, DIM(line)-1, "%sREADKEY %s", fromcard? "SCD ":"", hexkeygrip); -/* init_membuf (&data, 1024); */ -/* rc = assuan_transact (agent_ctx, line, */ -/* membuf_data_cb, &data, */ -/* default_inq_cb, ctrl, NULL, NULL); */ -/* if (rc) */ -/* { */ -/* xfree (get_membuf (&data, &len)); */ -/* return rc; */ -/* } */ -/* buf = get_membuf (&data, &len); */ -/* if (!buf) */ -/* return gpg_error (GPG_ERR_ENOMEM); */ -/* if (!gcry_sexp_canon_len (buf, len, NULL, NULL)) */ -/* { */ -/* xfree (buf); */ -/* return gpg_error (GPG_ERR_INV_SEXP); */ -/* } */ -/* *r_pubkey = buf; */ -/* return 0; */ -/* } */ + init_membuf (&data, 1024); + err = assuan_transact (agent_ctx, line, + membuf_data_cb, &data, + default_inq_cb, NULL, NULL, NULL); + if (err) + { + xfree (get_membuf (&data, &len)); + return err; + } + buf = get_membuf (&data, &len); + if (!buf) + return gpg_error_from_syserror (); + if (!gcry_sexp_canon_len (buf, len, NULL, NULL)) + { + xfree (buf); + return gpg_error (GPG_ERR_INV_SEXP); + } + *r_pubkey = buf; + return 0; +} diff --git a/g10/call-agent.h b/g10/call-agent.h index 1e7e15abc..43de14fe3 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -148,6 +148,10 @@ gpg_error_t agent_genkey (ctrl_t ctrl, char **cache_nonce_addr, const char *keyparms, int no_protection, gcry_sexp_t *r_pubkey); +/* Read a public key. */ +gpg_error_t agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip, + unsigned char **r_pubkey); + /* Create a signature. */ gpg_error_t agent_pksign (ctrl_t ctrl, const char *cache_nonce, const char *hexkeygrip, const char *desc, diff --git a/g10/card-util.c b/g10/card-util.c index 9c124bbfc..14268dfeb 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -1356,7 +1356,7 @@ do_change_keysize (int keyno, unsigned int nbits) static void -generate_card_keys (void) +generate_card_keys (ctrl_t ctrl) { struct agent_card_info_s info; int forced_chv1; @@ -1435,7 +1435,7 @@ generate_card_keys (void) the serialnumber and thus it won't harm. */ } - generate_keypair (NULL, info.serialno, want_backup); + generate_keypair (ctrl, NULL, info.serialno, want_backup); leave: agent_release_card_info (&info); @@ -1986,7 +1986,7 @@ card_edit (ctrl_t ctrl, strlist_t commands) break; case cmdGENERATE: - generate_card_keys (); + generate_card_keys (ctrl); break; case cmdPASSWD: diff --git a/g10/gpg.c b/g10/gpg.c index c31a55863..aa37a88b6 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -3709,12 +3709,12 @@ main (int argc, char **argv) if( opt.batch ) { if( argc > 1 ) wrong_args("--gen-key [parameterfile]"); - generate_keypair (argc? *argv : NULL, NULL, 0); + generate_keypair (ctrl, argc? *argv : NULL, NULL, 0); } else { if( argc ) wrong_args("--gen-key"); - generate_keypair (NULL, NULL, 0); + generate_keypair (ctrl, NULL, NULL, 0); } break; diff --git a/g10/keyedit.c b/g10/keyedit.c index fd42439a8..26e05a02d 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1794,7 +1794,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, break; case cmdADDKEY: - if (!generate_subkeypair (keyblock)) + if (!generate_subkeypair (ctrl, keyblock)) { redisplay = 1; modified = 1; diff --git a/g10/keygen.c b/g10/keygen.c index a5650a8bf..55048b163 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1254,6 +1254,91 @@ key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, } +/* Create a keyblock using the given KEYGRIP. ALGO is the OpenPGP + algorithm of that keygrip. */ +static int +do_create_from_keygrip (ctrl_t ctrl, int algo, const char *hexkeygrip, + kbnode_t pub_root, u32 timestamp, u32 expireval, + int is_subkey) +{ + int err; + PACKET *pkt; + PKT_public_key *pk; + gcry_sexp_t s_key; + const char *algoelem; + + if (hexkeygrip[0] == '&') + hexkeygrip++; + + switch (algo) + { + case PUBKEY_ALGO_RSA: algoelem = "ne"; break; + case PUBKEY_ALGO_DSA: algoelem = "pqgy"; break; + case PUBKEY_ALGO_ELGAMAL_E: algoelem = "pgy"; break; + case PUBKEY_ALGO_ECDH: + case PUBKEY_ALGO_ECDSA: algoelem = ""; break; + default: return gpg_error (GPG_ERR_INTERNAL); + } + + + /* Ask the agent for the public key matching HEXKEYGRIP. */ + { + unsigned char *public; + + err = agent_readkey (ctrl, 0, hexkeygrip, &public); + if (err) + return err; + err = gcry_sexp_sscan (&s_key, NULL, + public, gcry_sexp_canon_len (public, 0, NULL, NULL)); + xfree (public); + if (err) + return err; + } + + /* Build a public key packet. */ + pk = xtrycalloc (1, sizeof *pk); + if (!pk) + { + err = gpg_error_from_syserror (); + gcry_sexp_release (s_key); + return err; + } + + pk->timestamp = timestamp; + pk->version = 4; + if (expireval) + pk->expiredate = pk->timestamp + expireval; + pk->pubkey_algo = algo; + + if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH) + err = ecckey_from_sexp (pk->pkey, s_key, algo); + else + err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem); + if (err) + { + log_error ("key_from_sexp failed: %s\n", gpg_strerror (err) ); + gcry_sexp_release (s_key); + free_public_key (pk); + return err; + } + gcry_sexp_release (s_key); + + pkt = xtrycalloc (1, sizeof *pkt); + if (!pkt) + { + err = gpg_error_from_syserror (); + free_public_key (pk); + return err; + } + + pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY; + pkt->pkt.public_key = pk; + add_kbnode (pub_root, new_kbnode (pkt)); + + return 0; +} + + /* Common code for the key generation fucntion gen_xxx. */ static int common_gen (const char *keyparms, int algo, const char *algoelem, @@ -1691,14 +1776,53 @@ ask_key_flags(int algo,int subkey) } +/* Check whether we have a key for the key with HEXGRIP. Returns 0 if + there is no such key or the OpenPGP algo number for the key. */ +static int +check_keygrip (ctrl_t ctrl, const char *hexgrip) +{ + gpg_error_t err; + unsigned char *public; + size_t publiclen; + int algo; + + if (hexgrip[0] == '&') + hexgrip++; + + err = agent_readkey (ctrl, 0, hexgrip, &public); + if (err) + return 0; + publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL); + + get_pk_algo_from_canon_sexp (public, publiclen, &algo); + xfree (public); + + switch (algo) + { + case GCRY_PK_RSA: return PUBKEY_ALGO_RSA; + case GCRY_PK_DSA: return PUBKEY_ALGO_DSA; + case GCRY_PK_ELG_E: return PUBKEY_ALGO_ELGAMAL_E; + case GCRY_PK_ECDH: return PUBKEY_ALGO_ECDH; + case GCRY_PK_ECDSA: return PUBKEY_ALGO_ECDSA; + default: return 0; + } +} + + + /* Ask for an algorithm. The function returns the algorithm id to * create. If ADDMODE is false the function won't show an option to * create the primary and subkey combined and won't set R_USAGE * either. If a combined algorithm has been selected, the subkey - * algorithm is stored at R_SUBKEY_ALGO. */ + * algorithm is stored at R_SUBKEY_ALGO. If R_KEYGRIP is given, the + * user has the choice to enter the keygrip of an existing key. That + * keygrip is then stored at this address. The caller needs to free + * it. */ static int -ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage) +ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage, + char **r_keygrip) { + char *keygrip = NULL; char *answer; int algo; int dummy_algo; @@ -1736,6 +1860,9 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage) if (opt.expert && addmode) tty_printf (_(" (%d) ECDH (encrypt only)\n"), 12 ); + if (opt.expert && r_keygrip) + tty_printf (_(" (%d) Existing key\n"), 13 ); + for (;;) { *r_usage = 0; @@ -1744,6 +1871,7 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage) cpr_kill_prompt (); algo = *answer? atoi (answer) : 1; xfree(answer); + answer = NULL; if (algo == 1 && !addmode) { algo = PUBKEY_ALGO_RSA; @@ -1816,10 +1944,42 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage) *r_usage = PUBKEY_USAGE_ENC; break; } + else if (algo == 13 && opt.expert && r_keygrip) + { + for (;;) + { + xfree (answer); + answer = tty_get (_("Enter the keygrip: ")); + tty_kill_prompt (); + trim_spaces (answer); + if (!*answer) + { + xfree (answer); + answer = NULL; + continue; + } + + if (strlen (answer) != 40 && + !(answer[0] == '&' && strlen (answer+1) == 40)) + tty_printf + (_("Not a valid keygrip (expecting 40 hex digits)\n")); + else if (!(algo = check_keygrip (ctrl, answer)) ) + tty_printf (_("No key with this keygrip\n")); + else + break; /* Okay. */ + } + xfree (keygrip); + keygrip = answer; + answer = NULL; + *r_usage = ask_key_flags (algo, addmode); + break; + } else tty_printf (_("Invalid selection.\n")); } + if (r_keygrip) + *r_keygrip = keygrip; return algo; } @@ -3099,7 +3259,7 @@ read_parameter_file( const char *fname ) * imported to the card and a backup file created by gpg-agent. */ void -generate_keypair (const char *fname, const char *card_serialno, +generate_keypair (ctrl_t ctrl, const char *fname, const char *card_serialno, int card_backup_key) { unsigned int nbits; @@ -3180,7 +3340,11 @@ generate_keypair (const char *fname, const char *card_serialno, { int subkey_algo; - algo = ask_algo (0, &subkey_algo, &use); + /* Fixme: To support creating a primary key by keygrip we better + also define the keyword for the parameter file. Note that + the subkey case will never be asserted if a keygrip has been + given. */ + algo = ask_algo (ctrl, 0, &subkey_algo, &use, NULL); if (subkey_algo) { /* Create primary and subkey at once. */ @@ -3653,7 +3817,7 @@ do_generate_keypair (struct para_data_s *para, /* Add a new subkey to an existing key. Returns 0 if a new key has been generated and put into the keyblocks. */ gpg_error_t -generate_subkeypair (KBNODE keyblock) +generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock) { gpg_error_t err = 0; kbnode_t node; @@ -3712,9 +3876,11 @@ generate_subkeypair (KBNODE keyblock) if (serialno) tty_printf (_("Secret parts of primary key are stored on-card.\n")); - algo = ask_algo (1, NULL, &use); + xfree (hexgrip); + hexgrip = NULL; + algo = ask_algo (ctrl, 1, NULL, &use, &hexgrip); assert (algo); - nbits = ask_keysize (algo, 0); + nbits = hexgrip? 0 : ask_keysize (algo, 0); expire = ask_expire_interval (0, NULL); if (!cpr_enabled() && !cpr_get_answer_is_yes("keygen.sub.okay", _("Really create? (y/N) "))) @@ -3723,7 +3889,11 @@ generate_subkeypair (KBNODE keyblock) goto leave; } - err = do_create (algo, nbits, keyblock, cur_time, expire, 1, 0, NULL); + if (hexgrip) + err = do_create_from_keygrip (ctrl, algo, hexgrip, + keyblock, cur_time, expire, 1); + else + err = do_create (algo, nbits, keyblock, cur_time, expire, 1, 0, NULL); if (err) goto leave; diff --git a/g10/main.h b/g10/main.h index 9548731fc..7088abec9 100644 --- a/g10/main.h +++ b/g10/main.h @@ -240,8 +240,8 @@ const char *gpg_curve_to_oid (const char *name, unsigned int *r_nbits); u32 parse_expire_string(const char *string); u32 ask_expire_interval(int object,const char *def_expire); u32 ask_expiredate(void); -void generate_keypair (const char *fname, const char *card_serialno, - int card_backup_key); +void generate_keypair (ctrl_t ctrl, const char *fname, + const char *card_serialno, int card_backup_key); int keygen_set_std_prefs (const char *string,int personal); PKT_user_id *keygen_get_std_prefs (void); int keygen_add_key_expire( PKT_signature *sig, void *opaque ); @@ -253,7 +253,7 @@ int keygen_add_revkey(PKT_signature *sig, void *opaque); gpg_error_t make_backsig (PKT_signature *sig, PKT_public_key *pk, PKT_public_key *sub_pk, PKT_public_key *sub_psk, u32 timestamp, const char *cache_nonce); -gpg_error_t generate_subkeypair (kbnode_t pub_keyblock); +gpg_error_t generate_subkeypair (ctrl_t ctrl, kbnode_t pub_keyblock); #ifdef ENABLE_CARD_SUPPORT gpg_error_t generate_card_subkeypair (kbnode_t pub_keyblock, int keyno, const char *serialno); From ea9df94ec8d6b7b13bd65ea14caca015bd534460 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 22 Nov 2011 15:30:26 +0100 Subject: [PATCH 03/68] Don't print anonymous recipient messages in quiet mode. This is bug#1378. --- g10/ChangeLog | 5 +++++ g10/pubkey-enc.c | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index 892878030..c799fc965 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,8 @@ +2011-11-22 Werner Koch + + * pubkey-enc.c (get_session_key): Don't print anonymous recipient + messages in quiet mode. This is bug#1378. + 2011-11-06 Werner Koch * card-util.c (generate_card_keys): Add arg CTRL. diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 680182b5d..a0fe685f4 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -110,13 +110,15 @@ get_session_key (PKT_pubkey_enc * k, DEK * dek) if (!(sk->pubkey_usage & PUBKEY_USAGE_ENC)) continue; keyid_from_pk (sk, keyid); - log_info (_("anonymous recipient; trying secret key %s ...\n"), - keystr (keyid)); + if (!opt.quiet) + log_info (_("anonymous recipient; trying secret key %s ...\n"), + keystr (keyid)); rc = get_it (k, dek, sk, keyid); if (!rc) { - log_info (_("okay, we are the anonymous recipient.\n")); + if (!opt.quiet) + log_info (_("okay, we are the anonymous recipient.\n")); break; } else if (gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED) From 725d3589ada10266e4350f56a4f89e4d82b4dc16 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 24 Nov 2011 14:16:22 +0100 Subject: [PATCH 04/68] Updated the German translation. * po/de.po: Update. --- po/de.po | 56 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/po/de.po b/po/de.po index 5f80e0998..51d7e03fd 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.1.0\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2011-03-08 12:47+0100\n" +"PO-Revision-Date: 2011-11-24 14:15+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: German \n" "MIME-Version: 1.0\n" @@ -131,28 +131,28 @@ msgstr "Fehler beim Schreiben des Schlüssels: %s\n" msgid "" "An ssh process requested the use of key%%0A %s%%0A (%s)%%0ADo you want to " "allow this?" -msgstr "" +msgstr "Ein SSH Processs möchte folgenden Schlüssel verwenden:%%0A %s%%0A (%s)%%0AErlauben Sie dies?" msgid "Allow" -msgstr "" +msgstr "Erlauben" msgid "Deny" -msgstr "" +msgstr "Verweigern" -#, fuzzy, c-format +#, c-format msgid "Please enter the passphrase for the ssh key%%0A %F%%0A (%c)" -msgstr "Bitte geben Sie die Passphrase für den SSH-Schlüssel %0A %c ein." +msgstr "Bitte geben Sie die Passphrase für den SSH-Schlüssel%%0A %F%%0A (%c)%%0Aein." msgid "Please re-enter this passphrase" msgstr "Bitte geben Sie die Passphrase noch einmal ein:" -#, fuzzy, c-format +#, c-format msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A %" "s%%0Awithin gpg-agent's key storage" msgstr "" -"Bitte geben Sie eine Passphrase ein, um den empfangenen geheimen Schlüssel%%" -"0A %s%%0A im Schlüsselspeicher des gpg-agenten zu schützen." +"Bitte geben Sie eine Passphrase ein, um den empfangenen geheimen\n" +"Schlüssel%%0A %s%%0A %s%%0Aim Schlüsselspeicher des Gpg-Agenten zu schützen." msgid "does not match - try again" msgstr "Keine Ãœbereinstimmung - bitte nochmal versuchen." @@ -1437,9 +1437,8 @@ msgstr "Diesen Schlüssel aus dem Schlüsselbund löschen? (j/N) " msgid "This is a secret key! - really delete? (y/N) " msgstr "Dies ist ein privater Schlüssel! - Wirklich löschen? (j/N) " -#, fuzzy msgid "deleting secret key not implemented\n" -msgstr "Exportieren geheimer Schlüssel ist nicht erlaubt\n" +msgstr "Löschen des geheimen Schlüssel ist nicht implementiert\n" #, c-format msgid "deleting keyblock failed: %s\n" @@ -3594,6 +3593,19 @@ msgstr " (%d) ECDSA (Leistungsfähigkeit selber einstellbar)\n" msgid " (%d) ECDH (encrypt only)\n" msgstr " (%d) ECDH (nur verschlüsseln)\n" +#, c-format +msgid " (%d) Existing key\n" +msgstr " (%d) Vorhandener Schlüssel\n" + +msgid "Enter the keygrip: " +msgstr "Geben Sie den \"Keygrip\" ein: " + +msgid "Not a valid keygrip (expecting 40 hex digits)\n" +msgstr "Kein gültiger \"Keygrip\" (40 Hex-Ziffern werden erwartet)\n" + +msgid "No key with this keygrip\n" +msgstr "Kein Schlüssel mit diesem \"Keygrip\"\n" + #, c-format msgid "%s keys may be between %u and %u bits long.\n" msgstr "%s-Schlüssel können zwischen %u und %u Bit lang sein.\n" @@ -5882,15 +5894,6 @@ msgstr " (%d) Vorhandener Schlüssel\n" msgid " (%d) Existing key from card\n" msgstr " (%d) Vorhandener Schlüssel auf der Karte\n" -msgid "Enter the keygrip: " -msgstr "Geben Sie den \"Keygrip\" ein: " - -msgid "Not a valid keygrip (expecting 40 hex digits)\n" -msgstr "Kein gültiger \"Keygrip\" (40 Hex-Ziffern werden erwartet)\n" - -msgid "No key with this keygrip\n" -msgstr "Kein Schlüssel mit diesem \"Keygrip\"\n" - #, c-format msgid "error reading the card: %s\n" msgstr "Fehler beim Lesen von der Karte: %s\n" @@ -7676,23 +7679,22 @@ msgid "Configuration for OCSP" msgstr "Konfiguration zu OCSP" msgid "GPG for OpenPGP" -msgstr "" +msgstr "GPG für OpenPGP" msgid "GPG Agent" -msgstr "" +msgstr "GPG Agent" msgid "Smartcard Daemon" -msgstr "" +msgstr "Smartcard Daemon" msgid "GPG for S/MIME" -msgstr "" +msgstr "GPG für S/MIME" msgid "Directory Manager" -msgstr "" +msgstr "Directory Manager" -#, fuzzy msgid "PIN and Passphrase Entry" -msgstr "Falsche Passphrase!" +msgstr "Falsche PIN oder Passphrase!" #, c-format msgid "External verification of component %s failed" From d2a979452e541183cae7e6e04634b5bbdab9c9d7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 24 Nov 2011 15:48:24 +0100 Subject: [PATCH 05/68] Make HKP kyeserver engine work again. We had some debug code here which prevented it from working. The host selection code still needs a review! * ks-engine-http.c (ks_http_help): Do not print help for hkp. * ks-engine-hkp.c (ks_hkp_help): Print help only for hkp. (send_request): Remove test code. (map_host): Use xtrymalloc. * certcache.c (classify_pattern): Remove unused variable and make explicit substring search work. --- dirmngr/ChangeLog | 10 ++++++++++ dirmngr/certcache.c | 5 ++--- dirmngr/ks-action.c | 2 +- dirmngr/ks-engine-hkp.c | 8 ++++---- dirmngr/ks-engine-http.c | 2 +- dirmngr/ldap.c | 4 ++-- 6 files changed, 20 insertions(+), 11 deletions(-) diff --git a/dirmngr/ChangeLog b/dirmngr/ChangeLog index a06558c0e..0968b411c 100644 --- a/dirmngr/ChangeLog +++ b/dirmngr/ChangeLog @@ -1,3 +1,13 @@ +2011-11-24 Werner Koch + + * ks-engine-http.c (ks_http_help): Do not print help for hkp. + * ks-engine-hkp.c (ks_hkp_help): Print help only for hkp. + (send_request): Remove test code. + (map_host): Use xtrymalloc. + + * certcache.c (classify_pattern): Remove unused variable and make + explicit substring search work. + 2011-06-01 Marcus Brinkmann * Makefile.am (dirmngr_ldap_CFLAGS): Add $(LIBGCRYPT_CFLAGS), diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index 3ada60dfe..a8b84e6e3 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -681,11 +681,10 @@ get_cert_bysubject (const char *subject_dn, unsigned int seq) static enum pattern_class classify_pattern (const char *pattern, size_t *r_offset, size_t *r_sn_offset) { - enum pattern_class result = PATTERN_UNKNOWN; + enum pattern_class result; const char *s; int hexprefix = 0; int hexlength; - int mode = 0; *r_offset = *r_sn_offset = 0; @@ -718,7 +717,7 @@ classify_pattern (const char *pattern, size_t *r_offset, size_t *r_sn_offset) break; case '*': /* Case insensitive substring search. */ - mode = PATTERN_SUBSTR; + result = PATTERN_SUBSTR; s++; break; diff --git a/dirmngr/ks-action.c b/dirmngr/ks-action.c index 14de4d6c0..9ebf69b3c 100644 --- a/dirmngr/ks-action.c +++ b/dirmngr/ks-action.c @@ -87,7 +87,7 @@ ks_action_help (ctrl_t ctrl, const char *url) if (!parsed_uri) ks_print_help (ctrl, - "(Use the schema followed by a colon for specific help.)"); + "(Use an URL for engine specific help.)"); else http_release_parsed_uri (parsed_uri); return err; diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index d4a12111b..98187ab01 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -209,7 +209,7 @@ map_host (const char *name) int refidx; reftblsize = 100; - reftbl = xmalloc (reftblsize * sizeof *reftbl); + reftbl = xtrymalloc (reftblsize * sizeof *reftbl); if (!reftbl) return NULL; refidx = 0; @@ -280,7 +280,7 @@ map_host (const char *name) else { if (ai->ai_family == AF_INET) - hosttable[tmpidx]->v4 = 1; + hosttable[tmpidx]->v4 = 1; if (ai->ai_family == AF_INET6) hosttable[tmpidx]->v6 = 1; @@ -409,7 +409,7 @@ ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri) if (!uri) err = ks_print_help (ctrl, " hkp"); - else if (uri->is_http) + else if (uri->is_http && !strcmp (uri->scheme, "hkp")) err = ks_print_help (ctrl, data); else err = 0; @@ -472,7 +472,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr, char *request_buffer = NULL; *r_fp = NULL; - return gpg_error (GPG_ERR_NOT_SUPPORTED); + once_more: err = http_open (&http, post_cb? HTTP_REQ_POST : HTTP_REQ_GET, diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index 2ce1b19a1..b0e2e14cb 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -43,7 +43,7 @@ ks_http_help (ctrl_t ctrl, parsed_uri_t uri) if (!uri) err = ks_print_help (ctrl, " http"); - else if (uri->is_http) + else if (uri->is_http && strcmp (uri->scheme, "hkp")) err = ks_print_help (ctrl, data); else err = 0; diff --git a/dirmngr/ldap.c b/dirmngr/ldap.c index 87121fd83..638348b5b 100644 --- a/dirmngr/ldap.c +++ b/dirmngr/ldap.c @@ -666,7 +666,7 @@ fetch_next_cert_ldap (cert_fetch_context_t context, char *p, *pend; int n; int okay = 0; - int is_cms = 0; + /* int is_cms = 0; */ *value = NULL; *valuelen = 0; @@ -758,7 +758,7 @@ fetch_next_cert_ldap (cert_fetch_context_t context, { p = context->tmpbuf; p[n] = 0; /*(we allocated one extra byte for this.)*/ - is_cms = 0; + /* fixme: is_cms = 0; */ if ( (pend = strchr (p, ';')) ) *pend = 0; /* Strip off the extension. */ if (!ascii_strcasecmp (p, USERCERTIFICATE)) From 231d27e0fec905be52d679961332947c3331f15f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 24 Nov 2011 15:48:24 +0100 Subject: [PATCH 06/68] Make HKP keyserver engine work again. We had some debug code here which prevented it from working. The host selection code still needs a review! * ks-engine-http.c (ks_http_help): Do not print help for hkp. * ks-engine-hkp.c (ks_hkp_help): Print help only for hkp. (send_request): Remove test code. (map_host): Use xtrymalloc. * certcache.c (classify_pattern): Remove unused variable and make explicit substring search work. --- dirmngr/ChangeLog | 10 ++++++++++ dirmngr/certcache.c | 5 ++--- dirmngr/ks-action.c | 2 +- dirmngr/ks-engine-hkp.c | 8 ++++---- dirmngr/ks-engine-http.c | 2 +- dirmngr/ldap.c | 4 ++-- 6 files changed, 20 insertions(+), 11 deletions(-) diff --git a/dirmngr/ChangeLog b/dirmngr/ChangeLog index a06558c0e..0968b411c 100644 --- a/dirmngr/ChangeLog +++ b/dirmngr/ChangeLog @@ -1,3 +1,13 @@ +2011-11-24 Werner Koch + + * ks-engine-http.c (ks_http_help): Do not print help for hkp. + * ks-engine-hkp.c (ks_hkp_help): Print help only for hkp. + (send_request): Remove test code. + (map_host): Use xtrymalloc. + + * certcache.c (classify_pattern): Remove unused variable and make + explicit substring search work. + 2011-06-01 Marcus Brinkmann * Makefile.am (dirmngr_ldap_CFLAGS): Add $(LIBGCRYPT_CFLAGS), diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index 3ada60dfe..a8b84e6e3 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -681,11 +681,10 @@ get_cert_bysubject (const char *subject_dn, unsigned int seq) static enum pattern_class classify_pattern (const char *pattern, size_t *r_offset, size_t *r_sn_offset) { - enum pattern_class result = PATTERN_UNKNOWN; + enum pattern_class result; const char *s; int hexprefix = 0; int hexlength; - int mode = 0; *r_offset = *r_sn_offset = 0; @@ -718,7 +717,7 @@ classify_pattern (const char *pattern, size_t *r_offset, size_t *r_sn_offset) break; case '*': /* Case insensitive substring search. */ - mode = PATTERN_SUBSTR; + result = PATTERN_SUBSTR; s++; break; diff --git a/dirmngr/ks-action.c b/dirmngr/ks-action.c index 14de4d6c0..9ebf69b3c 100644 --- a/dirmngr/ks-action.c +++ b/dirmngr/ks-action.c @@ -87,7 +87,7 @@ ks_action_help (ctrl_t ctrl, const char *url) if (!parsed_uri) ks_print_help (ctrl, - "(Use the schema followed by a colon for specific help.)"); + "(Use an URL for engine specific help.)"); else http_release_parsed_uri (parsed_uri); return err; diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index d4a12111b..98187ab01 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -209,7 +209,7 @@ map_host (const char *name) int refidx; reftblsize = 100; - reftbl = xmalloc (reftblsize * sizeof *reftbl); + reftbl = xtrymalloc (reftblsize * sizeof *reftbl); if (!reftbl) return NULL; refidx = 0; @@ -280,7 +280,7 @@ map_host (const char *name) else { if (ai->ai_family == AF_INET) - hosttable[tmpidx]->v4 = 1; + hosttable[tmpidx]->v4 = 1; if (ai->ai_family == AF_INET6) hosttable[tmpidx]->v6 = 1; @@ -409,7 +409,7 @@ ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri) if (!uri) err = ks_print_help (ctrl, " hkp"); - else if (uri->is_http) + else if (uri->is_http && !strcmp (uri->scheme, "hkp")) err = ks_print_help (ctrl, data); else err = 0; @@ -472,7 +472,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr, char *request_buffer = NULL; *r_fp = NULL; - return gpg_error (GPG_ERR_NOT_SUPPORTED); + once_more: err = http_open (&http, post_cb? HTTP_REQ_POST : HTTP_REQ_GET, diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index 2ce1b19a1..b0e2e14cb 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -43,7 +43,7 @@ ks_http_help (ctrl_t ctrl, parsed_uri_t uri) if (!uri) err = ks_print_help (ctrl, " http"); - else if (uri->is_http) + else if (uri->is_http && strcmp (uri->scheme, "hkp")) err = ks_print_help (ctrl, data); else err = 0; diff --git a/dirmngr/ldap.c b/dirmngr/ldap.c index 87121fd83..638348b5b 100644 --- a/dirmngr/ldap.c +++ b/dirmngr/ldap.c @@ -666,7 +666,7 @@ fetch_next_cert_ldap (cert_fetch_context_t context, char *p, *pend; int n; int okay = 0; - int is_cms = 0; + /* int is_cms = 0; */ *value = NULL; *valuelen = 0; @@ -758,7 +758,7 @@ fetch_next_cert_ldap (cert_fetch_context_t context, { p = context->tmpbuf; p[n] = 0; /*(we allocated one extra byte for this.)*/ - is_cms = 0; + /* fixme: is_cms = 0; */ if ( (pend = strchr (p, ';')) ) *pend = 0; /* Strip off the extension. */ if (!ascii_strcasecmp (p, USERCERTIFICATE)) From 26b4a012e3eb3a6ce79a1e53f7cdfbbdf8c8e8f5 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 28 Nov 2011 16:16:38 +0900 Subject: [PATCH 07/68] PC/SC pinpad support. Before this change, it is layered like following: iso7816_verify iso7816_verify_kp apdu_send_simple, apdu_send_simple_kp ... After this change, it will be layered like: iso7816_verify iso7816_verify_kp apdu_send_simple apdu_keypad_verify ... and apdu_send_simple_kp will be deprecated. For PC/SC API, we use: SCardControl API to compose CCID PC_to_RDR_Secure message SCardTransmit API to compose CCID PC_to_RDR_XfrBlock message Considering the support of PC/SC, we have nothing to share between _kp version of iso7816_* and no _kp version. --- scd/ChangeLog | 35 +++++ scd/apdu.c | 362 ++++++++++++++++++++++++++++++++++++++++++++- scd/apdu.h | 3 + scd/app-dinsig.c | 2 +- scd/app-nks.c | 2 +- scd/app-openpgp.c | 4 +- scd/iso7816.c | 23 ++- scd/iso7816.h | 4 +- scd/pcsc-wrapper.c | 50 ++++++- 9 files changed, 460 insertions(+), 25 deletions(-) diff --git a/scd/ChangeLog b/scd/ChangeLog index 45c9c7c0c..9f991cec0 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,38 @@ +2011-11-28 Niibe Yutaka + + * iso7816.h (iso7816_verify_kp): Remove arguments of CHV and CHVLEN. + + * iso7816.c (iso7816_verify_kp): Call apdu_keypad_verify. Only + handle thecase with PININFO. + (iso7816_verify): Call apdu_send_simple. + + * app-openpgp.c (verify_a_chv, verify_chv3): Follow the change of + iso7816_verify_kp. + + * app-nks.c (verify_pin): Likewise. + + * app-dinsig.c (verify_pin): Likewise. + + * apdu.c: Include "iso7816.h". + (struct reader_table_s): New memeber function keypad_verify. + Add fields verify_ioctl and modify_ioctl in pcsc. + (CM_IOCTL_GET_FEATURE_REQUEST, FEATURE_VERIFY_PIN_DIRECT) + (FEATURE_MODIFY_PIN_DIRECT): New. + (pcsc_control): New. + (control_pcsc_direct, control_pcsc_wrapped, control_pcsc) + (check_pcsc_keypad, pcsc_keypad_verify): New. + (ccid_keypad_verify, apdu_keypad_verify): New. + (new_reader_slot): Initialize with check_pcsc_keypad, + pcsc_keypad_verify, verify_ioctl and modify_ioctl. + (open_ct_reader): Initialize keypad_verify with NULL. + (open_ccid_reader): Initialize keypad_verify. + (open_rapdu_reader): Initialize keypad_verify with NULL. + (apdu_open_reader): Initialize pcsc_control. + + * pcsc-wrapper.c (load_pcsc_driver): Initialize pcsc_control. + (handle_control): New. + (main): Handle the case 6 of handle_control. + 2011-08-10 Werner Koch * command.c (cmd_killscd): Use the new assuan force close flag diff --git a/scd/apdu.c b/scd/apdu.c index ac563adef..866ebb916 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -62,6 +62,7 @@ #include "apdu.h" #include "ccid-driver.h" +#include "iso7816.h" /* Due to conflicting use of threading libraries we usually can't link @@ -110,6 +111,7 @@ struct reader_table_s { int (*check_keypad)(int, int, int, int, int, int); void (*dump_status_reader)(int); int (*set_progress_cb)(int, gcry_handler_progress_t, void*); + int (*keypad_verify)(int, int, int, int, int, struct pininfo_s *); struct { ccid_driver_t handle; @@ -118,6 +120,8 @@ struct reader_table_s { unsigned long context; unsigned long card; unsigned long protocol; + unsigned long verify_ioctl; + unsigned long modify_ioctl; #ifdef NEED_PCSC_WRAPPER int req_fd; int rsp_fd; @@ -236,6 +240,11 @@ static char (* DLSTDCALL CT_close) (unsigned short ctn); #define PCSC_E_READER_UNAVAILABLE 0x80100017 #define PCSC_W_REMOVED_CARD 0x80100069 +#define CM_IOCTL_GET_FEATURE_REQUEST (0x42000000 + 3400) +#define FEATURE_VERIFY_PIN_DIRECT 0x06 +#define FEATURE_MODIFY_PIN_DIRECT 0x07 + + /* The PC/SC error is defined as a long as per specs. Due to left shifts bit 31 will get sign extended. We use this mask to fix it. */ @@ -304,6 +313,13 @@ long (* DLSTDCALL pcsc_transmit) (unsigned long card, unsigned long *recv_len); long (* DLSTDCALL pcsc_set_timeout) (unsigned long context, unsigned long timeout); +long (* DLSTDCALL pcsc_control) (unsigned long card, + unsigned long control_code, + const void *send_buffer, + unsigned long send_len, + void *recv_buffer, + unsigned long recv_len, + unsigned long *bytes_returned); /* Flag set if PC/SC returned the no-service error. */ static int pcsc_no_service; @@ -315,6 +331,10 @@ static int reset_pcsc_reader (int slot); static int apdu_get_status_internal (int slot, int hang, int no_atr_reset, unsigned int *status, unsigned int *changed); +static int check_pcsc_keypad (int slot, int command, int pin_mode, + int pinlen_min, int pinlen_max, int pin_padlen); +static int pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, + struct pininfo_s *pininfo); @@ -358,9 +378,10 @@ new_reader_slot (void) reader_table[reader].reset_reader = NULL; reader_table[reader].get_status_reader = NULL; reader_table[reader].send_apdu_reader = NULL; - reader_table[reader].check_keypad = NULL; + reader_table[reader].check_keypad = check_pcsc_keypad; reader_table[reader].dump_status_reader = NULL; reader_table[reader].set_progress_cb = NULL; + reader_table[reader].keypad_verify = pcsc_keypad_verify; reader_table[reader].used = 1; reader_table[reader].any_status = 0; @@ -371,6 +392,8 @@ new_reader_slot (void) reader_table[reader].pcsc.rsp_fd = -1; reader_table[reader].pcsc.pid = (pid_t)(-1); #endif + reader_table[reader].pcsc.verify_ioctl = 0; + reader_table[reader].pcsc.modify_ioctl = 0; return reader; } @@ -645,6 +668,7 @@ open_ct_reader (int port) reader_table[reader].send_apdu_reader = ct_send_apdu; reader_table[reader].check_keypad = NULL; reader_table[reader].dump_status_reader = ct_dump_reader_status; + reader_table[reader].keypad_verify = NULL; dump_reader_status (reader); return reader; @@ -1170,6 +1194,150 @@ pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen, } +#ifndef NEED_PCSC_WRAPPER +static int +control_pcsc_direct (int slot, unsigned long ioctl_code, + const unsigned char *cntlbuf, size_t len, + unsigned char *buffer, size_t *buflen) +{ + long err; + + err = pcsc_control (reader_table[slot].pcsc.card, ioctl_code, + cntlbuf, len, buffer, *buflen, buflen); + if (err) + { + log_error ("pcsc_control failed: %s (0x%lx)\n", + pcsc_error_string (err), err); + return pcsc_error_to_sw (err); + } + + return 0; +} +#endif /*!NEED_PCSC_WRAPPER*/ + + +#ifdef NEED_PCSC_WRAPPER +static int +control_pcsc_wrapped (int slot, unsigned long ioctl_code, + const unsigned char *cntlbuf, size_t len, + unsigned char *buffer, size_t *buflen) +{ + long err = PCSC_E_NOT_TRANSACTED; + reader_table_t slotp; + unsigned char msgbuf[9]; + int i, n; + size_t full_len; + + slotp = reader_table + slot; + + msgbuf[0] = 0x06; /* CONTROL command. */ + msgbuf[1] = ((len + 4) >> 24); + msgbuf[2] = ((len + 4) >> 16); + msgbuf[3] = ((len + 4) >> 8); + msgbuf[4] = ((len + 4) ); + msgbuf[5] = (ioctl_code >> 24); + msgbuf[6] = (ioctl_code >> 16); + msgbuf[7] = (ioctl_code >> 8); + msgbuf[8] = (ioctl_code ); + if ( writen (slotp->pcsc.req_fd, msgbuf, 9) + || writen (slotp->pcsc.req_fd, cntlbuf, len)) + { + log_error ("error sending PC/SC CONTROL request: %s\n", + strerror (errno)); + goto command_failed; + } + + /* Read the response. */ + if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9) + { + log_error ("error receiving PC/SC CONTROL response: %s\n", + i? strerror (errno) : "premature EOF"); + goto command_failed; + } + len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; + if (msgbuf[0] != 0x81 || len < 4) + { + log_error ("invalid response header from PC/SC received\n"); + goto command_failed; + } + len -= 4; /* Already read the error code. */ + err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) + | (msgbuf[7] << 8 ) | msgbuf[8]); + if (err) + { + log_error ("pcsc_control failed: %s (0x%lx)\n", + pcsc_error_string (err), err); + return pcsc_error_to_sw (err); + } + + full_len = len; + + n = *buflen < len ? *buflen : len; + if ((i=readn (slotp->pcsc.rsp_fd, buffer, n, &len)) || len != n) + { + log_error ("error receiving PC/SC CONTROL response: %s\n", + i? strerror (errno) : "premature EOF"); + goto command_failed; + } + *buflen = n; + + full_len -= len; + if (full_len) + { + log_error ("pcsc_send_apdu: provided buffer too short - truncated\n"); + err = PCSC_E_INVALID_VALUE; + } + /* We need to read any rest of the response, to keep the + protocol running. */ + while (full_len) + { + unsigned char dummybuf[128]; + + n = full_len < DIM (dummybuf) ? full_len : DIM (dummybuf); + if ((i=readn (slotp->pcsc.rsp_fd, dummybuf, n, &len)) || len != n) + { + log_error ("error receiving PC/SC CONTROL response: %s\n", + i? strerror (errno) : "premature EOF"); + goto command_failed; + } + full_len -= n; + } + + if (!err) + return 0; + + command_failed: + close (slotp->pcsc.req_fd); + close (slotp->pcsc.rsp_fd); + slotp->pcsc.req_fd = -1; + slotp->pcsc.rsp_fd = -1; + kill (slotp->pcsc.pid, SIGTERM); + slotp->pcsc.pid = (pid_t)(-1); + slotp->used = 0; + return pcsc_error_to_sw (err); +} +#endif /*NEED_PCSC_WRAPPER*/ + + + +/* Do some control with the value of IOCTL_CODE to the card inserted + to SLOT. Input buffer is specified by CNTLBUF of length LEN. + Output buffer is specified by BUFFER of length *BUFLEN, and the + actual output size will be stored at BUFLEN. Returns: A status word. + This routine is used for PIN pad input support. */ +static int +control_pcsc (int slot, unsigned long ioctl_code, + const unsigned char *cntlbuf, size_t len, + unsigned char *buffer, size_t *buflen) +{ +#ifdef NEED_PCSC_WRAPPER + return control_pcsc_wrapped (slot, ioctl_code, cntlbuf, len, buffer, buflen); +#else + return control_pcsc_direct (slot, ioctl_code, cntlbuf, len, buffer, buflen); +#endif +} + + #ifndef NEED_PCSC_WRAPPER static int close_pcsc_reader_direct (int slot) @@ -1808,6 +1976,138 @@ open_pcsc_reader (const char *portstr) } +/* Check whether the reader supports the ISO command code COMMAND + on the keypad. Return 0 on success. */ +static int +check_pcsc_keypad (int slot, int command, int pin_mode, + int pinlen_min, int pinlen_max, int pin_padlen) +{ + unsigned char buf[256]; + size_t len = 256; + int sw; + + (void)pin_mode; + (void)pinlen_min; + (void)pinlen_max; + (void)pin_padlen; + + check_again: + if (command == ISO7816_VERIFY) + { + if (reader_table[slot].pcsc.verify_ioctl == (unsigned long)-1) + return SW_NOT_SUPPORTED; + else if (reader_table[slot].pcsc.verify_ioctl != 0) + return 0; /* Success */ + } + else if (command == ISO7816_CHANGE_REFERENCE_DATA) + { + if (reader_table[slot].pcsc.modify_ioctl == (unsigned long)-1) + return SW_NOT_SUPPORTED; + else if (reader_table[slot].pcsc.modify_ioctl != 0) + return 0; /* Success */ + } + else + return SW_NOT_SUPPORTED; + + reader_table[slot].pcsc.verify_ioctl = (unsigned long)-1; + reader_table[slot].pcsc.modify_ioctl = (unsigned long)-1; + + sw = control_pcsc (slot, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, buf, &len); + if (sw) + return SW_NOT_SUPPORTED; + else + { + unsigned char *p = buf; + + while (p < buf + len) + { + unsigned char code = *p++; + + p++; /* Skip length */ + if (code == FEATURE_VERIFY_PIN_DIRECT) + reader_table[slot].pcsc.verify_ioctl + = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; + else if (code == FEATURE_MODIFY_PIN_DIRECT) + reader_table[slot].pcsc.modify_ioctl + = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; + p += 4; + } + } + + goto check_again; +} + + +#define PIN_VERIFY_STRUCTURE_SIZE 23 +static int +pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, + struct pininfo_s *pininfo) +{ + int sw; + unsigned char *pin_verify; + unsigned long len = PIN_VERIFY_STRUCTURE_SIZE; + unsigned char result[2]; + size_t resultlen = 2; + + if (!reader_table[slot].atrlen + && (sw = reset_pcsc_reader (slot))) + return sw; + + if (pininfo->mode != 1) + return SW_NOT_SUPPORTED; + + if (pininfo->padlen != 0) + return SW_NOT_SUPPORTED; + + if (!pininfo->minlen) + pininfo->minlen = 1; + if (!pininfo->maxlen) + pininfo->maxlen = 25; + + /* Note that the 25 is the maximum value the SPR532 allows. */ + if (pininfo->minlen < 1 || pininfo->minlen > 25 + || pininfo->maxlen < 1 || pininfo->maxlen > 25 + || pininfo->minlen > pininfo->maxlen) + return SW_HOST_INV_VALUE; + + pin_verify = xtrymalloc (len); + if (!pin_verify) + return SW_HOST_OUT_OF_CORE; + + pin_verify[0] = 0x00; /* bTimerOut */ + pin_verify[1] = 0x00; /* bTimerOut2 */ + pin_verify[2] = 0x82; /* bmFormatString: Byte, pos=0, left, ASCII. */ + pin_verify[3] = 0x00; /* bmPINBlockString */ + pin_verify[4] = 0x00; /* bmPINLengthFormat */ + pin_verify[5] = pininfo->maxlen; /* wPINMaxExtraDigit */ + pin_verify[6] = pininfo->minlen; /* wPINMaxExtraDigit */ + pin_verify[7] = 0x02; /* bEntryValidationCondition: Validation key pressed */ + if (pininfo->minlen && pininfo->maxlen && pininfo->minlen == pininfo->maxlen) + pin_verify[7] |= 0x01; /* Max size reached. */ + pin_verify[8] = 0xff; /* bNumberMessage: Default */ + pin_verify[9] = 0x09; /* wLangId: 0x0409: US English */ + pin_verify[10] = 0x04; /* wLangId: 0x0409: US English */ + pin_verify[11] = 0x00; /* bMsgIndex */ + pin_verify[12] = 0x00; /* bTeoPrologue[0] */ + pin_verify[13] = 0x00; /* bTeoPrologue[1] */ + pin_verify[14] = 0x00; /* bTeoPrologue[2] */ + pin_verify[15] = 0x04; /* ulDataLength */ + pin_verify[16] = 0x00; /* ulDataLength */ + pin_verify[17] = 0x00; /* ulDataLength */ + pin_verify[18] = 0x00; /* ulDataLength */ + pin_verify[19] = class; /* abData[0] */ + pin_verify[20] = ins; /* abData[1] */ + pin_verify[21] = p0; /* abData[2] */ + pin_verify[22] = p1; /* abData[3] */ + + sw = control_pcsc (slot, reader_table[slot].pcsc.verify_ioctl, + pin_verify, len, result, &resultlen); + xfree (pin_verify); + if (sw || resultlen < 2) + return sw? sw : SW_HOST_INCOMPLETE_CARD_RESPONSE; + sw = (result[resultlen-2] << 8) | result[resultlen-1]; + return sw; +} #ifdef HAVE_LIBUSB /* @@ -1945,6 +2245,35 @@ check_ccid_keypad (int slot, int command, int pin_mode, } +static int +ccid_keypad_verify (int slot, int class, int ins, int p0, int p1, + struct pininfo_s *pininfo) +{ + unsigned char apdu[4]; + int err, sw; + unsigned char result[2]; + size_t resultlen = 2; + + apdu[0] = class; + apdu[1] = ins; + apdu[2] = p0; + apdu[3] = p1; + err = ccid_transceive_secure (reader_table[slot].ccid.handle, + apdu, sizeof apdu, + pininfo->mode, pininfo->minlen, pininfo->maxlen, + pininfo->padlen, + result, 2, &resultlen); + if (err) + return err; + + if (resultlen < 2) + return SW_HOST_INCOMPLETE_CARD_RESPONSE; + + sw = (result[resultlen-2] << 8) | result[resultlen-1]; + return sw; +} + + /* Open the reader and try to read an ATR. */ static int open_ccid_reader (const char *portstr) @@ -1989,6 +2318,7 @@ open_ccid_reader (const char *portstr) reader_table[slot].check_keypad = check_ccid_keypad; reader_table[slot].dump_status_reader = dump_ccid_reader_status; reader_table[slot].set_progress_cb = set_progress_cb_ccid_reader; + reader_table[slot].keypad_verify = ccid_keypad_verify; /* Our CCID reader code does not support T=0 at all, thus reset the flag. */ reader_table[slot].is_t0 = 0; @@ -2281,6 +2611,7 @@ open_rapdu_reader (int portno, reader_table[slot].send_apdu_reader = my_rapdu_send_apdu; reader_table[slot].check_keypad = NULL; reader_table[slot].dump_status_reader = NULL; + reader_table[slot].keypad_verify = NULL; dump_reader_status (slot); rapdu_msg_release (msg); @@ -2461,6 +2792,7 @@ apdu_open_reader (const char *portstr, int *r_no_service) pcsc_end_transaction = dlsym (handle, "SCardEndTransaction"); pcsc_transmit = dlsym (handle, "SCardTransmit"); pcsc_set_timeout = dlsym (handle, "SCardSetTimeout"); + pcsc_control = dlsym (handle, "SCardControl"); if (!pcsc_establish_context || !pcsc_release_context @@ -2473,12 +2805,13 @@ apdu_open_reader (const char *portstr, int *r_no_service) || !pcsc_begin_transaction || !pcsc_end_transaction || !pcsc_transmit + || !pcsc_control /* || !pcsc_set_timeout */) { /* Note that set_timeout is currently not used and also not available under Windows. */ log_error ("apdu_open_reader: invalid PC/SC driver " - "(%d%d%d%d%d%d%d%d%d%d%d%d)\n", + "(%d%d%d%d%d%d%d%d%d%d%d%d%d)\n", !!pcsc_establish_context, !!pcsc_release_context, !!pcsc_list_readers, @@ -2490,7 +2823,8 @@ apdu_open_reader (const char *portstr, int *r_no_service) !!pcsc_begin_transaction, !!pcsc_end_transaction, !!pcsc_transmit, - !!pcsc_set_timeout ); + !!pcsc_set_timeout, + !!pcsc_control ); dlclose (handle); return -1; } @@ -2894,6 +3228,28 @@ apdu_check_keypad (int slot, int command, int pin_mode, } +int +apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, int pin_mode, + int pinlen_min, int pinlen_max, int pin_padlen) +{ + struct pininfo_s pininfo; + + pininfo.mode = pin_mode; + pininfo.minlen = pinlen_min; + pininfo.maxlen = pinlen_max; + pininfo.padlen = pin_padlen; + + if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) + return SW_HOST_NO_DRIVER; + + if (reader_table[slot].keypad_verify) + return reader_table[slot].keypad_verify (slot, class, ins, p0, p1, + &pininfo); + else + return SW_HOST_NOT_SUPPORTED; +} + + /* Dispatcher for the actual send_apdu function. Note, that this function should be called in locked state. */ static int diff --git a/scd/apdu.h b/scd/apdu.h index 7c0188782..4dff9eb95 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -114,6 +114,9 @@ int apdu_get_status (int slot, int hang, unsigned int *status, unsigned int *changed); int apdu_check_keypad (int slot, int command, int pin_mode, int pinlen_min, int pinlen_max, int pin_padlen); +int apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, + int pin_mode, int pinlen_min, int pinlen_max, + int pin_padlen); int apdu_send_simple (int slot, int extended_mode, int class, int ins, int p0, int p1, int lc, const char *data); diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c index 30beb8efb..50db78e1f 100644 --- a/scd/app-dinsig.c +++ b/scd/app-dinsig.c @@ -304,7 +304,7 @@ verify_pin (app_t app, gpg_strerror (rc)); return rc; } - rc = iso7816_verify_kp (app->slot, 0x81, "", 0, &pininfo); + rc = iso7816_verify_kp (app->slot, 0x81, &pininfo); /* Dismiss the prompt. */ pincb (pincb_arg, NULL, NULL); } diff --git a/scd/app-nks.c b/scd/app-nks.c index c1b2aa376..28ccb9af7 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -803,7 +803,7 @@ verify_pin (app_t app, int pwid, const char *desc, return rc; } - rc = iso7816_verify_kp (app->slot, pwid, "", 0, &pininfo); + rc = iso7816_verify_kp (app->slot, pwid, &pininfo); pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ } else diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index eb0b4f029..d7efad562 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1550,7 +1550,7 @@ verify_a_chv (app_t app, gpg_strerror (rc)); return rc; } - rc = iso7816_verify_kp (app->slot, 0x80+chvno, "", 0, &pininfo); + rc = iso7816_verify_kp (app->slot, 0x80+chvno, &pininfo); /* Dismiss the prompt. */ pincb (pincb_arg, NULL, NULL); @@ -1730,7 +1730,7 @@ verify_chv3 (app_t app, gpg_strerror (rc)); return rc; } - rc = iso7816_verify_kp (app->slot, 0x83, "", 0, &pininfo); + rc = iso7816_verify_kp (app->slot, 0x83, &pininfo); /* Dismiss the prompt. */ pincb (pincb_arg, NULL, NULL); } diff --git a/scd/iso7816.c b/scd/iso7816.c index 318fec8a2..1238552f6 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -281,22 +281,16 @@ iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo) /* Perform a VERIFY command on SLOT using the card holder verification - vector CHVNO with a CHV of lenght CHVLEN. With PININFO non-NULL - the keypad of the reader will be used. Returns 0 on success. */ + vector CHVNO. With PININFO non-NULL the keypad of the reader will + be used. Returns 0 on success. */ gpg_error_t -iso7816_verify_kp (int slot, int chvno, const char *chv, size_t chvlen, - iso7816_pininfo_t *pininfo) +iso7816_verify_kp (int slot, int chvno, iso7816_pininfo_t *pininfo) { int sw; - if (pininfo && pininfo->mode) - sw = apdu_send_simple_kp (slot, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv, - pininfo->mode, - pininfo->minlen, - pininfo->maxlen, - pininfo->padlen); - else - sw = apdu_send_simple (slot, 0, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv); + sw = apdu_keypad_verify (slot, 0x00, CMD_VERIFY, 0, chvno, + pininfo->mode, pininfo->minlen, pininfo->maxlen, + pininfo->padlen); return map_sw (sw); } @@ -305,7 +299,10 @@ iso7816_verify_kp (int slot, int chvno, const char *chv, size_t chvlen, gpg_error_t iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen) { - return iso7816_verify_kp (slot, chvno, chv, chvlen, NULL); + int sw; + + sw = apdu_send_simple (slot, 0, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv); + return map_sw (sw); } /* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder diff --git a/scd/iso7816.h b/scd/iso7816.h index a37759dbe..58e81d458 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -63,9 +63,7 @@ gpg_error_t iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo); gpg_error_t iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen); -gpg_error_t iso7816_verify_kp (int slot, - int chvno, const char *chv, size_t chvlen, - iso7816_pininfo_t *pininfo); +gpg_error_t iso7816_verify_kp (int slot, int chvno, iso7816_pininfo_t *pininfo); gpg_error_t iso7816_change_reference_data (int slot, int chvno, const char *oldchv, size_t oldchvlen, const char *newchv, size_t newchvlen); diff --git a/scd/pcsc-wrapper.c b/scd/pcsc-wrapper.c index ee974ac7b..73b25f4b3 100644 --- a/scd/pcsc-wrapper.c +++ b/scd/pcsc-wrapper.c @@ -178,6 +178,13 @@ long (* pcsc_transmit) (unsigned long card, unsigned long *recv_len); long (* pcsc_set_timeout) (unsigned long context, unsigned long timeout); +long (* pcsc_control) (unsigned long card, + unsigned long control_code, + const void *send_buffer, + unsigned long send_len, + void *recv_buffer, + unsigned long recv_len, + unsigned long *bytes_returned); @@ -335,6 +342,7 @@ load_pcsc_driver (const char *libname) pcsc_end_transaction = dlsym (handle, "SCardEndTransaction"); pcsc_transmit = dlsym (handle, "SCardTransmit"); pcsc_set_timeout = dlsym (handle, "SCardSetTimeout"); + pcsc_control = dlsym (handle, "SCardControl"); if (!pcsc_establish_context || !pcsc_release_context @@ -347,13 +355,14 @@ load_pcsc_driver (const char *libname) || !pcsc_begin_transaction || !pcsc_end_transaction || !pcsc_transmit + || !pcsc_control /* || !pcsc_set_timeout */) { /* Note that set_timeout is currently not used and also not available under Windows. */ fprintf (stderr, "apdu_open_reader: invalid PC/SC driver " - "(%d%d%d%d%d%d%d%d%d%d%d%d)\n", + "(%d%d%d%d%d%d%d%d%d%d%d%d%d)\n", !!pcsc_establish_context, !!pcsc_release_context, !!pcsc_list_readers, @@ -365,7 +374,8 @@ load_pcsc_driver (const char *libname) !!pcsc_begin_transaction, !!pcsc_end_transaction, !!pcsc_transmit, - !!pcsc_set_timeout ); + !!pcsc_set_timeout, + !!pcsc_control ); dlclose (handle); exit (1); } @@ -720,6 +730,38 @@ handle_transmit (unsigned char *argbuf, size_t arglen) } +/* Handle a control request. The argument is expected to be a buffer + which contains CONTROL_CODE (4-byte) and INPUT_BYTES. + */ +static void +handle_control (unsigned char *argbuf, size_t arglen) +{ + long err; + unsigned long ioctl_code; + unsigned long recv_len = 1024; + unsigned char buffer[1024]; + + if (arglen < 4) + bad_request ("CONTROL"); + + ioctl_code = (argbuf[0] << 24) | (argbuf[1] << 16) | (argbuf[2] << 8) | argbuf[3]; + argbuf += 4; + arglen -= 4; + + recv_len = sizeof (buffer); + err = pcsc_control (pcsc_card, ioctl_code, argbuf, arglen, + buffer, recv_len, &recv_len); + if (err) + { + if (verbose) + fprintf (stderr, PGM": pcsc_control failed: %s (0x%lx)\n", + pcsc_error_string (err), err); + request_failed (err); + return; + } + request_succeeded (buffer, recv_len); +} + static void print_version (int with_help) @@ -831,6 +873,10 @@ main (int argc, char **argv) handle_reset (argbuffer, arglen); break; + case 6: + handle_control (argbuffer, arglen); + break; + default: fprintf (stderr, PGM ": invalid request 0x%02X\n", c); exit (1); From 781e9746dff21fc2721373205e63d1d09722d590 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 28 Nov 2011 10:39:36 +0100 Subject: [PATCH 08/68] Improve ssh card key diagnostic message. * command-ssh.c (card_key_available): Change wording of no key diagnostic. (ssh_handler_request_identities): Do not call card_key_available if the scdaemon is disabled. --- agent/ChangeLog | 7 +++++++ agent/command-ssh.c | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/agent/ChangeLog b/agent/ChangeLog index 3c52e1f2c..26355794f 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,10 @@ +2011-11-28 Werner Koch + + * command-ssh.c (card_key_available): Change wording of no key + diagnostic. + (ssh_handler_request_identities): Do not call card_key_available + if the scdaemon is disabled. + 2011-09-12 Ben Kibbey * genkey.c (agent_ask_new_passphrase): Allow for an empty passphrase diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 7b4d47924..54e56eac0 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1710,7 +1710,7 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) } if (err) { - log_error (_("error getting default authentication keyID of card: %s\n"), + log_error (_("no authentication key for ssh on card: %s\n"), gpg_strerror (err)); xfree (serialno); return err; @@ -1924,7 +1924,8 @@ ssh_handler_request_identities (ctrl_t ctrl, reader - this should be allowed even without being listed in sshcontrol. */ - if (!card_key_available (ctrl, &key_public, &cardsn)) + if (!opt.disable_scdaemon + && !card_key_available (ctrl, &key_public, &cardsn)) { err = ssh_send_key_public (key_blobs, key_public, cardsn); gcry_sexp_release (key_public); From 77ee8fd55c9e599f41a3cad0ebaa23c72ca14409 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Mon, 28 Nov 2011 13:47:08 +0100 Subject: [PATCH 09/68] accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix * m4/gpg-error.m4: Update from git master. --- ChangeLog | 5 +++++ m4/gpg-error.m4 | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bd0201681..7e17ba8b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-11-28 Jim Meyering + + accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix + * m4/gpg-error.m4: Update from git master. + 2011-09-23 Werner Koch * configure.ac: Remove check for gcry_kdf_derive. diff --git a/m4/gpg-error.m4 b/m4/gpg-error.m4 index 2e5a0abce..35cbc78ce 100644 --- a/m4/gpg-error.m4 +++ b/m4/gpg-error.m4 @@ -15,10 +15,20 @@ dnl Test for libgpg-error and define GPG_ERROR_CFLAGS and GPG_ERROR_LIBS dnl AC_DEFUN([AM_PATH_GPG_ERROR], [ AC_REQUIRE([AC_CANONICAL_HOST]) - AC_ARG_WITH(gpg-error-prefix, - AC_HELP_STRING([--with-gpg-error-prefix=PFX], + dnl --with-libgpg-error-prefix=PFX is the preferred name for this option, + dnl since that is consistent with how our three siblings use the directory/ + dnl package name in --with-$dir_name-prefix=PFX. + AC_ARG_WITH(libgpg-error-prefix, + AC_HELP_STRING([--with-libgpg-error-prefix=PFX], [prefix where GPG Error is installed (optional)]), gpg_error_config_prefix="$withval", gpg_error_config_prefix="") + + dnl Accept --with-gpg-error-prefix and make it work the same as + dnl --with-libgpg-error-prefix above, for backwards compatibility, + dnl but do not document this old, inconsistently-named option. + AC_ARG_WITH(gpg-error-prefix,, + gpg_error_config_prefix="$withval", gpg_error_config_prefix="") + if test x$gpg_error_config_prefix != x ; then if test x${GPG_ERROR_CONFIG+set} != xset ; then GPG_ERROR_CONFIG=$gpg_error_config_prefix/bin/gpg-error-config From 88fea6abe6b83eb2a69dd62dbbfe19ad5c450d86 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 28 Nov 2011 20:28:10 +0100 Subject: [PATCH 10/68] Add build script to build all components in one run. Run this script in the parent directory of the working copies. It does a VPATH build in ~/tmp/gpg-tmp/b in the right order and installs everything below ~/tmp/gpg-tmp/. Based on a script by Jim Meyering. --- scripts/ChangeLog | 5 +++++ scripts/build-all.sh | 49 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100755 scripts/build-all.sh diff --git a/scripts/ChangeLog b/scripts/ChangeLog index c18359992..fec54059d 100644 --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,8 @@ +2011-11-28 Werner Koch , + Jim Meyering + + * build-all.sh: New. + 2011-08-10 Werner Koch * config.guess, config.sub: Update to version 2011-06-03. diff --git a/scripts/build-all.sh b/scripts/build-all.sh new file mode 100755 index 000000000..3cd4f303c --- /dev/null +++ b/scripts/build-all.sh @@ -0,0 +1,49 @@ +#! /bin/bash +# A simple script to build all parts of GnuPG from the git repos. +# +# Copyright 2011 Free Software Foundation, Inc. +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This file is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# Run this in another window: +#tail -n0 -F ~/tmp/gpg-tmp/b/{libgpg-error,libksba,libassuan,libgcrypt,gnupg}.log & + +p=$HOME/tmp/gpg-tmp +parts="libgpg-error libassuan libksba libgcrypt gnupg" +die=no +for i in $parts; do + if test -d $i ; then + : + else + die=yes + echo "component $i missing" + fi +done +test $die = yes && exit 1 + +mkdir $p || exit 1 +mkdir $p/b || exit 1 +for i in $parts; do + mkdir $p/b/$i || exit 1 +done + +export PATH=$p/bin:$PATH +export LD_LIBRARY_PATH=$p/lib +here="$(pwd)" + +prev= +cfg="configure --enable-maintainer-mode --prefix=$p" +for i in $parts; do + echo $i... + test -n "$prev" && cfg="$cfg --with-$prev-prefix=$p" + (cd $p/b/$i && eval $here/$i/$cfg && make && make check && make install) \ + > $p/b/$i.log 2>&1 \ + || { echo FAIL; break; } + prev=$i +done From 57d4f7fae13810f4daed266139c33057de38d114 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 29 Nov 2011 11:59:32 +0900 Subject: [PATCH 11/68] PC/SC pinpad support (pinpad input for modify pass phrase). --- scd/ChangeLog | 20 +++++++++ scd/apdu.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++ scd/apdu.h | 3 ++ scd/app-openpgp.c | 58 ++++++++++++++++-------- scd/iso7816.c | 51 +++++++++------------ scd/iso7816.h | 4 +- 6 files changed, 196 insertions(+), 51 deletions(-) diff --git a/scd/ChangeLog b/scd/ChangeLog index 9f991cec0..9c11fb309 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,23 @@ +2011-11-29 Niibe Yutaka + + * iso7816.h (iso7816_change_reference_data_kp): Remove arguments + of OLDCHV, OLDCHVLEN, NEWCHV, and NEWCHVLEN. + + * iso7816.c (iso7816_change_reference_data_kp): Call + apdu_keypad_modify. + (iso7816_change_reference_data): Don't call + iso7816_change_reference_data_kp. + + * apdu.h (apdu_keypad_modify): New. + + * apdu.c (pcsc_keypad_modify, apdu_keypad_modify): New. + (struct reader_table_s): New memeber function keypad_modify. + (new_reader_slot, open_ct_reader, open_ccid_reader) + (open_rapdu_reader): Initialize keypad_modify. + + * app-openpgp.c (do_change_pin): Handle keypad and call + iso7816_change_reference_data_kp if it is the case. + 2011-11-28 Niibe Yutaka * iso7816.h (iso7816_verify_kp): Remove arguments of CHV and CHVLEN. diff --git a/scd/apdu.c b/scd/apdu.c index 866ebb916..380450df3 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -112,6 +112,7 @@ struct reader_table_s { void (*dump_status_reader)(int); int (*set_progress_cb)(int, gcry_handler_progress_t, void*); int (*keypad_verify)(int, int, int, int, int, struct pininfo_s *); + int (*keypad_modify)(int, int, int, int, int, struct pininfo_s *); struct { ccid_driver_t handle; @@ -335,6 +336,8 @@ static int check_pcsc_keypad (int slot, int command, int pin_mode, int pinlen_min, int pinlen_max, int pin_padlen); static int pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, struct pininfo_s *pininfo); +static int pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, + struct pininfo_s *pininfo); @@ -382,6 +385,7 @@ new_reader_slot (void) reader_table[reader].dump_status_reader = NULL; reader_table[reader].set_progress_cb = NULL; reader_table[reader].keypad_verify = pcsc_keypad_verify; + reader_table[reader].keypad_modify = pcsc_keypad_modify; reader_table[reader].used = 1; reader_table[reader].any_status = 0; @@ -669,6 +673,7 @@ open_ct_reader (int port) reader_table[reader].check_keypad = NULL; reader_table[reader].dump_status_reader = ct_dump_reader_status; reader_table[reader].keypad_verify = NULL; + reader_table[reader].keypad_modify = NULL; dump_reader_status (reader); return reader; @@ -2108,6 +2113,88 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, sw = (result[resultlen-2] << 8) | result[resultlen-1]; return sw; } + + +#define PIN_MODIFY_STRUCTURE_SIZE 28 +static int +pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, + struct pininfo_s *pininfo) +{ + int sw; + unsigned char *pin_modify; + unsigned long len = PIN_MODIFY_STRUCTURE_SIZE; + unsigned char result[2]; + size_t resultlen = 2; + + if (!reader_table[slot].atrlen + && (sw = reset_pcsc_reader (slot))) + return sw; + + if (pininfo->mode != 1) + return SW_NOT_SUPPORTED; + + if (pininfo->padlen != 0) + return SW_NOT_SUPPORTED; + + if (!pininfo->minlen) + pininfo->minlen = 1; + if (!pininfo->maxlen) + pininfo->maxlen = 25; + + /* Note that the 25 is the maximum value the SPR532 allows. */ + if (pininfo->minlen < 1 || pininfo->minlen > 25 + || pininfo->maxlen < 1 || pininfo->maxlen > 25 + || pininfo->minlen > pininfo->maxlen) + return SW_HOST_INV_VALUE; + + pin_modify = xtrymalloc (len); + if (!pin_modify) + return SW_HOST_OUT_OF_CORE; + + pin_modify[0] = 0x00; /* bTimerOut */ + pin_modify[1] = 0x00; /* bTimerOut2 */ + pin_modify[2] = 0x82; /* bmFormatString: Byte, pos=0, left, ASCII. */ + pin_modify[3] = 0x00; /* bmPINBlockString */ + pin_modify[4] = 0x00; /* bmPINLengthFormat */ + pin_modify[5] = 0x00; /* bInsertionOffsetOld */ + pin_modify[6] = 0x00; /* bInsertionOffsetNew */ + pin_modify[7] = pininfo->maxlen; /* wPINMaxExtraDigit */ + pin_modify[8] = pininfo->minlen; /* wPINMaxExtraDigit */ + pin_modify[9] = 0x03; /* bConfirmPIN + * 0x00: new PIN once + * 0x01: new PIN twice (confirmation) + * 0x02: old PIN and new PIN once + * 0x03: old PIN and new PIN twice (confirmation) + */ + pin_modify[10] = 0x02; /* bEntryValidationCondition: Validation key pressed */ + if (pininfo->minlen && pininfo->maxlen && pininfo->minlen == pininfo->maxlen) + pin_modify[10] |= 0x01; /* Max size reached. */ + pin_modify[11] = 0xff; /* bNumberMessage: Default */ + pin_modify[12] = 0x09; /* wLangId: 0x0409: US English */ + pin_modify[13] = 0x04; /* wLangId: 0x0409: US English */ + pin_modify[14] = 0x00; /* bMsgIndex1 */ + pin_modify[15] = 0x00; /* bMsgIndex2 */ + pin_modify[16] = 0x00; /* bMsgIndex3 */ + pin_modify[17] = 0x00; /* bTeoPrologue[0] */ + pin_modify[18] = 0x00; /* bTeoPrologue[1] */ + pin_modify[19] = 0x00; /* bTeoPrologue[2] */ + pin_modify[20] = 0x04; /* ulDataLength */ + pin_modify[21] = 0x00; /* ulDataLength */ + pin_modify[22] = 0x00; /* ulDataLength */ + pin_modify[23] = 0x00; /* ulDataLength */ + pin_modify[24] = class; /* abData[0] */ + pin_modify[25] = ins; /* abData[1] */ + pin_modify[26] = p0; /* abData[2] */ + pin_modify[27] = p1; /* abData[3] */ + + sw = control_pcsc (slot, reader_table[slot].pcsc.modify_ioctl, + pin_modify, len, result, &resultlen); + xfree (pin_modify); + if (sw || resultlen < 2) + return sw? sw : SW_HOST_INCOMPLETE_CARD_RESPONSE; + sw = (result[resultlen-2] << 8) | result[resultlen-1]; + return sw; +} #ifdef HAVE_LIBUSB /* @@ -2319,6 +2406,7 @@ open_ccid_reader (const char *portstr) reader_table[slot].dump_status_reader = dump_ccid_reader_status; reader_table[slot].set_progress_cb = set_progress_cb_ccid_reader; reader_table[slot].keypad_verify = ccid_keypad_verify; + reader_table[slot].keypad_modify = NULL; /* Our CCID reader code does not support T=0 at all, thus reset the flag. */ reader_table[slot].is_t0 = 0; @@ -2612,6 +2700,7 @@ open_rapdu_reader (int portno, reader_table[slot].check_keypad = NULL; reader_table[slot].dump_status_reader = NULL; reader_table[slot].keypad_verify = NULL; + reader_table[slot].keypad_modify = NULL; dump_reader_status (slot); rapdu_msg_release (msg); @@ -3250,6 +3339,28 @@ apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, int pin_mode, } +int +apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, int pin_mode, + int pinlen_min, int pinlen_max, int pin_padlen) +{ + struct pininfo_s pininfo; + + pininfo.mode = pin_mode; + pininfo.minlen = pinlen_min; + pininfo.maxlen = pinlen_max; + pininfo.padlen = pin_padlen; + + if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) + return SW_HOST_NO_DRIVER; + + if (reader_table[slot].keypad_modify) + return reader_table[slot].keypad_modify (slot, class, ins, p0, p1, + &pininfo); + else + return SW_HOST_NOT_SUPPORTED; +} + + /* Dispatcher for the actual send_apdu function. Note, that this function should be called in locked state. */ static int diff --git a/scd/apdu.h b/scd/apdu.h index 4dff9eb95..e5b4c0878 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -117,6 +117,9 @@ int apdu_check_keypad (int slot, int command, int pin_mode, int apdu_keypad_verify (int slot, int class, int ins, int p0, int p1, int pin_mode, int pinlen_min, int pinlen_max, int pin_padlen); +int apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, + int pin_mode, int pinlen_min, int pinlen_max, + int pin_padlen); int apdu_send_simple (int slot, int extended_mode, int class, int ins, int p0, int p1, int lc, const char *data); diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index d7efad562..b3a3ae13a 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1912,11 +1912,17 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int chvno = atoi (chvnostr); char *resetcode = NULL; char *oldpinvalue = NULL; - char *pinvalue; + char *pinvalue = NULL; int reset_mode = !!(flags & APP_CHANGE_FLAG_RESET); int set_resetcode = 0; + iso7816_pininfo_t pininfo; + int use_keypad = 0; + int minlen = 6; (void)ctrl; + memset (&pininfo, 0, sizeof pininfo); + pininfo.mode = 1; + pininfo.minlen = minlen; if (reset_mode && chvno == 3) { @@ -1960,6 +1966,11 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, { /* Version 2 cards. */ + if (!opt.disable_keypad + && !iso7816_check_keypad (app->slot, + ISO7816_CHANGE_REFERENCE_DATA, &pininfo)) + use_keypad = 1; + if (reset_mode) { /* To reset a PIN the Admin PIN is required. */ @@ -1973,12 +1984,12 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, } else if (chvno == 1 || chvno == 3) { - int minlen = (chvno ==3)? 8 : 6; char *promptbuf = NULL; const char *prompt; if (chvno == 3) { + minlen = 8; rc = build_enter_admin_pin_prompt (app, &promptbuf); if (rc) goto leave; @@ -1986,7 +1997,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, } else prompt = _("||Please enter the PIN"); - rc = pincb (pincb_arg, prompt, &oldpinvalue); + rc = pincb (pincb_arg, prompt, use_keypad ? NULL : &oldpinvalue); xfree (promptbuf); promptbuf = NULL; if (rc) @@ -1996,7 +2007,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, goto leave; } - if (strlen (oldpinvalue) < minlen) + if (!use_keypad && strlen (oldpinvalue) < minlen) { log_info (_("PIN for CHV%d is too short;" " minimum length is %d\n"), chvno, minlen); @@ -2012,8 +2023,8 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, unsigned char *value; size_t valuelen; int remaining; - int minlen = 8; + minlen = 8; relptr = get_one_do (app, 0x00C4, &value, &valuelen, NULL); if (!relptr || valuelen < 7) { @@ -2060,17 +2071,20 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, else app->did_chv1 = app->did_chv2 = 0; - /* TRANSLATORS: Do not translate the "|*|" prefixes but - keep it at the start of the string. We need this elsewhere - to get some infos on the string. */ - rc = pincb (pincb_arg, - set_resetcode? _("|RN|New Reset Code") : - chvno == 3? _("|AN|New Admin PIN") : _("|N|New PIN"), - &pinvalue); - if (rc) + if (!use_keypad) { - log_error (_("error getting new PIN: %s\n"), gpg_strerror (rc)); - goto leave; + /* TRANSLATORS: Do not translate the "|*|" prefixes but + keep it at the start of the string. We need this elsewhere + to get some infos on the string. */ + rc = pincb (pincb_arg, + set_resetcode? _("|RN|New Reset Code") : + chvno == 3? _("|AN|New Admin PIN") : _("|N|New PIN"), + &pinvalue); + if (rc) + { + log_error (_("error getting new PIN: %s\n"), gpg_strerror (rc)); + goto leave; + } } @@ -2131,9 +2145,17 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, /* Version 2 cards. */ assert (chvno == 1 || chvno == 3); - rc = iso7816_change_reference_data (app->slot, 0x80 + chvno, - oldpinvalue, strlen (oldpinvalue), - pinvalue, strlen (pinvalue)); + if (use_keypad) + { + rc = iso7816_change_reference_data_kp (app->slot, 0x80 + chvno, + &pininfo); + /* Dismiss the prompt. */ + pincb (pincb_arg, NULL, NULL); + } + else + rc = iso7816_change_reference_data (app->slot, 0x80 + chvno, + oldpinvalue, strlen (oldpinvalue), + pinvalue, strlen (pinvalue)); } if (pinvalue) diff --git a/scd/iso7816.c b/scd/iso7816.c index 1238552f6..8d0f10557 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -305,17 +305,30 @@ iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen) return map_sw (sw); } +/* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder + verification vector CHVNO. With PININFO non-NULL the keypad of the + reader will be used. */ +gpg_error_t +iso7816_change_reference_data_kp (int slot, int chvno, + iso7816_pininfo_t *pininfo) +{ + int sw; + + sw = apdu_keypad_modify (slot, 0x00, CMD_CHANGE_REFERENCE_DATA, 0, chvno, + pininfo->mode, pininfo->minlen, pininfo->maxlen, + pininfo->padlen); + return map_sw (sw); +} + /* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder verification vector CHVNO. If the OLDCHV is NULL (and OLDCHVLEN 0), a "change reference data" is done, otherwise an "exchange reference data". The new reference data is expected in NEWCHV of - length NEWCHVLEN. With PININFO non-NULL the keypad of the reader - will be used. */ + length NEWCHVLEN. */ gpg_error_t -iso7816_change_reference_data_kp (int slot, int chvno, - const char *oldchv, size_t oldchvlen, - const char *newchv, size_t newchvlen, - iso7816_pininfo_t *pininfo) +iso7816_change_reference_data (int slot, int chvno, + const char *oldchv, size_t oldchvlen, + const char *newchv, size_t newchvlen) { int sw; char *buf; @@ -332,35 +345,13 @@ iso7816_change_reference_data_kp (int slot, int chvno, memcpy (buf, oldchv, oldchvlen); memcpy (buf+oldchvlen, newchv, newchvlen); - if (pininfo && pininfo->mode) - sw = apdu_send_simple_kp (slot, 0x00, CMD_CHANGE_REFERENCE_DATA, - oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf, - pininfo->mode, - pininfo->minlen, - pininfo->maxlen, - pininfo->padlen); - else - sw = apdu_send_simple (slot, 0, 0x00, CMD_CHANGE_REFERENCE_DATA, - oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf); + sw = apdu_send_simple (slot, 0, 0x00, CMD_CHANGE_REFERENCE_DATA, + oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf); xfree (buf); return map_sw (sw); } -/* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder - verification vector CHVNO. If the OLDCHV is NULL (and OLDCHVLEN - 0), a "change reference data" is done, otherwise an "exchange - reference data". The new reference data is expected in NEWCHV of - length NEWCHVLEN. */ -gpg_error_t -iso7816_change_reference_data (int slot, int chvno, - const char *oldchv, size_t oldchvlen, - const char *newchv, size_t newchvlen) -{ - return iso7816_change_reference_data_kp (slot, chvno, oldchv, oldchvlen, - newchv, newchvlen, NULL); -} - gpg_error_t iso7816_reset_retry_counter_kp (int slot, int chvno, diff --git a/scd/iso7816.h b/scd/iso7816.h index 58e81d458..5b99e869b 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -68,9 +68,7 @@ gpg_error_t iso7816_change_reference_data (int slot, int chvno, const char *oldchv, size_t oldchvlen, const char *newchv, size_t newchvlen); gpg_error_t iso7816_change_reference_data_kp (int slot, int chvno, - const char *oldchv, size_t oldchvlen, - const char *newchv, size_t newchvlen, - iso7816_pininfo_t *pininfo); + iso7816_pininfo_t *pininfo); gpg_error_t iso7816_reset_retry_counter (int slot, int chvno, const char *newchv, size_t newchvlen); gpg_error_t iso7816_reset_retry_counter_kp (int slot, int chvno, From c741c6fc3aaa8b75a434faa143c06dd059970d41 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 29 Nov 2011 08:52:12 +0100 Subject: [PATCH 12/68] Make sure HOME et al have no unsafe characters. --- ChangeLog | 4 ++++ autogen.sh | 20 ++++++++++++++++++++ scripts/ChangeLog | 4 ++++ scripts/build-all.sh | 18 +++++++++++++++++- 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7e17ba8b1..5e5a0149d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-11-29 Werner Koch + + * autogen.sh: Make sure HOME et al have no unsafe characters. + 2011-11-28 Jim Meyering accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix diff --git a/autogen.sh b/autogen.sh index f4a1de70f..8a424bce5 100755 --- a/autogen.sh +++ b/autogen.sh @@ -47,6 +47,26 @@ if test x"$1" = x"--force"; then shift fi +# Reject unsafe characters in $HOME, $tsdir and cwd. We consider spaces +# as unsafe because it is too easy to get scripts wrong in this regard. +am_lf=' +' +case `pwd` in + *[\;\\\"\#\$\&\'\`$am_lf\ \ ]*) + echo "unsafe working directory name"; DIE=yes;; +esac +case $tsdir in + *[\;\\\"\#\$\&\'\`$am_lf\ \ ]*) + echo "unsafe source directory: \`$tsdir'"; DIE=yes;; +esac +case $HOME in + *[\;\\\"\#\$\&\'\`$am_lf\ \ ]*) + echo "unsafe home directory: \`$HOME'"; DIE=yes;; +esac +if test "$DIE" = "yes"; then + exit 1 +fi + # Begin list of optional variables sourced from ~/.gnupg-autogen.rc w32_toolprefixes= w32_extraoptions= diff --git a/scripts/ChangeLog b/scripts/ChangeLog index fec54059d..1a664ca68 100644 --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,7 @@ +2011-11-29 Werner Koch + + * build-all.sh: Make sure HOME has no unsafe characters. + 2011-11-28 Werner Koch , Jim Meyering diff --git a/scripts/build-all.sh b/scripts/build-all.sh index 3cd4f303c..23af6203d 100755 --- a/scripts/build-all.sh +++ b/scripts/build-all.sh @@ -17,6 +17,23 @@ p=$HOME/tmp/gpg-tmp parts="libgpg-error libassuan libksba libgcrypt gnupg" die=no +here="`pwd`" + +# Reject unsafe characters in $PWD and $HOME. We consider spaces as +# unsafe because it is too easy to get scripts wrong in this regard. +am_lf=' +' +case $here in + *[\;\\\"\#\$\&\'\`$am_lf\ \ ]*) + echo "unsafe working directory: \`$here'"; die=yes;; +esac +case $HOME in + *[\;\\\"\#\$\&\'\`$am_lf\ \ ]*) + echo "unsafe home directory: \`$HOME'"; die=yes;; +esac +test $die = yes && exit 1 + +# Check that all components are available for i in $parts; do if test -d $i ; then : @@ -35,7 +52,6 @@ done export PATH=$p/bin:$PATH export LD_LIBRARY_PATH=$p/lib -here="$(pwd)" prev= cfg="configure --enable-maintainer-mode --prefix=$p" From 5a62b0d6ee7cecc2e41a429ccc586a1a129e1b04 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 29 Nov 2011 17:56:22 +0900 Subject: [PATCH 13/68] PC/SC pinpad support (pinpad input for modify pass phrase with resetcode, by admin). --- scd/ChangeLog | 24 ++++++++++++++- scd/apdu.c | 51 ++++++++++++++++--------------- scd/apdu.h | 4 --- scd/app-openpgp.c | 76 +++++++++++++++++++++++++++++++---------------- scd/iso7816.c | 52 +++++++++++++++++++++----------- scd/iso7816.h | 5 ++-- 6 files changed, 139 insertions(+), 73 deletions(-) diff --git a/scd/ChangeLog b/scd/ChangeLog index 9c11fb309..d0f779ebd 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,5 +1,27 @@ 2011-11-29 Niibe Yutaka + PC/SC pininput support for passphrase modification (2/2) + * apdu.h (apdu_send_simple_kp): Remove. + + * apdu.c (pcsc_keypad_modify): Add bConfirmPIN handling. + (apdu_send_simple_kp): Remove. + + * iso7816.h (iso7816_reset_retry_counter_kp): Remove arguments + of NEWCHV, and NEWCHVLEN. + (iso7816_reset_retry_counter_with_rc_kp, iso7816_put_data_kp): New. + + * iso7816.c (iso7816_reset_retry_counter_with_rc_kp): New. + (iso7816_reset_retry_counter_kp): Call apdu_keypad_modify. Only + handle the case with PININFO. + (iso7816_reset_retry_counter): Don't call + iso7816_reset_retry_counter_kp. + (iso7816_put_data_kp): New. + + * app-openpgp.c (do_change_pin): Add with_resetcode. + Handle keypad for unblocking pass phrase with resetcode, + setting up of resetcode, and unblocking by admin. + + PC/SC pininput support for passphrase modification (1/2) * iso7816.h (iso7816_change_reference_data_kp): Remove arguments of OLDCHV, OLDCHVLEN, NEWCHV, and NEWCHVLEN. @@ -23,7 +45,7 @@ * iso7816.h (iso7816_verify_kp): Remove arguments of CHV and CHVLEN. * iso7816.c (iso7816_verify_kp): Call apdu_keypad_verify. Only - handle thecase with PININFO. + handle the case with PININFO. (iso7816_verify): Call apdu_send_simple. * app-openpgp.c (verify_a_chv, verify_chv3): Follow the change of diff --git a/scd/apdu.c b/scd/apdu.c index 380450df3..4d11157e3 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -2125,6 +2125,32 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, unsigned long len = PIN_MODIFY_STRUCTURE_SIZE; unsigned char result[2]; size_t resultlen = 2; + unsigned char confirm_pin; + + /* bConfirmPIN + * 0x00: new PIN once + * 0x01: new PIN twice (confirmation) + * 0x02: old PIN and new PIN once + * 0x03: old PIN and new PIN twice (confirmation) + */ + switch (ins) + { + case ISO7816_CHANGE_REFERENCE_DATA: + confirm_pin = 0x03; + break; + case 0xDA: /* PUT_DATA */ + confirm_pin = 0x01; + break; + case ISO7816_RESET_RETRY_COUNTER: + if (p0 == 0) + confirm_pin = 0x03; + else + confirm_pin = 0x01; + break; + default: + confirm_pin = 0x00; + break; + } if (!reader_table[slot].atrlen && (sw = reset_pcsc_reader (slot))) @@ -2160,12 +2186,7 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, pin_modify[6] = 0x00; /* bInsertionOffsetNew */ pin_modify[7] = pininfo->maxlen; /* wPINMaxExtraDigit */ pin_modify[8] = pininfo->minlen; /* wPINMaxExtraDigit */ - pin_modify[9] = 0x03; /* bConfirmPIN - * 0x00: new PIN once - * 0x01: new PIN twice (confirmation) - * 0x02: old PIN and new PIN once - * 0x03: old PIN and new PIN twice (confirmation) - */ + pin_modify[9] = confirm_pin; pin_modify[10] = 0x02; /* bEntryValidationCondition: Validation key pressed */ if (pininfo->minlen && pininfo->maxlen && pininfo->minlen == pininfo->maxlen) pin_modify[10] |= 0x01; /* Max size reached. */ @@ -3794,24 +3815,6 @@ apdu_send_simple (int slot, int extended_mode, } -/* Same as apdu_send_simple but uses the keypad of the reader. */ -int -apdu_send_simple_kp (int slot, int class, int ins, int p0, int p1, - int lc, const char *data, - int pin_mode, - int pinlen_min, int pinlen_max, int pin_padlen) -{ - struct pininfo_s pininfo; - - pininfo.mode = pin_mode; - pininfo.minlen = pinlen_min; - pininfo.maxlen = pinlen_max; - pininfo.padlen = pin_padlen; - return send_le (slot, class, ins, p0, p1, lc, data, -1, - NULL, NULL, &pininfo, 0); -} - - /* This is a more generic version of the apdu sending routine. It takes an already formatted APDU in APDUDATA or length APDUDATALEN and returns with an APDU including the status word. With diff --git a/scd/apdu.h b/scd/apdu.h index e5b4c0878..ac1eeeb3b 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -123,10 +123,6 @@ int apdu_keypad_modify (int slot, int class, int ins, int p0, int p1, int apdu_send_simple (int slot, int extended_mode, int class, int ins, int p0, int p1, int lc, const char *data); -int apdu_send_simple_kp (int slot, int class, int ins, int p0, int p1, - int lc, const char *data, - int pin_mode, - int pinlen_min, int pinlen_max, int pin_padlen); int apdu_send (int slot, int extended_mode, int class, int ins, int p0, int p1, int lc, const char *data, unsigned char **retbuf, size_t *retbuflen); diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index b3a3ae13a..08d641db6 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1915,6 +1915,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, char *pinvalue = NULL; int reset_mode = !!(flags & APP_CHANGE_FLAG_RESET); int set_resetcode = 0; + int with_resetcode = 0; iso7816_pininfo_t pininfo; int use_keypad = 0; int minlen = 6; @@ -2024,6 +2025,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, size_t valuelen; int remaining; + with_resetcode = 1; minlen = 8; relptr = get_one_do (app, 0x00C4, &value, &valuelen, NULL); if (!relptr || valuelen < 7) @@ -2044,14 +2046,14 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, rc = pincb (pincb_arg, _("||Please enter the Reset Code for the card"), - &resetcode); + use_keypad ? NULL : &resetcode); if (rc) { log_info (_("PIN callback returned error: %s\n"), gpg_strerror (rc)); goto leave; } - if (strlen (resetcode) < minlen) + if (!use_keypad && strlen (resetcode) < minlen) { log_info (_("Reset Code is too short; minimum length is %d\n"), minlen); @@ -2088,40 +2090,65 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, } - if (resetcode) + if (with_resetcode) { - char *buffer; - - buffer = xtrymalloc (strlen (resetcode) + strlen (pinvalue) + 1); - if (!buffer) - rc = gpg_error_from_syserror (); + if (use_keypad) + { + rc = iso7816_reset_retry_counter_with_rc_kp (app->slot, 0x81, + &pininfo); + pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ + } else { - strcpy (stpcpy (buffer, resetcode), pinvalue); - rc = iso7816_reset_retry_counter_with_rc (app->slot, 0x81, - buffer, strlen (buffer)); - wipememory (buffer, strlen (buffer)); - xfree (buffer); + char *buffer; + + buffer = xtrymalloc (strlen (resetcode) + strlen (pinvalue) + 1); + if (!buffer) + rc = gpg_error_from_syserror (); + else + { + strcpy (stpcpy (buffer, resetcode), pinvalue); + rc = iso7816_reset_retry_counter_with_rc (app->slot, 0x81, + buffer, strlen (buffer)); + wipememory (buffer, strlen (buffer)); + xfree (buffer); + } } } else if (set_resetcode) { - if (strlen (pinvalue) < 8) + if (use_keypad) { - log_error (_("Reset Code is too short; minimum length is %d\n"), 8); - rc = gpg_error (GPG_ERR_BAD_PIN); + rc = pincb (pincb_arg, _("|RN|New Reset Code"), NULL); + rc = iso7816_put_data_kp (app->slot, 0xD3, &pininfo); + pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ } else - rc = iso7816_put_data (app->slot, 0, 0xD3, - pinvalue, strlen (pinvalue)); + if (strlen (pinvalue) < 8) + { + log_error (_("Reset Code is too short; minimum length is %d\n"), 8); + rc = gpg_error (GPG_ERR_BAD_PIN); + } + else + rc = iso7816_put_data (app->slot, 0, 0xD3, + pinvalue, strlen (pinvalue)); } else if (reset_mode) { - rc = iso7816_reset_retry_counter (app->slot, 0x81, - pinvalue, strlen (pinvalue)); - if (!rc && !app->app_local->extcap.is_v2) - rc = iso7816_reset_retry_counter (app->slot, 0x82, - pinvalue, strlen (pinvalue)); + if (use_keypad) + { + rc = pincb (pincb_arg, _("|N|New PIN"), NULL); + rc = iso7816_reset_retry_counter_kp (app->slot, 0x81, &pininfo); + pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ + } + else + { + rc = iso7816_reset_retry_counter (app->slot, 0x81, + pinvalue, strlen (pinvalue)); + if (!rc && !app->app_local->extcap.is_v2) + rc = iso7816_reset_retry_counter (app->slot, 0x82, + pinvalue, strlen (pinvalue)); + } } else if (!app->app_local->extcap.is_v2) { @@ -2149,8 +2176,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, { rc = iso7816_change_reference_data_kp (app->slot, 0x80 + chvno, &pininfo); - /* Dismiss the prompt. */ - pincb (pincb_arg, NULL, NULL); + pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ } else rc = iso7816_change_reference_data (app->slot, 0x80 + chvno, diff --git a/scd/iso7816.c b/scd/iso7816.c index 8d0f10557..8876b931a 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -354,26 +354,14 @@ iso7816_change_reference_data (int slot, int chvno, gpg_error_t -iso7816_reset_retry_counter_kp (int slot, int chvno, - const char *newchv, size_t newchvlen, - iso7816_pininfo_t *pininfo) +iso7816_reset_retry_counter_with_rc_kp (int slot, int chvno, + iso7816_pininfo_t *pininfo) { int sw; - if (!newchv || !newchvlen ) - return gpg_error (GPG_ERR_INV_VALUE); - - /* FIXME: The keypad mode has not yet been tested. */ - if (pininfo && pininfo->mode) - sw = apdu_send_simple_kp (slot, 0x00, CMD_RESET_RETRY_COUNTER, - 2, chvno, newchvlen, newchv, - pininfo->mode, - pininfo->minlen, - pininfo->maxlen, + sw = apdu_keypad_modify (slot, 0x00, CMD_RESET_RETRY_COUNTER, 0, chvno, + pininfo->mode, pininfo->minlen, pininfo->maxlen, pininfo->padlen); - else - sw = apdu_send_simple (slot, 0, 0x00, CMD_RESET_RETRY_COUNTER, - 2, chvno, newchvlen, newchv); return map_sw (sw); } @@ -393,11 +381,28 @@ iso7816_reset_retry_counter_with_rc (int slot, int chvno, } +gpg_error_t +iso7816_reset_retry_counter_kp (int slot, int chvno, + iso7816_pininfo_t *pininfo) +{ + int sw; + + sw = apdu_keypad_modify (slot, 0x00, CMD_RESET_RETRY_COUNTER, 2, chvno, + pininfo->mode, pininfo->minlen, pininfo->maxlen, + pininfo->padlen); + return map_sw (sw); +} + + gpg_error_t iso7816_reset_retry_counter (int slot, int chvno, const char *newchv, size_t newchvlen) { - return iso7816_reset_retry_counter_kp (slot, chvno, newchv, newchvlen, NULL); + int sw; + + sw = apdu_send_simple (slot, 0, 0x00, CMD_RESET_RETRY_COUNTER, + 2, chvno, newchvlen, newchv); + return map_sw (sw); } @@ -440,6 +445,19 @@ iso7816_get_data (int slot, int extended_mode, int tag, } +gpg_error_t +iso7816_put_data_kp (int slot, int tag, iso7816_pininfo_t *pininfo) +{ + int sw; + + sw = apdu_keypad_modify (slot, 0x00, CMD_PUT_DATA, + ((tag >> 8) & 0xff), (tag & 0xff), + pininfo->mode, pininfo->minlen, pininfo->maxlen, + pininfo->padlen); + return map_sw (sw); +} + + /* Perform a PUT DATA command on card in SLOT. Write DATA of length DATALEN to TAG. EXTENDED_MODE controls whether extended length headers or command chaining is used instead of single length diff --git a/scd/iso7816.h b/scd/iso7816.h index 5b99e869b..9ed7b219f 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -72,14 +72,15 @@ gpg_error_t iso7816_change_reference_data_kp (int slot, int chvno, gpg_error_t iso7816_reset_retry_counter (int slot, int chvno, const char *newchv, size_t newchvlen); gpg_error_t iso7816_reset_retry_counter_kp (int slot, int chvno, - const char *newchv, - size_t newchvlen, iso7816_pininfo_t *pininfo); gpg_error_t iso7816_reset_retry_counter_with_rc (int slot, int chvno, const char *data, size_t datalen); +gpg_error_t iso7816_reset_retry_counter_with_rc_kp (int slot, int chvno, + iso7816_pininfo_t *pininfo); gpg_error_t iso7816_get_data (int slot, int extended_mode, int tag, unsigned char **result, size_t *resultlen); +gpg_error_t iso7816_put_data_kp (int slot, int tag, iso7816_pininfo_t *pininfo); gpg_error_t iso7816_put_data (int slot, int extended_mode, int tag, const void *data, size_t datalen); gpg_error_t iso7816_put_data_odd (int slot, int extended_mode, int tag, From 982105f1ce85c92482def1d66f1f44e438ae5ab6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 28 Nov 2011 18:11:59 +0100 Subject: [PATCH 14/68] Use separate test module for dns-cert.c. * dns-cert.c (get_dns_cert): Factor test code out to ... * t-dns-cert.c: new file. --- common/ChangeLog | 5 +++ common/Makefile.am | 3 +- common/dns-cert.c | 62 +----------------------------- common/dns-cert.h | 2 +- common/t-dns-cert.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 103 insertions(+), 62 deletions(-) create mode 100644 common/t-dns-cert.c diff --git a/common/ChangeLog b/common/ChangeLog index 54435f4b9..dd7ef5398 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,8 @@ +2011-11-28 Werner Koch + + * dns-cert.c (get_dns_cert): Factor test code out to ... + * t-dns-cert.c: new file. + 2011-10-24 Werner Koch * dotlock.h, dotlock.c: Add alternative to allow distribution of diff --git a/common/Makefile.am b/common/Makefile.am index 555d0881d..7821e0442 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -162,7 +162,7 @@ if HAVE_W32_SYSTEM jnlib_tests += t-w32-reg endif module_tests = t-convert t-percent t-gettime t-sysutils t-sexputil \ - t-session-env t-openpgp-oid t-ssh-utils + t-session-env t-openpgp-oid t-ssh-utils t-dns-cert if !HAVE_W32CE_SYSTEM module_tests += t-exechelp endif @@ -196,3 +196,4 @@ t_exechelp_LDADD = $(t_common_ldadd) t_session_env_LDADD = $(t_common_ldadd) t_openpgp_oid_LDADD = $(t_common_ldadd) t_ssh_utils_LDADD = $(t_common_ldadd) +t_dns_cert_LDADD = $(t_common_ldadd) $(DNSLIBS) diff --git a/common/dns-cert.c b/common/dns-cert.c index 888ffb7b1..db1c7be39 100644 --- a/common/dns-cert.c +++ b/common/dns-cert.c @@ -46,13 +46,13 @@ #define T_CERT 37 #endif -/* ADNS has no support for CERT yes. */ +/* ADNS has no support for CERT yet. */ #define my_adns_r_cert 37 /* Returns -1 on error, 0 for no answer, 1 for PGP provided and 2 for - IPGP provided. Note that this fucntion retruns the first CERT + IPGP provided. Note that this function retruns the first CERT found with a supported type; it is expected that only one CERT record is used. */ int @@ -289,61 +289,3 @@ get_dns_cert (const char *name, size_t max_size, IOBUF *iobuf, return -1; #endif } - - - -/* Test with simon.josefsson.org */ - -#ifdef TEST -int -main(int argc,char *argv[]) -{ - unsigned char *fpr; - size_t fpr_len; - char *url; - int rc; - IOBUF iobuf; - - if(argc!=2) - { - printf("cert-test [name]\n"); - return 1; - } - - printf("CERT lookup on %s\n",argv[1]); - - rc=get_dns_cert (argv[1],16384,&iobuf,&fpr,&fpr_len,&url); - if(rc==-1) - printf("error\n"); - else if(rc==0) - printf("no answer\n"); - else if(rc==1) - { - printf("key found: %d bytes\n",(int)iobuf_get_temp_length(iobuf)); - iobuf_close(iobuf); - } - else if(rc==2) - { - if(fpr) - { - size_t i; - printf("Fingerprint found (%d bytes): ",(int)fpr_len); - for(i=0;i. + */ + +#include +#include +#include +#include + +#include "util.h" +#include "iobuf.h" +#include "dns-cert.h" + + +int +main (int argc, char **argv) +{ + unsigned char *fpr; + size_t fpr_len; + char *url; + int rc; + iobuf_t iobuf; + char const *name; + + if (argc) + { + argc--; + argv++; + } + + if (!argc) + name = "simon.josefsson.org"; + else if (argc == 1) + name = *argv; + else + { + fputs ("usage: t-dns-cert [name]\n", stderr); + return 1; + } + + printf ("CERT lookup on `%s'\n", name); + + rc = get_dns_cert (name, 16384, &iobuf, &fpr, &fpr_len, &url); + if (rc == -1) + fputs ("lookup result: error\n", stdout); + else if (!rc) + fputs ("lookup result: no answer\n", stdout); + else if (rc == 1) + { + printf ("lookup result: %d bytes\n", + (int)iobuf_get_temp_length(iobuf)); + iobuf_close (iobuf); + } + else if (rc == 2) + { + if (fpr) + { + int i; + + printf ("Fingerprint found (%d bytes): ", (int)fpr_len); + for (i = 0; i < fpr_len; i++) + printf ("%02X", fpr[i]); + putchar ('\n'); + } + else + printf ("No fingerprint found\n"); + + if (url) + printf ("URL found: %s\n", url); + else + printf ("No URL found\n"); + + xfree (fpr); + xfree (url); + } + + return 0; +} From f95cb909ba505f03ce81816c23dd58718b8cb6e6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 28 Nov 2011 18:18:12 +0100 Subject: [PATCH 15/68] Increase the default buffer size for DNS certificates. * common/t-dns-cert.c (main): Increase MAX_SIZE to 64k. * g10/keyserver.c (DEFAULT_MAX_CERT_SIZE): Increase from 16k to 64k. --- common/ChangeLog | 2 ++ g10/ChangeLog | 4 ++++ g10/keyserver.c | 5 +++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/common/ChangeLog b/common/ChangeLog index dd7ef5398..46a61dd7a 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,5 +1,7 @@ 2011-11-28 Werner Koch + * t-dns-cert.c (main): Increase MAX_SIZE to 64k. + * dns-cert.c (get_dns_cert): Factor test code out to ... * t-dns-cert.c: new file. diff --git a/g10/ChangeLog b/g10/ChangeLog index c799fc965..629de8172 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,7 @@ +2011-11-28 Werner Koch + + * keyserver.c (DEFAULT_MAX_CERT_SIZE): Increase from 16k to 64k. + 2011-11-22 Werner Koch * pubkey-enc.c (get_session_key): Don't print anonymous recipient diff --git a/g10/keyserver.c b/g10/keyserver.c index 68dd15567..efb08773f 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -115,8 +115,9 @@ static gpg_error_t keyserver_put (ctrl_t ctrl, strlist_t keyspecs, struct keyserver_spec *keyserver); -/* Reasonable guess */ -#define DEFAULT_MAX_CERT_SIZE 16384 +/* Reasonable guess. The commonly used test key simon.josefsson.org + is larger than 32k, thus we need at least this value. */ +#define DEFAULT_MAX_CERT_SIZE 65536 static size_t max_cert_size=DEFAULT_MAX_CERT_SIZE; From 295b9e29c5f8fa49a767f9404aaca0afa1f31683 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 28 Nov 2011 18:35:19 +0100 Subject: [PATCH 16/68] Re-indented dns-cert.c --- common/dns-cert.c | 207 +++++++++++++++++++++++----------------------- 1 file changed, 104 insertions(+), 103 deletions(-) diff --git a/common/dns-cert.c b/common/dns-cert.c index db1c7be39..cd8724a82 100644 --- a/common/dns-cert.c +++ b/common/dns-cert.c @@ -56,8 +56,8 @@ found with a supported type; it is expected that only one CERT record is used. */ int -get_dns_cert (const char *name, size_t max_size, IOBUF *iobuf, - unsigned char **fpr, size_t *fpr_len, char **url) +get_dns_cert (const char *name, size_t max_size, IOBUF * iobuf, + unsigned char **fpr, size_t * fpr_len, char **url) { #ifdef USE_DNS_CERT #ifdef USE_ADNS @@ -92,7 +92,7 @@ get_dns_cert (const char *name, size_t max_size, IOBUF *iobuf, return 0; } - for (rc = 0, count=0; !rc && count < answer->nrrs; count++) + for (rc = 0, count = 0; !rc && count < answer->nrrs; count++) { int datalen = answer->rrs.byteblock[count].len; const unsigned char *data = answer->rrs.byteblock[count].data; @@ -100,7 +100,7 @@ get_dns_cert (const char *name, size_t max_size, IOBUF *iobuf, if (datalen < 5) continue; /* Truncated CERT record - skip. */ - ctype = ((data[0]<<8)|data[1]); + ctype = ((data[0] << 8) | data[1]); /* (key tag and algorithm fields are not required.) */ data += 5; datalen -= 5; @@ -109,11 +109,11 @@ get_dns_cert (const char *name, size_t max_size, IOBUF *iobuf, { /* CERT type is PGP. Gpg checks for a minimum length of 11, thus we do the same. */ - *iobuf = iobuf_temp_with_content ((char*)data, datalen); + *iobuf = iobuf_temp_with_content ((char *)data, datalen); rc = 1; } else if (ctype == 6 && datalen && datalen < 1023 - && datalen >= data[0]+1 && fpr && fpr_len && url) + && datalen >= data[0] + 1 && fpr && fpr_len && url) { /* CERT type is IPGP. We made sure tha the data is plausible and that the caller requested the @@ -122,16 +122,16 @@ get_dns_cert (const char *name, size_t max_size, IOBUF *iobuf, if (*fpr_len) { *fpr = xmalloc (*fpr_len); - memcpy (*fpr, data+1, *fpr_len); + memcpy (*fpr, data + 1, *fpr_len); } else *fpr = NULL; if (datalen > *fpr_len + 1) { - *url = xmalloc (datalen - (*fpr_len+1) + 1); - memcpy (*url, data + (*fpr_len+1), datalen - (*fpr_len+1)); - (*url)[datalen - (*fpr_len+1)] = '\0'; + *url = xmalloc (datalen - (*fpr_len + 1) + 1); + memcpy (*url, data + (*fpr_len + 1), datalen - (*fpr_len + 1)); + (*url)[datalen - (*fpr_len + 1)] = '\0'; } else *url = NULL; @@ -147,137 +147,138 @@ get_dns_cert (const char *name, size_t max_size, IOBUF *iobuf, #else /*!USE_ADNS*/ unsigned char *answer; - int r,ret=-1; + int ret = -1; + int r; u16 count; - if(fpr) - *fpr=NULL; + if (fpr) + *fpr = NULL; - if(url) - *url=NULL; + if (url) + *url = NULL; - answer=xmalloc(max_size); + answer = xmalloc (max_size); - r=res_query(name,C_IN,T_CERT,answer,max_size); + r = res_query (name, C_IN, T_CERT, answer, max_size); /* Not too big, not too small, no errors and at least 1 answer. */ - if(r>=sizeof(HEADER) && r<=max_size - && (((HEADER *)answer)->rcode)==NOERROR - && (count=ntohs(((HEADER *)answer)->ancount))) + if (r >= sizeof (HEADER) && r <= max_size + && (((HEADER *) answer)->rcode) == NOERROR + && (count = ntohs (((HEADER *) answer)->ancount))) { int rc; - unsigned char *pt,*emsg; + unsigned char *pt, *emsg; - emsg=&answer[r]; + emsg = &answer[r]; - pt=&answer[sizeof(HEADER)]; + pt = &answer[sizeof (HEADER)]; /* Skip over the query */ - rc=dn_skipname(pt,emsg); - if(rc==-1) - goto fail; + rc = dn_skipname (pt, emsg); + if (rc == -1) + goto fail; - pt+=rc+QFIXEDSZ; + pt += rc + QFIXEDSZ; /* There are several possible response types for a CERT request. - We're interested in the PGP (a key) and IPGP (a URI) types. - Skip all others. TODO: A key is better than a URI since - we've gone through all this bother to fetch it, so favor that - if we have both PGP and IPGP? */ + We're interested in the PGP (a key) and IPGP (a URI) types. + Skip all others. TODO: A key is better than a URI since + we've gone through all this bother to fetch it, so favor that + if we have both PGP and IPGP? */ - while(count-->0 && pt 0 && pt < emsg) + { + u16 type, class, dlen, ctype; - rc=dn_skipname(pt,emsg); /* the name we just queried for */ - if(rc==-1) - break; + rc = dn_skipname (pt, emsg); /* the name we just queried for */ + if (rc == -1) + break; - pt+=rc; + pt += rc; - /* Truncated message? 15 bytes takes us to the point where - we start looking at the ctype. */ - if((emsg-pt)<15) - break; + /* Truncated message? 15 bytes takes us to the point where + we start looking at the ctype. */ + if ((emsg - pt) < 15) + break; - type=*pt++ << 8; - type|=*pt++; + type = *pt++ << 8; + type |= *pt++; - class=*pt++ << 8; - class|=*pt++; - /* We asked for IN and got something else !? */ - if(class!=C_IN) - break; + class = *pt++ << 8; + class |= *pt++; + /* We asked for IN and got something else !? */ + if (class != C_IN) + break; - /* ttl */ - pt+=4; + /* ttl */ + pt += 4; - /* data length */ - dlen=*pt++ << 8; - dlen|=*pt++; + /* data length */ + dlen = *pt++ << 8; + dlen |= *pt++; - /* We asked for CERT and got something else - might be a - CNAME, so loop around again. */ - if(type!=T_CERT) - { - pt+=dlen; - continue; - } + /* We asked for CERT and got something else - might be a + CNAME, so loop around again. */ + if (type != T_CERT) + { + pt += dlen; + continue; + } - /* The CERT type */ - ctype=*pt++ << 8; - ctype|=*pt++; + /* The CERT type */ + ctype = *pt++ << 8; + ctype |= *pt++; - /* Skip the CERT key tag and algo which we don't need. */ - pt+=3; + /* Skip the CERT key tag and algo which we don't need. */ + pt += 3; - dlen-=5; + dlen -= 5; - /* 15 bytes takes us to here */ + /* 15 bytes takes us to here */ - if(ctype==3 && iobuf && dlen) - { - /* PGP type */ - *iobuf=iobuf_temp_with_content((char *)pt,dlen); - ret=1; - break; - } - else if(ctype==6 && dlen && dlen<1023 && dlen>=pt[0]+1 - && fpr && fpr_len && url) - { - /* IPGP type */ - *fpr_len=pt[0]; + if (ctype == 3 && iobuf && dlen) + { + /* PGP type */ + *iobuf = iobuf_temp_with_content ((char *) pt, dlen); + ret = 1; + break; + } + else if (ctype == 6 && dlen && dlen < 1023 && dlen >= pt[0] + 1 + && fpr && fpr_len && url) + { + /* IPGP type */ + *fpr_len = pt[0]; - if(*fpr_len) - { - *fpr=xmalloc(*fpr_len); - memcpy(*fpr,&pt[1],*fpr_len); - } - else - *fpr=NULL; + if (*fpr_len) + { + *fpr = xmalloc (*fpr_len); + memcpy (*fpr, &pt[1], *fpr_len); + } + else + *fpr = NULL; - if(dlen>*fpr_len+1) - { - *url=xmalloc(dlen-(*fpr_len+1)+1); - memcpy(*url,&pt[*fpr_len+1],dlen-(*fpr_len+1)); - (*url)[dlen-(*fpr_len+1)]='\0'; - } - else - *url=NULL; + if (dlen > *fpr_len + 1) + { + *url = xmalloc (dlen - (*fpr_len + 1) + 1); + memcpy (*url, &pt[*fpr_len + 1], dlen - (*fpr_len + 1)); + (*url)[dlen - (*fpr_len + 1)] = '\0'; + } + else + *url = NULL; - ret=2; - break; - } + ret = 2; + break; + } - /* Neither type matches, so go around to the next answer. */ - pt+=dlen; - } + /* Neither type matches, so go around to the next answer. */ + pt += dlen; + } } fail: - xfree(answer); + xfree (answer); return ret; -#endif /*!USE_ADNS*/ +#endif /*!USE_ADNS */ #else /* !USE_DNS_CERT */ (void)name; (void)max_size; From 9dc89de7a840c4a210e64b402094235a72e1c921 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 28 Nov 2011 18:36:21 +0100 Subject: [PATCH 17/68] Actually increase buffer size of t-dns-cert.c. --- common/t-dns-cert.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/t-dns-cert.c b/common/t-dns-cert.c index a2b14f2c1..f3e8892a7 100644 --- a/common/t-dns-cert.c +++ b/common/t-dns-cert.c @@ -55,7 +55,7 @@ main (int argc, char **argv) printf ("CERT lookup on `%s'\n", name); - rc = get_dns_cert (name, 16384, &iobuf, &fpr, &fpr_len, &url); + rc = get_dns_cert (name, 65536, &iobuf, &fpr, &fpr_len, &url); if (rc == -1) fputs ("lookup result: error\n", stdout); else if (!rc) From d24f41641f5a7c3a9be2a6e585a7e2e5031c01d7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 29 Nov 2011 13:17:20 +0100 Subject: [PATCH 18/68] dns-cert.c: Use constants for better readability. --- common/ChangeLog | 4 ++++ common/dns-cert.c | 29 +++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/common/ChangeLog b/common/ChangeLog index 46a61dd7a..943862af9 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,7 @@ +2011-11-29 Werner Koch + + * dns-cert.c: Use new CERTTYPE_ constants for better readability. + 2011-11-28 Werner Koch * t-dns-cert.c (main): Increase MAX_SIZE to 64k. diff --git a/common/dns-cert.c b/common/dns-cert.c index cd8724a82..9b6c6c893 100644 --- a/common/dns-cert.c +++ b/common/dns-cert.c @@ -1,4 +1,4 @@ -/* dns-cert.c - DNS CERT code +/* dns-cert.c - DNS CERT code (rfc-4398) * Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc. * * This file is part of GNUPG. @@ -50,9 +50,21 @@ #define my_adns_r_cert 37 +/* Certificate types according to RFC-4398. */ +#define CERTTYPE_PKIX 1 /* X.509 as per PKIX. */ +#define CERTTYPE_SPKI 2 /* SPKI certificate. */ +#define CERTTYPE_PGP 3 /* OpenPGP packet. */ +#define CERTTYPE_IPKIX 4 /* The URL of an X.509 data object. */ +#define CERTTYPE_ISPKI 5 /* The URL of an SPKI certificate. */ +#define CERTTYPE_IPGP 6 /* The fingerprint and URL of an OpenPGP packet.*/ +#define CERTTYPE_ACPKIX 7 /* Attribute Certificate. */ +#define CERTTYPE_IACPKIX 8 /* The URL of an Attribute Certificate. */ +#define CERTTYPE_URI 253 /* URI private. */ +#define CERTTYPE_OID 254 /* OID private. */ + /* Returns -1 on error, 0 for no answer, 1 for PGP provided and 2 for - IPGP provided. Note that this function retruns the first CERT + IPGP provided. Note that this function returns the first CERT found with a supported type; it is expected that only one CERT record is used. */ int @@ -105,18 +117,18 @@ get_dns_cert (const char *name, size_t max_size, IOBUF * iobuf, data += 5; datalen -= 5; - if (ctype == 3 && datalen >= 11) + if (ctype == CERTTYPE_PGP && datalen >= 11) { /* CERT type is PGP. Gpg checks for a minimum length of 11, thus we do the same. */ *iobuf = iobuf_temp_with_content ((char *)data, datalen); rc = 1; } - else if (ctype == 6 && datalen && datalen < 1023 + else if (ctype == CERTTYPE_IPGP && datalen && datalen < 1023 && datalen >= data[0] + 1 && fpr && fpr_len && url) { - /* CERT type is IPGP. We made sure tha the data is - plausible and that the caller requested the + /* CERT type is IPGP. We made sure that the data is + plausible and that the caller requested this information. */ *fpr_len = data[0]; if (*fpr_len) @@ -236,14 +248,15 @@ get_dns_cert (const char *name, size_t max_size, IOBUF * iobuf, /* 15 bytes takes us to here */ - if (ctype == 3 && iobuf && dlen) + if (ctype == CERTTYPE_PGP && iobuf && dlen) { /* PGP type */ *iobuf = iobuf_temp_with_content ((char *) pt, dlen); ret = 1; break; } - else if (ctype == 6 && dlen && dlen < 1023 && dlen >= pt[0] + 1 + else if (ctype == CERTTYPE_IPGP + && dlen && dlen < 1023 && dlen >= pt[0] + 1 && fpr && fpr_len && url) { /* IPGP type */ From 6d5bb8e79dcee868e823de2c4e9d0ec9a9308dda Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 29 Nov 2011 18:02:05 +0100 Subject: [PATCH 19/68] Add parameter checks and extend documentation of estream. * estream.c (func_mem_create): Don't set FUNC_REALLOC if GROW is not set. Require FUNC_REALLOC if DATA is NULL and FUNC_FREE is given. --- common/ChangeLog | 4 ++++ common/estream.c | 41 +++++++++++++++++++++++++++++++---------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/common/ChangeLog b/common/ChangeLog index 943862af9..d5682fc4b 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,5 +1,9 @@ 2011-11-29 Werner Koch + * estream.c (func_mem_create): Don't set FUNC_REALLOC if GROW is + not set. Require FUNC_REALLOC if DATA is NULL and FUNC_FREE is + given. + * dns-cert.c: Use new CERTTYPE_ constants for better readability. 2011-11-28 Werner Koch diff --git a/common/estream.c b/common/estream.c index 8087a6287..20d365a63 100644 --- a/common/estream.c +++ b/common/estream.c @@ -539,7 +539,9 @@ typedef struct estream_cookie_mem supplied buffer with the initial conetnt of the memory buffer. If DATA is NULL, DATA_N and DATA_LEN need to be 0 as well. If DATA is not NULL, DATA_N gives the allocated size of DATA and DATA_LEN the - used length in DATA. */ + used length in DATA. If this fucntion succeeds DATA is now owned + by this function. If GROW is false FUNC_REALLOC is not + required. */ static int func_mem_create (void *ES__RESTRICT *ES__RESTRICT cookie, unsigned char *ES__RESTRICT data, size_t data_n, @@ -557,6 +559,11 @@ func_mem_create (void *ES__RESTRICT *ES__RESTRICT cookie, _set_errno (EINVAL); return -1; } + if (grow && func_free && !func_realloc) + { + _set_errno (EINVAL); + return -1; + } mem_cookie = mem_alloc (sizeof (*mem_cookie)); if (!mem_cookie) @@ -571,7 +578,8 @@ func_mem_create (void *ES__RESTRICT *ES__RESTRICT cookie, mem_cookie->data_len = data_len; mem_cookie->block_size = block_size; mem_cookie->flags.grow = !!grow; - mem_cookie->func_realloc = func_realloc ? func_realloc : mem_realloc; + mem_cookie->func_realloc + = grow? (func_realloc ? func_realloc : mem_realloc) : NULL; mem_cookie->func_free = func_free ? func_free : mem_free; *cookie = mem_cookie; err = 0; @@ -622,7 +630,8 @@ es_func_mem_write (void *cookie, const void *buffer, size_t size) assert (mem_cookie->memory_size >= mem_cookie->offset); nleft = mem_cookie->memory_size - mem_cookie->offset; - /* If we are not allowed to grow limit the size to the left space. */ + /* If we are not allowed to grow the buffer, limit the size to the + left space. */ if (!mem_cookie->flags.grow && size > nleft) size = nleft; @@ -663,6 +672,7 @@ es_func_mem_write (void *cookie, const void *buffer, size_t size) return -1; } + assert (mem_cookie->func_realloc); newbuf = mem_cookie->func_realloc (mem_cookie->memory, newsize); if (!newbuf) return -1; @@ -738,6 +748,7 @@ es_func_mem_seek (void *cookie, off_t *offset, int whence) return -1; } + assert (mem_cookie->func_realloc); newbuf = mem_cookie->func_realloc (mem_cookie->memory, newsize); if (!newbuf) return -1; @@ -2580,23 +2591,33 @@ es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode) +/* Create a new estream object in memory. If DATA is not NULL this + buffer will be used as the memory buffer; thus after this functions + returns with the success the the memory at DATA belongs to the new + estream. The allocated length of DATA is given by DATA_LEN and its + used length by DATA_N. Usually this is malloced buffer; if a + static buffer is provided, the caller must pass false for GROW and + provide a dummy function for FUNC_FREE. FUNC_FREE and FUNC_REALLOC + allow the caller to provide custom functions for realloc and free + to be used by the new estream object. Note that the realloc + function is also used for initial allocation. If DATA is NULL a + buffer is internally allocated; either using internal function or + those provide by the caller. It is an error to provide a realloc + function but no free function. Providing only a free function is + allowed as long as GROW is false. */ estream_t es_mopen (unsigned char *ES__RESTRICT data, size_t data_n, size_t data_len, unsigned int grow, func_realloc_t func_realloc, func_free_t func_free, const char *ES__RESTRICT mode) { + int create_called = 0; + estream_t stream = NULL; + void *cookie = NULL; unsigned int modeflags; - int create_called; - estream_t stream; - void *cookie; int err; es_syshd_t syshd; - cookie = 0; - stream = NULL; - create_called = 0; - err = parse_mode (mode, &modeflags, NULL); if (err) goto out; From 8cf2356fa8aa1dda644314e6e656b3df1586e297 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 30 Nov 2011 17:03:53 +0100 Subject: [PATCH 20/68] * common/estream.c (es_fopenmem_init): New. * common/estream.h (es_fopenmem_init): New. --- common/estream.c | 37 +++++++++++++++++++++++++++++++++++-- common/estream.h | 5 ++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/common/estream.c b/common/estream.c index 20d365a63..c55c7f26d 100644 --- a/common/estream.c +++ b/common/estream.c @@ -2606,7 +2606,7 @@ es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode) function but no free function. Providing only a free function is allowed as long as GROW is false. */ estream_t -es_mopen (unsigned char *ES__RESTRICT data, size_t data_n, size_t data_len, +es_mopen (void *ES__RESTRICT data, size_t data_n, size_t data_len, unsigned int grow, func_realloc_t func_realloc, func_free_t func_free, const char *ES__RESTRICT mode) @@ -2657,7 +2657,6 @@ es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode) return NULL; modeflags |= O_RDWR; - if (func_mem_create (&cookie, NULL, 0, 0, BUFFER_BLOCK_SIZE, 1, mem_realloc, mem_free, modeflags, @@ -2672,6 +2671,40 @@ es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode) } + +/* This is the same as es_fopenmem but intializes the memory with a + copy of (DATA,DATALEN). The stream is initally set to the + beginning. If MEMLIMIT is not 0 but shorter than DATALEN it + DATALEN will be used as the value for MEMLIMIT. */ +estream_t +es_fopenmem_init (size_t memlimit, const char *ES__RESTRICT mode, + const void *data, size_t datalen) +{ + estream_t stream; + + if (memlimit && memlimit < datalen) + memlimit = datalen; + + stream = es_fopenmem (memlimit, mode); + if (stream && data && datalen) + { + if (es_writen (stream, data, datalen, NULL)) + { + int saveerrno = errno; + es_fclose (stream); + stream = NULL; + _set_errno (saveerrno); + } + else + { + es_seek (stream, 0L, SEEK_SET, NULL); + es_set_indicators (stream, 0, 0); + } + } + return stream; +} + + estream_t es_fopencookie (void *ES__RESTRICT cookie, diff --git a/common/estream.h b/common/estream.h index 432143fd3..49662766e 100644 --- a/common/estream.h +++ b/common/estream.h @@ -76,6 +76,7 @@ #define es_fopen _ESTREAM_PREFIX(es_fopen) #define es_mopen _ESTREAM_PREFIX(es_mopen) #define es_fopenmem _ESTREAM_PREFIX(es_fopenmem) +#define es_fopenmem_init _ESTREAM_PREFIX(es_fopenmem_init) #define es_fdopen _ESTREAM_PREFIX(es_fdopen) #define es_fdopen_nc _ESTREAM_PREFIX(es_fdopen_nc) #define es_sysopen _ESTREAM_PREFIX(es_sysopen) @@ -262,13 +263,15 @@ int es_init (void); estream_t es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode); -estream_t es_mopen (unsigned char *ES__RESTRICT data, +estream_t es_mopen (void *ES__RESTRICT data, size_t data_n, size_t data_len, unsigned int grow, void *(*func_realloc) (void *mem, size_t size), void (*func_free) (void *mem), const char *ES__RESTRICT mode); estream_t es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode); +estream_t es_fopenmem_init (size_t memlimit, const char *ES__RESTRICT mode, + const void *data, size_t datalen); estream_t es_fdopen (int filedes, const char *mode); estream_t es_fdopen_nc (int filedes, const char *mode); estream_t es_sysopen (es_syshd_t *syshd, const char *mode); From 31f548a18aed729c05ea367f2d8a8104480430d5 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 30 Nov 2011 17:14:08 +0100 Subject: [PATCH 21/68] Rewrite dns-cert.c to not use the gpg-only iobuf stuff. * common/dns-cert.c: Remove iobuf.h. (get_dns_cert): Rename to _get_dns_cert. Remove MAX_SIZE arg. Change iobuf arg to a estream-t. Rewrite function to make use of estream instead of iobuf. Require all parameters. Return an gpg_error_t error instead of the type. Add arg ERRSOURCE. * common/dns-cert.h (get_dns_cert): New macro to pass the error source to _gpg_dns_cert. * common/t-dns-cert.c (main): Adjust for changes in get_dns_cert. * g10/keyserver.c (keyserver_import_cert): Ditto. * doc/gpg.texi (GPG Configuration Options): Remove max-cert-size. --- common/ChangeLog | 15 ++++ common/dns-cert.c | 195 ++++++++++++++++++++++++++++---------------- common/dns-cert.h | 9 +- common/t-dns-cert.c | 32 ++++---- doc/gpg.texi | 3 + g10/ChangeLog | 5 ++ g10/keyserver.c | 36 ++++---- 7 files changed, 186 insertions(+), 109 deletions(-) diff --git a/common/ChangeLog b/common/ChangeLog index d5682fc4b..96e4e31a2 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,18 @@ +2011-11-30 Werner Koch + + Rewrite dns-cert.c to not use the gpg-only iobuf stuff. + * dns-cert.c: Remove iobuf.h. + (get_dns_cert): Rename to _get_dns_cert. Remove MAX_SIZE arg. + Change iobuf arg to a estream-t. Rewrite function to make use of + estream instead of iobuf. Require all parameters. Return an + gpg_error_t error instead of the type. Add arg ERRSOURCE. + * dns-cert.h (get_dns_cert): New macro to pass the error source to + _gpg_dns_cert. + * t-dns-cert.c (main): Adjust for changes in get_dns_cert. + + * estream.c (es_fopenmem_init): New. + * estream.h (es_fopenmem_init): New. + 2011-11-29 Werner Koch * estream.c (func_mem_create): Don't set FUNC_REALLOC if GROW is diff --git a/common/dns-cert.c b/common/dns-cert.c index 9b6c6c893..56af13a1d 100644 --- a/common/dns-cert.c +++ b/common/dns-cert.c @@ -37,7 +37,6 @@ #endif #include "util.h" -#include "iobuf.h" #include "dns-cert.h" /* Not every installation has gotten around to supporting CERTs @@ -63,48 +62,58 @@ #define CERTTYPE_OID 254 /* OID private. */ -/* Returns -1 on error, 0 for no answer, 1 for PGP provided and 2 for - IPGP provided. Note that this function returns the first CERT - found with a supported type; it is expected that only one CERT - record is used. */ -int -get_dns_cert (const char *name, size_t max_size, IOBUF * iobuf, - unsigned char **fpr, size_t * fpr_len, char **url) +/* Returns 0 on success or an error code. If a PGP CERT record was + found, a new estream with that key will be returned at R_KEY and + the other return parameters are set to NULL/0. If an IPGP CERT + record was found the fingerprint is stored as an allocated block at + R_FPR and its length at R_FPRLEN; an URL is is allocated as a + string and returned at R_URL. Note that this function returns the + first CERT found with a supported type; it is expected that only + one CERT record is used. */ +gpg_error_t +_get_dns_cert (const char *name, estream_t *r_key, + unsigned char **r_fpr, size_t *r_fprlen, char **r_url, + gpg_err_source_t errsource) { #ifdef USE_DNS_CERT #ifdef USE_ADNS + gpg_error_t err; adns_state state; adns_answer *answer = NULL; - int rc; unsigned int ctype; int count; - rc = adns_init (&state, adns_if_noerrprint, NULL); - if (rc) + *r_key = NULL; + *r_fpr = NULL; + *r_fprlen = 0; + *r_url = NULL; + + if (adns_init (&state, adns_if_noerrprint, NULL)) { + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); log_error ("error initializing adns: %s\n", strerror (errno)); - return -1; + return err; } - rc = adns_synchronous (state, name, (adns_r_unknown | my_adns_r_cert), - adns_qf_quoteok_query, &answer); - if (rc) + if (adns_synchronous (state, name, (adns_r_unknown | my_adns_r_cert), + adns_qf_quoteok_query, &answer)) { + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); /* log_error ("DNS query failed: %s\n", strerror (errno)); */ adns_finish (state); - return -1; + return err; } if (answer->status != adns_s_ok) { /* log_error ("DNS query returned an error: %s (%s)\n", */ /* adns_strerror (answer->status), */ /* adns_errabbrev (answer->status)); */ - adns_free (answer); - adns_finish (state); - return 0; + err = gpg_err_make (errsource, GPG_ERR_NOT_FOUND); + goto leave; } - for (rc = 0, count = 0; !rc && count < answer->nrrs; count++) + err = gpg_err_make (errsource, GPG_ERR_NOT_FOUND); + for (count = 0; count < answer->nrrs; count++) { int datalen = answer->rrs.byteblock[count].len; const unsigned char *data = answer->rrs.byteblock[count].data; @@ -121,8 +130,12 @@ get_dns_cert (const char *name, size_t max_size, IOBUF * iobuf, { /* CERT type is PGP. Gpg checks for a minimum length of 11, thus we do the same. */ - *iobuf = iobuf_temp_with_content ((char *)data, datalen); - rc = 1; + *r_key = es_fopenmem_init (0, "rwb", data, datalen); + if (!*r_key) + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); + else + err = 0; + goto leave; } else if (ctype == CERTTYPE_IPGP && datalen && datalen < 1023 && datalen >= data[0] + 1 && fpr && fpr_len && url) @@ -130,50 +143,68 @@ get_dns_cert (const char *name, size_t max_size, IOBUF * iobuf, /* CERT type is IPGP. We made sure that the data is plausible and that the caller requested this information. */ - *fpr_len = data[0]; - if (*fpr_len) + *r_fprlen = data[0]; + if (*r_fprlen) { - *fpr = xmalloc (*fpr_len); - memcpy (*fpr, data + 1, *fpr_len); + *r_fpr = xtrymalloc (*r_fprlen); + if (!*r_fpr) + { + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); + goto leave; + } + memcpy (*r_fpr, data + 1, *r_fprlen); } else - *fpr = NULL; + *r_fpr = NULL; - if (datalen > *fpr_len + 1) + if (datalen > *r_fprlen + 1) { - *url = xmalloc (datalen - (*fpr_len + 1) + 1); - memcpy (*url, data + (*fpr_len + 1), datalen - (*fpr_len + 1)); - (*url)[datalen - (*fpr_len + 1)] = '\0'; + *url = xtrymalloc (datalen - (*r_fprlen + 1) + 1); + if (!*r_url) + { + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); + xfree (*r_fpr); + *r_fpr = NULL; + goto leave; + } + memcpy (*url, data + (*r_fprlen + 1), datalen - (*r_fprlen + 1)); + (*url)[datalen - (*r_fprlen + 1)] = '\0'; } else - *url = NULL; + *r_url = NULL; - rc = 2; + err = 0; + goto leave; } } + leave: adns_free (answer); adns_finish (state); - return rc; + return err; #else /*!USE_ADNS*/ + gpg_error_t err; unsigned char *answer; - int ret = -1; int r; u16 count; - if (fpr) - *fpr = NULL; + *r_key = NULL; + *r_fpr = NULL; + *r_fprlen = 0; + *r_url = NULL; - if (url) - *url = NULL; + /* Allocate a 64k buffer which is the limit for an DNS response. */ + answer = xtrymalloc (65536); + if (!answer) + return gpg_err_make (errsource, gpg_err_code_from_syserror ()); - answer = xmalloc (max_size); + err = gpg_err_make (errsource, GPG_ERR_NOT_FOUND); - r = res_query (name, C_IN, T_CERT, answer, max_size); + r = res_query (name, C_IN, T_CERT, answer, 65536); /* Not too big, not too small, no errors and at least 1 answer. */ - if (r >= sizeof (HEADER) && r <= max_size + if (r >= sizeof (HEADER) && r <= 65536 && (((HEADER *) answer)->rcode) == NOERROR && (count = ntohs (((HEADER *) answer)->ancount))) { @@ -188,8 +219,10 @@ get_dns_cert (const char *name, size_t max_size, IOBUF * iobuf, rc = dn_skipname (pt, emsg); if (rc == -1) - goto fail; - + { + err = gpg_err_make (errsource, GPG_ERR_INV_OBJ); + goto leave; + } pt += rc + QFIXEDSZ; /* There are several possible response types for a CERT request. @@ -204,7 +237,10 @@ get_dns_cert (const char *name, size_t max_size, IOBUF * iobuf, rc = dn_skipname (pt, emsg); /* the name we just queried for */ if (rc == -1) - break; + { + err = gpg_err_make (errsource, GPG_ERR_INV_OBJ); + goto leave; + } pt += rc; @@ -248,39 +284,54 @@ get_dns_cert (const char *name, size_t max_size, IOBUF * iobuf, /* 15 bytes takes us to here */ - if (ctype == CERTTYPE_PGP && iobuf && dlen) + if (ctype == CERTTYPE_PGP && dlen) { /* PGP type */ - *iobuf = iobuf_temp_with_content ((char *) pt, dlen); - ret = 1; - break; + *r_key = es_fopenmem_init (0, "rwb", pt, dlen); + if (!*r_key) + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); + else + err = 0; + goto leave; } else if (ctype == CERTTYPE_IPGP - && dlen && dlen < 1023 && dlen >= pt[0] + 1 - && fpr && fpr_len && url) + && dlen && dlen < 1023 && dlen >= pt[0] + 1) { /* IPGP type */ - *fpr_len = pt[0]; - - if (*fpr_len) + *r_fprlen = pt[0]; + if (*r_fprlen) { - *fpr = xmalloc (*fpr_len); - memcpy (*fpr, &pt[1], *fpr_len); + *r_fpr = xtrymalloc (*r_fprlen); + if (!*r_fpr) + { + err = gpg_err_make (errsource, + gpg_err_code_from_syserror ()); + goto leave; + } + memcpy (*r_fpr, &pt[1], *r_fprlen); } else - *fpr = NULL; + *r_fpr = NULL; - if (dlen > *fpr_len + 1) + if (dlen > *r_fprlen + 1) { - *url = xmalloc (dlen - (*fpr_len + 1) + 1); - memcpy (*url, &pt[*fpr_len + 1], dlen - (*fpr_len + 1)); - (*url)[dlen - (*fpr_len + 1)] = '\0'; + *r_url = xtrymalloc (dlen - (*r_fprlen + 1) + 1); + if (!*r_fpr) + { + err = gpg_err_make (errsource, + gpg_err_code_from_syserror ()); + xfree (*r_fpr); + *r_fpr = NULL; + goto leave; + } + memcpy (*r_url, &pt[*r_fprlen + 1], dlen - (*r_fprlen + 1)); + (*r_url)[dlen - (*r_fprlen + 1)] = '\0'; } else - *url = NULL; + *r_url = NULL; - ret = 2; - break; + err = 0; + goto leave; } /* Neither type matches, so go around to the next answer. */ @@ -288,18 +339,18 @@ get_dns_cert (const char *name, size_t max_size, IOBUF * iobuf, } } - fail: + leave: xfree (answer); - return ret; + return err; + #endif /*!USE_ADNS */ #else /* !USE_DNS_CERT */ (void)name; - (void)max_size; - (void)iobuf; - (void)fpr; - (void)fpr_len; - (void)url; + (void)r_key; + (void)r_fpr; + (void)r_fprlen; + (void)r_url; - return -1; + return gpg_err_make (errsource, GPG_ERR_NOT_SUPPORTED); #endif } diff --git a/common/dns-cert.h b/common/dns-cert.h index ebfeec838..a1d3d86da 100644 --- a/common/dns-cert.h +++ b/common/dns-cert.h @@ -19,8 +19,13 @@ #ifndef GNUPG_COMMON_DNS_CERT_H #define GNUPG_COMMON_DNS_CERT_H -int get_dns_cert (const char *name, size_t max_size, iobuf_t *iobuf, - unsigned char **fpr, size_t *fpr_len, char **url); +gpg_error_t _get_dns_cert (const char *name, estream_t *r_key, + unsigned char **r_fpr, size_t *r_fprlen, + char **r_url, + gpg_err_source_t errsource); +#define get_dns_cert(a,b,c,d,e) \ + _get_dns_cert ((a),(b),(c),(d),(e), GPG_ERR_SOURCE_DEFAULT); + #endif /*GNUPG_COMMON_DNS_CERT_H*/ diff --git a/common/t-dns-cert.c b/common/t-dns-cert.c index f3e8892a7..1dcae6f29 100644 --- a/common/t-dns-cert.c +++ b/common/t-dns-cert.c @@ -23,18 +23,17 @@ #include #include "util.h" -#include "iobuf.h" #include "dns-cert.h" int main (int argc, char **argv) { + gpg_error_t err; unsigned char *fpr; size_t fpr_len; char *url; - int rc; - iobuf_t iobuf; + estream_t key; char const *name; if (argc) @@ -55,18 +54,19 @@ main (int argc, char **argv) printf ("CERT lookup on `%s'\n", name); - rc = get_dns_cert (name, 65536, &iobuf, &fpr, &fpr_len, &url); - if (rc == -1) - fputs ("lookup result: error\n", stdout); - else if (!rc) - fputs ("lookup result: no answer\n", stdout); - else if (rc == 1) + err = get_dns_cert (name, &key, &fpr, &fpr_len, &url); + if (err) + printf ("get_dns_cert failed: %s <%s>\n", + gpg_strerror (err), gpg_strsource (err)); + else if (key) { - printf ("lookup result: %d bytes\n", - (int)iobuf_get_temp_length(iobuf)); - iobuf_close (iobuf); + int count = 0; + + while (es_getc (key) != EOF) + count++; + printf ("Key found (%d bytes)\n", count); } - else if (rc == 2) + else { if (fpr) { @@ -85,9 +85,11 @@ main (int argc, char **argv) else printf ("No URL found\n"); - xfree (fpr); - xfree (url); } + es_fclose (key); + xfree (fpr); + xfree (url); + return 0; } diff --git a/doc/gpg.texi b/doc/gpg.texi index d00e01f00..481e05e3d 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1584,9 +1584,12 @@ are available for all keyserver types, some common options are: Set the proxy to use for HTTP and HKP keyservers. This overrides the "http_proxy" environment variable, if any. + +@ifclear gpgtwoone @item max-cert-size When retrieving a key via DNS CERT, only accept keys up to this size. Defaults to 16384 bytes. +@end ifclear @item debug Turn on debug output in the keyserver helper program. Note that the diff --git a/g10/ChangeLog b/g10/ChangeLog index 629de8172..4dadaabcc 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,8 @@ +2011-11-30 Werner Koch + + * keyserver.c (keyserver_import_cert): Adjust for changed + get_dns_cert. + 2011-11-28 Werner Koch * keyserver.c (DEFAULT_MAX_CERT_SIZE): Increase from 16k to 64k. diff --git a/g10/keyserver.c b/g10/keyserver.c index efb08773f..102f65d38 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -1691,9 +1691,10 @@ int keyserver_import_cert (ctrl_t ctrl, const char *name,unsigned char **fpr,size_t *fpr_len) { + gpg_error_t err; char *domain,*look,*url; - IOBUF key; - int type,rc=G10ERR_GENERAL; + estream_t key; + look=xstrdup(name); @@ -1701,30 +1702,25 @@ keyserver_import_cert (ctrl_t ctrl, if(domain) *domain='.'; - type=get_dns_cert(look,max_cert_size,&key,fpr,fpr_len,&url); - if (!type || type == -1) - { - /* There might be an error in res_query which leads to an error - return (-1) in the case that nothing was found. Thus we take - all errors as key not found. */ - rc = G10ERR_NO_PUBKEY; - } - else if (type==1) + err = get_dns_cert (look, &key, fpr, fpr_len, &url); + if (err) + ; + else if (key) { int armor_status=opt.no_armor; /* CERTs are always in binary format */ opt.no_armor=1; - /* FIXME: Pass CTRL. */ - rc = import_keys_stream (NULL, key, NULL, fpr, fpr_len, - opt.keyserver_options.import_options); + err = import_keys_es_stream (ctrl, key, NULL, fpr, fpr_len, + opt.keyserver_options.import_options); opt.no_armor=armor_status; - iobuf_close(key); + es_fclose (key); + key = NULL; } - else if(type==2 && *fpr) + else if (*fpr) { /* We only consider the IPGP type if a fingerprint was provided. This lets us select the right key regardless of what a URL @@ -1736,7 +1732,7 @@ keyserver_import_cert (ctrl_t ctrl, spec=parse_keyserver_uri(url,1,NULL,0); if(spec) { - rc = keyserver_import_fprint (ctrl, *fpr,*fpr_len,spec); + err = keyserver_import_fprint (ctrl, *fpr,*fpr_len,spec); free_keyserver_spec(spec); } } @@ -1745,7 +1741,7 @@ keyserver_import_cert (ctrl_t ctrl, /* If only a fingerprint is provided, try and fetch it from our --keyserver */ - rc = keyserver_import_fprint (ctrl, *fpr,*fpr_len,opt.keyserver); + err = keyserver_import_fprint (ctrl, *fpr,*fpr_len,opt.keyserver); } else log_info(_("no keyserver known (use option --keyserver)\n")); @@ -1754,12 +1750,12 @@ keyserver_import_cert (ctrl_t ctrl, found, but no keyserver" " known (use option --keyserver)\n" ? */ - xfree(url); } + xfree(url); xfree(look); - return rc; + return err; } /* Import key pointed to by a PKA record. Return the requested From 2c5d02191203d54f6bb681a18d12550de6319c55 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 1 Dec 2011 11:09:51 +0900 Subject: [PATCH 22/68] Fix pinpad input support --- scd/ChangeLog | 5 ++++ scd/app-openpgp.c | 68 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/scd/ChangeLog b/scd/ChangeLog index d0f779ebd..80cddec49 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,8 @@ +2011-12-01 Niibe Yutaka + + * app-openpgp.c (do_change_pin): Fix pincb messages when + use_keypad == 1. + 2011-11-29 Niibe Yutaka PC/SC pininput support for passphrase modification (2/2) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 08d641db6..b51eb5be1 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1983,7 +1983,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, if (chvno == 2) set_resetcode = 1; } - else if (chvno == 1 || chvno == 3) + else if (!use_keypad && (chvno == 1 || chvno == 3)) { char *promptbuf = NULL; const char *prompt; @@ -1998,7 +1998,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, } else prompt = _("||Please enter the PIN"); - rc = pincb (pincb_arg, prompt, use_keypad ? NULL : &oldpinvalue); + rc = pincb (pincb_arg, prompt, &oldpinvalue); xfree (promptbuf); promptbuf = NULL; if (rc) @@ -2008,7 +2008,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, goto leave; } - if (!use_keypad && strlen (oldpinvalue) < minlen) + if (strlen (oldpinvalue) < minlen) { log_info (_("PIN for CHV%d is too short;" " minimum length is %d\n"), chvno, minlen); @@ -2044,21 +2044,24 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, goto leave; } - rc = pincb (pincb_arg, - _("||Please enter the Reset Code for the card"), - use_keypad ? NULL : &resetcode); - if (rc) + if (!use_keypad) { - log_info (_("PIN callback returned error: %s\n"), - gpg_strerror (rc)); - goto leave; - } - if (!use_keypad && strlen (resetcode) < minlen) - { - log_info (_("Reset Code is too short; minimum length is %d\n"), - minlen); - rc = gpg_error (GPG_ERR_BAD_PIN); - goto leave; + rc = pincb (pincb_arg, + _("||Please enter the Reset Code for the card"), + &resetcode); + if (rc) + { + log_info (_("PIN callback returned error: %s\n"), + gpg_strerror (rc)); + goto leave; + } + if (strlen (resetcode) < minlen) + { + log_info (_("Reset Code is too short; minimum length is %d\n"), + minlen); + rc = gpg_error (GPG_ERR_BAD_PIN); + goto leave; + } } } else @@ -2094,6 +2097,15 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, { if (use_keypad) { + rc = pincb (pincb_arg, + _("||Please enter the Reset Code for the card and New PIN"), + NULL); + if (rc) + { + log_info (_("PIN callback returned error: %s\n"), + gpg_strerror (rc)); + goto leave; + } rc = iso7816_reset_retry_counter_with_rc_kp (app->slot, 0x81, &pininfo); pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ @@ -2120,6 +2132,12 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, if (use_keypad) { rc = pincb (pincb_arg, _("|RN|New Reset Code"), NULL); + if (rc) + { + log_info (_("PIN callback returned error: %s\n"), + gpg_strerror (rc)); + goto leave; + } rc = iso7816_put_data_kp (app->slot, 0xD3, &pininfo); pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ } @@ -2138,6 +2156,12 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, if (use_keypad) { rc = pincb (pincb_arg, _("|N|New PIN"), NULL); + if (rc) + { + log_info (_("PIN callback returned error: %s\n"), + gpg_strerror (rc)); + goto leave; + } rc = iso7816_reset_retry_counter_kp (app->slot, 0x81, &pininfo); pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ } @@ -2174,6 +2198,16 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, if (use_keypad) { + rc = pincb (pincb_arg, + chvno == 3 ? + _("||Please enter the Admin PIN and New Admin PIN") : + _("||Please enter the PIN and New PIN"), NULL); + if (rc) + { + log_info (_("PIN callback returned error: %s\n"), + gpg_strerror (rc)); + goto leave; + } rc = iso7816_change_reference_data_kp (app->slot, 0x80 + chvno, &pininfo); pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ From 2336b09779d313c1594acf6df3bd8a8486e90458 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 1 Dec 2011 10:51:36 +0100 Subject: [PATCH 23/68] Generate the ChangeLog from commit logs. * scripts/gitlog-to-changelog: New script. Taken from gnulib. * scripts/git-log-fix: New file. * scripts/git-log-footer: New file. * doc/HACKING: Describe the ChangeLog policy * ChangeLog: New file. * Makefile.am (EXTRA_DIST): Add new files. (gen-ChangeLog): New. (dist-hook): Run gen-ChangeLog. Rename all ChangeLog files to ChangeLog-2011. --- ChangeLog | 1391 +----------------- ChangeLog-2011 | 1394 +++++++++++++++++++ Makefile.am | 24 +- agent/{ChangeLog => ChangeLog-2011} | 13 +- agent/Makefile.am | 3 +- common/{ChangeLog => ChangeLog-2011} | 11 + common/ChangeLog.jnlib | 11 + common/Makefile.am | 2 +- dirmngr/{ChangeLog => ChangeLog-2011} | 11 + dirmngr/ChangeLog.1 | 4 + dirmngr/Makefile.am | 2 +- doc/{ChangeLog => ChangeLog-2011} | 11 + doc/HACKING | 31 +- doc/Makefile.am | 2 +- g10/{ChangeLog => ChangeLog-2011} | 21 +- g10/Makefile.am | 2 +- g13/ChangeLog | 3 - g13/ChangeLog-2011 | 14 + g13/Makefile.am | 2 + include/{ChangeLog => ChangeLog-2011} | 11 + include/Makefile.am | 2 +- kbx/{ChangeLog => ChangeLog-2011} | 13 +- keyserver/{ChangeLog => ChangeLog-2011} | 23 +- keyserver/Makefile.am | 14 +- m4/{ChangeLog => ChangeLog-2011} | 11 + m4/Makefile.am | 5 +- po/{ChangeLog => ChangeLog-2011} | 14 +- po/de.po | 27 +- scd/{ChangeLog => ChangeLog-2011} | 13 +- scd/Makefile.am | 2 + scripts/{ChangeLog => ChangeLog-2011} | 11 + scripts/git-log-fix | 3 + scripts/git-log-footer | 14 + scripts/gitlog-to-changelog | 345 +++++ sm/{ChangeLog => ChangeLog-2011} | 13 +- sm/Makefile.am | 1 + tests/{ChangeLog => ChangeLog-2011} | 11 + tests/Makefile.am | 2 +- tests/openpgp/{ChangeLog => ChangeLog-2011} | 11 + tests/openpgp/Makefile.am | 2 +- tests/pkits/{ChangeLog => ChangeLog-2011} | 15 +- tests/pkits/Makefile.am | 12 +- tools/{ChangeLog => ChangeLog-2011} | 13 +- tools/Makefile.am | 2 +- 44 files changed, 2102 insertions(+), 1440 deletions(-) create mode 100644 ChangeLog-2011 rename agent/{ChangeLog => ChangeLog-2011} (99%) rename common/{ChangeLog => ChangeLog-2011} (99%) rename dirmngr/{ChangeLog => ChangeLog-2011} (99%) rename doc/{ChangeLog => ChangeLog-2011} (98%) rename g10/{ChangeLog => ChangeLog-2011} (99%) delete mode 100644 g13/ChangeLog create mode 100644 g13/ChangeLog-2011 rename include/{ChangeLog => ChangeLog-2011} (97%) rename kbx/{ChangeLog => ChangeLog-2011} (96%) rename keyserver/{ChangeLog => ChangeLog-2011} (98%) rename m4/{ChangeLog => ChangeLog-2011} (93%) rename po/{ChangeLog => ChangeLog-2011} (95%) rename scd/{ChangeLog => ChangeLog-2011} (99%) rename scripts/{ChangeLog => ChangeLog-2011} (81%) create mode 100644 scripts/git-log-fix create mode 100644 scripts/git-log-footer create mode 100755 scripts/gitlog-to-changelog rename sm/{ChangeLog => ChangeLog-2011} (99%) rename tests/{ChangeLog => ChangeLog-2011} (92%) rename tests/openpgp/{ChangeLog => ChangeLog-2011} (97%) rename tests/pkits/{ChangeLog => ChangeLog-2011} (83%) rename tools/{ChangeLog => ChangeLog-2011} (99%) diff --git a/ChangeLog b/ChangeLog index 5e5a0149d..8bd68a626 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,1383 +1,16 @@ -2011-11-29 Werner Koch +No more ChangeLog files +======================== - * autogen.sh: Make sure HOME et al have no unsafe characters. +Do not modify any of the ChangeLog files in GnuPG. Starting on +December 1st, 2011 we put change information only in the GIT commit +log, and generate a top-level ChangeLog file from logs at "make dist" +time. As such, there are strict requirements on the form of the +commit log messages. See doc/HACKING for details. The old ChangeLog +files have all be renamed to ChangeLog-2011. -2011-11-28 Jim Meyering - accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix - * m4/gpg-error.m4: Update from git master. -2011-09-23 Werner Koch - - * configure.ac: Remove check for gcry_kdf_derive. - -2011-08-10 Werner Koch - - * configure.ac: Fix new autoconf warnings. - -2011-05-20 Werner Koch - - * configure.ac: Require libgpg-error 1.10. - -2011-03-08 Werner Koch - - Release 2.1.0beta2. - - * configure.ac: Require libgcrypt 1.5.0. - (HAVE_GCRY_PK_ECDH, HAVE_GCRY_PK_GET_CURVE): Remove. - (utmp.h): Check for header. - -2011-02-25 Werner Koch - - * configure.ac: Require libksba 1.2. - -2011-02-04 Werner Koch - - * autogen.sh: Ensure that the git pre-commit hoom has been - enabled. Add a cleanpo filter if not yet set. - -2011-02-03 Werner Koch - - * configure.ac (HAVE_GCRY_PK_GET_CURVE): Use AC_TRY_LINK. - -2011-02-01 Werner Koch - - * configure.ac (HAVE_GCRY_PK_GET_CURVE): Define if availabale. - -2011-01-20 Werner Koch - - * configure.ac (AC_CONFIG_FILES): Remove keyserver/. - -2011-01-19 Werner Koch - - * configure.ac: Add new option --enable-gpg2-is-gpg. - (NAME_OF_INSTALLED_GPG): New ac_define. - * autogen.sh [--build-w32ce]: Use --enable-gpg2-is-gpg. - -2011-01-21 Werner Koch - - * configure.ac: Need Libgcrypt 1.4.6 due to AESWRAP. - (HAVE_GCRY_PK_ECDH): Add new test. - -2011-01-03 Werner Koch - - * README.SVN: Rename to README.GIT. - * Makefile.am (EXTRA_DIST): Adjust for that change. - -2010-12-14 Werner Koch - - * configure.ac (BUILD_WITH_GPG, BUILD_WITH_GPGSM) - (BUILD_WITH_AGENT, BUILD_WITH_SCDAEMON, BUILD_WITH_DIRMNGR) - (BUILD_WITH_G13): New defines. - -2010-11-23 Werner Koch - - * am/cmacros.am (extra_bin_ldflags): New. For W32CE set the stack - size to 256k. - -2010-11-17 Werner Koch - - * configure.ac (ENABLE_CARD_SUPPORT): Define. - -2010-10-27 Werner Koch - - * acinclude.m4 (GNUPG_TIME_T_UNSIGNED): New. - * configure.ac (AC_HEADER_TIME): Include before checking time_t. - (GNUPG_TIME_T_UNSIGNED): Add. - -2010-10-26 Werner Koch - - Release 2.1.0beta1. - -2010-10-18 Werner Koch - - * Makefile.am (install-data-hook): Add W32 specific hook. - -2010-10-08 Werner Koch - - * configure.ac: Add option --enable-dirmngr-auto-start. - (USE_DIRMNGR_AUTO_START): New ac_define. - * autogen.sh <--build-w32ce>: Use new option. - -2010-10-06 Werner Koch - - * configure.ac: Make --enable-standard-socket the default. - -2010-10-04 Werner Koch - - * configure.ac (GNUPG_CHECK_FAQPROG): Remove. - -2010-08-19 Werner Koch - - * configure.ac (AH_BOTTOM): Define GPG_ERR_ENABLE_ERRNO_MACROS. - -2010-08-09 Werner Koch - - * configure.ac (inet_pton): Check for it. - -2010-08-05 Werner Koch - - * configure.ac (AH_BOTTOM): Remove HTTP_USE_ESTREAM. - -2010-08-02 Werner Koch - - * configure.ac: Require libksba 1.1.0 due to the use of - ksba_reader_set_release_notify. - -2010-07-30 Werner Koch - - * configure.ac (GNUPG_PTH_PATH) [W32]: Require version 2.0.3. - -2010-07-25 Werner Koch - - * configure.ac (USE_LDAPWRAPPER): AC_DEFINE and AM_CONDITIONAL it. - -2010-06-09 Werner Koch - - * configure.ac (GNUPG_DIRMNGR_LDAP_PGM): Add option - --with-dirmngr-ldap-pgm. - - * am/cmacros.am (-DGNUPG_LOCALSTATEDIR): New. - (GNUPG_DEFAULT_DIRMNGR_LDAP): New. - -2010-06-08 Werner Koch - - * configure.ac: Add build support for dirmngr. - (try_ldap): Rename to try_ks_ldap. - (GNUPG_CHECK_LDAP): Also test if dirmngr is to be build. - - * Makefile.am (SUBDIRS): Add dirmngr. - -2010-06-07 Werner Koch - - * dirmngr/: New. - - * configure.ac: Add option --enable-gpgtar. - -2010-05-31 Werner Koch - - * configure.ac (AC_CHECK_FUNCS): Check for lstat. - -2010-04-30 Werner Koch - - * configure.ac: Add option --enable-standard-socket. - (USE_STANDARD_SOCKET): ac_define it. - -2010-04-14 Werner Koch - - * Makefile.am (keyserver) [W32CE]: Do not build for now. - - * configure.ac (use_zip): New. - (--disable-zip): New option. - (HAVE_ZIP): New. - * autogen.sh : Disable ZIP. - -2010-04-07 Werner Koch - - * autogen.sh: Take a .gnupg-autogen.rc file in account. - - * gl/mkdtemp.c (getpid) [W32CE]: New macro. - -2010-03-24 Werner Koch - - * configure.ac (AH_BOTTOM): Use /gnupg as the default homedir on - dosish systems which don't support drive letters (e.g. W32CE). - - * am/cmacros.am (extra_sys_libs): New. - -2010-03-23 Werner Koch - - * configure.ac (W32SOCKLIBS): Change value for W32CE. - -2010-03-12 Werner Koch - - * configure.ac (AC_INIT): Prepare for using git. - -2010-03-10 Werner Koch - - * jnlib/: Move all code to common/. - * Makefile.am (SUBDIRS): Remove jnlib. - * configure.ac (AC_CONFIG_FILES): Remove jnlib/Makefile. - - * configure.ac (AM_PATH_LIBASSUAN): Remove double test. - * acinclude.m4 (GNUPG_CHECK_ENDIAN): Remove bogus warning. - -2010-03-09 Werner Koch - - * configure.ac: Add option --disable-ccid-driver. - (AH_BOTTOM): Define GPG_ERR_ENABLE_GETTEXT_MACROS. - -2010-02-26 Werner Koch - - * gl/mkdtemp.c (__set_errno) [W32CE]: Use gpg_err_set_errno. - * gl/setenv.c (__set_errno) [W32CE]: Ditto. - * gl/unsetenv.c (__set_errno) [W32CE]: Ditto. - - * configure.ac (HAVE_W32CE_SYSTEM): New ac_define and - am_conditional. - (signal.h, getenv): Check for them. - - * autogen.sh: New option --build-w32ce. Remove obsolete option - --without-included-gettext. - -2009-12-08 Werner Koch - - * configure.ac (USE_DNS_CERT): Support ADNS. - -2009-12-07 Werner Koch - - * configure.ac: Check for ADNS before checking for the BIND - resolver. - (USE_ADNS): Fallback macro for PKA and CERT lookups. - -2009-10-20 Marcus Brinkmann - - * configure.ac: Check for fusermount and encfs. - -2009-10-16 Marcus Brinkmann - - * configure.ac: Check for libassuan instead of libassuan-pth. - -2009-10-12 Werner Koch - - * configure.ac: Use -O3 because newer gcc versions require that - for uninitialized variable warnings. - -2009-09-23 Werner Koch - - * configure.ac (HAVE_ASSUAN_SET_IO_MONITOR): Remove test. - (_ASSUAN_ONLY_GPG_ERRORS): Remove. - -2009-09-23 Marcus Brinkmann - - * configure.ac (NEED_LIBASSUAN_API, NEED_LIBASSUAN_VERSION): - Update to new API (2, 1.1.0). - -2009-09-21 Werner Koch - - Start a new development branch in the SVN trunk. The stable one - is now known in the SVN as branches/GNUPG-STABLE-2-0. - -2009-09-04 Werner Koch - - Release 2.0.13. - -2009-06-29 Werner Koch - - * configure.ac: Take care of --without-adns. Suggested by - Arfrever Frehtes Taifersar Arahesis. - -2009-06-17 Werner Koch - - Release 2.0.12. - -2009-06-05 David Shaw - - * configure.ac: Remove Camellia restriction. - -2009-04-01 Werner Koch - - * configure.ac: Test for fsync. - -2009-03-18 Werner Koch - - * configure.ac: Test for getrlimit. - -2009-03-03 Werner Koch - - Release 2.0.11. - -2009-01-12 Werner Koch - - Release 2.0.10. - -2008-12-09 Werner Koch - - Release 2.0.10rc1. - -2008-10-17 Werner Koch - - * configure.ac: Use more warning options with modern GCCs. - -2008-09-29 Werner Koch - - * configure.ac: Require libgcrypt 1.4. - -2008-08-27 David Shaw - - * configure.ac: Use printf for the most portable SVN version - detection. - - * configure.ac: Darwin's /bin/sh has a builtin echo that doesn't - understand '-n'. Use tr to trim the carriage return instead. - -2008-04-23 Werner Koch - - * configure.ac: Call gl_HEADER_SYS_SOCKET and gl_TYPE_SOCKLEN_T. - -2008-04-07 Werner Koch - - * configure.ac (ADNSLIBS): Test for adns. - (GPGKEYS_KDNS): New. - -2008-04-01 Werner Koch - - * configure.ac: Require curl 7.10 (Oct 1 2002) or later as we use - curl_version_info(). - (AC_INIT): Fix quoting. - -2008-03-27 Werner Koch - - * Makefile.am (dist_doc_DATA): New. Install README. - -2008-03-26 Werner Koch - - Release 2.0.9. - -2008-02-19 Werner Koch - - * configure.ac: Remove --with-pkits-tests. - -2008-02-15 Werner Koch - - * gl/allocsa.h, gl/m4/allocsa.m4: Replace HAVE_LONG_LONG by - HAVE_LONG_LONG_INT. - -2008-02-15 gettextize - - * configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.17. - -2007-12-20 Werner Koch - - Released 2.0.8. - -2007-12-17 Werner Koch - - * configure.ac: Add treatment for HAVE_LDAP_START_TLS_SA. - -2007-12-14 Werner Koch - - Released 2.0.8rc1. - -2007-12-12 Werner Koch - - * configure.ac (USE_CAMELLIA): Define by new option --enable-camellia. - -2007-12-03 Werner Koch - - * configure.ac: Add test gt_LC_MESSAGES.. - -2007-10-01 Werner Koch - - * configure.ac: Require assuan 1.0.4. - -2007-09-14 Werner Koch - - * configure.ac (GNUPG_LIBASSUAN_VERSION): New. - -2007-09-10 Werner Koch - - Released 2.0.7. - -2007-08-27 Werner Koch - - * configure.ac: Remove remaining support for internal regex. - Define DISABLE_REGEX automake conditional. Add option - --with-regex. - * autogen.sh [--build-w32]: Remove --disable-regex. Use --with-regex. - -2007-08-16 Werner Koch - - Released 2.0.6. - -2007-08-08 Werner Koch - - * configure.ac: Use AC_CANONICAL_HOST and not AC_CANONICAL_TARGET. - -2007-07-09 Werner Koch - - * configure.ac (AM_ICONV): Check for it even when building without - NLS. - -2007-07-05 Werner Koch - - Released 2.0.5. - - * configure.ac: Require libassuan 1.0.2. - -2007-07-05 Marcus Brinkmann - - * configure.ac: Invoke AM_LANGINFO_CODESET. - -2007-07-04 Werner Koch - - * Makefile.am (AUTOMAKE_OPTIONS): Add no-dist-gzip. - - Switched entire package to GPLv3+. - - * configure.ac: Require libksba 1.0.2. - - * COPYING: Updated to GPLv3. - * COPYING.LIB: New as jnlib/ uses this license. - - * gl/: Switched to GPLv3+. - - * intl/ Removed. - * configure.ac (AM_GNU_GETTEXT): Add external flag. - (AM_ICONV): New. - -2007-07-03 Werner Koch - - * configure.ac [W32]: Use ws2_32 instead of wsock32. - -2007-06-25 Werner Koch - - * gl/mkdtemp.c (gen_tempname) [MKDIR_TAKES_ONE_ARG]: Avoid - compiler warning by using the proper config macro. - -2007-06-15 Werner Koch - - * configure.ac: Call AM_PO_SUBDIRS. - (W32SOCKLIBS): New. - - * autogen.sh: Use = and not == in test to be POSIXly correct. - : Disable use of regex. - -2007-06-14 Werner Koch - - * configure.ac [AH_BOTTOM]: Remove the hardwired names of modules. - -2007-06-12 Werner Koch - - * configure.ac [AH_BOTTOM]: Define HTTP_NO_WSASTARTUP. - -2007-06-11 Werner Koch - - * am/cmacros.am (libcommonstd, libcommonpth, libcommonstd_ldadd) - (libcommonpth_ldadd): Add macros. - -2007-06-06 Werner Koch - - * configure.ac: Add a few notices message so make browsing of the - log file easier. - (CC_FOR_BUILD): New. - -2007-05-30 Werner Koch - - * configure.ac [W32]: Do not create a symlink to w32-pth.h. - Require the installation of the w32pth package. - -2007-05-29 Werner Koch - - * gl/: Updated to a newer version. - -2007-05-24 Werner Koch - - * configure.ac: Use -Wpointer-arith is possible. - -2007-05-15 Werner Koch - - * configure.ac: Renamed the estream macros. Remove -Wformat-nonliteral. - - * configure.ac: Call ESTREAM_INIT and define the memory - allocators for estream_asprintf. - (gl_MODULES): Remove vasprintf. - -2007-05-09 Werner Koch - - Released 2.0.4. - -2007-05-07 Werner Koch - - * configure.ac: Require libgcrypt 1.2.2 to avoid compiler warnings. - -2007-05-07 gettextize - - * configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.16.1. - -2007-05-07 Werner Koch - - * configure.ac: Bail out if no C-89 compiler has been found. - -2007-05-04 Werner Koch - - * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Add --enable-mailto - - * configure.ac: Require automake 1.10 - (AC_CONFIG_FILES): Rename gpgkeys_ to gpg2keys_. - (AM_PROG_CC_C_O): New. - -2007-03-08 Werner Koch - - Released 2.0.3. - - * autogen.sh: Add option --force. - -2007-01-31 Werner Koch - - Released 2.0.2. - -2006-11-30 Werner Koch - - * configure.ac: Save original LIBS when testing for dlopen. - -2006-11-28 Werner Koch - - Released 2.0.1. - -2006-11-23 Werner Koch - - Released 2.0.1rc1. - -2006-11-21 Werner Koch - - * configure.ac [AH_BOTTOM]: Disable PTH soft mapping. - (AC_CHECK_SIZEOF): Check for time_t. - (BUILD_INCLUDED_LIBINTL): Remove AM_PO_SUBDIRS as it is not - required for C. - -2006-11-15 Werner Koch - - * autogen.sh: Add convenience option --build-amd64. - -2006-11-14 Werner Koch - - * configure.ac (HAVE_ASSUAN_SET_IO_MONITOR): Test for it. - -2006-11-11 Werner Koch - - Released 2.0.0. - -2006-11-06 Werner Koch - - Released 1.9.95. - -2006-11-03 Werner Koch - - * configure.ac: Test for pty.h. From Gentoo. - -2006-10-24 Werner Koch - - Released 1.9.94. - -2006-10-20 Werner Koch - - * Makefile.am (stowinstall): Add convenience target. - -2006-10-18 Werner Koch - - * configure.ac: svn revison magic fixes for old bashs. Suggested - by Alain Guibert. - -2006-10-18 Werner Koch - - Released 1.9.93. - -2006-10-17 Werner Koch - - * autogen.sh <--build-w32>: Test also for a host "mingw32". - - * configure.ac: Removed W32LIBS. Use NETLIBS instead. - -2006-10-11 Werner Koch - - Released 1.9.92. - - * configure.ac: Require libassuan 0.9.3. - -2006-10-09 Werner Koch - - * acinclude.m4: Moved pth check to m4/gnupg-pth.m4. - -2006-10-06 Werner Koch - - * configure.ac: Also check for libassuan's pth version. - -2006-10-04 Werner Koch - - Released 1.9.91. - - * configure.ac: Require libassuan 0.9.1 which fixes a problem with - gpgsm. - -2006-09-27 Werner Koch - - * gl/strsep.h, gl/strsep.c, gl/m4/strsep.m4: Removed. - * gl/strpbrk.h, gl/strpbrk.c, gl/m4/strpbrk.m4: Removed. - * gl/Makefile.am: Removed module strsep and strpbrk. - * configure.ac: Check for strsep in the context of jnlib. Remove - check from gl_MODULES. Moved check for timegm into the jnlib context. - -2006-09-27 Marcus Brinkmann - - * Makefile.am: Fix cut & paste error. - -2006-09-25 Werner Koch - - Released 1.9.90. - -2006-09-22 Werner Koch - - * AUTHORS: Add information about used licenses. - -2006-09-20 Werner Koch - - * Makefile.am (dist-hook): Removed distfiles cruft. - (SUBDIRS): Added include - -2006-09-18 Werner Koch - - Released 1.9.23. - - * configure.ac (--enable-agent-only): Donot build tools and doc - (--disable-tools,--disable-doc): New. - * Makefile.am (SUBDIRS): Allow to conditional build tools and doc. - -2006-09-14 Werner Koch - - Replaced all call gpg_error_from_errno(errno) by - gpg_error_from_syserror(). - - * configure.ac: Build gpg by default. - (GNUPG_SYS_SO_PEERCRED): Removed. - -2006-09-13 Werner Koch - - * autogen.sh: Better detection of the cross compiler kit. - -2006-09-06 Marcus Brinkmann - - * configure.ac: New automake conditional RUN_GPG_TESTS. - -2006-09-06 Werner Koch - - * configure.ac: Define _ASSUAN_ONLY_GPG_ERRORS. Require Assuan - 0.9 and libgpg-error 1.4. - -2006-08-31 Werner Koch - - * configure.ac: Require libksba 1.0 and added API check for it. - (GPG_ERR_LOCKED): Removed DECL check as we require 1.2 anyway. - (have_libusb): New to give a feedback about CCID support - -2006-08-21 Werner Koch - - * configure.ac: Removed docbook tests. - (AC_CONFIG_FILES): Added gpgkeys_test and gpgkeys_mailto. - - * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Enable gpg. - -2006-08-17 Werner Koch - - * THANKS: Merged with the 1.4 one. - -2006-08-16 Werner Koch - - * configure.ac: Removed test for capabilities and mlock. - -2006-08-15 Werner Koch - - * Makefile.am (keyserver): Enable building of keyserver helpers. - - * configure.ac: Merged with the current configure from 1.4.5. - Require libgpg-error 1.2 and libksba 0.9.16. - -2006-07-29 Marcus Brinkmann - - * README: Spelling fixes. - -2006-07-27 Werner Koch - - Released 1.9.22. - - * configure.ac: Call AB_INIT. - -2006-07-03 Werner Koch - - * configure.ac: Test for ksba_dn_teststr. - -2006-06-30 Werner Koch - - * keyserver/: New. Taken from 1.4.4 - * Makefile.am (SUBDIRS): Include keyserver/. - * configure.ac: Include keyserver/. - (FAKE_CURL, GPGKEYS_CURL): New. - -2006-06-20 Werner Koch - - Released 1.9.21. - -2006-06-08 Marcus Brinkmann - - * configure.ac (PTH_LIBS): Add --all to pth-config invocation. - -2006-05-24 Werner Koch - - * configure.ac: New option --disable-optimization taked from 1.4.3. - -2006-05-23 Werner Koch - - * configure.ac (ZLIBS): New for zlib link commands. Add bzip2 - support. - -2006-05-22 Werner Koch - - * configure.ac (EXEEXT): New. - -2006-04-18 Werner Koch - - * configure.ac (PK_UID_CACHE_SIZE): New. - -2006-04-07 Werner Koch - - * configure.ac: Use new method to include the SVN revison. Now it - is the actual global revision number. - -2005-12-20 Werner Koch - - Released 1.9.20. - -2005-11-28 Werner Koch - - * configure.ac: Append the revision to the version string. - -2005-11-13 Werner Koch - - * am/cmacros.am (-DGNUPG_SYSCONFDIR): Define it. - -2005-11-11 Werner Koch - - * configure.ac (NEED_KSBA_VERSION: Require 0.9.13. - -2005-09-12 Werner Koch - - Released 1.9.19. - -2005-08-01 Werner Koch - - Released 1.9.18. - - * configure.ac: Require libksba 0.9.12 to match new features in gpgsm. - -2005-06-20 Werner Koch - - Released 1.9.17. - -2005-06-02 Werner Koch - - * configure.ac (HAVE_PTH): Define as alias for USE_GNU_PTH. It is - used by common/estream.c. - -2005-06-01 Werner Koch - - * configure.ac (gl_INIT): Add gnulib stuff. - (fseeko, ftello, ttyname, isascii): Replaced the AC_REPLACE_FUNCS - by a simple check. - (putc_unlocked): Removed check. Not used. - (strsep, mkdtemp, asprintf): Replaced checks by gnulib checks. - (xsize): Added will probably come handy soon. - (CFLAGS): Use -Wformat-security instead of - -Wformat-nonliteral. Add --Wno-format-y2k. - * gl/, gl/m4/: New. - -2005-05-15 Werner Koch - - * configure.ac: Remove option --disable-threads; require the use - of GNU Pth. - -2005-04-27 Werner Koch - - * configure.ac: Removed OpenSC detection and options. - * acinclude.m4: Ditto. - -2005-04-21 Werner Koch - - Released 1.9.16. - - * configure.ac: Do not build gpg by default. - -2005-04-20 Werner Koch - - * configure.ac: Test whether GPG_ERR_LOCKED is declared and - provide a replacement if not. - -2005-04-15 Werner Koch - - * configure.ac: Require libksba 0.9.11. - -2005-04-15 Marcus Brinkmann - - * configure.ac: Check for /usr/bin/shred and define SHRED. - - * configure.ac: Add --enable-symcryptrun, disabled by default. - Define automake variable BUILD_SYMCRYPTRUN. - Check for openpty -lutil, define LIBUTIL_LIBS. - -2005-03-03 Werner Koch - - * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): Accidently used - --ldflags instead of --cflags. Reported by Kazu Yamamoto. - -2005-02-03 Werner Koch - - * AUTHORS: Copied from 1.4 and edited to refelct the changes in - 1.9. - -2005-01-17 Werner Koch - - * configure.ac: Make --without-included-regex work as expected. - Fixed FTP location info for some libraries. - -2005-01-13 Werner Koch - - Released 1.9.15. - - * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): Link a simple test - program to see whether the installation is sane. - -2005-01-07 Werner Koch - - * configure.ac: Require gpg-error 1.0. - -2005-01-04 Werner Koch - - * configure.ac: Remove hack not to build gpg2 for W32. - * autogen.sh : Pass option --disable-gpg instead. - -2004-12-22 Werner Koch - - Released 1.9.14. - -2004-12-20 Werner Koch - - * configure.ac: Add PATHSEP_C and PATHSEP_S. For W32 let all - directories default to c:/gnupg. Require libassuan 0.6.9. - -2004-12-18 Werner Koch - - * configure.ac (AH_BOTTOM): Define EXEEXT_S. - - * autogen.sh: Updated --build-w32 feature. - -2004-12-15 Werner Koch - - * Makefile.am (SUBDIRS) [W32]: Do not build in tests/. - - * acinclude.m4: Add proper macro name quoting for use with - automake 1.9. - - * configure.ac: Add replacement check for ttyname. - Removed support for a included zlib. - -2004-12-06 Werner Koch - - * configure.ac (have_w32_system): New. Disable Pth checks for W32. - Link jnlib/w32-pth.h to pth.h. - -2004-12-03 Werner Koch - - Released 1.9.13. - -2004-11-26 Werner Koch - - * configure.ac: Replace strsep. Replaced use of "target" by - "host". - -2004-10-22 Werner Koch - - Released 1.9.12. - - * Makefile.am (AUTOMAKE_OPTIONS): Set option to create bzip2 tarball. - -2004-10-01 Werner Koch - - Released 1.9.11. - -2004-09-30 Werner Koch - - * README: Minor updates. - -2004-09-30 gettextize - - * configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.14.1. - -2004-08-16 Werner Koch - - * configure.ac: Build Makefile for tests/pkits. New option - --with-pkits-tests. - -2004-08-05 Werner Koch - - * configure.ac: Changed tests for libusb to also suuport the - stable version 0.1.x. - -2004-07-22 Werner Koch - - Released 1.9.10. - - * configure.ac: Define AM conditional HAVE_OPENSC. - -2004-07-21 Werner Koch - - * configure.ac: Don't set DIE to no after it might has been set to - yes. - -2004-07-20 Werner Koch - - * Makefile.am (sm): Build kbx only if gpgsm is to be build. - -2004-07-20 Werner Koch - - * configure.ac: New option --enable-agent-only. - -2004-06-08 Werner Koch - - Released 1.9.9. - -2004-06-06 Werner Koch - - * configure.ac: Require libksba 0.9.7. - -2004-04-29 Werner Koch - - Released 1.9.8. - -2004-04-20 Werner Koch - - * configure.ac: Remove the fopencookie test. We don't need the - dummy function because we conditionally use fopencookie, - fpencookie or a replacement at place. - -2004-04-02 Thomas Schwinge - - * autogen.sh: Added ACLOCAL_FLAGS. - -2004-04-06 Werner Koch - - Released 1.9.7. - - * configure.ac: Require libgcrypt 1.1.94. - Introduce PACKAGE_GT and set it to gnupg2. - -2004-03-23 Werner Koch - - * configure.ac: Define SAFE_VERSION_DASH and SAFE_VERSION_DOT. - -2004-03-09 Werner Koch - - * configure.ac (NEED_GPG_ERROR_VERSION): Set to 0.7. - -2004-03-06 Werner Koch - - Released 1.9.6. - - * configure.ac: Check the Libgcrypt API. - -2004-02-25 Werner Koch - - * configure.ac: New option --disable-threads to inhibit - unintentional builds without Pth. - -2004-02-21 Werner Koch - - Released 1.9.5. - -2004-02-20 Werner Koch - - * configure.ac: Fixed URLs in the notice messages. - -2004-02-18 Werner Koch - - * acinclude.m4: Removed macros to detect gpg-error, libgcrypt, - libassuan and ksba as they are now distributed in m4/. - -2004-02-13 Werner Koch - - * configure.ac: Require libksba 0.9.4 and libgcrypt 1.1.92. - -2004-02-12 Werner Koch - - * autogen.sh: Removed cruft from debugging. - - * am/cmacros.am: New. - -2004-02-11 Werner Koch - - * configure.ac: Removed the need for g10defs.h. Reworked the - --with-foo-pgm stuff. - - * autogen.sh (check_version): Removed bashism and simplified. - * acinclude.m4 (AM_PATH_OPENSC): Kludge to avoid error output for - a bad opensc-config. - -2004-01-30 Werner Koch - - Released 1.9.4. - - * configure.ac: Require libksba 0.9.3 due to another bug fix there. - -2004-01-29 Werner Koch - - * README: Updated. - - * configure.ac: Require libksba 0.9.2 due to bug fixes. - -2004-01-24 Werner Koch - - * configure.ac: Now requires libassuan 0.6.3. - -2003-12-23 Werner Koch - - Released 1.9.3. - - * README-alpha: Removed. - * configure.ac, Makefile.am: Add the tests and tools directories. - -2003-12-19 Werner Koch - - * configure.ac: Now require libgcrypt 1.1.91 to help testing the - latest libgcrypt changes. Requires libksab 0.9.1. - -2003-12-17 Werner Koch - - * configure.ac: Requires now libassuan 0.6.2. - (CFLAGS): Add --Wformat-noliteral in gcc mode. - -2003-12-16 Werner Koch - - * configure.ac: Check for funopen and fopencookie as part of the - jnlib checks. - -2003-12-09 Werner Koch - - * configure.ac: Add a min_automake_version. - * README.CVS: New. - * autogen.sh: Revamped except for the --build-w32 hack. - * Makefile.am: Add README.CVS - -2003-11-17 Werner Koch - - Release 1.9.2. - - * configure.ac: Requires now libassuan 0.6.1. - -2003-10-31 Werner Koch - - * configure.ac (NEED_KSBA_VERSION): Set to 0.9.0 due the changed - time interface. - -2003-10-21 Werner Koch - - * configure.ac (PRINTABLE_OS_NAME): Remove special case for The - Hurd; Robert Millan reported that the uname test is now - sufficient. - -2003-10-01 Werner Koch - - * configure.ac (AH_BOTTOM): Define GNUPG_MAJOR_VERSION. - -2003-09-23 Werner Koch - - Merged most of David Shaw's changes in 1.3 since 2003-06-03. - - * configure.ac: Drop all TIGER/192 support. - (uint64_t): Check for UINT64_C to go along with uint64_t. - (getaddrinfo): Check for it. - (sigset_t): Check for sigset_t and struct sigaction. This is for - Forte c89 on Solaris which seems to define only the function call - half of the two pairs by default. - (W32LIBS): Include wsock32 in W32LIBS. This is different from - NETLIBS so we don't need to force other platforms to pull in the - netlibs when they aren't actually needed. - -2003-09-06 Werner Koch - - Released 1.9.1. - - * configure.ac: Require newer versions of some libraries. - -2003-09-02 Werner Koch - - * configure.ac (HAVE_LIBUSB): Added a simple test for libusb. - -2003-08-19 Marcus Brinkmann - - * configure.ac (AM_PATH_GPG_ERROR): Add missing comma in - invocation. - -2003-08-06 Werner Koch - - * configure.ac: Check for libgpg-error. Print infos about missing - libraries more nicely. - * acinclude.m4 (AM_PATH_GPG_ERROR): Added. - -2003-08-05 Werner Koch - - Released 1.9.0. - - * configure.ac (GNUPG_DEFAULT_HONMEDIR): Changed back to ~/.gnupg. - -2003-07-31 Werner Koch - - * Makefile.am (DISTCLEANFILES): Add g10defs.h - -2003-06-18 Werner Koch - - * configure.ac (GNUPG_DEFAULT_HOMEDIR): Changed temporary to - .gnupg2 to avoid accidential use with production keys. - -2003-06-11 Werner Koch - - * configure.ac: Merged all stuff from current 1.3 version in. - * acinclude.m4: Merged required macros from current 1.2 version in. - -2003-06-04 Werner Koch - - * configure.ac, Makefile.am: Enable building of gpg. - -2003-04-29 Werner Koch - - * configure.ac: Build a limited version of scdaemon if libopensc - is not available. - - * configure.ac (ALL_LINUGAS): Removed. - - * Makefile.am (ACLOCAL_AMFLAGS): New. - * configure.ac (AM_GNU_GETTEXT_VERSION): New. Set to 0.11.5. - -2003-04-29 gettextize - - * Makefile.am (SUBDIRS): Add m4. - (ACLOCAL_AMFLAGS): New variable. - (EXTRA_DIST): Add scripts/config.rpath. - * configure.ac (AC_CONFIG_FILES): Add m4/Makefile. - -2003-04-29 Werner Koch - - * assuan/ : Removed. We now use libassuan. - * Makefile.am (SUBDIRS): Removed assuan - - * configure.ac: Check for libassuan. - -2003-01-09 Werner Koch - - * configure.ac (GNUPG_PROTECT_TOOL): New option --with-protect-tool. - (NEED_KSBA_VERSION): Does now require 0.4.6. - - * README: Noted where to find gpg-protect-tool. - -2002-10-31 Neal H. Walfield - - * configure.ac: Check for flockfile and funlockfile. Check for - isascii and putc_unlocked replacing them if not found. - - * configure.ac (PTH_LIBS): If pth is found, add the output of - `$PTH_CONFIG --ldflags`, not just `$PTH_CONFIG --libs`. - -2002-10-19 Werner Koch - - * configure.ac: Bumped version number to 1.9.0-cvs. - - NewPG (Aegypten project) to GnuPG merge. - -2002-09-20 Werner Koch - - Released 0.9.2. - -2002-09-05 Neal H. Walfield - - * configure.ac: Check for makeinfo. - -2002-09-03 Neal H. Walfield - - * autogen.sh (have_version): New function. Generalize and - simplify logic for finding and determining the versions of GNU - programs. Use it. - -2002-08-23 Werner Koch - - Released 0.9.1. - - * acinclude.m4 (AM_PATH_LIBGCRYPT): Updated from Libgcrypt. - (AM_PATH_OPENSC): Strip non-digits from the micro version. - -2002-08-21 Werner Koch - - Released 0.9.0. - - * configure.ac: Changed the default homedir to .gnupg. - * README-alpha: Removed. - -2002-08-19 Werner Koch - - * acinclude.m4: Removed -lpcsclite from KSBA_LIBS; copy+paste bug. - -2002-08-13 Werner Koch - - * acinclude.m4 (AM_PATH_OPENSC, AM_PATH_KSBA): New. - * configure.ac: Use them. - -2002-08-10 Werner Koch - - Released 0.3.10. - - * configure.ac (NEED_LIBKSBA_VERSION): Require 0.4.4. Add support - for gettext. - -2002-07-22 Werner Koch - - * configure.ac: Check for ftello and provide a replacement. - -2002-07-01 Werner Koch - - Released 0.3.9. - - * README: Short note on how to export in pkcs-12 format. - -2002-06-29 Werner Koch - - * configure.ac: Define --with options to set the default location - of the agent, scdaemon, pinentry and dirmngr. - -2002-06-27 Werner Koch - - * README: Short blurb on how to import a PKCS-12 file. - - * configure.ac (AH_BOTTOM): New to define some constants. - -2002-06-25 Werner Koch - - Released 0.3.8. - - * configure.ac (NEED_LIBGCRYPT_VERSION): Set to 1.1.8. - -2002-06-12 Werner Koch - - * configure.ac (NEED_LIBKSBA_VERSION): We need 0.4.3 now. - -2002-06-04 Werner Koch - - Released 0.3.7. - -2002-05-21 Werner Koch - - * configure.ac: We now require libgcrypt 1.1.7 and libksba 0.4.2. - -2002-05-14 Werner Koch - - * doc/: New - * configure.ac, Makefile.am: Added doc/. - -2002-05-03 Werner Koch - - Released 0.3.6. - -2002-04-25 Werner Koch - - * configure.ac: Check for setlocale. - -2002-04-24 Marcus Brinkmann - - * configure.ac: Check for locale.h. - -2002-04-15 Werner Koch - - Released 0.3.5. - - * NEWS: Started to describe release notes. - - * configure.ac (NEED_LIBKSBA_VERSION, NEED_LIBGCRYPT_VERSION): Defined - -2002-04-01 Werner Koch - - Released 0.3.4. - -2002-03-18 Werner Koch - - Released 0.3.3. - -2002-03-08 Werner Koch - - * README: Add some explanation on how to specify a user ID. - -2002-03-06 Werner Koch - - Released 0.3.2. - -2002-03-04 Werner Koch - - Released 0.3.1. - - * README: Explained some options and files. - -2002-02-14 Werner Koch - - * configure.ac: Fixed status messages related to presence of Pth. - -2002-02-13 Werner Koch - - * acinclude.m4 (GNUPG_SYS_SO_PEERCRED): New. - * configure.ac: use it. - -2002-02-12 Werner Koch - - * configure.ac: Check for PTH. Provide replacement fucntions for - apsrintf and fopencookie. - - * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): New. - -2002-02-07 Werner Koch - - Released 0.3.0. - - * configure.ac: Require libgcrypt 1.1.6. - -2002-02-01 Marcus Brinkmann - - * configure.ac (KSBA_CONFIG): Remove superfluous x in front of - variable. - -2002-01-26 Werner Koch - - * configure.ac: Add options to disable the build of some programs - and print a configure status at the end. - * acinclude.m4 (GNUPG_BUILD_PROGRAM): New. - - * scd/ : New. Added to Makefile and configure. - * configure.ac: Check for libopensc - * Makefile.am: Build scd only when libopensc is available - -2002-01-23 Werner Koch - - * configure.ac (mkdtemp): See whether we have to provide a - replacement. - -2001-12-18 Werner Koch - - Released 0.0.0. - -2001-12-17 Werner Koch - - * acinclude.m4: Add AM_PATH_LIBGCRYPT macro. - * configure.ac: and use it here. Figure out the location of libksba - -2001-12-15 Werner Koch - - * configure.ac (missing_dir): Bail out if asprintf and fopencookie - are not available. - -2001-12-04 Werner Koch - - * configure.ac (HAVE_JNLIB_LOGGING): always define it. - - - Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007. - 2010 Free Software Foundation, Inc. - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +Local Variables: +buffer-read-only: t +mode: text +End: diff --git a/ChangeLog-2011 b/ChangeLog-2011 new file mode 100644 index 000000000..cfba8f473 --- /dev/null +++ b/ChangeLog-2011 @@ -0,0 +1,1394 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + +2011-11-29 Werner Koch + + * autogen.sh: Make sure HOME et al have no unsafe characters. + +2011-11-28 Jim Meyering + + accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix + * m4/gpg-error.m4: Update from git master. + +2011-09-23 Werner Koch + + * configure.ac: Remove check for gcry_kdf_derive. + +2011-08-10 Werner Koch + + * configure.ac: Fix new autoconf warnings. + +2011-05-20 Werner Koch + + * configure.ac: Require libgpg-error 1.10. + +2011-03-08 Werner Koch + + Release 2.1.0beta2. + + * configure.ac: Require libgcrypt 1.5.0. + (HAVE_GCRY_PK_ECDH, HAVE_GCRY_PK_GET_CURVE): Remove. + (utmp.h): Check for header. + +2011-02-25 Werner Koch + + * configure.ac: Require libksba 1.2. + +2011-02-04 Werner Koch + + * autogen.sh: Ensure that the git pre-commit hoom has been + enabled. Add a cleanpo filter if not yet set. + +2011-02-03 Werner Koch + + * configure.ac (HAVE_GCRY_PK_GET_CURVE): Use AC_TRY_LINK. + +2011-02-01 Werner Koch + + * configure.ac (HAVE_GCRY_PK_GET_CURVE): Define if availabale. + +2011-01-20 Werner Koch + + * configure.ac (AC_CONFIG_FILES): Remove keyserver/. + +2011-01-19 Werner Koch + + * configure.ac: Add new option --enable-gpg2-is-gpg. + (NAME_OF_INSTALLED_GPG): New ac_define. + * autogen.sh [--build-w32ce]: Use --enable-gpg2-is-gpg. + +2011-01-21 Werner Koch + + * configure.ac: Need Libgcrypt 1.4.6 due to AESWRAP. + (HAVE_GCRY_PK_ECDH): Add new test. + +2011-01-03 Werner Koch + + * README.SVN: Rename to README.GIT. + * Makefile.am (EXTRA_DIST): Adjust for that change. + +2010-12-14 Werner Koch + + * configure.ac (BUILD_WITH_GPG, BUILD_WITH_GPGSM) + (BUILD_WITH_AGENT, BUILD_WITH_SCDAEMON, BUILD_WITH_DIRMNGR) + (BUILD_WITH_G13): New defines. + +2010-11-23 Werner Koch + + * am/cmacros.am (extra_bin_ldflags): New. For W32CE set the stack + size to 256k. + +2010-11-17 Werner Koch + + * configure.ac (ENABLE_CARD_SUPPORT): Define. + +2010-10-27 Werner Koch + + * acinclude.m4 (GNUPG_TIME_T_UNSIGNED): New. + * configure.ac (AC_HEADER_TIME): Include before checking time_t. + (GNUPG_TIME_T_UNSIGNED): Add. + +2010-10-26 Werner Koch + + Release 2.1.0beta1. + +2010-10-18 Werner Koch + + * Makefile.am (install-data-hook): Add W32 specific hook. + +2010-10-08 Werner Koch + + * configure.ac: Add option --enable-dirmngr-auto-start. + (USE_DIRMNGR_AUTO_START): New ac_define. + * autogen.sh <--build-w32ce>: Use new option. + +2010-10-06 Werner Koch + + * configure.ac: Make --enable-standard-socket the default. + +2010-10-04 Werner Koch + + * configure.ac (GNUPG_CHECK_FAQPROG): Remove. + +2010-08-19 Werner Koch + + * configure.ac (AH_BOTTOM): Define GPG_ERR_ENABLE_ERRNO_MACROS. + +2010-08-09 Werner Koch + + * configure.ac (inet_pton): Check for it. + +2010-08-05 Werner Koch + + * configure.ac (AH_BOTTOM): Remove HTTP_USE_ESTREAM. + +2010-08-02 Werner Koch + + * configure.ac: Require libksba 1.1.0 due to the use of + ksba_reader_set_release_notify. + +2010-07-30 Werner Koch + + * configure.ac (GNUPG_PTH_PATH) [W32]: Require version 2.0.3. + +2010-07-25 Werner Koch + + * configure.ac (USE_LDAPWRAPPER): AC_DEFINE and AM_CONDITIONAL it. + +2010-06-09 Werner Koch + + * configure.ac (GNUPG_DIRMNGR_LDAP_PGM): Add option + --with-dirmngr-ldap-pgm. + + * am/cmacros.am (-DGNUPG_LOCALSTATEDIR): New. + (GNUPG_DEFAULT_DIRMNGR_LDAP): New. + +2010-06-08 Werner Koch + + * configure.ac: Add build support for dirmngr. + (try_ldap): Rename to try_ks_ldap. + (GNUPG_CHECK_LDAP): Also test if dirmngr is to be build. + + * Makefile.am (SUBDIRS): Add dirmngr. + +2010-06-07 Werner Koch + + * dirmngr/: New. + + * configure.ac: Add option --enable-gpgtar. + +2010-05-31 Werner Koch + + * configure.ac (AC_CHECK_FUNCS): Check for lstat. + +2010-04-30 Werner Koch + + * configure.ac: Add option --enable-standard-socket. + (USE_STANDARD_SOCKET): ac_define it. + +2010-04-14 Werner Koch + + * Makefile.am (keyserver) [W32CE]: Do not build for now. + + * configure.ac (use_zip): New. + (--disable-zip): New option. + (HAVE_ZIP): New. + * autogen.sh : Disable ZIP. + +2010-04-07 Werner Koch + + * autogen.sh: Take a .gnupg-autogen.rc file in account. + + * gl/mkdtemp.c (getpid) [W32CE]: New macro. + +2010-03-24 Werner Koch + + * configure.ac (AH_BOTTOM): Use /gnupg as the default homedir on + dosish systems which don't support drive letters (e.g. W32CE). + + * am/cmacros.am (extra_sys_libs): New. + +2010-03-23 Werner Koch + + * configure.ac (W32SOCKLIBS): Change value for W32CE. + +2010-03-12 Werner Koch + + * configure.ac (AC_INIT): Prepare for using git. + +2010-03-10 Werner Koch + + * jnlib/: Move all code to common/. + * Makefile.am (SUBDIRS): Remove jnlib. + * configure.ac (AC_CONFIG_FILES): Remove jnlib/Makefile. + + * configure.ac (AM_PATH_LIBASSUAN): Remove double test. + * acinclude.m4 (GNUPG_CHECK_ENDIAN): Remove bogus warning. + +2010-03-09 Werner Koch + + * configure.ac: Add option --disable-ccid-driver. + (AH_BOTTOM): Define GPG_ERR_ENABLE_GETTEXT_MACROS. + +2010-02-26 Werner Koch + + * gl/mkdtemp.c (__set_errno) [W32CE]: Use gpg_err_set_errno. + * gl/setenv.c (__set_errno) [W32CE]: Ditto. + * gl/unsetenv.c (__set_errno) [W32CE]: Ditto. + + * configure.ac (HAVE_W32CE_SYSTEM): New ac_define and + am_conditional. + (signal.h, getenv): Check for them. + + * autogen.sh: New option --build-w32ce. Remove obsolete option + --without-included-gettext. + +2009-12-08 Werner Koch + + * configure.ac (USE_DNS_CERT): Support ADNS. + +2009-12-07 Werner Koch + + * configure.ac: Check for ADNS before checking for the BIND + resolver. + (USE_ADNS): Fallback macro for PKA and CERT lookups. + +2009-10-20 Marcus Brinkmann + + * configure.ac: Check for fusermount and encfs. + +2009-10-16 Marcus Brinkmann + + * configure.ac: Check for libassuan instead of libassuan-pth. + +2009-10-12 Werner Koch + + * configure.ac: Use -O3 because newer gcc versions require that + for uninitialized variable warnings. + +2009-09-23 Werner Koch + + * configure.ac (HAVE_ASSUAN_SET_IO_MONITOR): Remove test. + (_ASSUAN_ONLY_GPG_ERRORS): Remove. + +2009-09-23 Marcus Brinkmann + + * configure.ac (NEED_LIBASSUAN_API, NEED_LIBASSUAN_VERSION): + Update to new API (2, 1.1.0). + +2009-09-21 Werner Koch + + Start a new development branch in the SVN trunk. The stable one + is now known in the SVN as branches/GNUPG-STABLE-2-0. + +2009-09-04 Werner Koch + + Release 2.0.13. + +2009-06-29 Werner Koch + + * configure.ac: Take care of --without-adns. Suggested by + Arfrever Frehtes Taifersar Arahesis. + +2009-06-17 Werner Koch + + Release 2.0.12. + +2009-06-05 David Shaw + + * configure.ac: Remove Camellia restriction. + +2009-04-01 Werner Koch + + * configure.ac: Test for fsync. + +2009-03-18 Werner Koch + + * configure.ac: Test for getrlimit. + +2009-03-03 Werner Koch + + Release 2.0.11. + +2009-01-12 Werner Koch + + Release 2.0.10. + +2008-12-09 Werner Koch + + Release 2.0.10rc1. + +2008-10-17 Werner Koch + + * configure.ac: Use more warning options with modern GCCs. + +2008-09-29 Werner Koch + + * configure.ac: Require libgcrypt 1.4. + +2008-08-27 David Shaw + + * configure.ac: Use printf for the most portable SVN version + detection. + + * configure.ac: Darwin's /bin/sh has a builtin echo that doesn't + understand '-n'. Use tr to trim the carriage return instead. + +2008-04-23 Werner Koch + + * configure.ac: Call gl_HEADER_SYS_SOCKET and gl_TYPE_SOCKLEN_T. + +2008-04-07 Werner Koch + + * configure.ac (ADNSLIBS): Test for adns. + (GPGKEYS_KDNS): New. + +2008-04-01 Werner Koch + + * configure.ac: Require curl 7.10 (Oct 1 2002) or later as we use + curl_version_info(). + (AC_INIT): Fix quoting. + +2008-03-27 Werner Koch + + * Makefile.am (dist_doc_DATA): New. Install README. + +2008-03-26 Werner Koch + + Release 2.0.9. + +2008-02-19 Werner Koch + + * configure.ac: Remove --with-pkits-tests. + +2008-02-15 Werner Koch + + * gl/allocsa.h, gl/m4/allocsa.m4: Replace HAVE_LONG_LONG by + HAVE_LONG_LONG_INT. + +2008-02-15 gettextize + + * configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.17. + +2007-12-20 Werner Koch + + Released 2.0.8. + +2007-12-17 Werner Koch + + * configure.ac: Add treatment for HAVE_LDAP_START_TLS_SA. + +2007-12-14 Werner Koch + + Released 2.0.8rc1. + +2007-12-12 Werner Koch + + * configure.ac (USE_CAMELLIA): Define by new option --enable-camellia. + +2007-12-03 Werner Koch + + * configure.ac: Add test gt_LC_MESSAGES.. + +2007-10-01 Werner Koch + + * configure.ac: Require assuan 1.0.4. + +2007-09-14 Werner Koch + + * configure.ac (GNUPG_LIBASSUAN_VERSION): New. + +2007-09-10 Werner Koch + + Released 2.0.7. + +2007-08-27 Werner Koch + + * configure.ac: Remove remaining support for internal regex. + Define DISABLE_REGEX automake conditional. Add option + --with-regex. + * autogen.sh [--build-w32]: Remove --disable-regex. Use --with-regex. + +2007-08-16 Werner Koch + + Released 2.0.6. + +2007-08-08 Werner Koch + + * configure.ac: Use AC_CANONICAL_HOST and not AC_CANONICAL_TARGET. + +2007-07-09 Werner Koch + + * configure.ac (AM_ICONV): Check for it even when building without + NLS. + +2007-07-05 Werner Koch + + Released 2.0.5. + + * configure.ac: Require libassuan 1.0.2. + +2007-07-05 Marcus Brinkmann + + * configure.ac: Invoke AM_LANGINFO_CODESET. + +2007-07-04 Werner Koch + + * Makefile.am (AUTOMAKE_OPTIONS): Add no-dist-gzip. + + Switched entire package to GPLv3+. + + * configure.ac: Require libksba 1.0.2. + + * COPYING: Updated to GPLv3. + * COPYING.LIB: New as jnlib/ uses this license. + + * gl/: Switched to GPLv3+. + + * intl/ Removed. + * configure.ac (AM_GNU_GETTEXT): Add external flag. + (AM_ICONV): New. + +2007-07-03 Werner Koch + + * configure.ac [W32]: Use ws2_32 instead of wsock32. + +2007-06-25 Werner Koch + + * gl/mkdtemp.c (gen_tempname) [MKDIR_TAKES_ONE_ARG]: Avoid + compiler warning by using the proper config macro. + +2007-06-15 Werner Koch + + * configure.ac: Call AM_PO_SUBDIRS. + (W32SOCKLIBS): New. + + * autogen.sh: Use = and not == in test to be POSIXly correct. + : Disable use of regex. + +2007-06-14 Werner Koch + + * configure.ac [AH_BOTTOM]: Remove the hardwired names of modules. + +2007-06-12 Werner Koch + + * configure.ac [AH_BOTTOM]: Define HTTP_NO_WSASTARTUP. + +2007-06-11 Werner Koch + + * am/cmacros.am (libcommonstd, libcommonpth, libcommonstd_ldadd) + (libcommonpth_ldadd): Add macros. + +2007-06-06 Werner Koch + + * configure.ac: Add a few notices message so make browsing of the + log file easier. + (CC_FOR_BUILD): New. + +2007-05-30 Werner Koch + + * configure.ac [W32]: Do not create a symlink to w32-pth.h. + Require the installation of the w32pth package. + +2007-05-29 Werner Koch + + * gl/: Updated to a newer version. + +2007-05-24 Werner Koch + + * configure.ac: Use -Wpointer-arith is possible. + +2007-05-15 Werner Koch + + * configure.ac: Renamed the estream macros. Remove -Wformat-nonliteral. + + * configure.ac: Call ESTREAM_INIT and define the memory + allocators for estream_asprintf. + (gl_MODULES): Remove vasprintf. + +2007-05-09 Werner Koch + + Released 2.0.4. + +2007-05-07 Werner Koch + + * configure.ac: Require libgcrypt 1.2.2 to avoid compiler warnings. + +2007-05-07 gettextize + + * configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.16.1. + +2007-05-07 Werner Koch + + * configure.ac: Bail out if no C-89 compiler has been found. + +2007-05-04 Werner Koch + + * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Add --enable-mailto + + * configure.ac: Require automake 1.10 + (AC_CONFIG_FILES): Rename gpgkeys_ to gpg2keys_. + (AM_PROG_CC_C_O): New. + +2007-03-08 Werner Koch + + Released 2.0.3. + + * autogen.sh: Add option --force. + +2007-01-31 Werner Koch + + Released 2.0.2. + +2006-11-30 Werner Koch + + * configure.ac: Save original LIBS when testing for dlopen. + +2006-11-28 Werner Koch + + Released 2.0.1. + +2006-11-23 Werner Koch + + Released 2.0.1rc1. + +2006-11-21 Werner Koch + + * configure.ac [AH_BOTTOM]: Disable PTH soft mapping. + (AC_CHECK_SIZEOF): Check for time_t. + (BUILD_INCLUDED_LIBINTL): Remove AM_PO_SUBDIRS as it is not + required for C. + +2006-11-15 Werner Koch + + * autogen.sh: Add convenience option --build-amd64. + +2006-11-14 Werner Koch + + * configure.ac (HAVE_ASSUAN_SET_IO_MONITOR): Test for it. + +2006-11-11 Werner Koch + + Released 2.0.0. + +2006-11-06 Werner Koch + + Released 1.9.95. + +2006-11-03 Werner Koch + + * configure.ac: Test for pty.h. From Gentoo. + +2006-10-24 Werner Koch + + Released 1.9.94. + +2006-10-20 Werner Koch + + * Makefile.am (stowinstall): Add convenience target. + +2006-10-18 Werner Koch + + * configure.ac: svn revison magic fixes for old bashs. Suggested + by Alain Guibert. + +2006-10-18 Werner Koch + + Released 1.9.93. + +2006-10-17 Werner Koch + + * autogen.sh <--build-w32>: Test also for a host "mingw32". + + * configure.ac: Removed W32LIBS. Use NETLIBS instead. + +2006-10-11 Werner Koch + + Released 1.9.92. + + * configure.ac: Require libassuan 0.9.3. + +2006-10-09 Werner Koch + + * acinclude.m4: Moved pth check to m4/gnupg-pth.m4. + +2006-10-06 Werner Koch + + * configure.ac: Also check for libassuan's pth version. + +2006-10-04 Werner Koch + + Released 1.9.91. + + * configure.ac: Require libassuan 0.9.1 which fixes a problem with + gpgsm. + +2006-09-27 Werner Koch + + * gl/strsep.h, gl/strsep.c, gl/m4/strsep.m4: Removed. + * gl/strpbrk.h, gl/strpbrk.c, gl/m4/strpbrk.m4: Removed. + * gl/Makefile.am: Removed module strsep and strpbrk. + * configure.ac: Check for strsep in the context of jnlib. Remove + check from gl_MODULES. Moved check for timegm into the jnlib context. + +2006-09-27 Marcus Brinkmann + + * Makefile.am: Fix cut & paste error. + +2006-09-25 Werner Koch + + Released 1.9.90. + +2006-09-22 Werner Koch + + * AUTHORS: Add information about used licenses. + +2006-09-20 Werner Koch + + * Makefile.am (dist-hook): Removed distfiles cruft. + (SUBDIRS): Added include + +2006-09-18 Werner Koch + + Released 1.9.23. + + * configure.ac (--enable-agent-only): Donot build tools and doc + (--disable-tools,--disable-doc): New. + * Makefile.am (SUBDIRS): Allow to conditional build tools and doc. + +2006-09-14 Werner Koch + + Replaced all call gpg_error_from_errno(errno) by + gpg_error_from_syserror(). + + * configure.ac: Build gpg by default. + (GNUPG_SYS_SO_PEERCRED): Removed. + +2006-09-13 Werner Koch + + * autogen.sh: Better detection of the cross compiler kit. + +2006-09-06 Marcus Brinkmann + + * configure.ac: New automake conditional RUN_GPG_TESTS. + +2006-09-06 Werner Koch + + * configure.ac: Define _ASSUAN_ONLY_GPG_ERRORS. Require Assuan + 0.9 and libgpg-error 1.4. + +2006-08-31 Werner Koch + + * configure.ac: Require libksba 1.0 and added API check for it. + (GPG_ERR_LOCKED): Removed DECL check as we require 1.2 anyway. + (have_libusb): New to give a feedback about CCID support + +2006-08-21 Werner Koch + + * configure.ac: Removed docbook tests. + (AC_CONFIG_FILES): Added gpgkeys_test and gpgkeys_mailto. + + * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Enable gpg. + +2006-08-17 Werner Koch + + * THANKS: Merged with the 1.4 one. + +2006-08-16 Werner Koch + + * configure.ac: Removed test for capabilities and mlock. + +2006-08-15 Werner Koch + + * Makefile.am (keyserver): Enable building of keyserver helpers. + + * configure.ac: Merged with the current configure from 1.4.5. + Require libgpg-error 1.2 and libksba 0.9.16. + +2006-07-29 Marcus Brinkmann + + * README: Spelling fixes. + +2006-07-27 Werner Koch + + Released 1.9.22. + + * configure.ac: Call AB_INIT. + +2006-07-03 Werner Koch + + * configure.ac: Test for ksba_dn_teststr. + +2006-06-30 Werner Koch + + * keyserver/: New. Taken from 1.4.4 + * Makefile.am (SUBDIRS): Include keyserver/. + * configure.ac: Include keyserver/. + (FAKE_CURL, GPGKEYS_CURL): New. + +2006-06-20 Werner Koch + + Released 1.9.21. + +2006-06-08 Marcus Brinkmann + + * configure.ac (PTH_LIBS): Add --all to pth-config invocation. + +2006-05-24 Werner Koch + + * configure.ac: New option --disable-optimization taked from 1.4.3. + +2006-05-23 Werner Koch + + * configure.ac (ZLIBS): New for zlib link commands. Add bzip2 + support. + +2006-05-22 Werner Koch + + * configure.ac (EXEEXT): New. + +2006-04-18 Werner Koch + + * configure.ac (PK_UID_CACHE_SIZE): New. + +2006-04-07 Werner Koch + + * configure.ac: Use new method to include the SVN revison. Now it + is the actual global revision number. + +2005-12-20 Werner Koch + + Released 1.9.20. + +2005-11-28 Werner Koch + + * configure.ac: Append the revision to the version string. + +2005-11-13 Werner Koch + + * am/cmacros.am (-DGNUPG_SYSCONFDIR): Define it. + +2005-11-11 Werner Koch + + * configure.ac (NEED_KSBA_VERSION: Require 0.9.13. + +2005-09-12 Werner Koch + + Released 1.9.19. + +2005-08-01 Werner Koch + + Released 1.9.18. + + * configure.ac: Require libksba 0.9.12 to match new features in gpgsm. + +2005-06-20 Werner Koch + + Released 1.9.17. + +2005-06-02 Werner Koch + + * configure.ac (HAVE_PTH): Define as alias for USE_GNU_PTH. It is + used by common/estream.c. + +2005-06-01 Werner Koch + + * configure.ac (gl_INIT): Add gnulib stuff. + (fseeko, ftello, ttyname, isascii): Replaced the AC_REPLACE_FUNCS + by a simple check. + (putc_unlocked): Removed check. Not used. + (strsep, mkdtemp, asprintf): Replaced checks by gnulib checks. + (xsize): Added will probably come handy soon. + (CFLAGS): Use -Wformat-security instead of + -Wformat-nonliteral. Add --Wno-format-y2k. + * gl/, gl/m4/: New. + +2005-05-15 Werner Koch + + * configure.ac: Remove option --disable-threads; require the use + of GNU Pth. + +2005-04-27 Werner Koch + + * configure.ac: Removed OpenSC detection and options. + * acinclude.m4: Ditto. + +2005-04-21 Werner Koch + + Released 1.9.16. + + * configure.ac: Do not build gpg by default. + +2005-04-20 Werner Koch + + * configure.ac: Test whether GPG_ERR_LOCKED is declared and + provide a replacement if not. + +2005-04-15 Werner Koch + + * configure.ac: Require libksba 0.9.11. + +2005-04-15 Marcus Brinkmann + + * configure.ac: Check for /usr/bin/shred and define SHRED. + + * configure.ac: Add --enable-symcryptrun, disabled by default. + Define automake variable BUILD_SYMCRYPTRUN. + Check for openpty -lutil, define LIBUTIL_LIBS. + +2005-03-03 Werner Koch + + * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): Accidently used + --ldflags instead of --cflags. Reported by Kazu Yamamoto. + +2005-02-03 Werner Koch + + * AUTHORS: Copied from 1.4 and edited to refelct the changes in + 1.9. + +2005-01-17 Werner Koch + + * configure.ac: Make --without-included-regex work as expected. + Fixed FTP location info for some libraries. + +2005-01-13 Werner Koch + + Released 1.9.15. + + * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): Link a simple test + program to see whether the installation is sane. + +2005-01-07 Werner Koch + + * configure.ac: Require gpg-error 1.0. + +2005-01-04 Werner Koch + + * configure.ac: Remove hack not to build gpg2 for W32. + * autogen.sh : Pass option --disable-gpg instead. + +2004-12-22 Werner Koch + + Released 1.9.14. + +2004-12-20 Werner Koch + + * configure.ac: Add PATHSEP_C and PATHSEP_S. For W32 let all + directories default to c:/gnupg. Require libassuan 0.6.9. + +2004-12-18 Werner Koch + + * configure.ac (AH_BOTTOM): Define EXEEXT_S. + + * autogen.sh: Updated --build-w32 feature. + +2004-12-15 Werner Koch + + * Makefile.am (SUBDIRS) [W32]: Do not build in tests/. + + * acinclude.m4: Add proper macro name quoting for use with + automake 1.9. + + * configure.ac: Add replacement check for ttyname. + Removed support for a included zlib. + +2004-12-06 Werner Koch + + * configure.ac (have_w32_system): New. Disable Pth checks for W32. + Link jnlib/w32-pth.h to pth.h. + +2004-12-03 Werner Koch + + Released 1.9.13. + +2004-11-26 Werner Koch + + * configure.ac: Replace strsep. Replaced use of "target" by + "host". + +2004-10-22 Werner Koch + + Released 1.9.12. + + * Makefile.am (AUTOMAKE_OPTIONS): Set option to create bzip2 tarball. + +2004-10-01 Werner Koch + + Released 1.9.11. + +2004-09-30 Werner Koch + + * README: Minor updates. + +2004-09-30 gettextize + + * configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.14.1. + +2004-08-16 Werner Koch + + * configure.ac: Build Makefile for tests/pkits. New option + --with-pkits-tests. + +2004-08-05 Werner Koch + + * configure.ac: Changed tests for libusb to also suuport the + stable version 0.1.x. + +2004-07-22 Werner Koch + + Released 1.9.10. + + * configure.ac: Define AM conditional HAVE_OPENSC. + +2004-07-21 Werner Koch + + * configure.ac: Don't set DIE to no after it might has been set to + yes. + +2004-07-20 Werner Koch + + * Makefile.am (sm): Build kbx only if gpgsm is to be build. + +2004-07-20 Werner Koch + + * configure.ac: New option --enable-agent-only. + +2004-06-08 Werner Koch + + Released 1.9.9. + +2004-06-06 Werner Koch + + * configure.ac: Require libksba 0.9.7. + +2004-04-29 Werner Koch + + Released 1.9.8. + +2004-04-20 Werner Koch + + * configure.ac: Remove the fopencookie test. We don't need the + dummy function because we conditionally use fopencookie, + fpencookie or a replacement at place. + +2004-04-02 Thomas Schwinge + + * autogen.sh: Added ACLOCAL_FLAGS. + +2004-04-06 Werner Koch + + Released 1.9.7. + + * configure.ac: Require libgcrypt 1.1.94. + Introduce PACKAGE_GT and set it to gnupg2. + +2004-03-23 Werner Koch + + * configure.ac: Define SAFE_VERSION_DASH and SAFE_VERSION_DOT. + +2004-03-09 Werner Koch + + * configure.ac (NEED_GPG_ERROR_VERSION): Set to 0.7. + +2004-03-06 Werner Koch + + Released 1.9.6. + + * configure.ac: Check the Libgcrypt API. + +2004-02-25 Werner Koch + + * configure.ac: New option --disable-threads to inhibit + unintentional builds without Pth. + +2004-02-21 Werner Koch + + Released 1.9.5. + +2004-02-20 Werner Koch + + * configure.ac: Fixed URLs in the notice messages. + +2004-02-18 Werner Koch + + * acinclude.m4: Removed macros to detect gpg-error, libgcrypt, + libassuan and ksba as they are now distributed in m4/. + +2004-02-13 Werner Koch + + * configure.ac: Require libksba 0.9.4 and libgcrypt 1.1.92. + +2004-02-12 Werner Koch + + * autogen.sh: Removed cruft from debugging. + + * am/cmacros.am: New. + +2004-02-11 Werner Koch + + * configure.ac: Removed the need for g10defs.h. Reworked the + --with-foo-pgm stuff. + + * autogen.sh (check_version): Removed bashism and simplified. + * acinclude.m4 (AM_PATH_OPENSC): Kludge to avoid error output for + a bad opensc-config. + +2004-01-30 Werner Koch + + Released 1.9.4. + + * configure.ac: Require libksba 0.9.3 due to another bug fix there. + +2004-01-29 Werner Koch + + * README: Updated. + + * configure.ac: Require libksba 0.9.2 due to bug fixes. + +2004-01-24 Werner Koch + + * configure.ac: Now requires libassuan 0.6.3. + +2003-12-23 Werner Koch + + Released 1.9.3. + + * README-alpha: Removed. + * configure.ac, Makefile.am: Add the tests and tools directories. + +2003-12-19 Werner Koch + + * configure.ac: Now require libgcrypt 1.1.91 to help testing the + latest libgcrypt changes. Requires libksab 0.9.1. + +2003-12-17 Werner Koch + + * configure.ac: Requires now libassuan 0.6.2. + (CFLAGS): Add --Wformat-noliteral in gcc mode. + +2003-12-16 Werner Koch + + * configure.ac: Check for funopen and fopencookie as part of the + jnlib checks. + +2003-12-09 Werner Koch + + * configure.ac: Add a min_automake_version. + * README.CVS: New. + * autogen.sh: Revamped except for the --build-w32 hack. + * Makefile.am: Add README.CVS + +2003-11-17 Werner Koch + + Release 1.9.2. + + * configure.ac: Requires now libassuan 0.6.1. + +2003-10-31 Werner Koch + + * configure.ac (NEED_KSBA_VERSION): Set to 0.9.0 due the changed + time interface. + +2003-10-21 Werner Koch + + * configure.ac (PRINTABLE_OS_NAME): Remove special case for The + Hurd; Robert Millan reported that the uname test is now + sufficient. + +2003-10-01 Werner Koch + + * configure.ac (AH_BOTTOM): Define GNUPG_MAJOR_VERSION. + +2003-09-23 Werner Koch + + Merged most of David Shaw's changes in 1.3 since 2003-06-03. + + * configure.ac: Drop all TIGER/192 support. + (uint64_t): Check for UINT64_C to go along with uint64_t. + (getaddrinfo): Check for it. + (sigset_t): Check for sigset_t and struct sigaction. This is for + Forte c89 on Solaris which seems to define only the function call + half of the two pairs by default. + (W32LIBS): Include wsock32 in W32LIBS. This is different from + NETLIBS so we don't need to force other platforms to pull in the + netlibs when they aren't actually needed. + +2003-09-06 Werner Koch + + Released 1.9.1. + + * configure.ac: Require newer versions of some libraries. + +2003-09-02 Werner Koch + + * configure.ac (HAVE_LIBUSB): Added a simple test for libusb. + +2003-08-19 Marcus Brinkmann + + * configure.ac (AM_PATH_GPG_ERROR): Add missing comma in + invocation. + +2003-08-06 Werner Koch + + * configure.ac: Check for libgpg-error. Print infos about missing + libraries more nicely. + * acinclude.m4 (AM_PATH_GPG_ERROR): Added. + +2003-08-05 Werner Koch + + Released 1.9.0. + + * configure.ac (GNUPG_DEFAULT_HONMEDIR): Changed back to ~/.gnupg. + +2003-07-31 Werner Koch + + * Makefile.am (DISTCLEANFILES): Add g10defs.h + +2003-06-18 Werner Koch + + * configure.ac (GNUPG_DEFAULT_HOMEDIR): Changed temporary to + .gnupg2 to avoid accidential use with production keys. + +2003-06-11 Werner Koch + + * configure.ac: Merged all stuff from current 1.3 version in. + * acinclude.m4: Merged required macros from current 1.2 version in. + +2003-06-04 Werner Koch + + * configure.ac, Makefile.am: Enable building of gpg. + +2003-04-29 Werner Koch + + * configure.ac: Build a limited version of scdaemon if libopensc + is not available. + + * configure.ac (ALL_LINUGAS): Removed. + + * Makefile.am (ACLOCAL_AMFLAGS): New. + * configure.ac (AM_GNU_GETTEXT_VERSION): New. Set to 0.11.5. + +2003-04-29 gettextize + + * Makefile.am (SUBDIRS): Add m4. + (ACLOCAL_AMFLAGS): New variable. + (EXTRA_DIST): Add scripts/config.rpath. + * configure.ac (AC_CONFIG_FILES): Add m4/Makefile. + +2003-04-29 Werner Koch + + * assuan/ : Removed. We now use libassuan. + * Makefile.am (SUBDIRS): Removed assuan + + * configure.ac: Check for libassuan. + +2003-01-09 Werner Koch + + * configure.ac (GNUPG_PROTECT_TOOL): New option --with-protect-tool. + (NEED_KSBA_VERSION): Does now require 0.4.6. + + * README: Noted where to find gpg-protect-tool. + +2002-10-31 Neal H. Walfield + + * configure.ac: Check for flockfile and funlockfile. Check for + isascii and putc_unlocked replacing them if not found. + + * configure.ac (PTH_LIBS): If pth is found, add the output of + `$PTH_CONFIG --ldflags`, not just `$PTH_CONFIG --libs`. + +2002-10-19 Werner Koch + + * configure.ac: Bumped version number to 1.9.0-cvs. + + NewPG (Aegypten project) to GnuPG merge. + +2002-09-20 Werner Koch + + Released 0.9.2. + +2002-09-05 Neal H. Walfield + + * configure.ac: Check for makeinfo. + +2002-09-03 Neal H. Walfield + + * autogen.sh (have_version): New function. Generalize and + simplify logic for finding and determining the versions of GNU + programs. Use it. + +2002-08-23 Werner Koch + + Released 0.9.1. + + * acinclude.m4 (AM_PATH_LIBGCRYPT): Updated from Libgcrypt. + (AM_PATH_OPENSC): Strip non-digits from the micro version. + +2002-08-21 Werner Koch + + Released 0.9.0. + + * configure.ac: Changed the default homedir to .gnupg. + * README-alpha: Removed. + +2002-08-19 Werner Koch + + * acinclude.m4: Removed -lpcsclite from KSBA_LIBS; copy+paste bug. + +2002-08-13 Werner Koch + + * acinclude.m4 (AM_PATH_OPENSC, AM_PATH_KSBA): New. + * configure.ac: Use them. + +2002-08-10 Werner Koch + + Released 0.3.10. + + * configure.ac (NEED_LIBKSBA_VERSION): Require 0.4.4. Add support + for gettext. + +2002-07-22 Werner Koch + + * configure.ac: Check for ftello and provide a replacement. + +2002-07-01 Werner Koch + + Released 0.3.9. + + * README: Short note on how to export in pkcs-12 format. + +2002-06-29 Werner Koch + + * configure.ac: Define --with options to set the default location + of the agent, scdaemon, pinentry and dirmngr. + +2002-06-27 Werner Koch + + * README: Short blurb on how to import a PKCS-12 file. + + * configure.ac (AH_BOTTOM): New to define some constants. + +2002-06-25 Werner Koch + + Released 0.3.8. + + * configure.ac (NEED_LIBGCRYPT_VERSION): Set to 1.1.8. + +2002-06-12 Werner Koch + + * configure.ac (NEED_LIBKSBA_VERSION): We need 0.4.3 now. + +2002-06-04 Werner Koch + + Released 0.3.7. + +2002-05-21 Werner Koch + + * configure.ac: We now require libgcrypt 1.1.7 and libksba 0.4.2. + +2002-05-14 Werner Koch + + * doc/: New + * configure.ac, Makefile.am: Added doc/. + +2002-05-03 Werner Koch + + Released 0.3.6. + +2002-04-25 Werner Koch + + * configure.ac: Check for setlocale. + +2002-04-24 Marcus Brinkmann + + * configure.ac: Check for locale.h. + +2002-04-15 Werner Koch + + Released 0.3.5. + + * NEWS: Started to describe release notes. + + * configure.ac (NEED_LIBKSBA_VERSION, NEED_LIBGCRYPT_VERSION): Defined + +2002-04-01 Werner Koch + + Released 0.3.4. + +2002-03-18 Werner Koch + + Released 0.3.3. + +2002-03-08 Werner Koch + + * README: Add some explanation on how to specify a user ID. + +2002-03-06 Werner Koch + + Released 0.3.2. + +2002-03-04 Werner Koch + + Released 0.3.1. + + * README: Explained some options and files. + +2002-02-14 Werner Koch + + * configure.ac: Fixed status messages related to presence of Pth. + +2002-02-13 Werner Koch + + * acinclude.m4 (GNUPG_SYS_SO_PEERCRED): New. + * configure.ac: use it. + +2002-02-12 Werner Koch + + * configure.ac: Check for PTH. Provide replacement fucntions for + apsrintf and fopencookie. + + * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): New. + +2002-02-07 Werner Koch + + Released 0.3.0. + + * configure.ac: Require libgcrypt 1.1.6. + +2002-02-01 Marcus Brinkmann + + * configure.ac (KSBA_CONFIG): Remove superfluous x in front of + variable. + +2002-01-26 Werner Koch + + * configure.ac: Add options to disable the build of some programs + and print a configure status at the end. + * acinclude.m4 (GNUPG_BUILD_PROGRAM): New. + + * scd/ : New. Added to Makefile and configure. + * configure.ac: Check for libopensc + * Makefile.am: Build scd only when libopensc is available + +2002-01-23 Werner Koch + + * configure.ac (mkdtemp): See whether we have to provide a + replacement. + +2001-12-18 Werner Koch + + Released 0.0.0. + +2001-12-17 Werner Koch + + * acinclude.m4: Add AM_PATH_LIBGCRYPT macro. + * configure.ac: and use it here. Figure out the location of libksba + +2001-12-15 Werner Koch + + * configure.ac (missing_dir): Bail out if asprintf and fopencookie + are not available. + +2001-12-04 Werner Koch + + * configure.ac (HAVE_JNLIB_LOGGING): always define it. + + + Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007. + 2010 Free Software Foundation, Inc. + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/Makefile.am b/Makefile.am index 23edae4e3..292748abc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,9 +20,12 @@ ACLOCAL_AMFLAGS = -I m4 -I gl/m4 AUTOMAKE_OPTIONS = dist-bzip2 no-dist-gzip -DISTCHECK_CONFIGURE_FLAGS = --enable-symcryptrun --enable-mailto +DISTCHECK_CONFIGURE_FLAGS = --enable-symcryptrun --enable-mailto --enable-gpgtar -EXTRA_DIST = scripts/config.rpath scripts/potomo autogen.sh README.GIT +EXTRA_DIST = scripts/config.rpath scripts/potomo autogen.sh README.GIT \ + ChangeLog-2011 po/ChangeLog-2011 scripts/ChangeLog-2011 \ + scripts/gitlog-to-changelog \ + scripts/git-log-fix scripts/git-log-footer DISTCLEANFILES = g10defs.h if BUILD_GPGSM @@ -90,7 +93,7 @@ SUBDIRS = m4 gl include common ${kbx} \ dist_doc_DATA = README -dist-hook: +dist-hook: gen-ChangeLog echo "$(VERSION)" > $(distdir)/VERSION if HAVE_W32_SYSTEM @@ -106,5 +109,20 @@ install-data-hook: done endif + +gen_start_date = 2011-12-01T06:00:00 +.PHONY: gen-ChangeLog +gen-ChangeLog: + if test -d $(top_srcdir)/.git; then \ + (cd $(top_srcdir) && \ + ./scripts/gitlog-to-changelog \ + --amend=scripts/git-log-fix \ + --since=$(gen_start_date) ) > $(distdir)/cl-t; \ + cat $(top_srcdir)/scripts/git-log-footer >> $(distdir)/cl-t; \ + rm -f $(distdir)/ChangeLog; \ + mv $(distdir)/cl-t $(distdir)/ChangeLog; \ + fi + + stowinstall: $(MAKE) $(AM_MAKEFLAGS) install prefix=/usr/local/stow/gnupg diff --git a/agent/ChangeLog b/agent/ChangeLog-2011 similarity index 99% rename from agent/ChangeLog rename to agent/ChangeLog-2011 index 26355794f..f56be1f44 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-11-28 Werner Koch * command-ssh.c (card_key_available): Change wording of no key @@ -1524,7 +1531,7 @@ 2006-09-14 Werner Koch - Replaced all call gpg_error_from_errno(errno) by + Replaced all call gpg_error_from_errno(errno) by gpg_error_from_syserror(). * call-pinentry.c (start_pinentry): Replaced pipe_connect2 by @@ -3094,3 +3101,7 @@ Fri Aug 18 14:27:14 CEST 2000 Werner Koch This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/agent/Makefile.am b/agent/Makefile.am index f3fb4eaa9..00b7d43c9 100644 --- a/agent/Makefile.am +++ b/agent/Makefile.am @@ -25,7 +25,8 @@ libexec_PROGRAMS += gpg-preset-passphrase endif noinst_PROGRAMS = $(TESTS) -# EXTRA_DIST = gpg-agent.ico gpg-agent-resource.rc +EXTRA_DIST = ChangeLog-2011 + AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common -I$(top_srcdir)/intl diff --git a/common/ChangeLog b/common/ChangeLog-2011 similarity index 99% rename from common/ChangeLog rename to common/ChangeLog-2011 index 96e4e31a2..7fed0a742 100644 --- a/common/ChangeLog +++ b/common/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-11-30 Werner Koch Rewrite dns-cert.c to not use the gpg-only iobuf stuff. @@ -2481,3 +2488,7 @@ This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/common/ChangeLog.jnlib b/common/ChangeLog.jnlib index f51525e42..4ac02f3c2 100644 --- a/common/ChangeLog.jnlib +++ b/common/ChangeLog.jnlib @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2010-03-10 Werner Koch See gnupg/common/ChangeLog for newer changes. @@ -767,3 +774,7 @@ Mon Jan 24 13:04:28 CET 2000 Werner Koch This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/common/Makefile.am b/common/Makefile.am index 7821e0442..bb996bab7 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -18,7 +18,7 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = mkstrtable.awk exaudit.awk exstatus.awk \ +EXTRA_DIST = mkstrtable.awk exaudit.awk exstatus.awk ChangeLog-2011 \ audit-events.h status-codes.h README.jnlib ChangeLog.jnlib noinst_LIBRARIES = libcommon.a libcommonpth.a libgpgrl.a diff --git a/dirmngr/ChangeLog b/dirmngr/ChangeLog-2011 similarity index 99% rename from dirmngr/ChangeLog rename to dirmngr/ChangeLog-2011 index 0968b411c..84cf55288 100644 --- a/dirmngr/ChangeLog +++ b/dirmngr/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-11-24 Werner Koch * ks-engine-http.c (ks_http_help): Do not print help for hkp. @@ -1589,3 +1596,7 @@ This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/dirmngr/ChangeLog.1 b/dirmngr/ChangeLog.1 index 6d7a513e2..f7b50c7a1 100644 --- a/dirmngr/ChangeLog.1 +++ b/dirmngr/ChangeLog.1 @@ -800,3 +800,7 @@ There are old Dirmngr ChangeLog entries. ldapsearch -v -x -h www.trustcenter.de -b '' userCertificate -t cp /tmp/ testcert.der ./test-dirmngr + +Local Variables: +buffer-read-only: t +End: diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index 6c45681ab..e90daa41c 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -19,7 +19,7 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = OAUTHORS ONEWS ChangeLog.1 +EXTRA_DIST = OAUTHORS ONEWS ChangeLog.1 ChangeLog-2011 bin_PROGRAMS = dirmngr dirmngr-client diff --git a/doc/ChangeLog b/doc/ChangeLog-2011 similarity index 98% rename from doc/ChangeLog rename to doc/ChangeLog-2011 index 17c58ecd4..b830c0e11 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-10-12 Werner Koch * gpg.texi: Add a bunch of opindex items. @@ -858,3 +865,7 @@ This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/doc/HACKING b/doc/HACKING index 07f09c56b..d6cb8ab4c 100644 --- a/doc/HACKING +++ b/doc/HACKING @@ -3,7 +3,30 @@ (Some notes on GNUPG internals.) - ===> Under construction <======= +* No more ChangeLog files + +Do not modify any of the ChangeLog files in GnuPG. Starting on +December 1st, 2011 we put change information only in the GIT commit +log, and generate a top-level ChangeLog file from logs at "make dist" +time. As such, there are strict requirements on the form of the +commit log messages. The old ChangeLog files have all be renamed to +ChangeLog-2011 + + +* Commit log requirements + +Your commit log should always start with a one-line summary, the second +line should be blank, and the remaining lines are usually ChangeLog-style +entries for all affected files. However, it's fine -- even recommended -- +to write a few lines of prose describing the change, when the summary +and ChangeLog entries don't give enough of the big picture. Omit the +leading TABs that you're used to seeing in a "real" ChangeLog file, but +keep the maximum line length at 72 or smaller, so that the generated +ChangeLog lines, each with its leading TAB, will not exceed 80 columns. + + + +===> What follows is probably out of date <=== RFCs @@ -63,7 +86,7 @@ g10/keydb.h g10/keyid.c Helper functions to get the keyid, fingerprint etc. -g10/trustdb.c +g10/trustdb.c g10/trustdb.h g10/tdbdump.c Management of the trustdb.gpg @@ -74,7 +97,7 @@ g10/delkey.c Delete a key g10/kbnode.c Helper for the KBNODE linked list g10/main.h Prototypes and some constants g10/mainproc.c Message processing -g10/armor.c Ascii armor filter +g10/armor.c Ascii armor filter g10/mdfilter.c Filter to calculate hashs g10/textfilter.c Filter to handle CR/LF and trailing white space g10/cipher.c En-/Decryption filter @@ -88,7 +111,7 @@ g10/hkp.h Keyserver access g10/hkp.c g10/packet.h Defintion of OpenPGP structures. g10/passphrase.c Passphrase handling code -g10/pubkey-enc.c +g10/pubkey-enc.c g10/seckey-cert.c g10/seskey.c g10/import.c diff --git a/doc/Makefile.am b/doc/Makefile.am index f9fd00857..e228f2306 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -34,7 +34,7 @@ EXTRA_DIST = samplekeys.asc \ gnupg-card-architecture.pdf \ FAQ gnupg7.texi \ opt-homedir.texi see-also-note.texi specify-user-id.texi \ - gpgv.texi texi.css yat2m.c + gpgv.texi texi.css yat2m.c ChangeLog-2011 BUILT_SOURCES = gnupg-card-architecture.eps gnupg-card-architecture.png \ gnupg-card-architecture.pdf diff --git a/g10/ChangeLog b/g10/ChangeLog-2011 similarity index 99% rename from g10/ChangeLog rename to g10/ChangeLog-2011 index 4dadaabcc..31359d8c5 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-11-30 Werner Koch * keyserver.c (keyserver_import_cert): Adjust for changed @@ -2398,8 +2405,8 @@ * status.h (STATUS_ERROR): New status code. * status.c (get_status_string): Ditto. * mainproc.c (proc_plaintext): Emit it if multiple messages are - detected. Error out if more than one plaintext packet is - encountered. + detected. Error out if more than one plaintext packet is + encountered. * mainproc.c (literals_seen): New. 2007-02-26 Werner Koch @@ -2735,7 +2742,7 @@ 2006-09-14 Werner Koch - Replaced all call gpg_error_from_errno(errno) by + Replaced all call gpg_error_from_errno(errno) by gpg_error_from_syserror(). 2006-09-13 Werner Koch @@ -4804,7 +4811,7 @@ * tdbio.c (MY_O_BINARY): Need binary mode with Cygwin. From Werner on stable branch. - * g10.c, gpgv.c (main) [__CYGWIN32__]: Don't get the homedir from + * g10.c, gpgv.c (main) [__CYGWIN32__]: Don't get the homedir from the registry. From Werner on stable branch. * keyedit.c (show_key_with_all_names_colon): Make --with-colons @@ -8265,7 +8272,7 @@ (pk_from_block): Removed the namehash arg and changed all callers. (merge_selfsigs): Copy prefs to all keys. * trustdb.c (get_pref_data): Removed. - (is_algo_in_prefs): Removed. + (is_algo_in_prefs): Removed. (make_pref_record): Deleted and removed all class. * pkclist.c (select_algo_from_prefs): Adjusted for the new preference implementation. @@ -12053,3 +12060,7 @@ Thu Feb 12 22:24:42 1998 Werner Koch (wk@frodo) This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/g10/Makefile.am b/g10/Makefile.am index 56d5d10a4..e9f69b34d 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -18,7 +18,7 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = options.skel +EXTRA_DIST = options.skel ChangeLog-2011 AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common \ -I$(top_srcdir)/include -I$(top_srcdir)/intl diff --git a/g13/ChangeLog b/g13/ChangeLog deleted file mode 100644 index ecd72226b..000000000 --- a/g13/ChangeLog +++ /dev/null @@ -1,3 +0,0 @@ -2009-11-04 Werner Koch - - Under initial development - no need for a ChangeLog. diff --git a/g13/ChangeLog-2011 b/g13/ChangeLog-2011 new file mode 100644 index 000000000..5d372c23f --- /dev/null +++ b/g13/ChangeLog-2011 @@ -0,0 +1,14 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + +2009-11-04 Werner Koch + + Under initial development - no need for a ChangeLog. + +Local Variables: +buffer-read-only: t +End: diff --git a/g13/Makefile.am b/g13/Makefile.am index a8ae9eb25..b846dcda8 100644 --- a/g13/Makefile.am +++ b/g13/Makefile.am @@ -18,6 +18,8 @@ ## Process this file with automake to produce Makefile.in +EXTRA_DIST = ChangeLog-2011 + bin_PROGRAMS = g13 AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common diff --git a/include/ChangeLog b/include/ChangeLog-2011 similarity index 97% rename from include/ChangeLog rename to include/ChangeLog-2011 index 09d5b6e99..c4b44870b 100644 --- a/include/ChangeLog +++ b/include/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-02-01 Werner Koch * cipher.h (PUBKEY_MAX_NPKEY, PUBKEY_MAX_NSKEY): Bump up to @@ -442,3 +449,7 @@ Tue Mar 3 15:11:21 1998 Werner Koch (wk@isil.d.shuttle.de) This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/include/Makefile.am b/include/Makefile.am index 09176ded2..4d733ba91 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1 +1 @@ -EXTRA_DIST = cipher.h types.h host2net.h _regex.h +EXTRA_DIST = cipher.h types.h host2net.h _regex.h ChangeLog-2011 diff --git a/kbx/ChangeLog b/kbx/ChangeLog-2011 similarity index 96% rename from kbx/ChangeLog rename to kbx/ChangeLog-2011 index 9e77118a5..7641f532f 100644 --- a/kbx/ChangeLog +++ b/kbx/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-04-28 Werner Koch * keybox-openpgp.c: Include ../common/openpgpdefs.h. @@ -160,7 +167,7 @@ 2006-09-14 Werner Koch - Replaced all call gpg_error_from_errno(errno) by + Replaced all call gpg_error_from_errno(errno) by gpg_error_from_syserror(). 2005-10-08 Marcus Brinkmann @@ -383,3 +390,7 @@ This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/keyserver/ChangeLog b/keyserver/ChangeLog-2011 similarity index 98% rename from keyserver/ChangeLog rename to keyserver/ChangeLog-2011 index cc42a6426..01cca41c3 100644 --- a/keyserver/ChangeLog +++ b/keyserver/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-01-20 Werner Koch * gpgkeys_hkp.c (get_name): Remove test for KS_GETNAME. It is @@ -92,7 +99,7 @@ * curl-shim.c (curl_easy_init) [HAVE_W32_SYSTEM]: Call it. * gpgkeys_finger.c: s/_WIN32/HAVE_W32_SYSTEM/. (init_sockets): Remove. - (connect_server) [HAVE_W32_SYSTEM]: Call new function. + (connect_server) [HAVE_W32_SYSTEM]: Call new function. 2008-04-14 David Shaw @@ -105,7 +112,7 @@ 2008-04-07 Werner Koch * gpgkeys_kdns.c: New. - * Makefile.am: Support kdns. + * Makefile.am: Support kdns. * no-libgcrypt.c (gcry_strdup): Fix. It was not used. @@ -117,7 +124,7 @@ 2007-10-25 David Shaw (wk) From 1.4 (July): - + * gpgkeys_ldap.c (main): Fix bug in setting up whether to verify peer SSL cert. This used to work with older OpenLDAP, but is now more strictly handled. @@ -229,7 +236,7 @@ to OpenSSL. This is considered a bug fix and forgives all possible violations, pertaining to this issue, possibly occured in the past. - + * no-libgcrypt.c: Changed license to a simple all permissive one. * Makefile.am (gpg2keys_ldap_LDADD): For license reasons do not @@ -245,7 +252,7 @@ mismatch. 2006-09-19 Werner Koch - + * no-libgcrypt.c: New. Taken from ../tools. * Makefile.am: Add no-libgcrypt to all sources. @@ -714,7 +721,7 @@ 2004-10-28 Werner Koch - * Makefile.am (other_libs): + * Makefile.am (other_libs): 2004-10-18 David Shaw @@ -1346,3 +1353,7 @@ This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/keyserver/Makefile.am b/keyserver/Makefile.am index fd046cfc0..884b8eb2d 100644 --- a/keyserver/Makefile.am +++ b/keyserver/Makefile.am @@ -1,5 +1,5 @@ # Makefile.am - Makefile for keyservers -# Copyright (C) 2001, 2002, 2004, 2005, 2006, +# Copyright (C) 2001, 2002, 2004, 2005, 2006, # 2009 Free Software Foundation, Inc. # # This file is part of GnuPG. @@ -8,12 +8,12 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. -# +# # GnuPG is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, see . ## Process this file with automake to produce Makefile.in @@ -26,7 +26,9 @@ EXTRA_PROGRAMS = gpg2keys_ldap gpg2keys_hkp gpg2keys_finger gpg2keys_curl \ gpg2keys_kdns EXTRA_SCRIPTS = gpg2keys_mailto -AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common -I$(top_srcdir)/intl +EXTRA_DIST = ChangeLog-2011 + +AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common -I$(top_srcdir)/intl AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) @@ -62,11 +64,11 @@ if FAKE_CURL gpg2keys_curl_SOURCES += curl-shim.c curl-shim.h gpg2keys_curl_CPPFLAGS = $(AM_CPPFLAGS) gpg2keys_curl_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \ - $(other_libs) + $(other_libs) gpg2keys_hkp_SOURCES += curl-shim.c curl-shim.h gpg2keys_hkp_CPPFLAGS = $(AM_CPPFLAGS) gpg2keys_hkp_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \ - $(other_libs) + $(other_libs) else # Note that we need to include all other libs here as well because # some compilers don't care about inline functions and insert diff --git a/m4/ChangeLog b/m4/ChangeLog-2011 similarity index 93% rename from m4/ChangeLog rename to m4/ChangeLog-2011 index b13bd4f20..d466275a2 100644 --- a/m4/ChangeLog +++ b/m4/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-09-12 Werner Koch * libcurl.m4: Fix lost hash sign introduced by previous change. @@ -162,3 +169,7 @@ * uintmax_t.m4: New file, from gettext-0.11.5. * ulonglong.m4: New file, from gettext-0.11.5. * Makefile.am: New file. + +Local Variables: +buffer-read-only: t +End: diff --git a/m4/Makefile.am b/m4/Makefile.am index d0d84e23d..f94c0c1b2 100644 --- a/m4/Makefile.am +++ b/m4/Makefile.am @@ -12,7 +12,4 @@ EXTRA_DIST += estream.m4 EXTRA_DIST += sys_socket_h.m4 socklen.m4 - - - - +EXTRA_DIST += ChangeLog-2011 diff --git a/po/ChangeLog b/po/ChangeLog-2011 similarity index 95% rename from po/ChangeLog rename to po/ChangeLog-2011 index e4e560d07..3615b749a 100644 --- a/po/ChangeLog +++ b/po/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-05-12 Marcus Brinkmann * cs.po: Merge in dirmngr cs.po. Hope I got that right. @@ -184,7 +191,7 @@ package name mangling breaks make distcheck as it tries to rebuild the po file with the "correct" name. The upshot is never to use GNU in you po directory. - + * de.po: Fix a few fuzzy entries and translate new strings. 2007-07-04 Werner Koch @@ -308,7 +315,6 @@ * POTFILES.in: New. * de.po: New. - Copyright 2002, 2003, 2004, 2005, 2009 Free Software Foundation, Inc. This file is free software; as a special exception the author gives @@ -318,5 +324,7 @@ This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - +Local Variables: +buffer-read-only: t +End: diff --git a/po/de.po b/po/de.po index 51d7e03fd..fe83f7979 100644 --- a/po/de.po +++ b/po/de.po @@ -111,8 +111,8 @@ msgstr "Fehler beim Holen der Karten-Seriennummer: %s\n" msgid "detected card with S/N: %s\n" msgstr "Erkannte Karte hat die Seriennummer: %s\n" -#, c-format -msgid "error getting default authentication keyID of card: %s\n" +#, fuzzy, c-format +msgid "no authentication key for ssh on card: %s\n" msgstr "Fehler beim Holen der Authentisierungsschlüssel-ID der Karte: %s\n" #, c-format @@ -131,7 +131,9 @@ msgstr "Fehler beim Schreiben des Schlüssels: %s\n" msgid "" "An ssh process requested the use of key%%0A %s%%0A (%s)%%0ADo you want to " "allow this?" -msgstr "Ein SSH Processs möchte folgenden Schlüssel verwenden:%%0A %s%%0A (%s)%%0AErlauben Sie dies?" +msgstr "" +"Ein SSH Processs möchte folgenden Schlüssel verwenden:%%0A %s%%0A (%s)%%" +"0AErlauben Sie dies?" msgid "Allow" msgstr "Erlauben" @@ -141,7 +143,9 @@ msgstr "Verweigern" #, c-format msgid "Please enter the passphrase for the ssh key%%0A %F%%0A (%c)" -msgstr "Bitte geben Sie die Passphrase für den SSH-Schlüssel%%0A %F%%0A (%c)%%0Aein." +msgstr "" +"Bitte geben Sie die Passphrase für den SSH-Schlüssel%%0A %F%%0A (%c)%%" +"0Aein." msgid "Please re-enter this passphrase" msgstr "Bitte geben Sie die Passphrase noch einmal ein:" @@ -152,7 +156,8 @@ msgid "" "s%%0Awithin gpg-agent's key storage" msgstr "" "Bitte geben Sie eine Passphrase ein, um den empfangenen geheimen\n" -"Schlüssel%%0A %s%%0A %s%%0Aim Schlüsselspeicher des Gpg-Agenten zu schützen." +"Schlüssel%%0A %s%%0A %s%%0Aim Schlüsselspeicher des Gpg-Agenten zu " +"schützen." msgid "does not match - try again" msgstr "Keine Ãœbereinstimmung - bitte nochmal versuchen." @@ -5429,6 +5434,18 @@ msgstr "|AN|Neue Admin-PIN" msgid "|N|New PIN" msgstr "|N|Neue PIN" +#, fuzzy +msgid "||Please enter the Reset Code for the card and New PIN" +msgstr "Bitte geben Sie den Rückstellcode für diese Karte ein" + +#, fuzzy +msgid "||Please enter the Admin PIN and New Admin PIN" +msgstr "|A|Bitte die Admin-PIN eingeben." + +#, fuzzy +msgid "||Please enter the PIN and New PIN" +msgstr "||Bitte die PIN eingeben" + msgid "error reading application data\n" msgstr "Fehler beim Lesen der Anwendungsdaten\n" diff --git a/scd/ChangeLog b/scd/ChangeLog-2011 similarity index 99% rename from scd/ChangeLog rename to scd/ChangeLog-2011 index 80cddec49..9184af4c5 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-12-01 Niibe Yutaka * app-openpgp.c (do_change_pin): Fix pincb messages when @@ -1092,7 +1099,7 @@ 2006-09-14 Werner Koch - Replaced all call gpg_error_from_errno(errno) by + Replaced all call gpg_error_from_errno(errno) by gpg_error_from_syserror(). * command.c (scd_command_handler): Replaced @@ -2579,3 +2586,7 @@ This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/scd/Makefile.am b/scd/Makefile.am index 9153a4403..bdd457acd 100644 --- a/scd/Makefile.am +++ b/scd/Makefile.am @@ -17,6 +17,8 @@ ## Process this file with automake to produce Makefile.in +EXTRA_DIST = ChangeLog-2011 + bin_PROGRAMS = scdaemon if ! HAVE_W32_SYSTEM libexec_PROGRAMS = gnupg-pcsc-wrapper diff --git a/scripts/ChangeLog b/scripts/ChangeLog-2011 similarity index 81% rename from scripts/ChangeLog rename to scripts/ChangeLog-2011 index 1a664ca68..9a3eed3b0 100644 --- a/scripts/ChangeLog +++ b/scripts/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-11-29 Werner Koch * build-all.sh: Make sure HOME has no unsafe characters. @@ -49,3 +56,7 @@ This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/scripts/git-log-fix b/scripts/git-log-fix new file mode 100644 index 000000000..af702fe6f --- /dev/null +++ b/scripts/git-log-fix @@ -0,0 +1,3 @@ +# This file is expected to be used via gitlog-to-changelog's --amend=FILE +# option. It specifies what changes to make to each given SHA1's commit +# log and metadata, using Perl-eval'able expressions. diff --git a/scripts/git-log-footer b/scripts/git-log-footer new file mode 100644 index 000000000..c31fe936a --- /dev/null +++ b/scripts/git-log-footer @@ -0,0 +1,14 @@ + +2011-12-01 Werner Koch + + NB: Changes done before December 1st, 2011 are described in + per directory files named ChangeLog-2011. See doc/HACKING for + details. + + ----- + Copyright (C) 2011 Free Software Foundation, Inc. + + Copying and distribution of this file and/or the original GIT + commit log messages, with or without modification, are + permitted provided the copyright notice and this notice are + preserved. diff --git a/scripts/gitlog-to-changelog b/scripts/gitlog-to-changelog new file mode 100755 index 000000000..40a803554 --- /dev/null +++ b/scripts/gitlog-to-changelog @@ -0,0 +1,345 @@ +eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}' + & eval 'exec perl -wS "$0" $argv:q' + if 0; +# Convert git log output to ChangeLog format. + +my $VERSION = '2011-11-02 07:53'; # UTC +# The definition above must lie within the first 8 lines in order +# for the Emacs time-stamp write hook (at end) to update it. +# If you change this file with Emacs, please let the write hook +# do its job. Otherwise, update this string manually. + +# Copyright (C) 2008-2011 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Written by Jim Meyering + +use strict; +use warnings; +use Getopt::Long; +use POSIX qw(strftime); + +(my $ME = $0) =~ s|.*/||; + +# use File::Coda; # http://meyering.net/code/Coda/ +END { + defined fileno STDOUT or return; + close STDOUT and return; + warn "$ME: failed to close standard output: $!\n"; + $? ||= 1; +} + +sub usage ($) +{ + my ($exit_code) = @_; + my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR); + if ($exit_code != 0) + { + print $STREAM "Try `$ME --help' for more information.\n"; + } + else + { + print $STREAM < ChangeLog + $ME -- -n 5 foo > last-5-commits-to-branch-foo + +In a FILE specified via --amend, comment lines (starting with "#") are ignored. +FILE must consist of pairs where SHA is a 40-byte SHA1 (alone on +a line) referring to a commit in the current project, and CODE refers to one +or more consecutive lines of Perl code. Pairs must be separated by one or +more blank line. + +Here is sample input for use with --amend=FILE, from coreutils: + +3a169f4c5d9159283548178668d2fae6fced3030 +# fix typo in title: +s/all tile types/all file types/ + +1379ed974f1fa39b12e2ffab18b3f7a607082202 +# Due to a bug in vc-dwim, I mis-attributed a patch by Paul to myself. +# Change the author to be Paul. Note the escaped "@": +s,Jim .*>,Paul Eggert , + +EOF + } + exit $exit_code; +} + +# If the string $S is a well-behaved file name, simply return it. +# If it contains white space, quotes, etc., quote it, and return the new string. +sub shell_quote($) +{ + my ($s) = @_; + if ($s =~ m![^\w+/.,-]!) + { + # Convert each single quote to '\'' + $s =~ s/\'/\'\\\'\'/g; + # Then single quote the string. + $s = "'$s'"; + } + return $s; +} + +sub quoted_cmd(@) +{ + return join (' ', map {shell_quote $_} @_); +} + +# Parse file F. +# Comment lines (starting with "#") are ignored. +# F must consist of pairs where SHA is a 40-byte SHA1 +# (alone on a line) referring to a commit in the current project, and +# CODE refers to one or more consecutive lines of Perl code. +# Pairs must be separated by one or more blank line. +sub parse_amend_file($) +{ + my ($f) = @_; + + open F, '<', $f + or die "$ME: $f: failed to open for reading: $!\n"; + + my $fail; + my $h = {}; + my $in_code = 0; + my $sha; + while (defined (my $line = )) + { + $line =~ /^\#/ + and next; + chomp $line; + $line eq '' + and $in_code = 0, next; + + if (!$in_code) + { + $line =~ /^([0-9a-fA-F]{40})$/ + or (warn "$ME: $f:$.: invalid line; expected an SHA1\n"), + $fail = 1, next; + $sha = lc $1; + $in_code = 1; + exists $h->{$sha} + and (warn "$ME: $f:$.: duplicate SHA1\n"), + $fail = 1, next; + } + else + { + $h->{$sha} ||= ''; + $h->{$sha} .= "$line\n"; + } + } + close F; + + $fail + and exit 1; + + return $h; +} + +{ + my $since_date; + my $format_string = '%s%n%b%n'; + my $amend_file; + my $append_dot = 0; + GetOptions + ( + help => sub { usage 0 }, + version => sub { print "$ME version $VERSION\n"; exit }, + 'since=s' => \$since_date, + 'format=s' => \$format_string, + 'amend=s' => \$amend_file, + 'append-dot' => \$append_dot, + ) or usage 1; + + + defined $since_date + and unshift @ARGV, "--since=$since_date"; + + # This is a hash that maps an SHA1 to perl code (i.e., s/old/new/) + # that makes a correction in the log or attribution of that commit. + my $amend_code = defined $amend_file ? parse_amend_file $amend_file : {}; + + my @cmd = (qw (git log --log-size), + '--pretty=format:%H:%ct %an <%ae>%n%n'.$format_string, @ARGV); + open PIPE, '-|', @cmd + or die ("$ME: failed to run `". quoted_cmd (@cmd) ."': $!\n" + . "(Is your Git too old? Version 1.5.1 or later is required.)\n"); + + my $prev_date_line = ''; + my @prev_coauthors = (); + while (1) + { + defined (my $in = ) + or last; + $in =~ /^log size (\d+)$/ + or die "$ME:$.: Invalid line (expected log size):\n$in"; + my $log_nbytes = $1; + + my $log; + my $n_read = read PIPE, $log, $log_nbytes; + $n_read == $log_nbytes + or die "$ME:$.: unexpected EOF\n"; + + # Extract leading hash. + my ($sha, $rest) = split ':', $log, 2; + defined $sha + or die "$ME:$.: malformed log entry\n"; + $sha =~ /^[0-9a-fA-F]{40}$/ + or die "$ME:$.: invalid SHA1: $sha\n"; + + # If this commit's log requires any transformation, do it now. + my $code = $amend_code->{$sha}; + if (defined $code) + { + eval 'use Safe'; + my $s = new Safe; + # Put the unpreprocessed entry into "$_". + $_ = $rest; + + # Let $code operate on it, safely. + my $r = $s->reval("$code") + or die "$ME:$.:$sha: failed to eval \"$code\":\n$@\n"; + + # Note that we've used this entry. + delete $amend_code->{$sha}; + + # Update $rest upon success. + $rest = $_; + } + + my @line = split "\n", $rest; + my $author_line = shift @line; + defined $author_line + or die "$ME:$.: unexpected EOF\n"; + $author_line =~ /^(\d+) (.*>)$/ + or die "$ME:$.: Invalid line " + . "(expected date/author/email):\n$author_line\n"; + + my $date_line = sprintf "%s $2\n", strftime ("%F", localtime ($1)); + + # Format 'Co-authored-by: A U Thor ' lines in + # standard multi-author ChangeLog format. + my @coauthors = grep /^Co-authored-by:.*$/, @line; + for (@coauthors) + { + s/^Co-authored-by:\s*/\t /; + s/\s*/ + or warn "$ME: warning: missing email address for " + . substr ($_, 5) . "\n"; + } + + # If this header would be the same as the previous date/name/email/ + # coauthors header, then arrange not to print it. + if ($date_line ne $prev_date_line or "@coauthors" ne "@prev_coauthors") + { + $prev_date_line eq '' + or print "\n"; + print $date_line; + @coauthors + and print join ("\n", @coauthors), "\n"; + } + $prev_date_line = $date_line; + @prev_coauthors = @coauthors; + + # Omit "Co-authored-by..." and "Signed-off-by..." lines. + @line = grep !/^Signed-off-by: .*>$/, @line; + @line = grep !/^Co-authored-by: /, @line; + + # Remove leading and trailing blank lines. + if (@line) + { + while ($line[0] =~ /^\s*$/) { shift @line; } + while ($line[$#line] =~ /^\s*$/) { pop @line; } + } + + # If there were any lines + if (@line == 0) + { + warn "$ME: warning: empty commit message:\n $date_line\n"; + } + else + { + if ($append_dot) + { + # If the first line of the message has enough room, then + if (length $line[0] < 72) + { + # append a dot if there is no other punctuation or blank + # at the end. + $line[0] =~ /[[:punct:]\s]$/ + or $line[0] .= '.'; + } + } + + # Prefix each non-empty line with a TAB. + @line = map { length $_ ? "\t$_" : '' } @line; + + print "\n", join ("\n", @line), "\n"; + } + + defined ($in = ) + or last; + $in ne "\n" + and die "$ME:$.: unexpected line:\n$in"; + } + + close PIPE + or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n"; + # FIXME-someday: include $PROCESS_STATUS in the diagnostic + + # Complain about any unused entry in the --amend=F specified file. + my $fail = 0; + foreach my $sha (keys %$amend_code) + { + warn "$ME:$amend_file: unused entry: $sha\n"; + $fail = 1; + } + + exit $fail; +} + +# Local Variables: +# mode: perl +# indent-tabs-mode: nil +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "my $VERSION = '" +# time-stamp-format: "%:y-%02m-%02d %02H:%02M" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "'; # UTC" +# End: diff --git a/sm/ChangeLog b/sm/ChangeLog-2011 similarity index 99% rename from sm/ChangeLog rename to sm/ChangeLog-2011 index a77c7a88e..4a4df8632 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-09-20 Werner Koch * verify.c (gpgsm_verify): s/gcry_md_start_debug/gcry_md_debug/ @@ -1284,7 +1291,7 @@ h2007-11-22 Werner Koch 2006-09-14 Werner Koch - Replaced all call gpg_error_from_errno(errno) by + Replaced all call gpg_error_from_errno(errno) by gpg_error_from_syserror(). 2006-09-13 Werner Koch @@ -2955,3 +2962,7 @@ h2007-11-22 Werner Koch This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/sm/Makefile.am b/sm/Makefile.am index 89b553809..e8dfe0571 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -17,6 +17,7 @@ ## Process this file with automake to produce Makefile.in +EXTRA_DIST = ChangeLog-2011 bin_PROGRAMS = gpgsm diff --git a/tests/ChangeLog b/tests/ChangeLog-2011 similarity index 92% rename from tests/ChangeLog rename to tests/ChangeLog-2011 index aa93f0780..972dbf597 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-09-20 Jim Meyering avoid use of free'd pointer @@ -139,3 +146,7 @@ This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/tests/Makefile.am b/tests/Makefile.am index 70b5fe270..2142d33d6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -37,7 +37,7 @@ TESTS_ENVIRONMENT = GNUPGHOME=`/bin/pwd` GPG_AGENT_INFO= LC_ALL=C \ testscripts = sm-sign+verify sm-verify -EXTRA_DIST = runtest inittests $(testscripts) \ +EXTRA_DIST = runtest inittests $(testscripts) ChangeLog-2011 \ text-1.txt text-2.txt text-3.txt \ text-1.osig.pem text-1.dsig.pem text-1.osig-bad.pem \ text-2.osig.pem text-2.osig-bad.pem \ diff --git a/tests/openpgp/ChangeLog b/tests/openpgp/ChangeLog-2011 similarity index 97% rename from tests/openpgp/ChangeLog rename to tests/openpgp/ChangeLog-2011 index 18fbad852..4013a08f8 100644 --- a/tests/openpgp/ChangeLog +++ b/tests/openpgp/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-02-10 Werner Koch * ecc.test: New. @@ -411,3 +418,7 @@ Mon May 18 15:40:02 1998 Werner Koch (wk@isil.d.shuttle.de) This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index 8d6e5906b..ea1d54f8b 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -67,7 +67,7 @@ sample_keys = samplekeys/ecc-sample-1-pub.asc \ samplekeys/ecc-sample-2-sec.asc \ samplekeys/ecc-sample-3-sec.asc -EXTRA_DIST = defs.inc pinentry.sh $(TESTS) $(TEST_FILES) \ +EXTRA_DIST = defs.inc pinentry.sh $(TESTS) $(TEST_FILES) ChangeLog-2011 \ mkdemodirs signdemokey $(priv_keys) $(sample_keys) CLEANFILES = prepared.stamp x y yy z out err $(data_files) \ diff --git a/tests/pkits/ChangeLog b/tests/pkits/ChangeLog-2011 similarity index 83% rename from tests/pkits/ChangeLog rename to tests/pkits/ChangeLog-2011 index 992d1dfbb..d66e474ad 100644 --- a/tests/pkits/ChangeLog +++ b/tests/pkits/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2009-03-03 Werner Koch * inittests (clean_files): Use /bin/pwd here as well. @@ -11,11 +18,11 @@ 2008-02-19 Werner Koch - * inittests: Unpack test data onlyu if available. + * inittests: Unpack test data onlyu if available. * common.sh: Skip tests if PKITS test data is not available. * Makefile.am: Do not distribute test data. This allows to include the test suite in the distribution. - + * signature-verification: New. * validity-periods: New. * verifying-name-chaining: New. @@ -62,3 +69,7 @@ This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/tests/pkits/Makefile.am b/tests/pkits/Makefile.am index f59e5ec97..8098ad22b 100644 --- a/tests/pkits/Makefile.am +++ b/tests/pkits/Makefile.am @@ -1,18 +1,18 @@ # Makefile.am - tests using NIST's PKITS # Copyright (C) 2004, 2008 Free Software Foundation, Inc. -# +# # This file is part of GnuPG. -# +# # GnuPG is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. -# +# # GnuPG is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, see . @@ -43,8 +43,8 @@ testscripts = import-all-certs validate-all-certs \ private-certificate-extensions -EXTRA_DIST = inittests runtest common.sh $(testscripts) - import-all-certs.data +EXTRA_DIST = inittests runtest common.sh $(testscripts) ChangeLog-2011 \ + import-all-certs.data TESTS = $(testscripts) diff --git a/tools/ChangeLog b/tools/ChangeLog-2011 similarity index 99% rename from tools/ChangeLog rename to tools/ChangeLog-2011 index 9ae75d186..6821a8782 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog-2011 @@ -1,3 +1,10 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + 2011-08-26 Werner Koch * gpgconf-comp.c (gc_component): Mark for translation. Suggested @@ -766,7 +773,7 @@ 2006-09-12 Werner Koch - Replaced all call gpg_error_from_errno(errno) by + Replaced all call gpg_error_from_errno(errno) by gpg_error_from_syserror(). * gpg-connect-agent.c (read_and_print_response): With verbosity @@ -1271,3 +1278,7 @@ This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +Local Variables: +buffer-read-only: t +End: diff --git a/tools/Makefile.am b/tools/Makefile.am index 584967040..66be272aa 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -20,7 +20,7 @@ EXTRA_DIST = \ Manifest watchgnupg.c \ addgnupghome applygnupgdefaults gpgsm-gencert.sh \ lspgpot mail-signed-keys convert-from-106 sockprox.c \ - ccidmon.c + ccidmon.c ChangeLog-2011 AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common From 29e96e6b9a8e68e6554dd48bc2ce68ae9525d29f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 1 Dec 2011 18:13:44 +0100 Subject: [PATCH 24/68] Add hook to check the commit log syntax. * autogen.sh: Install commit-msg hook for git. --- autogen.sh | 7 ++ scripts/git-hooks/commit-msg | 127 +++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100755 scripts/git-hooks/commit-msg diff --git a/autogen.sh b/autogen.sh index 8a424bce5..0ec134d69 100755 --- a/autogen.sh +++ b/autogen.sh @@ -296,6 +296,13 @@ EOF git config --add filter.cleanpo.clean \ "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'" fi + if [ -f scripts/git-hooks/commit-msg -a ! -f .git/hooks/commit-msg ] ; then + cat <&2 +*** Activating commit log message check hook. *** +EOF + cp -av scripts/git-hooks/commit-msg .git/hooks/commit-msg + chmod -c +x .git/hooks/commit-msg + fi fi echo "Running aclocal -I m4 -I gl/m4 ${ACLOCAL_FLAGS:+$ACLOCAL_FLAGS }..." diff --git a/scripts/git-hooks/commit-msg b/scripts/git-hooks/commit-msg new file mode 100755 index 000000000..5a697c7a6 --- /dev/null +++ b/scripts/git-hooks/commit-msg @@ -0,0 +1,127 @@ +eval '(exit $?0)' && eval 'exec perl -w "$0" ${1+"$@"}' + & eval 'exec perl -w "$0" $argv:q' + if 0; + +# An hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, copy it to "~/.git/hooks/commit-msg". +# +# This script is based on the one from GNU coreutils. + +use strict; +use warnings; +(my $ME = $0) =~ s|.*/||; + +my $editor = $ENV{EDITOR} || 'vi'; +$ENV{PATH} = '/bin:/usr/bin'; + +# Rewrite the $LOG_FILE (old contents in @$LINE_REF) with an additional +# commented diagnostic "# $ERR" line at the top. +sub rewrite($$$) +{ + my ($log_file, $err, $line_ref) = @_; + local *LOG; + open LOG, '>', $log_file + or die "$ME: $log_file: failed to open for writing: $!"; + print LOG "# $err"; + print LOG @$line_ref; + close LOG + or die "$ME: $log_file: failed to rewrite: $!\n"; +} + +sub re_edit($) +{ + my ($log_file) = @_; + + warn "Interrupt (Ctrl-C) to abort...\n"; + + system 'sh', '-c', "$editor $log_file"; + ($? & 127) || ($? >> 8) + and die "$ME: $log_file: the editor ($editor) failed, aborting\n"; +} + +# Given a $LOG_FILE name and a \@LINE buffer, +# read the contents of the file into the buffer and analyze it. +# If the log message passes muster, return the empty string. +# If not, return a diagnostic. +sub check_msg($$) +{ + my ($log_file, $line_ref) = @_; + + local *LOG; + open LOG, '<', $log_file + or return "failed to open for reading: $!"; + @$line_ref = ; + close LOG; + + my @line = @$line_ref; + chomp @line; + + # Don't filter out blank or comment lines; git does that already, + # and if we were to ignore them here, it could lead to committing + # with lines that start with "#" in the log. + + # Filter out leading blank and comment lines. + # while (@line && $line[0] =~ /^(?:#.*|[ \t]*)$/) { shift @line; } + + # Filter out blank and comment lines at EOF. + # while (@line && $line[$#line] =~ /^(?:#.*|[ \t]*)$/) { pop @line; } + + @line == 0 + and return 'no log message'; + + # The first line should not be too short + 8 < length $line[0] || return 'summary line too short'; + + # The first line should not start with an asterisk or a hash sign. + # An asterisk might indicate that a change entry was started right + # at the first line. + $line[0] =~ /^[*#]/ && return "summary line starts with an * or #"; + + # Second line should be blank or not present. + 2 <= @line && length $line[1] + and return 'second line must be empty'; + + # Limit line length to allow for the ChangeLog's leading TAB. + foreach my $line (@line) + { + 72 < length $line && $line =~ /^[^#]/ + and return 'line longer than 72 characters'; + } + + return ''; +} + +{ + @ARGV == 1 + or die; + + my $log_file = $ARGV[0]; + + while (1) + { + my @line; + my $err = check_msg $log_file, \@line; + $err eq '' + and last; + $err = "$ME: $err\n"; + warn $err; + exit 1; + + # Insert the diagnostic as a comment on the first line of $log_file. + #rewrite $log_file, $err, \@line; + #re_edit $log_file; + # + ## Stop if our parent is killed. + #getppid() == 1 + # and last; + } +} + +# Local Variables: +# mode: perl +# End: From bf37c32367ba149559385ee90b6435cef8bd6412 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 2 Dec 2011 13:57:12 +0900 Subject: [PATCH 25/68] Fix pinpad input support for passphrase modification. * apdu.c (pcsc_keypad_verify): Have dummy Lc field with value 0. (pcsc_keypad_modify): Likewise. (pcsc_keypad_modify): It's only for ISO7816_CHANGE_REFERENCE_DATA. bConfirmPIN value is determined by the parameter p0. * app-openpgp.c (do_change_pin): The flag use_keypad should be 0 when reset_mode is on, or resetcode is on. use_keypad only makes sense for iso7816_change_reference_data_kp. * iso7816.h (iso7816_put_data_kp): Remove. (iso7816_reset_retry_counter_kp): Remove. (iso7816_reset_retry_counter_with_rc_kp): Remove. (iso7816_change_reference_data_kp): Add an argument: IS_EXCHANGE. * iso7816.c (iso7816_put_data_kp): Remove. (iso7816_reset_retry_counter_kp): Remove. (iso7816_reset_retry_counter_with_rc_kp): Remove. (iso7816_change_reference_data_kp): Add an argument: IS_EXCHANGE. --- scd/apdu.c | 44 ++++------- scd/app-openpgp.c | 182 +++++++++++++++++----------------------------- scd/iso7816.c | 51 ++----------- scd/iso7816.h | 6 +- 4 files changed, 89 insertions(+), 194 deletions(-) diff --git a/scd/apdu.c b/scd/apdu.c index 4d11157e3..c130d89bc 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -2043,7 +2043,7 @@ check_pcsc_keypad (int slot, int command, int pin_mode, } -#define PIN_VERIFY_STRUCTURE_SIZE 23 +#define PIN_VERIFY_STRUCTURE_SIZE 24 static int pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, struct pininfo_s *pininfo) @@ -2096,7 +2096,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, pin_verify[12] = 0x00; /* bTeoPrologue[0] */ pin_verify[13] = 0x00; /* bTeoPrologue[1] */ pin_verify[14] = 0x00; /* bTeoPrologue[2] */ - pin_verify[15] = 0x04; /* ulDataLength */ + pin_verify[15] = 0x05; /* ulDataLength */ pin_verify[16] = 0x00; /* ulDataLength */ pin_verify[17] = 0x00; /* ulDataLength */ pin_verify[18] = 0x00; /* ulDataLength */ @@ -2104,6 +2104,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, pin_verify[20] = ins; /* abData[1] */ pin_verify[21] = p0; /* abData[2] */ pin_verify[22] = p1; /* abData[3] */ + pin_verify[23] = 0x00; /* abData[4] */ sw = control_pcsc (slot, reader_table[slot].pcsc.verify_ioctl, pin_verify, len, result, &resultlen); @@ -2115,7 +2116,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, } -#define PIN_MODIFY_STRUCTURE_SIZE 28 +#define PIN_MODIFY_STRUCTURE_SIZE 29 static int pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, struct pininfo_s *pininfo) @@ -2125,32 +2126,6 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, unsigned long len = PIN_MODIFY_STRUCTURE_SIZE; unsigned char result[2]; size_t resultlen = 2; - unsigned char confirm_pin; - - /* bConfirmPIN - * 0x00: new PIN once - * 0x01: new PIN twice (confirmation) - * 0x02: old PIN and new PIN once - * 0x03: old PIN and new PIN twice (confirmation) - */ - switch (ins) - { - case ISO7816_CHANGE_REFERENCE_DATA: - confirm_pin = 0x03; - break; - case 0xDA: /* PUT_DATA */ - confirm_pin = 0x01; - break; - case ISO7816_RESET_RETRY_COUNTER: - if (p0 == 0) - confirm_pin = 0x03; - else - confirm_pin = 0x01; - break; - default: - confirm_pin = 0x00; - break; - } if (!reader_table[slot].atrlen && (sw = reset_pcsc_reader (slot))) @@ -2186,7 +2161,13 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, pin_modify[6] = 0x00; /* bInsertionOffsetNew */ pin_modify[7] = pininfo->maxlen; /* wPINMaxExtraDigit */ pin_modify[8] = pininfo->minlen; /* wPINMaxExtraDigit */ - pin_modify[9] = confirm_pin; + pin_modify[9] = (p0 == 0 ? 0x03 : 0x01); + /* bConfirmPIN + * 0x00: new PIN once + * 0x01: new PIN twice (confirmation) + * 0x02: old PIN and new PIN once + * 0x03: old PIN and new PIN twice (confirmation) + */ pin_modify[10] = 0x02; /* bEntryValidationCondition: Validation key pressed */ if (pininfo->minlen && pininfo->maxlen && pininfo->minlen == pininfo->maxlen) pin_modify[10] |= 0x01; /* Max size reached. */ @@ -2199,7 +2180,7 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, pin_modify[17] = 0x00; /* bTeoPrologue[0] */ pin_modify[18] = 0x00; /* bTeoPrologue[1] */ pin_modify[19] = 0x00; /* bTeoPrologue[2] */ - pin_modify[20] = 0x04; /* ulDataLength */ + pin_modify[20] = 0x05; /* ulDataLength */ pin_modify[21] = 0x00; /* ulDataLength */ pin_modify[22] = 0x00; /* ulDataLength */ pin_modify[23] = 0x00; /* ulDataLength */ @@ -2207,6 +2188,7 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, pin_modify[25] = ins; /* abData[1] */ pin_modify[26] = p0; /* abData[2] */ pin_modify[27] = p1; /* abData[3] */ + pin_modify[28] = 0x00; /* abData[4] */ sw = control_pcsc (slot, reader_table[slot].pcsc.modify_ioctl, pin_modify, len, result, &resultlen); diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index b51eb5be1..e3a448413 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1915,7 +1915,6 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, char *pinvalue = NULL; int reset_mode = !!(flags & APP_CHANGE_FLAG_RESET); int set_resetcode = 0; - int with_resetcode = 0; iso7816_pininfo_t pininfo; int use_keypad = 0; int minlen = 6; @@ -1975,6 +1974,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, if (reset_mode) { /* To reset a PIN the Admin PIN is required. */ + use_keypad = 0; app->did_chv3 = 0; rc = verify_chv3 (app, pincb, pincb_arg); if (rc) @@ -1983,37 +1983,40 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, if (chvno == 2) set_resetcode = 1; } - else if (!use_keypad && (chvno == 1 || chvno == 3)) + else if (chvno == 1 || chvno == 3) { - char *promptbuf = NULL; - const char *prompt; - - if (chvno == 3) + if (!use_keypad) { - minlen = 8; - rc = build_enter_admin_pin_prompt (app, &promptbuf); + char *promptbuf = NULL; + const char *prompt; + + if (chvno == 3) + { + minlen = 8; + rc = build_enter_admin_pin_prompt (app, &promptbuf); + if (rc) + goto leave; + prompt = promptbuf; + } + else + prompt = _("||Please enter the PIN"); + rc = pincb (pincb_arg, prompt, &oldpinvalue); + xfree (promptbuf); + promptbuf = NULL; if (rc) - goto leave; - prompt = promptbuf; - } - else - prompt = _("||Please enter the PIN"); - rc = pincb (pincb_arg, prompt, &oldpinvalue); - xfree (promptbuf); - promptbuf = NULL; - if (rc) - { - log_info (_("PIN callback returned error: %s\n"), - gpg_strerror (rc)); - goto leave; - } + { + log_info (_("PIN callback returned error: %s\n"), + gpg_strerror (rc)); + goto leave; + } - if (strlen (oldpinvalue) < minlen) - { - log_info (_("PIN for CHV%d is too short;" - " minimum length is %d\n"), chvno, minlen); - rc = gpg_error (GPG_ERR_BAD_PIN); - goto leave; + if (strlen (oldpinvalue) < minlen) + { + log_info (_("PIN for CHV%d is too short;" + " minimum length is %d\n"), chvno, minlen); + rc = gpg_error (GPG_ERR_BAD_PIN); + goto leave; + } } } else if (chvno == 2) @@ -2025,7 +2028,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, size_t valuelen; int remaining; - with_resetcode = 1; + use_keypad = 0; minlen = 8; relptr = get_one_do (app, 0x00C4, &value, &valuelen, NULL); if (!relptr || valuelen < 7) @@ -2044,24 +2047,21 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, goto leave; } - if (!use_keypad) + rc = pincb (pincb_arg, + _("||Please enter the Reset Code for the card"), + &resetcode); + if (rc) { - rc = pincb (pincb_arg, - _("||Please enter the Reset Code for the card"), - &resetcode); - if (rc) - { - log_info (_("PIN callback returned error: %s\n"), - gpg_strerror (rc)); - goto leave; - } - if (strlen (resetcode) < minlen) - { - log_info (_("Reset Code is too short; minimum length is %d\n"), - minlen); - rc = gpg_error (GPG_ERR_BAD_PIN); - goto leave; - } + log_info (_("PIN callback returned error: %s\n"), + gpg_strerror (rc)); + goto leave; + } + if (strlen (resetcode) < minlen) + { + log_info (_("Reset Code is too short; minimum length is %d\n"), + minlen); + rc = gpg_error (GPG_ERR_BAD_PIN); + goto leave; } } else @@ -2093,86 +2093,40 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, } - if (with_resetcode) + if (resetcode) { - if (use_keypad) - { - rc = pincb (pincb_arg, - _("||Please enter the Reset Code for the card and New PIN"), - NULL); - if (rc) - { - log_info (_("PIN callback returned error: %s\n"), - gpg_strerror (rc)); - goto leave; - } - rc = iso7816_reset_retry_counter_with_rc_kp (app->slot, 0x81, - &pininfo); - pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ - } + char *buffer; + + buffer = xtrymalloc (strlen (resetcode) + strlen (pinvalue) + 1); + if (!buffer) + rc = gpg_error_from_syserror (); else { - char *buffer; - - buffer = xtrymalloc (strlen (resetcode) + strlen (pinvalue) + 1); - if (!buffer) - rc = gpg_error_from_syserror (); - else - { - strcpy (stpcpy (buffer, resetcode), pinvalue); - rc = iso7816_reset_retry_counter_with_rc (app->slot, 0x81, - buffer, strlen (buffer)); - wipememory (buffer, strlen (buffer)); - xfree (buffer); - } + strcpy (stpcpy (buffer, resetcode), pinvalue); + rc = iso7816_reset_retry_counter_with_rc (app->slot, 0x81, + buffer, strlen (buffer)); + wipememory (buffer, strlen (buffer)); + xfree (buffer); } } else if (set_resetcode) { - if (use_keypad) + if (strlen (pinvalue) < 8) { - rc = pincb (pincb_arg, _("|RN|New Reset Code"), NULL); - if (rc) - { - log_info (_("PIN callback returned error: %s\n"), - gpg_strerror (rc)); - goto leave; - } - rc = iso7816_put_data_kp (app->slot, 0xD3, &pininfo); - pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ + log_error (_("Reset Code is too short; minimum length is %d\n"), 8); + rc = gpg_error (GPG_ERR_BAD_PIN); } else - if (strlen (pinvalue) < 8) - { - log_error (_("Reset Code is too short; minimum length is %d\n"), 8); - rc = gpg_error (GPG_ERR_BAD_PIN); - } - else - rc = iso7816_put_data (app->slot, 0, 0xD3, - pinvalue, strlen (pinvalue)); + rc = iso7816_put_data (app->slot, 0, 0xD3, + pinvalue, strlen (pinvalue)); } else if (reset_mode) { - if (use_keypad) - { - rc = pincb (pincb_arg, _("|N|New PIN"), NULL); - if (rc) - { - log_info (_("PIN callback returned error: %s\n"), - gpg_strerror (rc)); - goto leave; - } - rc = iso7816_reset_retry_counter_kp (app->slot, 0x81, &pininfo); - pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ - } - else - { - rc = iso7816_reset_retry_counter (app->slot, 0x81, - pinvalue, strlen (pinvalue)); - if (!rc && !app->app_local->extcap.is_v2) - rc = iso7816_reset_retry_counter (app->slot, 0x82, - pinvalue, strlen (pinvalue)); - } + rc = iso7816_reset_retry_counter (app->slot, 0x81, + pinvalue, strlen (pinvalue)); + if (!rc && !app->app_local->extcap.is_v2) + rc = iso7816_reset_retry_counter (app->slot, 0x82, + pinvalue, strlen (pinvalue)); } else if (!app->app_local->extcap.is_v2) { @@ -2208,7 +2162,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, gpg_strerror (rc)); goto leave; } - rc = iso7816_change_reference_data_kp (app->slot, 0x80 + chvno, + rc = iso7816_change_reference_data_kp (app->slot, 0x80 + chvno, 0, &pininfo); pincb (pincb_arg, NULL, NULL); /* Dismiss the prompt. */ } diff --git a/scd/iso7816.c b/scd/iso7816.c index 8876b931a..45f5e08bf 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -307,16 +307,18 @@ iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen) /* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder verification vector CHVNO. With PININFO non-NULL the keypad of the - reader will be used. */ + reader will be used. If IS_EXCHANGE is 0, a "change reference + data" is done, otherwise an "exchange reference data". */ gpg_error_t -iso7816_change_reference_data_kp (int slot, int chvno, +iso7816_change_reference_data_kp (int slot, int chvno, int is_exchange, iso7816_pininfo_t *pininfo) { int sw; - sw = apdu_keypad_modify (slot, 0x00, CMD_CHANGE_REFERENCE_DATA, 0, chvno, - pininfo->mode, pininfo->minlen, pininfo->maxlen, - pininfo->padlen); + sw = apdu_keypad_modify (slot, 0x00, CMD_CHANGE_REFERENCE_DATA, + is_exchange ? 1 : 0, + chvno, pininfo->mode, pininfo->minlen, + pininfo->maxlen, pininfo->padlen); return map_sw (sw); } @@ -353,19 +355,6 @@ iso7816_change_reference_data (int slot, int chvno, } -gpg_error_t -iso7816_reset_retry_counter_with_rc_kp (int slot, int chvno, - iso7816_pininfo_t *pininfo) -{ - int sw; - - sw = apdu_keypad_modify (slot, 0x00, CMD_RESET_RETRY_COUNTER, 0, chvno, - pininfo->mode, pininfo->minlen, pininfo->maxlen, - pininfo->padlen); - return map_sw (sw); -} - - gpg_error_t iso7816_reset_retry_counter_with_rc (int slot, int chvno, const char *data, size_t datalen) @@ -381,19 +370,6 @@ iso7816_reset_retry_counter_with_rc (int slot, int chvno, } -gpg_error_t -iso7816_reset_retry_counter_kp (int slot, int chvno, - iso7816_pininfo_t *pininfo) -{ - int sw; - - sw = apdu_keypad_modify (slot, 0x00, CMD_RESET_RETRY_COUNTER, 2, chvno, - pininfo->mode, pininfo->minlen, pininfo->maxlen, - pininfo->padlen); - return map_sw (sw); -} - - gpg_error_t iso7816_reset_retry_counter (int slot, int chvno, const char *newchv, size_t newchvlen) @@ -445,19 +421,6 @@ iso7816_get_data (int slot, int extended_mode, int tag, } -gpg_error_t -iso7816_put_data_kp (int slot, int tag, iso7816_pininfo_t *pininfo) -{ - int sw; - - sw = apdu_keypad_modify (slot, 0x00, CMD_PUT_DATA, - ((tag >> 8) & 0xff), (tag & 0xff), - pininfo->mode, pininfo->minlen, pininfo->maxlen, - pininfo->padlen); - return map_sw (sw); -} - - /* Perform a PUT DATA command on card in SLOT. Write DATA of length DATALEN to TAG. EXTENDED_MODE controls whether extended length headers or command chaining is used instead of single length diff --git a/scd/iso7816.h b/scd/iso7816.h index 9ed7b219f..336208aba 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -68,19 +68,15 @@ gpg_error_t iso7816_change_reference_data (int slot, int chvno, const char *oldchv, size_t oldchvlen, const char *newchv, size_t newchvlen); gpg_error_t iso7816_change_reference_data_kp (int slot, int chvno, + int is_exchange, iso7816_pininfo_t *pininfo); gpg_error_t iso7816_reset_retry_counter (int slot, int chvno, const char *newchv, size_t newchvlen); -gpg_error_t iso7816_reset_retry_counter_kp (int slot, int chvno, - iso7816_pininfo_t *pininfo); gpg_error_t iso7816_reset_retry_counter_with_rc (int slot, int chvno, const char *data, size_t datalen); -gpg_error_t iso7816_reset_retry_counter_with_rc_kp (int slot, int chvno, - iso7816_pininfo_t *pininfo); gpg_error_t iso7816_get_data (int slot, int extended_mode, int tag, unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_put_data_kp (int slot, int tag, iso7816_pininfo_t *pininfo); gpg_error_t iso7816_put_data (int slot, int extended_mode, int tag, const void *data, size_t datalen); gpg_error_t iso7816_put_data_odd (int slot, int extended_mode, int tag, From 96dc146fa17a7853277dbf3dc771c585a815c247 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 2 Dec 2011 17:04:58 +0100 Subject: [PATCH 26/68] Avoid possible double free in export.c. * g10/export.c (transfer_format_to_openpgp): Avoid possible double free of LIST. Reported by NIIBE Yutaka. --- g10/export.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g10/export.c b/g10/export.c index 7deee6b02..9a348523b 100644 --- a/g10/export.c +++ b/g10/export.c @@ -507,7 +507,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) } skey[skeyidx++] = NULL; - gcry_sexp_release (list); + gcry_sexp_release (list); list = NULL; /* We have no need for the CSUM valuel thus we don't parse it. */ /* list = gcry_sexp_find_token (top_list, "csum", 0); */ From 239659d3a0b8c0c378734ca3d1e9210a02e24da7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 2 Dec 2011 18:09:58 +0100 Subject: [PATCH 27/68] Support the Cherry ST-2000 card reader. * scd/ccid-driver.c (SCM_SCR331, SCM_SCR331DI, SCM_SCR335) (SCM_SCR3320, SCM_SPR532, CHERRY_ST2000): New constants. (parse_ccid_descriptor): Use them. (scan_or_find_usb_device, ccid_transceive_secure): Handle Cherry ST-2000. Suggested by Matthias-Christian Ott. --- THANKS | 1 + scd/ccid-driver.c | 34 ++++++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/THANKS b/THANKS index b5281f5ea..5bde9f33e 100644 --- a/THANKS +++ b/THANKS @@ -166,6 +166,7 @@ Martin Schulte schulte at thp.uni-koeln.de Matt Kraai kraai at alumni.carnegiemellon.edu Matthew Skala mskala at ansuz.sooke.bc.ca Matthew Wilcox matthew at wil.cx +Matthias-Christian Ott ott at mirix.org Matthias Urlichs smurf at noris.de Max Valianskiy maxcom at maxcom.ml.org Michael Engels michael.engels at uni-duesseldorf.de diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index eb1962594..7338ccc6f 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -213,6 +213,15 @@ enum { VENDOR_FSIJ = 0x234B }; +/* Some product ids. */ +#define SCM_SCR331 0xe001 +#define SCM_SCR331DI 0x5111 +#define SCM_SCR335 0x5115 +#define SCM_SCR3320 0x5117 +#define SCM_SPR532 0xe003 +#define CHERRY_ST2000 0x003e + + /* A list and a table with special transport descriptions. */ enum { TRANSPORT_USB = 0, /* Standard USB transport. */ @@ -954,11 +963,11 @@ parse_ccid_descriptor (ccid_driver_t handle, */ if (handle->id_vendor == VENDOR_SCM && handle->max_ifsd > 48 - && ( (handle->id_product == 0xe001 && handle->bcd_device < 0x0516) - ||(handle->id_product == 0x5111 && handle->bcd_device < 0x0620) - ||(handle->id_product == 0x5115 && handle->bcd_device < 0x0514) - ||(handle->id_product == 0xe003 && handle->bcd_device < 0x0504) - ||(handle->id_product == 0x5117 && handle->bcd_device < 0x0522) + && ( (handle->id_product == SCM_SCR331 && handle->bcd_device < 0x0516) + ||(handle->id_product == SCM_SCR331DI && handle->bcd_device < 0x0620) + ||(handle->id_product == SCM_SCR335 && handle->bcd_device < 0x0514) + ||(handle->id_product == SCM_SPR532 && handle->bcd_device < 0x0504) + ||(handle->id_product == SCM_SCR3320 && handle->bcd_device < 0x0522) )) { DEBUGOUT ("enabling workaround for buggy SCM readers\n"); @@ -1138,16 +1147,20 @@ scan_or_find_usb_device (int scan_mode, { ifcdesc = (interface->altsetting + set_no); /* The second condition is for older SCM SPR 532 who did - not know about the assigned CCID class. Instead of - trying to interpret the strings we simply check the - product ID. */ + not know about the assigned CCID class. The third + condition does the same for a Cherry SmartTerminal + ST-2000. Instead of trying to interpret the strings + we simply check the product ID. */ if (ifcdesc && ifcdesc->extra && ((ifcdesc->bInterfaceClass == 11 && ifcdesc->bInterfaceSubClass == 0 && ifcdesc->bInterfaceProtocol == 0) || (ifcdesc->bInterfaceClass == 255 && dev->descriptor.idVendor == VENDOR_SCM - && dev->descriptor.idProduct == 0xe003))) + && dev->descriptor.idProduct == SCM_SPR532) + || (ifcdesc->bInterfaceClass == 255 + && dev->descriptor.idVendor == VENDOR_CHERRY + && dev->descriptor.idProduct == CHERRY_ST2000))) { idev = usb_open (dev); if (!idev) @@ -3083,7 +3096,8 @@ ccid_transceive_secure (ccid_driver_t handle, Lc byte to the APDU. It seems that it will be replaced with the actual length instead of being appended before the APDU is send to the card. */ - cherry_mode = 1; + if (handle->id_product != CHERRY_ST2000) + cherry_mode = 1; break; default: return CCID_DRIVER_ERR_NOT_SUPPORTED; From 477360e8cdc458b0a36e9c7fb52a35f27766255d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 5 Dec 2011 10:54:59 +0100 Subject: [PATCH 28/68] Amend the agent code with more comments. * agent/command.c (server_local_s): Remove unused field MESSAGE_FD. --- agent/agent.h | 83 +++++++++++++++++++++++++++---------- agent/command.c | 102 +++++++++++++++++++++++++++++++++++----------- agent/gpg-agent.c | 22 +++++++++- 3 files changed, 161 insertions(+), 46 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index b323718fc..4f4e477a6 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -73,17 +73,20 @@ struct /* True if we handle sigusr2. */ int sigusr2_enabled; - /* Environment setting gathered at program start or changed using the + /* Environment settings gathered at program start or changed using the Assuan command UPDATESTARTUPTTY. */ session_env_t startup_env; char *startup_lc_ctype; char *startup_lc_messages; - const char *pinentry_program; /* Filename of the program to start as - pinentry. */ - const char *scdaemon_program; /* Filename of the program to handle - smartcard tasks. */ + /* Filename of the program to start as pinentry. */ + const char *pinentry_program; + + /* Filename of the program to handle smartcard tasks. */ + const char *scdaemon_program; + int disable_scdaemon; /* Never use the SCdaemon. */ + int no_grab; /* Don't let the pinentry grab the keyboard */ /* The name of the file pinentry shall tocuh before exiting. If @@ -98,31 +101,51 @@ struct /* Flag disallowing bypassing of the warning. */ int enforce_passphrase_constraints; + /* The require minmum length of a passphrase. */ unsigned int min_passphrase_len; + /* The minimum number of non-alpha characters in a passphrase. */ unsigned int min_passphrase_nonalpha; + /* File name with a patternfile or NULL if not enabled. */ const char *check_passphrase_pattern; + /* If not 0 the user is asked to change his passphrase after these number of days. */ unsigned int max_passphrase_days; + /* If set, a passphrase history will be written and checked at each passphrase change. */ int enable_passhrase_history; int running_detached; /* We are running detached from the tty. */ + /* If this global option is true, the passphrase cache is ignored + for signing operations. */ int ignore_cache_for_signing; + + /* If this global option is true, the user is allowed to + interactively mark certificate in trustlist.txt as trusted. */ int allow_mark_trusted; + + /* If this global option is true, the Assuan command + PRESET_PASSPHRASE is allowed. */ int allow_preset_passphrase; + + /* If this global option is true, the Assuan option + pinentry-mode=loopback is allowed. */ int allow_loopback_pinentry; + int keep_tty; /* Don't switch the TTY (for pinentry) on request */ int keep_display; /* Don't switch the DISPLAY (for pinentry) on request */ - int ssh_support; /* Enable ssh-agent emulation. */ + + /* This global option enables the ssh-agent subsystem. */ + int ssh_support; } opt; +/* Bit values for the --debug option. */ #define DBG_COMMAND_VALUE 1 /* debug commands i/o */ #define DBG_MPI_VALUE 2 /* debug mpi details */ #define DBG_CRYPTO_VALUE 4 /* debug low level crypto */ @@ -130,8 +153,9 @@ struct #define DBG_CACHE_VALUE 64 /* debug the caching */ #define DBG_MEMSTAT_VALUE 128 /* show memory statistics */ #define DBG_HASHING_VALUE 512 /* debug hashing operations */ -#define DBG_ASSUAN_VALUE 1024 +#define DBG_ASSUAN_VALUE 1024 /* Enable Assuan debugging. */ +/* Test macros for the debug option. */ #define DBG_COMMAND (opt.debug & DBG_COMMAND_VALUE) #define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE) #define DBG_MEMORY (opt.debug & DBG_MEMORY_VALUE) @@ -139,14 +163,18 @@ struct #define DBG_HASHING (opt.debug & DBG_HASHING_VALUE) #define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE) +/* Forward reference for local definitions in command.c. */ struct server_local_s; + +/* Forward reference for local definitions in call-scd.c. */ struct scd_local_s; /* Collection of data per session (aka connection). */ struct server_control_s { /* Private data used to fire up the connection thread. We use this - structure do avoid an extra allocation for just a few bytes. */ + structure do avoid an extra allocation for only a few bytes while + spawning a new connection thread. */ struct { gnupg_fd_t fd; } thread_startup; @@ -157,6 +185,7 @@ struct server_control_s /* Private data of the SCdaemon (call-scd.c). */ struct scd_local_s *scd_local; + /* Environment settings for the connection. */ session_env_t session_env; char *lc_ctype; char *lc_messages; @@ -177,37 +206,47 @@ struct server_control_s unsigned char keygrip[20]; int have_keygrip; - int use_auth_call; /* Hack to send the PKAUTH command instead of the - PKSIGN command to the scdaemon. */ - int in_passwd; /* Hack to inhibit enforced passphrase change - during an explicit passwd command. */ + /* A flag to enable a hack to send the PKAUTH command instead of the + PKSIGN command to the scdaemon. */ + int use_auth_call; - unsigned long s2k_count; /* Other than the calibrated count. */ + /* A flag to inhibit enforced passphrase change during an explicit + passwd command. */ + int in_passwd; + + /* The current S2K which might be different from the calibrated + count. */ + unsigned long s2k_count; }; +/* Information pertaining to pinentry requests. */ struct pin_entry_info_s { int min_digits; /* min. number of digits required or 0 for freeform entry */ int max_digits; /* max. number of allowed digits allowed*/ - int max_tries; - int failed_tries; + int max_tries; /* max. number of allowed tries. */ + int failed_tries; /* Number of tries so far failed. */ int with_qualitybar; /* Set if the quality bar should be displayed. */ int (*check_cb)(struct pin_entry_info_s *); /* CB used to check the PIN */ void *check_cb_arg; /* optional argument which might be of use in the CB */ const char *cb_errtext; /* used by the cb to display a specific error */ - size_t max_length; /* allocated length of the buffer */ - char pin[1]; + size_t max_length; /* Allocated length of the buffer PIN. */ + char pin[1]; /* The buffer to hold the PIN or passphrase. + It's actual allocated length is given by + MAX_LENGTH (above). */ }; +/* Types of the private keys. */ enum { - PRIVATE_KEY_UNKNOWN = 0, - PRIVATE_KEY_CLEAR = 1, - PRIVATE_KEY_PROTECTED = 2, - PRIVATE_KEY_SHADOWED = 3, - PROTECTED_SHARED_SECRET = 4 + PRIVATE_KEY_UNKNOWN = 0, /* Type of key is not known. */ + PRIVATE_KEY_CLEAR = 1, /* The key is not protected. */ + PRIVATE_KEY_PROTECTED = 2, /* The key is protected. */ + PRIVATE_KEY_SHADOWED = 3, /* The key is a stub for a smartcard + based key. */ + PROTECTED_SHARED_SECRET = 4 /* RFU. */ }; diff --git a/agent/command.c b/agent/command.c index f310a980c..0e7b962c4 100644 --- a/agent/command.c +++ b/agent/command.c @@ -50,31 +50,57 @@ /* The size of the import/export KEK key (in bytes). */ #define KEYWRAP_KEYSIZE (128/8) +/* A shortcut to call assuan_set_error using an gpg_err_code_t and a + text string. */ #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t)) - +/* Check that the maximum digest length we support has at least the + length of the keygrip. */ #if MAX_DIGEST_LEN < 20 #error MAX_DIGEST_LEN shorter than keygrip #endif -/* Data used to associate an Assuan context with local server data */ +/* Data used to associate an Assuan context with local server data. + This is this modules local part of the server_control_s struct. */ struct server_local_s { + /* Our Assuan context. */ assuan_context_t assuan_ctx; - int message_fd; + + /* If this flag is true, the passphrase cache is used for signing + operations. It defaults to true but may be set on a per + connection base. The global option opt.ignore_cache_for_signing + takes precedence over this flag. */ int use_cache_for_signing; - char *keydesc; /* Allocated description for the next key - operation. */ - int pause_io_logging; /* Used to suppress I/O logging during a command */ - int stopme; /* If set to true the agent will be terminated after - the end of this session. */ - int allow_pinentry_notify; /* Set if pinentry notifications should - be done. */ - void *import_key; /* Malloced KEK for the import_key command. */ - void *export_key; /* Malloced KEK for the export_key command. */ - int allow_fully_canceled; /* Client is aware of GPG_ERR_FULLY_CANCELED. */ - char *last_cache_nonce; /* Last CACHE_NOCNE sent as status (malloced). */ - char *last_passwd_nonce; /* Last PASSWD_NOCNE sent as status (malloced). */ + + /* An allocated description for the next key operation. This is + used if a pinnetry needs to be popped up. */ + char *keydesc; + + /* Flags to suppress I/O logging during a command. */ + int pause_io_logging; + + /* If this flags is set to true the agent will be terminated after + the end of the current session. */ + int stopme; + + /* Flag indicating whether pinentry notifications shall be done. */ + int allow_pinentry_notify; + + /* Malloced KEK (Key-Encryption-Key) for the import_key command. */ + void *import_key; + + /* Malloced KEK for the export_key command. */ + void *export_key; + + /* Client is aware of the error code GPG_ERR_FULLY_CANCELED. */ + int allow_fully_canceled; + + /* Last CACHE_NONCE sent as status (malloced). */ + char *last_cache_nonce; + + /* Last PASSWD_NONCE sent as status (malloced). */ + char *last_passwd_nonce; }; @@ -156,6 +182,8 @@ write_and_clear_outbuf (assuan_context_t ctx, membuf_t *mb) } +/* Clear the nonces used to enable the passphrase cache for certain + multi-command command sequences. */ static void clear_nonce_cache (ctrl_t ctrl) { @@ -176,6 +204,9 @@ clear_nonce_cache (ctrl_t ctrl) } +/* This function is called by Libassuan whenever thee client sends a + reset. It has been registered similar to the other Assuan + commands. */ static gpg_error_t reset_notify (assuan_context_t ctx, char *line) { @@ -196,8 +227,13 @@ reset_notify (assuan_context_t ctx, char *line) } -/* Skip over options. - Blanks after the options are also removed. */ +/* Skip over options in LINE. + + Blanks after the options are also removed. Options are indicated + by two leading dashes followed by a string consisting of non-space + characters. The special option "--" indicates an explicit end of + options; all what follows will not be considered an option. The + first no-option string also indicates the end of option parsing. */ static char * skip_options (const char *line) { @@ -213,7 +249,11 @@ skip_options (const char *line) return (char*)line; } -/* Check whether the option NAME appears in LINE */ + +/* Check whether the option NAME appears in LINE. An example for a + line with options is: + --algo=42 --data foo bar + This function would then only return true if NAME is "data". */ static int has_option (const char *line, const char *name) { @@ -226,6 +266,7 @@ has_option (const char *line, const char *name) return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); } + /* Same as has_option but does only test for the name of the option and ignores an argument, i.e. with NAME being "--hash" it would return true for "--hash" as well as for "--hash=foo". */ @@ -242,8 +283,9 @@ has_option_name (const char *line, const char *name) && (!s[n] || spacep (s+n) || s[n] == '=')); } + /* Return a pointer to the argument of the option with NAME. If such - an option is not given, it returns NULL. */ + an option is not given, NULL is retruned. */ static char * option_value (const char *line, const char *name) { @@ -265,7 +307,7 @@ option_value (const char *line, const char *name) } -/* Replace all '+' by a blank. */ +/* Replace all '+' by a blank in the string S. */ static void plus_to_blank (char *s) { @@ -296,8 +338,9 @@ parse_hexstring (assuan_context_t ctx, const char *string, size_t *len) return 0; } + /* Parse the keygrip in STRING into the provided buffer BUF. BUF must - provide space for 20 bytes. BUF is not changed if the function + provide space for 20 bytes. BUF is not changed if the function returns an error. */ static int parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf) @@ -319,7 +362,11 @@ parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf) } -/* Write an assuan status line. */ +/* Write an Assuan status line. KEYWORD is the first item on the + status line. The following arguments are all separated by a space + in the output. The last argument must be a NULL. Linefeeds and + carriage returns characters (which are not allowed in an Assuan + status line) are silently quoted in C-style. */ gpg_error_t agent_write_status (ctrl_t ctrl, const char *keyword, ...) { @@ -463,6 +510,7 @@ bump_key_eventcounter (void) eventcounter.any++; } + /* This function should be called for all card reader status changes. This function is assured not to do any context switches. */ @@ -1069,6 +1117,8 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx, } +/* Entry int for the command KEYINFO. This function handles the + command option processing. For details see hlp_keyinfo above. */ static gpg_error_t cmd_keyinfo (assuan_context_t ctx, char *line) { @@ -1140,6 +1190,7 @@ cmd_keyinfo (assuan_context_t ctx, char *line) +/* Helper for cmd_get_passphrase. */ static int send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw) { @@ -2415,6 +2466,8 @@ cmd_getinfo (assuan_context_t ctx, char *line) +/* This function is called by Libassuan to parse the OPTION command. + It has been registered similar to the other Assuan commands. */ static gpg_error_t option_handler (assuan_context_t ctx, const char *key, const char *value) { @@ -2574,7 +2627,8 @@ command_has_option (const char *cmd, const char *cmdopt) } -/* Tell the assuan library about our commands */ +/* Tell Libassuan about our commands. Also register the other Assuan + handlers. */ static int register_commands (assuan_context_t ctx) { @@ -2733,6 +2787,8 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd) } +/* Helper for the pinentry loopback mode. It merely passes the + parameters on to the client. */ gpg_error_t pinentry_loopback(ctrl_t ctrl, const char *keyword, unsigned char **buffer, size_t *size, diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 061687550..6dcde26af 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -309,6 +309,9 @@ static unsigned long pth_thread_id (void) Functions. */ +/* Allocate a string describing a library version by calling a GETFNC. + This function is expected to be called only once. GETFNC is + expected to have a semantic like gcry_check_version (). */ static char * make_libversion (const char *libname, const char *(*getfnc)(const char*)) { @@ -326,7 +329,9 @@ make_libversion (const char *libname, const char *(*getfnc)(const char*)) return result; } - +/* Return strings describing this program. The case values are + described in common/argparse.c:strusage. The values here override + the default values given by strusage. */ static const char * my_strusage (int level) { @@ -448,6 +453,9 @@ remove_socket (char *name) } } + +/* Cleanup code for this program. This is either called has an atexit + handler or directly. */ static void cleanup (void) { @@ -1268,6 +1276,8 @@ main (int argc, char **argv ) } +/* Exit entry point. This function should be called instead of a + plain exit. */ void agent_exit (int rc) { @@ -1294,6 +1304,11 @@ agent_exit (int rc) } +/* Each thread has its own local variables conveyed by a control + structure usually identified by an argument named CTRL. This + function is called immediately after allocating the control + structure. Its purpose is to setup the default values for that + structure. */ static void agent_init_default_ctrl (ctrl_t ctrl) { @@ -1319,6 +1334,8 @@ agent_init_default_ctrl (ctrl_t ctrl) } +/* Release all resources allocated by default in the control + structure. This is the counterpart to agent_init_default_ctrl. */ static void agent_deinit_default_ctrl (ctrl_t ctrl) { @@ -1720,6 +1737,7 @@ agent_sighup_action (void) } +/* A helper function to handle SIGUSR2. */ static void agent_sigusr2_action (void) { @@ -1730,6 +1748,8 @@ agent_sigusr2_action (void) } +/* The signal handler for this program. It is expected to be run in + its own trhead and not in the context of a signal handler. */ static void handle_signal (int signo) { From 9274d4d18281b3364fa8abaa821dddf124b105d7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 5 Dec 2011 15:14:47 +0100 Subject: [PATCH 29/68] Fix last change. * agent/command.c (start_command_handler): Remove use of removed var. --- agent/command.c | 1 - 1 file changed, 1 deletion(-) diff --git a/agent/command.c b/agent/command.c index 0e7b962c4..c33c0d61f 100644 --- a/agent/command.c +++ b/agent/command.c @@ -2739,7 +2739,6 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd) assuan_set_pointer (ctx, ctrl); ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local); ctrl->server_local->assuan_ctx = ctx; - ctrl->server_local->message_fd = -1; ctrl->server_local->use_cache_for_signing = 1; ctrl->digest.raw_value = 0; From 3f284e40502d8181b0b3ea66c77cd7c1252ea781 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 6 Dec 2011 16:45:46 +0100 Subject: [PATCH 30/68] gpgsm: Fix storing of the serial number * sm/certreqgen.c (create_request): Fix hex-bin conversion. --- sm/certreqgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sm/certreqgen.c b/sm/certreqgen.c index 41a6d7f05..b4857b30f 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -889,7 +889,7 @@ create_request (ctrl_t ctrl, *p++ = '0'; strcpy (p, string); for (p=hexbuf, len=0; p[0] && p[1]; p += 2) - ((unsigned char*)hexbuf)[len++] = xtoi_2 (s); + ((unsigned char*)hexbuf)[len++] = xtoi_2 (p); /* Now build the S-expression. */ snprintf (numbuf, DIM(numbuf), "%u:", (unsigned int)len); buf = p = xtrymalloc (1 + strlen (numbuf) + len + 1 + 1); From 5cdad8ff000152b4bd01953646bb87fe8703c70d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 6 Dec 2011 19:57:27 +0100 Subject: [PATCH 31/68] gpgsm: Allow arbitrary extensions for cert creation. * sm/certreqgen.c (pSUBJKEYID, pEXTENSION): New. (read_parameters): Add new keywords. (proc_parameters): Check values of new keywords. (create_request): Add SubjectKeyId and extensions. (parse_parameter_usage): Support "cert" and the encrypt alias "encr". --- doc/DETAILS | 1 + doc/gpgsm.texi | 6 +- sm/certreqgen.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++- sm/keylist.c | 1 + 4 files changed, 187 insertions(+), 5 deletions(-) diff --git a/doc/DETAILS b/doc/DETAILS index 543ae4d96..2e6874e9a 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -1036,6 +1036,7 @@ OIDs below the GnuPG arc: 1.3.6.1.4.1.11591.2.1.1 pkaAddress 1.3.6.1.4.1.11591.2.2 X.509 extensions 1.3.6.1.4.1.11591.2.2.1 standaloneCertificate + 1.3.6.1.4.1.11591.2.2.2 wellKnownPrivateKey 1.3.6.1.4.1.11591.2.12242973 invalid encoded OID diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 892083335..8e25baf62 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -1042,9 +1042,9 @@ already existing key. Key-Length will be ignored when given. @item Key-Usage: @var{usage-list} Space or comma delimited list of key usage, allowed values are -@samp{encrypt} and @samp{sign}. This is used to generate the keyUsage -extension. Please make sure that the algorithm is capable of this -usage. Default is to allow encrypt and sign. +@samp{encrypt}, @samp{sign} and @samp{cert}. This is used to generate +the keyUsage extension. Please make sure that the algorithm is +capable of this usage. Default is to allow encrypt and sign. @item Name-DN: @var{subject-name} This is the Distinguished Name (DN) of the subject in RFC-2253 format. diff --git a/sm/certreqgen.c b/sm/certreqgen.c index b4857b30f..15fc7a245 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -33,6 +33,22 @@ %commit %echo done EOF + + This parameter file was used to create the STEED CA: + Key-Type: RSA + Key-Length: 1024 + Key-Grip: 68A638998DFABAC510EA645CE34F9686B2EDF7EA + Key-Usage: cert + Serial: 1 + Name-DN: CN=The STEED Self-Signing Nonthority + Not-Before: 2011-11-11 + Not-After: 2106-02-06 + Subject-Key-Id: 68A638998DFABAC510EA645CE34F9686B2EDF7EA + Extension: 2.5.29.19 c 30060101ff020101 + Extension: 1.3.6.1.4.1.11591.2.2.2 n 0101ff + Signing-Key: 68A638998DFABAC510EA645CE34F9686B2EDF7EA + %commit + */ @@ -68,7 +84,9 @@ enum para_name pNOTBEFORE, pNOTAFTER, pSIGNINGKEY, - pHASHALGO + pHASHALGO, + pSUBJKEYID, + pEXTENSION }; struct para_data_s @@ -89,6 +107,7 @@ struct reqgen_ctrl_s }; +static const char oidstr_subjectKeyIdentifier[] = "2.5.29.14"; static const char oidstr_keyUsage[] = "2.5.29.15"; static const char oidstr_basicConstraints[] = "2.5.29.19"; static const char oidstr_standaloneCertificate[] = "1.3.6.1.4.1.11591.2.2.1"; @@ -170,8 +189,11 @@ parse_parameter_usage (struct para_data_s *para, enum para_name key) ; else if ( !ascii_strcasecmp (p, "sign") ) use |= GCRY_PK_USAGE_SIGN; - else if ( !ascii_strcasecmp (p, "encrypt") ) + else if ( !ascii_strcasecmp (p, "encrypt") + || !ascii_strcasecmp (p, "encr") ) use |= GCRY_PK_USAGE_ENCR; + else if ( !ascii_strcasecmp (p, "cert") ) + use |= GCRY_PK_USAGE_CERT; else { log_error ("line %d: invalid usage list\n", r->lnr); @@ -225,6 +247,8 @@ read_parameters (ctrl_t ctrl, estream_t fp, estream_t out_fp) { "Not-After", pNOTAFTER }, { "Signing-Key", pSIGNINGKEY }, { "Hash-Algo", pHASHALGO }, + { "Subject-Key-Id", pSUBJKEYID }, + { "Extension", pEXTENSION, 1 }, { NULL, 0 } }; char line[1024], *p; @@ -594,6 +618,59 @@ proc_parameters (ctrl_t ctrl, struct para_data_s *para, } } + /* Check the optional SubjectKeyId. */ + string = get_parameter_value (para, pSUBJKEYID, 0); + if (string) + { + for (s=string, i=0; hexdigitp (s); s++, i++) + ; + if (*s || (i&1)) + { + r = get_parameter (para, pSUBJKEYID, 0); + log_error (_("line %d: invalid subject-key-id\n"), r->lnr); + xfree (cardkeyid); + return gpg_error (GPG_ERR_INV_PARAMETER); + } + } + + /* Check the optional extensions. */ + for (seq=0; (string=get_parameter_value (para, pEXTENSION, seq)); seq++) + { + int okay = 0; + + s = strpbrk (string, " \t:"); + if (s) + { + s++; + while (spacep (s)) + s++; + if (*s && strchr ("nNcC", *s)) + { + s++; + while (spacep (s)) + s++; + if (*s == ':') + s++; + if (*s) + { + while (spacep (s)) + s++; + for (i=0; hexdigitp (s); s++, i++) + ; + if (!((*s && *s != ':') || !i || (i&1))) + okay = 1; + } + } + } + if (!okay) + { + r = get_parameter (para, pEXTENSION, seq); + log_error (_("line %d: invalid extension syntax\n"), r->lnr); + xfree (cardkeyid); + return gpg_error (GPG_ERR_INV_PARAMETER); + } + } + /* Create or retrieve the public key. */ if (cardkeyid) /* Take the key from the current smart card. */ { @@ -838,6 +915,14 @@ create_request (ctrl_t ctrl, err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1, "\x03\x02\x04\x30", 4); } + else if (use == GCRY_PK_USAGE_CERT) + { + /* For certify only we encode the bits: + KSBA_KEYUSAGE_KEY_CERT_SIGN + KSBA_KEYUSAGE_CRL_SIGN */ + err = ksba_certreq_add_extension (cr, oidstr_keyUsage, 1, + "\x03\x02\x01\x06", 4); + } else err = 0; /* Both or none given: don't request one. */ if (err) @@ -1009,6 +1094,101 @@ create_request (ctrl_t ctrl, goto leave; } } + + + /* Insert the SubjectKeyId. */ + string = get_parameter_value (para, pSUBJKEYID, 0); + if (string) + { + char *hexbuf; + + /* Allocate a buffer for in-place conversion. We also add 2 + extra bytes space for the tag and length field. */ + hexbuf = xtrymalloc (2 + strlen (string) + 1); + if (!hexbuf) + { + err = gpg_error_from_syserror (); + goto leave; + } + strcpy (hexbuf+2, string); + for (p=hexbuf+2, len=0; p[0] && p[1]; p += 2) + ((unsigned char*)hexbuf)[2+len++] = xtoi_2 (p); + if (len > 127) + { + err = gpg_error (GPG_ERR_TOO_LARGE); + xfree (hexbuf); + goto leave; + } + hexbuf[0] = 0x04; /* Tag for an Octet string. */ + hexbuf[1] = len; + err = ksba_certreq_add_extension (cr, oidstr_subjectKeyIdentifier, 0, + hexbuf, 2+len); + xfree (hexbuf); + if (err) + { + log_error ("error setting the subject-key-id: %s\n", + gpg_strerror (err)); + goto leave; + } + } + + /* Insert additional extensions. */ + for (seq=0; (string = get_parameter_value (para, pEXTENSION, seq)); seq++) + { + char *hexbuf; + char *oidstr; + int crit = 0; + + s = strpbrk (string, " \t:"); + if (!s) + { + err = gpg_error (GPG_ERR_INTERNAL); + goto leave; + } + + oidstr = xtrymalloc (s - string + 1); + if (!oidstr) + { + err = gpg_error_from_syserror (); + goto leave; + } + memcpy (oidstr, string, (s-string)); + oidstr[(s-string)] = 0; + + s++; + while (spacep (s)) + s++; + if (!*s) + { + err = gpg_error (GPG_ERR_INTERNAL); + xfree (oidstr); + goto leave; + } + + if (strchr ("cC", *s)) + crit = 1; + s++; + while (spacep (s)) + s++; + if (*s == ':') + s++; + while (spacep (s)) + s++; + + hexbuf = xtrystrdup (s); + if (!hexbuf) + { + err = gpg_error_from_syserror (); + xfree (oidstr); + goto leave; + } + for (p=hexbuf, len=0; p[0] && p[1]; p += 2) + ((unsigned char*)hexbuf)[len++] = xtoi_2 (p); + err = ksba_certreq_add_extension (cr, oidstr, crit, + hexbuf, len); + xfree (oidstr); + xfree (hexbuf); + } } else sigkey = public; diff --git a/sm/keylist.c b/sm/keylist.c index e67c2d8d3..a5023601f 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -187,6 +187,7 @@ static struct /* GnuPG extensions */ { "1.3.6.1.4.1.11591.2.1.1", "pkaAddress" }, { "1.3.6.1.4.1.11591.2.2.1", "standaloneCertificate" }, + { "1.3.6.1.4.1.11591.2.2.2", "wellKnownPrivateKey" }, /* Extensions used by the Bundesnetzagentur. */ { "1.3.6.1.4.1.8301.3.5", "validityModel" }, From 596b84a4de58def2155d3fe56462f6607f135b69 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 6 Dec 2011 21:43:18 +0100 Subject: [PATCH 32/68] gpgsm: Allow specification of an AuthorityKeyIdentifier. * sm/certreqgen.c (pAUTHKEYID): New. (read_parameters): Add keyword Authority-Key-Id. (proc_parameters): Check its value. (create_request): Insert an Authority-Key-Id. --- sm/certreqgen.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/sm/certreqgen.c b/sm/certreqgen.c index 15fc7a245..de7c39c65 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -85,6 +85,7 @@ enum para_name pNOTAFTER, pSIGNINGKEY, pHASHALGO, + pAUTHKEYID, pSUBJKEYID, pEXTENSION }; @@ -107,6 +108,7 @@ struct reqgen_ctrl_s }; +static const char oidstr_authorityKeyIdentifier[] = "2.5.29.35"; static const char oidstr_subjectKeyIdentifier[] = "2.5.29.14"; static const char oidstr_keyUsage[] = "2.5.29.15"; static const char oidstr_basicConstraints[] = "2.5.29.19"; @@ -247,6 +249,7 @@ read_parameters (ctrl_t ctrl, estream_t fp, estream_t out_fp) { "Not-After", pNOTAFTER }, { "Signing-Key", pSIGNINGKEY }, { "Hash-Algo", pHASHALGO }, + { "Authority-Key-Id", pAUTHKEYID }, { "Subject-Key-Id", pSUBJKEYID }, { "Extension", pEXTENSION, 1 }, { NULL, 0 } @@ -618,6 +621,21 @@ proc_parameters (ctrl_t ctrl, struct para_data_s *para, } } + /* Check the optional AuthorityKeyId. */ + string = get_parameter_value (para, pAUTHKEYID, 0); + if (string) + { + for (s=string, i=0; hexdigitp (s); s++, i++) + ; + if (*s || (i&1)) + { + r = get_parameter (para, pAUTHKEYID, 0); + log_error (_("line %d: invalid authority-key-id\n"), r->lnr); + xfree (cardkeyid); + return gpg_error (GPG_ERR_INV_PARAMETER); + } + } + /* Check the optional SubjectKeyId. */ string = get_parameter_value (para, pSUBJKEYID, 0); if (string) @@ -1095,6 +1113,44 @@ create_request (ctrl_t ctrl, } } + /* Insert the AuthorityKeyId. */ + string = get_parameter_value (para, pAUTHKEYID, 0); + if (string) + { + char *hexbuf; + + /* Allocate a buffer for in-place conversion. We also add 4 + extra bytes space for the tags and lengths fields. */ + hexbuf = xtrymalloc (4 + strlen (string) + 1); + if (!hexbuf) + { + err = gpg_error_from_syserror (); + goto leave; + } + strcpy (hexbuf+4, string); + for (p=hexbuf+4, len=0; p[0] && p[1]; p += 2) + ((unsigned char*)hexbuf)[4+len++] = xtoi_2 (p); + if (len > 125) + { + err = gpg_error (GPG_ERR_TOO_LARGE); + xfree (hexbuf); + goto leave; + } + hexbuf[0] = 0x30; /* Tag for a Sequence. */ + hexbuf[1] = len+2; + hexbuf[2] = 0x80; /* Context tag for an implicit Octet string. */ + hexbuf[3] = len; + err = ksba_certreq_add_extension (cr, oidstr_authorityKeyIdentifier, + 0, + hexbuf, 4+len); + xfree (hexbuf); + if (err) + { + log_error ("error setting the authority-key-id: %s\n", + gpg_strerror (err)); + goto leave; + } + } /* Insert the SubjectKeyId. */ string = get_parameter_value (para, pSUBJKEYID, 0); From cd3732841de32ce5c7841e6e158df3a5f1102f86 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 7 Dec 2011 11:01:39 +0100 Subject: [PATCH 33/68] Allow comments which will not show up in the ChangeLog * scripts/gitlog-to-changelog: Ignore lines after a "--" line. -- The first line with two dashes at the start of a line (optionally followed by white space) stops copying the commit log lines to the ChangeLog entry in "make dist". This is useful to allow adding comments to the log which are not useful in a ChangeLog. --- scripts/gitlog-to-changelog | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/gitlog-to-changelog b/scripts/gitlog-to-changelog index 40a803554..a7ea1948e 100755 --- a/scripts/gitlog-to-changelog +++ b/scripts/gitlog-to-changelog @@ -281,6 +281,15 @@ sub parse_amend_file($) @line = grep !/^Signed-off-by: .*>$/, @line; @line = grep !/^Co-authored-by: /, @line; + # Remove everything after a line with 2 dashes at the beginning. + my @tmpline; + foreach (@line) + { + last if /^--\s*$/; + push @tmpline,$_; + } + @line = @tmpline; + # Remove leading and trailing blank lines. if (@line) { From 14e4fdc9f97d6f12bf563adfff1e3157305d7795 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 7 Dec 2011 11:07:21 +0100 Subject: [PATCH 34/68] Correct punctuation in the ChangeLog summary line. * Makefile.am (gen-ChangeLog): Supply --append-dot. --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index 292748abc..5f9bf2ebf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -116,6 +116,7 @@ gen-ChangeLog: if test -d $(top_srcdir)/.git; then \ (cd $(top_srcdir) && \ ./scripts/gitlog-to-changelog \ + --append-dot \ --amend=scripts/git-log-fix \ --since=$(gen_start_date) ) > $(distdir)/cl-t; \ cat $(top_srcdir)/scripts/git-log-footer >> $(distdir)/cl-t; \ From 8a12a2000d82acfa881e8c18d028290100bf5e43 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 7 Dec 2011 16:15:15 +0100 Subject: [PATCH 35/68] gpgsm: Add new validation model "steed". * sm/gpgsm.h (VALIDATE_FLAG_STEED): New. * sm/gpgsm.c (gpgsm_parse_validation_model): Add model "steed". * sm/server.c (option_handler): Allow validation model "steed". * sm/certlist.c (gpgsm_cert_has_well_known_private_key): New. * sm/certchain.c (do_validate_chain): Handle the well-known-private-key attribute. Support the "steed" model. (gpgsm_validate_chain): Ditto. * sm/verify.c (gpgsm_verify): Return "steed" in the trust status line. * sm/keylist.c (list_cert_colon): Print the new 'w' flag. -- This is the first part of changes to implement the STEED proposal as described at http://g10code.com/steed.html . The idea for X.509 is not to use plain self-signed certificates but certificates signed by a dummy CA (i.e. one for which the private key is known). Having a single CA as an indication for the use of STEED might help other X.509 implementations to implement STEED. --- doc/DETAILS | 5 +++++ doc/gpgsm.texi | 9 ++++---- sm/certchain.c | 61 ++++++++++++++++++++++++++++++++++++++++---------- sm/certlist.c | 17 +++++++++++++- sm/gpgsm.c | 2 ++ sm/gpgsm.h | 7 ++++-- sm/keylist.c | 28 +++++++++++++++-------- sm/server.c | 2 +- sm/verify.c | 2 ++ 9 files changed, 104 insertions(+), 29 deletions(-) diff --git a/doc/DETAILS b/doc/DETAILS index 2e6874e9a..ddf7438f5 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -58,6 +58,10 @@ record; gpg2 does this by default and the option is a dummy. u = The key is ultimately valid. This often means that the secret key is available, but any key may be marked as ultimately valid. + w = The key has a well known private part. + s = The key has special validity. This means that it + might be self-signed and expected to be used in + the STEED sytem. If the validity information is given for a UID or UAT record, it describes the validity calculated based on this @@ -347,6 +351,7 @@ more arguments in future versions. "pgp" for the standard PGP WoT. "shell" for the standard X.509 model. "chain" for the chain model. + "steed" for the STEED model. Note that we use the term "TRUST_" in the status names for historic reasons; we now speak of validity. diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 8e25baf62..bdb03783e 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -451,10 +451,11 @@ address and the time when you verified the signature. @item --validation-model @var{name} @opindex validation-model This option changes the default validation model. The only possible -values are "shell" (which is the default) and "chain" which forces the -use of the chain model. The chain model is also used if an option in -the @file{trustlist.txt} or an attribute of the certificate requests it. -However the standard model (shell) is in that case always tried first. +values are "shell" (which is the default), "chain" which forces the +use of the chain model and "steed" for a new simplified model. The +chain model is also used if an option in the @file{trustlist.txt} or +an attribute of the certificate requests it. However the standard +model (shell) is in that case always tried first. @item --ignore-cert-extension @var{oid} @opindex ignore-cert-extension diff --git a/sm/certchain.c b/sm/certchain.c index 1a2632504..54c7a5772 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -1,6 +1,6 @@ /* certchain.c - certificate chain validation * Copyright (C) 2001, 2002, 2003, 2004, 2005, - * 2006, 2007, 2008 Free Software Foundation, Inc. + * 2006, 2007, 2008, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1193,6 +1193,7 @@ ask_marktrusted (ctrl_t ctrl, ksba_cert_t cert, int listmode) VALIDATE_FLAG_NO_DIRMNGR - Do not do any dirmngr isvalid checks. VALIDATE_FLAG_CHAIN_MODEL - Check according to chain model. + VALIDATE_FLAG_STEED - Check according to the STEED model. */ static int do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, @@ -1305,13 +1306,21 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, We used to do this only later but changed it to call the check right here so that we can access special flags associated with that specific root certificate. */ - istrusted_rc = gpgsm_agent_istrusted (ctrl, subject_cert, NULL, - rootca_flags); + if (gpgsm_cert_has_well_known_private_key (subject_cert)) + { + memset (rootca_flags, 0, sizeof *rootca_flags); + istrusted_rc = ((flags & VALIDATE_FLAG_STEED) + ? 0 : gpg_error (GPG_ERR_NOT_TRUSTED)); + } + else + istrusted_rc = gpgsm_agent_istrusted (ctrl, subject_cert, NULL, + rootca_flags); audit_log_cert (ctrl->audit, AUDIT_ROOT_TRUSTED, subject_cert, istrusted_rc); /* If the chain model extended attribute is used, make sure that our chain model flag is set. */ - if (has_validation_model_chain (subject_cert, listmode, listfp)) + if (!(flags & VALIDATE_FLAG_STEED) + && has_validation_model_chain (subject_cert, listmode, listfp)) rootca_flags->chain_model = 1; } @@ -1383,7 +1392,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, /* Set the flag for qualified signatures. This flag is deduced from a list of root certificates allowed for qualified signatures. */ - if (is_qualified == -1) + if (is_qualified == -1 && !(flags & VALIDATE_FLAG_STEED)) { gpg_error_t err; size_t buflen; @@ -1437,8 +1446,11 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, expired it does not make much sense to ask the user whether we wants to trust the root certificate. We should do this only if the certificate under question - will then be usable. */ + will then be usable. If the certificate has a well + known private key asking the user does not make any + sense. */ if ( !any_expired + && !gpgsm_cert_has_well_known_private_key (subject_cert) && (!listmode || !already_asked_marktrusted (subject_cert)) && ask_marktrusted (ctrl, subject_cert, listmode) ) rc = 0; @@ -1455,6 +1467,8 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, /* Check for revocations etc. */ if ((flags & VALIDATE_FLAG_NO_DIRMNGR)) ; + else if ((flags & VALIDATE_FLAG_STEED)) + ; /* Fixme: check revocations via DNS. */ else if (opt.no_trusted_cert_crl_check || rootca_flags->relax) ; else @@ -1586,8 +1600,16 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, performance reasons. */ if (is_root) { - istrusted_rc = gpgsm_agent_istrusted (ctrl, issuer_cert, NULL, - rootca_flags); + if (gpgsm_cert_has_well_known_private_key (issuer_cert)) + { + memset (rootca_flags, 0, sizeof *rootca_flags); + istrusted_rc = ((flags & VALIDATE_FLAG_STEED) + ? 0 : gpg_error (GPG_ERR_NOT_TRUSTED)); + } + else + istrusted_rc = gpgsm_agent_istrusted + (ctrl, issuer_cert, NULL, rootca_flags); + if (!istrusted_rc && rootca_flags->relax) { /* Ignore the error due to the relax flag. */ @@ -1627,6 +1649,8 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, be fixed. */ if ((flags & VALIDATE_FLAG_NO_DIRMNGR)) rc = 0; + else if ((flags & VALIDATE_FLAG_STEED)) + rc = 0; /* Fixme: XXX */ else if (is_root && (opt.no_trusted_cert_crl_check || (!istrusted_rc && rootca_flags->relax))) rc = 0; @@ -1722,7 +1746,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, capability of the certificate under question, store the result as user data in all certificates of the chain. We do this even if the validation itself failed. */ - if (is_qualified != -1) + if (is_qualified != -1 && !(flags & VALIDATE_FLAG_STEED)) { gpg_error_t err; chain_item_t ci; @@ -1780,8 +1804,8 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, do_validate_chain. This function is a wrapper to handle a root certificate with the chain_model flag set. If RETFLAGS is not NULL, flags indicating now the verification was done are stored - there. The only defined flag for RETFLAGS is - VALIDATE_FLAG_CHAIN_MODEL. + there. The only defined vits for RETFLAGS are + VALIDATE_FLAG_CHAIN_MODEL and VALIDATE_FLAG_STEED. If you are verifying a signature you should set CHECKTIME to the creation time of the signature. If your are verifying a @@ -1801,16 +1825,27 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime, if (!retflags) retflags = &dummy_retflags; + /* If the session requested a certain validation mode make sure the + corresponding flags are set. */ if (ctrl->validation_model == 1) flags |= VALIDATE_FLAG_CHAIN_MODEL; + else if (ctrl->validation_model == 2) + flags |= VALIDATE_FLAG_STEED; + /* If the chain model was forced, set this immediately into + RETFLAGS. */ *retflags = (flags & VALIDATE_FLAG_CHAIN_MODEL); + memset (&rootca_flags, 0, sizeof rootca_flags); rc = do_validate_chain (ctrl, cert, checktime, r_exptime, listmode, listfp, flags, &rootca_flags); - if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED + if (!rc && (flags & VALIDATE_FLAG_STEED)) + { + *retflags |= VALIDATE_FLAG_STEED; + } + else if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED && !(flags & VALIDATE_FLAG_CHAIN_MODEL) && (rootca_flags.valid && rootca_flags.chain_model)) { @@ -1824,6 +1859,8 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime, if (opt.verbose) do_list (0, listmode, listfp, _("validation model used: %s"), + (*retflags & VALIDATE_FLAG_STEED)? + "steed" : (*retflags & VALIDATE_FLAG_CHAIN_MODEL)? _("chain"):_("shell")); diff --git a/sm/certlist.c b/sm/certlist.c index 0e9031953..241364a3a 100644 --- a/sm/certlist.c +++ b/sm/certlist.c @@ -1,6 +1,6 @@ /* certlist.c - build list of certificates * Copyright (C) 2001, 2003, 2004, 2005, 2007, - * 2008 Free Software Foundation, Inc. + * 2008, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -210,6 +210,21 @@ gpgsm_cert_use_ocsp_p (ksba_cert_t cert) } +/* Return true if CERT has the well known private key extension. */ +int +gpgsm_cert_has_well_known_private_key (ksba_cert_t cert) +{ + int idx; + const char *oid; + + for (idx=0; !ksba_cert_get_extension (cert, idx, + &oid, NULL, NULL, NULL);idx++) + if (!strcmp (oid, "1.3.6.1.4.1.11591.2.2.2") ) + return 1; /* Yes. */ + return 0; /* No. */ +} + + static int same_subject_issuer (const char *subject, const char *issuer, ksba_cert_t cert) { diff --git a/sm/gpgsm.c b/sm/gpgsm.c index dc9f2e032..7164f4274 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -2004,6 +2004,8 @@ gpgsm_parse_validation_model (const char *model) return 0; else if ( !ascii_strcasecmp (model, "chain") ) return 1; + else if ( !ascii_strcasecmp (model, "steed") ) + return 2; else return -1; } diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 31cd95150..6c68af746 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -195,7 +195,9 @@ struct server_control_s certificates up the chain (0 = none, 1 = only signer) */ int use_ocsp; /* Set to true if OCSP should be used. */ - int validation_model; /* Set to 1 for the chain model. */ + int validation_model; /* 0 := standard model (shell), + 1 := chain model, + 2 := STEED model. */ }; @@ -307,7 +309,7 @@ int gpgsm_create_cms_signature (ctrl_t ctrl, /* Flags used with gpgsm_validate_chain. */ #define VALIDATE_FLAG_NO_DIRMNGR 1 #define VALIDATE_FLAG_CHAIN_MODEL 2 - +#define VALIDATE_FLAG_STEED 4 int gpgsm_walk_cert_chain (ctrl_t ctrl, ksba_cert_t start, ksba_cert_t *r_next); @@ -326,6 +328,7 @@ int gpgsm_cert_use_verify_p (ksba_cert_t cert); int gpgsm_cert_use_decrypt_p (ksba_cert_t cert); int gpgsm_cert_use_cert_p (ksba_cert_t cert); int gpgsm_cert_use_ocsp_p (ksba_cert_t cert); +int gpgsm_cert_has_well_known_private_key (ksba_cert_t cert); int gpgsm_certs_identical_p (ksba_cert_t cert_a, ksba_cert_t cert_b); int gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert, certlist_t *listaddr, int is_encrypt_to); diff --git a/sm/keylist.c b/sm/keylist.c index a5023601f..42c533a6d 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -1,6 +1,6 @@ /* keylist.c - Print certificates in various formats. - * Copyright (C) 1998, 1999, 2000, 2001, 2003, - * 2004, 2005, 2008, 2009 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2008, 2009, + * 2010, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -421,7 +421,12 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, && *not_after && strcmp (current_time, not_after) > 0 ) *truststring = 'e'; else if (valerr) - *truststring = 'i'; + { + if (gpgsm_cert_has_well_known_private_key (cert)) + *truststring = 'w'; /* Well, this is dummy CA. */ + else + *truststring = 'i'; + } else if (ctrl->with_validation && !is_root) *truststring = 'f'; } @@ -433,12 +438,17 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, { struct rootca_flags_s dummy_flags; - rc = gpgsm_agent_istrusted (ctrl, cert, NULL, &dummy_flags); - if (!rc) - *truststring = 'u'; /* Yes, we trust this one (ultimately). */ - else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED) - *truststring = 'n'; /* No, we do not trust this one. */ - /* (in case of an error we can't tell anything.) */ + if (gpgsm_cert_has_well_known_private_key (cert)) + *truststring = 'w'; /* Well, this is dummy CA. */ + else + { + rc = gpgsm_agent_istrusted (ctrl, cert, NULL, &dummy_flags); + if (!rc) + *truststring = 'u'; /* Yes, we trust this one (ultimately). */ + else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED) + *truststring = 'n'; /* No, we do not trust this one. */ + /* (in case of an error we can't tell anything.) */ + } } if (*truststring) diff --git a/sm/server.c b/sm/server.c index 19c4a1678..385eb538a 100644 --- a/sm/server.c +++ b/sm/server.c @@ -277,7 +277,7 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) else if (!strcmp (key, "validation-model")) { int i = gpgsm_parse_validation_model (value); - if ( i >= 0 && i <= 1 ) + if ( i >= 0 && i <= 2 ) ctrl->validation_model = i; else err = gpg_error (GPG_ERR_ASS_PARAMETER); diff --git a/sm/verify.c b/sm/verify.c index c77eb5744..1173f66d1 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -624,6 +624,8 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) } gpgsm_status (ctrl, STATUS_TRUST_FULLY, + (verifyflags & VALIDATE_FLAG_STEED)? + "0 steed": (verifyflags & VALIDATE_FLAG_CHAIN_MODEL)? "0 chain": "0 shell"); From ea0a21410b8fa460882c0f8de90b9291345fd4fc Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 12 Dec 2011 20:28:58 +0100 Subject: [PATCH 36/68] gitlog-to-changelog: New option --tear-off. * scripts/gitlog-to-changelog: Add option --tear-off. * Makefile.am (gen-ChangeLog): Use that option. --- Makefile.am | 2 +- scripts/gitlog-to-changelog | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Makefile.am b/Makefile.am index 5f9bf2ebf..49ec3fc78 100644 --- a/Makefile.am +++ b/Makefile.am @@ -116,7 +116,7 @@ gen-ChangeLog: if test -d $(top_srcdir)/.git; then \ (cd $(top_srcdir) && \ ./scripts/gitlog-to-changelog \ - --append-dot \ + --append-dot --tear-off \ --amend=scripts/git-log-fix \ --since=$(gen_start_date) ) > $(distdir)/cl-t; \ cat $(top_srcdir)/scripts/git-log-footer >> $(distdir)/cl-t; \ diff --git a/scripts/gitlog-to-changelog b/scripts/gitlog-to-changelog index a7ea1948e..d9f594f86 100755 --- a/scripts/gitlog-to-changelog +++ b/scripts/gitlog-to-changelog @@ -64,6 +64,7 @@ OPTIONS: makes a change to SHA1's commit log text or metadata. --append-dot append a dot to the first line of each commit message if there is no other punctuation or blank at the end. + --tear-off tear off all commit log lines after a '--' line. --since=DATE convert only the logs since DATE; the default is to convert all log entries. --format=FMT set format string for commit subject and body; @@ -175,6 +176,7 @@ sub parse_amend_file($) my $format_string = '%s%n%b%n'; my $amend_file; my $append_dot = 0; + my $tear_off = 0; GetOptions ( help => sub { usage 0 }, @@ -183,6 +185,7 @@ sub parse_amend_file($) 'format=s' => \$format_string, 'amend=s' => \$amend_file, 'append-dot' => \$append_dot, + 'tear-off' => \$tear_off, ) or usage 1; @@ -282,13 +285,16 @@ sub parse_amend_file($) @line = grep !/^Co-authored-by: /, @line; # Remove everything after a line with 2 dashes at the beginning. - my @tmpline; - foreach (@line) - { - last if /^--\s*$/; - push @tmpline,$_; + if ($tear_off) + { + my @tmpline; + foreach (@line) + { + last if /^--\s*$/; + push @tmpline,$_; + } + @line = @tmpline; } - @line = @tmpline; # Remove leading and trailing blank lines. if (@line) From cd29dc0f1cf7f3bd7938ffa65bf13f9a75d8c156 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 12 Dec 2011 20:34:12 +0100 Subject: [PATCH 37/68] Fix detection of card removal and insertion. * scd/apdu.c (apdu_connect): Return status codes for no card available and inactive card. * scd/command.c (TEST_CARD_REMOVAL): Also test for GPG_ERR_CARD_RESET. (open_card): Map apdu_connect status to GPG_ERR_CARD_RESET. --- scd/apdu.c | 15 +++++++++++++-- scd/command.c | 8 +++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/scd/apdu.c b/scd/apdu.c index c130d89bc..ae910825f 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -3051,11 +3051,14 @@ apdu_enum_reader (int slot, int *used) /* Connect a card. This is used to power up the card and make sure - that an ATR is available. */ + that an ATR is available. Depending on the reader backend it may + return an error for an inactive card or if no card is + available. */ int apdu_connect (int slot) { int sw; + unsigned int status; if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; @@ -3080,7 +3083,15 @@ apdu_connect (int slot) 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, NULL, NULL); + apdu_get_status_internal (slot, 1, 1, &status, NULL); + if (sw) + ; + else if (!(status & APDU_CARD_PRESENT)) + sw = SW_HOST_NO_CARD; + else if (((status & APDU_CARD_PRESENT) && !(status & APDU_CARD_ACTIVE)) + || !reader_table[slot].atrlen) + sw = SW_HOST_CARD_INACTIVE; + return sw; } diff --git a/scd/command.c b/scd/command.c index 9bb500523..655032fee 100644 --- a/scd/command.c +++ b/scd/command.c @@ -60,6 +60,7 @@ int _r = (r); \ if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \ || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED \ + || gpg_err_code (_r) == GPG_ERR_CARD_RESET \ || gpg_err_code (_r) == GPG_ERR_ENODEV ) \ update_card_removed ((c)->reader_slot, 1); \ } while (0) @@ -420,9 +421,8 @@ get_reader_slot (void) return 0; } -/* If the card has not yet been opened, do it. Note that this - function returns an Assuan error, so don't map the error a second - time. */ + +/* If the card has not yet been opened, do it. */ static gpg_error_t open_card (ctrl_t ctrl, const char *apptype) { @@ -477,6 +477,8 @@ open_card (ctrl_t ctrl, const char *apptype) { if (sw == SW_HOST_NO_CARD) err = gpg_error (GPG_ERR_CARD_NOT_PRESENT); + else if (sw == SW_HOST_CARD_INACTIVE) + err = gpg_error (GPG_ERR_CARD_RESET); else err = gpg_error (GPG_ERR_CARD); } From 11164662788036c4b15d30555ea33ec0b6f5a670 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 12 Dec 2011 21:02:54 +0100 Subject: [PATCH 38/68] scd: Retry command SERIALNO for an inactive card. * scd/command.c (cmd_serialno): Retry once for an inactive card. --- scd/command.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scd/command.c b/scd/command.c index 655032fee..b2a504cf0 100644 --- a/scd/command.c +++ b/scd/command.c @@ -518,8 +518,10 @@ cmd_serialno (assuan_context_t ctx, char *line) char *serial_and_stamp; char *serial; time_t stamp; + int retries = 0; /* Clear the remove flag so that the open_card is able to reread it. */ + retry: if (!reader_disabled && ctrl->server_local->card_removed) { if ( IS_LOCKED (ctrl) ) @@ -528,7 +530,12 @@ cmd_serialno (assuan_context_t ctx, char *line) } if ((rc = open_card (ctrl, *line? line:NULL))) - return rc; + { + /* In case of an inactive card, retry once. */ + if (gpg_err_code (rc) == GPG_ERR_CARD_RESET && retries++ < 1) + goto retry; + return rc; + } rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp); if (rc) From 24e121ef261731069868ca403b818f1168237f53 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 13 Dec 2011 16:55:42 +0100 Subject: [PATCH 39/68] scd: Introduce a virtual reader table. The vreader table makes the code more clear by explicitly talking about APDU slots and reader indices. It also accommodates for future extensions. * scd/scdaemon.h (server_control_s): Remove READER_SLOT. * scd/scdaemon.c (scd_init_default_ctrl): Do not init READER_SLOT. * scd/app.c (check_application_conflict): Add arg SLOT. * scd/command.c (slot_status_s): Rename to vreader_s. (server_local_s): Add field VREADER_IDX as replacement for the READER_SLOT in server_control_s. Change all users. (slot_table): Rename to vreader_table. Change all users. (vreader_slot): New. (do_reset, cmd_apdu): Map vreader to apdu slot. (get_reader_slot): Rename to get_current_reader. Return -1 on error. (open_card): Map vreader toapdu slot. Pass slot to check_application_conflict. (scd_command_handler): Init VREADER_IDX. (update_reader_status_file): Reset SLOT field on error. --- scd/app-common.h | 3 +- scd/app.c | 7 +- scd/command.c | 213 +++++++++++++++++++++++++++-------------------- scd/scdaemon.c | 2 +- scd/scdaemon.h | 3 - 5 files changed, 129 insertions(+), 99 deletions(-) diff --git a/scd/app-common.h b/scd/app-common.h index 6a1e2a763..e3d23c2b4 100644 --- a/scd/app-common.h +++ b/scd/app-common.h @@ -143,7 +143,8 @@ size_t app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff); /*-- app.c --*/ void app_dump_state (void); void application_notify_card_reset (int slot); -gpg_error_t check_application_conflict (ctrl_t ctrl, const char *name); +gpg_error_t check_application_conflict (ctrl_t ctrl, int slot, + const char *name); gpg_error_t select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app); char *get_supported_applications (void); diff --git a/scd/app.c b/scd/app.c index 6d652360c..6f0d7560b 100644 --- a/scd/app.c +++ b/scd/app.c @@ -213,18 +213,19 @@ application_notify_card_reset (int slot) used to request a specific application and the connection has already done a select_application. */ gpg_error_t -check_application_conflict (ctrl_t ctrl, const char *name) +check_application_conflict (ctrl_t ctrl, int slot, const char *name) { - int slot = ctrl->reader_slot; app_t app; + (void)ctrl; + if (slot < 0 || slot >= DIM (lock_table)) return gpg_error (GPG_ERR_INV_VALUE); app = lock_table[slot].initialized ? lock_table[slot].app : NULL; if (app && app->apptype && name) if ( ascii_strcasecmp (app->apptype, name)) - return gpg_error (GPG_ERR_CONFLICT); + return gpg_error (GPG_ERR_CONFLICT); return 0; } diff --git a/scd/command.c b/scd/command.c index b2a504cf0..2ade38afb 100644 --- a/scd/command.c +++ b/scd/command.c @@ -1,6 +1,6 @@ /* command.c - SCdaemon command handler * Copyright (C) 2001, 2002, 2003, 2004, 2005, - * 2007, 2008, 2009 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -62,32 +62,37 @@ || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED \ || gpg_err_code (_r) == GPG_ERR_CARD_RESET \ || gpg_err_code (_r) == GPG_ERR_ENODEV ) \ - update_card_removed ((c)->reader_slot, 1); \ + update_card_removed ((c)->server_local->vreader_idx, 1); \ } while (0) -#define IS_LOCKED(c) \ - (locked_session && locked_session != (c)->server_local \ - && (c)->reader_slot != -1 && locked_session->ctrl_backlink \ - && (c)->reader_slot == locked_session->ctrl_backlink->reader_slot) +#define IS_LOCKED(c) \ + (locked_session \ + && locked_session != (c)->server_local \ + && (c)->server_local->vreader_idx != -1 \ + && locked_session->ctrl_backlink \ + && ((c)->server_local->vreader_idx \ + == locked_session->ctrl_backlink->server_local->vreader_idx)) /* Flag indicating that the reader has been disabled. */ static int reader_disabled; -/* This structure is used to keep track of open readers (slots). */ -struct slot_status_s +/* This structure is used to keep track of user readers. To + eventually accommodate this structure for RFID cards, where more + than one card is used per reader, we name it virtual reader. */ +struct vreader_s { int valid; /* True if the other objects are valid. */ - int slot; /* Slot number of the reader or -1 if not open. */ + int slot; /* APDU slot number of the reader or -1 if not open. */ int reset_failed; /* A reset failed. */ int any; /* Flag indicating whether any status check has been done. This is set once to indicate that the status tracking for the slot has been initialized. */ - unsigned int status; /* Last status of the slot. */ - unsigned int changed; /* Last change counter of the slot. */ + unsigned int status; /* Last status of the reader. */ + unsigned int changed; /* Last change counter of the reader. */ }; @@ -114,6 +119,9 @@ struct server_local_s int event_signal; /* Or 0 if not used. */ #endif + /* Index into the vreader table (command.c) or -1 if not open. */ + int vreader_idx; + /* True if the card has been removed and a reset is required to continue operation. */ int card_removed; @@ -132,10 +140,8 @@ struct server_local_s }; -/* The table with information on all used slots. FIXME: This is a - different slot number than the one used by the APDU layer, and - should be renamed. */ -static struct slot_status_s slot_table[10]; +/* The table with information on all used virtual readers. */ +static struct vreader_s vreader_table[10]; /* To keep track of all running sessions, we link all active server @@ -174,25 +180,37 @@ initialize_module_command (void) } -/* Update the CARD_REMOVED element of all sessions using the reader - given by SLOT to VALUE. */ +/* Update the CARD_REMOVED element of all sessions using the virtual + reader given by VRDR to VALUE. */ static void -update_card_removed (int slot, int value) +update_card_removed (int vrdr, int value) { struct server_local_s *sl; for (sl=session_list; sl; sl = sl->next_session) if (sl->ctrl_backlink - && sl->ctrl_backlink->reader_slot == slot) + && sl->ctrl_backlink->server_local->vreader_idx == vrdr) { sl->card_removed = value; } /* Let the card application layer know about the removal. */ if (value) - application_notify_card_reset (slot); + application_notify_card_reset (vrdr); } +/* Helper to return the slot number for a given virtual reader index + VRDR. In case on an error -1 is returned. */ +static int +vreader_slot (int vrdr) +{ + if (vrdr == -1 || !(vrdr >= 0 && vrdr < DIM(vreader_table))) + return -1; + if (!vreader_table [vrdr].valid) + return -1; + return vreader_table[vrdr].slot; +} + /* Check whether the option NAME appears in LINE. Returns 1 or 0. */ static int @@ -279,9 +297,9 @@ hex_to_buffer (const char *string, size_t *r_length) static void do_reset (ctrl_t ctrl, int send_reset) { - int slot = ctrl->reader_slot; + int vrdr = ctrl->server_local->vreader_idx; - if (!(slot == -1 || (slot >= 0 && slot < DIM(slot_table)))) + if (!(vrdr == -1 || (vrdr >= 0 && vrdr < DIM(vreader_table)))) BUG (); /* If there is an active application, release it. Tell all other @@ -297,7 +315,7 @@ do_reset (ctrl_t ctrl, int send_reset) for (sl=session_list; sl; sl = sl->next_session) if (sl->ctrl_backlink - && sl->ctrl_backlink->reader_slot == slot) + && sl->ctrl_backlink->server_local->vreader_idx == vrdr) { sl->app_ctx_marked_for_release = 1; } @@ -306,13 +324,13 @@ do_reset (ctrl_t ctrl, int send_reset) /* If we want a real reset for the card, send the reset APDU and tell the application layer about it. */ - if (slot != -1 && send_reset && !IS_LOCKED (ctrl) ) + if (vrdr != -1 && send_reset && !IS_LOCKED (ctrl) ) { - if (apdu_reset (slot)) + if (apdu_reset (vreader_table[vrdr].slot)) { - slot_table[slot].valid = 0; + vreader_table[vrdr].valid = 0; } - application_notify_card_reset (slot); + application_notify_card_reset (vrdr); } /* If we hold a lock, unlock now. */ @@ -325,21 +343,21 @@ do_reset (ctrl_t ctrl, int send_reset) /* Reset the card removed flag for the current reader. We need to take the lock here so that the ticker thread won't concurrently try to update the file. Calling update_reader_status_file is - required to get hold of the new status of the card in the slot + required to get hold of the new status of the card in the vreader table. */ if (!pth_mutex_acquire (&status_file_update_lock, 0, NULL)) { - log_error ("failed to acquire status_fle_update lock\n"); - ctrl->reader_slot = -1; + log_error ("failed to acquire status_file_update lock\n"); + ctrl->server_local->vreader_idx = -1; return; } update_reader_status_file (0); /* Update slot status table. */ - update_card_removed (slot, 0); /* Clear card_removed flag. */ + update_card_removed (vrdr, 0); /* Clear card_removed flag. */ if (!pth_mutex_release (&status_file_update_lock)) log_error ("failed to release status_file_update lock\n"); /* Do this last, so that the update_card_removed above does its job. */ - ctrl->reader_slot = -1; + ctrl->server_local->vreader_idx = -1; } @@ -379,35 +397,38 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) } -/* Return the slot of the current reader or open the reader if no - other sessions are using a reader. Note, that we currently support +/* Return the index of the current reader or open the reader if no + other sessions are using that reader. If it is not possible to + open the reader -1 is returned. Note, that we currently support only one reader but most of the code (except for this function) should be able to cope with several readers. */ static int -get_reader_slot (void) +get_current_reader (void) { - struct slot_status_s *ss; + struct vreader_s *vr; - ss = &slot_table[0]; /* One reader for now. */ + /* We only support one reader for now. */ + vr = &vreader_table[0]; - /* Initialize the item if needed. */ - if (!ss->valid) + /* Initialize the vreader item if not yet done. */ + if (!vr->valid) { - ss->slot = -1; - ss->valid = 1; + vr->slot = -1; + vr->valid = 1; } /* Try to open the reader. */ - if (ss->slot == -1) + if (vr->slot == -1) { int no_service_flag; - ss->slot = apdu_open_reader (opt.reader_port, &no_service_flag); + + vr->slot = apdu_open_reader (opt.reader_port, &no_service_flag); /* If we still don't have a slot, we have no readers. Invalidate for now until a reader is attached. */ - if(ss->slot == -1) + if (vr->slot == -1) { - ss->valid = 0; + vr->valid = 0; } if (no_service_flag) @@ -417,8 +438,8 @@ get_reader_slot (void) } } - /* Return the slot_table index. */ - return 0; + /* Return the vreader index or -1. */ + return vr->valid ? 0 : -1; } @@ -427,7 +448,7 @@ static gpg_error_t open_card (ctrl_t ctrl, const char *apptype) { gpg_error_t err; - int slot; + int vrdr; if (reader_disabled) return gpg_error (GPG_ERR_NOT_OPERATIONAL); @@ -455,21 +476,25 @@ open_card (ctrl_t ctrl, const char *apptype) need to check that the client didn't requested a specific application different from the one in use before we continue. */ if (ctrl->app_ctx) - return check_application_conflict (ctrl, apptype); + { + return check_application_conflict + (ctrl, vreader_slot (ctrl->server_local->vreader_idx), apptype); + } - /* Setup the slot and select the application. */ - if (ctrl->reader_slot != -1) - slot = ctrl->reader_slot; + /* Setup the vreader and select the application. */ + if (ctrl->server_local->vreader_idx != -1) + vrdr = ctrl->server_local->vreader_idx; else - slot = get_reader_slot (); - ctrl->reader_slot = slot; - if (slot == -1) + vrdr = get_current_reader (); + ctrl->server_local->vreader_idx = vrdr; + if (vrdr == -1) err = gpg_error (reader_disabled? GPG_ERR_NOT_OPERATIONAL: GPG_ERR_CARD); else { /* Fixme: We should move the apdu_connect call to select_application. */ int sw; + int slot = vreader_slot (vrdr); ctrl->server_local->disconnect_allowed = 0; sw = apdu_connect (slot); @@ -1615,8 +1640,8 @@ static const char hlp_getinfo[] = "\n" "socket_name - Return the name of the socket.\n" "\n" - "status - Return the status of the current slot (in the future, may\n" - "also return the status of all slots). The status is a list of\n" + "status - Return the status of the current reader (in the future, may\n" + "also return the status of all readers). The status is a list of\n" "one-character flags. The following flags are currently defined:\n" " 'u' Usable card present. This is the normal state during operation.\n" " 'r' Card removed. A reset is necessary.\n" @@ -1660,22 +1685,22 @@ cmd_getinfo (assuan_context_t ctx, char *line) else if (!strcmp (line, "status")) { ctrl_t ctrl = assuan_get_pointer (ctx); - int slot = ctrl->reader_slot; + int vrdr = ctrl->server_local->vreader_idx; char flag = 'r'; - if (!ctrl->server_local->card_removed && slot != -1) + if (!ctrl->server_local->card_removed && vrdr != -1) { - struct slot_status_s *ss; + struct vreader_s *vr; - if (!(slot >= 0 && slot < DIM(slot_table))) + if (!(vrdr >= 0 && vrdr < DIM(vreader_table))) BUG (); - ss = &slot_table[slot]; + vr = &vreader_table[vrdr]; - if (!ss->valid) + if (!vr->valid) BUG (); - if (ss->any && (ss->status & 1)) + if (vr->any && (vr->status & 1)) flag = 'u'; } rc = assuan_send_data (ctx, &flag, 1); @@ -1790,6 +1815,7 @@ cmd_apdu (assuan_context_t ctx, char *line) int handle_more; const char *s; size_t exlen; + int slot; with_atr = has_option (line, "--atr"); handle_more = has_option (line, "--more"); @@ -1812,13 +1838,15 @@ cmd_apdu (assuan_context_t ctx, char *line) if ((rc = open_card (ctrl, NULL))) return rc; + slot = vreader_slot (ctrl->server_local->vreader_idx); + if (with_atr) { unsigned char *atr; size_t atrlen; char hexbuf[400]; - atr = apdu_get_atr (ctrl->reader_slot, &atrlen); + atr = apdu_get_atr (slot, &atrlen); if (!atr || atrlen > sizeof hexbuf - 2 ) { rc = gpg_error (GPG_ERR_INV_CARD); @@ -1840,7 +1868,7 @@ cmd_apdu (assuan_context_t ctx, char *line) unsigned char *result = NULL; size_t resultlen; - rc = apdu_send_direct (ctrl->reader_slot, exlen, + rc = apdu_send_direct (slot, exlen, apdu, apdulen, handle_more, &result, &resultlen); if (rc) @@ -1990,12 +2018,13 @@ scd_command_handler (ctrl_t ctrl, int fd) session_list = ctrl->server_local; ctrl->server_local->ctrl_backlink = ctrl; ctrl->server_local->assuan_ctx = ctx; + ctrl->server_local->vreader_idx = -1; /* We open the reader right at startup so that the ticker is able to update the status file. */ - if (ctrl->reader_slot == -1) + if (ctrl->server_local->vreader_idx == -1) { - ctrl->reader_slot = get_reader_slot (); + ctrl->server_local->vreader_idx = get_current_reader (); } /* Command processing loop. */ @@ -2197,32 +2226,33 @@ update_reader_status_file (int set_card_removed_flag) int idx; unsigned int status, changed; - /* Make sure that the reader has been opened. Like get_reader_slot, + /* Make sure that a reader has been opened. Like get_current_reader, this part of the code assumes that there is only one reader. */ - if (!slot_table[0].valid) - (void)get_reader_slot (); + if (!vreader_table[0].valid) + (void)get_current_reader (); /* Note, that we only try to get the status, because it does not make sense to wait here for a operation to complete. If we are busy working with a card, delays in the status file update should be acceptable. */ - for (idx=0; idx < DIM(slot_table); idx++) + for (idx=0; idx < DIM(vreader_table); idx++) { - struct slot_status_s *ss = slot_table + idx; + struct vreader_s *vr = vreader_table + idx; struct server_local_s *sl; int sw_apdu; - if (!ss->valid || ss->slot == -1) + if (!vr->valid || vr->slot == -1) continue; /* Not valid or reader not yet open. */ - sw_apdu = apdu_get_status (ss->slot, 0, &status, &changed); + sw_apdu = apdu_get_status (vr->slot, 0, &status, &changed); if (sw_apdu == SW_HOST_NO_READER) { /* Most likely the _reader_ has been unplugged. */ - apdu_close_reader(ss->slot); - ss->valid = 0; + apdu_close_reader (vr->slot); + vr->slot = -1; + vr->valid = 0; status = 0; - changed = ss->changed; + changed = vr->changed; } else if (sw_apdu) { @@ -2230,21 +2260,21 @@ update_reader_status_file (int set_card_removed_flag) continue; } - if (!ss->any || ss->status != status || ss->changed != changed ) + if (!vr->any || vr->status != status || vr->changed != changed ) { char *fname; char templ[50]; FILE *fp; - log_info ("updating slot %d status: 0x%04X->0x%04X (%u->%u)\n", - ss->slot, ss->status, status, ss->changed, changed); - ss->status = status; - ss->changed = changed; + log_info ("updating reader %d (%d) status: 0x%04X->0x%04X (%u->%u)\n", + idx, vr->slot, vr->status, status, vr->changed, changed); + vr->status = status; + vr->changed = changed; - /* FIXME: Should this be IDX instead of ss->slot? This + /* FIXME: Should this be IDX instead of vr->slot? This depends on how client sessions will associate the reader status with their session. */ - snprintf (templ, sizeof templ, "reader_%d.status", ss->slot); + snprintf (templ, sizeof templ, "reader_%d.status", vr->slot); fname = make_filename (opt.homedir, templ, NULL ); fp = fopen (fname, "w"); if (fp) @@ -2272,8 +2302,8 @@ update_reader_status_file (int set_card_removed_flag) envs[0] = envstr; envs[1] = NULL; - sprintf (numbuf1, "%d", ss->slot); - sprintf (numbuf2, "0x%04X", ss->status); + sprintf (numbuf1, "%d", vr->slot); + sprintf (numbuf2, "0x%04X", vr->status); sprintf (numbuf3, "0x%04X", status); args[0] = "--reader-port"; args[1] = numbuf1; @@ -2301,10 +2331,10 @@ update_reader_status_file (int set_card_removed_flag) /* Set the card removed flag for all current sessions. We will set this on any card change because a reset or SERIALNO request must be done in any case. */ - if (ss->any && set_card_removed_flag) + if (vr->any && set_card_removed_flag) update_card_removed (idx, 1); - ss->any = 1; + vr->any = 1; /* Send a signal to all clients who applied for it. */ send_client_notifications (); @@ -2320,8 +2350,9 @@ update_reader_status_file (int set_card_removed_flag) { /* FIXME: Use a real timeout. */ /* At least one connection and all allow a disconnect. */ - log_info ("disconnecting card in slot %d\n", ss->slot); - apdu_disconnect (ss->slot); + log_info ("disconnecting card in reader %d (%d)\n", + idx, vr->slot); + apdu_disconnect (vr->slot); } } diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 0999847ef..b4eee396e 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -913,7 +913,7 @@ scd_exit (int rc) static void scd_init_default_ctrl (ctrl_t ctrl) { - ctrl->reader_slot = -1; + (void)ctrl; } static void diff --git a/scd/scdaemon.h b/scd/scdaemon.h index 0cf2f249d..4c0a66330 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -97,9 +97,6 @@ struct server_control_s /* Local data of the server; used only in command.c. */ struct server_local_s *server_local; - /* Slot of the open reader or -1 if not open. */ - int reader_slot; - /* The application context used with this connection or NULL if none associated. Note that this is shared with the other connections: All connections accessing the same reader are using the same From 00c760f628f4cf0fc11e79d305c172f98123f815 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 13 Dec 2011 17:59:00 +0100 Subject: [PATCH 40/68] scd: New option --debug-assuan-log-cats. * scd/scdaemon.c (oDebugAssuanLogCats): New. (opts): Add option --debug-assuan-log-cats. (main): Implement option. * common/asshelp.c (set_libassuan_log_cats): New. -- The old way of setting the logging categories with an environment variable is awkward if sdaemon is spawned from a running gpg-agent. --- common/asshelp.c | 13 +++++++++++++ common/asshelp.h | 1 + doc/scdaemon.texi | 47 ++++++++++++++++++++++++++++------------------- scd/scdaemon.c | 5 +++++ 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/common/asshelp.c b/common/asshelp.c index c5d8bdf84..7ac6ff0cc 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -97,6 +97,19 @@ setup_libassuan_logging (unsigned int *debug_var_address) assuan_set_log_cb (my_libassuan_log_handler, debug_var_address); } +/* Change the Libassuan log categories to those given by NEWCATS. + NEWCATS is 0 the default category of ASSUAN_LOG_CONTROL is + selected. Note, that setup_libassuan_logging overrides the values + given here. */ +void +set_libassuan_log_cats (unsigned int newcats) +{ + if (newcats) + log_cats = newcats; + else /* Default to log the control channel. */ + log_cats = (1 << (ASSUAN_LOG_CONTROL - 1)); +} + static gpg_error_t diff --git a/common/asshelp.h b/common/asshelp.h index 0eb6553f9..728c03949 100644 --- a/common/asshelp.h +++ b/common/asshelp.h @@ -26,6 +26,7 @@ #include "session-env.h" void setup_libassuan_logging (unsigned int *debug_var_address); +void set_libassuan_log_cats (unsigned int newcats); gpg_error_t diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index 3c8427997..9184ce202 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -21,16 +21,16 @@ .IR dir ] .RB [ \-\-options .IR file ] -.RI [ options ] -.B \-\-server +.RI [ options ] +.B \-\-server .br .B scdaemon .RB [ \-\-homedir .IR dir ] .RB [ \-\-options .IR file ] -.RI [ options ] -.B \-\-daemon +.RI [ options ] +.B \-\-daemon .RI [ command_line ] @end ifset @@ -130,7 +130,7 @@ a numeric value or a keyword: @item none No debugging at all. A value of less than 1 may be used instead of the keyword. -@item basic +@item basic Some basic debug messages. A value between 1 and 2 may be used instead of the keyword. @item advanced @@ -165,8 +165,8 @@ usual C-Syntax. The currently defined bits are: @table @code @item 0 (1) command I/O -@item 1 (2) -values of big number integers +@item 1 (2) +values of big number integers @item 2 (4) low level crypto operations @item 5 (32) @@ -178,7 +178,7 @@ show memory statistics. @item 9 (512) write hashed data to files named @code{dbgmd-000*} @item 10 (1024) -trace Assuan protocol +trace Assuan protocol. See also option @option{--debug-assuan-log-cats}. @item 11 (2048) trace APDU I/O to the card. This may reveal sensitive data. @end table @@ -215,6 +215,15 @@ dump. This options enables it and also changes the working directory to @opindex debug-log-tid This option appends a thread ID to the PID in the log output. +@item --debug-assuan-log-cats @var{cats} +@opindex debug-assuan-log-cats +Changes the active Libassuan logging categories to @var{cats}. The +value for @var{cats} is an unsigned integer given in usual C-Syntax. +A value of of 0 switches to a default category. If this option is not +used the categories are taken from the environment variable +@samp{ASSUAN_DEBUG}. Note that this option has only an effect if the +Assuan debug flag has also been with the option @option{--debug}. For +a list of categories see the Libassuan manual. @item --no-detach @opindex no-detach @@ -240,7 +249,7 @@ Use @var{library} to access the smartcard reader. The current default is @file{libtowitoko.so}. Note that the use of this interface is deprecated; it may be removed in future releases. -@item --disable-ccid +@item --disable-ccid @opindex disable-ccid Disable the integrated support for CCID compliant readers. This allows to fall back to one of the other drivers even if the internal @@ -325,7 +334,7 @@ stripping off the two leading dashes. This application is currently only used by @command{gpg} but may in future also be useful with @command{gpgsm}. Version 1 and version 2 of -the card is supported. +the card is supported. The specifications for these cards are available at @uref{http://g10code.com/docs/openpgp-card-1.0.pdf} and @@ -395,7 +404,7 @@ about reader status changes. Its use is now deprecated in favor of @end table -@c +@c @c Examples @c @mansect examples @@ -410,7 +419,7 @@ $ scdaemon --server -v @c man end -@c +@c @c Assuan Protocol @c @manpause @@ -447,7 +456,7 @@ synchronizing access to a token between sessions. * Scdaemon APDU:: Send a verbatim APDU to the card @end menu -@node Scdaemon SERIALNO +@node Scdaemon SERIALNO @subsection Return the serial number This command should be used to check for the presence of a card. It is @@ -470,7 +479,7 @@ Return the serial number of the card using a status response like: @end example The trailing 0 should be ignored for now, it is reserved for a future -extension. The serial number is the hex encoded value identified by +extension. The serial number is the hex encoded value identified by the @code{0x5A} tag in the GDO file (FIX=0x2F02). @@ -522,7 +531,7 @@ READKEY @var{hexified_certid} @end example Return the public key for the given cert or key ID as an standard -S-Expression. +S-Expression. @@ -619,7 +628,7 @@ TO BE WRITTEN. @example PASSWD [--reset] [--nullpin] @var{chvno} @end example - + Change the PIN or reset the retry counter of the card holder verification vector number @var{chvno}. The option @option{--nullpin} is used to initialize the PIN of TCOS cards (6 byte NullPIN only). @@ -663,11 +672,11 @@ and only if the retry counter is still at 3. Restart the current connection; this is a kind of warm reset. It deletes the context used by this connection but does not actually -reset the card. +reset the card. This is used by gpg-agent to reuse a primary pipe connection and may be used by clients to backup from a conflict in the serial -command; i.e. to select another application. +command; i.e. to select another application. @@ -704,7 +713,7 @@ length up to N bytes. If N is not given a default value is used @mansect see also @ifset isman @command{gpg-agent}(1), -@command{gpgsm}(1), +@command{gpgsm}(1), @command{gpg2}(1) @end ifset @include see-also-note.texi diff --git a/scd/scdaemon.c b/scd/scdaemon.c index b4eee396e..c8905d4f0 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -72,6 +72,7 @@ enum cmd_and_opt_values oDebugAllowCoreDump, oDebugCCIDDriver, oDebugLogTid, + oDebugAssuanLogCats, oNoGreeting, oNoOptions, oHomedir, @@ -121,6 +122,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_n (oDebugCCIDDriver, "debug-ccid-driver", "@"), ARGPARSE_s_n (oDebugDisableTicker, "debug-disable-ticker", "@"), ARGPARSE_s_n (oDebugLogTid, "debug-log-tid", "@"), + ARGPARSE_p_u (oDebugAssuanLogCats, "debug-assuan-log-cats", "@"), ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")), ARGPARSE_s_s (oLogFile, "log-file", N_("|FILE|write a log to FILE")), ARGPARSE_s_s (oReaderPort, "reader-port", @@ -553,6 +555,9 @@ main (int argc, char **argv ) case oDebugLogTid: log_set_pid_suffix_cb (tid_log_callback); break; + case oDebugAssuanLogCats: + set_libassuan_log_cats (pargs.r.ret_ulong); + break; case oOptions: /* config files may not be nested (silently ignore them) */ From 07ea8c56b507b06d4bd70e94fa51914659afac4b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 14 Dec 2011 10:21:15 +0100 Subject: [PATCH 41/68] scd: Add debug option for reader function calls. * scd/scdaemon.h (DBG_READER_VALUE, DBG_READER): New. * scd/apdu.c (apdu_open_reader, apdu_close_reader) (apdu_shutdown_reader, apdu_connect, apdu_disconnect) (apdu_reset, apdu_get_atr, apdu_get_status): Add debug code. (apdu_activate): Remove this unused function. --- scd/apdu.c | 205 +++++++++++++++++++++++++++++++++---------------- scd/apdu.h | 1 - scd/scdaemon.h | 4 +- 3 files changed, 143 insertions(+), 67 deletions(-) diff --git a/scd/apdu.c b/scd/apdu.c index ae910825f..c37e8c4c3 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -2772,6 +2772,9 @@ apdu_open_reader (const char *portstr, int *r_no_service) static int pcsc_api_loaded, ct_api_loaded; int slot; + if (DBG_READER) + log_debug ("enter: apdu_open_reader: portstr=%s\n", portstr); + if (r_no_service) *r_no_service = 0; @@ -2786,6 +2789,8 @@ apdu_open_reader (const char *portstr, int *r_no_service) if (slot != -1) { once_available = 1; + if (DBG_READER) + log_debug ("leave: apdu_open_reader => slot=%d [ccid]\n", slot); return slot; /* got one */ } @@ -2796,14 +2801,22 @@ apdu_open_reader (const char *portstr, int *r_no_service) and over again. To reset this flag "gpgconf --kill scdaemon" can be used. */ if (once_available) - return -1; + { + if (DBG_READER) + log_debug ("leave: apdu_open_reader => slot=-1 (once_avail)\n"); + return -1; + } /* If a CCID reader specification has been given, the user does not want a fallback to other drivers. */ if (portstr) for (s=portstr, i=0; *s; s++) if (*s == ':' && (++i == 3)) - return -1; + { + if (DBG_READER) + log_debug ("leave: apdu_open_reader => slot=-1 (no ccid)\n"); + return -1; + } } #endif /* HAVE_LIBUSB */ @@ -2928,6 +2941,8 @@ apdu_open_reader (const char *portstr, int *r_no_service) if (slot == -1 && r_no_service && pcsc_no_service) *r_no_service = 1; + if (DBG_READER) + log_debug ("leave: apdu_open_reader => slot=%d [pc/sc]\n", slot); return slot; } @@ -2982,13 +2997,31 @@ apdu_close_reader (int slot) { int sw; + if (DBG_READER) + log_debug ("enter: apdu_close_reader: slot=%d\n", slot); + if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; + { + if (DBG_READER) + log_debug ("leave: apdu_close_reader => SW_HOST_NO_DRIVER\n"); + return SW_HOST_NO_DRIVER; + } sw = apdu_disconnect (slot); if (sw) - return sw; + { + if (DBG_READER) + log_debug ("leave: apdu_close_reader => 0x%x (apdu_disconnect)\n", sw); + return sw; + } if (reader_table[slot].close_reader) - return reader_table[slot].close_reader (slot); + { + sw = reader_table[slot].close_reader (slot); + if (DBG_READER) + log_debug ("leave: apdu_close_reader => 0x%x (close_reader)\n", sw); + return sw; + } + if (DBG_READER) + log_debug ("leave: apdu_close_reader => SW_HOST_NOT_SUPPORTED\n"); return SW_HOST_NOT_SUPPORTED; } @@ -3027,13 +3060,32 @@ apdu_shutdown_reader (int slot) { int sw; + if (DBG_READER) + log_debug ("enter: apdu_shutdown_reader: slot=%d\n", slot); + if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; + { + if (DBG_READER) + log_debug ("leave: apdu_shutdown_reader => SW_HOST_NO_DRIVER\n"); + return SW_HOST_NO_DRIVER; + } sw = apdu_disconnect (slot); if (sw) - return sw; + { + if (DBG_READER) + log_debug ("leave: apdu_shutdown_reader => 0x%x (apdu_disconnect)\n", + sw); + return sw; + } if (reader_table[slot].shutdown_reader) - return reader_table[slot].shutdown_reader (slot); + { + sw = reader_table[slot].shutdown_reader (slot); + if (DBG_READER) + log_debug ("leave: apdu_shutdown_reader => 0x%x (close_reader)\n", sw); + return sw; + } + if (DBG_READER) + log_debug ("leave: apdu_shutdown_reader => SW_HOST_NOT_SUPPORTED\n"); return SW_HOST_NOT_SUPPORTED; } @@ -3060,8 +3112,15 @@ apdu_connect (int slot) int sw; unsigned int status; + if (DBG_READER) + log_debug ("enter: apdu_connect: slot=%d\n", slot); + if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; + { + if (DBG_READER) + log_debug ("leave: apdu_connect => SW_HOST_NO_DRIVER\n"); + return SW_HOST_NO_DRIVER; + } /* Only if the access method provides a connect function we use it. If not, we expect that the card has been implicitly connected by @@ -3092,6 +3151,8 @@ apdu_connect (int slot) || !reader_table[slot].atrlen) sw = SW_HOST_CARD_INACTIVE; + if (DBG_READER) + log_debug ("leave: apdu_connect => sw=0x%x\n", sw); return sw; } @@ -3102,8 +3163,15 @@ apdu_disconnect (int slot) { int sw; + if (DBG_READER) + log_debug ("enter: apdu_disconnect: slot=%d\n", slot); + if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; + { + if (DBG_READER) + log_debug ("leave: apdu_disconnect => SW_HOST_NO_DRIVER\n"); + return SW_HOST_NO_DRIVER; + } if (reader_table[slot].disconnect_card) { @@ -3116,6 +3184,9 @@ apdu_disconnect (int slot) } else sw = 0; + + if (DBG_READER) + log_debug ("leave: apdu_disconnect => sw=0x%x\n", sw); return sw; } @@ -3151,11 +3222,22 @@ apdu_reset (int slot) { int sw; + if (DBG_READER) + log_debug ("enter: apdu_reset: slot=%d\n", slot); + if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; + { + if (DBG_READER) + log_debug ("leave: apdu_reset => SW_HOST_NO_DRIVER\n"); + return SW_HOST_NO_DRIVER; + } if ((sw = lock_slot (slot))) - return sw; + { + if (DBG_READER) + log_debug ("leave: apdu_reset => sw=0x%x (lock_slot)\n", sw); + return sw; + } reader_table[slot].last_status = 0; if (reader_table[slot].reset_reader) @@ -3171,73 +3253,47 @@ apdu_reset (int slot) } unlock_slot (slot); + if (DBG_READER) + log_debug ("leave: apdu_reset => sw=0x%x\n", sw); return sw; } -/* Activate a card if it has not yet been done. This is a kind of - reset-if-required. It is useful to test for presence of a card - before issuing a bunch of apdu commands. It does not wait on a - locked card. */ -int -apdu_activate (int slot) -{ - int sw; - unsigned int s; - - if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return SW_HOST_NO_DRIVER; - - if ((sw = trylock_slot (slot))) - return sw; - - if (reader_table[slot].get_status_reader) - sw = reader_table[slot].get_status_reader (slot, &s); - - if (!sw) - { - if (!(s & 2)) /* Card not present. */ - sw = SW_HOST_NO_CARD; - else if ( ((s & 2) && !(s & 4)) - || !reader_table[slot].atrlen ) - { - /* We don't have an ATR or a card is present though inactive: - do a reset now. */ - if (reader_table[slot].reset_reader) - { - reader_table[slot].last_status = 0; - sw = reader_table[slot].reset_reader (slot); - if (!sw) - { - /* If we got to here we know that a card is present - and usable. Thus remember this. */ - reader_table[slot].last_status = (APDU_CARD_USABLE - | APDU_CARD_PRESENT - | APDU_CARD_ACTIVE); - } - } - } - } - - unlock_slot (slot); - return sw; -} - - +/* Return the ATR or NULL if none is available. On success the length + of the ATR is stored at ATRLEN. The caller must free the returned + value. */ unsigned char * apdu_get_atr (int slot, size_t *atrlen) { unsigned char *buf; + if (DBG_READER) + log_debug ("enter: apdu_get_atr: slot=%d\n", slot); + if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) - return NULL; + { + if (DBG_READER) + log_debug ("leave: apdu_get_atr => NULL (bad slot)\n"); + return NULL; + } if (!reader_table[slot].atrlen) - return NULL; + { + if (DBG_READER) + log_debug ("leave: apdu_get_atr => NULL (no ATR)\n"); + return NULL; + } + buf = xtrymalloc (reader_table[slot].atrlen); if (!buf) - return NULL; + { + if (DBG_READER) + log_debug ("leave: apdu_get_atr => NULL (out of core)\n"); + return NULL; + } memcpy (buf, reader_table[slot].atr, reader_table[slot].atrlen); *atrlen = reader_table[slot].atrlen; + if (DBG_READER) + log_debug ("leave: apdu_get_atr => atrlen=%zu\n", *atrlen); return buf; } @@ -3308,7 +3364,26 @@ int apdu_get_status (int slot, int hang, unsigned int *status, unsigned int *changed) { - return apdu_get_status_internal (slot, hang, 0, status, changed); + int sw; + + if (DBG_READER) + log_debug ("enter: apdu_get_status: slot=%d hang=%d\n", slot, hang); + sw = apdu_get_status_internal (slot, hang, 0, status, changed); + if (DBG_READER) + { + if (status && changed) + log_debug ("leave: apdu_get_status => sw=0x%x status=%u changecnt=%u\n", + sw, *status, *changed); + else if (status) + log_debug ("leave: apdu_get_status => sw=0x%x status=%u\n", + sw, *status); + else if (changed) + log_debug ("leave: apdu_get_status => sw=0x%x changed=%u\n", + sw, *changed); + else + log_debug ("leave: apdu_get_status => sw=0x%x\n", sw); + } + return sw; } diff --git a/scd/apdu.h b/scd/apdu.h index ac1eeeb3b..f70425620 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -108,7 +108,6 @@ int apdu_disconnect (int slot); int apdu_set_progress_cb (int slot, gcry_handler_progress_t cb, void *cb_arg); -int apdu_activate (int slot); int apdu_reset (int slot); int apdu_get_status (int slot, int hang, unsigned int *status, unsigned int *changed); diff --git a/scd/scdaemon.h b/scd/scdaemon.h index 4c0a66330..74e8b7d44 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -72,8 +72,9 @@ struct #define DBG_CACHE_VALUE 64 /* debug the caching */ #define DBG_MEMSTAT_VALUE 128 /* show memory statistics */ #define DBG_HASHING_VALUE 512 /* debug hashing operations */ -#define DBG_ASSUAN_VALUE 1024 +#define DBG_ASSUAN_VALUE 1024 #define DBG_CARD_IO_VALUE 2048 +#define DBG_READER_VALUE 4096 /* Trace reader related functions. */ #define DBG_COMMAND (opt.debug & DBG_COMMAND_VALUE) #define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE) @@ -82,6 +83,7 @@ struct #define DBG_HASHING (opt.debug & DBG_HASHING_VALUE) #define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE) #define DBG_CARD_IO (opt.debug & DBG_CARD_IO_VALUE) +#define DBG_READER (opt.debug & DBG_READER_VALUE) struct server_local_s; struct app_ctx_s; From 2d91febbd8d30beb7eb33f7aa80ffd5691d1d3cc Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 14 Dec 2011 10:30:01 +0100 Subject: [PATCH 42/68] scd: Fix resetting and closing of the reader. * scd/command.c (update_card_removed): Do no act on an invalid VRDR. (do_reset): Ignore apdu_reset error codes for no and inactive card. Close the reader before setting the slot to -1. (update_reader_status_file): Notify the application before closing the reader. -- With this change the scd now works as it did in the past. In particular there is no more endless loop trying to open the reader by the update_reader_status_file ticker function. That bug basically blocked all card operations until the scdaemon was killed. --- scd/command.c | 67 +++++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/scd/command.c b/scd/command.c index 2ade38afb..0f5744829 100644 --- a/scd/command.c +++ b/scd/command.c @@ -180,25 +180,6 @@ initialize_module_command (void) } -/* Update the CARD_REMOVED element of all sessions using the virtual - reader given by VRDR to VALUE. */ -static void -update_card_removed (int vrdr, int value) -{ - struct server_local_s *sl; - - for (sl=session_list; sl; sl = sl->next_session) - if (sl->ctrl_backlink - && sl->ctrl_backlink->server_local->vreader_idx == vrdr) - { - sl->card_removed = value; - } - /* Let the card application layer know about the removal. */ - if (value) - application_notify_card_reset (vrdr); -} - - /* Helper to return the slot number for a given virtual reader index VRDR. In case on an error -1 is returned. */ static int @@ -212,6 +193,28 @@ vreader_slot (int vrdr) } +/* Update the CARD_REMOVED element of all sessions using the virtual + reader given by VRDR to VALUE. */ +static void +update_card_removed (int vrdr, int value) +{ + struct server_local_s *sl; + + if (vrdr == -1) + return; + + for (sl=session_list; sl; sl = sl->next_session) + if (sl->ctrl_backlink + && sl->ctrl_backlink->server_local->vreader_idx == vrdr) + { + sl->card_removed = value; + } + /* Let the card application layer know about the removal. */ + if (value) + application_notify_card_reset (vreader_slot (vrdr)); +} + + /* Check whether the option NAME appears in LINE. Returns 1 or 0. */ static int has_option (const char *line, const char *name) @@ -298,6 +301,7 @@ static void do_reset (ctrl_t ctrl, int send_reset) { int vrdr = ctrl->server_local->vreader_idx; + int slot; if (!(vrdr == -1 || (vrdr >= 0 && vrdr < DIM(vreader_table)))) BUG (); @@ -324,13 +328,22 @@ do_reset (ctrl_t ctrl, int send_reset) /* If we want a real reset for the card, send the reset APDU and tell the application layer about it. */ - if (vrdr != -1 && send_reset && !IS_LOCKED (ctrl) ) + slot = vreader_slot (vrdr); + if (slot != -1 && send_reset && !IS_LOCKED (ctrl) ) { - if (apdu_reset (vreader_table[vrdr].slot)) + application_notify_card_reset (slot); + switch (apdu_reset (slot)) { - vreader_table[vrdr].valid = 0; + case 0: + break; + case SW_HOST_NO_CARD: + case SW_HOST_CARD_INACTIVE: + break; + default: + apdu_close_reader (slot); + vreader_table[vrdr].slot = slot = -1; + break; } - application_notify_card_reset (vrdr); } /* If we hold a lock, unlock now. */ @@ -1696,11 +1709,7 @@ cmd_getinfo (assuan_context_t ctx, char *line) BUG (); vr = &vreader_table[vrdr]; - - if (!vr->valid) - BUG (); - - if (vr->any && (vr->status & 1)) + if (vr->valid && vr->any && (vr->status & 1)) flag = 'u'; } rc = assuan_send_data (ctx, &flag, 1); @@ -2248,9 +2257,9 @@ 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 (vr->slot); apdu_close_reader (vr->slot); vr->slot = -1; - vr->valid = 0; status = 0; changed = vr->changed; } From 45cf9de341405a228e331bd3893cbcd6b72306be Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 14 Dec 2011 15:42:28 +0100 Subject: [PATCH 43/68] agent: Pass comment lines from scd verbatim thru gpg-agent. * agent/call-scd.c (pass_status_thru): Pass comment lines verbatim. * tools/gpg-connect-agent.c (help_cmd_p): New. (main): Treat an "SCD HELP" the same as "HELP". --- NEWS | 13 ++++ agent/call-scd.c | 33 +++++--- tools/gpg-connect-agent.c | 156 +++++++++++++++++++++----------------- 3 files changed, 121 insertions(+), 81 deletions(-) diff --git a/NEWS b/NEWS index 08d6bfe6b..4364405b1 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,19 @@ Noteworthy changes in version 2.1.0beta3 * The Assuan commands KILLAGENT and KILLSCD are working again. + * SCdaemon does not anymore block after changing a card (regression + fix). + + * gpg-connect-agent does now proberly display the help output for + "SCD HELP" commands. + + * New GPGSM validation model "steed". + + * Improved certificate creation in GPGSM. + + * New option for GPG_AGENT to select a passphrase mode. The loopback + mode may be used to bypass Pinentry. + Noteworthy changes in version 2.1.0beta2 (2011-03-08) ----------------------------------------------------- diff --git a/agent/call-scd.c b/agent/call-scd.c index 74f94c0f6..3f535db6d 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -1,5 +1,6 @@ /* call-scd.c - fork of the scdaemon to do SC operations - * Copyright (C) 2001, 2002, 2005, 2007, 2010 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2005, 2007, 2010, + * 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1129,16 +1130,28 @@ pass_status_thru (void *opaque, const char *line) char keyword[200]; int i; - for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++) - keyword[i] = *line; - keyword[i] = 0; - /* truncate any remaining keyword stuff. */ - for (; *line && !spacep (line); line++) - ; - while (spacep (line)) - line++; + if (line[0] == '#' && (!line[1] || spacep (line+1))) + { + /* We are called in convey comments mode. Now, if we see a + comment marker as keyword we forward the line verbatim to the + the caller. This way the comment lines from scdaemon won't + appear as status lines with keyword '#'. */ + assuan_write_line (ctx, line); + } + else + { + for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++) + keyword[i] = *line; + keyword[i] = 0; - assuan_write_status (ctx, keyword, line); + /* Truncate any remaining keyword stuff. */ + for (; *line && !spacep (line); line++) + ; + while (spacep (line)) + line++; + + assuan_write_status (ctx, keyword, line); + } return 0; } diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index 8de67bbf0..117f3380c 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -67,25 +67,25 @@ enum cmd_and_opt_values /* The list of commands and options. */ static ARGPARSE_OPTS opts[] = { ARGPARSE_group (301, N_("@\nOptions:\n ")), - + ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")), ARGPARSE_s_n (oQuiet, "quiet", N_("quiet")), ARGPARSE_s_n (oHex, "hex", N_("print data out hex encoded")), ARGPARSE_s_n (oDecode,"decode", N_("decode received data lines")), - ARGPARSE_s_s (oRawSocket, "raw-socket", + ARGPARSE_s_s (oRawSocket, "raw-socket", N_("|NAME|connect to Assuan socket NAME")), - ARGPARSE_s_s (oTcpSocket, "tcp-socket", + ARGPARSE_s_s (oTcpSocket, "tcp-socket", N_("|ADDR|connect to Assuan server at ADDR")), - ARGPARSE_s_n (oExec, "exec", + ARGPARSE_s_n (oExec, "exec", N_("run the Assuan server given on the command line")), ARGPARSE_s_n (oNoExtConnect, "no-ext-connect", N_("do not use extended connect mode")), - ARGPARSE_s_s (oRun, "run", + ARGPARSE_s_s (oRun, "run", N_("|FILE|run commands from FILE on startup")), - ARGPARSE_s_n (oSubst, "subst", N_("run /subst on startup")), + ARGPARSE_s_n (oSubst, "subst", N_("run /subst on startup")), ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"), - ARGPARSE_s_s (oHomedir, "homedir", "@" ), + ARGPARSE_s_s (oHomedir, "homedir", "@" ), ARGPARSE_s_s (oAgentProgram, "agent-program", "@"), ARGPARSE_end () @@ -216,7 +216,7 @@ gnu_getcwd (void) #ifdef HAVE_W32CE_SYSTEM strcpy (buffer, "/"); return buffer; -#else +#else if (getcwd (buffer, size) == buffer) return buffer; xfree (buffer); @@ -246,22 +246,22 @@ unescape_string (const char *string) { switch (*s) { - case 'b': - case 't': - case 'v': - case 'n': - case 'f': - case 'r': - case '"': - case '\'': + case 'b': + case 't': + case 'v': + case 'n': + case 'f': + case 'r': + case '"': + case '\'': case '\\': n++; break; - case 'x': + case 'x': if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2)) n++; break; default: - if (s[1] && s[2] + if (s[1] && s[2] && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2)) n++; break; @@ -272,7 +272,7 @@ unescape_string (const char *string) esc = 1; else n++; - } + } buffer = xmalloc (n+1); d = (unsigned char*)buffer; @@ -291,7 +291,7 @@ unescape_string (const char *string) case '"': *d++ = '\"'; break; case '\'': *d++ = '\''; break; case '\\': *d++ = '\\'; break; - case 'x': + case 'x': if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2)) { s++; @@ -301,7 +301,7 @@ unescape_string (const char *string) break; default: - if (s[1] && s[2] + if (s[1] && s[2] && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2)) { *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2); @@ -315,7 +315,7 @@ unescape_string (const char *string) esc = 1; else *d++ = *s; - } + } *d = 0; return buffer; } @@ -334,7 +334,7 @@ unpercent_string (const char *string, int with_plus) for (s=(const unsigned char *)string; *s; s++) { if (*s == '%' && s[1] && s[2]) - { + { s++; n++; s++; @@ -350,7 +350,7 @@ unpercent_string (const char *string, int with_plus) for (s=(const unsigned char *)string; *s; s++) { if (*s == '%' && s[1] && s[2]) - { + { s++; *p++ = xtoi_2 (s); s++; @@ -387,7 +387,7 @@ set_var (const char *name, const char *value) xfree (var->value); var->value = value? xstrdup (value) : NULL; return var->value; -} +} static void @@ -455,12 +455,12 @@ arithmetic_op (int operator, const char *operands) case '+': result += value; break; case '-': result -= value; break; case '*': result *= value; break; - case '/': + case '/': if (!value) return NULL; result /= value; break; - case '%': + case '%': if (!value) return NULL; result %= value; @@ -480,10 +480,10 @@ arithmetic_op (int operator, const char *operands) /* Extended version of get_var. This returns a malloced string and - understand the function syntax: "func args". + understand the function syntax: "func args". Defined functions are - + get - Return a value described by the next argument: cwd - The current working directory. homedir - The gnupg homedir. @@ -525,7 +525,7 @@ arithmetic_op (int operator, const char *operands) Example: get_var_ext ("get sysconfdir") -> "/etc/gnupg" - + */ static char * get_var_ext (const char *name) @@ -630,7 +630,7 @@ get_var_ext (const char *name) { s++; intvalue = (int)strtol (s, NULL, 0); - result = xasprintf ("%s <%s>", + result = xasprintf ("%s <%s>", gpg_strerror (intvalue), gpg_strsource (intvalue)); } else if ( (s - name) == 1 && strchr ("+-*/%!|&", *name)) @@ -642,7 +642,7 @@ get_var_ext (const char *name) log_error ("unknown variable function `%.*s'\n", (int)(s-name), name); result = NULL; } - + xfree (free_me); recursion_count--; return result; @@ -667,7 +667,7 @@ substitute_line (char *buffer) p = strchr (line, '$'); if (!p) return result; /* No more variables. */ - + if (p[1] == '$') /* Escaped dollar sign. */ { memmove (p, p+1, strlen (p+1)+1); @@ -751,7 +751,7 @@ static char * substitute_line_copy (const char *buffer) { char *result, *p; - + p = xstrdup (buffer?buffer:""); result = substitute_line (p); if (!result) @@ -777,7 +777,7 @@ assign_variable (char *line, int syslet) p++; if (!*p) - set_var (name, NULL); /* Remove variable. */ + set_var (name, NULL); /* Remove variable. */ else if (syslet) { free_me = opt.enable_varsubst? substitute_line_copy (p) : NULL; @@ -791,7 +791,7 @@ assign_variable (char *line, int syslet) xfree (tmp); xfree (free_me); } - else + else { tmp = opt.enable_varsubst? substitute_line_copy (p) : NULL; if (tmp) @@ -857,11 +857,11 @@ show_definq (void) for (d=definq_list; d; d = d->next) if (d->name) - printf ("%-20s %c %s\n", + printf ("%-20s %c %s\n", d->name, d->is_var? 'v' : d->is_prog? 'p':'f', d->file); for (d=definq_list; d; d = d->next) if (!d->name) - printf ("%-20s %c %s\n", "*", + printf ("%-20s %c %s\n", "*", d->is_var? 'v': d->is_prog? 'p':'f', d->file); } @@ -871,14 +871,14 @@ static void clear_definq (void) { while (definq_list) - { + { definq_t tmp = definq_list->next; xfree (definq_list->name); xfree (definq_list); definq_list = tmp; } definq_list_tail = &definq_list; -} +} static void @@ -1005,7 +1005,7 @@ do_open (char *line) HANDLE prochandle, handle, newhandle; handle = (void*)_get_osfhandle (fd); - + prochandle = OpenProcess (PROCESS_DUP_HANDLE, FALSE, server_pid); if (!prochandle) { @@ -1030,7 +1030,7 @@ do_open (char *line) log_info ("file `%s' opened in \"%s\" mode, fd=%d (libc=%d)\n", name, mode, (int)open_fd_table[fd].handle, fd); set_int_var (varname, (int)open_fd_table[fd].handle); -#else +#else if (opt.verbose) log_info ("file `%s' opened in \"%s\" mode, fd=%d\n", name, mode, fd); @@ -1117,14 +1117,14 @@ do_serverpid (assuan_context_t ctx) int rc; membuf_t mb; char *buffer; - + init_membuf (&mb, 100); rc = assuan_transact (ctx, "GETINFO pid", getinfo_pid_cb, &mb, NULL, NULL, NULL, NULL); put_membuf (&mb, "", 1); buffer = get_membuf (&mb, NULL); if (rc || !buffer) - log_error ("command \"%s\" failed: %s\n", + log_error ("command \"%s\" failed: %s\n", "GETINFO pid", gpg_strerror (rc)); else { @@ -1136,6 +1136,22 @@ do_serverpid (assuan_context_t ctx) } +/* Return true if the command is either "HELP" or "SCD HELP". */ +static int +help_cmd_p (const char *line) +{ + if (!ascii_strncasecmp (line, "SCD", 3) + && (spacep (line+3) || !line[3])) + { + for (line += 3; spacep (line); line++) + ; + } + + return (!ascii_strncasecmp (line, "HELP", 4) + && (spacep (line+4) || !line[4])); +} + + /* gpg-connect-agent's entry point. */ int main (int argc, char **argv) @@ -1156,7 +1172,7 @@ main (int argc, char **argv) loopline_t head; loopline_t *tail; loopline_t current; - unsigned int nestlevel; + unsigned int nestlevel; int oneshot; char *condition; } loopstack[20]; @@ -1197,7 +1213,7 @@ main (int argc, char **argv) case oExec: opt.exec = 1; break; case oNoExtConnect: opt.connect_flags &= ~(1); break; case oRun: opt_run = pargs.r.ret_str; break; - case oSubst: + case oSubst: opt.enable_varsubst = 1; opt.trim_leading_spaces = 1; break; @@ -1339,7 +1355,7 @@ main (int argc, char **argv) log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) ); } - + for (loopidx=0; loopidx < DIM (loopstack); loopidx++) loopstack[loopidx].collecting = 0; loopidx = -1; @@ -1396,7 +1412,7 @@ main (int argc, char **argv) linesize = 0; keep_line = 1; } - n = read_line (script_fp? script_fp:stdin, + n = read_line (script_fp? script_fp:stdin, &line, &linesize, &maxlength); } if (n < 0) @@ -1422,7 +1438,7 @@ main (int argc, char **argv) log_info ("end of script\n"); continue; } - break; + break; } if (!maxlength) { @@ -1433,11 +1449,11 @@ main (int argc, char **argv) log_info (_("line shortened due to embedded Nul character\n")); if (line[n-1] == '\n') line[n-1] = 0; - + if (opt.trim_leading_spaces) { const char *s = line; - + while (spacep (s)) s++; if (s != line) @@ -1463,7 +1479,7 @@ main (int argc, char **argv) loopstack[loopidx+1].nestlevel--; else if (!strncmp (line, "/while", 6) && (!line[6]||spacep(line+6))) loopstack[loopidx+1].nestlevel++; - + if (loopstack[loopidx+1].nestlevel) continue; /* We reached the corresponding /end. */ @@ -1546,7 +1562,7 @@ main (int argc, char **argv) { current_datasink = fopen (fname, "wb"); if (!current_datasink) - log_error ("can't open `%s': %s\n", + log_error ("can't open `%s': %s\n", fname, strerror (errno)); } xfree (tmpline); @@ -1783,7 +1799,7 @@ main (int argc, char **argv) "/cleardef Delete all definitions.\n" "/sendfd FILE MODE Open FILE and pass descriptor to server.\n" "/recvfd Receive FD from server and print.\n" -"/open VAR FILE MODE Open FILE and assign the file descriptor to VAR.\n" +"/open VAR FILE MODE Open FILE and assign the file descriptor to VAR.\n" "/close FD Close file with descriptor FD.\n" "/showopen Show descriptors of all open files.\n" "/serverpid Retrieve the pid of the server.\n" @@ -1799,7 +1815,7 @@ main (int argc, char **argv) } else log_error (_("unknown command `%s'\n"), cmd ); - + continue; } @@ -1822,9 +1838,7 @@ main (int argc, char **argv) if (*line == '#' || !*line) continue; /* Don't expect a response for a comment line. */ - rc = read_and_print_response (ctx, (!ascii_strncasecmp (line, "HELP", 4) - && (spacep (line+4) || !line[4])), - &cmderr); + rc = read_and_print_response (ctx, help_cmd_p (line), &cmderr); if (rc) log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) ); if ((rc || cmderr) && script_fp) @@ -1833,7 +1847,7 @@ main (int argc, char **argv) fclose (script_fp); script_fp = NULL; } - + /* FIXME: If the last command was BYE or the server died for some other reason, we won't notice until we get the next @@ -1844,8 +1858,8 @@ main (int argc, char **argv) if (opt.verbose) log_info ("closing connection to agent\n"); - - return 0; + + return 0; } @@ -1911,7 +1925,7 @@ handle_inquire (assuan_context_t ctx, char *line) log_error ("error executing `%s': %s\n", d->file, strerror (errno)); else if (opt.verbose) - log_error ("handling inquiry `%s' by running `%s'\n", + log_error ("handling inquiry `%s' by running `%s'\n", name, d->file); } else @@ -1974,7 +1988,7 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr) *r_goterr = 0; for (;;) { - do + do { rc = assuan_read_line (ctx, &line, &linelen); if (rc) @@ -1985,7 +1999,7 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr) fwrite (line, linelen, 1, stdout); putchar ('\n'); } - } + } while (*line == '#' || !linelen); if (linelen >= 1 @@ -1999,7 +2013,7 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr) for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ ) { if (*s == '%' && j+2 < linelen) - { + { s++; j++; c = xtoi_2 ( s ); s++; j++; @@ -2054,7 +2068,7 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr) need_d = 0; } if (*s == '%' && j+2 < linelen) - { + { s++; j++; c = xtoi_2 ( s ); s++; j++; @@ -2073,7 +2087,7 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr) putchar ('\n'); } } - else + else { if (need_lf) { @@ -2083,7 +2097,7 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr) } if (linelen >= 1 - && line[0] == 'S' + && line[0] == 'S' && (line[1] == '\0' || line[1] == ' ')) { if (!current_datasink || current_datasink != stdout) @@ -2091,7 +2105,7 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr) fwrite (line, linelen, 1, stdout); putchar ('\n'); } - } + } else if (linelen >= 2 && line[0] == 'O' && line[1] == 'K' && (line[2] == '\0' || line[2] == ' ')) @@ -2121,11 +2135,11 @@ read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr) } *r_goterr = 1; return 0; - } + } else if (linelen >= 7 && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q' && line[3] == 'U' && line[4] == 'I' && line[5] == 'R' - && line[6] == 'E' + && line[6] == 'E' && (line[7] == '\0' || line[7] == ' ')) { if (!current_datasink || current_datasink != stdout) From dcd64131c60efd0189aa05d5dbce6b93547b04e3 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 14 Dec 2011 17:00:50 +0100 Subject: [PATCH 44/68] scd: Add the "undefined" stub application. * scd/app.c (select_application): Implement the "undefined" application. --- doc/scdaemon.texi | 11 +++++++++++ scd/app.c | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index 9184ce202..200fed890 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -181,6 +181,8 @@ write hashed data to files named @code{dbgmd-000*} trace Assuan protocol. See also option @option{--debug-assuan-log-cats}. @item 11 (2048) trace APDU I/O to the card. This may reveal sensitive data. +@item 12 (4096) +trace some card reader related function calls. @end table @item --debug-all @@ -327,6 +329,7 @@ stripping off the two leading dashes. * DINSIG Card:: The DINSIG card application * PKCS#15 Card:: The PKCS#15 card application * Geldkarte Card:: The Geldkarte application +* Undefined Card:: The Undefined stub application @end menu @node OpenPGP Card @@ -367,6 +370,14 @@ This is a simple application to display information of a German Geldkarte. The Geldkarte is a small amount debit card application which comes with almost all German banking cards. +@node Undefined Card +@subsection The Undefined card application ``undefined'' + +This is a stub application to allow the use of the APDU command even +if no supported application is found on the card. This application is +not used automatically but must be explicitly requested using the +SERIALNO command. + @c ******************************************* @c *************** **************** diff --git a/scd/app.c b/scd/app.c index 6f0d7560b..63ef4fa65 100644 --- a/scd/app.c +++ b/scd/app.c @@ -387,6 +387,14 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app) if (err && is_app_allowed ("geldkarte") && (!name || !strcmp (name, "geldkarte"))) err = app_select_geldkarte (app); + if (err && is_app_allowed ("undefined") + && (name && !strcmp (name, "undefined"))) + { + /* We switch to the "undefined" application only if explicitly + requested. */ + app->apptype = "UNDEFINED"; + err = 0; + } if (err && name) err = gpg_error (GPG_ERR_NOT_SUPPORTED); @@ -422,6 +430,8 @@ get_supported_applications (void) "p15", "dinsig", "geldkarte", + /* Note: "undefined" is not listed here because it needs special + treatment by the client. */ NULL }; int idx; From 0bac31ee9f74a25d76b08c3e0355a338908f083a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 14 Dec 2011 18:48:47 +0100 Subject: [PATCH 45/68] scd: Add more status word values for documentation. --- scd/apdu.c | 7 +++++-- scd/apdu.h | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/scd/apdu.c b/scd/apdu.c index c37e8c4c3..5a518465c 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -463,8 +463,11 @@ apdu_strerror (int rc) case SW_FILE_NOT_FOUND : return "file not found"; case SW_RECORD_NOT_FOUND:return "record not found"; case SW_REF_NOT_FOUND : return "reference not found"; - case SW_BAD_LC : return "bad Lc"; - case SW_BAD_P0_P1 : return "bad P0 or P1"; + case SW_NOT_ENOUGH_MEMORY: return "not enough memory space in the file"; + case SW_INCONSISTENT_LC: return "Lc inconsistent with TLV structure."; + case SW_INCORRECT_P0_P1: return "incorrect parameters P0,P1"; + case SW_BAD_LC : return "Lc inconsistent with P0,P1"; + case SW_BAD_P0_P1 : return "bad P0,P1"; case SW_INS_NOT_SUP : return "instruction not supported"; case SW_CLA_NOT_SUP : return "class not supported"; case SW_SUCCESS : return "success"; diff --git a/scd/apdu.h b/scd/apdu.h index f70425620..75025469e 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -41,6 +41,9 @@ enum { SW_NOT_SUPPORTED = 0x6a81, SW_FILE_NOT_FOUND = 0x6a82, SW_RECORD_NOT_FOUND = 0x6a83, + SW_NOT_ENOUGH_MEMORY= 0x6a84, /* Not enough memory space in the file. */ + SW_INCONSISTENT_LC = 0x6a85, /* Lc inconsistent with TLV structure. */ + SW_INCORRECT_P0_P1 = 0x6a86, SW_BAD_LC = 0x6a87, /* Lc does not match command or p1/p2. */ SW_REF_NOT_FOUND = 0x6a88, SW_BAD_P0_P1 = 0x6b00, From 792e137ec7997a0ff5c54ff970611238d28d4ba8 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 14 Dec 2011 18:56:10 +0100 Subject: [PATCH 46/68] scd: Skip S/N reading for the "undefined" application. * scd/app.c (select_application): Skip serial number reading. --- scd/app.c | 95 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 51 insertions(+), 44 deletions(-) diff --git a/scd/app.c b/scd/app.c index 63ef4fa65..31e56fb3f 100644 --- a/scd/app.c +++ b/scd/app.c @@ -242,11 +242,14 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app) app_t app = NULL; unsigned char *result = NULL; size_t resultlen; + int want_undefined; (void)ctrl; *r_app = NULL; + want_undefined = (name && !strcmp (name, "undefined")); + err = lock_reader (slot, ctrl); if (err) return err; @@ -326,45 +329,49 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app) /* Fixme: We should now first check whether a card is at all present. */ - /* Try to read the GDO file first to get a default serial number. */ - err = iso7816_select_file (slot, 0x3F00, 1, NULL, NULL); - if (!err) - err = iso7816_select_file (slot, 0x2F02, 0, NULL, NULL); - if (!err) - err = iso7816_read_binary (slot, 0, 0, &result, &resultlen); - if (!err) + /* Try to read the GDO file first to get a default serial number. + We skip this if the undefined application has been requested. */ + if (!want_undefined) { - size_t n; - const unsigned char *p; - - p = find_tlv_unchecked (result, resultlen, 0x5A, &n); - if (p) - resultlen -= (p-result); - if (p && n > resultlen && n == 0x0d && resultlen+1 == n) + err = iso7816_select_file (slot, 0x3F00, 1, NULL, NULL); + if (!err) + err = iso7816_select_file (slot, 0x2F02, 0, NULL, NULL); + if (!err) + err = iso7816_read_binary (slot, 0, 0, &result, &resultlen); + if (!err) { - /* The object it does not fit into the buffer. This is an - invalid encoding (or the buffer is too short. However, I - have some test cards with such an invalid encoding and - therefore I use this ugly workaround to return something - I can further experiment with. */ - log_info ("enabling BMI testcard workaround\n"); - n--; - } + size_t n; + const unsigned char *p; - if (p && n <= resultlen) - { - /* The GDO file is pretty short, thus we simply reuse it for - storing the serial number. */ - memmove (result, p, n); - app->serialno = result; - app->serialnolen = n; - err = app_munge_serialno (app); - if (err) - goto leave; + p = find_tlv_unchecked (result, resultlen, 0x5A, &n); + if (p) + resultlen -= (p-result); + if (p && n > resultlen && n == 0x0d && resultlen+1 == n) + { + /* The object it does not fit into the buffer. This is an + invalid encoding (or the buffer is too short. However, I + have some test cards with such an invalid encoding and + therefore I use this ugly workaround to return something + I can further experiment with. */ + log_info ("enabling BMI testcard workaround\n"); + n--; + } + + if (p && n <= resultlen) + { + /* The GDO file is pretty short, thus we simply reuse it for + storing the serial number. */ + memmove (result, p, n); + app->serialno = result; + app->serialnolen = n; + err = app_munge_serialno (app); + if (err) + goto leave; + } + else + xfree (result); + result = NULL; } - else - xfree (result); - result = NULL; } /* For certain error codes, there is no need to try more. */ @@ -373,7 +380,15 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app) goto leave; /* Figure out the application to use. */ - err = gpg_error (GPG_ERR_NOT_FOUND); + if (want_undefined) + { + /* We switch to the "undefined" application only if explicitly + requested. */ + app->apptype = "UNDEFINED"; + err = 0; + } + else + err = gpg_error (GPG_ERR_NOT_FOUND); if (err && is_app_allowed ("openpgp") && (!name || !strcmp (name, "openpgp"))) @@ -387,14 +402,6 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app) if (err && is_app_allowed ("geldkarte") && (!name || !strcmp (name, "geldkarte"))) err = app_select_geldkarte (app); - if (err && is_app_allowed ("undefined") - && (name && !strcmp (name, "undefined"))) - { - /* We switch to the "undefined" application only if explicitly - requested. */ - app->apptype = "UNDEFINED"; - err = 0; - } if (err && name) err = gpg_error (GPG_ERR_NOT_SUPPORTED); From 7737a2c269657189a583cde7f214f20871d264f8 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 15 Dec 2011 14:45:08 +0100 Subject: [PATCH 47/68] estream: New function es_fclose_snatch. * common/estream.c (cookie_ioctl_function_t): New type. (es_fclose_snatch): New function. (COOKIE_IOCTL_SNATCH_BUFFER): New constant. (struct estream_internal): Add field FUNC_IOCTL. (es_initialize): Clear FUNC_IOCTL. (es_func_mem_ioctl): New function. (es_fopenmem, es_fopenmem_init): Init FUNC_IOCTL. --- common/estream.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++ common/estream.h | 4 +- 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/common/estream.c b/common/estream.c index c55c7f26d..6b7bd8b75 100644 --- a/common/estream.c +++ b/common/estream.c @@ -217,6 +217,17 @@ struct notify_list_s }; typedef struct notify_list_s *notify_list_t; + +/* A private cookie function to implement an internal IOCTL + service. */ +typedef int (*cookie_ioctl_function_t) (void *cookie, int cmd, + void *ptr, size_t *len); +/* IOCTL commands for the private cookie function. */ +#define COOKIE_IOCTL_SNATCH_BUFFER 1 + + + + /* An internal stream object. */ struct estream_internal { @@ -231,6 +242,7 @@ struct estream_internal es_cookie_read_function_t func_read; es_cookie_write_function_t func_write; es_cookie_seek_function_t func_seek; + cookie_ioctl_function_t func_ioctl; es_cookie_close_function_t func_close; int strategy; es_syshd_t syshd; /* A copy of the sytem handle. */ @@ -771,6 +783,33 @@ es_func_mem_seek (void *cookie, off_t *offset, int whence) return 0; } +/* An IOCTL function for memory objects. */ +static int +es_func_mem_ioctl (void *cookie, int cmd, void *ptr, size_t *len) +{ + estream_cookie_mem_t mem_cookie = cookie; + int ret; + + if (cmd == COOKIE_IOCTL_SNATCH_BUFFER) + { + /* Return the internal buffer of the stream to the caller and + invalidate it for the stream. */ + *(void**)ptr = mem_cookie->memory; + *len = mem_cookie->offset; + mem_cookie->memory = NULL; + mem_cookie->memory_size = 0; + mem_cookie->offset = 0; + ret = 0; + } + else + { + _set_errno (EINVAL); + ret = -1; + } + + return ret; +} + /* Destroy function for memory objects. */ static int @@ -1608,6 +1647,7 @@ es_initialize (estream_t stream, stream->intern->func_read = functions.func_read; stream->intern->func_write = functions.func_write; stream->intern->func_seek = functions.func_seek; + stream->intern->func_ioctl = NULL; stream->intern->func_close = functions.func_close; stream->intern->strategy = _IOFBF; stream->intern->syshd = *syshd; @@ -2667,6 +2707,9 @@ es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode) if (es_create (&stream, cookie, &syshd, estream_functions_mem, modeflags, 0)) (*estream_functions_mem.func_close) (cookie); + if (stream) + stream->intern->func_ioctl = es_func_mem_ioctl; + return stream; } @@ -2701,6 +2744,10 @@ es_fopenmem_init (size_t memlimit, const char *ES__RESTRICT mode, es_set_indicators (stream, 0, 0); } } + + if (stream) + stream->intern->func_ioctl = es_func_mem_ioctl; + return stream; } @@ -3082,6 +3129,65 @@ es_fclose (estream_t stream) } +/* This is a special version of es_fclose which can be used with + es_fopenmem to return the memory buffer. This is feature is useful + to write to a memory buffer using estream. Note that the function + does not close the stream if the stream does not support snatching + the buffer. On error NULL is stored at R_BUFFER. Note that if no + write operation has happened, NULL may also be stored at BUFFER on + success. The caller needs to release the returned memory using + es_free. */ +int +es_fclose_snatch (estream_t stream, void **r_buffer, size_t *r_buflen) +{ + int err; + + /* Note: There is no need to lock the stream in a close call. The + object will be destroyed after the close and thus any other + contender for the lock would work on a closed stream. */ + + if (r_buffer) + { + cookie_ioctl_function_t func_ioctl = stream->intern->func_ioctl; + size_t buflen; + + *r_buffer = NULL; + + if (!func_ioctl) + { + _set_errno (EOPNOTSUPP); + err = -1; + goto leave; + } + + if (stream->flags.writing) + { + err = es_flush (stream); + if (err) + goto leave; + stream->flags.writing = 0; + } + + err = func_ioctl (stream->intern->cookie, COOKIE_IOCTL_SNATCH_BUFFER, + r_buffer, &buflen); + if (err) + goto leave; + if (r_buflen) + *r_buflen = buflen; + } + + err = do_close (stream, 0); + + leave: + if (err && r_buffer) + { + mem_free (*r_buffer); + *r_buffer = NULL; + } + return err; +} + + /* Register or unregister a close notification function for STREAM. FNC is the function to call and FNC_VALUE the value passed as second argument. To register the notification the value for MODE diff --git a/common/estream.h b/common/estream.h index 49662766e..bbe5b62d6 100644 --- a/common/estream.h +++ b/common/estream.h @@ -1,5 +1,5 @@ /* estream.h - Extended stream I/O Library - * Copyright (C) 2004, 2005, 2006, 2007, 2010 g10 Code GmbH + * Copyright (C) 2004, 2005, 2006, 2007, 2010, 2011 g10 Code GmbH * * This file is part of Libestream. * @@ -88,6 +88,7 @@ #define es_freopen _ESTREAM_PREFIX(es_freopen) #define es_fopencookie _ESTREAM_PREFIX(es_fopencookie) #define es_fclose _ESTREAM_PREFIX(es_fclose) +#define es_fclose_snatch _ESTREAM_PREFIX(es_fclose_snatch) #define es_onclose _ESTREAM_PREFIX(es_onclose) #define es_fileno _ESTREAM_PREFIX(es_fileno) #define es_fileno_unlocked _ESTREAM_PREFIX(es_fileno_unlocked) @@ -285,6 +286,7 @@ estream_t es_fopencookie (void *ES__RESTRICT cookie, const char *ES__RESTRICT mode, es_cookie_io_functions_t functions); int es_fclose (estream_t stream); +int es_fclose_snatch (estream_t stream, void **r_buffer, size_t *r_buflen); int es_onclose (estream_t stream, int mode, void (*fnc) (estream_t, void*), void *fnc_value); int es_fileno (estream_t stream); From b22d62bd1481dfe13d60a6d16b09b9297944f063 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 15 Dec 2011 14:47:04 +0100 Subject: [PATCH 48/68] scd: Add option --dump-atr to command APDU. * scd/atr.c: Rewrite. * scd/Makefile.am (scdaemon_SOURCES): Add atr.c and atr.h. * scd/command.c (cmd_apdu): Add option --dump-atr. --- scd/Makefile.am | 1 + scd/atr.c | 252 ++++++++++++++---------------------------------- scd/atr.h | 2 +- scd/command.c | 36 ++++++- 4 files changed, 107 insertions(+), 184 deletions(-) diff --git a/scd/Makefile.am b/scd/Makefile.am index bdd457acd..b42e53dff 100644 --- a/scd/Makefile.am +++ b/scd/Makefile.am @@ -37,6 +37,7 @@ card_apps = app-openpgp.c app-nks.c app-dinsig.c app-p15.c app-geldkarte.c scdaemon_SOURCES = \ scdaemon.c scdaemon.h \ command.c \ + atr.c atr.h \ apdu.c apdu.h \ ccid-driver.c ccid-driver.h \ iso7816.c iso7816.h \ diff --git a/scd/atr.c b/scd/atr.c index 16f26fb7d..b8668a41d 100644 --- a/scd/atr.c +++ b/scd/atr.c @@ -1,5 +1,5 @@ /* atr.c - ISO 7816 ATR fucntions - * Copyright (C) 2003 Free Software Foundation, Inc. + * Copyright (C) 2003, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -24,10 +24,9 @@ #include #include -#include "scdaemon.h" -#include "apdu.h" +#include "../common/estream.h" +#include "../common/logging.h" #include "atr.h" -#include "dynload.h" static int const fi_table[16] = { 0, 372, 558, 744, 1116,1488, 1860, -1, -1, 512, 768, 1024, 1536, 2048, -1, -1 }; @@ -35,37 +34,42 @@ static int const di_table[16] = { -1, 1, 2, 4, 8, 16, -1, -1, 0, -1, -2, -4, -8, -16, -32, -64}; -/* Dump the ATR of the card at SLOT in a human readable format to - stream FP. */ -int -atr_dump (int slot, FILE *fp) +/* Dump the ATR in (BUFFER,BUFLEN) to a human readable format and + return that as a malloced buffer. The caller must release this + buffer using es_free! On error this function returns NULL and sets + ERRNO. */ +char * +atr_dump (const void *buffer, size_t buflen) { - unsigned char *atrbuffer, *atr; - size_t atrlen; + const unsigned char *atr = buffer; + size_t atrlen = buflen; + estream_t fp; int have_ta, have_tb, have_tc, have_td; int n_historical; int idx, val; unsigned char chksum; + char *result; - atr = atrbuffer = apdu_get_atr (slot, &atrlen); - if (!atr) - return gpg_error (GPG_ERR_GENERAL); + fp = es_fopenmem (0, "rwb"); + if (!fp) + return NULL; - fprintf (fp, "Info on ATR of length %u at slot %d\n", - (unsigned int)atrlen, slot); if (!atrlen) { - fprintf (fp, "error: empty ATR\n"); + es_fprintf (fp, "error: empty ATR\n"); goto bailout; } + for (idx=0; idx < atrlen ; idx++) + es_fprintf (fp, "%s%02X", idx?" ":"", atr[idx]); + es_putc ('\n', fp); if (*atr == 0x3b) - fputs ("direct convention\n", fp); + es_fputs ("Direct convention\n", fp); else if (*atr == 0x3f) - fputs ("inverse convention\n", fp); + es_fputs ("Inverse convention\n", fp); else - fprintf (fp,"error: invalid TS character 0x%02x\n", *atr); + es_fprintf (fp,"error: invalid TS character 0x%02x\n", *atr); if (!--atrlen) goto bailout; atr++; @@ -79,34 +83,34 @@ atr_dump (int slot, FILE *fp) have_tc = !!(*atr & 0x40); have_td = !!(*atr & 0x80); n_historical = (*atr & 0x0f); - fprintf (fp, "%d historical characters indicated\n", n_historical); + es_fprintf (fp, "%d historical characters indicated\n", n_historical); if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen) - fputs ("error: ATR shorter than indicated by format character\n", fp); + es_fputs ("error: ATR shorter than indicated by format character\n", fp); if (!--atrlen) goto bailout; atr++; if (have_ta) { - fputs ("TA1: F=", fp); + es_fputs ("TA1: F=", fp); val = fi_table[(*atr >> 4) & 0x0f]; if (!val) - fputs ("internal clock", fp); + es_fputs ("internal clock", fp); else if (val == -1) - fputs ("RFU", fp); + es_fputs ("RFU", fp); else - fprintf (fp, "%d", val); - fputs (" D=", fp); + es_fprintf (fp, "%d", val); + es_fputs (" D=", fp); val = di_table[*atr & 0x0f]; if (!val) - fputs ("[impossible value]\n", fp); + es_fputs ("[impossible value]\n", fp); else if (val == -1) - fputs ("RFU\n", fp); + es_fputs ("RFU\n", fp); else if (val < 0 ) - fprintf (fp, "1/%d\n", val); + es_fprintf (fp, "1/%d\n", val); else - fprintf (fp, "%d\n", val); + es_fprintf (fp, "%d\n", val); if (!--atrlen) goto bailout; @@ -115,8 +119,9 @@ atr_dump (int slot, FILE *fp) if (have_tb) { - fprintf (fp, "TB1: II=%d PI1=%d%s\n", (*atr >> 5) & 3, *atr & 0x1f, - (*atr & 0x80)? " [high bit not cleared]":""); + es_fprintf (fp, "TB1: II=%d PI1=%d%s\n", + ((*atr >> 5) & 3), (*atr & 0x1f), + (*atr & 0x80)? " [high bit not cleared]":""); if (!--atrlen) goto bailout; atr++; @@ -125,9 +130,9 @@ atr_dump (int slot, FILE *fp) if (have_tc) { if (*atr == 255) - fputs ("TC1: guard time shortened to 1 etu\n", fp); + es_fputs ("TC1: guard time shortened to 1 etu\n", fp); else - fprintf (fp, "TC1: (extra guard time) N=%d\n", *atr); + es_fprintf (fp, "TC1: (extra guard time) N=%d\n", *atr); if (!--atrlen) goto bailout; @@ -140,10 +145,11 @@ atr_dump (int slot, FILE *fp) have_tb = !!(*atr & 0x20); have_tc = !!(*atr & 0x40); have_td = !!(*atr & 0x80); - fprintf (fp, "TD1: protocol T%d supported\n", *atr & 0x0f); + es_fprintf (fp, "TD1: protocol T%d supported\n", (*atr & 0x0f)); if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen) - fputs ("error: ATR shorter than indicated by format character\n", fp); + es_fputs ("error: ATR shorter than indicated by format character\n", + fp); if (!--atrlen) goto bailout; @@ -154,12 +160,12 @@ atr_dump (int slot, FILE *fp) if (have_ta) { - fprintf (fp, "TA2: (PTS) %stoggle, %splicit, T=%02X\n", - (*atr & 0x80)? "no-":"", - (*atr & 0x10)? "im": "ex", - (*atr & 0x0f)); + es_fprintf (fp, "TA2: (PTS) %stoggle, %splicit, T=%02X\n", + (*atr & 0x80)? "no-":"", + (*atr & 0x10)? "im": "ex", + (*atr & 0x0f)); if ((*atr & 0x60)) - fprintf (fp, "note: reserved bits are set (TA2=0x%02X)\n", *atr); + es_fprintf (fp, "note: reserved bits are set (TA2=0x%02X)\n", *atr); if (!--atrlen) goto bailout; atr++; @@ -167,7 +173,7 @@ atr_dump (int slot, FILE *fp) if (have_tb) { - fprintf (fp, "TB2: PI2=%d\n", *atr); + es_fprintf (fp, "TB2: PI2=%d\n", *atr); if (!--atrlen) goto bailout; atr++; @@ -175,7 +181,7 @@ atr_dump (int slot, FILE *fp) if (have_tc) { - fprintf (fp, "TC2: PWI=%d\n", *atr); + es_fprintf (fp, "TC2: PWI=%d\n", *atr); if (!--atrlen) goto bailout; atr++; @@ -187,10 +193,11 @@ atr_dump (int slot, FILE *fp) have_tb = !!(*atr & 0x20); have_tc = !!(*atr & 0x40); have_td = !!(*atr & 0x80); - fprintf (fp, "TD2: protocol T%d supported\n", *atr & 0x0f); + es_fprintf (fp, "TD2: protocol T%d supported\n", *atr & 0x0f); if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen) - fputs ("error: ATR shorter than indicated by format character\n", fp); + es_fputs ("error: ATR shorter than indicated by format character\n", + fp); if (!--atrlen) goto bailout; @@ -203,7 +210,7 @@ atr_dump (int slot, FILE *fp) { if (have_ta) { - fprintf (fp, "TA%d: IFSC=%d\n", idx, *atr); + es_fprintf (fp, "TA%d: IFSC=%d\n", idx, *atr); if (!--atrlen) goto bailout; atr++; @@ -211,7 +218,7 @@ atr_dump (int slot, FILE *fp) if (have_tb) { - fprintf (fp, "TB%d: BWI=%d CWI=%d\n", + es_fprintf (fp, "TB%d: BWI=%d CWI=%d\n", idx, (*atr >> 4) & 0x0f, *atr & 0x0f); if (!--atrlen) goto bailout; @@ -220,7 +227,7 @@ atr_dump (int slot, FILE *fp) if (have_tc) { - fprintf (fp, "TC%d: 0x%02X\n", idx, *atr); + es_fprintf (fp, "TC%d: 0x%02X\n", idx, *atr); if (!--atrlen) goto bailout; atr++; @@ -232,11 +239,12 @@ atr_dump (int slot, FILE *fp) have_tb = !!(*atr & 0x20); have_tc = !!(*atr & 0x40); have_td = !!(*atr & 0x80); - fprintf (fp, "TD%d: protocol T%d supported\n", idx, *atr & 0x0f); + es_fprintf (fp, "TD%d: protocol T%d supported\n", idx, *atr & 0x0f); if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen) - fputs ("error: ATR shorter than indicated by format character\n", - fp); + es_fputs ("error: " + "ATR shorter than indicated by format character\n", + fp); if (!--atrlen) goto bailout; @@ -247,150 +255,36 @@ atr_dump (int slot, FILE *fp) } if (n_historical + 1 > atrlen) - fputs ("error: ATR shorter than required for historical bytes " - "and checksum\n", fp); + es_fputs ("error: ATR shorter than required for historical bytes " + "and checksum\n", fp); if (n_historical) { - fputs ("Historical:", fp); + es_fputs ("HCH:", fp); for (; n_historical && atrlen ; n_historical--, atrlen--, atr++) - fprintf (fp, " %02X", *atr); - putchar ('\n'); + es_fprintf (fp, " %02X", *atr); + es_putc ('\n', fp); } if (!atrlen) - fputs ("error: checksum missing\n", fp); + es_fputs ("error: checksum missing\n", fp); else if (*atr == chksum) - fprintf (fp, "TCK: %02X (good)\n", *atr); + es_fprintf (fp, "TCK: %02X (good)\n", *atr); else - fprintf (fp, "TCK: %02X (bad; calculated %02X)\n", *atr, chksum); + es_fprintf (fp, "TCK: %02X (bad; computed %02X)\n", *atr, chksum); atrlen--; if (atrlen) - fprintf (fp, "error: %u bytes garbage at end of ATR\n", - (unsigned int)atrlen ); + es_fprintf (fp, "error: %u bytes garbage at end of ATR\n", + (unsigned int)atrlen ); bailout: - xfree (atrbuffer); - - return 0; -} - - -/* Note: This code has not yet been tested! It shall return -1 on - error or the number of historical bytes and store them at - HISTORICAL. */ -int -atr_get_historical (int slot, unsigned char historical[]) -{ - int result = -1; - unsigned char *atrbuffer = NULL; - unsigned char *atr; - size_t atrlen; - int have_ta, have_tb, have_tc, have_td; - int n_historical; - int idx; - unsigned char chksum; - - atr = atrbuffer = apdu_get_atr (slot, &atrlen); - if (!atr || atrlen < 2) - goto leave; - atrlen--; - atr++; - - chksum = *atr; - for (idx=1; idx < atrlen-1; idx++) - chksum ^= atr[idx]; - - have_ta = !!(*atr & 0x10); - have_tb = !!(*atr & 0x20); - have_tc = !!(*atr & 0x40); - have_td = !!(*atr & 0x80); - n_historical = (*atr & 0x0f); - - if (have_ta + have_tb + have_tc + have_td + n_historical >= atrlen) - goto leave; /* ATR shorter than indicated by format character. */ - atrlen--; - atr++; - - if (have_ta + have_tb + have_tc >= atrlen) - goto leave; - atrlen -= have_ta + have_tb + have_tc; - atr += have_ta + have_tb + have_tc; - - if (have_td) + es_putc ('\0', fp); /* We want a string. */ + if (es_fclose_snatch (fp, (void**)&result, NULL)) { - have_ta = !!(*atr & 0x10); - have_tb = !!(*atr & 0x20); - have_tc = !!(*atr & 0x40); - have_td = !!(*atr & 0x80); - if (have_ta + have_tb + have_tc + have_td + n_historical >= atrlen) - goto leave; /* ATR shorter than indicated by format character. */ - atrlen--; - atr++; + log_error ("oops: es_fclose_snatch failed: %s\n", strerror (errno)); + return NULL; } - else - have_ta = have_tb = have_tc = have_td = 0; - - if (have_ta + have_tb + have_tc >= atrlen) - goto leave; - atrlen -= have_ta + have_tb + have_tc; - atr += have_ta + have_tb + have_tc; - - if (have_td) - { - have_ta = !!(*atr & 0x10); - have_tb = !!(*atr & 0x20); - have_tc = !!(*atr & 0x40); - have_td = !!(*atr & 0x80); - if (have_ta + have_tb + have_tc + have_td + n_historical >= atrlen) - goto leave; /* ATR shorter than indicated by format character. */ - atrlen--; - atr++; - } - else - have_ta = have_tb = have_tc = have_td = 0; - - for (idx = 3; have_ta || have_tb || have_tc || have_td; idx++) - { - if (have_ta + have_tb + have_tc >= atrlen) - goto leave; - atrlen -= have_ta + have_tb + have_tc; - atr += have_ta + have_tb + have_tc; - - if (have_td) - { - have_ta = !!(*atr & 0x10); - have_tb = !!(*atr & 0x20); - have_tc = !!(*atr & 0x40); - have_td = !!(*atr & 0x80); - if (have_ta + have_tb + have_tc + have_td + n_historical >= atrlen) - goto leave; /* ATR shorter than indicated by format character. */ - atrlen--; - atr++; - } - else - have_ta = have_tb = have_tc = have_td = 0; - } - - if (n_historical >= atrlen) - goto leave; /* ATR shorter than required for historical bytes. */ - - if (n_historical) - { - for (idx=0; n_historical && atrlen; n_historical--, atrlen--, atr++) - historical[idx] = *atr; - } - - if (!atrlen || *atr != chksum) - goto leave; - - /* Don't care about garbage at the end of the ATR. */ - - result = n_historical; - - leave: - xfree (atrbuffer); return result; } diff --git a/scd/atr.h b/scd/atr.h index 5f07522d1..b06a83a60 100644 --- a/scd/atr.h +++ b/scd/atr.h @@ -20,7 +20,7 @@ #ifndef ATR_H #define ATR_H -int atr_dump (int slot, FILE *fp); +char *atr_dump (const void *buffer, size_t buflen); diff --git a/scd/command.c b/scd/command.c index 0f5744829..afd5ef231 100644 --- a/scd/command.c +++ b/scd/command.c @@ -35,11 +35,13 @@ #include #include "app-common.h" #include "apdu.h" /* Required for apdu_*_reader (). */ +#include "atr.h" #include "exechelp.h" #ifdef HAVE_LIBUSB #include "ccid-driver.h" #endif + /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */ #define MAXLEN_PIN 100 @@ -1795,7 +1797,7 @@ cmd_disconnect (assuan_context_t ctx, char *line) static const char hlp_apdu[] = - "APDU [--atr] [--more] [--exlen[=N]] [hexstring]\n" + "APDU [--[dump-]atr] [--more] [--exlen[=N]] [hexstring]\n" "\n" "Send an APDU to the current reader. This command bypasses the high\n" "level functions and sends the data directly to the card. HEXSTRING\n" @@ -1826,7 +1828,10 @@ cmd_apdu (assuan_context_t ctx, char *line) size_t exlen; int slot; - with_atr = has_option (line, "--atr"); + if (has_option (line, "--dump-atr")) + with_atr = 2; + else + with_atr = has_option (line, "--atr"); handle_more = has_option (line, "--more"); if ((s=has_option_name (line, "--exlen"))) @@ -1861,9 +1866,32 @@ cmd_apdu (assuan_context_t ctx, char *line) rc = gpg_error (GPG_ERR_INV_CARD); goto leave; } - bin2hex (atr, atrlen, hexbuf); + if (with_atr == 2) + { + char *string, *p, *pend; + + string = atr_dump (atr, atrlen); + if (string) + { + for (rc=0, p=string; !rc && (pend = strchr (p, '\n')); p = pend+1) + { + rc = assuan_send_data (ctx, p, pend - p + 1); + if (!rc) + rc = assuan_send_data (ctx, NULL, 0); + } + if (!rc && *p) + rc = assuan_send_data (ctx, p, strlen (p)); + es_free (string); + if (rc) + goto leave; + } + } + else + { + bin2hex (atr, atrlen, hexbuf); + send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0); + } xfree (atr); - send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0); } apdu = hex_to_buffer (line, &apdulen); From 27089564b6453deaf7b4ffe7cc5f5f290b6d892b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 15 Dec 2011 21:45:35 +0100 Subject: [PATCH 49/68] scd: Prefer application Geldkarte over DINSIG. * scd/app.c (select_application): Reorder application tests. -- Although the DINSIG application is available on most German cards, it is in reality not used. Thus showing the Geldkarte application is more desirable for a good user experience. --- scd/app.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scd/app.c b/scd/app.c index 31e56fb3f..76dc8b4de 100644 --- a/scd/app.c +++ b/scd/app.c @@ -397,11 +397,11 @@ select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app) err = app_select_nks (app); if (err && is_app_allowed ("p15") && (!name || !strcmp (name, "p15"))) err = app_select_p15 (app); - if (err && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig"))) - err = app_select_dinsig (app); if (err && is_app_allowed ("geldkarte") && (!name || !strcmp (name, "geldkarte"))) err = app_select_geldkarte (app); + if (err && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig"))) + err = app_select_dinsig (app); if (err && name) err = gpg_error (GPG_ERR_NOT_SUPPORTED); @@ -435,8 +435,8 @@ get_supported_applications (void) "openpgp", "nks", "p15", - "dinsig", "geldkarte", + "dinsig", /* Note: "undefined" is not listed here because it needs special treatment by the client. */ NULL From a98260c39f1c0ccdad004784cbc9440376766082 Mon Sep 17 00:00:00 2001 From: David Shaw Date: Thu, 15 Dec 2011 16:46:28 -0500 Subject: [PATCH 50/68] Merge fix for issue 1331 from 1.4. * photoid.c (generate_photo_id): Check for the JPEG magic numbers instead of JFIF since some programs generate an EXIF header first. --- g10/photoid.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/g10/photoid.c b/g10/photoid.c index 9045f0c16..c3d2745a8 100644 --- a/g10/photoid.c +++ b/g10/photoid.c @@ -1,5 +1,5 @@ /* photoid.c - photo ID handling code - * Copyright (C) 2001, 2002, 2005, 2006, 2008 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2005, 2006, 2008, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -141,8 +141,7 @@ generate_photo_id(PKT_public_key *pk,const char *photo_name) iobuf_close(file); /* Is it a JPEG? */ - if(photo[0]!=0xFF || photo[1]!=0xD8 || - photo[6]!='J' || photo[7]!='F' || photo[8]!='I' || photo[9]!='F') + if(photo[0]!=0xFF || photo[1]!=0xD8) { log_error(_("`%s' is not a JPEG file\n"),filename); xfree(photo); From f6251c0d0af92331388f5e9bcd1750cbadcaca8f Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 16 Dec 2011 09:07:56 +0900 Subject: [PATCH 51/68] Don't kill pinentry by SIGKILL but let it quit by SIGINT. * agent/call-pinentry.c (agent_popup_message_stop): To pinentry, send SIGINT (was: SIGKILL). --- agent/call-pinentry.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index d0cfd2b79..36093bb8b 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -1273,8 +1273,7 @@ agent_popup_message_stop (ctrl_t ctrl) assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1); } else if (pid > 0) - kill (pid, SIGKILL); /* Need to use SIGKILL due to bad - interaction of SIGINT with Pth. */ + kill (pid, SIGINT); #endif /* Now wait for the thread to terminate. */ From f4b7f7146349c388a2f3ce224ff2006606c66232 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 19 Dec 2011 18:26:47 +0100 Subject: [PATCH 52/68] scd: Fix for card change returning GPG_ERR_CARD_RESET. * scd/apdu.c (apdu_connect): Do not test for zero atrlen. -- When gpg-agent prompts for insertion of a card this error would be returned. Co-authored-by: Ben Kibbey --- scd/apdu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scd/apdu.c b/scd/apdu.c index 5a518465c..f47007551 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -3150,8 +3150,7 @@ apdu_connect (int slot) ; else if (!(status & APDU_CARD_PRESENT)) sw = SW_HOST_NO_CARD; - else if (((status & APDU_CARD_PRESENT) && !(status & APDU_CARD_ACTIVE)) - || !reader_table[slot].atrlen) + else if ((status & APDU_CARD_PRESENT) && !(status & APDU_CARD_ACTIVE)) sw = SW_HOST_CARD_INACTIVE; if (DBG_READER) From 07f20f313a0b13e5c93168a8a62ff1cbb94a4514 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 20 Dec 2011 13:34:27 +0900 Subject: [PATCH 53/68] Add error log and debug log for pcsc_keypad_verify and pcsc_keypad_modify. * scd/apdu.c (pcsc_keypad_verify): Add debug log and error log. (pcsc_keypad_modify): Likewise. --- scd/apdu.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/scd/apdu.c b/scd/apdu.c index f47007551..7bb122d30 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -2053,7 +2053,7 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, { int sw; unsigned char *pin_verify; - unsigned long len = PIN_VERIFY_STRUCTURE_SIZE; + int len = PIN_VERIFY_STRUCTURE_SIZE; unsigned char result[2]; size_t resultlen = 2; @@ -2109,12 +2109,21 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, pin_verify[22] = p1; /* abData[3] */ pin_verify[23] = 0x00; /* abData[4] */ + if (DBG_CARD_IO) + log_debug ("send secure: c=%02X i=%02X p1=%02X p2=%02X len=%d pinmax=%d\n", + class, ins, p0, p1, len, pininfo->maxlen); + sw = control_pcsc (slot, reader_table[slot].pcsc.verify_ioctl, pin_verify, len, result, &resultlen); xfree (pin_verify); if (sw || resultlen < 2) - return sw? sw : SW_HOST_INCOMPLETE_CARD_RESPONSE; + { + log_error ("control_pcsc failed: %d\n", sw); + return sw? sw: SW_HOST_INCOMPLETE_CARD_RESPONSE; + } sw = (result[resultlen-2] << 8) | result[resultlen-1]; + if (DBG_CARD_IO) + log_debug (" response: sw=%04X datalen=%d\n", sw, (unsigned int)resultlen); return sw; } @@ -2126,7 +2135,7 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, { int sw; unsigned char *pin_modify; - unsigned long len = PIN_MODIFY_STRUCTURE_SIZE; + int len = PIN_MODIFY_STRUCTURE_SIZE; unsigned char result[2]; size_t resultlen = 2; @@ -2193,12 +2202,21 @@ pcsc_keypad_modify (int slot, int class, int ins, int p0, int p1, pin_modify[27] = p1; /* abData[3] */ pin_modify[28] = 0x00; /* abData[4] */ + if (DBG_CARD_IO) + log_debug ("send secure: c=%02X i=%02X p1=%02X p2=%02X len=%d pinmax=%d\n", + class, ins, p0, p1, len, (int)pininfo->maxlen); + sw = control_pcsc (slot, reader_table[slot].pcsc.modify_ioctl, pin_modify, len, result, &resultlen); xfree (pin_modify); if (sw || resultlen < 2) - return sw? sw : SW_HOST_INCOMPLETE_CARD_RESPONSE; + { + log_error ("control_pcsc failed: %d\n", sw); + return sw? sw : SW_HOST_INCOMPLETE_CARD_RESPONSE; + } sw = (result[resultlen-2] << 8) | result[resultlen-1]; + if (DBG_CARD_IO) + log_debug (" response: sw=%04X datalen=%d\n", sw, (unsigned int)resultlen); return sw; } From 366512abe44d9e71bb2c699c29477afa6ac71cdd Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 20 Dec 2011 11:12:21 +0100 Subject: [PATCH 54/68] Require Libassuan 2.0.3 * configure.ac: Require Libassuan 2.0.3. * agent/call-scd.c (ASSUAN_CONVEY_COMMENTS): Remove macro replacement. * agent/command.c (cmd_killagent) [ASSUAN_FORCE_CLOSE]: Remove dependency. (cmd_killagent) [ASSUAN_FORCE_CLOSE]: Ditto. * scd/command.c (cmd_killscd) [ASSUAN_FORCE_CLOSE]: Ditto. --- agent/call-scd.c | 9 --------- agent/command.c | 4 ---- configure.ac | 2 +- scd/command.c | 7 ------- 4 files changed, 1 insertion(+), 21 deletions(-) diff --git a/agent/call-scd.c b/agent/call-scd.c index 3f535db6d..deff2949a 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -45,15 +45,6 @@ #define MAX_OPEN_FDS 20 #endif -/* This Assuan flag is only available since libassuan 2.0.2. Because - comments lines are comments anyway we can use a replacement which - might not do anything. assuan_{g,s}et_flag don't return an error - thus there won't be any ABI problem. */ -#ifndef ASSUAN_CONVEY_COMMENTS -#define ASSUAN_CONVEY_COMMENTS 4 -#endif - - /* Definition of module local data of the CTRL structure. */ struct scd_local_s { diff --git a/agent/command.c b/agent/command.c index c33c0d61f..ad86a3575 100644 --- a/agent/command.c +++ b/agent/command.c @@ -2310,12 +2310,8 @@ cmd_killagent (assuan_context_t ctx, char *line) return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket"); ctrl->server_local->stopme = 1; -#ifdef ASSUAN_FORCE_CLOSE assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1); return 0; -#else - return gpg_error (GPG_ERR_EOF); -#endif } diff --git a/configure.ac b/configure.ac index f71b9e867..9dd555ea7 100644 --- a/configure.ac +++ b/configure.ac @@ -46,7 +46,7 @@ NEED_LIBGCRYPT_API=1 NEED_LIBGCRYPT_VERSION=1.5.0 NEED_LIBASSUAN_API=2 -NEED_LIBASSUAN_VERSION=2.0.0 +NEED_LIBASSUAN_VERSION=2.0.3 NEED_KSBA_API=1 NEED_KSBA_VERSION=1.2.0 diff --git a/scd/command.c b/scd/command.c index afd5ef231..88f8ec2c9 100644 --- a/scd/command.c +++ b/scd/command.c @@ -1936,15 +1936,8 @@ cmd_killscd (assuan_context_t ctx, char *line) (void)line; ctrl->server_local->stopme = 1; -#ifdef ASSUAN_FORCE_CLOSE assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1); return 0; -#else - /* Actually returning an EOF does not anymore work with modern - Libassuan versions. However we keep that non working code until - we make a Libassuan with the force close flag a requirement. */ - return gpg_error (GPG_ERR_EOF); -#endif } From 779611494dbd187d09b05d2eb10faabd31a70156 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 20 Dec 2011 11:13:40 +0100 Subject: [PATCH 55/68] faq: Add section on US export restrictions. --- doc/faq.org | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/doc/faq.org b/doc/faq.org index ee6c0c758..a11fabebd 100644 --- a/doc/faq.org +++ b/doc/faq.org @@ -1167,13 +1167,8 @@ update this FAQ in the next month. See the section "Changes" for recent updates :CUSTOM_ID: i-get-sed-errors-when-running-configure-on-mac-os-x :END: - This will be fixed after GnuPG has been upgraded to autoconf-2.50. - Until then, find the line setting CDPATH in the configure script - and place an: - - : unset CDPATH - - statement below it. + This problem has been fixed for all modern GnuPG versions. + (By using an autoconf 2.50 generated configure script). ** Why does GnuPG 1.0.6 bail out on keyrings used with 1.0.7? :PROPERTIES: @@ -1470,6 +1465,41 @@ update this FAQ in the next month. See the section "Changes" for recent updates of the listing before before starting the import. +* Bug reporting and hacking + :PROPERTIES: + :CUSTOM_ID: bugreports-et-al + :END: + +** Copyright asssignments + :PROPERTIES: + :CUSTOM_ID: copyright-assigments + :END: + +** U.S. export restrictions + :PROPERTIES: + :CUSTOM_ID: us-export-restrictions + :END: + +GnuPG has originally been developed in Germany because we have been +able to do that without being affected by the US export restrictions. +We had to reject any contributions from US citizens or from people +living the the US. That changed by end of 2000 when the export +restrictions were basically dropped for all kind of freely available +software. However there are still some requirements in the US. +Quoting David Shaw: mail +#+begin_quote +For each release of GPG that I contributed to, I sent an email +containing a pointer to the new source code to the Commerce +Department. The rules changed slightly in 2004, so that you could +send a single email and then be done until the information in that +email changed, so I just sent "www.gnupg.org" and haven't bothered +with the email since. +#+end_quote + +The rules: http://www.bis.doc.gov/encryption/pubavailencsourcecodenofify.html +The 2004 rule change: http://edocket.access.gpo.gov/2004/04-26992.htm + + * Acknowledgements :PROPERTIES: :CUSTOM_ID: acknowledgements From fe2f1826991e8130f727ee15df1a4651f679752f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 20 Dec 2011 15:35:42 +0100 Subject: [PATCH 56/68] Add the STEED Self-Signing Nonthority certificate. * doc/com-certs.pem: Install it when creating a keybox. --- doc/com-certs.pem | 18 +++++++ tests/Makefile.am | 2 + ...A638998DFABAC510EA645CE34F9686B2EDF7EA.key | 10 ++++ tests/samplekeys/README | 7 ++- .../steed-self-signing-nonthority.pem | 54 +++++++++++++++++++ 5 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 tests/samplekeys/68A638998DFABAC510EA645CE34F9686B2EDF7EA.key create mode 100644 tests/samplekeys/steed-self-signing-nonthority.pem diff --git a/doc/com-certs.pem b/doc/com-certs.pem index 43e93b74c..b3d5fa2c3 100644 --- a/doc/com-certs.pem +++ b/doc/com-certs.pem @@ -482,3 +482,21 @@ G1RRiCiWgYaEtSIDAP0V9ehpcghfJLlmMBnxSf4n7OZvkd1whvme2rXaQxnZi2qV d2qclY03eJ7zx6Zpq8VFuVvOxvmFZ4mMe706runhCq+rHc5x6x0/oIMhDrk= -----END CERTIFICATE----- +Issuer ...: /CN=The STEED Self-Signing Nonthority +Serial ...: 01 +Subject ..: /CN=The STEED Self-Signing Nonthority + +-----BEGIN CERTIFICATE----- +MIICKDCCAZGgAwIBAgIBATANBgkqhkiG9w0BAQUFADAsMSowKAYDVQQDEyFUaGUg +U1RFRUQgU2VsZi1TaWduaW5nIE5vbnRob3JpdHkwIBcNMTExMTExMDAwMDAwWhgP +MjEwNjAyMDYwMDAwMDBaMCwxKjAoBgNVBAMTIVRoZSBTVEVFRCBTZWxmLVNpZ25p +bmcgTm9udGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAk2h9kqe8 +0eb8ESY7UGV6j6S5zuP5DiM4TWJ3jKG2y+D2CyA1Sl90iZ6zyN3zCB0yR1xxhpuw +xdrwBRovRFludAbx3MeynYhzXkk0Hwn038q1oIt2YUw3Igz34s24o455ZE86JQ/6 +5dC7ppF8Z1I9KBL96NO+qZR/alVAKxYAwS8CAwEAAaNYMFYwEgYDVR0TAQH/BAgw +BgEB/wIBATARBgorBgEEAdpHAgICBAMBAf8wHQYDVR0OBBYEFGimOJmN+rrFEOpk +XONPloay7ffqMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQB3JwUn +AbOdGv5ErojNSSP+yGZIy5av4wnkzK840Uj3jY6A5cuHroZGOD60hqLV2Hy0npox +zte4phWEKWmZiXd8SCmd3MFNgZSieiixye0qxSmuqYft2j6NhEXD5xc/iTTjFT42 +SjGPLKAICuMBuGPnoozOEVlgqwaDqKOUph5sqw== +-----END CERTIFICATE----- diff --git a/tests/Makefile.am b/tests/Makefile.am index 2142d33d6..307d82952 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -41,6 +41,8 @@ EXTRA_DIST = runtest inittests $(testscripts) ChangeLog-2011 \ text-1.txt text-2.txt text-3.txt \ text-1.osig.pem text-1.dsig.pem text-1.osig-bad.pem \ text-2.osig.pem text-2.osig-bad.pem \ + samplekeys/steed-self-signing-nonthority.pem \ + samplekeys/68A638998DFABAC510EA645CE34F9686B2EDF7EA.key \ samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key \ samplekeys/cert_g10code_pete1.pem \ samplekeys/cert_g10code_test1.pem \ diff --git a/tests/samplekeys/68A638998DFABAC510EA645CE34F9686B2EDF7EA.key b/tests/samplekeys/68A638998DFABAC510EA645CE34F9686B2EDF7EA.key new file mode 100644 index 000000000..8236349a0 --- /dev/null +++ b/tests/samplekeys/68A638998DFABAC510EA645CE34F9686B2EDF7EA.key @@ -0,0 +1,10 @@ +(private-key + (rsa + (n #0093687D92A7BCD1E6FC11263B50657A8FA4B9CEE3F90E23384D62778CA1B6CBE0F60B20354A5F74899EB3C8DDF3081D32475C71869BB0C5DAF0051A2F44596E7406F1DCC7B29D88735E49341F09F4DFCAB5A08B76614C37220CF7E2CDB8A38E79644F3A250FFAE5D0BBA6917C67523D2812FDE8D3BEA9947F6A55402B1600C12F#) + (e #010001#) + (d #11BAAE926B54482C04EDE1C59E877B5F382114F8D1BAAE926B54482C04EDE1C59E877B5F382114F8D1BAAE926B54482C04EDE1C59E877B5F382114F8D1BAAE905D3988DFC39FEF462A0655AC906CBC12F6D322795D3988DFC39FEF462A0655AC906CBC12F6D322795D3988DFC39FEF462A0655AC906CBC12F6D322795D3983C1#) + (p "\x00ÂBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBAÏ") + (q "\x00ÂBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB¡") + (u #00B28879D8EEE03F5546A5BBAD0C2213728879D8EEE03F5546A5BBAD0C2213728879D8EEE03F5546A5BBAD0C2213728879D8EEE03F5546A5BBAD0C221372887A30#) + ) + ) diff --git a/tests/samplekeys/README b/tests/samplekeys/README index a71f7987e..65255cb61 100644 --- a/tests/samplekeys/README +++ b/tests/samplekeys/README @@ -1,6 +1,6 @@ This is a collection of keys we use with the regression tests. -opensc-tests.p12 PKCS#12 key and certificates taken from OpenSC. +opensc-tests.p12 PKCS#12 key and certificates taken from OpenSC. Passphrase is "password" ov-user.p12 Private tests keys from www.openvalidation.org. @@ -17,5 +17,8 @@ gte.pem GTE CyberTrust Global Root cert-with-117-akas.pem A certificate with 117 subjectAltNames. +steed-self-signing-nonthority.pem + The STEED Self-Signing Nonthority. +68A638998DFABAC510EA645CE34F9686B2EDF7EA.key + The private Key of The STEED Self-Signing Nonthority. - diff --git a/tests/samplekeys/steed-self-signing-nonthority.pem b/tests/samplekeys/steed-self-signing-nonthority.pem new file mode 100644 index 000000000..c6a9c54e8 --- /dev/null +++ b/tests/samplekeys/steed-self-signing-nonthority.pem @@ -0,0 +1,54 @@ + + ID: 0x72B0BD08 + S/N: 01 + Issuer: CN=The STEED Self-Signing Nonthority + Subject: CN=The STEED Self-Signing Nonthority + sha1_fpr: E6:99:39:A2:5F:5D:93:F2:06:71:5D:C9:FC:1A:25:DC:72:B0:BD:08 + md5_fpr: C9:83:C8:13:91:53:5A:C2:9A:BA:AF:0E:9C:AF:93:0E + certid: BA9A5990A0E94A627D08D4D06FD15EC561FD15E8.01 + keygrip: 68A638998DFABAC510EA645CE34F9686B2EDF7EA + notBefore: 2011-11-11 00:00:00 + notAfter: 2106-02-06 00:00:00 + hashAlgo: 1.2.840.113549.1.1.5 (sha1WithRSAEncryption) + keyType: 1024 bit RSA + subjKeyId: 68A638998DFABAC510EA645CE34F9686B2EDF7EA + authKeyId: [none] + keyUsage: certSign crlSign + extKeyUsage: [none] + policies: [none] + chainLength: 1 + crlDP: [none] + authInfo: [none] + subjInfo: [none] + extn: 1.3.6.1.4.1.11591.2.2.2 (wellKnownPrivateKey) [3 octets] + + +-----BEGIN CERTIFICATE----- +MIICKDCCAZGgAwIBAgIBATANBgkqhkiG9w0BAQUFADAsMSowKAYDVQQDEyFUaGUg +U1RFRUQgU2VsZi1TaWduaW5nIE5vbnRob3JpdHkwIBcNMTExMTExMDAwMDAwWhgP +MjEwNjAyMDYwMDAwMDBaMCwxKjAoBgNVBAMTIVRoZSBTVEVFRCBTZWxmLVNpZ25p +bmcgTm9udGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAk2h9kqe8 +0eb8ESY7UGV6j6S5zuP5DiM4TWJ3jKG2y+D2CyA1Sl90iZ6zyN3zCB0yR1xxhpuw +xdrwBRovRFludAbx3MeynYhzXkk0Hwn038q1oIt2YUw3Igz34s24o455ZE86JQ/6 +5dC7ppF8Z1I9KBL96NO+qZR/alVAKxYAwS8CAwEAAaNYMFYwEgYDVR0TAQH/BAgw +BgEB/wIBATARBgorBgEEAdpHAgICBAMBAf8wHQYDVR0OBBYEFGimOJmN+rrFEOpk +XONPloay7ffqMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQB3JwUn +AbOdGv5ErojNSSP+yGZIy5av4wnkzK840Uj3jY6A5cuHroZGOD60hqLV2Hy0npox +zte4phWEKWmZiXd8SCmd3MFNgZSieiixye0qxSmuqYft2j6NhEXD5xc/iTTjFT42 +SjGPLKAICuMBuGPnoozOEVlgqwaDqKOUph5sqw== +-----END CERTIFICATE----- + +Created using these parameters: + + Key-Type: RSA + Key-Length: 1024 + Key-Grip: 68A638998DFABAC510EA645CE34F9686B2EDF7EA + Key-Usage: cert + Serial: 1 + Name-DN: CN=The STEED Self-Signing Nonthority + Not-Before: 2011-11-11 + Not-After: 2106-02-06 + Subject-Key-Id: 68A638998DFABAC510EA645CE34F9686B2EDF7EA + Extension: 2.5.29.19 c 30060101ff020101 + Extension: 1.3.6.1.4.1.11591.2.2.2 n 0101ff + Signing-Key: 68A638998DFABAC510EA645CE34F9686B2EDF7EA From 6f02c143440865781b4e3c1753e24e55a0de40e4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 20 Dec 2011 15:54:43 +0100 Subject: [PATCH 57/68] po: Update the German translation. --- po/de.po | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/po/de.po b/po/de.po index fe83f7979..8b982587b 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.1.0\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2011-11-24 14:15+0100\n" +"PO-Revision-Date: 2011-12-20 15:52+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: German \n" "MIME-Version: 1.0\n" @@ -111,9 +111,9 @@ msgstr "Fehler beim Holen der Karten-Seriennummer: %s\n" msgid "detected card with S/N: %s\n" msgstr "Erkannte Karte hat die Seriennummer: %s\n" -#, fuzzy, c-format +#, c-format msgid "no authentication key for ssh on card: %s\n" -msgstr "Fehler beim Holen der Authentisierungsschlüssel-ID der Karte: %s\n" +msgstr "Auf der Karte ist kein Authentisierungsschlüssel für SSH: %s\n" #, c-format msgid "no suitable card key found: %s\n" @@ -5434,17 +5434,11 @@ msgstr "|AN|Neue Admin-PIN" msgid "|N|New PIN" msgstr "|N|Neue PIN" -#, fuzzy -msgid "||Please enter the Reset Code for the card and New PIN" -msgstr "Bitte geben Sie den Rückstellcode für diese Karte ein" - -#, fuzzy msgid "||Please enter the Admin PIN and New Admin PIN" -msgstr "|A|Bitte die Admin-PIN eingeben." +msgstr "|A|Bitte die Admin-PIN sowie die neue Admin-PIN eingeben." -#, fuzzy msgid "||Please enter the PIN and New PIN" -msgstr "||Bitte die PIN eingeben" +msgstr "||Bitte die PIN sowie die neue PIN eingeben" msgid "error reading application data\n" msgstr "Fehler beim Lesen der Anwendungsdaten\n" @@ -5880,6 +5874,18 @@ msgstr "" msgid "line %d: invalid hash algorithm given\n" msgstr "Zeile %d: Ungültiges Hashverfahren\n" +#, c-format +msgid "line %d: invalid authority-key-id\n" +msgstr "Zeile %d: Ungültige Authentisierungsschlüssel-ID\n" + +#, c-format +msgid "line %d: invalid subject-key-id\n" +msgstr "Zeile %d: ungültige \"Subject-Key-Id\"\n" + +#, c-format +msgid "line %d: invalid extension syntax\n" +msgstr "Zeile %d: Ungültiger Syntax der Extension\n" + #, c-format msgid "line %d: error reading key `%s' from card: %s\n" msgstr "Zeile %d: Fehler beim Lesen des Schlüssels `%s' von der Karte: %s\n" @@ -7925,6 +7931,10 @@ msgstr "" "Syntax: gpg-check-pattern [optionen] Musterdatei\n" "Die von stdin gelesene Passphrase gegen die Musterdatei prüfen\n" +#, fuzzy +#~ msgid "||Please enter the Reset Code for the card and New PIN" +#~ msgstr "Bitte geben Sie den Rückstellcode für diese Karte ein" + #~ msgid " - probably dead - removing lock" #~ msgstr " - existiert wahrscheinlich nicht mehr - entferne Sperre" From 8e47f1e576f70d4dbe966523057fe3078006ae8b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 20 Dec 2011 15:55:43 +0100 Subject: [PATCH 58/68] Prepare for the beta3 release. --- NEWS | 4 ++-- README.maint | 2 +- configure.ac | 4 ++-- doc/HACKING | 13 ++++++++----- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/NEWS b/NEWS index 4364405b1..7d7740646 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -Noteworthy changes in version 2.1.0beta3 +Noteworthy changes in version 2.1.0beta3 (2011-12-20) ----------------------------------------------------- * Fixed regression in GPG's secret key export function. @@ -15,7 +15,7 @@ Noteworthy changes in version 2.1.0beta3 * gpg-connect-agent does now proberly display the help output for "SCD HELP" commands. - * New GPGSM validation model "steed". + * Preliminary support for the GPGSM validation model "steed". * Improved certificate creation in GPGSM. diff --git a/README.maint b/README.maint index f390afc97..bdcdbf9c0 100644 --- a/README.maint +++ b/README.maint @@ -27,8 +27,8 @@ Release process: * Run "make -C po update-po". * Write NEWS entries and set the release date in NEWS. * In configure.ac set "my_issvn" to "no". - * Put a "Release " line into the top level ChangeLog. * Commit all changes to GIT and push them. + * Do a commit with a "Release " line. * Run "./autogen.sh --force" (--force is required for the svn magic in configure.ac and a good idea in any case) diff --git a/configure.ac b/configure.ac index 9dd555ea7..b3c767878 100644 --- a/configure.ac +++ b/configure.ac @@ -24,8 +24,8 @@ min_automake_version="1.10" # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [2.1.0]) -m4_define([my_issvn], [yes]) +m4_define([my_version], [2.1.0beta3]) +m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) diff --git a/doc/HACKING b/doc/HACKING index d6cb8ab4c..0ef5b891d 100644 --- a/doc/HACKING +++ b/doc/HACKING @@ -23,7 +23,8 @@ and ChangeLog entries don't give enough of the big picture. Omit the leading TABs that you're used to seeing in a "real" ChangeLog file, but keep the maximum line length at 72 or smaller, so that the generated ChangeLog lines, each with its leading TAB, will not exceed 80 columns. - +If you want to add text which shall not be copied to the ChangeLog, +separate it by a line consisting of two dashes at the begin of a line. ===> What follows is probably out of date <=== @@ -39,15 +40,17 @@ RFCs 1750 Randomness Recommendations for Security. -1991 PGP Message Exchange Formats. - -2015 MIME Security with Pretty Good Privacy (PGP). +1991 PGP Message Exchange Formats (obsolete) 2144 The CAST-128 Encryption Algorithm. 2279 UTF-8, a transformation format of ISO 10646. -2440 OpenPGP. +2440 OpenPGP (obsolete). + +3156 MIME Security with Pretty Good Privacy (PGP). + +4880 Current OpenPGP specification. From 604c130a85d4203b9d84137a42673aeaff1c0bd1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 20 Dec 2011 16:46:18 +0100 Subject: [PATCH 59/68] Release 2.1.0beta3. From 97d1c884e62bba94e42bb5b2bb13cd3880334c31 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 20 Dec 2011 17:10:28 +0100 Subject: [PATCH 60/68] Post-release version number update --- NEWS | 4 ++++ configure.ac | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 7d7740646..65297dd37 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 2.1.0beta4 (unreleased) +----------------------------------------------------- + + Noteworthy changes in version 2.1.0beta3 (2011-12-20) ----------------------------------------------------- diff --git a/configure.ac b/configure.ac index b3c767878..9dd555ea7 100644 --- a/configure.ac +++ b/configure.ac @@ -24,8 +24,8 @@ min_automake_version="1.10" # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [2.1.0beta3]) -m4_define([my_issvn], [no]) +m4_define([my_version], [2.1.0]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) From c6aaf024651c7d55ac9fb77a53c084efb3adc1a9 Mon Sep 17 00:00:00 2001 From: David Shaw Date: Wed, 28 Dec 2011 16:41:31 -0500 Subject: [PATCH 61/68] Use the longest key ID available when talking to a HKP server. This is issue 1340. Now that PKSD is dead, and SKS supports long key IDs, this is safe to do. Patch from Daniel Kahn Gillmor . --- keyserver/gpgkeys_hkp.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/keyserver/gpgkeys_hkp.c b/keyserver/gpgkeys_hkp.c index d43a61ab5..ac7039d06 100644 --- a/keyserver/gpgkeys_hkp.c +++ b/keyserver/gpgkeys_hkp.c @@ -241,9 +241,10 @@ static int get_key(char *getkey) { CURLcode res; - char request[MAX_URL+60]; + char request[MAX_URL+92]; char *offset; struct curl_writer_ctx ctx; + size_t keylen; memset(&ctx,0,sizeof(ctx)); @@ -269,14 +270,19 @@ get_key(char *getkey) strcat(request,port); strcat(request,opt->path); /* request is MAX_URL+55 bytes long - MAX_URL covers the whole URL, - including any supplied path. The 60 overcovers this /pks/... etc - string plus the 8 bytes of key id */ + including any supplied path. The 92 overcovers this /pks/... etc + string plus the 8, 16, or 40 bytes of key id/fingerprint */ append_path(request,"/pks/lookup?op=get&options=mr&search=0x"); - /* fingerprint or long key id. Take the last 8 characters and treat - it like a short key id */ - if(strlen(getkey)>8) - offset=&getkey[strlen(getkey)-8]; + /* send only fingerprint, long key id, or short keyid. see: + https://tools.ietf.org/html/draft-shaw-openpgp-hkp-00#section-3.1.1.1 */ + keylen = strlen(getkey); + if(keylen >= 40) + offset=&getkey[keylen-40]; + else if(keylen >= 16) + offset=&getkey[keylen-16]; + else if(keylen >= 8) + offset=&getkey[keylen-8]; else offset=getkey; From a2d9e48fcca6cfc2dfadef6dbd3579a30314676b Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Mon, 2 Jan 2012 22:15:00 +0100 Subject: [PATCH 62/68] Only set gcrypt thread callback for older version of gcrypt. * agent/gpg-agent.c, dirmngr/dirmngr.c, g13/g13.c, scd/scdaemon.c (USE_GCRY_THREAD_CBS): New macro, defined if GCRY_THREAD_OPTION_VERSION is 0. (fixed_gcry_pth_init) [!USE_GCRY_THREAD_CBS]: Don't define. (main) [!USE_GCRY_THREAD_CBS]: Do not install thread callbacks. --- agent/gpg-agent.c | 9 +++++++++ dirmngr/dirmngr.c | 8 ++++++++ g13/g13.c | 10 ++++++++++ scd/scdaemon.c | 10 +++++++++- 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 6dcde26af..f98d821ae 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -289,11 +289,18 @@ static int check_for_running_agent (int silent, int mode); /* Pth wrapper function definitions. */ ASSUAN_SYSTEM_PTH_IMPL; +#if defined(GCRY_THREAD_OPTION_VERSION) && (GCRY_THREAD_OPTION_VERSION == 0) +#define USE_GCRY_THREAD_CBS 1 +#endif + +#ifdef USE_GCRY_THREAD_CBS GCRY_THREAD_OPTION_PTH_IMPL; + static int fixed_gcry_pth_init (void) { return pth_self ()? 0 : (pth_init () == FALSE) ? errno : 0; } +#endif #ifndef PTH_HAVE_PTH_THREAD_ID @@ -618,6 +625,7 @@ main (int argc, char **argv ) init_common_subsystems (&argc, &argv); +#ifdef USE_GCRY_THREAD_CBS /* Libgcrypt requires us to register the threading model first. Note that this will also do the pth_init. */ gcry_threads_pth.init = fixed_gcry_pth_init; @@ -627,6 +635,7 @@ main (int argc, char **argv ) log_fatal ("can't register GNU Pth with Libgcrypt: %s\n", gpg_strerror (err)); } +#endif /* Check that the libraries are suitable. Do it here because diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index e1bae7ea3..7d478b373 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -280,11 +280,17 @@ static void handle_connections (assuan_fd_t listen_fd); /* Pth wrapper function definitions. */ ASSUAN_SYSTEM_PTH_IMPL; +#if GCRY_THREAD_OPTION_VERSION == 0 +#define FIX_GCRY_PTH_INIT 1 +#endif + +#ifdef FIX_GCRY_PTH_INIT GCRY_THREAD_OPTION_PTH_IMPL; static int fixed_gcry_pth_init (void) { return pth_self ()? 0 : (pth_init () == FALSE) ? errno : 0; } +#endif #ifndef PTH_HAVE_PTH_THREAD_ID static unsigned long pth_thread_id (void) @@ -618,6 +624,7 @@ main (int argc, char **argv) i18n_init (); init_common_subsystems (&argc, &argv); +#ifdef USE_GCRY_THREAD_CBS /* Libgcrypt requires us to register the threading model first. Note that this will also do the pth_init. */ gcry_threads_pth.init = fixed_gcry_pth_init; @@ -627,6 +634,7 @@ main (int argc, char **argv) log_fatal ("can't register GNU Pth with Libgcrypt: %s\n", gpg_strerror (rc)); } +#endif gcry_control (GCRYCTL_DISABLE_SECMEM, 0); /* Check that the libraries are suitable. Do it here because diff --git a/g13/g13.c b/g13/g13.c index 8e5532c47..e38f21165 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -204,11 +204,18 @@ static void join_idle_task (void); /* Begin Pth wrapper functions. */ ASSUAN_SYSTEM_PTH_IMPL; +#if GCRY_THREAD_OPTION_VERSION == 0 +#define FIX_GCRY_PTH_INIT 1 +#endif + +#ifdef FIX_GCRY_PTH_INIT GCRY_THREAD_OPTION_PTH_IMPL; static int fixed_gcry_pth_init (void) { return pth_self ()? 0 : (pth_init () == FALSE) ? errno : 0; } +#endif + /* End Pth wrapper functions. */ @@ -361,6 +368,8 @@ main ( int argc, char **argv) i18n_init (); init_common_subsystems (&argc, &argv); + +#ifdef USE_GCRY_THREAD_CBS /* Libgcrypt requires us to register the threading model first. Note that this will also do the pth_init. */ gcry_threads_pth.init = fixed_gcry_pth_init; @@ -370,6 +379,7 @@ main ( int argc, char **argv) log_fatal ("can't register GNU Pth with Libgcrypt: %s\n", gpg_strerror (err)); } +#endif /* Check that the Libgcrypt is suitable. */ if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) diff --git a/scd/scdaemon.c b/scd/scdaemon.c index c8905d4f0..128ecc31d 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -208,12 +208,18 @@ static void handle_connections (int listen_fd); /* Pth wrapper function definitions. */ ASSUAN_SYSTEM_PTH_IMPL; +#if defined(GCRY_THREAD_OPTION_VERSION) && (GCRY_THREAD_OPTION_VERSION == 0) +#define USE_GCRY_THREAD_CBS 1 +#endif + +#ifdef USE_GCRY_THREAD_CBS GCRY_THREAD_OPTION_PTH_IMPL; + static int fixed_gcry_pth_init (void) { return pth_self ()? 0 : (pth_init () == FALSE) ? errno : 0; } - +#endif static char * @@ -413,6 +419,7 @@ main (int argc, char **argv ) /* Libgcrypt requires us to register the threading model first. Note that this will also do the pth_init. */ +#ifdef USE_GCRY_THREAD_CBS gcry_threads_pth.init = fixed_gcry_pth_init; err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth); if (err) @@ -420,6 +427,7 @@ main (int argc, char **argv ) log_fatal ("can't register GNU Pth with Libgcrypt: %s\n", gpg_strerror (err)); } +#endif /* Check that the libraries are suitable. Do it here because the option parsing may need services of the library */ From d01d9ff11f46cbd61b7b8c0e04431e4f0c4a8580 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 3 Jan 2012 11:13:30 +0100 Subject: [PATCH 63/68] Terminate csh commands with a semicolon. Fixes bug#1386. * agent/gpg-agent.c (main): Terminate csh style output with a semicolon. * scd/scdaemon.c: Ditto. --- agent/gpg-agent.c | 4 ++-- scd/scdaemon.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index f98d821ae..63f4ba2c8 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1197,11 +1197,11 @@ main (int argc, char **argv ) if (csh_style) { *strchr (infostr, '=') = ' '; - es_printf ("setenv %s\n", infostr); + es_printf ("setenv %s;\n", infostr); if (opt.ssh_support) { *strchr (infostr_ssh_sock, '=') = ' '; - es_printf ("setenv %s\n", infostr_ssh_sock); + es_printf ("setenv %s;\n", infostr_ssh_sock); } } else diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 128ecc31d..6f8d01049 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -843,7 +843,7 @@ main (int argc, char **argv ) if (csh_style) { *strchr (infostr, '=') = ' '; - es_printf ( "setenv %s\n", infostr); + es_printf ( "setenv %s;\n", infostr); } else { From 682df45d15661ed3544e2ed34bcb636200cc40f9 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 3 Jan 2012 11:14:14 +0100 Subject: [PATCH 64/68] Terminate csh commands with a semicolon also for dirmngr. * dirmngr/dirmngr.c (main): Terminate csh style output with a semicolon. --- dirmngr/dirmngr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 7d478b373..a72acd01c 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -1066,7 +1066,7 @@ main (int argc, char **argv) if (csh_style) { *strchr (infostr, '=') = ' '; - es_printf ( "setenv %s\n", infostr); + es_printf ( "setenv %s;\n", infostr); } else { From 61ccd8d92d9d3b8ba0eca3c2969d7f6f37e16405 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Tue, 3 Jan 2012 16:50:52 +0100 Subject: [PATCH 65/68] Fix last change: Only set gcrypt thread callback for older versions. * dirmngr/dirmngr.c, g13/g13.c: Rename FIX_GCRY_PTH_INIT to USE_GCRY_THREAD_CBS. --- dirmngr/dirmngr.c | 4 ++-- g13/g13.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index a72acd01c..2256c591c 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -281,10 +281,10 @@ static void handle_connections (assuan_fd_t listen_fd); ASSUAN_SYSTEM_PTH_IMPL; #if GCRY_THREAD_OPTION_VERSION == 0 -#define FIX_GCRY_PTH_INIT 1 +#define USE_GCRY_THREAD_CBS 1 #endif -#ifdef FIX_GCRY_PTH_INIT +#ifdef USE_GCRY_THREAD_CBS GCRY_THREAD_OPTION_PTH_IMPL; static int fixed_gcry_pth_init (void) { diff --git a/g13/g13.c b/g13/g13.c index e38f21165..bc05977c5 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -205,10 +205,10 @@ static void join_idle_task (void); ASSUAN_SYSTEM_PTH_IMPL; #if GCRY_THREAD_OPTION_VERSION == 0 -#define FIX_GCRY_PTH_INIT 1 +#define USE_GCRY_THREAD_CBS 1 #endif -#ifdef FIX_GCRY_PTH_INIT +#ifdef USE_GCRY_THREAD_CBS GCRY_THREAD_OPTION_PTH_IMPL; static int fixed_gcry_pth_init (void) { From 0dce26778ef8abd4fc40de689d7ec9b720d26430 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Tue, 3 Jan 2012 17:08:01 +0100 Subject: [PATCH 66/68] Fix compiler warnings. * common/dotlock.c (use_hardlinks_p, dotlock_take_unix): Check return value of link(). * g13/g13.c: Make sure err is initialized. * scd/scdaemon.c (main) [!USE_GCRY_THREAD_CBS]: Do not define ERR. --- common/dotlock.c | 30 +++++++++++++++++++++--------- g13/g13.c | 1 + scd/scdaemon.c | 2 ++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/common/dotlock.c b/common/dotlock.c index b4734b99f..58a3d0f2a 100644 --- a/common/dotlock.c +++ b/common/dotlock.c @@ -583,16 +583,21 @@ use_hardlinks_p (const char *tname) strcpy (lname, tname); strcat (lname, "x"); - link (tname, lname); - - if (stat (tname, &sb)) - res = -1; /* Ooops. */ - else if (sb.st_nlink == nlink + 1) - res = 0; /* Yeah, hardlinks are supported. */ + res = link (tname, lname); + if (res < 0) + res = -1; else - res = 1; /* No hardlink support. */ + { + if (stat (tname, &sb)) + res = -1; /* Ooops. */ + else if (sb.st_nlink == nlink + 1) + res = 0; /* Yeah, hardlinks are supported. */ + else + res = 1; /* No hardlink support. */ + + unlink (lname); + } - unlink (lname); jnlib_free (lname); return res; } @@ -948,6 +953,7 @@ dotlock_destroy (dotlock_t h) static int dotlock_take_unix (dotlock_t h, long timeout) { + int res; int wtime = 0; int sumtime = 0; int pid; @@ -1004,7 +1010,13 @@ dotlock_take_unix (dotlock_t h, long timeout) { struct stat sb; - link (h->tname, h->lockname); + res = link (h->tname, h->lockname); + if (res < 0) + { + my_error_1 ("lock not made: Oops: link of tmp file failed: %s\n", + strerror (errno)); + return -1; + } if (stat (h->tname, &sb)) { diff --git a/g13/g13.c b/g13/g13.c index bc05977c5..0f7309490 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -686,6 +686,7 @@ main ( int argc, char **argv) #endif /*0*/ /* Dispatch command. */ + err = 0; switch (cmd) { case aGPGConfList: diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 6f8d01049..e26beba13 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -382,7 +382,9 @@ main (int argc, char **argv ) { ARGPARSE_ARGS pargs; int orig_argc; +#ifdef USE_GCRY_THREAD_CBS gpg_error_t err; +#endif char **orig_argv; FILE *configfp = NULL; char *configname = NULL; From ff2095ad7b4be7eaf9468b6ef39fd979527ecc4f Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Tue, 3 Jan 2012 17:32:41 +0100 Subject: [PATCH 67/68] Revert last change, add comment about link() return values. * common/dotlock.c (use_hardlinks_p, dotlock_take_unix): Do not check return value of link(). --- common/dotlock.c | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/common/dotlock.c b/common/dotlock.c index 58a3d0f2a..5e17e64c6 100644 --- a/common/dotlock.c +++ b/common/dotlock.c @@ -583,21 +583,17 @@ use_hardlinks_p (const char *tname) strcpy (lname, tname); strcat (lname, "x"); - res = link (tname, lname); - if (res < 0) - res = -1; + /* We ignore the return value of link() because it is unreliable. */ + (void) link (tname, lname); + + if (stat (tname, &sb)) + res = -1; /* Ooops. */ + else if (sb.st_nlink == nlink + 1) + res = 0; /* Yeah, hardlinks are supported. */ else - { - if (stat (tname, &sb)) - res = -1; /* Ooops. */ - else if (sb.st_nlink == nlink + 1) - res = 0; /* Yeah, hardlinks are supported. */ - else - res = 1; /* No hardlink support. */ - - unlink (lname); - } + res = 1; /* No hardlink support. */ + unlink (lname); jnlib_free (lname); return res; } @@ -953,7 +949,6 @@ dotlock_destroy (dotlock_t h) static int dotlock_take_unix (dotlock_t h, long timeout) { - int res; int wtime = 0; int sumtime = 0; int pid; @@ -1010,13 +1005,8 @@ dotlock_take_unix (dotlock_t h, long timeout) { struct stat sb; - res = link (h->tname, h->lockname); - if (res < 0) - { - my_error_1 ("lock not made: Oops: link of tmp file failed: %s\n", - strerror (errno)); - return -1; - } + /* We ignore the return value of link() because it is unreliable. */ + (void) link (h->tname, h->lockname); if (stat (h->tname, &sb)) { From ed432f030e604f7b2fd4a79c2110d92b9cde7501 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Tue, 3 Jan 2012 17:38:24 +0100 Subject: [PATCH 68/68] Silence gcc warning. * sm/call-dirmngr.c (get_cached_cert): Make sure buflen is initialized. --- sm/call-dirmngr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index cdaa9dcfa..92f7a0e2c 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -816,7 +816,7 @@ get_cached_cert (assuan_context_t ctx, char hexfpr[2*20+1]; struct membuf mb; char *buf; - size_t buflen; + size_t buflen = 0; ksba_cert_t cert; *r_cert = NULL;