[git] GnuPG - branch, master, updated. gnupg-2.1.18-92-g7006352

by Werner Koch cvs at cvs.gnupg.org
Thu Feb 16 21:33:20 CET 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  7006352da773d82c47797bbf11e570ecafac6501 (commit)
       via  9a1a5ca0bc2cfb17ccf632de3e134b6d789c6855 (commit)
      from  09d71de4d4f0a813ba3e584540f899bfd6c568cd (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 7006352da773d82c47797bbf11e570ecafac6501
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Feb 16 21:25:58 2017 +0100

    dirmngr,w32: Load all system provided certificates.
    
    * dirmngr/certcache.c (CERTOPENSYSTEMSTORE) [W32]: New type.
    (CERTENUMCERTIFICATESINSTORE) [W32]: New type.
    (CERTCLOSESTORE) [W32]: New type.
    (load_certs_from_file) [W32]: Do not build.
    (load_certs_from_w32_store) [W32]: New.
    (load_certs_from_system) [W32]: Call new function.
    --
    
    GnuTLS loads the system certificates from the "ROOT" and "CA" store;
    thus we do the same.  On a Visa box you may for example see 21 from
    "ROOT" and 6 from "CA".
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c
index 626e440..cd026c2 100644
--- a/dirmngr/certcache.c
+++ b/dirmngr/certcache.c
@@ -100,6 +100,20 @@ static unsigned int total_extra_certificates;
 static unsigned int total_trusted_certificates;
 static unsigned int total_system_trusted_certificates;
 
+
+#ifdef HAVE_W32_SYSTEM
+/* We load some functions dynamically.  Provide typedefs for tehse
+ * fucntions.  */
+typedef HCERTSTORE (WINAPI *CERTOPENSYSTEMSTORE)
+  (HCRYPTPROV hProv, LPCSTR szSubsystemProtocol);
+typedef PCCERT_CONTEXT (WINAPI *CERTENUMCERTIFICATESINSTORE)
+  (HCERTSTORE hCertStore, PCCERT_CONTEXT pPrevCertContext);
+typedef WINBOOL (WINAPI *CERTCLOSESTORE)
+  (HCERTSTORE hCertStore,DWORD dwFlags);
+#endif /*HAVE_W32_SYSTEM*/
+
+
+
 

 /* Helper to do the cache locking.  */
 static void
@@ -444,9 +458,10 @@ load_certs_from_dir (const char *dirname, int are_trusted)
 }
 
 
+#ifndef HAVE_W32_SYSTEM
 /* 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
+ * All certificates are considered to be system provided trusted
  * certificates.  The cache should be in a locked state when calling
  * this function.  */
 static gpg_error_t
@@ -523,12 +538,133 @@ load_certs_from_file (const char *fname)
 
   return err;
 }
+#endif /*!HAVE_W32_SYSTEM*/
+
+#ifdef HAVE_W32_SYSTEM
+/* Load all certificates from the Windows store named STORENAME.  All
+ * certificates are considered to be system provided trusted
+ * certificates.  The cache should be in a locked state when calling
+ * this function.  */
+static void
+load_certs_from_w32_store (const char *storename)
+{
+  static int init_done;
+  static CERTOPENSYSTEMSTORE pCertOpenSystemStore;
+  static CERTENUMCERTIFICATESINSTORE pCertEnumCertificatesInStore;
+  static CERTCLOSESTORE pCertCloseStore;
+  gpg_error_t err;
+  HCERTSTORE w32store;
+  const CERT_CONTEXT *w32cert;
+  ksba_cert_t cert = NULL;
+  unsigned int count = 0;
+
+  /* Initialize on the first use.  */
+  if (!init_done)
+    {
+      static HANDLE hCrypt32;
+
+      init_done = 1;
+
+      hCrypt32 = LoadLibrary ("Crypt32.dll");
+      if (!hCrypt32)
+        {
+          log_error ("can't load Crypt32.dll: %s\n",  w32_strerror (-1));
+          return;
+        }
+
+      pCertOpenSystemStore = (CERTOPENSYSTEMSTORE)
+        GetProcAddress (hCrypt32, "CertOpenSystemStoreA");
+      pCertEnumCertificatesInStore = (CERTENUMCERTIFICATESINSTORE)
+        GetProcAddress (hCrypt32, "CertEnumCertificatesInStore");
+      pCertCloseStore = (CERTCLOSESTORE)
+        GetProcAddress (hCrypt32, "CertCloseStore");
+      if (   !pCertOpenSystemStore
+          || !pCertEnumCertificatesInStore
+          || !pCertCloseStore)
+        {
+          log_error ("can't load crypt32.dll: %s\n", "missing function");
+          pCertOpenSystemStore = NULL;
+        }
+    }
+
+  if (!pCertOpenSystemStore)
+    return;  /* Not initialized.  */
+
+
+  w32store = pCertOpenSystemStore (0, storename);
+  if (!w32store)
+    {
+      log_error ("can't open certificate store '%s': %s\n",
+                 storename, w32_strerror (-1));
+      return;
+    }
+
+  w32cert = NULL;
+  while ((w32cert = pCertEnumCertificatesInStore (w32store, w32cert)))
+    {
+      if (w32cert->dwCertEncodingType == X509_ASN_ENCODING)
+        {
+          ksba_cert_release (cert);
+          cert = NULL;
+          err = ksba_cert_new (&cert);
+          if (!err)
+            err = ksba_cert_init_from_mem (cert,
+                                           w32cert->pbCertEncoded,
+                                           w32cert->cbCertEncoded);
+          if (err)
+            {
+              log_error (_("can't parse certificate '%s': %s\n"),
+                         storename, gpg_strerror (err));
+              break;
+            }
+
+          err = put_cert (cert, 1, 2, NULL);
+          if (!err)
+            count++;
+          if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
+            log_info (_("certificate '%s' already cached\n"), storename);
+          else if (err)
+            log_error (_("error loading certificate '%s': %s\n"),
+                       storename, gpg_strerror (err));
+          else if (opt.verbose > 1)
+            {
+              char *p;
+
+              log_info (_("trusted certificate '%s' loaded\n"), storename);
+              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_cert_release (cert);
+  pCertCloseStore (w32store, 0);
+
+  if (DBG_X509)
+    log_debug ("number of certs loaded from store '%s': %u\n",
+               storename, count);
+
+}
+#endif /*HAVE_W32_SYSTEM*/
 
 
 /* Load the trusted certificates provided by the system.  */
 static gpg_error_t
 load_certs_from_system (void)
 {
+#ifdef HAVE_W32_SYSTEM
+
+  load_certs_from_w32_store ("ROOT");
+  load_certs_from_w32_store ("CA");
+
+  return 0;
+
+#else /*!HAVE_W32_SYSTEM*/
+
   /* A list of certificate bundles to try.  */
   static struct {
     const char *name;
@@ -554,8 +690,8 @@ load_certs_from_system (void)
         break;
       }
 
-
   return err;
+#endif /*!HAVE_W32_SYSTEM*/
 }
 
 

commit 9a1a5ca0bc2cfb17ccf632de3e134b6d789c6855
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Feb 16 18:58:27 2017 +0100

    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 at gnupg.org>

diff --git a/configure.ac b/configure.ac
index ce02d03..1733c5a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -990,6 +990,22 @@ else
   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])
 
diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c
index d68d503..626e440 100644
--- a/dirmngr/certcache.c
+++ b/dirmngr/certcache.c
@@ -1,5 +1,5 @@
 /* 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.
  *
@@ -29,10 +29,10 @@
 
 #include "dirmngr.h"
 #include "misc.h"
+#include "../common/ksba-io-support.h"
 #include "crlfetch.h"
 #include "certcache.h"
 
-
 #define MAX_EXTRA_CACHED_CERTS 1000
 
 /* Constants used to classify search patterns.  */
@@ -93,10 +93,12 @@ static npth_rwlock_t cert_cache_lock;
 static int initialization_done;
 
 /* 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_extra_certificates;
-
+static unsigned int total_trusted_certificates;
+static unsigned int total_system_trusted_certificates;
 
 

 /* 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);
               drop_count--;
               total_extra_certificates--;
+              if (ci->flags.trusted)
+                total_trusted_certificates--;
+              if (ci->flags.systrust)
+                total_system_trusted_certificates--;
             }
         }
       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.systrust = (is_trusted && is_trusted == 2);
 
+  if (ci->flags.trusted)
+    total_trusted_certificates++;
+  if (ci->flags.systrust)
+    total_system_trusted_certificates++;
+
   if (from_config)
     total_config_certificates++;
   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.  */
 void
 cert_cache_init (void)
@@ -444,6 +570,8 @@ cert_cache_init (void)
   init_cache_lock ();
   acquire_cache_write_lock ();
 
+  load_certs_from_system ();
+
   dname = make_filename (gnupg_sysconfdir (), "trusted-certs", NULL);
   load_certs_from_dir (dname, 1);
   xfree (dname);
@@ -490,6 +618,8 @@ cert_cache_deinit (int full)
 
   total_config_certificates = 0;
   total_extra_certificates = 0;
+  total_trusted_certificates = 0;
+  total_system_trusted_certificates = 0;
   initialization_done = 0;
   release_cache_lock ();
 }
@@ -502,6 +632,8 @@ cert_cache_print_stats (void)
             total_config_certificates);
   log_info (_("    runtime cached certificates: %u\n"),
             total_extra_certificates);
+  log_info (_("           trusted certificates: %u (%u)\n"),
+            total_trusted_certificates, total_system_trusted_certificates);
 }
 
 
@@ -1274,11 +1406,12 @@ find_cert_bysubject (ctrl_t ctrl, const char *subject_dn, ksba_sexp_t keyid)
 }
 
 
-/* Return 0 if the certificate is a trusted certificate. Returns
-   GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in
-   case of systems errors. */
+/* Return 0 if the certificate is a trusted certificate.  Returns
+ * GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in
+ * case of systems errors.  If WITH_SYSTRUST is set also system
+ * provided certificates are considered trusted.  */
 gpg_error_t
-is_trusted_cert (ksba_cert_t cert)
+is_trusted_cert (ksba_cert_t cert, int with_systrust)
 {
   unsigned char fpr[20];
   cert_item_t ci;
@@ -1289,7 +1422,7 @@ is_trusted_cert (ksba_cert_t cert)
   for (ci=cert_cache[*fpr]; ci; ci = ci->next)
     if (ci->cert && !memcmp (ci->fpr, fpr, 20))
       {
-        if (ci->flags.trusted)
+        if (ci->flags.trusted && (with_systrust || !ci->flags.systrust))
           {
             release_cache_lock ();
             return 0; /* Yes, it is trusted. */
diff --git a/dirmngr/certcache.h b/dirmngr/certcache.h
index 9986f15..ac93ee6 100644
--- a/dirmngr/certcache.h
+++ b/dirmngr/certcache.h
@@ -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);
 
 /* Return 0 if the certificate is a trusted certificate. Returns
-   GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in
-   case of systems errors. */
-gpg_error_t is_trusted_cert (ksba_cert_t cert);
+ * GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in
+ * case of systems errors.  If WITH_SYSTRUST is set also system
+ * 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
diff --git a/dirmngr/validate.c b/dirmngr/validate.c
index 68e1bb3..4139c22 100644
--- a/dirmngr/validate.c
+++ b/dirmngr/validate.c
@@ -189,7 +189,7 @@ allowed_ca (ksba_cert_t cert, int *chainlen)
     return err;
   if (!flag)
     {
-      if (!is_trusted_cert (cert))
+      if (!is_trusted_cert (cert, 0))
         {
           /* The German SigG Root CA's certificate does not flag
              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)
             goto leave;  /* No. */
 
-          err = is_trusted_cert (subject_cert);
+          err = is_trusted_cert (subject_cert, 0);
           if (!err)
             ; /* Yes we trust this cert.  */
           else if (gpg_err_code (err) == GPG_ERR_NOT_TRUSTED)

-----------------------------------------------------------------------

Summary of changes:
 configure.ac        |  16 +++
 dirmngr/certcache.c | 285 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 dirmngr/certcache.h |   7 +-
 dirmngr/validate.c  |   4 +-
 4 files changed, 299 insertions(+), 13 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list