[openssl-dev] How to do reneg with client certs in 1.1.0 API

Matt Caswell matt at openssl.org
Mon Feb 8 14:26:07 UTC 2016



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());

Matt





More information about the openssl-dev mailing list