diff options
-rw-r--r-- | g10/ChangeLog | 17 | ||||
-rw-r--r-- | g10/getkey.c | 28 | ||||
-rw-r--r-- | g10/hkp.c | 18 | ||||
-rw-r--r-- | g10/hkp.h | 2 | ||||
-rw-r--r-- | g10/keyserver.c | 162 | ||||
-rw-r--r-- | g10/main.h | 1 | ||||
-rw-r--r-- | g10/misc.c | 25 | ||||
-rw-r--r-- | g10/pubkey-enc.c | 25 |
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: * @@ -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); @@ -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: |