kbx,gpg: Allow lookup using a UBID.

* common/userids.c (classify_user_id): Detect UBIDs.
* kbx/backend-cache.c (blob_table_put): Store the public key type.
(be_cache_search): Add search mode for UBIDs.
* kbx/backend.h (struct db_request_part_s): Add cache.seqno_ubid.
* g10/keydb.c (keydb_search_desc_dump): Fix printing of keygrip.  Add
ubid printing.
* g10/call-keyboxd.c (keydb_search): Support search by UBID.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2019-09-27 10:05:07 +02:00
parent 280e9c9cfa
commit 4be79b5abe
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
7 changed files with 64 additions and 7 deletions

View File

@ -65,6 +65,9 @@
* (note that you can't search for these characters). Compare
* is not case sensitive.
* - If the userid starts with a '&' a 40 hex digits keygrip is expected.
* - If the userid starts with a '^' followed by 40 hex digits it describes
* a Unique-Blob-ID (UBID) which is the hash of keyblob or certificate as
* stored in the database. This is used in the IPC of the keyboxd.
*/
gpg_error_t
@ -251,6 +254,17 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
}
break;
case '^': /* UBID */
{
if (hex2bin (s+1, desc->u.ubid, 20) < 0)
{
rc = gpg_error (GPG_ERR_INV_USER_ID); /* Invalid. */
goto out;
}
mode = KEYDB_SEARCH_MODE_UBID;
}
break;
default:
if (s[0] == '0' && s[1] == 'x')
{

View File

@ -1144,10 +1144,11 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
*** PUBKEY_INFO <n> <ubid>
The type of the public key in the following D-lines or
communicated via a pipe. <n> is the value of =enum pubkey_types=
and <ubid> the Unique Blob ID which is a SHA-1 digest the entire
blob here formatted in hex.. The consumer of this status line
should be prepared to see a <ubid> of up to 64 characters.
and <ubid> the Unique Blob ID (UBID) which is a SHA-1 digest the
entire blob here formatted in hex. The consumer of this status
line should be prepared to see a <ubid> of up to 64 characters.
Note that the keyboxd SEARCH command can be used to lookup the
public key using the <ubid> prefixed with a caret (^).
* Format of the --attribute-fd output

View File

@ -1017,6 +1017,14 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
}
break;
case KEYDB_SEARCH_MODE_UBID:
{
unsigned char hexubid[20 * 2 + 1];
bin2hex (desc[0].u.grip, 20, hexubid);
snprintf (line, sizeof line, "SEARCH ^%s", hexubid);
}
break;
case KEYDB_SEARCH_MODE_FIRST:
snprintf (line, sizeof line, "SEARCH");
break;

View File

@ -456,6 +456,10 @@ keydb_search_desc_dump (struct keydb_search_desc *desc)
char b[MAX_FORMATTED_FINGERPRINT_LEN + 1];
char fpr[2 * MAX_FINGERPRINT_LEN + 1];
#if MAX_FINGERPRINT_LEN < 20
#error MAX_FINGERPRINT_LEN shorter than GRIP and UBID length/
#endif
switch (desc->mode)
{
case KEYDB_SEARCH_MODE_EXACT:
@ -495,7 +499,11 @@ keydb_search_desc_dump (struct keydb_search_desc *desc)
case KEYDB_SEARCH_MODE_SUBJECT:
return xasprintf ("SUBJECT: '%s'", desc->u.name);
case KEYDB_SEARCH_MODE_KEYGRIP:
return xasprintf ("KEYGRIP: %s", desc->u.grip);
bin2hex (desc[0].u.grip, 20, fpr);
return xasprintf ("KEYGRIP: %s", fpr);
case KEYDB_SEARCH_MODE_UBID:
bin2hex (desc[0].u.ubid, 20, fpr);
return xasprintf ("UBID: %s", fpr);
case KEYDB_SEARCH_MODE_FIRST:
return xasprintf ("FIRST");
case KEYDB_SEARCH_MODE_NEXT:

View File

@ -207,7 +207,7 @@ compare_blobs (const void *arg_a, const void *arg_b)
/* Put the blob (BLOBDATA, BLOBDATALEN) into the cache using UBID as
* the index. If it is already in the cache nothing happens. */
static void
blob_table_put (const unsigned char *ubid,
blob_table_put (const unsigned char *ubid, enum pubkey_types pktype,
const void *blobdata, unsigned int blobdatalen)
{
unsigned int hash;
@ -335,6 +335,7 @@ blob_table_put (const unsigned char *ubid,
b = blob_attic;
blob_attic = b->next;
b->next = NULL;
b->pktype = pktype;
b->data = blobdatacopy;
b->datalen = blobdatalen;
memcpy (b->ubid, ubid, 20);
@ -932,6 +933,7 @@ be_cache_search (ctrl_t ctrl, backend_handle_t backend_hd, db_request_t request,
reqpart->cache_seqno.fpr = 0;
reqpart->cache_seqno.kid = 0;
reqpart->cache_seqno.grip = 0;
reqpart->cache_seqno.ubid = 0;
err = 0;
goto leave;
}
@ -992,6 +994,27 @@ be_cache_search (ctrl_t ctrl, backend_handle_t backend_hd, db_request_t request,
/* ki = query_by_grip (desc[n].u.fpr, desc[n].fprlen); */
/* break; */
case KEYDB_SEARCH_MODE_UBID:
/* This is the quite special UBID mode: If this is
* encountered in the search list we will return just this
* one and obviously look only into the blob cache. */
if (reqpart->cache_seqno.ubid)
err = gpg_error (GPG_ERR_NOT_FOUND);
else
{
b = blob_table_get (desc[n].u.ubid);
if (b)
{
err = be_return_pubkey (ctrl, b->data, b->datalen,
b->pktype, desc[n].u.ubid);
blob_unref (b);
reqpart->cache_seqno.ubid++;
}
else
err = gpg_error (GPG_ERR_EOF);
}
goto leave;
default:
ki = NULL;
break;
@ -1123,7 +1146,7 @@ be_cache_pubkey (ctrl_t ctrl, const unsigned char *ubid,
return;
}
blob_table_put (ubid, blob, bloblen);
blob_table_put (ubid, pubkey_type, blob, bloblen);
kinfo = &info.primary;
key_table_put (kinfo->fpr, kinfo->fprlen, ubid, 0);

View File

@ -302,6 +302,8 @@ be_kbx_seek (ctrl_t ctrl, backend_handle_t backend_hd,
unsigned long skipped_long_blobs;
KEYDB_SEARCH_DESC desc;
(void)ctrl;
log_assert (backend_hd && backend_hd->db_type == DB_TYPE_KBX);
log_assert (request);

View File

@ -61,6 +61,7 @@ struct db_request_part_s
unsigned int fpr;
unsigned int kid;
unsigned int grip;
unsigned int ubid;
} cache_seqno;
};
typedef struct db_request_part_s *db_request_part_t;