void
AnyP::PortCfg::configureSslServerContext()
{
- if (!secure.certFile.isEmpty())
- Ssl::readCertChainAndPrivateKeyFromFiles(signingCert, signPkey, certsToChain, secure.certFile.c_str(), secure.privateKeyFile.c_str());
+ if (!secure.certs.empty()) {
+ Security::KeyData &keys = secure.certs.front();
+ Ssl::readCertChainAndPrivateKeyFromFiles(signingCert, signPkey, certsToChain, keys.certFile.c_str(), keys.privateKeyFile.c_str());
+ }
if (!signingCert) {
char buf[128];
--- /dev/null
+/*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_SRC_SECURITY_KEYDATA_H
+#define SQUID_SRC_SECURITY_KEYDATA_H
+
+#include "SBuf.h"
+#include "security/forward.h"
+
+namespace Security
+{
+
+/// TLS certificate and private key details from squid.conf
+class KeyData
+{
+public:
+ SBuf certFile; ///< path of file containing PEM format X.509 certificate
+ SBuf privateKeyFile; ///< path of file containing private key in PEM format
+};
+
+} // namespace Security
+
+#endif /* SQUID_SRC_SECURITY_KEYDATA_H */
+
EncryptorAnswer.cc \
EncryptorAnswer.h \
forward.h \
+ KeyData.h \
LockingPointer.h \
PeerOptions.cc \
PeerOptions.h \
Security::PeerOptions Security::ProxyOutgoingConfig;
Security::PeerOptions::PeerOptions(const Security::PeerOptions &p) :
- certFile(p.certFile),
- privateKeyFile(p.privateKeyFile),
sslOptions(p.sslOptions),
caDir(p.caDir),
crlFile(p.crlFile),
sslDomain(p.sslDomain),
parsedOptions(p.parsedOptions),
parsedFlags(p.parsedFlags),
+ certs(p.certs),
caFiles(p.caFiles),
parsedCrl(p.parsedCrl),
sslVersion(p.sslVersion),
}
if (strncmp(token, "cert=", 5) == 0) {
- certFile = SBuf(token + 5);
- if (privateKeyFile.isEmpty())
- privateKeyFile = certFile;
+ KeyData t;
+ t.privateKeyFile = t.certFile = SBuf(token + 5);
+ certs.emplace_back(t);
} else if (strncmp(token, "key=", 4) == 0) {
- privateKeyFile = SBuf(token + 4);
- if (certFile.isEmpty()) {
- debugs(3, DBG_PARSE_NOTE(1), "WARNING: cert= option needs to be set before key= is used.");
- certFile = privateKeyFile;
+ if (certs.empty() || certs.back().certFile.isEmpty()) {
+ debugs(3, DBG_PARSE_NOTE(1), "ERROR: cert= option must be set before key= is used.");
+ return;
}
+ KeyData &t = certs.back();
+ t.privateKeyFile = SBuf(token + 4);
} else if (strncmp(token, "version=", 8) == 0) {
debugs(0, DBG_PARSE_NOTE(1), "UPGRADE WARNING: SSL version= is deprecated. Use options= to limit protocols instead.");
sslVersion = xatoi(token + 8);
return; // no other settings are relevant
}
- if (!certFile.isEmpty())
- p->appendf(" %scert=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(certFile));
+ for (auto &i : certs) {
+ if (!i.certFile.isEmpty())
+ p->appendf(" %scert=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(i.certFile));
- if (!privateKeyFile.isEmpty() && privateKeyFile != certFile)
- p->appendf(" %skey=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(privateKeyFile));
+ if (!i.privateKeyFile.isEmpty() && i.privateKeyFile != i.certFile)
+ p->appendf(" %skey=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(i.privateKeyFile));
+ }
if (!sslOptions.isEmpty())
p->appendf(" %soptions=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(sslOptions));
#if USE_OPENSSL
// XXX: temporary performance regression. c_str() data copies and prevents this being a const method
- t = sslCreateClientContext(*this, certFile.c_str(), privateKeyFile.c_str(), sslCipher.c_str(),
- (setOptions ? parsedOptions : 0), parsedFlags);
+ t = sslCreateClientContext(*this, (setOptions ? parsedOptions : 0), parsedFlags);
#elif USE_GNUTLS && WHEN_READY_FOR_GNUTLS
t = createBlankContext();
#define SQUID_SRC_SECURITY_PEEROPTIONS_H
#include "ConfigParser.h"
-#include "SBuf.h"
-#include "security/forward.h"
+#include "security/KeyData.h"
class Packable;
void loadCrlFile();
public:
- SBuf certFile; ///< path of file containing PEM format X509 certificate
- SBuf privateKeyFile; ///< path of file containing private key in PEM format
SBuf sslOptions; ///< library-specific options string
SBuf caDir; ///< path of directory containing a set of trusted Certificate Authorities
SBuf crlFile; ///< path of file containing Certificate Revoke List
long parsedOptions; ///< parsed value of sslOptions
long parsedFlags; ///< parsed value of sslFlags
+ std::list<Security::KeyData> certs; ///< details from the cert= and file= config parameters
std::list<SBuf> caFiles; ///< paths of files containing trusted Certificate Authority
Security::CertRevokeList parsedCrl; ///< CRL to use when verifying the remote end certificate
typedef void *DhePointer;
#endif
+class KeyData;
+
} // namespace Security
#endif /* SQUID_SRC_SECURITY_FORWARD_H */
if (!SSL_CTX_use_certificate(sslContext, port.signingCert.get())) {
const int ssl_error = ERR_get_error();
- debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL certificate '" << port.secure.certFile << "': " << ERR_error_string(ssl_error, NULL));
+ const auto &keys = port.secure.certs.front();
+ debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire TLS certificate '" << keys.certFile << "': " << ERR_error_string(ssl_error, NULL));
SSL_CTX_free(sslContext);
return NULL;
}
if (!SSL_CTX_use_PrivateKey(sslContext, port.signPkey.get())) {
const int ssl_error = ERR_get_error();
- debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire SSL private key '" << port.secure.privateKeyFile << "': " << ERR_error_string(ssl_error, NULL));
+ const auto &keys = port.secure.certs.front();
+ debugs(83, DBG_CRITICAL, "ERROR: Failed to acquire TLS private key '" << keys.privateKeyFile << "': " << ERR_error_string(ssl_error, NULL));
SSL_CTX_free(sslContext);
return NULL;
}
#endif
Security::ContextPtr
-sslCreateClientContext(Security::PeerOptions &peer, const char *certfile, const char *keyfile, const char *cipher, long options, long fl)
+sslCreateClientContext(Security::PeerOptions &peer, long options, long fl)
{
Security::ContextPtr sslContext(peer.createBlankContext());
if (!sslContext)
SSL_CTX_set_info_callback(sslContext, ssl_info_cb);
#endif
- if (*cipher) {
- debugs(83, 5, "Using chiper suite " << cipher << ".");
+ if (!peer.sslCipher.isEmpty()) {
+ debugs(83, 5, "Using chiper suite " << peer.sslCipher << ".");
+ const char *cipher = peer.sslCipher.c_str();
if (!SSL_CTX_set_cipher_list(sslContext, cipher)) {
const int ssl_error = ERR_get_error();
fatalf("Failed to set SSL cipher suite '%s': %s\n",
}
}
- if (*certfile) {
- debugs(83, DBG_IMPORTANT, "Using certificate in " << certfile);
+ // TODO: support loading multiple cert/key pairs
+ auto &keys = peer.certs.front();
+ if (!keys.certFile.isEmpty()) {
+ debugs(83, DBG_IMPORTANT, "Using certificate in " << keys.certFile);
+ const char *certfile = keys.certFile.c_str();
if (!SSL_CTX_use_certificate_chain_file(sslContext, certfile)) {
const int ssl_error = ERR_get_error();
fatalf("Failed to acquire SSL certificate '%s': %s\n",
certfile, ERR_error_string(ssl_error, NULL));
}
- debugs(83, DBG_IMPORTANT, "Using private key in " << keyfile);
+ debugs(83, DBG_IMPORTANT, "Using private key in " << keys.privateKeyFile);
+ const char *keyfile = keys.privateKeyFile.c_str();
ssl_ask_password(sslContext, keyfile);
if (!SSL_CTX_use_PrivateKey_file(sslContext, keyfile, SSL_FILETYPE_PEM)) {
Security::ContextPtr sslCreateServerContext(AnyP::PortCfg &port);
/// \ingroup ServerProtocolSSLAPI
-Security::ContextPtr sslCreateClientContext(Security::PeerOptions &, const char *certfile, const char *keyfile, const char *cipher, long options, long flags);
+Security::ContextPtr sslCreateClientContext(Security::PeerOptions &, long options, long flags);
/// \ingroup ServerProtocolSSLAPI
int ssl_read_method(int, char *, int);
bool CertError::operator != (const CertError &ce) const STUB_RETVAL(false)
} // namespace Ssl
Security::ContextPtr sslCreateServerContext(AnyP::PortCfg &port) STUB_RETVAL(NULL)
-Security::ContextPtr sslCreateClientContext(Security::PeerOptions &, const char *, const char *, const char *, long, const char *) STUB_RETVAL(nullptr)
+Security::ContextPtr sslCreateClientContext(Security::PeerOptions &, long, const char *) STUB_RETVAL(nullptr)
int ssl_read_method(int, char *, int) STUB_RETVAL(0)
int ssl_write_method(int, const char *, int) STUB_RETVAL(0)
void ssl_shutdown_method(SSL *ssl) STUB