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 ; }