Am 08.02.2016 um 15:26 schrieb Matt Caswell:
On 08/02/16 13:45, Tomas Mraz wrote:
On Po, 2016-02-08 at 12:34 +0000, Matt Caswell wrote:

On 08/02/16 12:11, Rainer Jung wrote:

Renegotiation isn't entirely within the control of the server. A
server
can request that a renegotiation takes place. It is up to the client
whether it honours that request immediately; or perhaps its finishes
off
sending some application data before it gets around to honouring it;
or
perhaps it doesn't honour it at all.

   SSL_renegotiate(ssl);
   SSL_do_handshake(ssl);

This sequence makes the server send the HelloVerifyRequest. It is
then
back in a state where it can continue to receive application data
from
the client. At some later point the client may or may not initiate a
reneg.

   SSL_set_state(ssl, SSL_ST_ACCEPT);
   SSL_do_handshake(ssl);

This is really not a good idea, and I suspect is a hack that was
originally copied from s_server :-). Doing this will make the
connection
fail if the client sends application data next (which it is allowed
to do).

We don't know what we're going to get next from the client it could
be
more application data. It could be an immediate start of a new
handshake. The correct thing for the server to do is to attempt to
read
application data. If we happen to get a handshake instead then it
will
be automatically handled.

What if the server wants to discard all the application data that was
sent before the renegotiation completed? Or how the server can
recognize which part of data was received before renegotiation
completed and which after it?


You never get app data from two different epochs returned in a single
API call. In certain situations you can get a handshake finish occur
followed by a read of application data all within a single API call.
It's also valid that the attempt to read application data handled the
handshake but doesn't actually return any app data because the client
didn't send any yet (it *just* did the reneg).

So if you want to discard all application data until the client has
initiated a reneg and supplied a certificate then you'll want to do
something like:

SSL_renegotiate(ssl);
SSL_do_handshake(ssl);
do {
     read_some_app_data();
     if(no_client_cert_yet()) {
         discard_app_data();
     }
} while(no_client_cert_yet());

After doing some experiments I ended up calling SSL_peek() with a length of 0 bytes. That seems to reliably trigger the renegotiation handshake. Using this approach was easier, since we (Apache) have to handle various reneg scenarios:

- waiting for client certs
- doing a reneg because cipher requirements changed but no client certs involved
- sometimes no application data is expected after the renegotiation

I hope that effect of SSL_peek(ssl, buf, 0) is not just an implementation artefact and we can actually rely on it.

Regards,

Rainer

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

Reply via email to