mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
overhauled the trustdb stuff
This commit is contained in:
parent
b9dd2ebb2c
commit
aad7f1a0fc
18
doc/FAQ
18
doc/FAQ
@ -282,6 +282,20 @@
|
|||||||
For more see the chapter "The Web of Trust" in the
|
For more see the chapter "The Web of Trust" in the
|
||||||
Manual [gpg: Oops: Internal error: manual not found - sorry]
|
Manual [gpg: Oops: Internal error: manual not found - sorry]
|
||||||
|
|
||||||
|
Q: How do interpret some of the informational outputs:
|
||||||
|
A: While checking the validness of a key, GnuPG sometimes print
|
||||||
|
some informations which are prefixed with information about
|
||||||
|
the checked item:
|
||||||
|
"key 12345678.3456"
|
||||||
|
This is about the key with key ID 12345678 and the internal
|
||||||
|
number 3456, which is the record number of the so called
|
||||||
|
directory record in the trustdb.
|
||||||
|
"uid 12345678.3456/ACDE"
|
||||||
|
This is about the user ID for the same key; to identify the
|
||||||
|
user ID the last two bytes of a ripe-md-160 over the user ID
|
||||||
|
tring is printed.
|
||||||
|
"sig 12345678.3456/ACDE/9A8B7C6D"
|
||||||
|
This is about the signature with key ID 9A8B7C6D for the
|
||||||
|
above key and user ID, if it is a signature which is direct
|
||||||
|
on a key, the user ID part is empty (..//..).
|
||||||
|
|
||||||
|
602
g10/trustdb.c
602
g10/trustdb.c
@ -98,6 +98,11 @@ static int list_sigs( ulong pubkey_id );
|
|||||||
static int do_check( TRUSTREC *drec, unsigned *trustlevel );
|
static int do_check( TRUSTREC *drec, unsigned *trustlevel );
|
||||||
static int get_dir_record( PKT_public_key *pk, TRUSTREC *rec );
|
static int get_dir_record( PKT_public_key *pk, TRUSTREC *rec );
|
||||||
|
|
||||||
|
static void upd_pref_record( TRUSTREC *urec, u32 *keyid, PKT_signature *sig );
|
||||||
|
static void upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
|
||||||
|
TRUSTREC *drec, RECNO_LIST *recno_list, int recheck,
|
||||||
|
TRUSTREC *urec, const byte *uidhash, int revoke );
|
||||||
|
|
||||||
|
|
||||||
/* a table used to keep track of ultimately trusted keys
|
/* a table used to keep track of ultimately trusted keys
|
||||||
* which are the ones from our secrings */
|
* which are the ones from our secrings */
|
||||||
@ -769,7 +774,12 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
|
|||||||
|
|
||||||
read_record( rn, &rec, RECTYPE_UID );
|
read_record( rn, &rec, RECTYPE_UID );
|
||||||
uidrn = rec.r.uid.next;
|
uidrn = rec.r.uid.next;
|
||||||
/* fixme: continue if the uidrec is not marked valid */
|
if( !(rec.r.uid.uidflags & UIDF_CHECKED) )
|
||||||
|
continue; /* user id has not been checked */
|
||||||
|
if( !(rec.r.uid.uidflags & UIDF_VALID) )
|
||||||
|
continue; /* user id is not valid */
|
||||||
|
if( (rec.r.uid.uidflags & UIDF_REVOKED) )
|
||||||
|
continue; /* user id has been revoked */
|
||||||
|
|
||||||
/* loop over all signature records */
|
/* loop over all signature records */
|
||||||
for( rn = rec.r.uid.siglist; rn; rn = sigrn ) {
|
for( rn = rec.r.uid.siglist; rn; rn = sigrn ) {
|
||||||
@ -1650,6 +1660,7 @@ check_hint_sig( ulong lid, KBNODE keyblock, u32 *keyid, byte *uidrec_hash,
|
|||||||
PKT_signature *sigpkt = NULL;
|
PKT_signature *sigpkt = NULL;
|
||||||
TRUSTREC tmp;
|
TRUSTREC tmp;
|
||||||
u32 sigkid[2];
|
u32 sigkid[2];
|
||||||
|
int revoke = 0;
|
||||||
|
|
||||||
if( sigrec->r.sig.sig[sigidx].flag & SIGF_CHECKED )
|
if( sigrec->r.sig.sig[sigidx].flag & SIGF_CHECKED )
|
||||||
log_info(_("note: sig rec %lu[%d] in hintlist "
|
log_info(_("note: sig rec %lu[%d] in hintlist "
|
||||||
@ -1664,7 +1675,7 @@ check_hint_sig( ulong lid, KBNODE keyblock, u32 *keyid, byte *uidrec_hash,
|
|||||||
if( tmp.rectype != RECTYPE_DIR ) {
|
if( tmp.rectype != RECTYPE_DIR ) {
|
||||||
/* we need the dir record */
|
/* we need the dir record */
|
||||||
log_error(_("sig rec %lu[%d] in hintlist "
|
log_error(_("sig rec %lu[%d] in hintlist "
|
||||||
"of %u does not point to a dir record\n"),
|
"of %lu does not point to a dir record\n"),
|
||||||
sigrec->recnum, sigidx, hint_owner );
|
sigrec->recnum, sigidx, hint_owner );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1693,7 +1704,8 @@ check_hint_sig( ulong lid, KBNODE keyblock, u32 *keyid, byte *uidrec_hash,
|
|||||||
sigpkt = node->pkt->pkt.signature;
|
sigpkt = node->pkt->pkt.signature;
|
||||||
if( sigpkt->keyid[0] == sigkid[0]
|
if( sigpkt->keyid[0] == sigkid[0]
|
||||||
&& sigpkt->keyid[1] == sigkid[1]
|
&& sigpkt->keyid[1] == sigkid[1]
|
||||||
&& (sigpkt->sig_class&~3) == 0x10 ) {
|
&& ( (sigpkt->sig_class&~3) == 0x10
|
||||||
|
|| ( revoke = (sigpkt->sig_class == 0x30)) ) ) {
|
||||||
state = 2;
|
state = 2;
|
||||||
break; /* found */
|
break; /* found */
|
||||||
}
|
}
|
||||||
@ -1715,23 +1727,29 @@ check_hint_sig( ulong lid, KBNODE keyblock, u32 *keyid, byte *uidrec_hash,
|
|||||||
log_error(_("lid %lu: self-signature in hintlist\n"), lid );
|
log_error(_("lid %lu: self-signature in hintlist\n"), lid );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FiXME: handling fo SIGF_REVOKED is not correct! */
|
||||||
|
|
||||||
if( !rc ) { /* valid signature */
|
if( !rc ) { /* valid signature */
|
||||||
if( opt.verbose )
|
if( opt.verbose )
|
||||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
|
log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
|
||||||
"Good signature (3)\n"),
|
|
||||||
(ulong)keyid[1], lid, uhash[18], uhash[19],
|
(ulong)keyid[1], lid, uhash[18], uhash[19],
|
||||||
(ulong)sigpkt->keyid[1] );
|
(ulong)sigpkt->keyid[1],
|
||||||
|
revoke? _("Valid certificate revocation")
|
||||||
|
: _("Good certificate") );
|
||||||
sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED | SIGF_VALID;
|
sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED | SIGF_VALID;
|
||||||
|
if( revoke )
|
||||||
|
sigrec->r.sig.sig[sigidx].flag |= SIGF_REVOKED;
|
||||||
}
|
}
|
||||||
else if( rc == G10ERR_NO_PUBKEY ) {
|
else if( rc == G10ERR_NO_PUBKEY ) {
|
||||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
|
log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
|
||||||
"very strange: no public key\n"),
|
|
||||||
(ulong)keyid[1], lid, uhash[18], uhash[19],
|
(ulong)keyid[1], lid, uhash[18], uhash[19],
|
||||||
(ulong)sigpkt->keyid[1] );
|
(ulong)sigpkt->keyid[1],
|
||||||
|
_("very strange: no public key\n") );
|
||||||
sigrec->r.sig.sig[sigidx].flag = SIGF_NOPUBKEY;
|
sigrec->r.sig.sig[sigidx].flag = SIGF_NOPUBKEY;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: %s\n"),
|
log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
|
||||||
(ulong)keyid[1], lid, uhash[18], uhash[19],
|
(ulong)keyid[1], lid, uhash[18], uhash[19],
|
||||||
(ulong)sigpkt->keyid[1], g10_errstr(rc) );
|
(ulong)sigpkt->keyid[1], g10_errstr(rc) );
|
||||||
sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED;
|
sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED;
|
||||||
@ -1923,8 +1941,8 @@ upd_key_record( KBNODE keyblock, KBNODE keynode, u32 *keyid,
|
|||||||
{
|
{
|
||||||
TRUSTREC krec;
|
TRUSTREC krec;
|
||||||
KBNODE node;
|
KBNODE node;
|
||||||
PKT_public_key *pk = keynode->pkt->pkt.public_key,;
|
PKT_public_key *pk = keynode->pkt->pkt.public_key;
|
||||||
ulon lid = drec->recnum;
|
ulong lid = drec->recnum;
|
||||||
byte fpr[MAX_FINGERPRINT_LEN];
|
byte fpr[MAX_FINGERPRINT_LEN];
|
||||||
size_t fprlen;
|
size_t fprlen;
|
||||||
ulong recno, newrecno;
|
ulong recno, newrecno;
|
||||||
@ -1982,75 +2000,78 @@ upd_key_record( KBNODE keyblock, KBNODE keynode, u32 *keyid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for( node=keynode->next; node; node = node->next ) {
|
for( node=keynode->next; node; node = node->next ) {
|
||||||
|
PKT_signature *sig;
|
||||||
|
|
||||||
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||||
break; /* ready */
|
break; /* ready */
|
||||||
else if( node->pkt->pkttype == PKT_PUBLIC_SIGNATURE ) {
|
else if( node->pkt->pkttype != PKT_SIGNATURE )
|
||||||
PKT_signature *sig = node->pkt->pkt.signature;
|
continue;
|
||||||
|
|
||||||
if( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] )
|
sig = node->pkt->pkt.signature;
|
||||||
continue; /* not a self signature */
|
|
||||||
if( sig->sig_class == 0x18 && !keybind_seen ) { /* a keybinding */
|
if( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] )
|
||||||
if( keynode->pkt->pkttype == PKT_PUBLIC_KEY )
|
continue; /* not a self signature */
|
||||||
continue; /* oops, not for a main key */
|
if( sig->sig_class == 0x18 && !keybind_seen ) { /* a keybinding */
|
||||||
/* we check until we find a valid keybinding */
|
if( keynode->pkt->pkttype == PKT_PUBLIC_KEY )
|
||||||
rc = check_key_signature( keyblock, node, NULL );
|
continue; /* oops, not for a main key */
|
||||||
if( !rc ) {
|
/* we check until we find a valid keybinding */
|
||||||
if( opt.verbose )
|
rc = check_key_signature( keyblock, node, NULL );
|
||||||
log_info(_(
|
if( !rc ) {
|
||||||
"key %08lX.%lu: Good subkey binding\n"),
|
if( opt.verbose )
|
||||||
(ulong)keyid_from_pk(pk,NULL), lid );
|
|
||||||
krec.r.key.keyflags |= KEYF_CHECKED | KEYF_VALID;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log_info(_(
|
log_info(_(
|
||||||
"key %08lX.%lu: Invalid subkey binding: %s\n"),
|
"key %08lX.%lu: Good subkey binding\n"),
|
||||||
(ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
|
(ulong)keyid_from_pk(pk,NULL), lid );
|
||||||
krec.r.key.keyflags |= KEYF_CHECKED;
|
krec.r.key.keyflags |= KEYF_CHECKED | KEYF_VALID;
|
||||||
krec.r.key.keyflags &= ~KEYF_VALID;
|
|
||||||
}
|
|
||||||
keybind_seen = 1;
|
|
||||||
}
|
}
|
||||||
else if( sig->sig_class == 0x20 && !revoke_seen ) {
|
else {
|
||||||
if( keynode->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
log_info(_(
|
||||||
continue; /* a subkey is not expected here */
|
"key %08lX.%lu: Invalid subkey binding: %s\n"),
|
||||||
/* This is a key revocation certificate: check it */
|
(ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
|
||||||
rc = check_key_signature( keyblock, node, NULL );
|
krec.r.key.keyflags |= KEYF_CHECKED;
|
||||||
if( !rc ) {
|
krec.r.key.keyflags &= ~KEYF_VALID;
|
||||||
if( opt.verbose )
|
}
|
||||||
log_info(_(
|
keybind_seen = 1;
|
||||||
"key %08lX.%lu: Valid key revocation\n"),
|
}
|
||||||
(ulong)keyid_from_pk(pk,NULL), lid );
|
else if( sig->sig_class == 0x20 && !revoke_seen ) {
|
||||||
krec.r.key.keyflags |= KEYF_REVOKED;
|
if( keynode->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||||
}
|
continue; /* a subkey is not expected here */
|
||||||
else {
|
/* This is a key revocation certificate: check it */
|
||||||
|
rc = check_key_signature( keyblock, node, NULL );
|
||||||
|
if( !rc ) {
|
||||||
|
if( opt.verbose )
|
||||||
log_info(_(
|
log_info(_(
|
||||||
"key %08lX.%lu: Invalid key revocation: %s\n"),
|
"key %08lX.%lu: Valid key revocation\n"),
|
||||||
(ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
|
(ulong)keyid_from_pk(pk,NULL), lid );
|
||||||
}
|
krec.r.key.keyflags |= KEYF_REVOKED;
|
||||||
revoke_seen = 1;
|
|
||||||
}
|
}
|
||||||
else if( sig->sig_class == 0x28 && !revoke_seen ) {
|
else {
|
||||||
if( keynode->pkt->pkttype == PKT_PUBLIC_KEY )
|
log_info(_(
|
||||||
continue; /* a mainkey is not expected here */
|
"key %08lX.%lu: Invalid key revocation: %s\n"),
|
||||||
/* This is a subkey revocation certificate: check it */
|
(ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
|
||||||
/* fixme: we should also check the revocation
|
}
|
||||||
* is newer tha the key (OpenPGP) */
|
revoke_seen = 1;
|
||||||
rc = check_key_signature( keyblock, node, NULL );
|
}
|
||||||
if( !rc ) {
|
else if( sig->sig_class == 0x28 && !revoke_seen ) {
|
||||||
if( opt.verbose )
|
if( keynode->pkt->pkttype == PKT_PUBLIC_KEY )
|
||||||
log_info(_(
|
continue; /* a mainkey is not expected here */
|
||||||
"key %08lX.%lu: Valid subkey revocation\n"),
|
/* This is a subkey revocation certificate: check it */
|
||||||
(ulong)keyid_from_pk(pk,NULL), lid );
|
/* fixme: we should also check the revocation
|
||||||
krec.r.key.keyflags |= KEYF_REVOKED;
|
* is newer than the key (OpenPGP) */
|
||||||
}
|
rc = check_key_signature( keyblock, node, NULL );
|
||||||
else {
|
if( !rc ) {
|
||||||
|
if( opt.verbose )
|
||||||
log_info(_(
|
log_info(_(
|
||||||
"key %08lX.%lu: Invalid subkey binding: %s\n"),
|
"key %08lX.%lu: Valid subkey revocation\n"),
|
||||||
(ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
|
(ulong)keyid_from_pk(pk,NULL), lid );
|
||||||
}
|
krec.r.key.keyflags |= KEYF_REVOKED;
|
||||||
revoke_seen = 1;
|
|
||||||
}
|
}
|
||||||
} /* end signature */
|
else {
|
||||||
|
log_info(_(
|
||||||
|
"key %08lX.%lu: Invalid subkey binding: %s\n"),
|
||||||
|
(ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
|
||||||
|
}
|
||||||
|
revoke_seen = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write_record( &krec );
|
write_record( &krec );
|
||||||
@ -2076,22 +2097,24 @@ upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
|
|||||||
ulong lid = drec->recnum;
|
ulong lid = drec->recnum;
|
||||||
PKT_user_id *uid = uidnode->pkt->pkt.user_id;
|
PKT_user_id *uid = uidnode->pkt->pkt.user_id;
|
||||||
TRUSTREC urec;
|
TRUSTREC urec;
|
||||||
|
PKT_signature *selfsig = NULL;
|
||||||
byte uidhash[20];
|
byte uidhash[20];
|
||||||
|
KBNODE node;
|
||||||
ulong recno, newrecno;
|
ulong recno, newrecno;
|
||||||
|
int rc;
|
||||||
|
|
||||||
/* see whether we already have an uid record */
|
/* see whether we already have an uid record */
|
||||||
WORK WORK
|
|
||||||
rmd160_hash_buffer( uidhash, uid->name, uid->len );
|
rmd160_hash_buffer( uidhash, uid->name, uid->len );
|
||||||
for( recno=drec->r.dir.uidlist; recno; recno = urec.r.uid.next ) {
|
for( recno=drec->r.dir.uidlist; recno; recno = urec.r.uid.next ) {
|
||||||
read_record( recno, &urec, RECTYPE_UID );
|
read_record( recno, &urec, RECTYPE_UID );
|
||||||
if( !memcmp( uidhash, urec.r.uid.namehash, 20 ) )
|
if( !memcmp( uidhash, urec.r.uid.namehash, 20 ) )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( recno ) {
|
if( recno ) { /* we already have this record */
|
||||||
ins_recno_list( recno_list, recno, RECTYPE_UID );
|
ins_recno_list( recno_list, recno, RECTYPE_UID );
|
||||||
*uidrecno = recno;
|
|
||||||
}
|
}
|
||||||
else { /* new user id */
|
else { /* new user id */
|
||||||
|
recheck = 1;
|
||||||
memset( &urec, 0 , sizeof(urec) );
|
memset( &urec, 0 , sizeof(urec) );
|
||||||
urec.rectype = RECTYPE_UID;
|
urec.rectype = RECTYPE_UID;
|
||||||
urec.r.uid.lid = drec->recnum;
|
urec.r.uid.lid = drec->recnum;
|
||||||
@ -2105,131 +2128,229 @@ upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
|
|||||||
drec->dirty = 1;
|
drec->dirty = 1;
|
||||||
}
|
}
|
||||||
else { /* we already have an uid, append it to the list */
|
else { /* we already have an uid, append it to the list */
|
||||||
|
TRUSTREC save = urec;
|
||||||
for( ; recno; recno = urec.r.key.next )
|
for( ; recno; recno = urec.r.key.next )
|
||||||
read_record( recno, &urec, RECTYPE_UID );
|
read_record( recno, &urec, RECTYPE_UID );
|
||||||
urec.r.uid.next = newrecno;
|
urec.r.uid.next = newrecno;
|
||||||
write_record( &urec );
|
write_record( &urec );
|
||||||
|
urec = save;
|
||||||
}
|
}
|
||||||
*uidrecno = newrecno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( recheck || !(urec.r.uid.uidflags & UIDF_CHECKED) ) {
|
||||||
|
/* check self signatures */
|
||||||
|
urec.r.uid.uidflags = 0;
|
||||||
|
for( node=uidnode->next; node; node = node->next ) {
|
||||||
|
PKT_signature *sig;
|
||||||
|
|
||||||
|
if( node->pkt->pkttype == PKT_USER_ID )
|
||||||
|
break; /* ready */
|
||||||
|
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||||
|
break; /* ready */
|
||||||
|
if( node->pkt->pkttype != PKT_SIGNATURE )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sig = node->pkt->pkt.signature;
|
||||||
|
|
||||||
|
if( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] )
|
||||||
|
continue; /* not a self signature */
|
||||||
|
|
||||||
|
if( (sig->sig_class&~3) == 0x10 ) { /* regular self signature */
|
||||||
|
rc = check_key_signature( keyblock, node, NULL );
|
||||||
|
if( !rc ) {
|
||||||
|
if( opt.verbose )
|
||||||
|
log_info( "uid %08lX.%lu/%02X%02X: %s\n",
|
||||||
|
(ulong)keyid[1], lid, uidhash[18], uidhash[19],
|
||||||
|
_("Good self-signature") );
|
||||||
|
urec.r.uid.uidflags |= UIDF_CHECKED | UIDF_VALID;
|
||||||
|
if( !selfsig )
|
||||||
|
selfsig = sig; /* use the first valid sig */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log_info( "uid %08lX/%02X%02X: %s: %s\n",
|
||||||
|
(ulong)keyid[1], uidhash[18], uidhash[19],
|
||||||
|
_("Invalid self-signature"),
|
||||||
|
g10_errstr(rc) );
|
||||||
|
urec.r.uid.uidflags |= UIDF_CHECKED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( sig->sig_class == 0x30 ) { /* cert revocation */
|
||||||
|
rc = check_key_signature( keyblock, node, NULL );
|
||||||
|
if( !rc ) {
|
||||||
|
if( opt.verbose )
|
||||||
|
log_info( "uid %08lX.%lu/%02X%02X: %s\n",
|
||||||
|
(ulong)keyid[1], lid, uidhash[18], uidhash[19],
|
||||||
|
_("Valid user ID revocation\n") );
|
||||||
|
urec.r.uid.uidflags |= UIDF_CHECKED | UIDF_VALID;
|
||||||
|
urec.r.uid.uidflags |= UIDF_REVOKED;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log_info("uid %08lX/%02X%02X: %s: %s\n",
|
||||||
|
(ulong)keyid[1], uidhash[18], uidhash[19],
|
||||||
|
_("Invalid user ID revocation"),
|
||||||
|
g10_errstr(rc) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write_record( &urec );
|
||||||
|
} /* end check self-signatures */
|
||||||
|
|
||||||
|
|
||||||
|
if( (urec.r.uid.uidflags & (UIDF_CHECKED|UIDF_VALID))
|
||||||
|
!= (UIDF_CHECKED|UIDF_VALID) )
|
||||||
|
return; /* user ID is not valid, so no need to check more things */
|
||||||
|
|
||||||
|
/* check the preferences */
|
||||||
|
if( selfsig )
|
||||||
|
upd_pref_record( &urec, keyid, selfsig );
|
||||||
|
|
||||||
|
/* check non-self signatures */
|
||||||
|
for( node=uidnode->next; node; node = node->next ) {
|
||||||
|
PKT_signature *sig;
|
||||||
|
|
||||||
|
if( node->pkt->pkttype == PKT_USER_ID )
|
||||||
|
break; /* ready */
|
||||||
|
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||||
|
break; /* ready */
|
||||||
|
if( node->pkt->pkttype != PKT_SIGNATURE )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sig = node->pkt->pkt.signature;
|
||||||
|
|
||||||
|
if( keyid[0] == sig->keyid[0] || keyid[1] == sig->keyid[1] )
|
||||||
|
continue; /* skip self signature */
|
||||||
|
|
||||||
|
if( (sig->sig_class&~3) == 0x10 ) { /* regular certification */
|
||||||
|
upd_cert_record( keyblock, node, keyid, drec, recno_list,
|
||||||
|
recheck, &urec, uidhash, 0 );
|
||||||
|
}
|
||||||
|
else if( sig->sig_class == 0x30 ) { /* cert revocation */
|
||||||
|
upd_cert_record( keyblock, node, keyid, drec, recno_list,
|
||||||
|
recheck, &urec, uidhash, 1 );
|
||||||
|
}
|
||||||
|
} /* end check certificates */
|
||||||
|
|
||||||
|
write_record( &urec );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
upd_pref_record( PKT_signature *sig, ulong lid, const u32 *keyid,
|
upd_pref_record( TRUSTREC *urec, u32 *keyid, PKT_signature *sig )
|
||||||
TRUSTREC *urec, const byte *uidhash )
|
|
||||||
{
|
{
|
||||||
static struct {
|
static struct {
|
||||||
sigsubpkttype_t subpkttype;
|
sigsubpkttype_t subpkttype;
|
||||||
int preftype;
|
int preftype;
|
||||||
} prefs[] = {
|
} ptable[] = {
|
||||||
{ SIGSUBPKT_PREF_SYM, PREFTYPE_SYM },
|
{ SIGSUBPKT_PREF_SYM, PREFTYPE_SYM },
|
||||||
{ SIGSUBPKT_PREF_HASH, PREFTYPE_HASH },
|
{ SIGSUBPKT_PREF_HASH, PREFTYPE_HASH },
|
||||||
{ SIGSUBPKT_PREF_COMPR, PREFTYPE_COMPR },
|
{ SIGSUBPKT_PREF_COMPR, PREFTYPE_COMPR },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
TRUSTREC prec;
|
TRUSTREC prec;
|
||||||
|
ulong lid = urec->r.uid.lid ;
|
||||||
|
const byte *uidhash = urec->r.uid.namehash;
|
||||||
const byte *s;
|
const byte *s;
|
||||||
size_t n;
|
size_t n;
|
||||||
int k, i;
|
int k, i;
|
||||||
ulong recno_tbl[10];
|
|
||||||
int recno_idx = 0;
|
|
||||||
ulong recno;
|
ulong recno;
|
||||||
|
byte prefs_sig[200];
|
||||||
|
int n_prefs_sig = 0;
|
||||||
|
byte prefs_rec[200];
|
||||||
|
int n_prefs_rec = 0;
|
||||||
|
|
||||||
/* First delete all pref records
|
/* check for changed preferences */
|
||||||
|
for(k=0; ptable[k].subpkttype; k++ ) {
|
||||||
|
s = parse_sig_subpkt2( sig, ptable[k].subpkttype, &n );
|
||||||
|
if( s ) {
|
||||||
|
if( n_prefs_sig >= DIM(prefs_sig)-1 ) {
|
||||||
|
log_info("uid %08lX.%lu/%02X%02X: %s\n",
|
||||||
|
(ulong)keyid[1], lid, uidhash[18], uidhash[19],
|
||||||
|
_("Too many preferences") );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prefs_sig[n_prefs_sig++] = ptable[k].preftype;
|
||||||
|
prefs_sig[n_prefs_sig++] = *s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for( recno=urec->r.uid.prefrec; recno; recno = prec.r.pref.next ) {
|
||||||
|
read_record( recno, &prec, RECTYPE_PREF );
|
||||||
|
for(i = 0; i < ITEMS_PER_PREF_RECORD; i +=2 ) {
|
||||||
|
if( n_prefs_rec >= DIM(prefs_rec)-1 ) {
|
||||||
|
log_info("uid %08lX.%lu/%02X%02X: %s\n",
|
||||||
|
(ulong)keyid[1], lid, uidhash[18], uidhash[19],
|
||||||
|
_("Too many preferences items") );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prefs_rec[n_prefs_rec++] = prec.r.pref.data[i];
|
||||||
|
prefs_rec[n_prefs_rec++] = prec.r.pref.data[i+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( n_prefs_sig == n_prefs_rec
|
||||||
|
&& !memcmp( prefs_sig, prefs_rec, n_prefs_sig ) )
|
||||||
|
return; /* not chnaged */
|
||||||
|
|
||||||
|
/* Preferences have changed: Delete all pref records
|
||||||
* This is much simpler than checking whether we have to
|
* This is much simpler than checking whether we have to
|
||||||
* do update the record at all - the record cache may care about it
|
* do update the record at all - the record cache may care about it
|
||||||
* FIXME: We never get correct statistics if we do it like this */
|
*/
|
||||||
for( recno=urec->r.uid.prefrec; recno; recno = prec.r.pref.next ) {
|
for( recno=urec->r.uid.prefrec; recno; recno = prec.r.pref.next ) {
|
||||||
read_record( recno, &prec, RECTYPE_PREF );
|
read_record( recno, &prec, RECTYPE_PREF );
|
||||||
delete_record( recno );
|
delete_record( recno );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* and write the new ones */
|
if( n_prefs_sig > ITEMS_PER_PREF_RECORD )
|
||||||
i = 0;
|
log_info("cannot yet handle long preferences");
|
||||||
for(k=0; prefs[k].subpkttype; k++ ) {
|
|
||||||
s = parse_sig_subpkt2( sig, prefs[k].subpkttype, &n );
|
memset( &prec, 0, sizeof prec );
|
||||||
if( s ) {
|
prec.recnum = tdbio_new_recnum();
|
||||||
while( n ) {
|
prec.rectype = RECTYPE_PREF;
|
||||||
if( !i || i >= ITEMS_PER_PREF_RECORD ) {
|
prec.r.pref.lid = lid;
|
||||||
if( recno_idx >= DIM(recno_tbl)-1 ) {
|
if( n_prefs_sig <= ITEMS_PER_PREF_RECORD )
|
||||||
log_info("too many preferences\n");
|
memcpy( prec.r.pref.data, prefs_sig, n_prefs_sig );
|
||||||
break;
|
else { /* need more than one pref record */
|
||||||
}
|
TRUSTREC tmp;
|
||||||
if( i ) {
|
ulong nextrn;
|
||||||
recno_tbl[recno_idx]=tdbio_new_recnum();
|
int n = n_prefs_sig;
|
||||||
prec.recnum = recno_tbl[recno_idx++];
|
byte *pp = prefs_sig;
|
||||||
write_record( &prec );
|
|
||||||
}
|
memcpy( prec.r.pref.data, pp, ITEMS_PER_PREF_RECORD );
|
||||||
memset( &prec, 0, sizeof prec );
|
n -= ITEMS_PER_PREF_RECORD;
|
||||||
prec.rectype = RECTYPE_PREF;
|
pp += ITEMS_PER_PREF_RECORD;
|
||||||
prec.r.pref.lid = lid;
|
nextrn = prec.r.pref.next = tdbio_new_recnum();
|
||||||
i = 0;
|
do {
|
||||||
}
|
memset( &tmp, 0, sizeof tmp );
|
||||||
prec.r.pref.data[i++] = prefs[k].preftype;
|
tmp.recnum = nextrn;
|
||||||
prec.r.pref.data[i++] = *s++;
|
tmp.rectype = RECTYPE_PREF;
|
||||||
n--;
|
tmp.r.pref.lid = lid;
|
||||||
|
if( n <= ITEMS_PER_PREF_RECORD ) {
|
||||||
|
memcpy( tmp.r.pref.data, pp, n );
|
||||||
|
n = 0;
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
memcpy( tmp.r.pref.data, pp, ITEMS_PER_PREF_RECORD );
|
||||||
|
n -= ITEMS_PER_PREF_RECORD;
|
||||||
|
pp += ITEMS_PER_PREF_RECORD;
|
||||||
|
nextrn = tmp.r.pref.next = tdbio_new_recnum();
|
||||||
|
}
|
||||||
|
write_record( &tmp );
|
||||||
|
} while( n );
|
||||||
}
|
}
|
||||||
if( i ) { /* write the last one */
|
write_record( &prec );
|
||||||
recno_tbl[recno_idx]=tdbio_new_recnum();
|
urec->r.uid.prefrec = prec.recnum;
|
||||||
prec.recnum = recno_tbl[recno_idx++];
|
|
||||||
write_record( &prec );
|
|
||||||
}
|
|
||||||
/* now link them together */
|
|
||||||
for(i=0; i < recno_idx-1; i++ ) {
|
|
||||||
read_record( recno_tbl[i], &prec, RECTYPE_PREF );
|
|
||||||
prec.r.pref.next = recno_tbl[i+1];
|
|
||||||
write_record( &prec );
|
|
||||||
}
|
|
||||||
/* don't need to write the last one, but update the uid */
|
|
||||||
urec->r.uid.prefrec = recno_idx? recno_tbl[0] : 0;
|
|
||||||
urec->dirty = 1;
|
urec->dirty = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
|
||||||
* update self key signatures (class 0x10..0x13)
|
|
||||||
*/
|
|
||||||
static void
|
static void
|
||||||
upd_self_key_sigs( PKT_signature *sig, TRUSTREC *urec,
|
upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
|
||||||
ulong lid, const u32 *keyid, const byte *uidhash,
|
TRUSTREC *drec, RECNO_LIST *recno_list, int recheck,
|
||||||
KBNODE keyblock, KBNODE signode)
|
TRUSTREC *urec, const byte *uidhash, int revoke )
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* must verify this selfsignature here, so that we can
|
|
||||||
* build the preference record and validate the uid record
|
|
||||||
*/
|
|
||||||
if( !(urec->r.uid.uidflags & UIDF_CHECKED) ) {
|
|
||||||
rc = check_key_signature( keyblock, signode, NULL );
|
|
||||||
if( !rc ) {
|
|
||||||
if( opt.verbose )
|
|
||||||
log_info(_(
|
|
||||||
"key %08lX.%lu, uid %02X%02X: Good self-signature\n"),
|
|
||||||
(ulong)keyid[1], lid, uidhash[18], uidhash[19] );
|
|
||||||
upd_pref_record( sig, lid, keyid, urec, uidhash );
|
|
||||||
urec->r.uid.uidflags = UIDF_CHECKED | UIDF_VALID;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log_info(_("key %08lX, uid %02X%02X: Invalid self-signature: %s\n"),
|
|
||||||
(ulong)keyid[1], uidhash[18], uidhash[19], g10_errstr(rc) );
|
|
||||||
urec->r.uid.uidflags = UIDF_CHECKED;
|
|
||||||
}
|
|
||||||
urec->dirty = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************
|
|
||||||
* update non-self key signatures (class 0x10..0x13)
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
upd_nonself_key_sigs( PKT_signature *sig, TRUSTREC *urec,
|
|
||||||
ulong lid, const u32 *keyid, const byte *uidhash,
|
|
||||||
KBNODE keyblock, KBNODE signode, int fast)
|
|
||||||
{
|
{
|
||||||
/* We simply insert the signature into the sig records but
|
/* We simply insert the signature into the sig records but
|
||||||
* avoid duplicate ones. We do not check them here because
|
* avoid duplicate ones. We do not check them here because
|
||||||
@ -2240,6 +2361,8 @@ upd_nonself_key_sigs( PKT_signature *sig, TRUSTREC *urec,
|
|||||||
* be converted to a dir record as soon as a new public key is
|
* be converted to a dir record as soon as a new public key is
|
||||||
* inserted into the trustdb.
|
* inserted into the trustdb.
|
||||||
*/
|
*/
|
||||||
|
ulong lid = drec->recnum;
|
||||||
|
PKT_signature *sig = signode->pkt->pkt.signature;
|
||||||
TRUSTREC rec;
|
TRUSTREC rec;
|
||||||
ulong recno;
|
ulong recno;
|
||||||
TRUSTREC delrec;
|
TRUSTREC delrec;
|
||||||
@ -2294,19 +2417,19 @@ upd_nonself_key_sigs( PKT_signature *sig, TRUSTREC *urec,
|
|||||||
}
|
}
|
||||||
if( rec.r.sig.sig[i].lid == pk_lid ) {
|
if( rec.r.sig.sig[i].lid == pk_lid ) {
|
||||||
if( found_sig ) {
|
if( found_sig ) {
|
||||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
|
log_info( "sig %08lX.%lu/%02X%02X/%08lX: %s\n",
|
||||||
"duplicated signature - deleted\n"),
|
(ulong)keyid[1], lid, uidhash[18],
|
||||||
(ulong)keyid[1], lid, uidhash[18],
|
uidhash[19], (ulong)sig->keyid[1],
|
||||||
uidhash[19], (ulong)sig->keyid[1] );
|
_("Duplicated certificate - deleted") );
|
||||||
rec.r.sig.sig[i].lid = 0;
|
rec.r.sig.sig[i].lid = 0;
|
||||||
rec.dirty = 1;
|
rec.dirty = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
found_sig = 1;
|
found_sig = 1;
|
||||||
}
|
}
|
||||||
if( fast && (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
|
if( !recheck && !revoke && (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
|
||||||
continue; /* we already checked this signature */
|
continue; /* we already checked this signature */
|
||||||
if( fast && (rec.r.sig.sig[i].flag & SIGF_NOPUBKEY) )
|
if( !recheck && (rec.r.sig.sig[i].flag & SIGF_NOPUBKEY) )
|
||||||
continue; /* we do not have the public key */
|
continue; /* we do not have the public key */
|
||||||
|
|
||||||
read_record( rec.r.sig.sig[i].lid, &tmp, 0 );
|
read_record( rec.r.sig.sig[i].lid, &tmp, 0 );
|
||||||
@ -2315,28 +2438,35 @@ upd_nonself_key_sigs( PKT_signature *sig, TRUSTREC *urec,
|
|||||||
rc = check_key_signature( keyblock, signode, NULL );
|
rc = check_key_signature( keyblock, signode, NULL );
|
||||||
if( !rc ) { /* valid signature */
|
if( !rc ) { /* valid signature */
|
||||||
if( opt.verbose )
|
if( opt.verbose )
|
||||||
log_info(_(
|
log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
|
||||||
"key %08lX.%lu, uid %02X%02X, sig %08lX: "
|
|
||||||
"Good signature (1)\n"),
|
|
||||||
(ulong)keyid[1], lid, uidhash[18],
|
(ulong)keyid[1], lid, uidhash[18],
|
||||||
uidhash[19], (ulong)sig->keyid[1] );
|
uidhash[19], (ulong)sig->keyid[1],
|
||||||
|
revoke? _("Valid certificate revocation")
|
||||||
|
: _("Good certificate") );
|
||||||
rec.r.sig.sig[i].flag = SIGF_CHECKED | SIGF_VALID;
|
rec.r.sig.sig[i].flag = SIGF_CHECKED | SIGF_VALID;
|
||||||
|
if( revoke )
|
||||||
|
rec.r.sig.sig[i].flag |= SIGF_REVOKED;
|
||||||
}
|
}
|
||||||
else if( rc == G10ERR_NO_PUBKEY ) {
|
else if( rc == G10ERR_NO_PUBKEY ) {
|
||||||
if( (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
|
if( (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
|
||||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
|
log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
|
||||||
"public key lost\n"),
|
|
||||||
(ulong)keyid[1], lid, uidhash[18],
|
(ulong)keyid[1], lid, uidhash[18],
|
||||||
uidhash[19], (ulong)sig->keyid[1] );
|
uidhash[19], (ulong)sig->keyid[1],
|
||||||
|
_("public key lost") );
|
||||||
rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
|
rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
|
||||||
|
if( revoke )
|
||||||
|
rec.r.sig.sig[i].flag |= SIGF_REVOKED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX:"
|
log_info("sig %08lX.%lu/%02X%02X/%08lX: %s: %s\n",
|
||||||
" %s\n"),
|
|
||||||
(ulong)keyid[1], lid, uidhash[18],
|
(ulong)keyid[1], lid, uidhash[18],
|
||||||
uidhash[19], (ulong)sig->keyid[1],
|
uidhash[19], (ulong)sig->keyid[1],
|
||||||
|
revoke? _("Invalid certificate revocation")
|
||||||
|
: _("Invalid certificate"),
|
||||||
g10_errstr(rc));
|
g10_errstr(rc));
|
||||||
rec.r.sig.sig[i].flag = SIGF_CHECKED;
|
rec.r.sig.sig[i].flag = SIGF_CHECKED;
|
||||||
|
if( revoke )
|
||||||
|
rec.r.sig.sig[i].flag |= SIGF_REVOKED;
|
||||||
}
|
}
|
||||||
rec.dirty = 1;
|
rec.dirty = 1;
|
||||||
}
|
}
|
||||||
@ -2347,11 +2477,13 @@ upd_nonself_key_sigs( PKT_signature *sig, TRUSTREC *urec,
|
|||||||
&& (!tmp.r.sdir.pubkey_algo
|
&& (!tmp.r.sdir.pubkey_algo
|
||||||
|| tmp.r.sdir.pubkey_algo == sig->pubkey_algo )) {
|
|| tmp.r.sdir.pubkey_algo == sig->pubkey_algo )) {
|
||||||
if( !(rec.r.sig.sig[i].flag & SIGF_NOPUBKEY) )
|
if( !(rec.r.sig.sig[i].flag & SIGF_NOPUBKEY) )
|
||||||
log_info(_("key %08lX.%lu, uid %02X%02X: "
|
log_info("uid %08lX.%lu/%02X%02X: "
|
||||||
"has shadow dir %lu but not yet marked.\n"),
|
"has shadow dir %lu but not yet marked.\n",
|
||||||
(ulong)keyid[1], lid,
|
(ulong)keyid[1], lid,
|
||||||
uidhash[18], uidhash[19], tmp.recnum );
|
uidhash[18], uidhash[19], tmp.recnum );
|
||||||
rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
|
rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
|
||||||
|
if( revoke )
|
||||||
|
rec.r.sig.sig[i].flag |= SIGF_REVOKED;
|
||||||
rec.dirty = 1;
|
rec.dirty = 1;
|
||||||
/* fixme: should we verify that the record is
|
/* fixme: should we verify that the record is
|
||||||
* in the hintlist? - This case here should anyway
|
* in the hintlist? - This case here should anyway
|
||||||
@ -2388,31 +2520,40 @@ upd_nonself_key_sigs( PKT_signature *sig, TRUSTREC *urec,
|
|||||||
|
|
||||||
if( !rc ) { /* valid signature */
|
if( !rc ) { /* valid signature */
|
||||||
if( opt.verbose )
|
if( opt.verbose )
|
||||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
|
log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
|
||||||
"Good signature (2)\n"),
|
|
||||||
(ulong)keyid[1], lid, uidhash[18],
|
(ulong)keyid[1], lid, uidhash[18],
|
||||||
uidhash[19], (ulong)sig->keyid[1] );
|
uidhash[19], (ulong)sig->keyid[1],
|
||||||
|
revoke? _("Valid certificate revocation")
|
||||||
|
: _("Good certificate") );
|
||||||
newlid = pk_lid; /* this is the pk of the signature */
|
newlid = pk_lid; /* this is the pk of the signature */
|
||||||
newflag = SIGF_CHECKED | SIGF_VALID;
|
newflag = SIGF_CHECKED | SIGF_VALID;
|
||||||
|
if( revoke )
|
||||||
|
newflag |= SIGF_REVOKED;
|
||||||
}
|
}
|
||||||
else if( rc == G10ERR_NO_PUBKEY ) {
|
else if( rc == G10ERR_NO_PUBKEY ) {
|
||||||
if( opt.verbose > 1 )
|
if( opt.verbose > 1 )
|
||||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
|
log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
|
||||||
"no public key\n"),
|
(ulong)keyid[1], lid, uidhash[18],
|
||||||
(ulong)keyid[1], lid, uidhash[18],
|
uidhash[19], (ulong)sig->keyid[1], g10_errstr(rc) );
|
||||||
uidhash[19], (ulong)sig->keyid[1] );
|
|
||||||
newlid = create_shadow_dir( sig, lid );
|
newlid = create_shadow_dir( sig, lid );
|
||||||
newflag = SIGF_NOPUBKEY;
|
newflag = SIGF_NOPUBKEY;
|
||||||
|
if( revoke )
|
||||||
|
newflag |= SIGF_REVOKED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: %s\n"),
|
log_info( "sig %08lX.%lu/%02X%02X/%08lX: %s: %s\n",
|
||||||
(ulong)keyid[1], lid, uidhash[18], uidhash[19],
|
(ulong)keyid[1], lid, uidhash[18], uidhash[19],
|
||||||
(ulong)sig->keyid[1], g10_errstr(rc));
|
(ulong)sig->keyid[1],
|
||||||
|
revoke? _("Invalid certificate revocation")
|
||||||
|
: _("Invalid certificate"),
|
||||||
|
g10_errstr(rc));
|
||||||
newlid = create_shadow_dir( sig, lid );
|
newlid = create_shadow_dir( sig, lid );
|
||||||
newflag = SIGF_CHECKED;
|
newflag = SIGF_CHECKED;
|
||||||
|
if( revoke )
|
||||||
|
newflag |= SIGF_REVOKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( delrec.recnum ) { /* we can reuse a deleted slot */
|
if( delrec.recnum ) { /* we can reuse a deleted/unused slot */
|
||||||
delrec.r.sig.sig[delrecidx].lid = newlid;
|
delrec.r.sig.sig[delrecidx].lid = newlid;
|
||||||
delrec.r.sig.sig[delrecidx].flag= newflag;
|
delrec.r.sig.sig[delrecidx].flag= newflag;
|
||||||
write_record( &delrec );
|
write_record( &delrec );
|
||||||
@ -2434,80 +2575,6 @@ upd_nonself_key_sigs( PKT_signature *sig, TRUSTREC *urec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************
|
|
||||||
* Note: A signature made with a secondary key is not considered a
|
|
||||||
* self-signature.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
|
|
||||||
u32 *keyid, ulong *uidrecno, byte *uidhash,
|
|
||||||
KBNODE keyblock, KBNODE signode, int fast)
|
|
||||||
{
|
|
||||||
TRUSTREC urec;
|
|
||||||
ulong lid = drec->recnum;
|
|
||||||
|
|
||||||
if( !*uidrecno ) {
|
|
||||||
switch( sig->sig_class ) {
|
|
||||||
case 0x20:
|
|
||||||
case 0x28: /* We do not need uids for [sub]key revications */
|
|
||||||
case 0x18: /* or subkey binding */
|
|
||||||
memset( &urec, 0, sizeof urec ); /* to catch errors */
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
log_error("key %08lX: signature (class %02x) without user id\n",
|
|
||||||
(ulong)keyid[1], sig->sig_class );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
read_record( *uidrecno, &urec, RECTYPE_UID );
|
|
||||||
|
|
||||||
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
|
|
||||||
if( (sig->sig_class&~3) == 0x10 ) {
|
|
||||||
upd_self_key_sigs( sig, &urec, lid, keyid, uidhash,
|
|
||||||
keyblock, signode );
|
|
||||||
}
|
|
||||||
else if( sig->sig_class == 0x18 ) { /* key binding */
|
|
||||||
}
|
|
||||||
else if( sig->sig_class == 0x20 ) { /* key revocation */
|
|
||||||
/* FIXME */
|
|
||||||
}
|
|
||||||
else if( sig->sig_class == 0x28 ) { /* subkey revocation */
|
|
||||||
/* FIXME */
|
|
||||||
}
|
|
||||||
else if( sig->sig_class == 0x30 ) { /* cert revocation */
|
|
||||||
/* FIXME */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( (sig->sig_class&~3) == 0x10 ) {
|
|
||||||
upd_nonself_key_sigs( sig, &urec, lid, keyid, uidhash,
|
|
||||||
keyblock, signode, fast );
|
|
||||||
}
|
|
||||||
else if( sig->sig_class == 0x18 ) { /* key binding */
|
|
||||||
log_info(_("key %08lX: bogus key binding by %08lX\n"),
|
|
||||||
(ulong)keyid[1], (ulong)sig->keyid[1] );
|
|
||||||
}
|
|
||||||
else if( sig->sig_class == 0x20 ) { /* key revocation */
|
|
||||||
log_info(_("key %08lX: bogus key revocation by %08lX\n"),
|
|
||||||
(ulong)keyid[1], (ulong)sig->keyid[1] );
|
|
||||||
}
|
|
||||||
else if( sig->sig_class == 0x28 ) { /* subkey revocation */
|
|
||||||
log_info(_("key %08lX: bogus subkey revocation by %08lX\n"),
|
|
||||||
(ulong)keyid[1], (ulong)sig->keyid[1] );
|
|
||||||
}
|
|
||||||
else if( sig->sig_class == 0x30 ) { /* cert revocation */
|
|
||||||
/* fixme: a signator wants to revoke his certification signature */
|
|
||||||
}
|
|
||||||
|
|
||||||
if( urec.dirty ) {
|
|
||||||
write_record( &urec );
|
|
||||||
urec.dirty = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Update all the info from the public keyblock.
|
* Update all the info from the public keyblock.
|
||||||
* The key must already exist in the keydb.
|
* The key must already exist in the keydb.
|
||||||
@ -2528,8 +2595,6 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified )
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
u32 keyid[2]; /* keyid of primary key */
|
u32 keyid[2]; /* keyid of primary key */
|
||||||
ulong recno, lastrecno;
|
ulong recno, lastrecno;
|
||||||
ulong uidrecno = 0;
|
|
||||||
byte uidhash[20];
|
|
||||||
RECNO_LIST recno_list = NULL; /* list of verified records */
|
RECNO_LIST recno_list = NULL; /* list of verified records */
|
||||||
/* fixme: replace recno_list by a lookup on node->recno */
|
/* fixme: replace recno_list by a lookup on node->recno */
|
||||||
|
|
||||||
@ -2566,8 +2631,6 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified )
|
|||||||
&drec, &recno_list, recheck );
|
&drec, &recno_list, recheck );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WORk - WORK
|
|
||||||
/* delete keyrecords from the trustdb which are not anymore used */
|
/* delete keyrecords from the trustdb which are not anymore used */
|
||||||
/* should we really do this, or is it better to keep them and */
|
/* should we really do this, or is it better to keep them and */
|
||||||
/* mark as unused? */
|
/* mark as unused? */
|
||||||
@ -2626,12 +2689,9 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified )
|
|||||||
if( rc )
|
if( rc )
|
||||||
rc = tdbio_cancel_transaction();
|
rc = tdbio_cancel_transaction();
|
||||||
else {
|
else {
|
||||||
if( drec.dirty ) {
|
write_record( &drec );
|
||||||
drec.r.dir.dirflags &= ~DIRF_CHECKED; /* reset flag */
|
|
||||||
write_record( &drec );
|
|
||||||
}
|
|
||||||
if( modified && tdbio_is_dirty() )
|
if( modified && tdbio_is_dirty() )
|
||||||
*modified = 0;
|
*modified = 1;
|
||||||
rc = tdbio_end_transaction();
|
rc = tdbio_end_transaction();
|
||||||
}
|
}
|
||||||
rel_recno_list( &recno_list );
|
rel_recno_list( &recno_list );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user