mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-21 14:47:03 +01:00
* packet.h, build-packet.c (hash_public_key): Remove function ...
* keydb.h, keyid.c (hash_public_key, do_fingerprint_md): ... and make a new one here that shares code with the fingerprint calculations. This removes some duplicated functionality, and is also around 14% faster. (Every bit helps). * import.c (import_one): No longer need the Elgamal import warning. * getkey.c (get_pubkey_fast): This one is sort of obscure. get_pubkey_fast returns the primary key when requesting a subkey, so if a user has a key signed by a subkey (we don't do this, but used to), AND that key is not self-signed, AND the algorithm of the subkey in question is not present in GnuPG, AND the algorithm of the primary key that owns the subkey in question is present in GnuPG, then we will try and verify the subkey signature using the primary key algorithm and hit a BUG(). The fix is to not return a hit if the keyid is not the primary. All other users of get_pubkey_fast already expect a primary only.
This commit is contained in:
parent
888a6c2980
commit
db5ab5e730
@ -1,3 +1,26 @@
|
|||||||
|
2003-12-10 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
|
* packet.h, build-packet.c (hash_public_key): Remove function ...
|
||||||
|
|
||||||
|
* keydb.h, keyid.c (hash_public_key, do_fingerprint_md): ... and
|
||||||
|
make a new one here that shares code with the fingerprint
|
||||||
|
calculations. This removes some duplicated functionality, and is
|
||||||
|
also around 14% faster. (Every bit helps).
|
||||||
|
|
||||||
|
* import.c (import_one): No longer need the Elgamal import
|
||||||
|
warning.
|
||||||
|
|
||||||
|
* getkey.c (get_pubkey_fast): This one is sort of obscure.
|
||||||
|
get_pubkey_fast returns the primary key when requesting a subkey,
|
||||||
|
so if a user has a key signed by a subkey (we don't do this, but
|
||||||
|
used to), AND that key is not self-signed, AND the algorithm of
|
||||||
|
the subkey in question is not present in GnuPG, AND the algorithm
|
||||||
|
of the primary key that owns the subkey in question is present in
|
||||||
|
GnuPG, then we will try and verify the subkey signature using the
|
||||||
|
primary key algorithm and hit a BUG(). The fix is to not return a
|
||||||
|
hit if the keyid is not the primary. All other users of
|
||||||
|
get_pubkey_fast already expect a primary only.
|
||||||
|
|
||||||
2003-12-09 David Shaw <dshaw@jabberwocky.com>
|
2003-12-09 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
* keyid.c (do_fingerprint_md): Remove the rules to hash the old v3
|
* keyid.c (do_fingerprint_md): Remove the rules to hash the old v3
|
||||||
|
@ -254,85 +254,6 @@ do_public_key( IOBUF out, int ctb, PKT_public_key *pk )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
|
||||||
* Make a hash value from the public key certificate
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
hash_public_key( MD_HANDLE md, PKT_public_key *pk )
|
|
||||||
{
|
|
||||||
PACKET pkt;
|
|
||||||
int rc = 0;
|
|
||||||
int ctb;
|
|
||||||
ulong pktlen;
|
|
||||||
int c;
|
|
||||||
IOBUF a = iobuf_temp();
|
|
||||||
#if 0
|
|
||||||
FILE *fp = fopen("dump.pk", "a");
|
|
||||||
int i=0;
|
|
||||||
|
|
||||||
fprintf(fp, "\nHashing PK (v%d):\n", pk->version);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* build the packet */
|
|
||||||
init_packet(&pkt);
|
|
||||||
pkt.pkttype = PKT_PUBLIC_KEY;
|
|
||||||
pkt.pkt.public_key = pk;
|
|
||||||
if( (rc = build_packet( a, &pkt )) )
|
|
||||||
log_fatal("build public_key for hashing failed: %s\n", g10_errstr(rc));
|
|
||||||
|
|
||||||
if( !(pk->version == 3 && pk->pubkey_algo == 16) ) {
|
|
||||||
/* skip the constructed header but don't do this for our very old
|
|
||||||
* v3 ElG keys */
|
|
||||||
ctb = iobuf_get_noeof(a);
|
|
||||||
pktlen = 0;
|
|
||||||
if( (ctb & 0x40) ) {
|
|
||||||
c = iobuf_get_noeof(a);
|
|
||||||
if( c < 192 )
|
|
||||||
pktlen = c;
|
|
||||||
else if( c < 224 ) {
|
|
||||||
pktlen = (c - 192) * 256;
|
|
||||||
c = iobuf_get_noeof(a);
|
|
||||||
pktlen += c + 192;
|
|
||||||
}
|
|
||||||
else if( c == 255 ) {
|
|
||||||
pktlen = iobuf_get_noeof(a) << 24;
|
|
||||||
pktlen |= iobuf_get_noeof(a) << 16;
|
|
||||||
pktlen |= iobuf_get_noeof(a) << 8;
|
|
||||||
pktlen |= iobuf_get_noeof(a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
|
|
||||||
for( ; lenbytes; lenbytes-- ) {
|
|
||||||
pktlen <<= 8;
|
|
||||||
pktlen |= iobuf_get_noeof(a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* hash a header */
|
|
||||||
md_putc( md, 0x99 );
|
|
||||||
pktlen &= 0xffff; /* can't handle longer packets */
|
|
||||||
md_putc( md, pktlen >> 8 );
|
|
||||||
md_putc( md, pktlen & 0xff );
|
|
||||||
}
|
|
||||||
/* hash the packet body */
|
|
||||||
while( (c=iobuf_get(a)) != -1 ) {
|
|
||||||
#if 0
|
|
||||||
fprintf( fp," %02x", c );
|
|
||||||
if( (++i == 24) ) {
|
|
||||||
putc('\n', fp);
|
|
||||||
i=0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
md_putc( md, c );
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
putc('\n', fp);
|
|
||||||
fclose(fp);
|
|
||||||
#endif
|
|
||||||
iobuf_cancel(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
|
do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
|
||||||
{
|
{
|
||||||
|
15
g10/getkey.c
15
g10/getkey.c
@ -374,13 +374,15 @@ get_pubkey( PKT_public_key *pk, u32 *keyid )
|
|||||||
|
|
||||||
/* Get a public key and store it into the allocated pk. This function
|
/* Get a public key and store it into the allocated pk. This function
|
||||||
differs from get_pubkey() in that it does not do a check of the key
|
differs from get_pubkey() in that it does not do a check of the key
|
||||||
to avoid recursion. It should be used only in very certain cases. */
|
to avoid recursion. It should be used only in very certain cases.
|
||||||
|
It will only retrieve primary keys. */
|
||||||
int
|
int
|
||||||
get_pubkey_fast (PKT_public_key *pk, u32 *keyid)
|
get_pubkey_fast (PKT_public_key *pk, u32 *keyid)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
KEYDB_HANDLE hd;
|
KEYDB_HANDLE hd;
|
||||||
KBNODE keyblock;
|
KBNODE keyblock;
|
||||||
|
u32 pkid[2];
|
||||||
|
|
||||||
assert (pk);
|
assert (pk);
|
||||||
#if MAX_PK_CACHE_ENTRIES
|
#if MAX_PK_CACHE_ENTRIES
|
||||||
@ -416,17 +418,22 @@ get_pubkey_fast (PKT_public_key *pk, u32 *keyid)
|
|||||||
|
|
||||||
assert ( keyblock->pkt->pkttype == PKT_PUBLIC_KEY
|
assert ( keyblock->pkt->pkttype == PKT_PUBLIC_KEY
|
||||||
|| keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY );
|
|| keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY );
|
||||||
copy_public_key (pk, keyblock->pkt->pkt.public_key );
|
|
||||||
|
keyid_from_pk(keyblock->pkt->pkt.public_key,pkid);
|
||||||
|
if(keyid[0]==pkid[0] && keyid[1]==pkid[1])
|
||||||
|
copy_public_key (pk, keyblock->pkt->pkt.public_key );
|
||||||
|
else
|
||||||
|
rc=G10ERR_NO_PUBKEY;
|
||||||
|
|
||||||
release_kbnode (keyblock);
|
release_kbnode (keyblock);
|
||||||
|
|
||||||
/* Not caching key here since it won't have all of the fields
|
/* Not caching key here since it won't have all of the fields
|
||||||
properly set. */
|
properly set. */
|
||||||
|
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
KBNODE
|
KBNODE
|
||||||
get_pubkeyblock( u32 *keyid )
|
get_pubkeyblock( u32 *keyid )
|
||||||
{
|
{
|
||||||
|
@ -559,10 +559,6 @@ import_one( const char *fname, KBNODE keyblock,
|
|||||||
keyid_from_pk( pk, keyid );
|
keyid_from_pk( pk, keyid );
|
||||||
uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
|
uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
|
||||||
|
|
||||||
if(pk->pubkey_algo==PUBKEY_ALGO_ELGAMAL)
|
|
||||||
log_info(_("key %08lX: Elgamal primary key -"
|
|
||||||
" this may take some time to import\n"),(ulong)keyid[1]);
|
|
||||||
|
|
||||||
if( opt.verbose && !opt.interactive ) {
|
if( opt.verbose && !opt.interactive ) {
|
||||||
log_info( "pub %4u%c/%08lX %s ",
|
log_info( "pub %4u%c/%08lX %s ",
|
||||||
nbits_from_pk( pk ),
|
nbits_from_pk( pk ),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* keydb.h - Key database
|
/* keydb.h - Key database
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -237,6 +237,7 @@ KEYDB_HANDLE get_ctx_handle(GETKEY_CTX ctx);
|
|||||||
|
|
||||||
/*-- keyid.c --*/
|
/*-- keyid.c --*/
|
||||||
int pubkey_letter( int algo );
|
int pubkey_letter( int algo );
|
||||||
|
void hash_public_key( MD_HANDLE md, PKT_public_key *pk );
|
||||||
u32 keyid_from_sk( PKT_secret_key *sk, u32 *keyid );
|
u32 keyid_from_sk( PKT_secret_key *sk, u32 *keyid );
|
||||||
u32 keyid_from_pk( PKT_public_key *pk, u32 *keyid );
|
u32 keyid_from_pk( PKT_public_key *pk, u32 *keyid );
|
||||||
u32 keyid_from_sig( PKT_signature *sig, u32 *keyid );
|
u32 keyid_from_sig( PKT_signature *sig, u32 *keyid );
|
||||||
@ -250,13 +251,11 @@ const char *datestr_from_sig( PKT_signature *sig );
|
|||||||
const char *expirestr_from_pk( PKT_public_key *pk );
|
const char *expirestr_from_pk( PKT_public_key *pk );
|
||||||
const char *expirestr_from_sk( PKT_secret_key *sk );
|
const char *expirestr_from_sk( PKT_secret_key *sk );
|
||||||
const char *expirestr_from_sig( PKT_signature *sig );
|
const char *expirestr_from_sig( PKT_signature *sig );
|
||||||
|
|
||||||
const char *colon_strtime (u32 t);
|
const char *colon_strtime (u32 t);
|
||||||
const char *colon_datestr_from_pk (PKT_public_key *pk);
|
const char *colon_datestr_from_pk (PKT_public_key *pk);
|
||||||
const char *colon_datestr_from_sk (PKT_secret_key *sk);
|
const char *colon_datestr_from_sk (PKT_secret_key *sk);
|
||||||
const char *colon_datestr_from_sig (PKT_signature *sig);
|
const char *colon_datestr_from_sig (PKT_signature *sig);
|
||||||
const char *colon_expirestr_from_sig (PKT_signature *sig);
|
const char *colon_expirestr_from_sig (PKT_signature *sig);
|
||||||
|
|
||||||
byte *fingerprint_from_sk( PKT_secret_key *sk, byte *buf, size_t *ret_len );
|
byte *fingerprint_from_sk( PKT_secret_key *sk, byte *buf, size_t *ret_len );
|
||||||
byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
|
byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
|
||||||
|
|
||||||
|
118
g10/keyid.c
118
g10/keyid.c
@ -47,59 +47,80 @@ pubkey_letter( int algo )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function is useful for v4 fingerprints and v3 or v4 key
|
||||||
|
signing. */
|
||||||
|
void
|
||||||
|
hash_public_key( MD_HANDLE md, PKT_public_key *pk )
|
||||||
|
{
|
||||||
|
unsigned n=6;
|
||||||
|
unsigned nb[PUBKEY_MAX_NPKEY];
|
||||||
|
unsigned nn[PUBKEY_MAX_NPKEY];
|
||||||
|
byte *pp[PUBKEY_MAX_NPKEY];
|
||||||
|
int i;
|
||||||
|
int npkey = pubkey_get_npkey( pk->pubkey_algo );
|
||||||
|
|
||||||
|
/* Two extra bytes for the expiration date in v3 */
|
||||||
|
if(pk->version<4)
|
||||||
|
n+=2;
|
||||||
|
|
||||||
|
if(npkey==0 && pk->pkey[0] && mpi_is_opaque(pk->pkey[0]))
|
||||||
|
{
|
||||||
|
pp[0]=mpi_get_opaque(pk->pkey[0],&nn[0]);
|
||||||
|
n+=nn[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for(i=0; i < npkey; i++ )
|
||||||
|
{
|
||||||
|
nb[i] = mpi_get_nbits(pk->pkey[i]);
|
||||||
|
pp[i] = mpi_get_buffer( pk->pkey[i], nn+i, NULL );
|
||||||
|
n += 2 + nn[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
md_putc( md, 0x99 ); /* ctb */
|
||||||
|
/* What does it mean if n is greater than than 0xFFFF ? */
|
||||||
|
md_putc( md, n >> 8 ); /* 2 byte length header */
|
||||||
|
md_putc( md, n );
|
||||||
|
md_putc( md, pk->version );
|
||||||
|
|
||||||
|
md_putc( md, pk->timestamp >> 24 );
|
||||||
|
md_putc( md, pk->timestamp >> 16 );
|
||||||
|
md_putc( md, pk->timestamp >> 8 );
|
||||||
|
md_putc( md, pk->timestamp );
|
||||||
|
|
||||||
|
if(pk->version<4)
|
||||||
|
{
|
||||||
|
u16 days=0;
|
||||||
|
if(pk->expiredate)
|
||||||
|
days=(u16)((pk->expiredate - pk->timestamp) / 86400L);
|
||||||
|
|
||||||
|
md_putc( md, days >> 8 );
|
||||||
|
md_putc( md, days );
|
||||||
|
}
|
||||||
|
|
||||||
|
md_putc( md, pk->pubkey_algo );
|
||||||
|
|
||||||
|
if(npkey==0 && pk->pkey[0] && mpi_is_opaque(pk->pkey[0]))
|
||||||
|
md_write(md,pp[0],nn[0]);
|
||||||
|
else
|
||||||
|
for(i=0; i < npkey; i++ )
|
||||||
|
{
|
||||||
|
md_putc( md, nb[i]>>8);
|
||||||
|
md_putc( md, nb[i] );
|
||||||
|
md_write( md, pp[i], nn[i] );
|
||||||
|
m_free(pp[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static MD_HANDLE
|
static MD_HANDLE
|
||||||
do_fingerprint_md( PKT_public_key *pk )
|
do_fingerprint_md( PKT_public_key *pk )
|
||||||
{
|
{
|
||||||
MD_HANDLE md;
|
MD_HANDLE md;
|
||||||
unsigned n=6;
|
|
||||||
unsigned nb[PUBKEY_MAX_NPKEY];
|
|
||||||
unsigned nn[PUBKEY_MAX_NPKEY];
|
|
||||||
byte *pp[PUBKEY_MAX_NPKEY];
|
|
||||||
int i;
|
|
||||||
int npkey = pubkey_get_npkey( pk->pubkey_algo );
|
|
||||||
|
|
||||||
md = md_open( DIGEST_ALGO_SHA1, 0);
|
md = md_open( DIGEST_ALGO_SHA1, 0);
|
||||||
|
hash_public_key(md,pk);
|
||||||
|
md_final( md );
|
||||||
|
|
||||||
if(npkey==0 && pk->pkey[0] && mpi_is_opaque(pk->pkey[0]))
|
return md;
|
||||||
{
|
|
||||||
pp[0]=mpi_get_opaque(pk->pkey[0],&nn[0]);
|
|
||||||
n+=nn[0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
for(i=0; i < npkey; i++ )
|
|
||||||
{
|
|
||||||
nb[i] = mpi_get_nbits(pk->pkey[i]);
|
|
||||||
pp[i] = mpi_get_buffer( pk->pkey[i], nn+i, NULL );
|
|
||||||
n += 2 + nn[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
md_putc( md, 0x99 ); /* ctb */
|
|
||||||
/* What does it mean if n is greater than than 0xFFFF ? */
|
|
||||||
md_putc( md, n >> 8 ); /* 2 byte length header */
|
|
||||||
md_putc( md, n );
|
|
||||||
md_putc( md, 4 );
|
|
||||||
|
|
||||||
md_putc( md, pk->timestamp >> 24 );
|
|
||||||
md_putc( md, pk->timestamp >> 16 );
|
|
||||||
md_putc( md, pk->timestamp >> 8 );
|
|
||||||
md_putc( md, pk->timestamp );
|
|
||||||
|
|
||||||
md_putc( md, pk->pubkey_algo );
|
|
||||||
|
|
||||||
if(npkey==0 && pk->pkey[0] && mpi_is_opaque(pk->pkey[0]))
|
|
||||||
md_write(md,pp[0],nn[0]);
|
|
||||||
else
|
|
||||||
for(i=0; i < npkey; i++ )
|
|
||||||
{
|
|
||||||
md_putc( md, nb[i]>>8);
|
|
||||||
md_putc( md, nb[i] );
|
|
||||||
md_write( md, pp[i], nn[i] );
|
|
||||||
m_free(pp[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
md_final( md );
|
|
||||||
|
|
||||||
return md;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static MD_HANDLE
|
static MD_HANDLE
|
||||||
@ -122,7 +143,6 @@ do_fingerprint_md_sk( PKT_secret_key *sk )
|
|||||||
return do_fingerprint_md( &pk );
|
return do_fingerprint_md( &pk );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Get the keyid from the secret key and put it into keyid
|
* Get the keyid from the secret key and put it into keyid
|
||||||
* if this is not NULL. Return the 32 low bits of the keyid.
|
* if this is not NULL. Return the 32 low bits of the keyid.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* packet.h - packet definitions
|
/* packet.h - packet definitions
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||||
* Free Software Foundation, Inc.
|
* 2003 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -424,7 +424,6 @@ PACKET *create_gpg_control ( ctrlpkttype_t type,
|
|||||||
/*-- build-packet.c --*/
|
/*-- build-packet.c --*/
|
||||||
int build_packet( IOBUF inp, PACKET *pkt );
|
int build_packet( IOBUF inp, PACKET *pkt );
|
||||||
u32 calc_packet_length( PACKET *pkt );
|
u32 calc_packet_length( PACKET *pkt );
|
||||||
void hash_public_key( MD_HANDLE md, PKT_public_key *pk );
|
|
||||||
void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
|
void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
|
||||||
const byte *buffer, size_t buflen );
|
const byte *buffer, size_t buflen );
|
||||||
void build_sig_subpkt_from_sig( PKT_signature *sig );
|
void build_sig_subpkt_from_sig( PKT_signature *sig );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user