diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/TLSUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/TLSUtils.java
index 97dc8597f..cba78280f 100644
--- a/smack-core/src/main/java/org/jivesoftware/smack/util/TLSUtils.java
+++ b/smack-core/src/main/java/org/jivesoftware/smack/util/TLSUtils.java
@@ -16,9 +16,12 @@
*/
package org.jivesoftware.smack.util;
+import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
@@ -285,4 +288,51 @@ public class TLSUtils {
return null;
}
}
+
+ enum DefaultTrustStoreType {
+ jks,
+ unknown,
+ no_default,
+ }
+
+ private static final int JKS_MAGIC = 0xfeedfeed;
+ private static final int JKS_VERSION_1 = 1;
+ private static final int JKS_VERSION_2 = 2;
+
+ public static DefaultTrustStoreType getDefaultTruststoreType() throws IOException {
+ try (InputStream inputStream = getDefaultTruststoreStreamIfPossible()) {
+ if (inputStream == null) {
+ return DefaultTrustStoreType.no_default;
+ }
+
+ DataInputStream dis = new DataInputStream(inputStream);
+ int magic = dis.readInt();
+ int version = dis.readInt();
+
+ if (magic == JKS_MAGIC && (version == JKS_VERSION_1 || version == JKS_VERSION_2)) {
+ return DefaultTrustStoreType.jks;
+ }
+ }
+
+ return DefaultTrustStoreType.unknown;
+ }
+
+ /**
+ * Tries to determine if the default truststore type is of type jks and sets the javax.net.ssl.trustStoreType system
+ * property to 'JKS' if so. This is meant as workaround in situations where the default truststore type is (still)
+ * 'jks' but we run on a newer JRE/JDK which uses PKCS#12 as type. See for example Gentoo bug #712290.
+ */
+ public static void setDefaultTrustStoreTypeToJksIfRequired() {
+ DefaultTrustStoreType defaultTrustStoreType;
+ try {
+ defaultTrustStoreType = getDefaultTruststoreType();
+ } catch (IOException e) {
+ LOGGER.log(Level.WARNING, "Could not set keystore type to jks if required", e);
+ return;
+ }
+
+ if (defaultTrustStoreType == DefaultTrustStoreType.jks) {
+ System.setProperty("javax.net.ssl.trustStoreType", "JKS");
+ }
+ }
}
diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java
index a2c07772a..36e9afda2 100644
--- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java
+++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestFramework.java
@@ -1,6 +1,6 @@
/**
*
- * Copyright 2015-2019 Florian Schmaus
+ * Copyright 2015-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.
@@ -56,6 +56,7 @@ import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smack.util.StringUtils;
+import org.jivesoftware.smack.util.TLSUtils;
import org.jivesoftware.smackx.debugger.EnhancedDebuggerWindow;
import org.jivesoftware.smackx.iqregister.AccountManager;
@@ -71,6 +72,10 @@ import org.reflections.scanners.TypeAnnotationsScanner;
public class SmackIntegrationTestFramework {
+ static {
+ TLSUtils.setDefaultTrustStoreTypeToJksIfRequired();
+ }
+
private static final Logger LOGGER = Logger.getLogger(SmackIntegrationTestFramework.class.getName());
public static boolean SINTTEST_UNIT_TEST = false;