mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +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:
parent
094a7ab401
commit
6c4e740a59
@ -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>
|
2005-10-12 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
* options.h, getkey.c (merge_selfsigs_subkey), gpg.c (main),
|
* options.h, getkey.c (merge_selfsigs_subkey), gpg.c (main),
|
||||||
|
@ -2049,6 +2049,8 @@ merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode )
|
|||||||
int seq=0;
|
int seq=0;
|
||||||
size_t n;
|
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,
|
while((p=enum_sig_subpkt(sig->hashed,
|
||||||
SIGSUBPKT_SIGNATURE,&n,&seq,NULL)))
|
SIGSUBPKT_SIGNATURE,&n,&seq,NULL)))
|
||||||
if(n>3 && ((p[0]==3 && p[2]==0x19) || (p[0]==4 && p[1]==0x19)))
|
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;
|
seq=0;
|
||||||
/* It is safe to have this in the unhashed area since the
|
/* 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,
|
while((p=enum_sig_subpkt(sig->unhashed,SIGSUBPKT_SIGNATURE,
|
||||||
&n,&seq,NULL)))
|
&n,&seq,NULL)))
|
||||||
if(n>3 && ((p[0]==3 && p[2]==0x19) || (p[0]==4 && p[1]==0x19)))
|
if(n>3 && ((p[0]==3 && p[2]==0x19) || (p[0]==4 && p[1]==0x19)))
|
||||||
|
160
g10/keyedit.c
160
g10/keyedit.c
@ -63,6 +63,7 @@ static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
|||||||
static int menu_addrevoker( KBNODE pub_keyblock,
|
static int menu_addrevoker( KBNODE pub_keyblock,
|
||||||
KBNODE sec_keyblock, int sensitive );
|
KBNODE sec_keyblock, int sensitive );
|
||||||
static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
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_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
||||||
static int menu_set_preferences( 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,
|
static int menu_set_keyserver_url (const char *url,
|
||||||
@ -1338,8 +1339,8 @@ enum cmdids
|
|||||||
cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
|
cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
|
||||||
cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
|
cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
|
||||||
cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
|
cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
|
||||||
cmdEXPIRE, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF,
|
cmdEXPIRE, cmdBACKSIGN, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF,
|
||||||
cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
|
cmdSETPREF, cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
|
||||||
cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCLEAN, cmdNOP
|
cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCLEAN, cmdNOP
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1363,6 +1364,7 @@ static struct
|
|||||||
{ "key" , cmdSELKEY , 0, N_("select subkey N") },
|
{ "key" , cmdSELKEY , 0, N_("select subkey N") },
|
||||||
{ "check" , cmdCHECK , 0, N_("check signatures") },
|
{ "check" , cmdCHECK , 0, N_("check signatures") },
|
||||||
{ "c" , cmdCHECK , 0, NULL },
|
{ "c" , cmdCHECK , 0, NULL },
|
||||||
|
{ "backsign", cmdBACKSIGN , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
|
||||||
{ "sign" , cmdSIGN , KEYEDIT_NOT_SK|KEYEDIT_TAIL_MATCH,
|
{ "sign" , cmdSIGN , KEYEDIT_NOT_SK|KEYEDIT_TAIL_MATCH,
|
||||||
N_("sign selected user IDs [* see below for related commands]") },
|
N_("sign selected user IDs [* see below for related commands]") },
|
||||||
{ "s" , cmdSIGN , KEYEDIT_NOT_SK, NULL },
|
{ "s" , cmdSIGN , KEYEDIT_NOT_SK, NULL },
|
||||||
@ -2051,6 +2053,15 @@ keyedit_menu( const char *username, STRLIST locusr,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case cmdBACKSIGN:
|
||||||
|
if(menu_backsign(keyblock,sec_keyblock))
|
||||||
|
{
|
||||||
|
sec_modified = 1;
|
||||||
|
modified = 1;
|
||||||
|
redisplay = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case cmdPRIMARY:
|
case cmdPRIMARY:
|
||||||
if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
|
if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
|
||||||
merge_keys_and_selfsig( keyblock );
|
merge_keys_and_selfsig( keyblock );
|
||||||
@ -3622,6 +3633,151 @@ menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
|||||||
return 1;
|
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
|
static int
|
||||||
change_primary_uid_cb ( PKT_signature *sig, void *opaque )
|
change_primary_uid_cb ( PKT_signature *sig, void *opaque )
|
||||||
{
|
{
|
||||||
|
@ -711,7 +711,7 @@ keygen_add_revkey(PKT_signature *sig, void *opaque)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
make_backsig(PKT_signature *sig,PKT_public_key *pk,
|
make_backsig(PKT_signature *sig,PKT_public_key *pk,
|
||||||
PKT_public_key *sub_pk,PKT_secret_key *sub_sk)
|
PKT_public_key *sub_pk,PKT_secret_key *sub_sk)
|
||||||
{
|
{
|
||||||
|
@ -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_upd_std_prefs( PKT_signature *sig, void *opaque );
|
||||||
int keygen_add_keyserver_url(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 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 );
|
int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
||||||
#ifdef ENABLE_CARD_SUPPORT
|
#ifdef ENABLE_CARD_SUPPORT
|
||||||
int generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
|
int generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
|
||||||
|
@ -979,7 +979,7 @@ parse_options(char *str,unsigned int *options,
|
|||||||
for(i=0;opts[i].name;i++)
|
for(i=0;opts[i].name;i++)
|
||||||
if(opts[i].help)
|
if(opts[i].help)
|
||||||
printf("%s%*s%s\n",opts[i].name,
|
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);
|
g10_exit(0);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user