aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--g10/ChangeLog17
-rw-r--r--g10/getkey.c28
-rw-r--r--g10/hkp.c18
-rw-r--r--g10/hkp.h2
-rw-r--r--g10/keyserver.c162
-rw-r--r--g10/main.h1
-rw-r--r--g10/misc.c25
-rw-r--r--g10/pubkey-enc.c25
8 files changed, 160 insertions, 118 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index bd98bbeba..ea2c0d85b 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,4 +1,19 @@
-2002-03-12 David Shaw <[email protected]>
+2002-02-25 David Shaw <[email protected]>
+
+ * hkp.c (hkp_ask_import), hkp.h, keyserver.c (all): treat key
+ lists internally as fingerprints when possible. All this is via
+ KEYDB_SEARCH_DESC - no point in reinventing the wheel. This allows
+ the helper program to search the keyserver by fingerprint if
+ desired (and the keyserver supports it). Note that automatic
+ fingerprint promotion during refresh only applies to v4 keys as a
+ v4 fingerprint can be easily changed into a long or short key id,
+ and a v3 cannot.
+
+ * pubkey-enc.c, getkey.c, misc.c, main.h: Take two copies of
+ hextobyte() from pubkey-enc.c and getkey.c and make them into one
+ copy in misc.c.
+
+2002-02-22 David Shaw <[email protected]>
* keyserver.c (keyserver_search_prompt): Detect a "no keys found"
case even if the helper program does not explicitly say how many
diff --git a/g10/getkey.c b/g10/getkey.c
index 3821264c9..5f12040a5 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -451,34 +451,6 @@ seckey_available( u32 *keyid )
}
-
-static int
-hextobyte( const byte *s )
-{
- int c;
-
- if( *s >= '0' && *s <= '9' )
- c = 16 * (*s - '0');
- else if( *s >= 'A' && *s <= 'F' )
- c = 16 * (10 + *s - 'A');
- else if( *s >= 'a' && *s <= 'f' )
- c = 16 * (10 + *s - 'a');
- else
- return -1;
- s++;
- if( *s >= '0' && *s <= '9' )
- c += *s - '0';
- else if( *s >= 'A' && *s <= 'F' )
- c += 10 + *s - 'A';
- else if( *s >= 'a' && *s <= 'f' )
- c += 10 + *s - 'a';
- else
- return -1;
- return c;
-}
-
-
-
/****************
* Return the type of the user id:
*
diff --git a/g10/hkp.c b/g10/hkp.c
index 5c44d2681..62568f70f 100644
--- a/g10/hkp.c
+++ b/g10/hkp.c
@@ -48,15 +48,27 @@ static int urlencode_filter( void *opaque, int control,
* or other error codes.
*/
int
-hkp_ask_import( u32 *keyid, void *stats_handle)
+hkp_ask_import( KEYDB_SEARCH_DESC *desc, void *stats_handle)
{
struct http_context hd;
char *request;
int rc;
unsigned int hflags = opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY : 0;
+ u32 key[2];
+
+ if(desc->mode==KEYDB_SEARCH_MODE_FPR20)
+ keyid_from_fingerprint(desc->u.fpr,MAX_FINGERPRINT_LEN,key);
+ else if(desc->mode==KEYDB_SEARCH_MODE_LONG_KID ||
+ desc->mode==KEYDB_SEARCH_MODE_SHORT_KID)
+ {
+ key[0]=desc->u.kid[0];
+ key[1]=desc->u.kid[1];
+ }
+ else
+ return -1; /* HKP does not support v3 fingerprints */
log_info(_("requesting key %08lX from HKP keyserver %s\n"),
- (ulong)keyid[1],opt.keyserver_host );
+ (ulong)key[1],opt.keyserver_host );
request = m_alloc( strlen( opt.keyserver_host ) + 100 );
/* hkp does not accept the long keyid - we should really write a
* nicer one :-)
@@ -72,7 +84,7 @@ hkp_ask_import( u32 *keyid, void *stats_handle)
opt.keyserver_host,
atoi(opt.keyserver_port)>0?":":"",
atoi(opt.keyserver_port)>0?opt.keyserver_port:"",
- (ulong)keyid[1] );
+ (ulong)key[1] );
if(opt.keyserver_options.verbose>2)
log_info("request is \"%s\"\n",request);
diff --git a/g10/hkp.h b/g10/hkp.h
index 9ff8511d2..1fbf123f5 100644
--- a/g10/hkp.h
+++ b/g10/hkp.h
@@ -21,7 +21,7 @@
#ifndef G10_HKP_H
#define G10_HKP_H 1
-int hkp_ask_import( u32 *keyid, void *stats_handle);
+int hkp_ask_import( KEYDB_SEARCH_DESC *desc, void *stats_handle);
int hkp_import( STRLIST users );
int hkp_export( STRLIST users );
int hkp_search(STRLIST tokens);
diff --git a/g10/keyserver.c b/g10/keyserver.c
index 423c0eb45..2df47a0c5 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -177,7 +177,7 @@ printunquoted(char *string,char delim)
}
static int
-print_keyinfo(int count,char *keystring,u32 *keyid)
+print_keyinfo(int count,char *keystring,KEYDB_SEARCH_DESC *desc)
{
char *certid,*userid,*keytype,*tok;
int flags,keysize=0;
@@ -186,14 +186,12 @@ print_keyinfo(int count,char *keystring,u32 *keyid)
if((certid=strsep(&keystring,":"))==NULL)
return -1;
- /* Ideally this is the long key ID, but HKP uses the short key
- ID. */
- if(sscanf(certid,"%08lX%08lX",(ulong *)&keyid[0],(ulong *)&keyid[1])!=2)
- {
- keyid[0]=0;
- if(sscanf(certid,"%08lX",(ulong *)&keyid[1])!=1)
- return -1;
- }
+ classify_user_id (certid, desc);
+ if(desc->mode!=KEYDB_SEARCH_MODE_SHORT_KID &&
+ desc->mode!=KEYDB_SEARCH_MODE_LONG_KID &&
+ desc->mode!=KEYDB_SEARCH_MODE_FPR16 &&
+ desc->mode!=KEYDB_SEARCH_MODE_FPR20)
+ return -1;
if((tok=strsep(&keystring,":"))==NULL)
return -1;
@@ -249,7 +247,7 @@ print_keyinfo(int count,char *keystring,u32 *keyid)
if(expiretime>0)
printf(" expires %s,",strtimestamp(expiretime));
- printf(" keyid %s\n",certid);
+ printf(" key %s\n",certid);
return 0;
}
@@ -258,7 +256,8 @@ print_keyinfo(int count,char *keystring,u32 *keyid)
#define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\""
static int
-keyserver_spawn(int action,STRLIST list,u32 (*kidlist)[2],int count,int *prog)
+keyserver_spawn(int action,STRLIST list,
+ KEYDB_SEARCH_DESC *desc,int count,int *prog)
{
int ret=0,i,gotversion=0,outofband=0;
STRLIST temp;
@@ -333,8 +332,37 @@ keyserver_spawn(int action,STRLIST list,u32 (*kidlist)[2],int count,int *prog)
/* Which keys do we want? */
for(i=0;i<count;i++)
- fprintf(spawn->tochild,"0x%08lX%08lX\n",
- (ulong)kidlist[i][0],(ulong)kidlist[i][1]);
+ {
+ if(desc[i].mode==KEYDB_SEARCH_MODE_FPR20)
+ {
+ int f;
+
+ fprintf(spawn->tochild,"0x");
+
+ for(f=0;f<MAX_FINGERPRINT_LEN;f++)
+ fprintf(spawn->tochild,"%02X",(byte)desc[i].u.fpr[f]);
+
+ fprintf(spawn->tochild,"\n");
+ }
+ else if(desc[i].mode==KEYDB_SEARCH_MODE_FPR16)
+ {
+ int f;
+
+ fprintf(spawn->tochild,"0x");
+
+ for(f=0;f<16;f++)
+ fprintf(spawn->tochild,"%02X",(byte)desc[i].u.fpr[f]);
+
+ fprintf(spawn->tochild,"\n");
+ }
+ else if(desc[i].mode==KEYDB_SEARCH_MODE_LONG_KID)
+ fprintf(spawn->tochild,"0x%08lX%08lX\n",
+ (ulong)desc[i].u.kid[0],
+ (ulong)desc[i].u.kid[1]);
+ else
+ fprintf(spawn->tochild,"0x%08lX\n",
+ (ulong)desc[i].u.kid[1]);
+ }
fprintf(spawn->tochild,"\n");
@@ -526,7 +554,7 @@ keyserver_spawn(int action,STRLIST list,u32 (*kidlist)[2],int count,int *prog)
}
static int
-keyserver_work(int action,STRLIST list,u32 (*kidlist)[2],int count)
+keyserver_work(int action,STRLIST list,KEYDB_SEARCH_DESC *desc,int count)
{
int rc=0,ret=0;
@@ -550,7 +578,7 @@ keyserver_work(int action,STRLIST list,u32 (*kidlist)[2],int count)
{
case GET:
for(count--;count>=0;count--)
- if(hkp_ask_import(kidlist[count],stats_handle))
+ if(hkp_ask_import(&desc[count],stats_handle))
log_inc_errorcount();
break;
case SEND:
@@ -568,7 +596,7 @@ keyserver_work(int action,STRLIST list,u32 (*kidlist)[2],int count)
/* It's not the internal HKP code, so try and spawn a handler for it */
- rc=keyserver_spawn(action,list,kidlist,count,&ret);
+ rc=keyserver_spawn(action,list,desc,count,&ret);
if(ret)
{
switch(ret)
@@ -613,42 +641,37 @@ keyserver_export(STRLIST users)
int
keyserver_import(STRLIST users)
{
- u32 (*kidlist)[2];
+ KEYDB_SEARCH_DESC *desc;
int num=100,count=0;
int rc=0;
/* Build a list of key ids */
-
- kidlist=m_alloc(sizeof(u32)*2*num);
+ desc=m_alloc(sizeof(KEYDB_SEARCH_DESC)*num);
for(;users;users=users->next)
{
- KEYDB_SEARCH_DESC desc;
-
- classify_user_id (users->d, &desc);
- if(desc.mode==KEYDB_SEARCH_MODE_SHORT_KID ||
- desc.mode==KEYDB_SEARCH_MODE_LONG_KID)
+ classify_user_id (users->d, &desc[count]);
+ if(desc[count].mode!=KEYDB_SEARCH_MODE_SHORT_KID &&
+ desc[count].mode!=KEYDB_SEARCH_MODE_LONG_KID &&
+ desc[count].mode!=KEYDB_SEARCH_MODE_FPR16 &&
+ desc[count].mode!=KEYDB_SEARCH_MODE_FPR20)
{
- kidlist[count][0]=desc.u.kid[0];
- kidlist[count][1]=desc.u.kid[1];
- count++;
- if(count==num)
- {
- num+=100;
- kidlist=m_realloc(kidlist,sizeof(u32)*2*num);
- }
+ log_error(_("skipping invalid key ID \"%s\"\n"),users->d);
+ continue;
}
- else
+
+ count++;
+ if(count==num)
{
- log_error (_("skipping invalid key ID \"%s\"\n"), users->d );
- continue;
+ num+=100;
+ desc=m_realloc(desc,sizeof(KEYDB_SEARCH_DESC)*num);
}
}
if(count>0)
- rc=keyserver_work(GET,NULL,kidlist,count);
+ rc=keyserver_work(GET,NULL,desc,count);
- m_free(kidlist);
+ m_free(desc);
return rc;
}
@@ -673,7 +696,7 @@ keyserver_import_keyid(u32 *keyid)
/* code mostly stolen from do_export_stream */
static int
-keyidlist(STRLIST users,u32 (**kidlist)[2],int *count,int fakev3)
+keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
{
int rc=0,ndesc,num=100;
KBNODE keyblock=NULL,node;
@@ -683,7 +706,7 @@ keyidlist(STRLIST users,u32 (**kidlist)[2],int *count,int fakev3)
*count=0;
- *kidlist=m_alloc(sizeof(u32)*2*num);
+ *klist=m_alloc(sizeof(KEYDB_SEARCH_DESC)*num);
kdbhd=keydb_new(0);
@@ -734,37 +757,56 @@ keyidlist(STRLIST users,u32 (**kidlist)[2],int *count,int fakev3)
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],
- (*kidlist)[*count]);
+ (*klist)[*count].u.kid);
(*count)++;
if(*count==num)
{
num+=100;
- *kidlist=m_realloc(*kidlist,sizeof(u32)*2*num);
+ *klist=m_realloc(*klist,sizeof(KEYDB_SEARCH_DESC)*num);
}
}
- keyid_from_pk(node->pkt->pkt.public_key,(*kidlist)[*count]);
+ /* 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(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);
+ }
(*count)++;
if(*count==num)
{
num+=100;
- *kidlist=m_realloc(*kidlist,sizeof(u32)*2*num);
+ *klist=m_realloc(*klist,sizeof(KEYDB_SEARCH_DESC)*num);
}
}
}
- if( rc == -1 )
- rc = 0;
-
- leave:
- keydb_release(kdbhd);
- release_kbnode(keyblock);
+ if(rc==-1)
+ rc=0;
+
+ leave:
+ m_free(desc);
+ keydb_release(kdbhd);
+ release_kbnode(keyblock);
- return rc;
+ return rc;
}
/* Note this is different than the original HKP refresh. It allows
@@ -774,7 +816,7 @@ int
keyserver_refresh(STRLIST users)
{
int rc,count,fakev3=0;
- u32 (*kidlist)[2];
+ KEYDB_SEARCH_DESC *desc;
/* If refresh_add_fake_v3_keyids is on and it's a HKP scheme, then
enable fake v3 keyid generation. */
@@ -785,7 +827,7 @@ keyserver_refresh(STRLIST users)
strcasecmp(opt.keyserver_scheme,"x-broken-hkp")==0))
fakev3=1;
- rc=keyidlist(users,&kidlist,&count,fakev3);
+ rc=keyidlist(users,&desc,&count,fakev3);
if(rc)
return rc;
@@ -795,9 +837,9 @@ keyserver_refresh(STRLIST users)
log_info(_("%d keys to refresh\n"),count);
if(count>0)
- rc=keyserver_work(GET,NULL,kidlist,count);
+ rc=keyserver_work(GET,NULL,desc,count);
- m_free(kidlist);
+ m_free(desc);
return 0;
}
@@ -819,7 +861,7 @@ keyserver_search_prompt(IOBUF buffer,int count,const char *searchstr)
{
int i=0,validcount=1;
unsigned int maxlen=256,buflen=0;
- u32 (*keyids)[2];
+ KEYDB_SEARCH_DESC *desc;
byte *line=NULL;
char *answer;
@@ -832,7 +874,7 @@ keyserver_search_prompt(IOBUF buffer,int count,const char *searchstr)
count=1;
}
- keyids=m_alloc(count*sizeof(u32)*2);
+ desc=m_alloc(count*sizeof(KEYDB_SEARCH_DESC));
/* Read each line and show it to the user */
@@ -843,7 +885,7 @@ keyserver_search_prompt(IOBUF buffer,int count,const char *searchstr)
if(i==count)
{
count++;
- keyids=m_realloc(keyids,count*sizeof(u32)*2);
+ desc=m_realloc(desc,count*sizeof(KEYDB_SEARCH_DESC));
validcount=0;
}
@@ -861,7 +903,7 @@ keyserver_search_prompt(IOBUF buffer,int count,const char *searchstr)
rl=iobuf_read_line(buffer,&line,&buflen,&maxlen);
if(rl>0)
{
- if(print_keyinfo(i,line,keyids[i-1]))
+ if(print_keyinfo(i,line,&desc[i-1])==-1)
continue;
}
else
@@ -888,7 +930,7 @@ keyserver_search_prompt(IOBUF buffer,int count,const char *searchstr)
while((num=strsep(&split," ,"))!=NULL)
if(atoi(num)>=1 && atoi(num)<=i)
- keyserver_work(GET,NULL,&keyids[atoi(num)-1],1);
+ keyserver_work(GET,NULL,&desc[atoi(num)-1],1);
m_free(answer);
break;
@@ -896,7 +938,7 @@ keyserver_search_prompt(IOBUF buffer,int count,const char *searchstr)
}
}
- m_free(keyids);
+ m_free(desc);
m_free(line);
notfound:
diff --git a/g10/main.h b/g10/main.h
index cef6a8c32..5c1f34f42 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -68,6 +68,7 @@ int openpgp_md_test_algo( int algo );
int check_permissions(const char *path,int extension,int checkonly);
void idea_cipher_warn( int show );
char *pct_expando(const char *string,PKT_public_key *pk);
+int hextobyte( const char *s );
/*-- helptext.c --*/
void display_online_help( const char *keyword );
diff --git a/g10/misc.c b/g10/misc.c
index 5c3ef12de..2f8d28af7 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -550,3 +550,28 @@ pct_expando(const char *string,PKT_public_key *pk)
m_free(ret);
return NULL;
}
+
+int
+hextobyte( const char *s )
+{
+ int c;
+
+ if( *s >= '0' && *s <= '9' )
+ c = 16 * (*s - '0');
+ else if( *s >= 'A' && *s <= 'F' )
+ c = 16 * (10 + *s - 'A');
+ else if( *s >= 'a' && *s <= 'f' )
+ c = 16 * (10 + *s - 'a');
+ else
+ return -1;
+ s++;
+ if( *s >= '0' && *s <= '9' )
+ c += *s - '0';
+ else if( *s >= 'A' && *s <= 'F' )
+ c += 10 + *s - 'A';
+ else if( *s >= 'a' && *s <= 'f' )
+ c += 10 + *s - 'a';
+ else
+ return -1;
+ return c;
+}
diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
index 05ba85f85..d052b3c9b 100644
--- a/g10/pubkey-enc.c
+++ b/g10/pubkey-enc.c
@@ -263,31 +263,6 @@ get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid )
}
-static int
-hextobyte( const char *s )
-{
- int c;
-
- if( *s >= '0' && *s <= '9' )
- c = 16 * (*s - '0');
- else if( *s >= 'A' && *s <= 'F' )
- c = 16 * (10 + *s - 'A');
- else if( *s >= 'a' && *s <= 'f' )
- c = 16 * (10 + *s - 'a');
- else
- return -1;
- s++;
- if( *s >= '0' && *s <= '9' )
- c += *s - '0';
- else if( *s >= 'A' && *s <= 'F' )
- c += 10 + *s - 'A';
- else if( *s >= 'a' && *s <= 'f' )
- c += 10 + *s - 'a';
- else
- return -1;
- return c;
-}
-
/****************
* Get the session key from the given string.
* String is supposed to be formatted as this: