mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-02 12:01:32 +01:00
sync
This commit is contained in:
parent
c5b6f97767
commit
0a76a4465b
@ -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
|
||||
|
||||
|
||||
|
10
NEWS
10
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)
|
||||
|
134
README
134
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-----
|
||||
|
1
THANKS
1
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
|
||||
|
26
TODO
26
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
|
||||
|
||||
|
||||
|
@ -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=""
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
130
doc/DETAILS
130
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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
13
g10/OPTIONS
13
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.
|
||||
|
||||
|
27
g10/armor.c
27
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;
|
||||
}
|
||||
|
||||
|
32
g10/g10.c
32
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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
|
@ -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 );
|
||||
|
@ -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
|
||||
|
24
g10/keyid.c
24
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);
|
||||
}
|
||||
|
@ -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++ )
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
22
g10/misc.c
22
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 )
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)) )
|
||||
;
|
||||
|
@ -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 );
|
||||
|
234
g10/tdbio.c
234
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;
|
||||
}
|
||||
|
||||
|
70
g10/tdbio.h
70
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) | \
|
||||
|
255
g10/trustdb.c
255
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
BIN
tools/mk-tdata
BIN
tools/mk-tdata
Binary file not shown.
@ -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 =
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user