Home | History | Annotate | Download | only in security
      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 libcore.java.security;
     18 
     19 import java.security.Security;
     20 import java.security.spec.DSAPrivateKeySpec;
     21 import java.security.spec.DSAPublicKeySpec;
     22 import java.security.spec.ECPrivateKeySpec;
     23 import java.security.spec.ECPublicKeySpec;
     24 import java.security.spec.KeySpec;
     25 import java.security.spec.RSAPrivateCrtKeySpec;
     26 import java.security.spec.RSAPublicKeySpec;
     27 import java.util.Arrays;
     28 import java.util.Collections;
     29 import java.util.HashMap;
     30 import java.util.HashSet;
     31 import java.util.Iterator;
     32 import java.util.LinkedHashSet;
     33 import java.util.List;
     34 import java.util.Map;
     35 import java.util.Set;
     36 import javax.crypto.spec.DHPrivateKeySpec;
     37 import javax.crypto.spec.DHPublicKeySpec;
     38 import junit.framework.Assert;
     39 
     40 /**
     41  * This class defines expected string names for protocols, key types,
     42  * client and server auth types, cipher suites.
     43  *
     44  * Initially based on "Appendix A: Standard Names" of
     45  * <a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">
     46  * Java &trade; Secure Socket Extension (JSSE) Reference Guide
     47  * for the Java &trade; 2 Platform Standard Edition 5
     48  * </a>.
     49  *
     50  * Updated based on the
     51  * <a href="http://download.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html">
     52  * Java &trade; Cryptography Architecture Oracle Providers Documentation
     53  * for Java &trade; Platform Standard Edition 7
     54  * </a>.
     55  * See also the
     56  * <a href="http://download.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html">
     57  * Java &trade; Cryptography Architecture Standard Algorithm Name Documentation
     58  * </a>.
     59  *
     60  * Further updates based on the
     61  * <a href=http://java.sun.com/javase/6/docs/technotes/guides/security/p11guide.html">
     62  * Java &trade; PKCS#11 Reference Guide
     63  * </a>.
     64  */
     65 public final class StandardNames extends Assert {
     66 
     67     public static final boolean IS_RI
     68             = !"Dalvik Core Library".equals(System.getProperty("java.specification.name"));
     69     public static final String JSSE_PROVIDER_NAME = (IS_RI) ? "SunJSSE" : "AndroidOpenSSL";
     70     public static final String SECURITY_PROVIDER_NAME = (IS_RI) ? "SUN" : "BC";
     71 
     72     public static final String KEY_MANAGER_FACTORY_DEFAULT = (IS_RI) ? "SunX509" : "PKIX";
     73     public static final String TRUST_MANAGER_FACTORY_DEFAULT = "PKIX";
     74 
     75     public static final String KEY_STORE_ALGORITHM = (IS_RI) ? "JKS" : "BKS";
     76 
     77     /**
     78      * RFC 5746's Signaling Cipher Suite Value to indicate a request for secure renegotiation
     79      */
     80     public static final String CIPHER_SUITE_SECURE_RENEGOTIATION
     81             = "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
     82 
     83     /**
     84      * A map from algorithm type (e.g. Cipher) to a set of algorithms (e.g. AES, DES, ...)
     85      */
     86     public static final Map<String,Set<String>> PROVIDER_ALGORITHMS
     87             = new HashMap<String,Set<String>>();
     88 
     89     public static final Map<String,Set<String>> CIPHER_MODES
     90             = new HashMap<String,Set<String>>();
     91 
     92     public static final Map<String,Set<String>> CIPHER_PADDINGS
     93             = new HashMap<String,Set<String>>();
     94 
     95     private static void provide(String type, String algorithm) {
     96         Set<String> algorithms = PROVIDER_ALGORITHMS.get(type);
     97         if (algorithms == null) {
     98             algorithms = new HashSet();
     99             PROVIDER_ALGORITHMS.put(type, algorithms);
    100         }
    101         assertTrue("Duplicate " + type + " " + algorithm,
    102                    algorithms.add(algorithm.toUpperCase()));
    103     }
    104     private static void unprovide(String type, String algorithm) {
    105         Set<String> algorithms = PROVIDER_ALGORITHMS.get(type);
    106         assertNotNull(algorithms);
    107         assertTrue(algorithm, algorithms.remove(algorithm.toUpperCase()));
    108         if (algorithms.isEmpty()) {
    109             assertNotNull(PROVIDER_ALGORITHMS.remove(type));
    110         }
    111     }
    112     private static void provideCipherModes(String algorithm, String newModes[]) {
    113         Set<String> modes = CIPHER_MODES.get(algorithm);
    114         if (modes == null) {
    115             modes = new HashSet<String>();
    116             CIPHER_MODES.put(algorithm, modes);
    117         }
    118         modes.addAll(Arrays.asList(newModes));
    119     }
    120     private static void provideCipherPaddings(String algorithm, String newPaddings[]) {
    121         Set<String> paddings = CIPHER_PADDINGS.get(algorithm);
    122         if (paddings == null) {
    123             paddings = new HashSet<String>();
    124             CIPHER_PADDINGS.put(algorithm, paddings);
    125         }
    126         paddings.addAll(Arrays.asList(newPaddings));
    127     }
    128     static {
    129         provide("AlgorithmParameterGenerator", "DSA");
    130         provide("AlgorithmParameterGenerator", "DiffieHellman");
    131         provide("AlgorithmParameters", "AES");
    132         provide("AlgorithmParameters", "Blowfish");
    133         provide("AlgorithmParameters", "DES");
    134         provide("AlgorithmParameters", "DESede");
    135         provide("AlgorithmParameters", "DSA");
    136         provide("AlgorithmParameters", "DiffieHellman");
    137         provide("AlgorithmParameters", "OAEP");
    138         provide("AlgorithmParameters", "PBEWithMD5AndDES");
    139         provide("AlgorithmParameters", "PBEWithMD5AndTripleDES");
    140         provide("AlgorithmParameters", "PBEWithSHA1AndDESede");
    141         provide("AlgorithmParameters", "PBEWithSHA1AndRC2_40");
    142         provide("AlgorithmParameters", "RC2");
    143         provide("CertPathBuilder", "PKIX");
    144         provide("CertPathValidator", "PKIX");
    145         provide("CertStore", "Collection");
    146         provide("CertStore", "LDAP");
    147         provide("CertificateFactory", "X.509");
    148         // TODO: provideCipherModes and provideCipherPaddings for other Ciphers
    149         provide("Cipher", "AES");
    150         provideCipherModes("AES", new String[] { "CBC", "CFB", "CTR", "CTS", "ECB", "OFB" });
    151         provideCipherPaddings("AES", new String[] { "NoPadding", "PKCS5Padding" });
    152         provide("Cipher", "AESWrap");
    153         provide("Cipher", "ARCFOUR");
    154         provide("Cipher", "Blowfish");
    155         provide("Cipher", "DES");
    156         provide("Cipher", "DESede");
    157         provide("Cipher", "DESedeWrap");
    158         provide("Cipher", "PBEWithMD5AndDES");
    159         provide("Cipher", "PBEWithMD5AndTripleDES");
    160         provide("Cipher", "PBEWithSHA1AndDESede");
    161         provide("Cipher", "PBEWithSHA1AndRC2_40");
    162         provide("Cipher", "RC2");
    163         provide("Cipher", "RSA");
    164         // TODO: None?
    165         provideCipherModes("RSA", new String[] { "ECB" });
    166         // TODO: OAEPPadding
    167         provideCipherPaddings("RSA", new String[] { "NoPadding", "PKCS1Padding" });
    168         provide("Configuration", "JavaLoginConfig");
    169         provide("KeyAgreement", "DiffieHellman");
    170         provide("KeyFactory", "DSA");
    171         provide("KeyFactory", "DiffieHellman");
    172         provide("KeyFactory", "RSA");
    173         provide("KeyGenerator", "AES");
    174         provide("KeyGenerator", "ARCFOUR");
    175         provide("KeyGenerator", "Blowfish");
    176         provide("KeyGenerator", "DES");
    177         provide("KeyGenerator", "DESede");
    178         provide("KeyGenerator", "HmacMD5");
    179         provide("KeyGenerator", "HmacSHA1");
    180         provide("KeyGenerator", "HmacSHA256");
    181         provide("KeyGenerator", "HmacSHA384");
    182         provide("KeyGenerator", "HmacSHA512");
    183         provide("KeyGenerator", "RC2");
    184         provide("KeyInfoFactory", "DOM");
    185         provide("KeyManagerFactory", "PKIX");
    186         provide("KeyPairGenerator", "DSA");
    187         provide("KeyPairGenerator", "DiffieHellman");
    188         provide("KeyPairGenerator", "RSA");
    189         provide("KeyStore", "JCEKS");
    190         provide("KeyStore", "JKS");
    191         provide("KeyStore", "PKCS12");
    192         provide("Mac", "HmacMD5");
    193         provide("Mac", "HmacSHA1");
    194         provide("Mac", "HmacSHA256");
    195         provide("Mac", "HmacSHA384");
    196         provide("Mac", "HmacSHA512");
    197         // If adding a new MessageDigest, consider adding it to JarVerifier
    198         provide("MessageDigest", "MD2");
    199         provide("MessageDigest", "MD5");
    200         provide("MessageDigest", "SHA-256");
    201         provide("MessageDigest", "SHA-384");
    202         provide("MessageDigest", "SHA-512");
    203         provide("Policy", "JavaPolicy");
    204         provide("SSLContext", "SSLv3");
    205         provide("SSLContext", "TLSv1");
    206         provide("SSLContext", "TLSv1.1");
    207         provide("SSLContext", "TLSv1.2");
    208         provide("SecretKeyFactory", "DES");
    209         provide("SecretKeyFactory", "DESede");
    210         provide("SecretKeyFactory", "PBEWithMD5AndDES");
    211         provide("SecretKeyFactory", "PBEWithMD5AndTripleDES");
    212         provide("SecretKeyFactory", "PBEWithSHA1AndDESede");
    213         provide("SecretKeyFactory", "PBEWithSHA1AndRC2_40");
    214         provide("SecretKeyFactory", "PBKDF2WithHmacSHA1");
    215         provide("SecureRandom", "SHA1PRNG");
    216         provide("Signature", "MD2withRSA");
    217         provide("Signature", "MD5withRSA");
    218         provide("Signature", "NONEwithDSA");
    219         provide("Signature", "SHA1withDSA");
    220         provide("Signature", "SHA1withRSA");
    221         provide("Signature", "SHA256withRSA");
    222         provide("Signature", "SHA384withRSA");
    223         provide("Signature", "SHA512withRSA");
    224         provide("TerminalFactory", "PC/SC");
    225         provide("TransformService", "http://www.w3.org/2000/09/xmldsig#base64");
    226         provide("TransformService", "http://www.w3.org/2000/09/xmldsig#enveloped-signature");
    227         provide("TransformService", "http://www.w3.org/2001/10/xml-exc-c14n#");
    228         provide("TransformService", "http://www.w3.org/2001/10/xml-exc-c14n#WithComments");
    229         provide("TransformService", "http://www.w3.org/2002/06/xmldsig-filter2");
    230         provide("TransformService", "http://www.w3.org/TR/1999/REC-xpath-19991116");
    231         provide("TransformService", "http://www.w3.org/TR/1999/REC-xslt-19991116");
    232         provide("TransformService", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
    233         provide("TransformService", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments");
    234         provide("TrustManagerFactory", "PKIX");
    235         provide("XMLSignatureFactory", "DOM");
    236 
    237         // Not clearly documented by RI
    238         provide("GssApiMechanism", "1.2.840.113554.1.2.2");
    239         provide("GssApiMechanism", "1.3.6.1.5.5.2");
    240 
    241         // Not correctly documented by RI which left off the Factory suffix
    242         provide("SaslClientFactory", "CRAM-MD5");
    243         provide("SaslClientFactory", "DIGEST-MD5");
    244         provide("SaslClientFactory", "EXTERNAL");
    245         provide("SaslClientFactory", "GSSAPI");
    246         provide("SaslClientFactory", "PLAIN");
    247         provide("SaslServerFactory", "CRAM-MD5");
    248         provide("SaslServerFactory", "DIGEST-MD5");
    249         provide("SaslServerFactory", "GSSAPI");
    250 
    251         // Documentation seems to list alias instead of actual name
    252         // provide("MessageDigest", "SHA-1");
    253         provide("MessageDigest", "SHA");
    254 
    255         // Mentioned in javadoc, not documentation
    256         provide("SSLContext", "Default");
    257 
    258         // Not documented as in RI 6 but mentioned in Standard Names
    259         provide("AlgorithmParameters", "PBE");
    260         provide("SSLContext", "SSL");
    261         provide("SSLContext", "TLS");
    262 
    263         // Not documented as in RI 6 but that exist in RI 6
    264         if (IS_RI) {
    265             provide("CertStore", "com.sun.security.IndexedCollection");
    266             provide("KeyGenerator", "SunTlsKeyMaterial");
    267             provide("KeyGenerator", "SunTlsMasterSecret");
    268             provide("KeyGenerator", "SunTlsPrf");
    269             provide("KeyGenerator", "SunTlsRsaPremasterSecret");
    270             provide("KeyStore", "CaseExactJKS");
    271             provide("Mac", "HmacPBESHA1");
    272             provide("Mac", "SslMacMD5");
    273             provide("Mac", "SslMacSHA1");
    274             provide("SecureRandom", "NativePRNG");
    275             provide("Signature", "MD5andSHA1withRSA");
    276             provide("TrustManagerFactory", "SunX509");
    277         }
    278 
    279         // Only available with the SunPKCS11-NSS provider,
    280         // which seems to be enabled in OpenJDK 6 but not Oracle Java 6
    281         if (Security.getProvider("SunPKCS11-NSS") != null) {
    282             provide("AlgorithmParameters", "EC");
    283             provide("Cipher", "AES/CBC/NOPADDING");
    284             provide("Cipher", "DES/CBC/NOPADDING");
    285             provide("Cipher", "DESEDE/CBC/NOPADDING");
    286             provide("Cipher", "RSA/ECB/PKCS1PADDING");
    287             provide("KeyAgreement", "DH");
    288             provide("KeyAgreement", "ECDH");
    289             provide("KeyFactory", "DH");
    290             provide("KeyFactory", "EC");
    291             provide("KeyPairGenerator", "DH");
    292             provide("KeyPairGenerator", "EC");
    293             provide("KeyStore", "PKCS11");
    294             provide("MessageDigest", "SHA1");
    295             provide("SecretKeyFactory", "AES");
    296             provide("SecretKeyFactory", "ARCFOUR");
    297             provide("SecureRandom", "PKCS11");
    298             provide("Signature", "DSA");
    299             provide("Signature", "NONEWITHECDSA");
    300             provide("Signature", "RAWDSA");
    301             provide("Signature", "SHA1WITHECDSA");
    302             provide("Signature", "SHA256WITHECDSA");
    303             provide("Signature", "SHA384WITHECDSA");
    304             provide("Signature", "SHA512WITHECDSA");
    305         }
    306 
    307         // Documented as Standard Names, but do not exit in RI 6
    308         if (IS_RI) {
    309             unprovide("SSLContext", "TLSv1.1");
    310             unprovide("SSLContext", "TLSv1.2");
    311         }
    312 
    313         // Fixups for the RI
    314         if (IS_RI) {
    315             // different names: Standard Names says PKIX, JSSE Reference Guide says SunX509 or NewSunX509
    316             unprovide("KeyManagerFactory", "PKIX");
    317             provide("KeyManagerFactory", "SunX509");
    318             provide("KeyManagerFactory", "NewSunX509");
    319         }
    320 
    321         // Fixups for dalvik
    322         if (!IS_RI) {
    323 
    324             // whole types that we do not provide
    325             PROVIDER_ALGORITHMS.remove("Configuration");
    326             PROVIDER_ALGORITHMS.remove("GssApiMechanism");
    327             PROVIDER_ALGORITHMS.remove("KeyInfoFactory");
    328             PROVIDER_ALGORITHMS.remove("Policy");
    329             PROVIDER_ALGORITHMS.remove("SaslClientFactory");
    330             PROVIDER_ALGORITHMS.remove("SaslServerFactory");
    331             PROVIDER_ALGORITHMS.remove("TerminalFactory");
    332             PROVIDER_ALGORITHMS.remove("TransformService");
    333             PROVIDER_ALGORITHMS.remove("XMLSignatureFactory");
    334 
    335             // different names Diffie-Hellman vs DH
    336             unprovide("AlgorithmParameterGenerator", "DiffieHellman");
    337             provide("AlgorithmParameterGenerator", "DH");
    338             unprovide("AlgorithmParameters", "DiffieHellman");
    339             provide("AlgorithmParameters", "DH");
    340             unprovide("KeyAgreement", "DiffieHellman");
    341             provide("KeyAgreement", "DH");
    342             unprovide("KeyFactory", "DiffieHellman");
    343             provide("KeyFactory", "DH");
    344             unprovide("KeyPairGenerator", "DiffieHellman");
    345             provide("KeyPairGenerator", "DH");
    346 
    347             // different names PBEWithSHA1AndDESede vs PBEWithSHAAnd3-KEYTripleDES-CBC
    348             unprovide("AlgorithmParameters", "PBEWithSHA1AndDESede");
    349             unprovide("Cipher", "PBEWithSHA1AndDESede");
    350             unprovide("SecretKeyFactory", "PBEWithSHA1AndDESede");
    351             provide("AlgorithmParameters", "PKCS12PBE");
    352             provide("Cipher", "PBEWithSHAAnd3-KEYTripleDES-CBC");
    353             provide("SecretKeyFactory", "PBEWithSHAAnd3-KEYTripleDES-CBC");
    354 
    355             // different names: BouncyCastle actually uses the Standard name of SHA-1 vs SHA
    356             unprovide("MessageDigest", "SHA");
    357             provide("MessageDigest", "SHA-1");
    358 
    359             // Added to support Android KeyStore operations
    360             provide("Signature", "NONEwithRSA");
    361             provide("Cipher", "RSA/ECB/NOPADDING");
    362             provide("Cipher", "RSA/ECB/PKCS1PADDING");
    363 
    364             // different names: ARCFOUR vs ARC4
    365             unprovide("Cipher", "ARCFOUR");
    366             provide("Cipher", "ARC4");
    367             unprovide("KeyGenerator", "ARCFOUR");
    368             provide("KeyGenerator", "ARC4");
    369 
    370             // different case names: Blowfish vs BLOWFISH
    371             unprovide("AlgorithmParameters", "Blowfish");
    372             provide("AlgorithmParameters", "BLOWFISH");
    373             unprovide("Cipher", "Blowfish");
    374             provide("Cipher", "BLOWFISH");
    375             unprovide("KeyGenerator", "Blowfish");
    376             provide("KeyGenerator", "BLOWFISH");
    377 
    378             // Harmony has X.509, BouncyCastle X509
    379             // TODO remove one, probably Harmony's
    380             provide("CertificateFactory", "X509");
    381 
    382             // not just different names, but different binary formats
    383             unprovide("KeyStore", "JKS");
    384             provide("KeyStore", "BKS");
    385             unprovide("KeyStore", "JCEKS");
    386             provide("KeyStore", "BouncyCastle");
    387 
    388             // Noise to support KeyStore.PKCS12
    389             provide("Cipher", "PBEWITHMD5AND128BITAES-CBC-OPENSSL");
    390             provide("Cipher", "PBEWITHMD5AND192BITAES-CBC-OPENSSL");
    391             provide("Cipher", "PBEWITHMD5AND256BITAES-CBC-OPENSSL");
    392             provide("Cipher", "PBEWITHMD5ANDRC2");
    393             provide("Cipher", "PBEWITHSHA1ANDDES");
    394             provide("Cipher", "PBEWITHSHA1ANDRC2");
    395             provide("Cipher", "PBEWITHSHA256AND128BITAES-CBC-BC");
    396             provide("Cipher", "PBEWITHSHA256AND192BITAES-CBC-BC");
    397             provide("Cipher", "PBEWITHSHA256AND256BITAES-CBC-BC");
    398             provide("Cipher", "PBEWITHSHAAND128BITAES-CBC-BC");
    399             provide("Cipher", "PBEWITHSHAAND128BITRC2-CBC");
    400             provide("Cipher", "PBEWITHSHAAND128BITRC4");
    401             provide("Cipher", "PBEWITHSHAAND192BITAES-CBC-BC");
    402             provide("Cipher", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
    403             provide("Cipher", "PBEWITHSHAAND256BITAES-CBC-BC");
    404             provide("Cipher", "PBEWITHSHAAND40BITRC2-CBC");
    405             provide("Cipher", "PBEWITHSHAAND40BITRC4");
    406             provide("Cipher", "PBEWITHSHAANDTWOFISH-CBC");
    407             provide("Mac", "PBEWITHHMACSHA");
    408             provide("Mac", "PBEWITHHMACSHA1");
    409             provide("SecretKeyFactory", "PBEWITHHMACSHA1");
    410             provide("SecretKeyFactory", "PBEWITHMD5AND128BITAES-CBC-OPENSSL");
    411             provide("SecretKeyFactory", "PBEWITHMD5AND192BITAES-CBC-OPENSSL");
    412             provide("SecretKeyFactory", "PBEWITHMD5AND256BITAES-CBC-OPENSSL");
    413             provide("SecretKeyFactory", "PBEWITHMD5ANDRC2");
    414             provide("SecretKeyFactory", "PBEWITHSHA1ANDDES");
    415             provide("SecretKeyFactory", "PBEWITHSHA1ANDRC2");
    416             provide("SecretKeyFactory", "PBEWITHSHA256AND128BITAES-CBC-BC");
    417             provide("SecretKeyFactory", "PBEWITHSHA256AND192BITAES-CBC-BC");
    418             provide("SecretKeyFactory", "PBEWITHSHA256AND256BITAES-CBC-BC");
    419             provide("SecretKeyFactory", "PBEWITHSHAAND128BITAES-CBC-BC");
    420             provide("SecretKeyFactory", "PBEWITHSHAAND128BITRC2-CBC");
    421             provide("SecretKeyFactory", "PBEWITHSHAAND128BITRC4");
    422             provide("SecretKeyFactory", "PBEWITHSHAAND192BITAES-CBC-BC");
    423             provide("SecretKeyFactory", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
    424             provide("SecretKeyFactory", "PBEWITHSHAAND256BITAES-CBC-BC");
    425             provide("SecretKeyFactory", "PBEWITHSHAAND40BITRC2-CBC");
    426             provide("SecretKeyFactory", "PBEWITHSHAAND40BITRC4");
    427             provide("SecretKeyFactory", "PBEWITHSHAANDTWOFISH-CBC");
    428 
    429             // Needed by our OpenSSL provider
    430             provide("Cipher", "AES/CBC/NOPADDING");
    431             provide("Cipher", "AES/CBC/PKCS5PADDING");
    432             provide("Cipher", "AES/CFB/NOPADDING");
    433             provide("Cipher", "AES/CFB/PKCS5PADDING");
    434             provide("Cipher", "AES/CTR/NOPADDING");
    435             provide("Cipher", "AES/CTR/PKCS5PADDING");
    436             provide("Cipher", "AES/ECB/NOPADDING");
    437             provide("Cipher", "AES/ECB/PKCS5PADDING");
    438             provide("Cipher", "AES/OFB/NOPADDING");
    439             provide("Cipher", "AES/OFB/PKCS5PADDING");
    440             provide("Cipher", "DESEDE/CBC/NOPADDING");
    441             provide("Cipher", "DESEDE/CBC/PKCS5PADDING");
    442             provide("Cipher", "DESEDE/CFB/NOPADDING");
    443             provide("Cipher", "DESEDE/CFB/PKCS5PADDING");
    444             provide("Cipher", "DESEDE/ECB/NOPADDING");
    445             provide("Cipher", "DESEDE/ECB/PKCS5PADDING");
    446             provide("Cipher", "DESEDE/OFB/NOPADDING");
    447             provide("Cipher", "DESEDE/OFB/PKCS5PADDING");
    448 
    449             // removed LDAP
    450             unprovide("CertStore", "LDAP");
    451 
    452             // removed MD2
    453             unprovide("MessageDigest", "MD2");
    454             unprovide("Signature", "MD2withRSA");
    455 
    456             // removed RC2
    457             // NOTE the implementation remains to support PKCS12 keystores
    458             unprovide("AlgorithmParameters", "PBEWithSHA1AndRC2_40");
    459             unprovide("AlgorithmParameters", "RC2");
    460             unprovide("Cipher", "PBEWithSHA1AndRC2_40");
    461             unprovide("Cipher", "RC2");
    462             unprovide("KeyGenerator", "RC2");
    463             unprovide("SecretKeyFactory", "PBEWithSHA1AndRC2_40");
    464 
    465             // PBEWithMD5AndTripleDES is Sun proprietary
    466             unprovide("AlgorithmParameters", "PBEWithMD5AndTripleDES");
    467             unprovide("Cipher", "PBEWithMD5AndTripleDES");
    468             unprovide("SecretKeyFactory", "PBEWithMD5AndTripleDES");
    469 
    470             // missing from Bouncy Castle
    471             // Standard Names document says to use specific PBEWith*And*
    472             unprovide("AlgorithmParameters", "PBE");
    473 
    474             // missing from Bouncy Castle
    475             // TODO add to JDKAlgorithmParameters perhaps as wrapper on PBES2Parameters
    476             // For now, can use AlgorithmParametersSpec javax.crypto.spec.PBEParameterSpec instead
    477             unprovide("AlgorithmParameters", "PBEWithMD5AndDES"); // 1.2.840.113549.1.5.3
    478 
    479             // EC support
    480             // provide("AlgorithmParameters", "EC");
    481             provide("KeyAgreement", "ECDH");
    482             provide("KeyFactory", "EC");
    483             provide("KeyPairGenerator", "EC");
    484             provide("Signature", "NONEWITHECDSA");
    485             provide("Signature", "ECDSA"); // as opposed to SHA1WITHECDSA
    486             provide("Signature", "SHA256WITHECDSA");
    487             provide("Signature", "SHA384WITHECDSA");
    488             provide("Signature", "SHA512WITHECDSA");
    489 
    490             // Android's CA store
    491             provide("KeyStore", "AndroidCAStore");
    492 
    493             // Android's KeyStore provider
    494             if (Security.getProvider("AndroidKeyStore") != null) {
    495                 provide("KeyStore", "AndroidKeyStore");
    496             }
    497         }
    498     }
    499 
    500     public static final String SSL_CONTEXT_PROTOCOLS_DEFAULT = "Default";
    501     public static final Set<String> SSL_CONTEXT_PROTOCOLS = new HashSet<String>(Arrays.asList(
    502         SSL_CONTEXT_PROTOCOLS_DEFAULT,
    503         "SSL",
    504         // "SSLv2",
    505         "SSLv3",
    506         "TLS",
    507         "TLSv1",
    508         "TLSv1.1",
    509         "TLSv1.2"));
    510     public static final String SSL_CONTEXT_PROTOCOL_DEFAULT = "TLS";
    511 
    512     public static final Set<String> KEY_TYPES = new HashSet<String>(Arrays.asList(
    513         "RSA",
    514         "DSA",
    515         // DH_* are specified by standard names, but do not seem to be supported by RI
    516         // "DH_RSA",
    517         // "DH_DSA",
    518         "EC",
    519         "EC_EC",
    520         "EC_RSA"));
    521 
    522     public static final Set<String> SSL_SOCKET_PROTOCOLS = new HashSet<String>(Arrays.asList(
    523         // "SSLv2",
    524         "SSLv3",
    525         "TLSv1",
    526         "TLSv1.1",
    527         "TLSv1.2"));
    528     static {
    529         if (IS_RI) {
    530             /* Even though we use OpenSSL's SSLv23_method which
    531              * supports sending SSLv2 client hello messages, the
    532              * OpenSSL implementation in s23_client_hello disables
    533              * this if SSL_OP_NO_SSLv2 is specified, which we always
    534              * do to disable general use of SSLv2.
    535              */
    536             SSL_SOCKET_PROTOCOLS.add("SSLv2Hello");
    537         }
    538     }
    539 
    540     public static final Set<String> SSL_SOCKET_PROTOCOLS_SSLENGINE = new HashSet<String>(SSL_SOCKET_PROTOCOLS);
    541     static {
    542         // No TLSv1.1 or TLSv1.2 support on SSLEngine based provider
    543         if (!IS_RI) {
    544             SSL_SOCKET_PROTOCOLS_SSLENGINE.remove("TLSv1.1");
    545             SSL_SOCKET_PROTOCOLS_SSLENGINE.remove("TLSv1.2");
    546         }
    547     }
    548 
    549     /**
    550      * Valid values for X509TrustManager.checkClientTrusted authType,
    551      * either the algorithm of the public key or UNKNOWN.
    552      */
    553     public static final Set<String> CLIENT_AUTH_TYPES = new HashSet<String>(Arrays.asList(
    554         "RSA",
    555         "DSA",
    556         "EC",
    557         "UNKNOWN"));
    558 
    559     /**
    560      * Valid values for X509TrustManager.checkServerTrusted authType,
    561      * either key exchange algorithm part of the cipher suite
    562      * or UNKNOWN.
    563      */
    564     public static final Set<String> SERVER_AUTH_TYPES = new HashSet<String>(Arrays.asList(
    565         "DHE_DSS",
    566         "DHE_DSS_EXPORT",
    567         "DHE_RSA",
    568         "DHE_RSA_EXPORT",
    569         "DH_DSS_EXPORT",
    570         "DH_RSA_EXPORT",
    571         "DH_anon",
    572         "DH_anon_EXPORT",
    573         "KRB5",
    574         "KRB5_EXPORT",
    575         "RSA",
    576         "RSA_EXPORT",
    577         "RSA_EXPORT1024",
    578         "ECDH_ECDSA",
    579         "ECDH_RSA",
    580         "ECDHE_ECDSA",
    581         "ECDHE_RSA",
    582         "UNKNOWN"));
    583 
    584     public static final String CIPHER_SUITE_INVALID = "SSL_NULL_WITH_NULL_NULL";
    585 
    586     public static final Set<String> CIPHER_SUITES_NEITHER = new HashSet<String>();
    587 
    588     public static final Set<String> CIPHER_SUITES_RI = new LinkedHashSet<String>();
    589     public static final Set<String> CIPHER_SUITES_OPENSSL = new LinkedHashSet<String>();
    590 
    591     public static final Set<String> CIPHER_SUITES;
    592 
    593     private static final void addRi(String cipherSuite) {
    594         CIPHER_SUITES_RI.add(cipherSuite);
    595     }
    596 
    597     private static final void addOpenSsl(String cipherSuite) {
    598         CIPHER_SUITES_OPENSSL.add(cipherSuite);
    599     }
    600 
    601     private static final void addBoth(String cipherSuite) {
    602         addRi(cipherSuite);
    603         addOpenSsl(cipherSuite);
    604     }
    605 
    606     private static final void addNeither(String cipherSuite) {
    607         CIPHER_SUITES_NEITHER.add(cipherSuite);
    608     }
    609 
    610     static {
    611         // Note these are added in priority order as defined by RI 7 documentation.
    612         // defaultCipherSuites
    613         addNeither("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384");
    614         addNeither("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384");
    615         addNeither("TLS_RSA_WITH_AES_256_CBC_SHA256");
    616         addNeither("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384");
    617         addNeither("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384");
    618         addNeither("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256");
    619         addNeither("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256");
    620         addOpenSsl("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA");
    621         addOpenSsl("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA");
    622         addOpenSsl("TLS_RSA_WITH_AES_256_CBC_SHA");
    623         addOpenSsl("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA");
    624         addOpenSsl("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA");
    625         addOpenSsl("TLS_DHE_RSA_WITH_AES_256_CBC_SHA");
    626         addOpenSsl("TLS_DHE_DSS_WITH_AES_256_CBC_SHA");
    627         addRi(     "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256");
    628         addRi(     "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256");
    629         addRi(     "TLS_RSA_WITH_AES_128_CBC_SHA256");
    630         addRi(     "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256");
    631         addRi(     "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256");
    632         addRi(     "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256");
    633         addRi(     "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256");
    634         addBoth(   "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA");
    635         addBoth(   "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
    636         addBoth(   "TLS_RSA_WITH_AES_128_CBC_SHA");
    637         addBoth(   "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA");
    638         addBoth(   "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA");
    639         addBoth(   "TLS_DHE_RSA_WITH_AES_128_CBC_SHA");
    640         addBoth(   "TLS_DHE_DSS_WITH_AES_128_CBC_SHA");
    641         addBoth(   "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA");
    642         addBoth(   "TLS_ECDHE_RSA_WITH_RC4_128_SHA");
    643         addBoth(   "SSL_RSA_WITH_RC4_128_SHA");
    644         addBoth(   "TLS_ECDH_ECDSA_WITH_RC4_128_SHA");
    645         addBoth(   "TLS_ECDH_RSA_WITH_RC4_128_SHA");
    646         addBoth(   "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA");
    647         addBoth(   "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA");
    648         addBoth(   "SSL_RSA_WITH_3DES_EDE_CBC_SHA");
    649         addBoth(   "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA");
    650         addBoth(   "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA");
    651         addBoth(   "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA");
    652         addBoth(   "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA");
    653         addBoth(   "SSL_RSA_WITH_RC4_128_MD5");
    654         // RFC 5746's Signaling Cipher Suite Value to indicate a request for secure renegotiation
    655         addBoth(CIPHER_SUITE_SECURE_RENEGOTIATION);
    656 
    657         // non-defaultCipherSuites
    658         addNeither("TLS_DH_anon_WITH_AES_256_CBC_SHA256");
    659         addOpenSsl("TLS_ECDH_anon_WITH_AES_256_CBC_SHA");
    660         addOpenSsl("TLS_DH_anon_WITH_AES_256_CBC_SHA");
    661         addRi(     "TLS_DH_anon_WITH_AES_128_CBC_SHA256");
    662         addBoth(   "TLS_ECDH_anon_WITH_AES_128_CBC_SHA");
    663         addBoth(   "TLS_DH_anon_WITH_AES_128_CBC_SHA");
    664         addBoth(   "TLS_ECDH_anon_WITH_RC4_128_SHA");
    665         addBoth(   "SSL_DH_anon_WITH_RC4_128_MD5");
    666         addBoth(   "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA");
    667         addBoth(   "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA");
    668         addRi(     "TLS_RSA_WITH_NULL_SHA256");
    669         addBoth(   "TLS_ECDHE_ECDSA_WITH_NULL_SHA");
    670         addBoth(   "TLS_ECDHE_RSA_WITH_NULL_SHA");
    671         addBoth(   "SSL_RSA_WITH_NULL_SHA");
    672         addBoth(   "TLS_ECDH_ECDSA_WITH_NULL_SHA");
    673         addBoth(   "TLS_ECDH_RSA_WITH_NULL_SHA");
    674         addBoth(   "TLS_ECDH_anon_WITH_NULL_SHA");
    675         addBoth(   "SSL_RSA_WITH_NULL_MD5");
    676         addBoth(   "SSL_RSA_WITH_DES_CBC_SHA");
    677         addBoth(   "SSL_DHE_RSA_WITH_DES_CBC_SHA");
    678         addBoth(   "SSL_DHE_DSS_WITH_DES_CBC_SHA");
    679         addBoth(   "SSL_DH_anon_WITH_DES_CBC_SHA");
    680         addBoth(   "SSL_RSA_EXPORT_WITH_RC4_40_MD5");
    681         addBoth(   "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5");
    682         addBoth(   "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA");
    683         addBoth(   "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA");
    684         addBoth(   "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
    685         addBoth(   "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA");
    686 
    687         // Android does not have Keberos support
    688         addRi(     "TLS_KRB5_WITH_RC4_128_SHA");
    689         addRi(     "TLS_KRB5_WITH_RC4_128_MD5");
    690         addRi(     "TLS_KRB5_WITH_3DES_EDE_CBC_SHA");
    691         addRi(     "TLS_KRB5_WITH_3DES_EDE_CBC_MD5");
    692         addRi(     "TLS_KRB5_WITH_DES_CBC_SHA");
    693         addRi(     "TLS_KRB5_WITH_DES_CBC_MD5");
    694         addRi(     "TLS_KRB5_EXPORT_WITH_RC4_40_SHA");
    695         addRi(     "TLS_KRB5_EXPORT_WITH_RC4_40_MD5");
    696         addRi(     "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA");
    697         addRi(     "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5");
    698 
    699         // Dropped
    700         addNeither("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA");
    701         addNeither("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA");
    702 
    703         // Old non standard exportable encryption
    704         addNeither("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA");
    705         addNeither("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA");
    706 
    707         // No RC2
    708         addNeither("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5");
    709         addNeither("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA");
    710         addNeither("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5");
    711 
    712         CIPHER_SUITES = (IS_RI) ? CIPHER_SUITES_RI : CIPHER_SUITES_OPENSSL;
    713     }
    714 
    715     public static final List<String> CIPHER_SUITES_DEFAULT = (IS_RI)
    716             ? Arrays.asList("TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
    717                             "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
    718                             "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
    719                             "SSL_RSA_WITH_RC4_128_SHA",
    720                             "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
    721                             "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
    722                             "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
    723                             "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
    724                             "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
    725                             "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
    726                             "TLS_ECDH_RSA_WITH_RC4_128_SHA",
    727                             "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
    728                             "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
    729                             "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
    730                             "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
    731                             "TLS_RSA_WITH_AES_128_CBC_SHA",
    732                             "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
    733                             "SSL_RSA_WITH_RC4_128_MD5",
    734                             "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
    735                             "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
    736                             "SSL_RSA_WITH_3DES_EDE_CBC_SHA")
    737             : Arrays.asList("SSL_RSA_WITH_RC4_128_MD5",
    738                             "SSL_RSA_WITH_RC4_128_SHA",
    739                             "TLS_RSA_WITH_AES_128_CBC_SHA",
    740                             "TLS_RSA_WITH_AES_256_CBC_SHA",
    741                             "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
    742                             "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
    743                             "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
    744                             "TLS_ECDH_RSA_WITH_RC4_128_SHA",
    745                             "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
    746                             "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
    747                             "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
    748                             "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
    749                             "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
    750                             "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
    751                             "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
    752                             "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
    753                             "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
    754                             "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
    755                             "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
    756                             "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
    757                             "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
    758                             "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
    759                             "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
    760                             "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
    761                             "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
    762                             "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
    763                             "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
    764                             "SSL_RSA_WITH_DES_CBC_SHA",
    765                             "SSL_DHE_RSA_WITH_DES_CBC_SHA",
    766                             "SSL_DHE_DSS_WITH_DES_CBC_SHA",
    767                             "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
    768                             "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
    769                             "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
    770                             "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
    771                             CIPHER_SUITE_SECURE_RENEGOTIATION);
    772 
    773     public static final Set<String> CIPHER_SUITES_SSLENGINE = new HashSet<String>(CIPHER_SUITES);
    774     static {
    775         // No Elliptic Curve support on SSLEngine based provider
    776         if (!IS_RI) {
    777             Iterator<String> i = CIPHER_SUITES_SSLENGINE.iterator();
    778             while (i.hasNext()) {
    779                 String cs = i.next();
    780                 if (cs.startsWith("TLS_EC") || cs.equals(CIPHER_SUITE_SECURE_RENEGOTIATION)) {
    781                     i.remove();
    782                 }
    783             }
    784         }
    785     }
    786 
    787     public static final Map<String, Class<? extends KeySpec>> PRIVATE_KEY_SPEC_CLASSES;
    788     public static final Map<String, Class<? extends KeySpec>> PUBLIC_KEY_SPEC_CLASSES;
    789     public static final Map<String, Integer> MINIMUM_KEY_SIZE;
    790     static {
    791         PRIVATE_KEY_SPEC_CLASSES = new HashMap<String, Class<? extends KeySpec>>();
    792         PUBLIC_KEY_SPEC_CLASSES = new HashMap<String, Class<? extends KeySpec>>();
    793         MINIMUM_KEY_SIZE = new HashMap<String, Integer>();
    794         PRIVATE_KEY_SPEC_CLASSES.put("RSA", RSAPrivateCrtKeySpec.class);
    795         PUBLIC_KEY_SPEC_CLASSES.put("RSA", RSAPublicKeySpec.class);
    796         MINIMUM_KEY_SIZE.put("RSA", 256);
    797         PRIVATE_KEY_SPEC_CLASSES.put("DSA", DSAPrivateKeySpec.class);
    798         PUBLIC_KEY_SPEC_CLASSES.put("DSA", DSAPublicKeySpec.class);
    799         MINIMUM_KEY_SIZE.put("DSA", 512);
    800         PRIVATE_KEY_SPEC_CLASSES.put("DH", DHPrivateKeySpec.class);
    801         PUBLIC_KEY_SPEC_CLASSES.put("DH", DHPublicKeySpec.class);
    802         MINIMUM_KEY_SIZE.put("DH", 256);
    803         PRIVATE_KEY_SPEC_CLASSES.put("EC", ECPrivateKeySpec.class);
    804         PUBLIC_KEY_SPEC_CLASSES.put("EC", ECPublicKeySpec.class);
    805         MINIMUM_KEY_SIZE.put("EC", 256);
    806     }
    807 
    808     public static Class<? extends KeySpec> getPrivateKeySpecClass(String algName) {
    809         return PRIVATE_KEY_SPEC_CLASSES.get(algName);
    810     }
    811 
    812     public static Class<? extends KeySpec> getPublicKeySpecClass(String algName) {
    813         return PUBLIC_KEY_SPEC_CLASSES.get(algName);
    814     }
    815 
    816     public static int getMinimumKeySize(String algName) {
    817         return MINIMUM_KEY_SIZE.get(algName);
    818     }
    819 
    820     /**
    821      * Asserts that the cipher suites array is non-null and that it
    822      * all of its contents are cipher suites known to this
    823      * implementation. As a convenience, returns any unenabled cipher
    824      * suites in a test for those that want to verify separately that
    825      * all cipher suites were included.
    826      */
    827     public static Set<String> assertValidCipherSuites(Set<String> expected, String[] cipherSuites) {
    828         assertNotNull(cipherSuites);
    829         assertTrue(cipherSuites.length != 0);
    830 
    831         // Make sure all cipherSuites names are expected
    832         Set remainingCipherSuites = new HashSet<String>(expected);
    833         Set unknownCipherSuites = new HashSet<String>();
    834         for (String cipherSuite : cipherSuites) {
    835             boolean removed = remainingCipherSuites.remove(cipherSuite);
    836             if (!removed) {
    837                 unknownCipherSuites.add(cipherSuite);
    838             }
    839         }
    840         assertEquals("Unknown cipher suites", Collections.EMPTY_SET, unknownCipherSuites);
    841         return remainingCipherSuites;
    842     }
    843 
    844     /**
    845      * After using assertValidCipherSuites on cipherSuites,
    846      * assertSupportedCipherSuites additionally verifies that all
    847      * supported cipher suites where in the input array.
    848      */
    849     public static void assertSupportedCipherSuites(Set<String> expected, String[] cipherSuites) {
    850         Set<String> remainingCipherSuites = assertValidCipherSuites(expected, cipherSuites);
    851         assertEquals("Missing cipher suites", Collections.EMPTY_SET, remainingCipherSuites);
    852         assertEquals(expected.size(), cipherSuites.length);
    853     }
    854 
    855     /**
    856      * Asserts that the protocols array is non-null and that it all of
    857      * its contents are protocols known to this implementation. As a
    858      * convenience, returns any unenabled protocols in a test for
    859      * those that want to verify separately that all protocols were
    860      * included.
    861      */
    862     public static Set<String> assertValidProtocols(Set<String> expected, String[] protocols) {
    863         assertNotNull(protocols);
    864         assertTrue(protocols.length != 0);
    865 
    866         // Make sure all protocols names are expected
    867         Set remainingProtocols = new HashSet<String>(expected);
    868         Set unknownProtocols = new HashSet<String>();
    869         for (String protocol : protocols) {
    870             if (!remainingProtocols.remove(protocol)) {
    871                 unknownProtocols.add(protocol);
    872             }
    873         }
    874         assertEquals("Unknown protocols", Collections.EMPTY_SET, unknownProtocols);
    875         return remainingProtocols;
    876     }
    877 
    878     /**
    879      * After using assertValidProtocols on protocols,
    880      * assertSupportedProtocols additionally verifies that all
    881      * supported protocols where in the input array.
    882      */
    883     public static void assertSupportedProtocols(Set<String> expected, String[] protocols) {
    884         Set<String> remainingProtocols = assertValidProtocols(expected, protocols);
    885         assertEquals("Missing protocols", Collections.EMPTY_SET, remainingProtocols);
    886         assertEquals(expected.size(), protocols.length);
    887     }
    888 
    889     /**
    890      * Assert cipher suites match the default list in content and priority order.
    891      */
    892     public static void assertDefaultCipherSuites(String[] cipherSuites) {
    893         assertValidCipherSuites(CIPHER_SUITES, cipherSuites);
    894         assertEquals(CIPHER_SUITES_DEFAULT, Arrays.asList(cipherSuites));
    895     }
    896 
    897     /**
    898      * Get all supported mode names for the given cipher.
    899      */
    900     public static Set<String> getModesForCipher(String cipher) {
    901         return CIPHER_MODES.get(cipher);
    902     }
    903 
    904     /**
    905      * Get all supported padding names for the given cipher.
    906      */
    907     public static Set<String> getPaddingsForCipher(String cipher) {
    908         return CIPHER_PADDINGS.get(cipher);
    909     }
    910 }
    911