UPDATE 1/26/2015 -- It appears the most recent JRE/JDK for Java 8 (update >= 31) and JRE/JDK for Java 7 now include the Godaddy G2 CA server in the default trust store. If possible, it's urged you upgrade your JRE/JDK to the latest Java 8 update to resolve this issue.
UPDATE 11/29/2014 -- This is still a problem, and Godaddy appears to not care nor will do anything about it. There is a blog post here by Godaddy VP of Security Products from several months ago saying a fix was on it's way and provided a temporary work-around, but as-of today nothing has changed. It is important to note that Godaddy's G2 CA server has been around for a minimum of 5 years, and in that time Godaddy has not taken the proper steps to resolve this known issue. The work-around provided is just that, a work-around, not a solution. Users of 3rd party services have zero control over how the cert is installed on the server.
It seems users should avoid purchasing Godaddy SSL certs until they get serious about being a CA.
Here is their SSL team's contact info if you feel inclined to call:
GoDaddy SSL Team Support Number: 1-480-505-8852 -- Email: ra@godaddy.com
UPDATE 9/17/2014 -- This is still a problem, and Godaddy appears to not care nor will do anything about it. Come November when Google deprecates all SHA-1 certs, this will become a major issue. I highly recommend anyone who can contact Godaddy and point them here.
~
tl;dr; - final update with current solution/workaround at the bottom of this post (it is a GoDaddy problem and there is a workaround until they fix it)
I have a mail server that I'm attempting to send mail through from my Java app. I can sent on port 25 successfully so I know code works and all, but 25 is not encrypted session. I need to use TLS on port 587 which requires an SSL cert. I have a valid SSL Cert on the server that is signed by GoDaddy G2 CA and has been in place for a while now (no problems).
My issue, is I'm getting the famed PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
error message when trying to connect and send mail on 587.
From my understanding of many SO links as well as normal google-fu, this is usually caused when Java doesn't trust the cert or CA -- as is common for a self-signed cert. I've used several of the online SSL Cert checkers to make sure the chain is valid, etc. All appears to be normal... but java will not use the cert automatically.
I am aware there is a class file somewhere from Sun that will download and setup the cert in the local keystore so java will trust it... but this is not only impractical for an app that will be deployed to multiple systems, but is just silly for a Godaddy signed cert.
What's going on? How can I make java use the valid cert on the server without having to make java accept all certs?
EDIT: I just looked in my windows Java Control Panel (default install of jdk 7) and sure enough, under Signer CA
the Issued By: The Go Daddy Group, Inc. Go Daddy Class 2 Certification Authority
is listed... so what gives? My cert is a Godaddy cert...
UPDATE --
Here's the cert chain as-seen from openssl command recommended in comments:
~]# openssl s_client -connect smtp.somecompany.com:587 -starttls smtp
CONNECTED(00000003)
depth=2 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
verify error:num=19:self signed certificate in certificate chain
verify return:0
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=smtp.somecompany.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
2 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
3 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
---
Looks ok to me I think...
UPDATE 2 --
Ok, thanks to @Bruno I was able to determine my chain was messed up -- I re-keyed the server and now my chain appears as such:
~]# openssl s_client -connect smtp.somecompany.com:587 -starttls smtp
CONNECTED(00000003)
depth=2 C = US, ST = Arizona, L = Scottsdale, O = "GoDaddy.com, Inc.", CN = Go Daddy Root Certificate Authority - G2
verify error:num=19:self signed certificate in certificate chain
verify return:0
---
Certificate chain
0 s:/OU=Domain Control Validated/CN=smtp.somecompany.com
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
1 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
2 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
i:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
---
Which looks better than before. -- Java still throws the same exception about the cert path, etc. So it appears that the G2 cert chain is not, by default, trusted yet in java 7's default keystore.
FINAL UPDATE FOR COMPLETENESS @ 1/14/2014
Just as an update - This is indeed a GoDaddy problem (I've had lengthy support emails with them). They have 2 CA servers, one called Class 2 CA
and the other called G2 CA
. Their Class 2 CA
signs all SHA-1
certificates, while the G2 CA
signs all their SHA-2
certificates. This is where the problem lies - GoDaddy has not added their newer G2 CA
server to the default java truststore - causing default java installations to not trust it's authority, and hence, does not trust your chained certificate. The work-around until GoDaddy adds the G2 CA
server to the default truststore is to simply rekey your cert using SHA-1
as-to get a cert signed by the Class 2 CA
server. Rekeying is free for GoDaddy customers until your cert expires (obviously).
If u are using below properties while sending mail, then comment it. This works for me. But this might cause security problem.
if you import de GoDady G2 bundle into the java keystore solves the problem:
UPDATE 1/26/2015 -- It appears the most recent JRE/JDK for Java 8 (update >= 31) and JRE/JDK for Java 7 now include the Godaddy G2 CA server in the default trust store. If possible, it's urged you upgrade your JRE/JDK to the latest Java 8 update to resolve this issue.
UPDATE 11/29/2014 -- This is still a problem, and Godaddy appears to not care nor will do anything about it. There is a blog post
[here][1]
by Godaddy VP of Security Products from several months ago saying a fix was on it's way and provided a temporary work-around, but as-of today nothing has changed. It is important to note that Godaddy's G2 CA server has been around for a minimum of 5 years, and in that time Godaddy has not taken the proper steps to resolve this known issue. The work-around provided is just that, a work-around, not a solution. Users of 3rd party services have zero control over how the cert is installed on the server.It seems users should avoid purchasing Godaddy SSL certs until they get serious about being a CA.
Here is their SSL team's contact info if you feel inclined to call:
GoDaddy SSL Team Support Number: 1-480-505-8852 -- Email: ra@godaddy.com
UPDATE 9/17/2014 -- This is still a problem, and Godaddy appears to not care nor will do anything about it. Come November when Google deprecates all SHA-1 certs, this will become a major issue. I highly recommend anyone who can contact Godaddy and point them here.
~~~~
My initial post/question was regarding why my chain was not working. It became obvious I had a bad setup (which was quickly fixed with some advice from @Bruno and others - thanks). However, when my corrected chain still did not work with Java, it became apparent there was a much bigger problem lurking. It took a while, but the problem is actually with GoDaddy.
This actually is indeed a GoDaddy problem (I've had lengthy support emails with them).
They have 2 CA servers, one called
Class 2 CA
and the other calledG2 CA
. TheirClass 2 CA
signs allSHA-1
certificates, while theG2 CA
signs all theirSHA-2
certificates.This is where the problem lies - GoDaddy has not added their newer
G2 CA
server to the defaultJava truststore/keystore
- causing default Java installations to not trust it's authority, and hence, does not trust your chained certificate.The work-around until GoDaddy adds the
G2 CA
server to the default truststore/keystore is to simply rekey your cert usingSHA-1
as-to get a cert signed by theClass 2 CA
server. Rekeying is free for GoDaddy customers until your cert expires (obviously).Once you have a
SHA-1
cert signed by theClass 2 CA
server, your trust chain should work as expected and no custom truststore/keystore imports and/or setup is required.It does not make me happy that I must use a "weaker" cert in order to get it to work properly, and discussions with GoDaddy via email support thus far have indicated they have no current plans to add the
G2 CA
server to the default truststore/keystore. I guess until they do add it, make sure you get aSHA-1
Class 2 CA
server signed cert if you plan to work with Java.Mr. Fixer is right. Install the "GoDaddy G1 to G2 Cross" certificate in your certificate bundle file along with the intermediate certificate. This allows GoDaddy SHA-2 certificates to be trusted by any client that recognizes the SHA-1 roots including Java. You can get this file from https://certs.godaddy.com/repository Once this is installed, Java will build a certificate chain from your certificate to the "GoDaddy Secure Server Certificate (Intermediate Certificate)" to the "GoDaddy G1 to G2 Cross Certificate" to the GoDaddy SHA-1 root. You can also find a bundle file containing the cross certificate in our repository. One last note on this option: The signatures on root certificates aren't checked so even though you're relying on a SHA-1 root, this is just as secure as a full SHA-2 certificate chain.
To get Godaddy certificates to work in Java with SHA2 you will need to use their cross certificate in your chain to chain the G2(SHA2) root to the G1(SHA1) root until Java decides to update their repository. The Cross Certificate bundle can be downloaded here:
https://certs.godaddy.com/anonymous/repository.pki
GoDaddy Certificate Bundles - G2 With Cross to G1, includes Root