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:
parent
d8aa22f172
commit
086e589898
@ -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.
|
||||
|
||||
|
@ -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 );
|
||||
|
24
g10/keyid.c
24
g10/keyid.c
@ -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.
|
||||
|
234
g10/keyserver.c
234
g10/keyserver.c
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user