From: Alex Rousskov Date: Tue, 19 Mar 2019 20:30:55 +0000 (+0000) Subject: When using OpenSSL, trust intermediate CAs from trusted stores (#383) X-Git-Tag: SQUID_5_0_1~113 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=98f951b75c6867831828b18909240cdc5fab20cf;p=thirdparty%2Fsquid.git When using OpenSSL, trust intermediate CAs from trusted stores (#383) According to [1], GnuTLS and NSS do that by default. Use case: Chrome and Mozilla no longer trust Semantic root CAs _but_ still trust several whitelisted Semantic intermediate CAs[2]. Squid built with OpenSSL cannot do that without X509_V_FLAG_PARTIAL_CHAIN. [1] https://www.openldap.org/lists/openldap-devel/201506/msg00012.html [2] https://wiki.mozilla.org/CA/Additional_Trust_Changes#Symantec --- diff --git a/src/security/PeerOptions.cc b/src/security/PeerOptions.cc index be4022de54..13b1e1cff9 100644 --- a/src/security/PeerOptions.cc +++ b/src/security/PeerOptions.cc @@ -287,6 +287,7 @@ Security::PeerOptions::createClientContext(bool setOptions) updateContextNpn(t); updateContextCa(t); updateContextCrl(t); + updateContextTrust(t); } return t; @@ -702,6 +703,23 @@ Security::PeerOptions::updateContextCrl(Security::ContextPointer &ctx) #endif /* USE_OPENSSL */ } +void +Security::PeerOptions::updateContextTrust(Security::ContextPointer &ctx) +{ +#if USE_OPENSSL +#if defined(X509_V_FLAG_PARTIAL_CHAIN) + const auto st = SSL_CTX_get_cert_store(ctx.get()); + assert(st); + if (X509_STORE_set_flags(st, X509_V_FLAG_PARTIAL_CHAIN) != 1) { + debugs(83, DBG_IMPORTANT, "ERROR: Failed to enable trust in intermediate CA certificates: " << + Security::ErrorString(ERR_get_error())); + } +#endif +#elif USE_GNUTLS + // Modern GnuTLS versions trust intermediate CA certificates by default. +#endif /* TLS library */ +} + void Security::PeerOptions::updateSessionOptions(Security::SessionPointer &s) { diff --git a/src/security/PeerOptions.h b/src/security/PeerOptions.h index 849c1f3fbc..43da1afec1 100644 --- a/src/security/PeerOptions.h +++ b/src/security/PeerOptions.h @@ -56,6 +56,9 @@ public: /// setup the CRL details for the given context void updateContextCrl(Security::ContextPointer &); + /// decide which CAs to trust + void updateContextTrust(Security::ContextPointer &); + /// setup any library-specific options that can be set for the given session void updateSessionOptions(Security::SessionPointer &); diff --git a/src/security/ServerOptions.cc b/src/security/ServerOptions.cc index 6374070478..da4f355893 100644 --- a/src/security/ServerOptions.cc +++ b/src/security/ServerOptions.cc @@ -439,6 +439,7 @@ Security::ServerOptions::updateContextClientCa(Security::ContextPointer &ctx) } updateContextCrl(ctx); + updateContextTrust(ctx); } else { debugs(83, 9, "Not requiring any client certificates"); diff --git a/src/tests/stub_libsecurity.cc b/src/tests/stub_libsecurity.cc index cc48ce5e53..a917ecbaf2 100644 --- a/src/tests/stub_libsecurity.cc +++ b/src/tests/stub_libsecurity.cc @@ -86,6 +86,7 @@ void Security::PeerOptions::updateTlsVersionLimits() STUB Security::ContextPointer Security::PeerOptions::createBlankContext() const STUB_RETVAL(Security::ContextPointer()) void Security::PeerOptions::updateContextCa(Security::ContextPointer &) STUB void Security::PeerOptions::updateContextCrl(Security::ContextPointer &) STUB +void Security::PeerOptions::updateContextTrust(Security::ContextPointer &) STUB void Security::PeerOptions::updateSessionOptions(Security::SessionPointer &) STUB void Security::PeerOptions::dumpCfg(Packable*, char const*) const STUB void Security::PeerOptions::parseOptions() STUB