aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/ChangeLog11
-rw-r--r--g10/getkey.c67
-rw-r--r--g10/keyserver-internal.h2
-rw-r--r--g10/keyserver.c12
4 files changed, 61 insertions, 31 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 2f7bee308..d3df2552b 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,5 +1,16 @@
2006-03-13 David Shaw <[email protected]>
+ * keyserver-internal.h, keyserver.c (keyserver_import_pka): Use
+ the same API as the other auto-key-locate fetchers.
+
+ * getkey.c (get_pubkey_byname): Use the fingerprint of the key
+ that we actually fetched. This helps prevent problems where the
+ key that we fetched doesn't have the same name that we used to
+ fetch it. In the case of CERT and PKA, this is an actual security
+ requirement as the URL might point to a key put in by an attacker.
+ By forcing the use of the fingerprint, we won't use the attacker's
+ key here.
+
* keyserver-internal.h, keyserver.c (keyserver_spawn,
keyserver_work, keyserver_import_cert, keyserver_import_name,
keyserver_import_ldap): Pass fingerprint info through.
diff --git a/g10/getkey.c b/g10/getkey.c
index 1805eb041..8594ad9e6 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -922,11 +922,14 @@ get_pubkey_byname (PKT_public_key *pk,
for(akl=opt.auto_key_locate;akl;akl=akl->next)
{
+ unsigned char *fpr;
+ size_t fpr_len;
+
switch(akl->type)
{
case AKL_CERT:
glo_ctrl.in_auto_key_retrieve++;
- res=keyserver_import_cert(name,NULL,NULL);
+ res=keyserver_import_cert(name,&fpr,&fpr_len);
glo_ctrl.in_auto_key_retrieve--;
if(res==0)
@@ -935,35 +938,17 @@ get_pubkey_byname (PKT_public_key *pk,
break;
case AKL_PKA:
- {
- unsigned char fpr[MAX_FINGERPRINT_LEN];
-
- glo_ctrl.in_auto_key_retrieve++;
- res=keyserver_import_pka(name,fpr);
- glo_ctrl.in_auto_key_retrieve--;
-
- if(res==0)
- {
- int i;
- char fpr_string[MAX_FINGERPRINT_LEN*2+1];
-
- log_info(_("Automatically retrieved `%s' via %s\n"),
- name,"PKA");
-
- free_strlist(namelist);
- namelist=NULL;
-
- for(i=0;i<MAX_FINGERPRINT_LEN;i++)
- sprintf(fpr_string+2*i,"%02X",fpr[i]);
+ glo_ctrl.in_auto_key_retrieve++;
+ res=keyserver_import_pka(name,&fpr,&fpr_len);
- add_to_strlist( &namelist, fpr_string );
- }
- }
+ if(res==0)
+ log_info(_("Automatically retrieved `%s' via %s\n"),
+ name,"PKA");
break;
case AKL_LDAP:
glo_ctrl.in_auto_key_retrieve++;
- res=keyserver_import_ldap(name,NULL,NULL);
+ res=keyserver_import_ldap(name,&fpr,&fpr_len);
glo_ctrl.in_auto_key_retrieve--;
if(res==0)
@@ -979,7 +964,7 @@ get_pubkey_byname (PKT_public_key *pk,
if(opt.keyserver)
{
glo_ctrl.in_auto_key_retrieve++;
- res=keyserver_import_name(name,NULL,NULL,opt.keyserver);
+ res=keyserver_import_name(name,&fpr,&fpr_len,opt.keyserver);
glo_ctrl.in_auto_key_retrieve--;
if(res==0)
@@ -994,7 +979,7 @@ get_pubkey_byname (PKT_public_key *pk,
keyserver=keyserver_match(akl->spec);
glo_ctrl.in_auto_key_retrieve++;
- res=keyserver_import_name(name,NULL,NULL,keyserver);
+ res=keyserver_import_name(name,&fpr,&fpr_len,keyserver);
glo_ctrl.in_auto_key_retrieve--;
if(res==0)
@@ -1004,6 +989,34 @@ get_pubkey_byname (PKT_public_key *pk,
break;
}
+ /* Use the fingerprint of the key that we actually fetched.
+ This helps prevent problems where the key that we fetched
+ doesn't have the same name that we used to fetch it. In
+ the case of CERT and PKA, this is an actual security
+ requirement as the URL might point to a key put in by an
+ attacker. By forcing the use of the fingerprint, we
+ won't use the attacker's key here. */
+ if(res==0 && fpr)
+ {
+ int i;
+ char fpr_string[MAX_FINGERPRINT_LEN*2+1];
+
+ assert(fpr_len<=MAX_FINGERPRINT_LEN);
+
+ free_strlist(namelist);
+ namelist=NULL;
+
+ for(i=0;i<fpr_len;i++)
+ sprintf(fpr_string+2*i,"%02X",fpr[i]);
+
+ if(opt.verbose)
+ log_info("auto-key-locate found fingerprint %s\n",fpr_string);
+
+ add_to_strlist( &namelist, fpr_string );
+
+ xfree(fpr);
+ }
+
rc = key_byname( NULL, namelist, pk, NULL, 0,
include_unusable, ret_keyblock, ret_kdbhd);
if(rc!=G10ERR_NO_PUBKEY)
diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h
index 9b6def872..a36598695 100644
--- a/g10/keyserver-internal.h
+++ b/g10/keyserver-internal.h
@@ -45,7 +45,7 @@ int keyserver_search(STRLIST tokens);
int keyserver_fetch(STRLIST urilist);
int keyserver_import_cert(const char *name,
unsigned char **fpr,size_t *fpr_len);
-int keyserver_import_pka(const char *name,unsigned char *fpr);
+int keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len);
int keyserver_import_name(const char *name,unsigned char **fpr,size_t *fpr_len,
struct keyserver_spec *keyserver);
int keyserver_import_ldap(const char *name,
diff --git a/g10/keyserver.c b/g10/keyserver.c
index b4a8c14ac..31037c01d 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -2036,24 +2036,30 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len)
/* Import key pointed to by a PKA record. Return the requested
fingerprint in fpr. */
int
-keyserver_import_pka(const char *name,unsigned char *fpr)
+keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len)
{
char *uri;
int rc=-1;
- uri = get_pka_info (name, fpr);
+ *fpr=xmalloc(20);
+ *fpr_len=20;
+
+ uri = get_pka_info (name, *fpr);
if (uri)
{
struct keyserver_spec *spec;
spec = parse_keyserver_uri (uri, 1, NULL, 0);
if (spec)
{
- rc=keyserver_import_fprint (fpr, 20, spec);
+ rc=keyserver_import_fprint (*fpr, 20, spec);
free_keyserver_spec (spec);
}
xfree (uri);
}
+ if(rc!=0)
+ xfree(*fpr);
+
return rc;
}