From cvs at cvs.gnupg.org Sun Nov 6 17:52:41 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 06 Nov 2011 17:52:41 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-115-g958f29d Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 958f29d2251a96d09439e591ea3523133930e5e9 (commit) via 32118628a0f20f87791755a0a110491ad85e23ad (commit) from 7dfcc9f19acfe8f0dc70db8d981b79aac0589cf4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 958f29d2251a96d09439e591ea3523133930e5e9 Author: Werner Koch Date: Sun Nov 6 17:01:31 2011 +0100 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. diff --git a/g10/ChangeLog b/g10/ChangeLog index 4b5f2f1..8928780 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 5a10dbd..4451029 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]; */ - -/* *r_pubkey = NULL; */ -/* rc = start_agent (ctrl); */ -/* if (rc) */ -/* return rc; */ - -/* rc = assuan_transact (agent_ctx, "RESET",NULL, NULL, NULL, NULL, NULL, NULL); */ -/* if (rc) */ -/* return rc; */ - -/* snprintf (line, DIM(line)-1, "%sREADKEY %s", */ -/* fromcard? "SCD ":"", hexkeygrip); */ -/* line[DIM(line)-1] = 0; */ - -/* 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; */ -/* } */ +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; + err = start_agent (ctrl, 0); + if (err) + return err; + + 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); + + 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 1e7e15a..43de14f 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 9c124bb..14268df 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 c31a558..aa37a88 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 fd42439..26e05a0 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 a5650a8..55048b1 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 9548731..7088abe 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); commit 32118628a0f20f87791755a0a110491ad85e23ad Author: Werner Koch Date: Wed Nov 2 18:29:47 2011 +0100 typo fixes diff --git a/doc/gpg.texi b/doc/gpg.texi index 715b599..d00e01f 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} ----------------------------------------------------------------------- Summary of changes: doc/gpg.texi | 4 +- g10/ChangeLog | 12 ++++ g10/call-agent.c | 89 +++++++++++++------------- 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 +- 9 files changed, 248 insertions(+), 65 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Nov 11 16:54:12 2011 From: cvs at cvs.gnupg.org (by Jim Meyering) Date: Fri, 11 Nov 2011 16:54:12 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-14-g377ff84 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 377ff84d2187e02e723068d2b14a25cdbc7f5755 (commit) from ba7127721035ee0937167e16465cc9f40b39257d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 377ff84d2187e02e723068d2b14a25cdbc7f5755 Author: Jim Meyering Date: Fri Nov 11 11:38:19 2011 +0100 tests: avoid write-beyond-end-of-heap buffer In libgcrypt's "make check" (latest from git), I was surprised to see the "basic" test fail. Here's a patch: Avoid scary-looking (with MALLOC_CHECK_=3) "make check" test failure: *** glibc detected *** /h/j/w/co/libgcrypt/tests/.libs/lt-basic: free(): invalid pointer: 0x0000000001f9d080 *** ======= Backtrace: ========= /lib64/libc.so.6[0x3a5807c606] /w/libgcrypt/src/.libs/libgcrypt.so.19(+0x100c9)[0x7f890edb90c9] /w/libgcrypt/src/.libs/libgcrypt.so.19(+0xb03e)[0x7f890edb403e] /w/libgcrypt/src/.libs/libgcrypt.so.19(gcry_free+0x18)[0x7f890edb1eef] /w/libgcrypt/tests/.libs/lt-basic[0x4091f4] /w/libgcrypt/tests/.libs/lt-basic[0x40b541] /lib64/libc.so.6(__libc_start_main+0xed)[0x3a5802169d] /w/libgcrypt/tests/.libs/lt-basic[0x401979] ======= Memory map: ======== 00400000-00411000 r-xp 00000000 08:08 2787510 /w/co/libgcrypt/tests/.libs/lt-basic ... >From 722e6d470371bb3d995e0a6a67cd9c2ffd7bb664 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Fri, 11 Nov 2011 11:34:45 +0100 Subject: [PATCH] tests: avoid write-beyond-end-of-heap buffer * basic.c (check_bulk_cipher_modes): Allocate one more byte in each of the two test buffers. Otherwise, running "env -i MALLOC_CHECK_=3 ./basic" would abort. diff --git a/tests/ChangeLog b/tests/ChangeLog index 8e96898..573b331 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,10 @@ +2011-11-11 Jim Meyering + + tests: avoid write-beyond-end-of-heap buffer + * basic.c (check_bulk_cipher_modes): Allocate one more byte in + each of the two test buffers. Otherwise, running + "env -i MALLOC_CHECK_=3 ./basic" would abort. + 2011-09-15 Werner Koch * register.c: Remove. diff --git a/tests/basic.c b/tests/basic.c index cdc3462..9b2d0a8 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -1251,9 +1251,9 @@ check_bulk_cipher_modes (void) fprintf (stderr, "Starting bulk cipher checks.\n"); buflen = 16*100; /* We check a 1600 byte buffer. */ - buffer_base = gcry_xmalloc (buflen+15); + buffer_base = gcry_xmalloc (buflen+16); buffer = buffer_base + (16 - ((size_t)buffer_base & 0x0f)); - outbuf_base = gcry_xmalloc (buflen+15); + outbuf_base = gcry_xmalloc (buflen+16); outbuf = outbuf_base + (16 - ((size_t)outbuf_base & 0x0f)); ----------------------------------------------------------------------- Summary of changes: tests/ChangeLog | 7 +++++++ tests/basic.c | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Nov 22 16:21:52 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 22 Nov 2011 16:21:52 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-116-gea9df94 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via ea9df94ec8d6b7b13bd65ea14caca015bd534460 (commit) from 958f29d2251a96d09439e591ea3523133930e5e9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ea9df94ec8d6b7b13bd65ea14caca015bd534460 Author: Werner Koch Date: Tue Nov 22 15:30:26 2011 +0100 Don't print anonymous recipient messages in quiet mode. This is bug#1378. diff --git a/g10/ChangeLog b/g10/ChangeLog index 8928780..c799fc9 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 680182b..a0fe685 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) ----------------------------------------------------------------------- Summary of changes: g10/ChangeLog | 5 +++++ g10/pubkey-enc.c | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 24 15:08:37 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 24 Nov 2011 15:08:37 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-117-g725d358 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 725d3589ada10266e4350f56a4f89e4d82b4dc16 (commit) from ea9df94ec8d6b7b13bd65ea14caca015bd534460 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 725d3589ada10266e4350f56a4f89e4d82b4dc16 Author: Werner Koch Date: Thu Nov 24 14:16:22 2011 +0100 Updated the German translation. * po/de.po: Update. diff --git a/po/de.po b/po/de.po index 5f80e09..51d7e03 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 at 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" @@ -3595,6 +3594,19 @@ 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" ----------------------------------------------------------------------- Summary of changes: po/de.po | 56 +++++++++++++++++++++++++++++--------------------------- 1 files changed, 29 insertions(+), 27 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 24 16:42:41 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 24 Nov 2011 16:42:41 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-118-gd2a9794 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via d2a979452e541183cae7e6e04634b5bbdab9c9d7 (commit) from 725d3589ada10266e4350f56a4f89e4d82b4dc16 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d2a979452e541183cae7e6e04634b5bbdab9c9d7 Author: Werner Koch Date: Thu Nov 24 15:48:24 2011 +0100 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. diff --git a/dirmngr/ChangeLog b/dirmngr/ChangeLog index a06558c..0968b41 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 3ada60d..a8b84e6 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 14de4d6..9ebf69b 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 d4a1211..98187ab 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 2ce1b19..b0e2e14 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 87121fd..638348b 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)) ----------------------------------------------------------------------- Summary of changes: 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(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Nov 24 17:07:26 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 24 Nov 2011 17:07:26 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-120-g0689f0f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 0689f0fc32cc9a8e431d33ee3431d23f3fd1f258 (commit) via 231d27e0fec905be52d679961332947c3331f15f (commit) from d2a979452e541183cae7e6e04634b5bbdab9c9d7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0689f0fc32cc9a8e431d33ee3431d23f3fd1f258 Merge: 231d27e d2a9794 Author: Werner Koch Date: Thu Nov 24 16:16:43 2011 +0100 Merge branch 'master' of git+ssh://playfair.gnupg.org/git/gnupg commit 231d27e0fec905be52d679961332947c3331f15f Author: Werner Koch Date: Thu Nov 24 15:48:24 2011 +0100 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. diff --git a/dirmngr/ChangeLog b/dirmngr/ChangeLog index a06558c..0968b41 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 3ada60d..a8b84e6 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 14de4d6..9ebf69b 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 d4a1211..98187ab 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 2ce1b19..b0e2e14 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 87121fd..638348b 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)) ----------------------------------------------------------------------- Summary of changes: hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Nov 28 09:11:35 2011 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Mon, 28 Nov 2011 09:11:35 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-121-g26b4a01 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 26b4a012e3eb3a6ce79a1e53f7cdfbbdf8c8e8f5 (commit) from 0689f0fc32cc9a8e431d33ee3431d23f3fd1f258 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 26b4a012e3eb3a6ce79a1e53f7cdfbbdf8c8e8f5 Author: NIIBE Yutaka Date: Mon Nov 28 16:16:38 2011 +0900 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. diff --git a/scd/ChangeLog b/scd/ChangeLog index 45c9c7c..9f991ce 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 ac563ad..866ebb9 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; @@ -1172,6 +1196,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) { pcsc_release_context (reader_table[slot].pcsc.context); @@ -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 7c01887..4dff9eb 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 30beb8e..50db78e 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 c1b2aa3..28ccb9a 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 eb0b4f0..d7efad5 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 318fec8..1238552 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 a37759d..58e81d4 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 ee974ac..73b25f4 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); ----------------------------------------------------------------------- Summary of changes: 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(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Nov 28 11:41:02 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 28 Nov 2011 11:41:02 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-122-g781e974 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 781e9746dff21fc2721373205e63d1d09722d590 (commit) from 26b4a012e3eb3a6ce79a1e53f7cdfbbdf8c8e8f5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 781e9746dff21fc2721373205e63d1d09722d590 Author: Werner Koch Date: Mon Nov 28 10:39:36 2011 +0100 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. diff --git a/agent/ChangeLog b/agent/ChangeLog index 3c52e1f..2635579 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 7b4d479..54e56ea 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); ----------------------------------------------------------------------- Summary of changes: agent/ChangeLog | 7 +++++++ agent/command-ssh.c | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Nov 28 15:58:25 2011 From: cvs at cvs.gnupg.org (by Jim Meyering) Date: Mon, 28 Nov 2011 15:58:25 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-123-g77ee8fd Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 77ee8fd55c9e599f41a3cad0ebaa23c72ca14409 (commit) from 781e9746dff21fc2721373205e63d1d09722d590 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 77ee8fd55c9e599f41a3cad0ebaa23c72ca14409 Author: Jim Meyering Date: Mon Nov 28 13:47:08 2011 +0100 accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix * m4/gpg-error.m4: Update from git master. diff --git a/ChangeLog b/ChangeLog index bd02016..7e17ba8 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 2e5a0ab..35cbc78 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 ----------------------------------------------------------------------- Summary of changes: ChangeLog | 5 +++++ m4/gpg-error.m4 | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Nov 28 15:59:55 2011 From: cvs at cvs.gnupg.org (by Jim Meyering) Date: Mon, 28 Nov 2011 15:59:55 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-15-ge56e1de Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via e56e1ded234f73a3c6286fb2b3cc652d8ebabbfa (commit) from 377ff84d2187e02e723068d2b14a25cdbc7f5755 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e56e1ded234f73a3c6286fb2b3cc652d8ebabbfa Author: Jim Meyering Date: Mon Nov 28 13:46:16 2011 +0100 accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix * m4/gpg-error.m4: Update from git master. diff --git a/ChangeLog b/ChangeLog index 4bd3ee2..8d3d04d 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-15 Werner Koch * configure.ac: Bump LT version at C19/A0/R0 due to the ABI change. diff --git a/m4/gpg-error.m4 b/m4/gpg-error.m4 index 8d82925..eb5d7c4 100644 --- a/m4/gpg-error.m4 +++ b/m4/gpg-error.m4 @@ -14,10 +14,21 @@ dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) dnl Test for libgpg-error and define GPG_ERROR_CFLAGS and GPG_ERROR_LIBS dnl AC_DEFUN([AM_PATH_GPG_ERROR], -[ 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 ----------------------------------------------------------------------- Summary of changes: ChangeLog | 5 +++++ m4/gpg-error.m4 | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Mon Nov 28 16:00:39 2011 From: cvs at cvs.gnupg.org (by Jim Meyering) Date: Mon, 28 Nov 2011 16:00:39 +0100 Subject: [git] KSBA - branch, master, updated. libksba-1.2.0-1-g95d25a9 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "KSBA is a library to access X.509 certificates and CMS data.". The branch, master has been updated via 95d25a9bd2c638db9e7c45b38a37fa8222337411 (commit) from 0b81a5a30f4b57c80b379cd974914400c622f168 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 95d25a9bd2c638db9e7c45b38a37fa8222337411 Author: Jim Meyering Date: Mon Nov 28 13:45:36 2011 +0100 accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix * m4/gpg-error.m4: Update from git master. diff --git a/ChangeLog b/ChangeLog index ab252d9..ce9a49d 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-03-01 Werner Koch Release 1.2.0. diff --git a/m4/gpg-error.m4 b/m4/gpg-error.m4 index 2e5a0ab..35cbc78 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 ----------------------------------------------------------------------- Summary of changes: ChangeLog | 5 +++++ m4/gpg-error.m4 | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) hooks/post-receive -- KSBA is a library to access X.509 certificates and CMS data. http://git.gnupg.org From cvs at cvs.gnupg.org Mon Nov 28 16:00:48 2011 From: cvs at cvs.gnupg.org (by Jim Meyering) Date: Mon, 28 Nov 2011 16:00:48 +0100 Subject: [git] Assuan - branch, master, updated. libassuan-2.0.2-4-g2e037ba Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPC library used by GnuPG". The branch, master has been updated via 2e037baefdc40da6961721ad56fc7c38d4e492a8 (commit) from 01bc9280de76159be9512530b18d73488b269476 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2e037baefdc40da6961721ad56fc7c38d4e492a8 Author: Jim Meyering Date: Mon Nov 28 13:44:58 2011 +0100 accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix * m4/gpg-error.m4: Update from git master. diff --git a/ChangeLog b/ChangeLog index bd6f2c5..ee8e140 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-08-10 Werner Koch * configure.ac: Use http://bugs.gnupg.org as bug reporting diff --git a/m4/gpg-error.m4 b/m4/gpg-error.m4 index ef07fd7..f0b9f1f 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 ----------------------------------------------------------------------- Summary of changes: ChangeLog | 5 +++++ m4/gpg-error.m4 | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) hooks/post-receive -- IPC library used by GnuPG http://git.gnupg.org From cvs at cvs.gnupg.org Mon Nov 28 16:00:56 2011 From: cvs at cvs.gnupg.org (by Jim Meyering) Date: Mon, 28 Nov 2011 16:00:56 +0100 Subject: [git] GPG-ERROR - branch, master, updated. libgpg-error-1.10-26-gaaa3f53 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Error codes used by GnuPG et al.". The branch, master has been updated via aaa3f53457369125bcfa6eeaf283df77df87d4f9 (commit) from eec4aff343af43b09b6e4f4ef786bd7f0511a42c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit aaa3f53457369125bcfa6eeaf283df77df87d4f9 Author: Jim Meyering Date: Mon Nov 28 13:44:09 2011 +0100 accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix * src/gpg-error.m4 (AM_PATH_GPG_ERROR): Also accept --with-libgpg-error-prefix=PFX, for consistency with our three library sibling packages. diff --git a/ChangeLog b/ChangeLog index ecf78dd..b838b86 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-11-28 Jim Meyering + + accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix + * src/gpg-error.m4 (AM_PATH_GPG_ERROR): Also accept + --with-libgpg-error-prefix=PFX, for consistency with our three + library sibling packages. + 2011-08-23 Werner Koch * src/err-codes.h.in: Add GPG_ERR_DUP_KEY and GPG_ERR_AMBIGUOUS. diff --git a/src/gpg-error.m4 b/src/gpg-error.m4 index ef07fd7..f0b9f1f 100644 --- a/src/gpg-error.m4 +++ b/src/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 ----------------------------------------------------------------------- Summary of changes: ChangeLog | 7 +++++++ src/gpg-error.m4 | 14 ++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) hooks/post-receive -- Error codes used by GnuPG et al. http://git.gnupg.org From cvs at cvs.gnupg.org Mon Nov 28 21:22:39 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 28 Nov 2011 21:22:39 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-124-g88fea6a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 88fea6abe6b83eb2a69dd62dbbfe19ad5c450d86 (commit) from 77ee8fd55c9e599f41a3cad0ebaa23c72ca14409 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 88fea6abe6b83eb2a69dd62dbbfe19ad5c450d86 Author: Werner Koch Date: Mon Nov 28 20:28:10 2011 +0100 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. diff --git a/scripts/ChangeLog b/scripts/ChangeLog index c183599..fec5405 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 0000000..3cd4f30 --- /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 ----------------------------------------------------------------------- Summary of changes: scripts/ChangeLog | 5 +++++ scripts/build-all.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 0 deletions(-) create mode 100755 scripts/build-all.sh hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Nov 29 09:43:55 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 29 Nov 2011 09:43:55 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-125-gc741c6f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via c741c6fc3aaa8b75a434faa143c06dd059970d41 (commit) from 88fea6abe6b83eb2a69dd62dbbfe19ad5c450d86 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c741c6fc3aaa8b75a434faa143c06dd059970d41 Author: Werner Koch Date: Tue Nov 29 08:52:12 2011 +0100 Make sure HOME et al have no unsafe characters. diff --git a/ChangeLog b/ChangeLog index 7e17ba8..5e5a014 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 f4a1de7..8a424bc 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 fec5405..1a664ca 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 3cd4f30..23af620 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" ----------------------------------------------------------------------- Summary of changes: ChangeLog | 4 ++++ autogen.sh | 20 ++++++++++++++++++++ scripts/ChangeLog | 4 ++++ scripts/build-all.sh | 18 +++++++++++++++++- 4 files changed, 45 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Nov 29 10:52:06 2011 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 29 Nov 2011 10:52:06 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-128-g751d452 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 751d452116607eb5ddcbea970b6f24c7a427620e (commit) via 5a62b0d6ee7cecc2e41a429ccc586a1a129e1b04 (commit) via 57d4f7fae13810f4daed266139c33057de38d114 (commit) from c741c6fc3aaa8b75a434faa143c06dd059970d41 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 751d452116607eb5ddcbea970b6f24c7a427620e Merge: 5a62b0d c741c6f Author: NIIBE Yutaka Date: Tue Nov 29 17:59:56 2011 +0900 Merge branch 'master' of git+ssh://playfair.gnupg.org/git/gnupg commit 5a62b0d6ee7cecc2e41a429ccc586a1a129e1b04 Author: NIIBE Yutaka Date: Tue Nov 29 17:56:22 2011 +0900 PC/SC pinpad support (pinpad input for modify pass phrase with resetcode, by admin). diff --git a/scd/ChangeLog b/scd/ChangeLog index 9c11fb3..d0f779e 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 380450d..4d11157 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 e5b4c08..ac1eeeb 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 b3a3ae1..08d641d 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 8d0f105..8876b93 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); } @@ -394,10 +382,27 @@ 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 5b99e86..9ed7b21 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, commit 57d4f7fae13810f4daed266139c33057de38d114 Author: NIIBE Yutaka Date: Tue Nov 29 11:59:32 2011 +0900 PC/SC pinpad support (pinpad input for modify pass phrase). diff --git a/scd/ChangeLog b/scd/ChangeLog index 9f991ce..9c11fb3 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 866ebb9..380450d 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 4dff9eb..e5b4c08 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 d7efad5..b3a3ae1 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 1238552..8d0f105 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -306,16 +306,29 @@ 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. */ +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 58e81d4..5b99e86 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, ----------------------------------------------------------------------- Summary of changes: scd/ChangeLog | 44 +++++++++++++++- scd/apdu.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++------ scd/apdu.h | 7 +-- scd/app-openpgp.c | 130 +++++++++++++++++++++++++++++++-------------- scd/iso7816.c | 103 ++++++++++++++++++++----------------- scd/iso7816.h | 9 ++-- 6 files changed, 327 insertions(+), 116 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Nov 30 18:57:51 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 30 Nov 2011 18:57:51 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-136-g31f548a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 31f548a18aed729c05ea367f2d8a8104480430d5 (commit) via 8cf2356fa8aa1dda644314e6e656b3df1586e297 (commit) via 6d5bb8e79dcee868e823de2c4e9d0ec9a9308dda (commit) via d24f41641f5a7c3a9be2a6e585a7e2e5031c01d7 (commit) via 9dc89de7a840c4a210e64b402094235a72e1c921 (commit) via 295b9e29c5f8fa49a767f9404aaca0afa1f31683 (commit) via f95cb909ba505f03ce81816c23dd58718b8cb6e6 (commit) via 982105f1ce85c92482def1d66f1f44e438ae5ab6 (commit) from 751d452116607eb5ddcbea970b6f24c7a427620e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 31f548a18aed729c05ea367f2d8a8104480430d5 Author: Werner Koch Date: Wed Nov 30 17:14:08 2011 +0100 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. diff --git a/common/ChangeLog b/common/ChangeLog index d5682fc..96e4e31 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 9b6c6c8..56af13a 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 ebfeec8..a1d3d86 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 f3e8892..1dcae6f 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 d00e01f..481e05e 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. + + at ifclear gpgtwoone @item max-cert-size When retrieving a key via DNS CERT, only accept keys up to this size. Defaults to 16384 bytes. + at 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 629de81..4dadaab 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 efb0877..102f65d 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 commit 8cf2356fa8aa1dda644314e6e656b3df1586e297 Author: Werner Koch Date: Wed Nov 30 17:03:53 2011 +0100 * common/estream.c (es_fopenmem_init): New. * common/estream.h (es_fopenmem_init): New. diff --git a/common/estream.c b/common/estream.c index 20d365a..c55c7f2 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, @@ -2673,6 +2672,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, const char *ES__RESTRICT mode, diff --git a/common/estream.h b/common/estream.h index 432143f..4966276 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); commit 6d5bb8e79dcee868e823de2c4e9d0ec9a9308dda Author: Werner Koch Date: Tue Nov 29 18:02:05 2011 +0100 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. diff --git a/common/ChangeLog b/common/ChangeLog index 943862a..d5682fc 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 8087a62..20d365a 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; commit d24f41641f5a7c3a9be2a6e585a7e2e5031c01d7 Author: Werner Koch Date: Tue Nov 29 13:17:20 2011 +0100 dns-cert.c: Use constants for better readability. diff --git a/common/ChangeLog b/common/ChangeLog index 46a61dd..943862a 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 cd8724a..9b6c6c8 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 */ commit 9dc89de7a840c4a210e64b402094235a72e1c921 Author: Werner Koch Date: Mon Nov 28 18:36:21 2011 +0100 Actually increase buffer size of t-dns-cert.c. diff --git a/common/t-dns-cert.c b/common/t-dns-cert.c index a2b14f2..f3e8892 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) commit 295b9e29c5f8fa49a767f9404aaca0afa1f31683 Author: Werner Koch Date: Mon Nov 28 18:35:19 2011 +0100 Re-indented dns-cert.c diff --git a/common/dns-cert.c b/common/dns-cert.c index db1c7be..cd8724a 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? */ - - while(count-->0 && pt=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(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; - } - - /* Neither type matches, so go around to the next answer. */ - pt+=dlen; - } + 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 < emsg) + { + u16 type, class, dlen, ctype; + + rc = dn_skipname (pt, emsg); /* the name we just queried for */ + if (rc == -1) + break; + + pt += rc; + + /* 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++; + + class = *pt++ << 8; + class |= *pt++; + /* We asked for IN and got something else !? */ + if (class != C_IN) + break; + + /* ttl */ + pt += 4; + + /* 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; + } + + /* The CERT type */ + ctype = *pt++ << 8; + ctype |= *pt++; + + /* Skip the CERT key tag and algo which we don't need. */ + pt += 3; + + dlen -= 5; + + /* 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 (*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; + + ret = 2; + break; + } + + /* 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; commit f95cb909ba505f03ce81816c23dd58718b8cb6e6 Author: Werner Koch Date: Mon Nov 28 18:18:12 2011 +0100 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. diff --git a/common/ChangeLog b/common/ChangeLog index dd7ef53..46a61dd 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 c799fc9..629de81 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 68dd155..efb0877 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; commit 982105f1ce85c92482def1d66f1f44e438ae5ab6 Author: Werner Koch Date: Mon Nov 28 18:11:59 2011 +0100 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. diff --git a/common/ChangeLog b/common/ChangeLog index 54435f4..dd7ef53 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 555d088..7821e04 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 888ffb7..db1c7be 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; +} ----------------------------------------------------------------------- Summary of changes: common/ChangeLog | 30 ++++ common/Makefile.am | 3 +- common/dns-cert.c | 439 ++++++++++++++++++++++++++------------------------- common/dns-cert.h | 9 +- common/estream.c | 78 ++++++++-- common/estream.h | 5 +- common/t-dns-cert.c | 95 +++++++++++ doc/gpg.texi | 3 + g10/ChangeLog | 9 + g10/keyserver.c | 41 +++--- 10 files changed, 458 insertions(+), 254 deletions(-) create mode 100644 common/t-dns-cert.c hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org