1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

* keyserver.c (keyidlist): Go back to the old fast keyid lister. Only

merge selfsigs if we have to for honor-keyserver-url. (keyserver_refresh):
Keyserver URL handler moved here. (calculate_keyid_fpr): Removed.

* keydb.h, keyid.c (keystr_from_desc): Calculate a key string from a
KEYDB_SEARCH_DESC.
This commit is contained in:
David Shaw 2004-05-21 17:32:30 +00:00
parent d8aa22f172
commit 086e589898
4 changed files with 167 additions and 100 deletions

View File

@ -1,5 +1,13 @@
2004-05-21 David Shaw <dshaw@jabberwocky.com>
* keyserver.c (keyidlist): Go back to the old fast keyid lister.
Only merge selfsigs if we have to for honor-keyserver-url.
(keyserver_refresh): Keyserver URL handler moved here.
(calculate_keyid_fpr): Removed.
* keydb.h, keyid.c (keystr_from_desc): Calculate a key string from
a KEYDB_SEARCH_DESC.
* keyserver.c (keyserver_spawn): Fix keyserver options on tempfile
only platforms. Noted by Roger Sondermann.

View File

@ -243,6 +243,7 @@ size_t keystrlen(void);
const char *keystr(u32 *keyid);
const char *keystr_from_pk(PKT_public_key *pk);
const char *keystr_from_sk(PKT_secret_key *sk);
const char *keystr_from_desc(KEYDB_SEARCH_DESC *desc);
u32 keyid_from_sk( PKT_secret_key *sk, u32 *keyid );
u32 keyid_from_pk( PKT_public_key *pk, u32 *keyid );
u32 keyid_from_sig( PKT_signature *sig, u32 *keyid );

View File

@ -212,6 +212,30 @@ keystr_from_sk(PKT_secret_key *sk)
return keystr(sk->keyid);
}
const char *
keystr_from_desc(KEYDB_SEARCH_DESC *desc)
{
if(desc->mode==KEYDB_SEARCH_MODE_LONG_KID)
return keystr(desc->u.kid);
else if(desc->mode==KEYDB_SEARCH_MODE_FPR20)
{
u32 keyid[2];
keyid[0] = (unsigned char)desc->u.fpr[12] << 24
| (unsigned char)desc->u.fpr[13] << 16
| (unsigned char)desc->u.fpr[14] << 8
| (unsigned char)desc->u.fpr[15] ;
keyid[1] = (unsigned char)desc->u.fpr[16] << 24
| (unsigned char)desc->u.fpr[17] << 16
| (unsigned char)desc->u.fpr[18] << 8
| (unsigned char)desc->u.fpr[19] ;
return keystr(keyid);
}
else
BUG();
}
/****************
* 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.

View File

@ -850,7 +850,7 @@ keyserver_spawn(int action,STRLIST list,KEYDB_SEARCH_DESC *desc,
fprintf(spawn->tochild,"0x%08lX%08lX\n",
(ulong)desc[i].u.kid[0],
(ulong)desc[i].u.kid[1]);
else
else if(desc[i].mode==KEYDB_SEARCH_MODE_SHORT_KID)
fprintf(spawn->tochild,"0x%08lX\n",
(ulong)desc[i].u.kid[1]);
}
@ -1312,54 +1312,110 @@ keyserver_import_keyid(u32 *keyid)
return keyserver_work(GET,NULL,&desc,1,opt.keyserver);
}
static void
calculate_keyid_fpr(PKT_public_key *pk,KEYDB_SEARCH_DESC *desc)
{
if(pk->version<4)
{
desc->mode=KEYDB_SEARCH_MODE_LONG_KID;
keyid_from_pk(pk,desc->u.kid);
}
else
{
size_t dummy;
desc->mode=KEYDB_SEARCH_MODE_FPR20;
fingerprint_from_pk(pk,desc->u.fpr,&dummy);
}
}
/* code mostly stolen from do_export_stream */
static int
keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
{
int rc=0,num=100;
int rc=0,ndesc,num=100;
KBNODE keyblock=NULL,node;
GETKEY_CTX ctx;
KEYDB_HANDLE kdbhd;
KEYDB_SEARCH_DESC *desc;
STRLIST sl;
*count=0;
rc=get_pubkey_bynames(&ctx,NULL,users,&keyblock);
if(rc)
{
log_error("error reading key: %s\n", g10_errstr(rc) );
get_pubkey_end( ctx );
return rc;
}
*klist=m_alloc(sizeof(KEYDB_SEARCH_DESC)*num);
do
kdbhd=keydb_new(0);
if(!users)
{
ndesc = 1;
desc = m_alloc_clear ( ndesc * sizeof *desc);
desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
}
else
{
for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++)
;
desc = m_alloc ( ndesc * sizeof *desc);
for (ndesc=0, sl=users; sl; sl = sl->next)
{
if(classify_user_id (sl->d, desc+ndesc))
ndesc++;
else
log_error (_("key `%s' not found: %s\n"),
sl->d, g10_errstr (G10ERR_INV_USER_ID));
}
}
while (!(rc = keydb_search (kdbhd, desc, ndesc)))
{
if (!users)
desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
/* read the keyblock */
rc = keydb_get_keyblock (kdbhd, &keyblock );
if( rc )
{
log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
goto leave;
}
if((node=find_kbnode(keyblock,PKT_PUBLIC_KEY)))
{
PKT_public_key *pk=node->pkt->pkt.public_key;
/* This is to work around a bug in some keyservers (pksd and
OKS) that calculate v4 RSA keyids as if they were v3 RSA.
The answer is to refresh both the correct v4 keyid
(e.g. 99242560) and the fake v3 keyid (e.g. 68FDDBC7).
This only happens for key refresh using the HKP scheme
and if the refresh-add-fake-v3-keyids keyserver option is
set. */
if(fakev3 && is_RSA(node->pkt->pkt.public_key->pubkey_algo) &&
node->pkt->pkt.public_key->version>=4)
{
(*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID;
mpi_get_keyid(node->pkt->pkt.public_key->pkey[0],
(*klist)[*count].u.kid);
(*count)++;
/* Check the user ID for a preferred keyserver subpacket. */
if(*count==num)
{
num+=100;
*klist=m_realloc(*klist,sizeof(KEYDB_SEARCH_DESC)*num);
}
}
/* v4 keys get full fingerprints. v3 keys get long keyids.
This is because it's easy to calculate any sort of keyid
from a v4 fingerprint, but not a v3 fingerprint. */
if(node->pkt->pkt.public_key->version<4)
{
(*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID;
keyid_from_pk(node->pkt->pkt.public_key,
(*klist)[*count].u.kid);
}
else
{
size_t dummy;
(*klist)[*count].mode=KEYDB_SEARCH_MODE_FPR20;
fingerprint_from_pk(node->pkt->pkt.public_key,
(*klist)[*count].u.fpr,&dummy);
}
(*klist)[*count].skipfncvalue=NULL;
/* Are we honoring preferred keyservers? */
if(opt.keyserver_options.options&KEYSERVER_HONOR_KEYSERVER_URL)
{
PKT_user_id *uid=NULL;
PKT_signature *sig=NULL;
merge_keys_and_selfsig(keyblock);
for(node=node->next;node;node=node->next)
{
if(node->pkt->pkttype==PKT_USER_ID
@ -1381,82 +1437,23 @@ keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&plen);
if(p && plen)
{
struct keyserver_spec *keyserver;
byte *dupe=m_alloc(plen+1);
memcpy(dupe,p,plen);
dupe[plen]='\0';
/* Make up a keyserver structure and do an
import for this key. Note that a preferred
keyserver without a scheme:// will be
interpreted as hkp:// */
/* Try and parse the keyserver URL. If it
doesn't work, then we end up writing NULL
which indicates we are the same as any other
key. */
keyserver=parse_keyserver_uri(dupe,0,NULL,0);
(*klist)[*count].skipfncvalue=
parse_keyserver_uri(dupe,0,NULL,0);
m_free(dupe);
if(keyserver)
{
KEYDB_SEARCH_DESC desc;
calculate_keyid_fpr(pk,&desc);
rc=keyserver_work(GET,NULL,&desc,1,keyserver);
if(rc)
log_info(_("WARNING: unable to refresh key %s"
" via %s: %s\n"),
keystr_from_pk(pk),keyserver->uri,
g10_errstr(rc));
free_keyserver_spec(keyserver);
continue;
}
else
log_info(_("WARNING: unable to refresh key %s"
" via %s: %s\n"),
keystr_from_pk(pk),keyserver->uri,
g10_errstr(G10ERR_BAD_URI));
}
}
}
/* This is to work around a bug in some keyservers (pksd and
OKS) that calculate v4 RSA keyids as if they were v3 RSA.
The answer is to refresh both the correct v4 keyid
(e.g. 99242560) and the fake v3 keyid (e.g. 68FDDBC7).
This only happens for key refresh using the HKP scheme
and if the refresh-add-fake-v3-keyids keyserver option is
set. */
if(fakev3 && is_RSA(pk->pubkey_algo) && pk->version>=4)
{
(*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID;
mpi_get_keyid(pk->pkey[0],(*klist)[*count].u.kid);
(*count)++;
if(*count==num)
{
num+=100;
*klist=m_realloc(*klist,sizeof(KEYDB_SEARCH_DESC)*num);
}
}
/* v4 keys get full fingerprints. v3 keys get long keyids.
This is because it's easy to calculate any sort of key id
from a v4 fingerprint, but not a v3 fingerprint. */
if(pk->version<4)
{
(*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID;
keyid_from_pk(pk,(*klist)[*count].u.kid);
}
else
{
size_t dummy;
(*klist)[*count].mode=KEYDB_SEARCH_MODE_FPR20;
fingerprint_from_pk(pk,(*klist)[*count].u.fpr,&dummy);
}
(*count)++;
if(*count==num)
@ -1465,12 +1462,19 @@ keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
*klist=m_realloc(*klist,sizeof(KEYDB_SEARCH_DESC)*num);
}
}
release_kbnode(keyblock);
}
while(!get_pubkey_next(ctx,NULL,&keyblock));
return 0;
if(rc==-1)
rc=0;
leave:
if(rc)
m_free(*klist);
m_free(desc);
keydb_release(kdbhd);
release_kbnode(keyblock);
return rc;
}
/* Note this is different than the original HKP refresh. It allows
@ -1500,6 +1504,36 @@ keyserver_refresh(STRLIST users)
if(count>0)
{
int i;
/* Try to handle preferred keyserver keys first */
for(i=0;i<count;i++)
{
if(desc[i].skipfncvalue)
{
struct keyserver_spec *keyserver=desc[i].skipfncvalue;
/* We use the keyserver structure we parsed out before.
Note that a preferred keyserver without a scheme://
will be interpreted as hkp:// */
rc=keyserver_work(GET,NULL,&desc[i],1,keyserver);
if(rc)
log_info(_("WARNING: unable to refresh key %s"
" via %s: %s\n"),keystr_from_desc(&desc[i]),
keyserver->uri,g10_errstr(rc));
else
{
/* We got it, so mark it as NONE so we don't try and
get it again from the regular keyserver. */
desc[i].mode=KEYDB_SEARCH_MODE_NONE;
}
free_keyserver_spec(keyserver);
}
}
if(opt.keyserver)
{
if(count==1)