mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +02:00
dirmngr: Load all system provided certificates.
* configure.ac: Add option --default-trust-store. (DEFAULT_TRUST_STORE_FILE): New ac_define. * dirmngr/certcache.c: Include ksba-io-support.h. (total_trusted_certificates, total_system_trusted_certificates): New. (put_cert): Manage the new counters. (cert_cache_deinit): Reset them. (cert_cache_print_stats): Print them. (is_trusted_cert): Add arg WITH_SYSTRUST. Change all callers to pass false. (load_certs_from_file): New. (load_certs_from_system): New. (cert_cache_init): Load system certificates. -- Note that this code does not yet allow to load the system certificates on Windows. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
09d71de4d4
commit
9a1a5ca0bc
16
configure.ac
16
configure.ac
@ -990,6 +990,22 @@ else
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# Allow to set a fixed trust store file for system provided certificates.
|
||||||
|
#
|
||||||
|
AC_ARG_WITH([default-trust-store-file],
|
||||||
|
[AC_HELP_STRING([--with-default-trust-store-file=FILE],
|
||||||
|
[Use FILE as system trust store])],
|
||||||
|
default_trust_store_file="$withval",
|
||||||
|
default_trust_store_file="")
|
||||||
|
if test x"$default_trust_store_file" = xno;then
|
||||||
|
default_trust_store_file=""
|
||||||
|
fi
|
||||||
|
if test x"$default_trust_store_file" != x ; then
|
||||||
|
AC_DEFINE_UNQUOTED([DEFAULT_TRUST_STORE_FILE],
|
||||||
|
["$default_trust_store_file"], [Use as default system trust store file])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
AC_MSG_NOTICE([checking for networking options])
|
AC_MSG_NOTICE([checking for networking options])
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* certcache.c - Certificate caching
|
/* certcache.c - Certificate caching
|
||||||
* Copyright (C) 2004, 2005, 2007, 2008 g10 Code GmbH
|
* Copyright (C) 2004, 2005, 2007, 2008, 2017 g10 Code GmbH
|
||||||
*
|
*
|
||||||
* This file is part of DirMngr.
|
* This file is part of DirMngr.
|
||||||
*
|
*
|
||||||
@ -29,10 +29,10 @@
|
|||||||
|
|
||||||
#include "dirmngr.h"
|
#include "dirmngr.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "../common/ksba-io-support.h"
|
||||||
#include "crlfetch.h"
|
#include "crlfetch.h"
|
||||||
#include "certcache.h"
|
#include "certcache.h"
|
||||||
|
|
||||||
|
|
||||||
#define MAX_EXTRA_CACHED_CERTS 1000
|
#define MAX_EXTRA_CACHED_CERTS 1000
|
||||||
|
|
||||||
/* Constants used to classify search patterns. */
|
/* Constants used to classify search patterns. */
|
||||||
@ -93,10 +93,12 @@ static npth_rwlock_t cert_cache_lock;
|
|||||||
static int initialization_done;
|
static int initialization_done;
|
||||||
|
|
||||||
/* Total number of certificates loaded during initialization
|
/* Total number of certificates loaded during initialization
|
||||||
* (ie. configured) and extra certifcates cached during operation. */
|
* (ie. configured), extra certificates cached during operation,
|
||||||
|
* number of trusted and system trusted certificates. */
|
||||||
static unsigned int total_config_certificates;
|
static unsigned int total_config_certificates;
|
||||||
static unsigned int total_extra_certificates;
|
static unsigned int total_extra_certificates;
|
||||||
|
static unsigned int total_trusted_certificates;
|
||||||
|
static unsigned int total_system_trusted_certificates;
|
||||||
|
|
||||||
|
|
||||||
/* Helper to do the cache locking. */
|
/* Helper to do the cache locking. */
|
||||||
@ -288,6 +290,10 @@ put_cert (ksba_cert_t cert, int from_config, int is_trusted, void *fpr_buffer)
|
|||||||
clean_cache_slot (ci_mark);
|
clean_cache_slot (ci_mark);
|
||||||
drop_count--;
|
drop_count--;
|
||||||
total_extra_certificates--;
|
total_extra_certificates--;
|
||||||
|
if (ci->flags.trusted)
|
||||||
|
total_trusted_certificates--;
|
||||||
|
if (ci->flags.systrust)
|
||||||
|
total_system_trusted_certificates--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i==idx)
|
if (i==idx)
|
||||||
@ -331,6 +337,11 @@ put_cert (ksba_cert_t cert, int from_config, int is_trusted, void *fpr_buffer)
|
|||||||
ci->flags.trusted = !!is_trusted;
|
ci->flags.trusted = !!is_trusted;
|
||||||
ci->flags.systrust = (is_trusted && is_trusted == 2);
|
ci->flags.systrust = (is_trusted && is_trusted == 2);
|
||||||
|
|
||||||
|
if (ci->flags.trusted)
|
||||||
|
total_trusted_certificates++;
|
||||||
|
if (ci->flags.systrust)
|
||||||
|
total_system_trusted_certificates++;
|
||||||
|
|
||||||
if (from_config)
|
if (from_config)
|
||||||
total_config_certificates++;
|
total_config_certificates++;
|
||||||
else
|
else
|
||||||
@ -433,6 +444,121 @@ load_certs_from_dir (const char *dirname, int are_trusted)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Load certificates from FILE. The certifciates are expected to be
|
||||||
|
* PEM encoded so that it is possible to load several certificates.
|
||||||
|
* All certates rea considered to be system provided trusted
|
||||||
|
* certificates. The cache should be in a locked state when calling
|
||||||
|
* this function. */
|
||||||
|
static gpg_error_t
|
||||||
|
load_certs_from_file (const char *fname)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
estream_t fp = NULL;
|
||||||
|
gnupg_ksba_io_t ioctx = NULL;
|
||||||
|
ksba_reader_t reader;
|
||||||
|
ksba_cert_t cert = NULL;
|
||||||
|
|
||||||
|
fp = es_fopen (fname, "rb");
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_error (_("can't open '%s': %s\n"), fname, gpg_strerror (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = gnupg_ksba_create_reader (&ioctx,
|
||||||
|
(GNUPG_KSBA_IO_PEM | GNUPG_KSBA_IO_MULTIPEM),
|
||||||
|
fp, &reader);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("can't create reader: %s\n", gpg_strerror (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop to read all certificates from the file. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ksba_cert_release (cert);
|
||||||
|
cert = NULL;
|
||||||
|
err = ksba_cert_new (&cert);
|
||||||
|
if (!err)
|
||||||
|
err = ksba_cert_read_der (cert, reader);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_EOF)
|
||||||
|
err = 0;
|
||||||
|
else
|
||||||
|
log_error (_("can't parse certificate '%s': %s\n"),
|
||||||
|
fname, gpg_strerror (err));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = put_cert (cert, 1, 2, NULL);
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
|
||||||
|
log_info (_("certificate '%s' already cached\n"), fname);
|
||||||
|
else if (err)
|
||||||
|
log_error (_("error loading certificate '%s': %s\n"),
|
||||||
|
fname, gpg_strerror (err));
|
||||||
|
else if (opt.verbose > 1)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
log_info (_("trusted certificate '%s' loaded\n"), fname);
|
||||||
|
p = get_fingerprint_hexstring_colon (cert);
|
||||||
|
log_info (_(" SHA1 fingerprint = %s\n"), p);
|
||||||
|
xfree (p);
|
||||||
|
|
||||||
|
cert_log_name (_(" issuer ="), cert);
|
||||||
|
cert_log_subject (_(" subject ="), cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
ksba_reader_clear (reader, NULL, NULL);
|
||||||
|
}
|
||||||
|
while (!gnupg_ksba_reader_eof_seen (ioctx));
|
||||||
|
|
||||||
|
leave:
|
||||||
|
ksba_cert_release (cert);
|
||||||
|
gnupg_ksba_destroy_reader (ioctx);
|
||||||
|
es_fclose (fp);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Load the trusted certificates provided by the system. */
|
||||||
|
static gpg_error_t
|
||||||
|
load_certs_from_system (void)
|
||||||
|
{
|
||||||
|
/* A list of certificate bundles to try. */
|
||||||
|
static struct {
|
||||||
|
const char *name;
|
||||||
|
} table[] = {
|
||||||
|
#ifdef DEFAULT_TRUST_STORE_FILE
|
||||||
|
{ DEFAULT_TRUST_STORE_FILE }
|
||||||
|
#else
|
||||||
|
{ "/etc/ssl/ca-bundle.pem" },
|
||||||
|
{ "/etc/ssl/certs/ca-certificates.crt" },
|
||||||
|
{ "/etc/pki/tls/cert.pem" },
|
||||||
|
{ "/usr/local/share/certs/ca-root-nss.crt" },
|
||||||
|
{ "/etc/ssl/cert.pem" }
|
||||||
|
#endif /*!DEFAULT_TRUST_STORE_FILE*/
|
||||||
|
};
|
||||||
|
int idx;
|
||||||
|
gpg_error_t err = 0;
|
||||||
|
|
||||||
|
for (idx=0; idx < DIM (table); idx++)
|
||||||
|
if (!access (table[idx].name, F_OK))
|
||||||
|
{
|
||||||
|
/* Take the first available bundle. */
|
||||||
|
err = load_certs_from_file (table[idx].name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Initialize the certificate cache if not yet done. */
|
/* Initialize the certificate cache if not yet done. */
|
||||||
void
|
void
|
||||||
cert_cache_init (void)
|
cert_cache_init (void)
|
||||||
@ -444,6 +570,8 @@ cert_cache_init (void)
|
|||||||
init_cache_lock ();
|
init_cache_lock ();
|
||||||
acquire_cache_write_lock ();
|
acquire_cache_write_lock ();
|
||||||
|
|
||||||
|
load_certs_from_system ();
|
||||||
|
|
||||||
dname = make_filename (gnupg_sysconfdir (), "trusted-certs", NULL);
|
dname = make_filename (gnupg_sysconfdir (), "trusted-certs", NULL);
|
||||||
load_certs_from_dir (dname, 1);
|
load_certs_from_dir (dname, 1);
|
||||||
xfree (dname);
|
xfree (dname);
|
||||||
@ -490,6 +618,8 @@ cert_cache_deinit (int full)
|
|||||||
|
|
||||||
total_config_certificates = 0;
|
total_config_certificates = 0;
|
||||||
total_extra_certificates = 0;
|
total_extra_certificates = 0;
|
||||||
|
total_trusted_certificates = 0;
|
||||||
|
total_system_trusted_certificates = 0;
|
||||||
initialization_done = 0;
|
initialization_done = 0;
|
||||||
release_cache_lock ();
|
release_cache_lock ();
|
||||||
}
|
}
|
||||||
@ -502,6 +632,8 @@ cert_cache_print_stats (void)
|
|||||||
total_config_certificates);
|
total_config_certificates);
|
||||||
log_info (_(" runtime cached certificates: %u\n"),
|
log_info (_(" runtime cached certificates: %u\n"),
|
||||||
total_extra_certificates);
|
total_extra_certificates);
|
||||||
|
log_info (_(" trusted certificates: %u (%u)\n"),
|
||||||
|
total_trusted_certificates, total_system_trusted_certificates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1275,10 +1407,11 @@ find_cert_bysubject (ctrl_t ctrl, const char *subject_dn, ksba_sexp_t keyid)
|
|||||||
|
|
||||||
|
|
||||||
/* Return 0 if the certificate is a trusted certificate. Returns
|
/* Return 0 if the certificate is a trusted certificate. Returns
|
||||||
GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in
|
* GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in
|
||||||
case of systems errors. */
|
* case of systems errors. If WITH_SYSTRUST is set also system
|
||||||
|
* provided certificates are considered trusted. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
is_trusted_cert (ksba_cert_t cert)
|
is_trusted_cert (ksba_cert_t cert, int with_systrust)
|
||||||
{
|
{
|
||||||
unsigned char fpr[20];
|
unsigned char fpr[20];
|
||||||
cert_item_t ci;
|
cert_item_t ci;
|
||||||
@ -1289,7 +1422,7 @@ is_trusted_cert (ksba_cert_t cert)
|
|||||||
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))
|
||||||
{
|
{
|
||||||
if (ci->flags.trusted)
|
if (ci->flags.trusted && (with_systrust || !ci->flags.systrust))
|
||||||
{
|
{
|
||||||
release_cache_lock ();
|
release_cache_lock ();
|
||||||
return 0; /* Yes, it is trusted. */
|
return 0; /* Yes, it is trusted. */
|
||||||
|
@ -41,9 +41,10 @@ gpg_error_t cache_cert (ksba_cert_t cert);
|
|||||||
gpg_error_t cache_cert_silent (ksba_cert_t cert, void *fpr_buffer);
|
gpg_error_t cache_cert_silent (ksba_cert_t cert, void *fpr_buffer);
|
||||||
|
|
||||||
/* Return 0 if the certificate is a trusted certificate. Returns
|
/* Return 0 if the certificate is a trusted certificate. Returns
|
||||||
GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in
|
* GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in
|
||||||
case of systems errors. */
|
* case of systems errors. If WITH_SYSTRUST is set also system
|
||||||
gpg_error_t is_trusted_cert (ksba_cert_t cert);
|
* provided certificates are considered trusted. */
|
||||||
|
gpg_error_t is_trusted_cert (ksba_cert_t cert, int with_systrust);
|
||||||
|
|
||||||
|
|
||||||
/* Return a certificate object for the given fingerprint. FPR is
|
/* Return a certificate object for the given fingerprint. FPR is
|
||||||
|
@ -189,7 +189,7 @@ allowed_ca (ksba_cert_t cert, int *chainlen)
|
|||||||
return err;
|
return err;
|
||||||
if (!flag)
|
if (!flag)
|
||||||
{
|
{
|
||||||
if (!is_trusted_cert (cert))
|
if (!is_trusted_cert (cert, 0))
|
||||||
{
|
{
|
||||||
/* The German SigG Root CA's certificate does not flag
|
/* The German SigG Root CA's certificate does not flag
|
||||||
itself as a CA; thus we relax this requirement if we
|
itself as a CA; thus we relax this requirement if we
|
||||||
@ -537,7 +537,7 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
|
|||||||
if (err)
|
if (err)
|
||||||
goto leave; /* No. */
|
goto leave; /* No. */
|
||||||
|
|
||||||
err = is_trusted_cert (subject_cert);
|
err = is_trusted_cert (subject_cert, 0);
|
||||||
if (!err)
|
if (!err)
|
||||||
; /* Yes we trust this cert. */
|
; /* Yes we trust this cert. */
|
||||||
else if (gpg_err_code (err) == GPG_ERR_NOT_TRUSTED)
|
else if (gpg_err_code (err) == GPG_ERR_NOT_TRUSTED)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user