diff --git a/g10/ChangeLog b/g10/ChangeLog index 4620bcd88..438e6e0d6 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,20 @@ +2002-09-13 David Shaw + + * getkey.c (check_revocation_keys): Move.... + * main.h, sig-check.c (check_revocation_keys): to here. Also + return the signature_check error code rather than 0/1 and cache + the sig result. + + * sig-check.c (check_key_signature2): Divert to + check_revocation_keys if a revocation sig is made by someone other + than the pk owner. + + * getkey.c (merge_selfsigs_main): Tidy. + +2002-09-13 Werner Koch + + * g10.c (main) [__MINGW32__]: Activate oLoadExtension. + 2002-09-12 David Shaw * Makefile.am, hkp.c, hkp.h, keyserver.c (keyserver_work): Remove diff --git a/g10/g10.c b/g10/g10.c index 8206d641e..7beb5ae03 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -1385,7 +1385,7 @@ main( int argc, char **argv ) case oAlwaysTrust: opt.always_trust = 1; break; case oLoadExtension: #ifndef __riscos__ -#ifdef USE_DYNAMIC_LINKING +#if defined(USE_DYNAMIC_LINKING) || defined(__MINGW32__) if(check_permissions(pargs.r.ret_str,2)) log_info(_("cipher extension \"%s\" not loaded due to " "unsafe permissions\n"),pargs.r.ret_str); diff --git a/g10/getkey.c b/g10/getkey.c index c62a99709..fab0f6c9a 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -96,7 +96,6 @@ static int uid_cache_entries; /* number of entries in uid cache */ static void merge_selfsigs( KBNODE keyblock ); static int lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode ); -static int check_revocation_keys(PKT_public_key *pk,PKT_signature *sig); #if 0 static void @@ -1368,9 +1367,11 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) if(IS_KEY_REV(sig) && (sig->keyid[0]!=kid[0] || sig->keyid[1]!=kid[1])) { - if(check_revocation_keys(pk,sig)) - ; /* did not verify, or loop broken */ - else + /* Failure here means the sig did not verify, is was + not issued by a revocation key, or a revocation + key loop was broken. */ + + if(check_revocation_keys(pk,sig)==0) *r_revoked=1; /* In the future handle subkey and cert revocations? @@ -2407,69 +2408,8 @@ get_user_id_printable( u32 *keyid ) return p; } - - KEYDB_HANDLE get_ctx_handle(GETKEY_CTX ctx) { return ctx->kr_handle; } - -/* Check the revocation keys to see if any of them have revoked our - pk. sig is the revocation sig. pk is the key it is on. This code - will need to be modified if gpg ever becomes multi-threaded. Note - that this is written so that a revoked revoker can still issue - revocations: i.e. If A revokes B, but A is revoked, B is still - revoked. I'm not completely convinced this is the proper behavior, - but it matches how PGP does it. -dms */ - -/* Return 0 if pk is revoked, non-0 if not revoked */ -static int -check_revocation_keys(PKT_public_key *pk,PKT_signature *sig) -{ - static int busy=0; - int i,rc=-1; - - assert(IS_KEY_REV(sig)); - assert((sig->keyid[0]!=pk->keyid[0]) || (sig->keyid[0]!=pk->keyid[1])); - - if(busy) - { - /* return -1 (i.e. not revoked), but mark the pk as uncacheable - as we don't really know its revocation status until it is - checked directly. */ - - pk->dont_cache=1; - return -1; - } - - busy=1; - - /* printf("looking at %08lX with a sig from %08lX\n",(ulong)pk->keyid[1], - (ulong)sig->keyid[1]); */ - - /* is the issuer of the sig one of our revokers? */ - if( !pk->revkey && pk->numrevkeys ) - BUG(); - else - for(i=0;inumrevkeys;i++) { - u32 keyid[2]; - - keyid_from_fingerprint(pk->revkey[i].fpr,MAX_FINGERPRINT_LEN,keyid); - - if(keyid[0]==sig->keyid[0] && keyid[1]==sig->keyid[1]) { - MD_HANDLE md; - - md=md_open(sig->digest_algo,0); - hash_public_key(md,pk); - if(signature_check(sig,md)==0) { - rc=0; - break; - } - } - } - - busy=0; - - return rc; -} diff --git a/g10/main.h b/g10/main.h index 0d04911d7..4282a47c2 100644 --- a/g10/main.h +++ b/g10/main.h @@ -106,6 +106,7 @@ int clearsign_file( const char *fname, STRLIST locusr, const char *outfile ); int sign_symencrypt_file (const char *fname, STRLIST locusr); /*-- sig-check.c --*/ +int check_revocation_keys (PKT_public_key *pk, PKT_signature *sig); int check_key_signature( KBNODE root, KBNODE node, int *is_selfsig ); int check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expiredate, int *r_expired ); diff --git a/g10/sig-check.c b/g10/sig-check.c index 657ead52a..d4e8957b1 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -402,6 +402,71 @@ cache_sig_result ( PKT_signature *sig, int result ) } } + +/* Check the revocation keys to see if any of them have revoked our + pk. sig is the revocation sig. pk is the key it is on. This code + will need to be modified if gpg ever becomes multi-threaded. Note + that this guarantees that a designated revocation sig will never be + considered valid unless it is actually valid, as well as being + issued by a revocation key in a valid direct signature. Note that + this is written so that a revoked revoker can still issue + revocations: i.e. If A revokes B, but A is revoked, B is still + revoked. I'm not completely convinced this is the proper behavior, + but it matches how PGP does it. -dms */ + +/* Returns 0 if sig is valid (i.e. pk is revoked), non-0 if not + revoked */ +int +check_revocation_keys(PKT_public_key *pk,PKT_signature *sig) +{ + static int busy=0; + int i,rc=G10ERR_GENERAL; + + assert(IS_KEY_REV(sig)); + assert((sig->keyid[0]!=pk->keyid[0]) || (sig->keyid[0]!=pk->keyid[1])); + + if(busy) + { + /* return -1 (i.e. not revoked), but mark the pk as uncacheable + as we don't really know its revocation status until it is + checked directly. */ + + pk->dont_cache=1; + return rc; + } + + busy=1; + + /* printf("looking at %08lX with a sig from %08lX\n",(ulong)pk->keyid[1], + (ulong)sig->keyid[1]); */ + + /* is the issuer of the sig one of our revokers? */ + if( !pk->revkey && pk->numrevkeys ) + BUG(); + else + for(i=0;inumrevkeys;i++) + { + u32 keyid[2]; + + keyid_from_fingerprint(pk->revkey[i].fpr,MAX_FINGERPRINT_LEN,keyid); + + if(keyid[0]==sig->keyid[0] && keyid[1]==sig->keyid[1]) + { + MD_HANDLE md; + + md=md_open(sig->digest_algo,0); + hash_public_key(md,pk); + rc=signature_check(sig,md); + cache_sig_result(sig,rc); + break; + } + } + + busy=0; + + return rc; +} + /**************** * check the signature pointed to by NODE. This is a key signature. * If the function detects a self-signature, it uses the PK from @@ -456,11 +521,17 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, return rc; if( sig->sig_class == 0x20 ) { /* key revocation */ - md = md_open( algo, 0 ); - hash_public_key( md, pk ); - rc = do_check( pk, sig, md, r_expired ); - cache_sig_result ( sig, rc ); - md_close(md); + /* designated revoker? */ + if(pk->keyid[0]!=sig->keyid[0] || pk->keyid[1]!=sig->keyid[1]) + rc=check_revocation_keys(pk,sig); + else + { + md = md_open( algo, 0 ); + hash_public_key( md, pk ); + rc = do_check( pk, sig, md, r_expired ); + cache_sig_result ( sig, rc ); + md_close(md); + } } else if( sig->sig_class == 0x28 ) { /* subkey revocation */ KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );