2015-04-24

StartSSL in Java

Yesterday I had a moment to finally try NetBeans 8.0 against our existing Subversion managed code which I had migrated to an https location with a StartSSL certificate. The web browser and, in my hazy memory of the past, TortoiseSVN clients had had no issue with the new location so I was surprised to run into this error message:

Error validating server certificate for 'https://mysvnrepo.tld:443':
 - The certificate is not issued by a trusted authority. Use the fingerprint to validate the certificate manually!
 I didn't try accepting because that made me think I had something configured incorrectly. My NetBeans 7.3 install was working fine, but it was limping along in CLI mode for Subversion since it isn't updated for the latest Subversion client version to work with my updated working directories.

Some searching around the NetBeans forums lead me to some suggestions for debugging the issue using -Djavax.net.debug=ssl so I whipped up a test application that uses the Java URL class to GET the content of https pages. Accessing sites using GoDaddy certificates worked just fine, but the ones using StartSSL certificates was a no-go.
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
 StartSSL is reasonably new to the CA arena when compared to the likes of Verisign and Thawte, having operated a Certification Authority (CA) since 2005. Their model of operation is appealing, especially to the budget conscious, because you pay for verifications of individuals and organizations, not for issuing of certificates. When you compare their $59.90 fee for a StartSSL Verified status to get access to as many of their class 2/3 certificates as you need to places that charge you $150+/year for each web site certificate and $200+/year for each type of Microsoft Authenticode, Java, and Adobe AIR certificate you start to see why Thawte was worth so much to Verisign who was in turn purchased by Symantec. StartSSL is supported by Microsoft Windows, the major browsers and on mobile devices by having their root certificate included in those browsers and devices.

It isn't included in the Java cacerts file.

To get a CA root certificate added to the cacerts file, a CA is suppose to apply to the Oracle Java Root Certificate program. The startcom / startssl user Admin indicated in 2011 that they have done this with no success. Users have also tried via bug reports to get the certificate included and were rejected saying it must be the CA and not the users that drive CA inclusion.

I think someone has their head on backwards and is facing the wrong crowd. If the developers, the users of your language, are interested in having a CA added then the way they went about requesting it was exactly right. If a bunch of my users or potential users say they will stay with me or start using my product if I add support for API X, there is a strong incentive for me to contact the makers of API X and not wait for them to contact me. I suspect that in the beginning Sun didn't wait for Verisign and Thawte to come ask to be included in their cacerts file. Even Thawte's dead Personal Freemail CA is still in the list and Thawte says it can be dropped in 2011.

Curious what certs are in your Java install's cacerts file? Have keytool tell you. The trick is to tell keytool to list, verbosely, the cacerts keystore who's password by default is changeit. That's a lot of output so you may want to filter it to just the Owner lines.

*nix Shell:
echo 'changeit' | keytool -list -v -keystore $(find $JAVA_HOME -name cacerts) | grep 'Owner:'

Windows Power Shell:
PS C:\Program Files (x86)\Java\jre1.8.0_25\bin> .\keytool -list -v -keystore ..\lib\security\cacerts | select-string -pattern "Owner:"
Enter keystore password:  changeit

What to do?

The real bear is in desktop Java. For our server systems I can add StartSSL to the certificates. For my Subversion issue I can add an exception and if it doesn't stick I can add the StartSSL root to my desktop's cacerts file. It is not very reasonable for anyone but Oracle to add the StartSSL CA root to every end user's cacerts file which puts a damper on using StartSSL to sign Java Web Start applications or applets or access StartSSL signed web sites.

To avoid the Java security code signing restrictions I could switch away from Java Web Start to shipping "executable JAR files", but still I have issues accessing https servers using StartSSL signed certificates even though these sites work fine from the browser and C++/MFC code on windows using the CHttpFile class. I would still need to either add the StartSSL CA root to the cacerts file, disable certificate checking, or avoid the Java URL class and use something else like the Apache Commons HttpClient to dynamically insert trust for StartSSL. Blah.

I could go all-out. Include java.dll and friends and replace javaw(.exe) with MyApp(.exe) that points to my own cacerts file, uses my own icon, and tries harder to act like a native application. No waiting on Oracle. No trying to dynamically modify how certificates are checked. Keep using StartSSL. This would be at the cost of giving up everything Web start and others are doing for me.

Of course I could also stop using StartSSL and switch back to one of the authorities who's root CA key is in Oracle's Java cacerts file, but I wanted to expand the use of HTTPS, not run it at minimal levels. Or I could switch away from Java.

If you care about this issue, maybe we can use social media to raise our voices instead of getting shut down at a bug report for "open"jdk or swept behind the scenes of a CA only apply here forum. Let's see if we can get #startsslinjava trending. Share. Like. Blog. Pass along.
Post a Comment