aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2017-07-24 18:47:41 +0000
committerWerner Koch <[email protected]>2017-07-24 18:47:41 +0000
commit2ca0381d077d766593db26f4215b8eddee8d7963 (patch)
tree59c1a634fd6812742b14e9e3c1d5c4dae30b58c0
parentgpg: Store key origin info for new DANE and WKD retrieved keys. (diff)
downloadgnupg-2ca0381d077d766593db26f4215b8eddee8d7963.tar.gz
gnupg-2ca0381d077d766593db26f4215b8eddee8d7963.zip
gpg: Store key origin info for new keys from a keyserver
* g10/keyserver.c (keyserver_get_chunk): Use KEYORG_KS if request was done by fingerprint. * g10/import.c (apply_meta_data): Implement that. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--g10/import.c83
-rw-r--r--g10/keyserver.c12
2 files changed, 66 insertions, 29 deletions
diff --git a/g10/import.c b/g10/import.c
index e3c8c37b4..d22c8f457 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -1394,38 +1394,69 @@ apply_meta_data (kbnode_t keyblock, int origin, const char *url)
{
if (is_deleted_kbnode (node))
;
- else if (node->pkt->pkttype == PKT_PUBLIC_KEY
- && (origin == KEYORG_WKD || origin == KEYORG_DANE))
- {
- /* For WKD and DANE we insert origin information also for
- * the key but we don't record the URL because we have have
- * no use for that: An update using a keyserver has higher
- * precedence and will thus update this origin info. For
- * refresh using WKD or DANE we need to go via the User ID
- * anyway. Recall that we are only inserting a new key. */
+ else if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+ {
PKT_public_key *pk = node->pkt->pkt.public_key;
- pk->keyorg = origin;
- pk->keyupdate = curtime;
+ if (origin == KEYORG_WKD || origin == KEYORG_DANE)
+ {
+ /* For WKD and DANE we insert origin information also
+ * for the key but we don't record the URL because we
+ * have have no use for that: An update using a
+ * keyserver has higher precedence and will thus update
+ * this origin info. For refresh using WKD or DANE we
+ * need to go via the User ID anyway. Recall that we
+ * are only inserting a new key. */
+ pk->keyorg = origin;
+ pk->keyupdate = curtime;
+ }
+ else if (origin == KEYORG_KS && url)
+ {
+ /* If the key was retrieved from a keyserver using a
+ * fingerprint request we add the meta information.
+ * Note that the use of a fingerprint needs to be
+ * enforced by the caller of the import function. This
+ * is commonly triggered by verifying a modern signature
+ * which has an Issuer Fingerprint signature
+ * subpacket. */
+ pk->keyorg = origin;
+ pk->keyupdate = curtime;
+ pk->updateurl = xtrystrdup (url);
+ if (!pk->updateurl)
+ return gpg_error_from_syserror ();
+ }
}
- else if (node->pkt->pkttype == PKT_USER_ID
- && (origin == KEYORG_WKD || origin == KEYORG_DANE))
- {
- /* We insert origin information on a UID only when we
- * received them via the Web Key Directory or a DANE record.
- * The key we receive here from the WKD has been filtered to
- * contain only the user ID as looked up in the WKD. For a
- * DANE origin we this should also be the case. Thus we
- * will see here only one user id. */
+ else if (node->pkt->pkttype == PKT_USER_ID)
+ {
PKT_user_id *uid = node->pkt->pkt.user_id;
- uid->keyorg = origin;
- uid->keyupdate = curtime;
- if (url)
+ if (origin == KEYORG_WKD || origin == KEYORG_DANE)
{
- uid->updateurl = xtrystrdup (url);
- if (!uid->updateurl)
- return gpg_error_from_syserror ();
+ /* We insert origin information on a UID only when we
+ * received them via the Web Key Directory or a DANE
+ * record. The key we receive here from the WKD has
+ * been filtered to contain only the user ID as looked
+ * up in the WKD. For a DANE origin we this should also
+ * be the case. Thus we will see here only one user
+ * id. */
+ uid->keyorg = origin;
+ uid->keyupdate = curtime;
+ if (url)
+ {
+ uid->updateurl = xtrystrdup (url);
+ if (!uid->updateurl)
+ return gpg_error_from_syserror ();
+ }
+ }
+ else if (origin == KEYORG_KS && url)
+ {
+ /* If the key was retrieved from a keyserver using a
+ * fingerprint request we mark that also in the user ID.
+ * However we do not store the keyserver URL in the UID.
+ * A later update (merge) from a more trusted source
+ * will replace this info. */
+ uid->keyorg = origin;
+ uid->keyupdate = curtime;
}
}
}
diff --git a/g10/keyserver.c b/g10/keyserver.c
index 9586448fa..4d2a2c873 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -1590,11 +1590,12 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
{
gpg_error_t err = 0;
char **pattern;
- int idx, npat;
+ int idx, npat, npat_fpr;
estream_t datastream;
char *source = NULL;
size_t linelen; /* Estimated linelen for KS_GET. */
size_t n;
+ int only_fprs;
#define MAX_KS_GET_LINELEN 950 /* Somewhat lower than the real limit. */
@@ -1613,7 +1614,7 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
but we are sure that R_NDESC_USED has been updated. This avoids
a possible indefinite loop. */
linelen = 17; /* "KS_GET --quick --" */
- for (npat=idx=0; idx < ndesc; idx++)
+ for (npat=npat_fpr=0, idx=0; idx < ndesc; idx++)
{
int quiet = 0;
@@ -1635,6 +1636,8 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
desc[idx].mode == KEYDB_SEARCH_MODE_FPR20? 20 : 16,
pattern[npat]+2);
npat++;
+ if (desc[idx].mode == KEYDB_SEARCH_MODE_FPR20)
+ npat_fpr++;
}
}
else if(desc[idx].mode == KEYDB_SEARCH_MODE_LONG_KID)
@@ -1716,6 +1719,8 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
this is different from NPAT. */
*r_ndesc_used = idx;
+ only_fprs = (npat && npat == npat_fpr);
+
err = gpg_dirmngr_ks_get (ctrl, pattern, override_keyserver, quick,
&datastream, &source);
for (idx=0; idx < npat; idx++)
@@ -1747,7 +1752,8 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
(opt.keyserver_options.import_options
| IMPORT_NO_SECKEY),
keyserver_retrieval_screener, &screenerarg,
- 0 /* FIXME? */, NULL);
+ only_fprs? KEYORG_KS : 0,
+ source);
}
es_fclose (datastream);
xfree (source);