bool
Security::PeerConnector::initialize(Security::SessionPointer &serverSession)
{
-#if USE_OPENSSL
Security::ContextPointer ctx(getTlsContext());
- assert(ctx);
- if (!Ssl::CreateClient(ctx, serverConnection(), "server https start")) {
+ if (!ctx || !Security::CreateClientSession(ctx, serverConnection(), "server https start")) {
+ const auto xerrno = errno;
- const auto ssl_error = ERR_get_error();
+ if (!ctx) {
+ debugs(83, DBG_IMPORTANT, "Error initializing TLS connection: No security context.");
+ } // else CreateClientSession() did the appropriate debugs() already
ErrorState *anErr = new ErrorState(ERR_SOCKET_FAILURE, Http::scInternalServerError, request.getRaw());
- anErr->xerrno = errno;
+ anErr->xerrno = xerrno;
- debugs(83, DBG_IMPORTANT, "Error allocating TLS handle: " << Security::ErrorString(ssl_error));
noteNegotiationDone(anErr);
bail(anErr);
return false;
#define SSL_SESSION_ID_SIZE 32
#define SSL_SESSION_MAX_SIZE 10*1024
- #if USE_OPENSSL
+static bool
+CreateSession(const Security::ContextPointer &ctx, const Comm::ConnectionPointer &conn, Security::Io::Type type, const char *squidCtx)
+{
+ if (!Comm::IsConnOpen(conn)) {
+ debugs(83, DBG_IMPORTANT, "Gone connection");
+ return false;
+ }
+
+ const char *errAction = "with no TLS/SSL library";
- debugs(83, DBG_IMPORTANT, "ERROR: " << squidCtx << ' ' << errAction <<
- ": " << ERR_error_string(errCode, nullptr));
- #else
- debugs(83, DBG_IMPORTANT, "ERROR: " << squidCtx << ' ' << errAction);
+ int errCode = 0;
++#if USE_OPENSSL
+ Security::SessionPointer ssl(SSL_new(ctx.get()));
+ if (ssl) {
+ const int fd = conn->fd;
+ // without BIO, we would call SSL_set_fd(ssl.get(), fd) instead
+ if (BIO *bio = Ssl::Bio::Create(fd, type)) {
+ Ssl::Bio::Link(ssl.get(), bio); // cannot fail
+
+ fd_table[fd].ssl = ssl;
+ fd_table[fd].read_method = &ssl_read_method;
+ fd_table[fd].write_method = &ssl_write_method;
+ fd_note(fd, squidCtx);
+ return true;
+ }
+ errCode = ERR_get_error();
+ errAction = "failed to initialize I/O";
+ } else {
+ errCode = ERR_get_error();
+ errAction = "failed to allocate handle";
+ }
+#endif
++ debugs(83, DBG_IMPORTANT, "ERROR: " << squidCtx << ' ' << errAction <<
++ ": " << (errCode != 0 ? Security::ErrorString(errCode) : ""));
+ return false;
+}
+
+bool
+Security::CreateClientSession(const Security::ContextPointer &ctx, const Comm::ConnectionPointer &c, const char *squidCtx)
+{
+ return CreateSession(ctx, c, Security::Io::BIO_TO_SERVER, squidCtx);
+}
+
+bool
+Security::CreateServerSession(const Security::ContextPointer &ctx, const Comm::ConnectionPointer &c, const char *squidCtx)
+{
+ return CreateSession(ctx, c, Security::Io::BIO_TO_CLIENT, squidCtx);
+}
+
bool
Security::SessionIsResumed(const Security::SessionPointer &s)
{
namespace Security {
+/// Creates TLS Client connection structure (aka 'session' state) and initializes TLS/SSL I/O (Comm and BIO).
+/// On errors, emits DBG_IMPORTANT with details and returns false.
+bool CreateClientSession(const Security::ContextPointer &, const Comm::ConnectionPointer &, const char *squidCtx);
+
+/// Creates TLS Server connection structure (aka 'session' state) and initializes TLS/SSL I/O (Comm and BIO).
+/// On errors, emits DBG_IMPORTANT with details and returns false.
+bool CreateServerSession(const Security::ContextPointer &, const Comm::ConnectionPointer &, const char *squidCtx);
+
#if USE_OPENSSL
CtoCpp1(SSL_free, SSL *);
- typedef LockingPointer<SSL, Security::SSL_free_cpp, CRYPTO_LOCK_SSL> SessionPointer;
+ #if defined(CRYPTO_LOCK_SSL) // OpenSSL 1.0
+ inline int SSL_up_ref(SSL *t) {if (t) CRYPTO_add(&t->references, 1, CRYPTO_LOCK_SSL); return 0;}
+ #endif
+ typedef Security::LockingPointer<SSL, Security::SSL_free_cpp, HardFun<int, SSL *, SSL_up_ref> > SessionPointer;
typedef std::unique_ptr<SSL_SESSION, HardFun<void, SSL_SESSION*, &SSL_SESSION_free>> SessionStatePointer;
squid_bio_destroy,
NULL // squid_callback_ctrl not supported
};
+ #else
+ static BIO_METHOD *SquidMethods = NULL;
+ #endif
BIO *
-Ssl::Bio::Create(const int fd, Ssl::Bio::Type type)
+Ssl::Bio::Create(const int fd, Security::Io::Type type)
{
+ #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
if (BIO *bio = BIO_new(&SquidMethods)) {
BIO_int_ctrl(bio, BIO_C_SET_FD, type, fd);
return bio;
void
applyTlsDetailsToSSL(SSL *ssl, Security::TlsDetails::Pointer const &details, Ssl::BumpMode bumpMode);
+ #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+ // OpenSSL v1.0 bio compatibility functions
+ inline void *BIO_get_data(BIO *table) { return table->ptr; }
+ inline void BIO_set_data(BIO *table, void *data) { table->ptr = data; }
+ inline int BIO_get_init(BIO *table) { return table->init; }
+ inline void BIO_set_init(BIO *table, int init) { table->init = init; }
+ #endif
+
+#endif /* USE_OPENSSL */
#endif /* SQUID_SSL_BIO_H */