]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
author: Nathan Hoad <nathan@getoffmalawn.com>
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Tue, 5 Apr 2016 09:43:47 +0000 (12:43 +0300)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Tue, 5 Apr 2016 09:43:47 +0000 (12:43 +0300)
Add chained certificates and signing certificate to peek-then-bumped connections.

The scenario this patch addresses is when Squid is configured with an
intermediate signing CA certificate, and clients have the root CA installed on
their machines. What happens is that the generated certificates come down with
an unknown issuer (the intermediate signing certificate), with no
intermediates, so they are rejected. By adding the configured certificate chain
as old client-first mode did, the intermediate and root certificates come down
as well, resulting in the issuer being identified and the connection being
established "securely".

This work is submitted on behalf of Bloomberg L.P.

src/client_side.cc
src/ssl/support.cc
src/ssl/support.h

index 165ae8607f4bf313a419c7c842cf4f59950a4f28..03dcfd53a420e684a2be5627579de2981bca5d4e 100644 (file)
@@ -2867,6 +2867,9 @@ ConnStateData::sslCrtdHandleReply(const Helper::Reply &reply)
                     bool ret = Ssl::configureSSLUsingPkeyAndCertFromMemory(ssl, reply_message.getBody().c_str(), *port);
                     if (!ret)
                         debugs(33, 5, "Failed to set certificates to ssl object for PeekAndSplice mode");
+
+                    SSL_CTX *sslContext = SSL_get_SSL_CTX(ssl);
+                    Ssl::configureUnconfiguredSslContext(sslContext, signAlgorithm, *port);
                 } else {
                     auto ctx = Ssl::generateSslContextUsingPkeyAndCertFromMemory(reply_message.getBody().c_str(), *port);
                     getSslContextDone(ctx, true);
@@ -3026,6 +3029,9 @@ ConnStateData::getSslContextStart()
             auto ssl = fd_table[clientConnection->fd].ssl.get();
             if (!Ssl::configureSSL(ssl, certProperties, *port))
                 debugs(33, 5, "Failed to set certificates to ssl object for PeekAndSplice mode");
+
+            SSL_CTX *sslContext = SSL_get_SSL_CTX(ssl);
+            Ssl::configureUnconfiguredSslContext(sslContext, certProperties.signAlgorithm, *port);
         } else {
             auto dynCtx = Ssl::generateSslContext(certProperties, *port);
             getSslContextDone(dynCtx, true);
@@ -3041,17 +3047,10 @@ ConnStateData::getSslContextDone(Security::ContextPtr sslContext, bool isNew)
     // Try to add generated ssl context to storage.
     if (port->generateHostCertificates && isNew) {
 
-        if (signAlgorithm == Ssl::algSignTrusted) {
-            // Add signing certificate to the certificates chain
-            X509 *cert = port->signingCert.get();
-            if (SSL_CTX_add_extra_chain_cert(sslContext, cert)) {
-                // increase the certificate lock
-                CRYPTO_add(&(cert->references),1,CRYPTO_LOCK_X509);
-            } else {
-                const int ssl_error = ERR_get_error();
-                debugs(33, DBG_IMPORTANT, "WARNING: can not add signing certificate to SSL context chain: " << ERR_error_string(ssl_error, NULL));
-            }
-            Ssl::addChainToSslContext(sslContext, port->certsToChain.get());
+        if (sslContext && (signAlgorithm == Ssl::algSignTrusted)) {
+            Ssl::chainCertificatesToSSLContext(sslContext, *port);
+        } else if (signAlgorithm == Ssl::algSignTrusted) {
+            debugs(33, DBG_IMPORTANT, "WARNING: can not add signing certificate to SSL context chain because SSL context chain is invalid!");
         }
         //else it is self-signed or untrusted do not attrach any certificate
 
index 611c412d33063e41014b46f92669d1339be29e34..1205bd41b37b06ba75cf236528892dc636f9a990 100644 (file)
@@ -969,6 +969,30 @@ Ssl::generateSslContext(CertificateProperties const &properties, AnyP::PortCfg &
     return createSSLContext(cert, pkey, port);
 }
 
+void
+Ssl::chainCertificatesToSSLContext(SSL_CTX *sslContext, AnyP::PortCfg &port)
+{
+    assert(sslContext != NULL);
+    // Add signing certificate to the certificates chain
+    X509 *signingCert = port.signingCert.get();
+    if (SSL_CTX_add_extra_chain_cert(sslContext, signingCert)) {
+        // increase the certificate lock
+        CRYPTO_add(&(signingCert->references),1,CRYPTO_LOCK_X509);
+    } else {
+        const int ssl_error = ERR_get_error();
+        debugs(33, DBG_IMPORTANT, "WARNING: can not add signing certificate to SSL context chain: " << ERR_error_string(ssl_error, NULL));
+    }
+    Ssl::addChainToSslContext(sslContext, port.certsToChain.get());
+}
+
+void
+Ssl::configureUnconfiguredSslContext(SSL_CTX *sslContext, Ssl::CertSignAlgorithm signAlgorithm,AnyP::PortCfg &port)
+{
+    if (sslContext && signAlgorithm == Ssl::algSignTrusted) {
+        Ssl::chainCertificatesToSSLContext(sslContext, port);
+    }
+}
+
 bool
 Ssl::configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortCfg &port)
 {
index b54828693f527bb87c7a168ad93ba1b9707127a3..16b4b2fb549301b7f5425d97b51c753056bb8625 100644 (file)
@@ -239,6 +239,18 @@ Security::ContextPtr generateSslContextUsingPkeyAndCertFromMemory(const char * d
  */
 Security::ContextPtr createSSLContext(Security::CertPointer & x509, Ssl::EVP_PKEY_Pointer & pkey, AnyP::PortCfg &port);
 
+/**
+ \ingroup ServerProtocolSSLAPI
+ * Chain signing certificate and chained certificates to an SSL Context
+ */
+void chainCertificatesToSSLContext(SSL_CTX *sslContext, AnyP::PortCfg &port);
+
+/**
+ \ingroup ServerProtocolSSLAPI
+ * Configure a previously unconfigured SSL context object.
+ */
+void configureUnconfiguredSslContext(SSL_CTX *sslContext, Ssl::CertSignAlgorithm signAlgorithm,AnyP::PortCfg &port);
+
 /**
   \ingroup ServerProtocolSSLAPI
   * Generates a certificate and a private key using provided properies and set it