quarkus: Adding a self-signed certificate to keystore and setting `-Djavax.net.ssl.trustStore` gives PKIX path building failed message

Describe the bug

I have a quarkus native executable that needs to communicate with an endpoint secured with a self signed certificate. When building a container for this, I add my self-signed cert to the trust store and attempt to run the application.

Expected behavior

My executable should see that the self-signed certificate is available in the trust store and use it for communication.

Actual behavior

Fails to find a valid certification path to the target.

To Reproduce Steps to reproduce the behavior:

Given a dockerfile similar to this:

FROM quay.io/quarkus/centos-quarkus-maven:19.3.1-java11 AS build
RUN mkdir -p /tmp/ssl \    
  && cp /opt/graalvm/lib/security/cacerts /tmp/ssl
COPY custom-cert.crt /tmp/ssl
RUN keytool -import -alias self-signed -noprompt -storepass changeit -file /tmp/ssl/custom-cert.crt -keystore /tmp/ssl/cacerts
COPY . /usr/src/app/
RUN mvn --settings /usr/src/app/settings.xml -f /usr/src/app/pom.xml -Pnative clean package                                                                                                                                                                                                                                                                                                                                                                 

FROM registry.access.redhat.com/ubi8/ubi-minimal
WORKDIR /work/                                                                                                                                                                                                                              
COPY --from=build /usr/src/app/target/*-runner /work/application
COPY --from=build /tmp/ssl/ /work
RUN chmod 775 /work /work/application \
        && chown -R 1001 /work \
        && chmod -R "g+rwX" /work \
        && chown -R 1001:root /work
EXPOSE 8080
USER 1001                                                                                                                                                                                                                                              
CMD ["./application", "-Dquarkus.http.host=0.0.0.0", "-Djavax.net.ssl.trustStore=/work/cacerts"]

And an endpoint secured with a self-signed certificate, when the client code attempts to make a connection, you should see PKIX path building failed messages:

Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.ssl.Alert.createSSLException(Alert.java:131)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:320)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:263)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:258)
        at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:641)
        at sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:460)
        at sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:360)
        at sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
        at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
        at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
        at sun.security.ssl.TransportContext.dispatch(TransportContext.java:177)
        at sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
        at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1151)
        at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1062)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1515)
        at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:527)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:334)
        at org.eclipse.che.api.core.rest.DefaultHttpJsonRequest.doRequest(DefaultHttpJsonRequest.java:250)
        at org.eclipse.che.api.core.rest.DefaultHttpJsonRequest.request(DefaultHttpJsonRequest.java:164)
        at org.eclipse.che.incubator.workspace.telemetry.base.AbstractAnalyticsManager.getWorkspace(AbstractAnalyticsManager.java:156)
        ... 27 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:290)
        at sun.security.validator.Validator.validate(Validator.java:264)
        at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:313)
        at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:222)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129)
        at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:625)
        ... 46 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
        ... 52 more

Configuration

# Add your application.properties here, if applicable.
quarkus.ssl.native=true

Screenshots (If applicable, add screenshots to help explain your problem.)

Environment (please complete the following information):

  • Output of uname -a or ver:
  • Output of java -version:
  • GraalVM version (if different from Java):
  • Quarkus version or git rev:
  • Build tool (ie. output of mvnw --version or gradlew --version):

Additional context (Add any other context about the problem here.)

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 33 (16 by maintainers)

Commits related to this issue

Most upvoted comments

FYI, if you’re looking for the docs for this, you can find them at Quarkus - Using SSL With Native Executables

I’m going to try adding the cert to the default trust store path and keeping it in the hard-coded location as per https://quarkus.io/guides/native-and-ssl

You haven’t noticed anything but, while building the image, Quarkus has automatically set javax.net.ssl.trustStore to point to the cacerts file bundled in the GraalVM distribution. This file contains the root certificates.

I think maybe the confusion is in the “Working with containers” section, it says it should work by moving the cacerts to /work/cacerts and passing -Djavax.net.ssl.trustStore