From 831d014550863026dfefa774c961a21bd20c1e48 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 21 Feb 2017 14:55:04 +0100 Subject: [PATCH] dirmngr: Add special treatment for the standard hkps pool to ntbtls. * 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 --- dirmngr/certcache.c | 7 +++---- dirmngr/crlcache.c | 3 ++- dirmngr/http-ntbtls.c | 25 ++++++++++++++++++++----- dirmngr/http.h | 2 +- dirmngr/server.c | 5 +++-- dirmngr/validate.c | 30 ++++++++++++++++++++++++++---- dirmngr/validate.h | 22 ++++++++++++---------- 7 files changed, 67 insertions(+), 27 deletions(-) diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index 47eea25cc..c83b00e88 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -709,16 +709,15 @@ cert_cache_init (strlist_t hkp_cacerts) 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); + for (sl = hkp_cacerts; sl; sl = sl->next) + load_certs_from_file (sl->d, CERTTRUST_CLASS_HKP, 0); + initialization_done = 1; release_cache_lock (); diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index 3cd8cf420..c60d3fb06 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -1851,7 +1851,8 @@ crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl, 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) diff --git a/dirmngr/http-ntbtls.c b/dirmngr/http-ntbtls.c index 3038cae6b..00d6a58bf 100644 --- a/dirmngr/http-ntbtls.c +++ b/dirmngr/http-ntbtls.c @@ -41,20 +41,23 @@ gnupg_http_tls_verify_cb (void *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; + const char *hostname; (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; - (cert = ntbtls_x509_get_peer_cert (tls_context, idx)); idx++) + (cert = ntbtls_x509_get_peer_cert (tls, idx)); idx++) { if (!idx) hostcert = cert; @@ -73,10 +76,22 @@ gnupg_http_tls_verify_cb (void *opaque, } 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; diff --git a/dirmngr/http.h b/dirmngr/http.h index 331ee61b8..2609b9ede 100644 --- a/dirmngr/http.h +++ b/dirmngr/http.h @@ -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_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. */ }; diff --git a/dirmngr/server.c b/dirmngr/server.c index f726d1b35..961bba07d 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -1852,8 +1852,9 @@ cmd_validate (assuan_context_t ctx, char *line) } 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); diff --git a/dirmngr/validate.c b/dirmngr/validate.c index 5bd784fe1..3671a8b9e 100644 --- a/dirmngr/validate.c +++ b/dirmngr/validate.c @@ -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); +/* 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 @@ -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; + check_header_constants (); 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. */ - 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) diff --git a/dirmngr/validate.h b/dirmngr/validate.h index b6222b51f..c7082e3d1 100644 --- a/dirmngr/validate.h +++ b/dirmngr/validate.h @@ -22,28 +22,30 @@ #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. */ -#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. */ -#define VALIDATE_FLAG_RECURSIVE 8 +#define VALIDATE_FLAG_RECURSIVE 128 /* Validation mode as used for OCSP. */ -#define VALIDATE_FLAG_OCSP 16 +#define VALIDATE_FLAG_OCSP 256 /* Validation mode as used with TLS. */ -#define VALIDATE_FLAG_TLS 32 +#define VALIDATE_FLAG_TLS 512 /* 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