org.keycloak.common.crypto.CryptoIntegration Maven / Gradle / Ivy
The newest version!
package org.keycloak.common.crypto;
import java.security.KeyStore;
import java.security.Provider;
import java.security.Security;
import java.util.Comparator;
import java.util.List;
import java.util.ServiceLoader;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import org.jboss.logging.Logger;
import org.keycloak.common.util.BouncyIntegration;
/**
* @author Marek Posolda
*/
public class CryptoIntegration {
protected static final Logger logger = Logger.getLogger(CryptoIntegration.class);
private static final Object lock = new Object();
private static volatile CryptoProvider cryptoProvider;
public static void init(ClassLoader classLoader) {
if (cryptoProvider == null) {
synchronized (lock) {
if (cryptoProvider == null) {
cryptoProvider = detectProvider(classLoader);
logger.debugv("java security provider: {0}", BouncyIntegration.PROVIDER);
}
}
}
if (logger.isTraceEnabled()) {
logger.tracef(dumpJavaSecurityProviders());
logger.tracef(dumpSecurityProperties());
}
}
public static CryptoProvider getProvider() {
if (cryptoProvider == null) {
throw new IllegalStateException("Illegal state. Please init first before obtaining provider");
}
return cryptoProvider;
}
// Try to auto-detect provider
private static CryptoProvider detectProvider(ClassLoader classLoader) {
List foundProviders = StreamSupport.stream(ServiceLoader.load(CryptoProvider.class, classLoader).spliterator(), false)
.sorted(Comparator.comparingInt(CryptoProvider::order).reversed())
.collect(Collectors.toList());
if (foundProviders.isEmpty()) {
throw new IllegalStateException("Not able to load any cryptoProvider with the classLoader: " + classLoader);
} else {
logger.debugf("Detected crypto provider: %s", foundProviders.get(0).getClass().getName());
if (foundProviders.size() > 1) {
StringBuilder builder = new StringBuilder("Ignored crypto providers: ");
for (int i = 1 ; i < foundProviders.size() ; i++) {
builder.append(foundProviders.get(i).getClass().getName() + ", ");
}
logger.debugf(builder.toString());
}
return foundProviders.get(0);
}
}
public static String dumpJavaSecurityProviders() {
StringBuilder builder = new StringBuilder("Java security providers: [ \n");
for (Provider p : Security.getProviders()) {
builder.append(" " + p.toString() + " - " + p.getClass() + ", \n");
}
return builder.append("]").toString();
}
public static String dumpSecurityProperties() {
StringBuilder builder = new StringBuilder("Security properties: [ \n")
.append(" Java security properties file: " + System.getProperty("java.security.properties") + "\n")
.append(" Default keystore type: " + KeyStore.getDefaultType() + "\n")
.append(" KeyManagerFactory.getDefaultAlgorithm(): " + KeyManagerFactory.getDefaultAlgorithm() + "\n")
.append(" TrustManagerFactory.getDefaultAlgorithm(): " + TrustManagerFactory.getDefaultAlgorithm() + "\n")
.append(" keystore.type.compat: " + Security.getProperty("keystore.type.compat") + "\n");
Stream.of("javax.net.ssl.trustStoreType", "javax.net.ssl.trustStore", "javax.net.ssl.trustStoreProvider",
"javax.net.ssl.keyStoreType", "javax.net.ssl.keyStore", "javax.net.ssl.keyStoreProvider")
.forEach(propertyName -> builder.append(" " + propertyName + ": " + System.getProperty(propertyName) + "\n"));
return builder.append("]").toString();
}
public static void setProvider(CryptoProvider provider) {
logger.debugf("Using the crypto provider: %s", provider.getClass().getName());
cryptoProvider = provider;
}
}