[glib-networking/use-default-verify-paths: 1/2] wip



commit 33df709b0222a37c510faf9eec0441c79c1d4a8f
Author: Ignacio Casal Quinteiro <qignacio amazon com>
Date:   Tue Feb 12 09:25:18 2019 +0100

    wip

 tls/openssl/gtlsbackend-openssl.c      |  80 +---
 tls/openssl/gtlsbackend-openssl.h      |  12 +-
 tls/openssl/gtlsconnection-openssl.c   |   6 +-
 tls/openssl/gtlsdatabase-openssl.c     | 764 ++++++++++++++++++++++++++++++++-
 tls/openssl/gtlsdatabase-openssl.h     |  28 +-
 tls/openssl/gtlsfiledatabase-openssl.c | 762 ++------------------------------
 tls/openssl/gtlsfiledatabase-openssl.h |  28 +-
 7 files changed, 843 insertions(+), 837 deletions(-)
---
diff --git a/tls/openssl/gtlsbackend-openssl.c b/tls/openssl/gtlsbackend-openssl.c
index 96428ac..67971c1 100644
--- a/tls/openssl/gtlsbackend-openssl.c
+++ b/tls/openssl/gtlsbackend-openssl.c
@@ -36,16 +36,17 @@
 #include "gtlsclientconnection-openssl.h"
 #include "gtlsfiledatabase-openssl.h"
 
-typedef struct _GTlsBackendOpensslPrivate
+struct _GTlsBackendOpenssl
 {
+  GObject parent_instance;
+
   GMutex mutex;
   GTlsDatabase *default_database;
-} GTlsBackendOpensslPrivate;
+};
 
 static void g_tls_backend_openssl_interface_init (GTlsBackendInterface *iface);
 
 G_DEFINE_DYNAMIC_TYPE_EXTENDED (GTlsBackendOpenssl, g_tls_backend_openssl, G_TYPE_OBJECT, 0,
-                                G_ADD_PRIVATE_DYNAMIC (GTlsBackendOpenssl)
                                 G_IMPLEMENT_INTERFACE_DYNAMIC (G_TYPE_TLS_BACKEND,
                                                                g_tls_backend_openssl_interface_init))
 
@@ -144,12 +145,8 @@ gtls_openssl_init (gpointer data)
 static GOnce openssl_inited = G_ONCE_INIT;
 
 static void
-g_tls_backend_openssl_init (GTlsBackendOpenssl *backend)
+g_tls_backend_openssl_init (GTlsBackendOpenssl *self)
 {
-  GTlsBackendOpensslPrivate *priv;
-
-  priv = g_tls_backend_openssl_get_instance_private (backend);
-
   /* Once we call gtls_openssl_init(), we can't allow the module to be
    * unloaded (since if openssl gets unloaded but gcrypt doesn't, then
    * gcrypt will have dangling pointers to openssl's mutex functions).
@@ -159,21 +156,17 @@ g_tls_backend_openssl_init (GTlsBackendOpenssl *backend)
    */
   g_once (&openssl_inited, gtls_openssl_init, NULL);
 
-  g_mutex_init (&priv->mutex);
+  g_mutex_init (&self->mutex);
 }
 
 static void
 g_tls_backend_openssl_finalize (GObject *object)
 {
+  GTlsBackendOpenssl *self = G_TLS_BACKEND_OPENSSL (object);
   int i;
 
-  GTlsBackendOpenssl *backend = G_TLS_BACKEND_OPENSSL (object);
-  GTlsBackendOpensslPrivate *priv;
-
-  priv = g_tls_backend_openssl_get_instance_private (backend);
-
-  g_clear_object (&priv->default_database);
-  g_mutex_clear (&priv->mutex);
+  g_clear_object (&self->default_database);
+  g_mutex_clear (&self->mutex);
 
   CRYPTO_set_id_callback (NULL);
   CRYPTO_set_locking_callback (NULL);
@@ -187,49 +180,12 @@ g_tls_backend_openssl_finalize (GObject *object)
   G_OBJECT_CLASS (g_tls_backend_openssl_parent_class)->finalize (object);
 }
 
-static GTlsDatabase *
-g_tls_backend_openssl_real_create_database (GTlsBackendOpenssl  *self,
-                                            GError             **error)
-{
-  gchar *anchor_file = NULL;
-  GTlsDatabase *database;
-
-#ifdef G_OS_WIN32
-  if (g_getenv ("G_TLS_OPENSSL_HANDLE_CERT_RELOCATABLE") != NULL)
-    {
-      gchar *module_dir;
-
-      module_dir = g_win32_get_package_installation_directory_of_module (NULL);
-      anchor_file = g_build_filename (module_dir, "bin", "cert.pem", NULL);
-      g_free (module_dir);
-    }
-#endif
-
-  if (anchor_file == NULL)
-    {
-      const gchar *openssl_cert_file;
-
-      openssl_cert_file = g_getenv (X509_get_default_cert_file_env ());
-      if (openssl_cert_file == NULL)
-        openssl_cert_file = X509_get_default_cert_file ();
-
-      anchor_file = g_strdup (openssl_cert_file);
-    }
-
-  database = g_tls_file_database_new (anchor_file, error);
-  g_free (anchor_file);
-
-  return database;
-}
-
 static void
 g_tls_backend_openssl_class_init (GTlsBackendOpensslClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
   gobject_class->finalize = g_tls_backend_openssl_finalize;
-
-  klass->create_database = g_tls_backend_openssl_real_create_database;
 }
 
 static void
@@ -240,23 +196,19 @@ g_tls_backend_openssl_class_finalize (GTlsBackendOpensslClass *backend_class)
 static GTlsDatabase*
 g_tls_backend_openssl_get_default_database (GTlsBackend *backend)
 {
-  GTlsBackendOpenssl *openssl_backend = G_TLS_BACKEND_OPENSSL (backend);
-  GTlsBackendOpensslPrivate *priv;
+  GTlsBackendOpenssl *self = G_TLS_BACKEND_OPENSSL (backend);
   GTlsDatabase *result;
   GError *error = NULL;
 
-  priv = g_tls_backend_openssl_get_instance_private (openssl_backend);
-
-  g_mutex_lock (&priv->mutex);
+  g_mutex_lock (&self->mutex);
 
-  if (priv->default_database)
+  if (self->default_database)
     {
-      result = g_object_ref (priv->default_database);
+      result = g_object_ref (self->default_database);
     }
   else
     {
-      g_assert (G_TLS_BACKEND_OPENSSL_GET_CLASS (openssl_backend)->create_database);
-      result = G_TLS_BACKEND_OPENSSL_GET_CLASS (openssl_backend)->create_database (openssl_backend, &error);
+      result = G_TLS_DATABASE (g_tls_database_openssl_new (&error));
       if (error)
         {
           g_warning ("Couldn't load TLS file database: %s",
@@ -266,11 +218,11 @@ g_tls_backend_openssl_get_default_database (GTlsBackend *backend)
       else
         {
           g_assert (result);
-          priv->default_database = g_object_ref (result);
+          self->default_database = g_object_ref (result);
         }
     }
 
-  g_mutex_unlock (&priv->mutex);
+  g_mutex_unlock (&self->mutex);
 
   return result;
 }
diff --git a/tls/openssl/gtlsbackend-openssl.h b/tls/openssl/gtlsbackend-openssl.h
index 410b0fb..3ee4c7d 100644
--- a/tls/openssl/gtlsbackend-openssl.h
+++ b/tls/openssl/gtlsbackend-openssl.h
@@ -30,16 +30,8 @@
 G_BEGIN_DECLS
 
 #define G_TYPE_TLS_BACKEND_OPENSSL (g_tls_backend_openssl_get_type ())
-G_DECLARE_DERIVABLE_TYPE (GTlsBackendOpenssl, g_tls_backend_openssl,
-                          G, TLS_BACKEND_OPENSSL, GObject)
-
-struct _GTlsBackendOpensslClass
-{
-  GObjectClass parent_class;
-
-  GTlsDatabase*   (*create_database)      (GTlsBackendOpenssl         *backend,
-                                           GError                    **error);
-};
+G_DECLARE_FINAL_TYPE (GTlsBackendOpenssl, g_tls_backend_openssl,
+                      G, TLS_BACKEND_OPENSSL, GObject)
 
 void    g_tls_backend_openssl_register       (GIOModule *module);
 
diff --git a/tls/openssl/gtlsconnection-openssl.c b/tls/openssl/gtlsconnection-openssl.c
index 9b4b9b4..4b363fa 100644
--- a/tls/openssl/gtlsconnection-openssl.c
+++ b/tls/openssl/gtlsconnection-openssl.c
@@ -300,9 +300,9 @@ verify_ocsp_response (GTlsConnectionOpenssl *openssl,
   if (resp == NULL)
     return G_TLS_CERTIFICATE_GENERIC_ERROR;
 
-  return g_tls_file_database_openssl_verify_ocsp_response (database,
-                                                           peer_certificate,
-                                                           resp);
+  return g_tls_database_openssl_verify_ocsp_response (G_TLS_DATABASE_OPENSSL (database),
+                                                      peer_certificate,
+                                                      resp);
 #else
   return 0;
 #endif
diff --git a/tls/openssl/gtlsdatabase-openssl.c b/tls/openssl/gtlsdatabase-openssl.c
index 93461a2..b6a725a 100644
--- a/tls/openssl/gtlsdatabase-openssl.c
+++ b/tls/openssl/gtlsdatabase-openssl.c
@@ -1,5 +1,5 @@
 /*
- * gtlsdatabase-openssl.c
+ * gtlsfiledatabase-openssl.c
  *
  * Copyright (C) 2015 NICE s.r.l.
  *
@@ -26,14 +26,772 @@
 
 #include "gtlsdatabase-openssl.h"
 
-G_DEFINE_ABSTRACT_TYPE (GTlsDatabaseOpenssl, g_tls_database_openssl, G_TYPE_TLS_DATABASE)
+#include <gio/gio.h>
+#include <glib/gi18n-lib.h>
+#include "openssl-include.h"
+
+typedef struct _GTlsDatabaseOpensslPrivate
+{
+  /*
+   * This class is protected by mutex because the default GTlsDatabase
+   * is a global singleton, accessible via the default GTlsBackend.
+   */
+  GMutex mutex;
+
+  /* read-only after construct */
+  X509_STORE *store;
+
+  /*
+   * These are hash tables of gulong -> GPtrArray<GBytes>. The values of
+   * the ptr array are full DER encoded certificate values. The keys are byte
+   * arrays containing either subject DNs, issuer DNs, or full DER encoded certs
+   */
+  GHashTable *subjects;
+  GHashTable *issuers;
+
+  /*
+   * This is a table of GBytes -> GBytes. The values and keys are
+   * DER encoded certificate values.
+   */
+  GHashTable *complete;
+
+  /*
+   * This is a table of gchar * -> GPtrArray<GBytes>. The values of
+   * the ptr array are full DER encoded certificate values. The keys are the
+   * string handles. This array is populated on demand.
+   */
+  GHashTable *handles;
+} GTlsDatabaseOpensslPrivate;
+
+static void g_tls_database_openssl_initable_interface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GTlsDatabaseOpenssl, g_tls_database_openssl, G_TYPE_TLS_DATABASE,
+                         G_ADD_PRIVATE (GTlsDatabaseOpenssl)
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+                                                g_tls_database_openssl_initable_interface_init))
+
+static GHashTable *
+bytes_multi_table_new (void)
+{
+  return g_hash_table_new_full (g_int_hash, g_int_equal,
+                                (GDestroyNotify)g_free,
+                                (GDestroyNotify)g_ptr_array_unref);
+}
+
+static void
+bytes_multi_table_insert (GHashTable *table,
+                          gulong      key,
+                          GBytes     *value)
+{
+  GPtrArray *multi;
+
+  multi = g_hash_table_lookup (table, &key);
+  if (multi == NULL)
+    {
+      int *key_ptr;
+
+      key_ptr = g_new (int, 1);
+      *key_ptr = (int)key;
+      multi = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref);
+      g_hash_table_insert (table, key_ptr, multi);
+    }
+  g_ptr_array_add (multi, g_bytes_ref (value));
+}
+
+static GBytes *
+bytes_multi_table_lookup_ref_one (GHashTable *table,
+                                  gulong      key)
+{
+  GPtrArray *multi;
+
+  multi = g_hash_table_lookup (table, &key);
+  if (multi == NULL)
+    return NULL;
+
+  g_assert (multi->len > 0);
+  return g_bytes_ref (multi->pdata[0]);
+}
+
+static GList *
+bytes_multi_table_lookup_ref_all (GHashTable *table,
+                                  gulong      key)
+{
+  GPtrArray *multi;
+  GList *list = NULL;
+  guint i;
+
+  multi = g_hash_table_lookup (table, &key);
+  if (multi == NULL)
+    return NULL;
+
+  for (i = 0; i < multi->len; i++)
+    list = g_list_prepend (list, g_bytes_ref (multi->pdata[i]));
+
+  return g_list_reverse (list);
+}
+
+static GHashTable *
+create_handles_array_unlocked (GTlsDatabaseOpenssl *self,
+                               GHashTable          *complete)
+{
+  GHashTable *handles;
+  GHashTableIter iter;
+  GBytes *der;
+  gchar *handle;
+
+  handles = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
+                                   (GDestroyNotify)g_bytes_unref);
+
+  g_hash_table_iter_init (&iter, complete);
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&der))
+    {
+      g_assert (G_TLS_DATABASE_OPENSSL_GET_CLASS (self)->create_handle_for_certificate);
+      handle = G_TLS_DATABASE_OPENSSL_GET_CLASS (self)->create_handle_for_certificate (self, der);
+      if (handle != NULL)
+        g_hash_table_insert (handles, handle, g_bytes_ref (der));
+    }
+
+  return handles;
+}
+
+static gboolean
+initialize_tables (X509_STORE *store,
+                   GHashTable *subjects,
+                   GHashTable *issuers,
+                   GHashTable *complete)
+{
+  X509_STORE_CTX *store_ctx;
+  STACK_OF(X509) *chain = NULL;
+  gboolean ret = FALSE;
+  int i;
+
+  store_ctx = X509_STORE_CTX_new ();
+  if (store_ctx == NULL)
+    return FALSE;
+
+  if (!X509_STORE_CTX_init (store_ctx, store, NULL, NULL))
+    goto out;
+
+  chain = X509_STORE_CTX_get1_chain (store_ctx);
+
+  for (i = 0; i < sk_X509_num (chain); i++)
+    {
+      X509 *x;
+      unsigned long subject;
+      unsigned long issuer;
+      guint8 *data;
+      int size;
+      GBytes *der;
+
+      x = sk_X509_value (chain, i);
+      subject = X509_subject_name_hash (x);
+      issuer = X509_issuer_name_hash (x);
+
+      size = i2d_X509 (x, &data);
+      der = g_bytes_new_take (der, size);
+
+      g_hash_table_insert (complete, g_bytes_ref (der),
+                           g_bytes_ref (der));
+
+      bytes_multi_table_insert (subjects, subject, der);
+      bytes_multi_table_insert (issuers, issuer, der);
+
+      g_bytes_unref (der);
+    }
+
+  ret = TRUE;
+
+out:
+  X509_STORE_CTX_free (store_ctx);
+
+  if (chain)
+    sk_X509_pop_free (chain, X509_free);
+
+  return ret;
+}
+
+static void
+g_tls_database_openssl_finalize (GObject *object)
+{
+  GTlsDatabaseOpenssl *self = G_TLS_DATABASE_OPENSSL (object);
+  GTlsDatabaseOpensslPrivate *priv;
+
+  priv = g_tls_database_openssl_get_instance_private (self);
+
+  g_clear_pointer (&priv->subjects, g_hash_table_destroy);
+  g_clear_pointer (&priv->issuers, g_hash_table_destroy);
+  g_clear_pointer (&priv->complete, g_hash_table_destroy);
+  g_clear_pointer (&priv->handles, g_hash_table_destroy);
+
+  if (priv->store != NULL)
+    X509_STORE_free (priv->store);
+
+  g_mutex_clear (&priv->mutex);
+
+  G_OBJECT_CLASS (g_tls_database_openssl_parent_class)->finalize (object);
+}
+
+static void
+g_tls_database_openssl_init (GTlsDatabaseOpenssl *self)
+{
+  GTlsDatabaseOpensslPrivate *priv;
+
+  priv = g_tls_database_openssl_get_instance_private (self);
+
+  g_mutex_init (&priv->mutex);
+}
+
+static gchar *
+g_tls_database_openssl_create_certificate_handle (GTlsDatabase    *database,
+                                                  GTlsCertificate *certificate)
+{
+  GTlsDatabaseOpenssl *self = G_TLS_DATABASE_OPENSSL (database);
+  GTlsDatabaseOpensslPrivate *priv;
+  GBytes *der;
+  gboolean contains;
+  gchar *handle = NULL;
+
+  priv = g_tls_database_openssl_get_instance_private (self);
+
+  der = g_tls_certificate_openssl_get_bytes (G_TLS_CERTIFICATE_OPENSSL (certificate));
+  g_return_val_if_fail (der != NULL, FALSE);
+
+  g_mutex_lock (&priv->mutex);
+
+  /* At the same time look up whether this certificate is in list */
+  contains = g_hash_table_lookup (priv->complete, der) ? TRUE : FALSE;
+
+  g_mutex_unlock (&priv->mutex);
+
+  /* Certificate is in the database */
+  if (contains)
+    {
+      g_assert (G_TLS_DATABASE_OPENSSL_GET_CLASS (self)->create_handle_for_certificate);
+      handle = G_TLS_DATABASE_OPENSSL_GET_CLASS (self)->create_handle_for_certificate (self, der);
+    }
+
+  g_bytes_unref (der);
+  return handle;
+}
+
+static GTlsCertificate *
+g_tls_database_openssl_lookup_certificate_for_handle (GTlsDatabase            *database,
+                                                      const gchar             *handle,
+                                                      GTlsInteraction         *interaction,
+                                                      GTlsDatabaseLookupFlags  flags,
+                                                      GCancellable            *cancellable,
+                                                      GError                 **error)
+{
+  GTlsDatabaseOpenssl *self = G_TLS_DATABASE_OPENSSL (database);
+  GTlsDatabaseOpensslPrivate *priv;
+  GTlsCertificate *cert;
+  GBytes *der;
+
+  priv = g_tls_database_openssl_get_instance_private (self);
+
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    return NULL;
+
+  if (!handle)
+    return NULL;
+
+
+  /* Create the handles table if not already done */
+  if (!priv->handles)
+    priv->handles = create_handles_array_unlocked (self, priv->complete);
+
+  der = g_hash_table_lookup (priv->handles, handle);
+  if (der != NULL)
+    g_bytes_ref (der);
+
+  g_mutex_unlock (&priv->mutex);
+
+  if (der == NULL)
+    return NULL;
+
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    cert = NULL;
+  else
+    cert = g_tls_certificate_openssl_new (der, NULL);
+
+  g_bytes_unref (der);
+  return cert;
+}
+
+static GTlsCertificate *
+g_tls_database_openssl_lookup_certificate_issuer (GTlsDatabase             *database,
+                                                  GTlsCertificate          *certificate,
+                                                  GTlsInteraction          *interaction,
+                                                  GTlsDatabaseLookupFlags   flags,
+                                                  GCancellable             *cancellable,
+                                                  GError                  **error)
+{
+  GTlsDatabaseOpenssl *self = G_TLS_DATABASE_OPENSSL (database);
+  GTlsDatabaseOpensslPrivate *priv;
+  X509 *x;
+  unsigned long issuer_hash;
+  GBytes *der;
+  GTlsCertificate *issuer = NULL;
+
+  priv = g_tls_database_openssl_get_instance_private (self);
+
+  g_return_val_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (certificate), NULL);
+
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    return NULL;
+
+  if (flags & G_TLS_DATABASE_LOOKUP_KEYPAIR)
+    return NULL;
+
+  /* Dig out the issuer of this certificate */
+  x = g_tls_certificate_openssl_get_cert (G_TLS_CERTIFICATE_OPENSSL (certificate));
+  issuer_hash = X509_issuer_name_hash (x);
+
+  g_mutex_lock (&priv->mutex);
+  der = bytes_multi_table_lookup_ref_one (priv->subjects, issuer_hash);
+  g_mutex_unlock (&priv->mutex);
+
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    issuer = NULL;
+  else if (der != NULL)
+    issuer = g_tls_certificate_openssl_new (der, NULL);
+
+  if (der != NULL)
+    g_bytes_unref (der);
+  return issuer;
+
+  return NULL;
+}
+
+static GList *
+g_tls_database_openssl_lookup_certificates_issued_by (GTlsDatabase             *database,
+                                                      GByteArray               *issuer_raw_dn,
+                                                      GTlsInteraction          *interaction,
+                                                      GTlsDatabaseLookupFlags   flags,
+                                                      GCancellable             *cancellable,
+                                                      GError                  **error)
+{
+  GTlsDatabaseOpenssl *self = G_TLS_DATABASE_OPENSSL (database);
+  GTlsDatabaseOpensslPrivate *priv;
+  X509_NAME *x_name;
+  const unsigned char *in;
+  GList *issued = NULL;
+
+  priv = g_tls_database_openssl_get_instance_private (self);
+
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    return NULL;
+
+  /* We don't have any private keys here */
+  if (flags & G_TLS_DATABASE_LOOKUP_KEYPAIR)
+    return NULL;
+
+  in = issuer_raw_dn->data;
+  x_name = d2i_X509_NAME (NULL, &in, issuer_raw_dn->len);
+  if (x_name != NULL)
+    {
+      unsigned long issuer_hash;
+      GList *ders, *l;
+
+      issuer_hash = X509_NAME_hash (x_name);
+
+      /* Find the full DER value of the certificate */
+      g_mutex_lock (&priv->mutex);
+      ders = bytes_multi_table_lookup_ref_all (priv->issuers, issuer_hash);
+      g_mutex_unlock (&priv->mutex);
+
+      for (l = ders; l != NULL; l = g_list_next (l))
+        {
+          if (g_cancellable_set_error_if_cancelled (cancellable, error))
+            {
+              g_list_free_full (issued, g_object_unref);
+              issued = NULL;
+              break;
+            }
+
+          issued = g_list_prepend (issued, g_tls_certificate_openssl_new (l->data, NULL));
+        }
+
+      g_list_free_full (ders, (GDestroyNotify)g_bytes_unref);
+      X509_NAME_free (x_name);
+    }
+
+  return issued;
+}
+
+static GTlsCertificateFlags
+double_check_before_after_dates (GTlsCertificateOpenssl *chain)
+{
+  GTlsCertificateFlags gtls_flags = 0;
+  X509 *cert;
+
+  while (chain)
+    {
+      ASN1_TIME *not_before;
+      ASN1_TIME *not_after;
+
+      cert = g_tls_certificate_openssl_get_cert (chain);
+      not_before = X509_get_notBefore (cert);
+      not_after = X509_get_notAfter (cert);
+
+      if (X509_cmp_current_time (not_before) > 0)
+        gtls_flags |= G_TLS_CERTIFICATE_NOT_ACTIVATED;
+
+      if (X509_cmp_current_time (not_after) < 0)
+        gtls_flags |= G_TLS_CERTIFICATE_EXPIRED;
+
+      chain = G_TLS_CERTIFICATE_OPENSSL (g_tls_certificate_get_issuer
+                                         (G_TLS_CERTIFICATE (chain)));
+    }
+
+  return gtls_flags;
+}
+
+static STACK_OF(X509) *
+convert_certificate_chain_to_openssl (GTlsCertificateOpenssl *chain)
+{
+  GTlsCertificate *cert;
+  STACK_OF(X509) *openssl_chain;
+
+  openssl_chain = sk_X509_new_null ();
+
+  for (cert = G_TLS_CERTIFICATE (chain); cert; cert = g_tls_certificate_get_issuer (cert))
+    sk_X509_push (openssl_chain, g_tls_certificate_openssl_get_cert (G_TLS_CERTIFICATE_OPENSSL (cert)));
+
+  return openssl_chain;
+}
+
+static GTlsCertificateFlags
+g_tls_database_openssl_verify_chain (GTlsDatabase             *database,
+                                     GTlsCertificate          *chain,
+                                     const gchar              *purpose,
+                                     GSocketConnectable       *identity,
+                                     GTlsInteraction          *interaction,
+                                     GTlsDatabaseVerifyFlags   flags,
+                                     GCancellable             *cancellable,
+                                     GError                  **error)
+{
+  GTlsDatabaseOpenssl *self = G_TLS_DATABASE_OPENSSL (database);
+  GTlsDatabaseOpensslPrivate *priv;
+  STACK_OF(X509) *certs;
+  X509_STORE_CTX *csc;
+  X509 *x;
+  GTlsCertificateFlags result = 0;
+
+  g_return_val_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (chain),
+                        G_TLS_CERTIFICATE_GENERIC_ERROR);
+
+  priv = g_tls_database_openssl_get_instance_private (self);
+
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    return G_TLS_CERTIFICATE_GENERIC_ERROR;
+
+  certs = convert_certificate_chain_to_openssl (G_TLS_CERTIFICATE_OPENSSL (chain));
+
+  csc = X509_STORE_CTX_new ();
+
+  x = g_tls_certificate_openssl_get_cert (G_TLS_CERTIFICATE_OPENSSL (chain));
+  if (!X509_STORE_CTX_init (csc, priv->store, x, certs))
+    {
+      X509_STORE_CTX_free (csc);
+      sk_X509_free (certs);
+      return G_TLS_CERTIFICATE_GENERIC_ERROR;
+    }
+
+  if (X509_verify_cert (csc) <= 0)
+    result = g_tls_certificate_openssl_convert_error (X509_STORE_CTX_get_error (csc));
+
+  X509_STORE_CTX_free (csc);
+  sk_X509_free (certs);
+
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    return G_TLS_CERTIFICATE_GENERIC_ERROR;
+
+  /* We have to check these ourselves since openssl
+   * does not give us flags and UNKNOWN_CA will take priority.
+   */
+  result |= double_check_before_after_dates (G_TLS_CERTIFICATE_OPENSSL (chain));
+
+  if (identity)
+    result |= g_tls_certificate_openssl_verify_identity (G_TLS_CERTIFICATE_OPENSSL (chain),
+                                                         identity);
+
+  return result;
+}
+
+static gchar *
+g_tls_database_openssl_create_handle_for_certificate (GTlsDatabaseOpenssl *self,
+                                                      GBytes              *der)
+{
+  gchar *bookmark;
+  gchar *uri;
+
+  /*
+   * Here we create a URI that looks like
+   * system-trust:#11b2641821252596420e468c275771f5e51022c121a17bd7a89a2f37b6336c8f.
+   *
+   * system-trust is a meaningless URI scheme, and the handle does not
+   * even need to be a URI; this is just a nice stable way to uniquely
+   * identify a certificate.
+   */
+
+  bookmark = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, der);
+  uri = g_strconcat ("system-trust:#", bookmark, NULL);
+
+  g_free (bookmark);
+
+  return uri;
+}
+
+static gboolean
+g_tls_database_openssl_populate_trust_list (GTlsDatabaseOpenssl  *self,
+                                            X509_STORE           *store,
+                                            GError              **error)
+{
+  X509_LOOKUP *lookup;
+
+  lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file ());
+  if (lookup == NULL)
+    {
+      g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
+                   _("Failed to load system trust store file: %s"),
+                   ERR_error_string (ERR_get_error (), NULL));
+      return FALSE;
+    }
+
+  X509_LOOKUP_load_file (lookup, NULL, X509_FILETYPE_DEFAULT);
+
+  lookup = X509_STORE_add_lookup (store, X509_LOOKUP_hash_dir ());
+  if (lookup == NULL)
+    {
+      g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
+                   _("Failed to load system trust store: %s"),
+                   ERR_error_string (ERR_get_error (), NULL));
+      return FALSE;
+    }
+
+  X509_LOOKUP_add_dir (lookup, NULL, X509_FILETYPE_DEFAULT);
+
+  /* clear any errors */
+  ERR_clear_error ();
+
+  return TRUE;
+}
 
 static void
 g_tls_database_openssl_class_init (GTlsDatabaseOpensslClass *klass)
 {
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GTlsDatabaseClass *database_class = G_TLS_DATABASE_CLASS (klass);
+
+  gobject_class->finalize     = g_tls_database_openssl_finalize;
+
+  database_class->create_certificate_handle = g_tls_database_openssl_create_certificate_handle;
+  database_class->lookup_certificate_for_handle = g_tls_database_openssl_lookup_certificate_for_handle;
+  database_class->lookup_certificate_issuer = g_tls_database_openssl_lookup_certificate_issuer;
+  database_class->lookup_certificates_issued_by = g_tls_database_openssl_lookup_certificates_issued_by;
+  database_class->verify_chain = g_tls_database_openssl_verify_chain;
+
+  klass->create_handle_for_certificate = g_tls_database_openssl_create_handle_for_certificate;
+  klass->populate_trust_list = g_tls_database_openssl_populate_trust_list;
+}
+
+static gboolean
+g_tls_database_openssl_initable_init (GInitable    *initable,
+                                      GCancellable *cancellable,
+                                      GError      **error)
+{
+  GTlsDatabaseOpenssl *self = G_TLS_DATABASE_OPENSSL (initable);
+  GTlsDatabaseOpensslPrivate *priv;
+  X509_STORE *store;
+  GHashTable *subjects, *issuers, *complete;
+  gboolean result;
+
+  priv = g_tls_database_openssl_get_instance_private (self);
+
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    return FALSE;
+
+  store = X509_STORE_new ();
+  if (store == NULL)
+    {
+      g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
+                           _("Could not create CA store"));
+      result = FALSE;
+      goto out;
+    }
+
+  g_assert (G_TLS_DATABASE_OPENSSL_GET_CLASS (self)->populate_trust_list);
+  if (!G_TLS_DATABASE_OPENSSL_GET_CLASS (self)->populate_trust_list (self, store, error))
+    {
+      result = FALSE;
+      goto out;
+    }
+
+  subjects = bytes_multi_table_new ();
+  issuers = bytes_multi_table_new ();
+
+  complete = g_hash_table_new_full (g_bytes_hash, g_bytes_equal,
+                                    (GDestroyNotify)g_bytes_unref,
+                                    (GDestroyNotify)g_bytes_unref);
+
+  if (!initialize_tables (store, subjects, issuers, complete))
+    {
+      g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
+                           _("Could not initialize certificate chain data"));
+      result = FALSE;
+      goto out;
+    }
+
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    result = FALSE;
+
+  if (result)
+    {
+      g_mutex_lock (&priv->mutex);
+      if (!priv->store)
+        {
+          priv->store = store;
+          store = NULL;
+        }
+
+      if (!priv->subjects)
+        {
+          priv->subjects = subjects;
+          subjects = NULL;
+        }
+
+      if (!priv->issuers)
+        {
+          priv->issuers = issuers;
+          issuers = NULL;
+        }
+
+      if (!priv->complete)
+        {
+          priv->complete = complete;
+          complete = NULL;
+        }
+
+      g_mutex_unlock (&priv->mutex);
+    }
+
+out:
+  if (store != NULL)
+    X509_STORE_free (store);
+  if (subjects != NULL)
+    g_hash_table_unref (subjects);
+  if (issuers != NULL)
+    g_hash_table_unref (issuers);
+  if (complete != NULL)
+    g_hash_table_unref (complete);
+
+  return result;
 }
 
 static void
-g_tls_database_openssl_init (GTlsDatabaseOpenssl *openssl)
+g_tls_database_openssl_initable_interface_init (GInitableIface *iface)
+{
+  iface->init = g_tls_database_openssl_initable_init;
+}
+
+GTlsDatabaseOpenssl *
+g_tls_database_openssl_new (GError **error)
+{
+  g_return_val_if_fail (!error || !*error, NULL);
+
+  return g_initable_new (G_TYPE_TLS_DATABASE_OPENSSL, NULL, error, NULL);
+}
+
+GTlsCertificateFlags
+g_tls_database_openssl_verify_ocsp_response (GTlsDatabaseOpenssl *self,
+                                             GTlsCertificate     *chain,
+                                             OCSP_RESPONSE       *resp)
 {
+  GTlsCertificateFlags errors = 0;
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+  !defined(OPENSSL_NO_OCSP)
+  GTlsDatabaseOpensslPrivate *priv;
+  STACK_OF(X509) *chain_openssl = NULL;
+  OCSP_BASICRESP *basic_resp = NULL;
+  int ocsp_status = 0;
+  int i;
+
+  ocsp_status = OCSP_response_status (resp);
+  if (ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL)
+    {
+      errors = G_TLS_CERTIFICATE_GENERIC_ERROR;
+      goto end;
+    }
+
+  basic_resp = OCSP_response_get1_basic (resp);
+  if (basic_resp == NULL)
+    {
+      errors = G_TLS_CERTIFICATE_GENERIC_ERROR;
+      goto end;
+    }
+
+  chain_openssl = convert_certificate_chain_to_openssl (G_TLS_CERTIFICATE_OPENSSL (chain));
+  priv = g_tls_database_openssl_get_instance_private (self);
+  if ((chain_openssl == NULL) ||
+      (priv->store == NULL))
+    {
+      errors = G_TLS_CERTIFICATE_GENERIC_ERROR;
+      goto end;
+    }
+
+  if (OCSP_basic_verify (basic_resp, chain_openssl, priv->store, 0) <= 0)
+    {
+      errors = G_TLS_CERTIFICATE_GENERIC_ERROR;
+      goto end;
+    }
+
+  for (i = 0; i < OCSP_resp_count (basic_resp); i++)
+    {
+      OCSP_SINGLERESP *single_resp = OCSP_resp_get0 (basic_resp, i);
+      ASN1_GENERALIZEDTIME *revocation_time = NULL;
+      ASN1_GENERALIZEDTIME *this_update_time = NULL;
+      ASN1_GENERALIZEDTIME *next_update_time = NULL;
+      int crl_reason = 0;
+      int cert_status = 0;
+
+      if (single_resp == NULL)
+        continue;
+
+      cert_status = OCSP_single_get0_status (single_resp,
+                                             &crl_reason,
+                                             &revocation_time,
+                                             &this_update_time,
+                                             &next_update_time);
+      if (!OCSP_check_validity (this_update_time,
+                                next_update_time,
+                                300L,
+                                -1L))
+        {
+          errors = G_TLS_CERTIFICATE_GENERIC_ERROR;
+          goto end;
+        }
+
+      switch (cert_status)
+        {
+        case V_OCSP_CERTSTATUS_GOOD:
+          break;
+        case V_OCSP_CERTSTATUS_REVOKED:
+          errors = G_TLS_CERTIFICATE_REVOKED;
+          goto end;
+        case V_OCSP_CERTSTATUS_UNKNOWN:
+          errors = G_TLS_CERTIFICATE_GENERIC_ERROR;
+          goto end;
+        }
+    }
+
+end:
+  if (basic_resp != NULL)
+    OCSP_BASICRESP_free (basic_resp);
+
+  if (resp != NULL)
+    OCSP_RESPONSE_free (resp);
+
+#endif
+  return errors;
 }
diff --git a/tls/openssl/gtlsdatabase-openssl.h b/tls/openssl/gtlsdatabase-openssl.h
index fd31352..b22b0b2 100644
--- a/tls/openssl/gtlsdatabase-openssl.h
+++ b/tls/openssl/gtlsdatabase-openssl.h
@@ -31,32 +31,26 @@
 
 G_BEGIN_DECLS
 
-typedef enum {
-  G_TLS_DATABASE_OPENSSL_PINNED_CERTIFICATE = 1,
-  G_TLS_DATABASE_OPENSSL_ANCHORED_CERTIFICATE = 2,
-} GTlsDatabaseOpensslAssertion;
-
 #define G_TYPE_TLS_DATABASE_OPENSSL            (g_tls_database_openssl_get_type ())
-#define G_TLS_DATABASE_OPENSSL(inst)           (G_TYPE_CHECK_INSTANCE_CAST ((inst), 
G_TYPE_TLS_DATABASE_OPENSSL, GTlsDatabaseOpenssl))
-#define G_TLS_DATABASE_OPENSSL_CLASS(class)    (G_TYPE_CHECK_CLASS_CAST ((class), 
G_TYPE_TLS_DATABASE_OPENSSL, GTlsDatabaseOpensslClass))
-#define G_IS_TLS_DATABASE_OPENSSL(inst)        (G_TYPE_CHECK_INSTANCE_TYPE ((inst), 
G_TYPE_TLS_DATABASE_OPENSSL))
-#define G_IS_TLS_DATABASE_OPENSSL_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), 
G_TYPE_TLS_DATABASE_OPENSSL))
-#define G_TLS_DATABASE_OPENSSL_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), 
G_TYPE_TLS_DATABASE_OPENSSL, GTlsDatabaseOpensslClass))
 
-typedef struct _GTlsDatabaseOpensslClass GTlsDatabaseOpensslClass;
-typedef struct _GTlsDatabaseOpenssl      GTlsDatabaseOpenssl;
+G_DECLARE_DERIVABLE_TYPE (GTlsDatabaseOpenssl, g_tls_database_openssl, G, TLS_DATABASE_OPENSSL, GTlsDatabase)
 
 struct _GTlsDatabaseOpensslClass
 {
   GTlsDatabaseClass parent_class;
-};
 
-struct _GTlsDatabaseOpenssl
-{
-  GTlsDatabase parent_instance;
+  gchar    *(*create_handle_for_certificate)  (GTlsDatabaseOpenssl       *self,
+                                               GBytes                    *der);
+  gboolean  (*populate_trust_list)            (GTlsDatabaseOpenssl       *self,
+                                               X509_STORE                *store,
+                                               GError                   **error);
 };
 
-GType          g_tls_database_openssl_get_type              (void) G_GNUC_CONST;
+GTlsDatabaseOpenssl      *g_tls_database_openssl_new                      (GError **error);
+
+GTlsCertificateFlags      g_tls_database_openssl_verify_ocsp_response     (GTlsDatabaseOpenssl *self,
+                                                                           GTlsCertificate     *chain,
+                                                                           OCSP_RESPONSE       *resp);
 
 G_END_DECLS
 
diff --git a/tls/openssl/gtlsfiledatabase-openssl.c b/tls/openssl/gtlsfiledatabase-openssl.c
index e45a619..dd18c52 100644
--- a/tls/openssl/gtlsfiledatabase-openssl.c
+++ b/tls/openssl/gtlsfiledatabase-openssl.c
@@ -30,41 +30,12 @@
 #include <glib/gi18n-lib.h>
 #include "openssl-include.h"
 
-typedef struct _GTlsFileDatabaseOpensslPrivate
+struct _GTlsFileDatabaseOpenssl
 {
+  GTlsDatabaseOpenssl parent_instance;
+
   /* read-only after construct */
   gchar *anchor_filename;
-  STACK_OF(X509) *trusted;
-
-  /* protected by mutex */
-  GMutex mutex;
-
-  /*
-   * These are hash tables of gulong -> GPtrArray<GBytes>. The values of
-   * the ptr array are full DER encoded certificate values. The keys are byte
-   * arrays containing either subject DNs, issuer DNs, or full DER encoded certs
-   */
-  GHashTable *subjects;
-  GHashTable *issuers;
-
-  /*
-   * This is a table of GBytes -> GBytes. The values and keys are
-   * DER encoded certificate values.
-   */
-  GHashTable *complete;
-
-  /*
-   * This is a table of gchar * -> GTlsCertificate.
-   */
-  GHashTable *certs_by_handle;
-} GTlsFileDatabaseOpensslPrivate;
-
-enum {
-  STATUS_FAILURE,
-  STATUS_INCOMPLETE,
-  STATUS_SELFSIGNED,
-  STATUS_PINNED,
-  STATUS_ANCHORED,
 };
 
 enum
@@ -75,177 +46,16 @@ enum
 
 static void g_tls_file_database_openssl_file_database_interface_init (GTlsFileDatabaseInterface *iface);
 
-static void g_tls_file_database_openssl_initable_interface_init (GInitableIface *iface);
-
 G_DEFINE_TYPE_WITH_CODE (GTlsFileDatabaseOpenssl, g_tls_file_database_openssl, G_TYPE_TLS_DATABASE_OPENSSL,
-                         G_ADD_PRIVATE (GTlsFileDatabaseOpenssl)
                          G_IMPLEMENT_INTERFACE (G_TYPE_TLS_FILE_DATABASE,
-                                                g_tls_file_database_openssl_file_database_interface_init)
-                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
-                                                g_tls_file_database_openssl_initable_interface_init))
-
-static GHashTable *
-bytes_multi_table_new (void)
-{
-  return g_hash_table_new_full (g_int_hash, g_int_equal,
-                                (GDestroyNotify)g_free,
-                                (GDestroyNotify)g_ptr_array_unref);
-}
-
-static void
-bytes_multi_table_insert (GHashTable *table,
-                          gulong      key,
-                          GBytes     *value)
-{
-  GPtrArray *multi;
-
-  multi = g_hash_table_lookup (table, &key);
-  if (multi == NULL)
-    {
-      int *key_ptr;
-
-      key_ptr = g_new (int, 1);
-      *key_ptr = (int)key;
-      multi = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref);
-      g_hash_table_insert (table, key_ptr, multi);
-    }
-  g_ptr_array_add (multi, g_bytes_ref (value));
-}
-
-static GBytes *
-bytes_multi_table_lookup_ref_one (GHashTable *table,
-                                  gulong      key)
-{
-  GPtrArray *multi;
-
-  multi = g_hash_table_lookup (table, &key);
-  if (multi == NULL)
-    return NULL;
-
-  g_assert (multi->len > 0);
-  return g_bytes_ref (multi->pdata[0]);
-}
-
-static GList *
-bytes_multi_table_lookup_ref_all (GHashTable *table,
-                                  gulong      key)
-{
-  GPtrArray *multi;
-  GList *list = NULL;
-  guint i;
-
-  multi = g_hash_table_lookup (table, &key);
-  if (multi == NULL)
-    return NULL;
-
-  for (i = 0; i < multi->len; i++)
-    list = g_list_prepend (list, g_bytes_ref (multi->pdata[i]));
-
-  return g_list_reverse (list);
-}
-
-static gchar *
-create_handle_for_certificate (const gchar *filename,
-                               GBytes      *der)
-{
-  gchar *bookmark;
-  gchar *uri_part;
-  gchar *uri;
-
-  /*
-   * Here we create a URI that looks like:
-   * 
file:///etc/ssl/certs/ca-certificates.crt#11b2641821252596420e468c275771f5e51022c121a17bd7a89a2f37b6336c8f
-   */
-
-  uri_part = g_filename_to_uri (filename, NULL, NULL);
-  if (!uri_part)
-    return NULL;
-
-  bookmark = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, der);
-  uri = g_strconcat (uri_part, "#", bookmark, NULL);
-
-  g_free (bookmark);
-  g_free (uri_part);
-
-  return uri;
-}
-
-static gboolean
-load_anchor_file (GTlsFileDatabaseOpenssl  *file_database,
-                  const gchar              *filename,
-                  GHashTable               *subjects,
-                  GHashTable               *issuers,
-                  GHashTable               *complete,
-                  GHashTable               *certs_by_handle,
-                  GError                  **error)
-{
-  GTlsFileDatabaseOpensslPrivate *priv;
-  GList *list;
-  GList *l;
-  GBytes *der;
-  gchar *handle;
-  GError *my_error = NULL;
-
-  priv = g_tls_file_database_openssl_get_instance_private (file_database);
-
-  list = g_tls_certificate_list_new_from_file (filename, &my_error);
-  if (my_error)
-    {
-      g_propagate_error (error, my_error);
-      return FALSE;
-    }
-
-  for (l = list; l; l = l->next)
-    {
-      X509 *x;
-      unsigned long subject;
-      unsigned long issuer;
-
-      x = g_tls_certificate_openssl_get_cert (l->data);
-      subject = X509_subject_name_hash (x);
-      issuer = X509_issuer_name_hash (x);
-
-      der = g_tls_certificate_openssl_get_bytes (l->data);
-      g_return_val_if_fail (der != NULL, FALSE);
-
-      g_hash_table_insert (complete, g_bytes_ref (der),
-                           g_bytes_ref (der));
-
-      bytes_multi_table_insert (subjects, subject, der);
-      bytes_multi_table_insert (issuers, issuer, der);
-
-      handle = create_handle_for_certificate (priv->anchor_filename, der);
-      g_hash_table_insert (certs_by_handle, handle, g_object_ref (l->data));
-
-      g_bytes_unref (der);
-
-      g_object_unref (l->data);
-    }
-  g_list_free (list);
-
-  return TRUE;
-}
+                                                g_tls_file_database_openssl_file_database_interface_init))
 
 static void
 g_tls_file_database_openssl_finalize (GObject *object)
 {
-  GTlsFileDatabaseOpenssl *file_database = G_TLS_FILE_DATABASE_OPENSSL (object);
-  GTlsFileDatabaseOpensslPrivate *priv;
-
-  priv = g_tls_file_database_openssl_get_instance_private (file_database);
-
-  g_clear_pointer (&priv->subjects, g_hash_table_destroy);
-  g_clear_pointer (&priv->issuers, g_hash_table_destroy);
-  g_clear_pointer (&priv->complete, g_hash_table_destroy);
-  g_clear_pointer (&priv->certs_by_handle, g_hash_table_destroy);
-
-  g_free (priv->anchor_filename);
-  priv->anchor_filename = NULL;
+  GTlsFileDatabaseOpenssl *self = G_TLS_FILE_DATABASE_OPENSSL (object);
 
-  if (priv->trusted != NULL)
-    sk_X509_pop_free (priv->trusted, X509_free);
-
-  g_mutex_clear (&priv->mutex);
+  g_free (self->anchor_filename);
 
   G_OBJECT_CLASS (g_tls_file_database_openssl_parent_class)->finalize (object);
 }
@@ -256,81 +66,27 @@ g_tls_file_database_openssl_get_property (GObject    *object,
                                           GValue     *value,
                                           GParamSpec *pspec)
 {
-  GTlsFileDatabaseOpenssl *file_database = G_TLS_FILE_DATABASE_OPENSSL (object);
-  GTlsFileDatabaseOpensslPrivate *priv;
-
-  priv = g_tls_file_database_openssl_get_instance_private (file_database);
+  GTlsFileDatabaseOpenssl *self = G_TLS_FILE_DATABASE_OPENSSL (object);
 
   switch (prop_id)
     {
     case PROP_ANCHORS:
-      g_value_set_string (value, priv->anchor_filename);
+      g_value_set_string (value, self->anchor_filename);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
 }
 
-static STACK_OF(X509) *
-load_certs (const gchar *file_name)
-{
-  BIO *bio;
-  STACK_OF(X509) *certs;
-  STACK_OF(X509_INFO) *xis = NULL;
-  gint i;
-
-  if (file_name == NULL)
-    return NULL;
-
-  bio = BIO_new_file (file_name, "rb");
-  if (bio == NULL)
-    return NULL;
-
-  xis = PEM_X509_INFO_read_bio (bio, NULL, NULL, NULL);
-
-  BIO_free (bio);
-
-  certs = sk_X509_new_null ();
-  if (certs == NULL)
-    goto end;
-
-  for (i = 0; i < sk_X509_INFO_num (xis); i++)
-    {
-      X509_INFO *xi;
-
-      xi = sk_X509_INFO_value (xis, i);
-      if (xi->x509 != NULL)
-        {
-          if (!sk_X509_push (certs, xi->x509))
-            goto end;
-          xi->x509 = NULL;
-        }
-    }
-
-end:
-  sk_X509_INFO_pop_free (xis, X509_INFO_free);
-
-  if (sk_X509_num (certs) == 0)
-    {
-      sk_X509_pop_free (certs, X509_free);
-      certs = NULL;
-    }
-
-  return certs;
-}
-
 static void
 g_tls_file_database_openssl_set_property (GObject      *object,
                                           guint         prop_id,
                                           const GValue *value,
                                           GParamSpec   *pspec)
 {
-  GTlsFileDatabaseOpenssl *file_database = G_TLS_FILE_DATABASE_OPENSSL (object);
-  GTlsFileDatabaseOpensslPrivate *priv;
+  GTlsFileDatabaseOpenssl *self = G_TLS_FILE_DATABASE_OPENSSL (object);
   const gchar *anchor_path;
 
-  priv = g_tls_file_database_openssl_get_instance_private (file_database);
-
   switch (prop_id)
     {
     case PROP_ANCHORS:
@@ -342,317 +98,75 @@ g_tls_file_database_openssl_set_property (GObject      *object,
           return;
         }
 
-      if (priv->anchor_filename)
-        {
-          g_free (priv->anchor_filename);
-          if (priv->trusted != NULL)
-            sk_X509_pop_free (priv->trusted, X509_free);
-        }
-
-      priv->anchor_filename = g_strdup (anchor_path);
-      priv->trusted = load_certs (anchor_path);
+      g_free (self->anchor_filename);
+      self->anchor_filename = g_strdup (anchor_path);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
 }
 
-static void
-g_tls_file_database_openssl_init (GTlsFileDatabaseOpenssl *file_database)
-{
-  GTlsFileDatabaseOpensslPrivate *priv;
-
-  priv = g_tls_file_database_openssl_get_instance_private (file_database);
-
-  g_mutex_init (&priv->mutex);
-}
-
 static gchar *
-g_tls_file_database_openssl_create_certificate_handle (GTlsDatabase    *database,
-                                                       GTlsCertificate *certificate)
-{
-  GTlsFileDatabaseOpenssl *file_database = G_TLS_FILE_DATABASE_OPENSSL (database);
-  GTlsFileDatabaseOpensslPrivate *priv;
-  GBytes *der;
-  gboolean contains;
-  gchar *handle = NULL;
-
-  priv = g_tls_file_database_openssl_get_instance_private (file_database);
-
-  der = g_tls_certificate_openssl_get_bytes (G_TLS_CERTIFICATE_OPENSSL (certificate));
-  g_return_val_if_fail (der != NULL, FALSE);
-
-  g_mutex_lock (&priv->mutex);
-
-  /* At the same time look up whether this certificate is in list */
-  contains = g_hash_table_lookup (priv->complete, der) ? TRUE : FALSE;
-
-  g_mutex_unlock (&priv->mutex);
-
-  /* Certificate is in the database */
-  if (contains)
-    handle = create_handle_for_certificate (priv->anchor_filename, der);
-
-  g_bytes_unref (der);
-  return handle;
-}
-
-static GTlsCertificate *
-g_tls_file_database_openssl_lookup_certificate_for_handle (GTlsDatabase            *database,
-                                                           const gchar             *handle,
-                                                           GTlsInteraction         *interaction,
-                                                           GTlsDatabaseLookupFlags  flags,
-                                                           GCancellable            *cancellable,
-                                                           GError                 **error)
-{
-  GTlsFileDatabaseOpenssl *file_database = G_TLS_FILE_DATABASE_OPENSSL (database);
-  GTlsFileDatabaseOpensslPrivate *priv;
-  GTlsCertificate *cert;
-
-  priv = g_tls_file_database_openssl_get_instance_private (file_database);
-
-  if (g_cancellable_set_error_if_cancelled (cancellable, error))
-    return NULL;
-
-  if (!handle)
-    return NULL;
-
-  g_mutex_lock (&priv->mutex);
-
-  cert = g_hash_table_lookup (priv->certs_by_handle, handle);
-
-  g_mutex_unlock (&priv->mutex);
-
-  return cert ? g_object_ref (cert) : NULL;
-}
-
-static GTlsCertificate *
-g_tls_file_database_openssl_lookup_certificate_issuer (GTlsDatabase             *database,
-                                                       GTlsCertificate          *certificate,
-                                                       GTlsInteraction          *interaction,
-                                                       GTlsDatabaseLookupFlags   flags,
-                                                       GCancellable             *cancellable,
-                                                       GError                  **error)
+g_tls_file_database_openssl_create_handle_for_certificate (GTlsDatabaseOpenssl *self,
+                                                           GBytes              *der)
 {
-  GTlsFileDatabaseOpenssl *file_database = G_TLS_FILE_DATABASE_OPENSSL (database);
-  GTlsFileDatabaseOpensslPrivate *priv;
-  X509 *x;
-  unsigned long issuer_hash;
-  GBytes *der;
-  GTlsCertificate *issuer = NULL;
-
-  priv = g_tls_file_database_openssl_get_instance_private (file_database);
-
-  g_return_val_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (certificate), NULL);
-
-  if (g_cancellable_set_error_if_cancelled (cancellable, error))
-    return NULL;
-
-  if (flags & G_TLS_DATABASE_LOOKUP_KEYPAIR)
-    return NULL;
-
-  /* Dig out the issuer of this certificate */
-  x = g_tls_certificate_openssl_get_cert (G_TLS_CERTIFICATE_OPENSSL (certificate));
-  issuer_hash = X509_issuer_name_hash (x);
-
-  g_mutex_lock (&priv->mutex);
-  der = bytes_multi_table_lookup_ref_one (priv->subjects, issuer_hash);
-  g_mutex_unlock (&priv->mutex);
-
-  if (g_cancellable_set_error_if_cancelled (cancellable, error))
-    issuer = NULL;
-  else if (der != NULL)
-    issuer = g_tls_certificate_openssl_new (der, NULL);
-
-  if (der != NULL)
-    g_bytes_unref (der);
-  return issuer;
-
-  return NULL;
-}
-
-static GList *
-g_tls_file_database_openssl_lookup_certificates_issued_by (GTlsDatabase             *database,
-                                                           GByteArray               *issuer_raw_dn,
-                                                           GTlsInteraction          *interaction,
-                                                           GTlsDatabaseLookupFlags   flags,
-                                                           GCancellable             *cancellable,
-                                                           GError                  **error)
-{
-  GTlsFileDatabaseOpenssl *file_database = G_TLS_FILE_DATABASE_OPENSSL (database);
-  GTlsFileDatabaseOpensslPrivate *priv;
-  X509_NAME *x_name;
-  const unsigned char *in;
-  GList *issued = NULL;
-
-  priv = g_tls_file_database_openssl_get_instance_private (file_database);
+  gchar *bookmark;
+  gchar *uri_part;
+  gchar *uri;
 
-  if (g_cancellable_set_error_if_cancelled (cancellable, error))
-    return NULL;
+  /*
+   * Here we create a URI that looks like:
+   * 
file:///etc/ssl/certs/ca-certificates.crt#11b2641821252596420e468c275771f5e51022c121a17bd7a89a2f37b6336c8f
+   */
 
-  /* We don't have any private keys here */
-  if (flags & G_TLS_DATABASE_LOOKUP_KEYPAIR)
+  uri_part = g_filename_to_uri (G_TLS_FILE_DATABASE_OPENSSL (self)->anchor_filename,
+                                NULL, NULL);
+  if (!uri_part)
     return NULL;
 
-  in = issuer_raw_dn->data;
-  x_name = d2i_X509_NAME (NULL, &in, issuer_raw_dn->len);
-  if (x_name != NULL)
-    {
-      unsigned long issuer_hash;
-      GList *ders, *l;
-
-      issuer_hash = X509_NAME_hash (x_name);
-
-      /* Find the full DER value of the certificate */
-      g_mutex_lock (&priv->mutex);
-      ders = bytes_multi_table_lookup_ref_all (priv->issuers, issuer_hash);
-      g_mutex_unlock (&priv->mutex);
-
-      for (l = ders; l != NULL; l = g_list_next (l))
-        {
-          if (g_cancellable_set_error_if_cancelled (cancellable, error))
-            {
-              g_list_free_full (issued, g_object_unref);
-              issued = NULL;
-              break;
-            }
-
-          issued = g_list_prepend (issued, g_tls_certificate_openssl_new (l->data, NULL));
-        }
+  bookmark = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, der);
+  uri = g_strconcat (uri_part, "#", bookmark, NULL);
 
-      g_list_free_full (ders, (GDestroyNotify)g_bytes_unref);
-      X509_NAME_free (x_name);
-    }
+  g_free (bookmark);
+  g_free (uri_part);
 
-  return issued;
+  return uri;
 }
 
-static GTlsCertificateFlags
-double_check_before_after_dates (GTlsCertificateOpenssl *chain)
+static gboolean
+g_tls_file_database_openssl_populate_trust_list (GTlsDatabaseOpenssl  *database,
+                                                 X509_STORE           *store,
+                                                 GError              **error)
 {
-  GTlsCertificateFlags gtls_flags = 0;
-  X509 *cert;
+  GTlsFileDatabaseOpenssl *self = G_TLS_FILE_DATABASE_OPENSSL (database);
+  X509_LOOKUP *lookup;
 
-  while (chain)
+  lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file ());
+  if (lookup == NULL)
     {
-      ASN1_TIME *not_before;
-      ASN1_TIME *not_after;
-
-      cert = g_tls_certificate_openssl_get_cert (chain);
-      not_before = X509_get_notBefore (cert);
-      not_after = X509_get_notAfter (cert);
-
-      if (X509_cmp_current_time (not_before) > 0)
-        gtls_flags |= G_TLS_CERTIFICATE_NOT_ACTIVATED;
-
-      if (X509_cmp_current_time (not_after) < 0)
-        gtls_flags |= G_TLS_CERTIFICATE_EXPIRED;
-
-      chain = G_TLS_CERTIFICATE_OPENSSL (g_tls_certificate_get_issuer
-                                         (G_TLS_CERTIFICATE (chain)));
-    }
-
-  return gtls_flags;
-}
-
-static STACK_OF(X509) *
-convert_certificate_chain_to_openssl (GTlsCertificateOpenssl *chain)
-{
-  GTlsCertificate *cert;
-  STACK_OF(X509) *openssl_chain;
-
-  openssl_chain = sk_X509_new_null ();
-
-  for (cert = G_TLS_CERTIFICATE (chain); cert; cert = g_tls_certificate_get_issuer (cert))
-    sk_X509_push (openssl_chain, g_tls_certificate_openssl_get_cert (G_TLS_CERTIFICATE_OPENSSL (cert)));
-
-  return openssl_chain;
-}
-
-static GTlsCertificateFlags
-g_tls_file_database_openssl_verify_chain (GTlsDatabase             *database,
-                                          GTlsCertificate          *chain,
-                                          const gchar              *purpose,
-                                          GSocketConnectable       *identity,
-                                          GTlsInteraction          *interaction,
-                                          GTlsDatabaseVerifyFlags   flags,
-                                          GCancellable             *cancellable,
-                                          GError                  **error)
-{
-  GTlsFileDatabaseOpenssl *file_database;
-  GTlsFileDatabaseOpensslPrivate *priv;
-  STACK_OF(X509) *certs;
-  X509_STORE *store;
-  X509_STORE_CTX *csc;
-  X509 *x;
-  GTlsCertificateFlags result = 0;
-
-  g_return_val_if_fail (G_IS_TLS_CERTIFICATE_OPENSSL (chain),
-                        G_TLS_CERTIFICATE_GENERIC_ERROR);
-
-  file_database = G_TLS_FILE_DATABASE_OPENSSL (database);
-
-  priv = g_tls_file_database_openssl_get_instance_private (file_database);
-
-  if (g_cancellable_set_error_if_cancelled (cancellable, error))
-    return G_TLS_CERTIFICATE_GENERIC_ERROR;
-
-  certs = convert_certificate_chain_to_openssl (G_TLS_CERTIFICATE_OPENSSL (chain));
-
-  store = X509_STORE_new ();
-  csc = X509_STORE_CTX_new ();
-
-  x = g_tls_certificate_openssl_get_cert (G_TLS_CERTIFICATE_OPENSSL (chain));
-  if (!X509_STORE_CTX_init (csc, store, x, certs))
-    {
-      X509_STORE_CTX_free (csc);
-      X509_STORE_free (store);
-      sk_X509_free (certs);
-      return G_TLS_CERTIFICATE_GENERIC_ERROR;
-    }
-
-  if (priv->trusted)
-    {
-      X509_STORE_CTX_trusted_stack (csc, priv->trusted);
+      g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
+                   _("Failed to load system trust store file: %s"),
+                   ERR_error_string (ERR_get_error (), NULL));
+      return FALSE;
     }
 
-  if (X509_verify_cert (csc) <= 0)
-    result = g_tls_certificate_openssl_convert_error (X509_STORE_CTX_get_error (csc));
-
-  X509_STORE_CTX_free (csc);
-  X509_STORE_free (store);
-  sk_X509_free (certs);
+  X509_LOOKUP_load_file (lookup, self->anchor_filename, X509_FILETYPE_PEM);
 
-  if (g_cancellable_set_error_if_cancelled (cancellable, error))
-    return G_TLS_CERTIFICATE_GENERIC_ERROR;
-
-  /* We have to check these ourselves since openssl
-   * does not give us flags and UNKNOWN_CA will take priority.
-   */
-  result |= double_check_before_after_dates (G_TLS_CERTIFICATE_OPENSSL (chain));
-
-  if (identity)
-    result |= g_tls_certificate_openssl_verify_identity (G_TLS_CERTIFICATE_OPENSSL (chain),
-                                                         identity);
-
-  return result;
+  return TRUE;
 }
 
 static void
 g_tls_file_database_openssl_class_init (GTlsFileDatabaseOpensslClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-  GTlsDatabaseClass *database_class = G_TLS_DATABASE_CLASS (klass);
+  GTlsDatabaseOpensslClass *openssl_database_class = G_TLS_DATABASE_OPENSSL_CLASS (klass);
 
   gobject_class->get_property = g_tls_file_database_openssl_get_property;
   gobject_class->set_property = g_tls_file_database_openssl_set_property;
   gobject_class->finalize     = g_tls_file_database_openssl_finalize;
 
-  database_class->create_certificate_handle = g_tls_file_database_openssl_create_certificate_handle;
-  database_class->lookup_certificate_for_handle = g_tls_file_database_openssl_lookup_certificate_for_handle;
-  database_class->lookup_certificate_issuer = g_tls_file_database_openssl_lookup_certificate_issuer;
-  database_class->lookup_certificates_issued_by = g_tls_file_database_openssl_lookup_certificates_issued_by;
-  database_class->verify_chain = g_tls_file_database_openssl_verify_chain;
+  openssl_database_class->create_handle_for_certificate = 
g_tls_file_database_openssl_create_handle_for_certificate;
+  openssl_database_class->populate_trust_list           = g_tls_file_database_openssl_populate_trust_list;
 
   g_object_class_override_property (gobject_class, PROP_ANCHORS, "anchors");
 }
@@ -662,191 +176,7 @@ g_tls_file_database_openssl_file_database_interface_init (GTlsFileDatabaseInterf
 {
 }
 
-static gboolean
-g_tls_file_database_openssl_initable_init (GInitable    *initable,
-                                           GCancellable *cancellable,
-                                           GError      **error)
-{
-  GTlsFileDatabaseOpenssl *file_database = G_TLS_FILE_DATABASE_OPENSSL (initable);
-  GTlsFileDatabaseOpensslPrivate *priv;
-  GHashTable *subjects, *issuers, *complete, *certs_by_handle;
-  gboolean result;
-
-  priv = g_tls_file_database_openssl_get_instance_private (file_database);
-
-  if (g_cancellable_set_error_if_cancelled (cancellable, error))
-    return FALSE;
-
-  subjects = bytes_multi_table_new ();
-  issuers = bytes_multi_table_new ();
-
-  complete = g_hash_table_new_full (g_bytes_hash, g_bytes_equal,
-                                    (GDestroyNotify)g_bytes_unref,
-                                    (GDestroyNotify)g_bytes_unref);
-
-  certs_by_handle = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                           (GDestroyNotify)g_free,
-                                           (GDestroyNotify)g_object_unref);
-
-  if (priv->anchor_filename)
-    result = load_anchor_file (file_database,
-                               priv->anchor_filename,
-                               subjects, issuers, complete,
-                               certs_by_handle,
-                               error);
-  else
-    result = TRUE;
-
-  if (g_cancellable_set_error_if_cancelled (cancellable, error))
-    result = FALSE;
-
-  if (result)
-    {
-      g_mutex_lock (&priv->mutex);
-      if (!priv->subjects)
-        {
-          priv->subjects = subjects;
-          subjects = NULL;
-        }
-      if (!priv->issuers)
-        {
-          priv->issuers = issuers;
-          issuers = NULL;
-        }
-      if (!priv->complete)
-        {
-          priv->complete = complete;
-          complete = NULL;
-        }
-      if (!priv->certs_by_handle)
-        {
-          priv->certs_by_handle = certs_by_handle;
-          certs_by_handle = NULL;
-        }
-      g_mutex_unlock (&priv->mutex);
-    }
-
-  if (subjects != NULL)
-    g_hash_table_unref (subjects);
-  if (issuers != NULL)
-    g_hash_table_unref (issuers);
-  if (complete != NULL)
-    g_hash_table_unref (complete);
-  if (certs_by_handle != NULL)
-    g_hash_table_unref (certs_by_handle);
-  return result;
-}
-
 static void
-g_tls_file_database_openssl_initable_interface_init (GInitableIface *iface)
-{
-  iface->init = g_tls_file_database_openssl_initable_init;
-}
-
-GTlsCertificateFlags
-g_tls_file_database_openssl_verify_ocsp_response (GTlsDatabase    *database,
-                                                  GTlsCertificate *chain,
-                                                  OCSP_RESPONSE   *resp)
+g_tls_file_database_openssl_init (GTlsFileDatabaseOpenssl *file_database)
 {
-  GTlsCertificateFlags errors = 0;
-#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
-  !defined(OPENSSL_NO_OCSP)
-  GTlsFileDatabaseOpenssl *file_database;
-  GTlsFileDatabaseOpensslPrivate *priv;
-  STACK_OF(X509) *chain_openssl = NULL;
-  X509_STORE *store = NULL;
-  OCSP_BASICRESP *basic_resp = NULL;
-  int ocsp_status = 0;
-  int i;
-
-  ocsp_status = OCSP_response_status (resp);
-  if (ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL)
-    {
-      errors = G_TLS_CERTIFICATE_GENERIC_ERROR;
-      goto end;
-    }
-
-  basic_resp = OCSP_response_get1_basic (resp);
-  if (basic_resp == NULL)
-    {
-      errors = G_TLS_CERTIFICATE_GENERIC_ERROR;
-      goto end;
-    }
-
-  chain_openssl = convert_certificate_chain_to_openssl (G_TLS_CERTIFICATE_OPENSSL (chain));
-  file_database = G_TLS_FILE_DATABASE_OPENSSL (database);
-  priv = g_tls_file_database_openssl_get_instance_private (file_database);
-  store = X509_STORE_new ();
-  if ((chain_openssl == NULL) ||
-      (file_database == NULL) ||
-      (priv == NULL) ||
-      (priv->trusted == NULL) ||
-      (store == NULL))
-    {
-      errors = G_TLS_CERTIFICATE_GENERIC_ERROR;
-      goto end;
-    }
-
-  for (i = 0; i < sk_X509_num (priv->trusted); i++)
-    {
-      X509_STORE_add_cert (store, sk_X509_value (priv->trusted, i));
-    }
-
-  if (OCSP_basic_verify (basic_resp, chain_openssl, store, 0) <= 0)
-    {
-      errors = G_TLS_CERTIFICATE_GENERIC_ERROR;
-      goto end;
-    }
-
-  for (i = 0; i < OCSP_resp_count (basic_resp); i++)
-    {
-      OCSP_SINGLERESP *single_resp = OCSP_resp_get0 (basic_resp, i);
-      ASN1_GENERALIZEDTIME *revocation_time = NULL;
-      ASN1_GENERALIZEDTIME *this_update_time = NULL;
-      ASN1_GENERALIZEDTIME *next_update_time = NULL;
-      int crl_reason = 0;
-      int cert_status = 0;
-
-      if (single_resp == NULL)
-        continue;
-
-      cert_status = OCSP_single_get0_status (single_resp,
-                                             &crl_reason,
-                                             &revocation_time,
-                                             &this_update_time,
-                                             &next_update_time);
-      if (!OCSP_check_validity (this_update_time,
-                                next_update_time,
-                                300L,
-                                -1L))
-        {
-          errors = G_TLS_CERTIFICATE_GENERIC_ERROR;
-          goto end;
-        }
-
-      switch (cert_status)
-        {
-        case V_OCSP_CERTSTATUS_GOOD:
-          break;
-        case V_OCSP_CERTSTATUS_REVOKED:
-          errors = G_TLS_CERTIFICATE_REVOKED;
-          goto end;
-        case V_OCSP_CERTSTATUS_UNKNOWN:
-          errors = G_TLS_CERTIFICATE_GENERIC_ERROR;
-          goto end;
-        }
-    }
-
-end:
-  if (store != NULL)
-    X509_STORE_free (store);
-
-  if (basic_resp != NULL)
-    OCSP_BASICRESP_free (basic_resp);
-
-  if (resp != NULL)
-    OCSP_RESPONSE_free (resp);
-
-#endif
-  return errors;
 }
diff --git a/tls/openssl/gtlsfiledatabase-openssl.h b/tls/openssl/gtlsfiledatabase-openssl.h
index 67086db..9efd769 100644
--- a/tls/openssl/gtlsfiledatabase-openssl.h
+++ b/tls/openssl/gtlsfiledatabase-openssl.h
@@ -32,30 +32,10 @@
 G_BEGIN_DECLS
 
 #define G_TYPE_TLS_FILE_DATABASE_OPENSSL            (g_tls_file_database_openssl_get_type ())
-#define G_TLS_FILE_DATABASE_OPENSSL(inst)           (G_TYPE_CHECK_INSTANCE_CAST ((inst), 
G_TYPE_TLS_FILE_DATABASE_OPENSSL, GTlsFileDatabaseOpenssl))
-#define G_TLS_FILE_DATABASE_OPENSSL_CLASS(class)    (G_TYPE_CHECK_CLASS_CAST ((class), 
G_TYPE_TLS_FILE_DATABASE_OPENSSL, GTlsFileDatabaseOpensslClass))
-#define G_IS_TLS_FILE_DATABASE_OPENSSL(inst)        (G_TYPE_CHECK_INSTANCE_TYPE ((inst), 
G_TYPE_TLS_FILE_DATABASE_OPENSSL))
-#define G_IS_TLS_FILE_DATABASE_OPENSSL_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), 
G_TYPE_TLS_FILE_DATABASE_OPENSSL))
-#define G_TLS_FILE_DATABASE_OPENSSL_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), 
G_TYPE_TLS_FILE_DATABASE_OPENSSL, GTlsFileDatabaseOpensslClass))
-
-typedef struct _GTlsFileDatabaseOpensslClass GTlsFileDatabaseOpensslClass;
-typedef struct _GTlsFileDatabaseOpenssl      GTlsFileDatabaseOpenssl;
-
-struct _GTlsFileDatabaseOpensslClass
-{
-  GTlsDatabaseOpensslClass parent_class;
-};
-
-struct _GTlsFileDatabaseOpenssl
-{
-  GTlsDatabaseOpenssl parent_instance;
-};
-
-GType                        g_tls_file_database_openssl_get_type              (void) G_GNUC_CONST;
-
-GTlsCertificateFlags         g_tls_file_database_openssl_verify_ocsp_response  (GTlsDatabase    *database,
-                                                                                GTlsCertificate *chain,
-                                                                                OCSP_RESPONSE   *resp);
+
+G_DECLARE_FINAL_TYPE (GTlsFileDatabaseOpenssl, g_tls_file_database_openssl, G, TLS_FILE_DATABASE_OPENSSL, 
GTlsDatabaseOpenssl)
+
+GTlsDatabase                *g_tls_file_database_openssl_new                   (const gchar *anchor_file);
 
 G_END_DECLS
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]