[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