gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [gnunet-gtk] branch master updated: be precise about which


From: gnunet
Subject: [GNUnet-SVN] [gnunet-gtk] branch master updated: be precise about which cert from the chain to use for TLSA record
Date: Sat, 10 Mar 2018 21:32:07 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository gnunet-gtk.

The following commit(s) were added to refs/heads/master by this push:
     new eac1312f be precise about which cert from the chain to use for TLSA 
record
eac1312f is described below

commit eac1312f563a3db362e189c8b2c915d666110dca
Author: Christian Grothoff <address@hidden>
AuthorDate: Sat Mar 10 21:32:05 2018 +0100

    be precise about which cert from the chain to use for TLSA record
---
 src/namestore/plugin_gtk_namestore_tlsa.c | 157 +++++++++++++++++++++---------
 1 file changed, 113 insertions(+), 44 deletions(-)

diff --git a/src/namestore/plugin_gtk_namestore_tlsa.c 
b/src/namestore/plugin_gtk_namestore_tlsa.c
index 2a8ba21a..1fc970e4 100644
--- a/src/namestore/plugin_gtk_namestore_tlsa.c
+++ b/src/namestore/plugin_gtk_namestore_tlsa.c
@@ -567,20 +567,55 @@ tlsa_validate (void *cls,
 
 
 /**
+ * Context for TLS certificate import from network.
+ */
+struct ImportContext
+{
+
+  /**
+   * Network handle for the session.
+   */
+  struct GNUNET_NETWORK_Handle *sock;
+
+  /**
+   * DNS resolution request to resolve the domain name.
+   */
+  struct GNUNET_RESOLVER_RequestHandle *rh;
+
+  /**
+   * Builder for accessing widgets.
+   */
+  GtkBuilder *builder;
+
+  /**
+   * Domain name of the site we use to get the TLS cert record from.
+   */
+  char *name;
+
+  /**
+   * We succeeded with our TLS handshake, ignore further DNS replies.
+   */
+  int done;
+};
+
+
+/**
  * We have successfully established a TLS session to
  * import a certificate from the server.  Import the
  * X509 certificate into the GUI.
  *
  * @param session TLS session to import from
- * @param builder GTK builder to update GUI
+ * @param ic the import context
  */
 static void
 import_x509_certificate (gnutls_session_t session,
-                         GtkBuilder *builder)
+                         struct ImportContext *ic)
 {
+  GtkBuilder *builder = ic->builder;
   const gnutls_datum_t *cert_list;
   unsigned int cert_list_size = 0;
   gnutls_x509_crt_t cert;
+  unsigned int usage;
   unsigned int matching_type;
   unsigned int selector;
   gnutls_pubkey_t pk;
@@ -592,6 +627,7 @@ import_x509_certificate (gnutls_session_t session,
   uint8_t sha512[512/8];
   size_t ssize;
   GtkTextBuffer *tb;
+  unsigned int i;
 
   cert_list = gnutls_certificate_get_peers (session,
                                             &cert_list_size);
@@ -602,17 +638,82 @@ import_x509_certificate (gnutls_session_t session,
     GNUNET_break (0);
     return;
   }
-  /* we only import the first certificate. */
-  gnutls_x509_crt_init (&cert);
-  if (GNUTLS_E_SUCCESS !=
-      gnutls_x509_crt_import (cert,
-                              &cert_list[0],
-                              GNUTLS_X509_FMT_DER))
+
+  usage = get_selected_radio_value (builder,
+                                    usage_buttons);
+  /* Find out which certificate we care about based on usage */
+  for (i=0;i<cert_list_size;i++)
   {
-    GNUNET_break (0);
+    char san[256];
+    size_t san_size = sizeof (san);
+    unsigned int critical;
+    int matches_dn;
+    gnutls_x509_dn_t dn;
+    gnutls_datum_t str;
+
+    gnutls_x509_crt_init (&cert);
+    if (GNUTLS_E_SUCCESS !=
+        gnutls_x509_crt_import (cert,
+                                &cert_list[i],
+                                GNUTLS_X509_FMT_DER))
+    {
+      GNUNET_break (0);
+      gnutls_x509_crt_deinit (cert);
+      return;
+    }
+    if (1 == usage)
+      break; /* RFC 6394: first certificate (i==0) is to be pinned */
+    matches_dn = GNUNET_NO;
+    if ( (0 == gnutls_x509_crt_get_subject (cert,
+                                            &dn)) &&
+         (0 == gnutls_x509_dn_get_str (dn,
+                                       &str)) )
+    {
+      const char *cn;
+
+      cn = memmem (str.data,
+                   str.size,
+                   ",CN=",
+                   4);
+      if ( (NULL != cn) &&
+           ( ('\0' == cn[4 + strlen (ic->name)]) ||
+             (',' == cn[4 + strlen (ic->name)]) ) &&
+           (0 == strncasecmp (cn + 4,
+                              ic->name,
+                              strlen (ic->name))) )
+        matches_dn = GNUNET_YES;
+    }
+    for (unsigned int seq=0;
+         GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE != 
gnutls_x509_crt_get_subject_alt_name (cert,
+                                                                               
         seq,
+                                                                               
         san,
+                                                                               
         &san_size,
+                                                                               
         &critical);
+         seq++)
+    {
+      if (0 == strcasecmp (san,
+                           ic->name))
+      {
+        matches_dn = GNUNET_YES;
+        break;
+      }
+    }
+    /* usage = 3: we want to match DN, otherwise we do NOT want to
+       match DN */
+    if ( (GNUNET_NO == matches_dn)  ^ /* XOR */
+         (3 == usage) /* Domain issued certificate */ )
+      break;
     gnutls_x509_crt_deinit (cert);
+  }
+  if (i == cert_list_size)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "None of the %u certificates matches the usage %u\n",
+                cert_list_size,
+                usage);
     return;
   }
+
   selector = get_selected_radio_value (builder,
                                        selector_buttons);
   switch (selector)
@@ -720,39 +821,6 @@ import_x509_certificate (gnutls_session_t session,
 
 
 /**
- * Context for TLS certificate import from network.
- */
-struct ImportContext
-{
-
-  /**
-   * Network handle for the session.
-   */
-  struct GNUNET_NETWORK_Handle *sock;
-
-  /**
-   * DNS resolution request to resolve the domain name.
-   */
-  struct GNUNET_RESOLVER_RequestHandle *rh;
-
-  /**
-   * Builder for accessing widgets.
-   */
-  GtkBuilder *builder;
-
-  /**
-   * Domain name of the site we use to get the TLS cert record from.
-   */
-  char *name;
-
-  /**
-   * We succeeded with our TLS handshake, ignore further DNS replies.
-   */
-  int done;
-};
-
-
-/**
  * We got an address from DNS, start TLS handshake.
  *
  * @param cls our `struct ImportContext`
@@ -837,7 +905,8 @@ import_address_cb (void *cls,
 
   /* initialize TLS session */
   gnutls_init (&session, GNUTLS_CLIENT);
-  gnutls_session_set_ptr (session, ic);
+  gnutls_session_set_ptr (session,
+                          ic);
   gnutls_server_name_set (session,
                           GNUTLS_NAME_DNS,
                           ic->name,
@@ -886,7 +955,7 @@ import_address_cb (void *cls,
       break;
     case GNUTLS_CRT_X509:
       import_x509_certificate (session,
-                               ic->builder);
+                               ic);
       break;
     case GNUTLS_CRT_OPENPGP:
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]