[prev in list] [next in list] [prev in thread] [next in thread] 

List:       squid-cvs
Subject:    /bzr/squid3/trunk/ r12317: Bug fix: TLS/SSL Options does not apply to the dynamically generated cert
From:       Christos Tsantilas <chtsanti () users ! sourceforge ! net>
Date:       2012-09-06 13:12:26
Message-ID: 20120906131504.25255.qmail () squid-cache ! org
[Download RAW message or body]

--===============1249137327==
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

------------------------------------------------------------
revno: 12317
committer: Christos Tsantilas <chtsanti@users.sourceforge.net>
branch nick: trunk
timestamp: Thu 2012-09-06 16:12:26 +0300
message:
  Bug fix: TLS/SSL Options does not apply to the dynamically generated certificates
  
  The TLS/SSL options configured with http_port configuration parameter does not
  used to generate SSL_CTX context objects used to establish SSL connections.
  This is means that certificate based authentication, or SSL version selection
  and other SSL/TLS http_port options does not work for ssl-bumped connection.
  This patch fixes this problem.
  
  This is a Measurement Factory project
modified:
  src/anyp/PortCfg.cc
  src/anyp/PortCfg.h
  src/client_side.cc
  src/ssl/gadgets.h
  src/ssl/support.cc
  src/ssl/support.h
  src/tests/stub_libsslsquid.cc

--===============1249137327==
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"; name="r12317.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

=== modified file 'src/anyp/PortCfg.cc'
--- a/src/anyp/PortCfg.cc	2012-05-14 10:37:40 +0000
+++ b/src/anyp/PortCfg.cc	2012-09-06 13:12:26 +0000
@@ -96,20 +96,6 @@
 #if USE_SSL
 void AnyP::PortCfg::configureSslServerContext()
 {
-    staticSslContext.reset(
-        sslCreateServerContext(cert, key,
-                               version, cipher, options, sslflags, clientca,
-                               cafile, capath, crlfile, dhfile,
-                               sslContextSessionId));
-
-    if (!staticSslContext) {
-        char buf[128];
-        fatalf("%s_port %s initialization error", protocol,  s.ToURL(buf, \
                sizeof(buf)));
-    }
-
-    if (!sslBump)
-        return;
-
     if (cert)
         Ssl::readCertChainAndPrivateKeyFromFiles(signingCert, signPkey, \
certsToChain, cert, key);  
@@ -128,6 +114,35 @@
         char buf[128];
         fatalf("Unable to generate  signing SSL certificate for untrusted sites for \
%s_port %s", protocol, s.ToURL(buf, sizeof(buf)));  }
+
+    if (crlfile)
+        clientVerifyCrls.reset(Ssl::loadCrl(crlfile, sslContextFlags));
+
+    if (clientca) {
+        clientCA.reset(SSL_load_client_CA_file(clientca));
+        if (clientCA.get() == NULL) {
+            fatalf("Unable to read client CAs! from %s", clientca);
+        }
+    }
+
+    contextMethod = Ssl::contextMethod(version);
+    if (!contextMethod)
+        fatalf("Unable to compute context method to use");
+
+    if (dhfile)
+        dhParams.reset(Ssl::readDHParams(dhfile));
+
+    if (sslflags)
+        sslContextFlags = Ssl::parse_flags(sslflags);
+
+    sslOptions = Ssl::parse_options(options);
+
+    staticSslContext.reset(sslCreateServerContext(*this));
+
+    if (!staticSslContext) {
+        char buf[128];
+        fatalf("%s_port %s initialization error", protocol,  s.ToURL(buf, \
sizeof(buf))); +    }
 }
 #endif
 

=== modified file 'src/anyp/PortCfg.h'
--- a/src/anyp/PortCfg.h	2012-06-19 21:51:49 +0000
+++ b/src/anyp/PortCfg.h	2012-09-06 13:12:26 +0000
@@ -76,6 +76,13 @@
     Ssl::X509_STACK_Pointer certsToChain; ///<  x509 certificates to send with the \
                generated cert
     Ssl::X509_Pointer untrustedSigningCert; ///< x509 certificate for signing \
                untrusted generated certificates
     Ssl::EVP_PKEY_Pointer untrustedSignPkey; ///< private key for signing untrusted \
generated certificates +
+    Ssl::X509_CRL_STACK_Pointer clientVerifyCrls; ///< additional CRL lists to use \
when verifying the client certificate +    Ssl::X509_NAME_STACK_Pointer clientCA; \
///< CA certificates to use when verifying client certificates +    Ssl::DH_Pointer \
dhParams; ///< DH parameters for temporary/ephemeral DH key exchanges +    \
Ssl::ContextMethod contextMethod; ///< The context method (SSL_METHOD) to use when \
creating certificates +    long sslContextFlags; ///< flags modifying the use of SSL
+    long sslOptions; ///< SSL engine options
 #endif
 
     CBDATA_CLASS2(PortCfg); // namespaced

=== modified file 'src/client_side.cc'
--- a/src/client_side.cc	2012-08-30 09:02:06 +0000
+++ b/src/client_side.cc	2012-09-06 13:12:26 +0000
@@ -3700,7 +3700,7 @@
                 debugs(33, 5, HERE << "Certificate for " << sslConnectHostOrIp << " \
cannot be generated. ssl_crtd response: " << reply_message.getBody());  } else {
                 debugs(33, 5, HERE << "Certificate for " << sslConnectHostOrIp << " \
                was successfully recieved from ssl_crtd");
-                SSL_CTX *ctx = \
Ssl::generateSslContextUsingPkeyAndCertFromMemory(reply_message.getBody().c_str()); + \
SSL_CTX *ctx = Ssl::generateSslContextUsingPkeyAndCertFromMemory(reply_message.getBody().c_str(), \
*port);  getSslContextDone(ctx, true);
                 return;
             }
@@ -3844,7 +3844,7 @@
 #endif // USE_SSL_CRTD
 
         debugs(33, 5, HERE << "Generating SSL certificate for " << \
                certProperties.commonName);
-        dynCtx = Ssl::generateSslContext(certProperties);
+        dynCtx = Ssl::generateSslContext(certProperties, *port);
         getSslContextDone(dynCtx, true);
         return;
     }

=== modified file 'src/ssl/gadgets.h'
--- a/src/ssl/gadgets.h	2012-08-28 13:00:30 +0000
+++ b/src/ssl/gadgets.h	2012-09-06 13:12:26 +0000
@@ -26,6 +26,12 @@
  because they are used by ssl_crtd.
  */
 
+#if OPENSSL_VERSION_NUMBER < 0x00909000L
+typedef SSL_METHOD * ContextMethod;
+#else
+typedef const SSL_METHOD * ContextMethod;
+#endif
+
 /**
    \ingroup SslCrtdSslAPI
   * Add SSL locking (a.k.a. reference counting) to TidyPointer
@@ -55,6 +61,14 @@
             function(a); \
         }
 
+// Macro to be used to define the C++ wrapper function of a sk_*_pop_free
+// openssl family functions. The C++ function suffixed with the _free_wrapper
+// extension
+#define sk_free_wrapper(sk_object, argument, freefunction) \
+        extern "C++" inline void sk_object ## _free_wrapper(argument a) { \
+            sk_object ## _pop_free(a, freefunction); \
+        }
+
 /**
  \ingroup SslCrtdSslAPI
  * TidyPointer typedefs for  common SSL objects
@@ -62,8 +76,8 @@
 CtoCpp1(X509_free, X509 *)
 typedef LockingPointer<X509, X509_free_cpp, CRYPTO_LOCK_X509> X509_Pointer;
 
-CtoCpp1(sk_X509_free, STACK_OF(X509) *)
-typedef TidyPointer<STACK_OF(X509), sk_X509_free_cpp> X509_STACK_Pointer;
+sk_free_wrapper(sk_X509, STACK_OF(X509) *, X509_free)
+typedef TidyPointer<STACK_OF(X509), sk_X509_free_wrapper> X509_STACK_Pointer;
 
 CtoCpp1(EVP_PKEY_free, EVP_PKEY *)
 typedef LockingPointer<EVP_PKEY, EVP_PKEY_free_cpp, CRYPTO_LOCK_EVP_PKEY> \
EVP_PKEY_Pointer; @@ -95,6 +109,15 @@
 CtoCpp1(SSL_free, SSL *)
 typedef TidyPointer<SSL, SSL_free_cpp> SSL_Pointer;
 
+CtoCpp1(DH_free, DH *);
+typedef TidyPointer<DH, DH_free_cpp> DH_Pointer;
+
+sk_free_wrapper(sk_X509_CRL, STACK_OF(X509_CRL) *, X509_CRL_free)
+typedef TidyPointer<STACK_OF(X509_CRL), sk_X509_CRL_free_wrapper> \
X509_CRL_STACK_Pointer; +
+sk_free_wrapper(sk_X509_NAME, STACK_OF(X509_NAME) *, X509_NAME_free)
+typedef TidyPointer<STACK_OF(X509_NAME), sk_X509_NAME_free_wrapper> \
X509_NAME_STACK_Pointer; +
 /**
  \ingroup SslCrtdSslAPI
  * Create 1024 bits rsa key.

=== modified file 'src/ssl/support.cc'
--- a/src/ssl/support.cc	2012-08-28 19:12:13 +0000
+++ b/src/ssl/support.cc	2012-09-06 13:12:26 +0000
@@ -41,6 +41,7 @@
 #if USE_SSL
 
 #include "acl/FilledChecklist.h"
+#include "anyp/PortCfg.h"
 #include "fde.h"
 #include "globals.h"
 #include "protos.h"
@@ -451,8 +452,8 @@
 };
 
 /// \ingroup ServerProtocolSSLInternal
-static long
-ssl_parse_options(const char *options)
+long
+Ssl::parse_options(const char *options)
 {
     long op = 0;
     char *tmp;
@@ -545,8 +546,8 @@
 #define SSL_FLAG_VERIFY_CRL_ALL		(1<<6)
 
 /// \ingroup ServerProtocolSSLInternal
-static long
-ssl_parse_flags(const char *flags)
+long
+Ssl::parse_flags(const char *flags)
 {
     long fl = 0;
     char *tmp;
@@ -705,99 +706,71 @@
     return count;
 }
 
-SSL_CTX *
-sslCreateServerContext(const char *certfile, const char *keyfile, int version, const \
char *cipher, const char *options, const char *flags, const char *clientCA, const \
char *CAfile, const char *CApath, const char *CRLfile, const char *dhfile, const char \
*context) +STACK_OF(X509_CRL) *
+Ssl::loadCrl(const char *CRLFile, long &flags)
+{
+    X509_CRL *crl;
+    BIO *in = BIO_new_file(CRLFile, "r");
+    if (!in) {
+        debugs(83, 2, "WARNING: Failed to open CRL file '" << CRLFile << "'");
+        return NULL;
+    }
+
+    STACK_OF(X509_CRL) *CRLs = sk_X509_CRL_new_null();
+    if (!CRLs) {
+        debugs(83, 2, "WARNING: Failed to allocate X509_CRL stack  to load file '" \
<< CRLFile << "'"); +        return NULL;
+    }
+
+    int count = 0;
+    while ((crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL))) {
+        if (!sk_X509_CRL_push(CRLs, crl))
+            debugs(83, 2, "WARNING: Failed to add CRL from file '" << CRLFile << \
"'"); +        else
+            ++count;
+    }
+    BIO_free(in);
+
+    if (count)
+        flags |= SSL_FLAG_VERIFY_CRL;
+
+    return CRLs;
+}
+
+DH *
+Ssl::readDHParams(const char *dhfile)
+{
+    FILE *in = fopen(dhfile, "r");
+    DH *dh = NULL;
+    int codes;
+
+    if (in) {
+        dh = PEM_read_DHparams(in, NULL, NULL, NULL);
+        fclose(in);
+    }
+
+    if (!dh)
+        debugs(83, DBG_IMPORTANT, "WARNING: Failed to read DH parameters '" << \
dhfile << "'"); +    else if (dh && DH_check(dh, &codes) == 0) {
+        if (codes) {
+            debugs(83, DBG_IMPORTANT, "WARNING: Failed to verify DH parameters '" << \
dhfile  << "' (" << std::hex << codes  << ")"); +            DH_free(dh);
+            dh = NULL;
+        }
+    }
+    return dh;
+}
+
+static bool
+configureSslContext(SSL_CTX *sslContext, AnyP::PortCfg &port)
 {
     int ssl_error;
-#if OPENSSL_VERSION_NUMBER < 0x00909000L
-    SSL_METHOD *method;
-#else
-    const SSL_METHOD *method;
-#endif
-    SSL_CTX *sslContext;
-    long fl = ssl_parse_flags(flags);
-
-    ssl_initialize();
-
-    if (!keyfile)
-        keyfile = certfile;
-
-    if (!certfile)
-        certfile = keyfile;
-
-    if (!CAfile)
-        CAfile = clientCA;
-
-    if (!certfile) {
-        debugs(83, DBG_CRITICAL, "ERROR: No certificate file");
-        return NULL;
-    }
-
-    switch (version) {
-
-    case 2:
-#ifndef OPENSSL_NO_SSL2
-        debugs(83, 5, "Using SSLv2.");
-        method = SSLv2_server_method();
-#else
-        debugs(83, DBG_IMPORTANT, "SSLv2 is not available in this Proxy.");
-        return NULL;
-#endif
-        break;
-
-    case 3:
-        debugs(83, 5, "Using SSLv3.");
-        method = SSLv3_server_method();
-        break;
-
-    case 4:
-        debugs(83, 5, "Using TLSv1.");
-        method = TLSv1_server_method();
-        break;
-
-    case 5:
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L  // NP: not sure exactly which sub-version \
                yet.
-        debugs(83, 5, "Using TLSv1.1.");
-        method = TLSv1_1_server_method();
-#else
-        debugs(83, DBG_IMPORTANT, "TLSv1.1 is not available in this Proxy.");
-        return NULL;
-#endif
-        break;
-
-    case 6:
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version \
                yet.
-        debugs(83, 5, "Using TLSv1.2");
-        method = TLSv1_2_server_method();
-#else
-        debugs(83, DBG_IMPORTANT, "TLSv1.2 is not available in this Proxy.");
-        return NULL;
-#endif
-        break;
-
-    case 1:
-
-    default:
-        debugs(83, 5, "Using SSLv2/SSLv3.");
-        method = SSLv23_server_method();
-        break;
-    }
-
-    sslContext = SSL_CTX_new(method);
-
-    if (sslContext == NULL) {
-        ssl_error = ERR_get_error();
-        debugs(83, DBG_CRITICAL, "ERROR: Failed to allocate SSL context: " << \
                ERR_error_string(ssl_error, NULL));
-        return NULL;
-    }
-
-    SSL_CTX_set_options(sslContext, ssl_parse_options(options));
-
-    if (context && *context) {
-        SSL_CTX_set_session_id_context(sslContext, (const unsigned char *)context, \
                strlen(context));
-    }
-
-    if (fl & SSL_FLAG_NO_SESSION_REUSE) {
+    SSL_CTX_set_options(sslContext, port.sslOptions);
+
+    if (port.sslContextSessionId)
+        SSL_CTX_set_session_id_context(sslContext, (const unsigned char \
*)port.sslContextSessionId, strlen(port.sslContextSessionId)); +
+    if (port.sslContextFlags & SSL_FLAG_NO_SESSION_REUSE) {
         SSL_CTX_set_session_cache_mode(sslContext, SSL_SESS_CACHE_OFF);
     }
 
@@ -807,77 +780,38 @@
         SSL_CTX_set_quiet_shutdown(sslContext, 1);
     }
 
-    if (cipher) {
-        debugs(83, 5, "Using chiper suite " << cipher << ".");
+    if (port.cipher) {
+        debugs(83, 5, "Using chiper suite " << port.cipher << ".");
 
-        if (!SSL_CTX_set_cipher_list(sslContext, cipher)) {
+        if (!SSL_CTX_set_cipher_list(sslContext, port.cipher)) {
             ssl_error = ERR_get_error();
-            debugs(83, DBG_CRITICAL, "ERROR: Failed to set SSL cipher suite '" << \
                cipher << "': " << ERR_error_string(ssl_error, NULL));
-            SSL_CTX_free(sslContext);
-            return NULL;
+            debugs(83, DBG_CRITICAL, "ERROR: Failed to set SSL cipher suite '" << \
port.cipher << "': " << ERR_error_string(ssl_error, NULL)); +            return \
false;  }
     }
 
-    debugs(83, DBG_IMPORTANT, "Using certificate in " << certfile);
-
-    if (!SSL_CTX_use_certificate_chain_file(sslContext, certfile)) {
-        ssl_error = ERR_get_error();
-        debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL certificate '" << \
                certfile << "': " << ERR_error_string(ssl_error, NULL));
-        SSL_CTX_free(sslContext);
-        return NULL;
-    }
-
-    debugs(83, DBG_IMPORTANT, "Using private key in " << keyfile);
-    ssl_ask_password(sslContext, keyfile);
-
-    if (!SSL_CTX_use_PrivateKey_file(sslContext, keyfile, SSL_FILETYPE_PEM)) {
-        ssl_error = ERR_get_error();
-        debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL private key '" << \
                keyfile << "': " << ERR_error_string(ssl_error, NULL));
-        SSL_CTX_free(sslContext);
-        return NULL;
-    }
-
-    debugs(83, 5, "Comparing private and public SSL keys.");
-
-    if (!SSL_CTX_check_private_key(sslContext)) {
-        ssl_error = ERR_get_error();
-        debugs(83, DBG_CRITICAL, "ERROR: SSL private key '" << certfile << "' does \
                not match public key '" <<
-               keyfile << "': " << ERR_error_string(ssl_error, NULL));
-        SSL_CTX_free(sslContext);
-        return NULL;
-    }
-
     debugs(83, 9, "Setting RSA key generation callback.");
     SSL_CTX_set_tmp_rsa_callback(sslContext, ssl_temp_rsa_cb);
 
     debugs(83, 9, "Setting CA certificate locations.");
 
-    if ((CAfile || CApath) && !SSL_CTX_load_verify_locations(sslContext, CAfile, \
CApath)) { +    const char *cafile = port.cafile ? port.cafile : port.clientca;
+    if ((cafile || port.capath) && !SSL_CTX_load_verify_locations(sslContext, \
cafile, port.capath)) {  ssl_error = ERR_get_error();
         debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate \
locations: " << ERR_error_string(ssl_error, NULL));  }
 
-    if (!(fl & SSL_FLAG_NO_DEFAULT_CA) &&
+    if (!(port.sslContextFlags & SSL_FLAG_NO_DEFAULT_CA) &&
             !SSL_CTX_set_default_verify_paths(sslContext)) {
         ssl_error = ERR_get_error();
         debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting default CA \
certificate location: " << ERR_error_string(ssl_error, NULL));  }
 
-    if (clientCA) {
-        STACK_OF(X509_NAME) *cert_names;
-        debugs(83, 9, "Set client certifying authority list.");
-        cert_names = SSL_load_client_CA_file(clientCA);
-
-        if (cert_names == NULL) {
-            debugs(83, DBG_IMPORTANT, "ERROR: loading the client CA certificates \
                from '" << clientCA << "\': " << \
                ERR_error_string(ERR_get_error(),NULL));
-            SSL_CTX_free(sslContext);
-            return NULL;
-        }
-
+    if (port.clientCA.get()) {
         ERR_clear_error();
-        SSL_CTX_set_client_CA_list(sslContext, cert_names);
+        SSL_CTX_set_client_CA_list(sslContext, port.clientCA.get());
 
-        if (fl & SSL_FLAG_DELAYED_AUTH) {
+        if (port.sslContextFlags & SSL_FLAG_DELAYED_AUTH) {
             debugs(83, 9, "Not requesting client certificates until acl processing \
requires one");  SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
         } else {
@@ -885,17 +819,20 @@
             SSL_CTX_set_verify(sslContext, SSL_VERIFY_PEER | \
SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb);  }
 
-        if (CRLfile) {
-            ssl_load_crl(sslContext, CRLfile);
-            fl |= SSL_FLAG_VERIFY_CRL;
+        if (port.clientVerifyCrls.get()) {
+            X509_STORE *st = SSL_CTX_get_cert_store(sslContext);
+            for (int i = 0; i < sk_X509_CRL_num(port.clientVerifyCrls.get()); ++i) {
+                X509_CRL *crl = sk_X509_CRL_value(port.clientVerifyCrls.get(), i);
+                if (!X509_STORE_add_crl(st, crl))
+                    debugs(83, 2, "WARNING: Failed to add CRL");
+            }
         }
 
 #if X509_V_FLAG_CRL_CHECK
-        if (fl & SSL_FLAG_VERIFY_CRL_ALL)
+        if (port.sslContextFlags & SSL_FLAG_VERIFY_CRL_ALL)
             X509_STORE_set_flags(SSL_CTX_get_cert_store(sslContext), \
                X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
-        else if (fl & SSL_FLAG_VERIFY_CRL)
+        else if (port.sslContextFlags & SSL_FLAG_VERIFY_CRL)
             X509_STORE_set_flags(SSL_CTX_get_cert_store(sslContext), \
                X509_V_FLAG_CRL_CHECK);
-
 #endif
 
     } else {
@@ -903,33 +840,94 @@
         SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
     }
 
-    if (dhfile) {
-        FILE *in = fopen(dhfile, "r");
-        DH *dh = NULL;
-        int codes;
-
-        if (in) {
-            dh = PEM_read_DHparams(in, NULL, NULL, NULL);
-            fclose(in);
-        }
-
-        if (!dh)
-            debugs(83, DBG_IMPORTANT, "WARNING: Failed to read DH parameters '" << \
                dhfile << "'");
-        else if (dh && DH_check(dh, &codes) == 0) {
-            if (codes) {
-                debugs(83, DBG_IMPORTANT, "WARNING: Failed to verify DH parameters \
                '" << dhfile  << "' (" << std::hex << codes  << ")");
-                DH_free(dh);
-                dh = NULL;
-            }
-        }
-
-        if (dh)
-            SSL_CTX_set_tmp_dh(sslContext, dh);
+    if (port.dhParams.get()) {
+        SSL_CTX_set_tmp_dh(sslContext, port.dhParams.get());
     }
 
-    if (fl & SSL_FLAG_DONT_VERIFY_DOMAIN)
+    if (port.sslContextFlags & SSL_FLAG_DONT_VERIFY_DOMAIN)
         SSL_CTX_set_ex_data(sslContext, ssl_ctx_ex_index_dont_verify_domain, (void \
*) -1);  
+    return true;
+}
+
+SSL_CTX *
+sslCreateServerContext(AnyP::PortCfg &port)
+{
+    int ssl_error;
+    SSL_CTX *sslContext;
+    const char *keyfile, *certfile;
+    certfile = port.cert;
+    keyfile = port.key;
+
+    ssl_initialize();
+
+    if (!keyfile)
+        keyfile = certfile;
+
+    if (!certfile)
+        certfile = keyfile;
+
+    sslContext = SSL_CTX_new(port.contextMethod);
+
+    if (sslContext == NULL) {
+        ssl_error = ERR_get_error();
+        debugs(83, DBG_CRITICAL, "ERROR: Failed to allocate SSL context: " << \
ERR_error_string(ssl_error, NULL)); +        return NULL;
+    }
+
+    if (!SSL_CTX_use_certificate(sslContext, port.signingCert.get())) {
+        ssl_error = ERR_get_error();
+        debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL certificate '" << \
certfile << "': " << ERR_error_string(ssl_error, NULL)); +        \
SSL_CTX_free(sslContext); +        return NULL;
+    }
+
+    if (!SSL_CTX_use_PrivateKey(sslContext, port.signPkey.get())) {
+        ssl_error = ERR_get_error();
+        debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL private key '" << \
keyfile << "': " << ERR_error_string(ssl_error, NULL)); +        \
SSL_CTX_free(sslContext); +        return NULL;
+    }
+
+    Ssl::addChainToSslContext(sslContext, port.certsToChain.get());
+
+    /* Alternate code;
+        debugs(83, DBG_IMPORTANT, "Using certificate in " << certfile);
+
+        if (!SSL_CTX_use_certificate_chain_file(sslContext, certfile)) {
+            ssl_error = ERR_get_error();
+            debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL certificate '" << \
certfile << "': " << ERR_error_string(ssl_error, NULL)); +            \
SSL_CTX_free(sslContext); +            return NULL;
+        }
+
+        debugs(83, DBG_IMPORTANT, "Using private key in " << keyfile);
+        ssl_ask_password(sslContext, keyfile);
+
+        if (!SSL_CTX_use_PrivateKey_file(sslContext, keyfile, SSL_FILETYPE_PEM)) {
+            ssl_error = ERR_get_error();
+            debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL private key '" << \
keyfile << "': " << ERR_error_string(ssl_error, NULL)); +            \
SSL_CTX_free(sslContext); +            return NULL;
+        }
+
+        debugs(83, 5, "Comparing private and public SSL keys.");
+
+        if (!SSL_CTX_check_private_key(sslContext)) {
+            ssl_error = ERR_get_error();
+            debugs(83, DBG_CRITICAL, "ERROR: SSL private key '" << certfile << "' \
does not match public key '" << +                   keyfile << "': " << \
ERR_error_string(ssl_error, NULL)); +            SSL_CTX_free(sslContext);
+            return NULL;
+        }
+    */
+
+    if (!configureSslContext(sslContext, port)) {
+        debugs(83, DBG_CRITICAL, "ERROR: Configuring static SSL context");
+        SSL_CTX_free(sslContext);
+        return NULL;
+    }
+
     return sslContext;
 }
 
@@ -943,7 +941,7 @@
     const SSL_METHOD *method;
 #endif
     SSL_CTX *sslContext;
-    long fl = ssl_parse_flags(flags);
+    long fl = Ssl::parse_flags(flags);
 
     ssl_initialize();
 
@@ -1011,7 +1009,7 @@
                ERR_error_string(ssl_error, NULL));
     }
 
-    SSL_CTX_set_options(sslContext, ssl_parse_options(options));
+    SSL_CTX_set_options(sslContext, Ssl::parse_options(options));
 
     if (cipher) {
         debugs(83, 5, "Using chiper suite " << cipher << ".");
@@ -1299,21 +1297,84 @@
     return str;
 }
 
+Ssl::ContextMethod
+Ssl::contextMethod(int version)
+{
+    Ssl::ContextMethod method;
+
+    switch (version) {
+
+    case 2:
+#ifndef OPENSSL_NO_SSL2
+        debugs(83, 5, "Using SSLv2.");
+        method = SSLv2_server_method();
+#else
+        debugs(83, DBG_IMPORTANT, "SSLv2 is not available in this Proxy.");
+        return NULL;
+#endif
+        break;
+
+    case 3:
+        debugs(83, 5, "Using SSLv3.");
+        method = SSLv3_server_method();
+        break;
+
+    case 4:
+        debugs(83, 5, "Using TLSv1.");
+        method = TLSv1_server_method();
+        break;
+
+    case 5:
+#if OPENSSL_VERSION_NUMBER >= 0x10001000L  // NP: not sure exactly which sub-version \
yet. +        debugs(83, 5, "Using TLSv1.1.");
+        method = TLSv1_1_server_method();
+#else
+        debugs(83, DBG_IMPORTANT, "TLSv1.1 is not available in this Proxy.");
+        return NULL;
+#endif
+        break;
+
+    case 6:
+#if OPENSSL_VERSION_NUMBER >= 0x10001000L // NP: not sure exactly which sub-version \
yet. +        debugs(83, 5, "Using TLSv1.2");
+        method = TLSv1_2_server_method();
+#else
+        debugs(83, DBG_IMPORTANT, "TLSv1.2 is not available in this Proxy.");
+        return NULL;
+#endif
+        break;
+
+    case 1:
+
+    default:
+        debugs(83, 5, "Using SSLv2/SSLv3.");
+        method = SSLv23_server_method();
+        break;
+    }
+    return method;
+}
+
 /// \ingroup ServerProtocolSSLInternal
 /// Create SSL context and apply ssl certificate and private key to it.
-static SSL_CTX * createSSLContext(Ssl::X509_Pointer & x509, Ssl::EVP_PKEY_Pointer & \
pkey) +static SSL_CTX *
+createSSLContext(Ssl::X509_Pointer & x509, Ssl::EVP_PKEY_Pointer & pkey, \
AnyP::PortCfg &port)  {
-    Ssl::SSL_CTX_Pointer sslContext(SSL_CTX_new(SSLv23_server_method()));
+    Ssl::SSL_CTX_Pointer sslContext(SSL_CTX_new(port.contextMethod));
 
     if (!SSL_CTX_use_certificate(sslContext.get(), x509.get()))
         return NULL;
 
     if (!SSL_CTX_use_PrivateKey(sslContext.get(), pkey.get()))
         return NULL;
+
+    if (!configureSslContext(sslContext.get(), port))
+        return NULL;
+
     return sslContext.release();
 }
 
-SSL_CTX * Ssl::generateSslContextUsingPkeyAndCertFromMemory(const char * data)
+SSL_CTX *
+Ssl::generateSslContextUsingPkeyAndCertFromMemory(const char * data, AnyP::PortCfg \
&port)  {
     Ssl::X509_Pointer cert;
     Ssl::EVP_PKEY_Pointer pkey;
@@ -1323,10 +1384,11 @@
     if (!cert || !pkey)
         return NULL;
 
-    return createSSLContext(cert, pkey);
+    return createSSLContext(cert, pkey, port);
 }
 
-SSL_CTX * Ssl::generateSslContext(CertificateProperties const &properties)
+SSL_CTX *
+Ssl::generateSslContext(CertificateProperties const &properties, AnyP::PortCfg \
&port)  {
     Ssl::X509_Pointer cert;
     Ssl::EVP_PKEY_Pointer pkey;
@@ -1339,7 +1401,7 @@
     if (!pkey)
         return NULL;
 
-    return createSSLContext(cert, pkey);
+    return createSSLContext(cert, pkey, port);
 }
 
 bool Ssl::verifySslCertificate(SSL_CTX * sslContext, CertificateProperties const \
&properties) @@ -1432,6 +1494,12 @@
 {
     if (keyFilename == NULL)
         keyFilename = certFilename;
+
+    if (certFilename == NULL)
+        certFilename = keyFilename;
+
+    debugs(83, DBG_IMPORTANT, "Using certificate in " << certFilename);
+
     if (!chain)
         chain.reset(sk_X509_new_null());
     if (!chain)

=== modified file 'src/ssl/support.h'
--- a/src/ssl/support.h	2012-08-28 13:00:30 +0000
+++ b/src/ssl/support.h	2012-09-06 13:12:26 +0000
@@ -64,6 +64,11 @@
 #define SQUID_SSL_ERROR_MIN SQUID_X509_V_ERR_CERT_CHANGE
 #define SQUID_SSL_ERROR_MAX INT_MAX
 
+namespace AnyP
+{
+class PortCfg;
+};
+
 namespace Ssl
 {
 /// Squid defined error code (<0),  an error code returned by SSL X509 api, or \
SSL_ERROR_NONE @@ -74,7 +79,7 @@
 } //namespace Ssl
 
 /// \ingroup ServerProtocolSSLAPI
-SSL_CTX *sslCreateServerContext(const char *certfile, const char *keyfile, int \
version, const char *cipher, const char *options, const char *flags, const char \
*clientCA, const char *CAfile, const char *CApath, const char *CRLfile, const char \
*dhpath, const char *context); +SSL_CTX *sslCreateServerContext(AnyP::PortCfg &port);
 
 /// \ingroup ServerProtocolSSLAPI
 SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, int \
version, const char *cipher, const char *options, const char *flags, const char \
*CAfile, const char *CApath, const char *CRLfile); @@ -130,6 +135,36 @@
 }
 
 /**
+ \ingroup ServerProtocolSSLAPI
+ * Parses the SSL flags.
+ */
+long parse_flags(const char *flags);
+
+/**
+ \ingroup ServerProtocolSSLAPI
+ * Parses the SSL options.
+ */
+long parse_options(const char *options);
+
+/**
+ \ingroup ServerProtocolSSLAPI
+ * Load a CRLs list stored in a file
+ */
+STACK_OF(X509_CRL) *loadCrl(const char *CRLFile, long &flags);
+
+/**
+ \ingroup ServerProtocolSSLAPI
+ * Load DH params from file
+ */
+DH *readDHParams(const char *dhfile);
+
+/**
+ \ingroup ServerProtocolSSLAPI
+ * Compute the Ssl::ContextMethod (SSL_METHOD) from SSL version
+ */
+ContextMethod contextMethod(int version);
+
+/**
   \ingroup ServerProtocolSSLAPI
   * Generate a certificate to be used as untrusted signing certificate, based on a \
                trusted CA
 */
@@ -139,7 +174,7 @@
   \ingroup ServerProtocolSSLAPI
   * Decide on the kind of certificate and generate a CA- or self-signed one
 */
-SSL_CTX * generateSslContext(CertificateProperties const &properties);
+SSL_CTX * generateSslContext(CertificateProperties const &properties, AnyP::PortCfg \
&port);  
 /**
   \ingroup ServerProtocolSSLAPI
@@ -155,7 +190,7 @@
   * Read private key and certificate from memory and generate SSL context
   * using their.
  */
-SSL_CTX * generateSslContextUsingPkeyAndCertFromMemory(const char * data);
+SSL_CTX * generateSslContextUsingPkeyAndCertFromMemory(const char * data, \
AnyP::PortCfg &port);  
 /**
   \ingroup ServerProtocolSSLAPI

=== modified file 'src/tests/stub_libsslsquid.cc'
--- a/src/tests/stub_libsslsquid.cc	2012-08-28 13:00:30 +0000
+++ b/src/tests/stub_libsslsquid.cc	2012-09-06 13:12:26 +0000
@@ -42,7 +42,7 @@
 const String & Ssl::ErrorDetail::toString() const STUB_RETSTATREF(String)
 
 #include "ssl/support.h"
-SSL_CTX *sslCreateServerContext(const char *certfile, const char *keyfile, int \
version, const char *cipher, const char *options, const char *flags, const char \
*clientCA, const char *CAfile, const char *CApath, const char *CRLfile, const char \
*dhpath, const char *context) STUB_RETVAL(NULL) +SSL_CTX \
*sslCreateServerContext(AnyP::PortCfg &) STUB_RETVAL(NULL)  SSL_CTX \
*sslCreateClientContext(const char *certfile, const char *keyfile, int version, const \
char *cipher, const char *options, const char *flags, const char *CAfile, const char \
*CApath, const char *CRLfile) STUB_RETVAL(NULL)  int ssl_read_method(int, char *, \
int) STUB_RETVAL(0)  int ssl_write_method(int, const char *, int) STUB_RETVAL(0)
@@ -53,8 +53,8 @@
 // SSLGETATTRIBUTE sslGetCAAttribute;
 const char *sslGetUserCertificatePEM(SSL *ssl) STUB_RETVAL(NULL)
 const char *sslGetUserCertificateChainPEM(SSL *ssl) STUB_RETVAL(NULL)
-SSL_CTX * Ssl::generateSslContext(CertificateProperties const &properties) \
                STUB_RETVAL(NULL)
-SSL_CTX * Ssl::generateSslContextUsingPkeyAndCertFromMemory(const char * data) \
STUB_RETVAL(NULL) +SSL_CTX * Ssl::generateSslContext(CertificateProperties const \
&properties, AnyP::PortCfg &) STUB_RETVAL(NULL) +SSL_CTX * \
Ssl::generateSslContextUsingPkeyAndCertFromMemory(const char * data, AnyP::PortCfg &) \
STUB_RETVAL(NULL)  int Ssl::matchX509CommonNames(X509 *peer_cert, void *check_data, \
int (*check_func)(void *check_data,  ASN1_STRING *cn_data)) STUB_RETVAL(0)  int \
Ssl::asn1timeToString(ASN1_TIME *tm, char *buf, int len) STUB_RETVAL(0)  


--===============1249137327==--


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic