domain(NULL),
#if USE_OPENSSL
sslContext(NULL),
- sslSession(NULL),
#endif
front_end_https(0),
connection_auth(2 /* auto */)
#if USE_OPENSSL
if (sslContext)
SSL_CTX_free(sslContext);
-
- if (sslSession)
- SSL_SESSION_free(sslSession);
#endif
}
/// security settings for peer connection
Security::PeerOptions secure;
Security::ContextPtr sslContext;
-#if USE_OPENSSL
- SSL_SESSION *sslSession;
-#endif
+ Security::SessionStatePointer sslSession;
int front_end_https;
int connection_auth;
Adaptation::Icap::ServiceRep::ServiceRep(const ServiceConfigPointer &svcCfg):
AsyncJob("Adaptation::Icap::ServiceRep"), Adaptation::Service(svcCfg),
sslContext(NULL),
-#if USE_OPENSSL
- sslSession(NULL),
-#endif
theOptions(NULL), theOptionsFetcher(0), theLastUpdate(0),
theBusyConns(0),
theAllWaiters(0),
virtual void noteAdaptationAnswer(const Answer &answer);
Security::ContextPtr sslContext;
-#if USE_OPENSSL
- SSL_SESSION *sslSession;
-#endif
+ Security::SessionStatePointer sslSession;
private:
// stores Prepare() callback info
if (check)
check->dst_peer_name = *host;
- if (icapService->sslSession)
- SSL_set_session(ssl, icapService->sslSession);
+ Security::GetSessionResumeData(Security::SessionPointer(ssl), icapService->sslSession);
return ssl;
}
return;
const int fd = serverConnection()->fd;
- auto ssl = fd_table[fd].ssl.get();
- assert(ssl);
- if (!SSL_session_reused(ssl)) {
- if (icapService->sslSession)
- SSL_SESSION_free(icapService->sslSession);
- icapService->sslSession = SSL_get1_session(ssl);
- }
+ Security::GetSessionResumeData(fd_table[fd].ssl, icapService->sslSession);
}
void
return;
}
- if (SSL_session_reused(ssl)) {
+ if (Security::SessionIsResumed(fd_table[fd].ssl)) {
debugs(83, 2, "clientNegotiateSSL: Session " << SSL_get_session(ssl) <<
" reused on FD " << fd << " (" << fd_table[fd].ipaddr << ":" << (int)fd_table[fd].remote_port << ")");
} else {
#define SSL_SESSION_ID_SIZE 32
#define SSL_SESSION_MAX_SIZE 10*1024
+bool
+Security::SessionIsResumed(const Security::SessionPointer &s)
+{
+ return
+#if USE_OPENSSL
+ SSL_session_reused(s.get()) == 1;
+#elif USE_GNUTLS
+ gnutls_session_is_resumed(s.get()) != 0;
+#else
+ false;
+#endif
+}
+
+void
+Security::GetSessionResumeData(const Security::SessionPointer &s, Security::SessionStatePointer &data)
+{
+ if (!SessionIsResumed(s)) {
+#if USE_OPENSSL
+ data.reset(SSL_get1_session(s.get()));
+#elif USE_GNUTLS
+ gnutls_datum_t *tmp = nullptr;
+ (void)gnutls_session_get_data2(s.get(), tmp);
+ data.reset(tmp);
+#endif
+ }
+}
+
+void
+Security::SetSessionResumeData(const Security::SessionPtr &s, const Security::SessionStatePointer &data)
+{
+ if (s) {
+#if USE_OPENSSL
+ (void)SSL_set_session(s, data.get());
+#elif USE_GNUTLS
+ (void)gnutls_session_set_data(s, data->data, data->size);
+#endif
+ }
+}
+
static bool
isTlsServer()
{
CtoCpp1(SSL_free, SSL *);
typedef LockingPointer<SSL, Security::SSL_free_cpp, CRYPTO_LOCK_SSL> SessionPointer;
+typedef SSL_SESSION* SessionStatePtr;
+CtoCpp1(SSL_SESSION_free, SSL_SESSION *);
+typedef LockingPointer<SSL_SESSION, Security::SSL_SESSION_free_cpp, CRYPTO_LOCK_SSL_SESSION> SessionStatePointer;
+
#elif USE_GNUTLS
typedef gnutls_session_t SessionPtr;
CtoCpp1(gnutls_deinit, gnutls_session_t);
// library functions
typedef TidyPointer<struct gnutls_session_int, Security::gnutls_deinit_cpp> SessionPointer;
+typedef gnutls_datum_t *SessionStatePtr;
+CtoCpp1(gnutls_free, gnutls_datum_t *);
+typedef TidyPointer<gnutls_datum_t, Security::gnutls_free_cpp> SessionStatePointer;
+
#else
// use void* so we can check against NULL
typedef void* SessionPtr;
typedef TidyPointer<void, nullptr> SessionPointer;
+typedef TidyPointer<void, nullptr> SessionStatePointer;
#endif
+/// whether the session is a resumed one
+bool SessionIsResumed(const Security::SessionPointer &);
+
+/// Retrieve the data needed to resume this session on a later connection
+void GetSessionResumeData(const Security::SessionPointer &, Security::SessionStatePointer &);
+
+/// Set the data for resuming a previous session.
+/// Needs to be done before using the SessionPointer for a handshake.
+void SetSessionResumeData(const Security::SessionPtr &, const Security::SessionStatePointer &);
+
} // namespace Security
#endif /* SQUID_SRC_SECURITY_SESSION_H */
SBuf *host = new SBuf(peer->secure.sslDomain);
SSL_set_ex_data(ssl, ssl_ex_index_server, host);
- if (peer->sslSession)
- SSL_set_session(ssl, peer->sslSession);
+ Security::SetSessionResumeData(ssl, peer->sslSession);
} else {
SBuf *hostName = new SBuf(request->url.host());
SSL_set_ex_data(ssl, ssl_ex_index_server, (void*)hostName);
return;
}
- const int fd = serverConnection()->fd;
- Security::SessionPtr ssl = fd_table[fd].ssl.get();
- if (serverConnection()->getPeer() && !SSL_session_reused(ssl)) {
- if (serverConnection()->getPeer()->sslSession)
- SSL_SESSION_free(serverConnection()->getPeer()->sslSession);
-
- serverConnection()->getPeer()->sslSession = SSL_get1_session(ssl);
+ if (auto *peer = serverConnection()->getPeer()) {
+ const int fd = serverConnection()->fd;
+ Security::GetSessionResumeData(fd_table[fd].ssl, peer->sslSession);
}
}