1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

kbx: Add support for 32 byte fingerprints.

* common/userids.c (classify_user_id): Support 32 byte fingerprints.
* kbx/keybox-search-desc.h (KEYDB_SEARCH_MODE_FPR32): New.
(struct keydb_search_desc): Add field fprlen.
* kbx/keybox-defs.h (struct _keybox_openpgp_key_info): Add field
version and increase size of fpr to 32.
* kbx/keybox-blob.c: Define new version 2 for PGP and X509 blobs.
(struct keyboxblob_key): Add field fprlen and increase size of fpr.
(pgp_create_key_part_single): Allow larger fingerprints.
(create_blob_header): Implement blob version 2 and add arg want_fpr32.
(_keybox_create_openpgp_blob): Detect the need for blob version 2.
* kbx/keybox-search.c (blob_get_first_keyid): Support 32 byte
fingerprints.
(blob_cmp_fpr): Ditto.
(blob_cmp_fpr_part): Ditto.
(has_fingerprint): Add arg fprlen and pass on.
(keybox_search): Support KEYDB_SEARCH_MODE_FPR32 and adjust for
changed has_fingerprint.
* kbx/keybox-openpgp.c (parse_key): Support version 5 keys.
* kbx/keybox-dump.c (_keybox_dump_blob): Support blob version 2.

* g10/delkey.c (do_delete_key): Support KEYDB_SEARCH_MODE_FPR32.
* g10/export.c (exact_subkey_match_p): Ditto.
* g10/gpg.c (main): Ditto.
* g10/getkey.c (get_pubkey_byfprint): Adjust for changed
KEYDB_SEARCH_MODE_FPR.
* g10/keydb.c (keydb_search_desc_dump): Support
KEYDB_SEARCH_MODE_FPR32 and adjust for changed KEYDB_SEARCH_MODE_FPR.
(keydb_search): Add new arg fprlen and change all callers.
* g10/keyedit.c (find_by_primary_fpr): Ditto.
* g10/keyid.c (keystr_from_desc): Ditto.
* g10/keyring.c (keyring_search): Ditto.
* g10/keyserver.c (print_keyrec): Ditto.
(parse_keyrec): Ditto.
(keyserver_export): Ditto.
(keyserver_retrieval_screener): Ditto.
(keyserver_import): Ditto.
(keyserver_import_fprint): Ditto.
(keyidlist): Ditto.
(keyserver_get_chunk): Ditto.

* g10/keydb.c (keydb_search): Add new arg fprlen and change all
callers.

* sm/keydb.c (keydb_search_fpr): Adjust for changed
KEYDB_SEARCH_MODE_FPR.
--

This prepares the support for OpenPGP v5 keys.  The new version 2 blob
format is needed for the longer fingerprints and we also use this
opportunity to prepare for storing the keygrip in the blob for faster
lookup by keygrip.  Right now this is not yet functional.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2019-03-14 08:54:59 +01:00
parent a21ca3a1ef
commit f40e9d6a52
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
19 changed files with 440 additions and 130 deletions

View file

@ -265,14 +265,17 @@ parse_key (const unsigned char *data, size_t datalen,
unsigned char hashbuffer[768];
gcry_md_hd_t md;
int is_ecc = 0;
int is_v5;
/* unsigned int pkbytes; for v5: # of octets of the public key params. */
struct keyparm_s keyparm[OPENPGP_MAX_NPKEY];
unsigned char *helpmpibuf[OPENPGP_MAX_NPKEY] = { NULL };
if (datalen < 5)
return gpg_error (GPG_ERR_INV_PACKET);
version = *data++; datalen--;
if (version < 2 || version > 4 )
if (version < 2 || version > 5 )
return gpg_error (GPG_ERR_INV_PACKET); /* Invalid version. */
is_v5 = version == 5;
/*timestamp = ((data[0]<<24)|(data[1]<<16)|(data[2]<<8)|(data[3]));*/
data +=4; datalen -=4;
@ -288,6 +291,15 @@ parse_key (const unsigned char *data, size_t datalen,
return gpg_error (GPG_ERR_INV_PACKET);
algorithm = *data++; datalen--;
if (is_v5)
{
if (datalen < 4)
return gpg_error (GPG_ERR_INV_PACKET);
/* pkbytes = buf32_to_uint (data); */
data += 4;
datalen -= 4;
}
switch (algorithm)
{
case PUBKEY_ALGO_RSA:
@ -315,6 +327,7 @@ parse_key (const unsigned char *data, size_t datalen,
return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
}
ki->version = version;
ki->algo = algorithm;
for (i=0; i < npkey; i++ )
@ -411,29 +424,63 @@ parse_key (const unsigned char *data, size_t datalen,
have a scatter-gather enabled hash function. What we do here
is to use a static buffer if this one is large enough and
only use the regular hash functions if this buffer is not
large enough. */
if ( 3 + n < sizeof hashbuffer )
large enough.
FIXME: Factor this out to a shared fingerprint function.
*/
if (version == 5)
{
hashbuffer[0] = 0x99; /* CTB */
hashbuffer[1] = (n >> 8); /* 2 byte length header. */
hashbuffer[2] = n;
memcpy (hashbuffer + 3, data_start, n);
gcry_md_hash_buffer (GCRY_MD_SHA1, ki->fpr, hashbuffer, 3 + n);
if ( 5 + n < sizeof hashbuffer )
{
hashbuffer[0] = 0x9a; /* CTB */
hashbuffer[1] = (n >> 24);/* 4 byte length header. */
hashbuffer[2] = (n >> 16);
hashbuffer[3] = (n >> 8);
hashbuffer[4] = (n );
memcpy (hashbuffer + 5, data_start, n);
gcry_md_hash_buffer (GCRY_MD_SHA256, ki->fpr, hashbuffer, 5 + n);
}
else
{
err = gcry_md_open (&md, GCRY_MD_SHA256, 0);
if (err)
return err; /* Oops */
gcry_md_putc (md, 0x9a ); /* CTB */
gcry_md_putc (md, (n >> 24)); /* 4 byte length header. */
gcry_md_putc (md, (n >> 16));
gcry_md_putc (md, (n >> 8));
gcry_md_putc (md, (n ));
gcry_md_write (md, data_start, n);
memcpy (ki->fpr, gcry_md_read (md, 0), 32);
gcry_md_close (md);
}
ki->fprlen = 32;
memcpy (ki->keyid, ki->fpr, 8);
}
else
{
err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
if (err)
return err; /* Oops */
gcry_md_putc (md, 0x99 ); /* CTB */
gcry_md_putc (md, (n >> 8) ); /* 2 byte length header. */
gcry_md_putc (md, n );
gcry_md_write (md, data_start, n);
memcpy (ki->fpr, gcry_md_read (md, 0), 20);
gcry_md_close (md);
if ( 3 + n < sizeof hashbuffer )
{
hashbuffer[0] = 0x99; /* CTB */
hashbuffer[1] = (n >> 8); /* 2 byte length header. */
hashbuffer[2] = (n );
memcpy (hashbuffer + 3, data_start, n);
gcry_md_hash_buffer (GCRY_MD_SHA1, ki->fpr, hashbuffer, 3 + n);
}
else
{
err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
if (err)
return err; /* Oops */
gcry_md_putc (md, 0x99 ); /* CTB */
gcry_md_putc (md, (n >> 8)); /* 2 byte length header. */
gcry_md_putc (md, (n ));
gcry_md_write (md, data_start, n);
memcpy (ki->fpr, gcry_md_read (md, 0), 20);
gcry_md_close (md);
}
ki->fprlen = 20;
memcpy (ki->keyid, ki->fpr+12, 8);
}
ki->fprlen = 20;
memcpy (ki->keyid, ki->fpr+12, 8);
}
leave: