// 
// Decompiled by Procyon v0.6.0
// 

package io.netty.handler.ssl.util;

import io.netty.util.internal.logging.InternalLoggerFactory;
import java.security.AccessController;
import io.netty.util.internal.ThrowableUtil;
import java.security.Security;
import javax.net.ssl.SSLEngine;
import java.security.Provider;
import io.netty.util.internal.logging.InternalLogger;

public final class BouncyCastleUtil
{
    private static final InternalLogger logger;
    private static final String BC_PROVIDER_NAME = "BC";
    private static final String BC_PROVIDER = "org.bouncycastle.jce.provider.BouncyCastleProvider";
    private static final String BC_FIPS_PROVIDER_NAME = "BCFIPS";
    private static final String BC_FIPS_PROVIDER = "org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider";
    private static final String BC_JSSE_PROVIDER_NAME = "BCJSSE";
    private static final String BC_JSSE_PROVIDER = "org.bouncycastle.jsse.provider.BouncyCastleJsseProvider";
    private static final String BC_PEMPARSER = "org.bouncycastle.openssl.PEMParser";
    private static final String BC_JSSE_SSLENGINE = "org.bouncycastle.jsse.BCSSLEngine";
    private static final String BC_JSSE_ALPN_SELECTOR = "org.bouncycastle.jsse.BCApplicationProtocolSelector";
    private static volatile Throwable unavailabilityCauseBcProv;
    private static volatile Throwable unavailabilityCauseBcPkix;
    private static volatile Throwable unavailabilityCauseBcTls;
    private static volatile Provider bcProviderJce;
    private static volatile Provider bcProviderJsse;
    private static volatile Class<? extends SSLEngine> bcSSLEngineClass;
    private static volatile boolean attemptedLoading;
    
    public static boolean isBcProvAvailable() {
        ensureLoaded();
        return BouncyCastleUtil.unavailabilityCauseBcProv == null;
    }
    
    public static boolean isBcPkixAvailable() {
        ensureLoaded();
        return BouncyCastleUtil.unavailabilityCauseBcPkix == null;
    }
    
    public static boolean isBcTlsAvailable() {
        ensureLoaded();
        return BouncyCastleUtil.unavailabilityCauseBcTls == null;
    }
    
    public static Throwable unavailabilityCauseBcProv() {
        ensureLoaded();
        return BouncyCastleUtil.unavailabilityCauseBcProv;
    }
    
    public static Throwable unavailabilityCauseBcPkix() {
        ensureLoaded();
        return BouncyCastleUtil.unavailabilityCauseBcPkix;
    }
    
    public static Throwable unavailabilityCauseBcTls() {
        ensureLoaded();
        return BouncyCastleUtil.unavailabilityCauseBcTls;
    }
    
    public static boolean isBcJsseInUse(final SSLEngine engine) {
        ensureLoaded();
        final Class<? extends SSLEngine> bcEngineClass = BouncyCastleUtil.bcSSLEngineClass;
        return bcEngineClass != null && bcEngineClass.isInstance(engine);
    }
    
    public static Provider getBcProviderJce() {
        ensureLoaded();
        final Throwable cause = BouncyCastleUtil.unavailabilityCauseBcProv;
        final Provider provider = BouncyCastleUtil.bcProviderJce;
        if (cause != null || provider == null) {
            throw new IllegalStateException(cause);
        }
        return provider;
    }
    
    public static Provider getBcProviderJsse() {
        ensureLoaded();
        final Throwable cause = BouncyCastleUtil.unavailabilityCauseBcTls;
        final Provider provider = BouncyCastleUtil.bcProviderJsse;
        if (cause != null || provider == null) {
            throw new IllegalStateException(cause);
        }
        return provider;
    }
    
    public static Class<? extends SSLEngine> getBcSSLEngineClass() {
        ensureLoaded();
        return BouncyCastleUtil.bcSSLEngineClass;
    }
    
    static void reset() {
        BouncyCastleUtil.attemptedLoading = false;
        BouncyCastleUtil.unavailabilityCauseBcProv = null;
        BouncyCastleUtil.unavailabilityCauseBcPkix = null;
        BouncyCastleUtil.unavailabilityCauseBcTls = null;
        BouncyCastleUtil.bcProviderJce = null;
        BouncyCastleUtil.bcProviderJsse = null;
        BouncyCastleUtil.bcSSLEngineClass = null;
    }
    
    private static void ensureLoaded() {
        if (!BouncyCastleUtil.attemptedLoading) {
            tryLoading();
        }
    }
    
    private static void tryLoading() {
        AccessController.doPrivileged(() -> {
            try {
                Provider provider = Security.getProvider("BC");
                if (provider == null) {
                    provider = Security.getProvider("BCFIPS");
                }
                if (provider == null) {
                    final ClassLoader classLoader = BouncyCastleUtil.class.getClassLoader();
                    Class<?> bcProviderClass;
                    try {
                        bcProviderClass = Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider", true, classLoader);
                    }
                    catch (final ClassNotFoundException e) {
                        try {
                            bcProviderClass = Class.forName("org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider", true, classLoader);
                        }
                        catch (final ClassNotFoundException ex) {
                            ThrowableUtil.addSuppressed(e, ex);
                            throw e;
                        }
                    }
                    provider = (Provider)bcProviderClass.getConstructor((Class<?>[])new Class[0]).newInstance(new Object[0]);
                }
                BouncyCastleUtil.bcProviderJce = provider;
                BouncyCastleUtil.logger.debug("Bouncy Castle provider available");
            }
            catch (final Throwable e2) {
                BouncyCastleUtil.logger.debug("Cannot load Bouncy Castle provider", e2);
                BouncyCastleUtil.unavailabilityCauseBcProv = e2;
            }
            try {
                ClassLoader classLoader2 = BouncyCastleUtil.class.getClassLoader();
                final Provider provider2 = BouncyCastleUtil.bcProviderJce;
                if (provider2 != null) {
                    classLoader2 = provider2.getClass().getClassLoader();
                }
                Class.forName("org.bouncycastle.openssl.PEMParser", true, classLoader2);
                BouncyCastleUtil.logger.debug("Bouncy Castle PKIX available");
            }
            catch (final Throwable e3) {
                BouncyCastleUtil.logger.debug("Cannot load Bouncy Castle PKIX", e3);
                BouncyCastleUtil.unavailabilityCauseBcPkix = e3;
            }
            try {
                ClassLoader classLoader3 = BouncyCastleUtil.class.getClassLoader();
                Provider provider3 = Security.getProvider("BCJSSE");
                if (provider3 != null) {
                    classLoader3 = provider3.getClass().getClassLoader();
                }
                else {
                    final Class<?> providerClass = Class.forName("org.bouncycastle.jsse.provider.BouncyCastleJsseProvider", true, classLoader3);
                    provider3 = (Provider)providerClass.getConstructor((Class<?>[])new Class[0]).newInstance(new Object[0]);
                }
                BouncyCastleUtil.bcSSLEngineClass = (Class<? extends SSLEngine>)Class.forName("org.bouncycastle.jsse.BCSSLEngine", true, classLoader3);
                Class.forName("org.bouncycastle.jsse.BCApplicationProtocolSelector", true, classLoader3);
                BouncyCastleUtil.bcProviderJsse = provider3;
                BouncyCastleUtil.logger.debug("Bouncy Castle JSSE available");
            }
            catch (final Throwable e4) {
                BouncyCastleUtil.logger.debug("Cannot load Bouncy Castle TLS", e4);
                BouncyCastleUtil.unavailabilityCauseBcTls = e4;
            }
            BouncyCastleUtil.attemptedLoading = true;
            return null;
        });
    }
    
    private BouncyCastleUtil() {
    }
    
    static {
        logger = InternalLoggerFactory.getInstance(BouncyCastleUtil.class);
    }
}
