Jeremy,
I am very interested in the 25% scenario's you are referring to here.
What browser where you using?  Where were you trying to connect to, what 
Operating system were you trying to connect to,
I was reading up on extended cert's today and found out some interesting 
information from the Gibson Research Corp.

Best Regards,
~elaine.

-----Original Message-----
From: owner-openssl-us...@openssl.org [mailto:owner-openssl-us...@openssl.org] 
On Behalf Of jeremyf
Sent: Wednesday, October 09, 2013 3:24 PM
To: openssl-users@openssl.org
Subject: Strange OpenSSL error when my server accepts a new OpenSSL connection 
while existing ones are active

Hi all,

I'm working on adding OpenSSL support to my server program, and generally it's 
working pretty well, but I have come across a problem.

First, some background:  The server is single-threaded and uses non-blocking 
I/O and a select() loop to handle multiple clients simultaneously.  The server 
is linked to libssl.0.9.8.dylib and lib crypto.0.9.8.dylib (i.e. the libraries 
provided in /usr/lib by MacOS/X 10.8.5).  The client<->server protocol is a 
proprietary full-duplex messaging protocol; that is, the clients and the 
server are all allowed to send and receive data at any time, and the 
client<->server TCP connections remain connected indefinitely (i.e. until the 
client or server decides to disconnect).

The issue is this:  my clients can connect to the server, and sending and 
receiving data works fine (now that I got the SSL_ERROR_WANT_WRITE and 
SSL_ERROR_WANT_READ logic sorted out). but if a the server accept()'s a new 
client connection *while* other clients are in the middle of sending or 
receiving data, the SSL layer seems to break.  In particular, immediately 
after the server runs the setup routine below to set up the newly-accepted 
socket, SSL_read() on one or more of the other (pre-existing) clients' sockets 
will return -1, and ERR_print_errors_fp(stderr) gives this output:

        SSL_read() ERROR:  5673:error:140F3042:SSL 
routines:SSL_UNDEFINED_CONST_FUNCTION:called a function you should not 
call:/SourceCache/OpenSSL098/OpenSSL098-47.2/src/ssl/ssl_lib.c:2248:

After this error first appears, the server largely stops working.  Data 
movement stops, and if I try to connect another client I often get this error:

        SSL_read() ERROR: 5673:error:140760FC:SSL 
routines:SSL23_GET_CLIENT_HELLO:unknown 
protocol:/SourceCache/OpenSSL098/OpenSSL098-47.2/src/ssl/s23_srvr.c:578:

This happens about 25% of the time in my test scenario.  If I make sure that 
my pre-existing client connections are idle (no data being sent or received) 
at the moment when the new client connects, it never happens.  Does anyone 
know what might be going wrong here?  Have I found an OpenSSL bug, or is there 
some detail that I'm overlooking?  Some relevant code from my program is 
pasted below, in case it's helpful.

Thanks,
Jeremy

-----------

// Socket setup routine, called when the server accepts a new TCP socket int 
SSLSession :: SetupSSL(int sockfd) {
  _ctx = SSL_CTX_new(SSLv23_method());
  if (_ctx)
  {
     SSL_CTX_set_mode(_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);

     _ssl = SSL_new(_ctx);
     if (_ssl)
     {
        _sbio = BIO_new_socket(sockfd, BIO_NOCLOSE);
        if (_sbio)
        {
           SSL_set_bio(_ssl, _sbio, _sbio);
           SSL_set_accept_state(_ssl);

           BIO_set_nbio(_sbio, !blocking);
           ERR_print_errors_fp(stderr);

           return RESULT_SUCCESS;
        }
        else fprintf(stderr, "SSLSession:  BIO_new_socket() failed!\n");
     }
     else fprintf(stderr, "SSLSession:  SSL_new() failed!\n");
  }
  else fprintf(stderr, "SSLSession:  SSL_CTX_new() failed!\n");

  return RESULT_FAILURE;
}

// Socket read routine -- returns number of bytes read from SSL-land
int32 SSLSession :: Read(void *buffer, uint32 size) {
  if (_ssl == NULL) return -1;

  int32 bytes = SSL_read(_ssl, buffer, size);
  if (bytes > 0)
  {
     _sslState &= ~(SSL_STATE_READ_WANTS_READABLE_SOCKET | 
SSL_STATE_READ_WANTS_WRITEABLE_SOCKET);
  }
  else if (bytes == 0) return -1;  // connection was terminated
  else
  {
     int err = SSL_get_error(_ssl, bytes);
     if (err == SSL_ERROR_WANT_WRITE)
     {
        // We have to wait until our socket is writeable, and then repeat our 
SSL_read() call.
        _sslState &= ~SSL_STATE_READ_WANTS_READABLE_SOCKET;
        _sslState |=  SSL_STATE_READ_WANTS_WRITEABLE_SOCKET;
        bytes = 0;
     }
     else if (err == SSL_ERROR_WANT_READ)
     {
        // We have to wait until our socket is readable, and then repeat our 
SSL_read() call.
        _sslState |=  SSL_STATE_READ_WANTS_READABLE_SOCKET;
        _sslState &= ~SSL_STATE_READ_WANTS_WRITEABLE_SOCKET;
        bytes = 0;
     }
     else
     {
        fprintf(stderr, "SSL_read() ERROR:  ");
        ERR_print_errors_fp(stderr);
     }
  }
  return bytes;
}

// Socket write routine -- returns number of bytes written to SSL-land
int32 SSLSession :: Write(const void *buffer, uint32 size) {
  if (_ssl == NULL) return -1;

  int32 bytes = SSL_write(_ssl, buffer, size);
  if (bytes > 0)
  {
     _sslState &= ~(SSL_STATE_WRITE_WANTS_READABLE_SOCKET | 
SSL_STATE_WRITE_WANTS_WRITEABLE_SOCKET);
  }
  else if (bytes == 0) return -1;  // connection was terminated
  else
  {
     int err = SSL_get_error(_ssl, bytes);
     if (err == SSL_ERROR_WANT_READ)
     {
        // We have to wait until our socket is readable, and then repeat our 
SSL_write() call.
        _sslState |=  SSL_STATE_WRITE_WANTS_READABLE_SOCKET;
        _sslState &= ~SSL_STATE_WRITE_WANTS_WRITEABLE_SOCKET;
        bytes = 0;
     }
     else if (err == SSL_ERROR_WANT_WRITE)
     {
        // We have to wait until our socket is writeable, and then repeat our 
SSL_write() call.
        _sslState &= ~SSL_STATE_WRITE_WANTS_READABLE_SOCKET;
        _sslState |=  SSL_STATE_WRITE_WANTS_WRITEABLE_SOCKET;
        bytes = 0;
     }
     else
     {
        fprintf(stderr,"SSL_write() ERROR!");
        ERR_print_errors_fp(stderr);
     }
  }
  return bytes;
}

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to