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

* keygen.c (make_backsig): If DO_BACKSIGS is not defined, do not create

backsigs.

* getkey.c (merge_selfsigs_subkey): Find 0x19 backsigs on subkey selfsigs
and verify they are valid.  If DO_BACKSIGS is not defined, fake this as
always valid.

* packet.h, parse-packet.c (parse_signature): Make parse_signature
non-static so we can parse 0x19s in self-sigs.

* main.h, sig-check.c (check_backsig): Check a 0x19 signature.
(signature_check2): Give a backsig warning if there is no or a bad 0x19
with signatures from a subkey.
This commit is contained in:
David Shaw 2004-04-23 03:01:53 +00:00
parent 8030362eae
commit 4a07655935
7 changed files with 123 additions and 7 deletions

View File

@ -1,3 +1,19 @@
2004-04-22 David Shaw <dshaw@jabberwocky.com>
* keygen.c (make_backsig): If DO_BACKSIGS is not defined, do not
create backsigs.
* getkey.c (merge_selfsigs_subkey): Find 0x19 backsigs on subkey
selfsigs and verify they are valid. If DO_BACKSIGS is not
defined, fake this as always valid.
* packet.h, parse-packet.c (parse_signature): Make parse_signature
non-static so we can parse 0x19s in self-sigs.
* main.h, sig-check.c (check_backsig): Check a 0x19 signature.
(signature_check2): Give a backsig warning if there is no or a bad
0x19 with signatures from a subkey.
2004-04-21 David Shaw <dshaw@jabberwocky.com>
* parse-packet.c (dump_sig_subpkt, parse_one_sig_subpkt,

View File

@ -1923,8 +1923,51 @@ merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode )
key_expire = 0;
subpk->has_expired = key_expire >= curtime? 0 : key_expire;
subpk->expiredate = key_expire;
}
#ifndef DO_BACKSIGS
/* Pretend the backsig is present and accounted for. */
subpk->backsig=2;
#else
/* Find the first 0x19 embedded signature on our self-sig. */
if(subpk->backsig==0)
{
int seq=0;
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)))
break;
if(p==NULL)
{
seq=0;
/* It is safe to have this in the unhashed area since the
0x19 is located here 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)))
break;
}
if(p)
{
PKT_signature *backsig=m_alloc_clear(sizeof(PKT_signature));
IOBUF backsig_buf=iobuf_temp_with_content(p,n);
if(parse_signature(backsig_buf,PKT_SIGNATURE,n,backsig)==0)
{
if(check_backsig(mainpk,subpk,backsig)==0)
subpk->backsig=2;
else
subpk->backsig=1;
}
iobuf_close(backsig_buf);
free_seckey_enc(backsig);
}
}
#endif
}
/*

View File

@ -531,10 +531,12 @@ make_backsig(PKT_signature *sig, PKT_public_key *pk,
PKT_signature *backsig;
int rc;
#ifndef DO_BACKSIGS
/* 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;
#endif
cache_public_key (sub_pk);

View File

@ -1,5 +1,6 @@
/* main.h
* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
* 2004 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -119,6 +120,8 @@ int sign_symencrypt_file (const char *fname, STRLIST locusr);
/*-- sig-check.c --*/
int check_revocation_keys (PKT_public_key *pk, PKT_signature *sig);
int check_backsig(PKT_public_key *main_pk,PKT_public_key *sub_pk,
PKT_signature *backsig);
int check_key_signature( KBNODE root, KBNODE node, int *is_selfsig );
int check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
int *is_selfsig, u32 *r_expiredate, int *r_expired );

View File

@ -205,6 +205,7 @@ typedef struct {
without the key to check it */
int is_valid; /* key (especially subkey) is valid */
int dont_cache; /* do not cache this */
byte backsig; /* 0=none, 1=bad, 2=good */
u32 main_keyid[2]; /* keyid of the primary key */
u32 keyid[2]; /* calculated by keyid_from_pk() */
byte is_primary;
@ -352,6 +353,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
@ -397,6 +399,8 @@ int copy_some_packets( IOBUF inp, IOBUF out, off_t stopoff );
int skip_some_packets( IOBUF inp, unsigned n );
#endif
int parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
PKT_signature *sig );
const byte *enum_sig_subpkt ( const subpktarea_t *subpkts,
sigsubpkttype_t reqtype,
size_t *ret_n, int *start, int *critical );

View File

@ -55,8 +55,6 @@ static int parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen,
PACKET *packet );
static int parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen,
PACKET *packet );
static int parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
PKT_signature *sig );
static int parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen,
PKT_onepass_sig *ops );
static int parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
@ -1201,7 +1199,7 @@ void parse_revkeys(PKT_signature *sig)
}
}
static int
int
parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
PKT_signature *sig )
{

View File

@ -75,11 +75,29 @@ signature_check2( PKT_signature *sig, MD_HANDLE digest,
else if(!pk->is_valid && !pk->is_primary)
rc=G10ERR_BAD_PUBKEY; /* you cannot have a good sig from an
invalid subkey */
else {
else
{
if(r_expiredate)
*r_expiredate = pk->expiredate;
rc = do_check( pk, sig, digest, r_expired, r_revoked );
}
/* Check the backsig. This is a 0x19 signature from the
subkey on the primary key. The idea here is that it should
not be possible for someone to "steal" subkeys and claim
them as their own. The attacker couldn't actually use the
subkey, but they could try and claim ownership of any
signaures issued by it. */
if(rc==0 && !pk->is_primary && pk->backsig<2)
{
if(pk->backsig==0)
log_info(_("WARNING: signing subkey %08lX is not"
" cross-certified\n"),(ulong)keyid_from_pk(pk,NULL));
else
log_info(_("WARNING: signing subkey %08lX has an invalid"
" cross-certification\n"),
(ulong)keyid_from_pk(pk,NULL));
}
}
free_public_key( pk );
@ -473,6 +491,38 @@ check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
return rc;
}
/* Backsigs (0x19) have the same format as binding sigs (0x18), but
this function is simpler than check_key_signature in a few ways.
For example, there is no support for expiring backsigs since it is
questionable what such a thing actually means. Note also that the
sig cache check here, unlike other sig caches in GnuPG, is not
persistent. */
int
check_backsig(PKT_public_key *main_pk,PKT_public_key *sub_pk,
PKT_signature *backsig)
{
MD_HANDLE md;
int rc;
if(!opt.no_sig_cache && backsig->flags.checked)
{
if((rc=check_digest_algo(backsig->digest_algo)))
return rc;
return backsig->flags.valid? 0 : G10ERR_BAD_SIGN;
}
md=md_open(backsig->digest_algo,0);
hash_public_key(md,main_pk);
hash_public_key(md,sub_pk);
rc=do_check(sub_pk,backsig,md,NULL,NULL);
cache_sig_result(backsig,rc);
md_close(md);
return rc;
}
/****************
* check the signature pointed to by NODE. This is a key signature.
* If the function detects a self-signature, it uses the PK from