| Return Type | Function name | Arguments |
|---|---|---|
| hzEcode | hzTcpClient::ConnectSSL | (const char*,unsigned int,unsigned int,unsigned int,) |
Declared in file: hzTcpClient.h
Defined in file : hzTcpClient.cpp
Function Logic:
Function body:
hzEcode hzTcpClient::ConnectSSL (const char* hostname, unsigned int nPort, unsigned int nTimeoutR, unsigned int nTimeoutS)
{
_hzfunc("hzTcpClient::ConnectSSL") ;
static bool bBeenHere = false ;
const SSL_METHOD* sslMethod = 0;
SSL_CTX* sslCtx = 0;
int32_t sys_rc ;
hzEcode rc = E_OK ;
if (!bBeenHere)
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
SSL_library_init();
#else
OPENSSL_init_ssl(0,NULL);
#endif
bBeenHere = true ;
}
if (m_nSock)
{
if (m_Hostname == hostname && m_nPort == nPort)
return E_OK ;
m_Hostname.Clear() ;
m_pHost = 0;
Close() ;
}
if (m_Hostname && m_Hostname != hostname)
{
m_Hostname = hostname ;
m_pHost = 0;
}
m_pHost = gethostbyname(hostname) ;
if (!m_pHost)
{
threadLog("No Host found\n") ;
if (h_errno == TRY_AGAIN) return E_DNS_RETRY ;
if (h_errno == HOST_NOT_FOUND) return E_DNS_NOHOST ;
if (h_errno == NO_RECOVERY) return E_DNS_FAILED ;
if (h_errno == NO_DATA || h_errno == NO_ADDRESS)
return E_DNS_NODATA ;
m_Hostname.Clear() ;
return hzerr(E_DNS_NOHOST, "Unknown Host [%s]\n", hostname) ;
}
m_Hostname = hostname ;
m_nPort = nPort ;
memset(&m_SvrAddr, 0,sizeof(m_SvrAddr)) ;
m_SvrAddr.sin_family = AF_INET ;
memcpy(&m_SvrAddr.sin_addr, m_pHost->h_addr, m_pHost->h_length) ;
m_SvrAddr.sin_port = htons(nPort) ;
if ((m_nSock = socket(AF_INET, SOCK_STREAM, 0))< 0)
return hzerr(E_INITFAIL, "Could not create socket (returns %d, errno=%d)", m_nSock, errno) ;
threadLog("Using socket %d\n", m_nSock) ;
sys_rc = connect(m_nSock, (SOCKADDR*) &m_SvrAddr, sizeof(m_SvrAddr)) ;
if (sys_rc < 0)
{
threadLog("Could not connect to host (returns %d)", sys_rc) ;
return hzerr(E_HOSTFAIL, "Could not connect to host [%s] on port %d (errno=%d)", *m_Hostname, m_nPort, errno) ;
}
threadLog("Connected\n") ;
if (!nTimeoutR) nTimeoutR = 90;
if (!nTimeoutS) nTimeoutS = 90;
if (rc == E_OK) rc = SetRecvTimeout(nTimeoutR) ;
if (rc == E_OK) rc = SetSendTimeout(nTimeoutS) ;
if (rc != E_OK)
return hzerr(rc, "Could not set connection timeouts") ;
threadLog("Socket options set\n") ;
/*
** ** SSL/TLS part
** */
sslMethod = TLS_client_method() ;
if (!sslMethod)
{
Close() ;
return hzerr(E_INITFAIL, "No SSL Client Method issued") ;
}
threadLog("Method set\n") ;
sslCtx = SSL_CTX_new(sslMethod) ;
if (!sslCtx)
{
Close() ;
hzerr(E_INITFAIL, "No SSL Structure issued") ;
}
threadLog("CTX Created\n") ;
m_pSSL = SSL_new(sslCtx) ;
if (!m_pSSL)
{
threadLog("Could not allocate SSL structure\n") ;
return E_HOSTFAIL ;
}
threadLog("SSL allocated\n") ;
/*
** if (SSL_CTX_set_cipher_list(sslCtx, "ECDHE-RSA-AES128-GCM-SHA256") <= 0)
** {
** threadLog("Error setting the cipher list.\n");
** return E_HOSTFAIL ;
** }
** threadLog("Cipers Listed\n") ;
** */
sys_rc = SSL_set_fd(m_pSSL, m_nSock);
if (sys_rc != 1)
{
threadLog("Could not set SSL file descriptor\n") ;
return E_HOSTFAIL ;
}
threadLog("SSL fd set\n") ;
SSL_set_tlsext_host_name(m_pSSL, *m_Hostname) ;
SSL_set_connect_state(m_pSSL) ;
threadLog("SSL set as client\n") ;
sys_rc = SSL_connect(m_pSSL);
threadLog("Handshake done\n") ;
if (sys_rc != 1)
{
threadLog("Could not connect: %s\n", ShowErrorSSL(SSL_get_error(m_pSSL, sys_rc))) ;
return E_HOSTFAIL ;
}
threadLog("Connected Secure\n") ;
/*
** Move to separate function or scrap
** if (bCheckCert)
** {
** if (SSL_get_peer_certificate(m_pSSL) != NULL)
** {
** if (SSL_get_verify_result(m_pSSL) == X509_V_OK)
** threadLog("Client verification with SSL_get_verify_result() succeeded.\n") ;
** else
** threadLog("Client verification with SSL_get_verify_result() failed.\n") ;
** }
** }
** */
return E_OK ;
}