mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-05 12:31:50 +01: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:
parent
a21ca3a1ef
commit
f40e9d6a52
@ -226,14 +226,15 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i != 32 && i != 40)
|
if (i != 32 && i != 40 && i != 64)
|
||||||
{
|
{
|
||||||
rc = gpg_error (GPG_ERR_INV_USER_ID); /* Invalid length of fpr. */
|
rc = gpg_error (GPG_ERR_INV_USER_ID); /* Invalid length of fpr. */
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
for (i=0,si=s; si < se; i++, si +=2)
|
for (i=0,si=s; si < se; i++, si +=2)
|
||||||
desc->u.fpr[i] = hextobyte(si);
|
desc->u.fpr[i] = hextobyte(si);
|
||||||
for (; i < 20; i++)
|
desc->fprlen = i;
|
||||||
|
for (; i < 32; i++)
|
||||||
desc->u.fpr[i]= 0;
|
desc->u.fpr[i]= 0;
|
||||||
mode = KEYDB_SEARCH_MODE_FPR;
|
mode = KEYDB_SEARCH_MODE_FPR;
|
||||||
}
|
}
|
||||||
@ -326,6 +327,8 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
|
|||||||
}
|
}
|
||||||
desc->u.fpr[i] = c;
|
desc->u.fpr[i] = c;
|
||||||
}
|
}
|
||||||
|
for (; i < 32; i++)
|
||||||
|
desc->u.fpr[i]= 0;
|
||||||
mode = KEYDB_SEARCH_MODE_FPR16;
|
mode = KEYDB_SEARCH_MODE_FPR16;
|
||||||
}
|
}
|
||||||
else if ((hexlength == 40
|
else if ((hexlength == 40
|
||||||
@ -333,7 +336,7 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
|
|||||||
|| (s[hexlength] == '!' && s[hexlength + 1] == 0)))
|
|| (s[hexlength] == '!' && s[hexlength + 1] == 0)))
|
||||||
|| (!hexprefix && hexlength == 41 && *s == '0'))
|
|| (!hexprefix && hexlength == 41 && *s == '0'))
|
||||||
{
|
{
|
||||||
/* SHA1/RMD160 fingerprint. */
|
/* SHA1 fingerprint. */
|
||||||
int i;
|
int i;
|
||||||
if (hexlength == 41)
|
if (hexlength == 41)
|
||||||
s++;
|
s++;
|
||||||
@ -347,8 +350,31 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
|
|||||||
}
|
}
|
||||||
desc->u.fpr[i] = c;
|
desc->u.fpr[i] = c;
|
||||||
}
|
}
|
||||||
|
for (; i < 32; i++)
|
||||||
|
desc->u.fpr[i]= 0;
|
||||||
mode = KEYDB_SEARCH_MODE_FPR20;
|
mode = KEYDB_SEARCH_MODE_FPR20;
|
||||||
}
|
}
|
||||||
|
else if ((hexlength == 64
|
||||||
|
&& (s[hexlength] == 0
|
||||||
|
|| (s[hexlength] == '!' && s[hexlength + 1] == 0)))
|
||||||
|
|| (!hexprefix && hexlength == 65 && *s == '0'))
|
||||||
|
{
|
||||||
|
/* SHA256 fingerprint. */
|
||||||
|
int i;
|
||||||
|
if (hexlength == 65)
|
||||||
|
s++;
|
||||||
|
for (i=0; i < 32; i++, s+=2)
|
||||||
|
{
|
||||||
|
int c = hextobyte(s);
|
||||||
|
if (c == -1)
|
||||||
|
{
|
||||||
|
rc = gpg_error (GPG_ERR_INV_USER_ID);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
desc->u.fpr[i] = c;
|
||||||
|
}
|
||||||
|
mode = KEYDB_SEARCH_MODE_FPR32;
|
||||||
|
}
|
||||||
else if (!hexprefix)
|
else if (!hexprefix)
|
||||||
{
|
{
|
||||||
/* The fingerprint in an X.509 listing is often delimited by
|
/* The fingerprint in an X.509 listing is often delimited by
|
||||||
@ -368,14 +394,17 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
|
|||||||
}
|
}
|
||||||
if (i == 20)
|
if (i == 20)
|
||||||
mode = KEYDB_SEARCH_MODE_FPR20;
|
mode = KEYDB_SEARCH_MODE_FPR20;
|
||||||
|
for (; i < 32; i++)
|
||||||
|
desc->u.fpr[i]= 0;
|
||||||
}
|
}
|
||||||
if (!mode)
|
if (!mode)
|
||||||
{
|
{
|
||||||
/* Still not found. Now check for a space separated
|
/* Still not found. Now check for a space separated
|
||||||
OpenPGP v4 fingerprint like:
|
* OpenPGP v4 fingerprint like:
|
||||||
8061 5870 F5BA D690 3336 86D0 F2AD 85AC 1E42 B367
|
* 8061 5870 F5BA D690 3336 86D0 F2AD 85AC 1E42 B367
|
||||||
or
|
* or
|
||||||
8061 5870 F5BA D690 3336 86D0 F2AD 85AC 1E42 B367
|
* 8061 5870 F5BA D690 3336 86D0 F2AD 85AC 1E42 B367
|
||||||
|
* FIXME: Support OpenPGP v5 fingerprint
|
||||||
*/
|
*/
|
||||||
hexlength = strspn (s, " 0123456789abcdefABCDEF");
|
hexlength = strspn (s, " 0123456789abcdefABCDEF");
|
||||||
if (s[hexlength] && s[hexlength] != ' ')
|
if (s[hexlength] && s[hexlength] != ' ')
|
||||||
@ -410,6 +439,8 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
|
|||||||
}
|
}
|
||||||
if (i == 20)
|
if (i == 20)
|
||||||
mode = KEYDB_SEARCH_MODE_FPR20;
|
mode = KEYDB_SEARCH_MODE_FPR20;
|
||||||
|
for (; i < 32; i++)
|
||||||
|
desc->u.fpr[i]= 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!mode) /* Default to substring search. */
|
if (!mode) /* Default to substring search. */
|
||||||
|
@ -71,7 +71,8 @@ do_delete_key (ctrl_t ctrl, const char *username, int secret, int force,
|
|||||||
err = classify_user_id (username, &desc, 1);
|
err = classify_user_id (username, &desc, 1);
|
||||||
exactmatch = (desc.mode == KEYDB_SEARCH_MODE_FPR
|
exactmatch = (desc.mode == KEYDB_SEARCH_MODE_FPR
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR16
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR16
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR20);
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR20
|
||||||
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR32);
|
||||||
if (!err)
|
if (!err)
|
||||||
err = keydb_search (hd, &desc, 1, NULL);
|
err = keydb_search (hd, &desc, 1, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
|
16
g10/export.c
16
g10/export.c
@ -453,8 +453,9 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
|
|||||||
|
|
||||||
case KEYDB_SEARCH_MODE_FPR16:
|
case KEYDB_SEARCH_MODE_FPR16:
|
||||||
case KEYDB_SEARCH_MODE_FPR20:
|
case KEYDB_SEARCH_MODE_FPR20:
|
||||||
|
case KEYDB_SEARCH_MODE_FPR32:
|
||||||
case KEYDB_SEARCH_MODE_FPR:
|
case KEYDB_SEARCH_MODE_FPR:
|
||||||
fingerprint_from_pk (node->pkt->pkt.public_key, fpr,&fprlen);
|
fingerprint_from_pk (node->pkt->pkt.public_key, fpr, &fprlen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -474,13 +475,22 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case KEYDB_SEARCH_MODE_FPR16:
|
case KEYDB_SEARCH_MODE_FPR16:
|
||||||
if (!memcmp (desc->u.fpr, fpr, 16))
|
if (fprlen == 16 && !memcmp (desc->u.fpr, fpr, 16))
|
||||||
result = 1;
|
result = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEYDB_SEARCH_MODE_FPR20:
|
case KEYDB_SEARCH_MODE_FPR20:
|
||||||
|
if (fprlen == 20 && !memcmp (desc->u.fpr, fpr, 20))
|
||||||
|
result = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEYDB_SEARCH_MODE_FPR32:
|
||||||
|
if (fprlen == 32 && !memcmp (desc->u.fpr, fpr, 32))
|
||||||
|
result = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case KEYDB_SEARCH_MODE_FPR:
|
case KEYDB_SEARCH_MODE_FPR:
|
||||||
if (!memcmp (desc->u.fpr, fpr, 20))
|
if (fprlen == desc->fprlen && !memcmp (desc->u.fpr, fpr, desc->fprlen))
|
||||||
result = 1;
|
result = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
11
g10/getkey.c
11
g10/getkey.c
@ -899,6 +899,7 @@ key_byname (ctrl_t ctrl, GETKEY_CTX *retctx, strlist_t namelist,
|
|||||||
&& ctx->items[n].mode != KEYDB_SEARCH_MODE_LONG_KID
|
&& ctx->items[n].mode != KEYDB_SEARCH_MODE_LONG_KID
|
||||||
&& ctx->items[n].mode != KEYDB_SEARCH_MODE_FPR16
|
&& ctx->items[n].mode != KEYDB_SEARCH_MODE_FPR16
|
||||||
&& ctx->items[n].mode != KEYDB_SEARCH_MODE_FPR20
|
&& ctx->items[n].mode != KEYDB_SEARCH_MODE_FPR20
|
||||||
|
&& ctx->items[n].mode != KEYDB_SEARCH_MODE_FPR32
|
||||||
&& ctx->items[n].mode != KEYDB_SEARCH_MODE_FPR)
|
&& ctx->items[n].mode != KEYDB_SEARCH_MODE_FPR)
|
||||||
{
|
{
|
||||||
ctx->items[n].skipfnc = skip_unusable;
|
ctx->items[n].skipfnc = skip_unusable;
|
||||||
@ -1654,7 +1655,7 @@ get_pubkey_byfprint (ctrl_t ctrl, PKT_public_key *pk, kbnode_t *r_keyblock,
|
|||||||
if (r_keyblock)
|
if (r_keyblock)
|
||||||
*r_keyblock = NULL;
|
*r_keyblock = NULL;
|
||||||
|
|
||||||
if (fprint_len == 20 || fprint_len == 16)
|
if (fprint_len == 32 || fprint_len == 20 || fprint_len == 16)
|
||||||
{
|
{
|
||||||
struct getkey_ctx_s ctx;
|
struct getkey_ctx_s ctx;
|
||||||
KBNODE kb = NULL;
|
KBNODE kb = NULL;
|
||||||
@ -1670,9 +1671,9 @@ get_pubkey_byfprint (ctrl_t ctrl, PKT_public_key *pk, kbnode_t *r_keyblock,
|
|||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
|
|
||||||
ctx.nitems = 1;
|
ctx.nitems = 1;
|
||||||
ctx.items[0].mode = fprint_len == 16 ? KEYDB_SEARCH_MODE_FPR16
|
ctx.items[0].mode = KEYDB_SEARCH_MODE_FPR;
|
||||||
: KEYDB_SEARCH_MODE_FPR20;
|
|
||||||
memcpy (ctx.items[0].u.fpr, fprint, fprint_len);
|
memcpy (ctx.items[0].u.fpr, fprint, fprint_len);
|
||||||
|
ctx.items[0].fprlen = fprint_len;
|
||||||
if (pk)
|
if (pk)
|
||||||
ctx.req_usage = pk->req_usage;
|
ctx.req_usage = pk->req_usage;
|
||||||
rc = lookup (ctrl, &ctx, 0, &kb, &found_key);
|
rc = lookup (ctrl, &ctx, 0, &kb, &found_key);
|
||||||
@ -1745,8 +1746,6 @@ get_keyblock_byfprint_fast (kbnode_t *r_keyblock, KEYDB_HANDLE *r_hd,
|
|||||||
|
|
||||||
for (i = 0; i < MAX_FINGERPRINT_LEN && i < fprint_len; i++)
|
for (i = 0; i < MAX_FINGERPRINT_LEN && i < fprint_len; i++)
|
||||||
fprbuf[i] = fprint[i];
|
fprbuf[i] = fprint[i];
|
||||||
while (i < MAX_FINGERPRINT_LEN)
|
|
||||||
fprbuf[i++] = 0;
|
|
||||||
|
|
||||||
hd = keydb_new ();
|
hd = keydb_new ();
|
||||||
if (!hd)
|
if (!hd)
|
||||||
@ -1770,7 +1769,7 @@ get_keyblock_byfprint_fast (kbnode_t *r_keyblock, KEYDB_HANDLE *r_hd,
|
|||||||
if (r_hd)
|
if (r_hd)
|
||||||
*r_hd = hd;
|
*r_hd = hd;
|
||||||
|
|
||||||
err = keydb_search_fpr (hd, fprbuf);
|
err = keydb_search_fpr (hd, fprbuf, fprint_len);
|
||||||
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
||||||
{
|
{
|
||||||
if (!r_hd)
|
if (!r_hd)
|
||||||
|
@ -5077,6 +5077,7 @@ main (int argc, char **argv)
|
|||||||
|| desc.mode == KEYDB_SEARCH_MODE_LONG_KID
|
|| desc.mode == KEYDB_SEARCH_MODE_LONG_KID
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR16
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR16
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR20
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR20
|
||||||
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR32
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_KEYGRIP))
|
|| desc.mode == KEYDB_SEARCH_MODE_KEYGRIP))
|
||||||
{
|
{
|
||||||
|
@ -2957,9 +2957,7 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options,
|
|||||||
size_t an;
|
size_t an;
|
||||||
|
|
||||||
fingerprint_from_pk (pk, afp, &an);
|
fingerprint_from_pk (pk, afp, &an);
|
||||||
while (an < MAX_FINGERPRINT_LEN)
|
rc = keydb_search_fpr (hd, afp, an);
|
||||||
afp[an++] = 0;
|
|
||||||
rc = keydb_search_fpr (hd, afp);
|
|
||||||
}
|
}
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
|
44
g10/keydb.c
44
g10/keydb.c
@ -81,6 +81,7 @@ enum keyblock_cache_states {
|
|||||||
struct keyblock_cache {
|
struct keyblock_cache {
|
||||||
enum keyblock_cache_states state;
|
enum keyblock_cache_states state;
|
||||||
byte fpr[MAX_FINGERPRINT_LEN];
|
byte fpr[MAX_FINGERPRINT_LEN];
|
||||||
|
byte fprlen;
|
||||||
iobuf_t iobuf; /* Image of the keyblock. */
|
iobuf_t iobuf; /* Image of the keyblock. */
|
||||||
int pk_no;
|
int pk_no;
|
||||||
int uid_no;
|
int uid_no;
|
||||||
@ -566,8 +567,12 @@ keydb_search_desc_dump (struct keydb_search_desc *desc)
|
|||||||
bin2hex (desc->u.fpr, 20, fpr);
|
bin2hex (desc->u.fpr, 20, fpr);
|
||||||
return xasprintf ("FPR20: '%s'",
|
return xasprintf ("FPR20: '%s'",
|
||||||
format_hexfingerprint (fpr, b, sizeof (b)));
|
format_hexfingerprint (fpr, b, sizeof (b)));
|
||||||
case KEYDB_SEARCH_MODE_FPR:
|
case KEYDB_SEARCH_MODE_FPR32:
|
||||||
bin2hex (desc->u.fpr, 20, fpr);
|
bin2hex (desc->u.fpr, 20, fpr);
|
||||||
|
return xasprintf ("FPR32: '%s'",
|
||||||
|
format_hexfingerprint (fpr, b, sizeof (b)));
|
||||||
|
case KEYDB_SEARCH_MODE_FPR:
|
||||||
|
bin2hex (desc->u.fpr, desc->fprlen, fpr);
|
||||||
return xasprintf ("FPR: '%s'",
|
return xasprintf ("FPR: '%s'",
|
||||||
format_hexfingerprint (fpr, b, sizeof (b)));
|
format_hexfingerprint (fpr, b, sizeof (b)));
|
||||||
case KEYDB_SEARCH_MODE_ISSUER:
|
case KEYDB_SEARCH_MODE_ISSUER:
|
||||||
@ -1531,6 +1536,8 @@ keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb)
|
|||||||
fingerprint_from_pk (pk, desc.u.fpr, &len);
|
fingerprint_from_pk (pk, desc.u.fpr, &len);
|
||||||
if (len == 20)
|
if (len == 20)
|
||||||
desc.mode = KEYDB_SEARCH_MODE_FPR20;
|
desc.mode = KEYDB_SEARCH_MODE_FPR20;
|
||||||
|
else if (len == 32)
|
||||||
|
desc.mode = KEYDB_SEARCH_MODE_FPR32;
|
||||||
else
|
else
|
||||||
log_bug ("%s: Unsupported key length: %zu\n", __func__, len);
|
log_bug ("%s: Unsupported key length: %zu\n", __func__, len);
|
||||||
|
|
||||||
@ -1862,6 +1869,7 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
|||||||
int was_reset = hd->is_reset;
|
int was_reset = hd->is_reset;
|
||||||
/* If an entry is already in the cache, then don't add it again. */
|
/* If an entry is already in the cache, then don't add it again. */
|
||||||
int already_in_cache = 0;
|
int already_in_cache = 0;
|
||||||
|
int fprlen;
|
||||||
|
|
||||||
if (descindex)
|
if (descindex)
|
||||||
*descindex = 0; /* Make sure it is always set on return. */
|
*descindex = 0; /* Make sure it is always set on return. */
|
||||||
@ -1902,12 +1910,21 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
|||||||
/* NB: If one of the exact search modes below is used in a loop to
|
/* NB: If one of the exact search modes below is used in a loop to
|
||||||
walk over all keys (with the same fingerprint) the caching must
|
walk over all keys (with the same fingerprint) the caching must
|
||||||
have been disabled for the handle. */
|
have been disabled for the handle. */
|
||||||
|
if (desc[0].mode == KEYDB_SEARCH_MODE_FPR20)
|
||||||
|
fprlen = 20;
|
||||||
|
else if (desc[0].mode == KEYDB_SEARCH_MODE_FPR32)
|
||||||
|
fprlen = 32;
|
||||||
|
else if (desc[0].mode == KEYDB_SEARCH_MODE_FPR)
|
||||||
|
fprlen = desc[0].fprlen;
|
||||||
|
else
|
||||||
|
fprlen = 0;
|
||||||
|
|
||||||
if (!hd->no_caching
|
if (!hd->no_caching
|
||||||
&& ndesc == 1
|
&& ndesc == 1
|
||||||
&& (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
|
&& fprlen
|
||||||
|| desc[0].mode == KEYDB_SEARCH_MODE_FPR)
|
|
||||||
&& hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED
|
&& hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED
|
||||||
&& !memcmp (hd->keyblock_cache.fpr, desc[0].u.fpr, 20)
|
&& hd->keyblock_cache.fprlen == fprlen
|
||||||
|
&& !memcmp (hd->keyblock_cache.fpr, desc[0].u.fpr, fprlen)
|
||||||
/* Make sure the current file position occurs before the cached
|
/* Make sure the current file position occurs before the cached
|
||||||
result to avoid an infinite loop. */
|
result to avoid an infinite loop. */
|
||||||
&& (hd->current < hd->keyblock_cache.resource
|
&& (hd->current < hd->keyblock_cache.resource
|
||||||
@ -1922,8 +1939,7 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
|||||||
hd->current = hd->keyblock_cache.resource;
|
hd->current = hd->keyblock_cache.resource;
|
||||||
/* HD->KEYBLOCK_CACHE.OFFSET is the last byte in the record.
|
/* HD->KEYBLOCK_CACHE.OFFSET is the last byte in the record.
|
||||||
Seek just beyond that. */
|
Seek just beyond that. */
|
||||||
keybox_seek (hd->active[hd->current].u.kb,
|
keybox_seek (hd->active[hd->current].u.kb, hd->keyblock_cache.offset + 1);
|
||||||
hd->keyblock_cache.offset + 1);
|
|
||||||
keydb_stats.found_cached++;
|
keydb_stats.found_cached++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1986,8 +2002,8 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
|||||||
keyblock_cache_clear (hd);
|
keyblock_cache_clear (hd);
|
||||||
if (!hd->no_caching
|
if (!hd->no_caching
|
||||||
&& !rc
|
&& !rc
|
||||||
&& ndesc == 1 && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
|
&& ndesc == 1
|
||||||
|| desc[0].mode == KEYDB_SEARCH_MODE_FPR)
|
&& fprlen
|
||||||
&& hd->active[hd->current].type == KEYDB_RESOURCE_TYPE_KEYBOX)
|
&& hd->active[hd->current].type == KEYDB_RESOURCE_TYPE_KEYBOX)
|
||||||
{
|
{
|
||||||
hd->keyblock_cache.state = KEYBLOCK_CACHE_PREPARED;
|
hd->keyblock_cache.state = KEYBLOCK_CACHE_PREPARED;
|
||||||
@ -1997,11 +2013,14 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
|||||||
within the record. */
|
within the record. */
|
||||||
hd->keyblock_cache.offset
|
hd->keyblock_cache.offset
|
||||||
= keybox_offset (hd->active[hd->current].u.kb) - 1;
|
= keybox_offset (hd->active[hd->current].u.kb) - 1;
|
||||||
memcpy (hd->keyblock_cache.fpr, desc[0].u.fpr, 20);
|
memcpy (hd->keyblock_cache.fpr, desc[0].u.fpr, fprlen);
|
||||||
|
hd->keyblock_cache.fprlen = fprlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND
|
if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND
|
||||||
&& ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID && was_reset
|
&& ndesc == 1
|
||||||
|
&& desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID
|
||||||
|
&& was_reset
|
||||||
&& !already_in_cache)
|
&& !already_in_cache)
|
||||||
kid_not_found_insert (desc[0].u.kid);
|
kid_not_found_insert (desc[0].u.kid);
|
||||||
|
|
||||||
@ -2078,12 +2097,13 @@ keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
|
|||||||
* off. If you want to search the whole database, then you need to
|
* off. If you want to search the whole database, then you need to
|
||||||
* first call keydb_search_reset(). */
|
* first call keydb_search_reset(). */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
|
keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr, size_t fprlen)
|
||||||
{
|
{
|
||||||
KEYDB_SEARCH_DESC desc;
|
KEYDB_SEARCH_DESC desc;
|
||||||
|
|
||||||
memset (&desc, 0, sizeof desc);
|
memset (&desc, 0, sizeof desc);
|
||||||
desc.mode = KEYDB_SEARCH_MODE_FPR;
|
desc.mode = KEYDB_SEARCH_MODE_FPR;
|
||||||
memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN);
|
memcpy (desc.u.fpr, fpr, fprlen);
|
||||||
|
desc.fprlen = fprlen;
|
||||||
return keydb_search (hd, &desc, 1, NULL);
|
return keydb_search (hd, &desc, 1, NULL);
|
||||||
}
|
}
|
||||||
|
@ -244,9 +244,9 @@ gpg_error_t keydb_search_next (KEYDB_HANDLE hd);
|
|||||||
key id. */
|
key id. */
|
||||||
gpg_error_t keydb_search_kid (KEYDB_HANDLE hd, u32 *kid);
|
gpg_error_t keydb_search_kid (KEYDB_HANDLE hd, u32 *kid);
|
||||||
|
|
||||||
/* This is a convenience function for searching for keys with a long
|
/* This is a convenience function for searching for keys by
|
||||||
(20 byte) fingerprint. */
|
* fingerprint. */
|
||||||
gpg_error_t keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr);
|
gpg_error_t keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr, size_t fprlen);
|
||||||
|
|
||||||
|
|
||||||
/*-- pkclist.c --*/
|
/*-- pkclist.c --*/
|
||||||
|
@ -2566,7 +2566,8 @@ find_by_primary_fpr (ctrl_t ctrl, const char *fpr,
|
|||||||
if (classify_user_id (fpr, &desc, 1)
|
if (classify_user_id (fpr, &desc, 1)
|
||||||
|| !(desc.mode == KEYDB_SEARCH_MODE_FPR
|
|| !(desc.mode == KEYDB_SEARCH_MODE_FPR
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR16
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR16
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR20))
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR20
|
||||||
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR32))
|
||||||
{
|
{
|
||||||
log_error (_("\"%s\" is not a fingerprint\n"), fpr);
|
log_error (_("\"%s\" is not a fingerprint\n"), fpr);
|
||||||
err = gpg_error (GPG_ERR_INV_NAME);
|
err = gpg_error (GPG_ERR_INV_NAME);
|
||||||
@ -2591,10 +2592,16 @@ find_by_primary_fpr (ctrl_t ctrl, const char *fpr,
|
|||||||
&& !desc.u.fpr[18]
|
&& !desc.u.fpr[18]
|
||||||
&& !desc.u.fpr[19])
|
&& !desc.u.fpr[19])
|
||||||
;
|
;
|
||||||
else if (fprlen == 20 && (desc.mode == KEYDB_SEARCH_MODE_FPR20
|
else if (fprlen == 20 && desc.mode == KEYDB_SEARCH_MODE_FPR20
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR)
|
|
||||||
&& !memcmp (fprbin, desc.u.fpr, 20))
|
&& !memcmp (fprbin, desc.u.fpr, 20))
|
||||||
;
|
;
|
||||||
|
else if (fprlen == 32 && desc.mode == KEYDB_SEARCH_MODE_FPR32
|
||||||
|
&& !memcmp (fprbin, desc.u.fpr, 32))
|
||||||
|
;
|
||||||
|
else if (desc.mode == KEYDB_SEARCH_MODE_FPR
|
||||||
|
&& fprlen == desc.fprlen
|
||||||
|
&& !memcmp (fprbin, desc.u.fpr, fprlen))
|
||||||
|
;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_error (_("\"%s\" is not the primary fingerprint\n"), fpr);
|
log_error (_("\"%s\" is not the primary fingerprint\n"), fpr);
|
||||||
@ -2918,7 +2925,8 @@ keyedit_quick_set_expire (ctrl_t ctrl, const char *fpr, const char *expirestr,
|
|||||||
/* Parse the fingerprint. */
|
/* Parse the fingerprint. */
|
||||||
if (classify_user_id (subkeyfprs[idx], &desc, 1)
|
if (classify_user_id (subkeyfprs[idx], &desc, 1)
|
||||||
|| !(desc.mode == KEYDB_SEARCH_MODE_FPR
|
|| !(desc.mode == KEYDB_SEARCH_MODE_FPR
|
||||||
|| desc.mode == KEYDB_SEARCH_MODE_FPR20))
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR20
|
||||||
|
|| desc.mode == KEYDB_SEARCH_MODE_FPR32))
|
||||||
{
|
{
|
||||||
log_error (_("\"%s\" is not a proper fingerprint\n"),
|
log_error (_("\"%s\" is not a proper fingerprint\n"),
|
||||||
subkeyfprs[idx] );
|
subkeyfprs[idx] );
|
||||||
|
26
g10/keyid.c
26
g10/keyid.c
@ -481,6 +481,32 @@ keystr_from_desc(KEYDB_SEARCH_DESC *desc)
|
|||||||
return keystr(keyid);
|
return keystr(keyid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case KEYDB_SEARCH_MODE_FPR32:
|
||||||
|
{
|
||||||
|
u32 keyid[2];
|
||||||
|
|
||||||
|
keyid[0] = buf32_to_u32 (desc->u.fpr);
|
||||||
|
keyid[1] = buf32_to_u32 (desc->u.fpr+4);
|
||||||
|
return keystr(keyid);
|
||||||
|
}
|
||||||
|
|
||||||
|
case KEYDB_SEARCH_MODE_FPR:
|
||||||
|
{
|
||||||
|
u32 keyid[2];
|
||||||
|
|
||||||
|
if (desc->fprlen == 32)
|
||||||
|
{
|
||||||
|
keyid[0] = buf32_to_u32 (desc->u.fpr);
|
||||||
|
keyid[1] = buf32_to_u32 (desc->u.fpr+4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keyid[0] = buf32_to_u32 (desc->u.fpr+12);
|
||||||
|
keyid[1] = buf32_to_u32 (desc->u.fpr+16);
|
||||||
|
}
|
||||||
|
return keystr(keyid);
|
||||||
|
}
|
||||||
|
|
||||||
case KEYDB_SEARCH_MODE_FPR16:
|
case KEYDB_SEARCH_MODE_FPR16:
|
||||||
return "?v3 fpr?";
|
return "?v3 fpr?";
|
||||||
|
|
||||||
|
@ -997,6 +997,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
|||||||
break;
|
break;
|
||||||
case KEYDB_SEARCH_MODE_FPR16:
|
case KEYDB_SEARCH_MODE_FPR16:
|
||||||
case KEYDB_SEARCH_MODE_FPR20:
|
case KEYDB_SEARCH_MODE_FPR20:
|
||||||
|
case KEYDB_SEARCH_MODE_FPR32:
|
||||||
case KEYDB_SEARCH_MODE_FPR:
|
case KEYDB_SEARCH_MODE_FPR:
|
||||||
need_fpr = 1;
|
need_fpr = 1;
|
||||||
break;
|
break;
|
||||||
@ -1134,9 +1135,10 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
|||||||
pk = pkt.pkt.public_key;
|
pk = pkt.pkt.public_key;
|
||||||
++pk_no;
|
++pk_no;
|
||||||
|
|
||||||
if (need_fpr) {
|
if (need_fpr)
|
||||||
|
{
|
||||||
fingerprint_from_pk (pk, afp, &an);
|
fingerprint_from_pk (pk, afp, &an);
|
||||||
while (an < 20) /* fill up to 20 bytes */
|
while (an < 32) /* fill up to 32 bytes */
|
||||||
afp[an++] = 0;
|
afp[an++] = 0;
|
||||||
}
|
}
|
||||||
if (need_keyid)
|
if (need_keyid)
|
||||||
@ -1185,10 +1187,18 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
|
|||||||
goto found;
|
goto found;
|
||||||
break;
|
break;
|
||||||
case KEYDB_SEARCH_MODE_FPR20:
|
case KEYDB_SEARCH_MODE_FPR20:
|
||||||
case KEYDB_SEARCH_MODE_FPR:
|
|
||||||
if (pk && !memcmp (desc[n].u.fpr, afp, 20))
|
if (pk && !memcmp (desc[n].u.fpr, afp, 20))
|
||||||
goto found;
|
goto found;
|
||||||
break;
|
break;
|
||||||
|
case KEYDB_SEARCH_MODE_FPR32:
|
||||||
|
if (pk && !memcmp (desc[n].u.fpr, afp, 32))
|
||||||
|
goto found;
|
||||||
|
break;
|
||||||
|
case KEYDB_SEARCH_MODE_FPR:
|
||||||
|
if (pk && desc[n].fprlen >= 16 && desc[n].fprlen <= 32
|
||||||
|
&& !memcmp (desc[n].u.fpr, afp, desc[n].fprlen))
|
||||||
|
goto found;
|
||||||
|
break;
|
||||||
case KEYDB_SEARCH_MODE_FIRST:
|
case KEYDB_SEARCH_MODE_FIRST:
|
||||||
if (pk)
|
if (pk)
|
||||||
goto found;
|
goto found;
|
||||||
|
@ -527,6 +527,25 @@ print_keyrec (ctrl_t ctrl, int number,struct keyrec *keyrec)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* If we get a modern fingerprint, we have the most
|
||||||
|
flexibility. */
|
||||||
|
case KEYDB_SEARCH_MODE_FPR32:
|
||||||
|
{
|
||||||
|
u32 kid[2];
|
||||||
|
keyid_from_fingerprint (ctrl, keyrec->desc.u.fpr, 32, kid);
|
||||||
|
es_printf("key %s",keystr(kid));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEYDB_SEARCH_MODE_FPR:
|
||||||
|
{
|
||||||
|
u32 kid[2];
|
||||||
|
keyid_from_fingerprint (ctrl, keyrec->desc.u.fpr, keyrec->desc.fprlen,
|
||||||
|
kid);
|
||||||
|
es_printf("key %s",keystr(kid));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BUG();
|
BUG();
|
||||||
break;
|
break;
|
||||||
@ -614,7 +633,9 @@ parse_keyrec(char *keystring)
|
|||||||
if (err || (work->desc.mode != KEYDB_SEARCH_MODE_SHORT_KID
|
if (err || (work->desc.mode != KEYDB_SEARCH_MODE_SHORT_KID
|
||||||
&& work->desc.mode != KEYDB_SEARCH_MODE_LONG_KID
|
&& work->desc.mode != KEYDB_SEARCH_MODE_LONG_KID
|
||||||
&& work->desc.mode != KEYDB_SEARCH_MODE_FPR16
|
&& work->desc.mode != KEYDB_SEARCH_MODE_FPR16
|
||||||
&& work->desc.mode != KEYDB_SEARCH_MODE_FPR20))
|
&& work->desc.mode != KEYDB_SEARCH_MODE_FPR20
|
||||||
|
&& work->desc.mode != KEYDB_SEARCH_MODE_FPR32
|
||||||
|
&& work->desc.mode != KEYDB_SEARCH_MODE_FPR))
|
||||||
{
|
{
|
||||||
work->desc.mode=KEYDB_SEARCH_MODE_NONE;
|
work->desc.mode=KEYDB_SEARCH_MODE_NONE;
|
||||||
return ret;
|
return ret;
|
||||||
@ -996,7 +1017,9 @@ keyserver_export (ctrl_t ctrl, strlist_t users)
|
|||||||
if (err || (desc.mode != KEYDB_SEARCH_MODE_SHORT_KID
|
if (err || (desc.mode != KEYDB_SEARCH_MODE_SHORT_KID
|
||||||
&& desc.mode != KEYDB_SEARCH_MODE_LONG_KID
|
&& desc.mode != KEYDB_SEARCH_MODE_LONG_KID
|
||||||
&& desc.mode != KEYDB_SEARCH_MODE_FPR16
|
&& desc.mode != KEYDB_SEARCH_MODE_FPR16
|
||||||
&& desc.mode != KEYDB_SEARCH_MODE_FPR20))
|
&& desc.mode != KEYDB_SEARCH_MODE_FPR20
|
||||||
|
&& desc.mode != KEYDB_SEARCH_MODE_FPR32
|
||||||
|
&& desc.mode != KEYDB_SEARCH_MODE_FPR))
|
||||||
{
|
{
|
||||||
log_error(_("\"%s\" not a key ID: skipping\n"),users->d);
|
log_error(_("\"%s\" not a key ID: skipping\n"),users->d);
|
||||||
continue;
|
continue;
|
||||||
@ -1070,6 +1093,16 @@ keyserver_retrieval_screener (kbnode_t keyblock, void *opaque)
|
|||||||
if (fpr_len == 20 && !memcmp (fpr, desc[n].u.fpr, 20))
|
if (fpr_len == 20 && !memcmp (fpr, desc[n].u.fpr, 20))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (desc[n].mode == KEYDB_SEARCH_MODE_FPR32)
|
||||||
|
{
|
||||||
|
if (fpr_len == 32 && !memcmp (fpr, desc[n].u.fpr, 32))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (desc[n].mode == KEYDB_SEARCH_MODE_FPR)
|
||||||
|
{
|
||||||
|
if (fpr_len == desc[n].fprlen && !memcmp (fpr, desc[n].u.fpr, 32))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (desc[n].mode == KEYDB_SEARCH_MODE_FPR16)
|
else if (desc[n].mode == KEYDB_SEARCH_MODE_FPR16)
|
||||||
{
|
{
|
||||||
if (fpr_len == 16 && !memcmp (fpr, desc[n].u.fpr, 16))
|
if (fpr_len == 16 && !memcmp (fpr, desc[n].u.fpr, 16))
|
||||||
@ -1111,7 +1144,9 @@ keyserver_import (ctrl_t ctrl, strlist_t users)
|
|||||||
if (err || (desc[count].mode != KEYDB_SEARCH_MODE_SHORT_KID
|
if (err || (desc[count].mode != KEYDB_SEARCH_MODE_SHORT_KID
|
||||||
&& desc[count].mode != KEYDB_SEARCH_MODE_LONG_KID
|
&& desc[count].mode != KEYDB_SEARCH_MODE_LONG_KID
|
||||||
&& desc[count].mode != KEYDB_SEARCH_MODE_FPR16
|
&& desc[count].mode != KEYDB_SEARCH_MODE_FPR16
|
||||||
&& desc[count].mode != KEYDB_SEARCH_MODE_FPR20))
|
&& desc[count].mode != KEYDB_SEARCH_MODE_FPR20
|
||||||
|
&& desc[count].mode != KEYDB_SEARCH_MODE_FPR32
|
||||||
|
&& desc[count].mode != KEYDB_SEARCH_MODE_FPR))
|
||||||
{
|
{
|
||||||
log_error (_("\"%s\" not a key ID: skipping\n"), users->d);
|
log_error (_("\"%s\" not a key ID: skipping\n"), users->d);
|
||||||
continue;
|
continue;
|
||||||
@ -1171,10 +1206,13 @@ keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len,
|
|||||||
desc.mode=KEYDB_SEARCH_MODE_FPR16;
|
desc.mode=KEYDB_SEARCH_MODE_FPR16;
|
||||||
else if(fprint_len==20)
|
else if(fprint_len==20)
|
||||||
desc.mode=KEYDB_SEARCH_MODE_FPR20;
|
desc.mode=KEYDB_SEARCH_MODE_FPR20;
|
||||||
|
else if(fprint_len==32)
|
||||||
|
desc.mode=KEYDB_SEARCH_MODE_FPR32;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memcpy(desc.u.fpr,fprint,fprint_len);
|
memcpy(desc.u.fpr,fprint,fprint_len);
|
||||||
|
desc.fprlen = fprint_len;
|
||||||
|
|
||||||
/* TODO: Warn here if the fingerprint we got doesn't match the one
|
/* TODO: Warn here if the fingerprint we got doesn't match the one
|
||||||
we asked for? */
|
we asked for? */
|
||||||
@ -1291,7 +1329,7 @@ keyidlist (ctrl_t ctrl, strlist_t users, KEYDB_SEARCH_DESC **klist,
|
|||||||
This is because it's easy to calculate any sort of keyid
|
This is because it's easy to calculate any sort of keyid
|
||||||
from a v4 fingerprint, but not a v3 fingerprint. */
|
from a v4 fingerprint, but not a v3 fingerprint. */
|
||||||
|
|
||||||
if(node->pkt->pkt.public_key->version<4)
|
if (node->pkt->pkt.public_key->version < 4)
|
||||||
{
|
{
|
||||||
(*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID;
|
(*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID;
|
||||||
keyid_from_pk(node->pkt->pkt.public_key,
|
keyid_from_pk(node->pkt->pkt.public_key,
|
||||||
@ -1301,8 +1339,11 @@ keyidlist (ctrl_t ctrl, strlist_t users, KEYDB_SEARCH_DESC **klist,
|
|||||||
{
|
{
|
||||||
size_t dummy;
|
size_t dummy;
|
||||||
|
|
||||||
(*klist)[*count].mode=KEYDB_SEARCH_MODE_FPR20;
|
if (node->pkt->pkt.public_key->version == 4)
|
||||||
fingerprint_from_pk(node->pkt->pkt.public_key,
|
(*klist)[*count].mode = KEYDB_SEARCH_MODE_FPR20;
|
||||||
|
else
|
||||||
|
(*klist)[*count].mode = KEYDB_SEARCH_MODE_FPR32;
|
||||||
|
fingerprint_from_pk (node->pkt->pkt.public_key,
|
||||||
(*klist)[*count].u.fpr,&dummy);
|
(*klist)[*count].u.fpr,&dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1621,9 +1662,10 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
|
|||||||
int quiet = 0;
|
int quiet = 0;
|
||||||
|
|
||||||
if (desc[idx].mode == KEYDB_SEARCH_MODE_FPR20
|
if (desc[idx].mode == KEYDB_SEARCH_MODE_FPR20
|
||||||
|
|| desc[idx].mode == KEYDB_SEARCH_MODE_FPR32
|
||||||
|| desc[idx].mode == KEYDB_SEARCH_MODE_FPR16)
|
|| desc[idx].mode == KEYDB_SEARCH_MODE_FPR16)
|
||||||
{
|
{
|
||||||
n = 1+2+2*20;
|
n = 1+2+2*32;
|
||||||
if (idx && linelen + n > MAX_KS_GET_LINELEN)
|
if (idx && linelen + n > MAX_KS_GET_LINELEN)
|
||||||
break; /* Declare end of this chunk. */
|
break; /* Declare end of this chunk. */
|
||||||
linelen += n;
|
linelen += n;
|
||||||
@ -1635,10 +1677,12 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
|
|||||||
{
|
{
|
||||||
strcpy (pattern[npat], "0x");
|
strcpy (pattern[npat], "0x");
|
||||||
bin2hex (desc[idx].u.fpr,
|
bin2hex (desc[idx].u.fpr,
|
||||||
|
desc[idx].mode == KEYDB_SEARCH_MODE_FPR32? 32 :
|
||||||
desc[idx].mode == KEYDB_SEARCH_MODE_FPR20? 20 : 16,
|
desc[idx].mode == KEYDB_SEARCH_MODE_FPR20? 20 : 16,
|
||||||
pattern[npat]+2);
|
pattern[npat]+2);
|
||||||
npat++;
|
npat++;
|
||||||
if (desc[idx].mode == KEYDB_SEARCH_MODE_FPR20)
|
if (desc[idx].mode == KEYDB_SEARCH_MODE_FPR20
|
||||||
|
|| desc[idx].mode == KEYDB_SEARCH_MODE_FPR32)
|
||||||
npat_fpr++;
|
npat_fpr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1717,7 +1761,7 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember now many of search items were considered. Note that
|
/* Remember how many of the search items were considered. Note that
|
||||||
this is different from NPAT. */
|
this is different from NPAT. */
|
||||||
*r_ndesc_used = idx;
|
*r_ndesc_used = idx;
|
||||||
|
|
||||||
|
@ -62,7 +62,8 @@
|
|||||||
2 = OpenPGP
|
2 = OpenPGP
|
||||||
3 = X509
|
3 = X509
|
||||||
- byte Version number of this blob type
|
- byte Version number of this blob type
|
||||||
1 = The only defined value
|
1 = Blob with 20 byte fingerprints
|
||||||
|
2 = Blob with 32 byte fingerprints and no keyids.
|
||||||
- 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)
|
||||||
@ -70,19 +71,36 @@
|
|||||||
certificate
|
certificate
|
||||||
- u32 The length of the keyblock or certificate
|
- u32 The length of the keyblock or certificate
|
||||||
- u16 [NKEYS] Number of keys (at least 1!) [X509: always 1]
|
- u16 [NKEYS] Number of keys (at least 1!) [X509: always 1]
|
||||||
- u16 Size of the key information structure (at least 28).
|
- u16 Size of the key information structure (at least 28 or 56).
|
||||||
- NKEYS times:
|
- NKEYS times:
|
||||||
|
Version 1 blob:
|
||||||
- b20 The fingerprint of the key.
|
- b20 The fingerprint of the key.
|
||||||
Fingerprints are always 20 bytes, MD5 left padded with zeroes.
|
Fingerprints are always 20 bytes, MD5 left padded with zeroes.
|
||||||
- u32 Offset to the n-th key's keyID (a keyID is always 8 byte)
|
- u32 Offset to the n-th key's keyID (a keyID is always 8 byte)
|
||||||
or 0 if not known which is the case only for X.509.
|
or 0 if not known which is the case only for X.509.
|
||||||
|
Note that this separate keyid is not anymore used by
|
||||||
|
gnupg since the support for v3 keys has been removed.
|
||||||
|
We create this field anyway for backward compatibility with
|
||||||
|
old EOL-ed versions. Eventually we will completely move
|
||||||
|
to the version 2 blob format.
|
||||||
- u16 Key flags
|
- u16 Key flags
|
||||||
bit 0 = qualified signature (not yet implemented}
|
bit 0 = qualified signature (not yet implemented}
|
||||||
- u16 RFU
|
- u16 RFU
|
||||||
- bN Optional filler up to the specified length of this
|
- bN Optional filler up to the specified length of this
|
||||||
structure.
|
structure.
|
||||||
|
Version 2 blob:
|
||||||
|
- b32 The fingerprint of the key. This fingerprint is
|
||||||
|
either 20 or 32 bytes. A 20 byte fingerprint is
|
||||||
|
right filled with zeroes.
|
||||||
|
- u16 Key flags
|
||||||
|
bit 0 = qualified signature (not yet implemented}
|
||||||
|
bit 7 = 32 byte fingerprint in use.
|
||||||
|
- u16 RFU
|
||||||
|
- b20 keygrip
|
||||||
|
- bN Optional filler up to the specified length of this
|
||||||
|
structure.
|
||||||
- u16 Size of the serial number (may be zero)
|
- u16 Size of the serial number (may be zero)
|
||||||
- bN The serial number. N as giiven above.
|
- bN The serial number. N as given above.
|
||||||
- u16 Number of user IDs
|
- u16 Number of user IDs
|
||||||
- u16 [NUIDS] Size of user ID information structure
|
- u16 [NUIDS] Size of user ID information structure
|
||||||
- NUIDS times:
|
- NUIDS times:
|
||||||
@ -172,15 +190,12 @@ struct membuf {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* #if MAX_FINGERPRINT_LEN < 20 */
|
|
||||||
/* #error fingerprints are 20 bytes */
|
|
||||||
/* #endif */
|
|
||||||
|
|
||||||
struct keyboxblob_key {
|
struct keyboxblob_key {
|
||||||
char fpr[20];
|
char fpr[32];
|
||||||
u32 off_kid;
|
u32 off_kid;
|
||||||
ulong off_kid_addr;
|
ulong off_kid_addr;
|
||||||
u16 flags;
|
u16 flags;
|
||||||
|
u16 fprlen; /* Either 20 or 32 */
|
||||||
};
|
};
|
||||||
struct keyboxblob_uid {
|
struct keyboxblob_uid {
|
||||||
u32 off;
|
u32 off;
|
||||||
@ -380,10 +395,9 @@ pgp_create_key_part_single (KEYBOXBLOB blob, int n,
|
|||||||
int off;
|
int off;
|
||||||
|
|
||||||
fprlen = kinfo->fprlen;
|
fprlen = kinfo->fprlen;
|
||||||
if (fprlen > 20)
|
|
||||||
fprlen = 20;
|
|
||||||
memcpy (blob->keys[n].fpr, kinfo->fpr, fprlen);
|
memcpy (blob->keys[n].fpr, kinfo->fpr, fprlen);
|
||||||
if (fprlen != 20) /* v3 fpr - shift right and fill with zeroes. */
|
blob->keys[n].fprlen = fprlen;
|
||||||
|
if (fprlen < 20) /* v3 fpr - shift right and fill with zeroes. */
|
||||||
{
|
{
|
||||||
memmove (blob->keys[n].fpr + 20 - fprlen, blob->keys[n].fpr, fprlen);
|
memmove (blob->keys[n].fpr + 20 - fprlen, blob->keys[n].fpr, fprlen);
|
||||||
memset (blob->keys[n].fpr, 0, 20 - fprlen);
|
memset (blob->keys[n].fpr, 0, 20 - fprlen);
|
||||||
@ -533,31 +547,52 @@ release_kid_list (struct keyid_list *kl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Create a new blob header. If WANT_FPR32 is set a version 2 blob is
|
||||||
|
* created. */
|
||||||
static int
|
static int
|
||||||
create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
|
create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral,
|
||||||
|
int want_fpr32)
|
||||||
{
|
{
|
||||||
struct membuf *a = blob->buf;
|
struct membuf *a = blob->buf;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
put32 ( a, 0 ); /* blob length, needs fixup */
|
put32 ( a, 0 ); /* blob length, needs fixup */
|
||||||
put8 ( a, blobtype);
|
put8 ( a, blobtype);
|
||||||
put8 ( a, 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? 2:0 ); /* 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 */
|
||||||
|
|
||||||
put16 ( a, blob->nkeys );
|
put16 ( a, blob->nkeys );
|
||||||
|
if (want_fpr32)
|
||||||
|
put16 ( a, 32 + 2 + 2 + 20); /* size of key info */
|
||||||
|
else
|
||||||
put16 ( a, 20 + 4 + 2 + 2 ); /* size of key info */
|
put16 ( a, 20 + 4 + 2 + 2 ); /* size of key info */
|
||||||
for ( i=0; i < blob->nkeys; i++ )
|
for ( i=0; i < blob->nkeys; i++ )
|
||||||
{
|
{
|
||||||
|
if (want_fpr32)
|
||||||
|
{
|
||||||
|
put_membuf (a, blob->keys[i].fpr, blob->keys[i].fprlen);
|
||||||
|
blob->keys[i].off_kid_addr = a->len;
|
||||||
|
if (blob->keys[i].fprlen == 32)
|
||||||
|
put16 ( a, (blob->keys[i].flags | 0x80));
|
||||||
|
else
|
||||||
|
put16 ( a, blob->keys[i].flags);
|
||||||
|
put16 ( a, 0 ); /* reserved */
|
||||||
|
/* FIXME: Put the real grip here instead of the filler. */
|
||||||
|
put_membuf (a, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 20);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_assert (blob->keys[i].fprlen <= 20);
|
||||||
put_membuf (a, blob->keys[i].fpr, 20);
|
put_membuf (a, blob->keys[i].fpr, 20);
|
||||||
blob->keys[i].off_kid_addr = a->len;
|
blob->keys[i].off_kid_addr = a->len;
|
||||||
put32 ( a, 0 ); /* offset to keyid, fixed up later */
|
put32 ( a, 0 ); /* offset to keyid, fixed up later */
|
||||||
put16 ( a, blob->keys[i].flags );
|
put16 ( a, blob->keys[i].flags );
|
||||||
put16 ( a, 0 ); /* reserved */
|
put16 ( a, 0 ); /* reserved */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
|
put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
|
||||||
if (blob->serial)
|
if (blob->serial)
|
||||||
@ -593,11 +628,14 @@ create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
|
|||||||
|
|
||||||
/* space where we write keyIDs and other stuff so that the
|
/* space where we write keyIDs and other stuff so that the
|
||||||
pointers can actually point to somewhere */
|
pointers can actually point to somewhere */
|
||||||
if (blobtype == KEYBOX_BLOBTYPE_PGP)
|
if (blobtype == KEYBOX_BLOBTYPE_PGP && !want_fpr32)
|
||||||
{
|
{
|
||||||
/* We need to store the keyids for all pgp v3 keys because those key
|
/* For version 1 blobs, we need to store the keyids for all v3
|
||||||
IDs are not part of the fingerprint. While we are doing that, we
|
* keys because those key IDs are not part of the fingerprint.
|
||||||
fixup all the keyID offsets */
|
* While we are doing that, we fixup all the keyID offsets. For
|
||||||
|
* version 2 blobs (which can't carry v3 keys) we compute the
|
||||||
|
* keyids in the fly because they are just stripped down
|
||||||
|
* fingerprints. */
|
||||||
for (i=0; i < blob->nkeys; i++ )
|
for (i=0; i < blob->nkeys; i++ )
|
||||||
{
|
{
|
||||||
if (blob->keys[i].off_kid)
|
if (blob->keys[i].off_kid)
|
||||||
@ -711,9 +749,27 @@ _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob,
|
|||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
KEYBOXBLOB blob;
|
KEYBOXBLOB blob;
|
||||||
|
int need_fpr32 = 0;
|
||||||
|
|
||||||
*r_blob = NULL;
|
*r_blob = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
/* Check whether we need a blob with 32 bit fingerprints. We could
|
||||||
|
* use this always but for backward compatiblity we do this only for
|
||||||
|
* v5 keys. */
|
||||||
|
if (info->primary.version == 5)
|
||||||
|
need_fpr32 = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct _keybox_openpgp_key_info *kinfo;
|
||||||
|
for (kinfo = &info->subkeys; kinfo; kinfo = kinfo->next)
|
||||||
|
if (kinfo->version == 5)
|
||||||
|
{
|
||||||
|
need_fpr32 = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
blob = xtrycalloc (1, sizeof *blob);
|
blob = xtrycalloc (1, sizeof *blob);
|
||||||
if (!blob)
|
if (!blob)
|
||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
@ -756,7 +812,8 @@ _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob,
|
|||||||
|
|
||||||
init_membuf (&blob->bufbuf, 1024);
|
init_membuf (&blob->bufbuf, 1024);
|
||||||
blob->buf = &blob->bufbuf;
|
blob->buf = &blob->bufbuf;
|
||||||
err = create_blob_header (blob, KEYBOX_BLOBTYPE_PGP, as_ephemeral);
|
err = create_blob_header (blob, KEYBOX_BLOBTYPE_PGP,
|
||||||
|
as_ephemeral, need_fpr32);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
err = pgp_create_blob_keyblock (blob, image, imagelen);
|
err = pgp_create_blob_keyblock (blob, image, imagelen);
|
||||||
@ -943,7 +1000,7 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
|
|||||||
init_membuf (&blob->bufbuf, 1024);
|
init_membuf (&blob->bufbuf, 1024);
|
||||||
blob->buf = &blob->bufbuf;
|
blob->buf = &blob->bufbuf;
|
||||||
/* write out what we already have */
|
/* write out what we already have */
|
||||||
rc = create_blob_header (blob, KEYBOX_BLOBTYPE_X509, as_ephemeral);
|
rc = create_blob_header (blob, KEYBOX_BLOBTYPE_X509, as_ephemeral, 0);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
rc = x509_create_blob_cert (blob, cert);
|
rc = x509_create_blob_cert (blob, cert);
|
||||||
|
@ -99,10 +99,11 @@ struct _keybox_openpgp_key_info
|
|||||||
{
|
{
|
||||||
struct _keybox_openpgp_key_info *next;
|
struct _keybox_openpgp_key_info *next;
|
||||||
int algo;
|
int algo;
|
||||||
|
int version;
|
||||||
unsigned char grip[20];
|
unsigned char grip[20];
|
||||||
unsigned char keyid[8];
|
unsigned char keyid[8];
|
||||||
int fprlen; /* Either 16 or 20 */
|
int fprlen; /* Either 16, 20 or 32 */
|
||||||
unsigned char fpr[20];
|
unsigned char fpr[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _keybox_openpgp_uid_info
|
struct _keybox_openpgp_uid_info
|
||||||
|
@ -170,6 +170,7 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
|
|||||||
ulong nserial;
|
ulong nserial;
|
||||||
ulong unhashed;
|
ulong unhashed;
|
||||||
const byte *p;
|
const byte *p;
|
||||||
|
int is_fpr32; /* blob ersion 2 */
|
||||||
|
|
||||||
buffer = _keybox_get_blob_image (blob, &length);
|
buffer = _keybox_get_blob_image (blob, &length);
|
||||||
|
|
||||||
@ -207,7 +208,9 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
|
|||||||
fprintf (fp, "[can't dump this blob type]\n");
|
fprintf (fp, "[can't dump this blob type]\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/* Here we have either BLOGTYPE_X509 or BLOBTYPE_OPENPGP */
|
||||||
fprintf (fp, "Version: %d\n", buffer[5]);
|
fprintf (fp, "Version: %d\n", buffer[5]);
|
||||||
|
is_fpr32 = buffer[5] == 2;
|
||||||
|
|
||||||
if (length < 40)
|
if (length < 40)
|
||||||
{
|
{
|
||||||
@ -267,6 +270,14 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
|
|||||||
ulong kidoff, kflags;
|
ulong kidoff, kflags;
|
||||||
|
|
||||||
fprintf (fp, "Key-Fpr[%lu]: ", n );
|
fprintf (fp, "Key-Fpr[%lu]: ", n );
|
||||||
|
if (is_fpr32)
|
||||||
|
{
|
||||||
|
kflags = get16 (p + 32 );
|
||||||
|
for (i=0; i < ((kflags & 0x80)?32:20); i++ )
|
||||||
|
fprintf (fp, "%02X", p[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for (i=0; i < 20; i++ )
|
for (i=0; i < 20; i++ )
|
||||||
fprintf (fp, "%02X", p[i]);
|
fprintf (fp, "%02X", p[i]);
|
||||||
kidoff = get32 (p + 20);
|
kidoff = get32 (p + 20);
|
||||||
@ -276,6 +287,7 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
|
|||||||
for (i=0; i < 8; i++ )
|
for (i=0; i < 8; i++ )
|
||||||
fprintf (fp, "%02X", buffer[kidoff+i] );
|
fprintf (fp, "%02X", buffer[kidoff+i] );
|
||||||
kflags = get16 (p + 24 );
|
kflags = get16 (p + 24 );
|
||||||
|
}
|
||||||
fprintf( fp, "\nKey-Flags[%lu]: %04lX\n", n, kflags);
|
fprintf( fp, "\nKey-Flags[%lu]: %04lX\n", n, kflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,14 +265,17 @@ parse_key (const unsigned char *data, size_t datalen,
|
|||||||
unsigned char hashbuffer[768];
|
unsigned char hashbuffer[768];
|
||||||
gcry_md_hd_t md;
|
gcry_md_hd_t md;
|
||||||
int is_ecc = 0;
|
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];
|
struct keyparm_s keyparm[OPENPGP_MAX_NPKEY];
|
||||||
unsigned char *helpmpibuf[OPENPGP_MAX_NPKEY] = { NULL };
|
unsigned char *helpmpibuf[OPENPGP_MAX_NPKEY] = { NULL };
|
||||||
|
|
||||||
if (datalen < 5)
|
if (datalen < 5)
|
||||||
return gpg_error (GPG_ERR_INV_PACKET);
|
return gpg_error (GPG_ERR_INV_PACKET);
|
||||||
version = *data++; datalen--;
|
version = *data++; datalen--;
|
||||||
if (version < 2 || version > 4 )
|
if (version < 2 || version > 5 )
|
||||||
return gpg_error (GPG_ERR_INV_PACKET); /* Invalid version. */
|
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]));*/
|
/*timestamp = ((data[0]<<24)|(data[1]<<16)|(data[2]<<8)|(data[3]));*/
|
||||||
data +=4; datalen -=4;
|
data +=4; datalen -=4;
|
||||||
@ -288,6 +291,15 @@ parse_key (const unsigned char *data, size_t datalen,
|
|||||||
return gpg_error (GPG_ERR_INV_PACKET);
|
return gpg_error (GPG_ERR_INV_PACKET);
|
||||||
algorithm = *data++; datalen--;
|
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)
|
switch (algorithm)
|
||||||
{
|
{
|
||||||
case PUBKEY_ALGO_RSA:
|
case PUBKEY_ALGO_RSA:
|
||||||
@ -315,6 +327,7 @@ parse_key (const unsigned char *data, size_t datalen,
|
|||||||
return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
|
return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ki->version = version;
|
||||||
ki->algo = algorithm;
|
ki->algo = algorithm;
|
||||||
|
|
||||||
for (i=0; i < npkey; i++ )
|
for (i=0; i < npkey; i++ )
|
||||||
@ -411,12 +424,45 @@ parse_key (const unsigned char *data, size_t datalen,
|
|||||||
have a scatter-gather enabled hash function. What we do here
|
have a scatter-gather enabled hash function. What we do here
|
||||||
is to use a static buffer if this one is large enough and
|
is to use a static buffer if this one is large enough and
|
||||||
only use the regular hash functions if this buffer is not
|
only use the regular hash functions if this buffer is not
|
||||||
large enough. */
|
large enough.
|
||||||
|
FIXME: Factor this out to a shared fingerprint function.
|
||||||
|
*/
|
||||||
|
if (version == 5)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
if ( 3 + n < sizeof hashbuffer )
|
if ( 3 + n < sizeof hashbuffer )
|
||||||
{
|
{
|
||||||
hashbuffer[0] = 0x99; /* CTB */
|
hashbuffer[0] = 0x99; /* CTB */
|
||||||
hashbuffer[1] = (n >> 8); /* 2 byte length header. */
|
hashbuffer[1] = (n >> 8); /* 2 byte length header. */
|
||||||
hashbuffer[2] = n;
|
hashbuffer[2] = (n );
|
||||||
memcpy (hashbuffer + 3, data_start, n);
|
memcpy (hashbuffer + 3, data_start, n);
|
||||||
gcry_md_hash_buffer (GCRY_MD_SHA1, ki->fpr, hashbuffer, 3 + n);
|
gcry_md_hash_buffer (GCRY_MD_SHA1, ki->fpr, hashbuffer, 3 + n);
|
||||||
}
|
}
|
||||||
@ -426,8 +472,8 @@ parse_key (const unsigned char *data, size_t datalen,
|
|||||||
if (err)
|
if (err)
|
||||||
return err; /* Oops */
|
return err; /* Oops */
|
||||||
gcry_md_putc (md, 0x99 ); /* CTB */
|
gcry_md_putc (md, 0x99 ); /* CTB */
|
||||||
gcry_md_putc (md, (n >> 8) ); /* 2 byte length header. */
|
gcry_md_putc (md, (n >> 8)); /* 2 byte length header. */
|
||||||
gcry_md_putc (md, n );
|
gcry_md_putc (md, (n ));
|
||||||
gcry_md_write (md, data_start, n);
|
gcry_md_write (md, data_start, n);
|
||||||
memcpy (ki->fpr, gcry_md_read (md, 0), 20);
|
memcpy (ki->fpr, gcry_md_read (md, 0), 20);
|
||||||
gcry_md_close (md);
|
gcry_md_close (md);
|
||||||
@ -435,6 +481,7 @@ parse_key (const unsigned char *data, size_t datalen,
|
|||||||
ki->fprlen = 20;
|
ki->fprlen = 20;
|
||||||
memcpy (ki->keyid, ki->fpr+12, 8);
|
memcpy (ki->keyid, ki->fpr+12, 8);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
for (i=0; i < npkey; i++)
|
for (i=0; i < npkey; i++)
|
||||||
|
@ -38,7 +38,8 @@ typedef enum {
|
|||||||
KEYDB_SEARCH_MODE_LONG_KID,
|
KEYDB_SEARCH_MODE_LONG_KID,
|
||||||
KEYDB_SEARCH_MODE_FPR16,
|
KEYDB_SEARCH_MODE_FPR16,
|
||||||
KEYDB_SEARCH_MODE_FPR20,
|
KEYDB_SEARCH_MODE_FPR20,
|
||||||
KEYDB_SEARCH_MODE_FPR,
|
KEYDB_SEARCH_MODE_FPR32,
|
||||||
|
KEYDB_SEARCH_MODE_FPR, /* (Length of fpr in .fprlen) */
|
||||||
KEYDB_SEARCH_MODE_ISSUER,
|
KEYDB_SEARCH_MODE_ISSUER,
|
||||||
KEYDB_SEARCH_MODE_ISSUER_SN,
|
KEYDB_SEARCH_MODE_ISSUER_SN,
|
||||||
KEYDB_SEARCH_MODE_SN,
|
KEYDB_SEARCH_MODE_SN,
|
||||||
@ -49,7 +50,7 @@ typedef enum {
|
|||||||
} KeydbSearchMode;
|
} KeydbSearchMode;
|
||||||
|
|
||||||
|
|
||||||
/* Forwward declaration. See g10/packet.h. */
|
/* Forward declaration. See g10/packet.h. */
|
||||||
struct gpg_pkt_user_id_s;
|
struct gpg_pkt_user_id_s;
|
||||||
typedef struct gpg_pkt_user_id_s *gpg_pkt_user_id_t;
|
typedef struct gpg_pkt_user_id_s *gpg_pkt_user_id_t;
|
||||||
|
|
||||||
@ -73,6 +74,7 @@ struct keydb_search_desc
|
|||||||
u32 kid[2]; /* Note that this is in native endianness. */
|
u32 kid[2]; /* Note that this is in native endianness. */
|
||||||
unsigned char grip[20];
|
unsigned char grip[20];
|
||||||
} u;
|
} u;
|
||||||
|
byte fprlen; /* Only used with KEYDB_SEARCH_MODE_FPR. */
|
||||||
int exact; /* Use exactly this key ('!' suffix in gpg). */
|
int exact; /* Use exactly this key ('!' suffix in gpg). */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,18 +66,31 @@ blob_get_first_keyid (KEYBOXBLOB blob, u32 *kid)
|
|||||||
{
|
{
|
||||||
const unsigned char *buffer;
|
const unsigned char *buffer;
|
||||||
size_t length, nkeys, keyinfolen;
|
size_t length, nkeys, keyinfolen;
|
||||||
|
int fpr32;
|
||||||
|
|
||||||
buffer = _keybox_get_blob_image (blob, &length);
|
buffer = _keybox_get_blob_image (blob, &length);
|
||||||
if (length < 48)
|
if (length < 48)
|
||||||
return 0; /* blob too short */
|
return 0; /* blob too short */
|
||||||
|
fpr32 = buffer[5] == 2;
|
||||||
|
if (fpr32 && length < 56)
|
||||||
|
return 0; /* blob to short */
|
||||||
|
|
||||||
nkeys = get16 (buffer + 16);
|
nkeys = get16 (buffer + 16);
|
||||||
keyinfolen = get16 (buffer + 18);
|
keyinfolen = get16 (buffer + 18);
|
||||||
if (!nkeys || keyinfolen < 28)
|
if (!nkeys || keyinfolen < (fpr32?56:28))
|
||||||
return 0; /* invalid blob */
|
return 0; /* invalid blob */
|
||||||
|
|
||||||
kid[0] = get32 (buffer + 32);
|
if (fpr32 && (get16 (buffer + 20 + 32) & 0x80))
|
||||||
kid[1] = get32 (buffer + 36);
|
{
|
||||||
|
/* 32 byte fingerprint. */
|
||||||
|
kid[0] = get32 (buffer + 20);
|
||||||
|
kid[1] = get32 (buffer + 20 + 4);
|
||||||
|
}
|
||||||
|
else /* 20 byte fingerprint. */
|
||||||
|
{
|
||||||
|
kid[0] = get32 (buffer + 20 + 12);
|
||||||
|
kid[1] = get32 (buffer + 20 + 16);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -229,22 +242,23 @@ blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen)
|
|||||||
For X.509 this is always 1, for OpenPGP this is 1 for the primary
|
For X.509 this is always 1, for OpenPGP this is 1 for the primary
|
||||||
key and 2 and more for the subkeys. */
|
key and 2 and more for the subkeys. */
|
||||||
static int
|
static int
|
||||||
blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr)
|
blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr, unsigned int fprlen)
|
||||||
{
|
{
|
||||||
const unsigned char *buffer;
|
const unsigned char *buffer;
|
||||||
size_t length;
|
size_t length;
|
||||||
size_t pos, off;
|
size_t pos, off;
|
||||||
size_t nkeys, keyinfolen;
|
size_t nkeys, keyinfolen;
|
||||||
int idx;
|
int idx, fpr32, storedfprlen;
|
||||||
|
|
||||||
buffer = _keybox_get_blob_image (blob, &length);
|
buffer = _keybox_get_blob_image (blob, &length);
|
||||||
if (length < 40)
|
if (length < 40)
|
||||||
return 0; /* blob too short */
|
return 0; /* blob too short */
|
||||||
|
fpr32 = buffer[5] == 2;
|
||||||
|
|
||||||
/*keys*/
|
/*keys*/
|
||||||
nkeys = get16 (buffer + 16);
|
nkeys = get16 (buffer + 16);
|
||||||
keyinfolen = get16 (buffer + 18 );
|
keyinfolen = get16 (buffer + 18 );
|
||||||
if (keyinfolen < 28)
|
if (keyinfolen < (fpr32?56:28))
|
||||||
return 0; /* invalid blob */
|
return 0; /* invalid blob */
|
||||||
pos = 20;
|
pos = 20;
|
||||||
if (pos + (uint64_t)keyinfolen*nkeys > (uint64_t)length)
|
if (pos + (uint64_t)keyinfolen*nkeys > (uint64_t)length)
|
||||||
@ -253,12 +267,19 @@ blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr)
|
|||||||
for (idx=0; idx < nkeys; idx++)
|
for (idx=0; idx < nkeys; idx++)
|
||||||
{
|
{
|
||||||
off = pos + idx*keyinfolen;
|
off = pos + idx*keyinfolen;
|
||||||
if (!memcmp (buffer + off, fpr, 20))
|
if (fpr32)
|
||||||
|
storedfprlen = (get16 (buffer + off + 32) & 0x80)? 32:20;
|
||||||
|
else
|
||||||
|
storedfprlen = 20;
|
||||||
|
if (storedfprlen == fprlen
|
||||||
|
&& !memcmp (buffer + off, fpr, storedfprlen))
|
||||||
return idx+1; /* found */
|
return idx+1; /* found */
|
||||||
}
|
}
|
||||||
return 0; /* not found */
|
return 0; /* not found */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper for has_short_kid and has_long_kid. */
|
||||||
static int
|
static int
|
||||||
blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr,
|
blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr,
|
||||||
int fproff, int fprlen)
|
int fproff, int fprlen)
|
||||||
@ -267,25 +288,33 @@ blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr,
|
|||||||
size_t length;
|
size_t length;
|
||||||
size_t pos, off;
|
size_t pos, off;
|
||||||
size_t nkeys, keyinfolen;
|
size_t nkeys, keyinfolen;
|
||||||
int idx;
|
int idx, fpr32, storedfprlen;
|
||||||
|
|
||||||
buffer = _keybox_get_blob_image (blob, &length);
|
buffer = _keybox_get_blob_image (blob, &length);
|
||||||
if (length < 40)
|
if (length < 40)
|
||||||
return 0; /* blob too short */
|
return 0; /* blob too short */
|
||||||
|
fpr32 = buffer[5] == 2;
|
||||||
|
|
||||||
/*keys*/
|
/*keys*/
|
||||||
nkeys = get16 (buffer + 16);
|
nkeys = get16 (buffer + 16);
|
||||||
keyinfolen = get16 (buffer + 18 );
|
keyinfolen = get16 (buffer + 18 );
|
||||||
if (keyinfolen < 28)
|
if (keyinfolen < (fpr32?56:28))
|
||||||
return 0; /* invalid blob */
|
return 0; /* invalid blob */
|
||||||
pos = 20;
|
pos = 20;
|
||||||
if (pos + (uint64_t)keyinfolen*nkeys > (uint64_t)length)
|
if (pos + (uint64_t)keyinfolen*nkeys > (uint64_t)length)
|
||||||
return 0; /* out of bounds */
|
return 0; /* out of bounds */
|
||||||
|
|
||||||
|
if (fpr32)
|
||||||
|
fproff = 0; /* keyid are the high-order bits. */
|
||||||
for (idx=0; idx < nkeys; idx++)
|
for (idx=0; idx < nkeys; idx++)
|
||||||
{
|
{
|
||||||
off = pos + idx*keyinfolen;
|
off = pos + idx*keyinfolen;
|
||||||
if (!memcmp (buffer + off + fproff, fpr, fprlen))
|
if (fpr32)
|
||||||
|
storedfprlen = (get16 (buffer + off + 32) & 0x80)? 32:20;
|
||||||
|
else
|
||||||
|
storedfprlen = 20;
|
||||||
|
if (storedfprlen == fproff + fprlen
|
||||||
|
&& !memcmp (buffer + off + fproff, fpr, fprlen))
|
||||||
return idx+1; /* found */
|
return idx+1; /* found */
|
||||||
}
|
}
|
||||||
return 0; /* not found */
|
return 0; /* not found */
|
||||||
@ -650,9 +679,9 @@ has_long_kid (KEYBOXBLOB blob, u32 mkid, u32 lkid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
has_fingerprint (KEYBOXBLOB blob, const unsigned char *fpr)
|
has_fingerprint (KEYBOXBLOB blob, const unsigned char *fpr, unsigned int fprlen)
|
||||||
{
|
{
|
||||||
return blob_cmp_fpr (blob, fpr);
|
return blob_cmp_fpr (blob, fpr, fprlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
@ -1047,12 +1076,25 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc,
|
|||||||
if (pk_no)
|
if (pk_no)
|
||||||
goto found;
|
goto found;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEYDB_SEARCH_MODE_FPR:
|
case KEYDB_SEARCH_MODE_FPR:
|
||||||
case KEYDB_SEARCH_MODE_FPR20:
|
pk_no = has_fingerprint (blob, desc[n].u.fpr, desc[n].fprlen);
|
||||||
pk_no = has_fingerprint (blob, desc[n].u.fpr);
|
|
||||||
if (pk_no)
|
if (pk_no)
|
||||||
goto found;
|
goto found;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case KEYDB_SEARCH_MODE_FPR20:
|
||||||
|
pk_no = has_fingerprint (blob, desc[n].u.fpr, 20);
|
||||||
|
if (pk_no)
|
||||||
|
goto found;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEYDB_SEARCH_MODE_FPR32:
|
||||||
|
pk_no = has_fingerprint (blob, desc[n].u.fpr, 32);
|
||||||
|
if (pk_no)
|
||||||
|
goto found;
|
||||||
|
break;
|
||||||
|
|
||||||
case KEYDB_SEARCH_MODE_KEYGRIP:
|
case KEYDB_SEARCH_MODE_KEYGRIP:
|
||||||
if (has_keygrip (blob, desc[n].u.grip))
|
if (has_keygrip (blob, desc[n].u.grip))
|
||||||
goto found;
|
goto found;
|
||||||
|
@ -1052,6 +1052,7 @@ keydb_search_fpr (ctrl_t ctrl, KEYDB_HANDLE hd, const byte *fpr)
|
|||||||
memset (&desc, 0, sizeof desc);
|
memset (&desc, 0, sizeof desc);
|
||||||
desc.mode = KEYDB_SEARCH_MODE_FPR;
|
desc.mode = KEYDB_SEARCH_MODE_FPR;
|
||||||
memcpy (desc.u.fpr, fpr, 20);
|
memcpy (desc.u.fpr, fpr, 20);
|
||||||
|
desc.fprlen = 20;
|
||||||
return keydb_search (ctrl, hd, &desc, 1);
|
return keydb_search (ctrl, hd, &desc, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user