diff options
author | Werner Koch <wk@gnupg.org> | 1998-04-08 21:49:02 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 1998-04-08 21:49:02 +0200 |
commit | 8b10a87908f4d382735a046e7d043ebc250d8d67 (patch) | |
tree | 9c4255d5cd84df663f9a7001b7b6277e53cf6e6e /g10/getkey.c | |
parent | New tests (diff) | |
download | gnupg2-8b10a87908f4d382735a046e7d043ebc250d8d67.tar.xz gnupg2-8b10a87908f4d382735a046e7d043ebc250d8d67.zip |
test release
Diffstat (limited to 'g10/getkey.c')
-rw-r--r-- | g10/getkey.c | 102 |
1 files changed, 85 insertions, 17 deletions
diff --git a/g10/getkey.c b/g10/getkey.c index 7868df951..966bc5d69 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -69,7 +69,8 @@ static int pkc_cache_entries; /* number of entries in pkc cache */ static int lookup( PKT_public_cert *pkc, - int mode, u32 *keyid, const char *name ); + int mode, u32 *keyid, const char *name, + KBNODE *ret_keyblock ); static int lookup_skc( PKT_secret_cert *skc, int mode, u32 *keyid, const char *name ); @@ -238,7 +239,6 @@ get_pubkey( PKT_public_cert *pkc, u32 *keyid ) int rc = 0; pkc_cache_entry_t ce; - /* lets see wether we checked the keyid already */ for( kl = unknown_keyids; kl; kl = kl->next ) if( kl->keyid[0] == keyid[0] && kl->keyid[1] == keyid[1] ) @@ -259,7 +259,7 @@ get_pubkey( PKT_public_cert *pkc, u32 *keyid ) /* do a lookup */ - rc = lookup( pkc, 11, keyid, NULL ); + rc = lookup( pkc, 11, keyid, NULL, NULL ); if( !rc ) goto leave; @@ -329,8 +329,11 @@ hextobyte( const byte *s ) * - If the userid starts with a '*' a case insensitive substring search is * done (This is also the default). */ -int -get_pubkey_byname( PKT_public_cert *pkc, const char *name ) + + +static int +key_byname( int secret, + PKT_public_cert *pkc, PKT_secret_cert *skc, const char *name ) { int internal = 0; int rc = 0; @@ -424,23 +427,60 @@ get_pubkey_byname( PKT_public_cert *pkc, const char *name ) if( rc ) goto leave; - if( !pkc ) { - pkc = m_alloc_clear( sizeof *pkc ); - internal++; + if( secret ) { + if( !skc ) { + skc = m_alloc_clear( sizeof *skc ); + internal++; + } + rc = mode < 16? lookup_skc( skc, mode, keyid, name ) + : lookup_skc( skc, mode, keyid, fprint ); + } + else { + if( !pkc ) { + pkc = m_alloc_clear( sizeof *pkc ); + internal++; + } + rc = mode < 16? lookup( pkc, mode, keyid, name, NULL ) + : lookup( pkc, mode, keyid, fprint, NULL ); } - rc = mode < 16? lookup( pkc, mode, keyid, name ) - : lookup( pkc, mode, keyid, fprint ); leave: - if( internal ) - m_free(pkc); + if( internal && secret ) + m_free( skc ); + else if( internal ) + m_free( pkc ); return rc; } +int +get_pubkey_byname( PKT_public_cert *pkc, const char *name ) +{ + return key_byname( 0, pkc, NULL, name ); +} + + + +/**************** + * Search for a key with the given fingerprint and return the + * complete keyblock which may have more than only this key. + * The fingerprint should always be 20 bytes, fill with zeroes + * for 16 byte fprints. + */ +int +get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint ) +{ + int rc; + PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc ); + + rc = lookup( pkc, 20, NULL, fprint, ret_keyblock ); + + free_public_cert( pkc ); + return rc; +} /**************** - * Get a secret key and store it into skey + * Get a secret key and store it into skc */ int get_seckey( PKT_secret_cert *skc, u32 *keyid ) @@ -486,8 +526,8 @@ get_seckey_byname( PKT_secret_cert *skc, const char *name, int unprotect ) { int rc; - /* fixme: add support for compare_name */ - rc = lookup_skc( skc, name? 2:15, NULL, name ); + rc = name ? key_byname( 1, NULL, skc, name ) + : lookup_skc( skc, 15, NULL, NULL ); if( !rc && unprotect ) rc = check_secret_key( skc ); @@ -547,9 +587,12 @@ compare_name( const char *uid, size_t uidlen, const char *name, int mode ) * 20 = lookup by 20 byte fingerprint which is stored in NAME * Caller must provide an empty PKC, if the pubkey_algo is filled in, only * a key of this algo will be returned. + * If ret_keyblock is not NULL, the complete keyblock is returned also + * and the caller must release it. */ static int -lookup( PKT_public_cert *pkc, int mode, u32 *keyid, const char *name ) +lookup( PKT_public_cert *pkc, int mode, u32 *keyid, + const char *name, KBNODE *ret_keyblock ) { int rc; KBNODE keyblock = NULL; @@ -593,12 +636,22 @@ lookup( PKT_public_cert *pkc, int mode, u32 *keyid, const char *name ) } } else { /* keyid or fingerprint lookup */ + if( DBG_CACHE && (mode== 10 || mode==11) ) { + log_debug("lookup keyid=%08lx%08lx req_algo=%d mode=%d\n", + (ulong)keyid[0], (ulong)keyid[1], + pkc->pubkey_algo, mode ); + } for(k=keyblock; k; k = k->next ) { if( k->pkt->pkttype == PKT_PUBLIC_CERT || k->pkt->pkttype == PKT_PUBKEY_SUBCERT ) { if( mode == 10 || mode == 11 ) { u32 aki[2]; keyid_from_pkc( k->pkt->pkt.public_cert, aki ); + if( DBG_CACHE ) { + log_debug(" aki=%08lx%08lx algo=%d\n", + (ulong)aki[0], (ulong)aki[1], + k->pkt->pkt.public_cert->pubkey_algo ); + } if( aki[1] == keyid[1] && ( mode == 10 || aki[0] == keyid[0] ) && ( !pkc->pubkey_algo @@ -643,6 +696,10 @@ lookup( PKT_public_cert *pkc, int mode, u32 *keyid, const char *name ) assert( k->pkt->pkttype == PKT_PUBLIC_CERT || k->pkt->pkttype == PKT_PUBKEY_SUBCERT ); copy_public_cert( pkc, k->pkt->pkt.public_cert ); + if( ret_keyblock ) { + *ret_keyblock = keyblock; + keyblock = NULL; + } break; /* enumeration */ } release_kbnode( keyblock ); @@ -708,12 +765,22 @@ lookup_skc( PKT_secret_cert *skc, int mode, u32 *keyid, const char *name ) } } else { /* keyid or fingerprint lookup */ + if( DBG_CACHE && (mode== 10 || mode==11) ) { + log_debug("lookup_skc keyid=%08lx%08lx req_algo=%d mode=%d\n", + (ulong)keyid[0], (ulong)keyid[1], + skc->pubkey_algo, mode ); + } for(k=keyblock; k; k = k->next ) { if( k->pkt->pkttype == PKT_SECRET_CERT || k->pkt->pkttype == PKT_SECKEY_SUBCERT ) { if( mode == 10 || mode == 11 ) { u32 aki[2]; keyid_from_skc( k->pkt->pkt.secret_cert, aki ); + if( DBG_CACHE ) { + log_debug(" aki=%08lx%08lx algo=%d\n", + (ulong)aki[0], (ulong)aki[1], + k->pkt->pkt.secret_cert->pubkey_algo ); + } if( aki[1] == keyid[1] && ( mode == 10 || aki[0] == keyid[0] ) && ( !skc->pubkey_algo @@ -825,7 +892,8 @@ enum_secret_keys( void **context, PKT_secret_cert *skc ) while( (rc=parse_packet(c->iobuf, &pkt)) != -1 ) { if( rc ) ; /* e.g. unknown packet */ - else if( pkt.pkttype == PKT_SECRET_CERT ) { + else if( pkt.pkttype == PKT_SECRET_CERT + || pkt.pkttype == PKT_SECKEY_SUBCERT ) { copy_secret_cert( skc, pkt.pkt.secret_cert ); set_packet_list_mode(save_mode); return 0; /* found */ |