SSLEngine weird behavior in 11+21?

Xuelei Fan xuelei.fan at oracle.com
Thu Jul 12 21:09:57 UTC 2018


On 7/12/2018 1:04 PM, David Lloyd wrote:
> On Thu, Jul 12, 2018 at 2:30 PM Xuelei Fan <xuelei.fan at oracle.com> wrote:
>> On 7/12/2018 10:47 AM, Simone Bordet wrote:
>>> On Thu, Jul 12, 2018 at 4:34 PM Xuelei Fan <xuelei.fan at oracle.com> wrote:
> [...]
>>>> In TLS 1.3, half-close policy is used.  The server may not response with
>>>> the close_notify for client close_notify request.  See the "Closure
>>>> Alerts" section for more details:
>>>>       https://tools.ietf.org/html/draft-ietf-tls-tls13-28#section-6.1
>>>
>>> In that section I read:
>>> "Each party MUST send a "close_notify" alert before closing its write
>>> side of the connection, unless it has already sent some error alert."
>>>
>>> Given that, I expect that for close_notify, at step #2, the client
>>> goes into NEED_UNWRAP, as the server MUST send a close_notify too.
> [...]
>> Per the TLS 1.3 specification, the local can request to close its
>> writing side, but it cannot to request to close the peer writing side.
>> It means it is not defined about how to close the read side.  It could
>> lead to issues in practice.  I had a question in the IETF TLS email
>> list.  But unfortunately, I did not get a ideal solution:
>>       https://www.ietf.org/mail-archive/web/tls/current/msg25581.html
>>
>> In order to countermeasure the issues, JDK will try to close the
>> underlying socket if either side sends the close_notify message.
> 
> Please forgive my interjection - does this not explicitly violate the
> half-close policy?  The socket should not be closed until close_notify
> is both received (which means that read-shutdown is allowed) and sent
> (after which write-shutdown may be performed), should it not?
> 
In TLS 1.3 closure, receiving of the close_notify is not required:
   "... Both parties need not wait to receive a
    "close_notify" alert before closing their read side of the
    connection, though doing so would introduce the possibility of
    truncation."

TLS 1.2 also has similar specification:
    "It is not required for the initiator
    of the close to wait for the responding close_notify alert before
    closing the read side of the connection."

My reading the spec, the peer MUST send the close_notify, but it is not 
required to close the connection.

If the socket cannot be closed until close_notify get received, the 
local may never have a chance to close the socket unless the peer 
agrees.  It does not sound like to me.  The compatibility impact could 
be serious as previous application work in a duplex-close manner.
1. start and establish a TLS connection.
2. client call close(), and the server will response with a close_notify 
in TLS 1.2. the TLS connection can be closed gracefully.

While for TLS 1.3, #2 does not work if the client calling of close() 
closes the writing side only, and leave the reading side open.

I see the benefits of half-close.  I'm open to hear a better solution to 
take the benefit of half-close and avoid the compatibility issue.

I raised a similar question in the TLS mailing list:
    https://www.ietf.org/mail-archive/web/tls/current/msg25581.html

A new close_request alert might be able to solve the issue.  But I had 
no strong user case in practice about why we cannot close the underlying 
TCP socket if we don't want to read.  There was on census for the 
discussion in the IETF TLS mailing list, and the request was deferred.

Thanks,
Xuelei

>>> At this point, my gut feeling is that having a single codebase
>>> handling TLS 1.2 and TLS 1.3 would be difficult.
> 
> Is this feeling due to the half-closed situation?  Because it's my
> firm belief that an TLS 1.2 implementation which treats half-closed in
> the manner specified by TLS 1.3 cannot be shown (from the perspective
> of an outside observer) to be in violation of the specification, and
> furthermore, _not_ doing so may represent a theoretical existent
> security risk.
> 
> Put another way, imagine that my endpoint receives data and then sends
> data.  Now imagine that the receive side immediately receives
> close_notify after its data is processed but before the send
> (response) begins.  This obviously will terminate the connection
> before the data is output.
> 
> Now imagine that the close_notify is completely contained in a single
> TCP packet, and that packet is (for whatever reason) delayed on the
> network until my send is complete.  The OpenJDK TLS stack closes the
> socket at the right time (from my perspective), after both receive and
> send completed correctly. This delay has caused a material behavior
> change of my application, which is not a desirable effect.  Two
> different behaviors, with the only input difference being one of
> timing.
> 
> Imagine again now that the TLS 1.2 stack would not immediately send a
> close_notify, but instead would follow the half-close model as
> specified in TLS 1.3.  As far as the *peer* is aware, my endpoint is
> conformant, because the peer cannot possibly differentiate between the
> TLS stack deferring shutdown to the application versus the
> close_notify message being delayed on the network.  And, a bad actor
> can no longer affect the behavior of the application by delaying
> packets.
> 
> These reasons were, without a doubt, considerations when the rules
> were changed for TLS 1.3.  Also another important consideration was
> probably the observation that OpenSSL *already* appears to behave in
> this manner.  OpenJDK's behavior has always IMO been clearly incorrect
> in this regard, despite the wording of the specification, and seeing
> this belief borne out by the changes in the TLS 1.3 spec is somewhat
> vindicating in this regard.  But more importantly, I think this
> represents a chance to fix this long-standing bad behavior of the JDK.
> 



More information about the security-dev mailing list