mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +02:00
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. * common/miscellaneous.c (parse_compatibility_flags): New. * common/util.h (struct compatibility_flags_s): New. -- Backported-from-master: f0b373cec93bb01f02b9c0a3ab1f3e242b381c3f Backported-from-master: ce63eaa4f8f3f41aafcaddd8d658dacd522334a8
This commit is contained in:
parent
b356eddf3d
commit
77b6896f7a
@ -760,3 +760,83 @@ parse_debug_flag (const char *string, unsigned int *debugvar,
|
|||||||
*debugvar |= result;
|
*debugvar |= result;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Parse an --comaptibility_flags style argument consisting of comma
|
||||||
|
* separated strings.
|
||||||
|
*
|
||||||
|
* Returns: 0 on success or -1 and ERRNO set on error. On success the
|
||||||
|
* supplied variable is updated by the parsed flags.
|
||||||
|
*
|
||||||
|
* If STRING is NULL the enabled flags are printed.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
parse_compatibility_flags (const char *string, unsigned int *flagvar,
|
||||||
|
const struct compatibility_flags_s *flags)
|
||||||
|
|
||||||
|
{
|
||||||
|
unsigned long result = 0;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
if (!string)
|
||||||
|
{
|
||||||
|
if (flagvar)
|
||||||
|
{
|
||||||
|
log_info ("enabled compatibility flags:");
|
||||||
|
for (i=0; flags[i].name; i++)
|
||||||
|
if ((*flagvar & flags[i].flag))
|
||||||
|
log_printf (" %s", flags[i].name);
|
||||||
|
log_printf ("\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (spacep (string))
|
||||||
|
string++;
|
||||||
|
|
||||||
|
if (!strcmp (string, "?") || !strcmp (string, "help"))
|
||||||
|
{
|
||||||
|
log_info ("available compatibility flags:\n");
|
||||||
|
for (i=0; flags[i].name; i++)
|
||||||
|
log_info (" %s\n", flags[i].name);
|
||||||
|
if (flags[i].flag != 77)
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char **words;
|
||||||
|
words = strtokenize (string, ",");
|
||||||
|
if (!words)
|
||||||
|
return -1;
|
||||||
|
for (i=0; words[i]; i++)
|
||||||
|
{
|
||||||
|
if (*words[i])
|
||||||
|
{
|
||||||
|
for (j=0; flags[j].name; j++)
|
||||||
|
if (!strcmp (words[i], flags[j].name))
|
||||||
|
{
|
||||||
|
result |= flags[j].flag;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!flags[j].name)
|
||||||
|
{
|
||||||
|
if (!strcmp (words[i], "none"))
|
||||||
|
{
|
||||||
|
*flagvar = 0;
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else if (!strcmp (words[i], "all"))
|
||||||
|
result = ~0;
|
||||||
|
else
|
||||||
|
log_info ("unknown compatibility flag '%s' ignored\n",
|
||||||
|
words[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xfree (words);
|
||||||
|
}
|
||||||
|
|
||||||
|
*flagvar |= result;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -358,6 +358,15 @@ struct debug_flags_s
|
|||||||
int parse_debug_flag (const char *string, unsigned int *debugvar,
|
int parse_debug_flag (const char *string, unsigned int *debugvar,
|
||||||
const struct debug_flags_s *flags);
|
const struct debug_flags_s *flags);
|
||||||
|
|
||||||
|
struct compatibility_flags_s
|
||||||
|
{
|
||||||
|
unsigned int flag;
|
||||||
|
const char *name;
|
||||||
|
const char *desc;
|
||||||
|
};
|
||||||
|
int parse_compatibility_flags (const char *string, unsigned int *flagvar,
|
||||||
|
const struct compatibility_flags_s *flags);
|
||||||
|
|
||||||
|
|
||||||
/*-- Simple replacement functions. */
|
/*-- Simple replacement functions. */
|
||||||
|
|
||||||
|
@ -710,6 +710,14 @@ Include ephemeral flagged keys in the output of key listings. Note
|
|||||||
that they are included anyway if the key specification for a listing
|
that they are included anyway if the key specification for a listing
|
||||||
is given as fingerprint or keygrip.
|
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}
|
@item --debug-level @var{level}
|
||||||
@opindex debug-level
|
@opindex debug-level
|
||||||
Select the debug level for investigating problems. @var{level} may be
|
Select the debug level for investigating problems. @var{level} may be
|
||||||
|
@ -52,9 +52,11 @@ cert_usage_p (ksba_cert_t cert, int mode, int silent)
|
|||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
unsigned int use;
|
unsigned int use;
|
||||||
|
unsigned int encr_bits, sign_bits;
|
||||||
char *extkeyusages;
|
char *extkeyusages;
|
||||||
int have_ocsp_signing = 0;
|
int have_ocsp_signing = 0;
|
||||||
|
|
||||||
|
|
||||||
err = ksba_cert_get_ext_key_usages (cert, &extkeyusages);
|
err = ksba_cert_get_ext_key_usages (cert, &extkeyusages);
|
||||||
if (gpg_err_code (err) == GPG_ERR_NO_DATA)
|
if (gpg_err_code (err) == GPG_ERR_NO_DATA)
|
||||||
err = 0; /* no policy given */
|
err = 0; /* no policy given */
|
||||||
@ -158,10 +160,13 @@ cert_usage_p (ksba_cert_t cert, int mode, int silent)
|
|||||||
return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
|
return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((use & ((mode&1)?
|
encr_bits = (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT);
|
||||||
(KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT):
|
if ((opt.compat_flags & COMPAT_ALLOW_KA_TO_ENCR))
|
||||||
(KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
|
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;
|
return 0;
|
||||||
|
|
||||||
if (!silent)
|
if (!silent)
|
||||||
|
21
sm/gpgsm.c
21
sm/gpgsm.c
@ -200,6 +200,7 @@ enum cmd_and_opt_values {
|
|||||||
oIgnoreCertExtension,
|
oIgnoreCertExtension,
|
||||||
oIgnoreCertWithOID,
|
oIgnoreCertWithOID,
|
||||||
oRequireCompliance,
|
oRequireCompliance,
|
||||||
|
oCompatibilityFlags,
|
||||||
oNoAutostart
|
oNoAutostart
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -422,6 +423,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
ARGPARSE_s_s (oLCctype, "lc-ctype", "@"),
|
ARGPARSE_s_s (oLCctype, "lc-ctype", "@"),
|
||||||
ARGPARSE_s_s (oLCmessages, "lc-messages", "@"),
|
ARGPARSE_s_s (oLCmessages, "lc-messages", "@"),
|
||||||
ARGPARSE_s_s (oXauthority, "xauthority", "@"),
|
ARGPARSE_s_s (oXauthority, "xauthority", "@"),
|
||||||
|
ARGPARSE_s_s (oCompatibilityFlags, "compatibility-flags", "@"),
|
||||||
|
|
||||||
ARGPARSE_header (NULL, ""), /* Stop the header group. */
|
ARGPARSE_header (NULL, ""), /* Stop the header group. */
|
||||||
|
|
||||||
@ -457,6 +459,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. */
|
/* Global variable to keep an error count. */
|
||||||
int gpgsm_errors_seen = 0;
|
int gpgsm_errors_seen = 0;
|
||||||
|
|
||||||
@ -1233,6 +1243,15 @@ main ( int argc, char **argv)
|
|||||||
case oDebugNoChainValidation: opt.no_chain_validation = 1; break;
|
case oDebugNoChainValidation: opt.no_chain_validation = 1; break;
|
||||||
case oDebugIgnoreExpiration: opt.ignore_expiration = 1; break;
|
case oDebugIgnoreExpiration: opt.ignore_expiration = 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:
|
case oStatusFD:
|
||||||
ctrl.status_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 1);
|
ctrl.status_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 1);
|
||||||
break;
|
break;
|
||||||
@ -1509,6 +1528,8 @@ main ( int argc, char **argv)
|
|||||||
gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
|
gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
|
||||||
|
|
||||||
set_debug ();
|
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);
|
gnupg_set_compliance_extra_info (opt.min_rsa_length);
|
||||||
|
|
||||||
/* Although we always use gpgsm_exit, we better install a regualr
|
/* Although we always use gpgsm_exit, we better install a regualr
|
||||||
|
14
sm/gpgsm.h
14
sm/gpgsm.h
@ -150,6 +150,8 @@ struct
|
|||||||
* mode. */
|
* mode. */
|
||||||
int require_compliance;
|
int require_compliance;
|
||||||
|
|
||||||
|
/* Compatibility flags (COMPAT_FLAG_xxxx). */
|
||||||
|
unsigned int compat_flags;
|
||||||
} opt;
|
} opt;
|
||||||
|
|
||||||
/* Debug values and macros. */
|
/* Debug values and macros. */
|
||||||
@ -169,6 +171,18 @@ struct
|
|||||||
#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
|
#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
|
||||||
#define DBG_IPC (opt.debug & DBG_IPC_VALUE)
|
#define DBG_IPC (opt.debug & DBG_IPC_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 */
|
/* Forward declaration for an object defined in server.c */
|
||||||
struct server_local_s;
|
struct server_local_s;
|
||||||
|
|
||||||
|
28
sm/keylist.c
28
sm/keylist.c
@ -251,9 +251,11 @@ print_capabilities (ksba_cert_t cert, estream_t fp)
|
|||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
unsigned int use;
|
unsigned int use;
|
||||||
|
unsigned int is_encr, is_sign, is_cert;
|
||||||
size_t buflen;
|
size_t buflen;
|
||||||
char buffer[1];
|
char buffer[1];
|
||||||
|
|
||||||
|
|
||||||
err = ksba_cert_get_user_data (cert, "is_qualified",
|
err = ksba_cert_get_user_data (cert, "is_qualified",
|
||||||
&buffer, sizeof (buffer), &buflen);
|
&buffer, sizeof (buffer), &buflen);
|
||||||
if (!err && buflen)
|
if (!err && buflen)
|
||||||
@ -285,17 +287,33 @@ print_capabilities (ksba_cert_t cert, estream_t fp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_encr = is_sign = is_cert = 0;
|
||||||
|
|
||||||
if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
|
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);
|
es_putc ('e', fp);
|
||||||
if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
|
if (is_sign)
|
||||||
es_putc ('s', fp);
|
es_putc ('s', fp);
|
||||||
if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
|
if (is_cert)
|
||||||
es_putc ('c', fp);
|
es_putc ('c', fp);
|
||||||
if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
|
if (is_encr)
|
||||||
es_putc ('E', fp);
|
es_putc ('E', fp);
|
||||||
if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
|
if (is_sign)
|
||||||
es_putc ('S', fp);
|
es_putc ('S', fp);
|
||||||
if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
|
if (is_cert)
|
||||||
es_putc ('C', fp);
|
es_putc ('C', fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user