ip/libip.la \
$(top_builddir)/lib/libmiscutil.la \
$(SQUID_CPPUNIT_LIBS) \
+ $(SSLLIB) \
$(COMPAT_LIB) \
$(XTRA_LIBS)
tests_testHttp1Parser_LDFLAGS = $(LIBADD_DL)
certsToChain(),
untrustedSigningCert(),
untrustedSignPkey(),
- clientVerifyCrls(),
clientCA(),
dhParams(),
eecdhCurve(NULL)
fatalf("Unable to generate signing SSL certificate for untrusted sites for %s_port %s", AnyP::ProtocolType_str[transport.protocol], s.toUrl(buf, sizeof(buf)));
}
- if (!secure.crlFile.isEmpty())
- clientVerifyCrls.reset(Ssl::loadCrl(secure.crlFile.c_str(), secure.parsedFlags));
-
if (clientca) {
clientCA.reset(SSL_load_client_CA_file(clientca));
if (clientCA.get() == NULL) {
Security::CertPointer 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
char *eecdhCurve; ///< Elliptic curve for ephemeral EC-based DH key exchanges
sslDomain(p.sslDomain),
parsedOptions(p.parsedOptions),
parsedFlags(p.parsedFlags),
+ parsedCrl(p.parsedCrl),
sslVersion(p.sslVersion),
encryptTransport(p.encryptTransport)
{
caDir = SBuf(token + 7);
} else if (strncmp(token, "crlfile=", 8) == 0) {
crlFile = SBuf(token + 8);
+ loadCrlFile();
} else if (strncmp(token, "flags=", 6) == 0) {
if (parsedFlags != 0) {
debugs(3, DBG_PARSE_NOTE(1), "WARNING: Overwriting flags=" << sslFlags << " with " << SBuf(token + 6));
// XXX: temporary performance regression. c_str() data copies and prevents this being a const method
t = sslCreateClientContext(certFile.c_str(), privateKeyFile.c_str(), sslCipher.c_str(),
(setOptions ? parsedOptions : 0), parsedFlags,
- caFile.c_str(), caDir.c_str(), crlFile.c_str());
+ caFile.c_str(), caDir.c_str());
#endif
+ updateContextCrl(t);
+
return t;
}
return fl;
}
+/// Load a CRLs list stored in the file whose /path/name is in crlFile
+/// replaces any CRL loaded previously
+void
+Security::PeerOptions::loadCrlFile()
+{
+ parsedCrl.clear();
+ if (crlFile.isEmpty())
+ return;
+
+#if USE_OPENSSL
+ BIO *in = BIO_new_file(crlFile.c_str(), "r");
+ if (!in) {
+ debugs(83, 2, "WARNING: Failed to open CRL file " << crlFile);
+ return;
+ }
+
+ while (X509_CRL *crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL)) {
+ parsedCrl.emplace_back(Security::CrlPointer(crl));
+ }
+ BIO_free(in);
+#endif
+}
+
+void
+Security::PeerOptions::updateContextCrl(Security::ContextPointer &ctx)
+{
+#if USE_OPENSSL
+ bool verifyCrl = false;
+ X509_STORE *st = SSL_CTX_get_cert_store(ctx);
+ if (parsedCrl.size()) {
+ for (auto &i : parsedCrl) {
+ if (!X509_STORE_add_crl(st, i.get()))
+ debugs(83, 2, "WARNING: Failed to add CRL");
+ else
+ verifyCrl = true;
+ }
+ }
+
+#if X509_V_FLAG_CRL_CHECK
+ if ((parsedFlags & SSL_FLAG_VERIFY_CRL_ALL))
+ X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
+ else if (verifyCrl || (parsedFlags & SSL_FLAG_VERIFY_CRL))
+ X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK);
+#endif
+
+#endif /* USE_OPENSSL */
+}
+
void
parse_securePeerOptions(Security::PeerOptions *opt)
{
/// sync the context options with tls-min-version=N configuration
void updateTlsVersionLimits();
+ /// setup the CRL details for the given context
+ void updateContextCrl(Security::ContextPointer &);
+
/// output squid.conf syntax with 'pfx' prefix on parameters for the stored settings
void dumpCfg(Packable *, const char *pfx) const;
private:
long parseOptions();
long parseFlags();
+ void loadCrlFile();
public:
SBuf certFile; ///< path of file containing PEM format X509 certificate
long parsedOptions; ///< parsed value of sslOptions
long parsedFlags; ///< parsed value of sslFlags
+ Security::CertRevokeList parsedCrl; ///< CRL to use when verifying the remote end certificate
+
private:
int sslVersion;
#include <gnutls/x509.h>
#endif
#endif
+#include <list>
/* flags a SSL connection can be configured with */
#define SSL_FLAG_NO_DEFAULT_CA (1<<0)
typedef void * CertPointer;
#endif
+#if USE_OPENSSL
+CtoCpp1(X509_CRL_free, X509_CRL *)
+typedef LockingPointer<X509_CRL, X509_CRL_free_cpp, CRYPTO_LOCK_X509_CRL> CrlPointer;
+#elif USE_GNUTLS
+CtoCpp1(gnutls_x509_crl_deinit, gnutls_x509_crl_t)
+typedef Security::LockingPointer<struct gnutls_x509_crl_int, gnutls_x509_crl_deinit, -1> CrlPointer;
+#else
+typedef void *CrlPointer;
+#endif
+
+typedef std::list<Security::CrlPointer> CertRevokeList;
+
} // namespace Security
#endif /* SQUID_SRC_SECURITY_FORWARD_H */
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;
ssl_ex_index_ssl_validation_counter = SSL_get_ex_new_index(0, (void *) "ssl_validation_counter", NULL, NULL, &ssl_free_int);
}
-/// \ingroup ServerProtocolSSLInternal
-static int
-ssl_load_crl(SSL_CTX *sslContext, const char *CRLfile)
-{
- X509_STORE *st = SSL_CTX_get_cert_store(sslContext);
- X509_CRL *crl;
- BIO *in = BIO_new_file(CRLfile, "r");
- int count = 0;
-
- if (!in) {
- debugs(83, 2, "WARNING: Failed to open CRL file '" << CRLfile << "'");
- return 0;
- }
-
- while ((crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL))) {
- if (!X509_STORE_add_crl(st, crl))
- debugs(83, 2, "WARNING: Failed to add CRL from file '" << CRLfile << "'");
- else
- ++count;
-
- X509_CRL_free(crl);
- }
-
- BIO_free(in);
- return count;
-}
-
-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)
{
SSL_CTX_set_verify(sslContext, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb);
}
- 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 (port.secure.parsedFlags & 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 (port.secure.parsedFlags & SSL_FLAG_VERIFY_CRL)
- X509_STORE_set_flags(SSL_CTX_get_cert_store(sslContext), X509_V_FLAG_CRL_CHECK);
-#endif
+ port.secure.updateContextCrl(sslContext);
} else {
debugs(83, 9, "Not requiring any client certificates");
#endif
SSL_CTX *
-sslCreateClientContext(const char *certfile, const char *keyfile, const char *cipher, long options, long fl, const char *CAfile, const char *CApath, const char *CRLfile)
+sslCreateClientContext(const char *certfile, const char *keyfile, const char *cipher, long options, long fl, const char *CAfile, const char *CApath)
{
ssl_initialize();
debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate locations: " << ERR_error_string(ssl_error, NULL));
}
- if (*CRLfile) {
- ssl_load_crl(sslContext, CRLfile);
- fl |= SSL_FLAG_VERIFY_CRL;
- }
-
-#if X509_V_FLAG_CRL_CHECK
- if (fl & 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)
- X509_STORE_set_flags(SSL_CTX_get_cert_store(sslContext), X509_V_FLAG_CRL_CHECK);
-
-#endif
-
if (!(fl & SSL_FLAG_NO_DEFAULT_CA) &&
!SSL_CTX_set_default_verify_paths(sslContext)) {
const int ssl_error = ERR_get_error();
SSL_CTX *sslCreateServerContext(AnyP::PortCfg &port);
/// \ingroup ServerProtocolSSLAPI
-SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, const char *cipher, long options, long flags, const char *CAfile, const char *CApath, const char *CRLfile);
+SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, const char *cipher, long options, long flags, const char *CAfile, const char *CApath);
/// \ingroup ServerProtocolSSLAPI
int ssl_read_method(int, char *, int);
return (0 <= bm && bm < Ssl::bumpEnd) ? Ssl::BumpModeStr[bm] : NULL;
}
-/**
- \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
void Security::PeerOptions::parse(char const*) STUB
Security::ContextPointer Security::PeerOptions::createClientContext(bool) STUB_RETVAL(NULL)
void Security::PeerOptions::updateTlsVersionLimits() STUB
+void Security::PeerOptions::updateContextCrl(Security::ContextPointer &) STUB
void Security::PeerOptions::dumpCfg(Packable*, char const*) const STUB
long Security::PeerOptions::parseOptions() STUB_RETVAL(0)
long Security::PeerOptions::parseFlags() STUB_RETVAL(0)
bool CertError::operator != (const CertError &ce) const STUB_RETVAL(false)
} // namespace Ssl
SSL_CTX *sslCreateServerContext(AnyP::PortCfg &port) STUB_RETVAL(NULL)
-SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, const char *cipher, long options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile) STUB_RETVAL(NULL)
+SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, const char *cipher, long options, const char *flags, const char *CAfile, const char *CApath) STUB_RETVAL(NULL)
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
//GETX509ATTRIBUTE GetX509CAAttribute;
//GETX509ATTRIBUTE GetX509Fingerprint;
const char *BumpModeStr[] = {""};
-STACK_OF(X509_CRL) *loadCrl(const char *CRLFile, long &flags) STUB_RETVAL(NULL)
DH *readDHParams(const char *dhfile) STUB_RETVAL(NULL)
bool generateUntrustedCert(Security::CertPointer & untrustedCert, EVP_PKEY_Pointer & untrustedPkey, Security::CertPointer const & cert, EVP_PKEY_Pointer const & pkey) STUB_RETVAL(false)
SSL_CTX * generateSslContext(CertificateProperties const &properties, AnyP::PortCfg &port) STUB_RETVAL(NULL)