1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-18 14:17:03 +01:00

* keygen.c (make_backsig): New function to add a backsig to a binding sig

of signing subkeys.  Currently disabled. (write_keybinding): Call it here,
for signing subkeys only.

* sign.c (make_keysig_packet): Allow generating 0x19 signatures (same as
0x18 or 0x28, but used for backsigs).

* packet.h, build-packet.c (build_sig_subpkt): Add new SIGSUBPKT_SIGNATURE
type for embedded signatures.
This commit is contained in:
David Shaw 2004-04-13 01:17:32 +00:00
parent d97995dcf6
commit ce7d313333
5 changed files with 139 additions and 19 deletions

View File

@ -1,3 +1,15 @@
2004-04-12 David Shaw <dshaw@jabberwocky.com>
* keygen.c (make_backsig): New function to add a backsig to a
binding sig of signing subkeys. Currently disabled.
(write_keybinding): Call it here, for signing subkeys only.
* sign.c (make_keysig_packet): Allow generating 0x19 signatures
(same as 0x18 or 0x28, but used for backsigs).
* packet.h, build-packet.c (build_sig_subpkt): Add new
SIGSUBPKT_SIGNATURE type for embedded signatures.
2004-03-31 David Shaw <dshaw@jabberwocky.com> 2004-03-31 David Shaw <dshaw@jabberwocky.com>
* g10.c (main): --no-use-embedded-filename. * g10.c (main): --no-use-embedded-filename.

View File

@ -725,6 +725,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
case SIGSUBPKT_NOTATION: case SIGSUBPKT_NOTATION:
case SIGSUBPKT_POLICY: case SIGSUBPKT_POLICY:
case SIGSUBPKT_REV_KEY: case SIGSUBPKT_REV_KEY:
case SIGSUBPKT_SIGNATURE:
/* we do allow multiple subpackets */ /* we do allow multiple subpackets */
break; break;
@ -781,18 +782,20 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
else else
nlen = 1; /* just a 1 byte length header */ nlen = 1; /* just a 1 byte length header */
switch( type ) { switch( type )
{
/* The issuer being unhashed is a historical oddity. It /* The issuer being unhashed is a historical oddity. It
should work equally as well hashed. Of course, if even an should work equally as well hashed. Of course, if even an
unhashed issuer is tampered with, it makes it awfully hard unhashed issuer is tampered with, it makes it awfully hard
to verify the sig... */ to verify the sig... */
case SIGSUBPKT_ISSUER: case SIGSUBPKT_ISSUER:
case SIGSUBPKT_SIGNATURE:
hashed = 0; hashed = 0;
break; break;
default: default:
hashed = 1; hashed = 1;
break; break;
} }
if( critical ) if( critical )
type |= SIGSUBPKT_FLAG_CRITICAL; type |= SIGSUBPKT_FLAG_CRITICAL;

View File

@ -524,6 +524,98 @@ keygen_add_revkey(PKT_signature *sig, void *opaque)
return 0; return 0;
} }
static int
make_backsig(PKT_signature *sig, PKT_public_key *pk,
PKT_public_key *sub_pk, PKT_secret_key *sub_sk)
{
PKT_signature *backsig;
int rc;
/* This is not enabled yet, as I want to get a bit closer to RFC day
before enabling this. I've been burned before :) */
return 0;
cache_public_key (sub_pk);
rc=make_keysig_packet(&backsig,pk,NULL,sub_pk,sub_sk, 0x19, 0, 0, 0, 0,
NULL,NULL);
if( rc )
log_error("make_keysig_packet failed for backsig: %s\n", g10_errstr(rc) );
else
{
/* get it into a binary packed form. */
IOBUF backsig_out=iobuf_temp();
PACKET backsig_pkt;
byte *buf;
size_t pktlen=0;
init_packet(&backsig_pkt);
backsig_pkt.pkttype=PKT_SIGNATURE;
backsig_pkt.pkt.signature=backsig;
build_packet(backsig_out,&backsig_pkt);
free_packet(&backsig_pkt);
buf=iobuf_get_temp_buffer(backsig_out);
/* Remove the packet header */
if(buf[0]&0x40)
{
if(buf[1]<192)
{
pktlen=buf[1];
buf+=2;
}
else if(buf[1]<224)
{
pktlen=(buf[1]-192)*256;
pktlen+=buf[2]+192;
buf+=3;
}
else if(buf[1]==255)
{
pktlen =buf[2] << 24;
pktlen|=buf[3] << 16;
pktlen|=buf[4] << 8;
pktlen|=buf[5];
buf+=6;
}
else
BUG();
}
else
{
int mark=1;
switch(buf[0]&3)
{
case 3:
BUG();
break;
case 2:
pktlen =buf[mark++] << 24;
pktlen|=buf[mark++] << 16;
case 1:
pktlen|=buf[mark++] << 8;
case 0:
pktlen|=buf[mark++];
}
buf+=mark;
}
/* now make the binary blob into a subpacket */
build_sig_subpkt(sig,SIGSUBPKT_SIGNATURE,buf,pktlen);
iobuf_close(backsig_out);
}
return rc;
}
static int static int
write_direct_sig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk, write_direct_sig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
struct revocation_key *revkey ) struct revocation_key *revkey )
@ -616,7 +708,7 @@ write_keybinding( KBNODE root, KBNODE pub_root,
PKT_signature *sig; PKT_signature *sig;
int rc=0; int rc=0;
KBNODE node; KBNODE node;
PKT_public_key *pk, *subpk; PKT_public_key *pri_pk, *sub_pk;
struct opaque_data_usage_and_pk oduap; struct opaque_data_usage_and_pk oduap;
if( opt.verbose ) if( opt.verbose )
@ -626,30 +718,38 @@ write_keybinding( KBNODE root, KBNODE pub_root,
node = find_kbnode( pub_root, PKT_PUBLIC_KEY ); node = find_kbnode( pub_root, PKT_PUBLIC_KEY );
if( !node ) if( !node )
BUG(); BUG();
pk = node->pkt->pkt.public_key; pri_pk = node->pkt->pkt.public_key;
/* we have to cache the key, so that the verification of the signature /* we have to cache the key, so that the verification of the signature
* creation is able to retrieve the public key */ * creation is able to retrieve the public key */
cache_public_key (pk); cache_public_key (pri_pk);
/* find the last subkey */ /* find the last subkey */
subpk = NULL; sub_pk = NULL;
for(node=pub_root; node; node = node->next ) { for(node=pub_root; node; node = node->next ) {
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
subpk = node->pkt->pkt.public_key; sub_pk = node->pkt->pkt.public_key;
} }
if( !subpk ) if( !sub_pk )
BUG(); BUG();
/* and make the signature */ /* and make the signature */
oduap.usage = use; oduap.usage = use;
oduap.pk = subpk; oduap.pk = sub_pk;
rc = make_keysig_packet( &sig, pk, NULL, subpk, pri_sk, 0x18, 0, 0, 0, 0, rc=make_keysig_packet(&sig, pri_pk, NULL, sub_pk, pri_sk, 0x18, 0, 0, 0, 0,
keygen_add_key_flags_and_expire, &oduap ); keygen_add_key_flags_and_expire, &oduap );
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) );
return rc; return rc;
} }
/* make a backsig */
if(use&PUBKEY_USAGE_SIG)
{
rc=make_backsig(sig,pri_pk,sub_pk,sub_sk);
if(rc)
return rc;
}
pkt = m_alloc_clear( sizeof *pkt ); pkt = m_alloc_clear( sizeof *pkt );
pkt->pkttype = PKT_SIGNATURE; pkt->pkttype = PKT_SIGNATURE;
pkt->pkt.signature = sig; pkt->pkt.signature = sig;

View File

@ -352,6 +352,7 @@ typedef enum {
SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */ SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */
SIGSUBPKT_REVOC_REASON =29, /* reason for revocation */ SIGSUBPKT_REVOC_REASON =29, /* reason for revocation */
SIGSUBPKT_FEATURES =30, /* feature flags */ SIGSUBPKT_FEATURES =30, /* feature flags */
SIGSUBPKT_SIGNATURE =32, /* embedded signature */
SIGSUBPKT_FLAG_CRITICAL=128 SIGSUBPKT_FLAG_CRITICAL=128
} sigsubpkttype_t; } sigsubpkttype_t;

View File

@ -1164,7 +1164,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
MD_HANDLE md; MD_HANDLE md;
assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x1F assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x1F
|| sigclass == 0x20 || sigclass == 0x18 || sigclass == 0x20 || sigclass == 0x18 || sigclass == 0x19
|| sigclass == 0x30 || sigclass == 0x28 ); || sigclass == 0x30 || sigclass == 0x28 );
if (opt.force_v4_certs) if (opt.force_v4_certs)
@ -1203,14 +1203,19 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
md = md_open( digest_algo, 0 ); md = md_open( digest_algo, 0 );
/* hash the public key certificate and the user id */ /* hash the public key certificate */
hash_public_key( md, pk ); hash_public_key( md, pk );
if( sigclass == 0x18 || sigclass == 0x28 ) { /* subkey binding/revocation*/
if( sigclass == 0x18 || sigclass == 0x19 || sigclass == 0x28 )
{
/* hash the subkey binding/backsig/revocation */
hash_public_key( md, subpk ); hash_public_key( md, subpk );
} }
else if( sigclass != 0x1F && sigclass != 0x20 ) { else if( sigclass != 0x1F && sigclass != 0x20 )
{
/* hash the user id */
hash_uid (md, sigversion, uid); hash_uid (md, sigversion, uid);
} }
/* and make the signature packet */ /* and make the signature packet */
sig = m_alloc_clear( sizeof *sig ); sig = m_alloc_clear( sizeof *sig );
sig->version = sigversion; sig->version = sigversion;
@ -1266,8 +1271,7 @@ update_keysig_packet( PKT_signature **ret_sig,
PKT_public_key *subpk, PKT_public_key *subpk,
PKT_secret_key *sk, PKT_secret_key *sk,
int (*mksubpkt)(PKT_signature *, void *), int (*mksubpkt)(PKT_signature *, void *),
void *opaque void *opaque )
)
{ {
PKT_signature *sig; PKT_signature *sig;
int rc=0; int rc=0;