aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog12
-rw-r--r--g10/build-packet.c7
-rw-r--r--g10/keygen.c118
-rw-r--r--g10/packet.h1
-rw-r--r--g10/sign.c20
5 files changed, 139 insertions, 19 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 39dfa1844..20195a169 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,15 @@
+2004-04-12 David Shaw <[email protected]>
+
+ * 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 <[email protected]>
* g10.c (main): --no-use-embedded-filename.
diff --git a/g10/build-packet.c b/g10/build-packet.c
index b3bb3f32a..2513b36a0 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -725,6 +725,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
case SIGSUBPKT_NOTATION:
case SIGSUBPKT_POLICY:
case SIGSUBPKT_REV_KEY:
+ case SIGSUBPKT_SIGNATURE:
/* we do allow multiple subpackets */
break;
@@ -781,18 +782,20 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
else
nlen = 1; /* just a 1 byte length header */
- switch( type ) {
+ switch( type )
+ {
/* The issuer being unhashed is a historical oddity. It
should work equally as well hashed. Of course, if even an
unhashed issuer is tampered with, it makes it awfully hard
to verify the sig... */
case SIGSUBPKT_ISSUER:
+ case SIGSUBPKT_SIGNATURE:
hashed = 0;
break;
default:
hashed = 1;
break;
- }
+ }
if( critical )
type |= SIGSUBPKT_FLAG_CRITICAL;
diff --git a/g10/keygen.c b/g10/keygen.c
index ba5080b9d..c7df8ead4 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -525,6 +525,98 @@ keygen_add_revkey(PKT_signature *sig, void *opaque)
}
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
write_direct_sig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
struct revocation_key *revkey )
{
@@ -616,7 +708,7 @@ write_keybinding( KBNODE root, KBNODE pub_root,
PKT_signature *sig;
int rc=0;
KBNODE node;
- PKT_public_key *pk, *subpk;
+ PKT_public_key *pri_pk, *sub_pk;
struct opaque_data_usage_and_pk oduap;
if( opt.verbose )
@@ -626,30 +718,38 @@ write_keybinding( KBNODE root, KBNODE pub_root,
node = find_kbnode( pub_root, PKT_PUBLIC_KEY );
if( !node )
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
* creation is able to retrieve the public key */
- cache_public_key (pk);
+ cache_public_key (pri_pk);
/* find the last subkey */
- subpk = NULL;
+ sub_pk = NULL;
for(node=pub_root; node; node = node->next ) {
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();
/* and make the signature */
oduap.usage = use;
- oduap.pk = subpk;
- rc = make_keysig_packet( &sig, pk, NULL, subpk, pri_sk, 0x18, 0, 0, 0, 0,
- keygen_add_key_flags_and_expire, &oduap );
+ oduap.pk = sub_pk;
+ rc=make_keysig_packet(&sig, pri_pk, NULL, sub_pk, pri_sk, 0x18, 0, 0, 0, 0,
+ keygen_add_key_flags_and_expire, &oduap );
if( rc ) {
log_error("make_keysig_packet failed: %s\n", g10_errstr(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->pkttype = PKT_SIGNATURE;
pkt->pkt.signature = sig;
diff --git a/g10/packet.h b/g10/packet.h
index a9b3de5f8..d873c6ba7 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -352,6 +352,7 @@ typedef enum {
SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */
SIGSUBPKT_REVOC_REASON =29, /* reason for revocation */
SIGSUBPKT_FEATURES =30, /* feature flags */
+ SIGSUBPKT_SIGNATURE =32, /* embedded signature */
SIGSUBPKT_FLAG_CRITICAL=128
} sigsubpkttype_t;
diff --git a/g10/sign.c b/g10/sign.c
index f3343e387..1824060c2 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -1164,7 +1164,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
MD_HANDLE md;
assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x1F
- || sigclass == 0x20 || sigclass == 0x18
+ || sigclass == 0x20 || sigclass == 0x18 || sigclass == 0x19
|| sigclass == 0x30 || sigclass == 0x28 );
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 );
- /* hash the public key certificate and the user id */
+ /* hash the public key certificate */
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 );
- }
- else if( sigclass != 0x1F && sigclass != 0x20 ) {
+ }
+ else if( sigclass != 0x1F && sigclass != 0x20 )
+ {
+ /* hash the user id */
hash_uid (md, sigversion, uid);
- }
+ }
/* and make the signature packet */
sig = m_alloc_clear( sizeof *sig );
sig->version = sigversion;
@@ -1266,8 +1271,7 @@ update_keysig_packet( PKT_signature **ret_sig,
PKT_public_key *subpk,
PKT_secret_key *sk,
int (*mksubpkt)(PKT_signature *, void *),
- void *opaque
- )
+ void *opaque )
{
PKT_signature *sig;
int rc=0;