package org.bouncycastle.jsse.provider.test;

import java.security.AccessController;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Arrays;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;

import junit.framework.Test;
import junit.framework.TestSuite;

public class CipherSuitesTestSuite
    extends TestSuite
{
    static final boolean hasSslParameters;

    static
    {
        Class<?> clazz;
        try
        {
            clazz = loadClass("javax.net.ssl.SSLParameters");
        }
        catch (Exception e)
        {
            clazz = null;
        }

        hasSslParameters = (clazz != null);
    }

    private static Class<?> loadClass(final String className)
    {
        return AccessController.doPrivileged(new PrivilegedAction<Class<?>>()
        {
            public Class<?> run()
            {
                try
                {
                    ClassLoader classLoader = CipherSuitesTestSuite.class.getClassLoader();
                    return (null == classLoader)
                        ?   Class.forName(className)
                        :   classLoader.loadClass(className);
                }
                catch (Exception e)
                {
                }

                return null;
            }
        });
    }

    public CipherSuitesTestSuite()
    {
        super("CipherSuites");
    }

    public static Test suite()
        throws Exception
    {
        String javaVersion = System.getProperty("java.version");
        boolean oldJDK = javaVersion.startsWith("1.5") || javaVersion.startsWith("1.6");

        Provider bc = new BouncyCastleProvider();
        Provider bcjsse = oldJDK ? new BouncyCastleJsseProvider(bc) : new BouncyCastleJsseProvider();

        Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
        Security.insertProviderAt(bc, 1);

        Security.removeProvider(BouncyCastleJsseProvider.PROVIDER_NAME);
        Security.insertProviderAt(bcjsse, 2);


        CipherSuitesTestSuite testSuite = new CipherSuitesTestSuite();

        char[] serverPassword = "serverPassword".toCharArray();

        KeyPair caKeyPairDSA = TestUtils.generateDSAKeyPair();
        KeyPair caKeyPairEC = TestUtils.generateECKeyPair();
        KeyPair caKeyPairRSA = TestUtils.generateRSAKeyPair();

        X509Certificate caCertDSA = TestUtils.generateRootCert(caKeyPairDSA);
        X509Certificate caCertEC = TestUtils.generateRootCert(caKeyPairEC);
        X509Certificate caCertRSA = TestUtils.generateRootCert(caKeyPairRSA);

        KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(null, null);
        ks.setKeyEntry("serverDSA", caKeyPairDSA.getPrivate(), serverPassword, new X509Certificate[]{caCertDSA});
        ks.setKeyEntry("serverEC", caKeyPairEC.getPrivate(), serverPassword, new X509Certificate[]{caCertEC});
        ks.setKeyEntry("serverRSA", caKeyPairRSA.getPrivate(), serverPassword, new X509Certificate[]{caCertRSA});

        KeyStore ts = KeyStore.getInstance("JKS");
        ts.load(null, null);
        ts.setCertificateEntry("caDSA", caCertDSA);
        ts.setCertificateEntry("caEC", caCertEC);
        ts.setCertificateEntry("caRSA", caCertRSA);

        SSLContext sslContext = SSLContext.getInstance("TLS", BouncyCastleJsseProvider.PROVIDER_NAME);
        String[] cipherSuites;
        if (hasSslParameters)
        {
            cipherSuites = sslContext.getSupportedSSLParameters().getCipherSuites();
        }
        else
        {
            TrustManagerFactory trustMgrFact = TrustManagerFactory.getInstance("PKIX",
                BouncyCastleJsseProvider.PROVIDER_NAME);

            trustMgrFact.init(ts);

            sslContext.init(null, trustMgrFact.getTrustManagers(),
                SecureRandom.getInstance("DEFAULT", BouncyCastleProvider.PROVIDER_NAME));
            cipherSuites = sslContext.getSocketFactory().getSupportedCipherSuites();
        }

        Arrays.sort(cipherSuites);


        for (int t = 0; t < cipherSuites.length; t++)
        {
            String cipherSuite = cipherSuites[t];

            if (cipherSuite.contains("_WITH_NULL_") || cipherSuite.contains("_WITH_3DES_EDE_CBC_"))
            {
                /*
                 * TODO[jsse] jdk.tls.disabledAlgorithms default value doesn't permit these. Perhaps
                 * we could modify that security property when running this test suite.
                 */
                continue;
            }

            /*
             * TODO[jsse] Note that there may be failures for cipher suites that are listed as supported
             * even though the TlsCrypto instance doesn't implement them (JcaTlsCrypto is dependent on the
             * configured crypto providers).
             */

            CipherSuitesTestConfig config = new CipherSuitesTestConfig();
            config.cipherSuite = cipherSuite;
            config.clientTrustStore = ts;
            config.serverKeyStore = ks;
            config.serverPassword = serverPassword;

            testSuite.addTest(new CipherSuitesTestCase(config));
        }

        return testSuite;
    }
}

@@ -43,47 +43,8 @@
 t;%0A%0A
-import java.security.AccessController;%0A
 impo
@@ -127,88 +127,14 @@
 y.Pr
-ivilegedAction;%0Aimport java.security.Provider;%0Aimport java.security.SecureRandom
+ovider
 ;%0Aim
@@ -267,50 +267,8 @@
 ext;
-%0Aimport javax.net.ssl.TrustManagerFactory;
 %0A%0Aim
@@ -516,964 +516,8 @@
 e%0A%7B%0A
-    static final boolean hasSslParameters;%0A%0A    static%0A    %7B%0A        Class%3C?%3E clazz;%0A        try%0A        %7B%0A            clazz = loadClass(%22javax.net.ssl.SSLParameters%22);%0A        %7D%0A        catch (Exception e)%0A        %7B%0A            clazz = null;%0A        %7D%0A%0A        hasSslParameters = (clazz != null);%0A    %7D%0A%0A    private static Class%3C?%3E loadClass(final String className)%0A    %7B%0A        return AccessController.doPrivileged(new PrivilegedAction%3CClass%3C?%3E%3E()%0A        %7B%0A            public Class%3C?%3E run()%0A            %7B%0A                try%0A                %7B%0A                    ClassLoader classLoader = CipherSuitesTestSuite.class.getClassLoader();%0A                    return (null == classLoader)%0A                        ?   Class.forName(className)%0A                        :   classLoader.loadClass(className);%0A                %7D%0A                catch (Exception e)%0A                %7B%0A                %7D%0A%0A                return null;%0A            %7D%0A        %7D);%0A    %7D%0A%0A
     
@@ -2426,19 +2426,26 @@
 Context 
-ssl
+defaultSSL
 Context 
@@ -2474,11 +2474,15 @@
 ce(%22
-TLS
+Default
 %22, B
@@ -2513,32 +2513,33 @@
 PROVIDER_NAME);%0A
+%0A
         String%5B%5D
@@ -2555,536 +2555,21 @@
 ites
-;%0A        if (hasSslParameters)%0A        %7B%0A            cipherSuites = sslContext.getSupportedSSLParameters().getCipherSuites();%0A        %7D%0A        else%0A        %7B%0A            TrustManagerFactory trustMgrFact = TrustManagerFactory.getInstance(%22PKIX%22,%0A                BouncyCastleJsseProvider.PROVIDER_NAME);%0A%0A            trustMgrFact.init(ts);%0A%0A            sslContext.init(null, trustMgrFact.getTrustManagers(),%0A                SecureRandom.getInstance(%22DEFAULT%22, BouncyCastleProvider.PROVIDER_NAME));%0A            cipherSuites = ssl
+ = defaultSSL
 Cont
@@ -2618,26 +2618,16 @@
 uites();
-%0A        %7D
 %0A%0A      

Simplify the fetching of supported cipher suites for test