summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--NEWS10
-rw-r--r--README134
-rw-r--r--THANKS1
-rw-r--r--TODO26
-rw-r--r--VERSION2
-rwxr-xr-xchecks/defs.inc4
-rw-r--r--cipher/ChangeLog5
-rw-r--r--cipher/primegen.c1
-rw-r--r--cipher/random.c4
-rw-r--r--configure.in2
-rw-r--r--doc/DETAILS130
-rw-r--r--doc/Makefile.am2
-rw-r--r--doc/gpg.1pod5
-rw-r--r--g10/ChangeLog32
-rw-r--r--g10/OPTIONS13
-rw-r--r--g10/armor.c27
-rw-r--r--g10/g10.c32
-rw-r--r--g10/getkey.c4
-rw-r--r--g10/keydb.h8
-rw-r--r--g10/keyedit.c4
-rw-r--r--g10/keygen.c6
-rw-r--r--g10/keyid.c24
-rw-r--r--g10/keylist.c4
-rw-r--r--g10/main.h4
-rw-r--r--g10/mainproc.c27
-rw-r--r--g10/misc.c22
-rw-r--r--g10/openfile.c2
-rw-r--r--g10/options.h1
-rw-r--r--g10/packet.h2
-rw-r--r--g10/pkclist.c8
-rw-r--r--g10/plaintext.c45
-rw-r--r--g10/seskey.c1
-rw-r--r--g10/sign.c2
-rw-r--r--g10/tdbio.c234
-rw-r--r--g10/tdbio.h70
-rw-r--r--g10/trustdb.c255
-rw-r--r--g10/verify.c2
-rw-r--r--po/ChangeLog4
-rwxr-xr-xtools/mk-tdatabin26204 -> 35443 bytes
-rw-r--r--zlib/Makefile2
41 files changed, 708 insertions, 456 deletions
diff --git a/Makefile.am b/Makefile.am
index cd8ae7f6a..b8f6282bf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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 6695dd549..6197de5c3 100644
--- 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 fa2ea8c58..c220c00c2 100644
--- 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
@@ -97,18 +94,18 @@
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".
@@ -117,7 +114,7 @@
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.
@@ -125,16 +122,16 @@
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".
@@ -142,12 +139,12 @@
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.
@@ -155,13 +152,13 @@
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"
@@ -170,17 +167,17 @@
------------------
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.
@@ -192,40 +189,40 @@
* 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)
@@ -233,8 +230,8 @@
* Or by the usual substring:
- "Heine"
- "*Heine"
+ "Heine"
+ "*Heine"
The '*' indicates substring search explicitly.
@@ -264,21 +261,21 @@
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,
@@ -287,24 +284,10 @@
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"
@@ -314,17 +297,17 @@
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
@@ -342,14 +325,3 @@
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 4cf90edc1..70a82744e 100644
--- 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 53a3c9de8..b5cd73422 100644
--- 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.
@@ -28,14 +24,9 @@
* 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"
@@ -50,10 +41,5 @@
* 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 d15723fbe..52723e57f 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.3.2
+0.3.2b
diff --git a/checks/defs.inc b/checks/defs.inc
index 61e07ee5c..f3ff66f18 100755
--- a/checks/defs.inc
+++ b/checks/defs.inc
@@ -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=""
diff --git a/cipher/ChangeLog b/cipher/ChangeLog
index bee034920..010952863 100644
--- a/cipher/ChangeLog
+++ b/cipher/ChangeLog
@@ -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
diff --git a/cipher/primegen.c b/cipher/primegen.c
index 23aa1dbe8..66d40dbfc 100644
--- a/cipher/primegen.c
+++ b/cipher/primegen.c
@@ -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 );
diff --git a/cipher/random.c b/cipher/random.c
index f44e4c3af..75754cd01 100644
--- a/cipher/random.c
+++ b/cipher/random.c
@@ -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);
diff --git a/configure.in b/configure.in
index 005a1b5fb..80a5c07dd 100644
--- a/configure.in
+++ b/configure.in
@@ -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
diff --git a/doc/DETAILS b/doc/DETAILS
index a2de34306..1be782a1d 100644
--- a/doc/DETAILS
+++ b/doc/DETAILS
@@ -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 7 (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
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 020338b40..dc2ee585b 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -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
diff --git a/doc/gpg.1pod b/doc/gpg.1pod
index 726e97696..1fde885fa 100644
--- a/doc/gpg.1pod
+++ b/doc/gpg.1pod
@@ -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.
diff --git a/g10/ChangeLog b/g10/ChangeLog
index a637ac9e9..f6f935a57 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -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.
diff --git a/g10/OPTIONS b/g10/OPTIONS
index 3abe296d8..8e9cf8a6c 100644
--- a/g10/OPTIONS
+++ b/g10/OPTIONS
@@ -17,15 +17,7 @@
#-----------------------------------------------
#------------------- 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.
diff --git a/g10/armor.c b/g10/armor.c
index 46151eae8..45f962f01 100644
--- a/g10/armor.c
+++ b/g10/armor.c
@@ -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;
}
diff --git a/g10/g10.c b/g10/g10.c
index 8082fe2eb..308b58227 100644
--- 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 */
diff --git a/g10/getkey.c b/g10/getkey.c
index 3f8ac63b8..b73a00616 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -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
diff --git a/g10/keydb.h b/g10/keydb.h
index 58a170d27..a0398092a 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -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 );
diff --git a/g10/keyedit.c b/g10/keyedit.c
index ee50a7880..4369e9a86 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -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 );
diff --git a/g10/keygen.c b/g10/keygen.c
index d9f8579e4..b114b8444 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -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
diff --git a/g10/keyid.c b/g10/keyid.c
index 0809df93a..2e5c6aad6 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -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);
}
diff --git a/g10/keylist.c b/g10/keylist.c
index f06b4989f..d23a98f1e 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -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++ )
diff --git a/g10/main.h b/g10/main.h
index dcba0488f..fdb01343f 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -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);
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 9090fd4e1..cd3e85a8b 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -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,
diff --git a/g10/misc.c b/g10/misc.c
index 470307363..ec7c40a1a 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -22,10 +22,15 @@
#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 )
{
diff --git a/g10/openfile.c b/g10/openfile.c
index be2702b55..afa36b983 100644
--- a/g10/openfile.c
+++ b/g10/openfile.c
@@ -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);
}
}
diff --git a/g10/options.h b/g10/options.h
index 0929be328..80a6539ec 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -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 */
diff --git a/g10/packet.h b/g10/packet.h
index 0cefd8d10..cef9afe5c 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -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 );
diff --git a/g10/pkclist.c b/g10/pkclist.c
index 81e23c765..e509f0064 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -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"
diff --git a/g10/plaintext.c b/g10/plaintext.c
index 8d7b2a97e..1a22ecdbd 100644
--- a/g10/plaintext.c
+++ b/g10/plaintext.c
@@ -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);
}
diff --git a/g10/seskey.c b/g10/seskey.c
index 5b271a2d4..6e76d12db 100644
--- a/g10/seskey.c
+++ b/g10/seskey.c
@@ -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)) )
;
diff --git a/g10/sign.c b/g10/sign.c
index 14dfe417e..6192d5987 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -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 );
diff --git a/g10/tdbio.c b/g10/tdbio.c
index d3b9a7221..425e51cbb 100644
--- a/g10/tdbio.c
+++ b/g10/tdbio.c
@@ -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;
+}
+
diff --git a/g10/tdbio.h b/g10/tdbio.h
index facb5c307..7229d7222 100644
--- a/g10/tdbio.h
+++ b/g10/tdbio.h
@@ -32,15 +32,17 @@
#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) | \
diff --git a/g10/trustdb.c b/g10/trustdb.c
index 916eeffd1..593e12cd2 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -42,6 +42,10 @@
#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;
-}
diff --git a/g10/verify.c b/g10/verify.c
index 7a2f73130..02cc5d003 100644
--- a/g10/verify.c
+++ b/g10/verify.c
@@ -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;
diff --git a/po/ChangeLog b/po/ChangeLog
index e42ffac6d..d37483946 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -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.
diff --git a/tools/mk-tdata b/tools/mk-tdata
index 1664b3278..3b9e1c016 100755
--- a/tools/mk-tdata
+++ b/tools/mk-tdata
Binary files differ
diff --git a/zlib/Makefile b/zlib/Makefile
index 51a26a471..37c004567 100644
--- a/zlib/Makefile
+++ b/zlib/Makefile
@@ -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 =