Re: Alias internal format leaked to application code?

2020-06-01 Thread Simone Bordet
Hi,

On Mon, Jun 1, 2020 at 5:24 PM Xuelei Fan  wrote:
>
> Good catch, Simone.  It is not expected to parser the alias in application 
> code.  Would you like file a bug?

https://bugs.openjdk.java.net/browse/JDK-8246262.

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Alias internal format leaked to application code?

2020-06-01 Thread Simone Bordet
Hi,

when using "PKIX" as KeyManagerFactoryAlgorithm, the alias is
manipulated from what's in the keystore (for example, "jetty") to an
internal format such as "N.0.jetty", where N is an increasing number
(in sun.security.ssl.X509KeyManagerImpl.makeAlias()).

The problem is that (especially in case of SNI) the KeyManager could
be wrapped by a user-written KeyManager that may delegate to the JDK
one.

When the user-written KeyManager delegates to the JDK instance by
calling keyManager.getServerAliases(keyType, issuers), an array of
aliases is returned, but the aliases are of the internal format
described above.

This makes the user-written code fail any logic that is based on the
aliases, as comparing these internal formats with the ones present in
the KeyStore will fail.

Can you please clarify if this is expected behavior and whether
user-written code should "unwrap" this internal alias format (is it
defined somewhere?), or if this internal format is wrongly leaked to
user-written code?

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Reading from a closed socket: different behavior between Linux and other operating systems

2020-01-07 Thread Simone Bordet
Hi,

On Mon, Jan 6, 2020 at 5:39 PM Chris Hegarty  wrote:
> // force RST
> clientChannel.setOption(StandardSocketOptions.SO_LINGER, 0);

Just want to point out that when the channel/socket is set in
non-blocking mode, SO_LINGER is either not supported or gives
undefined behavior or throws (on Windows).

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Aftermath of TLS 1.3 in Java 11 with wrapped IOExceptions

2019-12-02 Thread Simone Bordet
Hi,

On Mon, Dec 2, 2019 at 7:36 PM Xuelei Fan  wrote:
>
> Hi,
>
> Could someone please help to verify if the attached patch (JDK 14) works
> HttpComponents?

I'm not sure I see the difference between a generic IOException and
SSLHandshakeException.

If a client is connecting to a busy proxy that sends a TLS
close_notify to the client, that would be a SSLHandshakeException even
though it may be actually possible to retry and get a successful
connection and TLS handshake.
On the other hand, if a busy proxy sends a FIN to the client, that
would be an IOException that may or not succeed when retried.
Or the server is running out of file descriptors, very likely will be
reported as an IOException, but retrying won't help.
Or the client is running out of file descriptors.
Or the client cannot connect to the server (again, a retry may or may
not be successful).

Bottom line is that for both cases (IOException and
SSLHandshakeException) a retry may be successful and as such client
code will have a hard time to detect when or not to retry in either
case.

SSLException (and subclasses) do not report the TLS AlertDescription
code, so it won't be possible to know the exact reason for the
SSLHandshakeException, and from it decide whether it's retryable or
not.

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Change in closeOutbound() behavior for unused SSLEngine

2019-10-16 Thread Simone Bordet
Hi,

On Wed, Oct 16, 2019 at 7:42 PM Xuelei Fan  wrote:
>
> Hi Simone,
>
> The compatibility impact makes sense to me. Would you mind file a new bug?

https://bugs.openjdk.java.net/browse/JDK-8232432

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Change in closeOutbound() behavior for unused SSLEngine

2019-10-16 Thread Simone Bordet
Hi,

On Wed, Oct 16, 2019 at 5:42 PM Xuelei Fan  wrote:
>
> The TLS protocol was changed to use half-close policy since TLS 1.3.  As
> means that sslEngine.closeOutbound() will close the outbound and keep
> the inbound open.  "NEED_UNWRAP" is used to indicate that the engine can
> still be used to decode input message.

Maybe it's a matter of interpretation, but the SSLEngine state was not
used to indicate what may _possibly_ be done in the future.
It was an exact indication of what an application should do _now_.
In the normal case (after the handshake is completed), closeOutbound()
turns the state into NEED_WRAP because wrapping will generate the
close_notify.
In this case, NEED_UNWRAP is strange because I just closed the
outbound, and it's not clear what I need to read right now.
In fact, most of the times the read will yield 0 bytes because the
other peer is not aware that we have closed the outbound (as nothing
was produced to be sent to the other peer).

> For the specific case bellow, it is reasonable to expect
> "NOT_HANDSHAKING" as the handshaking has not been started.  On the other
> side, as only the inbound open, it is also reasonable to me to use
> "NEED_UNWRAP" although there is nothing to unwrap.  I think, using
> ""NOT_HANDSHAKING" may lead to confusing about what the next operation,
> wrap() or unwrap(), could be in practice.  CLOSED is not an option to me
> as the inbound is still open.

CLOSED is the _result_ (not the state) after a wrap().
Seems to me that you are saying that NOT_HANDSHAKING is wrong because
it does not tell what to do now, and NEED_UNWRAP is also wrong
because, well, there is nothing to unwrap.
What remains is NEED_WRAP, which will correctly tell what an
application needs to do.
This is exactly what happens after the TLS handshake is completed: the
application is in NOT_HANDSHAKING and calling closeOutbound() changes
the state into NEED_WRAP.
So I think there is an asymmetry between the behavior of
closeOutbound() before and after the handshake that does not seem
justified?

> I understand there might be some compatibility issues for the use of
> half-close policy.  I may close both inbound and outbound of an engine
> in the application code if the connection is not used.

I think that if an application calls closeOutbound(), the
implementation should only do that.

> Is there a known compatibility impact on you applications?

Yes.
It's not possible to use the same code JDK 8 and JDK 11, unless there
is some "if (isJDK11Behavior())" throughout the code.

Looking just at JDK 11 behavior, what happens is:
* closeOutbound()
* state is now NEED_UNWRAP
* read from network, 0 bytes
* call unwrap(), produces a BUFFER_UNDERFLOW result, basically says
"wait for bytes to read" that will never come
* 0 bytes have been produced so nothing gets sent to the other peer
* the application does not know _when_ to send a FIN to the other peer
(it's waiting for the state to move away from NEED_UNWRAP and/or for a
CLOSED result)

Contrast that with:
* closeOutbound()
* state is now NEED_WRAP
* call wrap(), produces CLOSED result, basically says "we are done
with the output"
* 0 bytes have been produced, so no close_notify is sent to the other
peer, but we know from the CLOSED result that we can now send the FIN
to the other peer.

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Change in closeOutbound() behavior for unused SSLEngine

2019-10-16 Thread Simone Bordet
Hi,

SSLContext sslContext = SSLContext.getDefault();
SSLEngine sslEngine = sslContext.createSSLEngine();
sslEngine.closeOutbound();
SSLEngineResult.HandshakeStatus hsStatus = sslEngine.getHandshakeStatus();
System.err.println("hsStatus = " + hsStatus);

This prints "NOT_HANDSHAKING" in Java 8 and "NEED_UNWRAP" in JDK 11+.

In both cases, trying to wrap() consumes and produces 0 bytes (so the
close_notify is not generated, which I think is fine given that the
SSLEngine was never used) and produces a CLOSED result.

This case is common for connections that are established but never
used (not even a TLS byte was exchanged).

Is this change in behavior expected?

I find strange that calling closeOutbound() results in a NEED_UNWRAP
(as there is nothing to read).

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: JDK 13 SSLSession.getValue() throws NPE

2019-09-06 Thread Simone Bordet
Hi,

On Fri, Sep 6, 2019 at 6:48 AM Jaikiran Pai  wrote:
>
> Hi Simone,
>
> I remember hitting a similar issue back when I was testing a EA version
> of JDK 13. There was bug for it here
> https://bugs.openjdk.java.net/browse/JDK-8226649 and that one says it's
> fixed in "13" but doesn't have a build number associated with it. Which
> build of JDK 13 are you on?

I was using 13+29. The issue is fixed in 13+33.
Sorry for the noise.

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


JDK 13 SSLSession.getValue() throws NPE

2019-09-05 Thread Simone Bordet
Hi,

we have a number of TLS tests failing in Jetty when running on JDK 13,
while they work on JDK 11 and 12.

The simplest way to reproduce this is to open 2 TLS sockets to Jetty,
one after the other.

On the server, the first socket creates a SSLEngine which has a SSLSession.
Jetty calls SSLSession.getValue() to check whether a key (that we may
have put on the session during SNI processing) is there. For the first
socket this works.

The second socket, however, is using resumption. On the server, a new
SSLEngine is created, but its SSLSession has field "boundValues" ==
null so trying to call SSLSession.getValue() throws a NPE.

Is this a regression?

Thanks!

-- 
Simone Bordet

http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.


Re: Use of OpenSSL as JCE security provider if available on system

2019-03-21 Thread Simone Bordet
Hi,

On Thu, Mar 21, 2019 at 3:43 PM Sean Mullan  wrote:
> But, if we want to explore this further, I think it first makes sense to
> take a step back and focus more on what benefits an OpenSSL provider or
> "native bridge" would provide.

Benchmarked 3x-10x performance improvements.
https://nbsoftsolutions.com/blog/dropwizard-1-3-upcoming-tls-improvements

I guess the memory allocation/footprint has similar improvements, with
the JDK insisting at requiring ~17 KiB buffers to read HTTP requests
in the order of <1 KiB.

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Align SSLSocket and SSLEngine Javadocs

2018-08-27 Thread Simone Bordet
Xuelei,

On Mon, Aug 27, 2018 at 4:00 PM Xuelei Fan  wrote:
>
> H Simone,
>
> There is no change for the SSLSocket.startHandshake() and
> SSLEngine.beginHandshake() specification.  They are can be used for new
> handshake and key update.
>
> We want the specification independent from TLS versions as much as
> possible.  An application developer only need to know the
> functionalities, but not necessarily to understand the TLS protocol details.
>
> For TLS 1.2 and prior versions, the key update is performed with
> renegotiation;  for TLS 1.3, it is the KeyUpdate post-handshake.

Perhaps I was not clear. I'm not talking about the specification (what
the method does), just about the Javadoc.
A developer needs to know if calling a method causes a renegotiation or not :)

Would be great if your paragraph above ("For TLS 1.2 and prior ...")
would be included in the Javadoc.
In particular for SSLEngine, the current Javadoc says:

"Initiates handshaking (initial or renegotiation) on this SSLEngine."

It does not mention TLS 1.3 and does not mention KeyUpdate, so would
be great if it does.
And would be great if beginHandshake() and startHandshake() have a
very similar Javadoc.

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Align SSLSocket and SSLEngine Javadocs

2018-08-27 Thread Simone Bordet
Hi,

SSLSocket.startHandshake() and SSLEngine.beginHandshake() are similar
in that they start the TLS handshake, but they can also be used after
the TLS handshake.

SSLSocket.startHandshake() Javadoc seems to be more generic,
describing that the method may not only start a new handshake but also
be used to update encryption keys etc.

Especially in light of TLS 1.3 where renegotiation is forbidden, I
would like the Javadoc of these method to align and describe exactly
when they do with respect to the TLS protocol version.

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: SSLSocket session resumption not working with TLS 1.3 and 11+27

2018-08-24 Thread Simone Bordet
Hi,

On Fri, Aug 24, 2018 at 8:54 PM Adam Petcher  wrote:
> On 8/23/2018 3:28 PM, Simone Bordet wrote:
> > Hi,
> >
> > The code below reproduces a bug where session resumption is tested.
> > Turns out that session resumption does happen on the client and on the
> > server, but on the client the session id is not replaced with the
> > resumed session id (while it is on the server).
> >
> > The code prints:
> >
> > session1 = Session(1535051727187|TLS_AES_128_GCM_SHA256) - [29, -38, ...]
> > session2 = Session(1535051727187|TLS_AES_128_GCM_SHA256) - [11, -20, ...]
> >
> > where it can be seen that the second session has the same creationTime
> > as the first, but different session id (the array).
>
> Just to be clear: are you saying that a short handshake is happening in
> all cases,

I have not tested all cases, but a short handshake happens (on the
second connection) with the code I posted.

> or are there some cases where a full handshake (including
> Certificate and CertificateVerify) is used where you would expect a
> short handshake?

I have not seen this, but as I said, I have not tested all cases, such
as client authentication, etc.

 The fact that the session ID is different is expected,
> and it is a result of the fact that sessions are managed differently in
> the TLS 1.3 implementation.

However, on the server-side the session ID is the same, so I am
confused by the fact that on the client the session has been resumed,
but it has a different ID.

> You can no longer use session IDs to
> determine whether a full handshake was used.

Why not? I could not find a section in the TLS 1.3 RFC that mandates
that resumed session IDs must be different.
We have had in the past Jetty users that relied on this feature
heavily to confirm that they were actually resuming sessions - for
performance reasons.
Comparing SSLSession.creationTime seems more brittle.

> Also sessions are managed
> differently in the client and server code, so you should expect
> different behavior in client/server with respect to session IDs.

Indeed. Is this an implementation detail, or it's mandated by the RFC?

> > About the code below, note how it is necessary to attempt a read after
> > the first handshake to read the NewSessionTicket post-handshake
> > message that is otherwise not consumed by the client. This was not
> > necessary before.
> > Scenarios where clients don't read from the server (or where many
> > clients are created before one starts reading) will have a harder time
> > to use session resumption.
>
> This is also expected behavior in the current TLS 1.3 implementation. I
> created a ticket[1] to document your concerns and capture a few
> potential ways to improve things.
>
> [1] https://bugs.openjdk.java.net/browse/JDK-8209953

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


SSLSocket session resumption not working with TLS 1.3 and 11+27

2018-08-23 Thread Simone Bordet
Hi,

The code below reproduces a bug where session resumption is tested.
Turns out that session resumption does happen on the client and on the
server, but on the client the session id is not replaced with the
resumed session id (while it is on the server).

The code prints:

session1 = Session(1535051727187|TLS_AES_128_GCM_SHA256) - [29, -38, ...]
session2 = Session(1535051727187|TLS_AES_128_GCM_SHA256) - [11, -20, ...]

where it can be seen that the second session has the same creationTime
as the first, but different session id (the array).

About the code below, note how it is necessary to attempt a read after
the first handshake to read the NewSessionTicket post-handshake
message that is otherwise not consumed by the client. This was not
necessary before.
Scenarios where clients don't read from the server (or where many
clients are created before one starts reading) will have a harder time
to use session resumption.

Thanks!



public static void main(String[] args) throws Exception
{
String host = "localhost";
int port = 8443;

SSLContext serverSSLContext = ...;
SSLServerSocket sslServer =
(SSLServerSocket)serverSSLContext.getServerSocketFactory().createServerSocket(port);
Runnable serverReader = () ->
{
try
{
SSLSocket sslSocket = (SSLSocket)sslServer.accept();
InputStream input = sslSocket.getInputStream();
while (true)
{
int read = input.read();
if (read < 0)
break;
}
}
catch (Throwable x)
{
x.printStackTrace();
}
};
new Thread(serverReader).start();

SSLContext clientSSLContext = ...;

Socket client1 = new Socket(host, port);
SSLSocket sslClient1 =
(SSLSocket)clientSSLContext.getSocketFactory().createSocket(client1,
host, port, true);
AtomicReference session1 = new AtomicReference<>();
CountDownLatch handshakeLatch1 = new CountDownLatch(1);
sslClient1.addHandshakeCompletedListener(event ->
{
SSLSession session = event.getSession();
session1.set(session.toString() + " - " +
Arrays.toString(session.getId()));
handshakeLatch1.countDown();
});

sslClient1.startHandshake();
handshakeLatch1.await(1, TimeUnit.SECONDS);
try
{
sslClient1.setSoTimeout(1000);
sslClient1.getInputStream().read();
}
catch (SocketTimeoutException expected)
{
}

sslClient1.close();

new Thread(serverReader).start();

Socket client2 = new Socket(host, port);
SSLSocket sslClient2 =
(SSLSocket)clientSSLContext.getSocketFactory().createSocket(client2,
host, port, true);
AtomicReference session2 = new AtomicReference<>();
CountDownLatch handshakeLatch2 = new CountDownLatch(1);
sslClient2.addHandshakeCompletedListener(event ->
{
SSLSession session = event.getSession();
session2.set(session.toString() + " - " +
Arrays.toString(session.getId()));
handshakeLatch2.countDown();
});

sslClient2.startHandshake();
handshakeLatch2.await(1, TimeUnit.SECONDS);

System.err.println("session1 = " + session1);
System.err.println("session2 = " + session2);

sslClient2.close();
}

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


SSLSocket weird behavior in JDK 11+27

2018-08-23 Thread Simone Bordet
Hi,

SSLSocket is behaving weird in 11+27.
In particular:

* Setup a SSLServerSocket.
* Connect with a normal Socket (rawClient).
* Wrap rawClient into a SSLSocket (sslClient).
* sslClient.startHandshake()

Now a few cases:

A) immediate rawClient.close()
If the server is reading via InputStream.read(), then it reads -1.
But if the server reads via InputStream.read(byte[]), then
SSLProtocolException is thrown.
I believe the second behavior is correct, as the client does not send
the close_notify, so the server should throw?

B) sslClient writes data + rawClient.close()
The server reads correctly the data, then reads -1, both with read()
and read(byte[]).
I believe this is wrong as close_notify is not sent by the client.

Running the example with JDK 10 always produces no exceptions and
always reads -1.

Below you can find a reproducible case.

Thanks!



public static void main(String[] args) throws Exception
{
SSLContext sslContext = __sslCtxFactory.getSslContext();
int port = 8443;
try (SSLServerSocket sslServer =
(SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket(port))
{
Socket rawClient = new Socket("localhost", port);
SSLSocket sslClient =
(SSLSocket)sslContext.getSocketFactory().createSocket(rawClient,
"localhost", port, false);

SSLSocket socket = (SSLSocket)sslServer.accept();

CountDownLatch latch = new CountDownLatch(1);
new Thread(() ->
{
try
{
while (true)
{
//byte[] buffer = new byte[1024];
//int read = socket.getInputStream().read(buffer);
int read = socket.getInputStream().read();
System.err.println("read = " + read);
if (read < 0)
break;
}
}
catch (IOException x)
{
x.printStackTrace();
}
finally
{
latch.countDown();
}
}).start();

sslClient.startHandshake();

//OutputStream output = sslClient.getOutputStream();
//output.write(0);
//output.flush();

// Raw close.
rawClient.close();

latch.await(10, TimeUnit.SECONDS);
}
}

-- 
Simone Bordet

http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.


Re: SSLEngine weird behavior in 11+21?

2018-08-22 Thread Simone Bordet
Hi,

> > On 7/12/2018 1:17 PM, Simone Bordet wrote:
> > Currently:
> > - Server wraps 160, 6 and 907 in 3 wraps.
> > - Server *sends* the 1073 bytes in 1 TCP write
> > - Client unwraps 160, then goes into NEED_WRAP
> > - Client wraps 6, then goes again into NEED_UNWRAP to finish with the
> > 6 and 907 received by the server.
> >
> > What I'm suggesting:
> > - Server wraps 160, 6 and 907 in 3 wraps.
> > - Server *sends* the 1073 (160+6+907) bytes in 1 TCP write
> > - Client unwraps 160, stays in NEED_UNWRAP, unwraps the 6, unwraps the
> > 907, then goes into NEED_WRAP
> > - Client wraps 6 and 58
> > - Client *sends* the 64 (6+58) bytes in 1 TCP write.
> >
> > The 6 bytes of the dummy change_cipher_spec are *sent* just after
> > receiving the ServerHello in both cases, they are just *generated* at
> > different times.
> >
> > By having all the unwraps() consecutive and all the wraps()
> > consecutive you can enable a number of optimizations I described
> > earlier.
> >
> > Imagine a client that would perform a TCP *send* every time the state
> > moves away from NEED_WRAP.
> > Currently it would:
> > 1. TCP send for ClientHello
> > 2. Reads 1073 from server
> > 3. Unwrap 160, then NEED_WRAP
> > 4. Generate 6, then NEED_UNWRAP
> > 5. TCP send the 6 bytes
> > 6. Unwrap 6 and 907, then NEED_WRAP
> > 7. Generate 58 then FINISHED
> > 8 TCP send the 58 bytes.
> >
> > You can see that the client issues 3 TCP sends.
> >
> > With what I am suggesting, the client would only issue 2 TCP sends,
> > which seems more in line with the efforts in TLS 1.3 to be more
> > efficient.
> >
> > It would just be a matter of *generating* those 6 bytes a bit later,
> > *after* having fully unwrapped the ServerHello.
> >
> On Fri, Jul 13, 2018 at 3:45 PM Xuelei Fan  wrote:
> It's a good idea!

I just built:

$ hg id -i
76072a077ee1

and I can still see the (very) inefficient behavior above.
Are there plans to fix it?

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: SSLEngine weird behavior in 11+21?

2018-08-01 Thread Simone Bordet
Hi,

On Tue, Jul 31, 2018 at 9:56 PM Xuelei Fan  wrote:
> Hm, I see your point.  Because of the half-close policy, I think the
> server could keep sending messages other than the close_notify alert.

Exactly.

> My concern of the CLOSED+NOT_HANDSHAKING is that it does not indicate
> the following operations.

Sure it does. CLOSED while unwrapping tells the application that the
other side has closed.
Now the application has a choice: it can wrap() more data, or call
closeOutbound().
>From there, it follows SSLEngine instructions via the states.
Having to take into consideration not only the Result, not only the
HandshakeStatus, but also bytes produced seems weird to me.
I'd prefer to just rely only on Result and HandshakeStatus.

> Yes, but it is the desired behavior to me.  For the TLS 1.3 half close
> policy, it is not expected to generate close_notify reply unless the
> server close its outbound.  So the server can keep sending the
> application data after the read close, as it write side is open.

Exactly.

> The TLS 1.3 spec says:
>"Each party MUST send a "close_notify" alert before closing its write
> side of the connection, unless it has already sent some error alert.
> This does not have any effect on its read side of the connection."
>
> And the SSLEngine.closeOutbound() spec says:
> "Signals that no more outbound application data will be sent on
>  this SSLEngine."
>
> I think it is fine to keep the write side open while the read side closed.
>
> In this update, for TLS 1.2 connection, the duplex-close behavior is
> reserved: as the server received the close_notify, it moving to
> NEED_WRAP; and the a close_notify will be delivered, and then duplex
> close the connection.

Exactly, and without the need for the receiver of the close_notify to
call closeOutbound().
That will be a difference between TLS 1.2 and TLS 1.3 that
applications should take into consideration.

> However, for TLS 1.3 connection, if there is no call to
> server.closeOutbound(), the server write side keeps open even the read
> side has been closed.
>
> In this update, for TLS 1.3, I tried to support half-close for:
> 1. SSLEngine.closeIn/Outbound()
> 2. SSLSocket.shutdownIn/Output()
>
> and duplex-close for:
> 3. SSLSocket.close()
>
> Unfortunately, it does introduce a compatibility issue that an existing
> application may not close both inbound and outbound if the connection is
> desired to be duplex-closed.  In order to mitigate the impact, a new
> System Property in introduced, "jdk.tls.acknowledgeCloseNotify".  This
> compatibility issues could be mitigated by closing both inbound and
> outbound explicitly, or set the property to "true".  If the property
> value is "true", a corresponding close_notify alert will be sent when
> receiving a close_notify alert, and therefore the connection will be
> duplex closed.
>
> Does it make sense to you?

Yes.

Although I think application will need to make adjustments for TLS 1.3 anyway.
That system property will smooth things, but won't guarantee that an
application written for SSLEngine TLS 1.2 will work for SSLEngine TLS
1.3.

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: SSLEngine weird behavior in 11+21?

2018-07-31 Thread Simone Bordet
Hi,

On Tue, Jul 31, 2018 at 5:10 PM Xuelei Fan  wrote:
>
> Hi,
>
> On 7/31/2018 6:43 AM, Xuelei Fan wrote:
> > Current jdk11 tip with your patch:
> > 1. client.closeOutbound() then goes into NEED_WRAP.
> > 2. Client wraps 24 bytes, result is CLOSED, then goes into NEED_UNWRAP.
> > 3. Server unwraps 24 bytes, result is CLOSED, then goes into NEED_WRAP.
> > 4. Server wraps 0 bytes and stays in NEED_WRAP (?)
>
> In my testing (OpenJDK,
> test/jdk/javax/net/ssl/TLSv1/TLSEnginesClosureTest.java), for #4, the
> server could wrap the close_notify alert message for TLS 1.2 and prior
> versions (CLOSED/NOT_HANDSHAKING); and wrap data for TLS 1.3
> (OK/NOT_HANDSHAKING, half-close).
>
> Are you using TLS 1.3 with no data in your test case in #4?  Because of
> the half-close policy,  it may be the expected behavior if no
> application data can be delivered.

The problem with 4 between TLS 1.2 and your latest patch is that
before there was no need to call server.closeOutbound(): as the server
received the close_notify from the client, it was moving to NEED_WRAP
and if wrap() was called it would generate the close_notify reply.
With your latest patch, you _have_ to call server.closeOutbound()
otherwise 4 will always generate 0 bytes and spin loop.

That is why I prefer 2 to go into CLOSED+NOT_HANDSHAKING.
When it goes into CLOSE+NEED_UNWRAP, the application will follow the
instructions of SSLEngine and attempt an unwrap() immediately, while
instead it should stop wrapping/unwrapping and write the close_notify
to the server.

> For TLS 1.3
> 
> Trying to close engines from Client to Server
> Client wrapped 24 bytes.
> Client handshake status is NEED_UNWRAP Result is CLOSED
> Server unwrapping 24 bytes...
> Server handshake status is NEED_WRAP Result is CLOSED
> Server wrapped 16406 bytes.
> Server handshake status is NEED_WRAP Result is OK
> 

The above tells me that the server did not generate yet the
close_notify reply because it is still in NEED_WRAP.
Just to repeat myself I would prefer this:

> Client called closeOutbound() status is NEED_WRAP
> Client wrapped 24 bytes.
> Client handshake status is NOT_HANDSHAKING Result is CLOSED
> Server unwrapping 24 bytes...
> Server handshake status is NOT_HANDSHAKING Result is CLOSED
> Server wrapped 16406 bytes.
> Server handshake status is NOT_HANDSHAKING Result is OK
> Server called closeOutbound() status is NEED_WRAP
> Server wraps 24 bytes
> Server handshake status is NOT_HANDSHAKING Result is CLOSED

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: SSLEngine weird behavior in 11+21?

2018-07-31 Thread Simone Bordet
Hi,
On Tue, Jul 31, 2018 at 4:13 PM Xuelei Fan  wrote:
>
> The Status.CLOSED specification is defined as "The operation just closed
> this side of the SSLEngine, or the operation could not be completed
> because it was already closed.".   My reading of the spec, the CLOSED
> status means half-close.   If wrap() status is CLOSED, it means write
> side close; and unwrap() CLOSED is for read side close.
>
> I may prefer to:
> 1. client.closeOutbound() then goes into NEED_WRAP.
> 2. Client wraps 24 bytes, result is CLOSED, then goes into NEED_UNWRAP.
> 3. Server unwraps 24 bytes, result is CLOSED, then goes into NEED_WRAP.
> 4. server.closeOutbound() then goes into NEED_WRAP.
> 5. Server wraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING.
> 6. Client unwraps 24 bytes, result is CLOSED, then goes into
> NOT_HANDSHAKING.

Yes, we agreed that at step 2 and especially step 3 result must be CLOSED.

Please consider the case where data is sent before the close_notify
reply, and what would be good for you.

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: SSLEngine weird behavior in 11+21?

2018-07-31 Thread Simone Bordet
Hi,

On Tue, Jul 31, 2018 at 3:43 PM Xuelei Fan  wrote:
> > 1. client.closeOutbound() then goes into NEED_WRAP.
> > 2. Client wraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING.
> It might be a problem for application to make a right decision if using
> CLOSED status and NOT_HANDSHAKING handshake status together.
>
> As the write side is close, the client now only be able to receiving
> data from peer.  I think NEED_UNWRAP may be more appropriate for
> application development.

I think the key point here is that SSLEngine tells the application
what needs to be done.
Because you implemented half-close, NEED_UNWRAP is not _strictly_ needed here.
By staying in NOT_HANDSHAKING the normal flow will happen: data to
read from the server, pass to unwrap(), it may be data or
close_notify.
Let's imagine it is data; after unwrapping data, do you stay in
NEED_UNWRAP until the close_notify arrives?

I'm fine with either NOT_HANSHAKING or NEED_UNWRAP, but I prefer
NOT_HANDSHAKING.

> However, the CLOSED status may be confusing as the client may still want
> to read something later.
>
> I may prefer to use OK/NEED_UNWRAP.  What do you think?

I prefer CLOSED/NOT_HANDSHAKING, but OK/NEED_UNWRAP works too.

> > 3. Server unwraps 24 bytes, result is CLOSED, then goes into 
> > NOT_HANDSHAKING.
> Same reason as above, I may prefer to use OK/NEED_WRAP.

Here I strongly disagree.
It is fundamental for the application to know that it received the
close_notify from the client, because the application needs to call
closeOutbound(), eventually.
The CLOSED result is the only thing that tells the application to call
closeOutbound().
I think this is also good for backwards compatibility: with TLS 1.2 I
bet most application were relying on the CLOSED state.

I prefer CLOSED/NOT_HANDSHAKING; CLOSED/NEED_WRAP is ok too.

> > 4. server.closeOutbound() then goes into NEED_WRAP.
> > 5. Server wraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING.
> > 6. Client unwraps 24 bytes, result is CLOSED, then goes into 
> > NOT_HANDSHAKING.
> >
> Agreed.
>
> If no objections, I will make the update:
>
> 1. client.closeOutbound() then goes into NEED_WRAP.
> 2. Client wraps 24 bytes, result is OK, then goes into NEED_UNWRAP.
> 3. Server unwraps 24 bytes, result is OK, then goes into NEED_WRAP.

Nope: CLOSED, then NEED_WRAP, see above.

> 4. server.closeOutbound() then goes into NEED_WRAP.
> 5. Server wraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING.
> 6. Client unwraps 24 bytes, result is CLOSED, then goes into
> NOT_HANDSHAKING.

Let's make another case with data, and what I prefer:

1. client.closeOutbound() then goes into NEED_WRAP.
2. Client wraps 24 bytes, result is OK, then goes into NOT_HANDSHAKING.
3. Server unwraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING.
4. Server wraps data bytes, result is OK, stays in NOT_HANDSHAKING.
5. Client unwraps data bytes result is OK, stays in NOT_HANDSHAKING.
6. server.closeOutbound() then goes into NEED_WRAP.
7. Server wraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING.
8. Client unwraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING.

I'm fine for 2 and 5 to be NEED_UNWRAP; I'm fine for 3 and 4 to be NEED_WRAP.

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: SSLEngine weird behavior in 11+21?

2018-07-31 Thread Simone Bordet
Hi,

On Tue, Jul 31, 2018 at 11:39 AM Simone Bordet  wrote:
>
> Hi,
> On Mon, Jul 30, 2018 at 8:08 PM Xuelei Fan  wrote:
> > Would you mind look at the code I posted in the following thread:
> > http://mail.openjdk.java.net/pipermail/security-dev/2018-July/017708.html
>
> JDK 11+21:
> 1. client.closeOutbound() then goes into NEED_WRAP.
> 2. Client wraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING (?)
> 3. Server unwraps 24 bytes, result is CLOSED, then goes into NEED_WRAP.
> 4. Server wraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING.
> 5. Client unwraps 0 bytes (?)
>
> Current jdk11 tip with your patch:
> 1. client.closeOutbound() then goes into NEED_WRAP.
> 2. Client wraps 24 bytes, result is CLOSED, then goes into NEED_UNWRAP.
> 3. Server unwraps 24 bytes, result is CLOSED, then goes into NEED_WRAP.
> 4. Server wraps 0 bytes and stays in NEED_WRAP (?)
>
> I don't think this is right.
>
> While I previously complained about step 2 going into NOT_HANDSHAKING,
> if you now support full half close, then I think this may be
> reasonable, as the server may still send data and only later issue a
> close_notify.
> However, NEED_UNWRAP like it is now is also reasonable.
>
> At step 3, after the server unwraps the close_notify, the server
> should either stay in NOT_HANDSHAKING *and* require a call to
> closeOutbound() (which will move the state to NEED_WRAP), or it should
> go into NEED_WRAP *and* produce the close_notify.
> As it is now, SSLEngine tells the application to wrap(), but it wraps
> 0 bytes, but tells again the application to wrap(), but still produces
> 0 bytes, so it's going to be a tight spin loop - not good.

For completeness, calling server.closeOutbound() at step 4. correctly
moves SSLEngine into NEED_WRAP and a subsequent wrap() produces the 24
bytes of the close_notify and result CLOSED, then goes into
NOT_HANDSHAKING.

I think the current behavior (with your patch) needs to be fixed.
Since you implemented half-close, my preference would be this:

1. client.closeOutbound() then goes into NEED_WRAP.
2. Client wraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING.
3. Server unwraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING.
4. server.closeOutbound() then goes into NEED_WRAP.
5. Server wraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING.
6. Client unwraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING.

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: SSLEngine weird behavior in 11+21?

2018-07-31 Thread Simone Bordet
Hi,
On Mon, Jul 30, 2018 at 8:08 PM Xuelei Fan  wrote:
> Would you mind look at the code I posted in the following thread:
> http://mail.openjdk.java.net/pipermail/security-dev/2018-July/017708.html

JDK 11+21:
1. client.closeOutbound() then goes into NEED_WRAP.
2. Client wraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING (?)
3. Server unwraps 24 bytes, result is CLOSED, then goes into NEED_WRAP.
4. Server wraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING.
5. Client unwraps 0 bytes (?)

Current jdk11 tip with your patch:
1. client.closeOutbound() then goes into NEED_WRAP.
2. Client wraps 24 bytes, result is CLOSED, then goes into NEED_UNWRAP.
3. Server unwraps 24 bytes, result is CLOSED, then goes into NEED_WRAP.
4. Server wraps 0 bytes and stays in NEED_WRAP (?)

I don't think this is right.

While I previously complained about step 2 going into NOT_HANDSHAKING,
if you now support full half close, then I think this may be
reasonable, as the server may still send data and only later issue a
close_notify.
However, NEED_UNWRAP like it is now is also reasonable.

At step 3, after the server unwraps the close_notify, the server
should either stay in NOT_HANDSHAKING *and* require a call to
closeOutbound() (which will move the state to NEED_WRAP), or it should
go into NEED_WRAP *and* produce the close_notify.
As it is now, SSLEngine tells the application to wrap(), but it wraps
0 bytes, but tells again the application to wrap(), but still produces
0 bytes, so it's going to be a tight spin loop - not good.

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: SSLEngine weird behavior in 11+21?

2018-07-13 Thread Simone Bordet
Hi,

On Fri, Jul 13, 2018 at 3:45 PM Xuelei Fan  wrote:
> Thank you very much, Simone.  I find at least two improvements we can
> take.  It's really good!

Great!

Let know when they land in a 11+X release and we'll try them out.

Thanks!
-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: SSLEngine weird behavior in 11+21?

2018-07-12 Thread Simone Bordet
Hi,

On Thu, Jul 12, 2018 at 11:10 PM Xuelei Fan  wrote:
> 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.

Even in TLS 1.2 you cannot be sure that the server will send the
close_notify (e.g. bad server).
The half close problem is present in TCP, WebSocket, etc. and it's
typically solved with (idle) timeouts.

Client sends the close_notify, then reads, hoping to see the
close_notify from the server; if it does not see it, it closes the raw
socket after a timeout.
The timeout could account for receiving data (i.e. it is reset if
application data arrives), or not.

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: SSLEngine weird behavior in 11+21?

2018-07-12 Thread Simone Bordet
Hi,

On Thu, Jul 12, 2018 at 11:15 PM Xuelei Fan  wrote:
>
> On 7/12/2018 1:09 PM, Simone Bordet wrote:
> > Hi,
> > On Thu, Jul 12, 2018 at 10:05 PM David Lloyd  wrote:
> >> But more importantly, I think this
> >> represents a chance to fix this long-standing bad behavior of the JDK.
> >
> > Indeed!
> >
> > Another thing I was about to complain is that
> > SSLSocket.shutdownOutput() still throws:
> > UnsupportedOperationException("The method shutdownOutput() is not
> > supported in SSLSocket");
> >
> This happens before JDK 11 B20, right?

No, it still happens on 11+21.

Cheers

-- 
Simone Bordet

http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.


Re: SSLEngine weird behavior in 11+21?

2018-07-12 Thread Simone Bordet
Hi,

On Thu, Jul 12, 2018 at 9:29 PM Xuelei Fan  wrote:
> Per the TLS 1.3 specification:
>-  The server sends a dummy change_cipher_spec record immediately
>   after its first handshake message.  This may either be after a
>   ServerHello or a HelloRetryRequest.
>
> and
>-  If not offering early data, the client sends a dummy
>   change_cipher_spec record (see the third paragraph of Section 5.1)
>   immediately before its second flight.  This may either be before
>   its second ClientHello or before its encrypted handshake flight.
>   If offering early data, the record is placed immediately after the
>   first ClientHello.
>
> My read of the spec is that the dummy change_cipher_spec record is
> generated immediately after the ServerHello in server side, and before
> the 2nd flight in client side.

The spec is about *sending*, while I'm about *generating*.

Currently:
- Server wraps 160, 6 and 907 in 3 wraps.
- Server *sends* the 1073 bytes in 1 TCP write
- Client unwraps 160, then goes into NEED_WRAP
- Client wraps 6, then goes again into NEED_UNWRAP to finish with the
6 and 907 received by the server.

What I'm suggesting:
- Server wraps 160, 6 and 907 in 3 wraps.
- Server *sends* the 1073 (160+6+907) bytes in 1 TCP write
- Client unwraps 160, stays in NEED_UNWRAP, unwraps the 6, unwraps the
907, then goes into NEED_WRAP
- Client wraps 6 and 58
- Client *sends* the 64 (6+58) bytes in 1 TCP write.

The 6 bytes of the dummy change_cipher_spec are *sent* just after
receiving the ServerHello in both cases, they are just *generated* at
different times.

By having all the unwraps() consecutive and all the wraps()
consecutive you can enable a number of optimizations I described
earlier.

Imagine a client that would perform a TCP *send* every time the state
moves away from NEED_WRAP.
Currently it would:
1. TCP send for ClientHello
2. Reads 1073 from server
3. Unwrap 160, then NEED_WRAP
4. Generate 6, then NEED_UNWRAP
5. TCP send the 6 bytes
6. Unwrap 6 and 907, then NEED_WRAP
7. Generate 58 then FINISHED
8 TCP send the 58 bytes.

You can see that the client issues 3 TCP sends.

With what I am suggesting, the client would only issue 2 TCP sends,
which seems more in line with the efforts in TLS 1.3 to be more
efficient.

It would just be a matter of *generating* those 6 bytes a bit later,
*after* having fully unwrapped the ServerHello.

> We may consider a option to turn off the middlebox compatibility mode if
> it helps Jetty.

No need to.

> But the implementation code and the application should
> be ready to accept the fact that third party's implementation may be
> implemented in middlebox compatibility mode, and the change_cipher_spec
> record may still come in.

See above, it's not about processing the dummy change_cipher_spec,
it's just about generating it a little later.

> After #7 (FINISHED), if the client only send application data, but never
> call read again, it still works, right?  The application don't have to
> read something, I think.

Sure, it just can't take advantage of session resumption though.
The client never knows that there are post-handshake messages to read
because SSLEgine did not tell.
SSLEngine just said FINISHED and NOT_HANDSHAKING.

However, I see your point. Handshake messages could come at any time,
just that this one seems more part of the initial handshake,
especially if it's about session resumption.

> in #10, you said, "Client MUST unwrap ...".  Do you mean that the client
> cannot send application data without read/unwrap something?

It can send data, but won't be good to leave unprocessed bytes around.
The application would not know that there is stuff to read from the
network and to process as post-handshake messages.
It may never read from the network again.

> Half-close means that the server may not send the close_notify when it
> receive the client close_notify.  It's a very tricky policy.  The client
> close_notify only means the client want to close its writing side.  The
> server may not send the close_notify if it doesn't want to close.  If we
> have the client goes into NEED_UNWRAP, there is a potential dead waiting.

Good point.

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: SSLEngine weird behavior in 11+21?

2018-07-12 Thread Simone Bordet
Hi,
On Thu, Jul 12, 2018 at 10:05 PM David Lloyd  wrote:
> But more importantly, I think this
> represents a chance to fix this long-standing bad behavior of the JDK.

Indeed!

Another thing I was about to complain is that
SSLSocket.shutdownOutput() still throws:
UnsupportedOperationException("The method shutdownOutput() is not
supported in SSLSocket");

Thanks!

-- 
Simone Bordet

http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.


Re: SSLEngine weird behavior in 11+21?

2018-07-12 Thread Simone Bordet
this point, my gut feeling is that having a single codebase
handling TLS 1.2 and TLS 1.3 would be difficult.
I expect a few "if (tls > 1.2)" spread out in the code because now we
need additional information that we did not need before because
SSLEngine and its state machine was telling the application what next
step was required but now it's not always the case anymore.

I know that other SSLEngine users for widely used Java network servers
are around in this list :)
Would be great if they can feedback about whether JDK's SSLEngine with
TLS 1.3 is working well for them.

Thanks!

--
Simone Bordet

http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.


Re: SSLEngine weird behavior in 11+21?

2018-07-12 Thread Simone Bordet
Hi,

On Thu, Jul 12, 2018 at 12:06 AM Simone Bordet  wrote:
>
> Hi,
>
> I can see this (weird) behavior in SSLEngine for TLS 1.3 in JDK 11+21.
> It's a simple new connection (no resumption) that performs a TLS 1.3 
> handshake.
> The bytes numbers are those that I get, they may be different for
> others depending on certificate size, etc.
>
> 1. Client wraps 394 bytes then goes into NEED_UNWRAP.
> 2. Server unwraps 394 bytes then goes into NEED_TASK and then into NEED_WRAP.
> 3. Server wraps (in 3 wraps) 160, 6 and 907 bytes then goes into NEED_UNWRAP.
> 4. Client unwraps 160 bytes then goes into NEED_TASK and then into NEED_WRAP 
> (?)
> 5. Client wraps 6 bytes, then goes into NEED_UNWRAP.
> 6. Client unwraps (in 2 unwraps) 6 and 907 bytes, then goes into
> NEED_TASK and then into NEED_WRAP.
> 7. Client wraps 58 bytes and goes into FINISHED (?)
> 8. Server unwraps (in 2 unwraps) 6 and 58 bytes then goes into NEED_WRAP.
> 9. Server wraps 72 bytes then goes into FINISHED.
> 10. Client MUST unwrap those 72 bytes going again into FINISHED (which
> already happened at 7).
>
> There are 2 things that I find weird:
>
> A) That at 4, the client goes into NEED_WRAP, even if it has not
> finished to unwrap what the server sent. Apparently, it only goes into
> NEED_WRAP to generate a CHANGE_CIPHER_SPEC (I am guessing from the
> number of bytes generated), but then goes back into NEED_UNWRAP to
> finish reading what the server sent. This is also not optimal as it
> forces applications to do something with those 6 bytes: either put
> them aside (additional data structures that may not be needed) or -
> worse - write them to the server causing an additional write (after
> all the effort TLS 1.3 put in to have a 1 RTT handshake).
> I think that step 4 should go into NEED_UNWRAP, and that step 5 and
> step 6 should be switched, so that the client would unwrap the 160, 6
> and 907 sent by the server, and only after wrapping the 6 and the 58.
> To be clear, the current behavior is (u==unwrap, w=wrap): u160, w6,
> u6, u907, w58.
> I think it should be: u160, u6, u907, w6, w58.
>
> Is there any reason that the 6 bytes needs to be generated in-between
> the processing of the frames sent by the server?
>
> B)That at 7 the client goes into FINISHED, but it is not finished
> really: in fact it needs to perform step 10, but there is no
> indication from the SSLEngine that it must do so.
> Currently, step 7 says the client is finished and there is no clue
> that it must unwrap those last 72 bytes.
> I think step 7 should go into NEED_UNWRAP instead, and only at 10 go
> into FINISHED.

In addition to what reported above, I would like to report also the
weird behavior during the close handshake (i.e. when one side decides
to close the connection).

1. client.closeOutbound() then goes into NEED_WRAP.
2. Client wraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING (?)
3. Server unwraps 24 bytes, result is CLOSED, then goes into NEED_WRAP.
4. Server wraps 24 bytes, result is CLOSED, then goes into NOT_HANDSHAKING.
5. Client unwraps 0 bytes (?)

I think at step 2 the client should go into NEED_UNWRAP to read (at
step 5) the server response to the close_notify.
Instead, at step 5 the client unwraps 0 bytes so we are left with
those 24 bytes from the server that applications need to discard.

Also, I am not sure that the wrap result at step 2 and 3 should be
CLOSED, perhaps OK is better?
The server is actually closed at step 4, and the client at step 5.
However, this is a minor issue.

Attached the debug logs as you requested.

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


sslengine.log.gz
Description: application/gzip


SSLEngine weird behavior in 11+21?

2018-07-11 Thread Simone Bordet
Hi,

I can see this (weird) behavior in SSLEngine for TLS 1.3 in JDK 11+21.
It's a simple new connection (no resumption) that performs a TLS 1.3 handshake.
The bytes numbers are those that I get, they may be different for
others depending on certificate size, etc.

1. Client wraps 394 bytes then goes into NEED_UNWRAP.
2. Server unwraps 394 bytes then goes into NEED_TASK and then into NEED_WRAP.
3. Server wraps (in 3 wraps) 160, 6 and 907 bytes then goes into NEED_UNWRAP.
4. Client unwraps 160 bytes then goes into NEED_TASK and then into NEED_WRAP (?)
5. Client wraps 6 bytes, then goes into NEED_UNWRAP.
6. Client unwraps (in 2 unwraps) 6 and 907 bytes, then goes into
NEED_TASK and then into NEED_WRAP.
7. Client wraps 58 bytes and goes into FINISHED (?)
8. Server unwraps (in 2 unwraps) 6 and 58 bytes then goes into NEED_WRAP.
9. Server wraps 72 bytes then goes into FINISHED.
10. Client MUST unwrap those 72 bytes going again into FINISHED (which
already happened at 7).

There are 2 things that I find weird:

A) That at 4, the client goes into NEED_WRAP, even if it has not
finished to unwrap what the server sent. Apparently, it only goes into
NEED_WRAP to generate a CHANGE_CIPHER_SPEC (I am guessing from the
number of bytes generated), but then goes back into NEED_UNWRAP to
finish reading what the server sent. This is also not optimal as it
forces applications to do something with those 6 bytes: either put
them aside (additional data structures that may not be needed) or -
worse - write them to the server causing an additional write (after
all the effort TLS 1.3 put in to have a 1 RTT handshake).
I think that step 4 should go into NEED_UNWRAP, and that step 5 and
step 6 should be switched, so that the client would unwrap the 160, 6
and 907 sent by the server, and only after wrapping the 6 and the 58.
To be clear, the current behavior is (u==unwrap, w=wrap): u160, w6,
u6, u907, w58.
I think it should be: u160, u6, u907, w6, w58.

Is there any reason that the 6 bytes needs to be generated in-between
the processing of the frames sent by the server?

B)That at 7 the client goes into FINISHED, but it is not finished
really: in fact it needs to perform step 10, but there is no
indication from the SSLEngine that it must do so.
Currently, step 7 says the client is finished and there is no clue
that it must unwrap those last 72 bytes.
I think step 7 should go into NEED_UNWRAP instead, and only at 10 go
into FINISHED.

Thanks!

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: JDK 11+21 SSLSocket.close() deadlock?

2018-07-11 Thread Simone Bordet
Hi,

On Wed, Jul 11, 2018 at 2:25 AM Xuelei Fan  wrote:
>
> Hi Simone,
>
> Thank you for reporting this issue.  Now it is tracked in JBS:
> https://bugs.openjdk.java.net/browse/JDK-8207004
>
> In the following stacks, only one lock (on 0xac) can be observed.  Can I
> understand that the read() is blocked, and then the close() is blocked
> as well?  Did you have a test that we can use to reproduce this issue?

Yes, it's pretty crude but reduces at minimum the dependencies.
You have to provide a valid sslContext variable, but that should be
done for your environment.

Looking at sun.security.ssl.SSLSocketImpl.close(), I see that it tries
to grab the lock for read and then for write.
While the test case below shows a problem for reads, I believe the
same problem can be shown when the SSLSocket is blocked in writes due
to TCP congestion, and some other thread tries to asynchronously
close() it.

Thanks!

public void testDeadlock() throws Exception
{
int port = 8899;
// TODO: provide a valid sslContext here.
SSLServerSocket acceptor =
(SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket(port);

Socket client = new Socket("localhost", port);

SSLSocket sslServer = (SSLSocket)acceptor.accept();

CompletableFuture.runAsync(() ->
{
try
{
sslServer.startHandshake();
}
catch (Throwable x)
{
x.printStackTrace();
}
});

// Wait for sslServer to start reading from the client.
Thread.sleep(1000);

// Hangs here.
sslServer.close();

    client.close();
}



-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


JDK 11+21 SSLSocket.close() deadlock?

2018-07-10 Thread Simone Bordet
Hi,

Please look at the stack traces below.

The server code accept() a SSLSocket, then calls startHandshake() in a
different thread.
The client code sends the TLS handshake bytes very slowly.
The server code waits for a bit for the handshake to finish, then
attempts to close the socket, but it cannot due to the deadlock below.
The client stops sending the TLS handshake bytes and now the server is
stuck forever.

I think invoking close() should wake up the read() with an exception,
rather than trying to grab the same lock held by the read, as
asynchronous closes from other threads happen all the times.

The issue does not happen with JDK 9, 10, 11-ea+18, but does happen
with 11-ea+21.

Thanks!

---

"main@1" prio=5 tid=0x1 nid=NA waiting for monitor entry
  java.lang.Thread.State: BLOCKED
waiting for pool-1-thread-1@2224 to release lock on <0xac7> (a
sun.security.ssl.SSLSocketImpl)
  at sun.security.ssl.SSLSocketImpl.close(SSLSocketImpl.java:447)

"pool-1-thread-1@2224" prio=5 tid=0x19 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
blocks main@1
  at java.net.SocketInputStream.socketRead0(SocketInputStream.java:-1)
  at java.net.SocketInputStream.socketRead(SocketInputStream.java:115)
  at java.net.SocketInputStream.read(SocketInputStream.java:168)
  at java.net.SocketInputStream.read(SocketInputStream.java:140)
  at sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:464)
  at sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:167)
  at sun.security.ssl.SSLTransport.decode(SSLTransport.java:108)
  at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:877)
  at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:810)
  - locked <0xac7> (a sun.security.ssl.SSLSocketImpl)
  at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:383)

-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Feedback on SSLEngine.setHandshakeApplicationProtocolSelector()

2017-01-12 Thread Simone Bordet
Hi,

On Wed, Jan 11, 2017 at 5:57 PM, Simone Bordet <simone.bor...@gmail.com> wrote:
> Hi,
>
> I just wanted to report that I have implemented the new mechanism
> provided by SSLEngine.setHandshakeApplicationProtocolSelector() in
> Jetty, and it works well in a much much simpler way.
>
> The amount of code required now is trivial (a couple of lines), there
> is no need to parse the ClientHello, and we basically tap into the
> existing mechanism that Jetty had.
> No big surprises here since the new JDK mechanism is very similar to
> what Jetty has for JDK 8.

For the record, I have implemented also the client-side mechanism
using the JDK 9 APIs.
Looks simple enough and works fine.

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Feedback on SSLEngine.setHandshakeApplicationProtocolSelector()

2017-01-11 Thread Simone Bordet
Hi,

I just wanted to report that I have implemented the new mechanism
provided by SSLEngine.setHandshakeApplicationProtocolSelector() in
Jetty, and it works well in a much much simpler way.

The amount of code required now is trivial (a couple of lines), there
is no need to parse the ClientHello, and we basically tap into the
existing mechanism that Jetty had.
No big surprises here since the new JDK mechanism is very similar to
what Jetty has for JDK 8.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS-PSK status ?

2017-01-03 Thread Simone Bordet
Hi,

On Tue, Jan 3, 2017 at 6:50 PM, Xuelei Fan <xuelei@oracle.com> wrote:
> Now JDK-8049402 is public.
>
> https://bugs.openjdk.java.net/browse/JDK-8049402

Thanks !

The issue is marked as "fix for 10", so is it correct to assume that
nothing will be done in time for JDK 9 or even 8 (via backport) ?
It is just to know and to respond to people that asked about
supporting TLS-PSK support.

Thanks again !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


TLS-PSK status ?

2017-01-02 Thread Simone Bordet
Hi,

https://bugs.openjdk.java.net/browse/JDK-6476446

is closed as a duplicate of JDK-8049402, but unfortunately this latter
issue is not public.

Is there any status about the implementation of TLS-PSK (RFC 4279, 4785, 5489) ?

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: [9] RFR 8171443: (spec) An ALPN callback function may also ignore ALPN

2016-12-22 Thread Simone Bordet
Vincent,

On Thu, Dec 22, 2016 at 11:38 AM, Vincent Ryan
<vincent.x.r...@oracle.com> wrote:
> Please review this spec change to allow an ALPN callback function to also 
> disable ALPN usage
> and return no ALPN extension value during a TLS handshake.

As I understand it, the callback needs to convey 3 results:
1. a success -> non empty string
2. a failure -> null
3. no action -> empty string

I wonder if it is better to convey the failure by throwing an exception ?
This would also match the case where the implementation of the
function, for any reason, throws an unexpected exception such as NPE
or ClassCastException, etc.
I expect the SSLEngine implementation to catch Throwable from the
invocation of the callback and send back a TLS close message with code
120.

If the failure case is conveyed with an exception, then only 2 cases
remain, and then null can be used to signal "no action" ?

The SSLEngine implementation should also check that the String
returned is among those sent by the other peer, so an empty string is
as invalid as the string "no_proto" - hence the choice of null to
signal "no action".

Makes sense ?

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: [9] RFR 8170282: Enable ALPN parameters to be supplied during the TLS handshake

2016-12-09 Thread Simone Bordet
Hi,

On Fri, Dec 9, 2016 at 3:09 AM, David M. Lloyd <david.ll...@redhat.com> wrote:
> On 12/08/2016 07:34 PM, Bradford Wetmore wrote:
>>
>> Hi,
>>
>> Vinnie wrote:
>>>
>>> We understood when we examined these issues last year that the
>>> existing ALPN API would be sufficient. However it transpired,
>>> following HTTP2 server implementation efforts, that a particular
>>> use-case was difficult to address without sacrificing performance.
>>
>>
>> A few more details.
>>
>> The discussion/decisions we had last year ended with requiring servers
>> to inspect ClientHellos for the client's max TLS
>> protocol/ciphersuites/SNI/ALPNs/etc, and then do any necessary
>> configuration before actually starting the SSL/TLS/DTLS handshake on the
>> server side.  That included enabling specific SSL/TLS/DTLS protocols,
>> ordering the ciphersuites (calling
>> SSLParameters.setUseCipherSuitesOrder()) and ordering the ALPN values.
>> If it turned out that the resulting selected combination was incorrect,
>
>
> How could it turn out to be incorrect, when you know in advance what
> credentials you have, what cipher suites are available, and what protocols
> support which cipher suites?

If any logic you would run is different from JDK's, then the result
may be incorrect.
Say it another way, you run an old version of your code in a new JDK
version: the logic that was ok long time ago may not be the same years
later, and you get different results.

> I'm just curious because I'm pretty sure we
> haven't encountered this (I'll ask our web server folks to be sure though).

That would be helpful. Apart us (Jetty), nobody has actually
implemented ALPN using the new JDK9 API yet, as far as I know.

> Also I'd hate to see a worst-case situation where a this API was introduced
> (which is very reminiscent of ideas which were rejected for good reasons),
> and it turns out that in the end it's not quite sufficient after all,
> leaving a bit of dead code around.

>From how I understand this change, the whole mechanism of parsing the
ClientHello, running your logic, running again the ClientHello parsing
and the JDK logic, resulting in calling the application callbacks (for
SNI for example) twice, checking that both logics yielded the same
result, and if not take recovery actions, stays there, if you want to
go that way. You don't have to use the new code.

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Issues with ALPN implementation in JDK 9

2016-06-15 Thread Simone Bordet
Hi,

On Wed, Jun 15, 2016 at 8:12 PM, Jason Greene <jason.gre...@redhat.com> wrote:
> Here is an H2 example:
>
> The ClientHello expressing interest in both h2, and h1, and lists the ciphers:
> TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
> TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
>
> So in this case the client is expressing a preference for a CBC cipher using 
> stronger keys, but is blacklisted by h2 due to not being GCM, but this is 
> allowed by h1. The JDK will follow the client hello as the TLS spec 
> describes, and so it will select TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, and 
> the protocol stack will incorrectly select h1.
>
> Now technically H2 clients can avoid this by ordering h2 compliant ciphers on 
> top, but they might not do so.
>
> The flaw really starts to show when you have multiple alternative protocols 
> with completely different requirements. As an example, if you have a 
> hypothetical protocol which does not perform certificate based 
> authentication, and instead utilizes pre-shared keys or anonymous ciphers, 
> that protocol can never be selected unless those algs are on the top of the 
> list, if they are on the top of the list then h2 can’t be selected.
>

I'm not sure what you want to show here.
If you want to prefer ciphers, you have to give up on protocol and
viceversa, that's normal business.

If there is no decision, then there is a conflict; if there is a
decision, then the solution I propose works equally well to what you
guys propose.

There is no "flaw", it is just undecidable.
What am I missing ?

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Issues with ALPN implementation in JDK 9

2016-06-15 Thread Simone Bordet
Hi,

On Wed, Jun 15, 2016 at 1:31 PM, David M. Lloyd <david.ll...@redhat.com> wrote:
> The problem is that this is quite subjective.  In my opinion the current
> solution is both clean and precise:
>
> 1) Read the hello packet
> 2) Examine the protocols, host names, and cipher suites
> 3) Apply arbitrary user policy to select the enabled cipher suites and even
> possibly the SSL context to use based on:
>* The above information
>* The supported cipher suites (for each SSL context, if multiple)
>* The available host key types for each host and/or protocol
>* Any user-driven factor that goes beyond *just* HTTP 2

Sure, that's the duplication of what the JDK does.
Change logic in the JDK, change logic above.

How do you avoid to run the application SNI logic twice, once by you,
and once by the JDK ?
What if that SNI logic, provided by an external application, has side effects ?

Your bullets above are "precise" only under the assumption that those
bullets are exactly what the JDK does.
If it's not the case, then they're broken.

I understand for you is not a big deal to replicate the JDK logic and
keeping it up to date, and banning certain versions of your code to
run with certain versions of the JDK.
I hope you understand it's not the case for others; for example, we
don't control with what JDK versions people run Jetty.

If JDK 10 changes the logic, we will have to say: "Oh, sorry, you
cannot run Jetty 9 (the current version) with JDK 10".
And we won't be able to change the logic in Jetty 9, because we would
break previous JDKs.
We will be back to sniffing what JDK it is. Yuck.

> No matter what the JDK does, it will not be able to encapsulate a completely
> arbitrary user policy - certainly not precisely - during handshake, nor will
> it be able to allow for the selection of different SSLContexts based on that
> policy (let alone proxying the connection).

Can you detail a case ?

> The best that can be done in the
> JDK, in my opinion, is to provide various utilities to simplify implementing
> the above: a helpful SSL explorer style class, which includes mapping the
> protocol and cipher suite list (which I believe we agree on) and perhaps
> providing information about the key type(s) supported by each cipher suite,
> so the user can compare this against the available key types.

Unfortunately this SSL Explorer class has not yet been provided.
If it was, it would be helpful. But I think it will just hit the same
problems I hit: logic duplication and running SNI twice.

> Once you know what cipher suites are offered, and you have selected the
> protocol, host, and enabled cipher suites, there isn't a great deal of
> mystery left in the JDK: it simply carries out the negotiation that you
> specified.

IFF your logic is the same as the JDK.

I don't want to check this every time a JDK release is made.
Why you enjoy doing this this check, it's a mystery to me :)

> I agree with 1 and 2, at least in concept if not in specifics, but I think 3 
> is a mistake:
> if you've committed to an SSL context then it's already too late to make some
> possibly important decisions, and SNI can play a factor here too.
> We can make this easier but I think that trying to do this all inside of the
> handshake process is going to cut off some important use cases.

Which use cases ?

BTW, the delay of handshaker.started=true would be irrelevant to the
TLS mechanism, it's just an implementation detail.
The information that needs to be reported in the ServerHello is only
needed when the ServerHello is being constructed.

Had the JDK implementation been written with a delayed
handshaker.started=true we would have the best of both worlds.
You could write your own solution, we could write our own.
Yours will have some restrictions, and so will ours (just different ones).

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Issues with ALPN implementation in JDK 9

2016-06-15 Thread Simone Bordet
Hi,

On Wed, Jun 15, 2016 at 10:15 AM, Andrew Haley <a...@redhat.com> wrote:
> The problem I have with reading posts about JDK9 problems is that I
> can't tell the *severity* of the problems.  I don't know if something
> is a total blocker or an inconvenience.  When someone uses an internal
> sun.* class they may be doing something which must be done in order to
> get access which would be impossible otherwise.

I don't understand this comment.

The main issue of this thread is the current impossibility to have a
clean and precise ALPN implementation with minimal code.
Sure we can fallback to less optimal solutions that won't work in all cases.
Sure we can duplicate the JDK logic and keep it up-to-date, invoke SNI
twice, etc.
But I don't see the point of settling for a less than optimal solution
when there is room to make it better, and the effort is minimal.

Is this issue a blocker ? Surely not, it is possible to rewrite from
scratch a JSSE provider.
Would I do that ? No, thanks.

I am proposing 3 simple changes to be done:

1) Introduce a TLSProtocolNames class that can convert from TLS
protocol bytes to TLS protocol names.
2) Introduce a TLSCipherSuiteNames class that can convert from TLS
cipher suite bytes to TLS cipher suite names.
3) Delay handshaker.started=true so that it would simpler and more
precise for an application to handle ALPN.

I think these changes will benefit all the people involved in network
servers having to play with ALPN.

We *are* still in time, according to Mark Reinhold.
The changes are simple.

We have not heard from Oracle yet, but I can prepare a webrev if that helps.

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Issues with ALPN implementation in JDK 9

2016-06-15 Thread Simone Bordet
Hi,

On Wed, Jun 15, 2016 at 10:03 AM, Andrew Haley <a...@redhat.com> wrote:
> On 14/06/16 14:57, Simone Bordet wrote:
>> * Lack of facilities to convert TLS protocol bytes to protocol strings.
>> This class already exist in JDK, sun.security.ssl.ProtocolVersion, it
>> would just need to be exposed in javax.net.ssl.
>>
>> * Lack of facilities to convert TLS cipher bytes to cipher name strings.
>> As above, sun.security.ssl.CipherSuite exists, needs to be exposed publicly.
>>
>> Note that for the 2 bullets above, a recent message from Mark Reinhold
>> to jdk9-dev confirmed that JDK 9 is *not yet* feature complete, so I
>> hope they can be considered for inclusion.
>
> It's very late,

It's not too late, like Mark Reinhold said.

> and they certainly won't be considered unless
> someone proposes it.

I just did.

>  But can't we simply clone this class anyway?

Sure, but then every ALPN implementer out there will have their own,
they will need to be kept up to date when a new TLS protocol or a new
cipher is introduced in the JDK, etc. etc.
The TLS ciphers in the JDK have non-standard names for historical reasons, etc.

The classes are trivial, and can be tiny wrappers around the existing
ones like TLSProtocolNames and CipherSuiteNames.

> Incidentally, I can't tell which (if any) of the issues you describe
> are specific to JDK 9 (i.e. they would not be problems in JDK 8.)

Not sure what you mean here.
Unless you parse the TLS protocol in JDK 8, there is no particular
need for those classes.
With JDK9 we now need to parse the TLS protocol to handle ALPN, so
those classes would be handy.

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Issues with ALPN implementation in JDK 9

2016-06-14 Thread Simone Bordet
Hi,

On Tue, Jun 14, 2016 at 8:11 PM, Jason Greene <jason.gre...@redhat.com> wrote:
> If the case is that H3 blacks all RSA, then thats an easy test right? Just 
> verify that keystore has an ECDSA key.

I don't think it is that easy.

The server logic has to mimic exactly what the JDK logic is, that is
to verify the cipher and certificate compatibility.
Not only, the server has to run the logic for SNI, the same logic that
the JDK runs to get the right certificate. This logic would now run
twice.

As I said, it is doable as long as the server logic duplicates and
keeps in sync with the JDK logic so that it is guaranteed that the
application protocol chosen by the server ends up with a cipher,
chosen by the JDK, valid for that protocol.
The moment the logic is different, there is a problem.

Every time the JDK updates, you and me have to go and look inside the
JDK to check whether the logic is changed, and if so, update our
servers.
And then we have to say that version X of our server only works with
JDKs up to version Y, and that version X+1 of our server only works
with JDK version Y+1.
Been there, done that. I'd like to move to a better model that is future proof.
I don't control which JDK people use to run Jetty.

I would rather not duplicate all the JDK logic into an application.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Issues with ALPN implementation in JDK 9

2016-06-14 Thread Simone Bordet
Hi,

On Tue, Jun 14, 2016 at 5:58 PM, Simone Bordet <simone.bor...@gmail.com> wrote:
> The server could choose an ECDSA cipher for h3, the mandatory cipher
> for h2, so the list of cipher is (ECDSA, RSA). If, at this point, the
> server chooses the protocol *before* the JDK chooses the cipher, it
> may think that h3 is a good choice, but the TLS stack chooses the RSA
> cipher.
> At this point, you have the h3 protocol with the RSA cipher, which may
> be an invalid combination.

Just to add more information here.

If the server logic chooses h3 and also restricts the ciphers to only
(ECDSA) to make sure that h3 is chosen, the JDK may find that the
cipher is not good for the certificate, and therefore there are no
ciphers in common and the connection is terminated. There is no
negotiation, although h2 with RSA would have been a valid combination.

If handshaker.started=true is delayed, the server could wait for the
JDK to choose a cipher, and then a suitable protocol for that cipher,
which in the example would be h2, and the negotiation would be
successful.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Issues with ALPN implementation in JDK 9

2016-06-14 Thread Simone Bordet
Hi,

On Tue, Jun 14, 2016 at 5:26 PM, Jason T. Greene
<jason.gre...@redhat.com> wrote:
> With H2 all impls are required to support 
> TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

Unless it is discovered vulnerable.

> so that should be selectable either by your protocol stack or the TLS layer.  
> If you wanted to be especially lazy you could just exclude any blacklisted 
> cipher list presented in the client hello,  and verify that additional ones 
> are present, and if so set the rest as the available cipher set in SSL 
> params. The TLS stack will pick appropriately at that point.

Not in general, see my example.
The server could choose an ECDSA cipher for h3, the mandatory cipher
for h2, so the list of cipher is (ECDSA, RSA). If, at this point, the
server chooses the protocol *before* the JDK chooses the cipher, it
may think that h3 is a good choice, but the TLS stack chooses the RSA
cipher.
At this point, you have the h3 protocol with the RSA cipher, which may
be an invalid combination.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Issues with ALPN implementation in JDK 9

2016-06-14 Thread Simone Bordet
Hi,

On Tue, Jun 14, 2016 at 4:31 PM, David M. Lloyd <david.ll...@redhat.com> wrote:
>> During the unwrap(), the JDK implementation picks a cipher based on
>> the JDK logic.
>> In particular, in my case, I had a keystore with a certificate that
>> was *not* ECDSA.
>
> Could you not use the available keys as an input into your own protocol
> selection?  Granted you have to know what kind of key works with what
> algorithm, but if you already have a table of cipher suites, you might as
> well just add it on there...

By "keys" here you mean, exactly ?

>> However, this means duplicating all the JDK logic to make sure that
>> the server logic *before* calling unwrap() is the same of the JDK so
>> that when unwrap() is called there will be no failures.
>
> I don't think you have to duplicate the exact logic though.  It's not really
> a "black box": if you know the cipher suites supported by your available
> key(s) then you should have enough information to know, based on the client
> cipher suites and the per-protocol suites, and the cipher suites available
> in the SSL context(s), which protocols can complete.

Well, perhaps.

My point is that I implement some logic in the server, say version 10.
Server 10 works with JDK 9.1.0.
Time passes, JDK gets updated to 9.1.173, which has now a different
logic, for whatever reason.
Try to run server 10 with JDK 9.1.173 does not negotiate the right protocol.

>> I don't think this is maintainable; the JDK is entitled to change the
>> logic following CVEs, optimizations and what not, and each such change
>> risks to break existing server code.
>
>
> What kind of change do you anticipate being a breaking change?  Are you
> thinking of e.g. blacklisting some known-bad cipher suite or something?

Well, take ECDSA for instance. Before that, my logic on server version
10 was not caring about ECDSA.
My server version 10 was working with JDK 5, but not with JDK 9
(assuming that JDK 5 did not have support for ECDSA).
That is a breaking change to me.

I imagine in the future ECDSA be replaced by something else, or a
different DSA being used, I have to change the server code.
I would like to avoid that, and keep the server logic independent of
how the JDK chooses the cipher.

Makes sense ?

Thanks !

-- 
Simone Bordet

http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.


Issues with ALPN implementation in JDK 9

2016-06-14 Thread Simone Bordet
re not copied
into the handshaker and are not used to generate the ServerHello.

Conclusions.

I could not make a reliable ALPN implementation with the current JDK 9.
If I am off road, then that's good news, and I will be all ears for
alternative approaches.

If I am correct, I would like to discuss whether it would be possible
to delay handshaker.started=true to a later time, so that
SSLParameters can be changed just after the NEED_TASK step, so that
server applications will be able to interact with the JDK for what
pertains TLS protocols, ciphers, SNI, etc. without duplicating the
logic.

Comments welcome.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Request for review: 8144093: JEP 244/8051498 - TLS Application-Layer Protocol Negotiation Extension

2016-06-02 Thread Simone Bordet
Hi,

On Thu, Jun 2, 2016 at 8:20 PM, Bradford Wetmore
<bradford.wetm...@oracle.com> wrote:
> Hi Simone,
>
> I agree with you, it would be handy.  As part of the HTTPS 2.0 prohibited
> suites for ALPN, I wanted to do just such a convenience mapping in
> javax.net.ssl.StandardConstants.java:
>
>
> http://cr.openjdk.java.net/~wetmore/8051498/webrev.16/src/java.base/share/classes/javax/net/ssl/StandardConstants.java.frames.html
>
> public static final Map<Integer, String> cipherSuiteIntToString
>
> but was shot down and finally gave up.  We'd need to consider more how to
> expose some of the TLS internals that we don't currently do right now.
> (e.g. at the API layer or as a provider (SPI) call.)
>
> One of the problems you may not have noticed is also historical, in that
> JSSE was first released around the time of the finalization of TLSv1, so
> there is a mix of SSL_/TLS_ prefix for the older algorithms.  The TLS
> standard name String "TLS_RSA_WITH_3DES_EDE_CBC_SHA" is actually the
> SSLv3/Java Standard Name "SSL_RSA_WITH_3DES_EDE_CBC_SHA", which was set
> during the original SSLv3 spec, which later became the "Historic" RFC 6101.
>
> FYI, in JDK 9, you will lose the ability to call valueOf() due to modular
> encapsulation.
>
> We can file a RFE to do this.  Since JDK 9 just went FC last week, it will
> likely need to be a JDK 10 RFE.

Oh, no !

On net-dev we are still talking about changing the APIs for HttpClient
and WebSocket client, so can I please ask that this does not get
delayed another 5 years ?
We explicitly asked on net-dev if there was a freeze, and they replied
that it was still possible to change the APIs, so I presume it would
be possible to add a simple class to javax.net.ssl ?
It's a super simple class to expose, call it CipherNames, whose
implementation will be trivial and based on
sun.security.ssl.CipherSuite.
Right now I am doing the same accessing CipherSuite via reflection on
its private members.

I don't know if I am late to the party or way too early, but I cannot
believe that all others that are interested in ALPN in Java 9 went for
a workaround instead of asking here whether the cipher names could
have been exposed in a standard way.
Considering the historical issue you mention it is important that
there are no ambiguities in the cipher names, and having the JDK as
the only source is really important.

Can I ask you to reconsider this small change for JDK 9 ?

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Request for review: 8144093: JEP 244/8051498 - TLS Application-Layer Protocol Negotiation Extension

2016-06-02 Thread Simone Bordet
Hi,

On Wed, Dec 2, 2015 at 1:04 AM, Bradford Wetmore
<bradford.wetm...@oracle.com> wrote:
> Filling in a few more details [for server parsing]
>
> SSLContext.getInstance("protocol"); // returns a context with
> // "protocol" and possibly
> // other protocols enabled.
> SSLEngine ssle = SSLContext.createSSLEngine(...);
>
> Read ClientHello from Socket/SocketChannel/AsynchronousSocketChannel/etc.
>
> Parse ClientHello for requested protocol/alpn/ciphersuites
>
> choose protocol/alpn/ciphersuite value(s)

I'm trying to give this a go in Jetty and I stumbled into this
problem: when Jetty parses the ClientHello, it parses the ciphers in
the TLS format of 2 bytes.

For example, the ClientHello contains the cipher (0x00, 0x00).
I would need a way to convert the 2-bytes duple into the corresponding
cipher string.
For this example, it would be: "TLS_NULL_WITH_NULL_NULL".

Turns out that the JDK can do this via:

CipherSuite cipher = sun.security.ssl.CipherSuite.valueOf(byte1, byte2);
String name = cipher.name;

Unfortunately, class CipherSuite is package local, and in sun.* package.

Would be great if there was a standard way of going from the duple to
the string.

Having the cipher string would allow applications to compare what
parsed with application configurations strings, and it would match
with methods such as SSLEngine.getEnabledCipherSuites(), etc. which
handle String[].

Having the JDK to provide this facility would guarantee that the
naming is always consistent, and that it is always up-to-date with the
JDK in use.

Looking forward to your comments.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v7

2015-10-08 Thread Simone Bordet
Bradford,

On Sat, Oct 3, 2015 at 2:19 AM, Bradford Wetmore
<bradford.wetm...@oracle.com> wrote:
> Thanks for the comments everyone.  I'm submitting the following to the CCC
> (internal review board):
>
> http://cr.openjdk.java.net/~wetmore/8051498/webrev.17/
>
> Changes:
>
> 1.  No H2 Blacklist/Comparator
>
> 2.  set/getApplicationProtocols() back to SSLParameters.

Have you implemented this solution already ? Also for clients ?
Do you have feedback on actually implementing ALPN in this way ?

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v5

2015-09-25 Thread Simone Bordet
David,

sorry, but I don't understand your proposal.

Can you please write it down in pseudo code what a server application
should do and what the JDK should do to negotiate HTTP/2 with a client
?

I don't see how it is even possible for a user to decide anything
*before* the handshaking is even initiated, like you say.
It obviously does not have enough information.

This is the current algorithm (A=app code, J=JDK code):

A: sslParameters.setApplicationProtocols(H2, H1);
A: (optional, only needed for H2) sort ciphers to favor H2
A: start handshake
J: receive ClientHello
J: ciphers = intersect client/server ciphers
J: aps = intersect client/server application protocols
J: for each cipher in ciphers
J:for each ap in aps
J:if (ap.matches(cipher & other info)) break
J end // aps
[A: ap.matches() calls into application code to return whether ap is
good for the given info]
J:if (ap was not selected) continue; // to next cipher
J:if (trySetCipherSuite(cipher)) break; // success
J: end // ciphers
J: send ServerHello
J: terminate handshake
A: sslEngine/sslSocket.getApplicationProtocol()

Note that the JDK provides default implementations for H1 and H2 for
ap.matches(), but in general these will be implemented by application
code.

For an application that wants to support H2, this boils down to the
first 2 lines, the rest is in the JDK.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v5

2015-09-25 Thread Simone Bordet
Hi,

On Fri, Sep 25, 2015 at 3:44 AM, Xuelei Fan <xuelei@oracle.com> wrote:
> For example, a client wants to negotiate  {HTTP2,  HTTP1.1} or {HTTP1.1,
> HTTP2} and {TLS_RSA_WITH_AES_128_CBC_SHA,
> TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384}.
> HTTP1.1/TLS_RSA_WITH_AES_128_CBC_SHA should be negotiated per the TLS
> and HTTP2 specification.  If the cipher suites are sorted,
> TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 would be negotiated, this is not
> what the customer really expected.  The customer preference should be
> respected.
>
> I don't think we really need to re-order the cipher suites.

"We" as in the OpenJDK implementation *must not* reorder the cipher suites.
"We" as in an application that wants to use HTTP/2 *must* reorder the
cipher suites.
The comparator provided is only a help to the application to perform
this reordering.

> Let's consider the following client requests (prefer cipher suite more
> than application protocol; blacklisted_CS are HTTP2 blacklisted cipher
> suite):
>
> 1. {HTTP2, HTTP1.1} {strong_cipher_site, blacklisted_CS}
> HTTP2 and strong_cipher_site should be negotiated.  Need not to re-order
> cipher suites.
>
> 2. {HTTP1.1, HTTP2} {strong_cipher_site, blacklisted_CS}
> HTTP1.1 and strong_cipher_site should be negotiated. Need not to
> re-order cipher suites.
>
> 3. {HTTP2, HTTP1.1} {blacklisted_CS, strong_cipher_site}
> HTTP1.1 and blacklisted_CS should be negotiated. Need not to re-order
> cipher suites.

Of course you need to re-order in this case.
The application has just provided a preference for HTTP/2 in the
application protocol list, it actually happens that HTTP/2 could be
negotiated because strong ciphers are present, but instead HTTP/1.1 is
chosen.

> 4. {HTTP1.1, HTTP2} {blacklisted_CS, strong_cipher_site}
> HTTP1.1 and blacklisted_CS should be negotiated. Need not to re-order
> cipher suites.
>
> 5. {HTTP2} {strong_cipher_site, blacklisted_CS}
> HTTP2 and strong_cipher_site should be negotiated. Need not to re-order
> cipher suites.
>
> 6. {HTTP1.1} {strong_cipher_site, blacklisted_CS}
> HTTP1.1 and strong_cipher_site should be negotiated. Need not to
> re-order cipher suites.
>
> 7. {HTTP2} {blacklisted_CS, strong_cipher_site}
> blacklisted_CS would be filtered out as it does not appy to HTTP2.  Only
> strong_cipher_site presents in ClientHello message.
>
> HTTP2 and strong_cipher_site should be negotiated. Need not to re-order
> cipher suites.
>
> 8. {HTTP1.1} {blacklisted_CS, strong_cipher_site}
> HTTP1.1 and blacklisted_CS should be negotiated. Need not to re-order
> cipher suites.
>
> One concern may be that, the customer is not intent to negotiate HTTP2
> blacklisted cipher suite.  The customer just don't know which are the
> strong cipher suites among many cipher suites.  I think we may need a
> handy tool to order the cipher suites before configuration.
>
> // there are a few cipher suites are available
> String[] cipherSuites = ...  // a array of cipher suites.
>
> // Q: Don't know the strength of them
> // A: OK, there is a handy tool
> cipherSuites = cipherSuiteReorder.sort(cipherSuites);

Or, with the comparator:

cipherSuites = Arrays.sort(cipherSuites,
ApplicationProtocol.H2.CIPHER_COMPARATOR);

The comparator is the handy tool.

> // configure the cipher suites
> SSLParameters.setCipherSuites(cipherSuites);
>
> The order also apply to the normally cipher suites configuration, not
> only to application protocols.  The re-order should be called by
> customers explicitly.  JSSE would better not sort them automatically.
>
> I think, the handy sort tool cannot be simply bind to application
> protocol.  For example, HTTP2 has a blacklisted cipher suites.  OK,
> ApplicationProtocol.H2BLACKLISTCOMPARATOR is expected to make the sort.
>  If, in the future, a new application protocol (AP_NEW) has a different
> blacklist cipher suites, a new
> ApplicationProtocol.APNEWBLACKLISTCOMPARATOR would be defined.  If both
> {HTTP2, AP_NEW} would be requested, which comparator for the sorting
> would be used?  None of them can sort the cipher suite properly.  The
> comparator design will not work any more.

Sure it does.

Because you explicitly set a preference in the order of the
application protocol, you only sort to favour the best protocol.

In case you have [HTTP/2, AP_NEW, HTTP/1.1], then you can simply
compose the comparators to sort first with the H2.CIPHER_COMPARATOR,
then with AP_NEW.CIPHER_COMPARATOR.

cipherSuites = Arrays.sort(cipherSuites,
ApplicationProtocol.H2.CIPHER_COMPARATOR.thenComparing(AP_NEW.CIPHER_COMPARATOR));

> We may need a handy tool for the sorting for stronger cipher suites.
> But, AFAIU, the tool does not belong to ALPN.

Indeed, it belongs to ApplicationProtocol.H2, not to ApplicationProtocol.

-- 
Simone Bordet

http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.


Re: TLS ALPN Proposal v5

2015-09-25 Thread Simone Bordet
Hi,

On Fri, Sep 25, 2015 at 11:47 AM, Xuelei Fan <xuelei@oracle.com> wrote:
> Here is the question to answer, which preference should be respected
> firstly between cipher suite and application protocol?  If application
> protocol are preferred at first, of course, application preference
> should be respected at first; otherwise, cipher suite preference should
> be respected at first.

The answer to this question has been decided when the algorithm has
been chosen to be:

for each cipher
  for each application protocol
  end
end

All the rest being equal, ciphers dominate application protocol selection.

Are you suggesting to change this to:

for each application protocol
  for each cipher
  end
end

?

It's in the hands of the role that configures application protocols
and ciphers to decide whether it's more important to prefer a protocol
or a cipher.

Put it in a different way:

If the role prefers application protocols, it has to sort the ciphers
to influence that.
If the role prefers ciphers, it has to sort the ciphers.

No matter what, it has to sort the ciphers.

> Therefore, personally, I think application may want a handy tool to sort
> the cipher suite for the strength for general purpose, but not for
> application protocol.

Because HTTP/2 would probably be popular given the success of its
predecessor, it would be handy to have a HTTP/2 comparator to
influence the selection of the HTTP/2 protocol.

Nothing forbids to offer a comparator by cipher strength too.

-- 
Simone Bordet

http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.


Re: TLS ALPN Proposal v5

2015-09-25 Thread Simone Bordet
Hi,

On Fri, Sep 25, 2015 at 3:20 PM, Xuelei Fan <xuelei@oracle.com> wrote:
> For the complication, I posted the comments in previous mail here:
>
> -
>> In case you have [HTTP/2, AP_NEW, HTTP/1.1], then you can simply
>> compose the comparators to sort first with the H2.CIPHER_COMPARATOR,
>> then with AP_NEW.CIPHER_COMPARATOR.
>>
>> cipherSuites = Arrays.sort(cipherSuites,
>>ApplicationProtocol.H2.CIPHER_COMPARATOR.
>>thenComparing(AP_NEW.CIPHER_COMPARATOR));
>>
> Let's look at an example.  application_protocol_1 prefer cipher_suite_1,
> and application_protocol_1 prefer cipher_suite_2.
>
> The comparator for application_protocol_1 would set the preference as
> {cipher_suite_1, cipher_suite_2}.  and the comparator for
> application_protocol_2} would set the preference as {cipher_suite_2,
> cipher_suite_1}.
>
> The result to sort 1 and then 2, and the result to sort 2 and then 1 are
> different.
>
> The call sequence to the comparators, and the call to each comparator
> would result in difference result.  That's may be not the expected behavior.

The example is malformed, since it does not specify which ciphers are
good for which application protocol, and neither the order of the
application protocols.

Let me rewrite it:

application protocols: [ap1, ap2]
ciphers: [c1, c2]

ap1 requires c1, does not work with c2
ap2 requires c2, does not work with c1

Now the question is: you have to configure your system, what you want to do ?

If you want to favor ap1, then you sort [c1, c2]
If you want to favor ap2, then you sort [c2, c1]
If you want to favor c1, then you sort [c1, c2]
If you want to favor c2, then you sort [c2, c1]

If you want to favor ap1 *and* c2, you have to decide what is more
important between the two, because you cannot have both.

I don't see any problem, really.

That the results are different, sure, but they are predictable.
When the configuration uses one comparator, it will always be that
result, and same for the other comparator.

But you configure the comparators in base of what you want to do.

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


[no subject]

2015-09-25 Thread Simone Bordet
Hi,

On Fri, Sep 25, 2015 at 4:19 PM, Xuelei Fan <xuelei@oracle.com> wrote:
> Actually, it was a puzzle to me: whether a concrete server can support
> both HTTP/2 and HTTP/1.1, or not. If HTTP/2 mode of the server does not
> work, is it OK to fall-over to use HTTP/1.1 mode? I did not get the
> answer from the HTTP/2 spec.

Yes, there was an answer to Bradford's email:
https://lists.w3.org/Archives/Public/ietf-http-wg/2015JulSep/0160.html.
The answer is "yes".

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v5

2015-09-24 Thread Simone Bordet
Hi,

On Fri, Sep 25, 2015 at 1:45 AM, Bradford Wetmore
<bradford.wetm...@oracle.com> wrote:
> I think that a textual name will be better than:
>
> // Output:  javax.net.ssl.ApplicationProtocol$1@1b9e1916
>
> System.out.println(ApplicationProtocol.H2);
>
> and there's no UTF-8 ambiguity.

Sure, but then I would just keep getNetworkSequence(), and remove
getProtocolName(), since toString() is sufficient.
To have to implement getProtocolName(), I see it as a
non-strictly-needed burden to developers that implement
ApplicationProtocol.
I know of companies that want to use ALPN extensively because they use
many different communication protocols internally, so it won't be a
rare occasion to implement ApplicationProtocol.

> http://cr.openjdk.java.net/~wetmore/8051498/webrev.15/

I gather that the Map parameter can't be solved in other ways, right ?

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v5

2015-09-23 Thread Simone Bordet
Hi,

On Wed, Sep 23, 2015 at 7:04 AM, Bradford Wetmore
<bradford.wetm...@oracle.com> wrote:
>
>> This new proposal still requires that ciphers are sorted in a way that
>> matches the ApplicationProtocol order.
>> Would be nice if, along with the HTTP/2 blacklist, there is a HTTP/2
>> comparator that sorts ciphers putting the blacklisted ones at the end.
>
> Hm...is the sample code at the end of the initial class description
> insufficient?  Adding a comparator seems a little heavyweight in that it
> could require access to the ciphersuite internals and would add a lot of
> complexity for this one known use case.  When TLSv1.3 is done, the blacklist
> stuff in HTTP/2 goes away.

Sure, but until TLS 1.3 widely deployed, applications will have to
sort the ciphers to put HTTP/2 ones before the blacklisted ones.
Providing this comparator is as trivial as providing
ApplicationProtocol.HTTP2BLACKLIST, so I thought to mention it.

>> I also don't understand why there are 2 methods for the protocol name
>> ? What value does it bring to have 2 methods for the same thing ?
>
> Please see the IANA registry:
>
> http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
>
> for RFC 7301:
>
> http://www.rfc-editor.org/info/rfc7301
>
> getProtocolName() is the IANA/IETF textual representation of the protocol
> name (i.e. "Protocol" column), for example "HTTP/1.1", "SPDY/3", and "HTTP/2
> over TLS".  I suppose toString() could be used instead, but thought it might
> eventually output additional ALPN value state.  I don't have any concrete
> plans at this point.
>
> getNetworkSequence() is the identification sequence for the protocol (i.e.
> "Identification Sequence" column), and represents the actual byte
> identifiers that will travel the network in an ALPN extension.
>
> 0x68 0x74 0x74 0x70 0x2f 0x31 0x2e 0x31 ("http/1.1")
> 0x73 0x70 0x64 0x79 0x2f 0x33 ("spdy/3")
> 0x68 0x32 ("h2")
>
> When client wants to send the extension over the network, it grabs the
> ApplicationProtocols values from the SSLParameters, then calls
> getNetworkSequence() on each ApplicationProtocol to obtain the actual opaque
> ProtocolName(1..2^8-1) to send.  Likewise on the server side, we match the
> incoming active ALPN opaque values with the list of mutually agreeable ALPN
> values.  And of course, send back the final selected value.

Sure, but application will have to implement two methods instead of
one, and AFAIU the JDK implementation is never calling
getProtocolName() since it's just a description for humans.

> I've updated the webrev to include an SSLSocket test variant, and added a
> few more comments.
>
> http://cr.openjdk.java.net/~wetmore/8051498/webrev.14/
>
> Hopefully things are more clear now.  Thanks for your review/comments.

I see now, thanks for the pointers !

Indulge me a bit more below on the Map passed as parameter to
ApplicationProtocol :)

IIUC, by the time we are executing the code that calls
ApplicationProtocol.match(), the TLS protocol is already chosen and
it's available in SSLSession.
When remains is the transient value of cipher that is being chosen.
Because we already have modified the API to support the application
protocol transient value (by adding
SSLEngine.getHandshakeApplicationProtocol()) to be used by
KeyManagers, I was wondering if we cannot either:

A) add: String SSLEngine.getHandshakeCipherSuite(), to be used by
ApplicationProtocol

or

B) add: Map<String, String> SSLEngine.getHandshakeParameters() or
perhaps: Map<String, String> SSLParameters.getHandshakeParameters().

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v5

2015-09-22 Thread Simone Bordet
Hi,

On Sat, Sep 19, 2015 at 7:15 AM, Bradford Wetmore
<bradford.wetm...@oracle.com> wrote:
> Here is the new webrev:
>
> http://cr.openjdk.java.net/~wetmore/8051498/webrev.12/
>
> Unless there are major objections, we need to get ALPN into JDK very soon to
> make JDK 9.  We can still tweak the APIs if something is found later.
>
> Major changes:
>
> 1.  ApplicationProtocols interface + H2 + HTTP/1.1 impls
>
> Both client/server call SSLParameters.setApplicationProtocols(List<>) to set
> their preferences.
>
> The matches method can be used for:
>
> .  During server handshaking to determine an acceptable ALPN value.
>
> .  potentially during client preparation to eliminate known bad
> ciphersuites/protocols combos.  If you are going to only request TLSv1.1 and
> earlier, you can disable H2 because it won't match.
>
> In this second case, you may not have a SSLSocket/SSLEngine yet, but you
> still want to do the checks based on ciphersuite/protocol, so the second
> parameters can be null.
>
> 2.  ApplicationProtocolSelector gone.
>
> 3.  SSLParameters AP_HTTP_1_1/AP_H2 effectively moved to
> ApplicationProtocol.  Selection logic added to ApplicationProtocol.
>
> 4.  Moved ALPN values from SSLSession to SSLSocket/SSLSEngine.  Added a
> "handshaking in progress" variant.
>
> 5.  SSLSession.getPeerApplicationProtocols() and
> getHandshakeCipherSuiteList() are gone.  These are all handled internally.

This new proposal still requires that ciphers are sorted in a way that
matches the ApplicationProtocol order.
Would be nice if, along with the HTTP/2 blacklist, there is a HTTP/2
comparator that sorts ciphers putting the blacklisted ones at the end.

I don't like the first parameter of ApplicationProtocol.match() to be
a Map<String, String>; I would prefer a full blown class at this
point, that contains all the parameters, for example:

inner class ApplicationProtocol.Info
{
tlsProtocol
cipher
sslEngine
sessionIsResuming
etc.
}

I also don't understand why there are 2 methods for the protocol name
? What value does it bring to have 2 methods for the same thing ?
I would just use:

class ApplicationProtocol
{
public String getName()
}

RFC 7301 hints that the bytes to send over the network are the UTF-8
bytes from that string.

There are still a lot of details missing, such as where is the chosen
ALPN value stored (and how it can be retrieved by the KeyManager, for
example), as well as the webrev not showing any real implementation,
and how exactly the ApplicationProtocol instances are called, etc.

For example, client sends ["h2"], server has ["http/1.1", "h2"]. Will
the instance of ApplicationProtocol corresponding to "http/1.1" be
invoked at all ?
If not, there is a missing step in your algorithm above, where the
implementation intersects the ALPN values from both peers.

Finally, I think this API may be suitable for the server, but not much
for the client, which is equally important.

I don't see how a client application can figure out what protocol has
been chosen by the server, because there is no final notification
about that and the API seems totally geared towards server "matching"
more than client notification. For me this is a blocker.

Can you please provide an example of how a client application would
use this new API to be notified that the server has chosen protocol
"foo" ?

I still remain convinced that - so far - the Jetty API proposal (or
the similar version that was proposed here 2-3 proposals ago) is
superior to the latest ones.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v4

2015-09-07 Thread Simone Bordet
ake sure that whatever proposal enters JDK 9, session resumption
is supported.

My preference would go to the previous proposal (akin to Jetty - I
know I am biased) where protocol selection was happening in isolation
*after* cipher selection.
It is much simpler, and has the only drawback of not allowing
certificate selection based on application protocol (for which we
never had request from the community).

This proposal seems less clear to me, a bit of compromise between a
full fledged multi-selector API (it is in fact a 2-selector API for
cipher and application protocol) and the previous proposal (that was a
select-after-the-cipher selector API).

If the times are tight, I would go for the simpler approach and leave
the full fledged multi-selector API for JDK 10.

Thanks !

-- 
Simone Bordet

http://cometd.org
http://webtide.com
Developer advice, training, services and support
from the Jetty & CometD experts.


Re: TLS ALPN Proposal v3

2015-07-25 Thread Simone Bordet
Hi,

On Fri, Jul 24, 2015 at 9:38 PM, Jason Greene jason.gre...@redhat.com wrote:
 The truth is that there is a gap between the current capabilities of TLS 
 stacks and what the specs are trying to achieve. Ultimately the desired 
 semantic the specs are trying to achieve is that every ALPN protocol can have 
 its own TLS requirements. In this case H2 wanted TLS 1.3 behavior before it 
 was released. This is basically social engineering, the newer protocol is the 
 carrot for updating your TLS stack. However there are other potential 
 scenarios, such as protocols which desire to be encrypted but unauthenticated.

 To truly resolve this gap in a future proof manner, TLS stacks need to 
 support cipher suite selection based on the combination of ALPN protocol and 
 TLS version.

Had TLS 1.3 been released before H2, we would not need to choose the
cipher suite based on ALPN + TLS version, because any TLS 1.3 cipher
would do, and the support for ALPN would be much simpler (probably
akin to SNI).
The current situation is a temporary glitch produced by the H2
specification, and requires clients and servers to implement hacks to
support H2 (sorting ciphers, etc.).

Another thing to remember is that clients and servers may implement
different ways of selecting the various TLS parameters.
While server have to choose among TLS protocol versions, ciphers,
application protocols, etc., the client can only react to what the
server chose.
For a TLS implementation, it may be simpler to implement a client
(like browsers do) than a server; I think the server algorithm would
work for clients, but not necessarily viceversa.

Tradeoff between A) change radically the OpenJDK implementation to
support an iterative processing of TLS protocols, extensions (all of
them), ciphers, aliases, etc. that would be future proof (if that is
even possible) and B) hack in just enough of what is needed to support
H2 today (for which we already have working examples) ?

Would it be possible to fit the ALPN solution that would have been
implemented if TLS 1.3 was out before HTTP/2 to support the current
situation ?

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v3

2015-07-09 Thread Simone Bordet
Hi,

On Thu, Jul 9, 2015 at 1:42 AM, Bradford Wetmore
bradford.wetm...@oracle.com wrote:
 SSLParameters is a configuration class which is used to configure
 SSLSockets/SSLEngines.  SSLSession/ExtendedSSLSession is a class which holds
 negotiated Session values.  getReceivedApplicationProtocols() represents the
 Application Protocol values received from the peer, thus belongs in the
 SSLSession.

I suggest to rename

ExtendedSSLSession.getRequestedApplicationProtocols()

to

ExtendedSSLSession.getPeerApplicationProtocols()

The protocols are not really requested, they are more offered, but
IIUC the reason to add Requested to this method is to distinguish it
from SSLParameters.getApplicationProtocols() which returns the local
protocols, and in that spirit I think Peer is better for
ExtendedSSLSession.

 Xuelei/Simone wrote:
 Per my understanding, application protocol should be negotiated before
 cipher suite and protocol version negotiated.

 This is not possible for HTTP/2.
 Application protocol negotiation MUST happen *after* the TLS protocol
 and the TLS cipher are negotiated.

 Yes, that's my understanding as well.

Well, to be precise, either the application protocol is negotiated
after the cipher (and you need cipher sorting to influence the cipher
selection towards the application protocol you would like to choose),
or it must happen at the same time - that is, cipher and application
protocol must be chosen at the same time - but this implies that the
action of choosing that tuple may be invoked multiple times with the
current OpenJDK implementation.

Note that I don't know if the fact that cipher selection is an
iterative process is an OpenJDK implementation detail.
If other implementations are not iterative, then perhaps they have a
single moment where the tuple is chosen.

I support Xuelei in that you should ask confirmation to the HTTP/2 editor.
Also, remember that Firefox, Chrome, OpenSSL, nghttp2, etc. are all
open source and their code is available to verify the behavior.

 IIUC, the HTTP/2 blacklist is just strongly recommended (...SHOULD NOT use
 any of the cipher suites...black list), but not required.  Such potential
 peers must also support such a configuration, but in general, it will not.
 See section 9.2.2.  I think it's still considered compliant to the spec tho.

From experience, if a server breaks this SHOULD NOT, it won't work
with any browser.
We had our share of pain trying to figure out interoperability with
browsers for Jetty :)
Sure, it's a SHOULD NOT, but it's like a MUST NOT if you want a
browser to talk to a Java server (or a Java client to talk to a
current HTTP/2 server).

 Simone wrote two different ways to do selection:

 1) ... so that TLS protocol, cipher (possibly the alias too) and
 application protocol are chosen together, or
 2) we separate the TLS protocol and
 cipher negotiation (and alias) in one step, and we perform application
 protocol selection afterwards.

 Rather than completely redo the JSSE selection mechanism with the
 (version/ciphersuite/ALPN)-tuple idea (which would be a much more involved
 API and behavior change), I think the more straightforward solution (2) is
 better.

That's what we do in Jetty's ALPN implementation too.
Be aware that it rules out some possibility such as those mentioned by
Michael from RFC 7301.

 Also, it is critical to detail how the mechanism work.

 Example implementations for SSLFunction would be great to have: the
 typical HTTP/2 case is to select the application protocol based on the
 TLS protocol and the already negotiated cipher.

 I have a working test example which shows how the ALPN APIs can be used
 for HTTP/2 clients and servers. It is a minor configuration tweak to the
 jdk/test/javax/net/ssl/templates/SSLEngineTemplate.java test that we use as
 the basis for JSSE SSLEngine testing.

Do you have a Java 9 server that can negotiate h2 with current browsers ?

 http://cr.openjdk.java.net/~wetmore/8051498/webrev.04/test/javax/net/ssl/ALPN/SSLEngineAlpnHttp2.java.html

 See the configuration in createSSLEngines() around line 265 and 280.


 http://cr.openjdk.java.net/~wetmore/8051498/webrev.04/test/javax/net/ssl/ALPN/Http2ApplicationSelector.java.html

 Note the HTTP/2 blacklist and reordering code.

 The code is not actually working yet (haven't merged API/impl repos yet),
 but shows how to configure/use this API.

Just a reminder that the cipher blacklist is only valid for TLS 1.2.
For example, if the negotiated TLS protocol is 1.3, there is no need
to look at the ciphers (nor to sort them).

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v2

2015-06-05 Thread Simone Bordet
Hi,

On Fri, Jun 5, 2015 at 2:36 PM, Xuelei Fan xuelei@oracle.com wrote:
 See more inlines, please.

 Please help on one question I'm not sure of.  Per HTTP/2 specification,
 Does H2 server allow fallback to HTTP/1.1 if client requests a HTTP/2
 connection?  I did not find the answer from RFC 7540.

Yes.
The intended behavior is exactly to fall back to http/1.1 if h2 cannot
be negotiated.

This is implicitly explained in the ALPN spec, RFC 7301, see
http://tools.ietf.org/html/rfc7301#section-3.2.

 In TLS, if client requests to negotiate TLS v1.2, and server supports
 TLS 1.2, it is not allowed to fallback to TLS v1.1.  If there is not
 suitable cipher suite to negotiate TLS 1.2, the connection would be
 terminated immediately.  I'm not sure what's the spec for HTTP/2,
 HTTP/1.1 and HTTP/1.0.

HTTP/2 does not behave like TLS in this sense.

ALPN is for *application* protocol selection.
A client can send:

[h2, spdy/3.1, http/1.1]

Failing h2, spdy/3.1 is attempted, which is a completely different
protocol, with different restrictions, etc.

 Per RFC 7540, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 is a mandatory
 cipher suite for H2.

No.
It's a mandatory cipher for *TLS 1.2 deployments only*.

If the client uses TLS 1.4 does not have to have that cipher, and
hence there can be an empty intersection of ciphers with the server.
That cipher is only mentioned because all the mandatory TLS 1.2
ciphers have been blacklisted by HTTP/2.

If TLS 1.3 was specified before HTTP/2, that cipher would not even be
mentioned, and the HTTP/2 spec would have referenced only TLS 1.3 as
mandatory: no black lists, no special cipher.

The TLS and HTTP specifications will evolve independently, and there
cannot be a requirement that whenever TLS changes, an update to HTTP/2
must be published.

Hope this clarifies.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v2

2015-06-05 Thread Simone Bordet
Hi,

On Fri, Jun 5, 2015 at 4:46 PM, Xuelei Fan xuelei@oracle.com wrote:
 If H2 is not supported, SPDY/3.1 would be attempted, of SPDY/3.1 is not
 supported HTTP/1.1 would be attempted.

Correct.

 If H2 is supported in both side,
 but H2 does not work, it is a H2 problem that need to be addressed in H2
 layer.

If both client and server have h2 as a potentially supported
protocol, but the cipher to use h2 is not valid, then h2 is not
supported for that particular connection.
At that point, like you said above, spdy/3.1 is attempted, and so on.

 No application protocol fallback in TLS layer if the application
 protocol is supported.

Your interpretation of supported is not what browser and server
implementors mean :)

 I understand your concerns now.  I think we have different understanding
 of the ALPN protocols.  It's a good thing to understand the actually
 requirements of the industry, I think.  Thank you!

So where does this leave us know ?

By the way, while I have participated in the RFC 7540 discussions, and
implemented HTTP/2 in Jetty to be interoperable with a variety of
other clients and servers, feel free to ask clarifications to the RFC
7540 and RFC 7301 mailing lists, or even directly to the editors of
those RFCs; they are typically open to answer questions, I guess
especially so if they come from the OpenJDK team that is implementing
those specification.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v2

2015-06-04 Thread Simone Bordet
Hi,

On Thu, Jun 4, 2015 at 6:50 PM, Xuelei Fan xuelei@oracle.com wrote:
 Hm, I see your point now.  But I may not agree with your ALPN MUST
 happen after protocol/cipher suite negotiation conclusion.

 I parse this section as, a H2 server must be strong enough(comply to
 RFC7540), and a H2 client must also be strong enough (comply to
 RFC7540).  Otherwise, both side may terminated the connection, and
 cannot declare as complying to H2.  It is not necessary for an
 application protocol selector to detect whether a H2 server/client
 comply to H2 or not.

 If H2 is requested, it means that the client supports H2. Otherwise,
 it's a client application bug.

Not that simple, see below.

 If H2 is selected by a selected, it
 means that the selected server supports H2.  Otherwise, it is a selector
 implementation bug.  If something wrong in either client or server, it
 is expected to terminate the connection immediately, rather than
 downgrade to a not-strong enough level.

 From the points above, I think an application protocol selector may not
 need to know the negotiated protocol version and cipher suite.

No.

The client may send ciphers that are valid for http/1.1 (but invalid
for h2), along with ciphers that are good for h2 (as well as http/1.1
of course), plus the list of protocols it supports.
The client has no idea what the server supports.

When the server sees that the client supports h2, it MUST pick a
cipher that is valid for h2.
Alternatively, the ciphers on the server are sorted so that those
valid for h2 have higher priority (they are attempted before all the
others), so that there is a high chance that a h2 valid cipher is
chosen (but no guarantee) before choosing the application protocol.
When the application protocol selector callback is invoked, it can
only pick h2 IFF the cipher is h2 valid, otherwise it has to fallback
to http/1.1.

With your reasoning, the client can send [h2_invalid_cipher,
h2_valid_cipher], the server may pick h2_invalid_cipher, then the
application protocol selector is invoked, which will only look at the
protocols, pick h2 since it's supported by client and server, and now
you have an invalid connection: the h2 protocol with
h2_invalid_cipher.

We have been through these issues for months in the RFC 7540 expert
group, and the outcome is that protocol selection, for h2, depends on
the cipher.
We have also been through a number of scenarios where both the client
and the server send h2 valid ciphers, but their intersection is empty
(this may happen when a very old client talks to a very new server,
think TLS 1.2 vs TLS 1.4, or viceversa).
Same outcome: to pick h2 you MUST have a h2 valid cipher in common
between client and server, so application protocol selection, for h2,
depends on the cipher.

A bit of warning here: we are designing an API for ALPN, not for HTTP/2.
The ALPN API should be flexible enough to implement *at least* HTTP/2,
possibly even more complex scenarios (for example alias selection),
but IMHO it should not be tied to HTTP/2.

Again, I see 2 cases: either the JDK implementation picks the TLS
protocol, the cipher and the alias like it does now, and then invokes
the callback to pick the application protocol (current Jetty ALPN
behavior), or the implementation must be reviewed to perform TLS
protocol, cipher, alias and application protocol selection at once,
with a callback that will be invoked possibly multiple times until
it can find the right tuple to return.

The latter would be the optimal solution, the former has certainly
working implementations.

Hope this clarified.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v2

2015-06-04 Thread Simone Bordet
Hi,

On Thu, Jun 4, 2015 at 5:53 PM, Xuelei Fan xuelei@oracle.com wrote:
 On 6/4/2015 8:19 PM, Simone Bordet wrote:
 This is not possible for HTTP/2.
 Application protocol negotiation MUST happen *after* the TLS protocol
 and the TLS cipher are negotiated.

 Why? Is it a spec of HTTP/2?  It is a point I don't understand now.
 Please help with more details.

http://tools.ietf.org/html/rfc7540#section-9.2

You can only speak h2 if the cipher is strong enough as defined by RFC 7540.

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v2

2015-06-04 Thread Simone Bordet
Hi,

On Thu, Jun 4, 2015 at 3:08 PM, Michael McMahon
michael.x.mcma...@oracle.com wrote:
 On 04/06/15 13:19, Simone Bordet wrote:

 Hi,

 On Wed, Jun 3, 2015 at 8:23 AM, Xuelei Fan xuelei@oracle.com wrote:

 Per section 4, RFC 7301:
... The
 application_layer_protocol_negotiation ServerHello extension is
 intended to be definitive for the connection (until the connection is
 renegotiated) and is sent in plaintext to permit network elements to
 provide differentiated service for the connection when the TCP or UDP
 port number is not definitive for the application-layer protocol to
 be used in the connection.  By placing ownership of protocol
 selection on the server, ALPN facilitates scenarios in which
 certificate selection or connection rerouting may be based on the
 negotiated protocol.

 Per my understanding, application protocol should be negotiated before
 cipher suite and protocol version negotiated.

 This is not possible for HTTP/2.
 Application protocol negotiation MUST happen *after* the TLS protocol
 and the TLS cipher are negotiated.


 What do you mean by after? As far as TLS is concerned, all of this
 negotiation happens in one negotiation. The client proposes a list of
 ciphers and application protocols. The server chooses a cipher
 and application protocol and sends back its choices.

Currently, IIUC, the cipher selection is an iterative process where a
cipher is attempted until one is negotiated.
In this process, there is no looking at the application protocol.

Here we're trying to find a solution for ALPN, and either we 1) look
the application protocol in this iterative process (and therefore the
SSLFunction is invoked multiple times), so that TLS protocol, cipher
(possibly the alias too) and application protocol are chosen together,
at once (for each iteration); or 2) we separate the TLS protocol and
cipher negotiation (and alias) in one step, and we perform application
protocol selection afterwards.
The latter is how Jetty's ALPN works, and that's what I mean with *after*.
For HTTP/2 it won't work to pick the application protocol before the
cipher. Either at the same time, or after.

That is why I asked to specify how the mechanism worked.

 The HTTP/2 RFC specifically warns against splitting this negotiation
 with the example that a client could propose a mandatory TLS 1.2 cipher,
 but which is black-listed by HTTP/2. If (internally) the server chooses that
 cipher first,
 without knowing the application protocol is going to be HTTP/2
 then you end up with a non-compliant connection that will probably have
 to be closed for reason of insufficient security.

If the server chooses a blacklisted cipher, and then h2 as protocol,
it's a non compliant server.
Communication of clients with compliant (and properly configured)
servers is guaranteed if the application protocol is chosen after (or
at the same time of) the cipher.

If I understand you correctly, you are proposing to rework the
internal JDK code to perform TLS protocol, cipher, alias and
application protocol in one point, which is then possibly iterated
multiple times until a satisfactory tuple is selected ?

I am fine with this approach too, but I guess the API will be very
different from Jetty's ALPN and this current proposal (which is fine
as well - does not have to be similar to Jetty's).
I don't know enough about the TLS implementation to say how much work it is.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v2

2015-06-04 Thread Simone Bordet
Hi,

On Wed, Jun 3, 2015 at 2:56 AM, Bradford Wetmore
bradford.wetm...@oracle.com wrote:
 Hi,

 I have just posted the second iteration of the ALPN proposal which hopefully
 addresses all of the comments raised here.  It is in javadoc format, but
 things can certainly be adjusted:

 http://cr.openjdk.java.net/~wetmore/8051498/webrev.00/

 Please see the archive [1] for previous design discussion.  I will be
 writing up usage examples in the next few days.

 The significant changes:

 ExtendedSSLSession
 public ListString getReceivedApplicationProtocols() {

 This will allow applications to examine which protocol names were
 sent.

This is a constant once the application protocols are received, so it
can be surely retrieved from SSLParameters.
I don't understand why it is replicated here ?

 SSLParameters
 mentions both ALPN/NPN as possible protocols.  I removed the
 discussion about server and client since ALPN/NPN essentially
 reverse the roles.

 mentions appropriate character sets for String-byte[] conversions
 such as UTF-8 for ALPN.

 The application protocol selector is now a @FunctionalInterface
 (i.e. lambda-ready) called SSLFunction.  It is to throw an
 SSLException if no values are supported, or null if you want to
 treat as an unknown extension.

 Defined constants for HTTP/1.1 and HTTP/2.

 SSLSession

 Called out that getHandshakeSession's ciphersuite may vary until
 selected.

 SSLBase

 A new marker interface that SSLEngine/SSLSocket will implement.
 This will allow for a single SSLFunction instead of having
 SSLFunctionSSLEngine and SSLFunctionSSLSocket.  It does require
 that the lambda do a instanceof, unless we were to move the common
 Socket/Engine APIs into this class.

I'm not sure about this one being a marker interface.
I could understand if it extracted the common functionality of
SSLEngine and SSLSocket, but a marker interface does not really add
much, and perhaps I would prefer it entirely gone.

On the same note, why is SSLFunction generic at all ?

Also, it is critical to detail how the mechanism work.
Will SSLFunction be invoked multiple times, or only once ? When,
exactly, with respect to cipher selection and alias selection ?

Example implementations for SSLFunction would be great to have: the
typical HTTP/2 case is to select the application protocol based on the
TLS protocol and the already negotiated cipher.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal v2

2015-06-04 Thread Simone Bordet
Hi,

On Wed, Jun 3, 2015 at 8:23 AM, Xuelei Fan xuelei@oracle.com wrote:
 Per section 4, RFC 7301:
   ... The
application_layer_protocol_negotiation ServerHello extension is
intended to be definitive for the connection (until the connection is
renegotiated) and is sent in plaintext to permit network elements to
provide differentiated service for the connection when the TCP or UDP
port number is not definitive for the application-layer protocol to
be used in the connection.  By placing ownership of protocol
selection on the server, ALPN facilitates scenarios in which
certificate selection or connection rerouting may be based on the
negotiated protocol.

 Per my understanding, application protocol should be negotiated before
 cipher suite and protocol version negotiated.

This is not possible for HTTP/2.
Application protocol negotiation MUST happen *after* the TLS protocol
and the TLS cipher are negotiated.

 And the connection may be
 rerouted (even to different machines) for further operation.  The
 requested application protocols list should be the only information for
 the selection of a suitable application protocol.

Not sure what you exactly mean here, but you can't pick the HTTP/2
protocol unless you have the TLS protocol and TLS cipher available.
So *only* the list of protocol sent by the client is not enough for
HTTP/2, we would need additional contextual information.

What a HTTP/2 aware load balancer written in Java that offloads TLS
would need to do is to negotiate the TLS protocol, negotiate the TLS
cipher, *then* negotiate the application protocol (whether h2 or
http/1.1), and with the last information pick a backend server,
typically forwarding clear text bytes to the backend.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal

2015-05-27 Thread Simone Bordet
Hi,

On Tue, May 26, 2015 at 8:46 PM, Bradford Wetmore
bradford.wetm...@oracle.com wrote:
 I am not sure I follow this. Can you please sketch the steps/algorithm
 that will be done in your proposed solution ?

 I'm assuming you are talking about 1a and not 1b.

 Sure, most of the heavy lifting takes place in ServerHandshaker.

 ServerHandshaker.java
 =

 In the SunJSSE code:

 // currently line 330.
 private void clientHello(ClientHello mesg) throws IOException {

 // Was an ALPNExtension received?
 ALPNExtension alpnExt = (ALPNExtension)
 mesg.extensions.get(ExtensionTyp.EXT_ALPN);
 ...
 // Currently line 706 in JDK9.
 session = new SSLSessionImpl(protocolVersion,
  CipherSuite.C_NULL,
  getLocalSupportedSignAlgs(),
  sslContext.getSecureRandom(),
  getHostAddressSE(), getPortSE());
 ...
 session.setALPNNames(alpnExt.getNames());
 ...
 // choose cipher suite and corresponding private key
 // This function is at 987 currently.
 chooseCipherSuite(mesg);
 ...
 // Only adds an ALPN extension if non-empty.
 m1.extensions.add(applicationProtocolSelector.select(...));
 ...

 Above, chooseCipherSuite() iterates through the collection of suites. Inside
 that, trySetCipherSuite() attempts to verify that the suite is acceptable to
 use.  Inside that, setupPrivateKeyAndChain() does the actual KeyManager
 calls.

 if (conn != null) {
 alias = km.chooseServerAlias(algorithm, null, conn);
 } else {
 alias = km.chooseEngineServerAlias(algorithm, null, engine);
 }

 Now in the Application's Code:

 If you want the KeyManager to take this info into account, you need to
 create your own customer KM.

 public String chooseEngineServerAlias(String keyType,
   Principal[] issuers,
   SSLEngine engine) {

 ExtendedSSLSession session = engine.getHandshakeSession();
 String protocol = session.getProtocol();
 String ciphersuite = session.getCipherSuite();
 ListString alpns =
 session.getRequestedApplicationProtocolNames();

 // Some logic for which key to use...
 return choose(protocol, ciphersuite, alpns);
 }

 And then your actual ALPN selector:

 public String select(...) throws SSLProtocolException {
 ExtendedSSLSession session = engine.getHandshakeSession()
 String ciphersuite = session.getCipherSuite();
 ListString alpns =
 session.getRequestedApplicationProtocolNames();

 // Some logic for which key to use...
 return choose(protocol, ciphersuite, alpns);
 }

 Hopefully that is clear.

Let me see if I understand correctly.

In chooseEngineServerAlias() I will have a proposed cipher and the
list of app protos from the client.
The goal would be to choose the alias based on the app proto, as stated by 7301.

However, the app proto is not yet chosen here. If I don't have other
constraints to choose the app proto (e.g. SNI), the usual algorithm
applies: pick the first server app proto that is in common with the
client.
Let's assume this is h2; but looking at the cipher, it's not good, so
we have to pick another app proto, say http/1.1. Now the cipher is
good and we return the alias.
This is similar to what happens now with Jetty's ALPN: the cipher will
be chosen, then the ALPN callback invoked and there, by looking at the
cipher, we know we have to use http/1.1.

Let's assume now I have the constraint to choose h2 (e.g. I have a SNI
of http2.domain.com).
In chooseEngineServerAlias() I will look at SNI, and therefore choose
h2, then look at the proposed cipher, which is not good, so return
null.
Method chooseEngineServerAlias() will be called repeatedly for other
ciphers, until a cipher good for h2 is found, otherwise it's an alert
120.

Are you proposing to call select(...) from chooseEngineServerAlias(),
and give the ALPN callback a semantic that it may be called multiple
times, each time with a different cipher, and give access to the ALPN
callback implementation to SNI to choose the right protocol based on
that ?

Thanks!

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal

2015-05-26 Thread Simone Bordet
Hi,

On Tue, May 26, 2015 at 2:30 AM, Bradford Wetmore
bradford.wetm...@oracle.com wrote:
 Darn those Chicken/Eggs [1]!

 Yes, you are correct.  The steps for the current server code:

 1.  The ClientHello is parsed, and the SNI matcher callback is called. It
 does not return which value was matched in the ServerHello, just whether a
 SNI name was matched or not:

 The extension_data field of this extension SHALL be
 empty.

 2.  Begin generating the ServerHello, choose the Protocol Version.

 3.  Iterate through the list of client's ciphersuites and call the Server's
 KeyManager (KM) callback until the KM returns key material we can use.  A
 return string selects the proposed ciphersuite.

 So we currently don't know the selected ciphersuite until the KM has been
 called (possibly multiple times).

 If we choose the ALPN before the ciphersuite, the ciphersuite selection may
 end up being inappropriate (HTTP/2 blacklist).  If we choose the ciphersuite
 first, then the ALPN value wasn't used to drive the certificate selection.

 Two suggestions in preferred order below.

 In each of these cases, unfortunately there is currently no indication of
 the proposed Ciphersuite, so we need to modify the behavior of
 getHandshakeSession().getCipherSuite() to fill in the proposed CipherSuite
 before the call to the KM.  This seems ok with the current wording, but we'd
 need to make that explicit.  This value will change for each ciphersuite/KM
 choice attempt.

 Each suggestion below is followed by our previously proposed ALPN callback
 to make the actual ALPN value selection:


 1a.  Add a parallel method to ExtendedSSLSession:

 public ListString getRequestedApplicationProtocolNames();

 along with the previously proposed selected name:

 public String getApplicationProtocol()

 (I'll be changing these names.  I'm open to suggestions).

 When the KM is called, the TLS protocol (e.g. TLSv1.2) has already been
 selected.

 Both of the major selection parameters (protocol/proposed ciphersuite) are
 now available, and applications have access to the ordered ALPN list to see
 what the client's requested values were.

 -or-

 1b.  Keep API as is, and make two callbacks.  This first is an advisory
 value, the TLS protocol version and proposed ciphersuite will be available
 in getHandshakeSession().  The second callback sets the final value that
 will be sent.


 I think 1.a is my preference.

I am not sure I follow this. Can you please sketch the steps/algorithm
that will be done in your proposed solution ?

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal

2015-05-25 Thread Simone Bordet
Hi,

On Mon, May 25, 2015 at 12:08 PM, Michael McMahon
michael.x.mcma...@oracle.com wrote:
 Hi Brad,

 A couple of initial comments/questions.

 1) Certificate selection is one feature envisaged by ALPN. ie a client or a
 server
 ought to be able to choose a different certificate depending on the
 application name
 that gets negotiated. Is that possible with this API?

Interesting.

I can definitely see choosing the ALPN protocol based on the SNI name
sent by the client.
For example, a server able to speak http/1.1 and h2 receiving a
request for http1.domain.com wants to force http/1.1.
This would be possible, IIUC, using
sslEngine.getHandshakeSession().getRequestedServerNames() in the
ApplicationProtocolSelector implementation.

I see less common choosing the certificate given the application
protocol, but I understand it's mentioned in RFC 7301.

ALPN definitely needs the cipher to be negotiated to support HTTP/2,
so I hope it's not a chicken-egg problem.

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal

2015-05-25 Thread Simone Bordet
Hi,

On Mon, May 25, 2015 at 3:57 PM, Michael McMahon
michael.x.mcma...@oracle.com wrote:
 Perhaps, though it seems there are specific ALPNs for HTTP/1.1 (http/1.1)
 and for HTTP/2 (h2). So, I think you would use ALPN itself to do that
 negotiation.
 An incoming TLS connection without the ALPN extension is just assumed to be
 HTTP/1.1

Sure, but I can see a client looping over a list of domain names (e.g.
to check whether the sites support HTTP/2) and therefore not having
any knowledge of whether it should or not add the ALPN extension.
This client will always add it, but the server must force http/1.1 for
http1.domain.com.

 There aren't very many different applications envisaged yet. There are
 a couple of NAT related protocols registered. But, actually having thought
 about it
 again, client certificate selection happens in the X509ExtendedKeyManager
 class
 and that implementation could presumably call
 sslEngine.getHandshakeSession().getApplicationProtocol()
 and select the client cert using that information. It doesn't do that now
 obviously
 but I think it could in future if necessary.

Sure, unless the protocol is not available because ALPN code has not run yet.
For what I understand, currently cipher selection and certificate
selection happen at the same time, please correct me if I am wrong.

If that's the case, then we have a chicken-egg problem: you can't call
ALPN code before the cipher is selected, but you need ALPN to select
the certificate.
If those two steps can be split, then ALPN code could be put in
between and all is solved.

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal

2015-05-23 Thread Simone Bordet
Hi,

On Sat, May 23, 2015 at 3:13 AM, Bradford Wetmore
bradford.wetm...@oracle.com wrote:
 Thanks for the thorough reviews and comments, I really appreciate it and
 always learn something.  FunctionalInterface (@since 1.8) is something I
 haven't really explored yet, so off to the books.

Just to be clear, this is what I am proposing:

class SSLParameters
{
...
ListString getApplicationProtocols();
void setApplicationProtocols(ListString protocols);
void setApplicationProtocolSelector(ApplicationProtocolSelector selector);
ApplicationProtocolSelector getApplicationProtocolSelector();
}

@FunctionalInterface
interface ApplicationProtocolSelector
{
String select(ListString protocols) throws SSLException;
}

In this way, there is no need for a SSLBase to converge SSLSocket and
SSLEngine, the ApplicationProtocolSelector can be specified as a
lambda expression on SSLParameters, and everything is much simpler.

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal

2015-05-22 Thread Simone Bordet
 from including SPDY/*, since they are on their way out now, and
 NAT/STUN since there hasn't been any call for it so far.

I agree that only http/1.1 and h2 deserve a constant.

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal

2015-05-22 Thread Simone Bordet
Hi,

On Fri, May 22, 2015 at 8:54 PM, Sean Mullan sean.mul...@oracle.com wrote:
 There's actually a bunch of methods in common, so one possibility is to
 create a new interface containing the common methods (say SSLBase for now
 for lack of a better name). Then you could change SSLEngine and SSLSocket to
 implement SSLBase (which should be a compatible change), and then have a
 single method on ApplicationProtocolSelector. Question is if there are
 enough common methods to do what you want? I don't know enough about ALPN to
 answer that question.

There are 2 things that conflate here: one is to provide the mechanism
to support ALPN, and the second is to make sure that it is possible to
support HTTP/2.

ALPN per se, for example, does not need any information about
SSLEngine or TLS protocol versions or ciphers.
It just needs the protocol strings, so the ApplicationProtocolSelector
would just need select(ListString).

For HTTP/2, however, the choice of the protocol will depend on the TLS
version and the cipher, so we will need a way to obtain that
information.

Typically, in the code where you pass the ApplicationProtocolSelector
you have the SSLEngine available, e.g.:

sslEngine.getSSLParameters().setApplicationProtocolSelector(new
ApplicationProtocolSelector()
{
public String select(ListString clientProtocols)
{
// Here sslEngine will be in lexical scope
}
});

In this way, ApplicationProtocolSelector won't depend on SSLEngine or
SSLSocket, and can be reduced to a FunctionalInterface.

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS ALPN Proposal

2015-05-22 Thread Simone Bordet
Hi,

On Fri, May 22, 2015 at 9:14 PM, Bernd Eckenfels e...@zusammenkunft.net wrote:
 I would suggest to make this encoded in latin1 instead. This is
 supposed to be a 8bit clean encoding (and will be compatible to all
 ASCII only strings). It is still ugly and needs to be documanted
 cleanly that the string you get back might not be a string at all.

RFC 7301 hints that protocol string could be UTF-8 encoded:
http://tools.ietf.org/html/rfc7301#section-6

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: JEP 244: TLS Application-Layer Protocol Negotiation Extension

2015-04-13 Thread Simone Bordet
Hi,

On Mon, Apr 13, 2015 at 6:22 PM, David M. Lloyd david.ll...@redhat.com wrote:
 Do you know of a Java TLS implementation that has APIs like this already?  I
 am also interested in this for the ability to implement authentication
 mechanisms (GSSAPI and SASL) that rely on channel binding, so I would like
 to see such an API materialize as well.

I posted a while back such APIs from 3rd party JSSE implementations:
http://mail.openjdk.java.net/pipermail/security-dev/2014-August/011014.html
(at the end).

The problem that has been raised is that if you offer a generic TLS
extensions API, then the extension may have a semantic that it's not
implemented.

Imagine this TLS extensions API already existed, to add extensions to SSLEngine.
Now, ALPN comes along as a new TLS extension. An application could
create their own ALPNExtension subclass (extending a standard one
provided by the TLS extensions API), and add it to the ClientHello.
But there is no code in the JDK that calls the application, asking (on
the server) to select one of the protocols, for then send back the
chosen protocol to the client.
This could be solved by a callback API at the moment the ClientHello
is received by the server (and the ServerHello by the client), so the
application can examine the ALPN protocols.

The NPN extension was doing something even more complicated, creating
an additional TLS message that needed to be sent at the right time.

It may be that a TLS extensions API (to add/remove/query TLS
extensions) *and* a callback API to analyze hello messages when they
are received is enough to cover a lot of cases, perhaps even all
currently existing ones.

I asked for feedback some time ago about the status of the ALPN
implementation; would be great if the security team could update the
current status.

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: JEP Review Request: TLS Application-Layer Protocol Negotiation Extension

2015-02-03 Thread Simone Bordet
Hi,

On Mon, Feb 2, 2015 at 8:27 PM, Bradford Wetmore
bradford.wetm...@oracle.com wrote:
 The draft JEP “TLS Application-Layer Protocol Negotiation Extension” is now
 available for community review:

https://bugs.openjdk.java.net/browse/JDK-8051498

 This JEP is to add support for the Application Layer Protocol Negotiation
 (ALPN) TLS Hello extension [1] in JSSE. ALPN provides a mechanism for
 declaring the application protocols that are supported over a TLS
 connection.

 We need this functionality to make JDK 9, so this JEP needs to get into the
 JEP pipeline soon.  Community review is a precursor in the process before it
 can move to Submitted.

 For now, there is a simple API proposed (similar to JDK 8 SNI), but I'm
 parsing the discussions that took place on security-dev in August[2],
 September[3], and November 2014[4], and the current API is likely not
 flexible enough.

I have taken a quick look at the proposed API as reported here:
https://bugs.openjdk.java.net/browse/JDK-8062848.

I don't think it is enough, since what needs to be provided by the API
is the ability to run application code.
That is the API must be something like:

sslParameters.setALPNSelector(protocols - protocols.get(0));

That is, it should take a lambda of the form:

public String select(ListString protocols);

Also, the lambda would be different for clients and servers.

See my November message for further details:
http://mail.openjdk.java.net/pipermail/security-dev/2014-November/011399.html

Somehow orthogonal to this, the HTTP2 working group has finally
stabilized the requirements for negotiating HTTP2.
For a server that receives a list of ALPN protocols, and that wants to
negotiate h2, it has not only check that both itself and the client
support the h2 protocol, but also that the cipher requirements for
HTTP2 are satisfied.
Note that this requirement only exist for negotiating HTTP2.

While I agree that the major use case for ALPN is HTTP2, ALPN is
nevertheless a generic mechanism to negotiate the application protocol
over TLS, so the HTTP2 cipher selection should not be hardcoded.
So perhaps the JDK should also provide a utility class, say
HTTP2ALPNServerSelector, which implements the before mentioned lambda
adding the specific HTTP2 cipher logic, although this may be out of
scope for this ALPN work.
I mentioned it as a reminder that the API cannot be too closed, as
the protocol selection may need to access contextual information such
as the TSL protocol version, the negotiated cipher, possibly the
server name indication, etc.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: A fully fledged TLS Extensions API ?

2014-11-10 Thread Simone Bordet
Hi,

On Mon, Nov 10, 2014 at 2:07 PM, Florian Weimer fwei...@redhat.com wrote:
 On 11/07/2014 02:06 PM, Simone Bordet wrote:

 This email is about the idea to introduce in JDK 9 a fully fledged TLS
 Extensions API.

 Adding ALPN [0] support to JDK 9 requires, differently from other TLS
 extensions, to provide application code that will be run in the
 context of the TLS implementation, rather than just values such as
 booleans or strings.


 That's going to be interesting if you need to support non-blocking operation
 for use with SSLEngine.

In the case where you have to load the configuration from a place
where it may take a lot of time, you can easily change the ALPN API to
something like:

For the client:
void selected(String protocol, CompletableFutureVoid callback)

For the server:
void select(ListString protocols, CompletableFutureString callback)

and when you're done call callback.complete() or
callback.completeExceptionally().

This would mean that the TLS implementation has to wait for those
callbacks to be completed before proceeding.

On one side, having application code to complete the callbacks is, in
our experience, error prone (i.e. applications forget it)
On the other side, applications that make use of this API are
typically on the implementer side rather than on the developer side
(here I mean people that implement a server, rather than a developer
of a webapp), so I guess a callback, albeit more complex, may give
implementers more room for different implementations.

 IMHO this chance can be lifted to provide a full TLS Extensions API.

 I don't think this is possible because TLS extensions can alter the TLS
 handshake, result in additional messages being exchanged, and generally
 alter the protocol in unforeseeable ways.  On top of that, the concrete TLS
 implementation is not fixed, it can be swapped out, so tying the extension
 API to the existing OpenJDK internals will not work for everyone.

Can you expand what you mean here ?
If a TLS extensions API is provided by JDK 9, would it not be
implemented by providers like they do with the other APIs they have to
implement to be a compliant provider ?
It's a little more effort for providers, but with a public API should
be implementable by any provider and an application would be portable
across providers.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: A fully fledged TLS Extensions API ?

2014-11-10 Thread Simone Bordet
Hi,

On Mon, Nov 10, 2014 at 10:36 PM, Bernd Eckenfels
e...@zusammenkunft.net wrote:
 Hello,

 the question is, what is a extension API actually helping with: the JSSE
 implementation is slow to adopt to typical advances in TLS browser
 wars. While this is not so bad as nobody implements a Web Browser in
 Java anyway, it does make it harder for server vendors to offer a full
 stack (without native libraries or reverse proxies).

Well, JEP 110 (http://openjdk.java.net/jeps/110) is about a HTTP
client that supports h2.
I think it's not too far-fetched to expect jfx/swing widgets, JAX-RS
clients, etc. to support h2 in a close future, so I would not rule out
h2 support for clients.
ALPN would be a prerequisite for h2, since unlikely servers will
implement h2 in the clear.

 Having an API to handle extensions could help with this a bit, however
 a lot of the extensions cannot be bolted on, they alter the handshake
 sequence, introduce new messages or alter interpretatrion of existing
 enums. So while ALPN can be handled pretty easily, it would be harder
 for things like eliptic_curves or supported_signatures or SRP (or Poly
 authenticator) - or TLS_FALLBACK_SCSV (or simple things like rate
 limiting the renegotiations).

For example for the NPN extension to work, it requires collaboration
with the TLS implementation to send a new TLS message at the right
moment.
A JDK 9 client application would be able to add the NPN extension via
the API, but then the JDK would not be able to send the new message at
the right time because NPN won't be implemented in JDK 9.

There are several ways to handle these cases, but I agree that they
may expose an overspecification of the API similar to that of the
collections API: throw UnsupportedOperationException if you can't
handle it (e.g. Iterator.remove()).
Whether there is more advantage for applications to have the API and
risk an UOE, or not having the API and be stuck, I don't know (and
it's the reason for this email, to discuss it :)

A declaration of the impact of an extension on the TLS protocol, akin
to Spliterator.characteristics() may help. Some extensions have no
impact and may be freely added, others require the TLS implementation
cooperation.
A couple more callbacks for [Client|Server]Hello received, for
applications to interact with the extensions for SSLSocket (similar to
HandshakeCompletedListener) would be needed too.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


A fully fledged TLS Extensions API ?

2014-11-07 Thread Simone Bordet
Hi,

I was writing the email about the ALPN API proposal when I realized
that it would have been better to split the arguments in different
emails.

This email is about the idea to introduce in JDK 9 a fully fledged TLS
Extensions API.

Adding ALPN [0] support to JDK 9 requires, differently from other TLS
extensions, to provide application code that will be run in the
context of the TLS implementation, rather than just values such as
booleans or strings.

IMHO this chance can be lifted to provide a full TLS Extensions API.
Alternative providers such as IAIK offer a private API such as [1]:

SSLSocket.getActiveExtensions()
SSLSocket.getPeerExtensions()

Similarly, BouncyCastle offers [2]:

DefaultTlsClient.getClientExtensions()

In the JDK there is a class named SSLParameters that contains some of
the configuration values for TLS.
Some of those are duplicated in SSLSocket and SSLEngine (e.g.
wantClientAuth, needClientAuth, etc), with some temporal dependency
(call this before the other, if I have to trust the comments of
SSLSocketImpl.setHost()).
Eventually all values get forwarded to the handshaker, but from the
API point of view it's not very clear what API one should call (the
one on SSLEngine or the one on SSLParameters), nor where the ALPN
setup should be done.

The idea would then be to introduce a fully fledged TLS extensions API
to handle all the TLS extensions related things, such as
renegotiation, SNI, elliptic curves, NPN, ALPN, session tickets etc.
Both applications and the JDK implementation would be able to leverage
this new API.

Note that the bulk of this API already exists in sun.security.ssl.

My question is really whether JDK 9 could take in consideration such
TLS Extension API be exposed publicly for applications to use it.

See the other emails about ALPN and the interaction between ALPN and
HTTP 2 for further examples of where this TLS Extension API would come
handy.

Thanks !

[0] http://tools.ietf.org/html/rfc7301
[1] 
http://javadoc.iaik.tugraz.at/isasilk/current/iaik/security/ssl/SSLSocket.html
[2] 
https://www.bouncycastle.org/docs/docs1.5on/org/bouncycastle/crypto/tls/DefaultTlsClient.html

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


ALPN HTTP2

2014-11-07 Thread Simone Bordet
Hi,

below you can find few considerations about the interaction between
HTTP 2.0 (from now onwards just h2) and ALPN.

The h2 group at the IETF is having a big debate about section 9.2.2 of
draft-14 [0].
This section basically put a very strong requirement on the ciphers
that can be used to talk h2.
However, clients are entitled to offer weak ciphers and strong
ciphers, but only the strong ones can be used to talk h2.
With this, there is a dependency between the ALPN protocol chosen and
cipher selection; note that cipher selection should happen before the
ALPN server lambda invocation (as I proposed in the other email).

The algorihtm proposed by the h2 editors would be that h2 could only
be chosen by the ALPN server lambda IFF:

!cipher.isStream()  !cipher.isBlock()  cipher.supportsForwardSecrecy()

There is a big resistance among the h2 experts to have this algorithm
defined in the h2 spec, for many reasons. However, the h2 editors are
very resistant to changes (I have to say, backed by the TLS editor).
The fact that almost all TLS implementations out there don't have at
least one (or all) of the methods above (so basically the algorithm
above is not implementable) is not seen as a good enough reason to
remove section 9.2.2.

Furthermore, there is not direct correlation, in the TLS handshake,
between ciphers and protocols.
Speaking of the server side that I know better, the case is that I
take Jetty and run it in the shiny just released JDK 9. The TLS
implementation of JDK 9 adds new ciphers, one of which is named XYZ.
Jetty receives a TLS connection request, with cipher XYZ and ALPN
listing h2. The JDK Jetty runs on has XYZ, but Jetty has no idea
whether this cipher is good for h2 or not.
Jetty may pick XYZ and h2, thus succeeding at both cipher negotiation
(both client and server can use that cipher) and at protocol
negotiation (both client and server can speak h2), but when the client
receives the ServerHello, the client may say oh, no, XYZ is not good
for h2, I offered it for HTTP/1.1, but now it's too late and the only
possible solution is to close the connection, and reopen another one
excluding h2 from the protocols sent to the server (or excluding the
cipher XYZ - but how the client knows if a different cipher will
succeed ?).

Ironically, 9.2.2 may hamper h2 adoption.

Hopefully the h2 group will come to a better decision about section
9.2.2, perhaps without entangling protocol negotiation with cipher
negotiation, but we don't know yet.

In any case, I would suggest that the OpenJDK security-dev leaders
consider to add the capabilities to query a cipher for its properties
to OpenJDK.
There already exist a javax.crypto.Cipher class that perhaps may be
enhanced to expose those methods, along with a way to obtain the
selected Cipher instance from SSLSocket/SSLEngine.

On the same theme, it would not be too far fetched to think that a
server may want to provide h2.domain.com over h2, and h1.domain.com
over HTTP/1.1 for the same certificate *.domain.com.
For this to happen, the server ALPN lambda would need to extract the
SNI extension name, compare it with some virtual host configuration,
and then take a decision about the protocol to speak.
Again, a full fledged TLS Extension API would simplify this:

String sni = SSLEngine.getRemoteExtensions().find(SNIExtension.class).getName();

SNIMatcher won't be able, for example, to match regexp'ed virtual hosts.

In conclusion I'd like to point out the fact that a ALPN API into JDK
9 is a mandatory requisite to implement h2, but may not be sufficient,
since additional methods on Cipher and other TLS classes may be
needed.

Thanks !

[0] http://tools.ietf.org/html/draft-ietf-httpbis-http2-14

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS extensions API, ALPN and HTTP 2.0

2014-10-29 Thread Simone Bordet
Hi,

Another update on the subject.

It seems that the HTTP 2.0 working group has relaxed, after a
excruciating battle, requirements on ciphers and their entanglement
with the ALPN protocols advertised.
This results in many less requirements to have ALPN and HTTP 2.0 work together.

I am reviewing the JDK API and other open source API and will come up
soon with a proposal for the ALPN API.

Sorry for the long delay about this, but the outcome of the HTTP 2.0
working group was important to decide how much was needed in the JDK
for an implementation to be able to implement HTTP 2.0.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS extensions API, ALPN and HTTP 2.0

2014-09-29 Thread Simone Bordet
Hi,

On Sat, Sep 27, 2014 at 4:23 AM, Xuelei Fan xuelei@oracle.com wrote:
 I used to think it is better to have SSLExplorer as a public utility but
 not a part of JSSE, because the extract is not involved in TLS
 transactions.

I am not sure I understand this. Can you expand ?

A number of TLS Extensions are designed to be consumed by
applications: SNI, ALPN, NPN, renegotiation, etc.
Eventually these features crop up in the API (e.g.
SSLParameters.setServerNames()), or even applications need to have
control on whether these extensions have to be added or not (e.g.
ALPN) in a dynamic way that cannot be expressed via system properties.

So I would rather prefer a full fledged extensions API exposed by the
JDK (also to cope with future extensions).

 Please let me know if the SSLExplorer cannot meet your
 requirements.

Definitely not :)

It has too many assumptions on how many bytes have been read, it does
not work for async reads that may read only part of TLS frames, it
parses again the TLS bytes, etc.
Sure we can do all that in the application in order to fullfill
SSLExplorer requirements, but I really hope that is not the way to
solve this problem.
Every application out there would have its own tweaked version of
SSLExplorer, tweaks may introduce vulnerabilities, etc.
The whole point is to have a standard API to rely on.

Internally OpenJDK already does the parsing of the SNI extension, so I
see no point in forcing application to do it again: just expose what's
already been read.

I think we should go the extra mile and just expose in the right way
what's already in the JDK: there already is a ServerNameExtension
class, hopefully there will be NPNExtension, ALPNExtension classes,
etc, all part of the same API, which is available to applications.

As I said before, it seems that ALPN is only one piece required to
support HTTP/2.
The HTTP/2 spec editors are being adamant on cipher requirements, so
for example an application would need to know the type of cipher as
defined by RFC 5246 section 6.2.3: something like cipher.isStream(),
cipher.isBlock(), etc, along with whether the cipher supports forward
secrecy (currently ephemeral key exchange).

I will try to come up with the list of necessary things for HTTP/2,
but I would appreciate any thought on introducing a full fledged TLS
extensions API available to applications to the JDK.
I'd like to know in advance if this is not possible at all.

Thanks !

-- 
Simone Bordet

http://cometd.org
http://webtide.com
http://intalio.com
Developer advice, training, services and support
from the Jetty  CometD experts.
Intalio, the modern way to build business applications.


Re: TLS extensions API, ALPN and HTTP 2.0

2014-09-26 Thread Simone Bordet
Hi,

On Fri, Sep 26, 2014 at 8:03 PM, Sean Mullan sean.mul...@oracle.com wrote:
 On 09/17/2014 01:18 PM, Simone Bordet wrote:

 For the server to differentiate between those 2 connections he would
 need the SNI information, which I don't think it's currently available
 in JDK 8, right ?


 No. It is. We added support for SNI in JDK 8. See:

 http://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#SNIExtension

I understand one cannot extract the string with the SNI name into the
application, you can only match for certificates via SNIMatcher; and
that is the reason for SSLExplorer - to extract the SNI names.
Am I missing something ?

For example, how can I negotiate h2 via ALPN only for certain domains ?

ListString allowedDomains = ... // provided by some server configuration
SNIServerName sniName = ... // what here ?
if (allowedDomains.contains(sniName))
   doALPN();

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS extensions API, ALPN and HTTP 2.0

2014-09-17 Thread Simone Bordet
Hi,

On Tue, Sep 2, 2014 at 11:11 AM, Vincent Ryan vincent.x.r...@oracle.com wrote:
 Your OCA is still being processed. When that has completed your name will be 
 listed at:
   http://www.oracle.com/technetwork/community/oca-486395.html#b

 Until then, we can discuss these TLS/HTTP issues but we cannot include your 
 APIs or source code.

Just an update on this...

While ALPN should offer mechanism independent from the protocol
advertised or the cipher used in the TLS connection, it seems that the
HTTP/2.0 spec has put some constraint that link the protocol
advertised to the ciphers negotiated
(http://tools.ietf.org/html/draft-ietf-httpbis-http2-14#section-9.2.2).
Currently it seems that this HTTP/2 requirement is difficult, if not
impossible, to implement in the JDK.
I am following the HTTP/2 expert group to see if this issue is
resolved, and working on the Jetty code to implement this feature.

The idea being to wait a bit to define the ALPN APIs until this issue
is resolved, to see if the resolution requires changes in the ALPN
APIs.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS extensions API, ALPN and HTTP 2.0

2014-09-17 Thread Simone Bordet
Hi,

On Wed, Sep 17, 2014 at 12:57 PM, Michael McMahon
michael.x.mcma...@oracle.com wrote:
 Hi Simone,

 I'm interested to understand why you think this Http 2 requirement
 is difficult or impossible to implement in the JDK currently.

 I thought, cipher suite selection would be independent of the ALPN
 mechanism.

Indeed they should be independent, but section 9.2.2 poses constraint
and links the h2 protocol with a particular subset of ciphers.

The client can offer 2 ciphers, cipher1 that is valid per 9.2.2 and
will work for h2, and cipher2 that is not valid for h2, but will work
for http/1.1.

At this point, the server has to have a knowledge about what ciphers
are good for what protocol.
Writing this code in a future-proof way is difficult.

Even preferring client ciphers, which is only possible in JDK 8, is
not enough, as we may choose the wrong one if the client sends them
without a particular order.
For example two browsers may send one (cipher1, cipher2), and another
(cipher2, cipher1).

Say that in future cipher FOO is discovered and found to be suitable for h2.
An old h2 client is not aware of FOO, and won't accept it as valid for h2.
But when the old h2 client is deployed in JDK 9, which does offer FOO,
a server can select FOO because the client offered it, negotiate h2,
but the client will close the connection because it won't recognize
FOO as a valid cipher for h2.

My statement about the difficulty of implementation went a bit beyond
about strictly ALPN, but also taking in account server implementations
of h2.

We are trying to have section 9.2.2 modified so that it drops this
linking and leaves everything to TLS (for example by just stating that
a particular version (or greater) of TLS is mandatory for h2, without
mentioning ciphers).

For reference the discussion happens at
http://lists.w3.org/Archives/Public/ietf-http-wg/2014JulSep/2112.html.

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS extensions API, ALPN and HTTP 2.0

2014-09-17 Thread Simone Bordet
See also: https://github.com/http2/http2-spec/issues/612

On Wed, Sep 17, 2014 at 3:17 PM, Simone Bordet simone.bor...@gmail.com wrote:
 Hi,

 On Wed, Sep 17, 2014 at 12:57 PM, Michael McMahon
 michael.x.mcma...@oracle.com wrote:
 Hi Simone,

 I'm interested to understand why you think this Http 2 requirement
 is difficult or impossible to implement in the JDK currently.

 I thought, cipher suite selection would be independent of the ALPN
 mechanism.

 Indeed they should be independent, but section 9.2.2 poses constraint
 and links the h2 protocol with a particular subset of ciphers.

 The client can offer 2 ciphers, cipher1 that is valid per 9.2.2 and
 will work for h2, and cipher2 that is not valid for h2, but will work
 for http/1.1.

 At this point, the server has to have a knowledge about what ciphers
 are good for what protocol.
 Writing this code in a future-proof way is difficult.

 Even preferring client ciphers, which is only possible in JDK 8, is
 not enough, as we may choose the wrong one if the client sends them
 without a particular order.
 For example two browsers may send one (cipher1, cipher2), and another
 (cipher2, cipher1).

 Say that in future cipher FOO is discovered and found to be suitable for h2.
 An old h2 client is not aware of FOO, and won't accept it as valid for h2.
 But when the old h2 client is deployed in JDK 9, which does offer FOO,
 a server can select FOO because the client offered it, negotiate h2,
 but the client will close the connection because it won't recognize
 FOO as a valid cipher for h2.

 My statement about the difficulty of implementation went a bit beyond
 about strictly ALPN, but also taking in account server implementations
 of h2.

 We are trying to have section 9.2.2 modified so that it drops this
 linking and leaves everything to TLS (for example by just stating that
 a particular version (or greater) of TLS is mandatory for h2, without
 mentioning ciphers).

 For reference the discussion happens at
 http://lists.w3.org/Archives/Public/ietf-http-wg/2014JulSep/2112.html.

 --
 Simone Bordet
 http://bordet.blogspot.com
 ---
 Finally, no matter how good the architecture and design are,
 to deliver bug-free software with optimal performance and reliability,
 the implementation technique must be flawless.   Victoria Livschitz



-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS extensions API, ALPN and HTTP 2.0

2014-09-17 Thread Simone Bordet
Hi,

On Wed, Sep 17, 2014 at 4:11 PM, Michael McMahon
michael.x.mcma...@oracle.com wrote:
 Okay, I see the point you are making. It's more a question of whether
 the constraints themselves are appropriate.

And convince the HTTP/2 editors :(

 I've another question. In the work you've done so far, did you allow
 for the possibility of separate certificates to be selected per ALPN
 instance?

 I'm guessing that if multiple applications are to be supported
 over one TCP port (client or server) then different certificates might be
 needed for each application. Or is that not a reasonable assumption?

If I understand you correctly, you are saying that you want a
connection with SNI=foo.domain.com to *not* trigger ALPN, but a
connection with SNI=bar.domain.com to trigger ALPN ?

We don't support this right now in Jetty, but the current ALPN API
probably does: at the moment of selecting the protocol, the
application can retrieve the SNI and decide what protocol to select.
See for example:
http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnection.java#n49
There you can call getSSLEngine(), which will be able to return a
number of information about the handshake (such as the cipher chosen).

Makes sense ?

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: [undertow-dev] NoSuchMethod in 9ea-b30 getRawHostnameSE

2014-09-17 Thread Simone Bordet
Hi,

On Wed, Sep 17, 2014 at 5:04 PM, Bernd Eckenfels e...@zusammenkunft.net wrote:
 Hello,

 thanks Stuart, I should have known to look for this.

 I mentioned before, that this is a quite important thing for JSSE to
 support (or actually the SSL API). But I did not expect that the JEtty
 workaround is already used.

In Jetty we have a mechanism to start the server with ALPN only if we
have the right version of ALPN for the JDK that is running the server.
For example, Jetty would refuse to start with a message in JDK 9 with
ALPN enabled.
A bit harsh, but at least you know what's going on :)

But yes, having ALPN support in JDK 9 will definitely be great.

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS extensions API, ALPN and HTTP 2.0

2014-09-02 Thread Simone Bordet
Hi,

On Wed, Aug 20, 2014 at 1:03 PM, Simone Bordet simone.bor...@gmail.com wrote:
 On Tue, Aug 19, 2014 at 4:11 PM, Vincent Ryan vincent.x.r...@oracle.com 
 wrote:
 Finally, please confirm that you have already signed the OCA [1]

 I have not yet, it's running through legals ATM.
 I'll notify when this is done.

I emailed the signed OCA. Does it need to be processed before we can
talk about the design, or ... ?

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: TLS extensions API, ALPN and HTTP 2.0

2014-08-20 Thread Simone Bordet
Hi,

On Tue, Aug 19, 2014 at 4:11 PM, Vincent Ryan vincent.x.r...@oracle.com wrote:
 Hello Simone,

 Thanks for re-raising this issue. There are indeed plans to add support for 
 ALPN in JDK 9 but they’re still at an
 early stage so the timing is good.

 We would be interested in examining your implementation to explore how it 
 fits into the current TLS APIs.
 Removing the dependency on a boot class path setting is something we should 
 address in JDK 9.

 Would you be interested in co-operating on defining a new public API in JDK 9 
 for ALPN usage in TLS?

Yes.

 Typically, we use the SSLParameters class to support setting the proposed TLS 
 parameters and use the
 SSLSession class to support getting the negotiated TLS parameters. We could 
 easily adopt a similar model
 for ALPN.

I'll have a look, although ALPN is a connection property rather than a
session property.

 Finally, please confirm that you have already signed the OCA [1]

I have not yet, it's running through legals ATM.
I'll notify when this is done.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


TLS extensions API, ALPN and HTTP 2.0

2014-08-18 Thread Simone Bordet
Hi,

I was suggested to restart the discussion about the topic on this list.

I would like to reboot a discussion around an improved TLS extensions
API in order to support ALPN (see http://tools.ietf.org/html/rfc7301), which is
the mechanism required by HTTP 2.0 to negotiate the new version of the
HTTP protocol.

I sent a previous message hoping that such work would have been
included in JDK 8, but it was too late, see
http://mail.openjdk.java.net/pipermail/jdk8-dev/2013-March/002197.html.

I think this needs to be addressed so that a future version of the
Servlet specification can be implemented without requiring the hacks
described below.

Under the Jetty project, we have implemented ALPN as a set of patches
to OpenJDK classes, producing a jar that must be prepended to the boot
classpath in order for ALPN to work, see
https://www.eclipse.org/jetty/documentation/current/alpn-chapter.html.
The downside of this is that for every JDK release the ALPN jar may
need to be rebuilt incorporating JDK changes.
The patches are available at https://github.com/jetty-project/jetty-alpn,
while the API provided to applications is here:
http://git.eclipse.org/c/jetty/org.eclipse.jetty.alpn.git/

While this solution works, it would be great to have a clear API in
the JDK that would allow to add the required TLS extension without
requiring patched classes and boot classpath jars.

This would allow applications to manage easily and in one standardized
way TLS extensions like SNI, ALPN or NPN, chiper suite negotation,
renegotiation, etc.

Most of the classes are already in the sun.ssl.* package, so the effort
would be to clean them up and move them to a standard package.

A) Is there any plan to add a generic TLS extensions API to JDK 9 ?
B) Is there a plan, perhaps in concert with the Servlet EG, to prepare
to support ALPN in order to support HTTP 2.0 ?
C) What would be the process to start the effort to add a TLS
extensions API to the JDK ? Start a new JEP ?

Note that proprietary TLS Extentions API have been provided by other
JSSE implementers such as IAIK, see
http://javadoc.iaik.tugraz.at/isasilk/current/iaik/security/ssl/ExtensionList.html
and its usage in
http://javadoc.iaik.tugraz.at/isasilk/current/iaik/security/ssl/SSLSocket.html.

We are happy to contribute to this effort, but we seek guidance from the
experts in this list.

Thanks !

-- 
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Re: Next Protocol Negotiation TLS Extension

2013-03-25 Thread Simone Bordet
Hi,

On Fri, Mar 22, 2013 at 1:08 AM, Brad Wetmore
bradford.wetm...@oracle.com wrote:
 Hi Simone,

 I haven't looked at the proposal yet, but just from a scheduling point of
 view, unfortunately we're finishing up the implementation of the last of the
 planned features for JDK 8, so getting this into 8 is likely not possible.

Likely not possible means totally impossible or if you do this
and that, then it's possible ? :)

Do you know the status of JEP 114 ? Will it be shipped in JDK 8 ?

 We have an open bug for this (JDK-8007785) and it's on the radar for JDK 9.

Ok, if impossible I will eventually pop up again when JDK 8 is
released and JDK 9 work started.

Thanks !

--
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


Next Protocol Negotiation TLS Extension

2013-03-21 Thread Simone Bordet
Hi all,

[cross-posted to jdk8-dev and security-dev]

I am a member of the Jetty servlet container
(http://eclipse.org/jetty) team and the implementor of the Next
Protocol Negotiation (NPN) TLS Extension used by Jetty to support the
SPDY protocol (API at
http://git.eclipse.org/c/jetty/org.eclipse.jetty.npn.git/ and
implementation at https://github.com/jetty-project/jetty-npn).
The SPDY protocol has been chosen as the basis for HTTP 2.0.

I would like to ask for suggestions for what would be the best way to
have NPN support in OpenJDK 8 rather than via the Jetty NPN
implementation.

Currently, the Jetty implementation is kind of hacky in that it is
the smallest possible hack (in a positive meaning) to make NPN work in
OpenJDK. It modifies 5 sun.security.ssl.* classes and introduces 5 new
classes. These modifies classes must be put in the bootclasspath.
The API of public classes like SSLEngine is not modified; instead the
current implementation relies on a static class that maps SSLEngine
(or SSLSocket) with application code that is invoked at the right time
during the TLS handshake when NPN data is detected.

Currently, the Jetty project maintains the NPN implementation locked
with OpenJDK releases: every time the sun.security.ssl.* classes are
modified, we pull in the changes from OpenJDK, re-patch these classes
with NPN support and make a new release of the NPN jar.

The NPN TLS extension requires an API exposed to applications (usually
web servers, but they are applications for the Java runtime). In
this sense, JEP 114 (http://openjdk.java.net/jeps/114, SNI TLS
extension) is similar: I am guessing it also has to expose an API to
applications.
It seems to me that both NPN and SNI would require a standard way to
access TLS extensions at the proper time during the TLS handshake.
In light of this, it would be great if NPN could be piggybacked on JEP
114, exposing a standard TLS extensions API provided by OpenJDK that
application can use to plug in their code for NPN and/or SNI.

Now, I understand that designing a TLS extensions API is not as simple
as including the current Jetty NPN implementation in OpenJDK, but I
would rather see a generic solution in OpenJDK rather than a hacky
solution like current Jetty NPN's included in OpenJDK.
A private TLS extensions API already exists in the
sun.security.ssl.* classes, but it's mostly package private and of
course under sun.* packages. So perhaps the work to be done is not a
from-scratch effort.

I would like to get a discussion started on how NPN can be supported
in OpenJDK 8.

Ideally, my best plan would be:

* NPN included in JEP 114.
* JEP 114 designing a standard TLS extensions API that can serve for
both NPN and SNI (and, generically, others TLS extensions)
* JEP 114 shipped in OpenJDK 8.

We're happy to keep Jetty NPN up-to-date for OpenJDK 7 releases, but
we will really like to see NPN in OpenJDK 8.

We are open to comply with any legal papers that needs to be in place
for this contribution.

I will be more than happy to provide detailed information about the
implementation of Jetty NPN and have it discussed (or even reviewed)
by security experts.

Thanks !

--
Simone Bordet
http://bordet.blogspot.com
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz