mirror of
git://git.gnupg.org/gnupg.git
synced 2025-03-28 22:49:59 +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>
|
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
|
* keyserver.c (keyserver_spawn): Fix keyserver options on tempfile
|
||||||
only platforms. Noted by Roger Sondermann.
|
only platforms. Noted by Roger Sondermann.
|
||||||
|
|
||||||
|
@ -243,6 +243,7 @@ size_t keystrlen(void);
|
|||||||
const char *keystr(u32 *keyid);
|
const char *keystr(u32 *keyid);
|
||||||
const char *keystr_from_pk(PKT_public_key *pk);
|
const char *keystr_from_pk(PKT_public_key *pk);
|
||||||
const char *keystr_from_sk(PKT_secret_key *sk);
|
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_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 );
|
||||||
|
24
g10/keyid.c
24
g10/keyid.c
@ -212,6 +212,30 @@ keystr_from_sk(PKT_secret_key *sk)
|
|||||||
return keystr(sk->keyid);
|
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
|
* 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.
|
||||||
|
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",
|
fprintf(spawn->tochild,"0x%08lX%08lX\n",
|
||||||
(ulong)desc[i].u.kid[0],
|
(ulong)desc[i].u.kid[0],
|
||||||
(ulong)desc[i].u.kid[1]);
|
(ulong)desc[i].u.kid[1]);
|
||||||
else
|
else if(desc[i].mode==KEYDB_SEARCH_MODE_SHORT_KID)
|
||||||
fprintf(spawn->tochild,"0x%08lX\n",
|
fprintf(spawn->tochild,"0x%08lX\n",
|
||||||
(ulong)desc[i].u.kid[1]);
|
(ulong)desc[i].u.kid[1]);
|
||||||
}
|
}
|
||||||
@ -1312,54 +1312,110 @@ keyserver_import_keyid(u32 *keyid)
|
|||||||
return keyserver_work(GET,NULL,&desc,1,opt.keyserver);
|
return keyserver_work(GET,NULL,&desc,1,opt.keyserver);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* code mostly stolen from do_export_stream */
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
|
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;
|
KBNODE keyblock=NULL,node;
|
||||||
GETKEY_CTX ctx;
|
KEYDB_HANDLE kdbhd;
|
||||||
|
KEYDB_SEARCH_DESC *desc;
|
||||||
|
STRLIST sl;
|
||||||
|
|
||||||
*count=0;
|
*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);
|
*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)))
|
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)
|
if(opt.keyserver_options.options&KEYSERVER_HONOR_KEYSERVER_URL)
|
||||||
{
|
{
|
||||||
PKT_user_id *uid=NULL;
|
PKT_user_id *uid=NULL;
|
||||||
PKT_signature *sig=NULL;
|
PKT_signature *sig=NULL;
|
||||||
|
|
||||||
|
merge_keys_and_selfsig(keyblock);
|
||||||
|
|
||||||
for(node=node->next;node;node=node->next)
|
for(node=node->next;node;node=node->next)
|
||||||
{
|
{
|
||||||
if(node->pkt->pkttype==PKT_USER_ID
|
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);
|
p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&plen);
|
||||||
if(p && plen)
|
if(p && plen)
|
||||||
{
|
{
|
||||||
struct keyserver_spec *keyserver;
|
|
||||||
byte *dupe=m_alloc(plen+1);
|
byte *dupe=m_alloc(plen+1);
|
||||||
|
|
||||||
memcpy(dupe,p,plen);
|
memcpy(dupe,p,plen);
|
||||||
dupe[plen]='\0';
|
dupe[plen]='\0';
|
||||||
|
|
||||||
/* Make up a keyserver structure and do an
|
/* Try and parse the keyserver URL. If it
|
||||||
import for this key. Note that a preferred
|
doesn't work, then we end up writing NULL
|
||||||
keyserver without a scheme:// will be
|
which indicates we are the same as any other
|
||||||
interpreted as hkp:// */
|
key. */
|
||||||
|
|
||||||
keyserver=parse_keyserver_uri(dupe,0,NULL,0);
|
(*klist)[*count].skipfncvalue=
|
||||||
|
parse_keyserver_uri(dupe,0,NULL,0);
|
||||||
m_free(dupe);
|
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)++;
|
(*count)++;
|
||||||
|
|
||||||
if(*count==num)
|
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);
|
*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
|
/* Note this is different than the original HKP refresh. It allows
|
||||||
@ -1500,6 +1504,36 @@ keyserver_refresh(STRLIST users)
|
|||||||
|
|
||||||
if(count>0)
|
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(opt.keyserver)
|
||||||
{
|
{
|
||||||
if(count==1)
|
if(count==1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user