diff --git a/common/compliance.c b/common/compliance.c index 6c2fcd5b3..33a19fe06 100644 --- a/common/compliance.c +++ b/common/compliance.c @@ -40,6 +40,10 @@ static int initialized; static int module; +/* This value is used by DSA and RSA checks in addition to the hard + * coded length checks. It allows to increase the required key length + * using a confue file. */ +static unsigned int min_compliant_rsa_length; /* Return the address of a compliance cache variable for COMPLIANCE. * If no such variable exists NULL is returned. FOR_RNG returns the @@ -176,9 +180,10 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo, break; case is_rsa: - result = (keylength == 2048 - || keylength == 3072 - || keylength == 4096); + result = ((keylength == 2048 + || keylength == 3072 + || keylength == 4096) + && keylength >= min_compliant_rsa_length); /* Although rsaPSS was not part of the original evaluation * we got word that we can claim compliance. */ (void)algo_flags; @@ -190,7 +195,8 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo, size_t P = gcry_mpi_get_nbits (key[0]); size_t Q = gcry_mpi_get_nbits (key[1]); result = (Q == 256 - && (P == 2048 || P == 3072)); + && (P == 2048 || P == 3072) + && P >= min_compliant_rsa_length); } break; @@ -256,9 +262,10 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance, break; case PK_USE_ENCRYPTION: case PK_USE_SIGNING: - result = (keylength == 2048 - || keylength == 3072 - || keylength == 4096); + result = ((keylength == 2048 + || keylength == 3072 + || keylength == 4096) + && keylength >= min_compliant_rsa_length); break; default: log_assert (!"reached"); @@ -273,7 +280,9 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance, { size_t P = gcry_mpi_get_nbits (key[0]); size_t Q = gcry_mpi_get_nbits (key[1]); - result = (Q == 256 && (P == 2048 || P == 3072)); + result = (Q == 256 + && (P == 2048 || P == 3072) + && keylength >= min_compliant_rsa_length); } break; @@ -679,3 +688,11 @@ gnupg_compliance_option_string (enum gnupg_compliance_mode compliance) log_assert (!"invalid compliance mode"); } + + +/* Set additional infos for example taken from config files at startup. */ +void +gnupg_set_compliance_extra_info (unsigned int min_rsa) +{ + min_compliant_rsa_length = min_rsa; +} diff --git a/common/compliance.h b/common/compliance.h index 2f7039206..455efa544 100644 --- a/common/compliance.h +++ b/common/compliance.h @@ -91,5 +91,7 @@ int gnupg_parse_compliance_option (const char *string, const char *gnupg_compliance_option_string (enum gnupg_compliance_mode compliance); +void gnupg_set_compliance_extra_info (unsigned int min_rsa); + #endif /*GNUPG_COMMON_COMPLIANCE_H*/ diff --git a/doc/gpg.texi b/doc/gpg.texi index 02d7abb59..7723b7c53 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2948,7 +2948,13 @@ SHA224, SHA384, and SHA512 digests. @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}. +dash) and possibly others as shown when using "help" for @var{string}. + +@item --min-rsa-length @var{n} +@opindex min-rsa-length +This option adjusts the compliance mode "de-vs" for stricter key size +requirements. For example, a value of 3000 turns rsa2048 and dsa2048 +keys into non-VS-NfD compliant keys. @end table diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 52f939e1e..598d6653f 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -690,6 +690,16 @@ such broken signatures. If @command{gpgsm} prints an error like ``digest algo 8 has not been enabled'' you may want to try this option, with @samp{SHA256} for @var{name}. +@item --compliance @var{string} +@opindex compliance +Set the compliance mode. Valid values are shown when using "help" for +@var{string}. + +@item --min-rsa-length @var{n} +@opindex min-rsa-length +This option adjusts the compliance mode "de-vs" for stricter key size +requirements. For example, a value of 3000 turns rsa2048 and dsa2048 +keys into non-VS-NfD compliant keys. @item --faked-system-time @var{epoch} @opindex faked-system-time diff --git a/g10/gpg.c b/g10/gpg.c index c13bfc39b..b3be333e8 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -248,6 +248,7 @@ enum cmd_and_opt_values oPGP7, oPGP8, oDE_VS, + oMinRSALength, oRFC2440Text, oNoRFC2440Text, oCipherAlgo, @@ -629,6 +630,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oPGP7, "pgp7", "@"), ARGPARSE_s_n (oPGP8, "pgp8", "@"), ARGPARSE_s_s (oDefaultNewKeyAlgo, "default-new-key-algo", "@"), + ARGPARSE_p_u (oMinRSALength, "min-rsa-length", "@"), #ifndef NO_TRUST_MODELS ARGPARSE_s_n (oAlwaysTrust, "always-trust", "@"), #endif @@ -3009,6 +3011,8 @@ main (int argc, char **argv) set_compliance_option (pargs.r_opt); break; + case oMinRSALength: opt.min_rsa_length = pargs.r.ret_ulong; break; + case oRFC2440Text: opt.rfc2440_text=1; break; case oNoRFC2440Text: opt.rfc2440_text=0; break; @@ -3884,6 +3888,7 @@ main (int argc, char **argv) } set_debug (debug_level); + gnupg_set_compliance_extra_info (opt.min_rsa_length); if (DBG_CLOCK) log_clock ("start"); diff --git a/g10/options.h b/g10/options.h index 2ad86ae42..8df463ed4 100644 --- a/g10/options.h +++ b/g10/options.h @@ -224,6 +224,7 @@ struct unsigned int screen_lines; byte *show_subpackets; int rfc2440_text; + unsigned int min_rsa_length; /* Used for compliance checks. */ /* If true, let write failures on the status-fd exit the process. */ int exit_on_status_write_error; diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 67cfe2490..60e3f741a 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -160,6 +160,7 @@ enum cmd_and_opt_values { oDisablePolicyChecks, oEnablePolicyChecks, oAutoIssuerKeyRetrieve, + oMinRSALength, oWithFingerprint, oWithMD5Fingerprint, @@ -404,7 +405,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oDisablePubkeyAlgo, "disable-pubkey-algo", "@"), ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", "@"), ARGPARSE_s_n (oNoRandomSeedFile, "no-random-seed-file", "@"), - + ARGPARSE_p_u (oMinRSALength, "min-rsa-length", "@"), ARGPARSE_header (NULL, N_("Options for unattended use")), @@ -1446,6 +1447,8 @@ main ( int argc, char **argv) } break; + case oMinRSALength: opt.min_rsa_length = pargs.r.ret_ulong; break; + default: if (configname) pargs.err = ARGPARSE_PRINT_WARNING; @@ -1568,6 +1571,7 @@ main ( int argc, char **argv) gcry_control (GCRYCTL_RESUME_SECMEM_WARN); set_debug (); + gnupg_set_compliance_extra_info (opt.min_rsa_length); /* Although we always use gpgsm_exit, we better install a regular exit handler so that at least the secure memory gets wiped diff --git a/sm/gpgsm.h b/sm/gpgsm.h index acf8caeed..0dfd56daf 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -142,6 +142,8 @@ struct the integrity of the software at runtime. */ + unsigned int min_rsa_length; /* Used for compliance checks. */ + strlist_t keyserver; /* A list of certificate extension OIDs which are ignored so that