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.
Related
Environment- windows , java sdk 1.8 , apache http client 4.5.2 , keystore jks , trustore jks.
There is remote server , ssl connection done in both directions.
First part is trustore certifucate check done.
Keystore holds 2 chains of certificates with private keys
Second part is key store client negotiation, at this point , threw handshake there is failure.
After investigeting by wireshark help , problem is that wrong certificate sent back to remote server.
All debug flags are used , remote server sends tcp reset flag.
Weather wrong certificate chain deleted from keystore , handshake works.
Issue began after “wrong” certificate was updated because was expired.
Have to work with both chains
I have configured my Tomcat instance to use SSL on port 8443. I've verified it's working by hitting the main tomcat page thru https:8443 on my browser.
Now I'm trying to understand what I need to do to get a Java program to read from an HTTPS URL on that tomcat server. I followed the instructions here:
Java SSL Tutorial
I just copied the .keystore file down to my client that I generated with Java's keytool on my web server. It is self signed, just for dev work. This seemed a little weird to me since that also has the private key, right? I thought I would do something to export the public key and put that on my client, but I can't find a good guide on what steps I need to for that.
Anyway, when I tried using the .keystore generated on my server in my client, I get this error:
***
%% Invalidated: [Session-1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
main, SEND TLSv1 ALERT: fatal, description = certificate_unknown
main, WRITE: TLSv1 Alert, length = 2
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
I've set my client up to run with these JVM args:
-Djavax.net.ssl.keyStore=.keystore -Djavax.net.ssl.keyStorePassword=changeit -Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol -Djavax.net.debug=ssl
It does print out a bunch of stuff in that .keystore, so I'm sure it is reading it. But the server doesn't seem to like it when it tries to handshake.
What do I need to do to get that SSL Java client reading data from my webserver?
------- edit
Oops, I just noticed I was using the wrong JVM args for client. I changed to this and now it seems get further.
-Djavax.net.ssl.trustStore=.keystore -Djavax.net.ssl.trustStorePassword=changeit
I still haven't gotten it to read URL data yet. And I'm still wondering how to just give the client the public key so it can do its decryption instead of the entire server keystore.
---------- edit #2
Finally got it working. Had a couple of roadblocks along the way:
For some reason I had to make my URLs like this in Eclipse:
URL myurl = new URL("https", host, port, "/docs/setup.html", new sun.net.www.protocol.https.Handler());
HttpsURLConnection con = (HttpsURLConnection)myurl.openConnection();
Otherwise I'd get a class cast exception on the second line.
And, I had to regenerate my server .keystore file and copy to my client with an alternate name like this:
keytool -genkey -alias tomcat -keyalg RSA -ext san=ip:<my server ip>
I'd still like to gain a better understanding of what's needed on the client rather than the whole keystore, but at least I can play around with it now.
Java "keystore" files are used to serve two conceptually different purposes. One purpose is to serve as a key store, which is where one stores key pairs used to prove the machine's own identity. The other purpose is to serve as a trust store, which is used to store information used to identify other machines that one trusts.
You shouldn't copy the server's keystore file onto a client, since as you say it contains the private key of the server, which it contains because the file is a key store for the server. Rather, you want to create your own keystore file that serves as a trust store for the client, in which you want to import the server's certificate so your client will know to trust the server. To do that, you export a certificate from the server's keystore, and then import that certificate into the client's keystore file.
Some more detailed information appears in my related answer to this question:
Secret Key SSL Socket connections in 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 ?
I created a server in Java (Android) with SSLServerSocket with a self-signed certificate and i am trying to connect to the server with wget:
wget https://myAndroidserver:8080 -v --ca-certificate=client.pem --no-check-certificate
but it gives the following error:
OpenSSL: error: 14094410: SSL routines: SSL3_READ_BYTES: SSLv3 handshake failure alert
The following error is logged in my Java application:
error: 140890C7: SSL routines: SSL3_GET_CLIENT_CERTIFICATE: peer did not return a certificate (external/openssl/ssl/s3_srvr.c: 3271 0x5926f79c: 0x00000000)
How to solve it?
If I am reading your question correctly....
**server**:
OpenSSL: error: 14094410: SSL routines: SSL3_READ_BYTES: SSLv3 handshake failure alert
**client**:
error: 140890C7: SSL routines: SSL3_GET_CLIENT_CERTIFICATE: peer did not return a certificate (external/openssl/ssl/s3_srvr.c: 3271 0x5926f79c: 0x00000000)
SSL/TLS is not running on the server at port 8080; or its not serving a certificate.
You can also use OpenSSL's s_client with the -state flag to verify the messages sent and received:
$ openssl s_client -connect encrypted.google.com:443 -state
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read server session ticket A
SSL_connect:SSLv3 read finished A
There's also a -debug flag, but its very verbose and hard to decode. If you are going to perform debug traces, you might as well use Wireshark since it breaks out all the fields in the messages.
Thanks for availability to help.
To resolve the issue follow the steps on this website click here to create the keystore and all file necessary to client and server, and used the bcprov-jdk16-1.45.jar to create keystore (bks) and used this command on client(wget):
wget https://myserver:port --certificate=client.pem --no-check-certificate --private-key=client_key.pem
This website, https://dcs1.noaa.gov, recently updated their SSL certification. Since that change I cannot grab a file from there that I need. I get the following error:
--08:37:12-- https://dcs1.noaa.gov/pdts_compressed.txt
=> `pdts_compressed.txt'
Resolving dcs1.noaa.gov... 205.156.2.181
Connecting to dcs1.noaa.gov|205.156.2.181|:443... connected.
ERROR: Certificate verification error for dcs1.noaa.gov: unable to get local issuer certificate
To connect to dcs1.noaa.gov insecurely, use `--no-check-certificate'.
Unable to establish SSL connection.
I am running Red Hat Linux 4.x and updated all the openssl packages. The usual process I use to access this file is running in Java and uses URL.openStream() to read the file. The command wget also does not work so I am assuming that it is an SSL problem and not a java problem.
the cert is issued by Verisign, probably their root cert is in your servers root cert store. Open the webpage from your machine from a browser and you will see the cert is valid. You can also try to wget from another machine and it will work too.
Probably, the new server certificate is issued by an issuing authority that is not trusted by you. You need to import the issuing authority's certificate in your truststore.
You could try testing the SSL connection with openssl's s_client. I recently had a similar problem and had it resolved. Here's a link to that solution. It also includes information on how to use the s_client to test an SSL connection.
SSL Error: unable to get local issuer certificate