1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-02-23 20:08:04 +01:00

See ChangeLog: Thu Feb 17 13:39:32 CET 2000 Werner Koch

This commit is contained in:
Werner Koch 2000-02-17 12:41:58 +00:00
parent dc6e9a73a1
commit c03e6ee0aa
10 changed files with 256 additions and 206 deletions

3
NEWS
View File

@ -1,6 +1,9 @@
Noteworthy changes in the current test release Noteworthy changes in the current test release
---------------------------------------------- ----------------------------------------------
* The user is now asked for the reason of revocation as required
by the new OpenPGP draft.
* There is a ~/.gnupg/random_seed file now which saves the * There is a ~/.gnupg/random_seed file now which saves the
state of the internal RNG and increases system performance state of the internal RNG and increases system performance
somewhat. This way the full entropy source is only used in somewhat. This way the full entropy source is only used in

2
TODO
View File

@ -4,7 +4,7 @@
* --delete-secret-key should work even when the public key is not there. * --delete-secret-key should work even when the public key is not there.
* Add reason for revocation which is going to be a SHOULD * Print the reason for revocation at certain places.
* at least an option to prefer DSA keys over RSA when selecting the key to * at least an option to prefer DSA keys over RSA when selecting the key to
use. Depending on creatin time would be nice too. I thing this is use. Depending on creatin time would be nice too. I thing this is

View File

@ -1,3 +1,21 @@
Thu Feb 17 13:39:32 CET 2000 Werner Koch <wk@gnupg.de>
* revoke.c: Removed a bunch of commented code.
* packet.h (SIGSUBPKT_REVOC_REASON): New.
* build-packet.c (build_sig_subpkt): Support new sub packet.
* parse-packet.c (parse_one_sig_subpkt): Ditto.
(dump_sig_subpkt): Ditto.
* revoke.c (ask_revocation_reason): New.
(release_revocation_reason_info): New.
(revocation_reason_build_cb): New.
(gen_revoke): Ask for reason.
* main.h (struct revocation_reason_info): Add declaration.
* keyedit.c (menu_revsig): Add support for revocation reason.
(menu_revkey): Ditto.
(sign_uid_mk_attrib): Renamed to ...
(sign_mk_attrib): ... this, made static and add support for reasons.
Tue Feb 15 08:48:13 CET 2000 Werner Koch <wk@gnupg.de> Tue Feb 15 08:48:13 CET 2000 Werner Koch <wk@gnupg.de>
* build-packet.c (build_packet): Fixed fixing of old comment packets. * build-packet.c (build_packet): Fixed fixing of old comment packets.

View File

@ -646,7 +646,6 @@ void
build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
const byte *buffer, size_t buflen ) const byte *buffer, size_t buflen )
{ {
byte *data; byte *data;
size_t hlen, dlen, nlen; size_t hlen, dlen, nlen;
int found=0; int found=0;
@ -682,6 +681,7 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
case SIGSUBPKT_KEY_EXPIRE: case SIGSUBPKT_KEY_EXPIRE:
case SIGSUBPKT_NOTATION: case SIGSUBPKT_NOTATION:
case SIGSUBPKT_POLICY: case SIGSUBPKT_POLICY:
case SIGSUBPKT_REVOC_REASON:
hashed = 1; break; hashed = 1; break;
default: hashed = 0; break; default: hashed = 0; break;
} }

View File

@ -224,6 +224,29 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = {
"file (which is shown in brackets) will be used." "file (which is shown in brackets) will be used."
)}, )},
/* revoke.c (ask_revocation_reason) */
{ "ask_revocation_reason.code", N_(
"You should specify a reason for the certification. Depending on the\n"
"context you have the ability to choose from this list:\n"
" \"Key has been compromised\"\n"
" Use this if you have a reason to believe that unauthorized persons\n"
" got access to your secret key.\n"
" \"Key is superseded\"\n"
" Use this if you have replaced this key with a newer one.\n"
" \"Key is no longer used\"\n"
" Use this if you have retired this key.\n"
" \"User ID is non longer valid\"\n"
" Use this to state that the user ID should not longer be used;\n"
" this is normally used to mark an email address invalid.\n"
)},
/* revoke.c (ask_revocation_reason) */
{ "ask_revocation_reason.text", N_(
"If you like, you can enter a text describing why you issue this\n"
"revocation certificate. Please keep this text consis.\n"
"An empty line ends the text.\n"
)},
/* end of list */ /* end of list */
{ NULL, NULL } }; { NULL, NULL } };

View File

@ -74,8 +74,9 @@ static int enable_disable_key( KBNODE keyblock, int disable );
#define NODFLG_SELSIG (1<<10) /* indicate a selected signature */ #define NODFLG_SELSIG (1<<10) /* indicate a selected signature */
struct sign_uid_attrib { struct sign_attrib {
int non_exportable; int non_exportable;
struct revocation_reason_info *reason;
}; };
@ -239,16 +240,18 @@ check_all_keysigs( KBNODE keyblock, int only_selected )
int static int
sign_uid_mk_attrib( PKT_signature *sig, void *opaque ) sign_mk_attrib( PKT_signature *sig, void *opaque )
{ {
struct sign_uid_attrib *attrib = opaque; struct sign_attrib *attrib = opaque;
byte buf[8]; byte buf[8];
if( attrib->non_exportable ) { if( attrib->non_exportable ) {
buf[0] = 0; /* not exportable */ buf[0] = 0; /* not exportable */
build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 ); build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 );
} }
if( attrib->reason )
revocation_reason_build_cb( sig, attrib->reason );
return 0; return 0;
} }
@ -353,7 +356,7 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, int local )
&& (node->flag & NODFLG_MARK_A) ) { && (node->flag & NODFLG_MARK_A) ) {
PACKET *pkt; PACKET *pkt;
PKT_signature *sig; PKT_signature *sig;
struct sign_uid_attrib attrib; struct sign_attrib attrib;
assert( primary_pk ); assert( primary_pk );
memset( &attrib, 0, sizeof attrib ); memset( &attrib, 0, sizeof attrib );
@ -364,7 +367,7 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, int local )
NULL, NULL,
sk, sk,
0x10, 0, 0x10, 0,
sign_uid_mk_attrib, sign_mk_attrib,
&attrib ); &attrib );
if( rc ) { if( rc ) {
log_error(_("signing failed: %s\n"), g10_errstr(rc)); log_error(_("signing failed: %s\n"), g10_errstr(rc));
@ -1752,6 +1755,7 @@ menu_revsig( KBNODE keyblock )
int changed = 0; int changed = 0;
int upd_trust = 0; int upd_trust = 0;
int rc, any; int rc, any;
struct revocation_reason_info *reason = NULL;
/* FIXME: detect duplicates here */ /* FIXME: detect duplicates here */
tty_printf(_("You have signed these user IDs:\n")); tty_printf(_("You have signed these user IDs:\n"));
@ -1814,6 +1818,10 @@ menu_revsig( KBNODE keyblock )
_("Really create the revocation certificates? (y/N)")) ) _("Really create the revocation certificates? (y/N)")) )
return 0; /* forget it */ return 0; /* forget it */
reason = ask_revocation_reason( 0, 1, 0 );
if( !reason ) { /* user decided to cancel */
return 0;
}
/* now we can sign the user ids */ /* now we can sign the user ids */
reloop: /* (must use this, because we are modifing the list) */ reloop: /* (must use this, because we are modifing the list) */
@ -1821,7 +1829,7 @@ menu_revsig( KBNODE keyblock )
for( node=keyblock; node; node = node->next ) { for( node=keyblock; node; node = node->next ) {
KBNODE unode; KBNODE unode;
PACKET *pkt; PACKET *pkt;
struct sign_uid_attrib attrib; struct sign_attrib attrib;
PKT_secret_key *sk; PKT_secret_key *sk;
if( !(node->flag & NODFLG_MARK_A) if( !(node->flag & NODFLG_MARK_A)
@ -1831,6 +1839,8 @@ menu_revsig( KBNODE keyblock )
assert( unode ); /* we already checked this */ assert( unode ); /* we already checked this */
memset( &attrib, 0, sizeof attrib ); memset( &attrib, 0, sizeof attrib );
attrib.reason = reason;
node->flag &= ~NODFLG_MARK_A; node->flag &= ~NODFLG_MARK_A;
sk = m_alloc_secure_clear( sizeof *sk ); sk = m_alloc_secure_clear( sizeof *sk );
if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) { if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) {
@ -1842,11 +1852,12 @@ menu_revsig( KBNODE keyblock )
NULL, NULL,
sk, sk,
0x30, 0, 0x30, 0,
sign_uid_mk_attrib, sign_mk_attrib,
&attrib ); &attrib );
free_secret_key(sk); free_secret_key(sk);
if( rc ) { if( rc ) {
log_error(_("signing failed: %s\n"), g10_errstr(rc)); log_error(_("signing failed: %s\n"), g10_errstr(rc));
release_revocation_reason_info( reason );
return changed; return changed;
} }
changed = 1; /* we changed the keyblock */ changed = 1; /* we changed the keyblock */
@ -1861,7 +1872,7 @@ menu_revsig( KBNODE keyblock )
if( upd_trust ) if( upd_trust )
clear_trust_checked_flag( primary_pk ); clear_trust_checked_flag( primary_pk );
release_revocation_reason_info( reason );
return changed; return changed;
} }
@ -1878,6 +1889,13 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
int changed = 0; int changed = 0;
int upd_trust = 0; int upd_trust = 0;
int rc; int rc;
struct revocation_reason_info *reason = NULL;
reason = ask_revocation_reason( 1, 0, 0 );
if( !reason ) { /* user decided to cancel */
return 0;
}
reloop: /* (better this way because we are modifing the keyring) */ reloop: /* (better this way because we are modifing the keyring) */
mainpk = pub_keyblock->pkt->pkt.public_key; mainpk = pub_keyblock->pkt->pkt.public_key;
@ -1888,14 +1906,20 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
PKT_signature *sig; PKT_signature *sig;
PKT_secret_key *sk; PKT_secret_key *sk;
PKT_public_key *subpk = node->pkt->pkt.public_key; PKT_public_key *subpk = node->pkt->pkt.public_key;
struct sign_attrib attrib;
memset( &attrib, 0, sizeof attrib );
attrib.reason = reason;
node->flag &= ~NODFLG_SELKEY; node->flag &= ~NODFLG_SELKEY;
sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key ); sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk, 0x28, 0, rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk, 0x28, 0,
NULL, NULL ); sign_mk_attrib,
&attrib );
free_secret_key(sk); free_secret_key(sk);
if( rc ) { if( rc ) {
log_error(_("signing failed: %s\n"), g10_errstr(rc)); log_error(_("signing failed: %s\n"), g10_errstr(rc));
release_revocation_reason_info( reason );
return changed; return changed;
} }
changed = 1; /* we changed the keyblock */ changed = 1; /* we changed the keyblock */
@ -1914,6 +1938,7 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
if( upd_trust ) if( upd_trust )
clear_trust_checked_flag( mainpk ); clear_trust_checked_flag( mainpk );
release_revocation_reason_info( reason );
return changed; return changed;
} }

View File

@ -131,7 +131,12 @@ int dearmor_file( const char *fname );
int enarmor_file( const char *fname ); int enarmor_file( const char *fname );
/*-- revoke.c --*/ /*-- revoke.c --*/
struct revocation_reason_info;
int gen_revoke( const char *uname ); int gen_revoke( const char *uname );
int revocation_reason_build_cb( PKT_signature *sig, void *opaque );
struct revocation_reason_info *
ask_revocation_reason( int key_rev, int cert_rev, int hint );
void release_revocation_reason_info( struct revocation_reason_info *reason );
/*-- keylist.c --*/ /*-- keylist.c --*/
void public_key_list( STRLIST list ); void public_key_list( STRLIST list );

View File

@ -239,6 +239,7 @@ typedef enum {
SIGSUBPKT_POLICY =26, /* policy URL */ SIGSUBPKT_POLICY =26, /* policy URL */
SIGSUBPKT_KEY_FLAGS =27, /* key flags */ SIGSUBPKT_KEY_FLAGS =27, /* key flags */
SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */ SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */
SIGSUBPKT_REVOC_REASON =29, /* reason for revocation */
SIGSUBPKT_PRIV_ADD_SIG =101,/* signatur is also valid for this uid */ SIGSUBPKT_PRIV_ADD_SIG =101,/* signatur is also valid for this uid */
SIGSUBPKT_FLAG_CRITICAL=128 SIGSUBPKT_FLAG_CRITICAL=128

View File

@ -811,6 +811,13 @@ dump_sig_subpkt( int hashed, int type, int critical,
case SIGSUBPKT_SIGNERS_UID: case SIGSUBPKT_SIGNERS_UID:
p = "signer's user ID"; p = "signer's user ID";
break; break;
case SIGSUBPKT_REVOC_REASON:
if( length ) {
printf("revocation reason 0x%02x (", *buffer );
print_string( stdout, buffer+1, length-1, ')' );
p = ")";
}
break;
case SIGSUBPKT_PRIV_ADD_SIG: case SIGSUBPKT_PRIV_ADD_SIG:
p = "signs additional user ID"; p = "signs additional user ID";
break; break;
@ -848,6 +855,10 @@ parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
if( n < 8 ) /* minimum length needed */ if( n < 8 ) /* minimum length needed */
break; break;
return 0; return 0;
case SIGSUBPKT_REVOC_REASON:
if( !n )
break;
return 0;
case SIGSUBPKT_PREF_SYM: case SIGSUBPKT_PREF_SYM:
case SIGSUBPKT_PREF_HASH: case SIGSUBPKT_PREF_HASH:
case SIGSUBPKT_PREF_COMPR: case SIGSUBPKT_PREF_COMPR:
@ -885,7 +896,7 @@ can_handle_critical( const byte *buffer, size_t n, int type )
case SIGSUBPKT_PREF_COMPR: case SIGSUBPKT_PREF_COMPR:
return 1; return 1;
case SIGSUBPKT_POLICY: /* Is enough to show the policy? */ case SIGSUBPKT_POLICY: /* Is it enough to show the policy? */
default: default:
return 0; return 0;
} }

View File

@ -24,6 +24,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include <ctype.h>
#include "options.h" #include "options.h"
#include "packet.h" #include "packet.h"
@ -37,6 +38,38 @@
#include "i18n.h" #include "i18n.h"
struct revocation_reason_info {
int code;
char *desc;
};
int
revocation_reason_build_cb( PKT_signature *sig, void *opaque )
{
struct revocation_reason_info *reason = opaque;
char *ud = NULL;
byte *buffer;
size_t buflen = 1;
if( reason->desc ) {
ud = native_to_utf8( reason->desc );
buflen += strlen(ud);
}
buffer = m_alloc( buflen );
*buffer = reason->code;
if( ud ) {
memcpy(buffer+1, ud, strlen(ud) );
m_free( ud );
}
build_sig_subpkt( sig, SIGSUBPKT_REVOC_REASON, buffer, buflen );
m_free( buffer );
return 0;
}
/**************** /****************
* Generate a revocation certificate for UNAME * Generate a revocation certificate for UNAME
*/ */
@ -55,6 +88,7 @@ gen_revoke( const char *uname )
KBNODE keyblock = NULL; KBNODE keyblock = NULL;
KBNODE node; KBNODE node;
KBPOS kbpos; KBPOS kbpos;
struct revocation_reason_info *reason = NULL;
if( opt.batch ) { if( opt.batch ) {
log_error(_("sorry, can't do this in batch mode\n")); log_error(_("sorry, can't do this in batch mode\n"));
@ -62,19 +96,6 @@ gen_revoke( const char *uname )
} }
/* FIXME: ask for the reason of revocation
0x00 - No reason specified (key revocations or cert revocations)
Does not make sense!
0x01 - Key is superceded (key revocations)
0x02 - Key material has been compromised (key revocations)
0x03 - Key is no longer used (key revocations)
0x20 - User id information is no longer valid (cert revocations)
Following the revocation code is a string of octets which gives
information about the reason for revocation in human-readable form
*/
memset( &afx, 0, sizeof afx); memset( &afx, 0, sizeof afx);
memset( &zfx, 0, sizeof zfx); memset( &zfx, 0, sizeof zfx);
init_packet( &pkt ); init_packet( &pkt );
@ -136,6 +157,13 @@ gen_revoke( const char *uname )
goto leave; goto leave;
} }
/* get the reason for the revocation */
reason = ask_revocation_reason( 1, 0, 1 );
if( !reason ) { /* user decided to cancel */
rc = 0;
goto leave;
}
switch( is_secret_key_protected( sk ) ) { switch( is_secret_key_protected( sk ) ) {
case -1: case -1:
log_error(_("unknown protection algorithm\n")); log_error(_("unknown protection algorithm\n"));
@ -163,7 +191,9 @@ gen_revoke( const char *uname )
iobuf_push_filter( out, armor_filter, &afx ); iobuf_push_filter( out, armor_filter, &afx );
/* create it */ /* create it */
rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0, NULL, NULL); rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0,
revocation_reason_build_cb,
reason );
if( rc ) { if( rc ) {
log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc)); log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc));
goto leave; goto leave;
@ -198,193 +228,127 @@ gen_revoke( const char *uname )
iobuf_cancel(out); iobuf_cancel(out);
else else
iobuf_close(out); iobuf_close(out);
release_revocation_reason_info( reason );
return rc; return rc;
} }
#if 0 /* The code is not complete but anyway, now we use */
/* the edit menu to revoke signature */
/****************
* Return true if there is already a revocation signature for KEYID
* in KEYBLOCK at point node.
*/
static int
already_revoked( const KBNODE keyblock, const KBNODE node, u32 *keyid ) ) {
{
const KBNODE n = find_prev_kbnode( keyblock, node, PKT_USER_ID );
for( ; n; n = n->next ) {
PKT_signature *sig; struct revocation_reason_info *
if( n->pkt->pkttype == PKT_SIGNATURE ask_revocation_reason( int key_rev, int cert_rev, int hint )
&& (sig = node->pkt->pkt.signature)->sig_class == 0x30 {
&& sig->keyid[0] == keyid[0] int code;
&& sig->keyid[1] == keyid[1] ) char *description = NULL;
return 1; struct revocation_reason_info *reason;
const char *text_1 = _("Key has been compromised");
const char *text_2 = _("Key is superseded");
const char *text_3 = _("Key is no longer used");
const char *text_4 = _("User ID is non longer valid");
const char *code_text = NULL;
do {
m_free(description);
description = NULL;
tty_printf(_("Please select the reason for the revocation:\n"));
if( key_rev )
tty_printf(" 1 = %s\n", text_1 );
if( key_rev )
tty_printf(" 2 = %s\n", text_2 );
if( key_rev )
tty_printf(" 3 = %s\n", text_3 );
if( cert_rev )
tty_printf(" 4 = %s\n", text_4 );
tty_printf( " 0 = %s\n", _("Cancel") );
if( hint )
tty_printf(_("(Probably you want to select %d here)\n"), hint );
for(code = 0; !code;) {
int n;
char *answer = cpr_get("ask_revocation_reason.code",
_("Your decision? "));
trim_spaces( answer );
cpr_kill_prompt();
if( *answer == 'q' || *answer == 'Q' )
n = 0;
else if( !isdigit( *answer ) )
n = -1;
else if( hint && !*answer )
n = hint;
else
n = atoi(answer);
m_free(answer);
if( !n )
return NULL; /* cancel */
else if( key_rev && n == 1 ) {
code = 0x02; /* key has been compromised */
code_text = text_1;
}
else if( key_rev && n == 2 ) {
code = 0x01; /* key is superseded */
code_text = text_2;
}
else if( key_rev && n == 3 ) {
code = 0x03; /* key is no longer used */
code_text = text_3;
}
else if( cert_rev && n == 4 ) {
code = 0x20; /* uid is non longer valid */
code_text = text_4;
}
else
tty_printf(_("Invalid selection.\n"));
} }
else if( n->pkt->pkttype == PKT_USER_ID
break; tty_printf(_("Enter an optional description; "
else if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY "end it with an empty line:\n") );
break; for(;;) {
} char *answer = cpr_get("ask_revocation_reason.text", "> " );
return 0; trim_trailing_ws( answer, strlen(answer) );
cpr_kill_prompt();
if( !*answer ) {
m_free(answer);
break;
}
{
char *p = make_printable_string( answer, strlen(answer), 0 );
m_free(answer);
answer = p;
}
if( !description )
description = m_strdup(answer);
else {
char *p = m_alloc( strlen(description) + strlen(answer) + 2 );
strcpy(stpcpy(stpcpy( p, description),"\n"),answer);
m_free(description);
description = p;
}
m_free(answer);
}
tty_printf(_("Reason for revocation: %s\n"), code_text );
if( !description )
tty_printf(_("(No description given)\n") );
else
tty_printf("%s\n", description );
} while( !cpr_get_answer_is_yes("ask_revocation_reason.okay",
_("Is this okay? ")) );
reason = m_alloc( sizeof *reason );
reason->code = code;
reason->desc = description;
return reason;
} }
/**************** void
* Ask whether the signature should be revoked. If the user commits this, release_revocation_reason_info( struct revocation_reason_info *reason )
* flag bit 0 is set.
*/
static void
ask_revoke_sig( KBNODE keyblock, KBNODE node, PKT_signature *sig ) ) {
{ {
KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID ); if( reason ) {
m_free( reason->desc );
if( !unode ) { m_free( reason );
log_error("Oops: no user ID for signature\n");
return;
}
tty_printf(_("user ID: \""));
tty_print_utf8_string( unode->pkt->pkt.user_id->name,
unode->pkt->pkt.user_id->len, 0 );
tty_printf(_("\"\nsigned with your key %08lX at %s\n"),
sig->keyid[1], datestr_from_sig(sig) );
if( cpr_get_answer_is_yes("ask_revoke_sig.one",
_("Create a revocation certificate for this signature? (y/N)")) ) {
node->flag |= 1;
} }
} }
/****************
* Generate a signature revocation certificate for UNAME
*/
int
gen_sig_revoke( const char *uname )
{
int rc = 0;
armor_filter_context_t afx;
compress_filter_context_t zfx;
PACKET pkt;
IOBUF out = NULL;
KBNODE keyblock = NULL;
KBNODE node;
KBPOS kbpos;
int uidchg;
if( opt.batch ) {
log_error(_("sorry, can't do this in batch mode\n"));
return G10ERR_GENERAL;
}
memset( &afx, 0, sizeof afx);
memset( &zfx, 0, sizeof zfx);
init_packet( &pkt );
/* get the keyblock */
rc = find_keyblock_byname( &kbpos, uname );
if( rc ) {
log_error(_("public key for user `%s' not found\n"), uname );
goto leave;
}
/* read the keyblock */
rc = read_keyblock( &kbpos, &keyblock );
if( rc ) {
log_error(_("error reading the certificate: %s\n"), g10_errstr(rc) );
goto leave;
}
/* get the keyid from the keyblock */
node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
if( !node ) {
log_error(_("Oops; public key lost!\n"));
rc = G10ERR_GENERAL;
goto leave;
}
if( (rc = open_outfile( NULL, 0, &out )) )
goto leave;
if( opt.armor ) {
afx.what = 1;
iobuf_push_filter( out, armor_filter, &afx );
}
/* Now walk over all signatures which we did with one of
* our secret keys. Hmmm: Should we check for duplicate signatures */
clear_kbnode_flags( flags );
for( node = keyblock; node; node = node->next ) {
PKT_signature *sig;
if( node->pkt->pkttype == PKT_SIGNATURE
&& ((sig = node->pkt->pkt.signature)->sig_class&~3) == 0x10
&& seckey_available( sig->keyid )
&& !already_revoked( keyblock, node, sig->keyid ) ) { ) {
ask_revoke_sig( keyblock, node, sig )
}
else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
break;
}
for( node = keyblock; node; node = node->next ) { {
if( (node->flag & 1) )
break;
}
if( !node ) {
log_info(_("nothing to revoke\n"));
iobuf_cancel(out);
out = NULL;
goto leave;
}
init_packet( &pkt );
pkt.pkttype = PKT_PUBLIC_KEY;
pkt.pkt.public_key = keyblock->pkt->pkt.public_key;
rc = build_packet( out, &pkt );
if( rc ) {
log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
goto leave;
}
uidchg = 1;
for( node = keyblock; node; node = node->next ) {
if( node->pkt->pkttype == PKT_USER_ID )
uidchg = 1;
if( !(node->flag & 1) )
continue;
if( uidchg ) {
/* create a user ID packet */
.......
uidchg = 0;
}
/* create it */
rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x30, 0, NULL, NULL);
if( rc ) {
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;
}
}
leave:
release_kbnode( keyblock );
if( !out )
;
else if( rc )
iobuf_cancel(out);
else
iobuf_close(out);
return rc;
}
#endif /* unused code */