oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀
https://www.graalvm.org
Other
20.18k stars 1.62k forks source link

[gu] does not seem to use the default truststore #2585

Open ddimtirov opened 4 years ago

ddimtirov commented 4 years ago

Describe the issue I need gu to download artifacts from internal caching proxy, that has a certificate issued by the company CA and not traceable to any public CA. Even when I specify the custom trust store, GY complains with:

I/O error occurred: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Steps to reproduce the issue Please include both build steps as well as run steps

  1. Set the following environment variables:
    export JAVA_TOOL_OPTIONS="-Djavax.net.ssl.trustStore=~/acme-cacerts"
    export GRAALVM_CATALOG="file://$(readlink -e acme-graal-updater-component-catalog-java8.properties)"
    export GRAAVLM_CATALOG="$GRAALVM_CATALOG" # see  https://github.com/oracle/graal/issues/2576
  2. Run Gradle, under OpenJDK Java 8 using the Palantir GraalVM plugin
  3. Gradle downloads graalvm-ce-java8-20.1.0-amd64.tar.gz from Nexus
  4. When Gradle tries to run gu install native-image it fails with cert error

Running this reproduces the error:

$GRADLE_USER_HOME/caches/com.palantir.graal/20.1.0/8/graalvm-ce-java8-20.1.0/bin/gu install native-image

It also appears that gu does not pick the JAVA_TOOL_OPTIONS.

I have tried to copy the cacerts in $GRADLE_USER_HOME/caches/com.palantir.graal/20.1.0/8/graalvm-ce-java8-20.1.0/jre/lib/security/, but nothing changes.

Describe GraalVM and your environment:

ddimtirov commented 4 years ago

Looking at another issue, I noticed the --jvm flag. Guessing that it would make SVM behave more like a normal JVM I tried:

 $GRAALVM_HOME/bin/gu --jvm install native-image 

That worked!

Now I've got more questions:

sdedic commented 4 years ago

--jvm actually runs the tool with regular Java VM (GraalVM in this case).

bin/gu --help
GraalVM Component Updater v2.0.0
...
Runtime options:
  --native                                     Run using the native launcher with limited Java access (default).
  --jvm                                        Run on the Java Virtual Machine with Java access.
ddimtirov commented 4 years ago

Thanks, how about the other two questions? Is there a way to make the Gradle Graal plugin work behind firewall, with custom CA?

sdedic commented 4 years ago

Can I specify --jvm by default (i.d. equivalent to JAVA_TOOL_OPTIONS)

No. JAVA_TOOL_OPTIONS (or other env var to inject implicit options) is not supported at the moment by gu (none of the AOTed binaries in Graal supports that, AFAIK).

Is there a different way to specify the default certstore that gu would use? Is it compiled in?

See #1999

ddimtirov commented 4 years ago

Thank you!

ddimtirov commented 4 years ago

For anybody having the same problem, here is a workaround by intercepting the extractGraalTooling task:

tasks.named('extractGraalTooling') { t ->
    doFirst { // touch file, so the task will not try to install it
        def out = (t.outputDirectory as DirectoryProperty ).get().asFile.canonicalPath
        file("$out/bin/native-image").with { File ni ->
            ni.parentFile.mkdirs()
            ni.text = ""
        }
    }
    doLast { // patch the cacerts and install native-image ourselves passing '--jvm'
        def defaultCacerts = System.getProperty("java.home") + "/lib/security/cacerts"
        def cacerts = System.getProperty("javax.net.ssl.trustStore", defaultCacerts)
        def out = (t.outputDirectory as DirectoryProperty ).get().asFile.canonicalPath
        file("$out//jre/lib/security/cacerts").bytes=file(cacerts).bytes
        project.exec {
            executable "$out/bin/gu"
            args "--jvm", "install", "--no-progress", "--force", "--replace", "native-image"
        }
    }
}
hemapunniakotti commented 4 years ago

@ddimtirov I am facing a similar issue...

$gu install native-image Downloading: Component catalog from www.graalvm.org Processing Component: Native Image Downloading: Component native-image: Native Image from github.com I/O error occurred: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target..

I am trying install it mac through commandline. Where can I find the extractGraalTooling task file to make this change ?

ddimtirov commented 4 years ago

Closed by accident (fat fingers, small buttons)

ketanonline commented 3 years ago

I thought I'll demo Graalvm to my colleagues. I picked the best combination Micronaut with Graalvm to showcase the power. But I'm badly doomed by the Graalvm because of this cert error. I wasted 2 days to prepare the sample app. No luck coz Graalvm cli behind proxies just don't work.

Work arounds are just hacks and doesn't work for all.

My request to the authors, most tech companies have their firewalls and proxies before every request over internet. So please fix these issues.

PS: there's no issue in my local machine but it's not behind proxy.

Thanks!

aleqsss commented 2 years ago

Can I specify --jvm by default (i.d. equivalent to JAVA_TOOL_OPTIONS)

No. JAVA_TOOL_OPTIONS (or other env var to inject implicit options) is not supported at the moment by gu (none of the AOTed binaries in Graal supports that, AFAIK).

Is there a different way to specify the default certstore that gu would use? Is it compiled in?

See #1999

Is this still true for gu? I'm trying to use JAVA_TOOL_OPTIONS for the following: -Djavax.net.ssl.trustStore=/path/to/cacerts -Djavax.net.ssl.trustStorePassword=password

By doing the following: JAVA_TOOL_OPTIONS="-Djavax.net.ssl.trustStore=/path/to/cacerts -Djavax.net.ssl.trustStorePassword=password"

Where /path/to/cacerts has been updated with some extra certs we need in our environment.

And then doing: gu install native-image

But still get: I/O error occurred: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Is there still no way to pass these as environment variables?