22 #include "securesocket.h" 30 #define LASTERROR WSAGetLastError() 31 #define ERRNO_INTR WSAEINTR 33 #define LASTERROR errno 34 #define ERRNO_INTR EINTR 48 void SSLSessionFactory::Destroy()
50 SAFE_DELETE(m_instance);
55 #include <openssl/ssl.h> 56 #include <openssl/err.h> 57 #include <openssl/pem.h> 58 #include <openssl/x509.h> 59 #include <openssl/x509_vfy.h> 62 const char*
const PREFERRED_CIPHERS =
"HIGH:!aNULL:!kRSA:!SRP:!PSK:!CAMELLIA:!RC4:!MD5:!DSS";
64 SSLSessionFactory::SSLSessionFactory()
68 if (SSL_library_init() < 0)
69 DBG(DBG_ERROR,
"%s: could not initialize the SSL library\n", __FUNCTION__);
72 SSL_load_error_strings();
76 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) 77 m_ctx = SSL_CTX_new(TLS_client_method());
79 m_ctx = SSL_CTX_new(SSLv23_client_method());
82 DBG(DBG_ERROR,
"%s: could not create the SSL context\n", __FUNCTION__);
85 SSL_CTX_set_verify(static_cast<SSL_CTX*>(m_ctx), SSL_VERIFY_NONE, 0);
92 const long flags = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
93 (void)SSL_CTX_set_options(static_cast<SSL_CTX*>(m_ctx), flags);
101 if (SSL_CTX_set_cipher_list(static_cast<SSL_CTX*>(m_ctx), PREFERRED_CIPHERS) != 1)
102 DBG(DBG_ERROR,
"%s: Set cipher list failed\n", __FUNCTION__);
107 DBG(DBG_INFO,
"%s: SSL engine initialized\n", __FUNCTION__);
113 SSLSessionFactory::~SSLSessionFactory()
116 SSL_CTX_free(static_cast<SSL_CTX*>(m_ctx));
119 DBG(DBG_INFO,
"%s: SSL resources destroyed\n", __FUNCTION__);
126 SSL* ssl = SSL_new(static_cast<SSL_CTX*>(m_ctx));
133 SSL_set_mode(static_cast<SSL*>(ssl), SSL_MODE_AUTO_RETRY);
139 SecureSocket::SecureSocket(
void* ssl)
148 SecureSocket::~SecureSocket()
151 SSL_free(static_cast<SSL*>(m_ssl));
154 bool SecureSocket::Connect(
const char* server,
unsigned port,
int rcvbuf)
161 if (!TcpSocket::Connect(server, port, rcvbuf))
165 SSL_set_fd(static_cast<SSL*>(m_ssl), m_socket);
166 SSL_set_tlsext_host_name(static_cast<SSL*>(m_ssl), server);
171 int r = SSL_connect(static_cast<SSL*>(m_ssl));
176 int err = SSL_get_error(static_cast<SSL*>(m_ssl), r);
177 if (err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ)
179 DBG(DBG_DEBUG,
"%s: SSL retry (%d)\n", __FUNCTION__, err);
183 const char* errmsg = ERR_error_string(ERR_get_error(), NULL);
184 DBG(DBG_ERROR,
"%s: SSL connect failed: %s\n", __FUNCTION__, errmsg);
185 TcpSocket::Disconnect();
188 DBG(DBG_PROTO,
"%s: SSL handshake initialized\n", __FUNCTION__);
192 if (!IsCertificateValid(str))
194 DBG(DBG_ERROR,
"%s: could not get a valid certificate from the server\n", __FUNCTION__);
197 DBG(DBG_PROTO,
"%s: %s\n", __FUNCTION__, str.c_str());
201 size_t SecureSocket::ReceiveData(
void* buf,
size_t n)
203 if (m_connected && n > 0)
205 m_ssl_error = SSL_ERROR_NONE;
208 if (SSL_pending(static_cast<SSL*>(m_ssl)) == 0)
213 int s = TcpSocket::Listen(&m_timeout);
218 DBG(DBG_WARN,
"%s: socket(%p) timed out (%d)\n", __FUNCTION__, &m_socket, hangcount);
220 if (++hangcount >= m_attempt)
223 else if (m_errno != ERRNO_INTR)
228 int r = SSL_read(static_cast<SSL*>(m_ssl), buf, (
int) n);
231 int err = SSL_get_error(static_cast<SSL*>(m_ssl), r);
232 if (err == SSL_ERROR_WANT_READ)
234 DBG(DBG_DEBUG,
"%s: SSL retry\n", __FUNCTION__);
237 if (err == SSL_ERROR_WANT_WRITE)
239 DBG(DBG_DEBUG,
"%s: SSL wants write\n", __FUNCTION__);
243 const char* errmsg = ERR_error_string(ERR_get_error(), NULL);
244 DBG(DBG_ERROR,
"%s: SSL read failed: %s\n", __FUNCTION__, errmsg);
252 bool SecureSocket::SendData(
const char* buf,
size_t size)
254 if (m_connected && size > 0)
256 m_ssl_error = SSL_ERROR_NONE;
259 int r = SSL_write(static_cast<SSL*>(m_ssl), buf, (
int) size);
260 if (r > 0 && size == (
size_t) r)
262 int err = SSL_get_error(static_cast<SSL*>(m_ssl), r);
263 if (err == SSL_ERROR_WANT_WRITE)
265 DBG(DBG_DEBUG,
"%s: SSL retry\n", __FUNCTION__);
268 if (err == SSL_ERROR_WANT_READ)
270 DBG(DBG_DEBUG,
"%s: SSL wants read\n", __FUNCTION__);
274 const char* errmsg = ERR_error_string(ERR_get_error(), NULL);
275 DBG(DBG_ERROR,
"%s: SSL write failed: %s\n", __FUNCTION__, errmsg);
283 void SecureSocket::Disconnect()
287 SSL_shutdown(static_cast<SSL*>(m_ssl));
290 TcpSocket::Disconnect();
293 X509_free(static_cast<X509*>(m_cert));
298 bool SecureSocket::IsValid()
const 303 bool SecureSocket::IsCertificateValid(std::string& str)
306 X509_free(static_cast<X509*>(m_cert));
307 m_cert = SSL_get_peer_certificate(static_cast<SSL*>(m_ssl));
313 X509_NAME* name = X509_get_subject_name(static_cast<X509*>(m_cert));
314 str.assign(X509_NAME_oneline(name, buf,
sizeof(buf) - 1));
322 SSLSessionFactory::SSLSessionFactory()
326 DBG(DBG_INFO,
"%s: SSL feature is disabled\n", __FUNCTION__);
329 SSLSessionFactory::~SSLSessionFactory()
338 SecureSocket::SecureSocket(
void* ssl)
347 SecureSocket::~SecureSocket()
351 bool SecureSocket::Connect(
const char* server,
unsigned port,
int rcvbuf)
359 size_t SecureSocket::ReceiveData(
void* buf,
size_t n)
366 bool SecureSocket::SendData(
const char* buf,
size_t size)
373 void SecureSocket::Disconnect()
377 bool SecureSocket::IsValid()
const 382 bool SecureSocket::IsCertificateValid(std::string& str)
void * m_ctx
SSL default context for the application.
bool m_enabled
SSL feature status.