Try to guess the default truststore and path

Tested with OpenJDK 8 and 11. The 'JKS' fallback is for OpenJDK 11.
This commit is contained in:
Florian Schmaus 2020-03-09 13:39:19 +01:00
parent 6440f322fe
commit 00dd77b346
2 changed files with 47 additions and 2 deletions

View File

@ -2304,7 +2304,28 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
ks = null;
}
} else {
ks.load(null, null);
InputStream stream = TLSUtils.getDefaultTruststoreStreamIfPossible();
try {
// Note that PKCS12 keystores need a password one some Java platforms. Hence we try the famous
// 'changeit' here. See https://bugs.openjdk.java.net/browse/JDK-8194702
char[] password = "changeit".toCharArray();
try {
ks.load(stream, password);
} finally {
stream.close();
}
} catch (IOException e) {
LOGGER.log(Level.FINE, "KeyStore load() threw, attempting 'jks' fallback", e);
ks = KeyStore.getInstance("jks");
// Open the stream again, so that we read it from the beginning.
stream = TLSUtils.getDefaultTruststoreStreamIfPossible();
try {
ks.load(stream, null);
} finally {
stream.close();
}
}
}
}

View File

@ -1,6 +1,6 @@
/**
*
* Copyright 2014-2016 Florian Schmaus
* Copyright 2014-2020 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +16,9 @@
*/
package org.jivesoftware.smack.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
@ -29,6 +32,8 @@ import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
@ -45,6 +50,8 @@ import org.jivesoftware.smack.SmackException.SecurityNotPossibleException;
public class TLSUtils {
private static final Logger LOGGER = Logger.getLogger(TLSUtils.class.getName());
public static final String SSL = "SSL";
public static final String TLS = "TLS";
public static final String PROTO_SSL3 = SSL + "v3";
@ -261,4 +268,21 @@ public class TLSUtils {
}
throw new AssertionError("No trust manager for the default algorithm " + defaultAlgorithm + " found");
}
private static final File DEFAULT_TRUSTSTORE_PATH;
static {
String javaHome = System.getProperty("java.home");
String defaultTruststorePath = javaHome + File.separator + "lib" + File.separator + "security" + File.separator + "cacerts";
DEFAULT_TRUSTSTORE_PATH = new File(defaultTruststorePath);
}
public static FileInputStream getDefaultTruststoreStreamIfPossible() {
try {
return new FileInputStream(DEFAULT_TRUSTSTORE_PATH);
} catch (FileNotFoundException e) {
LOGGER.log(Level.WARNING, "Could not open default truststore at " + DEFAULT_TRUSTSTORE_PATH, e);
return null;
}
}
}