From b47603a0ac24902c5bb000f8ef27cfb99aceeb81 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 15 Nov 2016 17:50:03 +0100 Subject: [PATCH] gpg: Add new compliance mode "de-vs". * g10/options.h (CO_DE_VS): New. (GNUPG): Also allow CO_DE_VS. * g10/gpg.c (oDE_VS): New. (parse_compliance_option): Add "de-vs". (set_compliance_option): Set "de-vs". * g10/misc.c (compliance_option_string): Return a description string. (compliance_failure): Ditto. * g10/keygen.c (ask_algo): Take care of CO_DE_VS. (get_keysize_range): Ditto. (ask_curve): Add new field to CURVES and trun flags into bit flags. Allow only Brainpool curves in CO_DE_VS mode. -- As of now this compliance mode only restricts the set of algorithms and curves which can be created. Signed-off-by: Werner Koch --- g10/gpg.c | 11 ++++++++++- g10/keygen.c | 54 +++++++++++++++++++++++++++++++++------------------ g10/misc.c | 5 +++++ g10/options.h | 4 ++-- 4 files changed, 52 insertions(+), 22 deletions(-) diff --git a/g10/gpg.c b/g10/gpg.c index b5fe490eb..495356c3e 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -233,6 +233,7 @@ enum cmd_and_opt_values oPGP6, oPGP7, oPGP8, + oDE_VS, oRFC2440Text, oNoRFC2440Text, oCipherAlgo, @@ -2042,7 +2043,8 @@ parse_compliance_option (const char *string) { "rfc2440", oRFC2440 }, { "pgp6", oPGP6 }, { "pgp7", oPGP7 }, - { "pgp8", oPGP8 } + { "pgp8", oPGP8 }, + { "de-vs", oDE_VS } }; int i; @@ -2118,6 +2120,13 @@ set_compliance_option (enum cmd_and_opt_values option) case oPGP7: opt.compliance = CO_PGP7; break; case oPGP8: opt.compliance = CO_PGP8; break; case oGnuPG: opt.compliance = CO_GNUPG; break; + + case oDE_VS: + set_compliance_option (oOpenPGP); + opt.compliance = CO_DE_VS; + /* Fixme: Change other options. */ + break; + default: BUG (); } diff --git a/g10/keygen.c b/g10/keygen.c index b424c9877..d249556db 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1885,24 +1885,27 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage, tty_printf (_(" (%d) RSA and RSA (default)\n"), 1 ); #endif - if (!addmode) + if (!addmode && opt.compliance != CO_DE_VS) tty_printf (_(" (%d) DSA and Elgamal\n"), 2 ); - tty_printf (_(" (%d) DSA (sign only)\n"), 3 ); + if (opt.compliance != CO_DE_VS) + tty_printf (_(" (%d) DSA (sign only)\n"), 3 ); #if GPG_USE_RSA tty_printf (_(" (%d) RSA (sign only)\n"), 4 ); #endif if (addmode) { - tty_printf (_(" (%d) Elgamal (encrypt only)\n"), 5 ); + if (opt.compliance != CO_DE_VS) + tty_printf (_(" (%d) Elgamal (encrypt only)\n"), 5 ); #if GPG_USE_RSA tty_printf (_(" (%d) RSA (encrypt only)\n"), 6 ); #endif } if (opt.expert) { - tty_printf (_(" (%d) DSA (set your own capabilities)\n"), 7 ); + if (opt.compliance != CO_DE_VS) + tty_printf (_(" (%d) DSA (set your own capabilities)\n"), 7 ); #if GPG_USE_RSA tty_printf (_(" (%d) RSA (set your own capabilities)\n"), 8 ); #endif @@ -1930,7 +1933,13 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage, answer = cpr_get ("keygen.algo", _("Your selection? ")); cpr_kill_prompt (); algo = *answer? atoi (answer) : 1; - if ((algo == 1 || !strcmp (answer, "rsa+rsa")) && !addmode) + + if (opt.compliance == CO_DE_VS + && (algo == 2 || algo == 3 || algo == 5 || algo == 7)) + { + tty_printf (_("Invalid selection.\n")); + } + else if ((algo == 1 || !strcmp (answer, "rsa+rsa")) && !addmode) { algo = PUBKEY_ALGO_RSA; *r_subkey_algo = PUBKEY_ALGO_RSA; @@ -2051,7 +2060,7 @@ static void get_keysize_range (int algo, unsigned int *min, unsigned int *def, unsigned int *max) { - *min = 1024; + *min = opt.compliance == CO_DE_VS ? 2048: 1024; *def = DEFAULT_STD_KEYSIZE; *max = 4096; @@ -2197,26 +2206,27 @@ ask_curve (int *algo, int *subkey_algo) numbers in the menu regardless on how Gpg was configured. */ struct { const char *name; - int available; /* Available in Libycrypt (runtime checked) */ - int expert_only; const char* eddsa_curve; /* Corresponding EdDSA curve. */ const char *pretty_name; - int supported; /* Supported by gpg. */ + unsigned int supported : 1; /* Supported by gpg. */ + unsigned int de_vs : 1; /* Allowed in CO_DE_VS. */ + unsigned int expert_only : 1; /* Only with --expert */ + unsigned int available : 1; /* Available in Libycrypt (runtime checked) */ } curves[] = { #if GPG_USE_ECDSA || GPG_USE_ECDH # define MY_USE_ECDSADH 1 #else # define MY_USE_ECDSADH 0 #endif - { "Curve25519", 0, 0, "Ed25519", "Curve 25519", GPG_USE_EDDSA }, - { "Curve448", 0, 1, "Ed448", "Curve 448", 0/*reserved*/ }, - { "NIST P-256", 0, 1, NULL, NULL, MY_USE_ECDSADH }, - { "NIST P-384", 0, 0, NULL, NULL, MY_USE_ECDSADH }, - { "NIST P-521", 0, 1, NULL, NULL, MY_USE_ECDSADH }, - { "brainpoolP256r1", 0, 1, NULL, "Brainpool P-256", MY_USE_ECDSADH }, - { "brainpoolP384r1", 0, 1, NULL, "Brainpool P-384", MY_USE_ECDSADH }, - { "brainpoolP512r1", 0, 1, NULL, "Brainpool P-512", MY_USE_ECDSADH }, - { "secp256k1", 0, 1, NULL, NULL, MY_USE_ECDSADH }, + { "Curve25519", "Ed25519", "Curve 25519", !!GPG_USE_EDDSA, 0, 0, 0 }, + { "Curve448", "Ed448", "Curve 448", 0/*reserved*/ , 0, 1, 0 }, + { "NIST P-256", NULL, NULL, MY_USE_ECDSADH, 0, 1, 0 }, + { "NIST P-384", NULL, NULL, MY_USE_ECDSADH, 0, 0, 0 }, + { "NIST P-521", NULL, NULL, MY_USE_ECDSADH, 0, 1, 0 }, + { "brainpoolP256r1", NULL, "Brainpool P-256", MY_USE_ECDSADH, 1, 1, 0 }, + { "brainpoolP384r1", NULL, "Brainpool P-384", MY_USE_ECDSADH, 1, 1, 0 }, + { "brainpoolP512r1", NULL, "Brainpool P-512", MY_USE_ECDSADH, 1, 1, 0 }, + { "secp256k1", NULL, NULL, MY_USE_ECDSADH, 0, 1, 0 }, }; #undef MY_USE_ECDSADH int idx; @@ -2234,7 +2244,13 @@ ask_curve (int *algo, int *subkey_algo) curves[idx].available = 0; if (!curves[idx].supported) continue; - if (!opt.expert && curves[idx].expert_only) + + if (opt.compliance==CO_DE_VS) + { + if (!curves[idx].de_vs) + continue; /* Not allowed. */ + } + else if (!opt.expert && curves[idx].expert_only) continue; /* We need to switch from the ECDH name of the curve to the diff --git a/g10/misc.c b/g10/misc.c index 4f9ece349..4b9ad990b 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -1252,6 +1252,7 @@ compliance_option_string(void) case CO_PGP6: return "--pgp6"; case CO_PGP7: return "--pgp7"; case CO_PGP8: return "--pgp8"; + case CO_DE_VS: return "--compliance=de-vs"; } return ver; @@ -1287,6 +1288,10 @@ compliance_failure(void) case CO_PGP8: ver="PGP 8.x"; break; + + case CO_DE_VS: + ver="DE-VS applications"; + break; } log_info(_("this message may not be usable by %s\n"),ver); diff --git a/g10/options.h b/g10/options.h index 19b855aa4..8ed2cdbf7 100644 --- a/g10/options.h +++ b/g10/options.h @@ -140,7 +140,7 @@ struct enum { CO_GNUPG, CO_RFC4880, CO_RFC2440, - CO_PGP6, CO_PGP7, CO_PGP8 + CO_PGP6, CO_PGP7, CO_PGP8, CO_DE_VS } compliance; enum { @@ -327,7 +327,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; /* Compatibility flags. */ -#define GNUPG (opt.compliance==CO_GNUPG) +#define GNUPG (opt.compliance==CO_GNUPG || opt.compliance==CO_DE_VS) #define RFC2440 (opt.compliance==CO_RFC2440) #define RFC4880 (opt.compliance==CO_RFC4880) #define PGP6 (opt.compliance==CO_PGP6)