[glib-networking/mcatanzaro/fix-geary: 2/2] gnutls: fix use of non-default GTlsDatabases




commit d53e3a610f0b3eb57492d8dc24f1d2d1e7a2ec30
Author: Michael Catanzaro <mcatanzaro redhat com>
Date:   Wed Aug 25 13:36:58 2021 -0500

    gnutls: fix use of non-default GTlsDatabases
    
    In d94c3313 I reworked how we do certificate verification. This was
    mostly good, but it included a major mistake: I assumed that the
    GTlsDatabase was always a GTlsDatabaseGnutls. This was incorrect because
    our API allows configuring an arbitrary GTlsDatabase. Let's fall back to
    the original behavior in this case. It won't be as secure -- there will
    be no certificate revocation or key usage checks -- but this is
    necessary to maintain compatibility with existing code that isn't doing
    anything wrong.
    
    Fixes #169

 tls/gnutls/gtlsconnection-gnutls.c | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)
---
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index 54902666..6881cf21 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -127,7 +127,7 @@ update_credentials_cb (GObject    *gobject,
   int ret;
 
   database = g_tls_connection_get_database (G_TLS_CONNECTION (gnutls));
-  if (database)
+  if (database && G_IS_TLS_DATABASE_GNUTLS (database))
     {
       credentials = g_tls_database_gnutls_get_credentials (G_TLS_DATABASE_GNUTLS (database), &error);
       if (!credentials)
@@ -190,7 +190,7 @@ g_tls_connection_gnutls_initable_init (GInitable     *initable,
     flags |= GNUTLS_DATAGRAM;
 
   database = g_tls_connection_get_database (G_TLS_CONNECTION (gnutls));
-  if (database)
+  if (database && G_IS_TLS_DATABASE_GNUTLS (database))
     {
       priv->creds = g_tls_database_gnutls_get_credentials (G_TLS_DATABASE_GNUTLS (database), &my_error);
       if (!priv->creds)
@@ -993,6 +993,7 @@ g_tls_connection_gnutls_verify_chain (GTlsConnectionBase       *tls,
   GTlsCertificateFlags errors = 0;
   const char *hostname = NULL;
   char *free_hostname = NULL;
+  GTlsDatabase *database;
   guint gnutls_result;
   int ret;
 
@@ -1005,12 +1006,27 @@ g_tls_connection_gnutls_verify_chain (GTlsConnectionBase       *tls,
    * (a) is done by g_tls_database_verify_chain() and implemented using one of
    * several different functions of gnutls_x509_trust_list_t, e.g.
    * gnutls_x509_trust_list_verify_crt2() or one of the related functions.
-   *
-   * (b) is what we're doing here. The recommended way is to use
-   * gnutls_session_set_verify_cert(), but we can't do that because that would
-   * leave no way to implement the accept-certificate signal. The other way is
-   * to use gnutls_certificate_verify_peers3() or one of the related functions.
-   * This adds additional smarts that are not possible when using GTlsDatabase
+   * This is the best we can do if we have to use a GTlsDatabase that is not a
+   * GTlsDatabaseGnutls.
+   */
+  database = g_tls_connection_get_database (G_TLS_CONNECTION (gnutls));
+  if (!G_IS_TLS_DATABASE_GNUTLS (database))
+    {
+      return g_tls_database_verify_chain (database,
+                                          chain,
+                                          G_IS_TLS_CLIENT_CONNECTION (tls) ? 
G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER : G_TLS_DATABASE_PURPOSE_AUTHENTICATE_CLIENT,
+                                          identity,
+                                          g_tls_connection_get_interaction (G_TLS_CONNECTION (tls)),
+                                          G_TLS_DATABASE_VERIFY_NONE,
+                                          NULL,
+                                          error);
+    }
+
+  /* Now for (b). The recommended way is gnutls_session_set_verify_cert(), but
+   * we can't use that because that would leave no way to implement the
+   * GTlsConnection::accept-certificate signal. The other way is to use
+   * gnutls_certificate_verify_peers3() or one of the related functions. This
+   * adds additional smarts that are not possible when using GTlsDatabase
    * directly. For example, it checks name constraints, key usage, and basic
    * constraints. It also checks for stapled OCSP responses. Verification will
    * fail if the OCSP response indicates the certificate has been revoked.


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