dirmngr: Add special treatment for the standard hkps pool to ntbtls.
authorWerner Koch <wk@gnupg.org>
Tue, 21 Feb 2017 13:55:04 +0000 (14:55 +0100)
committerWerner Koch <wk@gnupg.org>
Tue, 21 Feb 2017 13:55:04 +0000 (14:55 +0100)
* dirmngr/validate.h (VALIDATE_FLAG_SYSTRUST): Remove
(VALIDATE_FLAG_EXTRATRUST): Remove
(VALIDATE_FLAG_TRUST_SYSTEM): New.
(VALIDATE_FLAG_TRUST_CONFIG): New.
(VALIDATE_FLAG_TRUST_HKP): New.
(VALIDATE_FLAG_TRUST_HKPSPOOL): New.
(VALIDATE_FLAG_MASK_TRUST): New.
* dirmngr/validate.c (check_header_constants): New.
(validate_cert_chain): Call new function.  Simplify call to
is_trusted_cert.
* dirmngr/crlcache.c (crl_parse_insert): Pass
VALIDATE_FLAG_TRUST_CONFIG to validate_cert_chain
* dirmngr/server.c (cmd_validate): Use VALDIATE_FLAG_TRUST_SYSTEM and
VALIDATE_FLAG_TRUST_CONFIG.
* dirmngr/http-ntbtls.c (gnupg_http_tls_verify_cb): Check provided TLS
context.  Set trustclass flags using the new VALIDATE_FLAG_TRUST
values.

* dirmngr/certcache.c (cert_cache_init): Load the standard pool
certificate prior to the --hkp-cacerts.
--

Note that this changes the way the standard cert is used: We require
that it is installed at /usr/share/gnupg and we do not allow to change
it.  If this is not desired, the the standard cert can be removed or
replaced by a newer one.

Signed-off-by: Werner Koch <wk@gnupg.org>
dirmngr/certcache.c
dirmngr/crlcache.c
dirmngr/http-ntbtls.c
dirmngr/http.h
dirmngr/server.c
dirmngr/validate.c
dirmngr/validate.h

index 47eea25..c83b00e 100644 (file)
@@ -709,16 +709,15 @@ cert_cache_init (strlist_t hkp_cacerts)
     load_certs_from_dir (fname, 0);
   xfree (fname);
 
     load_certs_from_dir (fname, 0);
   xfree (fname);
 
-  for (sl = hkp_cacerts; sl; sl = sl->next)
-    load_certs_from_file (sl->d, CERTTRUST_CLASS_HKP, 0);
-
-
   fname = make_filename_try (gnupg_datadir (),
                              "sks-keyservers.netCA.pem", NULL);
   if (fname)
     load_certs_from_file (fname, CERTTRUST_CLASS_HKPSPOOL, 1);
   xfree (fname);
 
   fname = make_filename_try (gnupg_datadir (),
                              "sks-keyservers.netCA.pem", NULL);
   if (fname)
     load_certs_from_file (fname, CERTTRUST_CLASS_HKPSPOOL, 1);
   xfree (fname);
 
+  for (sl = hkp_cacerts; sl; sl = sl->next)
+    load_certs_from_file (sl->d, CERTTRUST_CLASS_HKP, 0);
+
   initialization_done = 1;
   release_cache_lock ();
 
   initialization_done = 1;
   release_cache_lock ();
 
index 3cd8cf4..c60d3fb 100644 (file)
@@ -1851,7 +1851,8 @@ crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl,
            md = NULL;
 
             err = validate_cert_chain (ctrl, crlissuer_cert, NULL,
            md = NULL;
 
             err = validate_cert_chain (ctrl, crlissuer_cert, NULL,
-                                       (VALIDATE_FLAG_CRL
+                                       (VALIDATE_FLAG_TRUST_CONFIG
+                                        | VALIDATE_FLAG_CRL
                                         | VALIDATE_FLAG_RECURSIVE),
                                        r_trust_anchor);
             if (err)
                                         | VALIDATE_FLAG_RECURSIVE),
                                        r_trust_anchor);
             if (err)
index 3038cae..00d6a58 100644 (file)
@@ -41,20 +41,23 @@ gnupg_http_tls_verify_cb (void *opaque,
                           void *tls_context)
 {
   ctrl_t ctrl = opaque;
                           void *tls_context)
 {
   ctrl_t ctrl = opaque;
+  ntbtls_t tls = tls_context;
   gpg_error_t err;
   int idx;
   ksba_cert_t cert;
   ksba_cert_t hostcert = NULL;
   unsigned int validate_flags;
   gpg_error_t err;
   int idx;
   ksba_cert_t cert;
   ksba_cert_t hostcert = NULL;
   unsigned int validate_flags;
+  const char *hostname;
 
   (void)http;
   (void)session;
 
   log_assert (ctrl && ctrl->magic == SERVER_CONTROL_MAGIC);
 
   (void)http;
   (void)session;
 
   log_assert (ctrl && ctrl->magic == SERVER_CONTROL_MAGIC);
+  log_assert (!ntbtls_check_context (tls));
 
   /* Get the peer's certs fron ntbtls.  */
   for (idx = 0;
 
   /* Get the peer's certs fron ntbtls.  */
   for (idx = 0;
-       (cert = ntbtls_x509_get_peer_cert (tls_context, idx)); idx++)
+       (cert = ntbtls_x509_get_peer_cert (tls, idx)); idx++)
     {
       if (!idx)
         hostcert = cert;
     {
       if (!idx)
         hostcert = cert;
@@ -73,10 +76,22 @@ gnupg_http_tls_verify_cb (void *opaque,
     }
 
   validate_flags = VALIDATE_FLAG_TLS;
     }
 
   validate_flags = VALIDATE_FLAG_TLS;
-  /* if ((http_flags & HTTP_FLAG_TRUST_DEF)) */
-  /*   validate_flags |= VALIDATE_FLAG_??; */
-  if ((http_flags & HTTP_FLAG_TRUST_SYS))
-    validate_flags |= VALIDATE_FLAG_SYSTRUST;
+
+  /* Are we using the standard hkps:// pool use the dedicated
+   * root certificate.  */
+  hostname = ntbtls_get_hostname (tls);
+  if (hostname
+      && !ascii_strcasecmp (hostname, "hkps.pool.sks-keyservers.net"))
+    {
+      validate_flags |= VALIDATE_FLAG_TRUST_HKPSPOOL;
+    }
+  else /* Use the certificates as requested from the HTTP module.  */
+    {
+      if ((http_flags & HTTP_FLAG_TRUST_DEF))
+        validate_flags |= VALIDATE_FLAG_TRUST_HKP;
+      if ((http_flags & HTTP_FLAG_TRUST_SYS))
+        validate_flags |= VALIDATE_FLAG_TRUST_SYSTEM;
+    }
 
   if ((http_flags & HTTP_FLAG_NO_CRL))
     validate_flags |= VALIDATE_FLAG_NOCRLCHECK;
 
   if ((http_flags & HTTP_FLAG_NO_CRL))
     validate_flags |= VALIDATE_FLAG_NOCRLCHECK;
index 331ee61..2609b9e 100644 (file)
@@ -86,7 +86,7 @@ enum
     HTTP_FLAG_IGNORE_CL = 32,    /* Ignore content-length.  */
     HTTP_FLAG_IGNORE_IPv4 = 64,  /* Do not use IPv4.  */
     HTTP_FLAG_IGNORE_IPv6 = 128, /* Do not use IPv6.  */
     HTTP_FLAG_IGNORE_CL = 32,    /* Ignore content-length.  */
     HTTP_FLAG_IGNORE_IPv4 = 64,  /* Do not use IPv4.  */
     HTTP_FLAG_IGNORE_IPv6 = 128, /* Do not use IPv6.  */
-    HTTP_FLAG_TRUST_DEF   = 256, /* Use the default CAs.  */
+    HTTP_FLAG_TRUST_DEF   = 256, /* Use the CAs configured for HKP.  */
     HTTP_FLAG_TRUST_SYS   = 512, /* Also use the system defined CAs.  */
     HTTP_FLAG_NO_CRL     = 1024  /* Do not consult CRLs for https.  */
   };
     HTTP_FLAG_TRUST_SYS   = 512, /* Also use the system defined CAs.  */
     HTTP_FLAG_NO_CRL     = 1024  /* Do not consult CRLs for https.  */
   };
index f726d1b..961bba0 100644 (file)
@@ -1852,8 +1852,9 @@ cmd_validate (assuan_context_t ctx, char *line)
     }
 
   err = validate_cert_chain (ctrl, cert, NULL,
     }
 
   err = validate_cert_chain (ctrl, cert, NULL,
-                             ((tls_mode ? VALIDATE_FLAG_TLS : 0)
-                              | (systrust_mode ? VALIDATE_FLAG_SYSTRUST : 0)
+                             (VALIDATE_FLAG_TRUST_CONFIG
+                              | (tls_mode ? VALIDATE_FLAG_TLS : 0)
+                              | (systrust_mode ? VALIDATE_FLAG_TRUST_SYSTEM : 0)
                               | (no_crl ? VALIDATE_FLAG_NOCRLCHECK : 0)),
                              NULL);
 
                               | (no_crl ? VALIDATE_FLAG_NOCRLCHECK : 0)),
                              NULL);
 
index 5bd784f..3671a8b 100644 (file)
@@ -74,6 +74,29 @@ static const char oid_kp_ocspSigning[]    = "1.3.6.1.5.5.7.3.9";
 static gpg_error_t check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert);
 
 
 static gpg_error_t check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert);
 
 
+/* Make sure that the values defined in the headers are correct.  We
+ * can't use the preprocessor due to the use of enums.  */
+static void
+check_header_constants (void)
+{
+  log_assert (CERTTRUST_CLASS_SYSTEM   == VALIDATE_FLAG_TRUST_SYSTEM);
+  log_assert (CERTTRUST_CLASS_CONFIG   == VALIDATE_FLAG_TRUST_CONFIG);
+  log_assert (CERTTRUST_CLASS_HKP      == VALIDATE_FLAG_TRUST_HKP);
+  log_assert (CERTTRUST_CLASS_HKPSPOOL == VALIDATE_FLAG_TRUST_HKPSPOOL);
+
+#undef  X
+#define X (VALIDATE_FLAG_TRUST_SYSTEM | VALIDATE_FLAG_TRUST_CONFIG  \
+           | VALIDATE_FLAG_TRUST_HKP | VALIDATE_FLAG_TRUST_HKPSPOOL)
+
+#if ( X & VALIDATE_FLAG_MASK_TRUST ) !=  X
+# error VALIDATE_FLAG_MASK_TRUST is bad
+#endif
+#if ( ~X & VALIDATE_FLAG_MASK_TRUST )
+# error VALIDATE_FLAG_MASK_TRUST is bad
+#endif
+
+#undef X
+}
 
 
 /* Check whether CERT contains critical extensions we don't know
 
 
 /* Check whether CERT contains critical extensions we don't know
@@ -393,6 +416,7 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
   int any_no_policy_match = 0;
   chain_item_t chain;
 
   int any_no_policy_match = 0;
   chain_item_t chain;
 
+  check_header_constants ();
 
   if (r_exptime)
     *r_exptime = 0;
 
   if (r_exptime)
     *r_exptime = 0;
@@ -540,10 +564,8 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
           if (err)
             goto leave;  /* No. */
 
           if (err)
             goto leave;  /* No. */
 
-          err = is_trusted_cert
-            (subject_cert,
-             (CERTTRUST_CLASS_CONFIG
-              | (flags & VALIDATE_FLAG_SYSTRUST)? CERTTRUST_CLASS_SYSTEM : 0));
+          err = is_trusted_cert (subject_cert,
+                                 (flags & VALIDATE_FLAG_MASK_TRUST));
           if (!err)
             ; /* Yes we trust this cert.  */
           else if (gpg_err_code (err) == GPG_ERR_NOT_TRUSTED)
           if (!err)
             ; /* Yes we trust this cert.  */
           else if (gpg_err_code (err) == GPG_ERR_NOT_TRUSTED)
index b6222b5..c7082e3 100644 (file)
 #define VALIDATE_H
 
 
 #define VALIDATE_H
 
 
-/* Make use of the system provided root certificates.  */
-#define VALIDATE_FLAG_SYSTRUST     1
-
-/* Make use of extra provided root certificates.  */
-#define VALIDATE_FLAG_EXTRATRUST   2
+/* Flag values matching the CERTTRUST_CLASS values and a MASK for
+ * them.  check_header_constants() checks their consistency.  */
+#define VALIDATE_FLAG_TRUST_SYSTEM     1
+#define VALIDATE_FLAG_TRUST_CONFIG     2
+#define VALIDATE_FLAG_TRUST_HKP        4
+#define VALIDATE_FLAG_TRUST_HKPSPOOL   8
+#define VALIDATE_FLAG_MASK_TRUST      0x0f
 
 /* Standard CRL issuer certificate validation; i.e. CRLs are not
  * considered for CRL issuer certificates.  */
 
 /* Standard CRL issuer certificate validation; i.e. CRLs are not
  * considered for CRL issuer certificates.  */
-#define VALIDATE_FLAG_CRL          4
+#define VALIDATE_FLAG_CRL          64
 
 /* If this flag is set along with VALIDATE_FLAG_CRL a full CRL
  * verification is done.  */
 
 /* If this flag is set along with VALIDATE_FLAG_CRL a full CRL
  * verification is done.  */
-#define VALIDATE_FLAG_RECURSIVE    8
+#define VALIDATE_FLAG_RECURSIVE    128
 
 /* Validation mode as used for OCSP.  */
 
 /* Validation mode as used for OCSP.  */
-#define VALIDATE_FLAG_OCSP        16
+#define VALIDATE_FLAG_OCSP         256
 
 /* Validation mode as used with TLS.  */
 
 /* Validation mode as used with TLS.  */
-#define VALIDATE_FLAG_TLS         32
+#define VALIDATE_FLAG_TLS          512
 
 /* Don't do CRL checks.  */
 
 /* Don't do CRL checks.  */
-#define VALIDATE_FLAG_NOCRLCHECK  64
+#define VALIDATE_FLAG_NOCRLCHECK  1024
 
 
 /* Validate the certificate CHAIN up to the trust anchor. Optionally
 
 
 /* Validate the certificate CHAIN up to the trust anchor. Optionally