I'm using Java Web Start (JWS) to deploy and run my JavaFX application. The jnlp element of my jnlp file is defined as follows:
<jnlp spec="1.0+" xmlns:jfx="http://javafx.com" codebase="http://www.example.com/software" href="MyJnlp.jnlp">
My application successfully launches using the configuration above. I'm now trying to adjust the jnlp file such that the jars are downloaded over SSL. I purchased and installed an SSL certificate for my domain. I've confirmed that the certificate was successfully installed by pointing my browser to https://www.example.com/software/MyJar.jar and verifying that the jar is downloaded.
I updated the jnlpelement of my jnlp file as follows:
<jnlp spec="1.0+" xmlns:jfx="http://javafx.com" codebase="https://www.example.com/software" href="MyJnlp.jnlp">
When I launch the application by double clicking the jnlp file I get a warning from Java stating that "The connection to this website is untrusted" and clicking on "More Information" I see a message stating that "The Certificate Authority that issued the certificate is not trusted" (warnings pictured here)
My SSL certificate relies on a chain of SSL certificates to link it to a root certificate. I opened the Java console and verified that my root certificate is present under the System section of the Secure Site CA "Certificate Type" tab (pictured here).
As a test, I then tried importing my site's SSL certificate to the User section of the Secure Site "Certificate Type" tab. After my site's SSL certificate was imported I no longer received the warning.
Based on this test, it seems to me that Java may not be reading/able to read the intermediate certificates in the certificate chain that links my certificate to a root certificate.
I'd like my users to be able to launch the JWS application over https without importing my site's certificate or being prompted with a warning. Can anyone help?
Upon further investigation, it appears that my original suppositions surrounding the source of the failure may have been incorrect. I used openssl to view the certificate and certificate chain presented by the server hosting my Java Web Start codebase (I'm using openshift). The SSL data showed that although the SSL certificate for my custom domain was being presented, the certificate chain corresponded to RedHat's default SSL configuration (which obviously does not validate my custom domain's certificate).
My-MacBook-Pro:~ username$ openssl s_client -connect www.example.com:443
CONNECTED(00000003)
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
0 s:/C=US/ST=North Carolina/L=Raleigh/O=Red Hat Inc./CN=*.rhcloud.com
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
***CERTIFICATE FOR MY CUSTOM DOMAIN***
-----END CERTIFICATE-----
Since the server was presenting the certificate chain for openshift's default SSL support I decided to change the codebase attribute of my jnlp file to point to Redhat's provided domain which resolved the "Untrusted Connection" error.
I'm satisfied with this outcome. However, to use my custom domain I believe the right course of action would be to follow-up with Redhat to determine why the pem file which included my certificate chain is not being presented when accessing the server using my custom domain name.
Related
I generated a private key pair using KeyStore Explorer that was signed by Sectigo [formerly Comodo] yesterday. The goal is to employ this in an SSL mutual authentication scenario. I work with iWay, a java application, that will post messages to SAP's CPI, a service on cloud. The service on CPI has client authentication enabled [specific to the resource, not at host:port]. I have created a keystore with our private key and a truststore with some public certs in it. In response to a failed communication, I've enabled SSL debug on the application and here are my findings:
*** ServerHelloDone
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
<Empty>
***
This is reported at a stage when server cert was validated and accepted. In order to ensure whether or not the key in question took effect, I verified the logs and noticed the following, which assures that, it did [key name changed for security reasons]:
found key for : self_***.com_priv
I also verified that SAP accepts certificates when signed by valid CAs in the log that looked like this:
Cert Authorities:
...
<CN=USERTrust RSA Certification Authority, O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US>
...
This is how the signed cert look like, when opened on Windows:
I have the following questions:
1) The chain is displayed in the certificate when opened on Windows but not on KeyStore Explorer. Anyone know why?
2) The USERTrust root CA appears to be imported into SAP's trust store based on the log given above. In the picture above, the root cert, although, reported as Sectigo, which happens to be a friendly name, has its issuer name conforming to the one imported onto SAP's trust store:
I hence am not sure why java will not render this cert to SAP during TLS handshake. Any thoughts please?
3) The intermediate certificate has a property named Authority Information Access, in which, a link to its root is present. The properties of this root is entirely different from that of the root I see in picture at item 2 above. Does this matter at all?
Any help will be appreciated. Thanks.
Problem solved. It was due to the way, I imported the CA Reply into my private key. I imported only the signed entity certificate while it looks like I must had imported in PEM format. Thanks to Bruno who have explained the resolution HERE. I am relieved!
I am experiencing an issue when calling web service in my java project. The web service client is running in an java ee application deployed in WebSphere 7. The SSL certificate chain is having the root certificate of Go Daddy Class 2 Certificate Authority. and I do see it in the cacerts file under the WebsPhere JVM folder, but I am keeping getting untrusted certificate error:
java.security.cert.CertPathValidatorException: The certificate issued by OU=Go Daddy Class 2 Certification Authority, O="The Go Daddy Group, Inc.", C=US is not trusted; internal cause is:
java.security.cert.CertPathValidatorException: Certificate chaining error
Cant figure out why getting this error, and how I can resolve this issue. Please help me.
The web service is running in Server A, The client works well when I run it on my machine, the cacerts on my machine includes that root certificate.
When the client get deployed with an web application onto Server A, it doesn't work. We checked the cacerts file, it does include the go daddy root certificate.
When the client and webservice get deployed onto some other envs running with VeriSign certificate chain, it works as well.
Thanks
In my opinion, the CA root public key should be added to your trust store as you are using your server it as a webservice client and not a webservice server.
On your admin console, you should have:
Security->SSL certificate and key management->Key stores and certificates-> NodeDefaultTrustStore-> Signer certificates
Chaining error
You haven't imported the chain correctly, or there is something wrong with it. I use GoDaddy certificates and I don't get chaining errors, so it is more likely the former.
I had the following exception while writing to a SSL socket
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
It seems like the certificate of the target server is not trusted. I tested my implementation on a windows 7 machine, jdk7 and tomcat7 with no problem. The Exception is thrown on ubuntu 10 LTS with openJDK 6 and tomcat7. I got the sha1 and md5 fingerprint of the sockets target server. Am I right that the certificat of the server I am trying to stream to is not trustet on my ubuntu server? can I can the fingerprint to the tomcats keystore? If so, how do I do this?
It's not the fingerprint that you need to add to your trust store, but the actual certificate.
You can add the server certificate itself or add one of the CA certificates in the chain (if you wish to trust the all the certificates from that CA, not just that particular server).
To find out what the certificate is, you can use OpenSSL:
openssl s_client -showcerts -connect your.host.name:443
(Replace the host name and 443 by the actual ports you're using.)
The blocks between --BEGIN/END CERT...-- are the certificates in PEM format. You can check their content using openssl x509 -text -noout (and pasting each block there).
Save the certificate you want to import into a plain text file (e.g. certificate.pem). You should only import certificates that you trust. There's a certain leap of faith here. (You might want to connect with your browser and check whether the key material matches, for example.)
To import into your truststore use:
keytool -importcert -keystore truststore.jks -file certificate.pem
(You may need to specify an alias wit -alias some_name_you_choose.)
If you want this to affect your default truststore, replace truststore.jks with the path to lib/security/cacerts in your Java home directory (the default password should be changeit).
Since the target server seems to come from a well-known CA anyway (and it works with some versions of the JRE), the easiest fix is certainly to update your cacerts file manually, taking a copy from a JRE with which it works. After all, as the JSSE Reference Guide says:
IMPORTANT NOTE: The JDK ships with a limited number of trusted root
certificates in the /lib/security/cacerts file. As
documented in keytool, it is your responsibility to maintain (that is,
add/remove) the certificates contained in this file if you use this
file as a truststore.
Depending on the certificate configuration of the servers you contact,
you may need to add additional root certificate(s). Obtain the needed
specific root certificate(s) from the appropriate vendor.
It turns out it's certainly a problem with the certificate chain order (which is incorrect on this site), as shown by Qualys SSL Labs tester.
I'm trying to set up a test environment for our application that uses X.509 client authentication over HTTPS in Tomcat 6.0. The servlet code is expecting to get a certificate chain as an array of X509Certificate objects using the javax.servlet.request.X509Certificate of the servlet request. However, this array only contains a single item (the client certificate), where I'm expecting it to have two (the client certificate and the root CA certificate that signed it).
Here's what I've done so far:
Generate a self-signed CA certificate using openssl.
Import the CA certificate as a trusted root certificate into a newly create Java keystore.
Configure the Tomcat HTTPS connector to require client authentication using the keystore created in step 2 as the truststore:
clientAuth="true"
truststoreFile="<path_to_truststore>"
Generate a new client certificate using openssl and sign it with the CA certificate.
Start Tomcat.
Install the client certificate in Chrome and navigate to my server's homepage. Stepping through the code in debug, I can see that the array returned as the javax.servlet.request.X509Certificate attribute only has the client certificate.
I know that Tomcat is picking up the root CA certificate from the truststore because when I delete it from the truststore, I get an SSL connection error. It's just not making it into the servlet request like the documentation says it should. Am I missing any additional configuration here? Perhaps Tomcat (or Java or JSSE) is expecting some additional X509 V3 extensions or something?
Any help is appreciated!
EDIT
Looks like my setup is legit, and this falls into the category of unusual but expected behavior due to a simplified test environment. In an enterprise scenario it's unlikely that the root certificate authority is going to be directly signing client certificates for individual users. Clearly when this code was written and tested, there was at least one intermediate CA involved in the trust chain.
What your are seeing is what is expected: Chrome is not sending the CA.
During the TSL Handshake when authenticating the client, the server will send a list of acceptable CAs as part of its CertificateRequest Message (RFC), the browser will then present a Certificate signed by one of these CAs.
ADD
btw, a great way of debugging an SSL connection client side is to use the fantastic openssl tools
openssl s_client -connect ssl.server.com:443
or for SSLV3 only servers
openssl s_client -connect ssl.server.com:443 -ssl3
This will print (among other things) the list of acceptable CAs.
To debug the server side add this to the JVM command line -Djavax.net.debug=ssl
The identity keystore should contain the cert signed by the CA ; not the self-signed cert. The CA root should be in the truststore.
Also, what is the purpose of step 4 ?
I'm connecting to a web service over HTTPS. I've done all that I think is required to make it work, but in the end I get a handshake failure.
I found out that as a new user I can't post more than 2 links due to "spam protection" - thanx a lot stackoverflow...anyway here's a link to a pastebin post with all the links spelled out...so when I write "link#1" here it's a reference to these links: http://pastebin.com/y4zGNRC7
I verified the same behavior using HttpClient (GET on the service URL) and actually calling the web service via a CXF proxy
I'm setting both the keystore and truststore - I tried both the "in code" way ( link#1 ) and setting the system properties - i.e. System.setProperty("javax.net.ssl.keyStore", "mykeystore.jks");
SSL debug is on ( javax.net.debug=all )
SSL debug blurts out the contents of both keystore and truststore (i.e. looks like java "knows about them") - link#2
seems like there's some client-server communication going on, but then it crashes for some reason link#3
I successfully connected to the server using the client and CA certificates both in a browser (Chrome) and using openssl s_client
wireshark shows less client-server talk from java ( link#4 ) then for example from Chrome ( link#5 )
Another strange thing is, that I seem to be getting the same behavior when I set the keystore and when I don't (the only difference is that when I do the keystore contents get printed in the console, but that's it).
I tried googling the problem and I saw numerous similar posts here on stackoverflow, but nothing helped.
I tried changing the protocol version ("TLSv1", "SSLv3", even the weird v2 Hello).
Any help would be appreciated - maybe there's some fundamental thing I might have overlooked...I'm getting desperate here...
Thanx
PS I'm running java 1.6 update 30 on Fedora Core 15 (64bit)
The problem was that even though the keystore and truststore was set, java decided not to send the client certificate to the server. The reason for this was the fact, that the server requested a certificate signed by the RootCA authority, but the client certificate is signed by a SubCA authority (which is issued by the RootCA).
Originally the keystore only contained the client cert and the truststore the SubCA cert.
I then tried to add the SubCA cert to the keystore too, but java just ignored it.
So this solves the hanshake failure mystery, but not my problem.
I created a separate question for that...sigh :-(
why doesn't java send the client certificate during SSL handshake?
I think the trust store not containing the CA is the most likely issue. You can use the Java keytool to import the certificate for the site into the cacerts file doing something like:
keytool -keystore pathtocacerts -import -trustcacerts -v -alias aliasName -file root.crt
The default cacerts keystore password is changeit. The cacerts file is usually under jre/lib/security directory.
You don't provide enough information, but I'm guessing your client truststore is not properly configured. The truststore contains the trusted certificates that are used to sign other certs, and must include the root certificate(s) for the server and client cert chains. The client keystore contains the client SSL certificate and private key.