mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
gpg: Fix trustdb for v5key.
* g10/keydb.h (fpr20_from_pk): New. * g10/keyid.c (fpr20_from_pk): New. * g10/tdbio.c (tdbio_search_trust_byfpr): Use fpr20_from_pk. * g10/trustdb.c (keyid_from_fpr20): New. (verify_own_keys): Use keyid_from_fpr20. (tdb_update_ownertrust): Use fpr20_from_pk. (update_min_ownertrust): Likewise. (update_validity): Likewise. -- For the compatibility of existing implementation, we keep the format of trustdb untouched. The format of trustdb uses 20-byte fingerprint for the trust record entry. To handle both of v4key (with 20-byte fingerprint) and v5 key (with 32-byte fingerprint), we introduce FPR20 fingerprint, internally. For v4key, FPR20 is as same as v4 fingerprint. For v5key, FPR20 is constructed from v5key fingerprint. GnuPG-bug-id: 5000 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
20982bbd75
commit
373c975859
@ -553,6 +553,7 @@ const char *colon_datestr_from_pk (PKT_public_key *pk);
|
|||||||
const char *colon_datestr_from_sig (PKT_signature *sig);
|
const char *colon_datestr_from_sig (PKT_signature *sig);
|
||||||
const char *colon_expirestr_from_sig (PKT_signature *sig);
|
const char *colon_expirestr_from_sig (PKT_signature *sig);
|
||||||
byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
|
byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
|
||||||
|
void fpr20_from_pk (PKT_public_key *pk, byte array[20]);
|
||||||
char *hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen);
|
char *hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen);
|
||||||
char *format_hexfingerprint (const char *fingerprint,
|
char *format_hexfingerprint (const char *fingerprint,
|
||||||
char *buffer, size_t buflen);
|
char *buffer, size_t buflen);
|
||||||
|
32
g10/keyid.c
32
g10/keyid.c
@ -867,6 +867,38 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get FPR20 for the given PK/SK into ARRAY.
|
||||||
|
*
|
||||||
|
* FPR20 is special form of fingerprint of length 20 for the record of
|
||||||
|
* trustdb. For v4key, having fingerprint with SHA-1, FPR20 is the
|
||||||
|
* same one. For v5key, FPR20 is constructed from its fingerprint
|
||||||
|
* with SHA-2, so that its kid of last 8-byte can be as same as
|
||||||
|
* kid of v5key fingerprint.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fpr20_from_pk (PKT_public_key *pk, byte array[20])
|
||||||
|
{
|
||||||
|
if (!pk->fprlen)
|
||||||
|
compute_fingerprint (pk);
|
||||||
|
|
||||||
|
if (!array)
|
||||||
|
array = xmalloc (pk->fprlen);
|
||||||
|
|
||||||
|
if (pk->fprlen == 32) /* v5 fingerprint */
|
||||||
|
{
|
||||||
|
memcpy (array + 0, pk->fpr + 20, 4);
|
||||||
|
memcpy (array + 4, pk->fpr + 24, 4);
|
||||||
|
memcpy (array + 8, pk->fpr + 28, 4);
|
||||||
|
memcpy (array + 12, pk->fpr + 0, 4); /* kid[0] */
|
||||||
|
memcpy (array + 16, pk->fpr + 4, 4); /* kid[1] */
|
||||||
|
}
|
||||||
|
else /* v4 fingerprint */
|
||||||
|
memcpy (array, pk->fpr, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return an allocated buffer with the fingerprint of PK formatted as
|
/* Return an allocated buffer with the fingerprint of PK formatted as
|
||||||
* a plain hexstring. If BUFFER is NULL the result is a malloc'd
|
* a plain hexstring. If BUFFER is NULL the result is a malloc'd
|
||||||
* string. If BUFFER is not NULL the result will be copied into this
|
* string. If BUFFER is not NULL the result will be copied into this
|
||||||
|
@ -1909,12 +1909,9 @@ tdbio_search_trust_byfpr (ctrl_t ctrl, const byte *fingerprint, TRUSTREC *rec)
|
|||||||
gpg_error_t
|
gpg_error_t
|
||||||
tdbio_search_trust_bypk (ctrl_t ctrl, PKT_public_key *pk, TRUSTREC *rec)
|
tdbio_search_trust_bypk (ctrl_t ctrl, PKT_public_key *pk, TRUSTREC *rec)
|
||||||
{
|
{
|
||||||
byte fingerprint[MAX_FINGERPRINT_LEN];
|
byte fingerprint[20];
|
||||||
size_t fingerlen;
|
|
||||||
|
|
||||||
fingerprint_from_pk( pk, fingerprint, &fingerlen );
|
fpr20_from_pk (pk, fingerprint);
|
||||||
for (; fingerlen < 20; fingerlen++)
|
|
||||||
fingerprint[fingerlen] = 0;
|
|
||||||
return tdbio_search_trust_byfpr (ctrl, fingerprint, rec);
|
return tdbio_search_trust_byfpr (ctrl, fingerprint, rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,49 @@
|
|||||||
#include "tofu.h"
|
#include "tofu.h"
|
||||||
#include "key-clean.h"
|
#include "key-clean.h"
|
||||||
|
|
||||||
|
static u32
|
||||||
|
keyid_from_fpr20 (ctrl_t ctrl, const byte *fpr, u32 *keyid)
|
||||||
|
{
|
||||||
|
u32 dummy_keyid[2];
|
||||||
|
int fprlen;
|
||||||
|
|
||||||
|
if( !keyid )
|
||||||
|
keyid = dummy_keyid;
|
||||||
|
|
||||||
|
/* Problem: We do only use fingerprints in the trustdb but
|
||||||
|
* we need the keyID here to indetify the key; we can only
|
||||||
|
* use that ugly hack to distinguish between 16 and 20
|
||||||
|
* bytes fpr - it does not work always so we better change
|
||||||
|
* the whole validation code to only work with
|
||||||
|
* fingerprints */
|
||||||
|
fprlen = (!fpr[16] && !fpr[17] && !fpr[18] && !fpr[19])? 16:20;
|
||||||
|
|
||||||
|
if (fprlen != 20)
|
||||||
|
{
|
||||||
|
/* This is special as we have to lookup the key first. */
|
||||||
|
PKT_public_key pk;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
memset (&pk, 0, sizeof pk);
|
||||||
|
rc = get_pubkey_byfprint (ctrl, &pk, NULL, fpr, fprlen);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_printhex (fpr, fprlen,
|
||||||
|
"Oops: keyid_from_fingerprint: no pubkey; fpr:");
|
||||||
|
keyid[0] = 0;
|
||||||
|
keyid[1] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
keyid_from_pk (&pk, keyid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keyid[0] = buf32_to_u32 (fpr+12);
|
||||||
|
keyid[1] = buf32_to_u32 (fpr+16);
|
||||||
|
}
|
||||||
|
|
||||||
|
return keyid[1];
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */
|
typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */
|
||||||
|
|
||||||
@ -277,23 +320,14 @@ verify_own_keys (ctrl_t ctrl)
|
|||||||
/* scan the trustdb to find all ultimately trusted keys */
|
/* scan the trustdb to find all ultimately trusted keys */
|
||||||
for (recnum=1; !tdbio_read_record (recnum, &rec, 0); recnum++ )
|
for (recnum=1; !tdbio_read_record (recnum, &rec, 0); recnum++ )
|
||||||
{
|
{
|
||||||
if ( rec.rectype == RECTYPE_TRUST
|
if (rec.rectype == RECTYPE_TRUST
|
||||||
&& (rec.r.trust.ownertrust & TRUST_MASK) == TRUST_ULTIMATE)
|
&& (rec.r.trust.ownertrust & TRUST_MASK) == TRUST_ULTIMATE)
|
||||||
{
|
{
|
||||||
byte *fpr = rec.r.trust.fingerprint;
|
|
||||||
int fprlen;
|
|
||||||
u32 kid[2];
|
u32 kid[2];
|
||||||
|
|
||||||
/* Problem: We do only use fingerprints in the trustdb but
|
keyid_from_fpr20 (ctrl, rec.r.trust.fingerprint, kid);
|
||||||
* we need the keyID here to indetify the key; we can only
|
|
||||||
* use that ugly hack to distinguish between 16 and 20
|
|
||||||
* butes fpr - it does not work always so we better change
|
|
||||||
* the whole validation code to only work with
|
|
||||||
* fingerprints */
|
|
||||||
fprlen = (!fpr[16] && !fpr[17] && !fpr[18] && !fpr[19])? 16:20;
|
|
||||||
keyid_from_fingerprint (ctrl, fpr, fprlen, kid);
|
|
||||||
if (!add_utk (kid))
|
if (!add_utk (kid))
|
||||||
log_info(_("key %s occurs more than once in the trustdb\n"),
|
log_info (_("key %s occurs more than once in the trustdb\n"),
|
||||||
keystr(kid));
|
keystr(kid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -779,15 +813,13 @@ tdb_update_ownertrust (ctrl_t ctrl, PKT_public_key *pk, unsigned int new_trust )
|
|||||||
}
|
}
|
||||||
else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
||||||
{ /* no record yet - create a new one */
|
{ /* no record yet - create a new one */
|
||||||
size_t dummy;
|
|
||||||
|
|
||||||
if (DBG_TRUST)
|
if (DBG_TRUST)
|
||||||
log_debug ("insert ownertrust %u\n", new_trust );
|
log_debug ("insert ownertrust %u\n", new_trust );
|
||||||
|
|
||||||
memset (&rec, 0, sizeof rec);
|
memset (&rec, 0, sizeof rec);
|
||||||
rec.recnum = tdbio_new_recnum (ctrl);
|
rec.recnum = tdbio_new_recnum (ctrl);
|
||||||
rec.rectype = RECTYPE_TRUST;
|
rec.rectype = RECTYPE_TRUST;
|
||||||
fingerprint_from_pk (pk, rec.r.trust.fingerprint, &dummy);
|
fpr20_from_pk (pk, rec.r.trust.fingerprint);
|
||||||
rec.r.trust.ownertrust = new_trust;
|
rec.r.trust.ownertrust = new_trust;
|
||||||
write_record (ctrl, &rec);
|
write_record (ctrl, &rec);
|
||||||
tdb_revalidation_mark (ctrl);
|
tdb_revalidation_mark (ctrl);
|
||||||
@ -837,15 +869,13 @@ update_min_ownertrust (ctrl_t ctrl, u32 *kid, unsigned int new_trust)
|
|||||||
}
|
}
|
||||||
else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
||||||
{ /* no record yet - create a new one */
|
{ /* no record yet - create a new one */
|
||||||
size_t dummy;
|
|
||||||
|
|
||||||
if (DBG_TRUST)
|
if (DBG_TRUST)
|
||||||
log_debug ("insert min_ownertrust %u\n", new_trust );
|
log_debug ("insert min_ownertrust %u\n", new_trust );
|
||||||
|
|
||||||
memset (&rec, 0, sizeof rec);
|
memset (&rec, 0, sizeof rec);
|
||||||
rec.recnum = tdbio_new_recnum (ctrl);
|
rec.recnum = tdbio_new_recnum (ctrl);
|
||||||
rec.rectype = RECTYPE_TRUST;
|
rec.rectype = RECTYPE_TRUST;
|
||||||
fingerprint_from_pk (pk, rec.r.trust.fingerprint, &dummy);
|
fpr20_from_pk (pk, rec.r.trust.fingerprint);
|
||||||
rec.r.trust.min_ownertrust = new_trust;
|
rec.r.trust.min_ownertrust = new_trust;
|
||||||
write_record (ctrl, &rec);
|
write_record (ctrl, &rec);
|
||||||
tdb_revalidation_mark (ctrl);
|
tdb_revalidation_mark (ctrl);
|
||||||
@ -925,12 +955,10 @@ update_validity (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid,
|
|||||||
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
||||||
{
|
{
|
||||||
/* No record yet - create a new one. */
|
/* No record yet - create a new one. */
|
||||||
size_t dummy;
|
|
||||||
|
|
||||||
memset (&trec, 0, sizeof trec);
|
memset (&trec, 0, sizeof trec);
|
||||||
trec.recnum = tdbio_new_recnum (ctrl);
|
trec.recnum = tdbio_new_recnum (ctrl);
|
||||||
trec.rectype = RECTYPE_TRUST;
|
trec.rectype = RECTYPE_TRUST;
|
||||||
fingerprint_from_pk (pk, trec.r.trust.fingerprint, &dummy);
|
fpr20_from_pk (pk, trec.r.trust.fingerprint);
|
||||||
trec.r.trust.ownertrust = 0;
|
trec.r.trust.ownertrust = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user