aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2019-09-27 08:05:07 +0000
committerWerner Koch <[email protected]>2019-09-27 08:05:07 +0000
commit4be79b5abeae82b9840e6aa93874f743e13c6df7 (patch)
tree2d9310b43f277203adcd14858cd593f9b7004bd7
parentkbx: First take on a cache for the keyboxd. (diff)
downloadgnupg-4be79b5abeae82b9840e6aa93874f743e13c6df7.tar.gz
gnupg-4be79b5abeae82b9840e6aa93874f743e13c6df7.zip
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 <[email protected]>
-rw-r--r--common/userids.c14
-rw-r--r--doc/DETAILS9
-rw-r--r--g10/call-keyboxd.c8
-rw-r--r--g10/keydb.c10
-rw-r--r--kbx/backend-cache.c27
-rw-r--r--kbx/backend-kbx.c2
-rw-r--r--kbx/backend.h1
7 files changed, 64 insertions, 7 deletions
diff --git a/common/userids.c b/common/userids.c
index 55bd85546..eb714a9af 100644
--- a/common/userids.c
+++ b/common/userids.c
@@ -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')
{
diff --git a/doc/DETAILS b/doc/DETAILS
index ed5cadec6..0610108f4 100644
--- a/doc/DETAILS
+++ b/doc/DETAILS
@@ -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
diff --git a/g10/call-keyboxd.c b/g10/call-keyboxd.c
index 97f84c03d..88ad07817 100644
--- a/g10/call-keyboxd.c
+++ b/g10/call-keyboxd.c
@@ -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;
diff --git a/g10/keydb.c b/g10/keydb.c
index 6ca239475..39ec5442e 100644
--- a/g10/keydb.c
+++ b/g10/keydb.c
@@ -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:
diff --git a/kbx/backend-cache.c b/kbx/backend-cache.c
index d5b46b50a..10a6f6bd9 100644
--- a/kbx/backend-cache.c
+++ b/kbx/backend-cache.c
@@ -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);
diff --git a/kbx/backend-kbx.c b/kbx/backend-kbx.c
index e58b74a3b..851f2dadf 100644
--- a/kbx/backend-kbx.c
+++ b/kbx/backend-kbx.c
@@ -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);
diff --git a/kbx/backend.h b/kbx/backend.h
index 8b389d35c..675ec213d 100644
--- a/kbx/backend.h
+++ b/kbx/backend.h
@@ -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;