Search code examples
gradlegradlew

gradlew.bat (and gradlew) SSLHandShakeException on wrappers but not on installed gradle


 Downloading https://services.gradle.org/distributions/gradle-2.12-bin.zip

 Exception in thread "main" 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

Similar issue to this:

gradlew.bat (and gradlew) SSLHandShakeException

Except I only get this exception when executing via the wrapper? (Installed local gradle command works without any problems.) I tried the solutions suggested and just cannot get it to work. I even downloaded and installed the certificate from https://services.gradle.org/distributions/ in cacerts

 keytool -import -file "C:\tmp\gradlew.x509.base64.cer" -alias gradle -keystore "C:\Apps\java\jre\lib\security\cacerts"

I got the command from the wrapper:

 java -Dorg.gradle.appname=gradlew -classpath "C:\mystuff\gradle-2.12\samples\java\multiproject\\gradle\wrapper\gradle-wrapper.jar" org.gradle.wrapper.GradleWrapperMain clean

My guess is maybe something is wrong with the certificate itself or maybe I am using the wrong encoding?

 $ java -version
 Picked up _JAVA_OPTIONS: -Xmx512M
 java version "1.7.0_25"
 Java(TM) SE Runtime Environment (build 1.7.0_25-b17)
 Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

To complicate this, I tried installing certificate from gradle using the method suggested here, which appears to have worked (according to output)

http://infposs.blogspot.ca/2013/06/installcert-and-java-7.html

But when I run the wrapper, I still get the same error.


Solution

  • I do not know a lot about SSL certs, but I noticed that when I try to install cert for the url above, 2 certificates are actually returned... Taking a closer look at the java code in InstallCert.java I noticed that it only installs (naively?) the 1st certificate.

    I changed the code in InstallCert.java (added a for loop) and viola, the certificate was installed and gradle and java were happy to exchange handshakes and everyone lived happily ever after.

    Here's the code I changed

    for (int i = 0; i < chain.length; i++) {
    
        final X509Certificate cert = chain[i];
        final String alias = host + "-" + (i + 1);
        ks.setCertificateEntry(alias, cert);
    
        final OutputStream out = new FileOutputStream(file);
        ks.store(out, passphrase);
        out.close();
    
        System.out.println();
        System.out.println(cert);
        System.out.println();
        System.out.println(
                "Added certificate to keystore 'cacerts' using alias '"
                        + alias + "'");
     }
    

    It goes at the end of the main function where the actual keystore methods are called.

    So if you make the modification above to InstallCert.java, solution is pretty simple:

    javac InstallCert.java
    java InstallCert services.gradle.org
    

    By the way what led me to investigate this avenue is when I ran the client against an older version of java (1.6 I think), it spit out the following error:

        java.security.cert.CertPathValidatorException: The certificate issued by ... is not trusted; internal cause is:
        java.security.cert.CertPathValidatorException: Certificate chaining error