From 48da5f940b537b09b1fd6a5023922bd792d5954c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 11 Sep 1998 05:47:32 +0000 Subject: [PATCH] *** empty log message *** --- AUTHORS | 11 +- NEWS | 12 ++ THANKS | 5 +- TODO | 22 ++- VERSION | 2 +- cipher/ChangeLog | 4 + cipher/Makefile.am | 10 +- configure.in | 2 +- doc/gpg.1pod | 6 + g10/ChangeLog | 21 +++ g10/Makefile.am | 5 +- g10/armor.c | 1 + g10/build-packet.c | 36 +++- g10/delkey.c | 160 +++++++++++++++++ g10/encode.c | 1 + g10/g10.c | 424 +++++++++++++++++++++++++-------------------- g10/getkey.c | 11 +- g10/keydb.h | 2 +- g10/keyedit.c | 127 +------------- g10/keygen.c | 2 +- g10/main.h | 4 +- g10/options.h | 1 + g10/packet.h | 3 +- g10/parse-packet.c | 1 + g10/pkclist.c | 10 +- g10/pubkey-enc.c | 79 +++++++-- g10/revoke.c | 2 +- g10/seckey-cert.c | 9 +- g10/sign.c | 2 +- g10/trustdb.c | 2 +- util/ChangeLog | 9 + util/iobuf.c | 25 ++- util/ttyio.c | 8 + zlib/Makefile | 8 +- 34 files changed, 650 insertions(+), 377 deletions(-) create mode 100644 g10/delkey.c diff --git a/AUTHORS b/AUTHORS index 779b4edac..35e7049ad 100644 --- a/AUTHORS +++ b/AUTHORS @@ -6,7 +6,16 @@ Werner Koch. Designed and implemented gnupg. TRANSLATIONS Marco d'Itri 1997-02-22 Disclaim -Twofish Matthew Skala ???????????? +GPG Matthew Skala 1998-08-10 +Disclaims changes (Twofish code). +mskala@ansuz.sooke.bc.ca +GPG Natural Resources Canada 1998-08-11 +Disclaims changes by Matthew Skala. +TRANSLATIONS Gaël Quéri ????????????? +fr.po + +TRANSLATIONS Walter Koch ??????????? +de.po diff --git a/NEWS b/NEWS index b2e229f36..10aca85a5 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,15 @@ +Noteworthy changes in version 0.3.5 +----------------------------------- + * New option --throw-keyid to create anonymous enciphered messages. + If gpg detects such a message it tires all available secret keys + in turn so decode it. This is a gnupg extension and not in OpenPGP + but it has been discussed there and afaik some products use this + scheme too (Suggested by Nimrod Zimmerman). + + * Fixed a bug with 5 byte length headers. + + * --delete-[secret-]key is now also availabe in gpgm. + Noteworthy changes in version 0.3.4 ----------------------------------- * New options --comment and --set-filename; see g10/OPTIONS diff --git a/THANKS b/THANKS index 8cbda750b..054c6a3a8 100644 --- a/THANKS +++ b/THANKS @@ -27,6 +27,7 @@ Martin Schulte schulte@thp.uni-koeln.de Matthew Skala mskala@ansuz.sooke.bc.ca Max Valianskiy maxcom@maxcom.ml.org Nicolas Graner Nicolas.Graner@cri.u-psud.fr +Nimrod Zimerman zimerman@forfree.at Oskari Jääskeläinen f33003a@cc.hut.fi Peter Gutmann pgut001@cs.auckland.ac.nz Ralph Gillen gillen@theochem.uni-duesseldorf.de @@ -46,5 +47,5 @@ Wim Vandeputte bunbun@reptile.rug.ac.be Thanks to the German Unix User Group for providing FTP space and Martin Hamilton for hosting the mailing list. -Many thanks to Gerlinde for having so much patience with me while -hacking late in the evening. +Many thanks to my wife Gerlinde for having so much patience with +me while hacking late in the evening. diff --git a/TODO b/TODO index ac98f08cf..0bbb4f359 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,12 @@ + * cleanup for SHM einbauen (non-linux) + + * shared memory access funktioniert nicht wenn seuid installiert. + + * ElGamal key benutzen wenn die DSA keyid angegeben ist?? + + * Apply Paul D. Smith's sugestions for building in another direcory. + * salted and iterated S2Ks don't work (see passphrase.c). * Replace the SIGUSR1 stuff by semaphores to avoid loss of a signal. @@ -7,11 +15,6 @@ * fix the expire stuff for v4 packets. - * check whether it is valid to pack the signature stuff (onepass, data, - sig) into a compressed packet - or should we only compress the data? - what does pgp 5 do, what does OpenPGP say= - ==> I think it is okay, should be tested against pgp5 - * Fix Oscaris problems with the trustdb. * invalid packets (Marco) und Markus Gruber @@ -40,8 +43,6 @@ * add an option to re-create a public key from a secret key. Think about a backup system of only the secret part of the secret key. - * replace getkey.c#enum_secret_keys - * OpenBSD has sometimes problems reading from /dev/random. * change the fake_data stuff to mpi_set_opaque @@ -54,3 +55,10 @@ * Add some stuff for DU cc + * check for "expect" before running test genkey1024 + + * use "passphrase" instead of "pass phrase" + * Use "user ID", "trustdb" and "WARNING". + + * armor.c cannot handle concatenated armored messages. + diff --git a/VERSION b/VERSION index 42045acae..789f9a52b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.4 +0.3.4a diff --git a/cipher/ChangeLog b/cipher/ChangeLog index cb6082e34..7b16f1215 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,7 @@ +Mon Sep 7 17:04:33 1998 Werner Koch (wk@(none)) + + * Makefile.am: Fixes to allow a different build directory + Thu Aug 6 17:25:38 1998 Werner Koch,mobil,,, (wk@tobold) * random.c (get_random_byte): Removed and changed all callers diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 36dd0c537..a9d5a5cad 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -44,11 +44,13 @@ libcipher_a_SOURCES = cipher.c \ EXTRA_tiger_SOURCES = tiger.c EXTRA_twofish_SOURCES = twofish.c -tiger: tiger.c - $(COMPILE) -shared -fPIC -o tiger tiger.c -twofish: twofish.c - $(COMPILE) -shared -fPIC -o twofish twofish.c +tiger: $(srcdir)/tiger.c + $(COMPILE) -shared -fPIC -o tiger $(srcdir)/tiger.c + +twofish: $(srcdir)/twofish.c + $(COMPILE) -shared -fPIC -o twofish $(srcdir)/twofish.c + install-exec-hook: @list='$(pkglib_PROGRAMS)'; for p in $$list; do \ diff --git a/configure.in b/configure.in index 681845f0a..fc6d3db49 100644 --- a/configure.in +++ b/configure.in @@ -21,7 +21,7 @@ fi VERSION=`cat $srcdir/VERSION` PACKAGE=gnupg -ALL_LINGUAS="en de it" +ALL_LINGUAS="en de it fr" AC_SUBST(VERSION) AC_SUBST(PACKAGE) AC_DEFINE_UNQUOTED(VERSION, "$VERSION") diff --git a/doc/gpg.1pod b/doc/gpg.1pod index 98863102d..93b1a199f 100644 --- a/doc/gpg.1pod +++ b/doc/gpg.1pod @@ -333,6 +333,12 @@ B<--compress-algo> I If this is not used the OpenPGP behaviour is used; i.e. the compression algorith is selected from the preferences. +B<--throw-keyid> + Do not put the keyid into encrypted packets. This option + hides the receiver of the message and is a countermeasure + against traffic analysis. It may slow down the decryption + process because all available secret keys are tried. + B<--passphrase-fd> I Read the passphrase from file descriptor I. If you use 0 for I, the passphrase will be read from stdin. This diff --git a/g10/ChangeLog b/g10/ChangeLog index 526cf152d..f2406eac6 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,24 @@ +Wed Sep 9 11:15:03 1998 Werner Koch (wk@(none)) + + * packet.h (PKT_pubkey_enc): New flah throw_keyid, and add logic to + implement it. + * g10.c (main): New Option --throw-keyid + + * getkey.c (enum_secret_keys): Add new ar and changed all callers. + +Tue Sep 8 20:04:09 1998 Werner Koch (wk@(none)) + + * delkey.c (delete_key): Moved from keyedit.c. + +Mon Sep 7 16:37:52 1998 Werner Koch (wk@(none)) + + * build-packet.c (calc_length_header): New arg new_ctb to correctly + calculate the length of new style packets. + + * armor.c (is_armored): Checks for symkey_enc packets. + + * pkclist.c (select_algo_from_prefs): 3DEs substitute is now CAST5. + Tue Aug 11 17:54:50 1998 Werner Koch (wk@(none)) * build-packet.c (do_secret_key): Fixed handling of old keys. diff --git a/g10/Makefile.am b/g10/Makefile.am index 0097ace5f..c6d5b135e 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -16,6 +16,7 @@ common_source = \ free-packet.c \ getkey.c \ keydb.h \ + delkey.c \ pkclist.c \ skclist.c \ ringedit.c \ @@ -77,8 +78,8 @@ LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@ gpgm_LDADD = g10maint.o $(LDADD) -g10maint.o: g10.c - $(COMPILE) -DIS_G10MAINT -o g10maint.o -c g10.c +g10maint.o: $(srcdir)/g10.c + $(COMPILE) -DIS_G10MAINT -o g10maint.o -c $(srcdir)/g10.c $(PROGRAMS): $(needed_libs) diff --git a/g10/armor.c b/g10/armor.c index f5116acd0..38e1b190d 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -158,6 +158,7 @@ is_armored( byte *buf ) pkttype = ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf); switch( pkttype ) { case PKT_MARKER: + case PKT_SYMKEY_ENC: case PKT_PUBLIC_KEY: case PKT_SECRET_KEY: case PKT_PUBKEY_ENC: diff --git a/g10/build-packet.c b/g10/build-packet.c index a7c709302..a877b7e3c 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -47,7 +47,7 @@ static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd ); static int do_signature( IOBUF out, int ctb, PKT_signature *sig ); static int do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops ); -static int calc_header_length( u32 len ); +static int calc_header_length( u32 len, int new_ctb ); static int write_16(IOBUF inp, u16 a); static int write_32(IOBUF inp, u32 a); static int write_header( IOBUF out, int ctb, u32 len ); @@ -135,11 +135,13 @@ u32 calc_packet_length( PACKET *pkt ) { u32 n=0; + int new_ctb = 0; assert( pkt->pkt.generic ); switch( pkt->pkttype ) { case PKT_PLAINTEXT: n = calc_plaintext( pkt->pkt.plaintext ); + new_ctb = pkt->pkt.plaintext->new_ctb; break; case PKT_USER_ID: case PKT_COMMENT: @@ -156,7 +158,8 @@ calc_packet_length( PACKET *pkt ) log_bug("invalid packet type in calc_packet_length()"); break; } - n += calc_header_length(n); + + n += calc_header_length(n, new_ctb); return n; } @@ -374,8 +377,14 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) IOBUF a = iobuf_temp(); write_version( a, ctb ); - write_32(a, enc->keyid[0] ); - write_32(a, enc->keyid[1] ); + if( enc->throw_keyid ) { + write_32(a, 0 ); /* don't tell Eve who can decrypt the message */ + write_32(a, 0 ); + } + else { + write_32(a, enc->keyid[0] ); + write_32(a, enc->keyid[1] ); + } iobuf_put(a,enc->pubkey_algo ); n = pubkey_get_nenc( enc->pubkey_algo ); if( !n ) @@ -739,16 +748,25 @@ write_32(IOBUF out, u32 a) * calculate the length of a header */ static int -calc_header_length( u32 len ) +calc_header_length( u32 len, int new_ctb ) { if( !len ) return 1; /* only the ctb */ - else if( len < 256 ) + + if( new_ctb ) { + if( len < 192 ) + return 2; + if( len < 8384 ) + return 3; + else + return 6; + } + if( len < 256 ) return 2; - else if( len < 65536 ) + if( len < 65536 ) return 3; - else - return 5; + + return 5; } /**************** diff --git a/g10/delkey.c b/g10/delkey.c new file mode 100644 index 000000000..210528404 --- /dev/null +++ b/g10/delkey.c @@ -0,0 +1,160 @@ +/* delkey.c - delte keys + * Copyright (C) 1998 Free Software Foundation, Inc. + * + * This file is part of GNUPG. + * + * GNUPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GNUPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "options.h" +#include "packet.h" +#include "errors.h" +#include "iobuf.h" +#include "keydb.h" +#include "memory.h" +#include "util.h" +#include "main.h" +#include "trustdb.h" +#include "filter.h" +#include "ttyio.h" +#include "status.h" +#include "i18n.h" + + +/**************** + * Delete a public or secret key from a keyring. + */ +int +delete_key( const char *username, int secret ) +{ + int rc = 0; + KBNODE keyblock = NULL; + KBNODE node; + KBPOS kbpos; + PKT_public_key *pk = NULL; + PKT_secret_key *sk = NULL; + u32 keyid[2]; + int okay=0; + int yes; + + /* search the userid */ + rc = secret? find_secret_keyblock_byname( &kbpos, username ) + : find_keyblock_byname( &kbpos, username ); + if( rc ) { + log_error(_("%s: user not found\n"), username ); + goto leave; + } + + /* read the keyblock */ + rc = read_keyblock( &kbpos, &keyblock ); + if( rc ) { + log_error("%s: read problem: %s\n", username, g10_errstr(rc) ); + goto leave; + } + + /* get the keyid from the keyblock */ + node = find_kbnode( keyblock, secret? PKT_SECRET_KEY:PKT_PUBLIC_KEY ); + if( !node ) { + log_error("Oops; key not found anymore!\n"); + rc = G10ERR_GENERAL; + goto leave; + } + + if( secret ) { + sk = node->pkt->pkt.secret_key; + keyid_from_sk( sk, keyid ); + } + else { + pk = node->pkt->pkt.public_key; + keyid_from_pk( pk, keyid ); + rc = seckey_available( keyid ); + if( !rc ) { + log_error(_( + "there is a secret key for this public key!\n")); + log_info(_( + "use option \"--delete-secret-key\" to delete it first.\n")); + rc = -1; + } + else if( rc != G10ERR_NO_SECKEY ) + log_error("%s: get secret key: %s\n", username, g10_errstr(rc) ); + else + rc = 0; + } + + if( rc ) + rc = 0; + else if( opt.batch && secret ) + log_error(_("can't do that in batchmode\n")); + else if( opt.batch && opt.answer_yes ) + okay++; + else if( opt.batch ) + log_error(_("can't do that in batchmode without \"--yes\"\n")); + else { + char *p; + size_t n; + + if( secret ) + tty_printf("sec %4u%c/%08lX %s ", + nbits_from_sk( sk ), + pubkey_letter( sk->pubkey_algo ), + keyid[1], datestr_from_sk(sk) ); + else + tty_printf("pub %4u%c/%08lX %s ", + nbits_from_pk( pk ), + pubkey_letter( pk->pubkey_algo ), + keyid[1], datestr_from_pk(pk) ); + p = get_user_id( keyid, &n ); + tty_print_string( p, n ); + m_free(p); + tty_printf("\n\n"); + + yes = cpr_get_answer_is_yes( secret? N_("delete_key.secret.okay") + : N_("delete_key.okay"), + _("Delete this key from the keyring? ")); + if( !cpr_enabled() && secret && yes ) { + /* I think it is not required to check a passphrase; if + * the user is so stupid as to let others access his secret keyring + * (and has no backup) - it is up him to read some very + * basic texts about security. + */ + yes = cpr_get_answer_is_yes(N_("delete_key.secret.okay"), + _("This is a secret key! - really delete? ")); + } + if( yes ) + okay++; + } + + + if( okay ) { + rc = delete_keyblock( &kbpos ); + if( rc ) { + log_error("delete_keyblock failed: %s\n", g10_errstr(rc) ); + goto leave; + } + } + + leave: + release_kbnode( keyblock ); + return rc; +} + diff --git a/g10/encode.c b/g10/encode.c index 1d505500a..ae8b26116 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -377,6 +377,7 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out ) enc = m_alloc_clear( sizeof *enc ); enc->pubkey_algo = pk->pubkey_algo; keyid_from_pk( pk, enc->keyid ); + enc->throw_keyid = opt.throw_keyid; frame = encode_session_key( dek, pubkey_nbits( pk->pubkey_algo, pk->pkey ) ); rc = pubkey_encrypt( pk->pubkey_algo, enc->data, frame, pk->pkey ); diff --git a/g10/g10.c b/g10/g10.c index d230ad9b1..a41ecb335 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -63,7 +63,7 @@ enum cmd_and_opt_values { aNull = 0, oVerbose = 'v', oCompress = 'z', oBatch = 500, - aClearsign = 539, + aClearsign, aStore, aKeygen, aSignEncr, @@ -94,6 +94,47 @@ enum cmd_and_opt_values { aNull = 0, aDeArmor, aEnArmor, aGenRandom, + + oFingerprint, + oDoNotExportRSA, + oAnswerYes, + oAnswerNo, + oKeyring, + oSecretKeyring, + oDefaultKey, + oOptions, + oDebug, + oDebugAll, + oStatusFD, + oNoComment, + oCompletesNeeded, + oMarginalsNeeded, + oLoadExtension, + oRFC1991, + oCipherAlgo, + oDigestAlgo, + oCompressAlgo, + oPasswdFD, + oQuickRandom, + oNoVerbose, + oTrustDBName, + oNoSecmemWarn, + oNoArmor, + oNoDefKeyring, + oNoGreeting, + oNoOptions, + oNoBatch, + oHomedir, + oWithColons, + oSkipVerify, + oCompressKeys, + oCompressSigs, + oAlwaysTrust, + oEmuChecksumBug, + oRunAsShmCP, + oSetFilename, + oComment, + oThrowKeyid, aTest }; @@ -107,37 +148,39 @@ static ARGPARSE_OPTS opts[] = { { aDetachedSign, "detach-sign", 256, N_("make a detached signature")}, { aEncr, "encrypt", 256, N_("encrypt data")}, { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")}, - { 507, "store", 256, N_("store only")}, + { aStore, "store", 256, N_("store only")}, { aDecrypt, "decrypt", 256, N_("decrypt data (default)")}, - { 550, "verify" , 256, N_("verify a signature")}, + { aVerify, "verify" , 256, N_("verify a signature")}, #endif - { 551, "list-keys", 256, N_("list keys")}, - { 552, "list-sigs", 256, N_("list keys and signatures")}, - { 508, "check-sigs",256, N_("check key signatures")}, - { 515, "fingerprint", 256, N_("list keys and fingerprints")}, - { 558, "list-secret-keys", 256, N_("list secret keys")}, + { aListKeys, "list-keys", 256, N_("list keys")}, + { aListSigs, "list-sigs", 256, N_("list keys and signatures")}, + { aCheckKeys, "check-sigs",256, N_("check key signatures")}, + { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")}, + { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")}, #ifdef IS_G10 - { 503, "gen-key", 256, N_("generate a new key pair")}, - { 505, "delete-key",256, N_("remove key from the public keyring")}, - { 524, "edit-key" ,256, N_("sign or edit a key")}, - { 542, "gen-revoke",256, N_("generate a revocation certificate")}, + { aKeygen, "gen-key", 256, N_("generate a new key pair")}, #endif - { 537, "export" , 256, N_("export keys") }, - { 563, "export-secret-keys" , 256, "@" }, - { 565, "do-not-export-rsa", 0, "@" }, - { 530, "import", 256 , N_("import/merge keys")}, - { 521, "list-packets",256,N_("list only the sequence of packets")}, + { aDeleteKey, "delete-key",256, N_("remove key from the public keyring")}, + #ifdef IS_G10 + { aEditKey, "edit-key" ,256, N_("sign or edit a key")}, + { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")}, + #endif + { aExport, "export" , 256, N_("export keys") }, + { aExportSecret, "export-secret-keys" , 256, "@" }, + { oDoNotExportRSA, "do-not-export-rsa", 0, "@" }, + { aImport, "import", 256 , N_("import/merge keys")}, + { aListPackets, "list-packets",256,N_("list only the sequence of packets")}, #ifdef IS_G10MAINT - { 564, "export-ownertrust", 256, N_("export the ownertrust values")}, - { 525, "import-ownertrust", 256 , N_("import ownertrust values")}, - { 567, "check-trustdb",0 , N_("|[NAMES]|check the trust database")}, - { 546, "dearmor", 256, N_("De-Armor a file or stdin") }, - { 547, "enarmor", 256, N_("En-Armor a file or stdin") }, - { 555, "print-md" , 256, N_("|algo [files]|print message digests")}, - { 516, "print-mds" , 256, N_("print all message digests")}, + { aExportOwnerTrust, "export-ownertrust", 256, N_("export the ownertrust values")}, + { aImportOwnerTrust, "import-ownertrust", 256 , N_("import ownertrust values")}, + { aCheckTrustDB, "check-trustdb",0 , N_("|[NAMES]|check the trust database")}, + { aDeArmor, "dearmor", 256, N_("De-Armor a file or stdin") }, + { aEnArmor, "enarmor", 256, N_("En-Armor a file or stdin") }, + { aPrintMD, "print-md" , 256, N_("|algo [files]|print message digests")}, + { aPrintMDs, "print-mds" , 256, N_("print all message digests")}, #ifdef MAINTAINER_OPTIONS - { 513, "gen-prime" , 256, "@" }, - { 548, "gen-random" , 256, "@" }, + { aPrimegen, "gen-prime" , 256, "@" }, + { aGenRandom, "gen-random" , 256, "@" }, #endif #endif @@ -154,29 +197,30 @@ static ARGPARSE_OPTS opts[] = { { oVerbose, "verbose", 0, N_("verbose") }, /* { oDryRun, "dry-run", 0, N_("do not make any changes") }, */ { oBatch, "batch", 0, N_("batch mode: never ask")}, - { 501, "yes", 0, N_("assume yes on most questions")}, - { 502, "no", 0, N_("assume no on most questions")}, - { 509, "keyring" ,2, N_("add this keyring to the list of keyrings")}, - { 517, "secret-keyring" ,2, N_("add this secret keyring to the list")}, - { 541, "default-key" ,2, N_("|NAME|use NAME as default secret key")}, - { 518, "options" , 2, N_("read options from file")}, + { oAnswerYes, "yes", 0, N_("assume yes on most questions")}, + { oAnswerNo, "no", 0, N_("assume no on most questions")}, + { oKeyring, "keyring" ,2, N_("add this keyring to the list of keyrings")}, + { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")}, + { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")}, + { oOptions, "options" , 2, N_("read options from file")}, - { 510, "debug" ,4|16, N_("set debugging flags")}, - { 511, "debug-all" ,0, N_("enable full debugging")}, - { 512, "status-fd" ,1, N_("|FD|write status info to this FD") }, - { 534, "no-comment", 0, N_("do not write comment packets")}, - { 535, "completes-needed", 1, N_("(default is 1)")}, - { 536, "marginals-needed", 1, N_("(default is 3)")}, - { 560, "load-extension" ,2, N_("|file|load extension module")}, - { 561, "rfc1991", 0, N_("emulate the mode described in RFC1991")}, + { oDebug, "debug" ,4|16, N_("set debugging flags")}, + { oDebugAll, "debug-all" ,0, N_("enable full debugging")}, + { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") }, + { oNoComment, "no-comment", 0, N_("do not write comment packets")}, + { oCompletesNeeded, "completes-needed", 1, N_("(default is 1)")}, + { oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")}, + { oLoadExtension, "load-extension" ,2, N_("|file|load extension module")}, + { oRFC1991, "rfc1991", 0, N_("emulate the mode described in RFC1991")}, #ifdef IS_G10 - { 527, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")}, - { 529, "digest-algo", 2 , N_("|NAME|use message digest algorithm NAME")}, - { 556, "compress-algo", 1 , N_("|N|use compress algorithm N")}, + { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")}, + { oDigestAlgo, "digest-algo", 2 , N_("|NAME|use message digest algorithm NAME")}, + { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")}, + { oThrowKeyid, "throw-keyid", 0, N_("throw keyid field of encrypted packets")}, #else /* some dummies */ - { 527, "cipher-algo", 2 , "@"}, - { 529, "digest-algo", 2 , "@"}, - { 556, "compress-algo", 1 , "@"}, + { oCipherAlgo, "cipher-algo", 2 , "@"}, + { oDigestAlgo, "digest-algo", 2 , "@"}, + { oCompressAlgo, "compress-algo", 1 , "@"}, #endif #ifdef IS_G10 @@ -190,41 +234,40 @@ static ARGPARSE_OPTS opts[] = { /* hidden options */ #ifdef IS_G10MAINT - { 514, "test" , 0, "@" }, - { 564, "list-ownertrust",0 , "@"}, - { 567, "check-trustdb",0 , "@"}, - { 531, "list-trustdb",0 , "@"}, - { 533, "list-trust-path",0, "@"}, + { aTest, "test" , 0, "@" }, + { aExportOwnerTrust, "list-ownertrust",0 , "@"}, /* alias */ + { aListTrustDB, "list-trustdb",0 , "@"}, + { aListTrustPath, "list-trust-path",0, "@"}, #endif #ifdef IS_G10 { oKOption, NULL, 0, "@"}, - { 504, "delete-secret-key",0, "@" }, - { 524, "edit-sig" ,0, "@"}, /* alias for edit-key */ - { 523, "passphrase-fd",1, "@" }, - { 506, "sign-key" ,256, "@" }, /* alias for edit-key */ + { aEditKey, "edit-sig" ,0, "@"}, /* alias for edit-key */ + { oPasswdFD, "passphrase-fd",1, "@" }, + { aSignKey, "sign-key" ,256, "@" }, /* alias for edit-key */ #endif - { 532, "quick-random", 0, "@"}, - { 526, "no-verbose", 0, "@"}, - { 538, "trustdb-name", 2, "@" }, - { 540, "no-secmem-warning", 0, "@" }, /* used only by regression tests */ - { 519, "no-armor", 0, "@"}, - { 520, "no-default-keyring", 0, "@" }, - { 522, "no-greeting", 0, "@" }, - { 543, "no-options", 0, "@" }, /* shortcut for --options /dev/null */ - { 544, "homedir", 2, "@" }, /* defaults to "~/.gnupg" */ - { 545, "no-batch", 0, "@" }, - { 549, "with-colons", 0, "@"}, - { 551, "list-key", 0, "@" }, /* alias */ - { 552, "list-sig", 0, "@" }, /* alias */ - { 508, "check-sig",0, "@" }, /* alias */ - { 553, "skip-verify",0, "@" }, - { 557, "compress-keys",0, "@"}, - { 566, "compress-sigs",0, "@"}, - { 559, "always-trust", 0, "@"}, - { 562, "emulate-checksum-bug", 0, "@"}, - { 554, "run-as-shm-coprocess", 4, "@" }, - { 568, "set-filename", 2, "@" }, - { 569, "comment", 2, "@" }, + { aDeleteSecretKey, "delete-secret-key",0, "@" }, + { oQuickRandom, "quick-random", 0, "@"}, + { oNoVerbose, "no-verbose", 0, "@"}, + { oTrustDBName, "trustdb-name", 2, "@" }, + { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */ + { oNoArmor, "no-armor", 0, "@"}, + { oNoDefKeyring, "no-default-keyring", 0, "@" }, + { oNoGreeting, "no-greeting", 0, "@" }, + { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */ + { oHomedir, "homedir", 2, "@" }, /* defaults to "~/.gnupg" */ + { oNoBatch, "no-batch", 0, "@" }, + { oWithColons, "with-colons", 0, "@"}, + { aListKeys, "list-key", 0, "@" }, /* alias */ + { aListSigs, "list-sig", 0, "@" }, /* alias */ + { aCheckKeys, "check-sig",0, "@" }, /* alias */ + { oSkipVerify, "skip-verify",0, "@" }, + { oCompressKeys, "compress-keys",0, "@"}, + { oCompressSigs, "compress-sigs",0, "@"}, + { oAlwaysTrust, "always-trust", 0, "@"}, + { oEmuChecksumBug, "emulate-checksum-bug", 0, "@"}, + { oRunAsShmCP, "run-as-shm-coprocess", 4, "@" }, + { oSetFilename, "set-filename", 2, "@" }, + { oComment, "comment", 2, "@" }, {0} }; @@ -277,22 +320,22 @@ strusage( int level ) #endif break; - case 31: p = "\n"; break; + case 31: p = _("\nSupported algorithms:\n"); break; case 32: if( !ciphers ) - ciphers = build_list("Supported ciphers: ", cipher_algo_to_string, + ciphers = build_list("Cipher: ", cipher_algo_to_string, check_cipher_algo ); p = ciphers; break; case 33: if( !pubkeys ) - pubkeys = build_list("Supported pubkeys: ", pubkey_algo_to_string, + pubkeys = build_list("Pubkey: ", pubkey_algo_to_string, check_pubkey_algo ); p = pubkeys; break; case 34: if( !digests ) - digests = build_list("Supported digests: ", digest_algo_to_string, + digests = build_list("Hash: ", digest_algo_to_string, check_digest_algo ); p = digests; break; @@ -471,17 +514,17 @@ main( int argc, char **argv ) pargs.argv = &argv; pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */ while( arg_parse( &pargs, opts) ) { - if( pargs.r_opt == 510 || pargs.r_opt == 511 ) + if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll ) parse_debug++; - else if( pargs.r_opt == 518 ) { + else if( pargs.r_opt == oOptions ) { /* yes there is one, so we do not try the default one, but * read the option file when it is encountered at the commandline */ default_config = 0; } - else if( pargs.r_opt == 543 ) + else if( pargs.r_opt == oNoOptions ) default_config = 0; /* --no-options */ - else if( pargs.r_opt == 544 ) + else if( pargs.r_opt == oHomedir ) opt.homedir = pargs.r.ret_str; } @@ -518,20 +561,116 @@ main( int argc, char **argv ) while( optfile_parse( configfp, configname, &configlineno, &pargs, opts) ) { switch( pargs.r_opt ) { + case aCheckKeys: set_cmd( &cmd, aCheckKeys); break; + case aListPackets: set_cmd( &cmd, aListPackets); break; + case aImport: set_cmd( &cmd, aImport); break; + case aExport: set_cmd( &cmd, aExport); break; + case aListKeys: set_cmd( &cmd, aListKeys); break; + case aListSigs: set_cmd( &cmd, aListSigs); break; + case aExportSecret: set_cmd( &cmd, aExportSecret); break; + case aDeleteSecretKey: set_cmd( &cmd, aDeleteSecretKey); break; + case aDeleteKey: set_cmd( &cmd, aDeleteKey); break; - case oArmor: opt.armor = 1; opt.no_armor=0; break; #ifdef IS_G10 case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break; case aSym: set_cmd( &cmd, aSym); break; case aDecrypt: set_cmd( &cmd, aDecrypt); break; case aEncr: set_cmd( &cmd, aEncr); break; + case aSign: set_cmd( &cmd, aSign ); break; + case aKeygen: set_cmd( &cmd, aKeygen); break; + case aSignKey: set_cmd( &cmd, aSignKey); break; + case aStore: set_cmd( &cmd, aStore); break; + case aEditKey: set_cmd( &cmd, aEditKey); break; + case aClearsign: set_cmd( &cmd, aClearsign); break; + case aGenRevoke: set_cmd( &cmd, aGenRevoke); break; + case aVerify: set_cmd( &cmd, aVerify); break; + #else + #ifdef MAINTAINER_OPTIONS + case aPrimegen: set_cmd( &cmd, aPrimegen); break; + case aTest: set_cmd( &cmd, aTest); break; + case aGenRandom: set_cmd( &cmd, aGenRandom); break; + #endif + case aPrintMD: set_cmd( &cmd, aPrintMD); break; + case aPrintMDs: set_cmd( &cmd, aPrintMDs); break; + case aListTrustDB: set_cmd( &cmd, aListTrustDB); break; + case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break; + case aListTrustPath: set_cmd( &cmd, aListTrustPath); break; + case aDeArmor: set_cmd( &cmd, aDeArmor); break; + case aEnArmor: set_cmd( &cmd, aEnArmor); break; + case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break; + case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break; + #endif /* IS_G10MAINT */ + + + + case oArmor: opt.armor = 1; opt.no_armor=0; break; + case oOutput: opt.outfile = pargs.r.ret_str; break; + case oVerbose: g10_opt_verbose++; + opt.verbose++; opt.list_sigs=1; break; + case oKOption: set_cmd( &cmd, aKMode ); break; + + case oBatch: opt.batch = 1; greeting = 0; break; + case oAnswerYes: opt.answer_yes = 1; break; + case oAnswerNo: opt.answer_no = 1; break; + case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break; + case oDebug: opt.debug |= pargs.r.ret_ulong; break; + case oDebugAll: opt.debug = ~0; break; + case oStatusFD: set_status_fd( pargs.r.ret_int ); break; + case oFingerprint: opt.fingerprint++; break; + case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break; + case oOptions: + /* config files may not be nested (silently ignore them) */ + if( !configfp ) { + m_free(configname); + configname = m_strdup(pargs.r.ret_str); + goto next_pass; + } + break; + case oNoArmor: opt.no_armor=1; opt.armor=0; break; + case oNoDefKeyring: default_keyring = 0; break; + case oNoGreeting: greeting = 0; break; + case oNoVerbose: g10_opt_verbose = 0; + opt.verbose = 0; opt.list_sigs=0; break; + case oQuickRandom: quick_random_gen(1); break; + case oNoComment: opt.no_comment=1; break; + case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break; + case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break; + case oTrustDBName: trustdb_name = pargs.r.ret_str; break; + case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break; + case oNoOptions: break; /* no-options */ + case oHomedir: opt.homedir = pargs.r.ret_str; break; + case oNoBatch: opt.batch = 0; break; + case oWithColons: opt.with_colons=':'; break; + + case oSkipVerify: opt.skip_verify=1; break; + case oCompressAlgo: opt.def_compress_algo = pargs.r.ret_int; break; + case oCompressKeys: opt.compress_keys = 1; break; + case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break; + case oAlwaysTrust: opt.always_trust = 1; break; + case oLoadExtension: register_cipher_extension(pargs.r.ret_str); break; + case oRFC1991: opt.rfc1991 = 1; opt.no_comment = 1; break; + case oEmuChecksumBug: opt.emulate_bugs |= EMUBUG_GPGCHKSUM; break; + case oDoNotExportRSA: opt.do_not_export_rsa = 1; break; + case oCompressSigs: opt.compress_sigs = 1; break; + case oRunAsShmCP: + #ifdef USE_SHM_COPROCESSING + opt.shm_coprocess = 1; + requested_shm_size = pargs.r.ret_ulong; + #else + log_error("shared memory coprocessing is not available\n"); + #endif + break; + case oSetFilename: opt.set_filename = pargs.r.ret_str; break; + case oComment: opt.comment_string = pargs.r.ret_str; break; + case oThrowKeyid: opt.throw_keyid = 1; break; + + #ifdef IS_G10 case oRemote: /* store the remote users */ sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str)); strcpy(sl->d, pargs.r.ret_str); sl->next = remusr; remusr = sl; break; - case aSign: set_cmd( &cmd, aSign ); break; case oTextmode: opt.textmode=1; break; case oUser: /* store the local users */ sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str)); @@ -540,107 +679,17 @@ main( int argc, char **argv ) locusr = sl; break; case oCompress: opt.compress = pargs.r.ret_int; break; - case 503: set_cmd( &cmd, aKeygen); break; - case 504: set_cmd( &cmd, aDeleteSecretKey); break; - case 505: set_cmd( &cmd, aDeleteKey); break; - case 506: set_cmd( &cmd, aSignKey); break; - case 507: set_cmd( &cmd, aStore); break; - case 523: set_passphrase_fd( pargs.r.ret_int ); break; - case 524: set_cmd( &cmd, aEditKey); break; - case 527: def_cipher_string = m_strdup(pargs.r.ret_str); break; - case 529: def_digest_string = m_strdup(pargs.r.ret_str); break; - case aClearsign: set_cmd( &cmd, aClearsign); break; - case 540: secmem_set_flags( secmem_get_flags() | 1 ); break; - case 542: set_cmd( &cmd, aGenRevoke); break; - case 550: set_cmd( &cmd, aVerify); break; + case oPasswdFD: set_passphrase_fd( pargs.r.ret_int ); break; + case oCipherAlgo: def_cipher_string = m_strdup(pargs.r.ret_str); break; + case oDigestAlgo: def_digest_string = m_strdup(pargs.r.ret_str); break; + case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break; #else - case 527: - case 529: - break; - #endif /* !IS_G10 */ + case oCipherAlgo: + case oDigestAlgo: + case oNoSecmemWarn: + break; /* dummies */ + #endif - #ifdef IS_G10MAINT - #ifdef MAINTAINER_OPTIONS - case 513: set_cmd( &cmd, aPrimegen); break; - case 514: set_cmd( &cmd, aTest); break; - case 548: set_cmd( &cmd, aGenRandom); break; - #endif - case 516: set_cmd( &cmd, aPrintMDs); break; - case 531: set_cmd( &cmd, aListTrustDB); break; - case 567: set_cmd( &cmd, aCheckTrustDB); break; - case 533: set_cmd( &cmd, aListTrustPath); break; - case 540: break; /* dummy */ - case 546: set_cmd( &cmd, aDeArmor); break; - case 547: set_cmd( &cmd, aEnArmor); break; - case 555: set_cmd( &cmd, aPrintMD); break; - case 564: set_cmd( &cmd, aExportOwnerTrust); break; - case 525: set_cmd( &cmd, aImportOwnerTrust); break; - #endif /* IS_G10MAINT */ - - case oOutput: opt.outfile = pargs.r.ret_str; break; - case oVerbose: g10_opt_verbose++; - opt.verbose++; opt.list_sigs=1; break; - case oKOption: set_cmd( &cmd, aKMode ); break; - - case oBatch: opt.batch = 1; greeting = 0; break; - case 501: opt.answer_yes = 1; break; - case 502: opt.answer_no = 1; break; - case 508: set_cmd( &cmd, aCheckKeys); break; - case 509: append_to_strlist( &nrings, pargs.r.ret_str); break; - case 510: opt.debug |= pargs.r.ret_ulong; break; - case 511: opt.debug = ~0; break; - case 512: set_status_fd( pargs.r.ret_int ); break; - case 515: opt.fingerprint++; break; - case 517: append_to_strlist( &sec_nrings, pargs.r.ret_str); break; - case 518: - /* config files may not be nested (silently ignore them) */ - if( !configfp ) { - m_free(configname); - configname = m_strdup(pargs.r.ret_str); - goto next_pass; - } - break; - case 519: opt.no_armor=1; opt.armor=0; break; - case 520: default_keyring = 0; break; - case 521: set_cmd( &cmd, aListPackets); break; - case 522: greeting = 0; break; - case 526: g10_opt_verbose = 0; - opt.verbose = 0; opt.list_sigs=0; break; - case 530: set_cmd( &cmd, aImport); break; - case 532: quick_random_gen(1); break; - case 534: opt.no_comment=1; break; - case 535: opt.completes_needed = pargs.r.ret_int; break; - case 536: opt.marginals_needed = pargs.r.ret_int; break; - case 537: set_cmd( &cmd, aExport); break; - case 538: trustdb_name = pargs.r.ret_str; break; - case 541: opt.def_secret_key = pargs.r.ret_str; break; - case 543: break; /* no-options */ - case 544: opt.homedir = pargs.r.ret_str; break; - case 545: opt.batch = 0; break; - case 549: opt.with_colons=':'; break; - case 551: set_cmd( &cmd, aListKeys); break; - case 552: set_cmd( &cmd, aListSigs); break; - case 553: opt.skip_verify=1; break; - case 556: opt.def_compress_algo = pargs.r.ret_int; break; - case 557: opt.compress_keys = 1; break; - case 558: set_cmd( &cmd, aListSecretKeys); break; - case 559: opt.always_trust = 1; break; - case 560: register_cipher_extension(pargs.r.ret_str); break; - case 561: opt.rfc1991 = 1; opt.no_comment = 1; break; - case 562: opt.emulate_bugs |= EMUBUG_GPGCHKSUM; break; - case 563: set_cmd( &cmd, aExportSecret); break; - case 565: opt.do_not_export_rsa = 1; break; - case 566: opt.compress_sigs = 1; break; - case 554: - #ifdef USE_SHM_COPROCESSING - opt.shm_coprocess = 1; - requested_shm_size = pargs.r.ret_ulong; - #else - log_error("shared memory coprocessing is not available\n"); - #endif - break; - case 568: opt.set_filename = pargs.r.ret_str; break; - case 569: opt.comment_string = pargs.r.ret_str; break; default : errors++; pargs.err = configfp? 1:2; break; } } @@ -867,6 +916,8 @@ main( int argc, char **argv ) keyedit_menu(fname, locusr ); break; + #endif /* IS_G10 */ + case aDeleteSecretKey: if( argc != 1 ) wrong_args(_("--delete-secret-key username")); @@ -878,7 +929,6 @@ main( int argc, char **argv ) log_error("%s: delete key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) ); break; - #endif /* IS_G10 */ case aCheckKeys: opt.check_sigs = 1; diff --git a/g10/getkey.c b/g10/getkey.c index 10899a6df..189ef0be1 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -510,7 +510,7 @@ get_seckey( PKT_secret_key *sk, u32 *keyid ) /* check the secret key (this may prompt for a passprase to * unlock the secret key */ - rc = check_secret_key( sk ); + rc = check_secret_key( sk, 0 ); } return rc; @@ -551,7 +551,7 @@ get_seckey_byname( PKT_secret_key *sk, const char *name, int unprotect ) else rc = key_byname( 1, NULL, sk, name ); if( !rc && unprotect ) - rc = check_secret_key( sk ); + rc = check_secret_key( sk, 0 ); return rc; } @@ -984,10 +984,10 @@ lookup_sk( PKT_secret_key *sk, int mode, u32 *keyid, const char *name, * 4) Always call this function a last time with SK set to NULL, * so that can free it's context. * - * Return + * */ int -enum_secret_keys( void **context, PKT_secret_key *sk ) +enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys ) { int rc=0; PACKET pkt; @@ -1022,7 +1022,8 @@ enum_secret_keys( void **context, PKT_secret_key *sk ) while( (rc=parse_packet(c->iobuf, &pkt)) != -1 ) { if( rc ) ; /* e.g. unknown packet */ - else if( pkt.pkttype == PKT_SECRET_KEY ) { + else if( pkt.pkttype == PKT_SECRET_KEY + || ( with_subkeys && pkt.pkttype == PKT_SECRET_SUBKEY ) ) { copy_secret_key( sk, pkt.pkt.secret_key ); set_packet_list_mode(save_mode); return 0; /* found */ diff --git a/g10/keydb.h b/g10/keydb.h index 2d3f61f88..c85f93787 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -119,7 +119,7 @@ int get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint, size_t fprint_len ); int seckey_available( u32 *keyid ); int get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock ); -int enum_secret_keys( void **context, PKT_secret_key *sk ); +int enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys ); char*get_user_id_string( u32 *keyid ); char*get_user_id( u32 *keyid, size_t *rn ); diff --git a/g10/keyedit.c b/g10/keyedit.c index a0a62526d..c0a082bba 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -56,7 +56,7 @@ static int count_keys_with_flag( KBNODE keyblock, unsigned flag ); static int count_selected_uids( KBNODE keyblock ); static int count_selected_keys( KBNODE keyblock ); - +#define CONTROL_D ('D' - 'A' + 1) #define NODFLG_BADSIG (1<<0) /* bad signature */ #define NODFLG_NOKEY (1<<1) /* no public key */ @@ -309,125 +309,6 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified ) - -/**************** - * Delete a public or secret key from a keyring. - */ -int -delete_key( const char *username, int secret ) -{ - int rc = 0; - KBNODE keyblock = NULL; - KBNODE node; - KBPOS kbpos; - PKT_public_key *pk = NULL; - PKT_secret_key *sk = NULL; - u32 keyid[2]; - int okay=0; - int yes; - - /* search the userid */ - rc = secret? find_secret_keyblock_byname( &kbpos, username ) - : find_keyblock_byname( &kbpos, username ); - if( rc ) { - log_error(_("%s: user not found\n"), username ); - goto leave; - } - - /* read the keyblock */ - rc = read_keyblock( &kbpos, &keyblock ); - if( rc ) { - log_error("%s: read problem: %s\n", username, g10_errstr(rc) ); - goto leave; - } - - /* get the keyid from the keyblock */ - node = find_kbnode( keyblock, secret? PKT_SECRET_KEY:PKT_PUBLIC_KEY ); - if( !node ) { - log_error("Oops; key not found anymore!\n"); - rc = G10ERR_GENERAL; - goto leave; - } - - if( secret ) { - sk = node->pkt->pkt.secret_key; - keyid_from_sk( sk, keyid ); - } - else { - pk = node->pkt->pkt.public_key; - keyid_from_pk( pk, keyid ); - rc = seckey_available( keyid ); - if( !rc ) { - log_error(_( - "there is a secret key for this public key!\n")); - log_info(_( - "use option \"--delete-secret-key\" to delete it first.\n")); - rc = -1; - } - else if( rc != G10ERR_NO_SECKEY ) - log_error("%s: get secret key: %s\n", username, g10_errstr(rc) ); - else - rc = 0; - } - - if( rc ) - rc = 0; - else if( opt.batch && secret ) - log_error(_("can't do that in batchmode\n")); - else if( opt.batch && opt.answer_yes ) - okay++; - else if( opt.batch ) - log_error(_("can't do that in batchmode without \"--yes\"\n")); - else { - char *p; - size_t n; - - if( secret ) - tty_printf("sec %4u%c/%08lX %s ", - nbits_from_sk( sk ), - pubkey_letter( sk->pubkey_algo ), - keyid[1], datestr_from_sk(sk) ); - else - tty_printf("pub %4u%c/%08lX %s ", - nbits_from_pk( pk ), - pubkey_letter( pk->pubkey_algo ), - keyid[1], datestr_from_pk(pk) ); - p = get_user_id( keyid, &n ); - tty_print_string( p, n ); - m_free(p); - tty_printf("\n\n"); - - yes = cpr_get_answer_is_yes( secret? N_("delete_key.secret.okay") - : N_("delete_key.okay"), - _("Delete this key from the keyring? ")); - if( !cpr_enabled() && secret && yes ) { - /* I think it is not required to check a passphrase; if - * the user is so stupid as to let others access his secret keyring - * (and has no backup) - it is up him to read some very - * basic texts about security. - */ - yes = cpr_get_answer_is_yes(N_("delete_key.secret.okay"), - _("This is a secret key! - really delete? ")); - } - if( yes ) - okay++; - } - - - if( okay ) { - rc = delete_keyblock( &kbpos ); - if( rc ) { - log_error("delete_keyblock failed: %s\n", g10_errstr(rc) ); - goto leave; - } - } - - leave: - release_kbnode( keyblock ); - return rc; -} - - /**************** * Change the passphrase of the primary and all secondary keys. * We use only one passphrase for all keys. @@ -457,7 +338,7 @@ change_passphrase( KBNODE keyblock ) break; default: tty_printf(_("Key is protected.\n")); - rc = check_secret_key( sk ); + rc = check_secret_key( sk, 0 ); if( !rc ) passphrase = get_last_passphrase(); break; @@ -468,7 +349,7 @@ change_passphrase( KBNODE keyblock ) if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) { PKT_secret_key *subsk = node->pkt->pkt.secret_key; set_next_passphrase( passphrase ); - rc = check_secret_key( subsk ); + rc = check_secret_key( subsk, 0 ); } } @@ -635,6 +516,8 @@ keyedit_menu( const char *username, STRLIST locusr ) arg_number = 0; if( !*answer ) cmd = cmdLIST; + else if( *answer == CONTROL_D ) + cmd = cmdQUIT; else if( isdigit( *answer ) ) { cmd = cmdSELUID; arg_number = atoi(answer); diff --git a/g10/keygen.c b/g10/keygen.c index afe5bb4f9..47a24b2ae 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -951,7 +951,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock ) break; default: tty_printf("Key is protected.\n"); - rc = check_secret_key( sk ); + rc = check_secret_key( sk, 0 ); if( !rc ) passphrase = get_last_passphrase(); break; diff --git a/g10/main.h b/g10/main.h index bba90ef5a..a8132fa74 100644 --- a/g10/main.h +++ b/g10/main.h @@ -71,8 +71,10 @@ int clearsign_file( const char *fname, STRLIST locusr, const char *outfile ); /*-- sig-check.c --*/ int check_key_signature( KBNODE root, KBNODE node, int *is_selfsig ); -/*-- keyedit.c --*/ +/*-- delkey.c --*/ int delete_key( const char *username, int secure ); + +/*-- keyedit.c --*/ void keyedit_menu( const char *username, STRLIST locusr ); /*-- keygen.c --*/ diff --git a/g10/options.h b/g10/options.h index 4c8ec6138..a4b4167c4 100644 --- a/g10/options.h +++ b/g10/options.h @@ -54,6 +54,7 @@ struct { int shm_coprocess; const char *set_filename; const char *comment_string; + int throw_keyid; } opt; diff --git a/g10/packet.h b/g10/packet.h index 495e72216..0a4adc5f8 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -68,6 +68,7 @@ typedef struct { u32 keyid[2]; /* 64 bit keyid */ byte version; byte pubkey_algo; /* algorithm used for public key scheme */ + byte throw_keyid; MPI data[PUBKEY_MAX_NENC]; } PKT_pubkey_enc; @@ -276,7 +277,7 @@ int signature_check( PKT_signature *sig, MD_HANDLE digest ); /*-- seckey-cert.c --*/ int is_secret_key_protected( PKT_secret_key *sk ); -int check_secret_key( PKT_secret_key *sk ); +int check_secret_key( PKT_secret_key *sk, int retries ); int protect_secret_key( PKT_secret_key *sk, DEK *dek ); /*-- pubkey-enc.c --*/ diff --git a/g10/parse-packet.c b/g10/parse-packet.c index bc7aca510..2601e1571 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -578,6 +578,7 @@ parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) k->keyid[0] = read_32(inp); pktlen -= 4; k->keyid[1] = read_32(inp); pktlen -= 4; k->pubkey_algo = iobuf_get_noeof(inp); pktlen--; + k->throw_keyid = 0; /* only used as flag for build_packet */ if( list_mode ) printf(":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n", k->version, k->pubkey_algo, (ulong)k->keyid[0], (ulong)k->keyid[1]); diff --git a/g10/pkclist.c b/g10/pkclist.c index e85b289f5..b4d79f281 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -36,6 +36,10 @@ #include "status.h" #include "i18n.h" + +#define CONTROL_D ('D' - 'A' + 1) + + /**************** * Returns true if an ownertrust has changed. */ @@ -113,7 +117,7 @@ edit_ownertrust( ulong lid, int mode ) else if( *p == ans[0] || *p == ans[1] ) { tty_printf(_("You will see a list of signators etc. here\n")); } - else if( mode && (*p == ans[2] || *p == ans[3]) ) { + else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) { break ; /* back to the menu */ } m_free(p); p = NULL; @@ -596,9 +600,9 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype ) } if( preftype == PREFTYPE_SYM && i == CIPHER_ALGO_3DES ) { - i = CIPHER_ALGO_BLOWFISH; + i = CIPHER_ALGO_CAST5; if( opt.verbose ) - log_info("replacing 3DES by Blowfish\n"); + log_info("replacing 3DES by CAST5\n"); } diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index f6a15fccf..2e9a14aa5 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -33,6 +33,8 @@ #include "status.h" #include "i18n.h" +static int get_it( PKT_pubkey_enc *k, + DEK *dek, PKT_secret_key *sk, u32 *keyid ); /**************** * Get the session key from a pubkey enc paket and return @@ -41,27 +43,70 @@ int get_session_key( PKT_pubkey_enc *k, DEK *dek ) { - int rc = 0; + PKT_secret_key *sk = NULL; + int rc; + + if( is_RSA(k->pubkey_algo) ) /* warn about that */ + write_status(STATUS_RSA_OR_IDEA); + + rc = check_pubkey_algo( k->pubkey_algo ); + if( rc ) + goto leave; + + if( k->keyid[0] || k->keyid[1] ) { + sk = m_alloc_clear( sizeof *sk ); + sk->pubkey_algo = k->pubkey_algo; /* we want a pubkey with this algo*/ + if( !(rc = get_seckey( sk, k->keyid )) ) + rc = get_it( k, dek, sk, k->keyid ); + } + else { /* anonymous receiver: Try all available secret keys */ + void *enum_context = NULL; + u32 keyid[2]; + + for(;;) { + if( sk ) + free_secret_key( sk ); + sk = m_alloc_clear( sizeof *sk ); + rc=enum_secret_keys( &enum_context, sk, 1); + if( rc ) { + rc = G10ERR_NO_SECKEY; + break; + } + if( sk->pubkey_algo != k->pubkey_algo ) + continue; + keyid_from_sk( sk, keyid ); + log_info(_("anonymous receiver; trying secret key %08lX ...\n"), + (ulong)keyid[1] ); + rc = check_secret_key( sk, 1 ); /* ask only once */ + if( !rc ) + rc = get_it( k, dek, sk, keyid ); + if( !rc ) { + log_info( _("okay, we are the anonymous receiver.\n") ); + break; + } + } + enum_secret_keys( &enum_context, NULL, 0 ); /* free context */ + } + + leave: + if( sk ) + free_secret_key( sk ); + return rc; +} + + +static int +get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid ) +{ + int rc; MPI plain_dek = NULL; byte *frame = NULL; unsigned n, nframe; u16 csum, csum2; - PKT_secret_key *sk = m_alloc_clear( sizeof *sk ); - if( is_RSA(k->pubkey_algo) ) /* warn about that */ - write_status(STATUS_RSA_OR_IDEA); - rc=check_pubkey_algo( k->pubkey_algo ); + rc = pubkey_decrypt(sk->pubkey_algo, &plain_dek, k->data, sk->skey ); if( rc ) goto leave; - - sk->pubkey_algo = k->pubkey_algo; /* we want a pubkey with this algo*/ - if( (rc = get_seckey( sk, k->keyid )) ) - goto leave; - - rc = pubkey_decrypt(k->pubkey_algo, &plain_dek, k->data, sk->skey ); - if( rc ) - goto leave; - free_secret_key( sk ); sk = NULL; frame = mpi_get_buffer( plain_dek, &nframe, NULL ); mpi_free( plain_dek ); plain_dek = NULL; @@ -88,7 +133,7 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) if( n + 7 > nframe ) { rc = G10ERR_WRONG_SECKEY; goto leave; } if( frame[n] == 1 && frame[nframe-1] == 2 ) { - log_error("old encoding of DEK is not supported\n"); + log_info("old encoding of DEK is not supported\n"); rc = G10ERR_CIPHER_ALGO; goto leave; } @@ -129,7 +174,7 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) /* check that the algo is in the preferences */ { PKT_public_key *pk = m_alloc_clear( sizeof *pk ); - if( (rc = get_pubkey( pk, k->keyid )) ) + if( (rc = get_pubkey( pk, keyid )) ) log_error("public key problem: %s\n", g10_errstr(rc) ); else if( !pk->local_id && query_trust_record(pk) ) log_error("can't check algorithm against preferences\n"); @@ -144,8 +189,6 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) leave: mpi_free(plain_dek); m_free(frame); - if( sk ) - free_secret_key( sk ); return rc; } diff --git a/g10/revoke.c b/g10/revoke.c index 278bdca35..61d1e4c5c 100644 --- a/g10/revoke.c +++ b/g10/revoke.c @@ -132,7 +132,7 @@ gen_revoke( const char *uname ) tty_printf("Warning: This key is not protected!\n"); break; default: - rc = check_secret_key( sk ); + rc = check_secret_key( sk, 0 ); break; } if( rc ) diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c index df5c2b9b8..819f79c9c 100644 --- a/g10/seckey-cert.c +++ b/g10/seckey-cert.c @@ -154,15 +154,18 @@ do_check( PKT_secret_key *sk ) /**************** * Check the secret key - * Ask up to 3 times for a correct passphrase + * Ask up to 3 (or n) times for a correct passphrase */ int -check_secret_key( PKT_secret_key *sk ) +check_secret_key( PKT_secret_key *sk, int n ) { int rc = G10ERR_BAD_PASS; int i; - for(i=0; i < 3 && rc == G10ERR_BAD_PASS; i++ ) { + if( n < 1 ) + n = 3; /* use the default value */ + + for(i=0; i < n && rc == G10ERR_BAD_PASS; i++ ) { if( i ) log_error(_("Invalid passphrase; please try again ...\n")); rc = do_check( sk ); diff --git a/g10/sign.c b/g10/sign.c index d3f49e1df..63b7c8248 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -81,7 +81,7 @@ complete_sig( PKT_signature *sig, PKT_secret_key *sk, MD_HANDLE md ) { int rc=0; - if( !(rc=check_secret_key( sk )) ) + if( !(rc=check_secret_key( sk, 0 )) ) rc = do_sign( sk, sig, md, 0 ); /* fixme: should we check whether the signature is okay? diff --git a/g10/trustdb.c b/g10/trustdb.c index 642d1b5e9..efe7bcaf0 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -351,7 +351,7 @@ verify_own_keys() PKT_public_key *pk = m_alloc_clear( sizeof *pk ); u32 keyid[2]; - while( !(rc=enum_secret_keys( &enum_context, sk) ) ) { + while( !(rc=enum_secret_keys( &enum_context, sk, 0 ) ) ) { keyid_from_sk( sk, keyid ); if( DBG_TRUST ) diff --git a/util/ChangeLog b/util/ChangeLog index 9ef232582..8644bb7d6 100644 --- a/util/ChangeLog +++ b/util/ChangeLog @@ -1,3 +1,12 @@ +Wed Sep 9 13:52:28 1998 Werner Koch (wk@(none)) + + * ttyio.c (do_get): Ctrl-D is now a valid but special character + +Mon Sep 7 13:52:41 1998 Werner Koch (wk@(none)) + + * iobuf.c (get_real_fname): New and changed file_filter datastructures + and their initialization. + Tue Aug 11 15:12:35 1998 Werner Koch (wk@(none)) * miscutil.c (answer_is_yes): i18ned diff --git a/util/iobuf.c b/util/iobuf.c index 6ad001334..b7ccd1ecd 100644 --- a/util/iobuf.c +++ b/util/iobuf.c @@ -34,6 +34,7 @@ typedef struct { FILE *fp; /* open file handle */ + int print_only_name; /* flags indicating that fname is not a real file*/ char fname[1]; /* name of the file */ } file_filter_ctx_t ; @@ -56,6 +57,7 @@ typedef struct { static int underflow(IOBUF a); +static const char *get_real_fname( IOBUF a ); /**************** * Read data from a file into buf which has an allocated length of *LEN. @@ -451,7 +453,7 @@ iobuf_cancel( IOBUF a ) const char *s; if( a && a->usage == 2 ) { - s = iobuf_get_fname(a); + s = get_real_fname(a); if( s && *s ) remove(s); /* remove the file. Fixme: this will fail for MSDOZE*/ } /* because the file is still open */ @@ -486,16 +488,19 @@ iobuf_open( const char *fname ) FILE *fp; file_filter_ctx_t *fcx; size_t len; + int print_only = 0; if( !fname || (*fname=='-' && !fname[1]) ) { fp = stdin; /* fixme: set binary mode for msdoze */ fname = "[stdin]"; + print_only = 1; } else if( !(fp = fopen(fname, "rb")) ) return NULL; a = iobuf_alloc(1, 8192 ); fcx = m_alloc( sizeof *fcx + strlen(fname) ); fcx->fp = fp; + fcx->print_only_name = print_only; strcpy(fcx->fname, fname ); a->filter = file_filter; a->filter_ov = fcx; @@ -517,16 +522,19 @@ iobuf_create( const char *fname ) FILE *fp; file_filter_ctx_t *fcx; size_t len; + int print_only = 0; if( !fname || (*fname=='-' && !fname[1]) ) { fp = stdout; fname = "[stdout]"; + print_only = 1; } else if( !(fp = fopen(fname, "wb")) ) return NULL; a = iobuf_alloc(2, 8192 ); fcx = m_alloc( sizeof *fcx + strlen(fname) ); fcx->fp = fp; + fcx->print_only_name = print_only; strcpy(fcx->fname, fname ); a->filter = file_filter; a->filter_ov = fcx; @@ -1085,6 +1093,21 @@ iobuf_seek( IOBUF a, ulong newpos ) +/**************** + * Retrieve the real filename + */ +static const char * +get_real_fname( IOBUF a ) +{ + for( ; a; a = a->chain ) + if( !a->chain && a->filter == file_filter ) { + file_filter_ctx_t *b = a->filter_ov; + return b->print_only_name? NULL : b->fname; + } + + return NULL; +} + /**************** * Retrieve the filename */ diff --git a/util/ttyio.c b/util/ttyio.c index 38143cba5..9f095d86e 100644 --- a/util/ttyio.c +++ b/util/ttyio.c @@ -39,6 +39,8 @@ #include "memory.h" #include "ttyio.h" +#define CONTROL_D ('D' - 'A' + 1) + #ifdef __MINGW32__ /* use the odd Win32 functions */ static struct { @@ -279,6 +281,8 @@ do_get( const char *prompt, int hidden ) if( !hidden ) last_prompt_len++; c = *cbuf; + if( c == CONTROL_D ) + log_info("control d found\n"); if( c == '\t' ) c = ' '; else if( c > 0xa0 ) @@ -292,6 +296,10 @@ do_get( const char *prompt, int hidden ) } buf[i++] = c; } + if( *cbuf != '\n' ) { + buf[0] = CONTROL_D; + i = 1; + } if( hidden ) { diff --git a/zlib/Makefile b/zlib/Makefile index c01b193b8..b98090a3b 100644 --- a/zlib/Makefile +++ b/zlib/Makefile @@ -66,7 +66,7 @@ host_alias = i586-pc-linux-gnu host_triplet = i586-pc-linux-gnu target_alias = i586-pc-linux-gnu target_triplet = i586-pc-linux-gnu -CATALOGS = en.gmo de.gmo it.gmo +CATALOGS = en.gmo de.gmo it.gmo fr.gmo CATOBJEXT = .gmo CC = gcc CPP = gcc -E @@ -74,7 +74,7 @@ DATADIRNAME = share DYNLINK_LDFLAGS = -rdynamic G10_LOCALEDIR = /usr/local/share/locale GENCAT = -GMOFILES = en.gmo de.gmo it.gmo +GMOFILES = en.gmo de.gmo it.gmo fr.gmo GMSGFMT = /usr/local/bin/msgfmt GT_NO = GT_YES = #YES# @@ -87,12 +87,12 @@ MKINSTALLDIRS = scripts/mkinstalldirs MPI_EXTRA_ASM_OBJS = MSGFMT = /usr/local/bin/msgfmt PACKAGE = gnupg -POFILES = en.po de.po it.po +POFILES = en.po de.po it.po fr.po POSUB = po RANLIB = ranlib USE_INCLUDED_LIBINTL = yes USE_NLS = yes -VERSION = 0.3.4 +VERSION = 0.3.4a ZLIBS = l =