mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
kbx: Redefine the UBID which is now the primary fingerprint.
* common/util.h (UBID_LEN): New. Use it at all places. * kbx/keybox-blob.c (create_blob_finish): Do not write the UBID item. * kbx/keybox-dump.c (print_ubib): Remove. (_keybox_dump_blob): Do not print the now removed ubid flag. * kbx/keybox-search-desc.h (struct keydb_search_desc): Use constants for the size of the ubid and grip. * kbx/keybox-search.c (blob_cmp_ubid): New. (has_ubid): Make it a simple wrapper around blob_cmp_ubid. (keybox_get_data): Add arg 'r_ubid'. * kbx/frontend.h (enum kbxd_store_modes): New. * kbx/kbxserver.c (cmd_store): Add new option --insert. * kbx/backend-cache.c (be_cache_initialize): New. (be_cache_add_resource): Call it here. * kbx/backend-kbx.c (be_kbx_seek): Remove args 'fpr' and 'fprlen'. (be_kbx_search): Get the UBID from keybox_get_data. * kbx/backend-support.c (be_fingerprint_from_blob): Replace by ... (be_ubid_from_blob): new. Change all callers. * kbx/frontend.c (kbxd_add_resource): Temporary disable the cache but use the new cache init function. (kbxd_store): Replace arg 'only_update' by 'mode'. Seek using the ubid. Take care of the mode. -- It turned out that using the hash of the entire blob was not helpful. Thus we redefine the Unique-Blob-ID (UBID) as the primary fingerprint of the blob. In case this is a v5 OpenPGP key a left truncated version of the SHA-256 hash is used; in all other cases the full SHA-1 hash. Using a SHA-256 hash does not make sense because v4 keys are and will for some time be the majority of keys and thus padding them with zeroes won't make any difference. Even if fingerprint collisions can eventually be created we will assume that the keys are bogus and that it does not make sense to store its twin also in our key storage. We can also easily extend the update code to detect a collision and reject the update. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
f59455d054
commit
915297705a
18 changed files with 170 additions and 180 deletions
|
@ -321,6 +321,36 @@ blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr,
|
|||
}
|
||||
|
||||
|
||||
/* Returns true if found. */
|
||||
static int
|
||||
blob_cmp_ubid (KEYBOXBLOB blob, const unsigned char *ubid)
|
||||
{
|
||||
const unsigned char *buffer;
|
||||
size_t length;
|
||||
size_t pos;
|
||||
size_t nkeys, keyinfolen;
|
||||
int fpr32;
|
||||
|
||||
buffer = _keybox_get_blob_image (blob, &length);
|
||||
if (length < 40)
|
||||
return 0; /* blob too short */
|
||||
fpr32 = buffer[5] == 2;
|
||||
|
||||
/*keys*/
|
||||
nkeys = get16 (buffer + 16);
|
||||
keyinfolen = get16 (buffer + 18 );
|
||||
if (!nkeys || keyinfolen < (fpr32?56:28))
|
||||
return 0; /* invalid blob */
|
||||
pos = 20;
|
||||
if (pos + (uint64_t)keyinfolen*nkeys > (uint64_t)length)
|
||||
return 0; /* out of bounds */
|
||||
|
||||
if (!memcmp (buffer + pos, ubid, UBID_LEN))
|
||||
return 1; /* found */
|
||||
return 0; /* not found */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
blob_cmp_name (KEYBOXBLOB blob, int idx,
|
||||
const char *name, size_t namelen, int substr, int x509)
|
||||
|
@ -696,36 +726,16 @@ has_keygrip (KEYBOXBLOB blob, const unsigned char *grip)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* The UBID is the primary fingerprint. For OpenPGP v5 keys only the
|
||||
* leftmost 20 bytes (UBID_LEN) are used. */
|
||||
static inline int
|
||||
has_ubid (KEYBOXBLOB blob, const unsigned char *ubid)
|
||||
{
|
||||
size_t length;
|
||||
const unsigned char *buffer;
|
||||
size_t image_off, image_len;
|
||||
unsigned char ubid_blob[20];
|
||||
|
||||
buffer = _keybox_get_blob_image (blob, &length);
|
||||
if (length < 40)
|
||||
return 0; /*GPG_ERR_TOO_SHORT*/
|
||||
|
||||
if ((get16 (buffer + 6) & 4))
|
||||
{
|
||||
/* The blob has a stored UBID. */
|
||||
return !memcmp (ubid, buffer + length - 40, 20);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Need to compute the UBID. */
|
||||
image_off = get32 (buffer+8);
|
||||
image_len = get32 (buffer+12);
|
||||
if ((uint64_t)image_off+(uint64_t)image_len > (uint64_t)length)
|
||||
return 0; /*GPG_ERR_TOO_SHORT*/
|
||||
|
||||
gcry_md_hash_buffer (GCRY_MD_SHA1, ubid_blob, buffer+image_off,image_len);
|
||||
return !memcmp (ubid, ubid_blob, 20);
|
||||
}
|
||||
return blob_cmp_ubid (blob, ubid);
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
has_issuer (KEYBOXBLOB blob, const char *name)
|
||||
{
|
||||
|
@ -1209,17 +1219,18 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc,
|
|||
|
||||
|
||||
/*
|
||||
Functions to return a certificate or a keyblock. To be used after
|
||||
a successful search operation.
|
||||
*/
|
||||
* Functions to return a certificate or a keyblock. To be used after
|
||||
* a successful search operation.
|
||||
*/
|
||||
|
||||
/* Return the raw data from the last found blob. Caller must release
|
||||
* the value stored at R_BUFFER. If called with NULL for R_BUFFER
|
||||
* only the needed length for the buffer and the public key type is
|
||||
* returned. */
|
||||
* returned. R_PUBKEY_TYPE and R_UBID can be used to return these
|
||||
* attributes. */
|
||||
gpg_error_t
|
||||
keybox_get_data (KEYBOX_HANDLE hd, void **r_buffer, size_t *r_length,
|
||||
enum pubkey_types *r_pubkey_type)
|
||||
enum pubkey_types *r_pubkey_type, unsigned char *r_ubid)
|
||||
{
|
||||
const unsigned char *buffer;
|
||||
size_t length;
|
||||
|
@ -1259,6 +1270,20 @@ keybox_get_data (KEYBOX_HANDLE hd, void **r_buffer, size_t *r_length,
|
|||
if ((uint64_t)image_off+(uint64_t)image_len > (uint64_t)length)
|
||||
return gpg_error (GPG_ERR_TOO_SHORT);
|
||||
|
||||
if (r_ubid)
|
||||
{
|
||||
size_t keyinfolen;
|
||||
|
||||
/* We do a quick but sufficient consistency check. For the full
|
||||
* check see blob_cmp_ubid. */
|
||||
if (!get16 (buffer + 16) /* No keys. */
|
||||
|| (keyinfolen = get16 (buffer + 18)) < 28
|
||||
|| (20 + (uint64_t)keyinfolen) > (uint64_t)length)
|
||||
return gpg_error (GPG_ERR_TOO_SHORT);
|
||||
|
||||
memcpy (r_ubid, buffer + 20, UBID_LEN);
|
||||
}
|
||||
|
||||
if (r_length)
|
||||
*r_length = image_len;
|
||||
if (r_buffer)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue