*** empty log message ***
authorWerner Koch <wk@gnupg.org>
Fri, 11 Sep 1998 05:47:32 +0000 (05:47 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 11 Sep 1998 05:47:32 +0000 (05:47 +0000)
34 files changed:
AUTHORS
NEWS
THANKS
TODO
VERSION
cipher/ChangeLog
cipher/Makefile.am
configure.in
doc/gpg.1pod
g10/ChangeLog
g10/Makefile.am
g10/armor.c
g10/build-packet.c
g10/delkey.c [new file with mode: 0644]
g10/encode.c
g10/g10.c
g10/getkey.c
g10/keydb.h
g10/keyedit.c
g10/keygen.c
g10/main.h
g10/options.h
g10/packet.h
g10/parse-packet.c
g10/pkclist.c
g10/pubkey-enc.c
g10/revoke.c
g10/seckey-cert.c
g10/sign.c
g10/trustdb.c
util/ChangeLog
util/iobuf.c
util/ttyio.c
zlib/Makefile

diff --git a/AUTHORS b/AUTHORS
index 779b4ed..35e7049 100644 (file)
--- 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 b2e229f..10aca85 100644 (file)
--- 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 8cbda75..054c6a3 100644 (file)
--- 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 ac98f08..0bbb4f3 100644 (file)
--- 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
 
     * 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 42045ac..789f9a5 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.3.4
+0.3.4a
index cb6082e..7b16f12 100644 (file)
@@ -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
index 36dd0c5..a9d5a5c 100644 (file)
@@ -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 \
index 681845f..fc6d3db 100644 (file)
@@ -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")
index 9886310..93b1a19 100644 (file)
@@ -333,6 +333,12 @@ B<--compress-algo> I<number>
     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<n>
     Read the passphrase from file descriptor I<n>. If you use
     0 for I<n>, the passphrase will be read from stdin.  This
index 526cf15..f2406ea 100644 (file)
@@ -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.
index 0097ace..c6d5b13 100644 (file)
@@ -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)
index f5116ac..38e1b19 100644 (file)
@@ -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:
index a7c7093..a877b7e 100644 (file)
@@ -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 (file)
index 0000000..2105284
--- /dev/null
@@ -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 <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <ctype.h>
+
+#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;
+}
+
index 1d50550..ae8b261 100644 (file)
@@ -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 );
index d230ad9..a41ecb3 100644 (file)
--- 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
+    { 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
+    { aKeygen, "gen-key",   256, N_("generate a new key pair")},
   #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")},
+    { aDeleteKey, "delete-key",256, N_("remove key from the public keyring")},
   #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")},
+    { aEditKey, "edit-key"  ,256, N_("sign or edit a key")},
+    { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
   #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")},
+    { 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")},
-
-    { 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")},
+    { 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")},
+
+    { 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,81 +561,64 @@ 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 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));
-           strcpy(sl->d, pargs.r.ret_str);
-           sl->next = locusr;
-           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 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 540: secmem_set_flags( secmem_get_flags() | 1 ); break;
-         case 542: set_cmd( &cmd, aGenRevoke); break;
-         case 550: set_cmd( &cmd, aVerify); break;
+         case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
+         case aVerify: set_cmd( &cmd, aVerify); break;
        #else
-         case 527:
-         case 529:
-           break;
-       #endif /* !IS_G10 */
-
-       #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;
+           case aPrimegen: set_cmd( &cmd, aPrimegen); break;
+           case aTest: set_cmd( &cmd, aTest); break;
+           case aGenRandom: 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;
+         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 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:
+         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);
@@ -600,38 +626,33 @@ main( int argc, char **argv )
                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:
+         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;
@@ -639,8 +660,36 @@ main( int argc, char **argv )
            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;
+         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 oTextmode: opt.textmode=1;  break;
+         case oUser: /* store the local users */
+           sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
+           strcpy(sl->d, pargs.r.ret_str);
+           sl->next = locusr;
+           locusr = sl;
+           break;
+         case oCompress: opt.compress = pargs.r.ret_int; 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 oCipherAlgo:
+         case oDigestAlgo:
+         case oNoSecmemWarn:
+           break;  /* dummies */
+       #endif
+
          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;
index 10899a6..189ef0b 100644 (file)
@@ -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 */
index 2d3f61f..c85f937 100644 (file)
@@ -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 );
 
index a0a6252..c0a082b 100644 (file)
@@ -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);
index afe5bb4..47a24b2 100644 (file)
@@ -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;
index bba90ef..a8132fa 100644 (file)
@@ -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 --*/
index 4c8ec61..a4b4167 100644 (file)
@@ -54,6 +54,7 @@ struct {
     int shm_coprocess;
     const char *set_filename;
     const char *comment_string;
+    int throw_keyid;
 } opt;
 
 
index 495e722..0a4adc5 100644 (file)
@@ -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 --*/
index bc7aca5..2601e15 100644 (file)
@@ -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]);
index e85b289..b4d79f2 100644 (file)
 #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");
     }
 
 
index f6a15fc..2e9a14a 100644 (file)
@@ -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
 int
 get_session_key( PKT_pubkey_enc *k, DEK *dek )
 {
-    int rc = 0;
-    MPI plain_dek  = NULL;
-    byte *frame = NULL;
-    unsigned n, nframe;
-    u16 csum, csum2;
-    PKT_secret_key *sk = m_alloc_clear( sizeof *sk );
+    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 );
+
+    rc = check_pubkey_algo( k->pubkey_algo );
     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;
+    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;
 
-    rc = pubkey_decrypt(k->pubkey_algo, &plain_dek, k->data, sk->skey );
+    rc = pubkey_decrypt(sk->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;
 }
 
index 278bdca..61d1e4c 100644 (file)
@@ -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 )
index df5c2b9..819f79c 100644 (file)
@@ -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 );
index d3f49e1..63b7c82 100644 (file)
@@ -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?
index 642d1b5..efe7bca 100644 (file)
@@ -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 )
index 9ef2325..8644bb7 100644 (file)
@@ -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
index 6ad0013..b7ccd1e 100644 (file)
@@ -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;
@@ -1086,6 +1094,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
  */
 const char *
index 38143cb..9f095d8 100644 (file)
@@ -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 ) {
index c01b193..b98090a 100644 (file)
@@ -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 =