mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
dirmngr: New option --ignore-cert
* dirmngr/dirmngr.h (struct fingerprint_list_s): Add field binlen. (opt): Add field ignored_certs. * dirmngr/dirmngr.c: Add option --ignore-cert (parse_rereadable_options): Handle that option. (parse_ocsp_signer): Rename to ... (parse_fingerprint_item): this and add two args. * dirmngr/certcache.c (put_cert): Ignore all to be igored certs. Change callers to handle the new error return. -- This option is useful as a workaround in case we ill run into other chain validation errors like what we fixed in GnuPG-bug-id: 5639
This commit is contained in:
parent
6879937885
commit
4b3e9a44b5
@ -43,7 +43,8 @@
|
|||||||
LENGTH bytes. The function checks that the STRING will convert
|
LENGTH bytes. The function checks that the STRING will convert
|
||||||
exactly to LENGTH bytes. The string is delimited by either end of
|
exactly to LENGTH bytes. The string is delimited by either end of
|
||||||
string or a white space character. The function returns -1 on
|
string or a white space character. The function returns -1 on
|
||||||
error or the length of the parsed string. */
|
error or the length of the parsed string. In-place conversion is
|
||||||
|
allowed but the Source string might be garbled on error. */
|
||||||
int
|
int
|
||||||
hex2bin (const char *string, void *buffer, size_t length)
|
hex2bin (const char *string, void *buffer, size_t length)
|
||||||
{
|
{
|
||||||
|
@ -262,13 +262,14 @@ clean_cache_slot (cert_item_t ci)
|
|||||||
* fingerprint of the certificate will be stored there. FPR_BUFFER
|
* fingerprint of the certificate will be stored there. FPR_BUFFER
|
||||||
* needs to point to a buffer of at least 20 bytes. The fingerprint
|
* needs to point to a buffer of at least 20 bytes. The fingerprint
|
||||||
* will be stored on success or when the function returns
|
* will be stored on success or when the function returns
|
||||||
* GPG_ERR_DUP_VALUE. */
|
* GPG_ERR_DUP_VALUE or GPG_ERR_NOT_ENABLED. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
put_cert (ksba_cert_t cert, int permanent, unsigned int trustclass,
|
put_cert (ksba_cert_t cert, int permanent, unsigned int trustclass,
|
||||||
void *fpr_buffer)
|
void *fpr_buffer)
|
||||||
{
|
{
|
||||||
unsigned char help_fpr_buffer[20], *fpr;
|
unsigned char help_fpr_buffer[20], *fpr;
|
||||||
cert_item_t ci;
|
cert_item_t ci;
|
||||||
|
fingerprint_list_t ignored;
|
||||||
|
|
||||||
fpr = fpr_buffer? fpr_buffer : &help_fpr_buffer;
|
fpr = fpr_buffer? fpr_buffer : &help_fpr_buffer;
|
||||||
|
|
||||||
@ -317,6 +318,14 @@ put_cert (ksba_cert_t cert, int permanent, unsigned int trustclass,
|
|||||||
}
|
}
|
||||||
|
|
||||||
cert_compute_fpr (cert, fpr);
|
cert_compute_fpr (cert, fpr);
|
||||||
|
/* Compare against the list of to be ignored certificates. */
|
||||||
|
for (ignored = opt.ignored_certs; ignored; ignored = ignored->next)
|
||||||
|
if (ignored->binlen == 20 && !memcmp (fpr, ignored->hexfpr, 20))
|
||||||
|
{
|
||||||
|
/* We are configured not to use this certificate. */
|
||||||
|
return gpg_error (GPG_ERR_NOT_ENABLED);
|
||||||
|
}
|
||||||
|
|
||||||
for (ci=cert_cache[*fpr]; ci; ci = ci->next)
|
for (ci=cert_cache[*fpr]; ci; ci = ci->next)
|
||||||
if (ci->cert && !memcmp (ci->fpr, fpr, 20))
|
if (ci->cert && !memcmp (ci->fpr, fpr, 20))
|
||||||
return gpg_error (GPG_ERR_DUP_VALUE);
|
return gpg_error (GPG_ERR_DUP_VALUE);
|
||||||
@ -440,6 +449,8 @@ load_certs_from_dir (const char *dirname, unsigned int trustclass)
|
|||||||
cert_log_subject (_(" subject ="), cert);
|
cert_log_subject (_(" subject ="), cert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (gpg_err_code (err) == GPG_ERR_NOT_ENABLED)
|
||||||
|
log_info ("certificate '%s' skipped due to configuration\n", fname);
|
||||||
else
|
else
|
||||||
log_error (_("error loading certificate '%s': %s\n"),
|
log_error (_("error loading certificate '%s': %s\n"),
|
||||||
fname, gpg_strerror (err));
|
fname, gpg_strerror (err));
|
||||||
@ -510,6 +521,8 @@ load_certs_from_file (const char *fname, unsigned int trustclasses,
|
|||||||
err = put_cert (cert, 1, trustclasses, NULL);
|
err = put_cert (cert, 1, trustclasses, NULL);
|
||||||
if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
|
if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
|
||||||
log_info (_("certificate '%s' already cached\n"), fname);
|
log_info (_("certificate '%s' already cached\n"), fname);
|
||||||
|
else if (gpg_err_code (err) == GPG_ERR_NOT_ENABLED)
|
||||||
|
log_info ("certificate '%s' skipped due to configuration\n", fname);
|
||||||
else if (err)
|
else if (err)
|
||||||
log_error (_("error loading certificate '%s': %s\n"),
|
log_error (_("error loading certificate '%s': %s\n"),
|
||||||
fname, gpg_strerror (err));
|
fname, gpg_strerror (err));
|
||||||
@ -625,6 +638,9 @@ load_certs_from_w32_store (const char *storename)
|
|||||||
if (DBG_X509)
|
if (DBG_X509)
|
||||||
log_debug (_("certificate '%s' already cached\n"), storename);
|
log_debug (_("certificate '%s' already cached\n"), storename);
|
||||||
}
|
}
|
||||||
|
else if (gpg_err_code (err) == GPG_ERR_NOT_ENABLED)
|
||||||
|
log_info ("certificate '%s' skipped due to configuration\n",
|
||||||
|
storename);
|
||||||
else if (err)
|
else if (err)
|
||||||
log_error (_("error loading certificate '%s': %s\n"),
|
log_error (_("error loading certificate '%s': %s\n"),
|
||||||
storename, gpg_strerror (err));
|
storename, gpg_strerror (err));
|
||||||
@ -852,6 +868,8 @@ cache_cert (ksba_cert_t cert)
|
|||||||
log_info (_("certificate already cached\n"));
|
log_info (_("certificate already cached\n"));
|
||||||
else if (!err)
|
else if (!err)
|
||||||
log_info (_("certificate cached\n"));
|
log_info (_("certificate cached\n"));
|
||||||
|
else if (gpg_err_code (err) == GPG_ERR_NOT_ENABLED)
|
||||||
|
log_info ("certificate skipped due to configuration\n");
|
||||||
else
|
else
|
||||||
log_error (_("error caching certificate: %s\n"), gpg_strerror (err));
|
log_error (_("error caching certificate: %s\n"), gpg_strerror (err));
|
||||||
return err;
|
return err;
|
||||||
@ -872,7 +890,10 @@ cache_cert_silent (ksba_cert_t cert, void *fpr_buffer)
|
|||||||
release_cache_lock ();
|
release_cache_lock ();
|
||||||
if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
|
if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
|
||||||
err = 0;
|
err = 0;
|
||||||
if (err)
|
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_NOT_ENABLED)
|
||||||
|
log_info ("certificate skipped due to configuration\n");
|
||||||
|
else if (err)
|
||||||
log_error (_("error caching certificate: %s\n"), gpg_strerror (err));
|
log_error (_("error caching certificate: %s\n"), gpg_strerror (err));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -143,6 +143,7 @@ enum cmd_and_opt_values {
|
|||||||
oSocketName,
|
oSocketName,
|
||||||
oLDAPWrapperProgram,
|
oLDAPWrapperProgram,
|
||||||
oHTTPWrapperProgram,
|
oHTTPWrapperProgram,
|
||||||
|
oIgnoreCert,
|
||||||
oIgnoreCertExtension,
|
oIgnoreCertExtension,
|
||||||
oUseTor,
|
oUseTor,
|
||||||
oNoUseTor,
|
oNoUseTor,
|
||||||
@ -216,6 +217,7 @@ static gpgrt_opt_t opts[] = {
|
|||||||
N_("|N|do not return more than N items in one query")),
|
N_("|N|do not return more than N items in one query")),
|
||||||
ARGPARSE_s_u (oFakedSystemTime, "faked-system-time", "@"), /*(epoch time)*/
|
ARGPARSE_s_u (oFakedSystemTime, "faked-system-time", "@"), /*(epoch time)*/
|
||||||
ARGPARSE_s_n (oDisableCheckOwnSocket, "disable-check-own-socket", "@"),
|
ARGPARSE_s_n (oDisableCheckOwnSocket, "disable-check-own-socket", "@"),
|
||||||
|
ARGPARSE_s_s (oIgnoreCert,"ignore-cert", "@"),
|
||||||
ARGPARSE_s_s (oIgnoreCertExtension,"ignore-cert-extension", "@"),
|
ARGPARSE_s_s (oIgnoreCertExtension,"ignore-cert-extension", "@"),
|
||||||
|
|
||||||
|
|
||||||
@ -419,7 +421,9 @@ static void cleanup (void);
|
|||||||
#if USE_LDAP
|
#if USE_LDAP
|
||||||
static ldap_server_t parse_ldapserver_file (const char* filename, int ienoent);
|
static ldap_server_t parse_ldapserver_file (const char* filename, int ienoent);
|
||||||
#endif /*USE_LDAP*/
|
#endif /*USE_LDAP*/
|
||||||
static fingerprint_list_t parse_ocsp_signer (const char *string);
|
static fingerprint_list_t parse_fingerprint_item (const char *string,
|
||||||
|
const char *optionname,
|
||||||
|
int want_binary);
|
||||||
static void netactivity_action (void);
|
static void netactivity_action (void);
|
||||||
static void handle_connections (assuan_fd_t listen_fd);
|
static void handle_connections (assuan_fd_t listen_fd);
|
||||||
static void gpgconf_versions (void);
|
static void gpgconf_versions (void);
|
||||||
@ -667,6 +671,12 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread)
|
|||||||
xfree (opt.ocsp_signer);
|
xfree (opt.ocsp_signer);
|
||||||
opt.ocsp_signer = tmp;
|
opt.ocsp_signer = tmp;
|
||||||
}
|
}
|
||||||
|
while (opt.ignored_certs)
|
||||||
|
{
|
||||||
|
fingerprint_list_t tmp = opt.ignored_certs->next;
|
||||||
|
xfree (opt.ignored_certs);
|
||||||
|
opt.ignored_certs = tmp;
|
||||||
|
}
|
||||||
FREE_STRLIST (opt.ignored_cert_extensions);
|
FREE_STRLIST (opt.ignored_cert_extensions);
|
||||||
http_register_tls_ca (NULL);
|
http_register_tls_ca (NULL);
|
||||||
FREE_STRLIST (hkp_cacert_filenames);
|
FREE_STRLIST (hkp_cacert_filenames);
|
||||||
@ -732,7 +742,8 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread)
|
|||||||
case oAllowVersionCheck: opt.allow_version_check = 1; break;
|
case oAllowVersionCheck: opt.allow_version_check = 1; break;
|
||||||
case oOCSPResponder: opt.ocsp_responder = pargs->r.ret_str; break;
|
case oOCSPResponder: opt.ocsp_responder = pargs->r.ret_str; break;
|
||||||
case oOCSPSigner:
|
case oOCSPSigner:
|
||||||
opt.ocsp_signer = parse_ocsp_signer (pargs->r.ret_str);
|
opt.ocsp_signer = parse_fingerprint_item (pargs->r.ret_str,
|
||||||
|
"--ocsp-signer", 0);
|
||||||
break;
|
break;
|
||||||
case oOCSPMaxClockSkew: opt.ocsp_max_clock_skew = pargs->r.ret_int; break;
|
case oOCSPMaxClockSkew: opt.ocsp_max_clock_skew = pargs->r.ret_int; break;
|
||||||
case oOCSPMaxPeriod: opt.ocsp_max_period = pargs->r.ret_int; break;
|
case oOCSPMaxPeriod: opt.ocsp_max_period = pargs->r.ret_int; break;
|
||||||
@ -754,6 +765,24 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case oIgnoreCert:
|
||||||
|
{
|
||||||
|
fingerprint_list_t item, r;
|
||||||
|
item = parse_fingerprint_item (pargs->r.ret_str, "--ignore-cert", 20);
|
||||||
|
if (item)
|
||||||
|
{ /* Append */
|
||||||
|
if (!opt.ignored_certs)
|
||||||
|
opt.ignored_certs = item;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (r = opt.ignored_certs; r->next; r = r->next)
|
||||||
|
;
|
||||||
|
r->next = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case oIgnoreCertExtension:
|
case oIgnoreCertExtension:
|
||||||
add_to_strlist (&opt.ignored_cert_extensions, pargs->r.ret_str);
|
add_to_strlist (&opt.ignored_cert_extensions, pargs->r.ret_str);
|
||||||
break;
|
break;
|
||||||
@ -1709,8 +1738,13 @@ parse_ldapserver_file (const char* filename, int ignore_enoent)
|
|||||||
}
|
}
|
||||||
#endif /*USE_LDAP*/
|
#endif /*USE_LDAP*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Parse a fingerprint entry as used by --ocsc-signer. OPTIONNAME as
|
||||||
|
* a description on the options used. WANT_BINARY requests to store a
|
||||||
|
* binary fingerprint. Returns NULL on error and logs that error. */
|
||||||
static fingerprint_list_t
|
static fingerprint_list_t
|
||||||
parse_ocsp_signer (const char *string)
|
parse_fingerprint_item (const char *string,
|
||||||
|
const char *optionname, int want_binary)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
char *fname;
|
char *fname;
|
||||||
@ -1735,10 +1769,15 @@ parse_ocsp_signer (const char *string)
|
|||||||
if (j != 40 || !(spacep (string+i) || !string[i]))
|
if (j != 40 || !(spacep (string+i) || !string[i]))
|
||||||
{
|
{
|
||||||
log_error (_("%s:%u: invalid fingerprint detected\n"),
|
log_error (_("%s:%u: invalid fingerprint detected\n"),
|
||||||
"--ocsp-signer", 0);
|
optionname, 0);
|
||||||
xfree (item);
|
xfree (item);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (want_binary)
|
||||||
|
{
|
||||||
|
item->binlen = 20;
|
||||||
|
hex2bin (item->hexfpr, item->hexfpr, 20);
|
||||||
|
}
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1821,6 +1860,12 @@ parse_ocsp_signer (const char *string)
|
|||||||
log_error (_("%s:%u: invalid fingerprint detected\n"), fname, lnr);
|
log_error (_("%s:%u: invalid fingerprint detected\n"), fname, lnr);
|
||||||
errflag = 1;
|
errflag = 1;
|
||||||
}
|
}
|
||||||
|
else if (want_binary)
|
||||||
|
{
|
||||||
|
item->binlen = 20;
|
||||||
|
hex2bin (item->hexfpr, item->hexfpr, 20);
|
||||||
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
while (spacep (p+i))
|
while (spacep (p+i))
|
||||||
i++;
|
i++;
|
||||||
|
@ -74,6 +74,7 @@ typedef struct fingerprint_list_s *fingerprint_list_t;
|
|||||||
struct fingerprint_list_s
|
struct fingerprint_list_s
|
||||||
{
|
{
|
||||||
fingerprint_list_t next;
|
fingerprint_list_t next;
|
||||||
|
char binlen; /* If this is not 0 hexfpr actually carries a binary fpr. */
|
||||||
char hexfpr[20+20+1];
|
char hexfpr[20+20+1];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -119,6 +120,10 @@ struct
|
|||||||
int ignore_ocsp_service_url; /* Ignore OCSP service URLs as given in
|
int ignore_ocsp_service_url; /* Ignore OCSP service URLs as given in
|
||||||
the certificate. */
|
the certificate. */
|
||||||
|
|
||||||
|
/* A list of fingerprints of certififcates we should completely
|
||||||
|
* ignore. These are all stored in binary format. */
|
||||||
|
fingerprint_list_t ignored_certs;
|
||||||
|
|
||||||
/* A list of certificate extension OIDs which are ignored so that
|
/* A list of certificate extension OIDs which are ignored so that
|
||||||
one can claim that a critical extension has been handled. One
|
one can claim that a critical extension has been handled. One
|
||||||
OID per string. */
|
OID per string. */
|
||||||
|
@ -588,6 +588,25 @@ won't be rejected due to an unknown critical extension. Use this
|
|||||||
option with care because extensions are usually flagged as critical
|
option with care because extensions are usually flagged as critical
|
||||||
for a reason.
|
for a reason.
|
||||||
|
|
||||||
|
@item --ignore-cert @var{fpr}|@var{file}
|
||||||
|
@opindex ignore-cert
|
||||||
|
Entirely ignore certificates with the fingerprint @var{fpr}. As an
|
||||||
|
alternative to the fingerprint a filename can be given in which case
|
||||||
|
all certificates described in that file are ignored. Any argument
|
||||||
|
which contains a slash, dot or tilde is considered a filename. Usual
|
||||||
|
filename expansion takes place: A tilde at the start followed by a
|
||||||
|
slash is replaced by the content of @env{HOME}, no slash at start
|
||||||
|
describes a relative filename which will be searched at the home
|
||||||
|
directory. To make sure that the @var{file} is searched in the home
|
||||||
|
directory, either prepend the name with "./" or use a name which
|
||||||
|
contains a dot. The format of such a file is a list of SHA-1
|
||||||
|
fingerprint, one per line with optional colons between the bytes.
|
||||||
|
Empty lines and lines prefixed with a hash mark are ignored.
|
||||||
|
|
||||||
|
This option is useful as a quick workaround to exclude certain
|
||||||
|
certificates from the system store.
|
||||||
|
|
||||||
|
|
||||||
@item --hkp-cacert @var{file}
|
@item --hkp-cacert @var{file}
|
||||||
Use the root certificates in @var{file} for verification of the TLS
|
Use the root certificates in @var{file} for verification of the TLS
|
||||||
certificates used with @code{hkps} (keyserver access over TLS). If
|
certificates used with @code{hkps} (keyserver access over TLS). If
|
||||||
|
Loading…
x
Reference in New Issue
Block a user