SSLHandshakeException: Received fatal alert :handshake_failure

Hola forum,

I'm having a bit of a problem with ssl sockets currently. Please bear with me as this is my first run at using ssl sockets for anything and I've done a fair bit of searching on google already.

Here's the code I'm using:

(kindly ignore any typos as they are the result of having to manually type the code in - the code resides on a seperate system).

int port = 443;

String hostname ="hostname";

TrustManager[] trustAllCerts =new TrustManager[]{

new X509TrustManager(){

publicvoid checkClientTrusted(X509Certificate[] arg0, String arg1)throws CertificateExcpetion{}

publicvoid checkServerTrusted(X509Certificate[] arg0, String arg1)throws CertificateException{}

public X509Certificate[] getAcceptedIssuers(){

returnnew X509Certificate[0];

}

SSLContext sslContext = SSLContext.getInstance("SSL");

sslContext.init(null, trustAllCerts,new SecureRandom());

SSLSocketFactory factory = sslContext.getSocketFactory();

SSLSocket socket = (SSLSocket)factory.getSocketFactory(hostname, port);

socket.setUseClientMode9true);

socket.startHandshake();

...

this throws the following exception from startHandshake():

javax.net.ssl.SSLHandhakeException: Received fatal alert: handshake_failure

at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)

at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(Unknown Source)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Uknown Source)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)

at testcode.main(testcode.java 62)

Any insight? I would be most appreciative. Thanks!

[2522 byte] By [cjmosea] at [2007-10-3 3:23:45]
# 1

no replies? well here's an update to the issue. I've since done away with the trust all certs trust manager as I could not get that to work at all. I've imported the certificate (self signed) of the server I'm trying to connect to into a keystore and I'm now getting a validation exception: no trusted certificate found

code added:

KeyStore trustStore = KeyStore.getInstance("JKS");

trustStore.load(new FileInputStream("c:\trustcertstore"), "password".toCharArray());

TrustManagerFactoryu tmf = TrustManagerFactory.getInstance("SunX509");

tmf.init(trustStore);

...

ssslContext.init(null, tmf.getTrustManagers(), new SecureRandom());

I've imported the certificate and I've tried doing it for the default cacerts and currently in my own keystore and all to no avail. How can I track down further what is happening here? Is there any way for me to determine whether this certificate is not valid for the server that is trying to authenicate against it..? (e.g., it was emailed to me and I can't say for certain whether it is the correct cert for the server i am trying to connect to or not).

thanks

edit:

Ok, I set java.net.debug to all and have a bit more information (can't copy and paste as code is on a seperate system and I'm not about to type in the 13+ pages of debugging info).

The first thing I get is

adding as trusted cert:

Subject: CN=anmae ....

Issuer: Cn=samename...

...

now I'm trying to determine if what I see elsewhere means that the cert I was given is not the right one. Specifically elsewhere in debug info I see:

*** Certificate chain

chain [0] = [

[

Version: V3

Subject: CN=adifferentnamethenabove (and the actual host name for what I'm trying to connect to)...

...

no where in the chain[..] entries do I see anything matching the original trusted certificate that I have.

Can anyone provide some insight?

Duke dollars available.

Message was edited by:

cjmose

cjmosea at 2007-7-14 21:16:22 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 2

well, yet some more information. I tinkered around with my keystore and believe I did not have the correct certificate authorities in my keystore. I've latered that and I'm now on to a new issue:

specifically I'm receiveing a SocketException: Software caused connection abort: recv failed

This is happening after the handshake. Does this mean that the server requires client authentication?

thanks!

cjmosea at 2007-7-14 21:16:22 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 3
The TrustManager you showed in the IP won't accept any certificates. Get rid of it and use the standard one.
ejpa at 2007-7-14 21:16:22 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 4

Thanks - The trust manager in the initial post was there originally to ignore certificate validation for test purposes. If you look at the second post I've created a trust manager from a custom trust store (same result if i use the default store though).

I just can't quite figure out why I'm getting this SocketException: recv failed

cjmosea at 2007-7-14 21:16:22 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 5
You're getting a handshake_failure alert from the other end for some reason.Can you turn on -Djavax.net.debug=ssl,handshake,trustmanager at both ends and report.
ejpa at 2007-7-14 21:16:22 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 6

ejp thanks for the reply - unfortunately I have 0 control over the server that I am attempting to establish a connection to and I don't think I can get them to do much of anything (just getting their server certificate was some work).

Could this exception be caused by the server requiring client validation? I checked the various socket settings (forget the property names) but none of them indicated that client validation was required.

Let me know if just the debug on the client side would be helpful and I'll type it in.

--edit, alright here are what I think the relevant parts of the debugging info from the client side(bear with me as this has to be hand transcribed-). Please let me know if more is needed-

found key for : key alias

chain[0] = [

....

]

***

addiing as trusted cert:

...

adding as trusted cert:

...

trigger seeding of SecureRandom

done seeding SecureRandom

dexport control - checking the cipher suites

export control - no cached value available...

export control - storing legal entry into cache...

%% No cached client session

** ClientHello, TLSv1

RandomCookie:...

Session ID: {}

Cipher Suites: ...

Compression Methods: { 0 }

***

main, WRITE: TLSv1 Handshake. length = 73

main, WRITE: SSLv2 client hello message, length = 98

main, READ: TLSv1 Handshake, length = 74

***ServerHello, TSLv1

RandomCookie: ...

Cipher Suite: ...

COmpression Method: 0

***

%% Created: ...

**SSL_RSA_WITH_RC4_128_MD5

main, READ: TLSv1 Handshake, length = 2702

*** Certificate chain

chain [0] = ...

[2] : ...

[3] : ...

[4] : ...

[5] : ...

chain [1] = ...

[2] : ...

[3] : ...

[4] : ...

[5] : ...

chain[2] =...

[2]: ...

***

Found trusted certificate:

....

main, READ: TLSv1 Handshake, length = 278

*** CertificateRequest

Cert Types: RSA, DSS,

Cert Authorities:

...

*** ServerHelloDone

*** Certificate chain

***

*** ClientKeyExchange, RSA PreMasterSecret, TLSv1

Random Secret: ...

main, WRITE: TLSv! Handshake, length = 141

SESSION KEYGEN:

PreMaster Secret:

...

CONNECTION KEYGEN:

Client Nonce:

...

Server Nonce:

...

Master Secret:

...

Client MAC write Secret:

...

Server MAC write Secret:

...

Client write key:

..

Server write key:

...

...no IV for cipher

main, WRITe: TLSv1 Change Cipher spec, length = 1

*** Finished

verify_data: ...

**

main, WRITE: TLSv1 Handshake, length = 32

main, waiting for close_notify or alert: state 1

main, Exception while waiting for close java.net.SocketException: Software caused connection abort: recv failed main, handling exception: java.net.SocketException: Software caused connection abort: recv failed

java.net.SocketException: Software caused connection abort: recv failed

at java.netSocketInputStream.socketRead0(Native Method)

at java.net.SocketInputStream.read(Unknown Source)

at com.sun.net.ssl.interal.ssl.InputRecord.readFully(Uknown Source)

at com.sun.net.ssl.internal.ssl.InputRecord.read(Unknown Source)

at com.sun.net.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)

at com.sun.net.ssl.internal.ssl.SSLCoketImpl.waitForClose(Unknown Source)

at com.sun.net.ssl.internal.ssl.HanshakeOutStream.flush(Unknown Source)

at com.sun.net.ssl.internal.ssl.Handshaker.sendChagneCipherSpec(Unknown Source)

at com.sun.net.ssl.internal.ssl.ClientHandshaker.sendChangeCipherAndFInish(Unknown Source)

at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(Unknown Source)

at com.sun.net.ssl.internal.ssl.CLientHandshaker.processMessage(Unknown Source)

at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)

at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)

at com.sun.net.internal.ssl.SLSocketImpl.startHandshake(Unknown Source)

at https.TestSSLSockets.main(TestSSLSockets.java:104)

thanks again!

Message was edited by:

cjmose

cjmosea at 2007-7-14 21:16:22 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 7

That could be it. There is a CertificateRequest from the server:

*** CertificateRequest

Cert Types: RSA, DSS,

Cert Authorities:

In TLS/SSL the client is entitled to ignore this, and your client is doing so, but Sun have added a 'needClientAuth' setting whereby the server makes the above request and terminates the handshake if it doesn't get a reply.

So your client needs a certificate in its keystore that the server trusts in its truststore.

ejpa at 2007-7-14 21:16:22 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...
# 8
ejp,thanks much - I'll see if I can check with the folks running the server and see if they even know whether they've set it to require client authentication. Is there any way I can check whether this is the case from the socket connection?Thanks again!
cjmosea at 2007-7-14 21:16:22 > top of Java-index,Security,Java Secure Socket Extension (JSSE)...