users@tyrus.java.net

Re: SSL handshake failures with Android 5.0

From: Matthew Mah <matthew.y.mah_at_gmail.com>
Date: Sun, 18 Jan 2015 11:18:35 -0500

I am not having any luck with enabling the SSL debugging. And it looks
like others have not had success either:
http://stackoverflow.com/questions/4065502/how-to-enable-ssl-debugging-on-the-android-platform

I can debug the server side, which is a Tomcat server. I see the
certificates go out, followed by:
> http-nio-8080-exec-4, called closeOutbound()
> http-nio-8080-exec-4, closeOutboundInternal()
> http-nio-8080-exec-4, SEND TLSv1.2 ALERT: warning, description =
> close_notify
> http-nio-8080-exec-4, WRITE: TLSv1.2 Alert, length = 2
> [Raw write]: length = 7
> 0000: 15 03 03 00 02 01 00

I have also played with the server cipher suites
server.ssl.ciphers = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA

When I run "openssl s_client -connect server:port", I get:
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-SHA
Verify return code: 19 (self signed certificate in certificate chain)

So the server has TLSv1.2, and a cipher that should be supported by
Android 5.0
http://developer.android.com/reference/javax/net/ssl/SSLSocket.html

The self signed certificate is the StartCom root certificate, which is
trusted by Android. I have not figured out yet how to get the openssl
command to trust this, but I suspect this is not an issue because
Android 4.4 has no problems with the certificate.

Do I need to look at the java-based client, or is the openssl
verification sufficient?

Thanks,
Matt

On 01/17/2015 07:26 PM, Petr Janouch wrote:
> Hi,
>
> if you don't know how to pass -Djavax.net.debug=all option as a
> command line argument to your Android application, you can set it in
> the application code before calling clinet.connectToServer() like
> this: |System.getProperties().put(||"javax.net.debug"||, ||"all"||);|
>
> I just hope it is supported on Android and gives as valuable output as
> on Oracle JDK.
>
> ClientProperties.LOG_HTTP_UPGRADE will not help you, because it just
> prints HTTP upgrade messages and is useful to see negotiated headers.
> Your program does not get that far, because it fails below
> HTTP/Websocket level.
>
> I would recommend you to create a simple Tyrus SSL client that would
> connect to the same server as your Android application. Use it on
> Oracle JDK/Open JDK and use -Djavax.net.debug=all to see what
> protocol/cypher suites/certificate is the server trying to use.
>
> Petr
>
>
> On Jan 17, 2015, at 9:12 PM, Matthew Mah wrote:
>
>> Petr,
>>
>> Thank you for the references and example on how to configure SSL/TLS.
>> This is clear and should be very helpful.
>>
>> The exception stack trace is attached for an Android 5 device. I do
>> not find it illuminating.
>>
>> I am not sure how to run Android Studio to pass the option
>> -Djavax.net.debug=all
>>
>> I have enabled the client trace
>> client.getProperties().put(ClientProperties.LOG_HTTP_UPGRADE, true);
>> but unfortunately this prints to standard output, which I can read on
>> an Android 4.4 device (which connects), but not on Android 5 (SSL
>> handshake failure).
>> http://stackoverflow.com/q/26535287/4107809
>>
>> So far merely changing the TLS values on the client has not helped.
>>
>> There are some reports that particular cipher suites are cause
>> problems, I will try changing which are enabled and report back if I
>> make further progress.
>> https://code.google.com/p/android/issues/detail?id=81603
>>
>> Thanks again,
>> Matt
>>
>> On 01/17/2015 09:31 AM, Petr Janouch wrote:
>>> Hi Matt,
>>>
>>> first could you send the entire Exception? The Deployment exception
>>> is just a wrapper and its cause should tell as more.
>>>
>>> If the exception stack trace does not clarify the problem, you can
>>> run your client with -Djavax.net.debug=all and it will print a
>>> detailed SSL debug output. This output might tell you what went
>>> wrong. If it does not, post it here and I will have a look at it
>>> (Just make sure it does not contain any information you don't want
>>> us to see ;) ).
>>>
>>> You can refer to Tyrus documentation where it is shown how o
>>> configure ssl on the client:
>>> https://tyrus.java.net/documentation/1.9/user-guide.html#d0e1128
>>> The link shows how to use
>>> the ClientProperties.SSL_ENGINE_CONFIGURATOR and
>>> classes SslContextConfigurator and SslEngineConfigurator to
>>> configure SSL. You should not use WLS_SSL_PROTOCOLS_PROPERTY, it is
>>> an internal API and therefore it is not documented.
>>>
>>> About how to configure protocols. This page contains the standard
>>> names of protocols and cipher suites:
>>> http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#jssenames
>>> Those are the names that are expected in SslEngineConfigurator
>>> methods parameters.
>>>
>>> Here is a modified sample from the documentation that configures
>>> Tyrus client to use SSL TLS 1 and TLS 1.1 and also prints the result
>>> and the information which protocols are supported on your platform:
>>>
>>> final ClientManager client = createClient();
>>> final SslContextConfigurator defaultConfig = new
>>> SslContextConfigurator();
>>>
>>> defaultConfig.retrieve(System.getProperties());
>>> // or setup SSLContextConfigurator using its API.
>>>
>>> SslEngineConfigurator sslEngineConfigurator =
>>> new SslEngineConfigurator(defaultConfig, true,
>>> false, false);
>>>
>>> sslEngineConfigurator.setEnabledProtocols(new String[]{"TLSv1",
>>> "TLSv1.1"});
>>> // the specified protocols must be supported by the
>>> platform, so just to check:
>>> SSLEngine sslEngine =
>>> sslEngineConfigurator.createSSLEngine("whatever");
>>>
>>> System.out.println("Suported: ");
>>> for (String s : sslEngine.getSupportedProtocols()) {
>>> System.out.println(s);
>>> }
>>>
>>> System.out.println("Enabled: ");
>>> for (String s : sslEngine.getEnabledProtocols()) {
>>> System.out.println(s);
>>> }
>>>
>>> client.getProperties().put(ClientProperties.SSL_ENGINE_CONFIGURATOR,
>>> sslEngineConfigurator);
>>>
>>> Hope this will help.
>>> Petr
>>>
>>> On Jan 17, 2015, at 12:43 AM, Matthew Mah wrote:
>>>
>>>> Could you please elaborate on how this can be done?
>>>>
>>>> From the documentation,
>>>> https://tyrus.java.net/apidocs/1.9/org/glassfish/tyrus/client/ClientManager.htm
>>>>
>>>> I am not sure whether to set WLS_SSL_PROTOCOLS_PROPERTY or the
>>>> ClientProperties.SSL_ENGINE_CONFIGURATOR. It is also not apparent
>>>> what String or array of Strings to use.
>>>>
>>>> https://tyrus.java.net/apidocs/1.9/org/glassfish/tyrus/client/SslEngineConfigurator.html#setEnabledProtocols(java.lang.String[])
>>>>
>>>> Thanks,
>>>> Matt
>>>>
>>>> On 01/16/2015 05:59 PM, Salatiel Filho wrote:
>>>>>
>>>>> Try disable tlsv1.2 And check if it works.
>>>>>
>>>>> On Jan 16, 2015 5:04 PM, "Matthew Mah" <matthew.y.mah_at_gmail.com
>>>>> <mailto:matthew.y.mah_at_gmail.com>> wrote:
>>>>>
>>>>> I am encountering problems connecting Android 5.0 using the
>>>>> tyrus websocket to either nginx or tomcat servers using a
>>>>> secure websocket.
>>>>>
>>>>> javax.websocket.DeploymentException: SSL handshake has failed
>>>>>
>>>>> The code works fine for Android 4.4 , so I think this is
>>>>> related to the SSL changes in Android 5.0:
>>>>> http://developer.android.com/about/versions/android-5.0-changes.html#ssl
>>>>>
>>>>> Is there a way I can tell what exactly is failing? I am not
>>>>> sure whether its a problem with the certificate or with the
>>>>> TLS protocol or the cipher suites available.
>>>>>
>>>>> Thanks,
>>>>> Matt
>>>>>
>>>>
>>>
>>
>> <exceptionStackTrace.txt>
>