Implement SNI support for the TlsStream class

fixes #8610
This commit is contained in:
Gunnar Beutner 2015-03-05 14:15:42 +01:00
parent 4a2a6d999a
commit fd9dc32a3d
5 changed files with 16 additions and 10 deletions

View File

@ -39,7 +39,7 @@ bool I2_EXPORT TlsStream::m_SSLIndexInitialized = false;
* @param role The role of the client.
* @param sslContext The SSL context for the client.
*/
TlsStream::TlsStream(const Socket::Ptr& socket, ConnectionRole role, const boost::shared_ptr<SSL_CTX>& sslContext)
TlsStream::TlsStream(const Socket::Ptr& socket, const String& hostname, ConnectionRole role, const boost::shared_ptr<SSL_CTX>& sslContext)
: SocketEvents(socket, this), m_Eof(false), m_HandshakeOK(false), m_VerifyOK(true), m_ErrorCode(0),
m_ErrorOccurred(false), m_Socket(socket), m_Role(role), m_SendQ(new FIFO()), m_RecvQ(new FIFO()),
m_CurrentAction(TlsActionNone), m_Retry(false)
@ -73,8 +73,14 @@ TlsStream::TlsStream(const Socket::Ptr& socket, ConnectionRole role, const boost
if (m_Role == RoleServer)
SSL_set_accept_state(m_SSL.get());
else
else {
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
if (!hostname.IsEmpty())
SSL_set_tlsext_host_name(m_SSL.get(), hostname.CStr());
#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
SSL_set_connect_state(m_SSL.get());
}
}
TlsStream::~TlsStream(void)

View File

@ -48,7 +48,7 @@ class I2_BASE_API TlsStream : public Stream, private SocketEvents
public:
DECLARE_PTR_TYPEDEFS(TlsStream);
TlsStream(const Socket::Ptr& socket, ConnectionRole role, const boost::shared_ptr<SSL_CTX>& sslContext);
TlsStream(const Socket::Ptr& socket, const String& hostname, ConnectionRole role, const boost::shared_ptr<SSL_CTX>& sslContext);
~TlsStream(void);
boost::shared_ptr<X509> GetClientCertificate(void) const;

View File

@ -153,7 +153,7 @@ int PkiUtility::SaveCert(const String& host, const String& port, const String& k
return 1;
}
TlsStream::Ptr stream = new TlsStream(client, RoleClient, sslContext);
TlsStream::Ptr stream = new TlsStream(client, String(), RoleClient, sslContext);
try {
stream->Handshake();
@ -219,7 +219,7 @@ int PkiUtility::RequestCertificate(const String& host, const String& port, const
return 1;
}
TlsStream::Ptr stream = new TlsStream(client, RoleClient, sslContext);
TlsStream::Ptr stream = new TlsStream(client, String(), RoleClient, sslContext);
try {
stream->Handshake();

View File

@ -210,7 +210,7 @@ void ApiListener::ListenerThreadProc(const Socket::Ptr& server)
for (;;) {
try {
Socket::Ptr client = server->Accept();
Utility::QueueAsyncCallback(boost::bind(&ApiListener::NewClientHandler, this, client, RoleServer), LowLatencyScheduler);
Utility::QueueAsyncCallback(boost::bind(&ApiListener::NewClientHandler, this, client, String(), RoleServer), LowLatencyScheduler);
} catch (const std::exception&) {
Log(LogCritical, "ApiListener", "Cannot accept new connection.");
}
@ -246,7 +246,7 @@ void ApiListener::AddConnection(const Endpoint::Ptr& endpoint)
try {
endpoint->SetConnecting(true);
client->Connect(host, port);
NewClientHandler(client, RoleClient);
NewClientHandler(client, endpoint->GetName(), RoleClient);
endpoint->SetConnecting(false);
} catch (const std::exception& ex) {
endpoint->SetConnecting(false);
@ -265,7 +265,7 @@ void ApiListener::AddConnection(const Endpoint::Ptr& endpoint)
*
* @param client The new client.
*/
void ApiListener::NewClientHandler(const Socket::Ptr& client, ConnectionRole role)
void ApiListener::NewClientHandler(const Socket::Ptr& client, const String& hostname, ConnectionRole role)
{
CONTEXT("Handling new API client connection");
@ -274,7 +274,7 @@ void ApiListener::NewClientHandler(const Socket::Ptr& client, ConnectionRole rol
{
ObjectLock olock(this);
try {
tlsStream = new TlsStream(client, role, m_SSLContext);
tlsStream = new TlsStream(client, hostname, role, m_SSLContext);
} catch (const std::exception&) {
Log(LogCritical, "ApiListener", "Cannot create TLS stream from client connection.");
return;

View File

@ -86,7 +86,7 @@ private:
bool AddListener(const String& node, const String& service);
void AddConnection(const Endpoint::Ptr& endpoint);
void NewClientHandler(const Socket::Ptr& client, ConnectionRole role);
void NewClientHandler(const Socket::Ptr& client, const String& hostname, ConnectionRole role);
void ListenerThreadProc(const Socket::Ptr& server);
WorkQueue m_RelayQueue;