Mixe for Privacy and Anonymity in the Internet
Public Member Functions | Private Member Functions | Private Attributes
CATLSClientSocket Class Reference

#include <CATLSClientSocket.hpp>

Inheritance diagram for CATLSClientSocket:
[legend]
Collaboration diagram for CATLSClientSocket:
[legend]

List of all members.

Public Member Functions

 CATLSClientSocket ()
 ~CATLSClientSocket ()
SINT32 sendFully (const UINT8 *buff, UINT32 len)
 Sends all data over the network.
SINT32 send (const UINT8 *buff, UINT32 len)
 Sends all data over the network.
SINT32 receive (UINT8 *buff, UINT32 len)
 Will receive some bytes from the socket.
SINT32 close ()
 Shuts down the socket.
SINT32 connect (CASocketAddr &psa, UINT32 msTimeout)
 Establishes the actual TCP/IP connection and performs the TLS handshake.
SINT32 setServerCertificate (CACertificate *pCert)
 Sets the Certifcate we accept as server identification.

Private Member Functions

SINT32 doTLSConnect (CASocketAddr &psa)
 Does the TLS handshake.

Private Attributes

SSL * m_pSSL
SSL_CTX * m_pCtx
CACertificatem_pRootCert
bool m_bConnectedTLS
 is the TLS layer established ?

Detailed Description

Definition at line 48 of file CATLSClientSocket.hpp.


Constructor & Destructor Documentation

Definition at line 35 of file CATLSClientSocket.cpp.

References m_bConnectedTLS, m_pCtx, m_pRootCert, and m_pSSL.

  {
    m_bConnectedTLS = false;
    m_pCtx = SSL_CTX_new( TLSv1_client_method() );
#ifdef SSL_OP_NO_TICKET
    // disable buggy TLS client extensions, as otherwise we will get no connection to a Java TLS server; the bug is fixes in OpenSSL > 0.9.8g
    SSL_CTX_set_options(m_pCtx, SSL_OP_ALL|SSL_OP_NO_TICKET);
#else
    SSL_CTX_set_options(m_pCtx, SSL_OP_ALL);
#endif
    m_pSSL = NULL;
    m_pRootCert=NULL;
    //m_pSocket=new CASocket();

  }

Definition at line 51 of file CATLSClientSocket.cpp.

References close(), m_pCtx, and m_pRootCert.

  {
    close();
    SSL_CTX_free(m_pCtx);
    //delete m_pSocket;
    //m_pSocket = NULL;
    delete m_pRootCert;
    m_pRootCert = NULL;
  }

Here is the call graph for this function:


Member Function Documentation

Shuts down the socket.

This is an overridden virtual function which shuts down the TLS layer first

Reimplemented from CASocket.

Definition at line 65 of file CATLSClientSocket.cpp.

References m_bConnectedTLS, and m_pSSL.

Referenced by connect(), doTLSConnect(), CAAccountingBIInterface::initBIConnection(), CAAccountingBIInterface::terminateBIConnection(), and ~CATLSClientSocket().

  {
    if(m_bConnectedTLS)
      {
        SSL_shutdown(m_pSSL);
        m_bConnectedTLS = false;
      }
    if(m_pSSL!=NULL)
      {
        SSL_free(m_pSSL);
      }
    m_pSSL=NULL;
    return CASocket::close();
  }

Establishes the actual TCP/IP connection and performs the TLS handshake.

Establishes the TCP/IP connection, performs the TLS handshake and checks the server certificate validity.

Definition at line 170 of file CATLSClientSocket.cpp.

References close(), CASocket::connect(), doTLSConnect(), and E_SUCCESS.

Referenced by CAAccountingBIInterface::initBIConnection().

  {
    SINT32 rc;
    // call base class connect function
    if( (rc=CASocket::connect(psa, msTimeout)) != E_SUCCESS)
    {
      CASocket::close();
      return rc;
    }
    // do our own connection initialisation (TLS handshake)
    rc = doTLSConnect(psa);
    return rc;
  }

Here is the call graph for this function:

Does the TLS handshake.

The TCP Connection must be established first and openSSL library must be initialized

Definition at line 97 of file CATLSClientSocket.cpp.

References close(), E_SUCCESS, E_UNKNOWN, CACertificate::getX509(), m_bConnectedTLS, m_pCtx, m_pRootCert, m_pSSL, CASocket::m_Socket, and CAMsg::printMsg().

Referenced by connect().

  {
    SINT32 status;
    #ifdef DEBUG
      CAMsg::printMsg(LOG_DEBUG,"starting tls connect\n");
    #endif
    if(m_bConnectedTLS)
      return E_UNKNOWN;

    m_pSSL=SSL_new(m_pCtx);
    // do the standard part of the ssl handshake
    
    SSL_set_fd( m_pSSL, m_Socket );
    if((status = SSL_connect( m_pSSL )) != 1) 
    {
        int err = SSL_get_error(m_pSSL, status);
        CAMsg::printMsg(LOG_INFO,"CATLSClientSocket::doTLSConnect() failed! Reason: %i\n", err);
      SSL_shutdown(m_pSSL);
      close();
      m_bConnectedTLS = false;
      return E_UNKNOWN;
    }
    #ifdef DEBUG
      CAMsg::printMsg(LOG_DEBUG,"connect passed\n");
    #endif

    // ssl handshake ok, now let's check the server's identity
    // Note: This code was stolen from LinuxJournal
    // issue 89: An Introduction to OpenSSL Programming, Part I of II


    // is the certificate valid?
    SINT32 ret=SSL_get_verify_result( m_pSSL );
    if(ret != X509_V_OK&&ret!=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT )
      {
        CAMsg::printMsg(LOG_ERR, "SSLClientSocket: the Server certificate is INVALID!! Error: %i\n",ret);
        close();
        m_bConnectedTLS = false;
        return E_UNKNOWN;
      }
    X509* peerCert=SSL_get_peer_certificate(m_pSSL);
    if(peerCert==NULL)
      {
        CAMsg::printMsg(LOG_ERR, "SSLClientSocket: the Server shows no certificate!\n");
        close();
        m_bConnectedTLS = false;
        return E_UNKNOWN;
      }
    ret=1;
    if(m_pRootCert!=NULL)
      {
        EVP_PKEY* pubKey=X509_get_pubkey(m_pRootCert->getX509());
        ret=X509_verify(peerCert,pubKey);
      }
    X509_free(peerCert);
    if(ret!=1)
      {
        CAMsg::printMsg(LOG_ERR, "SSLClientSocket: could not verify server certificate!\n");
        close();
        m_bConnectedTLS = false;
        return E_UNKNOWN;
      }
    m_bConnectedTLS = true;
    return E_SUCCESS;
  }

Here is the call graph for this function:

SINT32 CATLSClientSocket::receive ( UINT8 buff,
UINT32  len 
) [virtual]

Will receive some bytes from the socket.

May block or not depending on whatever this socket was set to blocking or non-blocking mode. Warning: If socket is in blocking mode and receive is called, receive will block until some data is available, EVEN IF AN OTHER THREAD WILL CLOSE THIS SOCKET!

Parameters:
buffthe buffer which get the received data
lensize of buff
Returns:
SOCKET_ERROR if an error occured
Return values:
E_AGAIN,ifsocket was in non-blocking mode and receive would block or a timeout was reached
0if socket was gracefully closed
Returns:
the number of bytes received (always >0)

Reimplemented from CASocket.

Definition at line 244 of file CATLSClientSocket.cpp.

References E_AGAIN, m_pSSL, CAMsg::printMsg(), and SOCKET_ERROR.

{
  SINT32 ret=::SSL_read(m_pSSL,(char*)buff,len);
  if(ret<0)
    {
      int err = SSL_get_error(m_pSSL, ret);
    if ( (SSL_ERROR_WANT_READ == err) ||
       (SSL_ERROR_WANT_WRITE == err) )
      {
        return E_AGAIN;
      }

    if( (err == SSL_ERROR_SYSCALL) && (ret == -1) )
    {
      int errnum = errno;
      CAMsg::printMsg(LOG_ERR, "TLS-Socket: receive I/O error occured: %s\n", strerror(errnum));
    }
    return SOCKET_ERROR;
    }
  return ret;
}

Here is the call graph for this function:

SINT32 CATLSClientSocket::send ( const UINT8 buff,
UINT32  len 
) [virtual]

Sends all data over the network.

This may block, until all data was sent.

Parameters:
buffthe buffer of data to send
lencontent length
Return values:
E_UNKNOWNif an error occured
E_SUCCESSif successfull

Reimplemented from CASocket.

Definition at line 190 of file CATLSClientSocket.cpp.

References E_AGAIN, E_SUCCESS, m_pSSL, CAMsg::printMsg(), and SOCKET_ERROR.

{
  if(len==0)
  {
    return E_SUCCESS; //nothing to send
  }
  SINT32 ret=::SSL_write(m_pSSL,(char*)buff,len);
  if(ret<0)
  {
      int err = SSL_get_error(m_pSSL, ret);
    if ( (SSL_ERROR_WANT_READ == err) ||
       (SSL_ERROR_WANT_WRITE == err) )
      {
        return E_AGAIN;
      }

    if( (err == SSL_ERROR_SYSCALL) && (ret == -1) )
    {
      int errnum = errno;
      CAMsg::printMsg(LOG_ERR, "TLS-Socket: send I/O error occured: %s\n", strerror(errnum));
    }
    return SOCKET_ERROR;
  }
  return ret;
}

Here is the call graph for this function:

SINT32 CATLSClientSocket::sendFully ( const UINT8 buff,
UINT32  len 
) [virtual]

Sends all data over the network.

This may block, until all data was sent.

Parameters:
buffthe buffer of data to send
lencontent length
Return values:
E_UNKNOWNif an error occured
E_SUCCESSif successfull

Reimplemented from CASocket.

Definition at line 222 of file CATLSClientSocket.cpp.

References E_SUCCESS, E_UNKNOWN, and m_pSSL.

  {
    if(len==0)
      return E_SUCCESS; //nothing to send
    SINT32 ret=::SSL_write(m_pSSL,(char*)buff,len);
    if(ret < 0 || ret < len)
      return E_UNKNOWN;
    return E_SUCCESS;
  }

Sets the Certifcate we accept as server identification.

Init the SSL object.

Set to NULL if you do not want any certificate checking. At the moment only a depth of verification path of zero or one is supported!

SSL_init_library() must be called before this!

Definition at line 86 of file CATLSClientSocket.cpp.

References CACertificate::clone(), E_SUCCESS, and m_pRootCert.

Referenced by CAAccountingBIInterface::initBIConnection().

  {
    m_pRootCert=pCert->clone();
    return E_SUCCESS;
  }

Here is the call graph for this function:


Member Data Documentation

is the TLS layer established ?

Definition at line 89 of file CATLSClientSocket.hpp.

Referenced by CATLSClientSocket(), close(), and doTLSConnect().

SSL_CTX* CATLSClientSocket::m_pCtx [private]

Definition at line 85 of file CATLSClientSocket.hpp.

Referenced by CATLSClientSocket(), doTLSConnect(), and ~CATLSClientSocket().

SSL* CATLSClientSocket::m_pSSL [private]

Definition at line 84 of file CATLSClientSocket.hpp.

Referenced by CATLSClientSocket(), close(), doTLSConnect(), receive(), send(), and sendFully().


The documentation for this class was generated from the following files: