gpgsm: New option --compatibility-flags.

* sm/gpgsm.c (oCompatibilityFlags): New option.
(compatibility_flags): new.
(main): Parse and print them in verbose mode.
* sm/gpgsm.h (opt): Add field compat_glags.:
(COMPAT_ALLOW_KA_TO_ENCR): New.
* sm/keylist.c (print_capabilities): Take care of the new flag.
* sm/certlist.c (cert_usage_p): Ditto.
This commit is contained in:
Werner Koch 2022-06-13 17:46:40 +02:00
parent ce63eaa4f8
commit f0b373cec9
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
5 changed files with 76 additions and 9 deletions

View File

@ -733,6 +733,14 @@ Include ephemeral flagged keys in the output of key listings. Note
that they are included anyway if the key specification for a listing
is given as fingerprint or keygrip.
@item --compatibility-flags @var{flags}
@opindex compatibility-flags
Set compatibility flags to work around problems due to non-compliant
certificates or data. The @var{flags} are given as a comma separated
list of flag names and are OR-ed together. The special flag "none"
clears the list and allows to start over with an empty list. To get a
list of available flags the sole word "help" can be used.
@item --debug-level @var{level}
@opindex debug-level
Select the debug level for investigating problems. @var{level} may be

View File

@ -51,9 +51,11 @@ cert_usage_p (ksba_cert_t cert, int mode, int silent)
{
gpg_error_t err;
unsigned int use;
unsigned int encr_bits, sign_bits;
char *extkeyusages;
int have_ocsp_signing = 0;
err = ksba_cert_get_ext_key_usages (cert, &extkeyusages);
if (gpg_err_code (err) == GPG_ERR_NO_DATA)
err = 0; /* no policy given */
@ -157,10 +159,13 @@ cert_usage_p (ksba_cert_t cert, int mode, int silent)
return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
}
if ((use & ((mode&1)?
(KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT):
(KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
)
encr_bits = (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT);
if ((opt.compat_flags & COMPAT_ALLOW_KA_TO_ENCR))
encr_bits |= KSBA_KEYUSAGE_KEY_AGREEMENT;
sign_bits = (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION);
if ((use & ((mode&1)? encr_bits : sign_bits)))
return 0;
if (!silent)

View File

@ -210,6 +210,7 @@ enum cmd_and_opt_values {
oUseKeyboxd,
oKeyboxdProgram,
oRequireCompliance,
oCompatibilityFlags,
oNoAutostart
};
@ -442,6 +443,7 @@ static gpgrt_opt_t opts[] = {
ARGPARSE_s_s (oLCmessages, "lc-messages", "@"),
ARGPARSE_s_s (oXauthority, "xauthority", "@"),
ARGPARSE_s_s (oChUid, "chuid", "@"),
ARGPARSE_s_s (oCompatibilityFlags, "compatibility-flags", "@"),
ARGPARSE_header (NULL, ""), /* Stop the header group. */
@ -479,6 +481,14 @@ static struct debug_flags_s debug_flags [] =
};
/* The list of compatibility flags. */
static struct compatibility_flags_s compatibility_flags [] =
{
{ COMPAT_ALLOW_KA_TO_ENCR, "allow-ka-to-encr" },
{ 0, NULL }
};
/* Global variable to keep an error count. */
int gpgsm_errors_seen = 0;
@ -1271,6 +1281,15 @@ main ( int argc, char **argv)
case oDebugIgnoreExpiration: opt.ignore_expiration = 1; break;
case oDebugForceECDHSHA1KDF: opt.force_ecdh_sha1kdf = 1; break;
case oCompatibilityFlags:
if (parse_compatibility_flags (pargs.r.ret_str, &opt.compat_flags,
compatibility_flags))
{
pargs.r_opt = ARGPARSE_INVALID_ARG;
pargs.err = ARGPARSE_PRINT_ERROR;
}
break;
case oStatusFD:
ctrl.status_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 1);
break;
@ -1584,6 +1603,8 @@ main ( int argc, char **argv)
gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
set_debug ();
if (opt.verbose) /* Print the compatibility flags. */
parse_compatibility_flags (NULL, &opt.compat_flags, compatibility_flags);
gnupg_set_compliance_extra_info (opt.min_rsa_length);
/* Although we always use gpgsm_exit, we better install a regular

View File

@ -176,6 +176,9 @@ struct
* HEX_OR_FILENAME. The actual value needs to be encoded as a SET OF
* attribute values. */
strlist_t attributes;
/* Compatibility flags (COMPAT_FLAG_xxxx). */
unsigned int compat_flags;
} opt;
/* Debug values and macros. */
@ -199,6 +202,18 @@ struct
#define DBG_CLOCK (opt.debug & DBG_CLOCK_VALUE)
#define DBG_LOOKUP (opt.debug & DBG_LOOKUP_VALUE)
/* Compatibility flags */
/* Telesec RSA cards produced for NRW in 2022 came with only the
* keyAgreement bit set. This flag allows there use for encryption
* anyway. Example cert:
* Issuer: /CN=DOI CA 10a/OU=DOI/O=PKI-1-Verwaltung/C=DE
* key usage: digitalSignature nonRepudiation keyAgreement
* policies: 1.3.6.1.4.1.7924.1.1:N:
*/
#define COMPAT_ALLOW_KA_TO_ENCR 1
/* Forward declaration for an object defined in server.c */
struct server_local_s;

View File

@ -304,9 +304,11 @@ print_capabilities (ksba_cert_t cert, estream_t fp)
{
gpg_error_t err;
unsigned int use;
unsigned int is_encr, is_sign, is_cert;
size_t buflen;
char buffer[1];
err = ksba_cert_get_user_data (cert, "is_qualified",
&buffer, sizeof (buffer), &buflen);
if (!err && buflen)
@ -338,17 +340,33 @@ print_capabilities (ksba_cert_t cert, estream_t fp)
return;
}
is_encr = is_sign = is_cert = 0;
if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
is_encr = 1;
if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
is_sign = 1;
if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
is_cert = 1;
/* We need to returned the faked key usage to frontends so that they
* can select the right key. Note that we don't do this for the
* human readable keyUsage. */
if ((opt.compat_flags & COMPAT_ALLOW_KA_TO_ENCR)
&& (use & KSBA_KEYUSAGE_KEY_AGREEMENT))
is_encr = 1;
if (is_encr)
es_putc ('e', fp);
if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
if (is_sign)
es_putc ('s', fp);
if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
if (is_cert)
es_putc ('c', fp);
if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
if (is_encr)
es_putc ('E', fp);
if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
if (is_sign)
es_putc ('S', fp);
if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
if (is_cert)
es_putc ('C', fp);
}