RFR JDK-8240871: SSLEngine handshake status immediately after the handshake can be NOT_HANDSHAKING rather than FINISHED with TLSv1.3

Xuelei Fan xuelei.fan at oracle.com
Tue May 26 18:08:49 UTC 2020


Ping ...

On 5/13/2020 1:44 PM, Xuelei Fan wrote:
> On 5/13/2020 9:41 AM, Anthony Scarpino wrote:
>> On 4/30/20 10:19 AM, Xuelei Fan wrote:
>>> Hi,
>>>
>>> Could I get the following update reviewed:
>>>      http://cr.openjdk.java.net/~xuelei/8240871/webrev.00/
>>>
>>> For TLS 1.3 full handshake, if the last handshake flight wraps the 
>>> Finished together with other handshake message, for example client 
>>> certificate, the flight could be wrapped and encrypted in one record 
>>> and delegated tasks would be used.  There is no chance to return 
>>> FINISHED handshake status with SSLEngine.(un)wrap(). However, per the 
>>> HandshakeStatus.FINISHED specification, this handshake status is only 
>>> generated by a call to SSLEngine.wrap()/unwrap() and it is never 
>>> generated by SSLEngine.getHandshakeStatus().
>>>
>>> In order to workaround this case for TLS 1.3, the FINISHED status 
>>> could present with SSLEngine.wrap() while delivering of the 
>>> NewSessionTicket post-handshake message.  If this post-handshake 
>>> message is not needed, a follow-on SSLEngine.wrap() should be called 
>>> to indicate the FINISHED handshake status.  Although this special 
>>> SSLEngine.wrap() should not consume or produce any application or 
>>> network data.
>>>
>>> I also clean up some debug log, names and code style a little bit.
>>>
>>> The update could be confirmed with Tomcat and Firefox in private 
>>> mode, as described in the bug description.  As this case happens only 
>>> when psk_key_exchange_modes does not present, which is not a behavior 
>>> supported by JDK, I did not find a workaround for a new regression 
>>> test yet.  I added the labels, noreg-external and noreg-hard.
>>>
>>> Thanks,
>>> Xuelei
>>
>> I do not fully understand the situation, mostly because of SSLEngine 
>> semantics.  In normal operation, does is HandshakeStatus.FINISHED 
>> returned when Finished is received or after the NewSessionTicket message?
> Not exactly.  For TLS 1.2, FINISHED will be returned with unwrap() of 
> the finished handshake message.  However, for TLS 1.3, FINISHED will be 
> returned any longer, because the finished handshake message is wrapped 
> with certificate message in one record.
> 
> For TLS 1.3:
> 1. client send certificate, certificate verify and finished handshake 
> message in one record.
> 2. server call unwrap(), and return NEED_TASK to handle the certificate 
> and certificate verify.
> 
> So, no more FINISHED for the unwrap() return.
> 
> It is fine if there is a after NewSessionTicket message.  The wrap() for 
> the post-handshake message will return FINISHED.
> 
> The bug reported is a special one that the Firefox is run in private 
> mode, which does not request NewSessionTicket.  So there is no 
> post-handshake generated and sent in server side.  Then, there is no 
> FINISHED can be used if applications depends on it.
> 
> To workaround the case, a dummy wrap() or unwrap() could be used to get 
> the FINISHED.  The wrap() or unwrap() actually do nothing but return the 
> FINISHED status.
> 
>> My understanding would have been after Finished because NST is suppose 
>> to be a post handshake message.  So in this case there is no problem, 
>> correct?
>>
> Correct.
> 
>> I'm trying to figure out why you need an empty NST.  Is the problem 
>> when a number of messages are bundled together.  For example, the 
>> Finished message with a partial NST, then Finished isn't processed and 
>> both sides are waiting?  Or do both sides continue normal traffic, 
>> it's jut the HandshakeStatus.FINISHED is one operation behind?
>>
> It should be fine as empty NST is just a signal to indicate the next 
> call to wrap().  The next call to wrap() just use the signal for the 
> return of FINISHED status, not network data produced, delivered or 
> consumed.
> 
>>
>> One code comment so far:
>> 433:  The debug message purpose was to say the NST is a stateless 
>> ticket and not a preshared key.  Can we keep "stateless" in the message?
>>
> NewSessionTicket.java?  Sure, I may just want to shrink to one line.  It 
> was not intended.
> 
> Xuelei


More information about the security-dev mailing list