diff --git a/docs/reference/gio/gio-docs.xml b/docs/reference/gio/gio-docs.xml
index d67b79e..c7e511e 100644
--- a/docs/reference/gio/gio-docs.xml
+++ b/docs/reference/gio/gio-docs.xml
@@ -138,6 +138,10 @@
       <xi:include href="xml/gtlsclientconnection.xml"/>
       <xi:include href="xml/gtlsserverconnection.xml"/>
       <xi:include href="xml/gtlsbackend.xml"/>
+      <xi:include href="xml/gtlsdatabase.xml"/>
+      <xi:include href="xml/gtlsfiledatabase.xml"/>
+      <xi:include href="xml/gtlsinteraction.xml"/>
+      <xi:include href="xml/gtlspassword.xml"/>
     </chapter>
     <chapter id="resolver">
       <title>DNS resolution</title>
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index 87617a6..05b20e9 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -3020,9 +3020,11 @@ GTlsBackend
 GTlsBackendInterface
 g_tls_backend_get_default
 g_tls_backend_supports_tls
+g_tls_backend_get_default_database
 g_tls_backend_get_certificate_type
 g_tls_backend_get_client_connection_type
 g_tls_backend_get_server_connection_type
+g_tls_backend_get_file_database_type
 <SUBSECTION Standard>
 G_IS_TLS_BACKEND
 G_TLS_BACKEND
@@ -3071,6 +3073,10 @@ g_tls_connection_set_rehandshake_mode
 g_tls_connection_get_rehandshake_mode
 g_tls_connection_set_use_system_certdb
 g_tls_connection_get_use_system_certdb
+g_tls_connection_get_database
+g_tls_connection_set_database
+g_tls_connection_get_interaction
+g_tls_connection_set_interaction
 <SUBSECTION>
 g_tls_connection_handshake
 g_tls_connection_handshake_async
@@ -3113,6 +3119,58 @@ g_tls_client_connection_get_type
 </SECTION>
 
 <SECTION>
+<FILE>gtlsdatabase</FILE>
+<TITLE>GTlsDatabase</TITLE>
+GTlsDatabase
+GTlsDatabaseVerifyFlags
+G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER
+G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT
+g_tls_database_verify_chain
+g_tls_database_verify_chain_async
+g_tls_database_verify_chain_finish
+GTlsDatabaseLookupFlags
+g_tls_database_lookup_certificate_issuer
+g_tls_database_lookup_certificate_issuer_async
+g_tls_database_lookup_certificate_issuer_finish
+g_tls_database_lookup_certificates_issued_by
+g_tls_database_lookup_certificates_issued_by_async
+g_tls_database_lookup_certificates_issued_by_finish
+g_tls_database_create_certificate_handle
+g_tls_database_lookup_certificate_for_handle
+g_tls_database_lookup_certificate_for_handle_async
+g_tls_database_lookup_certificate_for_handle_finish
+<SUBSECTION Standard>
+G_IS_TLS_DATABASE
+G_IS_TLS_DATABASE_CLASS
+G_TLS_DATABASE
+G_TLS_DATABASE_CLASS
+G_TLS_DATABASE_GET_CLASS
+G_TYPE_TLS_DATABASE
+G_TYPE_TLS_DATABASE_LOOKUP_FLAGS
+G_TYPE_TLS_DATABASE_VERIFY_FLAGS
+<SUBSECTION Private>
+g_tls_database_lookup_flags_get_type
+g_tls_database_verify_flags_get_type
+g_tls_database_get_type
+GTlsDatabasePrivate
+</SECTION>
+
+<SECTION>
+<FILE>gtlsfiledatabase</FILE>
+<TITLE>GTlsFileDatabase</TITLE>
+GTlsFileDatabase
+GTlsFileDatabaseInterface
+g_tls_file_database_new
+<SUBSECTION Standard>
+G_TLS_FILE_DATABASE
+G_TLS_FILE_DATABASE_GET_INTERFACE
+G_TYPE_TLS_FILE_DATABASE
+G_IS_TLS_FILE_DATABASE
+<SUBSECTION Private>
+g_tls_file_database_get_type
+</SECTION>
+
+<SECTION>
 <FILE>gtlsserverconnection</FILE>
 <TITLE>GTlsServerConnection</TITLE>
 GTlsServerConnection
@@ -3128,6 +3186,60 @@ g_tls_server_connection_get_type
 </SECTION>
 
 <SECTION>
+<FILE>gtlspassword</FILE>
+<TITLE>GTlsPassword</TITLE>
+GTlsPassword
+GTlsPasswordInterface
+GTlsPasswordFlags
+g_tls_password_new
+g_tls_password_set_value
+g_tls_password_take_value
+g_tls_password_get_value
+g_tls_password_get_description
+g_tls_password_get_flags
+<SUBSECTION Standard>
+g_tls_password_flags_get_type
+g_tls_password_get_type
+G_IS_TLS_PASSWORD
+G_TLS_PASSWORD
+G_TLS_PASSWORD_GET_INTERFACE
+G_TYPE_TLS_PASSWORD
+G_TYPE_TLS_PASSWORD_FLAGS
+</SECTION>
+
+<SECTION>
+<FILE>gtlsinteraction</FILE>
+<TITLE>GTlsInteraction</TITLE>
+GTlsInteraction
+GTlsInteractionResult
+g_tls_interaction_ask_password
+g_tls_interaction_ask_password_finish
+<SUBSECTION Standard>
+GTlsInteractionClass
+G_IS_TLS_INTERACTION
+G_IS_TLS_INTERACTION_CLASS
+G_TYPE_TLS_INTERACTION
+G_TLS_INTERACTION
+G_TLS_INTERACTION_CLASS
+G_TLS_INTERACTION_GET_CLASS
+G_TYPE_TLS_INTERACTION_RESULT
+<SUBSECTION Private>
+GTlsInteractionPrivate
+g_tls_interaction_get_type
+g_tls_interaction_result_get_type
+GTlsConsoleInteraction
+GTlsConsoleInteractionClass
+G_IS_TLS_CONSOLE_INTERACTION
+G_IS_TLS_CONSOLE_INTERACTION_CLASS
+g_tls_console_interaction_new
+G_TLS_CONSOLE_INTERACTION
+G_TYPE_TLS_CONSOLE_INTERACTION
+G_TLS_CONSOLE_INTERACTION_CLASS
+G_TLS_CONSOLE_INTERACTION_GET_CLASS
+g_tls_console_interaction_get_type
+</SECTION>
+
+<SECTION>
 <FILE>gtimezonemonitor</FILE>
 <TITLE>GTimeZoneMonitor</TITLE>
 GTimeZoneMonitor
diff --git a/docs/reference/gio/gio.types b/docs/reference/gio/gio.types
index 335e0eb..685a900 100644
--- a/docs/reference/gio/gio.types
+++ b/docs/reference/gio/gio.types
@@ -110,6 +110,8 @@ g_tls_backend_get_type
 g_tls_certificate_get_type
 g_tls_client_connection_get_type
 g_tls_connection_get_type
+g_tls_database_get_type
+g_tls_file_database_get_type
 g_tls_server_connection_get_type
 g_unix_connection_get_type
 g_unix_fd_list_get_type
diff --git a/gio/Makefile.am b/gio/Makefile.am
index 7bd6618..d158bfc 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -381,6 +381,10 @@ libgio_2_0_la_SOURCES =		\
 	gtlscertificate.c	\
 	gtlsclientconnection.c	\
 	gtlsconnection.c	\
+	gtlsdatabase.c		\
+	gtlsfiledatabase.c	\
+	gtlsinteraction.c	\
+	gtlspassword.c		\
 	gtlsserverconnection.c	\
 	gunionvolumemonitor.c 	\
 	gunionvolumemonitor.h 	\
@@ -532,6 +536,10 @@ gio_headers =			\
 	gtlscertificate.h	\
 	gtlsclientconnection.h	\
 	gtlsconnection.h	\
+	gtlsdatabase.h		\
+	gtlsfiledatabase.h	\
+	gtlsinteraction.h	\
+	gtlspassword.h		\
 	gtlsserverconnection.h	\
 	gvfs.h 			\
 	gvolume.h 		\
diff --git a/gio/gdummytlsbackend.c b/gio/gdummytlsbackend.c
index f297f74..5a2463b 100644
--- a/gio/gdummytlsbackend.c
+++ b/gio/gdummytlsbackend.c
@@ -30,6 +30,8 @@
 #include "gtlsbackend.h"
 #include "gtlscertificate.h"
 #include "gtlsclientconnection.h"
+#include "gtlsdatabase.h"
+#include "gtlsfiledatabase.h"
 #include "gtlsserverconnection.h"
 #include "gsimpleasyncresult.h"
 
@@ -40,9 +42,11 @@
 
 static GType _g_dummy_tls_certificate_get_type (void);
 static GType _g_dummy_tls_connection_get_type (void);
+static GType _g_dummy_tls_database_get_type (void);
 
 struct _GDummyTlsBackend {
-  GObject parent_instance;
+  GObject       parent_instance;
+  GTlsDatabase *database;
 };
 
 static void g_dummy_tls_backend_iface_init (GTlsBackendInterface *iface);
@@ -67,12 +71,20 @@ g_dummy_tls_backend_class_init (GDummyTlsBackendClass *backend_class)
 {
 }
 
+static GTlsDatabase*
+g_dummy_tls_backend_get_default_database (GTlsBackend *backend)
+{
+  return g_object_new (_g_dummy_tls_database_get_type (), NULL);
+}
+
 static void
 g_dummy_tls_backend_iface_init (GTlsBackendInterface *iface)
 {
   iface->get_certificate_type = _g_dummy_tls_certificate_get_type;
   iface->get_client_connection_type = _g_dummy_tls_connection_get_type;
   iface->get_server_connection_type = _g_dummy_tls_connection_get_type;
+  iface->get_file_database_type = _g_dummy_tls_database_get_type;
+  iface->get_default_database = g_dummy_tls_backend_get_default_database;
 }
 
 /* Dummy certificate type */
@@ -188,6 +200,7 @@ enum
   PROP_CONN_REQUIRE_CLOSE_NOTIFY,
   PROP_CONN_REHANDSHAKE_MODE,
   PROP_CONN_CERTIFICATE,
+  PROP_CONN_DATABASE,
   PROP_CONN_PEER_CERTIFICATE,
   PROP_CONN_PEER_CERTIFICATE_ERRORS,
   PROP_CONN_VALIDATION_FLAGS,
@@ -251,6 +264,7 @@ g_dummy_tls_connection_class_init (GDummyTlsConnectionClass *connection_class)
   g_object_class_override_property (gobject_class, PROP_CONN_REQUIRE_CLOSE_NOTIFY, "require-close-notify");
   g_object_class_override_property (gobject_class, PROP_CONN_REHANDSHAKE_MODE, "rehandshake-mode");
   g_object_class_override_property (gobject_class, PROP_CONN_CERTIFICATE, "certificate");
+  g_object_class_override_property (gobject_class, PROP_CONN_DATABASE, "database");
   g_object_class_override_property (gobject_class, PROP_CONN_PEER_CERTIFICATE, "peer-certificate");
   g_object_class_override_property (gobject_class, PROP_CONN_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors");
   g_object_class_override_property (gobject_class, PROP_CONN_VALIDATION_FLAGS, "validation-flags");
@@ -281,3 +295,92 @@ g_dummy_tls_connection_initable_iface_init (GInitableIface  *iface)
   iface->init = g_dummy_tls_connection_initable_init;
 }
 
+/* Dummy database type.
+ */
+
+typedef struct _GDummyTlsDatabase      GDummyTlsDatabase;
+typedef struct _GDummyTlsDatabaseClass GDummyTlsDatabaseClass;
+
+struct _GDummyTlsDatabase {
+  GTlsDatabase parent_instance;
+};
+
+struct _GDummyTlsDatabaseClass {
+  GTlsDatabaseClass parent_class;
+};
+
+enum
+{
+  PROP_DATABASE_0,
+
+  PROP_ANCHORS,
+};
+
+static void g_dummy_tls_database_file_database_iface_init (GTlsFileDatabaseInterface *iface);
+static void g_dummy_tls_database_initable_iface_init (GInitableIface *iface);
+
+#define g_dummy_tls_database_get_type _g_dummy_tls_database_get_type
+G_DEFINE_TYPE_WITH_CODE (GDummyTlsDatabase, g_dummy_tls_database, G_TYPE_TLS_DATABASE,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_TLS_FILE_DATABASE,
+                                                g_dummy_tls_database_file_database_iface_init);
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+                                                g_dummy_tls_database_initable_iface_init);)
+
+
+static void
+g_dummy_tls_database_get_property (GObject    *object,
+                                   guint       prop_id,
+                                   GValue     *value,
+                                   GParamSpec *pspec)
+{
+  /* We need to define this method to make GObject happy, but it will
+   * never be possible to construct a working GDummyTlsDatabase, so
+   * it doesn't have to do anything useful.
+   */
+}
+
+static void
+g_dummy_tls_database_set_property (GObject      *object,
+                                   guint         prop_id,
+                                   const GValue *value,
+                                   GParamSpec   *pspec)
+{
+  /* Just ignore all attempts to set properties. */
+}
+
+static void
+g_dummy_tls_database_class_init (GDummyTlsDatabaseClass *database_class)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (database_class);
+
+  gobject_class->get_property = g_dummy_tls_database_get_property;
+  gobject_class->set_property = g_dummy_tls_database_set_property;
+
+  g_object_class_override_property (gobject_class, PROP_ANCHORS, "anchors");
+}
+
+static void
+g_dummy_tls_database_init (GDummyTlsDatabase *database)
+{
+}
+
+static void
+g_dummy_tls_database_file_database_iface_init (GTlsFileDatabaseInterface  *iface)
+{
+}
+
+static gboolean
+g_dummy_tls_database_initable_init (GInitable       *initable,
+                                    GCancellable    *cancellable,
+                                    GError         **error)
+{
+  g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE,
+                       _("TLS support is not available"));
+  return FALSE;
+}
+
+static void
+g_dummy_tls_database_initable_iface_init (GInitableIface  *iface)
+{
+  iface->init = g_dummy_tls_database_initable_init;
+}
diff --git a/gio/gio.h b/gio/gio.h
index 2958059..9281dde 100644
--- a/gio/gio.h
+++ b/gio/gio.h
@@ -124,7 +124,11 @@
 #include <gio/gtlscertificate.h>
 #include <gio/gtlsclientconnection.h>
 #include <gio/gtlsconnection.h>
+#include <gio/gtlsdatabase.h>
+#include <gio/gtlsfiledatabase.h>
+#include <gio/gtlsinteraction.h>
 #include <gio/gtlsserverconnection.h>
+#include <gio/gtlspassword.h>
 #include <gio/gvfs.h>
 #include <gio/gvolume.h>
 #include <gio/gvolumemonitor.h>
diff --git a/gio/gio.symbols b/gio/gio.symbols
index 00d5328..07eec98 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -781,6 +781,7 @@ g_tls_authentication_mode_get_type
 g_tls_certificate_flags_get_type
 g_tls_rehandshake_mode_get_type
 g_emblemed_icon_get_type
+g_tls_database_verify_flags_get_type
 g_emblemed_icon_new
 g_emblemed_icon_get_icon
 g_emblemed_icon_get_emblems
@@ -1420,6 +1421,7 @@ g_tls_certificate_new_from_pem
 g_tls_certificate_verify
 g_tls_connection_emit_accept_certificate
 g_tls_connection_get_certificate
+g_tls_connection_get_interaction
 g_tls_connection_get_peer_certificate
 g_tls_connection_get_peer_certificate_errors
 g_tls_connection_get_rehandshake_mode
@@ -1430,6 +1432,7 @@ g_tls_connection_handshake
 g_tls_connection_handshake_async
 g_tls_connection_handshake_finish
 g_tls_connection_set_certificate
+g_tls_connection_set_interaction
 g_tls_connection_set_rehandshake_mode
 g_tls_connection_set_require_close_notify
 g_tls_connection_set_use_system_certdb
@@ -1444,6 +1447,24 @@ g_tls_client_connection_set_use_ssl3
 g_tls_client_connection_set_validation_flags
 g_tls_server_connection_get_type
 g_tls_server_connection_new
+g_tls_database_get_type
+g_tls_database_lookup_issuer
+g_tls_database_lookup_issuer_async
+g_tls_database_lookup_issuer_finish
+g_tls_database_verify_chain
+g_tls_database_verify_chain_async
+g_tls_database_verify_chain_finish
+g_tls_file_database_get_type
+g_tls_file_database_new
+g_tls_interaction_get_type
+g_tls_interaction_ask_password
+g_tls_interaction_ask_password_finish
+g_tls_password_get_type
+g_tls_password_get_value
+g_tls_password_set_value
+g_tls_password_take_value
+g_tls_password_get_flags
+g_tls_password_get_description
 g_time_zone_monitor_get_type
 g_time_zone_monitor_get
 g_dbus_interface_get_info
diff --git a/gio/gioenums.h b/gio/gioenums.h
index 4ea72a9..b724f2a 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -1393,6 +1393,48 @@ typedef enum {
 } GTlsRehandshakeMode;
 
 /**
+ * GTlsPasswordFlags:
+ * @G_TLS_PASSWORD_NONE: No flags
+ * @G_TLS_PASSWORD_RETRY: The password was wrong, and the user should retry.
+ * @G_TLS_PASSWORD_MANY_TRIES: Hint to the user that the password has been
+ *    wrong many times, and the user may not have many chances left.
+ * @G_TLS_PASSWORD_FINAL_TRY: Hint to the user that this is the last try to get
+ *    this password right.
+ *
+ * Various flags for the password.
+ *
+ * Since: 2.30
+ */
+
+typedef enum _GTlsPasswordFlags
+{
+  G_TLS_PASSWORD_NONE = 0,
+  G_TLS_PASSWORD_RETRY = 1 << 1,
+  G_TLS_PASSWORD_MANY_TRIES = 1 << 2,
+  G_TLS_PASSWORD_FINAL_TRY = 1 << 3
+} GTlsPasswordFlags;
+
+/**
+ * GTlsInteractionResult:
+ * @G_TLS_INTERACTION_HANDLED: The interaction completed, and resulting data
+ *     is available.
+ * @G_TLS_INTERACTION_ABORTED: The user cancelled the interaction, and requested
+ *     the operation to be aborted.
+ * @G_TLS_INTERACTION_UNHANDLED: The interaction was unhandled (i.e. not
+ *     implemented).
+ *
+ * #GTlsInteractionResult is returned by various functions in #GTlsInteraction
+ * when finishing an interaction request.
+ *
+ * Since: 2.30
+ */
+typedef enum {
+  G_TLS_INTERACTION_HANDLED,
+  G_TLS_INTERACTION_ABORTED,
+  G_TLS_INTERACTION_UNHANDLED
+} GTlsInteractionResult;
+
+/**
  * GDBusInterfaceSkeletonFlags:
  * @G_DBUS_INTERFACE_SKELETON_FLAGS_NONE: No flags set.
  * @G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD: Each method invocation is handled in
@@ -1428,6 +1470,34 @@ typedef enum
   G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START = (1<<0)
 } GDBusObjectManagerClientFlags;
 
+/**
+ * GTlsDatabaseVerifyFlags:
+ * @G_TLS_DATABASE_VERIFY_NONE: No verification flags
+ *
+ * Flags for g_tls_database_verify_chain().
+ *
+ * Since: 2.30
+ */
+typedef enum {
+  G_TLS_DATABASE_VERIFY_NONE = 0,
+} GTlsDatabaseVerifyFlags;
+
+/**
+ * GTlsDatabaseLookupFlags:
+ * @G_TLS_DATABASE_LOOKUP_NONE: No lookup flags
+ * @G_TLS_DATABASE_LOOKUP_KEYPAIR: Restrict lookup to certificates that have
+ *     a private key.
+ *
+ * Flags for g_tls_database_lookup_handle(), g_tls_database_lookup_issuer(),
+ * and g_tls_database_lookup_issued().
+ *
+ * Since: 2.30
+ */
+typedef enum {
+  G_TLS_DATABASE_LOOKUP_NONE = 0,
+  G_TLS_DATABASE_LOOKUP_KEYPAIR = 1,
+} GTlsDatabaseLookupFlags;
+
 G_END_DECLS
 
 #endif /* __GIO_ENUMS_H__ */
diff --git a/gio/giotypes.h b/gio/giotypes.h
index af27586..ec3620d 100644
--- a/gio/giotypes.h
+++ b/gio/giotypes.h
@@ -206,6 +206,11 @@ typedef struct _GThemedIcon                   GThemedIcon;
 typedef struct _GTlsCertificate               GTlsCertificate;
 typedef struct _GTlsClientConnection          GTlsClientConnection; /* Dummy typedef */
 typedef struct _GTlsConnection                GTlsConnection;
+typedef struct _GTlsContext                   GTlsContext;
+typedef struct _GTlsDatabase                  GTlsDatabase;
+typedef struct _GTlsFileDatabase              GTlsFileDatabase;
+typedef struct _GTlsInteraction               GTlsInteraction;
+typedef struct _GTlsPassword                  GTlsPassword;
 typedef struct _GTlsServerConnection          GTlsServerConnection; /* Dummy typedef */
 typedef struct _GVfs                          GVfs; /* Dummy typedef */
 
diff --git a/gio/gtlsbackend.c b/gio/gtlsbackend.c
index a87137f..d528c5d 100644
--- a/gio/gtlsbackend.c
+++ b/gio/gtlsbackend.c
@@ -150,6 +150,24 @@ g_tls_backend_supports_tls (GTlsBackend *backend)
 }
 
 /**
+ * g_tls_backend_get_default_database:
+ * @backend: the #GTlsBackend
+ *
+ * Gets the default #GTlsDatabase used to verify TLS connections.
+ *
+ * Return value: the default database, which should be unreffed when done.
+ *
+ * Since: 2.30
+ */
+GTlsDatabase *
+g_tls_backend_get_default_database (GTlsBackend *backend)
+{
+  g_return_val_if_fail (G_IS_TLS_BACKEND (backend), NULL);
+  g_return_val_if_fail (G_TLS_BACKEND_GET_INTERFACE (backend)->get_default_database, NULL);
+  return G_TLS_BACKEND_GET_INTERFACE (backend)->get_default_database (backend);
+}
+
+/**
  * g_tls_backend_get_certificate_type:
  * @backend: the #GTlsBackend
  *
@@ -199,3 +217,19 @@ g_tls_backend_get_server_connection_type (GTlsBackend *backend)
 {
   return G_TLS_BACKEND_GET_INTERFACE (backend)->get_server_connection_type ();
 }
+
+/**
+ * g_tls_backend_get_file_database_type:
+ * @backend: the #GTlsBackend
+ *
+ * Gets the #GTyep of @backend's #GTlsFileDatabase implementation.
+ *
+ * Return value: the #GType of backend's #GTlsFileDatabase implementation.
+ *
+ * Since: 2.30
+ */
+GType
+g_tls_backend_get_file_database_type (GTlsBackend *backend)
+{
+  return G_TLS_BACKEND_GET_INTERFACE (backend)->get_file_database_type ();
+}
diff --git a/gio/gtlsbackend.h b/gio/gtlsbackend.h
index 24ae911..813dc55 100644
--- a/gio/gtlsbackend.h
+++ b/gio/gtlsbackend.h
@@ -58,9 +58,12 @@ typedef struct _GTlsBackendInterface GTlsBackendInterface;
 /**
  * GTlsBackendInterface:
  * @g_iface: The parent interface.
+ * @supports_tls: returns whether the backend supports TLS.
+ * @get_default_database: returns a default #GTlsDatabase instance.
  * @get_certificate_type: returns the #GTlsCertificate implementation type
  * @get_client_connection_type: returns the #GTlsClientConnection implementation type
  * @get_server_connection_type: returns the #GTlsServerConnection implementation type
+ * @get_file_database_type: returns the #GTlsFileDatabase implementation type.
  *
  * Provides an interface for describing TLS-related types.
  *
@@ -71,21 +74,26 @@ struct _GTlsBackendInterface
   GTypeInterface g_iface;
 
   /* methods */
-  gboolean ( *supports_tls)               (GTlsBackend *backend);
-  GType    ( *get_certificate_type)       (void);
-  GType    ( *get_client_connection_type) (void);
-  GType    ( *get_server_connection_type) (void);
+  gboolean       ( *supports_tls)               (GTlsBackend *backend);
+  GTlsDatabase * ( *get_default_database)       (GTlsBackend *backend);
+  GType          ( *get_certificate_type)       (void);
+  GType          ( *get_client_connection_type) (void);
+  GType          ( *get_server_connection_type) (void);
+  GType          ( *get_file_database_type)     (void);
 };
 
-GType        g_tls_backend_get_type                   (void) G_GNUC_CONST;
+GType          g_tls_backend_get_type                   (void) G_GNUC_CONST;
 
-GTlsBackend *g_tls_backend_get_default                (void);
+GTlsBackend *  g_tls_backend_get_default                (void);
 
-gboolean     g_tls_backend_supports_tls               (GTlsBackend *backend);
+GTlsDatabase * g_tls_backend_get_default_database       (GTlsBackend *backend);
 
-GType        g_tls_backend_get_certificate_type       (GTlsBackend *backend);
-GType        g_tls_backend_get_client_connection_type (GTlsBackend *backend);
-GType        g_tls_backend_get_server_connection_type (GTlsBackend *backend);
+gboolean       g_tls_backend_supports_tls               (GTlsBackend *backend);
+
+GType          g_tls_backend_get_certificate_type       (GTlsBackend *backend);
+GType          g_tls_backend_get_client_connection_type (GTlsBackend *backend);
+GType          g_tls_backend_get_server_connection_type (GTlsBackend *backend);
+GType          g_tls_backend_get_file_database_type     (GTlsBackend *backend);
 
 G_END_DECLS
 
diff --git a/gio/gtlsconnection.c b/gio/gtlsconnection.c
index 74da0e4..bdd54b7 100644
--- a/gio/gtlsconnection.c
+++ b/gio/gtlsconnection.c
@@ -28,6 +28,8 @@
 #include "gtlsbackend.h"
 #include "gtlscertificate.h"
 #include "gtlsclientconnection.h"
+#include "gtlsdatabase.h"
+#include "gtlsinteraction.h"
 #include "glibintl.h"
 
 /**
@@ -77,6 +79,8 @@ enum {
   PROP_REQUIRE_CLOSE_NOTIFY,
   PROP_REHANDSHAKE_MODE,
   PROP_USE_SYSTEM_CERTDB,
+  PROP_DATABASE,
+  PROP_INTERACTION,
   PROP_CERTIFICATE,
   PROP_PEER_CERTIFICATE,
   PROP_PEER_CERTIFICATE_ERRORS
@@ -112,7 +116,7 @@ g_tls_connection_class_init (GTlsConnectionClass *klass)
    * verify peer certificates. See
    * g_tls_connection_set_use_system_certdb().
    *
-   * Since: 2.28
+   * Deprecated: 2.30: Use GTlsConnection:database instead
    */
   g_object_class_install_property (gobject_class, PROP_USE_SYSTEM_CERTDB,
 				   g_param_spec_boolean ("use-system-certdb",
@@ -123,6 +127,38 @@ g_tls_connection_class_init (GTlsConnectionClass *klass)
 							 G_PARAM_CONSTRUCT |
 							 G_PARAM_STATIC_STRINGS));
   /**
+   * GTlsConnection:database:
+   *
+   * The certificate database to use when verifying this TLS connection.
+   * If no cerificate database is set, then the default database will be
+   * used. See g_tls_backend_get_default_database().
+   *
+   * Since: 2.30
+   */
+  g_object_class_install_property (gobject_class, PROP_DATABASE,
+				   g_param_spec_object ("database",
+							 P_("Database"),
+							 P_("Certificate database to use for looking up or verifying certificates"),
+							 G_TYPE_TLS_DATABASE,
+							 G_PARAM_READWRITE |
+							 G_PARAM_STATIC_STRINGS));
+  /**
+   * GTlsConnection:interaction:
+   *
+   * A #GTlsInteraction object to be used when the connection or certificate
+   * database need to interact with the user. This will be used to prompt the
+   * user for passwords where necessary.
+   *
+   * Since: 2.30
+   */
+  g_object_class_install_property (gobject_class, PROP_INTERACTION,
+                                   g_param_spec_object ("interaction",
+                                                        P_("Interaction"),
+                                                        P_("Optional object for user interaction"),
+                                                        G_TYPE_TLS_INTERACTION,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_STATIC_STRINGS));
+  /**
    * GTlsConnection:require-close-notify:
    *
    * Whether or not proper TLS close notification is required.
@@ -306,7 +342,7 @@ g_tls_connection_set_property (GObject      *object,
  * client-side connections, unless that bit is not set in
  * #GTlsClientConnection:validation-flags).
  *
- * Since: 2.28
+ * Deprecated: 2.30: Use g_tls_connection_set_database() instead
  */
 void
 g_tls_connection_set_use_system_certdb (GTlsConnection *conn,
@@ -328,7 +364,7 @@ g_tls_connection_set_use_system_certdb (GTlsConnection *conn,
  *
  * Return value: whether @conn uses the system certificate database
  *
- * Since: 2.28
+ * Deprecated: 2.30: Use g_tls_connection_get_database() instead
  */
 gboolean
 g_tls_connection_get_use_system_certdb (GTlsConnection *conn)
@@ -344,6 +380,60 @@ g_tls_connection_get_use_system_certdb (GTlsConnection *conn)
 }
 
 /**
+ * g_tls_connection_set_database:
+ * @conn: a #GTlsConnection
+ * @database: a #GTlsDatabase
+ *
+ * Sets the certificate database that is used to verify peer certificates.
+ * This is set to the default database by default. See
+ * g_tls_backend_get_default_database(). If set to %NULL, then
+ * peer certificate validation will always set the
+ * %G_TLS_CERTIFICATE_UNKNOWN_CA error (meaning
+ * #GTlsConnection::accept-certificate will always be emitted on
+ * client-side connections, unless that bit is not set in
+ * #GTlsClientConnection:validation-flags).
+ *
+ * Since: 2.30
+ */
+void
+g_tls_connection_set_database (GTlsConnection *conn,
+                               GTlsDatabase   *database)
+{
+  g_return_if_fail (G_IS_TLS_CONNECTION (conn));
+  g_return_if_fail (database == NULL || G_IS_TLS_DATABASE (database));
+
+  g_object_set (G_OBJECT (conn),
+		"database", database,
+		NULL);
+}
+
+/**
+ * g_tls_connection_get_database:
+ * @conn: a #GTlsConnection
+ *
+ * Gets the certificate database that @conn uses to verify
+ * peer certificates. See g_tls_connection_set_database().
+ *
+ * Return value: the certificate database that @conn uses or %NULL
+ *
+ * Since: 2.30
+ */
+GTlsDatabase*
+g_tls_connection_get_database (GTlsConnection *conn)
+{
+  GTlsDatabase *database = NULL;
+
+  g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL);
+
+  g_object_get (G_OBJECT (conn),
+		"database", &database,
+		NULL);
+  if (database)
+    g_object_unref (database);
+  return database;
+}
+
+/**
  * g_tls_connection_set_certificate:
  * @conn: a #GTlsConnection
  * @certificate: the certificate to use for @conn
@@ -405,6 +495,56 @@ g_tls_connection_get_certificate (GTlsConnection *conn)
 }
 
 /**
+ * g_tls_connection_set_interaction:
+ * @conn: a connection
+ * @interaction: (allow-none): an interaction object, or %NULL
+ *
+ * Set the object that will be used to interact with the user. It will be used
+ * for things like prompting the user for passwords.
+ *
+ * The @interaction argument will normally be a derived subclass of
+ * #GTlsInteraction. %NULL can also be provided if no user interaction
+ * should occur for this connection.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_connection_set_interaction (GTlsConnection       *conn,
+                                  GTlsInteraction      *interaction)
+{
+  g_return_if_fail (G_IS_TLS_CONNECTION (conn));
+  g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
+
+  g_object_set (G_OBJECT (conn), "interaction", interaction, NULL);
+}
+
+/**
+ * g_tls_connection_get_interaction:
+ * @conn: a connection
+ *
+ * Get the object that will be used to interact with the user. It will be used
+ * for things like prompting the user for passwords. If %NULL is returned, then
+ * no user interaction will occur for this connection.
+ *
+ * Returns: (transfer none): The interaction object.
+ *
+ * Since: 2.30
+ */
+GTlsInteraction *
+g_tls_connection_get_interaction (GTlsConnection       *conn)
+{
+  GTlsInteraction *interaction = NULL;
+
+  g_return_val_if_fail (G_IS_TLS_CONNECTION (conn), NULL);
+
+  g_object_get (G_OBJECT (conn), "interaction", &interaction, NULL);
+  if (interaction)
+    g_object_unref (interaction);
+
+  return interaction;
+}
+
+/**
  * g_tls_connection_get_peer_certificate:
  * @conn: a #GTlsConnection
  *
diff --git a/gio/gtlsconnection.h b/gio/gtlsconnection.h
index 7786c43..79a8f85 100644
--- a/gio/gtlsconnection.h
+++ b/gio/gtlsconnection.h
@@ -83,14 +83,24 @@ struct _GTlsConnectionClass
 
 GType                 g_tls_connection_get_type                    (void) G_GNUC_CONST;
 
+#ifndef G_DISABLE_DEPRECATED
 void                  g_tls_connection_set_use_system_certdb       (GTlsConnection       *conn,
 								    gboolean              use_system_certdb);
 gboolean              g_tls_connection_get_use_system_certdb       (GTlsConnection       *conn);
+#endif /* G_DISABLE_DEPRECATED */
+
+void                  g_tls_connection_set_database                (GTlsConnection       *conn,
+								    GTlsDatabase         *database);
+GTlsDatabase *        g_tls_connection_get_database                (GTlsConnection       *conn);
 
 void                  g_tls_connection_set_certificate             (GTlsConnection       *conn,
-								    GTlsCertificate      *certificate);
+                                                                    GTlsCertificate      *certificate);
 GTlsCertificate      *g_tls_connection_get_certificate             (GTlsConnection       *conn);
 
+void                  g_tls_connection_set_interaction             (GTlsConnection       *conn,
+                                                                    GTlsInteraction      *interaction);
+GTlsInteraction *     g_tls_connection_get_interaction             (GTlsConnection       *conn);
+
 GTlsCertificate      *g_tls_connection_get_peer_certificate        (GTlsConnection       *conn);
 GTlsCertificateFlags  g_tls_connection_get_peer_certificate_errors (GTlsConnection       *conn);
 
diff --git a/gio/gtlsdatabase.c b/gio/gtlsdatabase.c
new file mode 100644
index 0000000..9f2ff7b
--- /dev/null
+++ b/gio/gtlsdatabase.c
@@ -0,0 +1,967 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2010 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include "gtlsdatabase.h"
+
+#include "gasyncresult.h"
+#include "gcancellable.h"
+#include "glibintl.h"
+#include "gsimpleasyncresult.h"
+#include "gsocketconnectable.h"
+#include "gtlscertificate.h"
+#include "gtlsinteraction.h"
+
+/**
+ * SECTION:gtlsdatabase
+ * @short_description: TLS database type
+ * @include: gio/gio.h
+ *
+ * #GTlsDatabase is used to lookup certificates and other information
+ * from a certificate or key store. It is an abstract base class which
+ * TLS library specific subtypes override.
+ *
+ * Most common client applications will not directly interact with
+ * #GTlsDatabase. It is used internally by #GTlsConnection.
+ *
+ * Since: 2.30
+ */
+
+/**
+ * GTlsDatabase:
+ *
+ * Abstract base class for the backend-specific database types.
+ *
+ * Since: 2.30
+ */
+
+G_DEFINE_ABSTRACT_TYPE (GTlsDatabase, g_tls_database, G_TYPE_OBJECT);
+
+enum {
+  UNLOCK_REQUIRED,
+
+  LAST_SIGNAL
+};
+
+/**
+ * G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER:
+ *
+ * The purpose used to verify the server certificate in a TLS connection. This
+ * is the most common purpose in use. Used by TLS clients.
+ */
+
+/**
+ * G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT:
+ *
+ * The purpose used to verify the client certificate in a TLS connection.
+ * Used by TLS servers.
+ */
+
+static void
+g_tls_database_init (GTlsDatabase *cert)
+{
+
+}
+
+typedef struct _AsyncVerifyChain {
+  GTlsCertificate *chain;
+  gchar *purpose;
+  GSocketConnectable *identity;
+  GTlsInteraction *interaction;
+  GTlsDatabaseVerifyFlags flags;
+  GTlsCertificateFlags verify_result;
+} AsyncVerifyChain;
+
+static void
+async_verify_chain_free (gpointer data)
+{
+  AsyncVerifyChain *args = data;
+  g_clear_object (&args->chain);
+  g_free (args->purpose);
+  g_clear_object (&args->identity);
+  g_clear_object (&args->interaction);
+  g_slice_free (AsyncVerifyChain, args);
+}
+
+static void
+async_verify_chain_thread (GSimpleAsyncResult *res,
+                           GObject            *object,
+                           GCancellable       *cancellable)
+{
+  AsyncVerifyChain *args = g_simple_async_result_get_op_res_gpointer (res);
+  GError *error = NULL;
+
+  args->verify_result = g_tls_database_verify_chain (G_TLS_DATABASE (object),
+                                                     args->chain,
+                                                     args->purpose,
+                                                     args->identity,
+                                                     args->interaction,
+                                                     args->flags,
+                                                     cancellable,
+                                                     &error);
+
+  if (error)
+      g_simple_async_result_take_error (res, error);
+}
+
+static void
+g_tls_database_real_verify_chain_async (GTlsDatabase           *self,
+                                        GTlsCertificate        *chain,
+                                        const gchar            *purpose,
+                                        GSocketConnectable     *identity,
+                                        GTlsInteraction        *interaction,
+                                        GTlsDatabaseVerifyFlags flags,
+                                        GCancellable           *cancellable,
+                                        GAsyncReadyCallback     callback,
+                                        gpointer                user_data)
+{
+  GSimpleAsyncResult *res;
+  AsyncVerifyChain *args;
+
+  args = g_slice_new0 (AsyncVerifyChain);
+  args->chain = g_object_ref (chain);
+  args->purpose = g_strdup (purpose);
+  args->identity = identity ? g_object_ref (identity) : NULL;
+  args->interaction = interaction ? g_object_ref (interaction) : NULL;
+  args->flags = flags;
+
+  res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+                                   g_tls_database_real_verify_chain_async);
+  g_simple_async_result_set_op_res_gpointer (res, args, async_verify_chain_free);
+  g_simple_async_result_run_in_thread (res, async_verify_chain_thread,
+                                       G_PRIORITY_DEFAULT, cancellable);
+  g_object_unref (res);
+}
+
+static GTlsCertificateFlags
+g_tls_database_real_verify_chain_finish (GTlsDatabase          *self,
+                                         GAsyncResult          *result,
+                                         GError               **error)
+{
+  AsyncVerifyChain *args;
+
+  g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), G_TLS_CERTIFICATE_GENERIC_ERROR);
+  g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+                        g_tls_database_real_verify_chain_async), FALSE);
+
+  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+    return G_TLS_CERTIFICATE_GENERIC_ERROR;
+
+  args = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+  return args->verify_result;
+}
+
+typedef struct {
+  gchar *handle;
+  GTlsInteraction *interaction;
+  GTlsDatabaseLookupFlags flags;
+  GTlsCertificate *result;
+} AsyncLookupCertificateForHandle;
+
+static void
+async_lookup_certificate_for_handle_free (gpointer data)
+{
+  AsyncLookupCertificateForHandle *args = data;
+
+  g_free (args->handle);
+  g_clear_object (&args->interaction);
+  g_clear_object (&args->result);
+  g_slice_free (AsyncLookupCertificateForHandle, args);
+}
+
+static void
+async_lookup_certificate_for_handle_thread (GSimpleAsyncResult *res,
+                                            GObject            *object,
+                                            GCancellable       *cancellable)
+{
+  AsyncLookupCertificateForHandle *args = g_simple_async_result_get_op_res_gpointer (res);
+  GError *error = NULL;
+
+  args->result = g_tls_database_lookup_certificate_for_handle (G_TLS_DATABASE (object),
+                                                               args->handle,
+                                                               args->interaction,
+                                                               args->flags,
+                                                               cancellable,
+                                                               &error);
+
+  if (error)
+      g_simple_async_result_take_error (res, error);
+}
+
+static void
+g_tls_database_real_lookup_certificate_for_handle_async (GTlsDatabase           *self,
+                                                         const gchar            *handle,
+                                                         GTlsInteraction        *interaction,
+                                                         GTlsDatabaseLookupFlags flags,
+                                                         GCancellable           *cancellable,
+                                                         GAsyncReadyCallback     callback,
+                                                         gpointer                user_data)
+{
+  GSimpleAsyncResult *res;
+  AsyncLookupCertificateForHandle *args;
+
+  g_return_if_fail (callback != NULL);
+
+  args = g_slice_new0 (AsyncLookupCertificateForHandle);
+  args->handle = g_strdup (handle);
+  args->interaction = interaction ? g_object_ref (interaction) : NULL;
+
+  res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+                                   g_tls_database_real_lookup_certificate_for_handle_async);
+  g_simple_async_result_set_op_res_gpointer (res, args, async_lookup_certificate_for_handle_free);
+  g_simple_async_result_run_in_thread (res, async_lookup_certificate_for_handle_thread,
+                                       G_PRIORITY_DEFAULT, cancellable);
+  g_object_unref (res);
+}
+
+static GTlsCertificate*
+g_tls_database_real_lookup_certificate_for_handle_finish (GTlsDatabase          *self,
+                                                          GAsyncResult          *result,
+                                                          GError               **error)
+{
+  AsyncLookupCertificateForHandle *args;
+  GTlsCertificate *certificate;
+
+  g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+  g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+                        g_tls_database_real_lookup_certificate_for_handle_async), FALSE);
+
+  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+    return NULL;
+
+  args = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+  certificate = args->result;
+  args->result = NULL;
+  return certificate;
+}
+
+
+typedef struct {
+  GTlsCertificate *certificate;
+  GTlsInteraction *interaction;
+  GTlsDatabaseLookupFlags flags;
+  GTlsCertificate *issuer;
+} AsyncLookupCertificateIssuer;
+
+static void
+async_lookup_certificate_issuer_free (gpointer data)
+{
+  AsyncLookupCertificateIssuer *args = data;
+
+  g_clear_object (&args->certificate);
+  g_clear_object (&args->interaction);
+  g_clear_object (&args->issuer);
+  g_slice_free (AsyncLookupCertificateIssuer, args);
+}
+
+static void
+async_lookup_certificate_issuer_thread (GSimpleAsyncResult *res,
+                            GObject            *object,
+                            GCancellable       *cancellable)
+{
+  AsyncLookupCertificateIssuer *args = g_simple_async_result_get_op_res_gpointer (res);
+  GError *error = NULL;
+
+  args->issuer = g_tls_database_lookup_certificate_issuer (G_TLS_DATABASE (object),
+                                                           args->certificate,
+                                                           args->interaction,
+                                                           args->flags,
+                                                           cancellable,
+                                                           &error);
+
+  if (error)
+      g_simple_async_result_take_error (res, error);
+}
+
+static void
+g_tls_database_real_lookup_certificate_issuer_async (GTlsDatabase           *self,
+                                                     GTlsCertificate        *certificate,
+                                                     GTlsInteraction        *interaction,
+                                                     GTlsDatabaseLookupFlags flags,
+                                                     GCancellable           *cancellable,
+                                                     GAsyncReadyCallback     callback,
+                                                     gpointer                user_data)
+{
+  GSimpleAsyncResult *res;
+  AsyncLookupCertificateIssuer *args;
+
+  g_return_if_fail (G_IS_TLS_CERTIFICATE (certificate));
+  g_return_if_fail (callback != NULL);
+
+  args = g_slice_new0 (AsyncLookupCertificateIssuer);
+  args->certificate = g_object_ref (certificate);
+  args->flags = flags;
+  args->interaction = interaction ? g_object_ref (interaction) : NULL;
+
+  res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+                                   g_tls_database_real_lookup_certificate_issuer_async);
+  g_simple_async_result_set_op_res_gpointer (res, args, async_lookup_certificate_issuer_free);
+  g_simple_async_result_run_in_thread (res, async_lookup_certificate_issuer_thread,
+                                       G_PRIORITY_DEFAULT, cancellable);
+  g_object_unref (res);
+}
+
+static GTlsCertificate*
+g_tls_database_real_lookup_certificate_issuer_finish (GTlsDatabase          *self,
+                                                      GAsyncResult          *result,
+                                                      GError               **error)
+{
+  AsyncLookupCertificateIssuer *args;
+  GTlsCertificate *issuer;
+
+  g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+  g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+                        g_tls_database_real_lookup_certificate_issuer_async), FALSE);
+
+  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+    return NULL;
+
+  args = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+  issuer = args->issuer;
+  args->issuer = NULL;
+  return issuer;
+}
+
+typedef struct {
+  GByteArray *issuer;
+  GTlsInteraction *interaction;
+  GTlsDatabaseLookupFlags flags;
+  GList *results;
+} AsyncLookupCertificatesIssuedBy;
+
+static void
+async_lookup_certificates_issued_by_free (gpointer data)
+{
+  AsyncLookupCertificatesIssuedBy *args = data;
+  GList *l;
+
+  g_byte_array_unref (args->issuer);
+  g_clear_object (&args->interaction);
+  for (l = args->results; l; l = g_list_next (l))
+    g_object_unref (l->data);
+  g_list_free (args->results);
+  g_slice_free (AsyncLookupCertificatesIssuedBy, args);
+}
+
+static void
+async_lookup_certificates_issued_by_thread (GSimpleAsyncResult *res,
+                                            GObject            *object,
+                                            GCancellable       *cancellable)
+{
+  AsyncLookupCertificatesIssuedBy *args = g_simple_async_result_get_op_res_gpointer (res);
+  GError *error = NULL;
+
+  args->results = g_tls_database_lookup_certificates_issued_by (G_TLS_DATABASE (object),
+                                                                args->issuer,
+                                                                args->interaction,
+                                                                args->flags,
+                                                                cancellable,
+                                                                &error);
+
+  if (error)
+      g_simple_async_result_take_error (res, error);
+}
+
+static void
+g_tls_database_real_lookup_certificates_issued_by_async (GTlsDatabase           *self,
+                                                         GByteArray             *issuer,
+                                                         GTlsInteraction        *interaction,
+                                                         GTlsDatabaseLookupFlags flags,
+                                                         GCancellable           *cancellable,
+                                                         GAsyncReadyCallback     callback,
+                                                         gpointer                user_data)
+{
+  GSimpleAsyncResult *res;
+  AsyncLookupCertificatesIssuedBy *args;
+
+  g_return_if_fail (callback);
+
+  args = g_slice_new0 (AsyncLookupCertificatesIssuedBy);
+  args->issuer = g_byte_array_ref (issuer);
+  args->flags = flags;
+  args->interaction = interaction ? g_object_ref (interaction) : NULL;
+
+  res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+                                   g_tls_database_real_lookup_certificates_issued_by_async);
+  g_simple_async_result_set_op_res_gpointer (res, args, async_lookup_certificates_issued_by_free);
+  g_simple_async_result_run_in_thread (res, async_lookup_certificates_issued_by_thread,
+                                       G_PRIORITY_DEFAULT, cancellable);
+  g_object_unref (res);
+}
+
+static GList*
+g_tls_database_real_lookup_certificates_issued_by_finish (GTlsDatabase          *self,
+                                                          GAsyncResult          *result,
+                                                          GError               **error)
+{
+  AsyncLookupCertificatesIssuedBy *args;
+  GList *results;
+
+  g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+  g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+                        g_tls_database_real_lookup_certificates_issued_by_async), FALSE);
+
+  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+    return NULL;
+
+  args = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+  results = args->results;
+  args->results = NULL;
+  return results;
+}
+
+static void
+g_tls_database_class_init (GTlsDatabaseClass *klass)
+{
+  klass->verify_chain_async = g_tls_database_real_verify_chain_async;
+  klass->verify_chain_finish = g_tls_database_real_verify_chain_finish;
+  klass->lookup_certificate_for_handle_async = g_tls_database_real_lookup_certificate_for_handle_async;
+  klass->lookup_certificate_for_handle_finish = g_tls_database_real_lookup_certificate_for_handle_finish;
+  klass->lookup_certificate_issuer_async = g_tls_database_real_lookup_certificate_issuer_async;
+  klass->lookup_certificate_issuer_finish = g_tls_database_real_lookup_certificate_issuer_finish;
+  klass->lookup_certificates_issued_by_async = g_tls_database_real_lookup_certificates_issued_by_async;
+  klass->lookup_certificates_issued_by_finish = g_tls_database_real_lookup_certificates_issued_by_finish;
+}
+
+/**
+ * g_tls_database_verify_chain:
+ * @self: a #GTlsDatabase
+ * @chain: a #GTlsCertificate chain
+ * @purpose: the purpose that this certificate chain will be used for.
+ * @identity: (allow-none): the expected peer identity
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: additional verify flags
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Verify's a certificate chain after looking up and adding any missing
+ * certificates to the chain.
+ *
+ * @chain is a chain of #GTlsCertificate objects each pointing to the next
+ * certificate in the chain by its %issuer property. The chain may initially
+ * consist of one or more certificates. After the verification process is
+ * complete, @chain may be modified by adding missing certificates, or removing
+ * extra certificates. If a certificate anchor was found, then it is added to
+ * the @chain.
+ *
+ * @purpose describes the purpose (or usage) for which the certificate
+ * is being used. Typically @purpose will be set to #G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER
+ * which means that the certificate is being used to authenticate a server
+ * (and we are acting as the client).
+ *
+ * The @identity is used to check for pinned certificates (trust exceptions)
+ * in the database. These will override the normal verification process on a
+ * host by host basis.
+ *
+ * Currently there are no @flags, and %G_TLS_DATABASE_VERIFY_NONE should be
+ * used.
+ *
+ * This function can block, use g_tls_database_verify_chain_async() to perform
+ * the verification operation asynchronously.
+ *
+ * Return value: the appropriate #GTlsCertificateFlags which represents the
+ * result of verification.
+ *
+ * Since: 2.30
+ */
+GTlsCertificateFlags
+g_tls_database_verify_chain (GTlsDatabase           *self,
+                             GTlsCertificate        *chain,
+                             const gchar            *purpose,
+                             GSocketConnectable     *identity,
+                             GTlsInteraction        *interaction,
+                             GTlsDatabaseVerifyFlags flags,
+                             GCancellable           *cancellable,
+                             GError                **error)
+{
+  g_return_val_if_fail (G_IS_TLS_DATABASE (self), G_TLS_CERTIFICATE_GENERIC_ERROR);
+  g_return_val_if_fail (G_IS_TLS_DATABASE (self),
+                        G_TLS_CERTIFICATE_GENERIC_ERROR);
+  g_return_val_if_fail (G_IS_TLS_CERTIFICATE (chain),
+                        G_TLS_CERTIFICATE_GENERIC_ERROR);
+  g_return_val_if_fail (purpose, G_TLS_CERTIFICATE_GENERIC_ERROR);
+  g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction),
+                        G_TLS_CERTIFICATE_GENERIC_ERROR);
+  g_return_val_if_fail (identity == NULL || G_IS_SOCKET_CONNECTABLE (identity),
+                        G_TLS_CERTIFICATE_GENERIC_ERROR);
+  g_return_val_if_fail (error == NULL || *error == NULL, G_TLS_CERTIFICATE_GENERIC_ERROR);
+
+  g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain,
+                        G_TLS_CERTIFICATE_GENERIC_ERROR);
+
+  return G_TLS_DATABASE_GET_CLASS (self)->verify_chain (self,
+                                                        chain,
+                                                        purpose,
+                                                        identity,
+                                                        interaction,
+                                                        flags,
+                                                        cancellable,
+                                                        error);
+}
+
+/**
+ * g_tls_database_verify_chain_async:
+ * @self: a #GTlsDatabase
+ * @chain: a #GTlsCertificate chain
+ * @purpose: the purpose that this certificate chain will be used for.
+ * @identity: (allow-none): the expected peer identity
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: additional verify flags
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @callback: callback to call when the operation completes
+ * @user_data: the data to pass to the callback function
+ *
+ * Asynchronously verify's a certificate chain after looking up and adding
+ * any missing certificates to the chain. See g_tls_database_verify_chain()
+ * for more information.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_database_verify_chain_async (GTlsDatabase           *self,
+                                   GTlsCertificate        *chain,
+                                   const gchar            *purpose,
+                                   GSocketConnectable     *identity,
+                                   GTlsInteraction        *interaction,
+                                   GTlsDatabaseVerifyFlags flags,
+                                   GCancellable           *cancellable,
+                                   GAsyncReadyCallback     callback,
+                                   gpointer                user_data)
+{
+  g_return_if_fail (G_IS_TLS_DATABASE (self));
+  g_return_if_fail (G_IS_TLS_CERTIFICATE (chain));
+  g_return_if_fail (purpose != NULL);
+  g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
+  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+  g_return_if_fail (identity == NULL || G_IS_SOCKET_CONNECTABLE (identity));
+  g_return_if_fail (callback != NULL);
+
+  g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain_async);
+  G_TLS_DATABASE_GET_CLASS (self)->verify_chain_async (self,
+                                                       chain,
+                                                       purpose,
+                                                       identity,
+                                                       interaction,
+                                                       flags,
+                                                       cancellable,
+                                                       callback,
+                                                       user_data);
+}
+
+/**
+ * g_tls_database_verify_chain_finish:
+ * @self: a #GTlsDatabase
+ * @result: a #GAsyncResult.
+ * @error: a #GError pointer, or %NULL
+ *
+ * Finish an asynchronous verify chain operation. See
+ * g_tls_database_verify_chain() for more information. *
+ * Return value: the appropriate #GTlsCertificateFlags which represents the
+ * result of verification.
+ *
+ * Since: 2.30
+ */
+GTlsCertificateFlags
+g_tls_database_verify_chain_finish (GTlsDatabase          *self,
+                                    GAsyncResult          *result,
+                                    GError               **error)
+{
+  g_return_val_if_fail (G_IS_TLS_DATABASE (self), G_TLS_CERTIFICATE_GENERIC_ERROR);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), G_TLS_CERTIFICATE_GENERIC_ERROR);
+  g_return_val_if_fail (error == NULL || *error == NULL, G_TLS_CERTIFICATE_GENERIC_ERROR);
+  g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->verify_chain_finish,
+                        G_TLS_CERTIFICATE_GENERIC_ERROR);
+  return G_TLS_DATABASE_GET_CLASS (self)->verify_chain_finish (self,
+                                                               result,
+                                                               error);
+}
+
+/**
+ * g_tls_database_create_certificate_handle:
+ * @self: a #GTlsDatabase
+ * @certificate: certificate for which to create a handle.
+ *
+ * Create a handle string for the certificate. The database will only be able
+ * to create a handle for certificates that originate from the database. In
+ * cases where the database cannot create a handle for a certificate, %NULL
+ * will be returned.
+ *
+ * This handle should be stable across various instances of the application,
+ * and between applications. If a certificate is modified in the database,
+ * then it is not guaranteed that this handle will continue to point to it.
+ *
+ * Returns: (allow-none): a newly allocated string containing the handle.
+ * Since: 2.30
+ */
+gchar*
+g_tls_database_create_certificate_handle (GTlsDatabase            *self,
+                                          GTlsCertificate         *certificate)
+{
+  g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
+  g_return_val_if_fail (G_IS_TLS_CERTIFICATE (certificate), NULL);
+  g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->create_certificate_handle, NULL);
+  return G_TLS_DATABASE_GET_CLASS (self)->create_certificate_handle (self,
+                                                                     certificate);
+}
+
+/**
+ * g_tls_database_lookup_certificate_for_handle:
+ * @self: a #GTlsDatabase
+ * @handle: a certificate handle
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: Flags which affect the lookup.
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Lookup a certificate by its handle.
+ *
+ * The handle should have been created by calling g_tls_database_create_handle()
+ * on a #GTlsDatabase object of the same TLS backend. The handle is designed
+ * to remain valid across instantiations of the database.
+ *
+ * If the handle is no longer valid, or does not point to a certificate in
+ * this database, then %NULL will be returned.
+ *
+ * This function can block, use g_tls_database_lookup_certificate_for_handle_async() to perform
+ * the lookup operation asynchronously.
+ *
+ * Return value: (transfer full) (allow-none): a newly allocated
+ * #GTlsCertificate, or %NULL. Use g_object_unref() to release the certificate.
+ *
+ * Since: 2.30
+ */
+GTlsCertificate*
+g_tls_database_lookup_certificate_for_handle (GTlsDatabase            *self,
+                                              const gchar             *handle,
+                                              GTlsInteraction         *interaction,
+                                              GTlsDatabaseLookupFlags  flags,
+                                              GCancellable            *cancellable,
+                                              GError                 **error)
+{
+  g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
+  g_return_val_if_fail (handle != NULL, NULL);
+  g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL);
+  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+  g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle, NULL);
+  return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle (self,
+                                                                         handle,
+                                                                         interaction,
+                                                                         flags,
+                                                                         cancellable,
+                                                                         error);
+}
+
+
+/**
+ * g_tls_database_lookup_certificate_for_handle_async:
+ * @self: a #GTlsDatabase
+ * @handle: a certificate handle
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: Flags which affect the lookup.
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @callback: callback to call when the operation completes
+ * @user_data: the data to pass to the callback function
+ *
+ * Asynchronously lookup a certificate by its handle in the database. See
+ * g_tls_database_lookup_handle() for more information.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_database_lookup_certificate_for_handle_async (GTlsDatabase            *self,
+                                                    const gchar             *handle,
+                                                    GTlsInteraction         *interaction,
+                                                    GTlsDatabaseLookupFlags  flags,
+                                                    GCancellable            *cancellable,
+                                                    GAsyncReadyCallback      callback,
+                                                    gpointer                 user_data)
+{
+  g_return_if_fail (G_IS_TLS_DATABASE (self));
+  g_return_if_fail (handle != NULL);
+  g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
+  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+  g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_async);
+  return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_async (self,
+                                                                               handle,
+                                                                               interaction,
+                                                                               flags,
+                                                                               cancellable,
+                                                                               callback,
+                                                                               user_data);
+}
+
+/**
+ * g_tls_database_lookup_certificate_for_handle_finish:
+ * @self: a #GTlsDatabase
+ * @result: a #GAsyncResult.
+ * @error: a #GError pointer, or %NULL
+ *
+ * Finish an asynchronous lookup of a certificate by its handle. See
+ * g_tls_database_lookup_handle() for more information.
+ *
+ * If the handle is no longer valid, or does not point to a certificate in
+ * this database, then %NULL will be returned.
+ *
+ * Return value: (transfer full): a newly allocated #GTlsCertificate object.
+ * Use g_object_unref() to release the certificate.
+ *
+ * Since: 2.30
+ */
+GTlsCertificate*
+g_tls_database_lookup_certificate_for_handle_finish (GTlsDatabase            *self,
+                                                     GAsyncResult            *result,
+                                                     GError                 **error)
+{
+  g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+  g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_finish, NULL);
+  return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_for_handle_finish (self,
+                                                                                result,
+                                                                                error);
+}
+
+/**
+ * g_tls_database_lookup_certificate_issuer:
+ * @self: a #GTlsDatabase
+ * @certificate: a #GTlsCertificate
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: flags which affect the lookup operation
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Lookup the issuer of @certificate in the database.
+ *
+ * The %issuer property
+ * of @certificate is not modified, and the two certificates are not hooked
+ * into a chain.
+ *
+ * This function can block, use g_tls_database_lookup_certificate_issuer_async() to perform
+ * the lookup operation asynchronously.
+ *
+ * Return value: (transfer full): a newly allocated issuer #GTlsCertificate,
+ * or %NULL. Use g_object_unref() to release the certificate.
+ *
+ * Since: 2.30
+ */
+GTlsCertificate*
+g_tls_database_lookup_certificate_issuer (GTlsDatabase           *self,
+                                          GTlsCertificate        *certificate,
+                                          GTlsInteraction        *interaction,
+                                          GTlsDatabaseLookupFlags flags,
+                                          GCancellable           *cancellable,
+                                          GError                **error)
+{
+  g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
+  g_return_val_if_fail (G_IS_TLS_CERTIFICATE (certificate), NULL);
+  g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL);
+  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+  g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer, NULL);
+  return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer (self,
+                                                                     certificate,
+                                                                     interaction,
+                                                                     flags,
+                                                                     cancellable,
+                                                                     error);
+}
+
+/**
+ * g_tls_database_lookup_certificate_issuer_async:
+ * @self: a #GTlsDatabase
+ * @certificate: a #GTlsCertificate
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: flags which affect the lookup operation
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @callback: callback to call when the operation completes
+ * @user_data: the data to pass to the callback function
+ *
+ * Asynchronously lookup the issuer of @certificate in the database. See
+ * g_tls_database_lookup_certificate_issuer() for more information.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_database_lookup_certificate_issuer_async (GTlsDatabase           *self,
+                                                GTlsCertificate        *certificate,
+                                                GTlsInteraction        *interaction,
+                                                GTlsDatabaseLookupFlags flags,
+                                                GCancellable           *cancellable,
+                                                GAsyncReadyCallback     callback,
+                                                gpointer                user_data)
+{
+  g_return_if_fail (G_IS_TLS_DATABASE (self));
+  g_return_if_fail (G_IS_TLS_CERTIFICATE (certificate));
+  g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
+  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+  g_return_if_fail (callback != NULL);
+  g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_async);
+  G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_async (self,
+                                                        certificate,
+                                                        interaction,
+                                                        flags,
+                                                        cancellable,
+                                                        callback,
+                                                        user_data);
+}
+
+/**
+ * g_tls_database_lookup_certificate_issuer_finish:
+ * @self: a #GTlsDatabase
+ * @result: a #GAsyncResult.
+ * @error: a #GError pointer, or %NULL
+ *
+ * Finish an asynchronous lookup issuer operation. See
+ * g_tls_database_lookup_certificate_issuer() for more information.
+ *
+ * Return value: (transfer full): a newly allocated issuer #GTlsCertificate,
+ * or %NULL. Use g_object_unref() to release the certificate.
+ *
+ * Since: 2.30
+ */
+GTlsCertificate*
+g_tls_database_lookup_certificate_issuer_finish (GTlsDatabase          *self,
+                                                 GAsyncResult          *result,
+                                                 GError               **error)
+{
+  g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+  g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_finish, NULL);
+  return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificate_issuer_finish (self,
+                                                                result,
+                                                                error);
+}
+
+/**
+ * g_tls_database_lookup_certificates_issued_by:
+ * @self: a #GTlsDatabase
+ * @issuer_raw_dn: a #GByteArray which holds the DER encoded issuer DN.
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: Flags which affect the lookup operation.
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @error: (allow-none): a #GError, or %NULL
+ *
+ * Lookup certificates issued by this issuer in the database.
+ *
+ * This function can block, use g_tls_database_lookup_certificates_issued_by_async() to perform
+ * the lookup operation asynchronously.
+ *
+ * Return value: (transfer full): a newly allocated list of #GTlsCertificate objects.
+ * Use g_object_unref() on each certificate, and g_list_free() on the release the list.
+ *
+ * Since: 2.30
+ */
+GList*
+g_tls_database_lookup_certificates_issued_by (GTlsDatabase           *self,
+                                              GByteArray             *issuer_raw_dn,
+                                              GTlsInteraction        *interaction,
+                                              GTlsDatabaseLookupFlags flags,
+                                              GCancellable           *cancellable,
+                                              GError                **error)
+{
+  g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
+  g_return_val_if_fail (issuer_raw_dn, NULL);
+  g_return_val_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction), NULL);
+  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+  g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by, NULL);
+  return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by (self,
+                                                                         issuer_raw_dn,
+                                                                         interaction,
+                                                                         flags,
+                                                                         cancellable,
+                                                                         error);
+}
+
+/**
+ * g_tls_database_lookup_certificates_issued_by_async:
+ * @self: a #GTlsDatabase
+ * @issuer_raw_dn: a #GByteArray which holds the DER encoded issuer DN.
+ * @interaction: (allow-none): used to interact with the user if necessary
+ * @flags: Flags which affect the lookup operation.
+ * @cancellable: (allow-none): a #GCancellable, or %NULL
+ * @callback: callback to call when the operation completes
+ * @user_data: the data to pass to the callback function
+ *
+ * Asynchronously lookup certificates issued by this issuer in the database. See
+ * g_tls_database_lookup_certificates_issued_by() for more information.
+ *
+ * The database may choose to hold a reference to the issuer byte array for the duration
+ * of of this asynchronous operation. The byte array should not be modified during
+ * this time.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_database_lookup_certificates_issued_by_async (GTlsDatabase           *self,
+                                                    GByteArray             *issuer_raw_dn,
+                                                    GTlsInteraction        *interaction,
+                                                    GTlsDatabaseLookupFlags flags,
+                                                    GCancellable           *cancellable,
+                                                    GAsyncReadyCallback     callback,
+                                                    gpointer                user_data)
+{
+  g_return_if_fail (G_IS_TLS_DATABASE (self));
+  g_return_if_fail (issuer_raw_dn != NULL);
+  g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
+  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+  g_return_if_fail (callback != NULL);
+  g_return_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_async);
+  G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_async (self,
+                                                                        issuer_raw_dn,
+                                                                        interaction,
+                                                                        flags,
+                                                                        cancellable,
+                                                                        callback,
+                                                                        user_data);
+}
+
+/**
+ * g_tls_database_lookup_certificates_issued_by_finish:
+ * @self: a #GTlsDatabase
+ * @result: a #GAsyncResult.
+ * @error: a #GError pointer, or %NULL
+ *
+ * Finish an asynchronous lookup of certificates. See
+ * g_tls_database_lookup_certificates_issued_by() for more information.
+ *
+ * Return value: (transfer full): a newly allocated list of #GTlsCertificate objects.
+ * Use g_object_unref() on each certificate, and g_list_free() on the release the list.
+ *
+ * Since: 2.30
+ */
+GList*
+g_tls_database_lookup_certificates_issued_by_finish (GTlsDatabase          *self,
+                                                     GAsyncResult          *result,
+                                                     GError               **error)
+{
+  g_return_val_if_fail (G_IS_TLS_DATABASE (self), NULL);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+  g_return_val_if_fail (G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_finish, NULL);
+  return G_TLS_DATABASE_GET_CLASS (self)->lookup_certificates_issued_by_finish (self,
+                                                                                result,
+                                                                                error);
+}
diff --git a/gio/gtlsdatabase.h b/gio/gtlsdatabase.h
new file mode 100644
index 0000000..9f93cc9
--- /dev/null
+++ b/gio/gtlsdatabase.h
@@ -0,0 +1,235 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2010 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#ifndef __G_TLS_DATABASE_H__
+#define __G_TLS_DATABASE_H__
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER "1.3.6.1.5.5.7.3.1"
+#define G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT "1.3.6.1.5.5.7.3.2"
+
+#define G_TYPE_TLS_DATABASE            (g_tls_database_get_type ())
+#define G_TLS_DATABASE(inst)           (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_TLS_DATABASE, GTlsDatabase))
+#define G_TLS_DATABASE_CLASS(class)    (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_TLS_DATABASE, GTlsDatabaseClass))
+#define G_IS_TLS_DATABASE(inst)        (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_TLS_DATABASE))
+#define G_IS_TLS_DATABASE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_TLS_DATABASE))
+#define G_TLS_DATABASE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), G_TYPE_TLS_DATABASE, GTlsDatabaseClass))
+
+typedef struct _GTlsDatabaseClass   GTlsDatabaseClass;
+typedef struct _GTlsDatabasePrivate GTlsDatabasePrivate;
+
+struct _GTlsDatabase
+{
+  GObject parent_instance;
+
+  GTlsDatabasePrivate *priv;
+};
+
+struct _GTlsDatabaseClass
+{
+  GObjectClass parent_class;
+
+  /* virtual methods */
+
+  GTlsCertificateFlags  (*verify_chain)                         (GTlsDatabase            *self,
+                                                                 GTlsCertificate         *chain,
+                                                                 const gchar             *purpose,
+                                                                 GSocketConnectable      *identity,
+                                                                 GTlsInteraction         *interaction,
+                                                                 GTlsDatabaseVerifyFlags  flags,
+                                                                 GCancellable            *cancellable,
+                                                                 GError                 **error);
+
+  void                  (*verify_chain_async)                   (GTlsDatabase            *self,
+                                                                 GTlsCertificate         *chain,
+                                                                 const gchar             *purpose,
+                                                                 GSocketConnectable      *identity,
+                                                                 GTlsInteraction         *interaction,
+                                                                 GTlsDatabaseVerifyFlags  flags,
+                                                                 GCancellable            *cancellable,
+                                                                 GAsyncReadyCallback      callback,
+                                                                 gpointer                 user_data);
+
+  GTlsCertificateFlags  (*verify_chain_finish)                  (GTlsDatabase            *self,
+                                                                 GAsyncResult            *result,
+                                                                 GError                 **error);
+
+  gchar*                (*create_certificate_handle)            (GTlsDatabase            *self,
+                                                                 GTlsCertificate         *certificate);
+
+  GTlsCertificate*      (*lookup_certificate_for_handle)        (GTlsDatabase            *self,
+                                                                 const gchar             *handle,
+                                                                 GTlsInteraction         *interaction,
+                                                                 GTlsDatabaseLookupFlags  flags,
+                                                                 GCancellable            *cancellable,
+                                                                 GError                 **error);
+
+  void                  (*lookup_certificate_for_handle_async)  (GTlsDatabase            *self,
+                                                                 const gchar             *handle,
+                                                                 GTlsInteraction         *interaction,
+                                                                 GTlsDatabaseLookupFlags  flags,
+                                                                 GCancellable            *cancellable,
+                                                                 GAsyncReadyCallback      callback,
+                                                                 gpointer                 user_data);
+
+  GTlsCertificate*      (*lookup_certificate_for_handle_finish) (GTlsDatabase            *self,
+                                                                 GAsyncResult            *result,
+                                                                 GError                 **error);
+
+  GTlsCertificate*      (*lookup_certificate_issuer)            (GTlsDatabase            *self,
+                                                                 GTlsCertificate         *certificate,
+                                                                 GTlsInteraction         *interaction,
+                                                                 GTlsDatabaseLookupFlags  flags,
+                                                                 GCancellable            *cancellable,
+                                                                 GError                 **error);
+
+  void                  (*lookup_certificate_issuer_async)      (GTlsDatabase            *self,
+                                                                 GTlsCertificate         *certificate,
+                                                                 GTlsInteraction         *interaction,
+                                                                 GTlsDatabaseLookupFlags  flags,
+                                                                 GCancellable            *cancellable,
+                                                                 GAsyncReadyCallback      callback,
+                                                                 gpointer                 user_data);
+
+  GTlsCertificate*      (*lookup_certificate_issuer_finish)     (GTlsDatabase            *self,
+                                                                 GAsyncResult            *result,
+                                                                 GError                 **error);
+
+  GList*                (*lookup_certificates_issued_by)        (GTlsDatabase            *self,
+                                                                 GByteArray              *issuer_raw_dn,
+                                                                 GTlsInteraction         *interaction,
+                                                                 GTlsDatabaseLookupFlags  flags,
+                                                                 GCancellable            *cancellable,
+                                                                 GError                 **error);
+
+  void                  (*lookup_certificates_issued_by_async)  (GTlsDatabase            *self,
+                                                                 GByteArray              *issuer_raw_dn,
+                                                                 GTlsInteraction         *interaction,
+                                                                 GTlsDatabaseLookupFlags  flags,
+                                                                 GCancellable            *cancellable,
+                                                                 GAsyncReadyCallback      callback,
+                                                                 gpointer                 user_data);
+
+  GList*                (*lookup_certificates_issued_by_finish) (GTlsDatabase            *self,
+                                                                 GAsyncResult            *result,
+                                                                 GError                 **error);
+
+  /*< private >*/
+  /* Padding for future expansion */
+  gpointer padding[16];
+};
+
+GType                g_tls_database_get_type                              (void) G_GNUC_CONST;
+
+GTlsCertificateFlags g_tls_database_verify_chain                          (GTlsDatabase            *self,
+                                                                           GTlsCertificate         *chain,
+                                                                           const gchar             *purpose,
+                                                                           GSocketConnectable      *identity,
+                                                                           GTlsInteraction         *interaction,
+                                                                           GTlsDatabaseVerifyFlags  flags,
+                                                                           GCancellable            *cancellable,
+                                                                           GError                 **error);
+
+void                 g_tls_database_verify_chain_async                    (GTlsDatabase            *self,
+                                                                           GTlsCertificate         *chain,
+                                                                           const gchar             *purpose,
+                                                                           GSocketConnectable      *identity,
+                                                                           GTlsInteraction         *interaction,
+                                                                           GTlsDatabaseVerifyFlags  flags,
+                                                                           GCancellable            *cancellable,
+                                                                           GAsyncReadyCallback      callback,
+                                                                           gpointer                 user_data);
+
+GTlsCertificateFlags g_tls_database_verify_chain_finish                   (GTlsDatabase            *self,
+                                                                           GAsyncResult            *result,
+                                                                           GError                 **error);
+
+gchar*               g_tls_database_create_certificate_handle             (GTlsDatabase            *self,
+                                                                           GTlsCertificate         *certificate);
+
+GTlsCertificate*     g_tls_database_lookup_certificate_for_handle         (GTlsDatabase            *self,
+                                                                           const gchar             *handle,
+                                                                           GTlsInteraction         *interaction,
+                                                                           GTlsDatabaseLookupFlags  flags,
+                                                                           GCancellable            *cancellable,
+                                                                           GError                 **error);
+
+void                 g_tls_database_lookup_certificate_for_handle_async   (GTlsDatabase            *self,
+                                                                           const gchar             *handle,
+                                                                           GTlsInteraction         *interaction,
+                                                                           GTlsDatabaseLookupFlags  flags,
+                                                                           GCancellable            *cancellable,
+                                                                           GAsyncReadyCallback      callback,
+                                                                           gpointer                 user_data);
+
+GTlsCertificate*     g_tls_database_lookup_certificate_for_handle_finish  (GTlsDatabase            *self,
+                                                                           GAsyncResult            *result,
+                                                                           GError                 **error);
+
+GTlsCertificate*     g_tls_database_lookup_certificate_issuer             (GTlsDatabase            *self,
+                                                                           GTlsCertificate         *certificate,
+                                                                           GTlsInteraction         *interaction,
+                                                                           GTlsDatabaseLookupFlags  flags,
+                                                                           GCancellable            *cancellable,
+                                                                           GError                 **error);
+
+void                 g_tls_database_lookup_certificate_issuer_async       (GTlsDatabase            *self,
+                                                                           GTlsCertificate         *certificate,
+                                                                           GTlsInteraction         *interaction,
+                                                                           GTlsDatabaseLookupFlags  flags,
+                                                                           GCancellable            *cancellable,
+                                                                           GAsyncReadyCallback      callback,
+                                                                           gpointer                 user_data);
+
+GTlsCertificate*     g_tls_database_lookup_certificate_issuer_finish      (GTlsDatabase            *self,
+                                                                           GAsyncResult            *result,
+                                                                           GError                 **error);
+
+GList*               g_tls_database_lookup_certificates_issued_by         (GTlsDatabase            *self,
+                                                                           GByteArray              *issuer_raw_dn,
+                                                                           GTlsInteraction         *interaction,
+                                                                           GTlsDatabaseLookupFlags  flags,
+                                                                           GCancellable            *cancellable,
+                                                                           GError                 **error);
+
+void                 g_tls_database_lookup_certificates_issued_by_async    (GTlsDatabase            *self,
+                                                                            GByteArray              *issuer_raw_dn,
+                                                                            GTlsInteraction         *interaction,
+                                                                            GTlsDatabaseLookupFlags  flags,
+                                                                            GCancellable            *cancellable,
+                                                                            GAsyncReadyCallback      callback,
+                                                                            gpointer                 user_data);
+
+GList*               g_tls_database_lookup_certificates_issued_by_finish   (GTlsDatabase            *self,
+                                                                            GAsyncResult            *result,
+                                                                            GError                 **error);
+
+G_END_DECLS
+
+#endif /* __G_TLS_DATABASE_H__ */
diff --git a/gio/gtlsfiledatabase.c b/gio/gtlsfiledatabase.c
new file mode 100644
index 0000000..0c59722
--- /dev/null
+++ b/gio/gtlsfiledatabase.c
@@ -0,0 +1,104 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2010 Collabora, Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include "gtlsfiledatabase.h"
+
+#include "ginitable.h"
+#include "gtlsbackend.h"
+#include "gtlsdatabase.h"
+#include "glibintl.h"
+
+/**
+ * SECTION:gtlsfiledatabase
+ * @short_description: TLS file based database type
+ * @include: gio/gio.h
+ *
+ * #GTlsFileDatabase is implemented by #GTlsDatabase objects which load
+ * their certificate information from a file. It is in interface which
+ * TLS library specific subtypes implement.
+ *
+ * Since: 2.30
+ */
+
+/**
+ * GTlsFileDatabase:
+ *
+ * Implemented by a #GTlsDatabase which allows you to load certificates
+ * from a file.
+ *
+ * Since: 2.30
+ */
+G_DEFINE_INTERFACE (GTlsFileDatabase, g_tls_file_database, G_TYPE_TLS_DATABASE)
+
+static void
+g_tls_file_database_default_init (GTlsFileDatabaseInterface *iface)
+{
+  /**
+   * GTlsFileDatabase:anchors:
+   *
+   * The path to a file containing PEM encoded certificate authority
+   * root anchors. The certificates in this file will be treated as
+   * root authorities for the purpose of verifying other certificates
+   * via the g_tls_database_verify_chain() operation.
+   *
+   * Since: 2.30
+   */
+  g_object_interface_install_property (iface,
+                                       g_param_spec_string ("anchors",
+                                                           P_("Anchors"),
+                                                           P_("The certificate authority anchor file"),
+                                                           NULL,
+                                                           G_PARAM_READWRITE |
+                                                           G_PARAM_CONSTRUCT |
+                                                           G_PARAM_STATIC_STRINGS));
+}
+
+/**
+ * g_tls_file_database_new:
+ * @anchors: filename of anchor certificate authorities.
+ * @error: #GError for error reporting, or %NULL to ignore.
+ *
+ * Creates a new #GTlsFileDatabase which uses anchor certificate authorities
+ * in @anchors to verify certificate chains.
+ *
+ * The certificates in @anchors must be PEM encoded.
+ *
+ * Return value: the new #GTlsFileDatabase, or %NULL on error
+ *
+ * Since: 2.30
+ */
+GTlsDatabase*
+g_tls_file_database_new (const gchar     *anchors,
+                         GError         **error)
+{
+  GObject *database;
+  GTlsBackend *backend;
+
+  backend = g_tls_backend_get_default ();
+  database = g_initable_new (g_tls_backend_get_file_database_type (backend),
+                             NULL, error,
+                             "anchors", anchors,
+                             NULL);
+  return G_TLS_DATABASE (database);
+}
diff --git a/gio/gtlsfiledatabase.h b/gio/gtlsfiledatabase.h
new file mode 100644
index 0000000..bc6a17f
--- /dev/null
+++ b/gio/gtlsfiledatabase.h
@@ -0,0 +1,56 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2010 Collabora, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the licence or (at
+ * your option) any later version.
+ *
+ * See the included COPYING file for more information.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#ifndef __G_TLS_FILE_DATABASE_H__
+#define __G_TLS_FILE_DATABASE_H__
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_TLS_FILE_DATABASE                (g_tls_file_database_get_type ())
+#define G_TLS_FILE_DATABASE(inst)               (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_TLS_FILE_DATABASE, GTlsFileDatabase))
+#define G_IS_TLS_FILE_DATABASE(inst)            (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_TLS_FILE_DATABASE))
+#define G_TLS_FILE_DATABASE_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), G_TYPE_TLS_FILE_DATABASE, GTlsFileDatabaseInterface))
+
+typedef struct _GTlsFileDatabaseInterface GTlsFileDatabaseInterface;
+
+/**
+ * GTlsFileDatabaseInterface:
+ * @g_iface: The parent interface.
+ *
+ * Provides an interface for #GTlsFileDatabase implementations.
+ *
+ */
+struct _GTlsFileDatabaseInterface
+{
+  GTypeInterface g_iface;
+
+  /*< private >*/
+  /* Padding for future expansion */
+  gpointer padding[8];
+};
+
+GType                        g_tls_file_database_get_type              (void) G_GNUC_CONST;
+
+GTlsDatabase*                g_tls_file_database_new                   (const gchar  *anchors,
+                                                                        GError      **error);
+
+G_END_DECLS
+
+#endif /* __G_TLS_FILE_DATABASE_H___ */
diff --git a/gio/gtlsinteraction.c b/gio/gtlsinteraction.c
new file mode 100644
index 0000000..2e1f7ad
--- /dev/null
+++ b/gio/gtlsinteraction.c
@@ -0,0 +1,197 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2011 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gtlsinteraction.h"
+#include "gtlspassword.h"
+#include "gasyncresult.h"
+#include "gsimpleasyncresult.h"
+#include "gioenumtypes.h"
+#include "glibintl.h"
+
+
+/**
+ * SECTION:gtlsinteraction
+ * @short_description: Interaction with the user during TLS operations.
+ * @include: gio/gio.h
+ *
+ * #GTlsInteraction provides a mechanism for the TLS connection and database
+ * code to interact with the user. It can be used to ask the user for passwords.
+ *
+ * To use a #GTlsInteraction with a TLS connection use
+ * g_tls_connection_set_interaction().
+ *
+ * Callers should instantiate a subclass of this that implements all the
+ * various callbacks to show the required dialogs, such as
+ * #GtkTlsInteraction. If no interaction is desired, usually %NULL can be
+ * passed, see each method taking a #GTlsInteraction for details.
+ */
+
+/**
+ * GTlsInteraction:
+ *
+ * An object representing interaction that the TLS connection and database
+ * might have with the user.
+ *
+ * Since: 2.30
+ */
+
+/**
+ * GTlsInteractionClass:
+ *
+ * The class for #GTlsInteraction.
+ *
+ * Since: 2.30
+ */
+
+G_DEFINE_TYPE (GTlsInteraction, g_tls_interaction, G_TYPE_OBJECT);
+
+GTlsInteractionResult
+g_tls_interaction_default_ask_password (GTlsInteraction    *interaction,
+                                        GTlsPassword       *password)
+{
+  return G_TLS_INTERACTION_UNHANDLED;
+}
+
+void
+g_tls_interaction_default_ask_password_async (GTlsInteraction    *interaction,
+                                              GTlsPassword       *password,
+                                              GAsyncReadyCallback callback,
+                                              gpointer            user_data)
+{
+  GSimpleAsyncResult *res;
+
+  res = g_simple_async_result_new (G_OBJECT (interaction), callback, user_data,
+                                   g_tls_interaction_default_ask_password);
+  g_simple_async_result_complete_in_idle (res);
+  g_object_unref (res);
+}
+
+GTlsInteractionResult
+g_tls_interaction_default_ask_password_finish (GTlsInteraction    *interaction,
+                                               GAsyncResult       *result)
+{
+  g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (interaction),
+                        g_tls_interaction_default_ask_password), G_TLS_INTERACTION_UNHANDLED);
+  return G_TLS_INTERACTION_UNHANDLED;
+}
+
+static void
+g_tls_interaction_init (GTlsInteraction *interaction)
+{
+}
+
+static void
+g_tls_interaction_class_init (GTlsInteractionClass *klass)
+{
+  klass->ask_password = g_tls_interaction_default_ask_password;
+  klass->ask_password_async = g_tls_interaction_default_ask_password_async;
+  klass->ask_password_finish = g_tls_interaction_default_ask_password_finish;
+}
+
+/**
+ * g_tls_interaction_ask_password:
+ * @interaction: a #GTlsInteraction object
+ * @password: a #GTlsPassword object
+ *
+ * This function is normally called by #GTlsConnection or #GTlsDatabase to
+ * ask the user for a password.
+ *
+ * Derived subclasses usually implement a password prompt, although they may
+ * also choose to provide a password from elsewhere. The @password value will
+ * be filled in and then @callback will be called. Alternatively the user may
+ * abort this password request, which will usually abort the TLS connection.
+ *
+ * Returns: The status of the ask password interaction.
+ *
+ * Since: 2.30
+ */
+GTlsInteractionResult
+g_tls_interaction_ask_password (GTlsInteraction    *interaction,
+                                GTlsPassword       *password)
+{
+  g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED);
+  g_return_val_if_fail (G_IS_TLS_PASSWORD (password), G_TLS_INTERACTION_UNHANDLED);
+  return G_TLS_INTERACTION_GET_CLASS (interaction)->ask_password (interaction, password);
+}
+
+/**
+ * g_tls_interaction_ask_password_async:
+ * @interaction: a #GTlsInteraction object
+ * @password: a #GTlsPassword object
+ * @callback: will be called when the interaction completes
+ * @user_data: (allow-none): data to pass to the @callback
+ *
+ * This function is normally called by #GTlsConnection or #GTlsDatabase to
+ * ask the user for a password.
+ *
+ * Derived subclasses usually implement a password prompt, although they may
+ * also choose to provide a password from elsewhere. The @password value will
+ * be filled in and then @callback will be called. Alternatively the user may
+ * abort this password request, which will usually abort the TLS connection.
+ *
+ * The @callback will be invoked on thread-default main context of the thread
+ * that called this function. The @callback should call
+ * g_tls_interaction_ask_password_finish() to get the status of the user
+ * interaction.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_interaction_ask_password_async (GTlsInteraction    *interaction,
+                                      GTlsPassword       *password,
+                                      GAsyncReadyCallback callback,
+                                      gpointer            user_data)
+{
+  g_return_if_fail (G_IS_TLS_INTERACTION (interaction));
+  g_return_if_fail (G_IS_TLS_PASSWORD (password));
+  g_return_if_fail (callback != NULL);
+  G_TLS_INTERACTION_GET_CLASS (interaction)->ask_password_async (interaction, password,
+                                                                 callback, user_data);
+}
+
+/**
+ * g_tls_interaction_ask_password_finish:
+ * @interaction: a #GTlsInteraction object
+ * @result: the result passed to the callback
+ *
+ * Complete an ask password user interaction request. This should be once
+ * the g_tls_interaction_ask_password() completion callback is called.
+ *
+ * If %G_TLS_INTERACTION_HANDLED is returned, then the #GTlsPassword passed
+ * to g_tls_interaction_ask_password() will have its password filled in.
+ *
+ * Returns: The status of the ask password interaction.
+ *
+ * Since: 2.30
+ */
+GTlsInteractionResult
+g_tls_interaction_ask_password_finish (GTlsInteraction    *interaction,
+                                       GAsyncResult       *result)
+{
+  g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), G_TLS_INTERACTION_UNHANDLED);
+  return G_TLS_INTERACTION_GET_CLASS (interaction)->ask_password_finish (interaction, result);
+}
diff --git a/gio/gtlsinteraction.h b/gio/gtlsinteraction.h
new file mode 100644
index 0000000..68b313f
--- /dev/null
+++ b/gio/gtlsinteraction.h
@@ -0,0 +1,101 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2011 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#ifndef __G_TLS_INTERACTION_H__
+#define __G_TLS_INTERACTION_H__
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_TLS_INTERACTION         (g_tls_interaction_get_type ())
+#define G_TLS_INTERACTION(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_TLS_INTERACTION, GTlsInteraction))
+#define G_TLS_INTERACTION_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_TLS_INTERACTION, GTlsInteractionClass))
+#define G_IS_TLS_INTERACTION(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_TLS_INTERACTION))
+#define G_IS_TLS_INTERACTION_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_TLS_INTERACTION))
+#define G_TLS_INTERACTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_TLS_INTERACTION, GTlsInteractionClass))
+
+typedef struct _GTlsInteractionClass   GTlsInteractionClass;
+typedef struct _GTlsInteractionPrivate GTlsInteractionPrivate;
+
+struct _GTlsInteraction
+{
+  GObject parent_instance;
+
+  GTlsInteractionPrivate *priv;
+};
+
+struct _GTlsInteractionClass
+{
+  GObjectClass parent_class;
+
+  /* virtual methods: */
+
+  GTlsInteractionResult  (* ask_password)        (GTlsInteraction    *interaction,
+                                                  GTlsPassword       *password);
+
+  void                   (* ask_password_async)  (GTlsInteraction    *interaction,
+                                                  GTlsPassword       *password,
+                                                  GAsyncReadyCallback callback,
+                                                  gpointer            user_data);
+
+  GTlsInteractionResult  (* ask_password_finish) (GTlsInteraction    *interaction,
+                                                  GAsyncResult       *result);
+
+  /*< private >*/
+  /* Padding for future expansion */
+  void (*_g_reserved1) (void);
+  void (*_g_reserved2) (void);
+  void (*_g_reserved3) (void);
+  void (*_g_reserved4) (void);
+  void (*_g_reserved5) (void);
+  void (*_g_reserved6) (void);
+  void (*_g_reserved7) (void);
+  void (*_g_reserved8) (void);
+  void (*_g_reserved9) (void);
+  void (*_g_reserved10) (void);
+  void (*_g_reserved11) (void);
+  void (*_g_reserved12) (void);
+  void (*_g_reserved13) (void);
+  void (*_g_reserved14) (void);
+};
+
+GType                  g_tls_interaction_get_type            (void) G_GNUC_CONST;
+
+GTlsInteractionResult  g_tls_interaction_ask_password        (GTlsInteraction    *interaction,
+                                                              GTlsPassword       *password);
+
+void                   g_tls_interaction_ask_password_async  (GTlsInteraction    *interaction,
+                                                              GTlsPassword       *password,
+                                                              GAsyncReadyCallback callback,
+                                                              gpointer            user_data);
+
+GTlsInteractionResult  g_tls_interaction_ask_password_finish (GTlsInteraction    *interaction,
+                                                              GAsyncResult       *result);
+
+G_END_DECLS
+
+#endif /* __G_TLS_INTERACTION_H__ */
diff --git a/gio/gtlspassword.c b/gio/gtlspassword.c
new file mode 100644
index 0000000..496515b
--- /dev/null
+++ b/gio/gtlspassword.c
@@ -0,0 +1,436 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2011 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+#include "glib.h"
+#include "glibintl.h"
+
+#include "gioenumtypes.h"
+#include "gtlspassword.h"
+
+#include <string.h>
+
+/**
+ * SECTION:gtlspassword
+ * @title: GTlsPassword
+ * @short_description: TLS Passwords for prompting
+ * @include: gio/gio.h
+ *
+ * Holds a password used in TLS.
+ */
+
+/**
+ * GTlsPassword:
+ *
+ * An abstract interface representing a password used in TLS. Often used in
+ * user interaction such as unlocking a key storage token.
+ *
+ * Since: 2.30
+ */
+
+enum
+{
+  PROP_0,
+  PROP_FLAGS,
+  PROP_DESCRIPTION,
+  PROP_WARNING
+};
+
+struct _GTlsPasswordPrivate
+{
+  guchar *value;
+  gsize length;
+  GDestroyNotify destroy;
+  GTlsPasswordFlags flags;
+  gchar *description;
+  gchar *warning;
+};
+
+G_DEFINE_TYPE (GTlsPassword, g_tls_password, G_TYPE_OBJECT);
+
+static void
+g_tls_password_init (GTlsPassword *password)
+{
+  password->priv = G_TYPE_INSTANCE_GET_PRIVATE (password, G_TYPE_TLS_PASSWORD,
+                                              GTlsPasswordPrivate);
+}
+
+static const guchar *
+g_tls_password_real_get_value (GTlsPassword  *password,
+                               gsize         *length)
+{
+  if (length)
+    *length = password->priv->length;
+  return password->priv->value;
+}
+
+static void
+g_tls_password_real_take_value (GTlsPassword  *password,
+                                guchar        *value,
+                                gssize         length,
+                                GDestroyNotify destroy)
+{
+  if (password->priv->destroy)
+      (password->priv->destroy) (password->priv->value);
+  password->priv->destroy = NULL;
+  password->priv->value = NULL;
+  password->priv->length = 0;
+
+  if (length < 0)
+    length = strlen ((gchar*) value);
+
+  password->priv->value = value;
+  password->priv->length = length;
+  password->priv->destroy = destroy;
+}
+
+static const gchar*
+g_tls_password_real_get_default_warning (GTlsPassword  *password)
+{
+  GTlsPasswordFlags flags;
+
+  flags = g_tls_password_get_flags (password);
+
+  if (flags & G_TLS_PASSWORD_FINAL_TRY)
+    return _("This is the last chance to ether the password correctly before your access is locked out.");
+  if (flags & G_TLS_PASSWORD_MANY_TRIES)
+    return _("Several password entered have been incorrect, and your access will be locked out after further failures.");
+  if (flags & G_TLS_PASSWORD_RETRY)
+    return _("The password entered is incorrect.");
+
+  return NULL;
+}
+
+static void
+g_tls_password_get_property (GObject    *object,
+                             guint       prop_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
+{
+  GTlsPassword *password = G_TLS_PASSWORD (object);
+
+  switch (prop_id)
+    {
+    case PROP_FLAGS:
+      g_value_set_flags (value, g_tls_password_get_flags (password));
+      break;
+    case PROP_WARNING:
+      g_value_set_string (value, g_tls_password_get_warning (password));
+      break;
+    case PROP_DESCRIPTION:
+      g_value_set_string (value, g_tls_password_get_description (password));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_tls_password_set_property (GObject    *object,
+                             guint       prop_id,
+                             const GValue     *value,
+                             GParamSpec *pspec)
+{
+  GTlsPassword *password = G_TLS_PASSWORD (object);
+
+  switch (prop_id)
+    {
+    case PROP_FLAGS:
+      g_tls_password_set_flags (password, g_value_get_flags (value));
+      break;
+    case PROP_WARNING:
+      g_tls_password_set_warning (password, g_value_get_string (value));
+      break;
+    case PROP_DESCRIPTION:
+      g_tls_password_set_description (password, g_value_get_string (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_tls_password_finalize (GObject *object)
+{
+  GTlsPassword *password = G_TLS_PASSWORD (object);
+
+  g_tls_password_real_take_value (password, NULL, 0, NULL);
+  g_free (password->priv->warning);
+  g_free (password->priv->description);
+
+  G_OBJECT_CLASS (g_tls_password_parent_class)->finalize (object);
+}
+
+static void
+g_tls_password_class_init (GTlsPasswordClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  klass->get_value = g_tls_password_real_get_value;
+  klass->take_value = g_tls_password_real_take_value;
+  klass->get_default_warning = g_tls_password_real_get_default_warning;
+
+  gobject_class->get_property = g_tls_password_get_property;
+  gobject_class->set_property = g_tls_password_set_property;
+  gobject_class->finalize = g_tls_password_finalize;
+
+  g_type_class_add_private (klass, sizeof (GTlsPasswordPrivate));
+
+  g_object_class_install_property (gobject_class, PROP_FLAGS,
+             g_param_spec_flags ("flags", "Flags", "Flags about the password",
+                                 G_TYPE_TLS_PASSWORD_FLAGS, G_TLS_PASSWORD_NONE,
+                                 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_DESCRIPTION,
+             g_param_spec_string ("description", "Description", "Description of what the password is for",
+                                  "", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_WARNING,
+             g_param_spec_string ("warning", "Warning", "Warning about the password",
+                                 "", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+}
+
+/**
+ * g_tls_password_new:
+ * @flags: the password flags
+ * @description: description of what the password is for
+ *
+ * Create a new #GTlsPassword object.
+ *
+ * Returns: (transfer-full): The newly allocated password object
+ */
+GTlsPassword *
+g_tls_password_new (GTlsPasswordFlags  flags,
+                    const gchar       *description)
+{
+  return g_object_new (G_TYPE_TLS_PASSWORD,
+                       "flags", flags,
+                       "description", description,
+                       NULL);
+}
+
+/**
+ * g_tls_password_get_value:
+ * @password: a #GTlsPassword object
+ * @length: (allow-none): location to place the length of the password.
+ *
+ * Get the password value. If @length is not %NULL then it will be filled
+ * in with the length of the password value.
+ *
+ * Returns: The password value owned by the password object.
+ *
+ * Since: 2.30
+ */
+const guchar *
+g_tls_password_get_value (GTlsPassword  *password,
+                          gsize         *length)
+{
+  g_return_val_if_fail (G_IS_TLS_PASSWORD (password), NULL);
+  return G_TLS_PASSWORD_GET_CLASS (password)->get_value (password, length);
+}
+
+/**
+ * g_tls_password_set_value:
+ * @password: a #GTlsPassword object
+ * @value: the new password value
+ * @length: the length of the password, or -1
+ *
+ * Set the value for this password. The @value will be copied by the password
+ * object.
+ *
+ * Specify the @length, for a non-null-terminated password. Pass -1 as
+ * @length if using a null-terminated password, and @length will be calculated
+ * automatically.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_password_set_value (GTlsPassword  *password,
+                          const guchar  *value,
+                          gssize         length)
+{
+  g_return_if_fail (G_IS_TLS_PASSWORD (password));
+
+  if (length < 0)
+    length = strlen ((gchar *)value);
+
+  g_tls_password_take_value (password, g_memdup (value, length), length, g_free);
+}
+
+/**
+ * g_tls_password_take_value:
+ * @password: a #GTlsPassword object
+ * @value: the value for the password
+ * @length: the length of the password, or -1
+ * @destroy: (allow-none): a function to use to free the password.
+ *
+ * Provide the value for this password.
+ *
+ * The @value will be owned by the password object, and later freed using
+ * the @destroy function callback.
+ *
+ * Specify the @length, for a non-null-terminated password. Pass -1 as
+ * @length if using a null-terminated password, and @length will be calculated
+ * automatically.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_password_take_value (GTlsPassword  *password,
+                           guchar        *value,
+                           gssize         length,
+                           GDestroyNotify destroy)
+{
+  g_return_if_fail (G_IS_TLS_PASSWORD (password));
+  G_TLS_PASSWORD_GET_CLASS (password)->take_value (password, value,
+                                                   length, destroy);
+}
+
+/**
+ * g_tls_password_get_flags:
+ * @password: a #GTlsPassword object
+ *
+ * Get flags about the password.
+ *
+ * Return value: The flags about the password.
+ *
+ * Since: 2.30
+ */
+GTlsPasswordFlags
+g_tls_password_get_flags (GTlsPassword *password)
+{
+  g_return_val_if_fail (G_IS_TLS_PASSWORD (password), G_TLS_PASSWORD_NONE);
+  return password->priv->flags;
+}
+
+/**
+ * g_tls_password_set_flags:
+ * @password: a #GTlsPassword object
+ * @flags: The flags about the password
+ *
+ * Set flags about the password.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_password_set_flags (GTlsPassword      *password,
+                          GTlsPasswordFlags  flags)
+{
+  g_return_if_fail (G_IS_TLS_PASSWORD (password));
+
+  password->priv->flags = flags;
+
+  g_object_notify (G_OBJECT (password), "flags");
+}
+
+/**
+ * g_tls_password_get_description:
+ * @password: a #GTlsPassword object
+ *
+ * Get a description string about what the password will be used for.
+ *
+ * Return value: The description of the password.
+ *
+ * Since: 2.30
+ */
+const gchar*
+g_tls_password_get_description (GTlsPassword *password)
+{
+  g_return_val_if_fail (G_IS_TLS_PASSWORD (password), NULL);
+  return password->priv->description;
+}
+
+/**
+ * g_tls_password_set_description:
+ * @password: a #GTlsPassword object
+ * @flags: The description of the password
+ *
+ * Set a description string about what the password will be used for.
+ *
+ * Since: 2.30
+ */
+void
+g_tls_password_set_description (GTlsPassword      *password,
+                                const gchar       *description)
+{
+  gchar *copy;
+
+  g_return_if_fail (G_IS_TLS_PASSWORD (password));
+
+  copy = g_strdup (description);
+  g_free (password->priv->description);
+  password->priv->description = copy;
+
+  g_object_notify (G_OBJECT (password), "description");
+}
+
+/**
+ * g_tls_password_get_warning:
+ * @password: a #GTlsPassword object
+ *
+ * Get a user readable translated warning. Usually this warning is a
+ * representation of the password flags returned from
+ * g_tls_password_get_flags().
+ *
+ * Return value: The warning.
+ *
+ * Since: 2.30
+ */
+const gchar *
+g_tls_password_get_warning (GTlsPassword      *password)
+{
+  g_return_val_if_fail (G_IS_TLS_PASSWORD (password), NULL);
+
+  if (password->priv->warning == NULL)
+    return G_TLS_PASSWORD_GET_CLASS (password)->get_default_warning (password);
+
+  return password->priv->warning;
+}
+
+/**
+ * g_tls_password_set_warning:
+ * @password: a #GTlsPassword object
+ * @warning: The user readable warning
+ *
+ * Set a user readable translated warning. Usually this warning is a
+ * representation of the password flags returned from
+ * g_tls_password_get_flags().
+ *
+ * Since: 2.30
+ */
+void
+g_tls_password_set_warning (GTlsPassword      *password,
+                            const gchar       *warning)
+{
+  gchar *copy;
+
+  g_return_if_fail (G_IS_TLS_PASSWORD (password));
+
+  copy = g_strdup (warning);
+  g_free (password->priv->warning);
+  password->priv->warning = copy;
+
+  g_object_notify (G_OBJECT (password), "warning");
+}
diff --git a/gio/gtlspassword.h b/gio/gtlspassword.h
new file mode 100644
index 0000000..53c77f7
--- /dev/null
+++ b/gio/gtlspassword.h
@@ -0,0 +1,101 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2011 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#ifndef __G_TLS_PASSWORD_H__
+#define __G_TLS_PASSWORD_H__
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_TLS_PASSWORD         (g_tls_password_get_type ())
+#define G_TLS_PASSWORD(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_TLS_PASSWORD, GTlsPassword))
+#define G_TLS_PASSWORD_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_TLS_PASSWORD, GTlsPasswordClass))
+#define G_IS_TLS_PASSWORD(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_TLS_PASSWORD))
+#define G_IS_TLS_PASSWORD_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_TLS_PASSWORD))
+#define G_TLS_PASSWORD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_TLS_PASSWORD, GTlsPasswordClass))
+
+typedef struct _GTlsPasswordClass   GTlsPasswordClass;
+typedef struct _GTlsPasswordPrivate GTlsPasswordPrivate;
+
+struct _GTlsPassword
+{
+  GObject parent_instance;
+
+  GTlsPasswordPrivate *priv;
+};
+
+struct _GTlsPasswordClass
+{
+  GObjectClass parent_class;
+
+  /* methods */
+
+  const guchar *    ( *get_value)            (GTlsPassword  *password,
+                                              gsize         *length);
+
+  void              ( *take_value)           (GTlsPassword  *password,
+                                              guchar        *value,
+                                              gssize         length,
+                                              GDestroyNotify destroy);
+
+  const gchar*      ( *get_default_warning)  (GTlsPassword  *password);
+
+  /*< private >*/
+  /* Padding for future expansion */
+  gpointer padding[4];
+};
+
+GType             g_tls_password_get_type            (void) G_GNUC_CONST;
+
+GTlsPassword *    g_tls_password_new                 (GTlsPasswordFlags  flags,
+                                                      const gchar       *description);
+
+const guchar *    g_tls_password_get_value           (GTlsPassword      *password,
+                                                      gsize             *length);
+void              g_tls_password_set_value           (GTlsPassword      *password,
+                                                      const guchar      *value,
+                                                      gssize             length);
+void              g_tls_password_take_value          (GTlsPassword      *password,
+                                                      guchar            *value,
+                                                      gssize             length,
+                                                      GDestroyNotify     destroy);
+
+GTlsPasswordFlags g_tls_password_get_flags           (GTlsPassword      *password);
+void              g_tls_password_set_flags           (GTlsPassword      *password,
+                                                      GTlsPasswordFlags  flags);
+
+const gchar*      g_tls_password_get_description     (GTlsPassword      *password);
+void              g_tls_password_set_description     (GTlsPassword      *password,
+                                                      const gchar       *description);
+
+const gchar *     g_tls_password_get_warning         (GTlsPassword      *password);
+void              g_tls_password_set_warning         (GTlsPassword      *password,
+                                                      const gchar       *warning);
+
+G_END_DECLS
+
+#endif /* __G_TLS_PASSWORD_H__ */
diff --git a/gio/tests/.gitignore b/gio/tests/.gitignore
index 7df867e..a24e332 100644
--- a/gio/tests/.gitignore
+++ b/gio/tests/.gitignore
@@ -78,6 +78,7 @@ socket-client
 socket-server
 srvtarget
 test.mo
+tls
 unix-fd
 unix-streams
 volumemonitor
diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am
index 9929254..fea29da 100644
--- a/gio/tests/Makefile.am
+++ b/gio/tests/Makefile.am
@@ -193,7 +193,9 @@ socket_server_SOURCES	  = socket-server.c
 socket_server_LDADD	  = $(progs_ldadd) \
 	$(top_builddir)/gthread/libgthread-2.0.la
 
-socket_client_SOURCES	  = socket-client.c
+socket_client_SOURCES	  = socket-client.c \
+                            gtlsconsoleinteraction.c \
+                            gtlsconsoleinteraction.h
 socket_client_LDADD	  = $(progs_ldadd) \
 	$(top_builddir)/gthread/libgthread-2.0.la
 
diff --git a/gio/tests/gtlsconsoleinteraction.c b/gio/tests/gtlsconsoleinteraction.c
new file mode 100644
index 0000000..470e6db
--- /dev/null
+++ b/gio/tests/gtlsconsoleinteraction.c
@@ -0,0 +1,107 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2011 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gtlsconsoleinteraction.h"
+
+/*
+ * WARNING: This is not the example you're looking for [slow hand wave]. This
+ * is not industrial strength, it's just for testing. It uses embarassing
+ * functions like getpass() and does lazy things with threads.
+ */
+
+G_DEFINE_TYPE (GTlsConsoleInteraction, g_tls_console_interaction, G_TYPE_TLS_INTERACTION);
+
+static GTlsInteractionResult
+g_tls_console_interaction_ask_password (GTlsInteraction    *interaction,
+                                        GTlsPassword       *password)
+{
+  const gchar *value;
+  gchar *prompt;
+
+  prompt = g_strdup_printf ("Password \"%s\"': ", g_tls_password_get_description (password));
+  value = getpass (prompt);
+  g_free (prompt);
+
+  g_tls_password_set_value (password, (guchar *)value, -1);
+  return G_TLS_INTERACTION_HANDLED;
+}
+
+static void
+ask_password_with_getpass (GSimpleAsyncResult    *res,
+                           GObject               *object,
+                           GCancellable          *cancellable)
+{
+  GTlsPassword *password;
+
+  password = g_simple_async_result_get_op_res_gpointer (res);
+  g_tls_console_interaction_ask_password (G_TLS_INTERACTION (object), password);
+}
+
+void
+g_tls_console_interaction_ask_password_async (GTlsInteraction    *interaction,
+                                              GTlsPassword       *password,
+                                              GAsyncReadyCallback callback,
+                                              gpointer            user_data)
+{
+  GSimpleAsyncResult *res;
+
+  res = g_simple_async_result_new (G_OBJECT (interaction), callback, user_data,
+                                   g_tls_console_interaction_ask_password);
+  g_simple_async_result_set_op_res_gpointer (res, g_object_ref (password), g_object_unref);
+  g_simple_async_result_run_in_thread (res, ask_password_with_getpass,
+                                       G_PRIORITY_DEFAULT, NULL);
+  g_object_unref (res);
+}
+
+GTlsInteractionResult
+g_tls_console_interaction_ask_password_finish (GTlsInteraction    *interaction,
+                                               GAsyncResult       *result)
+{
+  g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (interaction),
+                        g_tls_console_interaction_ask_password), G_TLS_INTERACTION_ABORTED);
+  return G_TLS_INTERACTION_HANDLED;
+}
+
+static void
+g_tls_console_interaction_init (GTlsConsoleInteraction *interaction)
+{
+
+}
+
+static void
+g_tls_console_interaction_class_init (GTlsConsoleInteractionClass *klass)
+{
+  GTlsInteractionClass *interaction_class = G_TLS_INTERACTION_CLASS (klass);
+  interaction_class->ask_password = g_tls_console_interaction_ask_password;
+  interaction_class->ask_password_async = g_tls_console_interaction_ask_password_async;
+  interaction_class->ask_password_finish = g_tls_console_interaction_ask_password_finish;
+}
+
+GTlsInteraction *
+g_tls_console_interaction_new (void)
+{
+  return g_object_new (G_TYPE_TLS_CONSOLE_INTERACTION, NULL);
+}
diff --git a/gio/tests/gtlsconsoleinteraction.h b/gio/tests/gtlsconsoleinteraction.h
new file mode 100644
index 0000000..eaf4d18
--- /dev/null
+++ b/gio/tests/gtlsconsoleinteraction.h
@@ -0,0 +1,56 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2011 Collabora, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#ifndef __G_TLS_CONSOLE_INTERACTION_H__
+#define __G_TLS_CONSOLE_INTERACTION_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_TLS_CONSOLE_INTERACTION         (g_tls_console_interaction_get_type ())
+#define G_TLS_CONSOLE_INTERACTION(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_TLS_CONSOLE_INTERACTION, GTlsConsoleInteraction))
+#define G_TLS_CONSOLE_INTERACTION_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_TLS_CONSOLE_INTERACTION, GTlsConsoleInteractionClass))
+#define G_IS_TLS_CONSOLE_INTERACTION(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_TLS_CONSOLE_INTERACTION))
+#define G_IS_TLS_CONSOLE_INTERACTION_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_TLS_CONSOLE_INTERACTION))
+#define G_TLS_CONSOLE_INTERACTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_TLS_CONSOLE_INTERACTION, GTlsConsoleInteractionClass))
+
+typedef struct _GTlsConsoleInteraction        GTlsConsoleInteraction;
+typedef struct _GTlsConsoleInteractionClass   GTlsConsoleInteractionClass;
+
+struct _GTlsConsoleInteraction
+{
+  GTlsInteraction parent_instance;
+};
+
+struct _GTlsConsoleInteractionClass
+{
+  GTlsInteractionClass parent_class;
+};
+
+GType                  g_tls_console_interaction_get_type    (void) G_GNUC_CONST;
+
+GTlsInteraction *      g_tls_console_interaction_new         (void);
+
+G_END_DECLS
+
+#endif /* __G_TLS_CONSOLE_INTERACTION_H__ */
diff --git a/gio/tests/socket-client.c b/gio/tests/socket-client.c
index 6068034..578b0c8 100644
--- a/gio/tests/socket-client.c
+++ b/gio/tests/socket-client.c
@@ -5,6 +5,8 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "gtlsconsoleinteraction.h"
+
 GMainLoop *loop;
 
 gboolean verbose = FALSE;
@@ -59,59 +61,57 @@ accept_certificate (GTlsClientConnection *conn, GTlsCertificate *cert,
   return TRUE;
 }
 
-int
-main (int argc,
-      char *argv[])
+static GTlsCertificate *
+lookup_client_certificate (GTlsClientConnection *conn, GError **error)
 {
-  GSocket *socket;
-  GSocketAddress *src_address;
-  GSocketAddress *address;
-  GSocketType socket_type;
-  GSocketFamily socket_family;
-  GError *error = NULL;
-  GOptionContext *context;
-  GCancellable *cancellable;
-  GSocketAddressEnumerator *enumerator;
-  GSocketConnectable *connectable;
-  GIOStream *connection;
-  GInputStream *istream;
-  GOutputStream *ostream;
-
-  g_thread_init (NULL);
-
-  g_type_init ();
-
-  context = g_option_context_new (" <hostname>[:port] - Test GSocket client stuff");
-  g_option_context_add_main_entries (context, cmd_entries, NULL);
-  if (!g_option_context_parse (context, &argc, &argv, &error))
+  GList *l, *accepted;
+  GList *c, *certificates;
+  GTlsDatabase *database;
+  GTlsCertificate *certificate = NULL;
+  GTlsConnection *base;
+
+  accepted = g_tls_client_connection_get_accepted_cas (conn);
+  for (l = accepted; l != NULL; l = g_list_next (l))
     {
-      g_printerr ("%s: %s\n", argv[0], error->message);
-      return 1;
+      base = G_TLS_CONNECTION (conn);
+      database = g_tls_connection_get_database (base);
+      certificates = g_tls_database_lookup_certificates_issued_by (database, l->data,
+                                                                   g_tls_connection_get_interaction (base),
+                                                                   G_TLS_DATABASE_LOOKUP_KEYPAIR,
+                                                                   NULL, error);
+      if (error && *error)
+        break;
+
+      if (certificates)
+          certificate = g_object_ref (certificates->data);
+
+      for (c = certificates; c != NULL; c = g_list_next (c))
+        g_object_unref (c->data);
+      g_list_free (certificates);
     }
 
-  if (argc != 2)
-    {
-      g_printerr ("%s: %s\n", argv[0], "Need to specify hostname / unix socket name");
-      return 1;
-    }
+  for (l = accepted; l != NULL; l = g_list_next (l))
+    g_byte_array_unref (l->data);
+  g_list_free (accepted);
 
-  if (use_udp && tls)
-    {
-      g_printerr ("DTLS (TLS over UDP) is not supported");
-      return 1;
-    }
-
-  if (cancel_timeout)
-    {
-      cancellable = g_cancellable_new ();
-      g_thread_create (cancel_thread, cancellable, FALSE, NULL);
-    }
-  else
-    {
-      cancellable = NULL;
-    }
+  if (certificate == NULL && error && !*error)
+    g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED,
+                         "Server requested a certificate, but could not find relevant certificate in database.");
+  return certificate;
+}
 
-  loop = g_main_loop_new (NULL, FALSE);
+static gboolean
+make_connection (const char *argument, GTlsCertificate *certificate, GCancellable *cancellable,
+                 GSocket **socket, GSocketAddress **address, GIOStream **connection,
+                 GInputStream **istream, GOutputStream **ostream, GError **error)
+{
+  GSocketType socket_type;
+  GSocketFamily socket_family;
+  GSocketAddressEnumerator *enumerator;
+  GSocketConnectable *connectable;
+  GSocketAddress *src_address;
+  GTlsInteraction *interaction;
+  GError *err = NULL;
 
   if (use_udp)
     socket_type = G_SOCKET_TYPE_DATAGRAM;
@@ -123,116 +123,187 @@ main (int argc,
   else
     socket_family = G_SOCKET_FAMILY_IPV4;
 
-  socket = g_socket_new (socket_family, socket_type, 0, &error);
-  if (socket == NULL)
-    {
-      g_printerr ("%s: %s\n", argv[0], error->message);
-      return 1;
-    }
+  *socket = g_socket_new (socket_family, socket_type, 0, error);
+  if (*socket == NULL)
+    return FALSE;
 
   if (read_timeout)
-    g_socket_set_timeout (socket, read_timeout);
+    g_socket_set_timeout (*socket, read_timeout);
 
   if (unix_socket)
     {
       GSocketAddress *addr;
 
-      addr = socket_address_from_string (argv[1]);
+      addr = socket_address_from_string (argument);
       if (addr == NULL)
-	{
-	  g_printerr ("%s: Could not parse '%s' as unix socket name\n", argv[0], argv[1]);
-	  return 1;
-	}
+        {
+          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                       "Could not parse '%s' as unix socket name", argument);
+          return FALSE;
+        }
       connectable = G_SOCKET_CONNECTABLE (addr);
     }
   else
     {
-      connectable = g_network_address_parse (argv[1], 7777, &error);
+      connectable = g_network_address_parse (argument, 7777, error);
       if (connectable == NULL)
-	{
-	  g_printerr ("%s: %s\n", argv[0], error->message);
-	  return 1;
-	}
+        return FALSE;
     }
 
   enumerator = g_socket_connectable_enumerate (connectable);
   while (TRUE)
     {
-      address = g_socket_address_enumerator_next (enumerator, cancellable, &error);
-      if (address == NULL)
-	{
-	  if (error == NULL)
-	    g_printerr ("%s: No more addresses to try\n", argv[0]);
-	  else
-	    g_printerr ("%s: %s\n", argv[0], error->message);
-	  return 1;
-	}
-
-      if (g_socket_connect (socket, address, cancellable, &error))
-	break;
-      g_printerr ("%s: Connection to %s failed: %s, trying next\n", argv[0], socket_address_to_string (address), error->message);
-      g_error_free (error);
-      error = NULL;
-
-      g_object_unref (address);
+      *address = g_socket_address_enumerator_next (enumerator, cancellable, error);
+      if (*address == NULL)
+        {
+          if (error == NULL)
+            g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                 "No more addresses to try");
+          return FALSE;
+        }
+
+      if (g_socket_connect (*socket, *address, cancellable, &err))
+        break;
+      g_message ("Connection to %s failed: %s, trying next\n", socket_address_to_string (*address), err->message);
+      g_clear_error (&err);
+
+      g_object_unref (*address);
     }
   g_object_unref (enumerator);
 
   g_print ("Connected to %s\n",
-	   socket_address_to_string (address));
+           socket_address_to_string (*address));
 
-  src_address = g_socket_get_local_address (socket, &error);
+  src_address = g_socket_get_local_address (*socket, error);
   if (!src_address)
     {
-      g_printerr ("Error getting local address: %s\n",
-		  error->message);
-      return 1;
+      g_prefix_error (error, "Error getting local address: ");
+      return FALSE;
     }
+
   g_print ("local address: %s\n",
-	   socket_address_to_string (src_address));
+           socket_address_to_string (src_address));
   g_object_unref (src_address);
 
   if (use_udp)
     {
-      connection = NULL;
-      istream = NULL;
-      ostream = NULL;
+      *connection = NULL;
+      *istream = NULL;
+      *ostream = NULL;
     }
   else
-    connection = G_IO_STREAM (g_socket_connection_factory_create_connection (socket));
+    *connection = G_IO_STREAM (g_socket_connection_factory_create_connection (*socket));
 
   if (tls)
     {
       GIOStream *tls_conn;
 
-      tls_conn = g_tls_client_connection_new (connection, connectable, &error);
+      tls_conn = g_tls_client_connection_new (*connection, connectable, error);
       if (!tls_conn)
-	{
-	  g_printerr ("Could not create TLS connection: %s\n",
-		      error->message);
-	  return 1;
-	}
+        {
+          g_prefix_error (error, "Could not create TLS connection: ");
+          return FALSE;
+        }
 
       g_signal_connect (tls_conn, "accept-certificate",
-			G_CALLBACK (accept_certificate), NULL);
+                        G_CALLBACK (accept_certificate), NULL);
 
-      if (!g_tls_connection_handshake (G_TLS_CONNECTION (tls_conn),
-				       cancellable, &error))
-	{
-	  g_printerr ("Error during TLS handshake: %s\n",
-		      error->message);
-	  return 1;
-	}
+      interaction = g_tls_console_interaction_new ();
+      g_tls_connection_set_interaction (G_TLS_CONNECTION (tls_conn), interaction);
+      g_object_unref (interaction);
 
-      g_object_unref (connection);
-      connection = G_IO_STREAM (tls_conn);
+      if (certificate)
+        g_tls_connection_set_certificate (G_TLS_CONNECTION (tls_conn), certificate);
+
+      g_object_unref (*connection);
+      *connection = G_IO_STREAM (tls_conn);
+
+      if (!g_tls_connection_handshake (G_TLS_CONNECTION (tls_conn),
+                                       cancellable, error))
+        {
+          g_prefix_error (error, "Error during TLS handshake: ");
+          return FALSE;
+        }
     }
   g_object_unref (connectable);
 
-  if (connection)
+  if (*connection)
     {
-      istream = g_io_stream_get_input_stream (connection);
-      ostream = g_io_stream_get_output_stream (connection);
+      *istream = g_io_stream_get_input_stream (*connection);
+      *ostream = g_io_stream_get_output_stream (*connection);
+    }
+
+  return TRUE;
+}
+
+int
+main (int argc,
+      char *argv[])
+{
+  GSocket *socket;
+  GSocketAddress *address;
+  GError *error = NULL;
+  GOptionContext *context;
+  GCancellable *cancellable;
+  GIOStream *connection;
+  GInputStream *istream;
+  GOutputStream *ostream;
+  GSocketAddress *src_address;
+  GTlsCertificate *certificate = NULL;
+  gint i;
+
+  g_thread_init (NULL);
+
+  g_type_init ();
+
+  context = g_option_context_new (" <hostname>[:port] - Test GSocket client stuff");
+  g_option_context_add_main_entries (context, cmd_entries, NULL);
+  if (!g_option_context_parse (context, &argc, &argv, &error))
+    {
+      g_printerr ("%s: %s\n", argv[0], error->message);
+      return 1;
+    }
+
+  if (argc != 2)
+    {
+      g_printerr ("%s: %s\n", argv[0], "Need to specify hostname / unix socket name");
+      return 1;
+    }
+
+  if (use_udp && tls)
+    {
+      g_printerr ("DTLS (TLS over UDP) is not supported");
+      return 1;
+    }
+
+  if (cancel_timeout)
+    {
+      cancellable = g_cancellable_new ();
+      g_thread_create (cancel_thread, cancellable, FALSE, NULL);
+    }
+  else
+    {
+      cancellable = NULL;
+    }
+
+  loop = g_main_loop_new (NULL, FALSE);
+
+  for (i = 0; i < 2; i++)
+    {
+      if (make_connection (argv[1], certificate, cancellable, &socket, &address,
+                           &connection, &istream, &ostream, &error))
+          break;
+
+      if (g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED))
+        {
+          g_clear_error (&error);
+          certificate = lookup_client_certificate (G_TLS_CLIENT_CONNECTION (connection), &error);
+          if (certificate != NULL)
+            continue;
+        }
+
+      g_printerr ("%s: %s", argv[0], error->message);
+      return 1;
     }
 
   /* TODO: Test non-blocking connect/handshake */
