1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-09 23:39:51 +02:00

* keyedit.c (keyedit_menu, menu_backsign): New "backsign" command to

add 0x19 backsigs to old keys that don't have them.

* misc.c (parse_options): Fix build warning.

* main.h, keygen.c (make_backsig): Make public.
This commit is contained in:
David Shaw 2005-10-14 04:07:13 +00:00
parent 094a7ab401
commit 6c4e740a59
6 changed files with 175 additions and 5 deletions

View File

@ -1,3 +1,12 @@
2005-10-13 David Shaw <dshaw@jabberwocky.com>
* keyedit.c (keyedit_menu, menu_backsign): New "backsign" command
to add 0x19 backsigs to old keys that don't have them.
* misc.c (parse_options): Fix build warning.
* main.h, keygen.c (make_backsig): Make public.
2005-10-12 David Shaw <dshaw@jabberwocky.com>
* options.h, getkey.c (merge_selfsigs_subkey), gpg.c (main),

View File

@ -2049,6 +2049,8 @@ merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode )
int seq=0;
size_t n;
/* We do this while() since there may be other embedded
signatures in the future. We only want 0x19 here. */
while((p=enum_sig_subpkt(sig->hashed,
SIGSUBPKT_SIGNATURE,&n,&seq,NULL)))
if(n>3 && ((p[0]==3 && p[2]==0x19) || (p[0]==4 && p[1]==0x19)))
@ -2058,7 +2060,8 @@ merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode )
{
seq=0;
/* It is safe to have this in the unhashed area since the
0x19 is located here for convenience, not security. */
0x19 is located on the selfsig for convenience, not
security. */
while((p=enum_sig_subpkt(sig->unhashed,SIGSUBPKT_SIGNATURE,
&n,&seq,NULL)))
if(n>3 && ((p[0]==3 && p[2]==0x19) || (p[0]==4 && p[1]==0x19)))

View File

@ -63,6 +63,7 @@ static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
static int menu_addrevoker( KBNODE pub_keyblock,
KBNODE sec_keyblock, int sensitive );
static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
static int menu_backsign(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 );
static int menu_set_keyserver_url (const char *url,
@ -1338,8 +1339,8 @@ enum cmdids
cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
cmdEXPIRE, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF,
cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
cmdEXPIRE, cmdBACKSIGN, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF,
cmdSETPREF, cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCLEAN, cmdNOP
};
@ -1363,6 +1364,7 @@ static struct
{ "key" , cmdSELKEY , 0, N_("select subkey N") },
{ "check" , cmdCHECK , 0, N_("check signatures") },
{ "c" , cmdCHECK , 0, NULL },
{ "backsign", cmdBACKSIGN , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
{ "sign" , cmdSIGN , KEYEDIT_NOT_SK|KEYEDIT_TAIL_MATCH,
N_("sign selected user IDs [* see below for related commands]") },
{ "s" , cmdSIGN , KEYEDIT_NOT_SK, NULL },
@ -2051,6 +2053,15 @@ keyedit_menu( const char *username, STRLIST locusr,
}
break;
case cmdBACKSIGN:
if(menu_backsign(keyblock,sec_keyblock))
{
sec_modified = 1;
modified = 1;
redisplay = 1;
}
break;
case cmdPRIMARY:
if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
merge_keys_and_selfsig( keyblock );
@ -3622,6 +3633,151 @@ menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
return 1;
}
static int
menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
{
int rc,modified=0;
PKT_public_key *main_pk;
PKT_secret_key *main_sk,*sub_sk=NULL;
KBNODE node;
assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
merge_keys_and_selfsig(pub_keyblock);
main_pk=pub_keyblock->pkt->pkt.public_key;
main_sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
keyid_from_pk(main_pk,NULL);
for(node=pub_keyblock;node;node=node->next)
{
PKT_public_key *sub_pk=NULL;
KBNODE node2,sig_pk=NULL,sig_sk=NULL;
char *passphrase;
if(sub_sk)
{
free_secret_key(sub_sk);
sub_sk=NULL;
}
/* Find a signing subkey with no backsig */
if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY
&& (node->pkt->pkt.public_key->pubkey_usage&PUBKEY_USAGE_SIG)
&& !node->pkt->pkt.public_key->backsig)
sub_pk=node->pkt->pkt.public_key;
if(!sub_pk)
continue;
/* Find the selected selfsig on this subkey */
for(node2=node->next;
node2 && node2->pkt->pkttype==PKT_SIGNATURE;
node2=node2->next)
if(node2->pkt->pkt.signature->version>=4
&& node2->pkt->pkt.signature->flags.chosen_selfsig)
{
sig_pk=node2;
break;
}
if(!sig_pk)
continue;
/* Find the secret subkey that matches the public subkey */
for(node2=sec_keyblock;node2;node2=node2->next)
if(node2->pkt->pkttype==PKT_SECRET_SUBKEY
&& !cmp_public_secret_key(sub_pk,node2->pkt->pkt.secret_key))
{
sub_sk=copy_secret_key(NULL,node2->pkt->pkt.secret_key);
break;
}
if(!sub_sk)
continue;
/* Now finally find the matching selfsig on the secret subkey.
We can't use chosen_selfsig here (it's not set for secret
keys), so we just pick the selfsig with the right class.
This is what menu_expire does as well. */
for(node2=node2->next;
node2 && node2->pkt->pkttype==PKT_SIGNATURE;
node2=node2->next)
if(node2->pkt->pkt.signature->version>=4
&& node2->pkt->pkt.signature->keyid[0]==sig_pk->pkt->pkt.signature->keyid[0]
&& node2->pkt->pkt.signature->keyid[1]==sig_pk->pkt->pkt.signature->keyid[1]
&& node2->pkt->pkt.signature->sig_class==sig_pk->pkt->pkt.signature->sig_class)
{
sig_sk=node2;
break;
}
if(!sig_sk)
continue;
/* Now we can get to work. We have a main key and secret part,
a signing subkey with signature and secret part with
signature. */
passphrase=get_last_passphrase();
set_next_passphrase(passphrase);
xfree(passphrase);
rc=make_backsig(sig_pk->pkt->pkt.signature,main_pk,sub_pk,sub_sk);
if(rc==0)
{
PKT_signature *newsig;
PACKET *newpkt;
passphrase=get_last_passphrase();
set_next_passphrase(passphrase);
xfree(passphrase);
rc=update_keysig_packet(&newsig,sig_pk->pkt->pkt.signature,main_pk,
NULL,sub_pk,main_sk,NULL,NULL);
if(rc==0)
{
/* Put the new sig into place on the pubkey */
newpkt=xmalloc_clear(sizeof(*newpkt));
newpkt->pkttype=PKT_SIGNATURE;
newpkt->pkt.signature=newsig;
free_packet(sig_pk->pkt);
xfree(sig_pk->pkt);
sig_pk->pkt=newpkt;
/* Put the new sig into place on the seckey */
newpkt=xmalloc_clear(sizeof(*newpkt));
newpkt->pkttype=PKT_SIGNATURE;
newpkt->pkt.signature=copy_signature(NULL,newsig);
free_packet(sig_sk->pkt);
xfree(sig_sk->pkt);
sig_sk->pkt=newpkt;
modified=1;
}
else
{
log_error("update_keysig_packet failed: %s\n",g10_errstr(rc));
break;
}
}
else
{
log_error("make_backsig failed: %s\n",g10_errstr(rc));
break;
}
}
set_next_passphrase(NULL);
free_secret_key(main_sk);
if(sub_sk)
free_secret_key(sub_sk);
return modified;
}
static int
change_primary_uid_cb ( PKT_signature *sig, void *opaque )
{

View File

@ -711,7 +711,7 @@ keygen_add_revkey(PKT_signature *sig, void *opaque)
return 0;
}
static int
int
make_backsig(PKT_signature *sig,PKT_public_key *pk,
PKT_public_key *sub_pk,PKT_secret_key *sub_sk)
{

View File

@ -182,6 +182,8 @@ int keygen_add_std_prefs( PKT_signature *sig, void *opaque );
int keygen_upd_std_prefs( PKT_signature *sig, void *opaque );
int keygen_add_keyserver_url(PKT_signature *sig, void *opaque);
int keygen_add_revkey(PKT_signature *sig, void *opaque);
int make_backsig(PKT_signature *sig,PKT_public_key *pk,
PKT_public_key *sub_pk,PKT_secret_key *sub_sk);
int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
#ifdef ENABLE_CARD_SUPPORT
int generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,

View File

@ -979,7 +979,7 @@ parse_options(char *str,unsigned int *options,
for(i=0;opts[i].name;i++)
if(opts[i].help)
printf("%s%*s%s\n",opts[i].name,
maxlen+2-strlen(opts[i].name),"",_(opts[i].help));
maxlen+2-(int)strlen(opts[i].name),"",_(opts[i].help));
g10_exit(0);
}