63

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).

SnakeDoc
  • 13,611
  • 17
  • 65
  • 97
  • Do you control the server? What is its certificate chain? You can see this with `openssl -connect the.server.name:587 -starttls smtp`. – Bruno Sep 11 '13 at 18:38
  • i do control the server, it's here in our office. its out public-facing email server (zimbra). it's signed by godaddy's G2 CA, which uses a chain (chain is installed on the server and the various ssl verification tools online say the chain is valid). – SnakeDoc Sep 11 '13 at 19:04
  • @Bruno - your openssl command won't work for me. says no command `-connect`. i tried ssh also... – SnakeDoc Sep 11 '13 at 19:06
  • Sorry, I meant `openssl s_client -connect the.server.name:587 -starttls smtp`. – Bruno Sep 11 '13 at 20:09
  • hmm... it tells me a whole bunch -- but one of the lines says something about a self-signed cert in the chain. I read up on why that would be, and it appears that it will display that for any cert since somewhere along the cert line, one of them must be self-signed (such as the CA signing it's own cert). So basically, everything looks ok in the command output... – SnakeDoc Sep 12 '13 at 17:05
  • That first line is OK when you're not specifying the CA list in that command. It's the certificate chain that might provide more information, in particular if it's in the right order and goes up to something issued by a CA trusted by the JRE. – Bruno Sep 12 '13 at 17:14
  • @Bruno I just updated the OP to show my cert chain as seen from the openssl command. It looks ok to me? no? – SnakeDoc Sep 12 '13 at 17:34
  • 8
    Just as an update - This is indeed a GoDaddy problem. 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`. – SnakeDoc Jan 14 '14 at 00:03
  • You should probably put this in your own answer to make it more visible. – Bruno Jan 14 '14 at 14:42
  • @Bruno I have added it to the last "`update`" section above. thanks. – SnakeDoc Jan 14 '14 at 15:42
  • Very difficult to understand the question with so many "updates" thrown in everywhere. I find putting updates at the end, in chronological order best. – Richard Brightwell Oct 09 '15 at 15:43
  • @SnakeDoc Is it necessary to give certificate for SSL connection? I am consuming apis in android that are secure with SSL. Is there a way I can consume without certificate. I can't ask question due to limit reach thats why asking here – Zeeshan Nov 26 '15 at 21:00

11 Answers11

45

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 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/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 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).

Once you have a SHA-1 cert signed by the Class 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 a SHA-1 Class 2 CA server signed cert if you plan to work with Java.

SnakeDoc
  • 13,611
  • 17
  • 65
  • 97
  • 2
    This solution worked for me when our windows mobile 6.5 devices would not authenticate with our webservices. Thanks so much for the help – Ben Anderson Feb 28 '14 at 20:37
  • Thanks for your research on this and for sharing. In the Java Control Panel, on the Advanced tab, there is an option for 'Use certificates and keys in browser keystore,' so it should not be checking the cert against the Java keystore (I would think). But when I use Google Chrome, I'm still having a problem... – Baodad Jul 31 '14 at 21:20
  • 3
    I just received an email from GoDaddy today stating that I should rekey my ssl certificate to SHA-2 so it will continue to work flawlessly with Chrome after November. However, in doing so, it will use the G2 CA instead of the Class 2 CA, which will cause it to fail with Java. What to do.. what to do? – Brain2000 Sep 16 '14 at 23:02
  • 2
    I saw the same message as @Brian2000. Full details by GoDaddy on Chrome phasing out SHA-1 is here: https://garage.godaddy.com/webpro/security/google-chrome-phasing-ssl-certs-using-sha-1/ We may be in trouble unless GoDaddy soon adds their G2 CA server the default Java truststore/keystore. – Johnny Oshika Sep 16 '14 at 23:16
  • Personally I think people need to hound on GoDaddy and link them to this page. If I'm the only person who's brought this to their attention, they will shrug it off like they have so far. – SnakeDoc Sep 17 '14 at 15:17
  • Just looked, even on the latest Java8 JDK/JRE, the G2 CA server is still not in the default java truststore. This is about to be a major headache for my company, for one. – SnakeDoc Sep 17 '14 at 22:09
  • I just installed Java 8u38 and I am pleased to report that the G2 CA certificate IS in the default Java truststore! – Brain2000 Jan 26 '15 at 22:47
  • @Brain2000 very nice! Looks like this update just rolled out a few days ago. I'll update my post to make mention upgrading will now fix this... although there's bound to be a lot of individuals who are in positions where they cannot use the latest JRE/JDK and must still with Java7 or something. – SnakeDoc Jan 26 '15 at 22:56
  • @SnakeDoc Looks like the latest Java 7 also has the certificate! I'm reading that it was first added in November. Clearly I've been living under a rock for the last two months. – Brain2000 Jan 27 '15 at 17:23
20

Mr. Fixer and Wayne Thayer's answers have been downvoted, but they are actually advocating the correct work-arounds. In fact, Wayne Thayer leads GoDaddy's SSL business, so he probably knows. You should install the "GoDaddy G1 to G2 Cross" certificate in your certificate chain along with the intermediate certificate.

Downgrading to SHA1 is not an ideal option since it's being deprecated and will cause you more work in the future. Fortunately, GoDaddy has provided a crossover certificate that solves this problem. They posted instructions, which Wayne has duplicated, and they're buried in the comments here.

I have personally tested this solution with a SHA2 cert, and it works well. It's a far superior solution vs. re-keying and downgrading to SHA1. When SHA2 becomes required, this option won't be available anyway, and there might still be Java toolchains out there without the new certificate.

According to GoDaddy support, as of July 2014, the correct root certificate was included in recent versions of Java 8, and in September 2014, Wayne Thayer of GoDaddy also said that the certificate "is scheduled to be added to Java in the next few months". I have checked the cacerts file in Java 8 for Mac OS downloaded from here, and it does indeed contain the SHA2 root certificate.

So instead of your chain looking like this:

  • Go Daddy Root Certificate Authority – G2: (SHA-2) – Hash 47 BE AB C9 22 EA E8 0E 78 78 34 62 A7 9F 45 C2 54 FD E6 8B. This is the root certificate that’s built into some systems (e.g. Chrome). SnakeDoc claims that "it's not built into Java, Windows CE, Microsoft Exchange, and more platforms".
  • Go Daddy Secure Certificate Authority – G2: (SHA-2) – Hash 27 AC 93 69 FA F2 52 07 BB 26 27 CE FA CC BE 4E F9 C3 19 B8
  • Your SHA2 certificate

It should look like this:

  • Go Daddy Class 2 Certification Authority: (SHA-1) – Hash 27 96 BA E6 3F 18 01 E2 77 26 1B A0 D7 77 70 02 8F 20 EE E4. This is the old root certificate that’s built into most systems, including java.
  • Go Daddy Root Certificate Authority – G2: (SHA-2) – Hash 34 0B 28 80 F4 46 FC C0 4E 59 ED 33 F5 2B 3D 08 D6 24 29 64. This is the so-called “GoDaddy G1 to G2 Cross Certificate”.
  • Go Daddy Secure Certificate Authority – G2: (SHA-2) – Hash 27 AC 93 69 FA F2 52 07 BB 26 27 CE FA CC BE 4E F9 C3 19 B8
  • Your SHA-2 Certificate

See also - my blog post summarizing this issue with work-arounds.

  • "GoDaddy has also said that the certificate will be included in future Java releases." can you point to where that is said? This has been an open issue reported multiple times for well over a year (with many java releases in-between), and has been an issue for many years prior to it being reported (the G2 CA server's cert was signed in 2009, so it's been an issue for 5+ years so far). Also it's suspect when brand new and/or no-activity accounts post these work-arounds as answers. – SnakeDoc Nov 28 '14 at 21:29
  • I see you updated your post, but still haven't answered the underlying issue. Godaddy apparently has no plans to fix this, and **your proposed "solution" is not a solution, it is a work-around/hack**. If you try to work with a service that uses a SHA-2 Godaddy SSL cert from Java, it won't trust it, and you won't have any control over it. The solution is for Godaddy to add their G2 CA server into the default Java truststore... something we've been waiting 5+ years for. – SnakeDoc Nov 28 '14 at 22:11
  • Sure, happy to help clarify. I'm not sure why GoDaddy is so unclear on this issue, but [this comment from two month ago](https://garage.godaddy.com/webpro/security/google-chrome-phasing-ssl-certs-using-sha-1/#comment-1593798484) (which I did link to in my answer) is where they say "the GoDaddy G2 root is scheduled to be added to Java in the next few months". I have no interest in defending GoDaddy on this front, but Downgrading to SHA1 is a bad option. This chain will work with services that have their SHA-2 root, their SHA-1 root or both. Can you clarify why you think it's broken? – Isaac Potoczny-Jones Nov 29 '14 at 00:47
  • they are the only major CA I am aware of that requires one to jump through hoops to make their certs compatible with standard devices and platforms. being a CA is not a joke, but godaddy seems to take it lightly. until they actually add their root CA to the default trust store, users should avoid purchasing ssl certs through them. -- I repeat -- It's been 5+ years they have NOT done this. Users have zero control over 3rd party services (api's etc). I personally have notified them multiple times over the past 1+ years. There is no excuse. This is a work-around, not a solution. – SnakeDoc Nov 29 '14 at 05:01
  • 5
    I don't have a dog in this fight. I'm just trying to get the correct workaround out there. You may have a legitimate issue with GoDaddy, but please don't take it out on me or the people who come here looking for a workable solution. The top-voted solution of downgrading to SHA1 is insecure and is not forward-compatible with the SHA1 deprecation. I agree that the root CA needs to get into Java, but a server-side workaround is the only way to deal with Java versions that have already shipped without the cert. Please stop down-voting people who post the workaround that GoDaddy has published. – Isaac Potoczny-Jones Nov 29 '14 at 06:43
  • If you look, the top voted answer was posted in January, well before Google et al announced SHA-1 deprecation. Godaddy's G2 CA server has been around for a minimum of 5 years. Java is not the only platform affected, users are reporting Windows CE, and Microsoft Exchange as well; there are likely many more going unreported. If you look at the blog post by Wayne, it was not posted until after my most recent attempt to convey the gravity of the situation to Godaddy, and that was many months ago. I am not taking anything out on you, but what you posted is no solution, it's a workaround and a hack. – SnakeDoc Nov 29 '14 at 20:25
  • 1
    I did note the timeline and I recognize that this thread is older than GoDaddy's blog post on how to address it. Nevertheless someone has been downvoting the only viable solution for months. This behavior has wasted a huge amount of my time and my team's time. – Isaac Potoczny-Jones Nov 29 '14 at 21:15
  • 1
    I am trying to install the install the cross certificate on Windows 2003. I am following these instructions http://technet.microsoft.com/en-us/library/dd441378(v=office.13).aspx Is this the correct way to install the cross certificate? I have done this but still have the problem. – Dave Dec 10 '14 at 16:45
  • 1
    "Install the GoDaddy G1 to G2 Cross certificate in your certificate bundle file along with the intermediate certificate. " -- How do I do this? I'm running Apache 2.2 – user64141 Mar 24 '15 at 16:29
13

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

[gd_bundle-g2-g1.crt][1] 
Mr. Fixer
  • 141
  • 1
  • 2
  • Are you saying that if the server serving the SSL SHA-2 GoDaddy cert installs this crossover root cert bundle, then Java will be able to connect to it without modifying the java lib/security/cacert chain? – nvioli Oct 02 '14 at 14:47
  • Supposedly you will not have to modify the java cert to get the cross certificate to work. However, I found that the SHA2 G2 certificate is now included in the default Java security store. I installed Java 8u31. – Brain2000 Jan 26 '15 at 22:49
11

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.

Wayne Thayer
  • 121
  • 1
  • 2
4

Following comments and the output of openssl s_client -connect the.server.name:587 -starttls smtp.

In a certificate chain, cert n should be issued by cert n+1 in the list: the issuer (i) of cert n should be the subject (s) of cert n+1.

 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

Here, cert 0 is issued by cert 1 (fine), cert 1 is issued by cert 2 (fine), cert 2 is self-signed (also fine, this is the root CA).

However, cert 2 isn't issued by cert 3. Cert 3 is misplaced (and probably the same as cert 1). This is likely to cause problems, since this makes the chain invalid.

You should at least remove cert 3 from your configuration. In addition, you can also remove cert 2, since having root CAs isn't necessary (it's up to the client to know it anyway).

Bruno
  • 119,590
  • 31
  • 270
  • 376
  • ok, this may be the real issue then. how would I go about removing the 3rd cert? I don't want to remove the entire thing, which is what google seems to return in my search... instead i'd like to just remove the 3rd cert line so that the chain is valid... – SnakeDoc Sep 12 '13 at 18:02
  • 1
    How did you configure your mail server? I'm not sure what kind of configuration Zimbra uses (if that's what you're using). – Bruno Sep 12 '13 at 18:04
  • I used the web-gui "Install Certificate" wizard... which has me upload the 3 necessary files... the cert, the g2 cert, and the bundle-g2 cert. I'm assuming the 3rd cert thing may be left-over from our old expired cert or something? so I guess i should try to remove the cert, then re-apply? – SnakeDoc Sep 12 '13 at 18:08
  • 1
    My guess is that the bundle already contained the g2 cert. One way or another, you really only need 2 certs here: cert 0 (your cert) and cert 1 (the intermediate G2). I'd check the content of the bundle files. You can feed each `--BEGIN/END--` section into `openssl x509 -text -noout` to see what these certs are. – Bruno Sep 12 '13 at 18:12
  • oh wow... you are right. I just opened the gd_bundle-g2.crt and gdig2.crt and both contain the same hash (the bundle contains two hashes, one is the same as the g2ig2.crt and the other is different, so assuming it has both!). It looks like Zimbra will only allow me to install a new cert if I generate a new CSR and have godaddy regenerate their cert... so I guess i'll try it out. – SnakeDoc Sep 12 '13 at 18:16
  • 1
    I'm surprised you need to regenerate the CSR. I would try to reconfigure with the existing certs before going through the CA process again. It looks like there are some command-line tools if the wizard doesn't help: http://wiki.zimbra.com/wiki/Administration_Console_and_CLI_Certificate_Tools I don't really know Zimbra, but it looks Java-based. If you can find where its keystore is, you might be able to re-import the chain with keytool if you've found the right alias (same method as [here](http://stackoverflow.com/a/9300727/372643)). – Bruno Sep 12 '13 at 18:18
  • welp, i jumped the gun and created a new csr and requested a re-key on godaddy (it's free). only downside is the new key doesn't kick in until this evening (6pm and it's only 11:30am here). But I think this will fix this... Yes it's rather strange zimbra would only allow you to install a new cert if there was a current CSR setup for it. Zimbra is 100% java from my understanding... making it javawesome. ;-P – SnakeDoc Sep 12 '13 at 18:32
  • whoops, it's 6pm GMT, making it 11AM PST... so i'll install the new cert now and see what happens. – SnakeDoc Sep 12 '13 at 18:36
  • Ok, see my latest update in the OP. Same exception, but chain looks better now. My guess is java7's default keystore just doesn't trust the godaddy g2 ca yet... hopefully it will be added in the future so I don't have to jump through hoops... – SnakeDoc Sep 12 '13 at 18:47
  • 1
    Just to make sure, have you tried to import that root CA into your `security/cacerts` file with `keytool`? (I'd make a copy of the original file first, also make sure it's the one used by your application, if you have both JDK and standalone JRE installed, for example). – Bruno Sep 13 '13 at 14:57
  • 1
    I was able to basically confirm the G2 CA is not default trusted by java yesterday - see this godaddy link: http://support.godaddy.com/groups/ssl-certificates/forum/topic/ssl-cert-not-recognized-by-java/#post-734093 -- godaddy has their "Class 2 CA" added to the default truststore, but not the "G2 CA". So the gist... it basically wont work by default unless I manually set the keystore to trust that CA on every deployed machine this program will run on... a PITA imho. – SnakeDoc Sep 13 '13 at 15:43
4

if you import de GoDady G2 bundle into the java keystore solves the problem:

export JAVA_HOME=/usr/lib/jvm/java-8-oracle/
wget https://certs.godaddy.com/repository/gd_bundle-g2.crt
$JAVA_HOME/bin/keytool -import -alias root -file ./gd_bundle-g2.crt -storepass changeit -trustcacerts -keystore $JAVA_HOME/jre/lib/security/cacerts
jpereira
  • 648
  • 7
  • 12
1

It sounds like your mail server is not signed by Go Daddy Class 2 Certification Authority, but is actually signed by one of their intermediate certificate authorities. You will need to verify this for yourself. Assuming this is the case...

In theory, your software should work - since the intermediate certificate is signed by the class 2 authority and you have the class 2 authority in the default JDK certificate store. However, I have found that it just does not work unless you also add the intermediate certificate to your certificate store. Here is a link to a blog post describing a similar experience:

http://drcs.ca/blog/adding-godaddy-intermediate-certificates-to-java-jdk/

Here is a direct link to more GoDaddy intermediate certificates: https://certs.godaddy.com/anonymous/repository.pki

I cannot advise on exactly which certificate you must add - it depends on which CA is used in your mail server.

[update]

is there a way to do this programmically?

Maybe. Depends on what you want to do. I have used the java.security.KeyStore class to automatically update a private keystore directly from Java code without using keytool. It is conceptually simple - load the keystore from a file, read the new certificate, add it to the keystore and then write out the keystore to new file. However it takes a while to get the details right and it may not be worth the trouble just to import a single certificate.

Still, it is interesting to try. Checkout KeyStore JavaDoc and read up on the load, store and setCertificateEntry methods.

Guido Simone
  • 7,912
  • 2
  • 19
  • 21
  • +1 as this seems to be the underlying culprit - it is signed by the intermediate authority, not the main Class 2 authority... *rats!* -- the link you posted on how to import the cert seems fine and all, but is there a way to do this programmically? I'd like to avoid having to ship the product with cert files and have some script install them... there's too many variables that could go wrong, such as installation system os, etc... – SnakeDoc Sep 11 '13 at 17:34
  • Ok, I'm going to accept this as the answer, since it's more "proper" solution than my hacky-work-around below. My workaround basically ignores the keystore and says "trust this server's cert", at least from my understanding... making your solution more permanent and elegant. – SnakeDoc Sep 11 '13 at 18:59
  • 5
    FYI, this has been filed as a [JDK bug](https://bugs.openjdk.java.net/browse/JDK-8024889). Note also that GoDaddy has issued a [cross certificate from the G2 to the G1 root](https://certs.godaddy.com/anonymous/repository.pki) (the one used by the mail server). You should be able to download the "Go Daddy G1 to G2 Cross Certificate" and configure the mail server certificate chain to include this certificate at the end of the chain. Then the JRE will be able to build a trusted chain from the G2 root in the cacerts file. – Bill Shannon Sep 16 '13 at 22:07
1

In the "Java Control Panel" I just added the GD Root Certificate to the "Secure Site CA" and I no longer have the cert error when using Java. The cert I added was: Go Daddy Class 2 Certification Authority Root Certificate - G2

lanbrown
  • 19
  • 1
0

Update - this "solution" is no longer valid (see my above accepted answer) - keeping this answer because it did help alleviate the problem so long as the side-effects are tolerable.

Ok, I may have found a work-around for my case.

props.put("mail.smtp.ssl.trust", "smtp.somecompany.com");

I added this to my Session construction, and now it works. This is a work-around, not a fix imho since I still do not know why my Godaddy SSL cert is not default trusted... it is not a self-signed cert.

Anyone please feel free to chime in as I'd really like to understand this problem.

SnakeDoc
  • 13,611
  • 17
  • 65
  • 97
  • 2
    As far as I know, this disables the certificate verification for that particular host, which isn't a good idea. – Bruno Sep 11 '13 at 18:38
  • 1
    right, this is why i call this a work-around instead of a solution. in my particular case, it's a server here at our office, but would still be susceptible to a man-in-the-middle attack since it will always trust whatever cert the server responds with... even if it's changed or wrong. – SnakeDoc Sep 11 '13 at 19:01
0

Here is what you can try. Add the GoDaddy root and intermediate certificates to trust manager at run time. i.e start if the application.

static final String GD_CERT1 = //"-----BEGIN CERTIFICATE-----" "MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx" +"EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT" +"EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp" +"ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3" +"MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH" +"EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE" +"CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD" +"EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi" +"MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD" +"BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv" +"K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e" +"cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY" +"pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n" +"eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB" +"AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV" +"HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv" +"9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v" +"b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n" +"b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG" +"CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv" +"MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz" +"91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2" +"RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi" +"DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11" +"GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x" +"LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB"; //+"-----END CERTIFICATE-----";

static final String GD_CERT2 =
//"-----BEGIN CERTIFICATE-----"
"MIIEfTCCA2WgAwIBAgIDG+cVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVT"
+"MSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIEluYy4xMTAvBgNVBAsTKEdv"
+"IERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMTAx"
+"MDcwMDAwWhcNMzEwNTMwMDcwMDAwWjCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT"
+"B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHku"
+"Y29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1"
+"dGhvcml0eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv3Fi"
+"CPH6WTT3G8kYo/eASVjpIoMTpsUgQwE7hPHmhUmfJ+r2hBtOoLTbcJjHMgGxBT4H"
+"Tu70+k8vWTAi56sZVmvigAf88xZ1gDlRe+X5NbZ0TqmNghPktj+pA4P6or6KFWp/"
+"3gvDthkUBcrqw6gElDtGfDIN8wBmIsiNaW02jBEYt9OyHGC0OPoCjM7T3UYH3go+"
+"6118yHz7sCtTpJJiaVElBWEaRIGMLKlDliPfrDqBmg4pxRyp6V0etp6eMAo5zvGI"
+"gPtLXcwy7IViQyU0AlYnAZG0O3AqP26x6JyIAX2f1PnbU21gnb8s51iruF9G/M7E"
+"GwM8CetJMVxpRrPgRwIDAQABo4IBFzCCARMwDwYDVR0TAQH/BAUwAwEB/zAOBgNV"
+"HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9BUFuIMGU2g/eMB8GA1Ud"
+"IwQYMBaAFNLEsNKR1EwRcbNhyz2h/t2oatTjMDQGCCsGAQUFBwEBBCgwJjAkBggr"
+"BgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20vMDIGA1UdHwQrMCkwJ6Al"
+"oCOGIWh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Ryb290LmNybDBGBgNVHSAEPzA9"
+"MDsGBFUdIAAwMzAxBggrBgEFBQcCARYlaHR0cHM6Ly9jZXJ0cy5nb2RhZGR5LmNv"
+"bS9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAWQtTvZKGEacke+1bMc8d"
+"H2xwxbhuvk679r6XUOEwf7ooXGKUwuN+M/f7QnaF25UcjCJYdQkMiGVnOQoWCcWg"
+"OJekxSOTP7QYpgEGRJHjp2kntFolfzq3Ms3dhP8qOCkzpN1nsoX+oYggHFCJyNwq"
+"9kIDN0zmiN/VryTyscPfzLXs4Jlet0lUIDyUGAzHHFIYSaRt4bNYC8nY7NmuHDKO"
+"KHAN4v6mF56ED71XcLNa6R+ghlO773z/aQvgSMO3kwvIClTErF0UZzdsyqUvMQg3"
+"qm5vjLyb4lddJIGvl5echK1srDdMZvNhkREg5L4wn3qkKQmw4TRfZHcYQFHfjDCm"
+"rw==";
//+"-----END CERTIFICATE-----";

static final String GD_CERT3 =
//"-----BEGIN CERTIFICATE-----"
"MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh"
+"MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE"
+"YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3"
+"MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo"
+"ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg"
+"MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN"
+"ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA"
+"PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w"
+"wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi"
+"EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY"
+"avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+"
+"YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE"
+"sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h"
+"/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5"
+"IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj"
+"YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD"
+"ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy"
+"OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P"
+"TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ"
+"HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER"
+"dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf"
+"ReYNnyicsbkqWletNw+vHX/bvZ8=";
//+"-----END CERTIFICATE-----";

public static void main(String[] args) throws Exception {

    TrustManagerFactory dtmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    dtmf.init((KeyStore) null); // gets you the default trust manager


    X509TrustManager defaultTm = null;
    for (TrustManager tm : dtmf.getTrustManagers()) 
    {
        if (tm instanceof X509TrustManager) 
        {
            defaultTm = (X509TrustManager) tm;
            break;
        }
    }


    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    byte [] decoded = Base64.getDecoder().decode(GD_CERT1);
    ByteArrayInputStream in = new ByteArrayInputStream(decoded);
    Certificate ca1 = cf.generateCertificate(in);
    in.close();

    decoded = Base64.getDecoder().decode(GD_CERT2);
    in = new ByteArrayInputStream(decoded);
    Certificate ca2 = cf.generateCertificate(in);
    in.close();

    decoded = Base64.getDecoder().decode(GD_CERT3);
    in = new ByteArrayInputStream(decoded);
    Certificate ca3 = cf.generateCertificate(in);
    in.close();

    String keyStoreType = KeyStore.getDefaultType();
    KeyStore ks = KeyStore.getInstance(keyStoreType);
    ks.load(null, null);
    ks.setCertificateEntry("cert1", ca1);
    ks.setCertificateEntry("cert2", ca2);
    ks.setCertificateEntry("cert3", ca3);


    TrustManagerFactory gdtmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    gdtmf.init(ks);

    X509TrustManager gdTm = null;
    for (TrustManager tm : gdtmf.getTrustManagers()) 
    {
        if (tm instanceof X509TrustManager) 
        {
            gdTm = (X509TrustManager) tm;
            break;
        }
    }

    TrustManager tms[] = new TrustManager[2];
    tms[0] = gdTm;
    tms[1] = defaultTm;


    try 
    {
         SSLContext sslCtx = SSLContext.getInstance("TLS");
        sslCtx.init(null, tms, new SecureRandom());
    } 
    catch (java.security.GeneralSecurityException e) 
    {
        e.printStackTrace();
        throw e;
    }

     HttpsURLConnection.setDefaultSSLSocketFactory(sslCtx.getSocketFactory());
}

I copied the coded from my working version. so there might be complication error. you just need to work through those.

junaid
  • 21
  • 2
  • 2
-2

If u are using below properties while sending mail, then comment it. This works for me. But this might cause security problem.

props.put("mail.smtp.starttls.enable","true");
Andrey Korneyev
  • 26,353
  • 15
  • 70
  • 71