From fa1155e89ebb4b16ee95549b8ab72672df3a0c54 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 13 Jul 2017 17:28:32 +0200 Subject: [PATCH] gpg: New option --key-origin. * g10/keydb.h (KEYORG_): Rename to KEYORG_. * g10/packet.h (PKT_user_id): Rename field keysrc to keyorg. Adjust users. (PKT_public_key): Ditto. (PKT_ring_trust): Ditto. * g10/options.h (struct opt): Add field key_origin. * g10/getkey.c (parse_key_origin): New. * g10/gpg.c (oKeyOrigin): New. (opts): Add "keys-origin". (main): Set option. Signed-off-by: Werner Koch --- doc/DETAILS | 11 ++++++----- doc/gpg.texi | 7 +++++++ g10/build-packet.c | 6 +++--- g10/call-dirmngr.c | 1 + g10/getkey.c | 35 +++++++++++++++++++++++++++++++++++ g10/gpg.c | 16 ++++++++++++---- g10/keydb.h | 16 +++++++++------- g10/options.h | 3 +++ g10/packet.h | 6 +++--- g10/parse-packet.c | 8 ++++---- 10 files changed, 83 insertions(+), 26 deletions(-) diff --git a/doc/DETAILS b/doc/DETAILS index b915f0658..cbeead777 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -1347,12 +1347,13 @@ CREATE TABLE signatures ( - 2 :: Key source on a user id (UID) - 1 octet :: Key Source; i.e. the origin of the key: - 0 :: Unknown source. - - 1 :: Direct import from a file. - - 2 :: Public keyserver. - - 3 :: Preferred keysrver. + - 1 :: Public keyserver. + - 2 :: Preferred keysrver. + - 3 :: OpenPGP DANE. - 4 :: Web Key Directory. - - 5 :: Web Key Directory via sub-domain. - - 6 :: OpenPGP DANE. + - 5 :: Import from a trusted URL. + - 6 :: Import from a trusted file. + - 7 :: Self generated. - 4 octets :: Time of last update. This is a a four-octet scalar with the seconds since Epoch. - 1 octet :: Scalar with the length of the following field. diff --git a/doc/gpg.texi b/doc/gpg.texi index bc83eff75..64dd50267 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2254,6 +2254,13 @@ hint to optimize its buffer allocation strategy. It is also used by the @option{--status-fd} line ``PROGRESS'' to provide a value for ``total'' if that is not available by other means. +@item --key-origin @var{string} +@opindex key-origin +gpg can track the origin of a key. Certain origins are implicitly +known (e.g. keyserver, web key directory) and set. For a standard +import the origin of the keys imported can be set with this optionb. +To list the possible values use "help" for @var{string}. + @item --import-options @code{parameters} @opindex import-options This is a space or comma delimited string that gives options for diff --git a/g10/build-packet.c b/g10/build-packet.c index fa2674b2a..6d00fc5c1 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -213,7 +213,7 @@ build_packet_and_meta (iobuf_t out, PACKET *pkt) PKT_user_id *uid = pkt->pkt.user_id; rt.subtype = RING_TRUST_UID; - rt.keysrc = uid->keysrc; + rt.keyorg = uid->keyorg; rt.keyupdate = uid->keyupdate; rt.url = uid->updateurl; err = do_ring_trust (out, &rt); @@ -225,7 +225,7 @@ build_packet_and_meta (iobuf_t out, PACKET *pkt) PKT_public_key *pk = pkt->pkt.public_key; rt.subtype = RING_TRUST_KEY; - rt.keysrc = pk->keysrc; + rt.keyorg = pk->keyorg; rt.keyupdate = pk->keyupdate; rt.url = pk->updateurl; err = do_ring_trust (out, &rt); @@ -395,7 +395,7 @@ do_ring_trust (iobuf_t out, PKT_ring_trust *rt) iobuf_put (out, rt->subtype); if (rt->subtype == RING_TRUST_KEY || rt->subtype == RING_TRUST_UID) { - iobuf_put (out, rt->keysrc); + iobuf_put (out, rt->keyorg); write_32 (out, rt->keyupdate); iobuf_put (out, namelen); if (namelen) diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c index cb6c69cd7..76fa07257 100644 --- a/g10/call-dirmngr.c +++ b/g10/call-dirmngr.c @@ -379,6 +379,7 @@ ks_status_cb (void *opaque, const char *line) if ((s = has_leading_keyword (line, parm->keyword? parm->keyword : "SOURCE"))) { + /* Note that the arg for "S SOURCE" is the URL of a keyserver. */ if (!parm->source) { parm->source = xtrystrdup (s); diff --git a/g10/getkey.c b/g10/getkey.c index a3df8578a..285ea35d7 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -4294,6 +4294,41 @@ parse_auto_key_locate (char *options) } +/* Parse the argument for --key-origin. Return false on error. */ +int +parse_key_origin (char *string) +{ + struct { const char *name; int origin; } list[] = { + { "self", KEYORG_SELF }, + { "file", KEYORG_FILE }, + { "url", KEYORG_URL }, + { "wkd", KEYORG_WKD }, + { "dane", KEYORG_DANE }, + { "ks-pref", KEYORG_KS_PREF }, + { "ks", KEYORG_KS }, + { "unknown", KEYORG_UNKNOWN } + }; + int i; + + if (!ascii_strcasecmp (string, "help")) + { + log_info (_("valid values for option '%s':\n"), "--key-origin"); + for (i=0; i < DIM (list); i++) + log_info (" %s\n", list[i].name); + g10_exit (1); + } + + for (i=0; i < DIM (list); i++) + if (!ascii_strcasecmp (string, list[i].name)) + { + opt.key_origin = list[i].origin; + return 1; + } + + return 0; +} + + /* Returns true if a secret key is available for the public key with key id KEYID; returns false if not. This function ignores legacy keys. Note: this is just a fast check and does not tell us whether diff --git a/g10/gpg.c b/g10/gpg.c index 3e153736a..38eeddf21 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -419,6 +419,7 @@ enum cmd_and_opt_values oOnlySignTextIDs, oDisableSignerUID, oSender, + oKeyOrigin, oNoop }; @@ -615,6 +616,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_s (oKeyServer, "keyserver", "@"), ARGPARSE_s_s (oKeyServerOptions, "keyserver-options", "@"), + ARGPARSE_s_s (oKeyOrigin, "key-origin", "@"), ARGPARSE_s_s (oImportOptions, "import-options", "@"), ARGPARSE_s_s (oImportFilter, "import-filter", "@"), ARGPARSE_s_s (oExportOptions, "export-options", "@"), @@ -2845,10 +2847,10 @@ main (int argc, char **argv) case oCompliance: { - int compliance = gnupg_parse_compliance_option (pargs.r.ret_str, - compliance_options, - DIM (compliance_options), - opt.quiet); + int compliance = gnupg_parse_compliance_option + (pargs.r.ret_str, + compliance_options, DIM (compliance_options), + opt.quiet); if (compliance < 0) g10_exit (1); set_compliance_option (compliance); @@ -3462,6 +3464,12 @@ main (int argc, char **argv) release_akl(); break; + case oKeyOrigin: + if(!parse_key_origin (pargs.r.ret_str)) + log_error (_("invalid argument for option \"%.50s\"\n"), + "--key-origin"); + break; + case oEnableLargeRSA: #if SECMEM_BUFFER_SIZE >= 65536 opt.flags.large_rsa=1; diff --git a/g10/keydb.h b/g10/keydb.h index 40167230c..bad314991 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -119,13 +119,14 @@ union pref_hint /* Constants to describe from where a key was fetched or updated. */ enum { - KEYSRC_UNKNOWN = 0, - KEYSRC_FILE = 1, /* Direct import from a file. */ - KEYSRC_KS = 2, /* Public keyserver. */ - KEYSRC_PREF_KS = 3, /* Preferred keysrver. */ - KEYSRC_WKD = 4, /* Web Key Directory. */ - KEYSRC_WKD_SD = 5, /* Web Key Directory but from a sub domain. */ - KEYSRC_DANE = 6 /* OpenPGP DANE. */ + KEYORG_UNKNOWN = 0, + KEYORG_KS = 1, /* Public keyserver. */ + KEYORG_KS_PREF = 2, /* Preferred keysrver. */ + KEYORG_DANE = 3, /* OpenPGP DANE. */ + KEYORG_WKD = 4, /* Web Key Directory. */ + KEYORG_URL = 5, /* Trusted URL. */ + KEYORG_FILE = 6, /* Trusted file. */ + KEYORG_SELF = 7, /* We generated it. */ }; @@ -396,6 +397,7 @@ char *get_user_id_byfpr_native (ctrl_t ctrl, const byte *fpr); void release_akl(void); int parse_auto_key_locate(char *options); +int parse_key_origin (char *string); /*-- keyid.c --*/ int pubkey_letter( int algo ); diff --git a/g10/options.h b/g10/options.h index 98417d7df..5bb506e52 100644 --- a/g10/options.h +++ b/g10/options.h @@ -263,6 +263,9 @@ struct struct akl *next; } *auto_key_locate; + /* The value of --key-origin. See parse_key_origin(). */ + int key_origin; + int passphrase_repeat; int pinentry_mode; diff --git a/g10/packet.h b/g10/packet.h index cf2121c6c..56ac50376 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -285,7 +285,7 @@ typedef struct u32 created; /* according to the self-signature */ u32 keyupdate; /* From the ring trust packet. */ char *updateurl; /* NULL or the URL of the last update origin. */ - byte keysrc; /* From the ring trust packet. */ + byte keyorg; /* From the ring trust packet. */ byte selfsigversion; struct { @@ -407,7 +407,7 @@ typedef struct u32 trust_timestamp; byte trust_depth; byte trust_value; - byte keysrc; /* From the ring trust packet. */ + byte keyorg; /* From the ring trust packet. */ u32 keyupdate; /* From the ring trust packet. */ char *updateurl; /* NULL or the URL of the last update origin. */ const byte *trust_regexp; @@ -498,7 +498,7 @@ typedef struct { unsigned int trustval; unsigned int sigcache; unsigned char subtype; /* The subtype of this ring trust packet. */ - unsigned char keysrc; /* The origin of the key (KEYSRC_*). */ + unsigned char keyorg; /* The origin of the key (KEYSRC_*). */ u32 keyupdate; /* The wall time the key was last updated. */ char *url; /* NULL or the URL of the source. */ } PKT_ring_trust; diff --git a/g10/parse-packet.c b/g10/parse-packet.c index dbb7af84d..0b6ee8b4e 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -2942,7 +2942,7 @@ parse_ring_trust (parse_packet_ctx_t ctx, unsigned long pktlen) int i; unsigned int namelen; - rt.keysrc = iobuf_get_noeof (inp); + rt.keyorg = iobuf_get_noeof (inp); pktlen--; rt.keyupdate = read_32 (inp); pktlen -= 4; @@ -2974,7 +2974,7 @@ parse_ring_trust (parse_packet_ctx_t ctx, unsigned long pktlen) es_fprintf (listfp, ":trust packet: %s upd=%lu src=%d%s", (rt.subtype == RING_TRUST_UID? "uid" : "key"), (unsigned long)rt.keyupdate, - rt.keysrc, + rt.keyorg, (rt.url? " url=":"")); if (rt.url) { @@ -3016,7 +3016,7 @@ parse_ring_trust (parse_packet_ctx_t ctx, unsigned long pktlen) { PKT_user_id *uid = ctx->last_pkt.pkt.user_id; - uid->keysrc = rt.keysrc; + uid->keyorg = rt.keyorg; uid->keyupdate = rt.keyupdate; uid->updateurl = rt.url; rt.url = NULL; @@ -3027,7 +3027,7 @@ parse_ring_trust (parse_packet_ctx_t ctx, unsigned long pktlen) { PKT_public_key *pk = ctx->last_pkt.pkt.public_key; - pk->keysrc = rt.keysrc; + pk->keyorg = rt.keyorg; pk->keyupdate = rt.keyupdate; pk->updateurl = rt.url; rt.url = NULL;