This went to openssl-users but just to be sure...

-- 
[Eric Rescorla                                   [EMAIL PROTECTED]]
                http://www.rtfm.com/


"Andy Schneider" <[EMAIL PROTECTED]> writes:
> It looks like although it has the right data and probably the right
> frame (since it gets the MAC correctly) the client is in some state
> where it isn't using the correct data to compute the MAC. Anyone any
> hints as to why this maybe? 
[...lots of discussion deleted...]

I can't exactly replicate the behavior you're seeing. I
seem to be able to do an arbitrary number of SSL_reads() 
interlaced with a rehandshake. Writes, however, are a different
matter. If I try to write interlaced with a rehandshake 
I get MAC errors right away.

After some investigation, the problem appears to be that
you can't safely interlace SSL_write() with rehandshakes.

Consider the following sequence of events:

CLIENT                          SERVER

                                SSL_renegotiate();
                                SSL_do_handshake();
                                        calls ssl_init_wbio_buffer()
                                        sends HelloRequest

SSL_read()
        read the HelloRequest and
        start the handshake, 
        sending the ClientHello

                                SSL_write()
                                        this write gets buffered.
                                SSL_read();

Now, when SSL_read() reads the ClientHello it eventually calls
ssl3_accept() which calls ssl_init_wbio_buffer AGAIN. This causes
the buffer to be zeroed with the result that the record from
the SSL_write() gets lost. Then when the ServerHello is transmitted
the client tries to decrypt it with the wrong CBC residue (or the
wrong part of RC4 keystream) and the wrong sequence #. This causes
MAC errors. This is a bug in OpenSSL.

The quick and dirty fix seems to be is to change ssl_init_wbio_buffer
by adding a BIO_flush() (see below). There may be something cleaner,
though. I don't immediately see how this fix can do any harm,
but there may well be somethign unobvious that I'm missing.

int ssl_init_wbio_buffer(SSL *s,int push)
        {
        BIO *bbio;

        if (s->bbio == NULL)
                {
                bbio=BIO_new(BIO_f_buffer());
                if (bbio == NULL) return(0);
                s->bbio=bbio;
                }
        else
                {
                bbio=s->bbio;
EKR: --->       (void)BIO_flush(bbio); 
                if (s->bbio == s->wbio)
                        s->wbio=BIO_pop(s->wbio);
                }
        (void)BIO_reset(bbio);
/*      if (!BIO_set_write_buffer_size(bbio,16*1024)) */
        if (!BIO_set_read_buffer_size(bbio,1))
                {
                SSLerr(SSL_F_SSL_INIT_WBIO_BUFFER,ERR_R_BUF_LIB);
                return(0);
                }
        if (push)
                {
                if (s->wbio != bbio)
                        s->wbio=BIO_push(bbio,s->wbio);
                }
        else
                {
                if (s->wbio == bbio)
                        s->wbio=BIO_pop(bbio);
                }
        return(1);
        }


Andy, let me know if this patch fixes your problem. It fixes mine :)

-Ekr

P.S. Does OpenSSL have some official way to report bugs?
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]



Reply via email to