On 7/12/2018 1:04 PM, David Lloyd wrote:
On Thu, Jul 12, 2018 at 2:30 PM Xuelei Fan <xuelei....@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....@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.

Reply via email to