diff options
author | David Shaw <[email protected]> | 2002-08-06 16:58:58 +0000 |
---|---|---|
committer | David Shaw <[email protected]> | 2002-08-06 16:58:58 +0000 |
commit | 111f78b1ff39bb760f2db0308a08abfd17fd15bc (patch) | |
tree | a575d2d26ab8a0694214c88c6d1c2a9e9c886bd7 | |
parent | * options.skel: Changed comments. (diff) | |
download | gnupg-111f78b1ff39bb760f2db0308a08abfd17fd15bc.tar.gz gnupg-111f78b1ff39bb760f2db0308a08abfd17fd15bc.zip |
* revoke.c (export_minimal_pk, gen_desig_revoke, gen_revoke): Export a
minimal pk along with the revocation cert when in --pgpX mode so that PGP
can import it.
-rw-r--r-- | g10/ChangeLog | 6 | ||||
-rw-r--r-- | g10/revoke.c | 305 |
2 files changed, 179 insertions, 132 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index aa5f656db..44842724a 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,9 @@ +2002-08-06 David Shaw <[email protected]> + + * revoke.c (export_minimal_pk, gen_desig_revoke, gen_revoke): + Export a minimal pk along with the revocation cert when in --pgpX + mode so that PGP can import it. + 2002-08-06 Werner Koch <[email protected]> * options.skel: Changed comments. diff --git a/g10/revoke.c b/g10/revoke.c index c99bf4c80..d90bcb581 100644 --- a/g10/revoke.c +++ b/g10/revoke.c @@ -71,7 +71,125 @@ revocation_reason_build_cb( PKT_signature *sig, void *opaque ) return 0; } +/* Outputs a minimal pk (as defined by 2440) from a keyblock. A + minimal pk consists of the public key packet and a user ID. We try + and pick a user ID that has a uid signature, and include it if + possible. */ +static int +export_minimal_pk(IOBUF out,KBNODE keyblock, + PKT_signature *revsig,PKT_signature *revkey) +{ + KBNODE node; + PACKET pkt; + PKT_user_id *uid=NULL; + PKT_signature *selfsig=NULL; + u32 keyid[2]; + int rc; + + node=find_kbnode(keyblock,PKT_PUBLIC_KEY); + if(!node) + { + log_error(_("key incomplete\n")); + return G10ERR_GENERAL; + } + + keyid_from_pk(node->pkt->pkt.public_key,keyid); + + pkt=*node->pkt; + rc=build_packet(out,&pkt); + if(rc) + { + log_error(_("build_packet failed: %s\n"), g10_errstr(rc) ); + return rc; + } + + init_packet(&pkt); + pkt.pkttype=PKT_SIGNATURE; + + /* the revocation itself, if any. 2440 likes this to come first. */ + if(revsig) + { + pkt.pkt.signature=revsig; + rc=build_packet(out,&pkt); + if(rc) + { + log_error(_("build_packet failed: %s\n"), g10_errstr(rc) ); + return rc; + } + } + + /* If a revkey in a 1F sig is present, include it too */ + if(revkey) + { + pkt.pkt.signature=revkey; + rc=build_packet(out,&pkt); + if(rc) + { + log_error(_("build_packet failed: %s\n"), g10_errstr(rc) ); + return rc; + } + } + while(!selfsig) + { + KBNODE signode; + + node=find_next_kbnode(node,PKT_USER_ID); + if(!node) + { + /* We're out of user IDs - none were self-signed. */ + if(uid) + break; + else + { + log_error(_("key %08lX incomplete\n"),(ulong)keyid[1]); + return G10ERR_GENERAL; + } + } + + if(node->pkt->pkt.user_id->attrib_data) + continue; + + uid=node->pkt->pkt.user_id; + signode=node; + + while((signode=find_next_kbnode(signode,PKT_SIGNATURE))) + { + if(keyid[0]==signode->pkt->pkt.signature->keyid[0] && + keyid[1]==signode->pkt->pkt.signature->keyid[1] && + IS_UID_SIG(signode->pkt->pkt.signature)) + { + selfsig=signode->pkt->pkt.signature; + break; + } + } + } + + pkt.pkttype=PKT_USER_ID; + pkt.pkt.user_id=uid; + + rc=build_packet(out,&pkt); + if(rc) + { + log_error(_("build_packet failed: %s\n"), g10_errstr(rc) ); + return rc; + } + + if(selfsig) + { + pkt.pkttype=PKT_SIGNATURE; + pkt.pkt.signature=selfsig; + + rc=build_packet(out,&pkt); + if(rc) + { + log_error(_("build_packet failed: %s\n"), g10_errstr(rc) ); + return rc; + } + } + + return 0; +} /**************** * Generate a revocation certificate for UNAME via a designated revoker @@ -81,7 +199,6 @@ gen_desig_revoke( const char *uname ) { int rc = 0; armor_filter_context_t afx; - PACKET pkt; PKT_public_key *pk = NULL; PKT_secret_key *sk = NULL; PKT_signature *sig = NULL; @@ -146,8 +263,7 @@ gen_desig_revoke( const char *uname ) size_t n; char *p; u32 sk_keyid[2]; - PKT_user_id *uid=NULL; - PKT_signature *selfsig=NULL,*revsig=NULL; + PKT_signature *revkey=NULL; any=1; keyid_from_sk(sk,sk_keyid); @@ -210,40 +326,24 @@ gen_desig_revoke( const char *uname ) } /* Spit out a minimal pk as well, since otherwise there is - no way to know which key to attach this revocation - to. */ - - node=find_kbnode(keyblock,PKT_PUBLIC_KEY); - if(!node) - { - rc=G10ERR_GENERAL; - log_error(_("key %08lX incomplete\n"),(ulong)keyid[1]); - goto leave; - } - - pkt = *node->pkt; - rc=build_packet(out,&pkt); - if( rc ) { - log_error(_("build_packet failed: %s\n"), g10_errstr(rc) ); - goto leave; - } - - /* Include the direct key signature that contains this - revocation key. We're allowed to include sensitive - revocation keys along with a revocation, and this may - be the only time the recipient has seen it. Note that - this means that if we have multiple different sensitive - revocation keys in a given direct key signature, we're - going to include them all here. This is annoying, but - the good outweighs the bad, since without including - this a sensitive revoker can't really do their job. - People should not include multiple sensitive revocation - keys in one signature: 2440 says "Note that it may be - appropriate to isolate this subpacket within a separate - signature so that it is not combined with other - subpackets that need to be exported." -dms */ - - while(!revsig) + no way to know which key to attach this revocation to. + Also include the direct key signature that contains + this revocation key. We're allowed to include + sensitive revocation keys along with a revocation, as + this may be the only time the recipient has seen it. + Note that this means that if we have multiple different + sensitive revocation keys in a given direct key + signature, we're going to include them all here. This + is annoying, but the good outweighs the bad, since + without including this a sensitive revoker can't really + do their job. People should not include multiple + sensitive revocation keys in one signature: 2440 says + "Note that it may be appropriate to isolate this + subpacket within a separate signature so that it is not + combined with other subpackets that need to be + exported." -dms */ + + while(!revkey) { KBNODE signode; @@ -269,94 +369,19 @@ gen_desig_revoke( const char *uname ) signode->pkt->pkt.signature->revkey[j]->fpr, MAX_FINGERPRINT_LEN)==0) { - revsig=signode->pkt->pkt.signature; + revkey=signode->pkt->pkt.signature; break; } } } } - if(revsig) - { - pkt.pkttype = PKT_SIGNATURE; - pkt.pkt.signature = revsig; - - rc = build_packet( out, &pkt ); - if( rc ) { - log_error(_("build_packet failed: %s\n"), g10_errstr(rc) ); - goto leave; - } - } - else + if(!revkey) BUG(); - init_packet( &pkt ); - pkt.pkttype = PKT_SIGNATURE; - pkt.pkt.signature = sig; - - rc = build_packet( out, &pkt ); - if( rc ) { - log_error(_("build_packet failed: %s\n"), g10_errstr(rc) ); - goto leave; - } - - while(!selfsig) - { - KBNODE signode; - - node=find_next_kbnode(node,PKT_USER_ID); - if(!node) - { - /* We're out of user IDs - none were - self-signed. */ - if(uid) - break; - else - { - rc=G10ERR_GENERAL; - log_error(_("key %08lX incomplete\n"),(ulong)keyid[1]); - goto leave; - } - } - - if(node->pkt->pkt.user_id->attrib_data) - continue; - - uid=node->pkt->pkt.user_id; - signode=node; - - while((signode=find_next_kbnode(signode,PKT_SIGNATURE))) - { - if(keyid[0]==signode->pkt->pkt.signature->keyid[0] && - keyid[1]==signode->pkt->pkt.signature->keyid[1] && - IS_UID_SIG(signode->pkt->pkt.signature)) - { - selfsig=signode->pkt->pkt.signature; - break; - } - } - } - - pkt.pkttype = PKT_USER_ID; - pkt.pkt.user_id = uid; - - rc = build_packet( out, &pkt ); - if( rc ) { - log_error(_("build_packet failed: %s\n"), g10_errstr(rc) ); + rc=export_minimal_pk(out,keyblock,sig,revkey); + if(rc) goto leave; - } - - if(selfsig) - { - pkt.pkttype = PKT_SIGNATURE; - pkt.pkt.signature = selfsig; - - rc = build_packet( out, &pkt ); - if( rc ) { - log_error(_("build_packet failed: %s\n"), g10_errstr(rc) ); - goto leave; - } - } /* and issue a usage notice */ tty_printf(_("Revocation certificate created.\n")); @@ -398,7 +423,7 @@ gen_revoke( const char *uname ) PKT_signature *sig = NULL; u32 sk_keyid[2]; IOBUF out = NULL; - KBNODE keyblock = NULL; + KBNODE keyblock = NULL, pub_keyblock = NULL; KBNODE node; KEYDB_HANDLE kdbhd; struct revocation_reason_info *reason = NULL; @@ -453,11 +478,20 @@ gen_revoke( const char *uname ) pk = m_alloc_clear( sizeof *pk ); /* FIXME: We should get the public key direct from the secret one */ - rc = get_pubkey( pk, sk_keyid ); - if( rc ) { + + pub_keyblock=get_pubkeyblock(sk_keyid); + if(!pub_keyblock) + { log_error(_("no corresponding public key: %s\n"), g10_errstr(rc) ); goto leave; - } + } + + node=find_kbnode(pub_keyblock,PKT_PUBLIC_KEY); + if(!node) + BUG(); + + pk=node->pkt->pkt.public_key; + if( cmp_public_secret_key( pk, sk ) ) { log_error(_("public key does not match secret key!\n") ); rc = G10ERR_GENERAL; @@ -514,15 +548,25 @@ gen_revoke( const char *uname ) log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc)); goto leave; } - init_packet( &pkt ); - pkt.pkttype = PKT_SIGNATURE; - pkt.pkt.signature = sig; - rc = build_packet( out, &pkt ); - if( rc ) { - log_error(_("build_packet failed: %s\n"), g10_errstr(rc) ); - goto leave; - } + if(opt.pgp2 || opt.pgp6 || opt.pgp7) + { + rc=export_minimal_pk(out,NULL /*pub_keyblock*/,sig,NULL); + if(rc) + goto leave; + } + else + { + init_packet( &pkt ); + pkt.pkttype = PKT_SIGNATURE; + pkt.pkt.signature = sig; + + rc = build_packet( out, &pkt ); + if( rc ) { + log_error(_("build_packet failed: %s\n"), g10_errstr(rc) ); + goto leave; + } + } /* and issue a usage notice */ tty_printf(_("Revocation certificate created.\n\n" @@ -532,14 +576,11 @@ gen_revoke( const char *uname ) "your media become unreadable. But have some caution: The print system of\n" "your machine might store the data and make it available to others!\n")); - - leave: - if( pk ) - free_public_key( pk ); if( sig ) free_seckey_enc( sig ); release_kbnode( keyblock ); + release_kbnode( pub_keyblock ); keydb_release (kdbhd); if( rc ) iobuf_cancel(out); |