diff options
Diffstat (limited to '')
-rw-r--r-- | g10/keyedit.c | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/g10/keyedit.c b/g10/keyedit.c index 1ba92a2cd..b2fb13d28 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -57,6 +57,7 @@ static int count_keys_with_flag( KBNODE keyblock, unsigned flag ); static int count_selected_uids( KBNODE keyblock ); static int count_selected_keys( KBNODE keyblock ); static int menu_revsig( KBNODE keyblock ); +static int menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock ); #define CONTROL_D ('D' - 'A' + 1) @@ -523,7 +524,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands ) { enum cmdids { cmdNONE = 0, cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN, - cmdLSIGN, cmdREVSIG, + cmdLSIGN, cmdREVSIG, cmdREVKEY, cmdDEBUG, cmdSAVE, cmdADDUID, cmdDELUID, cmdADDKEY, cmdDELKEY, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE, cmdNOP }; @@ -560,6 +561,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands ) { N_("passwd") , cmdPASSWD , 1, N_("change the passphrase") }, { N_("trust") , cmdTRUST , 0, N_("change the ownertrust") }, { N_("revsig") , cmdREVSIG , 0, N_("revoke signatures") }, + { N_("revkey") , cmdREVKEY , 1, N_("revoke a secondary key") }, { NULL, cmdNONE } }; enum cmdids cmd; @@ -830,6 +832,28 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands ) } break; + case cmdREVKEY: { + int n1; + + if( !(n1=count_selected_keys( keyblock )) ) + tty_printf(_("You must select at least one key.\n")); + else if( sec_keyblock && !cpr_get_answer_is_yes( + "keyedit.revoke.subkey.okay", + n1 > 1? + _("Do you really want to revoke the selected keys? "): + _("Do you really want to revoke this key? ") + )) + ; + else { + if( menu_revkey( keyblock, sec_keyblock ) ) { + modified = 1; + /*sec_modified = 1;*/ + } + redisplay = 1; + } + } + break; + case cmdEXPIRE: if( menu_expire( keyblock, sec_keyblock ) ) { merge_keys_and_selfsig( sec_keyblock ); @@ -1663,4 +1687,56 @@ menu_revsig( KBNODE keyblock ) return changed; } +/**************** + * Revoke some of the secondary keys. + * Hmmm: Should we add a revocation to the secret keyring too? + * Does its all make sense to duplicate most of the information? + */ +static int +menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock ) +{ + PKT_public_key *mainpk; + KBNODE node; + int changed = 0; + int upd_trust = 0; + int rc; + + reloop: /* (better this way becuase we are modifing the keyring) */ + mainpk = pub_keyblock->pkt->pkt.public_key; + for( node = pub_keyblock; node; node = node->next ) { + if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY + && (node->flag & NODFLG_SELKEY) ) { + PACKET *pkt; + PKT_signature *sig; + PKT_secret_key *sk; + PKT_public_key *subpk = node->pkt->pkt.public_key; + + node->flag &= ~NODFLG_SELKEY; + sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key ); + rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk, 0x28, 0, + NULL, NULL ); + free_secret_key(sk); + if( rc ) { + log_error(_("signing failed: %s\n"), g10_errstr(rc)); + return changed; + } + changed = 1; /* we changed the keyblock */ + upd_trust = 1; + + pkt = m_alloc_clear( sizeof *pkt ); + pkt->pkttype = PKT_SIGNATURE; + pkt->pkt.signature = sig; + insert_kbnode( node, new_kbnode(pkt), PKT_SIGNATURE ); + goto reloop; + } + } + commit_kbnode( &pub_keyblock ); + /*commit_kbnode( &sec_keyblock );*/ + + if( upd_trust ) + clear_trust_checked_flag( mainpk ); + + return changed; +} + |