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:
parent
8030362eae
commit
4a07655935
@ -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,
|
||||
|
45
g10/getkey.c
45
g10/getkey.c
@ -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
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 );
|
||||
|
@ -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 );
|
||||
|
@ -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 )
|
||||
{
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user