From f86b1a15ad4bb7bcc1e9f7d209aabcb23641f7df Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 15 Nov 2016 13:03:29 +0100 Subject: [PATCH] gpg: New option --compliance. * g10/gpg.c (oCompliance): New. (opts): Add "--compliance". (parse_tofu_policy): Use a generic description string for "help". (parse_compliance_option): New. (main): Add option oCompliance. Factor out code for compliance setting to ... (set_compliance_option): new. Signed-off-by: Werner Koch --- doc/gpg.texi | 6 ++ g10/gpg.c | 165 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 125 insertions(+), 46 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 6cc35e04e..aff3aebbc 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2618,6 +2618,12 @@ this does is disable @option{--throw-keyids} and set @option{--escape-from-lines}. All algorithms are allowed except for the SHA224, SHA384, and SHA512 digests. +@item --compliance @var{string} +@opindex compliance +This option can be used instead of one of the options above. Valid +values for @var{string} are the above option names (without the double +dash) and possibly others as shown when using "help" for @var{value}. + @end table diff --git a/g10/gpg.c b/g10/gpg.c index 4e266729c..b5fe490eb 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -224,6 +224,7 @@ enum cmd_and_opt_values oMarginalsNeeded, oMaxCertDepth, oLoadExtension, + oCompliance, oGnuPG, oRFC2440, oRFC4880, @@ -613,6 +614,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_s (oLoadExtension, "load-extension", "@"), /* Dummy. */ + ARGPARSE_s_s (oCompliance, "compliance", "@"), ARGPARSE_s_n (oGnuPG, "gnupg", "@"), ARGPARSE_s_n (oGnuPG, "no-pgp2", "@"), ARGPARSE_s_n (oGnuPG, "no-pgp6", "@"), @@ -2010,7 +2012,7 @@ parse_tofu_policy (const char *policystr) if (!ascii_strcasecmp (policystr, "help")) { - log_info (_("available TOFU policies:\n")); + log_info (_("valid values for option '%s':\n"), "--tofu-policy"); for (i=0; i < DIM (list); i++) log_info (" %s\n", list[i].keyword); g10_exit (1); @@ -2027,6 +2029,105 @@ parse_tofu_policy (const char *policystr) g10_exit (1); } + +/* Parse the value of --compliance. */ +static int +parse_compliance_option (const char *string) +{ + struct { const char *keyword; enum cmd_and_opt_values option; } list[] = { + { "gnupg", oGnuPG }, + { "openpgp", oOpenPGP }, + { "rfc4880bis", oRFC4880bis }, + { "rfc4880", oRFC4880 }, + { "rfc2440", oRFC2440 }, + { "pgp6", oPGP6 }, + { "pgp7", oPGP7 }, + { "pgp8", oPGP8 } + }; + int i; + + if (!ascii_strcasecmp (string, "help")) + { + log_info (_("valid values for option '%s':\n"), "--compliance"); + for (i=0; i < DIM (list); i++) + log_info (" %s\n", list[i].keyword); + g10_exit (1); + } + + for (i=0; i < DIM (list); i++) + if (!ascii_strcasecmp (string, list[i].keyword)) + return list[i].option; + + log_error (_("invalid value for option '%s'\n"), "--compliance"); + if (!opt.quiet) + log_info (_("(use \"help\" to list choices)\n")); + g10_exit (1); +} + + + +/* Helper to set compliance related options. This is a separte + * function so that it can also be used by the --compliance option + * parser. */ +static void +set_compliance_option (enum cmd_and_opt_values option) +{ + switch (option) + { + case oRFC4880bis: + opt.flags.rfc4880bis = 1; + /* fall through. */ + case oOpenPGP: + case oRFC4880: + /* This is effectively the same as RFC2440, but with + "--enable-dsa2 --no-rfc2440-text --escape-from-lines + --require-cross-certification". */ + opt.compliance = CO_RFC4880; + opt.flags.dsa2 = 1; + opt.flags.require_cross_cert = 1; + opt.rfc2440_text = 0; + opt.allow_non_selfsigned_uid = 1; + opt.allow_freeform_uid = 1; + opt.escape_from = 1; + opt.not_dash_escaped = 0; + opt.def_cipher_algo = 0; + opt.def_digest_algo = 0; + opt.cert_digest_algo = 0; + opt.compress_algo = -1; + opt.s2k_mode = 3; /* iterated+salted */ + opt.s2k_digest_algo = DIGEST_ALGO_SHA1; + opt.s2k_cipher_algo = CIPHER_ALGO_3DES; + break; + case oRFC2440: + opt.compliance = CO_RFC2440; + opt.flags.dsa2 = 0; + opt.rfc2440_text = 1; + opt.allow_non_selfsigned_uid = 1; + opt.allow_freeform_uid = 1; + opt.escape_from = 0; + opt.not_dash_escaped = 0; + opt.def_cipher_algo = 0; + opt.def_digest_algo = 0; + opt.cert_digest_algo = 0; + opt.compress_algo = -1; + opt.s2k_mode = 3; /* iterated+salted */ + opt.s2k_digest_algo = DIGEST_ALGO_SHA1; + opt.s2k_cipher_algo = CIPHER_ALGO_3DES; + break; + case oPGP6: opt.compliance = CO_PGP6; break; + case oPGP7: opt.compliance = CO_PGP7; break; + case oPGP8: opt.compliance = CO_PGP8; break; + case oGnuPG: opt.compliance = CO_GNUPG; break; + default: + BUG (); + } +} + + + + + + /* This function called to initialized a new control object. It is assumed that this object has been zeroed out before calling this function. */ @@ -2702,52 +2803,24 @@ main (int argc, char **argv) /* Dummy so that gpg 1.4 conf files can work. Should eventually be removed. */ break; + + case oCompliance: + set_compliance_option (parse_compliance_option (pargs.r.ret_str)); + break; + case oOpenPGP: + case oRFC2440: + case oRFC4880: case oRFC4880bis: - opt.flags.rfc4880bis = 1; - /* fall through. */ - case oOpenPGP: - case oRFC4880: - /* This is effectively the same as RFC2440, but with - "--enable-dsa2 --no-rfc2440-text --escape-from-lines - --require-cross-certification". */ - opt.compliance = CO_RFC4880; - opt.flags.dsa2 = 1; - opt.flags.require_cross_cert = 1; - opt.rfc2440_text = 0; - opt.allow_non_selfsigned_uid = 1; - opt.allow_freeform_uid = 1; - opt.escape_from = 1; - opt.not_dash_escaped = 0; - opt.def_cipher_algo = 0; - opt.def_digest_algo = 0; - opt.cert_digest_algo = 0; - opt.compress_algo = -1; - opt.s2k_mode = 3; /* iterated+salted */ - opt.s2k_digest_algo = DIGEST_ALGO_SHA1; - opt.s2k_cipher_algo = CIPHER_ALGO_3DES; - break; - case oRFC2440: - opt.compliance = CO_RFC2440; - opt.flags.dsa2 = 0; - opt.rfc2440_text = 1; - opt.allow_non_selfsigned_uid = 1; - opt.allow_freeform_uid = 1; - opt.escape_from = 0; - opt.not_dash_escaped = 0; - opt.def_cipher_algo = 0; - opt.def_digest_algo = 0; - opt.cert_digest_algo = 0; - opt.compress_algo = -1; - opt.s2k_mode = 3; /* iterated+salted */ - opt.s2k_digest_algo = DIGEST_ALGO_SHA1; - opt.s2k_cipher_algo = CIPHER_ALGO_3DES; - break; - case oPGP6: opt.compliance = CO_PGP6; break; - case oPGP7: opt.compliance = CO_PGP7; break; - case oPGP8: opt.compliance = CO_PGP8; break; - case oGnuPG: opt.compliance = CO_GNUPG; break; - case oRFC2440Text: opt.rfc2440_text=1; break; - case oNoRFC2440Text: opt.rfc2440_text=0; break; + case oPGP6: + case oPGP7: + case oPGP8: + case oGnuPG: + set_compliance_option (pargs.r_opt); + break; + + case oRFC2440Text: opt.rfc2440_text=1; break; + case oNoRFC2440Text: opt.rfc2440_text=0; break; + case oSetFilename: if(utf8_strings) opt.set_filename = pargs.r.ret_str;