diff options
Diffstat (limited to 'g10/keyedit.c')
-rw-r--r-- | g10/keyedit.c | 152 |
1 files changed, 148 insertions, 4 deletions
diff --git a/g10/keyedit.c b/g10/keyedit.c index b27b64706..6c54c6a7b 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -49,6 +49,7 @@ static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock, int photo ); static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock ); static int menu_delsig( KBNODE pub_keyblock ); static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock ); +static int menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock ); static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock ); static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock ); static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock ); @@ -877,10 +878,10 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN, cmdLSIGN, cmdNRSIGN, cmdNRLSIGN, cmdREVSIG, cmdREVKEY, cmdDELSIG, cmdPRIMARY, cmdDEBUG, cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, - cmdADDKEY, cmdDELKEY, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, - cmdPREF, cmdEXPIRE, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, - cmdSETPREF, cmdUPDPREF, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, - cmdCHKTRUST, cmdNOP }; + cmdADDKEY, cmdDELKEY, cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, + cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE, cmdENABLEKEY, + cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF, cmdUPDPREF, cmdINVCMD, + cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST, cmdNOP }; static struct { const char *name; enum cmdids id; int need_sk; @@ -913,6 +914,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, { N_("delphoto"), cmdDELUID , 0,1,0, NULL }, { N_("addkey") , cmdADDKEY , 1,1,0, N_("add a secondary key") }, { N_("delkey") , cmdDELKEY , 0,1,0, N_("delete a secondary key") }, + { N_("addrevoker"),cmdADDREVOKER,1,1,0, N_("add a revocation key") }, { N_("delsig") , cmdDELSIG , 0,1,0, N_("delete signatures") }, { N_("expire") , cmdEXPIRE , 1,1,0, N_("change the expire date") }, { N_("primary") , cmdPRIMARY , 1,1,0, N_("flag user ID as primary")}, @@ -1247,6 +1249,15 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, } break; + case cmdADDREVOKER: + if( menu_addrevoker( keyblock, sec_keyblock ) ) { + redisplay = 1; + sec_modified = modified = 1; + merge_keys_and_selfsig( sec_keyblock ); + merge_keys_and_selfsig( keyblock ); + } + break; + case cmdREVKEY: { int n1; @@ -2010,6 +2021,139 @@ menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock ) } +/**************** + * Ask for a new revoker, do the selfsignature and put it into + * both keyblocks. + * Return true if there is a new revoker + */ +static int +menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock ) +{ + PKT_public_key *pk=NULL,*revoker_pk=NULL; + PKT_secret_key *sk=NULL; + PKT_signature *sig=NULL; + PACKET *pkt; + struct revocation_key revkey; + size_t fprlen; + int rc; + + assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY); + assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY); + + pk=pub_keyblock->pkt->pkt.public_key; + sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key); + + for(;;) + { + char *answer; + u32 keyid[2]; + char *p; + size_t n; + + if(revoker_pk) + free_public_key(revoker_pk); + + revoker_pk=m_alloc_clear(sizeof(*revoker_pk)); + + tty_printf("\n"); + + answer=cpr_get_utf8("keyedit.add_revoker", + _("Enter the user ID of the designated revoker: ")); + if(answer[0]=='\0' || answer[0]=='\004') + goto fail; + + rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL); + + if(rc) + { + log_error (_("key `%s' not found: %s\n"),answer,g10_errstr(rc)); + continue; + } + + fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen); + if(fprlen!=20) + { + log_error(_("cannot appoint a PGP 2.x style key as a " + "designated revoker\n")); + continue; + } + + if(cmp_public_keys(revoker_pk,pk)==0) + { + /* This actually causes no harm (after all, a key that + designates itself as a revoker is the same as a + regular key), but it's easy enough to check. */ + log_error(_("you cannot appoint a key as its own " + "designated revoker\n")); + continue; + } + + keyid_from_pk(revoker_pk,keyid); + + tty_printf("\npub %4u%c/%08lX %s ", + nbits_from_pk( revoker_pk ), + pubkey_letter( revoker_pk->pubkey_algo ), + (ulong)keyid[1], datestr_from_pk(pk) ); + + p = get_user_id( keyid, &n ); + tty_print_utf8_string( p, n ); + m_free(p); + tty_printf("\n"); + print_fingerprint(revoker_pk,NULL,2); + tty_printf("\n"); + + tty_printf("WARNING: appointing a key as a designated revoker " + "cannot be undone!\n"); + + tty_printf("\n"); + + if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay", + "Are you sure you want to appoint this " + "key as a designated revoker? (y/N): ")) + continue; + + revkey.class=0x80; + revkey.algid=revoker_pk->pubkey_algo; + free_public_key(revoker_pk); + break; + } + + rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 0, 0, 0, + keygen_add_revkey,&revkey ); + if( rc ) + { + log_error("signing failed: %s\n", g10_errstr(rc) ); + goto fail; + } + + free_secret_key(sk); + sk=NULL; + + /* insert into secret keyblock */ + pkt = m_alloc_clear( sizeof *pkt ); + pkt->pkttype = PKT_SIGNATURE; + pkt->pkt.signature = copy_signature(NULL, sig); + insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE ); + + /* insert into public keyblock */ + pkt = m_alloc_clear( sizeof *pkt ); + pkt->pkttype = PKT_SIGNATURE; + pkt->pkt.signature = sig; + insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE ); + + return 1; + + fail: + if(sk) + free_secret_key(sk); + if(sig) + free_seckey_enc(sig); + if(revoker_pk) + free_public_key(revoker_pk); + + return 0; +} + static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock ) |