mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg: Cache a once computed fingerprint in PKT_public_key.
* g10/packet.h (PKT_public_key): Add fields fpr and fprlen. * g10/keyid.c (do_fingerprint_md): Remove. (compute_fingerprint): New. (keyid_from_pk): Simplify. (fingerprint_from_pk): Simplify. (hexfingerprint): Avoid using extra array. -- This is similar to what we are doing with the keyid for a long time. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
1b1f649dea
commit
60f3845921
116
g10/keyid.c
116
g10/keyid.c
@ -253,20 +253,6 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
|
||||
}
|
||||
|
||||
|
||||
static gcry_md_hd_t
|
||||
do_fingerprint_md( PKT_public_key *pk )
|
||||
{
|
||||
gcry_md_hd_t md;
|
||||
|
||||
if (gcry_md_open (&md, pk->version == 5 ? GCRY_MD_SHA256 : GCRY_MD_SHA1, 0))
|
||||
BUG ();
|
||||
hash_public_key (md,pk);
|
||||
gcry_md_final (md);
|
||||
|
||||
return md;
|
||||
}
|
||||
|
||||
|
||||
/* fixme: Check whether we can replace this function or if not
|
||||
describe why we need it. */
|
||||
u32
|
||||
@ -520,6 +506,37 @@ keystr_from_desc(KEYDB_SEARCH_DESC *desc)
|
||||
}
|
||||
|
||||
|
||||
/* Compute the fingerprint and keyid and store it in PK. */
|
||||
static void
|
||||
compute_fingerprint (PKT_public_key *pk)
|
||||
{
|
||||
const byte *dp;
|
||||
gcry_md_hd_t md;
|
||||
size_t len;
|
||||
|
||||
if (gcry_md_open (&md, pk->version == 5 ? GCRY_MD_SHA256 : GCRY_MD_SHA1, 0))
|
||||
BUG ();
|
||||
hash_public_key (md, pk);
|
||||
gcry_md_final (md);
|
||||
dp = gcry_md_read (md, 0);
|
||||
len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
|
||||
log_assert (len <= MAX_FINGERPRINT_LEN);
|
||||
memcpy (pk->fpr, dp, len);
|
||||
pk->fprlen = len;
|
||||
if (pk->version == 5)
|
||||
{
|
||||
pk->keyid[0] = buf32_to_u32 (dp);
|
||||
pk->keyid[1] = buf32_to_u32 (dp+4);
|
||||
}
|
||||
else
|
||||
{
|
||||
pk->keyid[0] = buf32_to_u32 (dp+12);
|
||||
pk->keyid[1] = buf32_to_u32 (dp+16);
|
||||
}
|
||||
gcry_md_close( md);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the keyid from the public key PK and store it at KEYID unless
|
||||
* this is NULL. Returns the 32 bit short keyid.
|
||||
@ -532,37 +549,11 @@ keyid_from_pk (PKT_public_key *pk, u32 *keyid)
|
||||
if (!keyid)
|
||||
keyid = dummy_keyid;
|
||||
|
||||
if( pk->keyid[0] || pk->keyid[1] )
|
||||
{
|
||||
if (!pk->fprlen)
|
||||
compute_fingerprint (pk);
|
||||
|
||||
keyid[0] = pk->keyid[0];
|
||||
keyid[1] = pk->keyid[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
const byte *dp;
|
||||
gcry_md_hd_t md;
|
||||
|
||||
md = do_fingerprint_md(pk);
|
||||
if(md)
|
||||
{
|
||||
dp = gcry_md_read ( md, 0 );
|
||||
if (pk->version == 5)
|
||||
{
|
||||
keyid[0] = buf32_to_u32 (dp);
|
||||
keyid[1] = buf32_to_u32 (dp+4);
|
||||
}
|
||||
else
|
||||
{
|
||||
keyid[0] = buf32_to_u32 (dp+12);
|
||||
keyid[1] = buf32_to_u32 (dp+16);
|
||||
}
|
||||
gcry_md_close (md);
|
||||
pk->keyid[0] = keyid[0];
|
||||
pk->keyid[1] = keyid[1];
|
||||
}
|
||||
else
|
||||
pk->keyid[0] = pk->keyid[1] = keyid[0]= keyid[1] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
return keyid[1]; /*FIXME:shortkeyid ist different for v5*/
|
||||
}
|
||||
@ -805,6 +796,7 @@ colon_expirestr_from_sig (PKT_signature *sig)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Return a byte array with the fingerprint for the given PK/SK
|
||||
* The length of the array is returned in ret_len. Caller must free
|
||||
@ -813,31 +805,15 @@ colon_expirestr_from_sig (PKT_signature *sig)
|
||||
byte *
|
||||
fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
|
||||
{
|
||||
const byte *dp;
|
||||
size_t len;
|
||||
gcry_md_hd_t md;
|
||||
if (!pk->fprlen)
|
||||
compute_fingerprint (pk);
|
||||
|
||||
md = do_fingerprint_md (pk);
|
||||
dp = gcry_md_read (md, 0);
|
||||
len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
|
||||
log_assert (len <= MAX_FINGERPRINT_LEN);
|
||||
if (!array)
|
||||
array = xmalloc ( len );
|
||||
memcpy (array, dp, len );
|
||||
if (pk->version == 5)
|
||||
{
|
||||
pk->keyid[0] = buf32_to_u32 (dp);
|
||||
pk->keyid[1] = buf32_to_u32 (dp+4);
|
||||
}
|
||||
else
|
||||
{
|
||||
pk->keyid[0] = buf32_to_u32 (dp+12);
|
||||
pk->keyid[1] = buf32_to_u32 (dp+16);
|
||||
}
|
||||
gcry_md_close( md);
|
||||
array = xmalloc (pk->fprlen);
|
||||
memcpy (array, pk->fpr, pk->fprlen);
|
||||
|
||||
if (ret_len)
|
||||
*ret_len = len;
|
||||
*ret_len = pk->fprlen;
|
||||
return array;
|
||||
}
|
||||
|
||||
@ -852,19 +828,19 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
|
||||
char *
|
||||
hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen)
|
||||
{
|
||||
unsigned char fpr[MAX_FINGERPRINT_LEN];
|
||||
size_t len;
|
||||
if (!pk->fprlen)
|
||||
compute_fingerprint (pk);
|
||||
|
||||
fingerprint_from_pk (pk, fpr, &len);
|
||||
if (!buffer)
|
||||
{
|
||||
buffer = xtrymalloc (2 * len + 1);
|
||||
buffer = xtrymalloc (2 * pk->fprlen + 1);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
}
|
||||
else if (buflen < 2*len+1)
|
||||
else if (buflen < 2 * pk->fprlen + 1)
|
||||
log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen);
|
||||
bin2hex (fpr, len, buffer);
|
||||
|
||||
bin2hex (pk->fpr, pk->fprlen, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -394,6 +394,7 @@ typedef struct
|
||||
byte pubkey_algo;
|
||||
byte pubkey_usage; /* for now only used to pass it to getkey() */
|
||||
byte req_usage; /* hack to pass a request to getkey() */
|
||||
byte fprlen; /* 0 or length of FPR. */
|
||||
u32 has_expired; /* set to the expiration date if expired */
|
||||
/* keyid of the primary key. Never access this value directly.
|
||||
Instead, use pk_main_keyid(). */
|
||||
@ -401,6 +402,8 @@ typedef struct
|
||||
/* keyid of this key. Never access this value directly! Instead,
|
||||
use pk_keyid(). */
|
||||
u32 keyid[2];
|
||||
/* Fingerprint of the key. Only valid if FPRLEN is not 0. */
|
||||
byte fpr[MAX_FINGERPRINT_LEN];
|
||||
prefitem_t *prefs; /* list of preferences (may be NULL) */
|
||||
struct
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user