Hi,

We are running SCTP connections with DTLS enabled in our application. We
have adapted openssl version (openssl-1.1.0e) to achieve the same.

We have generated the self signed root and node certificates for testing.
We have a strange problem with the incomplete DTLS handshake if we run the
DTLS client and DTLS server is different systems.If we run the DTLS client
and server in same system handshake is successful, handshake is not
successful if run client and server in different VM's.

This strange problem happens only for SCTP/DTLS connection. With the same
set of certificates TCP/TLS connection is successful and we are able to
exchange the application data.

I am attaching the code bits for SSL_accept and SSL_connect and also the
wireshark trace of unsuccessful handshake. Please assist me to debug this
problem.

SSL_accept returns  SSL_ERROR_WANT_READ(2) infinite times but SSL_connect
is called 4 or 5 times and select system call timeout.

Thanks,
Mahesh G S
    bool pollSocketForEvents(long aTlsError)
    {
      /* This function is to implement the SSL Socket call behaviour
              http://jmarshall.com/stuff/handling-nbio-errors-in-openssl.html */
              
      fd_set readFds, writeFds;
      struct timeval timeout;
      int retValue;
      
      int nfds = getSocketId();
      
      FD_SET(nfds, &readFds);
      FD_SET(nfds, &writeFds);

      /* Wait for 5 Seconds */
      timeout.tv_usec = 0;
      timeout.tv_sec = 5;

      if (SSL_ERROR_WANT_READ == aTlsError)
      {
        retValue = select(nfds + 1, &readFds, NULL, NULL, &timeout);
        if (retValue <= 0)
        {
          // Timeout or error just return failure
          return false;
        }
      }

      if (SSL_ERROR_WANT_WRITE == aTlsError)
      {
        retValue = select(nfds + 1, NULL, &writeFds, NULL, &timeout);
        if (retValue <= 0)
        { 
          // Timeout or error just return failure
          return false;
        }
      }

      return true;
    }   


    void acceptTlsConnection()
    {   
        TRACE_CALL_BEGIN_MGR (ivManager);

        long aTlsError;
        bool retry = true;
        const char *aFile;
        int aLine;
        long aRetValue;
                  
        /* Create an SSL Session for server */
        if (createSSLSession(false))
        {
          /* Throw failure exception */
          TRACE_CALL_END_MGR (ivManager);    
          throw (TLSException(TLSException::eSSLContextCreationFailure, " Error 
while creating context for accepted connection"));            
        }

        do
        {
          /* Clear SSL error queue */
          ERR_clear_error();

          /* Initiate SSL Handshake */
          aRetValue = SSL_accept(ivSSL);

          if (aRetValue <= 0)
          {
            aTlsError = SSL_get_error(ivSSL, aRetValue);          

            switch(aTlsError)
            {
              case SSL_ERROR_WANT_READ:                
              case SSL_ERROR_WANT_WRITE:
              {
                  /* Select on the socket for read/write events */
                  retry = pollSocketForEvents(aTlsError);

                  /* Nothing to do retry for accepting new connection */
                  INSD_LOG(ivManager, INSD_LOG_INFO," SSL_accept() fails to 
accept new connection "
                  "need to retry, returned error code %d ", aTlsError);
              }
              break;

              case SSL_ERROR_SYSCALL:

              if (EWOULDBLOCK == errno || EAGAIN == errno)
              {
                /* Nothing to do retry for accepting new connection */
                INSD_LOG(ivManager, INSD_LOG_INFO," SSL_accept() fails to 
accept new connection "
                "need to retry, returned error code %d ", aTlsError);
              }
              else
              {
                int aRet = ERR_get_error_line(&aFile, &aLine);
                
                INSD_LOG(ivManager, INSD_LOG_ERROR," SSL File : %s , Line 
number : %d , "
                  "Socket Id %d, Linux Error Code %d", aFile, aLine, 
getSocketId(), errno);
                
                INSD_LOG(ivManager, INSD_LOG_ERROR,"SSL_accept () :: Result 
Code : %d ", aTlsError);

                retry = false;
              }

              break;

              default:
              {
                int aRet = ERR_get_error_line(&aFile, &aLine);
                
                INSD_LOG(ivManager, INSD_LOG_ERROR,"(SSL_accept) Failed to 
accept new connection, "
                  " Socket Id %d, Return Value %d ", getSocketId(), aTlsError);
                
                INSD_LOG(ivManager, INSD_LOG_ERROR," SSL File : %s , Line 
number : %d , Linux Error Code %d", aFile, aLine, errno);
                

                retry = false;
              }
              
              break;
              }        
            }
          }while (aRetValue != 1 && retry != false);

          if (aRetValue <= 0)
          {
            /* Throw failure exception */
            TRACE_CALL_END_MGR (ivManager);    
            throw (TLSException(TLSException::eSSLAcceptFailure, " Error while 
accepting connection from client "));            
          }
          
          ivTlsState = connected;

          INSD_LOG(ivManager, INSD_LOG_DEBUG, "New connection accepted, Socket 
ID %d", getSocketId());

          TRACE_CALL_END_MGR (ivManager);    
          return;
    }
                
                
    void initTlsConnection()
    {

        TRACE_CALL_BEGIN_MGR (ivManager);

        long aTlsError = -1;
        bool retry = true;
        const char *aFile;
        int aLine;
        long aRetValue;

        /* DTLS handshake should be established only after the SCTP connectx() 
is successful */
        if (ivSocketState == DiameterSocket::eConnected)
        {        
          /* Create an SSL Session for client*/
          if (createSSLSession())
          {
            TRACE_CALL_END_MGR (ivManager);    

            /* Throw failure exception */
            throw (TLSException(TLSException::eSSLContextCreationFailure, " 
Error while creating context for client connection"));            
          }
          
          do
          {
            /* Clear openssl error queue */
            ERR_clear_error();

            /* Initiate SSL Handshake */
            aRetValue = SSL_connect(ivSSL);

            if (aRetValue <= 0)
            {
              aTlsError = SSL_get_error(ivSSL, aRetValue);          
              
              switch(aTlsError)
              {
                case SSL_ERROR_WANT_READ:                
                case SSL_ERROR_WANT_WRITE:
                {
                  /* Select on the socket for read/write events */
                  retry = pollSocketForEvents(aTlsError);

                  /* Nothing to do, retry to connect again*/
                  INSD_LOG(ivManager, INSD_LOG_INFO," SSL_connect() fails to 
connect "
                  "need to retry, returned error code %d , retry ? %s", 
aTlsError, retry?"true":"false");
                }
                break;

                case SSL_ERROR_SYSCALL:

                if (EWOULDBLOCK == errno || EAGAIN == errno)
                {
                  /* Nothing to do, retry to connect again */
                }
                else
                {
                  int aRet = ERR_get_error_line(&aFile, &aLine);
                  
                  INSD_LOG(ivManager, INSD_LOG_ERROR," SSL File : %s , Line 
number : %d , "
                    "Socket Id %d, Linux Error Code %d", aFile, aLine, 
getSocketId(), errno);
                  
                  INSD_LOG(ivManager, INSD_LOG_ERROR,"SSL_connect () :: Result 
Code : %d ", aTlsError);

                  retry = false;
                }

                break;

                default:
                {
                  int aRet = ERR_get_error_line(&aFile, &aLine);
                  
                  INSD_LOG(ivManager, INSD_LOG_ERROR,"(SSL_connect) Failed to 
connect to server, "
                    " Socket Id %d, Return Value %d ", getSocketId(), 
aTlsError);
                  
                  INSD_LOG(ivManager, INSD_LOG_ERROR," SSL File : %s , Line 
number : %d , Linux Error Code %d", aFile, aLine, errno);

                  retry = false;
                }
                
                break;
              }        
            }
          }while (aRetValue != 1 && retry != false);

          if (aRetValue <= 0)
          {
            TRACE_CALL_END_MGR (ivManager);    

            /* Throw failure exception */
            throw (TLSException(TLSException::eSSLConnectFailure, " Error while 
connecting to server "));            
          }
          
          ivTlsState = connected;

          INSD_LOG(ivManager, INSD_LOG_DEBUG, "Connection established");

        }

        TRACE_CALL_END_MGR (ivManager);    
        return;
    }
                

Attachment: proxy.cap
Description: Binary data

-- 
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users

Reply via email to