Unknown host: java.security.cert.CertificateException: No X509TrustManager implementation available

Hi All -
I thought I had this resolved, but its still a problem when trying to access the WSDL over HTTPS.
It’s a business requirement to use HTTPS even though the webservice is on the same machine.
This is not a problem on a normal Lucee installation, or one done through CommandBox.

When using cfinvoke to consume a webservice - Lucee gives the following error.

java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext)

At the bottom of the stack trace it shows:

Caused by: java.security.UnrecoverableKeyException: Password verification failed
_ at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:778)_

A dump of the java variables from Lucee server shows the correct keystore password in:
javax.net.ssl.trustStorePassword

javax.net.ssl.trustStore shows path at:
/opt/tomcat319/webapps/1364/WEB-INF/lucee-server/context/security/cacerts

Can Lucee be forced to use a different keystore?
Where is the password set within Lucee to access that keystore?

Java 1.8.0_171-b11
JRE path: /opt/java/jdk-8u171/jre

How would someone solve this problem without guessing?

“How would someone solve this problem without guessing?”

“Use the source, Luke.”

The line directly BELOW the line you posted from the sun keystore load would have been where in Lucee it’s calling that function from, and how it’s passing the password. Since you didn’t provide that, I’ll go blindly looking for the string cacerts… And see:

https://github.com/lucee/Lucee/blob/master/core/src/main/java/lucee/runtime/config/ConfigServerImpl.java


        public Resource getSecurityDirectory(){

        Resource cacerts=null;

        // javax.net.ssl.trustStore

        String trustStore = SystemUtil.getPropertyEL("javax.net.ssl.trustStore");

        if(trustStore!=null){

                cacerts = ResourcesImpl.getFileResourceProvider().getResource(trustStore);

        }

        // security/cacerts

        if(cacerts==null || !cacerts.exists()) {

                cacerts = getConfigDir().getRealResource("security/cacerts");

                if(!cacerts.exists())cacerts.mkdirs();

        }

        return cacerts;

        }

It uses the property if specified.

From the cfadmin source


    public static Query getSSLCertificate(Config config,String host, int port) throws PageException {

        Resource cacerts=config.getSecurityDirectory();

        CertificateInstaller installer;

                try {

                        installer = new CertificateInstaller(cacerts,host,port);

                } catch (Exception e) {

                        throw Caster.toPageException(e);

                }

        X509Certificate[] certs = installer.getCertificates();

It doesn’t specify a password, so from CertificateInstaller source:


        public CertificateInstaller(Resource source,String host, int port) throws IOException, KeyStoreException, GeneralSecurityException {

                this(source,host,port,"changeit".toCharArray());

        }

        public CertificateInstaller(Resource source,String host, int port, char[] passphrase) throws IOException, KeyStoreException, GeneralSecurityException {

                this.source=source;

                this.host=host;

                this.port=port;

                this.passphrase=passphrase;

It always uses changeit

Soooooo

Did you change the keystore password?

Was there a reason?

I’ve never seen a cacerts file actually use a different keystore password in production. Nor is there really any reason to, the certs in the file are public information. (given out freely any time you connect to the site itself) If it had private keys, I’d feel differently.

It seems you’re trying to be too clever, and keep shooting yourself in the foot!

Thank you very much for taking the time to post that. I’ll take another look and see if I can be less clever and more smarter. :wink: