sslv2 and sslv3 compatability or a cert issue? - java

I have a unix script running in server "CCC" from which am calling a servlet running in another server "GGG".(The server GGG is a secure server, having extra firewalls compared to normal server)
Also, the CCC is a ETL server, which is having a JRE. The script is calling the servlet using http, since I rule is applied, so redirection is happening to https, and the port no is also changing.
And am getting a bad certificate error, when i try to invoke the servlet.
The servlet URL when given in normal IE or chrome is giving me a valid response, am able to hit the server GGG.
The error am getting is :
javax.net.ssl.SSLHandshakeException: bad certificate
at com.ibm.jsse.bg.a(Unknown Source)
at com.ibm.jsse.b.a(Unknown Source)
at com.ibm.jsse.b.write(Unknown Source)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:81)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:139)
at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:827)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:1975)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:993)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:397)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:170)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:396)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:324)
at com.tgt.task.client.TaskClient.doGet(TaskClient.java:153)
at com.tgt.task.client.TaskClient.runClient(TaskClient.java:91)
at com.tgt.task.client.TaskClient.completeTask(TaskClient.java:68)
at com.tgt.task.client.TaskClient.main(TaskClient.java:53)
So, initially i checked the certs in cacerts for CCC server, it is having all the root certs, except the cert issued to the URL.
We found the issue started after the BIG IP cert renewal for the URL, i have followed up with my network team to have a look into the issue, they have confirmed that traffic from server CCC is going through fine to GGG passing the firewalls.
So captured the traffic when we tried to invoke the URL, we got the below:
client server SSLV2 282 Client Hello
server client SSLV3 1631 Server Hello
server client SSLv3 433 Certificate
client server SSLV3 190 Alert(Level: Fatal, Description: Bad Certificate)
Can you let me know is the issue because of the SSL versions used by the client and the server ?
or some other thing that i missed out in my analysis.
I even tried to import the cert for the URL in to cacerts in server CCC, but i got the errors:
keytool error: java.lang.Exception: Input not an X.509 certificate
So , i took the PKCS7 cert for the URl and tried to convert it into .cer and tried to import, but got the same error.

If it works with the browser, but not with a script, it has often to do with Server Name Indication (SNI). With SNI you can have multiple hosts with different certificates behind the same IP address. While all current browser support SNI, other implementations might not or might not enable SNI by default. If the client fails to use SNI on a site with multiple certificates behind the same IP it just gets the default certificate, which is often the wrong one.
I don't which Java version you are running, but I suggest you determine your version and then google of how to use SNI with your version. From my understanding SNI was enabled only in Java version 7.

I have checked the captured network packet and found that the URL is providing the correct certificate to the server CCC as per the SSL configuartions at BIG IP end, the client CCC is not able to validate it. And returning a bad certificate message.
here i tried openssl and tried the command:
s_client -connect host:443
verify error:num=20:unable to get local issuer certificate
verify error:num=27:certificate not trusted
verify error:num=21:unable to verify the first certificate
`No client certificate CA names sent`
SSL handshake has read 1745 bytes and written 304 bytes
New, TLSv1/SSLv3, Cipher is RC4-SHA
Server public key is 1024 bit
Compression: NONE
Expansion: NONE
SSL-Session:
Start Time: 1402019174
Timeout : 300 (sec)
Verify return code: 21 (unable to verify the first certificate)
I guess my server is not sending the complete trust chains list, as a result, client is not able to validate it.
Am not sure whether my analysis is correct or not, also i referred the below post:
OpenSSL: unable to verify the first certificate for Experian URL
If i need to send my server to send the complete trusted chain list, where i need to change the settings ? at BIG Ip end, or at server end ?

Related

Spark app not sending intermediate / chain certificates

I've got an app written using the Spark Java framework, with TLS enabled.
See:
Service https = ignite()
.port(8443)
.secure(keystorePath, keystorePass, truststorePath, truststorePass);
This is being served on port 443 via an iptables rule that redirects incoming 443 to 8443.
The problem I am having is that when using the Qualys ssl labs test (https://www.ssllabs.com/ssltest/) the server is not providing the intermediate certificates that have been configured in my truststore.
Similar results occur when I use openssl s_client:
Verify return code: 21 (unable to verify the first certificate)
Along with
depth=0 /OU=Domain Control Validated/OU=PositiveSSL/CN=my.app.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 /OU=Domain Control Validated/OU=PositiveSSL/CN=my.app.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 /OU=Domain Control Validated/OU=PositiveSSL/CN=my.app.com
verify error:num=21:unable to verify the first certificate
verify return:1
From what I can tell, it appears that the server (spark java app, or embedded Jetty I suppose) is not serving up the intermediate certificates for chain validation.
Browsers see the site as secure, but I believe that's because the browsers are downloading the necessary intermediate certificates on their own.
The reason that this is a problem is that I am trying to use Stripe payment webhooks, and they have strict regulations in terms of the TLS cert chain being valid.
I am not sure where to begin on figuring out why these intermediate certs are not being served by my app. Could anyone offer some advice?
I have more or less the same exact problem. I followed the instructions at the Java Spark website (sparse that they are) and only get a Server Error for my efforts.
I imported a third-party certificate in my keystore file. I generated the CSR externally to the java keytool.
I moved the keystone file on the server where the "mydomain.com" exists.
I have the same basic code to do a test "secureHello" (per their documentation), passing the path to the keystore.jks file as the first parameter, and the password as the second.
RESULT: SERVER ERROR.
Not sure what I can try next. Clearly, I'm missing something.
4 hours banging my head on the desk so far (today)...

error while mailing from Java (SSLHandShake Exception)

I am getting following exception while sending mails from Java.
31/03 14:06:19:571 INFO [ ] IBSUtils sendMailfromsmtp() MessagingException in Sending Mail :javax.mail.MessagingException: Can't send command to SMTP host;
nested exception is:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed
It's sending mails in stand alone java programs but while running from JBoss server its throwing this exception. Code has been working from six months but suddenly its starts throwing this exception.
Seems some certificate Expired.
I've ever get this kind of error when my application(IBM Java 1.6) handle connection with webserver(Oracle Java 1.6). There might be Handshake exception while negotiating SSH protocol.
You'd better set your Java protocol manually.
// Using IBM jre there will be a handshake failure as IBM java 1.6 will
// negotiate to server SSLv3 protocol while it SHOULD be TLSv1
System.setProperty("https.protocols", "TLSv1");
Seems some certificate Expired.
Correct. The server certificate has expired. Get it renewed, or complain to them if you can't get it done yourself.
Or else it hasn't come into its validity period yet.
Answering your request on how to get get information about the probably expired certificate:
Find out which server your mail is delivered to. Where this is configured depends on you utility class for sending mail, JEE style is to get it from a mail session configured in jboss.
Assuming you deliver your mail to somehost on port 25 you could use openssl s_client to perform a TLS handshake to get the certificate:
openssl s_client -starttls smtp -crlf -connect somehost:25
This gives you the certificate itself (the base64 encoded part between the "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE----- " delimiters and some basic information abobout it. Store the certificate including the delimiting lines in a file, say cert.pem.
You can then decode it using
openssl x509 -text -noout <cert.pem
This gives you all the information in the certificate as readable text.

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

We have configure a Big F5 load balancer virtual server for a particular IP address which redirects incoming https requests to several Windows servers where there is functionality to generate responses.
I am using SoapUI to test access to these windows servers via the IP address of virtual server in the Big F5.
Using Server and Client certificates generated by the organization where the we have also this set up and sending requests via SoapUI I get the predicted responses back.
The business requirements call for Commercially signed certificates by Thawte.
We created a Certifcate Servcice Request (CSR) to generate a Server certificate and its private key and then we had it signed by Thawte, and also requested a Client Commercially signed certificate from Thawte.
We loaded both certificates in SoapUI client and the Big F5 load balancer but we attempting to test the requests we get the "javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake" error.
My questions are:
How can I monitor where exactly the 2 way SSL handshake is terminated
The actual reason what exactly is happening?.. why using commercially signed certificates this does not work now?
Any replies are welcome. Thanks.
However when we swithch Serverto commercially signed by Thawte
This is possibly due to the Java security feature. If so you need to edit the soapui-4.x.x.vmoptions file located at soapui-4.x.x\bin folder and add -Dsun.security.ssl.allowUnsafeRenegotiation=true to the end.
You may also need to export the certificate as a pfx file and set it up in soapUI preference page. For details you can check http://geekswithblogs.net/gvdmaaden/archive/2011/02/24/how-to-configure-soapui-with-client-certificate-authentication.aspx and http://forums.devarticles.com/java-development-38/javax-net-ssl-sslhandshakeexception-received-fatal-alert-handshake-failure-11809.html .
The client is a SoapUI request that has not changed except a different client certificate
That suggests that the server doesn't trust the new client certificate, which in turn implies that the client certificate wasn't even sent because it wasn't signed by one of the server's trusted signers. Closing the connection is the server's only real option in this circumstance, as there isn't an SSL alert for it.
Make sure you have address translation on and the SNAt set to Auto Map for your VIP

Java SSL connection and UNKNOWN SERVER CERTIFICATE warning

I'm using Netty for asynchronous http(s) requests. When the url for the request is https I'm adding this to the pipeline:
SSLEngine engine = SecureChatSslContextFactory.getClientContext().createSSLEngine();
engine.setUseClientMode(true);
pipeline.addLast("ssl", new SslHandler(engine));
This works well, I get the response back and everything, but a warning is being written to the output saying: UNKNOWN SERVER CERTIFICATE, for example if I issue a request for: https://www.google.com this is what I get:
UNKNOWN SERVER CERTIFICATE: CN=www.google.com, O=Google Inc, L=Mountain View, ST=California, C=US
Since everything is still working it's not that much of an issue for me, but there are two things I would like to know:
Why do I get that warning? googles' certificate is a "well known" one, the browsers don't seem to warn about it. Should I somehow tell the ssl engine where to look for the certificates?
Can I somehow catch this warning at runtime instead of having this message printed out?
Thanks.
Check to make sure that the "trust store" is correctly identified to Netty when you do this, you may have to look at adding ${JAVA_HOME}/jre/lib/security/cacerts as a trusted store.
If that's not configured you probably won't be able to connect over SSL
Dave,
Take a look at the code sample in this thread: Set up Netty with 2-way SSL Handsake (client and server certificate)
I think that will help you with your keystore and truststore setup.

Question on ssl handshake and behavior in java

I am using https to connect to an https server.
Specifically I am using apache httpclient and I configure the ssl context to use my keystore and truststore.
The https server I am using is IIS7 and is configured to require client authentication.
I think I have set it up properly.
Anyway, if I configure the httpClent's ssl context with a keystore (i.e. with client certificates) valid for IIS then there is no problem connecting.
Now my problem is the following:
If I do not configure the ssl context with any client certificate to send to IIS, there is no connection with the server. What makes me think though, is the fact that I was expecting to see some java exception in the code as a result of a hanshake failure alert.
Monitoring what is happening with wireshark, I could not see a certificate request from IIS to my application, but I noticed that after ServerHelloDone everything was encrypted.
I did not expect that. I think the handshake is usually in cleartext.
I used private key to decrypt traces and i saw a certificate request from IIS but after many starting and opening of new connections.
My app send back as a response a certificate of length 0 and IIS replies with a TLSv1 Finished.
After that the packets stop (i.e. seems that the communication ends).
I was expecting a handshake alert.
My question is, is this how it is supposed to work or at least how IIS works?
Or if I do not see the alert something is wrong with my use case?
Thanks
It sounds like IIS is only requiring client certificates for certain URLs (ie, for example.com/foo, but not example.com/bar).
In the initial handshake, it does not know which url you are requesting, so it does not require a certificate. When it sees that you are requesting a restricted resource (/foo), it then rehandshakes, requiring a certificate.
However, I would still expect a handshake_failure to occur.
As I was saying in an answer to this question, as far as I remember, IIS uses re-negotiation to get the client certificate. You should be able to change this behaviour using netsh and clientcertnegotiate=enable (depending on the version of IIS you're using).
You might also be interest in this similar question.
Failing to supply a certificate in response to a CertificateRequest isn't an SSL protocol error, so there is no handshake_error. 'Requiring' instead of just 'needing' client certificates is added-in by SSL libraries, and all they can do if you don't send one is just close the connection.

Categories

Resources