summaryrefslogtreecommitdiffstats
path: root/dirmngr/certcache.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2017-02-16 11:51:57 +0100
committerWerner Koch <wk@gnupg.org>2017-02-16 11:51:57 +0100
commit5c4e67afd6385b48065de6a0f2dd0bfd936ab90b (patch)
tree70d2cd28dec3906206b2a6fa4ef28db574da1e1e /dirmngr/certcache.c
parentindent: Reformat and extend some comments in dirmngr. (diff)
downloadgnupg2-5c4e67afd6385b48065de6a0f2dd0bfd936ab90b.tar.xz
gnupg2-5c4e67afd6385b48065de6a0f2dd0bfd936ab90b.zip
dirmngr: Prepare certcache for forthcoming changes.
* dirmngr/certcache.c (cert_item_s): Rename 'flags.loaded' to 'flags.config'. Add 'flags.systrust'. (total_loaded_certificates): Rename to total_config_certificates. (put_cert): Rename args for clarity. Set SYSTRUST flag. (load_certs_from_dir): Make sure put_cert does not set the SYSTRUST flag. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'dirmngr/certcache.c')
-rw-r--r--dirmngr/certcache.c68
1 files changed, 40 insertions, 28 deletions
diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c
index d13d80b44..d68d503d5 100644
--- a/dirmngr/certcache.c
+++ b/dirmngr/certcache.c
@@ -68,8 +68,12 @@ struct cert_item_s
char *subject_dn; /* The malloced subject DN - maybe NULL. */
struct
{
- unsigned int loaded:1; /* It has been explicitly loaded. */
+ unsigned int config:1; /* This has been loaded from the configuration. */
unsigned int trusted:1; /* This is a trusted root certificate. */
+ unsigned int systrust:1;/* The certifciate is trusted because it
+ * is in the system's store of trusted
+ * certificates (i.e. not configured using
+ * GnuPG mechanisms. */
} flags;
};
typedef struct cert_item_s *cert_item_t;
@@ -88,9 +92,9 @@ static npth_rwlock_t cert_cache_lock;
/* Flag to track whether the cache has been initialized. */
static int initialization_done;
-/* Total number of certificates loaded during initialization and
- cached during operation. */
-static unsigned int total_loaded_certificates;
+/* Total number of certificates loaded during initialization
+ * (ie. configured) and extra certifcates cached during operation. */
+static unsigned int total_config_certificates;
static unsigned int total_extra_certificates;
@@ -229,13 +233,20 @@ clean_cache_slot (cert_item_t ci)
/* Put the certificate CERT into the cache. It is assumed that the
- cache is locked while this function is called. If FPR_BUFFER is not
- NULL the fingerprint of the certificate will be stored there.
- FPR_BUFFER neds to point to a buffer of at least 20 bytes. The
- fingerprint will be stored on success or when the function returns
- gpg_err_code(GPG_ERR_DUP_VALUE). */
+ * cache is locked while this function is called.
+ *
+ * FROM_CONFIG indicates that CERT is a permanent certificate and
+ * should stay in the cache. IS_TRUSTED requests that the trusted
+ * flag is set for the certificate; a value of 1 indicates the the
+ * cert is trusted due to GnuPG mechanisms, a value of 2 indicates
+ * that it is trusted because it has been taken from the system's
+ * store of trusted certificates. If FPR_BUFFER is not NULL the
+ * fingerprint of the certificate will be stored there. FPR_BUFFER
+ * needs to point to a buffer of at least 20 bytes. The fingerprint
+ * will be stored on success or when the function returns
+ * GPG_ERR_DUP_VALUE. */
static gpg_error_t
-put_cert (ksba_cert_t cert, int is_loaded, int is_trusted, void *fpr_buffer)
+put_cert (ksba_cert_t cert, int from_config, int is_trusted, void *fpr_buffer)
{
unsigned char help_fpr_buffer[20], *fpr;
cert_item_t ci;
@@ -243,17 +254,17 @@ put_cert (ksba_cert_t cert, int is_loaded, int is_trusted, void *fpr_buffer)
fpr = fpr_buffer? fpr_buffer : &help_fpr_buffer;
/* If we already reached the caching limit, drop a couple of certs
- from the cache. Our dropping strategy is simple: We keep a
- static index counter and use this to start looking for
- certificates, then we drop 5 percent of the oldest certificates
- starting at that index. For a large cache this is a fair way of
- removing items. An LRU strategy would be better of course.
- Because we append new entries to the head of the list and we want
- to remove old ones first, we need to do this from the tail. The
- implementation is not very efficient but compared to the long
- time it takes to retrieve a certifciate from an external resource
- it seems to be reasonable. */
- if (!is_loaded && total_extra_certificates >= MAX_EXTRA_CACHED_CERTS)
+ * from the cache. Our dropping strategy is simple: We keep a
+ * static index counter and use this to start looking for
+ * certificates, then we drop 5 percent of the oldest certificates
+ * starting at that index. For a large cache this is a fair way of
+ * removing items. An LRU strategy would be better of course.
+ * Because we append new entries to the head of the list and we want
+ * to remove old ones first, we need to do this from the tail. The
+ * implementation is not very efficient but compared to the long
+ * time it takes to retrieve a certificate from an external resource
+ * it seems to be reasonable. */
+ if (!from_config && total_extra_certificates >= MAX_EXTRA_CACHED_CERTS)
{
static int idx;
cert_item_t ci_mark;
@@ -270,7 +281,7 @@ put_cert (ksba_cert_t cert, int is_loaded, int is_trusted, void *fpr_buffer)
{
ci_mark = NULL;
for (ci = cert_cache[i]; ci; ci = ci->next)
- if (ci->cert && !ci->flags.loaded)
+ if (ci->cert && !ci->flags.config)
ci_mark = ci;
if (ci_mark)
{
@@ -316,11 +327,12 @@ put_cert (ksba_cert_t cert, int is_loaded, int is_trusted, void *fpr_buffer)
return gpg_error (GPG_ERR_INV_CERT_OBJ);
}
ci->subject_dn = ksba_cert_get_subject (cert, 0);
- ci->flags.loaded = !!is_loaded;
+ ci->flags.config = !!from_config;
ci->flags.trusted = !!is_trusted;
+ ci->flags.systrust = (is_trusted && is_trusted == 2);
- if (is_loaded)
- total_loaded_certificates++;
+ if (from_config)
+ total_config_certificates++;
else
total_extra_certificates++;
@@ -390,7 +402,7 @@ load_certs_from_dir (const char *dirname, int are_trusted)
continue;
}
- err = put_cert (cert, 1, are_trusted, NULL);
+ err = put_cert (cert, 1, !!are_trusted, NULL);
if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
log_info (_("certificate '%s' already cached\n"), fname);
else if (!err)
@@ -476,7 +488,7 @@ cert_cache_deinit (int full)
}
}
- total_loaded_certificates = 0;
+ total_config_certificates = 0;
total_extra_certificates = 0;
initialization_done = 0;
release_cache_lock ();
@@ -487,7 +499,7 @@ void
cert_cache_print_stats (void)
{
log_info (_("permanently loaded certificates: %u\n"),
- total_loaded_certificates);
+ total_config_certificates);
log_info (_(" runtime cached certificates: %u\n"),
total_extra_certificates);
}