diff --git a/common/compliance.c b/common/compliance.c index 1cda1ec16..eaecee7b0 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 @@ -178,9 +182,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; @@ -192,7 +197,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; @@ -258,9 +264,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"); @@ -275,7 +282,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; @@ -683,3 +692,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 20b562eb8..e29ff4ee2 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 3209a2d7a..eed213d78 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2881,7 +2881,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 a3e1bc2e6..d3d83e4a5 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -667,6 +667,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 abab14426..81185523f 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -242,6 +242,7 @@ enum cmd_and_opt_values oPGP7, oPGP8, oDE_VS, + oMinRSALength, oRFC2440Text, oNoRFC2440Text, oCipherAlgo, @@ -664,6 +665,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_n (oPGP6, "pgp6", "@"), ARGPARSE_s_n (oPGP7, "pgp7", "@"), ARGPARSE_s_n (oPGP8, "pgp8", "@"), + ARGPARSE_p_u (oMinRSALength, "min-rsa-length", "@"), ARGPARSE_s_n (oRFC2440Text, "rfc2440-text", "@"), ARGPARSE_s_n (oNoRFC2440Text, "no-rfc2440-text", "@"), @@ -2891,6 +2893,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; @@ -3751,6 +3755,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 f91dbd5e7..03b46f8de 100644 --- a/g10/options.h +++ b/g10/options.h @@ -214,6 +214,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 5c1f0bb07..4af639faa 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -156,6 +156,7 @@ enum cmd_and_opt_values { oDisablePolicyChecks, oEnablePolicyChecks, oAutoIssuerKeyRetrieve, + oMinRSALength, oWithFingerprint, oWithMD5Fingerprint, @@ -404,6 +405,9 @@ static ARGPARSE_OPTS 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_s_n (oNoCommonCertsImport, "no-common-certs-import", "@"), ARGPARSE_s_s (oIgnoreCertExtension, "ignore-cert-extension", "@"), ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"), @@ -1381,6 +1385,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; @@ -1477,6 +1483,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 regualr exit handler so that at least the secure memory gets wiped diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 9d9a303f8..21c677ebe 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -130,6 +130,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