Home | History | Annotate | Download | only in ssl
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package org.conscrypt.javax.net.ssl;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.assertNotNull;
     21 import static org.junit.Assert.assertNotSame;
     22 import static org.junit.Assert.assertNull;
     23 import static org.junit.Assert.assertSame;
     24 import static org.junit.Assert.assertTrue;
     25 import static org.junit.Assert.fail;
     26 
     27 import java.io.IOException;
     28 import java.security.AccessController;
     29 import java.security.InvalidAlgorithmParameterException;
     30 import java.security.KeyManagementException;
     31 import java.security.KeyStore;
     32 import java.security.KeyStoreException;
     33 import java.security.NoSuchAlgorithmException;
     34 import java.security.PrivilegedAction;
     35 import java.security.Provider;
     36 import java.security.Security;
     37 import java.security.UnrecoverableKeyException;
     38 import java.util.ArrayList;
     39 import java.util.Arrays;
     40 import java.util.Collections;
     41 import java.util.List;
     42 import java.util.concurrent.Callable;
     43 import javax.net.ServerSocketFactory;
     44 import javax.net.SocketFactory;
     45 import javax.net.ssl.KeyManager;
     46 import javax.net.ssl.KeyManagerFactory;
     47 import javax.net.ssl.KeyManagerFactorySpi;
     48 import javax.net.ssl.ManagerFactoryParameters;
     49 import javax.net.ssl.SSLContext;
     50 import javax.net.ssl.SSLEngine;
     51 import javax.net.ssl.SSLServerSocket;
     52 import javax.net.ssl.SSLServerSocketFactory;
     53 import javax.net.ssl.SSLSessionContext;
     54 import javax.net.ssl.SSLSocket;
     55 import javax.net.ssl.SSLSocketFactory;
     56 import javax.net.ssl.TrustManager;
     57 import javax.net.ssl.TrustManagerFactory;
     58 import javax.net.ssl.TrustManagerFactorySpi;
     59 import javax.net.ssl.X509KeyManager;
     60 import junit.framework.AssertionFailedError;
     61 import libcore.java.security.StandardNames;
     62 import org.conscrypt.TestUtils;
     63 import org.junit.Test;
     64 import org.junit.runner.RunWith;
     65 import org.junit.runners.JUnit4;
     66 
     67 @RunWith(JUnit4.class)
     68 public class SSLContextTest {
     69 
     70     @Test
     71     public void test_SSLContext_getDefault() throws Exception {
     72         SSLContext sslContext = SSLContext.getDefault();
     73         assertNotNull(sslContext);
     74         try {
     75             sslContext.init(null, null, null);
     76             fail();
     77         } catch (KeyManagementException expected) {
     78             // Ignored.
     79         }
     80     }
     81 
     82     @Test
     83     public void test_SSLContext_setDefault() throws Exception {
     84         try {
     85             SSLContext.setDefault(null);
     86             fail();
     87         } catch (NullPointerException expected) {
     88             // Ignored.
     89         }
     90 
     91         SSLContext defaultContext = SSLContext.getDefault();
     92         for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
     93             SSLContext oldContext = SSLContext.getDefault();
     94             assertNotNull(oldContext);
     95             SSLContext newContext = SSLContext.getInstance(protocol);
     96             assertNotNull(newContext);
     97             assertNotSame(oldContext, newContext);
     98             SSLContext.setDefault(newContext);
     99             assertSame(newContext, SSLContext.getDefault());
    100         }
    101         SSLContext.setDefault(defaultContext);
    102     }
    103 
    104     @Test
    105     public void test_SSLContext_defaultConfiguration() throws Exception {
    106         SSLConfigurationAsserts.assertSSLContextDefaultConfiguration(SSLContext.getDefault());
    107 
    108         for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
    109             SSLContext sslContext = SSLContext.getInstance(protocol);
    110             if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
    111                 sslContext.init(null, null, null);
    112             }
    113             SSLConfigurationAsserts.assertSSLContextDefaultConfiguration(sslContext);
    114         }
    115     }
    116 
    117     @Test
    118     public void test_SSLContext_pskOnlyConfiguration_defaultProviderOnly() throws Exception {
    119         // Test the scenario where only a PSKKeyManager is provided and no TrustManagers are
    120         // provided.
    121         SSLContext sslContext = SSLContext.getInstance("TLS");
    122         sslContext.init(new KeyManager[] { PSKKeyManagerProxy.getConscryptPSKKeyManager(
    123                                 new PSKKeyManagerProxy())},
    124                 new TrustManager[0], null);
    125         List<String> expectedCipherSuites =
    126                 new ArrayList<String>(StandardNames.CIPHER_SUITES_DEFAULT_PSK);
    127         expectedCipherSuites.add(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION);
    128         assertEnabledCipherSuites(expectedCipherSuites, sslContext);
    129     }
    130 
    131     @Test
    132     public void test_SSLContext_x509AndPskConfiguration_defaultProviderOnly() throws Exception {
    133         // Test the scenario where an X509TrustManager and PSKKeyManager are provided.
    134         SSLContext sslContext = SSLContext.getInstance("TLS");
    135         sslContext.init(new KeyManager[] {PSKKeyManagerProxy.getConscryptPSKKeyManager(
    136                                 new PSKKeyManagerProxy())},
    137                 null, // Use default trust managers, one of which is an X.509 one.
    138                 null);
    139         List<String> expectedCipherSuites =
    140                 new ArrayList<String>(StandardNames.CIPHER_SUITES_DEFAULT_PSK);
    141         expectedCipherSuites.addAll(StandardNames.CIPHER_SUITES_DEFAULT);
    142         assertEnabledCipherSuites(expectedCipherSuites, sslContext);
    143 
    144         // Test the scenario where an X509KeyManager and PSKKeyManager are provided.
    145         sslContext = SSLContext.getInstance("TLS");
    146         // Just an arbitrary X509KeyManager -- it won't be invoked in this test.
    147         X509KeyManager x509KeyManager = new RandomPrivateKeyX509ExtendedKeyManager(null);
    148         sslContext.init(
    149                 new KeyManager[] {x509KeyManager,
    150                         PSKKeyManagerProxy.getConscryptPSKKeyManager(new PSKKeyManagerProxy())},
    151                 new TrustManager[0], null);
    152         assertEnabledCipherSuites(expectedCipherSuites, sslContext);
    153     }
    154 
    155     @Test
    156     public void test_SSLContext_emptyConfiguration_defaultProviderOnly() throws Exception {
    157         // Test the scenario where neither X.509 nor PSK KeyManagers or TrustManagers are provided.
    158         SSLContext sslContext = SSLContext.getInstance("TLS");
    159         sslContext.init(new KeyManager[0], new TrustManager[0], null);
    160         assertEnabledCipherSuites(
    161                 Collections.singletonList(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION),
    162                 sslContext);
    163     }
    164 
    165     @Test
    166     public void test_SSLContext_init_correctProtocolVersionsEnabled() throws Exception {
    167         for (String tlsVersion : StandardNames.SSL_CONTEXT_PROTOCOLS) {
    168             // Don't test the "Default" instance.
    169             if (StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT.equals(tlsVersion)) {
    170                 continue;
    171             }
    172 
    173             SSLContext context = SSLContext.getInstance(tlsVersion);
    174             context.init(null, null, null);
    175 
    176             StandardNames.assertSSLContextEnabledProtocols(
    177                     tlsVersion, ((SSLSocket) (context.getSocketFactory().createSocket()))
    178                                         .getEnabledProtocols());
    179             StandardNames.assertSSLContextEnabledProtocols(tlsVersion,
    180                     ((SSLServerSocket) (context.getServerSocketFactory().createServerSocket()))
    181                             .getEnabledProtocols());
    182             StandardNames.assertSSLContextEnabledProtocols(
    183                     tlsVersion, context.getDefaultSSLParameters().getProtocols());
    184             StandardNames.assertSSLContextEnabledProtocols(
    185                     tlsVersion, context.createSSLEngine().getEnabledProtocols());
    186         }
    187     }
    188 
    189     private static void assertEnabledCipherSuites(
    190             List<String> expectedCipherSuites, SSLContext sslContext) throws Exception {
    191         TestUtils.assumeSetEndpointIdentificationAlgorithmAvailable();
    192         assertContentsInOrder(
    193                 expectedCipherSuites, sslContext.createSSLEngine().getEnabledCipherSuites());
    194         assertContentsInOrder(expectedCipherSuites,
    195                 sslContext.createSSLEngine().getSSLParameters().getCipherSuites());
    196         assertContentsInOrder(
    197                 expectedCipherSuites, sslContext.getSocketFactory().getDefaultCipherSuites());
    198         assertContentsInOrder(
    199                 expectedCipherSuites, sslContext.getServerSocketFactory().getDefaultCipherSuites());
    200 
    201         SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket();
    202         try {
    203             assertContentsInOrder(expectedCipherSuites, sslSocket.getEnabledCipherSuites());
    204             assertContentsInOrder(
    205                     expectedCipherSuites, sslSocket.getSSLParameters().getCipherSuites());
    206         } finally {
    207             try {
    208                 sslSocket.close();
    209             } catch (IOException ignored) {
    210             }
    211         }
    212 
    213         SSLServerSocket sslServerSocket =
    214                 (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket();
    215         try {
    216             assertContentsInOrder(expectedCipherSuites, sslServerSocket.getEnabledCipherSuites());
    217         } finally {
    218             try {
    219                 sslSocket.close();
    220             } catch (IOException ignored) {
    221             }
    222         }
    223     }
    224 
    225     @Test
    226     public void test_SSLContext_getInstance() throws Exception {
    227         try {
    228             SSLContext.getInstance(null);
    229             fail();
    230         } catch (NullPointerException expected) {
    231             // Ignored.
    232         }
    233         for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
    234             assertNotNull(SSLContext.getInstance(protocol));
    235             assertNotSame(SSLContext.getInstance(protocol), SSLContext.getInstance(protocol));
    236         }
    237 
    238         try {
    239             SSLContext.getInstance(null, (String) null);
    240             fail();
    241         } catch (Exception expected) {
    242             if (javaVersion() >= 9) {
    243                 assertTrue("Expected NullPointerException on Java 9, was "
    244                                 + expected.getClass().getName(),
    245                         expected instanceof NullPointerException);
    246             } else {
    247                 assertTrue(
    248                         "Expected IllegalArgumentException, was " + expected.getClass().getName(),
    249                         expected instanceof IllegalArgumentException);
    250             }
    251         }
    252         try {
    253             SSLContext.getInstance(null, "");
    254             fail();
    255         } catch (Exception expected) {
    256             if (javaVersion() >= 9) {
    257                 assertTrue("Expected NullPointerException on Java 9, was "
    258                         + expected.getClass().getName(),
    259                     expected instanceof NullPointerException);
    260             } else {
    261                 assertTrue(
    262                     "Expected IllegalArgumentException, was " + expected.getClass().getName(),
    263                     expected instanceof IllegalArgumentException);
    264             }
    265         }
    266         for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
    267             try {
    268                 SSLContext.getInstance(protocol, (String) null);
    269                 fail();
    270             } catch (IllegalArgumentException expected) {
    271                 // Ignored.
    272             }
    273         }
    274         try {
    275             SSLContext.getInstance(null, StandardNames.JSSE_PROVIDER_NAME);
    276             fail();
    277         } catch (NullPointerException expected) {
    278             // Ignored.
    279         }
    280     }
    281 
    282     @Test
    283     public void test_SSLContext_getProtocol() throws Exception {
    284         for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
    285             String protocolName = SSLContext.getInstance(protocol).getProtocol();
    286             assertNotNull(protocolName);
    287             assertTrue(protocol.startsWith(protocolName));
    288         }
    289     }
    290 
    291     @Test
    292     public void test_SSLContext_getProvider() throws Exception {
    293         Provider provider = SSLContext.getDefault().getProvider();
    294         assertNotNull(provider);
    295         assertEquals(StandardNames.JSSE_PROVIDER_NAME, provider.getName());
    296     }
    297 
    298     @Test
    299     public void test_SSLContext_init_Default() throws Exception {
    300         // Assert that initializing a default SSLContext fails because it's supposed to be
    301         // initialized already.
    302         SSLContext sslContext = SSLContext.getInstance(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT);
    303         try {
    304             sslContext.init(null, null, null);
    305             fail();
    306         } catch (KeyManagementException expected) {
    307             // Ignored.
    308         }
    309         try {
    310             sslContext.init(new KeyManager[0], new TrustManager[0], null);
    311             fail();
    312         } catch (KeyManagementException expected) {
    313             // Ignored.
    314         }
    315         try {
    316             sslContext.init(new KeyManager[] {new KeyManager(){}},
    317                     new TrustManager[] {new TrustManager(){}}, null);
    318             fail();
    319         } catch (KeyManagementException expected) {
    320             // Ignored.
    321         }
    322     }
    323 
    324     @Test
    325     public void test_SSLContext_init_withNullManagerArrays() throws Exception {
    326         // Assert that SSLContext.init works fine even when provided with null arrays of
    327         // KeyManagers and TrustManagers.
    328         // The contract of SSLContext.init is that it will for default X.509 KeyManager and
    329         // TrustManager from the highest priority KeyManagerFactory and TrustManagerFactory.
    330         for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
    331             if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
    332                 // Default SSLContext is provided in an already initialized state
    333                 continue;
    334             }
    335             SSLContext sslContext = SSLContext.getInstance(protocol);
    336             sslContext.init(null, null, null);
    337         }
    338     }
    339 
    340     @Test
    341     public void test_SSLContext_init_withEmptyManagerArrays() throws Exception {
    342         // Assert that SSLContext.init works fine even when provided with empty arrays of
    343         // KeyManagers and TrustManagers.
    344         // The contract of SSLContext.init is that it will not look for default X.509 KeyManager and
    345         // TrustManager.
    346         // This test thus installs a Provider of KeyManagerFactory and TrustManagerFactory whose
    347         // factories throw exceptions which will make this test fail if the factories are used.
    348         Provider provider = new ThrowExceptionKeyAndTrustManagerFactoryProvider();
    349         invokeWithHighestPrioritySecurityProvider(provider, new Callable<Void>() {
    350             @Override
    351             public Void call() throws Exception {
    352                 assertEquals(ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
    353                     TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
    354                         .getProvider()
    355                         .getClass());
    356                 assertEquals(ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
    357                     KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
    358                         .getProvider()
    359                         .getClass());
    360 
    361                 KeyManager[] keyManagers = new KeyManager[0];
    362                 TrustManager[] trustManagers = new TrustManager[0];
    363                 for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
    364                     if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
    365                         // Default SSLContext is provided in an already initialized state
    366                         continue;
    367                     }
    368                     SSLContext sslContext = SSLContext.getInstance(protocol);
    369                     sslContext.init(keyManagers, trustManagers, null);
    370                 }
    371 
    372                 return null;
    373             }
    374         });
    375     }
    376 
    377     @Test
    378     public void test_SSLContext_init_withoutX509() throws Exception {
    379         // Assert that SSLContext.init works fine even when provided with KeyManagers and
    380         // TrustManagers which don't include the X.509 ones.
    381         // The contract of SSLContext.init is that it will not look for default X.509 KeyManager and
    382         // TrustManager.
    383         // This test thus installs a Provider of KeyManagerFactory and TrustManagerFactory whose
    384         // factories throw exceptions which will make this test fail if the factories are used.
    385         Provider provider = new ThrowExceptionKeyAndTrustManagerFactoryProvider();
    386         invokeWithHighestPrioritySecurityProvider(provider, new Callable<Void>() {
    387             @Override
    388             public Void call() throws Exception {
    389                 assertEquals(ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
    390                     TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
    391                         .getProvider()
    392                         .getClass());
    393                 assertEquals(ThrowExceptionKeyAndTrustManagerFactoryProvider.class,
    394                     KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
    395                         .getProvider()
    396                         .getClass());
    397 
    398                 KeyManager[] keyManagers = new KeyManager[]{new KeyManager() {
    399                 }};
    400                 TrustManager[] trustManagers = new TrustManager[]{new TrustManager() {
    401                 }};
    402                 for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
    403                     if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
    404                         // Default SSLContext is provided in an already initialized state
    405                         continue;
    406                     }
    407                     SSLContext sslContext = SSLContext.getInstance(protocol);
    408                     sslContext.init(keyManagers, trustManagers, null);
    409                 }
    410 
    411                 return null;
    412             }
    413         });
    414     }
    415 
    416     public static class ThrowExceptionKeyAndTrustManagerFactoryProvider extends Provider {
    417         public ThrowExceptionKeyAndTrustManagerFactoryProvider() {
    418             super("ThrowExceptionKeyAndTrustManagerProvider", 1.0,
    419                     "SSLContextTest fake KeyManagerFactory  and TrustManagerFactory provider");
    420 
    421             put("TrustManagerFactory." + TrustManagerFactory.getDefaultAlgorithm(),
    422                     ThrowExceptionTrustManagagerFactorySpi.class.getName());
    423             put("TrustManagerFactory.PKIX", ThrowExceptionTrustManagagerFactorySpi.class.getName());
    424 
    425             put("KeyManagerFactory." + KeyManagerFactory.getDefaultAlgorithm(),
    426                     ThrowExceptionKeyManagagerFactorySpi.class.getName());
    427             put("KeyManagerFactory.PKIX", ThrowExceptionKeyManagagerFactorySpi.class.getName());
    428         }
    429     }
    430 
    431     public static class ThrowExceptionTrustManagagerFactorySpi extends TrustManagerFactorySpi {
    432         @Override
    433         protected void engineInit(KeyStore ks) throws KeyStoreException {
    434             fail();
    435         }
    436 
    437         @Override
    438         protected void engineInit(ManagerFactoryParameters spec)
    439                 throws InvalidAlgorithmParameterException {
    440             fail();
    441         }
    442 
    443         @Override
    444         protected TrustManager[] engineGetTrustManagers() {
    445             throw new AssertionFailedError();
    446         }
    447     }
    448 
    449     public static class ThrowExceptionKeyManagagerFactorySpi extends KeyManagerFactorySpi {
    450         @Override
    451         protected void engineInit(KeyStore ks, char[] password)
    452                 throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
    453             fail();
    454         }
    455 
    456         @Override
    457         protected void engineInit(ManagerFactoryParameters spec)
    458                 throws InvalidAlgorithmParameterException {
    459             fail();
    460         }
    461 
    462         @Override
    463         protected KeyManager[] engineGetKeyManagers() {
    464             throw new AssertionFailedError();
    465         }
    466     }
    467 
    468     /**
    469      * Installs the specified security provider as the highest provider, invokes the provided
    470      * {@link Callable}, and removes the provider.
    471      *
    472      * @return result returned by the {@code callable}.
    473      */
    474     private static <T> T invokeWithHighestPrioritySecurityProvider(
    475             Provider provider, Callable<T> callable) throws Exception {
    476         int providerPosition = -1;
    477         try {
    478             providerPosition = Security.insertProviderAt(provider, 1);
    479             assertEquals(1, providerPosition);
    480             return callable.call();
    481         } finally {
    482             if (providerPosition != -1) {
    483                 Security.removeProvider(provider.getName());
    484             }
    485         }
    486     }
    487 
    488     @Test
    489     public void test_SSLContext_getSocketFactory() throws Exception {
    490         for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
    491             if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
    492                 SSLContext.getInstance(protocol).getSocketFactory();
    493             } else {
    494                 try {
    495                     SSLContext.getInstance(protocol).getSocketFactory();
    496                     fail();
    497                 } catch (IllegalStateException expected) {
    498                     // Ignored.
    499                 }
    500             }
    501 
    502             SSLContext sslContext = SSLContext.getInstance(protocol);
    503             if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
    504                 sslContext.init(null, null, null);
    505             }
    506             SocketFactory sf = sslContext.getSocketFactory();
    507             assertNotNull(sf);
    508             assertTrue(SSLSocketFactory.class.isAssignableFrom(sf.getClass()));
    509         }
    510     }
    511 
    512     @Test
    513     public void test_SSLContext_getServerSocketFactory() throws Exception {
    514         for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
    515             if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
    516                 SSLContext.getInstance(protocol).getServerSocketFactory();
    517             } else {
    518                 try {
    519                     SSLContext.getInstance(protocol).getServerSocketFactory();
    520                     fail();
    521                 } catch (IllegalStateException expected) {
    522                     // Ignored.
    523                 }
    524             }
    525 
    526             SSLContext sslContext = SSLContext.getInstance(protocol);
    527             if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
    528                 sslContext.init(null, null, null);
    529             }
    530             ServerSocketFactory ssf = sslContext.getServerSocketFactory();
    531             assertNotNull(ssf);
    532             assertTrue(SSLServerSocketFactory.class.isAssignableFrom(ssf.getClass()));
    533         }
    534     }
    535 
    536     @Test
    537     public void test_SSLContext_createSSLEngine() throws Exception {
    538         for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
    539             if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
    540                 SSLContext.getInstance(protocol).createSSLEngine();
    541             } else {
    542                 try {
    543                     SSLContext.getInstance(protocol).createSSLEngine();
    544                     fail();
    545                 } catch (IllegalStateException expected) {
    546                     // Ignored.
    547                 }
    548             }
    549 
    550             if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
    551                 SSLContext.getInstance(protocol).createSSLEngine(null, -1);
    552             } else {
    553                 try {
    554                     SSLContext.getInstance(protocol).createSSLEngine(null, -1);
    555                     fail();
    556                 } catch (IllegalStateException expected) {
    557                     // Ignored.
    558                 }
    559             }
    560 
    561             {
    562                 SSLContext sslContext = SSLContext.getInstance(protocol);
    563                 if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
    564                     sslContext.init(null, null, null);
    565                 }
    566                 SSLEngine se = sslContext.createSSLEngine();
    567                 assertNotNull(se);
    568             }
    569 
    570             {
    571                 SSLContext sslContext = SSLContext.getInstance(protocol);
    572                 if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
    573                     sslContext.init(null, null, null);
    574                 }
    575                 SSLEngine se = sslContext.createSSLEngine(null, -1);
    576                 assertNotNull(se);
    577             }
    578         }
    579     }
    580 
    581     @Test
    582     public void test_SSLContext_getServerSessionContext() throws Exception {
    583         for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
    584             SSLContext sslContext = SSLContext.getInstance(protocol);
    585             SSLSessionContext sessionContext = sslContext.getServerSessionContext();
    586             assertNotNull(sessionContext);
    587 
    588             if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
    589                 assertSame(
    590                         SSLContext.getInstance(protocol).getServerSessionContext(), sessionContext);
    591             } else {
    592                 assertNotSame(
    593                         SSLContext.getInstance(protocol).getServerSessionContext(), sessionContext);
    594             }
    595         }
    596     }
    597 
    598     @Test
    599     public void test_SSLContext_getClientSessionContext() throws Exception {
    600         for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
    601             SSLContext sslContext = SSLContext.getInstance(protocol);
    602             SSLSessionContext sessionContext = sslContext.getClientSessionContext();
    603             assertNotNull(sessionContext);
    604 
    605             if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
    606                 assertSame(
    607                         SSLContext.getInstance(protocol).getClientSessionContext(), sessionContext);
    608             } else {
    609                 assertNotSame(
    610                         SSLContext.getInstance(protocol).getClientSessionContext(), sessionContext);
    611             }
    612         }
    613     }
    614 
    615     @Test
    616     public void test_SSLContextTest_TestSSLContext_create() {
    617         TestSSLContext testContext = TestSSLContext.create();
    618         assertNotNull(testContext);
    619         assertNotNull(testContext.clientKeyStore);
    620         assertNull(testContext.clientStorePassword);
    621         assertNotNull(testContext.serverKeyStore);
    622         assertNotNull(testContext.clientKeyManagers);
    623         assertNotNull(testContext.serverKeyManagers);
    624         if (testContext.clientKeyManagers.length == 0) {
    625             fail("No client KeyManagers");
    626         }
    627         if (testContext.serverKeyManagers.length == 0) {
    628             fail("No server KeyManagers");
    629         }
    630         assertNotNull(testContext.clientKeyManagers[0]);
    631         assertNotNull(testContext.serverKeyManagers[0]);
    632         assertNotNull(testContext.clientTrustManager);
    633         assertNotNull(testContext.serverTrustManager);
    634         assertNotNull(testContext.clientContext);
    635         assertNotNull(testContext.serverContext);
    636         assertNotNull(testContext.serverSocket);
    637         assertNotNull(testContext.host);
    638         assertTrue(testContext.port != 0);
    639         testContext.close();
    640     }
    641 
    642     @Test(expected = NoSuchAlgorithmException.class)
    643     public void test_SSLContext_SSLv3Unsupported() throws Exception {
    644         // Find the default provider for TLS and verify that it does NOT support SSLv3.
    645         Provider defaultTlsProvider = null;
    646         for (String protocol : new String[] {"SSLContext.TLSv1.2", "SSLContext.TLSv1"}) {
    647             for (Provider p : Security.getProviders()) {
    648                 if (p.get(protocol) != null) {
    649                     defaultTlsProvider = p;
    650                     break;
    651                 }
    652             }
    653         }
    654         assertNotNull(defaultTlsProvider);
    655         SSLContext.getInstance("SSLv3", defaultTlsProvider);
    656     }
    657 
    658     private static void assertContentsInOrder(List<String> expected, String... actual) {
    659         if (expected.size() != actual.length) {
    660             fail("Unexpected length. Expected len <" + expected.size() + ">, actual len <"
    661                     + actual.length + ">, expected <" + expected + ">, actual <"
    662                     + Arrays.asList(actual) + ">");
    663         }
    664         if (!expected.equals(Arrays.asList(actual))) {
    665             fail("Unexpected element(s). Expected <" + expected + ">, actual <"
    666                     + Arrays.asList(actual) + ">");
    667         }
    668     }
    669 
    670     private static boolean isAndroid() {
    671         boolean android;
    672         try {
    673             Class.forName("android.app.Application", false, getSystemClassLoader());
    674             android = true;
    675         } catch (Throwable ignored) {
    676             // Failed to load the class uniquely available in Android.
    677             android = false;
    678         }
    679         return android;
    680     }
    681 
    682     private static int javaVersion() {
    683         final int majorVersion;
    684 
    685         if (isAndroid()) {
    686             majorVersion = 6;
    687         } else {
    688             majorVersion = majorVersionFromJavaSpecificationVersion();
    689         }
    690 
    691         return majorVersion;
    692     }
    693 
    694     private static int majorVersionFromJavaSpecificationVersion() {
    695         return majorVersion(System.getProperty("java.specification.version", "1.6"));
    696     }
    697 
    698     private static int majorVersion(final String javaSpecVersion) {
    699         final String[] components = javaSpecVersion.split("\\.");
    700         final int[] version = new int[components.length];
    701         for (int i = 0; i < components.length; i++) {
    702             version[i] = Integer.parseInt(components[i]);
    703         }
    704 
    705         if (version[0] == 1) {
    706             assert version[1] >= 6;
    707             return version[1];
    708         } else {
    709             return version[0];
    710         }
    711     }
    712 
    713     private static ClassLoader getSystemClassLoader() {
    714         if (System.getSecurityManager() == null) {
    715             return ClassLoader.getSystemClassLoader();
    716         } else {
    717             return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
    718                 @Override
    719                 public ClassLoader run() {
    720                     return ClassLoader.getSystemClassLoader();
    721                 }
    722             });
    723         }
    724     }
    725 }
    726