1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-05-28 21:50:02 +02:00

kbx: Store the UBIB in the blob.

* kbx/keybox-blob.c (create_blob_header): New blob flag UBIB.
(create_blob_finish): Write the UBIB.
* kbx/keybox-dump.c (print_ubib): New.
(_keybox_dump_blob): Print UBIB flag.
* kbx/keybox-search.c (has_ubid): Compare the stored UBIB if
available.
--

This make scanning the keybox for a given UBIB much faster once it has
been stored.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2019-09-27 13:51:52 +02:00
parent 4be79b5abe
commit 0af1c6447d
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 77 additions and 11 deletions

View File

@ -67,6 +67,7 @@
- u16 Blob flags - u16 Blob flags
bit 0 = contains secret key material (not used) bit 0 = contains secret key material (not used)
bit 1 = ephemeral blob (e.g. used while querying external resources) bit 1 = ephemeral blob (e.g. used while querying external resources)
bit 2 = blob has an UBID field.
- u32 Offset to the OpenPGP keyblock or the X.509 DER encoded - u32 Offset to the OpenPGP keyblock or the X.509 DER encoded
certificate certificate
- u32 The length of the keyblock or certificate - u32 The length of the keyblock or certificate
@ -143,7 +144,10 @@
IDs go here. IDs go here.
- bN Space for the keyblock or certificate. - bN Space for the keyblock or certificate.
- bN RFU. This is the remaining space after keyblock and before - bN RFU. This is the remaining space after keyblock and before
the checksum. It is not covered by the checksum. the checksum. Not part of the SHA-1 checksum.
- bN Only if blob flags bit 2 is set: 20 octet Unique Blob-ID (UBID).
This is the SHA-1 checksum of the keyblock or certificate.
This is not part of the SHA-1 checksum below.
- b20 SHA-1 checksum (useful for KS synchronization?) - b20 SHA-1 checksum (useful for KS synchronization?)
Note, that KBX versions before GnuPG 2.1 used an MD5 Note, that KBX versions before GnuPG 2.1 used an MD5
checksum. However it was only created but never checked. checksum. However it was only created but never checked.
@ -173,6 +177,10 @@
#include "../common/gettime.h" #include "../common/gettime.h"
#include "../common/host2net.h"
#define get32(a) buf32_to_ulong ((a))
/* special values of the signature status */ /* special values of the signature status */
@ -559,7 +567,7 @@ create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral,
put32 ( a, 0 ); /* blob length, needs fixup */ put32 ( a, 0 ); /* blob length, needs fixup */
put8 ( a, blobtype); put8 ( a, blobtype);
put8 ( a, want_fpr32? 2:1 ); /* blob type version */ put8 ( a, want_fpr32? 2:1 ); /* blob type version */
put16 ( a, as_ephemeral? 2:0 ); /* blob flags */ put16 ( a, as_ephemeral? 6:4 ); /* blob flags */
put32 ( a, 0 ); /* offset to the raw data, needs fixup */ put32 ( a, 0 ); /* offset to the raw data, needs fixup */
put32 ( a, 0 ); /* length of the raw data, needs fixup */ put32 ( a, 0 ); /* length of the raw data, needs fixup */
@ -686,8 +694,8 @@ create_blob_finish (KEYBOXBLOB blob)
unsigned char *pp; unsigned char *pp;
size_t n; size_t n;
/* Write a placeholder for the checksum */ /* Write placeholders for the UBID and the checksum */
put_membuf (a, NULL, 20); put_membuf (a, NULL, 40);
/* get the memory area */ /* get the memory area */
n = 0; /* (Just to avoid compiler warning.) */ n = 0; /* (Just to avoid compiler warning.) */
@ -721,8 +729,11 @@ create_blob_finish (KEYBOXBLOB blob)
blob->fixups = NULL; blob->fixups = NULL;
} }
/* Compute and store the UBID. (image_off) (image_len) */
gcry_md_hash_buffer (GCRY_MD_SHA1, p + n - 40, p + get32 (p+8), get32 (p+12));
/* Compute and store the SHA-1 checksum. */ /* Compute and store the SHA-1 checksum. */
gcry_md_hash_buffer (GCRY_MD_SHA1, p + n - 20, p, n - 20); gcry_md_hash_buffer (GCRY_MD_SHA1, p + n - 20, p, n - 40);
pp = xtrymalloc (n); pp = xtrymalloc (n);
if ( !pp ) if ( !pp )

View File

@ -63,6 +63,41 @@ print_string (FILE *fp, const byte *p, size_t n, int delim)
} }
static void
print_ubib (const byte *buffer, size_t length, FILE *fp)
{
const byte *p;
int i;
size_t image_off, image_len;
unsigned char digest[20];
fprintf (fp, "UBIB: ");
if (length < 40)
{
fputs ("[blob too short for a stored UBIB]\n", fp);
return;
}
p = buffer + length - 40;
for (i=0; i < 20; p++, i++)
fprintf (fp, "%02X", *p);
image_off = get32 (buffer+8);
image_len = get32 (buffer+12);
if ((uint64_t)image_off+(uint64_t)image_len > (uint64_t)length)
{
fputs (" [image claims to be longer than the blob]\n", fp);
return;
}
gcry_md_hash_buffer (GCRY_MD_SHA1, digest, buffer+image_off,image_len);
if (memcmp (digest, buffer + length - 40, 20))
fputs (" [does not match the image]\n", fp);
else
fputc ('\n', fp);
}
static int static int
print_checksum (const byte *buffer, size_t length, size_t unhashed, FILE *fp) print_checksum (const byte *buffer, size_t length, size_t unhashed, FILE *fp)
{ {
@ -171,6 +206,7 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
ulong unhashed; ulong unhashed;
const byte *p; const byte *p;
int is_fpr32; /* blob ersion 2 */ int is_fpr32; /* blob ersion 2 */
int have_ubib = 0;
buffer = _keybox_get_blob_image (blob, &length); buffer = _keybox_get_blob_image (blob, &length);
@ -237,6 +273,14 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
fputs ("ephemeral", fp); fputs ("ephemeral", fp);
any++; any++;
} }
if ((n & 4))
{
if (any)
putc (',', fp);
fputs ("ubid", fp);
any++;
have_ubib = 1;
}
putc (')', fp); putc (')', fp);
} }
putc ('\n', fp); putc ('\n', fp);
@ -422,6 +466,8 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
n = get32 ( buffer + length - unhashed); n = get32 ( buffer + length - unhashed);
fprintf (fp, "Storage-Flags: %08lx\n", n ); fprintf (fp, "Storage-Flags: %08lx\n", n );
} }
if (have_ubib)
print_ubib (buffer, length, fp);
print_checksum (buffer, length, unhashed, fp); print_checksum (buffer, length, unhashed, fp);
return 0; return 0;
} }

View File

@ -707,14 +707,23 @@ has_ubid (KEYBOXBLOB blob, const unsigned char *ubid)
buffer = _keybox_get_blob_image (blob, &length); buffer = _keybox_get_blob_image (blob, &length);
if (length < 40) if (length < 40)
return 0; /*GPG_ERR_TOO_SHORT*/ return 0; /*GPG_ERR_TOO_SHORT*/
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); 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*/
return !memcmp (ubid, ubid_blob, 20); gcry_md_hash_buffer (GCRY_MD_SHA1, ubid_blob, buffer+image_off,image_len);
return !memcmp (ubid, ubid_blob, 20);
}
} }
static inline int static inline int