1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

See ChangeLog: Tue Dec 8 13:15:16 CET 1998 Werner Koch

This commit is contained in:
Werner Koch 1998-12-08 12:20:53 +00:00
parent df1326eb05
commit ab986970eb
36 changed files with 514 additions and 149 deletions

View file

@ -1,3 +1,25 @@
Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* trustdb.c (upd_uid_record): Now uses the newest self-signature
(insert_trust_record): Now calls update with recheck set to true.
(register_trusted_key): New.
(verify_own_keys): Enhanced by list of trusted keys.
* g10.c (main): Print a warning when a devel version is used.
(main): New option --trusted-key
* import.c (merge_blocks): Fixed merging of new user ids and
added merging of subkeys.
(append_uid): Ditto.
(merge_keysig): New.
(append_key): New.
* getkey.c (merge_one_pk_and_selfsig): Get the expiration time
from the newest self-signature.
(merge_keys_and_selfsig): Ditto.
* free-packet.c (cmp_secret_key): New.
Fri Nov 27 21:37:41 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* g10.c: New option --lock-once

View file

@ -345,7 +345,7 @@ free_packet( PACKET *pkt )
}
/****************
* Returns 0 if they match.
* returns 0 if they match.
*/
int
cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
@ -370,6 +370,33 @@ cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
return 0;
}
/****************
* Returns 0 if they match.
* We only compare the public parts.
*/
int
cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b )
{
int n, i;
if( a->timestamp != b->timestamp )
return -1;
if( a->expiredate != b->expiredate )
return -1;
if( a->pubkey_algo != b->pubkey_algo )
return -1;
n = pubkey_get_npkey( b->pubkey_algo );
if( !n )
return -1; /* can't compare due to unknown algorithm */
for(i=0; i < n; i++ ) {
if( mpi_cmp( a->skey[i], b->skey[i] ) )
return -1;
}
return 0;
}
/****************
* Returns 0 if they match.
*/

View file

@ -23,6 +23,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#define MAINTAINER_OPTIONS
@ -107,6 +108,7 @@ enum cmd_and_opt_values { aNull = 0,
oKeyring,
oSecretKeyring,
oDefaultKey,
oTrustedKey,
oOptions,
oDebug,
oDebugAll,
@ -224,7 +226,7 @@ static ARGPARSE_OPTS opts[] = {
{ oKeyring, "keyring" ,2, N_("add this keyring to the list of keyrings")},
{ oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
{ oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
{ oCharset, "charset" , 2, N_("|NAME| set terminal charset to NAME") },
{ oCharset, "charset" , 2, N_("|NAME|set terminal charset to NAME") },
{ oOptions, "options" , 2, N_("read options from file")},
{ oDebug, "debug" ,4|16, N_("set debugging flags")},
@ -234,6 +236,7 @@ static ARGPARSE_OPTS opts[] = {
{ oCompletesNeeded, "completes-needed", 1, N_("(default is 1)")},
{ oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")},
{ oMaxCertDepth, "max-cert-depth", 1, "@" },
{ oTrustedKey, "trusted-key", 2, N_("|KEYID|ulimately trust this key")},
{ oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")},
{ oRFC1991, "rfc1991", 0, N_("emulate the mode described in RFC1991")},
{ oS2KMode, "s2k-mode", 1, N_("|N|use passphrase mode N")},
@ -706,6 +709,7 @@ main( int argc, char **argv )
case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break;
case oNoOptions: break; /* no-options */
case oHomedir: opt.homedir = pargs.r.ret_str; break;
case oNoBatch: opt.batch = 0; break;
@ -837,6 +841,13 @@ main( int argc, char **argv )
log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
}
{ const char *p = strusage(13);
for( ; *p && (isdigit(*p) || *p=='.'); p++ )
;
if( p )
log_info("NOTE: This is a development version!\n");
}
if( log_get_errorcount(0) )
g10_exit(2);

View file

@ -383,23 +383,27 @@ classify_user_id( const char *name, u32 *keyid, byte *fprint,
else if( i == 32 || ( i == 33 && *s == '0' ) ) { /* md5 fingerprint */
if( i==33 )
s++;
memset(fprint+16, 4, 0);
for(j=0; j < 16; j++, s+=2 ) {
int c = hextobyte( s );
if( c == -1 )
return 0;
fprint[j] = c;
if( fprint ) {
memset(fprint+16, 4, 0);
for(j=0; j < 16; j++, s+=2 ) {
int c = hextobyte( s );
if( c == -1 )
return 0;
fprint[j] = c;
}
}
mode = 16;
}
else if( i == 40 || ( i == 41 && *s == '0' ) ) { /* sha1/rmd160 fprint*/
if( i==33 )
s++;
for(j=0; j < 20; j++, s+=2 ) {
int c = hextobyte( s );
if( c == -1 )
return 0;
fprint[j] = c;
if( fprint ) {
for(j=0; j < 20; j++, s+=2 ) {
int c = hextobyte( s );
if( c == -1 )
return 0;
fprint[j] = c;
}
}
mode = 20;
}
@ -693,6 +697,7 @@ merge_one_pk_and_selfsig( KBNODE keyblock, KBNODE knode )
PKT_signature *sig;
KBNODE k;
u32 kid[2];
u32 sigdate = 0;
assert( knode->pkt->pkttype == PKT_PUBLIC_KEY
|| knode->pkt->pkttype == PKT_PUBLIC_SUBKEY );
@ -709,6 +714,7 @@ merge_one_pk_and_selfsig( KBNODE keyblock, KBNODE knode )
}
else
keyid_from_pk( pk, kid );
for(k=keyblock; k; k = k->next ) {
if( k->pkt->pkttype == PKT_SIGNATURE
&& (sig=k->pkt->pkt.signature)->sig_class >= 0x10
@ -716,16 +722,22 @@ merge_one_pk_and_selfsig( KBNODE keyblock, KBNODE knode )
&& sig->keyid[0] == kid[0]
&& sig->keyid[1] == kid[1]
&& sig->version > 3 ) {
/* okay this is (the first) self-signature which can be used
/* okay this is a self-signature which can be used.
* We use the latest self-signature.
* FIXME: We should only use this if the signature is valid
* but this is time consuming - we must provide another
* way to handle this
*/
const byte *p;
u32 ed;
p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL );
pk->expiredate = p? pk->timestamp + buffer_to_u32(p):0;
ed = p? pk->timestamp + buffer_to_u32(p):0;
if( sig->timestamp > sigdate ) {
pk->expiredate = ed;
sigdate = sig->timestamp;
}
/* fixme: add usage etc. to pk */
break;
}
}
}
@ -742,6 +754,7 @@ merge_keys_and_selfsig( KBNODE keyblock )
PKT_signature *sig;
KBNODE k;
u32 kid[2] = { 0, 0 };
u32 sigdate = 0;
for(k=keyblock; k; k = k->next ) {
if( k->pkt->pkttype == PKT_PUBLIC_KEY
@ -764,21 +777,28 @@ merge_keys_and_selfsig( KBNODE keyblock )
&& (sig=k->pkt->pkt.signature)->sig_class >= 0x10
&& sig->sig_class <= 0x30 && sig->version > 3
&& sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1] ) {
/* okay this is (the first) self-signature which can be used
/* okay this is a self-signature which can be used.
* FIXME: We should only use this if the signature is valid
* but this is time consuming - we must provide another
* way to handle this
*/
const byte *p;
u32 ed;
p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL );
if( pk ) {
pk->expiredate = p? pk->timestamp + buffer_to_u32(p):0;
/* fixme: add usage etc. */
pk = NULL; /* use only the first self signature */
ed = p? pk->timestamp + buffer_to_u32(p):0;
if( sig->timestamp > sigdate ) {
pk->expiredate = ed;
sigdate = sig->timestamp;
}
}
else {
sk->expiredate = p? sk->timestamp + buffer_to_u32(p):0;
sk = NULL; /* use only the first self signature */
ed = p? sk->timestamp + buffer_to_u32(p):0;
if( sig->timestamp > sigdate ) {
sk->expiredate = ed;
sigdate = sig->timestamp;
}
}
}
}

View file

@ -1,14 +1,14 @@
/* import.c
* Copyright (C) 1998 Free Software Foundation, Inc.
*
* This file is part of GNUPG.
* This file is part of GnuPG.
*
* GNUPG is free software; you can redistribute it and/or modify
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GNUPG is distributed in the hope that it will be useful,
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
@ -64,8 +64,12 @@ static int merge_blocks( const char *fname, KBNODE keyblock_orig,
int *n_uids, int *n_sigs, int *n_subk );
static int append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
const char *fname, u32 *keyid );
static int append_key( KBNODE keyblock, KBNODE node, int *n_sigs,
const char *fname, u32 *keyid );
static int merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
const char *fname, u32 *keyid );
static int merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs,
const char *fname, u32 *keyid );
/****************
@ -683,7 +687,7 @@ chk_self_sigs( const char *fname, KBNODE keyblock,
unode->flag |= 2; /* mark as invalid */
}
unode->flag |= 1; /* mark that user-id checked */
unode->flag |= 1; /* mark that signature checked */
}
}
return 0;
@ -759,8 +763,6 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid )
*
* o compare the signatures: If we already have this signature, check
* that they compare okay; if not, issue a warning and ask the user.
* FIXME: add the check that we don't have duplicate signatures and the
* warning in cases where the old/new signatures don't match.
* o Simply add the signature. Can't verify here because we may not have
* the signature's public key yet; verification is done when putting it
* into the trustdb, which is done automagically as soon as this pubkey
@ -799,20 +801,18 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
KBNODE n2 = clone_kbnode(node);
insert_kbnode( keyblock_orig, n2, 0 );
n2->flag |= 1;
node->flag |= 1;
log_info_f(fname, _("key %08lX: revocation certificate added\n"),
(ulong)keyid[1]);
}
}
}
/* 2nd: try to merge new ones in */
/* 2nd: try to merge new certificates in */
for(onode=keyblock_orig->next; onode; onode=onode->next ) {
if( !(onode->flag & 1) && onode->pkt->pkttype == PKT_USER_ID) {
/* find the user id in the imported keyblock */
for(node=keyblock->next; node; node=node->next )
if( !(node->flag & 1)
&& node->pkt->pkttype == PKT_USER_ID
if( node->pkt->pkttype == PKT_USER_ID
&& !cmp_user_ids( onode->pkt->pkt.user_id,
node->pkt->pkt.user_id ) )
break;
@ -826,15 +826,14 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
/* 3rd: add new user-ids */
for(node=keyblock->next; node; node=node->next ) {
if( !(node->flag & 1) && node->pkt->pkttype == PKT_USER_ID) {
if( node->pkt->pkttype == PKT_USER_ID) {
/* do we have this in the original keyblock */
for(onode=keyblock_orig->next; onode; onode=onode->next )
if( !(onode->flag & 1)
&& onode->pkt->pkttype == PKT_USER_ID
&& cmp_user_ids( onode->pkt->pkt.user_id,
node->pkt->pkt.user_id ) )
if( onode->pkt->pkttype == PKT_USER_ID
&& !cmp_user_ids( onode->pkt->pkt.user_id,
node->pkt->pkt.user_id ) )
break;
if( !node ) { /* this is a new user id: append */
if( !onode ) { /* this is a new user id: append */
rc = append_uid( keyblock_orig, node, n_sigs, fname, keyid);
if( rc )
return rc;
@ -843,8 +842,62 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
}
}
/* 4th: add new subkeys */
/* FIXME */
/* merge subkey certifcates */
for(onode=keyblock_orig->next; onode; onode=onode->next ) {
if( !(onode->flag & 1)
&& ( onode->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| onode->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
/* find the subkey in the imported keyblock */
for(node=keyblock->next; node; node=node->next ) {
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
&& !cmp_public_keys( onode->pkt->pkt.public_key,
node->pkt->pkt.public_key ) )
break;
else if( node->pkt->pkttype == PKT_SECRET_SUBKEY
&& !cmp_secret_keys( onode->pkt->pkt.secret_key,
node->pkt->pkt.secret_key ) )
break;
}
if( node ) { /* found: merge */
rc = merge_keysigs( onode, node, n_sigs, fname, keyid );
if( rc )
return rc;
}
}
}
/* add new subkeys */
for(node=keyblock->next; node; node=node->next ) {
onode = NULL;
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
/* do we have this in the original keyblock? */
for(onode=keyblock_orig->next; onode; onode=onode->next )
if( onode->pkt->pkttype == PKT_PUBLIC_SUBKEY
&& !cmp_public_keys( onode->pkt->pkt.public_key,
node->pkt->pkt.public_key ) )
break;
if( !onode ) { /* this is a new subkey: append */
rc = append_key( keyblock_orig, node, n_sigs, fname, keyid);
if( rc )
return rc;
++*n_subk;
}
}
else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
/* do we have this in the original keyblock? */
for(onode=keyblock_orig->next; onode; onode=onode->next )
if( onode->pkt->pkttype == PKT_SECRET_SUBKEY
&& !cmp_secret_keys( onode->pkt->pkt.secret_key,
node->pkt->pkt.secret_key ) )
break;
if( !onode ) { /* this is a new subkey: append */
rc = append_key( keyblock_orig, node, n_sigs, fname, keyid);
if( rc )
return rc;
++*n_subk;
}
}
}
return 0;
}
@ -858,25 +911,43 @@ static int
append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
const char *fname, u32 *keyid )
{
KBNODE n;
KBNODE n, n_where=NULL;
assert(node->pkt->pkttype == PKT_USER_ID );
/* at lease a self signature comes next to the user-id */
if( node->next->pkt->pkttype == PKT_USER_ID ) {
log_error_f(fname, _("key %08lX: our copy has no self-signature\n"),
(ulong)keyid[1]);
return G10ERR_GENERAL;
}
for( ;node && node->pkt->pkttype != PKT_USER_ID; node = node->next ) {
/* find the position */
for( n = keyblock; n; n_where = n, n = n->next ) {
if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| n->pkt->pkttype == PKT_SECRET_SUBKEY )
break;
}
if( !n )
n_where = NULL;
/* and append/insert */
while( node ) {
/* we add a clone to the original keyblock, because this
* one is released first */
n = clone_kbnode(node);
add_kbnode( keyblock, n );
node->flag |= 1;
if( n_where ) {
insert_kbnode( n_where, n, 0 );
n_where = n;
}
else
add_kbnode( keyblock, n );
n->flag |= 1;
node->flag |= 1;
if( n->pkt->pkttype == PKT_SIGNATURE )
++*n_sigs;
node = node->next;
if( node && node->pkt->pkttype != PKT_SIGNATURE )
break;
}
return 0;
@ -909,33 +980,113 @@ merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
if( n->pkt->pkttype != PKT_SIGNATURE )
continue;
found = 0;
for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next)
for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next){
if( n2->pkt->pkttype == PKT_SIGNATURE
&& n->pkt->pkt.signature->keyid[0]
== n2->pkt->pkt.signature->keyid[0]
&& n->pkt->pkt.signature->keyid[1]
== n2->pkt->pkt.signature->keyid[1] ) {
found++;
break;
== n2->pkt->pkt.signature->keyid[1]
&& n->pkt->pkt.signature->timestamp
<= n2->pkt->pkt.signature->timestamp
&& n->pkt->pkt.signature->sig_class
== n2->pkt->pkt.signature->sig_class ) {
found++;
break;
}
}
if( found ) { /* we already have this signature */
/* Hmmm: should we compare the timestamp etc?
* but then we have first to see whether this signature is valid
* - or simply add it in such a case and let trustdb logic
* decide whether to remove the old one
*/
continue;
if( !found ) {
/* This signature is new or newer, append N to DST.
* We add a clone to the original keyblock, because this
* one is released first */
n2 = clone_kbnode(n);
insert_kbnode( dst, n2, PKT_SIGNATURE );
n2->flag |= 1;
n->flag |= 1;
++*n_sigs;
}
/* This signature is new, append N to DST it.
* We add a clone to the original keyblock, because this
* one is released first */
n2 = clone_kbnode(n);
insert_kbnode( dst, n2, PKT_SIGNATURE );
n2->flag |= 1;
n->flag |= 1;
++*n_sigs;
}
return 0;
}
/****************
* Merge the sigs from SRC onto DST. SRC and DST are both a PKT_xxx_SUBKEY.
*/
static int
merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs,
const char *fname, u32 *keyid )
{
KBNODE n, n2;
int found=0;
assert( dst->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| dst->pkt->pkttype == PKT_SECRET_SUBKEY );
for(n=src->next; n ; n = n->next ) {
if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| n->pkt->pkttype == PKT_PUBLIC_KEY )
break;
if( n->pkt->pkttype != PKT_SIGNATURE )
continue;
found = 0;
for(n2=dst->next; n2; n2 = n2->next){
if( n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| n2->pkt->pkttype == PKT_PUBLIC_KEY )
break;
if( n2->pkt->pkttype == PKT_SIGNATURE
&& n->pkt->pkt.signature->keyid[0]
== n2->pkt->pkt.signature->keyid[0]
&& n->pkt->pkt.signature->keyid[1]
== n2->pkt->pkt.signature->keyid[1]
&& n->pkt->pkt.signature->timestamp
<= n2->pkt->pkt.signature->timestamp
&& n->pkt->pkt.signature->sig_class
== n2->pkt->pkt.signature->sig_class ) {
found++;
break;
}
}
if( !found ) {
/* This signature is new or newer, append N to DST.
* We add a clone to the original keyblock, because this
* one is released first */
n2 = clone_kbnode(n);
insert_kbnode( dst, n2, PKT_SIGNATURE );
n2->flag |= 1;
n->flag |= 1;
++*n_sigs;
}
}
return 0;
}
/****************
* append the subkey starting with NODE and all signatures to KEYBLOCK.
* Mark all new and copied packets by setting flag bit 0.
*/
static int
append_key( KBNODE keyblock, KBNODE node, int *n_sigs,
const char *fname, u32 *keyid )
{
KBNODE n;
assert( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| node->pkt->pkttype == PKT_SECRET_SUBKEY );
while( node ) {
/* we add a clone to the original keyblock, because this
* one is released first */
n = clone_kbnode(node);
add_kbnode( keyblock, n );
n->flag |= 1;
node->flag |= 1;
if( n->pkt->pkttype == PKT_SIGNATURE )
++*n_sigs;
node = node->next;
if( node && node->pkt->pkttype != PKT_SIGNATURE )
break;
}
return 0;

View file

@ -614,7 +614,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands )
if( !stricmp( answer, cmds[i].name ) )
break;
if( cmds[i].need_sk && !sec_keyblock ) {
tty_printf(_("Need the secret key to to this.\n"));
tty_printf(_("Need the secret key to do this.\n"));
cmd = cmdNOP;
}
else

View file

@ -272,7 +272,8 @@ PKT_public_key *copy_public_key_new_namehash( PKT_public_key *d,
PKT_secret_key *copy_secret_key( PKT_secret_key *d, PKT_secret_key *s );
PKT_signature *copy_signature( PKT_signature *d, PKT_signature *s );
PKT_user_id *copy_user_id( PKT_user_id *d, PKT_user_id *s );
int cmp_public_keys( PKT_public_key *d, PKT_public_key *s );
int cmp_public_keys( PKT_public_key *a, PKT_public_key *b );
int cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b );
int cmp_signatures( PKT_signature *a, PKT_signature *b );
int cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk );
int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );

View file

@ -230,7 +230,7 @@ hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create )
if( create && !pass ) {
randomize_buffer(s2k->salt, 8, 1);
if( s2k->mode == 3 )
s2k->count = 96; /* = 56536 */
s2k->count = 96; /* 65536 iterations */
}
if( s2k->mode == 3 ) {

View file

@ -46,6 +46,11 @@
#error Must change structure of trustdb
#endif
struct keyid_list {
struct keyid_list *next;
u32 keyid[2];
};
struct local_id_item {
struct local_id_item *next;
ulong lid;
@ -102,9 +107,10 @@ 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 );
static struct keyid_list *trusted_key_list;
/* a table used to keep track of ultimately trusted keys
* which are the ones from our secrings */
* which are the ones from our secrings and the trusted keys */
static LOCAL_ID_TABLE ultikey_table;
/* list of unused lid items and tables */
@ -438,8 +444,30 @@ trust_letter( unsigned value )
}
}
void
register_trusted_key( const char *string )
{
u32 keyid[2];
struct keyid_list *r;
if( classify_user_id( string, keyid, NULL, NULL, NULL ) != 11 ) {
log_error(_("'%s' is not a valid long keyID\n"), string );
return;
}
for( r = trusted_key_list; r; r = r->next )
if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] )
return;
r = m_alloc( sizeof *r );
r->keyid[0] = keyid[0];
r->keyid[1] = keyid[1];
r->next = trusted_key_list;
trusted_key_list = r;
}
/****************
* Verify that all our public keys are in the trustDB.
* Verify that all our public keys are in the trustdb.
*/
static int
verify_own_keys()
@ -449,8 +477,48 @@ verify_own_keys()
PKT_secret_key *sk = m_alloc_clear( sizeof *sk );
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
u32 keyid[2];
struct keyid_list *kl;
/* put the trusted keys into the trusted key table */
for( kl = trusted_key_list; kl; kl = kl->next ) {
keyid[0] = kl->keyid[0];
keyid[1] = kl->keyid[1];
/* get the public key */
memset( pk, 0, sizeof *pk );
rc = get_pubkey( pk, keyid );
if( rc ) {
log_info(_("key %08lX: no public key for trusted key - skipped\n"),
(ulong)keyid[1] );
}
else {
/* make sure that the pubkey is in the trustdb */
rc = query_trust_record( pk );
if( rc == -1 ) { /* put it into the trustdb */
rc = insert_trust_record( pk );
if( rc ) {
log_error(_("key %08lX: can't put it into the trustdb\n"),
(ulong)keyid[1] );
}
}
else if( rc ) {
log_error(_("key %08lX: query record failed\n"),
(ulong)keyid[1] );
}
else {
if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) )
log_error(_("key %08lX: already in trusted key table\n"),
(ulong)keyid[1]);
else if( opt.verbose > 1 )
log_info(_("key %08lX: accepted as trusted key.\n"),
(ulong)keyid[1]);
}
}
release_public_key_parts( pk );
}
while( !(rc=enum_secret_keys( &enum_context, sk, 0 ) ) ) {
int have_pk = 0;
keyid_from_sk( sk, keyid );
if( DBG_TRUST )
@ -460,6 +528,11 @@ verify_own_keys()
log_info(_("NOTE: secret key %08lX is NOT protected.\n"),
(ulong)keyid[1] );
for( kl = trusted_key_list; kl; kl = kl->next ) {
if( kl->keyid[0] == keyid[0] && kl->keyid[1] == keyid[1] )
goto skip; /* already in trusted key table */
}
/* see whether we can access the public key of this secret key */
memset( pk, 0, sizeof *pk );
rc = get_pubkey( pk, keyid );
@ -468,6 +541,7 @@ verify_own_keys()
(ulong)keyid[1] );
goto skip;
}
have_pk=1;
if( cmp_public_secret_key( pk, sk ) ) {
log_info(_("key %08lX: secret and public key don't match\n"),
@ -495,20 +569,30 @@ verify_own_keys()
log_debug("key %08lX.%lu: stored into ultikey_table\n",
(ulong)keyid[1], pk->local_id );
if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) )
log_error(_("key %08lX: already in secret key table\n"),
log_error(_("key %08lX: already in trusted key table\n"),
(ulong)keyid[1]);
else if( opt.verbose > 1 )
log_info(_("key %08lX: accepted as secret key.\n"),
log_info(_("key %08lX: accepted as trusted key.\n"),
(ulong)keyid[1]);
skip:
release_secret_key_parts( sk );
release_public_key_parts( pk );
if( have_pk )
release_public_key_parts( pk );
}
if( rc != -1 )
log_error(_("enumerate secret keys failed: %s\n"), g10_errstr(rc) );
else
rc = 0;
/* release the trusted keyid table */
{ struct keyid_list *kl2;
for( kl = trusted_key_list; kl; kl = kl2 ) {
kl2 = kl->next;
m_free( kl );
}
trusted_key_list = NULL;
}
enum_secret_keys( &enum_context, NULL, 0 ); /* free context */
free_secret_key( sk );
free_public_key( pk );
@ -1727,7 +1811,7 @@ get_dir_record( PKT_public_key *pk, TRUSTREC *rec )
/****************
* This function simply looks for the key in the trustdb
* and makes sure that pk->local_id is set to the coreect value.
* and makes sure that pk->local_id is set to the correct value.
* Return: 0 = found
* -1 = not found
* other = error
@ -2282,6 +2366,9 @@ upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
urec.r.uid.uidflags |= UIDF_CHECKED | UIDF_VALID;
if( !selfsig )
selfsig = sig; /* use the first valid sig */
else if( sig->timestamp > selfsig->timestamp
&& sig->sig_class >= selfsig->sig_class )
selfsig = sig; /* but this one is newer */
}
else {
log_info( "uid %08lX/%02X%02X: %s: %s\n",
@ -2293,7 +2380,13 @@ upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
}
else if( sig->sig_class == 0x30 ) { /* cert revocation */
rc = check_key_signature( keyblock, node, NULL );
if( !rc ) {
if( !rc && selfsig && selfsig->timestamp > sig->timestamp ) {
log_info( "uid %08lX.%lu/%02X%02X: %s\n",
(ulong)keyid[1], lid, uidhash[18], uidhash[19],
_("Valid user ID revocation skipped "
"due to a newer self signature\n") );
}
else if( !rc ) {
if( opt.verbose )
log_info( "uid %08lX.%lu/%02X%02X: %s\n",
(ulong)keyid[1], lid, uidhash[18], uidhash[19],
@ -2569,11 +2662,13 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
rec.r.sig.sig[i].flag |= SIGF_REVOKED;
}
else if( rc == G10ERR_NO_PUBKEY ) {
#if 0 /* fixme: For some reason this really happens? */
if( (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
(ulong)keyid[1], lid, uidhash[18],
uidhash[19], (ulong)sig->keyid[1],
_("Hmmm, public key lost?") );
#endif
rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
if( revoke )
rec.r.sig.sig[i].flag |= SIGF_REVOKED;
@ -2918,7 +3013,7 @@ insert_trust_record( PKT_public_key *pk )
}
/* and put all the other stuff into the keydb */
rc = update_trust_record( keyblock, 0, NULL );
rc = update_trust_record( keyblock, 1, NULL );
if( !rc )
process_hintlist( hintlist, dirrec.r.dir.lid );

View file

@ -45,6 +45,7 @@ void list_trustdb(const char *username);
void list_trust_path( const char *username );
void export_ownertrust(void);
void import_ownertrust(const char *fname);
void register_trusted_key( const char *string );
void check_trustdb( const char *username );
void update_trustdb( void );
int init_trustdb( int level, const char *dbname );