sync
authorWerner Koch <wk@gnupg.org>
Tue, 14 Jul 1998 17:10:28 +0000 (17:10 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 14 Jul 1998 17:10:28 +0000 (17:10 +0000)
41 files changed:
Makefile.am
NEWS
README
THANKS
TODO
VERSION
checks/defs.inc
cipher/ChangeLog
cipher/primegen.c
cipher/random.c
configure.in
doc/DETAILS
doc/Makefile.am
doc/gpg.1pod
g10/ChangeLog
g10/OPTIONS
g10/armor.c
g10/g10.c
g10/getkey.c
g10/keydb.h
g10/keyedit.c
g10/keygen.c
g10/keyid.c
g10/keylist.c
g10/main.h
g10/mainproc.c
g10/misc.c
g10/openfile.c
g10/options.h
g10/packet.h
g10/pkclist.c
g10/plaintext.c
g10/seskey.c
g10/sign.c
g10/tdbio.c
g10/tdbio.h
g10/trustdb.c
g10/verify.c
po/ChangeLog
tools/mk-tdata
zlib/Makefile

index cd8ae7f..b8f6282 100644 (file)
@@ -17,5 +17,8 @@ dist-hook:
                || cp -p $(srcdir)/$$dir/$$i $(distdir)/$$dir/$$i; \
            done ; \
        done
+       for file in po/cat-id-tbl.c po/gnupg.pot; do \
+           rm $(distdir)/$$file || true ; \
+       done
 
 
diff --git a/NEWS b/NEWS
index 6695dd5..6197de5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,13 @@
+Noteworthy changes in version 0.3.3
+-----------------------------------
+    * Removed options --gen-prime and --gen-random.
+
+    * Signatures are now checked even if the output file could not
+      be created. Command "--verify" tries to find the detached data.
+
+    * gpg now disables core dumps.
+
+
 Noteworthy changes in version 0.3.2
 -----------------------------------
     * Fixed some bugs when using --textmode (-seat)
diff --git a/README b/README
index fa2ea8c..c220c00 100644 (file)
--- a/README
+++ b/README
@@ -1,9 +1,6 @@
------BEGIN PGP SIGNED MESSAGE-----
-
-
-                  GNUPG - The GNU Privacy Guard
-                 -------------------------------
-                          Version 0.3
+                 GNUPG - The GNU Privacy Guard
+                -------------------------------
+                         Version 0.3
 
 
     As you can see from the version number, the program may have some
@@ -51,7 +48,7 @@
     is still available, but due to the larger size of such signatures it
     is depreciated (Please note that the GNUPG implementation of ElGamal
     signatures is *not* insecure).  Symmetric algorithms are: Blowfish
-    and CAST5,  Digest algorithms are MD5, RIPEMD160, SHA1 and TIGER/192.
+    and CAST5, Digest algorithms are MD5, RIPEMD160, SHA1 and TIGER/192.
 
 
 
@@ -60,7 +57,7 @@
 
     See the file INSTALL.  Here is a quick summary:
 
-    1)  "./configure"
+    1) "./configure"
 
     2) "make"
 
@@ -75,7 +72,7 @@
     Key Generation
     --------------
 
-        gpg --gen-key
+       gpg --gen-key
 
     This asks some questions and then starts key generation. To create
     good random numbers for prime number generation, it uses a /dev/random
@@ -88,7 +85,7 @@
     You should make a revocation certificate in case someone gets
     knowledge of your secret key or you forgot your passphrase:
 
-        gpg --gen-revoke your_user_id
+       gpg --gen-revoke your_user_id
 
     Run this command and store it away; output is always ASCII armored,
     so that you can print it and (hopefully never) re-create it if
     If you decided to create a DSA key, you should add an ElGamal
     for encryption:
 
-        gpg --add-key user_id_of_your_key
+       gpg --add-key user_id_of_your_key
 
     and follow the displayed instructions (select "ElGamal using v4 packets").
 
 
     You can sign a key with this command:
 
-        gpg --sign-key Donald
+       gpg --sign-key Donald
 
     This let you sign the key of "Donald" with your default userid.
 
-        gpg --sign-key -u Karl -u Joe Donald
+       gpg --sign-key -u Karl -u Joe Donald
 
     This let you sign the key of of "Donald" with the userids of "Karl"
     and "Joe".
     whether you want to sign this key.
 
     You may remove a signature at any time using the option "--edit-sig",
-    which asks for the sigs to remove.  Self-signatures are not removable.
+    which asks for the sigs to remove. Self-signatures are not removable.
 
 
 
     Sign
     ----
 
-        gpg -s file
+       gpg -s file
 
     This creates a file file.gpg which is compressed and has a signature
     attached.
 
-        gpg -sa file
+       gpg -sa file
 
     Same as above, but file.gpg is ascii armored.
 
-        gpg -s -o out file
+       gpg -s -o out file
 
     Creates a signature of file, but writes the output to the file "out".
 
     Encrypt
     -------
 
-        gpg -e -r heine file
+       gpg -e -r heine file
 
     This encrypts files with the public key of "heine" and writes it
     to "file.gpg"
 
-        echo "hallo" | gpg -ea -r heine | mail heine
+       echo "hallo" | gpg -ea -r heine | mail heine
 
     Ditto, but encrypts "hallo\n" and mails it as ascii armored message.
 
     Sign and Encrypt
     ----------------
 
-        gpg -se -r heine file
+       gpg -se -r heine file
 
     This encrypts files with the public key of "heine" and writes it
     to "file.gpg" after signing it with the default user id.
 
 
-        gpg -se -r heine -u Suttner file
+       gpg -se -r heine -u Suttner file
 
     Ditto, but sign the file with the user id "Suttner"
 
     ------------------
     To export your complete keyring(s) do this:
 
-        gpg --export
+       gpg --export
 
     To export only some user ids do this:
 
-        gpg --export userids
+       gpg --export userids
 
     Use "-a" or "--armor" to create ASCII armored output.
 
     Importing keys is done with the option, you guessed it, "--import":
 
-        gpg --import [filenames]
+       gpg --import [filenames]
 
     New keys are appended to the default keyring and already existing
     keys are merged.  Keys without a self-signature are ignored.
 
     * Only by the short keyid (prepend a zero if it begins with A..F):
 
-        "234567C4"
-        "0F34E556E"
-        "01347A56A"
-        "0xAB123456
+       "234567C4"
+       "0F34E556E"
+       "01347A56A"
+       "0xAB123456
 
     * By a complete keyid:
 
-        "234AABBCC34567C4"
-        "0F323456784E56EAB"
-        "01AB3FED1347A5612"
-        "0x234AABBCC34567C4"
+       "234AABBCC34567C4"
+       "0F323456784E56EAB"
+       "01AB3FED1347A5612"
+       "0x234AABBCC34567C4"
 
     * By a fingerprint:
 
-        "1234343434343434C434343434343434"
-        "123434343434343C3434343434343734349A3434"
-        "0E12343434343434343434EAB3484343434343434"
+       "1234343434343434C434343434343434"
+       "123434343434343C3434343434343734349A3434"
+       "0E12343434343434343434EAB3484343434343434"
 
       The first one is MD5 the others are ripemd160 or sha1.
 
     * By an exact string (not yet implemented):
 
-        "=Heinrich Heine <heinrichh@uni-duesseldorf.de>"
+       "=Heinrich Heine <heinrichh@uni-duesseldorf.de>"
 
     * By an email address:
 
-        "<heinrichh@uni-duesseldorf.de>"
+       "<heinrichh@uni-duesseldorf.de>"
 
       This can be used by a keyserver instead of a substring to
       find this key faster.
 
     * By the Local ID (from the trustdb):
 
-        "#34"
+       "#34"
 
       This can be used by a MUA to specify an exact key after selecting
       a key from GNUPG (by the use of a special option or an extra utility)
 
     * Or by the usual substring:
 
-        "Heine"
-        "*Heine"
+       "Heine"
+       "*Heine"
 
       The '*' indicates substring search explicitly.
 
     Esoteric commands
     -----------------
 
-        gpg --list-packets datafile
+       gpg --list-packets datafile
 
     Use this to list the contents of a data file. If the file is encrypted
     you are asked for the passphrase, so that GNUPG is able to look at the
     inner structure of a encrypted packet.
 
-        gpgm --list-trustdb
+       gpgm --list-trustdb
 
     List the contents of the trustdb in a human readable format
 
-        gpgm --list-trustdb  <usernames>
+       gpgm --list-trustdb  <usernames>
 
     List the tree of certificates for the given usernames
 
-        gpgm --list-trust-path  depth  username
+       gpgm --list-trust-path  depth  username
 
     List the possible trust paths for the given username, up to the specified
     depth.  If depth is negative, duplicate introducers are not listed,
      using a negative number). This option may create new entries in the
     trustdb.
 
-        gpgm --print-mds  filenames
+       gpgm --print-mds  filenames
 
     List all available message digest values for the fiven filenames
 
-        gpgm --gen-prime n
-
-    Generate and print a simple prime number of size n
-
-        gpgm --gen-prime n q
-
-    Generate a prime number suitable for ElGamal signatures of size n with
-    a q as largest prime factor of n-1.
-
-        gpgm --gen-prime n q 1
-
-    Ditto, but calculate a generator too.
-
-
     For more options/commands see the file g10/OPTIONS, or use "gpg --help"
 
 
     can be used multiple times, all values are ORed; n maybe prefixed with
     0x to use hex-values.
 
-         value  used for
-         -----  ----------------------------------------------
-          1     packet reading/writing
-          2     MPI details
-          4     ciphers and primes (may reveal sensitive data)
-          8     iobuf filter functions
-          16    iobuf stuff
-          32    memory allocation stuff
-          64    caching
-          128   show memory statistics at exit
-          256   trust verification stuff
+        value  used for
+        -----  ----------------------------------------------
+         1     packet reading/writing
+         2     MPI details
+         4     ciphers and primes (may reveal sensitive data)
+         8     iobuf filter functions
+         16    iobuf stuff
+         32    memory allocation stuff
+         64    caching
+         128   show memory statistics at exit
+         256   trust verification stuff
 
 
     Other Notes
     post them to the mailing list <g10@net.lut.ac.uk> (this is a closed list,
     please subscribe before posting).
 
-
-
------BEGIN PGP SIGNATURE-----
-Version: 2.6.3ia
-Charset: noconv
-
-iQB1AwUBNaIyMR0Z9MEMmFelAQGGFgMAm0RkKqH6DwIl3cu4ETQROprnwbl0sc21
-05CQCsATs/0oQ8R2GhH1vXyHQnGw4Abg8IHqe+fADUA8cpf1ijfPzgeq+qhp7rqs
-EenOw3xe8RrsrvovkCy91AtYl8zyVdC8
-=IgnL
------END PGP SIGNATURE-----
diff --git a/THANKS b/THANKS
index 4cf90ed..70a8274 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -23,6 +23,7 @@ Marco d'Itri            md@linux.it
 Mark Adler             madler@alumni.caltech.edu
 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
 Peter Gutmann          pgut001@cs.auckland.ac.nz
 Ralph Gillen           gillen@theochem.uni-duesseldorf.de
diff --git a/TODO b/TODO
index 53a3c9d..b5cd734 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,25 +1,21 @@
+    * Change the internal represenation of keyid into a struct which
+      can also hold the localid and extend the localid to hold information
+      of the subkey number because two subkeys may have the same keyid.
 
+    * invalid packets (Marco)
 
-    * clearsig of zero length files does not work
-
-    * Change the inernal represenation of keyid into a struct which
-      can also hold the localid
+    * what about the CR,LF in cleartext singatures?
 
     * add option --restore-ownertrust
 
     * always put key signatures before the first subkey.
 
-    * Change the formatting of log_xxxx to GNU standards
-      ("name:filename:line: text")
-
     * add a way to delete subkeys (in edit-keys?)
 
     * make preferences work
 
     * rewrite --list-packets or put it into another tool.
 
-    * add field to PKT_user_id to hold the hash context
-
     * add usage arguments to get_key_byname or return a PKC_LIST with
       all keys and add a selection.
 
     * Burn the buffers used by fopen(), or use read(2). Does this
       really make sense?
 
-
     * enable a SIGSEGV handler while using zlib functions
 
-    * improve iobuf by reading more than one byte at once,
-      this shoud espceially done for the buffer in the chain.
-      Change the buffering to a mbuf like scheme? Need it for PSST anyway.
-    * add a way to distinguish between errors and eof in the underflow/flush
-      function of iobuf.
+    * Change the buffering to a mbuf like scheme? Need it for PSST anyway.
     * add checking of armor trailers
     * remove all "Fixmes"
 
     * 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.
 
-    * add fingerprint/keyid hashing. We need a new field in PKC to
-      flag that we may have a cached signature for this (and use the address
-      of PKC to lookup the hash).
-
     * replace getkey.c#enum_secret_keys
 
-
diff --git a/VERSION b/VERSION
index d15723f..52723e5 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.3.2
+0.3.2b
index 61e07ee..f3ff66f 100755 (executable)
@@ -22,8 +22,8 @@ dsa_keyrings="--keyring ./pubring.pkr --secret-keyring ./secring.skr"
 
 
 plain_files="plain-1 plain-2 plain-3"
-#data_files="data-500 data-9000 data-32000 data-80000"
-data_files="data-500 data-9000"
+data_files="data-500 data-9000 data-32000 data-80000"
+#data_files="data-500 data-9000"
 exp_files=""
 
 
index bee0349..0109528 100644 (file)
@@ -1,3 +1,8 @@
+Mon Jul 13 21:30:52 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * random.c (read_pool): Simple alloc if secure_alloc is not set.
+       (get_random_bits): Ditto.
+
 Thu Jul  9 13:01:14 1998  Werner Koch  (wk@isil.d.shuttle.de)
 
        * dynload.c (load_extension): Function now nbails out if
index 23aa1db..66d40db 100644 (file)
@@ -281,7 +281,6 @@ gen_prime( unsigned  nbits, int secret, int randomlevel )
     mods = m_alloc( no_of_small_prime_numbers * sizeof *mods );
     /* make nbits fit into MPI implementation */
     nlimbs = (nbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB;
-    assert( nlimbs );
     val_2  = mpi_alloc( nlimbs );
     mpi_set_ui(val_2, 2);
     val_3  = mpi_alloc( nlimbs );
index f44e4c3..75754cd 100644 (file)
@@ -153,7 +153,7 @@ get_random_bits( size_t nbits, int level, int secure )
     size_t nbytes = (nbits+7)/8;
 
     MASK_LEVEL(level);
-    buf = secure? m_alloc_secure( nbytes ) : m_alloc( nbytes );
+    buf = secure && secure_alloc ? m_alloc_secure( nbytes ) : m_alloc( nbytes );
     read_pool( buf, nbytes, level );
     return buf;
 }
@@ -222,7 +222,7 @@ read_pool( byte *buffer, size_t length, int level )
        needed = length - pool_balance;
        if( needed > POOLSIZE )
            BUG();
-       p = m_alloc_secure( needed );
+       p = secure_alloc ? m_alloc_secure( needed ) : m_alloc(needed);
        read_random_source( p, needed, 2 ); /* read /dev/random */
        add_randomness( p, needed, 3);
        m_free(p);
index 005a1b5..80a5c07 100644 (file)
@@ -182,7 +182,7 @@ fi
 dnl Checks for library functions.
 AC_FUNC_VPRINTF
 AC_CHECK_FUNCS(strerror stpcpy strlwr tcgetattr rand strtoul mlock mmap)
-AC_CHECK_FUNCS(memmove gettimeofday getrusage gethrtime)
+AC_CHECK_FUNCS(memmove gettimeofday getrusage gethrtime setrlimit)
 
 
 dnl check whether we have a random device
index a2de343..1be782a 100644 (file)
@@ -56,7 +56,7 @@ Record type 1:
 --------------
     Version information for this TrustDB.  This is always the first
     record of the DB and the only one with type 1.
-     1 byte value 1
+     1 byte value 2
      3 bytes 'gpg'  magic value
      1 byte Version of the TrustDB
      3 byte reserved
@@ -81,42 +81,79 @@ Record type 2: (directory record)
     These are static values which are never changed without user interaction.
 
      1 byte value 2
-     1 byte   reserved
-     8 bytes keyid (We keep it here to speed up searching by keyid)
-     1 u32   Local-Id. This is simply the record number of this record.
-     1 u32   primary public key (record number of it)
+     1 byte  reserved
+     1 u32   LID     . (This is simply the record number of this record.)
+     1 u32   List of key-records (the first one is the primary key)
+     1 u32   List of uid-records
      1 u32   cache record
-     1 u32   sigrecord
-     1 byte  No signatures flag  (used to avoid duplicate building).
-     3 byte  reserved
-     1 u32   userid record
-     6 byte reserved
+     1 byte  ownertrust
+     1 byte  sigflag
+    20 byte reserved
 
 
-Record type 3:
+Record type 3: (key record)
 --------------
     Informations about a primary public key.
-    These are static values which are never changed without user interaction.
+    (This is mainly used to lookup a trust record)
 
      1 byte value 3
-     1 byte   reserved
-     1 u32   owner  This is used to bind all records for
-            a given certificate together. It is valid only in this TrustDB
-            and useful if we have duplicate keyids
-            It points back to the directory node.
-     1 byte pubkey algorithm
-     1 byte length of the fingerprint (in bytes)
+     1 byte  reserved
+     1 u32   LID
+     1 u32   next   - next key record
+     8 bytes reserved
+     1 byte  pubkey algorithm
+     1 byte  length of the fingerprint (in bytes)
      20 bytes fingerprint of the public key
-     1 byte ownertrust if there is no trust defined for the userid:
-     3 byte reserved
+             (This is the value we use to identify a key)
+
+Record type 4: (uid record)
+--------------
+    Informations about a userid
+    We do not store the userid but the hash value of the userid because that
+    is sufficient.
+
+     1 byte value 4
+     1 byte reserved
+     1 u32  LID  points to the directory record.
+     1 u32  next   next userid
+     1 u32  pointer to preference record
+     1 u32  siglist  list of valid signatures
+     2 byte reserved
+     20 bytes ripemd160 hash of the username.
 
 
-Record type 4: (cache record)
+Record type 5: (pref record)
+--------------
+    Informations about preferences
+
+     1 byte value 5
+     1 byte   reserved
+     1 u32  LID; points to the directory record (and not to the uid record!).
+           (or 0 for standard preference record)
+     1 u32  next
+
+Record type 6  (sigrec)
+-------------
+    Used to keep track of valid key signatures. Self-signatures are not
+    stored.
+
+     1 byte   value 6
+     1 byte   reserved
+     1 u32    LID          points back to the dir record
+     1 u32    next   next sigrec of this owner or 0 to indicate the
+                    last sigrec.
+     6 times
+       1 u32  Local_id of signators dir record
+       1 byte reserved
+
+
+
+Record type 9: (cache record)
 --------------
     Used to bind the trustDB to the concrete instance of keyblock in
     a pubring. This is used to cache information.
 
-     1 byte   value 4
+     1 byte   value 9
      1 byte   reserved
      1 u32    Local-Id.
      8 bytes  keyid of the primary key (needed?)
@@ -141,23 +178,9 @@ Record type 4:     (cache record)
                4 = fully trusted
                5 = ultimately trusted (have secret key too).
 
-Record type 5  (sigrec)
--------------
-    Used to keep track of valid key signatures. Self-signatures are not
-    stored.
 
-     1 byte   value 5
-     1 byte   reserved
-     1 u32    For Local-Id (points back to the directory record)
-     1 u32    chain: next sigrec of this owner or 0 to indicate the
-             last sigrec.
-     6 times
-       1 u32  Local_id of signators pubkey record
-       1 byte reserved
-
-
-Record Type 6 (hash table)
--------------
+Record Type 10 (hash table)
+--------------
     Due to the fact that we use the keyid to lookup keys, we can
     implement quick access by some simple hash methods, and avoid
     the overhead of gdbm.  A property of keyids is that they can be
@@ -171,7 +194,7 @@ Record Type 6 (hash table)
     big table. The hash value is simple the 1st, 2nd, ... byte of
     the keyid (depending on the indirection level).
 
-     1 byte value 5
+     1 byte value 10
      1 byte reserved
      n u32  recnum; n depends on th record length:
            n = (reclen-2)/4  which yields 9 for the current record length
@@ -194,38 +217,19 @@ Record Type 6 (hash table)
         if this is not the correct dir record, we look at the next
         dir record which is linked by the link field.
 
-Record type  (hash list)
--------------
+Record type 11 (hash list)
+--------------
     see hash table for an explanation.
 
-    1 byte value 6
+    1 byte value 11
     1 byte reserved
-    1 u32  chain        next hash list record
+    1 u32  next         next hash list record
     n times             n = (reclen-6)/5
        1 byte hash
        1 u32  recnum
 
     For the current record length of 40, n is 6
 
-Record type 8: (userid)
---------------
-    Informations about a userid
-    We do not store the userid but the hash value of the userid because that
-    is sufficient.
-
-     1 byte value 8
-     1 byte   reserved
-     1 u32  owner; points to the directory record.
-     1 u32  next userid
-     1 byte subtype: 0 = a real user id
-                    1 = not a real userid, but a "dummy" user of length 0
-                        which is used to represent stuff that is directly
-                        bound to the key.
-     20 bytes ripemd160 hash of the username.
-     1 u32  pointer to preference record
-     1 byte ownertrust
-     4 byte reserved
-
 
 
 Packet Headers
index 020338b..dc2ee58 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to create Makefile.in
 
-EXTRA_DIST = DETAILS rfcs gpg.1pod gpg.1
+EXTRA_DIST = DETAILS rfcs gpg.1pod gpg.1 FAQ
 
 man_MANS = gpg.1
 
index 726e976..1fde885 100644 (file)
@@ -55,7 +55,10 @@ B<--verify> [[I<sigfile>] {I<signed-files>}]
     detached signature when not used in batch mode). If
     only a sigfile is given, it may be a complete signature
     or a detached signature, in which case the signed stuff
-    is expected from stdin. With more than 1 argument, the
+    is expected in a file without the I<.sig> or I<.asc>
+    extension (if such a file does not exist it is expected
+    at stdin - use B<-> as filename to force a read from
+    stdin). With more than 1 argument, the
     first should be a detached signature and the remaining
     files are the signed stuff.
 
index a637ac9..f6f935a 100644 (file)
@@ -1,3 +1,35 @@
+Tue Jul 14 18:09:51 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * keyid.c (fingerprint_from_pk): Add argument and changed all callers.
+       (fingerprint_from_sk): Ditto.
+
+Tue Jul 14 10:10:03 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * plaintext.c (handle_plaintext): Now returns create error if
+       the file could not be created or the user responded not to overwrite
+       the file.
+       * mainproc.c (proc_plaintext): Tries again if the file could not
+       be created to check the signature without output.
+
+       * misc.c (disable_core_dumps): New.
+       * g10.c (main): disable coredumps for gpg
+
+       * g10.c (MAINTAINER_OPTIONS): New to disable some options
+
+Mon Jul 13 16:47:54 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * plaintext.c (hash_datafiles): New arg for better support of
+       detached sigs. Changed all callers.
+       * mainproc.c (proc_signature_packets): Ditto.
+
+       * g10.c (main): New option "compress-sigs"
+       * sig.c (sign_file): detached signatures are not anymore compressed
+       unless the option --compress-sigs is used.
+
+Thu Jul  9 19:54:54 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * armor.c: Fixes to allow zero length cleartext signatures
+
 Thu Jul  9 14:52:47 1998  Werner Koch  (wk@isil.d.shuttle.de)
 
        * g10.c (build_list): Now drops setuid.
index 3abe296..8e9cf8a 100644 (file)
 #-----------------------------------------------
 #------------------- Commands ------------------
 #-----------------------------------------------
-# With some expections, these cannot be combined
-
-gen-prime
-# Generate a prime.
-# With one argument:  take it as the bitsize and make a simple prime of
-#                    this size
-# With two arguments: Generate a prime, usable for DL algorithms.
-# With three arguments: same as above, but a third argument indicates
-#                      that a generator should also be calculated.
+# With some exceptions, these cannot be combined
 
 print-md algo
 # print the message digest of algorithm ALGO for stdin or all
@@ -53,4 +45,7 @@ compress-keys
 # algorithm with --compress-algo" - Default is to not compress keys, as
 # this is better for interoperability.
 
+compress-sigs
+# Normally, compressing of signatures does not make sense; so this
+# is disabled for detached signatures unless this option is used.
 
index 46151ea..45f962f 100644 (file)
@@ -62,6 +62,7 @@ typedef enum {
     fhdrSKIPHeader,
     fhdrCLEARSIG,
     fhdrREADClearsig,
+    fhdrNullClearsig,
     fhdrEMPTYClearsig,
     fhdrCHECKClearsig,
     fhdrCHECKClearsig2,
@@ -343,6 +344,8 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
                                *r_hashes |= hashes;
                        }
                    }
+                   else if( clearsig && n > 15 && !memcmp(buf, "-----", 5 ) )
+                       state = fhdrNullClearsig;
                    else
                        state = fhdrCHECKDashEscaped3;
                }
@@ -386,7 +389,10 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
                buf[n++] = c;
            if( n < buflen || c == '\n' ) {
                buf[n] = 0;
-               state = fhdrCHECKDashEscaped3;
+               if( n > 15 && !memcmp(buf, "-----", 5 ) )
+                   state = fhdrNullClearsig;
+               else
+                   state = fhdrCHECKDashEscaped3;
            }
            else {
                /* fixme: we should check whether this line continues
@@ -396,6 +402,10 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
            }
            break;
 
+         case fhdrNullClearsig: /* zero length cleartext */
+           state = fhdrENDClearsig;
+           break;
+
          case fhdrENDClearsig:
          case fhdrCHECKBegin:
            state = state == fhdrCHECKBegin ? fhdrINITSkip : fhdrERRORShow;
@@ -587,10 +597,8 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
            buf[1] = '\n';
            n = 2;
        }
-
     }
 
-
     *r_buflen = n;
     *r_empty = empty;
     return state;
@@ -627,6 +635,7 @@ check_input( armor_filter_context_t *afx, IOBUF a )
        rc = -1;
        break;
 
+      case fhdrNullClearsig:
       case fhdrCLEARSIG: /* start fake package mode (for clear signatures) */
        afx->helplen = n;
        afx->helpidx = 0;
@@ -679,7 +688,8 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
            rc = -1;
            continue;
        }
-       if( afx->helpidx < afx->helplen ) { /* flush the last buffer */
+       if( state != fhdrNullClearsig
+           && afx->helpidx < afx->helplen ) { /* flush the last buffer */
            n = afx->helplen;
            for(nn=afx->helpidx; len < size && nn < n ; nn++ )
                buf[len++] = afx->helpbuf[nn];
@@ -693,7 +703,8 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
        /* read a new one */
        n = DIM(afx->helpbuf);
        afx->helpidx = 0;
-       state = find_header( state, afx->helpbuf, &n, a, 0,
+       state = find_header( state, afx->helpbuf, &n, a,
+                             state == fhdrNullClearsig? afx->helplen:0,
                                                &emplines, &afx->hashes );
        switch( state) {
          case fhdrERROR:
@@ -723,8 +734,10 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
     buf[0] = (len-2) >> 8;
     buf[1] = (len-2);
     if( state == fhdrENDClearsig ) { /* write last (ending) length header */
-       buf[len++] = 0;
-       buf[len++] = 0;
+       if( buf[0] || buf[1] ) { /* write only if length of text is > 0 */
+           buf[len++] = 0;
+           buf[len++] = 0;
+       }
        rc = 0;
     }
 
index 8082fe2..308b582 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <unistd.h>
 
+/* #define MAINTAINER_OPTIONS */
 
 #include "packet.h"
 #include "iobuf.h"
@@ -85,8 +86,10 @@ static ARGPARSE_OPTS opts[] = {
     { 547, "enarmor", 0, N_("En-Armor a file or stdin") },
     { 555, "print-md" , 0, N_("|algo [files]|print message digests")},
     { 516, "print-mds" , 0, N_("print all message digests")},
+    #ifdef MAINTAINER_OPTIONS
     { 513, "gen-prime" , 0, "@" },
     { 548, "gen-random" , 0, "@" },
+    #endif
   #endif
 
     { 301, NULL, 0, N_("@\nOptions:\n ") },
@@ -165,6 +168,7 @@ static ARGPARSE_OPTS opts[] = {
     { 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, "@"},
 
@@ -413,6 +417,7 @@ main( int argc, char **argv )
      */
     log_set_name("gpg");
     secure_random_alloc(); /* put random number into secure memory */
+    disable_core_dumps();
     init_signals();
   #endif
     i18n_init();
@@ -529,15 +534,17 @@ main( int argc, char **argv )
        #endif /* !IS_G10 */
 
        #ifdef IS_G10MAINT
-         case 513: set_cmd( &cmd, aPrimegen); break;
-         case 514: set_cmd( &cmd, aTest); break;
+         #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 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 548: set_cmd( &cmd, aGenRandom); break;
          case 555: set_cmd( &cmd, aPrintMD); break;
          case 564: set_cmd( &cmd, aListOwnerTrust); break;
        #endif /* IS_G10MAINT */
@@ -596,6 +603,7 @@ main( int argc, char **argv )
          case 562: opt.emulate_bugs |= 1; break;
          case 563: set_cmd( &cmd, aExportSecret); break;
          case 565: opt.do_not_export_rsa = 1; break;
+         case 566: opt.compress_sigs = 1; break;
          default : errors++; pargs.err = configfp? 1:2; break;
        }
     }
@@ -725,16 +733,16 @@ main( int argc, char **argv )
        if( argc > 1 )
            wrong_args(_("--store [filename]"));
        if( (rc = encode_store(fname)) )
-           log_error("%s: store failed: %s\n",
-                                print_fname_stdin(fname), g10_errstr(rc) );
+           log_error_f( print_fname_stdin(fname),
+                       "store failed: %s\n", g10_errstr(rc) );
        break;
     #ifdef IS_G10
       case aSym: /* encrypt the given file only with the symmetric cipher */
        if( argc > 1 )
            wrong_args(_("--symmetric [filename]"));
        if( (rc = encode_symmetric(fname)) )
-           log_error("%s: symmetric encryption failed: %s\n",
-                           print_fname_stdin(fname), g10_errstr(rc) );
+           log_error_f(print_fname_stdin(fname),
+                       "symmetric encryption failed: %s\n",g10_errstr(rc) );
        break;
 
       case aEncr: /* encrypt the given file */
@@ -933,6 +941,7 @@ main( int argc, char **argv )
        break;
 
 
+     #ifdef MAINTAINER_OPTIONS
       case aPrimegen:
        if( argc == 1 ) {
            mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1);
@@ -960,7 +969,9 @@ main( int argc, char **argv )
        else
            usage(1);
        break;
+      #endif /* MAINTAINER OPTIONS */
 
+      #ifdef MAINTAINER_OPTIONS
       case aGenRandom:
        if( argc < 1 || argc > 2 )
            wrong_args("--gen-random level [hex]");
@@ -977,6 +988,7 @@ main( int argc, char **argv )
            }
        }
        break;
+      #endif /* MAINTAINER OPTIONS */
 
       case aPrintMD:
        if( argc < 1)
@@ -1007,7 +1019,9 @@ main( int argc, char **argv )
        }
        break;
 
+     #ifdef MAINTAINER_OPTIONS
       case aTest: do_test( argc? atoi(*argv): 1 ); break;
+      #endif /* MAINTAINER OPTIONS */
 
       case aListTrustDB:
        if( !argc )
@@ -1085,7 +1099,7 @@ do_not_use_RSA()
 
     if( !did_rsa_note ) {
        did_rsa_note = 1;
-       log_info(_("RSA keys are depreciated; please consider "
+       log_info(_("RSA keys are deprecated; please consider "
                   "creating a new key and use this key in the future\n"));
     }
 }
@@ -1194,10 +1208,12 @@ print_mds( const char *fname, int algo )
 
 
 
+#ifdef MAINTAINER_OPTIONS
 static void
 do_test(int times)
 {
     m_check(NULL);
 }
+#endif /* MAINTAINER OPTIONS */
 #endif /* IS_G10MAINT */
 
index 3f8ac63..b73a006 100644 (file)
@@ -758,7 +758,7 @@ lookup( PKT_public_key *pk, int mode,  u32 *keyid,
                    else if( mode == 16 || mode == 20 ) {
                        size_t an;
                        byte *afp = fingerprint_from_pk(
-                                       k->pkt->pkt.public_key, &an );
+                                       k->pkt->pkt.public_key, NULL, &an );
 
                        if( DBG_CACHE ) {
                            u32 aki[2];
@@ -897,7 +897,7 @@ lookup_sk( PKT_secret_key *sk, int mode,  u32 *keyid, const char *name )
                    else if( mode == 16 || mode == 20 ) {
                        size_t an;
                        byte *afp = fingerprint_from_sk(
-                                       k->pkt->pkt.secret_key, &an );
+                                       k->pkt->pkt.secret_key, NULL, &an );
                        if( an == mode && !memcmp( afp, name, an)
                            && ( !sk->pubkey_algo
                                 || sk->pubkey_algo
index 58a170d..a039809 100644 (file)
@@ -25,6 +25,7 @@
 #include "packet.h"
 #include "cipher.h"
 
+#define MAX_FINGERPRINT_LEN 20
 
 
 /****************
@@ -80,11 +81,12 @@ struct pubkey_find_info {
     u32  keyid[2];
     unsigned nbits;
     byte pubkey_algo;
-    byte fingerprint[20];
+    byte fingerprint[MAX_FINGERPRINT_LEN];
     char userid[1];
 };
 
 
+
 /*-- pkclist.c --*/
 int  check_signatures_trust( PKT_signature *sig );
 void release_pk_list( PK_LIST pk_list );
@@ -128,8 +130,8 @@ unsigned nbits_from_sk( PKT_secret_key *sk );
 const char *datestr_from_pk( PKT_public_key *pk );
 const char *datestr_from_sk( PKT_secret_key *sk );
 const char *datestr_from_sig( PKT_signature *sig );
-byte *fingerprint_from_sk( PKT_secret_key *sk, size_t *ret_len );
-byte *fingerprint_from_pk( PKT_public_key *pk, size_t *ret_len );
+byte *fingerprint_from_sk( PKT_secret_key *sk, byte *buf. size_t *ret_len );
+byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
 
 /*-- kbnode.c --*/
 KBNODE new_kbnode( PACKET *pkt );
index ee50a78..4369e9a 100644 (file)
@@ -45,7 +45,7 @@ show_fingerprint( PKT_public_key *pk )
     byte *array, *p;
     size_t i, n;
 
-    p = array = fingerprint_from_pk( pk, &n );
+    p = array = fingerprint_from_pk( pk, NULL, &n );
     tty_printf("             Fingerprint:");
     if( n == 20 ) {
        for(i=0; i < n ; i++, i++, p += 2 ) {
@@ -292,7 +292,7 @@ sign_key( const char *username, STRLIST locusr )
        if( !opt.batch ) {
            /* ask whether we really should do anything */
            answer = tty_get(
-                       _("To you want to remove some of the invalid sigs? "));
+               _("Do you want to remove some of the invalid signatures? "));
            tty_kill_prompt();
            if( answer_is_yes(answer) )
                remove_keysigs( keyblock, pk_keyid, 0 );
index d9f8579..b114b84 100644 (file)
@@ -442,9 +442,9 @@ ask_keysize( int algo )
        else if( nbits < 768 )
            tty_printf(_("keysize too small; 768 is smallest value allowed.\n"));
        else if( nbits > 2048 ) {
-           tty_printf(_("Keysizes larger than 2048 are not suggested, because "
+           tty_printf(_("Keysizes larger than 2048 are not suggested because "
                         "computations take REALLY long!\n"));
-           answer = tty_get(_("Are you sure, that you want this keysize? "));
+           answer = tty_get(_("Are you sure that you want this keysize? "));
            tty_kill_prompt();
            if( answer_is_yes(answer) ) {
                m_free(answer);
@@ -685,7 +685,7 @@ ask_passphrase( STRING2KEY **ret_s2k )
            tty_printf(_(
            "You don't want a passphrase - this is probably a *bad* idea!\n"
            "I will do it anyway.  You can change your passphrase at any time,\n"
-           "using this program with the option \"--change-passphrase\"\n\n"));
+           "using this program with the option \"--change-passphrase\".\n\n"));
            break;
        }
        else
index 0809df9..2e5c6aa 100644 (file)
@@ -262,13 +262,13 @@ datestr_from_sig( PKT_signature *sig )
 /**************** .
  * Return a byte array with the fingerprint for the given PK/SK
  * The length of the array is returned in ret_len. Caller must free
- * the array.
+ * the array or provide array as buffer of length MAX_FINGERPRINT_LEN
  */
 
 byte *
-fingerprint_from_pk( PKT_public_key *pk, size_t *ret_len )
+fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
 {
-    byte *p, *buf, *array;
+    byte *p, *buf;
     const char *dp;
     size_t len;
     unsigned n;
@@ -287,7 +287,8 @@ fingerprint_from_pk( PKT_public_key *pk, size_t *ret_len )
            m_free(buf);
        }
        md_final(md);
-       array = m_alloc( 16 );
+       if( !array )
+           array = m_alloc( 16 );
        len = 16;
        memcpy(array, md_read(md, DIGEST_ALGO_MD5), 16 );
        md_close(md);
@@ -297,7 +298,9 @@ fingerprint_from_pk( PKT_public_key *pk, size_t *ret_len )
        md = do_fingerprint_md(pk);
        dp = md_read( md, 0 );
        len = md_digest_length( md_get_algo( md ) );
-       array = m_alloc( len );
+       assert( len <= MAX_FINGERPRINT_LEN );
+       if( !array )
+           array = m_alloc( len );
        memcpy(array, dp, len );
        md_close(md);
     }
@@ -307,9 +310,9 @@ fingerprint_from_pk( PKT_public_key *pk, size_t *ret_len )
 }
 
 byte *
-fingerprint_from_sk( PKT_secret_key *sk, size_t *ret_len )
+fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len )
 {
-    byte *p, *buf, *array;
+    byte *p, *buf;
     const char *dp;
     size_t len;
     unsigned n;
@@ -328,7 +331,8 @@ fingerprint_from_sk( PKT_secret_key *sk, size_t *ret_len )
            m_free(buf);
        }
        md_final(md);
-       array = m_alloc( 16 );
+       if( !array )
+           array = m_alloc( 16 );
        len = 16;
        memcpy(array, md_read(md, DIGEST_ALGO_MD5), 16 );
        md_close(md);
@@ -338,7 +342,9 @@ fingerprint_from_sk( PKT_secret_key *sk, size_t *ret_len )
        md = do_fingerprint_md_sk(sk);
        dp = md_read( md, 0 );
        len = md_digest_length( md_get_algo( md ) );
-       array = m_alloc( len );
+       assert( len <= MAX_FINGERPRINT_LEN );
+       if( !array )
+           array = m_alloc( len );
        memcpy(array, dp, len );
        md_close(md);
     }
index f06b498..d23a98f 100644 (file)
@@ -339,8 +339,8 @@ fingerprint( PKT_public_key *pk, PKT_secret_key *sk )
     byte *array, *p;
     size_t i, n;
 
-    p = array = pk? fingerprint_from_pk( pk, &n )
-                  : fingerprint_from_sk( sk, &n );
+    p = array = pk? fingerprint_from_pk( pk, NULL, &n )
+                  : fingerprint_from_sk( sk, NULL, &n );
     if( opt.with_colons ) {
        printf("fpr:::::::::");
        for(i=0; i < n ; i++, p++ )
index dcba048..fdb0134 100644 (file)
@@ -47,6 +47,7 @@ void do_not_use_RSA(void);
 
 /*-- misc.c --*/
 void trap_unaligned(void);
+void disable_core_dumps(void);
 u16 checksum_u16( unsigned n );
 u16 checksum( byte *p, unsigned n );
 u16 checksum_mpi( MPI a );
@@ -119,7 +120,8 @@ int verify_signatures( int nfiles, char **files );
 int decrypt_message( const char *filename );
 
 /*-- plaintext.c --*/
-int hash_datafiles( MD_HANDLE md, STRLIST files, int textmode );
+int hash_datafiles( MD_HANDLE md, STRLIST files, const char *sigfilename,
+                   int textmode );
 
 /*-- signal.c --*/
 void init_signals(void);
index 9090fd4..cd3e85a 100644 (file)
@@ -51,6 +51,7 @@ typedef struct {
     int sigs_only;   /* process only signatures and reject all other stuff */
     int encrypt_only; /* process only encrytion messages */
     STRLIST signed_data;
+    const char *sigfilename;
     DEK *dek;
     int last_was_session_key;
     KBNODE list;   /* the current list of packets */
@@ -262,7 +263,7 @@ proc_plaintext( CTX c, PACKET *pkt )
                clearsig = 1;
        }
     }
-    if( !any ) { /* no onepass sig packet: enable all algos */
+    if( !any ) { /* no onepass sig packet: enable all standard algos */
        md_enable( c->mfx.md, DIGEST_ALGO_RMD160 );
        md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
        md_enable( c->mfx.md, DIGEST_ALGO_MD5 );
@@ -273,13 +274,13 @@ proc_plaintext( CTX c, PACKET *pkt )
            m_check( c->mfx.md->list );
     }
     rc = handle_plaintext( pt, &c->mfx, c->sigs_only, clearsig );
+    if( rc == G10ERR_CREATE_FILE && !c->sigs_only) {
+       /* can't write output but we hash it anyway to
+        * check the signature */
+       rc = handle_plaintext( pt, &c->mfx, 1, clearsig );
+    }
     if( rc )
        log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
-    if( c->mfx.md ) {
-       m_check(c->mfx.md);
-       if( c->mfx.md->list )
-           m_check( c->mfx.md->list );
-    }
     free_packet(pkt);
     c->last_was_session_key = 0;
 }
@@ -288,7 +289,8 @@ proc_plaintext( CTX c, PACKET *pkt )
 static int
 proc_compressed_cb( IOBUF a, void *info )
 {
-    return proc_signature_packets( a, ((CTX)info)->signed_data );
+    return proc_signature_packets( a, ((CTX)info)->signed_data,
+                                     ((CTX)info)->sigfilename );
 }
 
 static int
@@ -405,8 +407,8 @@ print_fingerprint( PKT_public_key *pk, PKT_secret_key *sk )
     byte *array, *p;
     size_t i, n;
 
-    p = array = sk? fingerprint_from_sk( sk, &n )
-                  : fingerprint_from_pk( pk, &n );
+    p = array = sk? fingerprint_from_sk( sk, NULL, &n )
+                  : fingerprint_from_pk( pk, NULL, &n );
     if( opt.with_colons ) {
        printf("fpr:::::::::");
        for(i=0; i < n ; i++, p++ )
@@ -665,12 +667,13 @@ proc_packets( IOBUF a )
 }
 
 int
-proc_signature_packets( IOBUF a, STRLIST signedfiles )
+proc_signature_packets( IOBUF a, STRLIST signedfiles, const char *sigfilename )
 {
     CTX c = m_alloc_clear( sizeof *c );
     int rc;
     c->sigs_only = 1;
     c->signed_data = signedfiles;
+    c->sigfilename = sigfilename;
     rc = do_proc_packets( c, a );
     m_free( c );
     return rc;
@@ -881,7 +884,7 @@ proc_tree( CTX c, KBNODE node )
            }
            /* ask for file and hash it */
            if( c->sigs_only )
-               rc = hash_datafiles( c->mfx.md, c->signed_data,
+               rc = hash_datafiles( c->mfx.md, c->signed_data, c->sigfilename,
                            n1->pkt->pkt.onepass_sig->sig_class == 0x01 );
            else
                rc = ask_for_detached_datafile( &c->mfx,
@@ -902,7 +905,7 @@ proc_tree( CTX c, KBNODE node )
            free_md_filter_context( &c->mfx );
            c->mfx.md = md_open(sig->digest_algo, 0);
            if( c->sigs_only )
-               rc = hash_datafiles( c->mfx.md, c->signed_data,
+               rc = hash_datafiles( c->mfx.md, c->signed_data, c->sigfilename,
                                     sig->sig_class == 0x01 );
            else
                rc = ask_for_detached_datafile( &c->mfx,
index 4703073..ec7c40a 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 #if defined(__linux__) && defined(__alpha__)
   #include <asm/sysinfo.h>
   #include <asm/unistd.h>
 #endif
+#ifdef HAVE_SETRLIMIT
+  #include <sys/time.h>
+  #include <sys/resource.h>
+#endif
 #include "util.h"
 #include "main.h"
 #include "options.h"
@@ -70,6 +75,23 @@ trap_unaligned(void)
 #endif
 
 
+void
+disable_core_dumps()
+{
+  #ifdef HAVE_SETRLIMIT
+    struct rlimit limit;
+
+    limit.rlim_cur = 0;
+    limit.rlim_max = 0;
+    if( setrlimit( RLIMIT_CORE, &limit ) )
+       log_fatal("can't disable core dumps: %s\n", strerror(errno) );
+  #else
+    log_info("WARNING: Program may create a core file!\n");
+  #endif
+}
+
+
+
 u16
 checksum_u16( unsigned n )
 {
index be2702b..afa36b9 100644 (file)
@@ -142,6 +142,8 @@ open_sigfile( const char *iname )
            buf = m_strdup(iname);
            buf[len-4] = 0 ;
            a = iobuf_open( buf );
+           if( opt.verbose )
+               log_info("assuming signed data in '%s'\n", buf );
            m_free(buf);
        }
     }
index 0929be3..80a6539 100644 (file)
@@ -47,6 +47,7 @@ struct {
     const char *homedir;
     int skip_verify;
     int compress_keys;
+    int compress_sigs;
     int always_trust;
     int rfc1991;
     unsigned emulate_bugs; /* bug emulation flags */
index 0cefd8d..cef9afe 100644 (file)
@@ -222,7 +222,7 @@ typedef enum {
 
 /*-- mainproc.c --*/
 int proc_packets( IOBUF a );
-int proc_signature_packets( IOBUF a, STRLIST signedfiles );
+int proc_signature_packets( IOBUF a, STRLIST signedfiles, const char *sigfile );
 int proc_encryption_packets( IOBUF a );
 int list_packets( IOBUF a );
 
index 81e23c7..e509f00 100644 (file)
@@ -63,7 +63,7 @@ query_ownertrust( ulong lid )
        return 0;
     }
 
-    tty_printf(_("No ownertrust defined for %lu:\n"
+    tty_printf(_("No owner trust defined for %lu:\n"
               "%4u%c/%08lX %s \""), lid,
              nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
              (ulong)keyid[1], datestr_from_pk( pk ) );
@@ -143,7 +143,7 @@ _("Could not find a valid trust path to the key.  Let's see whether we\n"
     while( !(rc=enum_trust_web( &context, &lid )) ) {
        rc = get_ownertrust( lid, &trust );
        if( rc )
-           log_fatal("Ooops: couldn't get ownertrust for %lu\n", lid);
+           log_fatal("Ooops: couldn't get owner trust for %lu\n", lid);
        if( trust == TRUST_UNDEFINED || trust == TRUST_EXPIRED ||
            trust == TRUST_UNKNOWN ) {
            if( query_ownertrust( lid ) )
@@ -155,7 +155,7 @@ _("Could not find a valid trust path to the key.  Let's see whether we\n"
     enum_trust_web( &context, NULL ); /* close */
 
     if( !any )
-       tty_printf(_("No ownertrust values changed.\n\n") );
+       tty_printf(_("No owner trust values changed.\n\n") );
 
     return rc? rc : any? 0:-1;
 }
@@ -366,7 +366,7 @@ check_signatures_trust( PKT_signature *sig )
       case TRUST_MARGINAL:
        write_status( STATUS_TRUST_MARGINAL );
        log_info(_(
-        "WARNING: This key is not certified with enough trusted signatures!\n"
+        "WARNING: This key is not certified with sufficiently trusted signatures!\n"
                ));
        log_info(_(
         "         It is not certain that the signature belongs to the owner.\n"
index 8d7b2a9..1a22ecd 100644 (file)
@@ -109,14 +109,17 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
        /* no filename or "-" given; write to stdout */
        fp = stdout;
     }
-    else if( overwrite_filep( fname ) )
+    else if( (rc=overwrite_filep( fname )) ) {
+       if( rc == -1 )
+           rc = G10ERR_CREATE_FILE;
        goto leave;
+    }
 
     if( fp || nooutput )
        ;
     else if( !(fp = fopen(fname,"wb")) ) {
        log_error("Error creating '%s': %s\n", fname, strerror(errno) );
-       rc = G10ERR_WRITE_FILE;
+       rc = G10ERR_CREATE_FILE;
        goto leave;
     }
 
@@ -245,20 +248,43 @@ ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname )
 }
 
 
+static void
+do_hash( MD_HANDLE md, IOBUF fp, int textmode )
+{
+    text_filter_context_t tfx;
+    int c;
+
+    if( textmode ) {
+       memset( &tfx, 0, sizeof tfx);
+       iobuf_push_filter( fp, text_filter, &tfx );
+    }
+    while( (c = iobuf_get(fp)) != -1 )
+       md_putc(md, c );
+}
+
+
 /****************
  * Hash the given files and append the hash to hash context md.
  * If FILES is NULL, hash stdin.
  */
 int
-hash_datafiles( MD_HANDLE md, STRLIST files, int textmode )
+hash_datafiles( MD_HANDLE md, STRLIST files,
+               const char *sigfilename, int textmode )
 {
     IOBUF fp;
     STRLIST sl=NULL;
-    text_filter_context_t tfx;
-    int c;
 
-    if( !files )
+    if( !files ) {
+       /* check whether we can opne the signed material */
+       fp = open_sigfile( sigfilename );
+       if( fp ) {
+           do_hash( md, fp, textmode );
+           iobuf_close(fp);
+           return 0;
+       }
+       /* no we can't (no sigfile) - read signed stuff from stdin */
        add_to_strlist( &sl, "-");
+    }
     else
        sl = files;
 
@@ -271,12 +297,7 @@ hash_datafiles( MD_HANDLE md, STRLIST files, int textmode )
                free_strlist(sl);
            return G10ERR_OPEN_FILE;
        }
-       if( textmode ) {
-           memset( &tfx, 0, sizeof tfx);
-           iobuf_push_filter( fp, text_filter, &tfx );
-       }
-       while( (c = iobuf_get(fp)) != -1 )
-           md_putc(md, c );
+       do_hash( md, fp, textmode );
        iobuf_close(fp);
     }
 
index 5b271a2..6e76d12 100644 (file)
@@ -86,6 +86,7 @@ encode_session_key( DEK *dek, unsigned nbits )
     frame[n++] = 2;
     i = nframe - 6 - dek->keylen;
     assert( i > 0 );
+    /* FIXME: replace the loop by a call to get_random_bits() */
     for( ; i ; i-- ) {
        while( !(c = get_random_byte(1)) )
            ;
index 14dfe41..6192d59 100644 (file)
@@ -226,7 +226,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
        iobuf_push_filter( out, encrypt_filter, &efx );
     }
 
-    if( opt.compress && !outfile ) {
+    if( opt.compress && !outfile && ( !detached || opt.compress_sigs) ) {
        if( old_style )
            zfx.algo = 1;
        iobuf_push_filter( out, compress_filter, &zfx );
index d3b9a72..425e51c 100644 (file)
@@ -147,7 +147,7 @@ create_db( const char *fname )
     fp =fopen( fname, "w" );
     if( !fp )
        log_fatal_f( fname, _("can't create %s: %s\n"), strerror(errno) );
-    fwrite_8( fp, 1 );
+    fwrite_8( fp, 2 );
     fwrite_8( fp, 'g' );
     fwrite_8( fp, 'p' );
     fwrite_8( fp, 'g' );
@@ -195,55 +195,67 @@ tdbio_dump_record( ulong rnum, TRUSTREC *rec, FILE *fp    )
       case RECTYPE_VER: fprintf(fp, "version\n");
        break;
       case RECTYPE_DIR:
-       fprintf(fp, "dir keyid=%08lX, key=%lu, ctl=%lu, sig=%lu",
-                   (ulong)rec->r.dir.keyid[1],
-                   rec->r.dir.keyrec, rec->r.dir.ctlrec, rec->r.dir.sigrec );
-       if( rec->r.dir.no_sigs == 1 )
+       fprintf(fp, "dir %lu, keys=%lu, uids=%lu, cach=%lu, ot=%02x",
+                   rec->r.dir.lid,
+                   rec->r.dir.keylist,
+                   rec->r.dir.uidlist,
+                   rec->r.dir.cacherec,
+                   rec->r.dir.ownertrust );
+       if( rec->r.dir.sigflag == 1 )
            fputs(", (none)", fp );
-       else if( rec->r.dir.no_sigs == 2 )
+       else if( rec->r.dir.sigflag == 2 )
            fputs(", (invalid)", fp );
-       else if( rec->r.dir.no_sigs == 3 )
+       else if( rec->r.dir.sigflag == 3 )
            fputs(", (revoked)", fp );
-       else if( rec->r.dir.no_sigs )
+       else if( rec->r.dir.sigflag )
            fputs(", (??)", fp );
        putc('\n', fp);
        break;
-      case RECTYPE_KEY: fprintf(fp,
-                   "key %08lX, own=%lu, ownertrust=%02x, fl=%d\n",
-                  (ulong)rec->r.key.keyid[1],
-                  rec->r.key.owner, rec->r.key.ownertrust,
+      case RECTYPE_KEY:
+       fprintf(fp, "key %lu, next=%lu, algo=%d, flen=%d\n",
+                  rec->r.key.lid,
+                  rec->r.key.next,
+                  rec->r.key.pubkey_algo,
                   rec->r.key.fingerprint_len );
        break;
       case RECTYPE_UID:
-       if( !rec->r.uid.subtype )
-           fprintf(fp,
-                   "uid %02x%02x, owner=%lu, chain=%lu, pref=%lu, otr=%02x\n",
-                  rec->r.uid.namehash[18], rec->r.uid.namehash[19],
-                  rec->r.uid.owner, rec->r.uid.chain, (ulong)rec->r.uid.prefrec,
-                  rec->r.uid.ownertrust );
-       else
-           fprintf(fp,
-                   "uid subtype%d, owner=%lu, chain=%lu\n",
-                  rec->r.uid.subtype, rec->r.uid.owner, rec->r.uid.chain);
+       fprintf(fp, "uid %lu, next=%lu, pref=%lu, sig=%lu, hash=%02X%02X\n",
+                   rec->r.uid.lid,
+                   rec->r.uid.next,
+                   rec->r.uid.prefrec,
+                   rec->r.uid.siglist,
+                   rec->r.uid.namehash[18], rec->r.uid.namehash[19]);
        break;
-      case RECTYPE_CTL: fprintf(fp, "ctl\n");
+      case RECTYPE_PREF:
+       fprintf(fp, "pref %lu, next=%lu\n",
+                   rec->r.uid.lid,
+                   rec->r.uid.next);
        break;
       case RECTYPE_SIG:
-       fprintf(fp, "sigrec, owner=%lu, chain=%lu\n",
-                        rec->r.sig.owner, rec->r.sig.chain );
+       fprintf(fp, "sig %lu, next=%lu\n",
+                        rec->r.sig.lid, rec->r.sig.next );
        for(i=any=0; i < SIGS_PER_RECORD; i++ ) {
-           if( rec->r.sig.sig[i].local_id ) {
+           if( rec->r.sig.sig[i].lid ) {
                if( !any ) {
                    putc('\t', fp);
                    any++;
                }
-               fprintf(fp, "  %lu:%02x", rec->r.sig.sig[i].local_id,
-                                             rec->r.sig.sig[i].flag );
+               fprintf(fp, "  %lu:%02x", rec->r.sig.sig[i].lid,
+                                         rec->r.sig.sig[i].flag );
            }
        }
        if( any )
            putc('\n', fp);
        break;
+      case RECTYPE_CACH:
+       fprintf(fp, "cach\n");
+       break;
+      case RECTYPE_HTBL:
+       fprintf(fp, "htbl\n");
+       break;
+      case RECTYPE_HTBL:
+       fprintf(fp, "hlst\n");
+       break;
       default:
        fprintf(fp, "%d (unknown)\n", rec->rectype );
        break;
@@ -287,8 +299,7 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
       case 0:  /* unused record */
        break;
       case RECTYPE_VER: /* version record */
-       /* g10 was the original name */
-       if( memcmp(buf+1, "gpg", 3 ) && memcmp(buf+1, "g10", 3 ) ) {
+       if( memcmp(buf+1, "gpg", 3 ) ) {
            log_error_f( db_name, _("not a trustdb file\n") );
            rc = G10ERR_TRUSTDB;
        }
@@ -306,51 +317,60 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
                                                             (ulong)recnum );
            rc = G10ERR_TRUSTDB;
        }
-       if( rec->r.ver.version != 1 ) {
+       if( rec->r.ver.version != 2 ) {
            log_error_f( db_name, "invalid file version %d\n",
                                                        rec->r.ver.version );
            rc = G10ERR_TRUSTDB;
        }
        break;
       case RECTYPE_DIR:   /*directory record */
-       rec->r.dir.local_id = buftoulong(p); p += 4;
-       rec->r.dir.keyid[0] = buftou32(p); p += 4;
-       rec->r.dir.keyid[1] = buftou32(p); p += 4;
-       rec->r.dir.keyrec   = buftoulong(p); p += 4;
-       rec->r.dir.ctlrec   = buftoulong(p); p += 4;
-       rec->r.dir.sigrec   = buftoulong(p); p += 4;
-       rec->r.dir.no_sigs = *p++;
-       if( rec->r.dir.local_id != recnum ) {
-           log_error_f( db_name, "dir local_id != recnum (%lu,%lu)\n",
-                                       (ulong)rec->r.dir.local_id,
-                                       (ulong)recnum );
+       rec->r.dir.lid      = buftoulong(p); p += 4;
+       rec->r.dir.keylist  = buftoulong(p); p += 4;
+       rec->r.dir.uidlist  = buftoulong(p); p += 4;
+       rec->r.dir.cacherec = buftoulong(p); p += 4;
+       rec->r.dir.ownertrust = *p++;
+       rec->r.dir.sigflag    = *p++;
+       if( rec->r.dir.lid != recnum ) {
+           log_error_f( db_name, "dir LID != recnum (%lu,%lu)\n",
+                                        rec->r.dir.lid, (ulong)recnum );
            rc = G10ERR_TRUSTDB;
        }
        break;
       case RECTYPE_KEY:   /* public key record */
-       rec->r.key.owner    = buftoulong(p); p += 4;
-       rec->r.dir.keyid[0] = buftou32(p); p += 4;
-       rec->r.dir.keyid[1] = buftou32(p); p += 4;
+       rec->r.key.lid      = buftoulong(p); p += 4;
+       rec->r.key.next     = buftoulong(p); p += 4;
+       p += 8;
        rec->r.key.pubkey_algo = *p++;
        rec->r.key.fingerprint_len = *p++;
        if( rec->r.key.fingerprint_len < 1 || rec->r.key.fingerprint_len > 20 )
            rec->r.key.fingerprint_len = 20;
-       memcpy( rec->r.key.fingerprint, p, 20); p += 20;
-       rec->r.key.ownertrust = *p++;
+       memcpy( rec->r.key.fingerprint, p, 20);
        break;
-      case RECTYPE_CTL:   /* control record */
-       rec->r.ctl.owner    = buftoulong(p); p += 4;
-       memcpy(rec->r.ctl.blockhash, p, 20); p += 20;
-       rec->r.ctl.trustlevel = *p++;
+      case RECTYPE_UID:   /* user id record */
+       rec->r.uid.lid      = buftoulong(p); p += 4;
+       rec->r.uid.next     = buftoulong(p); p += 4;
+       rec->r.uid.prefrec  = buftoulong(p); p += 4;
+       rec->r.uid.siglist  = buftoulong(p); p += 4;
+       p += 2;
+       memcpy( rec->r.uid.namehash, p, 20);
+       break;
+      case RECTYPE_PREF:  /* preference record */
+       rec->r.pref.lid     = buftoulong(p); p += 4;
+       rec->r.pref.next    = buftoulong(p); p += 4;
        break;
       case RECTYPE_SIG:
-       rec->r.sig.owner   = buftoulong(p); p += 4;
-       rec->r.sig.chain   = buftoulong(p); p += 4;
+       rec->r.sig.lid     = buftoulong(p); p += 4;
+       rec->r.sig.next    = buftoulong(p); p += 4;
        for(i=0; i < SIGS_PER_RECORD; i++ ) {
-           rec->r.sig.sig[i].local_id = buftoulong(p); p += 4;
+           rec->r.sig.sig[i].lid  = buftoulong(p); p += 4;
            rec->r.sig.sig[i].flag = *p++;
        }
        break;
+      case RECTYPE_CACH:   /* cache record (FIXME)*/
+       rec->r.cache.lid    = buftoulong(p); p += 4;
+       memcpy(rec->r.cache.blockhash, p, 20); p += 20;
+       rec->r.cache.trustlevel = *p++;
+       break;
       default:
        log_error_f( db_name, "invalid record type %d at recnum %lu\n",
                                              rec->rectype, (ulong)recnum );
@@ -385,40 +405,53 @@ tdbio_write_record( ulong recnum, TRUSTREC *rec )
        break;
 
       case RECTYPE_DIR:   /*directory record */
-       ulongtobuf(p, rec->r.dir.local_id); p += 4;
-       u32tobuf(p, rec->r.key.keyid[0]); p += 4;
-       u32tobuf(p, rec->r.key.keyid[1]); p += 4;
-       ulongtobuf(p, rec->r.dir.keyrec); p += 4;
-       ulongtobuf(p, rec->r.dir.ctlrec); p += 4;
-       ulongtobuf(p, rec->r.dir.sigrec); p += 4;
-       *p++ = rec->r.dir.no_sigs;
-       assert( rec->r.dir.local_id == recnum );
+       ulongtobuf(p, rec->r.dir.lid); p += 4;
+       ulongtobuf(p, rec->r.dir.keylist); p += 4;
+       ulongtobuf(p, rec->r.dir.uidlist); p += 4;
+       ulongtobuf(p, rec->r.dir.cacherec); p += 4;
+       *p++ = rec->r.dir.ownertrust;
+       *p++ = rec->r.dir.sigflag;
+       assert( rec->r.dir.lid == recnum );
        break;
 
       case RECTYPE_KEY:
-       ulongtobuf(p, rec->r.key.owner); p += 4;
-       u32tobuf(p, rec->r.key.keyid[0]); p += 4;
-       u32tobuf(p, rec->r.key.keyid[1]); p += 4;
+       ulongtobuf(p, rec->r.key.lid); p += 4;
+       ulongtobuf(p, rec->r.key.next); p += 4;
+       p += 8;
        *p++ = rec->r.key.pubkey_algo;
        *p++ = rec->r.key.fingerprint_len;
        memcpy( p, rec->r.key.fingerprint, 20); p += 20;
-       *p++ = rec->r.key.ownertrust;
        break;
 
-      case RECTYPE_CTL:   /* control record */
-       ulongtobuf(p, rec->r.ctl.owner); p += 4;
-       memcpy(p, rec->r.ctl.blockhash, 20); p += 20;
-       *p++ = rec->r.ctl.trustlevel;
+      case RECTYPE_UID:   /* user id record */
+       ulongtobuf(p, rec->r.uid.lid); p += 4;
+       ulongtobuf(p, rec->r.uid.next); p += 4;
+       ulongtobuf(p, rec->r.uid.prefrec); p += 4;
+       ulongtobuf(p, rec->r.uid.siglist); p += 4;
+       p += 2;
+       memcpy( p, rec->r.uid.namehash, 20 ); p += 20;
+       break;
+
+      case RECTYPE_PREF:
+       ulongtobuf(p, rec->r.pref.lid); p += 4;
+       ulongtobuf(p, rec->r.pref.next); p += 4;
        break;
 
       case RECTYPE_SIG:
-       ulongtobuf(p, rec->r.sig.owner); p += 4;
-       ulongtobuf(p, rec->r.sig.chain); p += 4;
+       ulongtobuf(p, rec->r.sig.lid); p += 4;
+       ulongtobuf(p, rec->r.sig.next); p += 4;
        for(i=0; i < SIGS_PER_RECORD; i++ ) {
-           ulongtobuf(p, rec->r.sig.sig[i].local_id); p += 4;
+           ulongtobuf(p, rec->r.sig.sig[i].lid); p += 4;
            *p++ = rec->r.sig.sig[i].flag;
        }
        break;
+
+      case RECTYPE_CACH:   /* FIXME*/
+       ulongtobuf(p, rec->r.cache.lid); p += 4;
+       memcpy(p, rec->r.cache.blockhash, 20); p += 20;
+       *p++ = rec->r.cache.trustlevel;
+       break;
+
       default:
        BUG();
     }
@@ -475,7 +508,7 @@ tdbio_new_recnum()
  * Note: To increase performance, we could use a index search here.
  */
 int
-tdbio_search_record( PKT_public_key *pk, TRUSTREC *rec )
+tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec )
 {
     ulong recnum;
     u32 keyid[2];
@@ -484,30 +517,26 @@ tdbio_search_record( PKT_public_key *pk, TRUSTREC *rec )
     int rc;
 
     keyid_from_pk( pk, keyid );
-    fingerprint = fingerprint_from_pk( pk, &fingerlen );
+    fingerprint = fingerprint_from_pk( pk, NULL, &fingerlen );
     assert( fingerlen == 20 || fingerlen == 16 );
 
     for(recnum=1; !(rc=tdbio_read_record( recnum, rec, 0)); recnum++ ) {
-       if( rec->rectype != RECTYPE_DIR )
+       if( rec->rectype != RECTYPE_KEY )
            continue;
-       if( rec->r.dir.keyid[0] == keyid[0]
-           && rec->r.dir.keyid[1] == keyid[1]){
-           TRUSTREC keyrec;
-
-           if( tdbio_read_record( rec->r.dir.keyrec, &keyrec, RECTYPE_KEY ) ) {
-               log_error("%lu: ooops: invalid key record\n", recnum );
+       if( rec->r.key.pubkey_algo == pk->pubkey_algo
+           && !memcmp(rec->r.key.fingerprint, fingerprint, fingerlen) ) {
+           /* found: read the dir record for this key */
+           rc = tdbio_read_record( rec->r.key.lid, rec, RECTYPE_DIR);
+           if( rc )
                break;
-           }
-           if( keyrec.r.key.pubkey_algo == pk->pubkey_algo
-               && !memcmp(keyrec.r.key.fingerprint, fingerprint, fingerlen) ){
-               if( pk->local_id && pk->local_id != recnum )
-                   log_error_f(db_name,
-                              "found record, but local_id from memory does "
-                              "not match recnum (%lu,%lu)\n",
-                                    (ulong)pk->local_id, (ulong)recnum );
-               pk->local_id = recnum;
-               return 0;
-           }
+
+           if( pk->local_id && pk->local_id != recnum )
+               log_error_f(db_name,
+                          "found record, but LID from memory does "
+                          "not match recnum (%lu,%lu)\n",
+                                               pk->local_id, recnum );
+           pk->local_id = recnum;
+           return 0;
        }
     }
     if( rc != -1 )
@@ -516,3 +545,22 @@ tdbio_search_record( PKT_public_key *pk, TRUSTREC *rec )
 }
 
 
+int
+tdbio_update_sigflag( ulong lid, int sigflag )
+{
+    TRUSTREC rec;
+
+    if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
+       log_error("update_sigflag: read failed\n");
+       return G10ERR_TRUSTDB;
+    }
+
+    rec.r.dir.sigflag = sigflag;
+    if( tdbio_write_record( lid, &rec ) ) {
+       log_error("update_sigflag: write failed\n");
+       return G10ERR_TRUSTDB;
+    }
+
+    return 0;
+}
+
index facb5c3..7229d72 100644 (file)
 #define RECTYPE_VER  1
 #define RECTYPE_DIR  2
 #define RECTYPE_KEY  3
-#define RECTYPE_CTL  4
-#define RECTYPE_SIG  5
-#define RECTYPE_HTBL 6
-#define RECTYPE_HLST 7
-#define RECTYPE_UID  8
+#define RECTYPE_UID  4
+#define RECTYPE_PREF 5
+#define RECTYPE_SIG  6
+#define RECTYPE_CACH 9
+#define RECTYPE_HTBL 10
+#define RECTYPE_HLST 11
 
 
 struct trust_record {
     int  rectype;
+    struct trust_record *next;
     union {
        struct {            /* version record: */
            byte version;   /* should be 1 */
@@ -53,49 +55,50 @@ struct trust_record {
            byte max_cert_depth;
        } ver;
        struct {            /* directory record */
-           ulong local_id;
-           u32  keyid[2];
-           ulong keyrec;   /* recno of primary public key record */
-           ulong ctlrec;   /* recno of control record */
-           ulong sigrec;   /* recno of first signature record (osolete) */
-           ulong uidrec;   /* recno of first user-id record */
-           ulong link;     /* to next dir record */
-           byte no_sigs;   /* does not have sigature and checked */
+           ulong lid;
+           ulong keylist;  /* List of keys (the first is the primary key)*/
+           ulong uidlist;  /* list of uid records */
+           ulong cacherec; /* the cache record */
+           byte ownertrust;
+           byte sigflag;
        } dir;
        struct {            /* primary public key record */
-           ulong owner;
-           u32  keyid[2];
+           ulong lid;
+           ulong next;    /* next key */
            byte pubkey_algo;
            byte fingerprint_len;
            byte fingerprint[20];
-           byte ownertrust;
        } key;
        struct {            /* user id reord */
-           ulong owner;    /* point back to the directory record */
-           ulong chain;    /* points to next user id record */
-           byte  subtype;  /* must be 0 */
-           byte  namehash[20]; /* ripemd hash of the username */
-           byte ownertrust;
-           u32  prefrec;   /* recno of reference record */
+           ulong lid;      /* point back to the directory record */
+           ulong next;    /* points to next user id record */
+           ulong prefrec;   /* recno of reference record */
+           ulong siglist;   /* list of valid signatures (w/o self-sig)*/
+           byte namehash[20]; /* ripemd hash of the username */
        } uid;
-       struct {            /* control record */
-           ulong owner;
-           byte blockhash[20];
-           byte trustlevel;   /* calculated trustlevel */
-       } ctl;
+       struct {            /* preference reord */
+           ulong lid;      /* point back to the directory record */
+                           /* or 0 for a glocal pref record */
+           ulong next;    /* points to next pref record */
+       } pref;
        struct {            /* signature record */
-           ulong owner;  /* local_id of record owner (pubkey record) */
-           ulong chain;  /* offset of next record or NULL for last one */
+           ulong lid;
+           ulong next;   /* recnno of next record or NULL for last one */
            struct {
-               ulong  local_id; /* of pubkey record of signator (0=unused) */
-               byte flag;     /* reserved */
+               ulong lid;       /* of pubkey record of signator (0=unused) */
+               byte flag;       /* reserved */
            } sig[SIGS_PER_RECORD];
        } sig;
+       struct {            /* cache record */
+           ulong lid;
+           byte blockhash[20];
+           byte trustlevel;   /* calculated trustlevel */
+       } cache;
        struct {
            ulong item[ITEMS_PER_HTBL_RECORD];
        } htbl;
        struct {
-           ulong chain;
+           ulong next;
            struct {
                byte hash;
                ulong rnum;
@@ -126,7 +129,8 @@ void tdbio_dump_record( ulong rnum, TRUSTREC *rec, FILE *fp );
 int tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected );
 int tdbio_write_record( ulong recnum, TRUSTREC *rec );
 ulong tdbio_new_recnum(void);
-int tdbio_search_record( PKT_public_key *pk, TRUSTREC *rec );
+int tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec );
+int tdbio_update_sigflag( ulong lid, int sigflag );
 
 
 #define buftoulong( p )  ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
index 916eeff..593e12c 100644 (file)
 #include "tdbio.h"
 
 
+#if MAX_FINGERPRINT_LEN > 20
+  #error Must change structure of trustdb
+#endif
+
 typedef struct local_id_info *LOCAL_ID_INFO;
 struct local_id_info {
     LOCAL_ID_INFO next;
@@ -85,11 +89,10 @@ static int do_list_path( TRUST_INFO *stack, int depth, int max_depth,
                         LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist );
 
 static int list_sigs( ulong pubkey_id );
-static int build_sigrecs( ulong pubkeyid );
+static int build_sigrecs( ulong local_id );
 static int propagate_trust( TRUST_SEG_LIST tslist );
-static int do_check( ulong pubkeyid, TRUSTREC *drec, unsigned *trustlevel );
+static int do_check( TRUSTREC *drec, unsigned *trustlevel );
 
-static int update_no_sigs( ulong lid, int no_sigs );
 
 /* a table used to keep track of ultimately trusted keys
  * which are the ones from our secrings */
@@ -186,12 +189,11 @@ set_signature_packets_local_id( PKT_signature *sig )
     if( rc)
        goto leave;
     if( !pk->local_id ) {
-       rc = tdbio_search_record( pk, &rec );
+       rc = tdbio_search_dir_record( pk, &rec );
        if( rc == -1 )
            rc = insert_trust_record( pk );
        if( rc )
            goto leave;
-       /* fixme: we should propagate the local_id to all copies of the PK */
     }
     sig->local_id = pk->local_id;
 
@@ -666,35 +668,36 @@ check_sigs( KBNODE keyblock, int *selfsig_okay, int *revoked )
  * to the trustdb
  */
 static int
-build_sigrecs( ulong pubkeyid )
+build_sigrecs( ulong lid )
 {
     TRUSTREC rec, krec, rec2;
-    KBNODE keyblock = NULL;
-    KBNODE node;
+   KBNODE keyblock = NULL;
+   KBNODE node;
     int rc=0;
     int i, selfsig, revoked;
     ulong rnum, rnum2;
     ulong first_sigrec = 0;
 
     if( DBG_TRUST )
-       log_debug("trustdb: build_sigrecs for pubkey %lu\n", (ulong)pubkeyid );
+       log_debug("trustdb: build_sigrecs for LID %lu\n", lid );
 
     /* get the keyblock */
-    if( (rc=tdbio_read_record( pubkeyid, &rec, RECTYPE_DIR )) ) {
-       log_error(_("%lu: build_sigrecs: can't read dir record\n"), pubkeyid );
+    if( (rc=tdbio_read_record( lid, &rec, RECTYPE_DIR )) ) {
+       log_error( "build_sigrecs: can't read dir record %lu\n"), lid );
        goto leave;
     }
-    if( (rc=tdbio_read_record( rec.r.dir.keyrec, &krec, RECTYPE_KEY )) ) {
-       log_error(_("%lu: build_sigrecs: can't read key record\n"), pubkeyid);
+    if( (rc=tdbio_read_record( rec.r.dir.keylist, &krec, RECTYPE_KEY )) ) {
+       log_error("build_sigrecs: can't read primary key record %lu\n"), lid);
        goto leave;
     }
     rc = get_keyblock_byfprint( &keyblock, krec.r.key.fingerprint,
                                           krec.r.key.fingerprint_len );
     if( rc ) {
-       log_error(_("build_sigrecs: get_keyblock_byfprint failed: %s\n"),
-                                                           g10_errstr(rc) );
+       log_error( "build_sigrecs: keyblock for %lu not found: %s\n",
+                                                   lid, g10_errstr(rc) );
        goto leave;
     }
+
     /* check all key signatures */
     rc = check_sigs( keyblock, &selfsig, &revoked );
     if( rc ) {
@@ -703,19 +706,18 @@ build_sigrecs( ulong pubkeyid )
     }
     if( !selfsig ) {
        log_error(_("build_sigrecs: self-signature missing\n") );
-       update_no_sigs( pubkeyid, 2 );
+       tdbio_update_sigflag( lid, 2 );
        rc = G10ERR_BAD_CERT;
        goto leave;
     }
     if( revoked ) {
        log_info(_("build_sigrecs: key has been revoked\n") );
-       update_no_sigs( pubkeyid, 3 );
+       tdbio_update_sigflag( lid, 3 );
     }
     else
-       update_no_sigs( pubkeyid, 0 ); /* assume we have sigs */
+       tdbio_update_sigflag( lid, 0 ); /* assume we have sigs */
 
-    /* valid key signatures are now marked; we can now build the
-     * sigrecs */
+    /* valid key signatures are now marked; we can now build the sigrecs */
     memset( &rec, 0, sizeof rec );
     rec.rectype = RECTYPE_SIG;
     i = 0;
@@ -740,8 +742,8 @@ build_sigrecs( ulong pubkeyid )
                /* write the record */
                rnum = tdbio_new_recnum();
                if( rnum2 ) { /* write the stored record */
-                   rec2.r.sig.owner = pubkeyid;
-                   rec2.r.sig.chain = rnum; /* the next record number */
+                   rec2.r.sig.lid  = lid;
+                   rec2.r.sig.next = rnum; /* the next record number */
                    rc = tdbio_write_record( rnum2, &rec2 );
                    if( rc ) {
                        log_error(_("build_sigrecs: write_record failed\n") );
@@ -756,7 +758,7 @@ build_sigrecs( ulong pubkeyid )
                rec.rectype = RECTYPE_SIG;
                i = 0;
            }
-           rec.r.sig.sig[i].local_id = node->pkt->pkt.signature->local_id;
+           rec.r.sig.sig[i].lid  = node->pkt->pkt.signature->local_id;
            rec.r.sig.sig[i].flag = 0;
            i++;
        }
@@ -765,8 +767,8 @@ build_sigrecs( ulong pubkeyid )
        /* write the record */
        rnum = tdbio_new_recnum();
        if( rnum2 ) { /* write the stored record */
-           rec2.r.sig.owner = pubkeyid;
-           rec2.r.sig.chain = rnum;
+           rec2.r.sig.lid  = lid;
+           rec2.r.sig.next = rnum;
            rc = tdbio_write_record( rnum2, &rec2 );
            if( rc ) {
                log_error(_("build_sigrecs: write_record failed\n") );
@@ -776,8 +778,8 @@ build_sigrecs( ulong pubkeyid )
                first_sigrec = rnum2;
        }
        if( i ) { /* write the pending record */
-           rec.r.sig.owner = pubkeyid;
-           rec.r.sig.chain = 0;
+           rec.r.sig.lid = lid;
+           rec.r.sig.next = 0;
            rc = tdbio_write_record( rnum, &rec );
            if( rc ) {
                log_error(_("build_sigrecs: write_record failed\n") );
@@ -787,8 +789,7 @@ build_sigrecs( ulong pubkeyid )
                first_sigrec = rnum;
        }
     }
-    if( first_sigrec ) {
-       /* update the dir record */
+    if( first_sigrec ) { /* update the uid records */
        if( (rc =tdbio_read_record( pubkeyid, &rec, RECTYPE_DIR )) ) {
            log_error(_("update_dir_record: read failed\n"));
            goto leave;
@@ -800,7 +801,7 @@ build_sigrecs( ulong pubkeyid )
        }
     }
     else
-       update_no_sigs( pubkeyid, revoked? 3:1 ); /* no signatures */
+       tdbio_update_sigflag( lid, revoked? 3:1 ); /* no signatures */
 
   leave:
     release_kbnode( keyblock );
@@ -900,12 +901,24 @@ propagate_trust( TRUST_SEG_LIST tslist )
 }
 
 
+
 /****************
- * we have the pubkey record but nothing more is known.
- * (function may re-read dr)
+ * check whether we already build signature records
+ * Return: true if we have.
  */
 static int
-do_check( ulong pubkeyid, TRUSTREC *dr, unsigned *trustlevel )
+do_we_have_sigs( TRUSTREC *dr )
+{
+}
+
+
+/****************
+ * we have the pubkey record and all needed informations are in the trustdb
+ * but nothing more is known.
+ * (this function may re-read the dir record dr)
+ */
+static int
+do_check( TRUSTREC *dr, unsigned *trustlevel )
 {
     int i, rc=0;
     TRUST_SEG_LIST tsl, tsl2, tslist;
@@ -919,16 +932,27 @@ do_check( ulong pubkeyid, TRUSTREC *dr, unsigned *trustlevel )
 
     *trustlevel = TRUST_UNDEFINED;
 
+    if( !dr->r.dir.keylist ) {
+       log_error("Ooops, no keys\n");
+       return G10ERR_TRUSTDB
+    }
+    if( !dr->r.dir.uidlist ) {
+       log_error("Ooops, no user ids\n");
+       return G10ERR_TRUSTDB
+    }
+
     /* verify the cache */
 
     /* do we have sigrecs */
-    if( !dr->r.dir.sigrec && !dr->r.dir.no_sigs) {
-       /* no sigrecs, so build them */
-       rc = build_sigrecs( pubkeyid );
+    if( !do_we_have_sigs( dr ) ) { /* no sigrecs, so build them */
+       rc = build_sigrecs( dr->lid );
        if( !rc ) /* and read again */
-           rc = tdbio_read_record( pubkeyid, dr, RECTYPE_DIR );
+           rc = tdbio_read_record( dr->lid, dr, RECTYPE_DIR );
     }
 
+
+   !!!!WORK!!!!
+
     if( dr->r.dir.no_sigs == 3 )
        tflags |= TRUST_FLAG_REVOKED;
 
@@ -1199,9 +1223,7 @@ list_trust_path( int max_depth, const char *username )
  *             yes: return trustlevel from cache
  *             no:  make a cache record and all the other stuff
  *     not found:
- *         Return with a trustlevel, saying that we do not have
- *         a trust record for it. The caller may use insert_trust_record()
- *         and then call this function here again.
+ *         try to insert the pubkey into the trustdb and check again
  *
  * Problems: How do we get the complete keyblock to check that the
  *          cache record is actually valid?  Think we need a clever
@@ -1225,17 +1247,17 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
     /* get the pubkey record */
     if( pk->local_id ) {
        if( tdbio_read_record( pk->local_id, &rec, RECTYPE_DIR ) ) {
-           log_error(_("check_trust: read dir record failed\n"));
+           log_error("check_trust: read dir record failed\n");
            return G10ERR_TRUSTDB;
        }
     }
     else { /* no local_id: scan the trustdb */
-       if( (rc=tdbio_search_record( pk, &rec )) && rc != -1 ) {
-           log_error(_("check_trust: search_record failed: %s\n"),
+       if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 ) {
+           log_error("check_trust: search dir record failed: %s\n",
                                                            g10_errstr(rc));
            return rc;
        }
-       else if( rc == -1 ) {
+       else if( rc == -1 ) { /* not found - insert */
            rc = insert_trust_record( pk );
            if( rc ) {
                log_error(_("key %08lX: insert trust record failed: %s\n"),
@@ -1263,7 +1285,7 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
         trustlevel = TRUST_EXPIRED;
     }
     else {
-       rc = do_check( pk->local_id, &rec, &trustlevel );
+       rc = do_check( &rec, &trustlevel );
        if( rc ) {
            log_error(_("key %08lX.%lu: trust check failed: %s\n"),
                            keyid[1], pk->local_id, g10_errstr(rc));
@@ -1424,24 +1446,119 @@ query_trust_record( PKT_public_key *pk )
  * This function fails if this record already exists.
  */
 int
-insert_trust_record( PKT_public_key *pk )
+insert_trust_record( PKT_public_key *orig_pk )
 {
-    TRUSTREC rec;
+    TRUSTREC dirrec, *rec;
+    TRUSTREC **keylist_tail, *keylist;
+    TRUSTREC **uidlist_tail, *uidlist;
+    KBNODE keyblock = NULL;
+    KBNODE node;
     u32 keyid[2];
     ulong knum, dnum;
     byte *fingerprint;
     size_t fingerlen;
+    int rc = 0;
 
 
-    if( pk->local_id )
+    if( orig_pk->local_id )
        log_bug("pk->local_id=%lu\n", (ulong)pk->local_id );
 
-    keyid_from_pk( pk, keyid );
-    fingerprint = fingerprint_from_pk( pk, &fingerlen );
+    fingerprint = fingerprint_from_pk( orig_pk, &fingerlen );
+
+    /* fixme: assert that we do not have this record.
+     * we can do this by searching for the primary keyid
+     */
+
+    /* get the keyblock which has the key */
+    rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
+    if( rc ) { /* that should never happen */
+       log_error( "insert_trust_record: keyblock not found: %s\n",
+                                                         g10_errstr(rc) );
+       return rc;
+    }
+
+    /* prepare dir record */
+    memset( &dirrec, 0, sizeof dirrec );
+    dirrec.rectype = RECTYPE_DIR;
+    dirrec.r.dir.lid = tdbio_new_recnum();
+
+    keylist = NULL;
+    keylist_tail = &dirrec.r.dir.keylist;
+    uidlist = NULL;
+    uidlist_tail = &dirrec.r.dir.uidlist;
+    /* loop over the keyblock */
+    for( node=keyblock; node; node = node->next ) {
+       if( node->pkt->pkttype == PKT_PUBLIC_KEY
+           || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
+           PKT_public_key *pk = node->pkt->pkt.public_key;
+
+           if( keylist && node->pkt->pkttype == PKT_PUBLIC_KEY )
+               BUG();  /* more than one primary key */
+           fingerprint = fingerprint_from_pk( orig_pk, &fingerlen );
+           rec = m_alloc_clear( sizeof *rec );
+           rec->r.key.pubkey_algo = pk->pubkey_algo;
+           rec->r.key.fingerprint_len = fingerlen;
+           memcpy(rec->r.key.fingerprint, fingerprint, fingerlen );
+
+           if( keylist )
+               keylist_tail = &keylist->next;
+           *keylist_tail = keylist = rec;
+       }
+       else if( node->pkt->pkttype == PKT_USER_ID ) {
+           PKT_user_id *uid = node->pkt->pkt.user_id;
+
+           rec = m_alloc_clear( sizeof *rec );
+           rmd160_hash_buffer( rec->r.uid.namehash, uid->name, uid->len );
+
+           if( uidlist )
+               uidlist_tail = &uidlist->next;
+           *uidlist_tail = uidlist = rec;
+       }
+       if( node->pkt->pkttype == PKT_SIGNATURE
+           && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10
+                 || node->pkt->pkt.signature->sig_class == 0x20
+                 || node->pkt->pkt.signature->sig_class == 0x30) ) {
+           int selfsig;
+           rc = check_key_signature( keyblock, node, &selfsig );
+           if( !rc ) {
+               rc = set_signature_packets_local_id( node->pkt->pkt.signature );
+               if( rc )
+                   log_fatal("set_signature_packets_local_id failed: %s\n",
+                                                             g10_errstr(rc));
+               if( selfsig ) {
+                   node->flag |= 2; /* mark signature valid */
+                   *selfsig_okay = 1;
+               }
+               else if( node->pkt->pkt.signature->sig_class == 0x20 )
+                   *revoked = 1;
+               else
+                   node->flag |= 1; /* mark signature valid */
+
+               if( node->pkt->pkt.signature->sig_class != 0x20 ) {
+                   if( !dups )
+                       dups = new_lid_table();
+                   if( ins_lid_table_item( dups,
+                                       node->pkt->pkt.signature->local_id, 0) )
+                       node->flag |= 4; /* mark as duplicate */
+               }
+           }
+           if( DBG_TRUST )
+               log_debug("trustdb: sig from %08lX.%lu: %s%s\n",
+                               (ulong)node->pkt->pkt.signature->keyid[1],
+                               node->pkt->pkt.signature->local_id,
+                               g10_errstr(rc), (node->flag&4)?"  (dup)":"" );
+       }
+    }
+
+
+
+
+
+
+
+
 
-    /* fixme: assert that we do not have this record. */
 
-    dnum = tdbio_new_recnum();
     knum = tdbio_new_recnum();
     /* build dir record */
     memset( &rec, 0, sizeof rec );
@@ -1451,10 +1568,6 @@ insert_trust_record( PKT_public_key *pk )
     rec.r.dir.keyid[1] = keyid[1];
     rec.r.dir.keyrec   = knum;
     rec.r.dir.no_sigs = 0;
-    if( tdbio_write_record( dnum, &rec ) ) {
-       log_error("writing dir record failed\n");
-       return G10ERR_TRUSTDB;
-    }
     /* and the key record */
     memset( &rec, 0, sizeof rec );
     rec.rectype = RECTYPE_KEY;
@@ -1469,8 +1582,14 @@ insert_trust_record( PKT_public_key *pk )
        log_error("wrinting key record failed\n");
        return G10ERR_TRUSTDB;
     }
+
+    if( tdbio_write_record( dirrec.r.dir.lid, &dirrec ) ) {
+       log_error("writing dir record failed\n");
+       return G10ERR_TRUSTDB;
+    }
+
     /* and store the LID */
-    pk->local_id = dnum;
+    orig_pk->local_id = dnum;
 
     return 0;
 }
@@ -1504,27 +1623,5 @@ update_ownertrust( ulong lid, unsigned new_trust )
 
 
 
-/****************
- * Kludge to prevent duplicate build_sigrecs() due to an invalid
- * certificate (no selfsignature or something like this)
- */
-static int
-update_no_sigs( ulong lid, int no_sigs )
-{
-    TRUSTREC rec;
-
-    if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
-       log_error("update_no_sigs: read failed\n");
-       return G10ERR_TRUSTDB;
-    }
-
-    rec.r.dir.no_sigs = no_sigs;
-    if( tdbio_write_record( lid, &rec ) ) {
-       log_error("update_no_sigs: write failed\n");
-       return G10ERR_TRUSTDB;
-    }
-
-    return 0;
-}
 
 
index 7a2f731..02cc5d0 100644 (file)
@@ -77,7 +77,7 @@ verify_signatures( int nfiles, char **files )
     sl = NULL;
     for(i=1 ; i < nfiles; i++ )
        add_to_strlist( &sl, files[i] );
-    rc = proc_signature_packets( fp, sl );
+    rc = proc_signature_packets( fp, sl, sigfile );
     free_strlist(sl);
     iobuf_close(fp);
     return rc;
index e42ffac..d374839 100644 (file)
@@ -1,3 +1,7 @@
+Thu Jul  9 21:14:51 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * de.po: Fixed typos and added new translations.
+
 Fri Jun 26 11:44:24 1998  Werner Koch  (wk@isil.d.shuttle.de)
 
        * it.po: New file from Marco.
index 1664b32..3b9e1c0 100755 (executable)
Binary files a/tools/mk-tdata and b/tools/mk-tdata differ
index 51a26a4..37c0045 100644 (file)
@@ -92,7 +92,7 @@ POSUB = po
 RANLIB = ranlib
 USE_INCLUDED_LIBINTL = yes
 USE_NLS = yes
-VERSION = 0.3.2
+VERSION = 0.3.2b
 ZLIBS = 
 l =