Imported Upstream version 2.72.alpha
[platform/upstream/glib-networking.git] / tls / openssl / gtlsfiledatabase-openssl.c
index e45a619..7e2f928 100644 (file)
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
  * gtlsfiledatabase-openssl.c
  *
 #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;
@@ -57,7 +59,7 @@ typedef struct _GTlsFileDatabaseOpensslPrivate
    * This is a table of gchar * -> GTlsCertificate.
    */
   GHashTable *certs_by_handle;
-} GTlsFileDatabaseOpensslPrivate;
+};
 
 enum {
   STATUS_FAILURE,
@@ -75,14 +77,10 @@ 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)
@@ -100,7 +98,7 @@ bytes_multi_table_insert (GHashTable *table,
   GPtrArray *multi;
 
   multi = g_hash_table_lookup (table, &key);
-  if (multi == NULL)
+  if (!multi)
     {
       int *key_ptr;
 
@@ -119,7 +117,7 @@ bytes_multi_table_lookup_ref_one (GHashTable *table,
   GPtrArray *multi;
 
   multi = g_hash_table_lookup (table, &key);
-  if (multi == NULL)
+  if (!multi)
     return NULL;
 
   g_assert (multi->len > 0);
@@ -135,7 +133,7 @@ bytes_multi_table_lookup_ref_all (GHashTable *table,
   guint i;
 
   multi = g_hash_table_lookup (table, &key);
-  if (multi == NULL)
+  if (!multi)
     return NULL;
 
   for (i = 0; i < multi->len; i++)
@@ -179,15 +177,12 @@ load_anchor_file (GTlsFileDatabaseOpenssl  *file_database,
                   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)
     {
@@ -206,7 +201,7 @@ load_anchor_file (GTlsFileDatabaseOpenssl  *file_database,
       issuer = X509_issuer_name_hash (x);
 
       der = g_tls_certificate_openssl_get_bytes (l->data);
-      g_return_val_if_fail (der != NULL, FALSE);
+      g_return_val_if_fail (der, FALSE);
 
       g_hash_table_insert (complete, g_bytes_ref (der),
                            g_bytes_ref (der));
@@ -214,7 +209,7 @@ load_anchor_file (GTlsFileDatabaseOpenssl  *file_database,
       bytes_multi_table_insert (subjects, subject, der);
       bytes_multi_table_insert (issuers, issuer, der);
 
-      handle = create_handle_for_certificate (priv->anchor_filename, der);
+      handle = create_handle_for_certificate (file_database->anchor_filename, der);
       g_hash_table_insert (certs_by_handle, handle, g_object_ref (l->data));
 
       g_bytes_unref (der);
@@ -230,22 +225,16 @@ 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_clear_pointer (&file_database->subjects, g_hash_table_destroy);
+  g_clear_pointer (&file_database->issuers, g_hash_table_destroy);
+  g_clear_pointer (&file_database->complete, g_hash_table_destroy);
+  g_clear_pointer (&file_database->certs_by_handle, g_hash_table_destroy);
 
-  g_free (priv->anchor_filename);
-  priv->anchor_filename = NULL;
+  g_free (file_database->anchor_filename);
+  file_database->anchor_filename = NULL;
 
-  if (priv->trusted != NULL)
-    sk_X509_pop_free (priv->trusted, X509_free);
-
-  g_mutex_clear (&priv->mutex);
+  g_mutex_clear (&file_database->mutex);
 
   G_OBJECT_CLASS (g_tls_file_database_openssl_parent_class)->finalize (object);
 }
@@ -257,68 +246,17 @@ g_tls_file_database_openssl_get_property (GObject    *object,
                                           GParamSpec *pspec)
 {
   GTlsFileDatabaseOpenssl *file_database = G_TLS_FILE_DATABASE_OPENSSL (object);
-  GTlsFileDatabaseOpensslPrivate *priv;
-
-  priv = g_tls_file_database_openssl_get_instance_private (file_database);
 
   switch (prop_id)
     {
     case PROP_ANCHORS:
-      g_value_set_string (value, priv->anchor_filename);
+      g_value_set_string (value, file_database->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,
@@ -326,11 +264,8 @@ g_tls_file_database_openssl_set_property (GObject      *object,
                                           GParamSpec   *pspec)
 {
   GTlsFileDatabaseOpenssl *file_database = G_TLS_FILE_DATABASE_OPENSSL (object);
-  GTlsFileDatabaseOpensslPrivate *priv;
   const gchar *anchor_path;
 
-  priv = g_tls_file_database_openssl_get_instance_private (file_database);
-
   switch (prop_id)
     {
     case PROP_ANCHORS:
@@ -342,15 +277,8 @@ 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 (file_database->anchor_filename);
+      file_database->anchor_filename = g_strdup (anchor_path);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -360,11 +288,7 @@ g_tls_file_database_openssl_set_property (GObject      *object,
 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);
+  g_mutex_init (&file_database->mutex);
 }
 
 static gchar *
@@ -372,26 +296,23 @@ 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_return_val_if_fail (der, FALSE);
 
-  g_mutex_lock (&priv->mutex);
+  g_mutex_lock (&file_database->mutex);
 
   /* At the same time look up whether this certificate is in list */
-  contains = g_hash_table_lookup (priv->complete, der) ? TRUE : FALSE;
+  contains = g_hash_table_lookup (file_database->complete, der) ? TRUE : FALSE;
 
-  g_mutex_unlock (&priv->mutex);
+  g_mutex_unlock (&file_database->mutex);
 
   /* Certificate is in the database */
   if (contains)
-    handle = create_handle_for_certificate (priv->anchor_filename, der);
+    handle = create_handle_for_certificate (file_database->anchor_filename, der);
 
   g_bytes_unref (der);
   return handle;
@@ -406,22 +327,19 @@ g_tls_file_database_openssl_lookup_certificate_for_handle (GTlsDatabase
                                                            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);
+  g_mutex_lock (&file_database->mutex);
 
-  cert = g_hash_table_lookup (priv->certs_by_handle, handle);
+  cert = g_hash_table_lookup (file_database->certs_by_handle, handle);
 
-  g_mutex_unlock (&priv->mutex);
+  g_mutex_unlock (&file_database->mutex);
 
   return cert ? g_object_ref (cert) : NULL;
 }
@@ -435,14 +353,11 @@ g_tls_file_database_openssl_lookup_certificate_issuer (GTlsDatabase
                                                        GError                  **error)
 {
   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))
@@ -455,16 +370,16 @@ g_tls_file_database_openssl_lookup_certificate_issuer (GTlsDatabase
   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);
+  g_mutex_lock (&file_database->mutex);
+  der = bytes_multi_table_lookup_ref_one (file_database->subjects, issuer_hash);
+  g_mutex_unlock (&file_database->mutex);
 
   if (g_cancellable_set_error_if_cancelled (cancellable, error))
     issuer = NULL;
-  else if (der != NULL)
+  else if (der)
     issuer = g_tls_certificate_openssl_new (der, NULL);
 
-  if (der != NULL)
+  if (der)
     g_bytes_unref (der);
   return issuer;
 
@@ -480,13 +395,10 @@ g_tls_file_database_openssl_lookup_certificates_issued_by (GTlsDatabase
                                                            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);
-
   if (g_cancellable_set_error_if_cancelled (cancellable, error))
     return NULL;
 
@@ -496,7 +408,7 @@ g_tls_file_database_openssl_lookup_certificates_issued_by (GTlsDatabase
 
   in = issuer_raw_dn->data;
   x_name = d2i_X509_NAME (NULL, &in, issuer_raw_dn->len);
-  if (x_name != NULL)
+  if (x_name)
     {
       unsigned long issuer_hash;
       GList *ders, *l;
@@ -504,11 +416,11 @@ g_tls_file_database_openssl_lookup_certificates_issued_by (GTlsDatabase
       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);
+      g_mutex_lock (&file_database->mutex);
+      ders = bytes_multi_table_lookup_ref_all (file_database->issuers, issuer_hash);
+      g_mutex_unlock (&file_database->mutex);
 
-      for (l = ders; l != NULL; l = g_list_next (l))
+      for (l = ders; l; l = g_list_next (l))
         {
           if (g_cancellable_set_error_if_cancelled (cancellable, error))
             {
@@ -527,155 +439,25 @@ g_tls_file_database_openssl_lookup_certificates_issued_by (GTlsDatabase
   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_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);
-    }
-
-  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);
-
-  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 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);
-
-  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;
-
-  g_object_class_override_property (gobject_class, PROP_ANCHORS, "anchors");
-}
-
-static void
-g_tls_file_database_openssl_file_database_interface_init (GTlsFileDatabaseInterface *iface)
-{
-}
-
 static gboolean
-g_tls_file_database_openssl_initable_init (GInitable    *initable,
-                                           GCancellable *cancellable,
-                                           GError      **error)
+g_tls_file_database_openssl_populate_trust_list (GTlsDatabaseOpenssl  *self,
+                                                 X509_STORE           *store,
+                                                 GError              **error)
 {
-  GTlsFileDatabaseOpenssl *file_database = G_TLS_FILE_DATABASE_OPENSSL (initable);
-  GTlsFileDatabaseOpensslPrivate *priv;
+  GTlsFileDatabaseOpenssl *file_database = G_TLS_FILE_DATABASE_OPENSSL (self);
   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;
+  if (!X509_STORE_load_locations (store, file_database->anchor_filename, NULL))
+    {
+      char error_buffer[256];
+      ERR_error_string_n (ERR_get_error (), error_buffer, sizeof (error_buffer));
+      g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
+                   _("Failed to populate trust list from %s: %s"),
+                   file_database->anchor_filename,
+                   error_buffer);
+      return FALSE;
+    }
 
   subjects = bytes_multi_table_new ();
   issuers = bytes_multi_table_new ();
@@ -688,165 +470,74 @@ g_tls_file_database_openssl_initable_init (GInitable    *initable,
                                            (GDestroyNotify)g_free,
                                            (GDestroyNotify)g_object_unref);
 
-  if (priv->anchor_filename)
+  if (file_database->anchor_filename)
     result = load_anchor_file (file_database,
-                               priv->anchor_filename,
+                               file_database->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)
+      g_mutex_lock (&file_database->mutex);
+      if (!file_database->subjects)
         {
-          priv->subjects = subjects;
+          file_database->subjects = subjects;
           subjects = NULL;
         }
-      if (!priv->issuers)
+      if (!file_database->issuers)
         {
-          priv->issuers = issuers;
+          file_database->issuers = issuers;
           issuers = NULL;
         }
-      if (!priv->complete)
+      if (!file_database->complete)
         {
-          priv->complete = complete;
+          file_database->complete = complete;
           complete = NULL;
         }
-      if (!priv->certs_by_handle)
+      if (!file_database->certs_by_handle)
         {
-          priv->certs_by_handle = certs_by_handle;
+          file_database->certs_by_handle = certs_by_handle;
           certs_by_handle = NULL;
         }
-      g_mutex_unlock (&priv->mutex);
+      g_mutex_unlock (&file_database->mutex);
     }
 
-  if (subjects != NULL)
+  if (subjects)
     g_hash_table_unref (subjects);
-  if (issuers != NULL)
+  if (issuers)
     g_hash_table_unref (issuers);
-  if (complete != NULL)
+  if (complete)
     g_hash_table_unref (complete);
-  if (certs_by_handle != NULL)
+  if (certs_by_handle)
     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_class_init (GTlsFileDatabaseOpensslClass *klass)
 {
-  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;
-        }
+  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);
 
-      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;
-        }
-    }
+  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;
 
-end:
-  if (store != NULL)
-    X509_STORE_free (store);
+  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;
 
-  if (basic_resp != NULL)
-    OCSP_BASICRESP_free (basic_resp);
+  openssl_database_class->populate_trust_list = g_tls_file_database_openssl_populate_trust_list;
 
-  if (resp != NULL)
-    OCSP_RESPONSE_free (resp);
+  g_object_class_override_property (gobject_class, PROP_ANCHORS, "anchors");
+}
 
-#endif
-  return errors;
+static void
+g_tls_file_database_openssl_file_database_interface_init (GTlsFileDatabaseInterface *iface)
+{
 }