Cleanup key array logic to make llvm scan-build happier
We can't have the size != 0 without keys != NULL, but the fact we
checked one at the start and the other later was confusing the static
checks from scan-build. Use size in both places; it keeps scan-build
happy and make the code a little easier to read.
Make keyd more robust in the face of socket errors
We were mostly ignoring errors back from reads or writes to the keyd
socket. Check that we've read/written as many bytes as we expect and
pull some of this out to common functions for sending keys/replies.
Check return value when writing PID to DB4 upgrade lock file
When writing our PID to the lock file for upgrading the DB4 version
we didn't check it was actually successful. This doesn't matter in
general (because it's the existence or not of the file we care about)
but catch it and error out appropriate anyway.
Fix issue with looking up keys by fingerprint via HKP interface
The index variable for the current parameter was being reused to parse
the fingerprint, resulting in attempting to free an unallocated piece of
memory and crashing. Use a different loop variable instead.
With the changes to the backends to store keys using the full fingerprints
it can be useful to force a key to be re-indexed and thus transitioned to
a fingerprint rather than 64 bit key id index. Ideally we'd want to be
able to do this across the entire backend, but that's a bit heavyweight for
a full keyserver so add the ability to do it for a single key to start with.
Check that signature data lengths do not exceed the available data
Some signatures have been witnessed on the keyserver network where the
hashed data lengths reported exceed the size of the overall packet. It
is assumed these are the results of some corruption somewhere, so if
they're detected don't try to parse any further (and drop them if we're
doing signature checking).
Don't end an existing transaction if trying to delete a non-existent key
The DB4 key deletion routine would always exit the current transaction
if the key wasn't found, even if it had been called by another function
which had entered the transaction. Only do so if the deletion routine
itself is what caused the transaction to be started.
Up until now the DB4 backend has used the 64 bit key ID as the index
into the key database. The fingerprint has always been a better idea
and it's easy to create a v3 key that causes a collision, so switch to
using the fingerprint in the DB4 backend.
These changes to not require an upgrade to an existing DB4 setup; keys
will get transitioned to the new storage method as they are updated in
the keyserver.
Observed in keys sent to the keyserver and taken from either RFC 4880
or the source of various older PGP implementations. Some of these are
legacy but we can identify and ignore them.
Switch keysubkeys to returning an array of fingerprints instead of IDs
No functional change at present because the users only currently use the
64 bit key ID, so add a helper function fingerprint2keyid as well (which
only works for v4 keys, but v3 keys can't have subkeys).
Introduce and use a structure to hold OpenPGP fingerprints
Fingerprint lengths can be 16 bytes (for v3 keys) or 20 bytes (for v4
keys). Rather than passing around a size and fingerprint buffer separately
use a structure to hold both pieces of information and just pass that
around.
Fix issues found by llvm scan-build static analysis
A mixture of fixes: some variables set but never used (fix by either
removing or correctly checking error codes), some unlikely but possible
memory leaks, some invalid casting.
Rather than defining a static set of database functions use a well
known initialisation function for each database backend that then
returns a database context structure. This structure contains function
pointers for all of the functions previously held in dbstructs as well
as a private instance context pointer.
For the moment this doesn't provide any change to behaviour, but it
provides the initial preparation for allowing multiple database instance
(whether of the same or differing types) to be used at the same time.
A hash variant that uses 8 SHA-1 instances and results in a double width
hash (320 bits instead of SHA-1's 160 bits). This was used in older
versions of PGP and there are quite a few keys on the keyservers with
signatures using it. Added mainly to enable the sig hash checking
routine to do some sanity checking on these signatures.
This was originally for pulling keys from an old pksd keyserver setup.
The code has bit-rotted and no one should have been running pksd for
years now, so just remove the backend entirely. DB4 has been the best
choice for onak backend for some time now.
Extend database backends to support fetching by key fingerprint
Up until now the database backends have supported fetching a specific
key only by 64 bit key id. We should really have been using the
fingerprint where possible. Add a new backend function, fetch_key_fp,
to allow us to fetch using the fingerprint, and a generic implementation
that just truncates the fingerprint to get the 64 bit key id (valid for
v4 only). The HKP, keyd and dynamic backends gain full passthrough
support for retrieval by fingerprint with this commit.
The key size of an elliptic curve key is given by the OID defining the
curve. Add support for understanding the OIDs listed in RFC6637 (256,
384 + 521 bits).
Old versions of GnuPG put Elgamal (type 16) keys inside v3 packets.
The method of getting the keyid for these keys was via a RIPE MD160
hash approach similar to the SHA-1 approach used in v4. While nothing
supports this these days there are keys in the public keyserver
network that contain this sort of data and if we don't parse the keyid
correctly we can't show things like self-sigs.
With the increased use of signature subkeys and the fact long
keyids are being used to do HKP lookups we need to store a mapping
of the subkey long keyids to primary key ids. Previously the fact
we did this for the 32 bit subkey id was enough. Add a new DB for
the DB4 backend that can map the 64 bit subkey ID to the 64 bit
primary key ID.
Check that libcurl supports SSL if using HKPS with HKP backend
Use CURL's runtime feature checking to ensure that we have support
for SSL before trying to use a HKPS (HTTPS) remote keyserver with
the HKP keydb backend.
Try to use a user specific configuration file if available
Try looking for $XDG_CONFIG_HOME/onak.conf (or $HOME/.config/onak.conf
if $XDG_CONFIG_HOME is not set) before looking for the system wide
config file. This allows users to use their own config file without
having to always use the -c option to provide it.
A harmless failure to cleanup the config structure before exiting
keydctl and a more major (small, but key runs for a long period of
time) leak of the search string for fetching a key by text string
in keyd.
wotsap wasn't paying attention to keys that were revoked, leading to them
being included in the output key/signature lists. Force the load of a key
before colouring it so we can ignore it if it's revoked.
The initial commit of the HKP backend just took a hostname as the "db_dir"
parameter. Extend this to cope with an http:// or hkp:// style URL, allowing
the port to be specified as well.
Clean up use of K&R style function definitions in md5.c
md5_process_block / md5_read_ctx had K&R style function definitions.
Clean them up to use ANSI C style like the rest of the code (including
other functions in that file). Spotted by Doxygen.
Switch keyd to allow multiple clients to be served at once
keyd was only accepting a single connection at a time and dealing with
all the requests from it before accepting the next client. This causes
delays in regular HKP processing while running something like wotsap on
a live keyserver.
Most of the pieces were already in place to deal with a per request select
based processing loop, so this commit switches to that model. A better
solution in the future may be to consider the use of libevent or libev,
but at present this enables the use of long runs stats programs while
still being able to service HKP requests in reasonable time.
A potential use case of onak is as a proxy server. Add an HKP backend
that uses libcurl to make requests to a remote keyserver to fetch, search
or store keys. The "db_dir" configuration parameter becomes the base
host name for the remote keyserver e.g.:
db_backend hkp
db_dir the.earth.li
In the future the addition of the ability to stack database backends
should allow this to be used to turn onak into a caching keyserver.
Wotsap (http://www.lysator.liu.se/~jc/wotsap/) is a web of trust
statistics and pathfinding tool. It takes a set of preformatted key
data covering the primary UID and signatures on each key.
This commit adds a tool which will generate the file data required for
wotsap. These files still need ar/bzip2 run against them in order to
be fed into wotsap, but are generated from the live keyring data.
Sufficiently recent versions of nettle have support for RIPEMD160 and
there are various keys in the wild that use this algorithm, so add an
autoconf check for the nettle support and use it if it's available.
Add -c option to maxpath / sixdegrees to specify config file
maxpath + sixdegrees weren't allowing a config file to be specified
in the same fashion as onak. Add the -c option so they do so, which
helps when using these tools in a non-system install setup.
Prevent read_openpgp_stream from returning empty packets
If read_openpgp_stream got an invalid packet that had a semi valid
header it could potentially return an empty package, which would
confuse splitkeys. Cleanup the final package returned if it turns
out we didn't have valid data for it.
Only seed initial Debian package database if key file is available.
If the Debian package detected no keyring database on installation it
would seed the database with my key, from
/usr/share/doc/onak/noodles.key.gz. This is against Debian policy 12.3 -
packages cannot require files from /usr/share/doc/ to function. Only
seed the database if the file exists, avoiding issues installing when
skipping /usr/share/doc/
Start pulling non-library material out of core source files
As part of moving towards a libonak start pulling things that are related
to the onak keyserver out of the core PGP related source files. Start
with logthing, our logging framework, instead moving towards an onak_status_t
enum to allow up to bubble up errors to the caller.
Massage the existing function/structure comments into something that
Doxygen likes, and document a few additional bits and pieces that
Doxygen was complaining about.
Signatures include the first 2 octets of the hash the signature is
over. Checking this matches what we expect is an easy way to drop
corrupt or incorrect signatures. It doesn't provide any cryptographic
verification but is a useful sanity check when accepting keys.
Avoid race condition when receiving incoming mails
There's a race condition between us starting to accept a new incoming
mail and taking the lock to start processing it; a second copy of
onak-mail may come in and start to process the incomplete mail we're
in the process of receiving. Receive to a tmp file and rename to .onak
after we've received everything.
Fixes Debian bug #650557. Thanks to Helmut Grohne <helmut@subdivi.de>
GPG 1.4.12 switches to using the full fingerprint of a key when requesting
a refresh (commit 6fe25e5602fabe92c68e5ba30e4777221e8612df). We were only
supporting retrieval by 32 or 64 bit key ID. Detect when we're passed a
fingerprint and truncate it to the last 64 bits so we can look it up.
In the future we probably want to extend to being able to do lookups by
full fingerprint.
Use nettle for hashing when available rather than internal MD5/SHA1 routines
Change the internal MD5/SHA1 routines to match nettle's name and
calling convention and add suitable autoconf bits to auto-select
nettle if it's available, otherwise fall back to the internal
routines as usual.
Not so much of an issue for MD5/SHA1 (though we might end up with
more optimised routines in some instances), but allows easier use
of other hashing/crypto functions in the future.