Skip to content

Commit

Permalink
Disable TLS session resumption
Browse files Browse the repository at this point in the history
  • Loading branch information
catalinr-m authored and sergiohs84 committed Oct 22, 2021
1 parent f90f321 commit 61e6a44
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/chatClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1202,11 +1202,13 @@ void Client::initWithDbSession(const char* sid)
mChatdClient.reset(new chatd::Client(this));
chats->loadFromDb();

#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
if (websocketIO && websocketIO->hasSessionCache())
{
auto&& sessions = mDnsCache.getTlsSessions();
websocketIO->restoreSessions(std::move(sessions));
}
#endif

// Get aliases from cache
mAliasAttrHandle = mUserAttrCache->getAttr(mMyHandle,
Expand Down
2 changes: 2 additions & 0 deletions src/chatd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2024,11 +2024,13 @@ void Connection::wsSendMsgCb(const char *, size_t)
mSendPromise.resolve();
}

#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
bool Connection::wsSSLsessionUpdateCb(const CachedSession &sess)
{
// update the session's data in the DNS cache
return mDnsCache.updateTlsSession(sess);
}
#endif

// inbound command processing
// multiple commands can appear as one WebSocket frame, but commands never cross frame boundaries
Expand Down
2 changes: 2 additions & 0 deletions src/chatd.h
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,9 @@ class Connection: public karere::DeleteTrackable, public WebsocketsClient
void wsCloseCb(int errcode, int errtype, const char *preason, size_t preason_len) override;
void wsHandleMsgCb(char *data, size_t len) override;
void wsSendMsgCb(const char *, size_t) override;
#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
bool wsSSLsessionUpdateCb(const CachedSession &sess) override;
#endif

void onSocketClose(int ercode, int errtype, const std::string& reason);
promise::Promise<void> reconnect();
Expand Down
19 changes: 17 additions & 2 deletions src/net/libwebsocketsIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,16 @@ LibwebsocketsIO::LibwebsocketsIO(Mutex &mutex, ::mega::Waiter* waiter, ::mega::M
info.protocols = protocols;
info.gid = -1;
info.uid = -1;
info.foreign_loops = (void**)&(libuvWaiter->eventloop);
info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
info.options |= LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS;
info.options |= LWS_SERVER_OPTION_LIBUV;
info.options |= LWS_SERVER_OPTION_UV_NO_SIGSEGV_SIGFPE_SPIN;
info.foreign_loops = (void**)&(libuvWaiter->eventloop);
info.tls_session_timeout = TLS_SESSION_TIMEOUT; // default: 300 (seconds); (default cache size is 10, should be fine)
#if !WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
info.options |= LWS_SERVER_OPTION_DISABLE_TLS_SESSION_CACHE;
#else
info.tls_session_timeout = TLS_SESSION_TIMEOUT; // default was 300 (seconds); (default cache size is 10, should be fine)
#endif
// Disable TLS 1.3 support, because session resumption did not work with it, even with "ticket" support enabled on Mega servers.
// Note: Using this flag is deprecated. The newer API is SSL_CTX_set_max_proto_version(), but unfortunately the underlying
// SSL_CTX is not accessible from here. Care should be taken for the next LWS upgrade.
Expand All @@ -66,6 +70,7 @@ LibwebsocketsIO::~LibwebsocketsIO()
lws_context_destroy(wscontext);
}

#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
void LibwebsocketsIO::restoreSessions(vector<CachedSession> &&sessions)
{
if (sessions.empty()) return;
Expand All @@ -91,6 +96,7 @@ void LibwebsocketsIO::restoreSessions(vector<CachedSession> &&sessions)
}
}
}
#endif // WEBSOCKETS_TLS_SESSION_CACHE_ENABLED

void LibwebsocketsIO::addevents(::mega::Waiter* waiter, int)
{
Expand Down Expand Up @@ -256,11 +262,13 @@ bool LibwebsocketsClient::connectViaClientInfo(const char *ip, const char *host,
i.ietf_version_or_minus_one = -1;
i.userdata = this;

#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
if (ssl)
{
mTlsSession.hostname = host;
mTlsSession.port = port;
}
#endif

wsi = lws_client_connect_via_info(&i);

Expand All @@ -274,6 +282,7 @@ void LibwebsocketsClient::wsDisconnect(bool immediate)
return;
}

#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
if (mTlsSession.dropFromStorage())
{
wsSSLsessionUpdateCb(mTlsSession);
Expand All @@ -287,6 +296,7 @@ void LibwebsocketsClient::wsDisconnect(bool immediate)
mTlsSession.blob = nullptr;
mTlsSession.saveToStorage(false); // done, don't do it again later
}
#endif

if (immediate)
{
Expand Down Expand Up @@ -441,6 +451,7 @@ int LibwebsocketsClient::wsCallback(struct lws *wsi, enum lws_callback_reasons r

client->wsConnectCb();

#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
//
// deal with the TLS session

Expand Down Expand Up @@ -500,6 +511,8 @@ int LibwebsocketsClient::wsCallback(struct lws *wsi, enum lws_callback_reasons r
s->hostname.c_str(), s->port);
}
s->blob = nullptr; // stored or not, don't keep it in memory
#endif // WEBSOCKETS_TLS_SESSION_CACHE_ENABLED

break;
}
case LWS_CALLBACK_CLIENT_CLOSED:
Expand Down Expand Up @@ -605,6 +618,7 @@ int LibwebsocketsClient::wsCallback(struct lws *wsi, enum lws_callback_reasons r
}


#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
bool LwsCache::dump(lws_vhost *vh, CachedSession *s)
{
return vh && s &&
Expand Down Expand Up @@ -647,3 +661,4 @@ int LwsCache::loadCb(lws_context *, lws_tls_session_dump *info)

return 0;
}
#endif // WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
8 changes: 8 additions & 0 deletions src/net/libwebsocketsIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ class LibwebsocketsIO : public WebsocketsIO

void addevents(::mega::Waiter*, int) override;

#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
bool hasSessionCache() const override { return true; }
void restoreSessions(std::vector<CachedSession> &&sessions) override;
#endif

protected:
bool wsResolveDNS(const char *hostname, std::function<void(int, const std::vector<std::string>&, const std::vector<std::string>&)> f) override;
Expand All @@ -31,6 +33,7 @@ class LibwebsocketsIO : public WebsocketsIO
int wsGetNoNameErrorCode() override;

private:
#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
// Note: While theoretically a LWS context can have multiple vhosts, it's a
// feature applicable to servers, and they need to be explicitly created.
// Implicitly, as in our case, only the default vhost will be created.
Expand All @@ -40,6 +43,7 @@ class LibwebsocketsIO : public WebsocketsIO
static const char constexpr *DEFAULT_VHOST = "default";

static constexpr int TLS_SESSION_TIMEOUT = 180 * 24 * 3600; // ~6 months, in seconds
#endif
};

class LibwebsocketsClient : public WebsocketsClientImpl
Expand Down Expand Up @@ -72,9 +76,12 @@ class LibwebsocketsClient : public WebsocketsClientImpl
static int wsCallback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *data, size_t len);

private:
#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
CachedSession mTlsSession;
#endif
};

#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
class LwsCache
{
public:
Expand All @@ -85,5 +92,6 @@ class LwsCache
static int dumpCb(lws_context *, lws_tls_session_dump *info);
static int loadCb(lws_context *, lws_tls_session_dump *info);
};
#endif

#endif /* libwebsocketsIO_h */
4 changes: 4 additions & 0 deletions src/net/websocketsIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,15 @@ void WebsocketsClientImpl::wsProcessNextMsgCb()
client->wsProcessNextMsgCb();
}

#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
bool WebsocketsClientImpl::wsSSLsessionUpdateCb(const CachedSession &sess)
{
WebsocketsIO::MutexGuard lock(this->mutex);
WEBSOCKETS_LOG_DEBUG("TLS session updated for %s:%d",
sess.hostname.c_str(), sess.port);
return client->wsSSLsessionUpdateCb(sess);
}
#endif

WebsocketsClient::WebsocketsClient(bool writeBinary)
: ctx(nullptr)
Expand Down Expand Up @@ -414,6 +416,7 @@ bool DNScache::isMatch(int shard, const std::string &ipv4, const std::string &ip
return match;
}

#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
bool DNScache::updateTlsSession(const CachedSession &sess)
{
// find the dns record that corresponds to this session
Expand Down Expand Up @@ -461,3 +464,4 @@ std::vector<CachedSession> DNScache::getTlsSessions()

return sessions;
}
#endif // WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
13 changes: 13 additions & 0 deletions src/net/websocketsIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#include "db.h"
#include "url.h"

// Disable TLS session resumption until we figure out why Chrome using the same BoringSSL does not have any issues
#define WEBSOCKETS_TLS_SESSION_CACHE_ENABLED 0

#define WEBSOCKETS_LOG_DEBUG(fmtString,...) KARERE_LOG_DEBUG(krLogChannel_websockets, fmtString, ##__VA_ARGS__)
#define WEBSOCKETS_LOG_INFO(fmtString,...) KARERE_LOG_INFO(krLogChannel_websockets, fmtString, ##__VA_ARGS__)
#define WEBSOCKETS_LOG_WARNING(fmtString,...) KARERE_LOG_WARNING(krLogChannel_websockets, fmtString, ##__VA_ARGS__)
Expand All @@ -21,6 +24,7 @@
class WebsocketsClient;
class WebsocketsClientImpl;

#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
struct CachedSession
{
std::string hostname; // host.domain
Expand All @@ -44,6 +48,7 @@ struct CachedSession
// in the cb to link to one of these instances, in case of connection failure.
int disconnectAction = MEGA_DROP;
};
#endif // WEBSOCKETS_TLS_SESSION_CACHE_ENABLED

class DNScache
{
Expand All @@ -70,8 +75,10 @@ class DNScache
time_t age(int shard);
const karere::Url &getUrl(int shard);

#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
bool updateTlsSession(const CachedSession &sess);
std::vector<CachedSession> getTlsSessions();
#endif

private:
struct DNSrecord
Expand Down Expand Up @@ -115,8 +122,10 @@ class WebsocketsIO : public ::mega::EventTrigger
}
};

#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
virtual bool hasSessionCache() const { return false; }
virtual void restoreSessions(std::vector<CachedSession> &&) { }
#endif

protected:
MyMegaApi mApi;
Expand Down Expand Up @@ -168,7 +177,9 @@ class WebsocketsClient
// Called after sending a message through the socket
// (it may be implemented by clients that require messages to be sent individually and sequentially)
virtual void wsProcessNextMsgCb() {}
#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
virtual bool wsSSLsessionUpdateCb(const CachedSession &) { return false; }
#endif

/* Public key pinning, by default this flag is enabled (true), it only should be disabled for testing purposes */
static bool publicKeyPinning;
Expand All @@ -189,7 +200,9 @@ class WebsocketsClientImpl
void wsHandleMsgCb(char *data, size_t len);
void wsSendMsgCb(const char *data, size_t len);
void wsProcessNextMsgCb();
#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
bool wsSSLsessionUpdateCb(const CachedSession &sess);
#endif

virtual bool wsSendMessage(char *msg, size_t len) = 0;
virtual void wsDisconnect(bool immediate) = 0;
Expand Down
2 changes: 2 additions & 0 deletions src/presenced.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,13 @@ void Client::onSocketClose(int errcode, int errtype, const std::string& reason)
}
}

#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
bool Client::wsSSLsessionUpdateCb(const CachedSession &sess)
{
// update the session's data in the DNS cache
return mDnsCache.updateTlsSession(sess);
}
#endif

std::string Config::toString() const
{
Expand Down
2 changes: 2 additions & 0 deletions src/presenced.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,9 @@ class Client: public karere::DeleteTrackable, public WebsocketsClient,
void wsCloseCb(int errcode, int errtype, const char *preason, size_t preason_len) override;
void wsHandleMsgCb(char *data, size_t len) override;
void wsSendMsgCb(const char *, size_t) override {}
#if WEBSOCKETS_TLS_SESSION_CACHE_ENABLED
bool wsSSLsessionUpdateCb(const CachedSession &sess) override;
#endif

void onSocketClose(int ercode, int errtype, const std::string& reason);
promise::Promise<void> reconnect();
Expand Down

0 comments on commit 61e6a44

Please sign in to comment.