Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[18.0.0.1] SSL certificates issue #4377

Closed
hrstoyanov opened this issue Jul 27, 2018 · 15 comments
Closed

[18.0.0.1] SSL certificates issue #4377

hrstoyanov opened this issue Jul 27, 2018 · 15 comments

Comments

@hrstoyanov
Copy link

Here is an SSL exception I get when trying to communicate with Stripe.Com APIs:

0.2.1.3=US, OID.2.5.4.15=Private Organization was sent from the target host.  The signer might need to be added to local trust store keystore.p12, located in SSL configuration alias defaultSSLConfig.  The extended error message
 from the SSL handshake exception is: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
[ERROR   ] CWPKI0022E: SSL HANDSHAKE FAILURE:  A signer with SubjectDN CN=api.stripe.com, O="Stripe, Inc", L=San Francisco, ST=California, C=US, SERIALNUMBER=4675506, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, OID.1.3.6.1.4.1.311.6
0.2.1.3=US, OID.2.5.4.15=Private Organization was sent from the target host.  The signer might need to be added to local trust store keystore.p12, located in SSL configuration alias defaultSSLConfig.  The extended error message
 from the SSL handshake exception is: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Stripe.Com's certificates are perfectly verifiable by only using the root certificates supplied in JDK's \jre\lib\security\cacerts.

Why is OpenLiberty forcing me to import Stripe's certificates in other keystores? And what happens when Stripe's current certificate expires???

@hrstoyanov
Copy link
Author

This is related to #3117

@hrstoyanov hrstoyanov changed the title SSL certificates issue [18.0.0.1] SSL certificates issue Jul 27, 2018
@aguibert
Copy link
Contributor

@acdemyers FYI

@acdemyers
Copy link
Contributor

Liberty SSL does not use cacerts file by default, it has far to much trust. If users would like to use the cacerts file for trust then they will have to create a SSL configuration and keystore configuration to point to the cacerts file.

@aguibert
Copy link
Contributor

@acdemyers would it be possible to allow a user to opt-into trusting cacerts with a single boolean value? Such as:

<sslDefault trustCACerts="true"/> <!-- default=false -->

@acdemyers
Copy link
Contributor

@aguibert I have never been in favor of doing this kind of special casing in the SSL code. Yet another hidden configuration, then this makes it even more complicated. The hidden defaultSSLConfig can look different depending on a config option. I really think it better for users to add the configuration themselves so the know exactly what they have.

@hrstoyanov
Copy link
Author

hrstoyanov commented Jul 30, 2018

@acdemyers @aguibert
Thank you for discussing this.

I encountered the issue using Stripe.Com's own Java API (arguably, the most popular payment processor for startups). You can just go to https://api.stripe.com with a browser and see the certificate chain (just click on the lock symbol in the address bar). The Stripe own cert is short lived - a few months. It would be major pain to keep rebuilding/deploying thrust store files every few months in production.

However, I was able to import in a trust store the parent certificate (from DigiCert) and use it for Stripe Java API. I think it is valid for about 10 years, so the pain is much smaller, but one still needs to build store file

I think @aguibert suggestion to be able to tap into JDK's cacert is excellent option to have. If these certs are good enough for the JDK, they surely should be good enough for OL. Plus, there would be no need to build key/trust store files.

@acdemyers
Copy link
Contributor

acdemyers commented Jul 30, 2018

@hrstoyanov The thing is you can tap into the jdk's cacerts file, just create a configuration entry to point to it. eg.

<ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" trustStoreRef="defaultTrustStore" />
<keyStore id="defaultKeyStore" password="<password for default key/keystore"/>
<keyStore id="defaultTrustStore" location="<enter path to JDK cacerts file>" type="JKS" password="changeit" />

Or if you are on a level where default keystore gets auto generated you can do have:

<ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" trustStoreRef="defaultTrustStore" />
<keyStore id="defaultTrustStore" location="<enter path to JDK cacerts file>" type="JKS" password="changeit" />

@hrstoyanov
Copy link
Author

.. also, this SSL issue is dependent on the way some vendor's Java webs ervice API is using TLS. For example, using the Amazon AWS Java API 2.0 never exhibited that SSL issue, which I suspect is because they go directly for the JDK's cacerts and are imuine to OL SSL configurations. I have not seen the issue with Auth0.Com (a very popular and affordable JWT single-sigh on provider) Java API either.

@hrstoyanov
Copy link
Author

hrstoyanov commented Jul 30, 2018

@acdemyers Thanks,
I will try your suggestion and point OL to Jdk's cacert store. As I explained, I have also the option to import the parent certificate.

In case some one needs Gradle code to automatically build stores, I hope this would save your some pain:

task deployTLSCertificates {
    def keystore = "${buildDir}/wlp/usr/servers/defaultServer/${server_keystore_location}"
    doLast {
        delete keystore
        exec {
            //Create the key store
            //ignoreExitValue true
            commandLine 'keytool', '-noprompt', '-genkey',
                    '-deststoretype', 'PKCS12',
                    '-keysize', '4096',
                    '-alias', 'replserver',
                    '-keyalg', 'RSA',
                    '-keystore', keystore,
                    '-dname', 'CN=MyCo.Com,OU=MyCo.Com,O=MyCos.Com,L=Irvine,S=California,C=US',S=California, C=US"',
                    '-storepass', "${server_keystore_password}",
                    '-keypass', "${server_keystore_password}"
        }

        //Import all *.cer CA files
        fileTree(dir: "${projectDir}/src/main/liberty/config", include: '**/*.cer').each { file ->
            exec {
                //ignoreExitValue true
                commandLine 'keytool','-noprompt', '-trustcacerts', '-importcert',
                        //'-v',
                        '-alias', file.name.replaceFirst(~/\.[^\.]+$/, ''), //some simple name
                        '-file', file,
                        '-keystore', keystore,
                        '-storepass', "${server_keystore_password}",
                        '-keypass', "${server_keystore_password}"
            }
        }

    }
}

@acdemyers
Copy link
Contributor

@hrstoyanov So do you want to use the JDK's default SSLContext and not Liberty's?

@hrstoyanov
Copy link
Author

hrstoyanov commented Jul 30, 2018

@acdemyers, I probably have to compare Stripe.Com's vs Amazon WAS vs Auth0.Com Java web service wrapper APIs to see why one of them picks up OL SSL config and the other two - don't. I don't intend to use SSL for any other purpose in my app.

Fortunately all of the JAva API wrappers above are open source on github.com, so if I have the time, I will do it.

...Just for the record, I was nearly tempted to ditch all of these vendor Java wrappers and go straight with the newly minted Microprofile Rest Client ... but decided to play it safe. Further, OL allows me to keep my WARs super skinny by moving these vendor APIs in shared libraries - again, if someone want to save some pain and go skinny:

configurations {
    ...
    auth0 { transitive = true }
    aws { transitive = true }
    stripe { transitive = true }
}
...
dependencies{
    providedCompile "software.amazon.awssdk:ses:${aws_version}"
    providedCompile "com.auth0:auth0:${auth0_java_version}"
    providedCompile "com.stripe:stripe-java:${stripe_java_version}"
}
...
task deployAuth0SharedLib(type: Copy) {
    description 'Deploy Auth0 jars into the OpenLiberty shared libs folder.'
    from configurations.auth0
    into "$buildDir/wlp/usr/servers/defaultServer/auth0"
}

task undeployJMustacheSharedLib(type: Delete) {
    description 'Undeploy JMustache shared lib jars'
    delete "$buildDir/wlp/usr/servers/defaultServer/jmustache"
}

task deployAWSSharedLib(type: Copy) {
    description 'Deploy AWS jars into the OpenLiberty shared libs folder.'
    from configurations.aws
    into "$buildDir/wlp/usr/servers/defaultServer/aws"
}

and then in your server.xml:

...
 <library id="auth0Lib">
        <fileset dir="${server.config.dir}/auth0" includes="*.jar" scanInterval="5s"/>
    </library>

    <library id="awsLib">
        <fileset dir="${server.config.dir}/aws" includes="*.jar" scanInterval="5s"/>
    </library>

    <library id="stripeLib">
        <fileset dir="${server.config.dir}/stripe" includes="*.jar" scanInterval="5s"/>
    </library>
     <application context-root="/"
                 type="war"
                 id="my_webapp"
                 location="my-webapp.war"
                 name="myweb app">
        <classloader commonLibraryRef="auth0Lib, awsLib, stripeLib" />
    </application>

@hrstoyanov
Copy link
Author

@acdemyers btw, your example on how to reference JDK's cacert sounds like solution to this issue, fell free to close it

@aguibert
Copy link
Contributor

Thanks for the discussion @hrstoyanov, closing out this issue

@hrstoyanov
Copy link
Author

np, @aguibert
Just one thing to consider - maybe improve the SSL docs a bit. The solution seems straightforward, but it did not occur to me.

@hutchig
Copy link
Contributor

hutchig commented Jul 1, 2019

IBM Event Streams on Cloud Public would also need something like:
<sslDefault trustCACerts="true"/> <!-- default=false -->

They use Let'sEncrypt and refresh server's certificates routinely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants