Hello.

The following two ssl3 negotiations illustrate a problem I have
been having with the local variable got_new_session in the
(s3_srvr.c) SSL3_accept function:


==================================================================
| My app (not using sockets)     | openssl s_server
---------------------------------+--------------------------------
| SSL3_accept called             | SSL3_accept called
| got_new_session = 0            | got_new_session = 0
| STATE SSL3_ST_SR_CLNT_HELLO_A  | STATE SSL3_ST_SR_CLNT_HELLO_A
| got_new_session = 1            | got_new_session = 1
| STATE SSL3_ST_SW_SRVR_HELLO_A  | STATE SSL3_ST_SW_SRVR_HELLO_A
| STATE SSL3_ST_SW_CERT_A        | STATE SSL3_ST_SW_CERT_A
| STATE SSL3_ST_SW_KEY_EXCH_A    | STATE SSL3_ST_SW_KEY_EXCH_A
| STATE SSL3_ST_SW_CERT_REQ_A    | STATE SSL3_ST_SW_CERT_REQ_A
| STATE SSL3_ST_SW_FLUSH         | STATE SSL3_ST_SW_FLUSH
| STATE SSL3_ST_SR_CERT_A        | STATE SSL3_ST_SR_CERT_A
|                                |
| SSL_ERROR_WANT_READ            |
| SSL3_accept called  <--------  |
| got_new_session = 0 <--------  |
|                                |
| STATE SSL3_ST_SR_CERT_A        |
| STATE SSL3_ST_SR_KEY_EXCH_A    | STATE SSL3_ST_SR_KEY_EXCH_A
| STATE SSL3_ST_SR_CERT_VRFY_A   | STATE SSL3_ST_SR_CERT_VRFY_A
| STATE SSL3_ST_SR_FINISHED_A    | STATE SSL3_ST_SR_FINISHED_A
| STATE SSL3_ST_SW_CHANGE_A      | STATE SSL3_ST_SW_CHANGE_A
| STATE SSL3_ST_SW_FINISHED_A    | STATE SSL3_ST_SW_FINISHED_A
| STATE SSL3_ST_SW_FLUSH         | STATE SSL3_ST_SW_FLUSH
| SSL_ST_OK                      | SSL_ST_OK
| got new session == 0 <-------  | got new session == 1 <-------
|                                | session saved in cache
|                                | sess_accept_good++;
==================================================================


When trying to read the certificate, my application needs to
read more data (using (non-blocking) memory buffer BIO's), and
when SSL3_accept() is reentered, the local variable
got_new_session is reset to 0.

This means that in SSL_ST_OK, the session is not stored in the
cache and sess_accept_good is not incremented.

I have made a patch for this problem, placing the variable
got_new_session in the SSL connection "object". This way, the
variable is remembered across several SSL3_accept invocations.

Since I'm not very familiar with the code, I am uncertain
to which places this variable needs to be reset. As the
"constructor" SSL_new does a memset 0 on the entire structure
we AFAIK do not need to reset it initially.

In addition to that I reset the variable in the switch cases:
                case SSL_ST_RENEGOTIATE:
                        s->new_session=1;
                        /* s->state=SSL_ST_ACCEPT; */

                case SSL_ST_BEFORE:
                case SSL_ST_ACCEPT:
                case SSL_ST_BEFORE|SSL_ST_ACCEPT:
                case SSL_ST_OK|SSL_ST_ACCEPT:

..and in SSL_ST_OK (right after checking if got_new_session != 0).

Patch files are attached (they probably contain MS-DOS line-breaks).

I apologize in advance if I should be blatantly wrong, the
problem is already known, or if I have messed up in any
other way.

At least, the patch fixes my problems.

I would also like to know why only the ssl3_accept uses
a variable like got_new_session. I did not find anything
similar in ssl2 accept.


Best Regards,

�ivind Hardy Danielsen, M.Sc.       eMail: [EMAIL PROTECTED]
Senior System Architect

Cameon ANS - http://www.cameon.net/
--- ..\..\openssl\ssl\ssl.h     Mon Mar 25 15:37:27 2002
+++ ssl.h       Thu Apr 11 14:13:48 2002
@@ -591,6 +591,7 @@
                         * for received */
        int state;      /* where we are */
        int rstate;     /* where we are when reading */
+       int got_new_session;
 
        BUF_MEM *init_buf;      /* buffer used during init */
        int init_num;           /* amount read/written */
--- ..\..\openssl\ssl\s3_srvr.c Mon Mar 25 15:37:26 2002
+++ s3_srvr.c   Thu Apr 11 14:12:32 2002
@@ -167,7 +167,6 @@
        long num1;
        int ret= -1;
        int new_state,state,skip=0;
-       int got_new_session=0;
 
        RAND_add(&Time,sizeof(Time),0);
        ERR_clear_error();
@@ -203,6 +202,7 @@
                case SSL_ST_BEFORE|SSL_ST_ACCEPT:
                case SSL_ST_OK|SSL_ST_ACCEPT:
 
+                       s->got_new_session = 0;
                        s->server=1;
                        if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
 
@@ -280,7 +280,7 @@
                        s->shutdown=0;
                        ret=ssl3_get_client_hello(s);
                        if (ret <= 0) goto end;
-                       got_new_session=1;
+                       s->got_new_session=1;
                        s->state=SSL3_ST_SW_SRVR_HELLO_A;
                        s->init_num=0;
                        break;
@@ -513,8 +513,9 @@
 
                        s->init_num=0;
 
-                       if (got_new_session) /* skipped if we just sent a HelloRequest 
*/
+                       if (s->got_new_session) /* skipped if we just sent a 
+HelloRequest */
                                {
+                               s->got_new_session = 0;
                                /* actually not necessarily a 'new' session  */
                                
                                s->new_session=0;

Reply via email to