Home | History | Annotate | Download | only in jsse
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package org.apache.harmony.xnet.provider.jsse;
     19 
     20 import java.security.GeneralSecurityException;
     21 import java.util.Hashtable;
     22 import javax.crypto.Cipher;
     23 
     24 /**
     25  * Represents Cipher Suite as defined in TLS 1.0 spec.,
     26  * A.5. The CipherSuite;
     27  * C. CipherSuite definitions.
     28  * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec.</a>
     29  *
     30  */
     31 public class CipherSuite {
     32 
     33     /**
     34      * true if this cipher suite is supported
     35      */
     36     boolean supported = true;
     37 
     38     /**
     39      * cipher suite key exchange
     40      */
     41     final int keyExchange;
     42 
     43     /**
     44      * algorithm used for authentication ("RSA", "DSA", "DH", null for anonymous)
     45      */
     46     final String authType;
     47 
     48     /**
     49      * cipher
     50      */
     51     final String cipherName;
     52 
     53     /**
     54      * Cipher information
     55      */
     56     final int keyMaterial;
     57     final int expandedKeyMaterial;
     58     final int effectiveKeyBytes;
     59     final int ivSize;
     60     final private int blockSize;
     61 
     62     // cipher suite code
     63     private final byte[] cipherSuiteCode;
     64 
     65     // cipher suite name
     66     private final String name;
     67 
     68     // true if cipher suite is exportable
     69     private final boolean isExportable;
     70 
     71     // Hash algorithm
     72     final private String hashName;
     73 
     74     // MAC algorithm
     75     final private String hmacName;
     76 
     77     // Hash size
     78     final private int hashSize;
     79 
     80     /**
     81      * key exchange values
     82      */
     83     static final int KEY_EXCHANGE_RSA = 1;
     84     static final int KEY_EXCHANGE_RSA_EXPORT = 2;
     85     static final int KEY_EXCHANGE_DHE_DSS = 3;
     86     static final int KEY_EXCHANGE_DHE_DSS_EXPORT = 4;
     87     static final int KEY_EXCHANGE_DHE_RSA = 5;
     88     static final int KEY_EXCHANGE_DHE_RSA_EXPORT = 6;
     89     static final int KEY_EXCHANGE_DH_DSS = 7;
     90     static final int KEY_EXCHANGE_DH_RSA = 8;
     91     static final int KEY_EXCHANGE_DH_anon = 9;
     92     static final int KEY_EXCHANGE_DH_anon_EXPORT = 10;
     93     static final int KEY_EXCHANGE_DH_DSS_EXPORT = 11;
     94     static final int KEY_EXCHANGE_DH_RSA_EXPORT = 12;
     95 
     96     /**
     97      * TLS cipher suite codes
     98      */
     99     static final byte[] CODE_SSL_NULL_WITH_NULL_NULL = { 0x00, 0x00 };
    100     static final byte[] CODE_SSL_RSA_WITH_NULL_MD5 = { 0x00, 0x01 };
    101     static final byte[] CODE_SSL_RSA_WITH_NULL_SHA = { 0x00, 0x02 };
    102     static final byte[] CODE_SSL_RSA_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x03 };
    103     static final byte[] CODE_SSL_RSA_WITH_RC4_128_MD5 = { 0x00, 0x04 };
    104     static final byte[] CODE_SSL_RSA_WITH_RC4_128_SHA = { 0x00, 0x05 };
    105     static final byte[] CODE_SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00, 0x06 };
    106     // BEGIN android-removed
    107     // static final byte[] CODE_TLS_RSA_WITH_IDEA_CBC_SHA = { 0x00, 0x07 };
    108     // END android-removed
    109     static final byte[] CODE_SSL_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x08 };
    110     static final byte[] CODE_SSL_RSA_WITH_DES_CBC_SHA = { 0x00, 0x09 };
    111     static final byte[] CODE_SSL_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x0A };
    112     // BEGIN android-removed
    113     // static final byte[] CODE_SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0B };
    114     // static final byte[] CODE_SSL_DH_DSS_WITH_DES_CBC_SHA = { 0x00, 0x0C };
    115     // static final byte[] CODE_SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x0D };
    116     // static final byte[] CODE_SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0E };
    117     // static final byte[] CODE_SSL_DH_RSA_WITH_DES_CBC_SHA = { 0x00, 0x0F };
    118     // static final byte[] CODE_SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x10 };
    119     // END android-removed
    120     static final byte[] CODE_SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x11 };
    121     static final byte[] CODE_SSL_DHE_DSS_WITH_DES_CBC_SHA = { 0x00, 0x12 };
    122     static final byte[] CODE_SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x13 };
    123     static final byte[] CODE_SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x14 };
    124     static final byte[] CODE_SSL_DHE_RSA_WITH_DES_CBC_SHA = { 0x00, 0x15 };
    125     static final byte[] CODE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x16 };
    126     static final byte[] CODE_SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x17 };
    127     static final byte[] CODE_SSL_DH_anon_WITH_RC4_128_MD5 = { 0x00, 0x18 };
    128     static final byte[] CODE_SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x19 };
    129     static final byte[] CODE_SSL_DH_anon_WITH_DES_CBC_SHA = { 0x00, 0x1A };
    130     static final byte[] CODE_SSL_DH_anon_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x1B };
    131 
    132     // AES Cipher Suites from RFC 3268 - http://www.ietf.org/rfc/rfc3268.txt
    133     static final byte[] CODE_TLS_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x2F };
    134     //static final byte[] CODE_TLS_DH_DSS_WITH_AES_128_CBC_SHA = { 0x00, 0x30 };
    135     //static final byte[] CODE_TLS_DH_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x31 };
    136     static final byte[] CODE_TLS_DHE_DSS_WITH_AES_128_CBC_SHA = { 0x00, 0x32 };
    137     static final byte[] CODE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x33 };
    138     static final byte[] CODE_TLS_DH_anon_WITH_AES_128_CBC_SHA = { 0x00, 0x34 };
    139     static final byte[] CODE_TLS_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x35 };
    140     //static final byte[] CODE_TLS_DH_DSS_WITH_AES_256_CBC_SHA = { 0x00, 0x36 };
    141     //static final byte[] CODE_TLS_DH_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x37 };
    142     static final byte[] CODE_TLS_DHE_DSS_WITH_AES_256_CBC_SHA = { 0x00, 0x38 };
    143     static final byte[] CODE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x39 };
    144     static final byte[] CODE_TLS_DH_anon_WITH_AES_256_CBC_SHA = { 0x00, 0x3A };
    145 
    146     static final CipherSuite SSL_NULL_WITH_NULL_NULL = new CipherSuite(
    147             "SSL_NULL_WITH_NULL_NULL", true, 0, null, null, null,
    148             CODE_SSL_NULL_WITH_NULL_NULL);
    149 
    150     static final CipherSuite SSL_RSA_WITH_NULL_MD5 = new CipherSuite(
    151             "SSL_RSA_WITH_NULL_MD5", true, KEY_EXCHANGE_RSA, "RSA", null, "MD5",
    152             CODE_SSL_RSA_WITH_NULL_MD5);
    153 
    154     static final CipherSuite SSL_RSA_WITH_NULL_SHA = new CipherSuite(
    155             "SSL_RSA_WITH_NULL_SHA", true, KEY_EXCHANGE_RSA, "RSA", null, "SHA",
    156             CODE_SSL_RSA_WITH_NULL_SHA);
    157 
    158     static final CipherSuite SSL_RSA_EXPORT_WITH_RC4_40_MD5 = new CipherSuite(
    159             "SSL_RSA_EXPORT_WITH_RC4_40_MD5", true, KEY_EXCHANGE_RSA_EXPORT,
    160             "RSA", "RC4_40", "MD5", CODE_SSL_RSA_EXPORT_WITH_RC4_40_MD5);
    161 
    162     static final CipherSuite SSL_RSA_WITH_RC4_128_MD5 = new CipherSuite(
    163             "SSL_RSA_WITH_RC4_128_MD5", false, KEY_EXCHANGE_RSA, "RSA", "RC4_128",
    164             "MD5", CODE_SSL_RSA_WITH_RC4_128_MD5);
    165 
    166     static final CipherSuite SSL_RSA_WITH_RC4_128_SHA = new CipherSuite(
    167             "SSL_RSA_WITH_RC4_128_SHA", false, KEY_EXCHANGE_RSA, "RSA", "RC4_128",
    168             "SHA", CODE_SSL_RSA_WITH_RC4_128_SHA);
    169 
    170     static final CipherSuite SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = new CipherSuite(
    171             "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", true, KEY_EXCHANGE_RSA_EXPORT,
    172             "RSA", "RC2_CBC_40", "MD5", CODE_SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5);
    173 
    174     // BEGIN android-removed
    175     // static final CipherSuite TLS_RSA_WITH_IDEA_CBC_SHA = new CipherSuite(
    176     //         "TLS_RSA_WITH_IDEA_CBC_SHA", false, KEY_EXCHANGE_RSA, "RSA", "IDEA_CBC",
    177     //         "SHA", CODE_TLS_RSA_WITH_IDEA_CBC_SHA);
    178     // END android-removed
    179 
    180     static final CipherSuite SSL_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
    181             "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", true, KEY_EXCHANGE_RSA_EXPORT,
    182             "RSA", "DES40_CBC", "SHA", CODE_SSL_RSA_EXPORT_WITH_DES40_CBC_SHA);
    183 
    184     static final CipherSuite SSL_RSA_WITH_DES_CBC_SHA = new CipherSuite(
    185             "SSL_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_RSA, "RSA", "DES_CBC",
    186             "SHA", CODE_SSL_RSA_WITH_DES_CBC_SHA);
    187 
    188     static final CipherSuite SSL_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
    189             "SSL_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_RSA,
    190             "RSA", "3DES_EDE_CBC", "SHA", CODE_SSL_RSA_WITH_3DES_EDE_CBC_SHA);
    191 
    192     // BEGIN android-removed
    193     // static final CipherSuite SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
    194     //         "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", true,
    195     //         KEY_EXCHANGE_DH_DSS_EXPORT, "DH", "DES40_CBC", "SHA",
    196     //         CODE_SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA);
    197     //
    198     // static final CipherSuite SSL_DH_DSS_WITH_DES_CBC_SHA = new CipherSuite(
    199     //         "SSL_DH_DSS_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_DSS,
    200     //         "DH", "DES_CBC", "SHA", CODE_SSL_DH_DSS_WITH_DES_CBC_SHA);
    201     //
    202     // static final CipherSuite SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
    203     //         "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_DSS,
    204     //         "DH", "3DES_EDE_CBC", "SHA", CODE_SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA);
    205     //
    206     // static final CipherSuite SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
    207     //         "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", true,
    208     //         KEY_EXCHANGE_DH_RSA_EXPORT, "DH", "DES40_CBC", "SHA",
    209     //         CODE_SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA);
    210     //
    211     // static final CipherSuite SSL_DH_RSA_WITH_DES_CBC_SHA = new CipherSuite(
    212     //         "SSL_DH_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_RSA,
    213     //         "DH", "DES_CBC", "SHA", CODE_SSL_DH_RSA_WITH_DES_CBC_SHA);
    214     //
    215     // static final CipherSuite SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
    216     //         "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_RSA,
    217     //         "DH", "3DES_EDE_CBC", "SHA", CODE_SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA);
    218     // END android-removed
    219 
    220     static final CipherSuite SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
    221             "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", true,
    222             KEY_EXCHANGE_DHE_DSS_EXPORT, "DSA", "DES40_CBC", "SHA",
    223             CODE_SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA);
    224 
    225     static final CipherSuite SSL_DHE_DSS_WITH_DES_CBC_SHA = new CipherSuite(
    226             "SSL_DHE_DSS_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DHE_DSS,
    227             "DSA", "DES_CBC", "SHA", CODE_SSL_DHE_DSS_WITH_DES_CBC_SHA);
    228 
    229     static final CipherSuite SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
    230             "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DHE_DSS,
    231             "DSA", "3DES_EDE_CBC", "SHA", CODE_SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA);
    232 
    233     static final CipherSuite SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
    234             "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", true,
    235             KEY_EXCHANGE_DHE_RSA_EXPORT, "RSA", "DES40_CBC", "SHA",
    236             CODE_SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA);
    237 
    238     static final CipherSuite SSL_DHE_RSA_WITH_DES_CBC_SHA = new CipherSuite(
    239             "SSL_DHE_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DHE_RSA,
    240             "RSA", "DES_CBC", "SHA", CODE_SSL_DHE_RSA_WITH_DES_CBC_SHA);
    241 
    242     static final CipherSuite SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
    243             "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DHE_RSA,
    244             "RSA", "3DES_EDE_CBC", "SHA", CODE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA);
    245 
    246     static final CipherSuite SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 = new CipherSuite(
    247             "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", true,
    248             KEY_EXCHANGE_DH_anon_EXPORT, "DH", "RC4_40", "MD5",
    249             CODE_SSL_DH_anon_EXPORT_WITH_RC4_40_MD5);
    250 
    251     static final CipherSuite SSL_DH_anon_WITH_RC4_128_MD5 = new CipherSuite(
    252             "SSL_DH_anon_WITH_RC4_128_MD5", false, KEY_EXCHANGE_DH_anon,
    253             "DH", "RC4_128", "MD5", CODE_SSL_DH_anon_WITH_RC4_128_MD5);
    254 
    255     static final CipherSuite SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
    256             "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", true,
    257             KEY_EXCHANGE_DH_anon_EXPORT, "DH", "DES40_CBC", "SHA",
    258             CODE_SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA);
    259 
    260     static final CipherSuite SSL_DH_anon_WITH_DES_CBC_SHA = new CipherSuite(
    261             "SSL_DH_anon_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_anon,
    262             "DH", "DES_CBC", "SHA", CODE_SSL_DH_anon_WITH_DES_CBC_SHA);
    263 
    264     static final CipherSuite SSL_DH_anon_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
    265             "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_anon,
    266             "DH", "3DES_EDE_CBC", "SHA", CODE_SSL_DH_anon_WITH_3DES_EDE_CBC_SHA);
    267 
    268     static final CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA
    269             = new CipherSuite("TLS_RSA_WITH_AES_128_CBC_SHA",
    270                               false,
    271                               KEY_EXCHANGE_RSA,
    272                               "RSA",
    273                               "AES_128",
    274                               "SHA",
    275                               CODE_TLS_RSA_WITH_AES_128_CBC_SHA);
    276     static final CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_SHA
    277             = new CipherSuite("TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
    278                               false,
    279                               KEY_EXCHANGE_DHE_DSS,
    280                               "DSA",
    281                               "AES_128",
    282                               "SHA",
    283                               CODE_TLS_DHE_DSS_WITH_AES_128_CBC_SHA);
    284     static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA
    285             = new CipherSuite("TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
    286                               false,
    287                               KEY_EXCHANGE_DHE_RSA,
    288                               "RSA",
    289                               "AES_128",
    290                               "SHA",
    291                               CODE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
    292     static final CipherSuite TLS_DH_anon_WITH_AES_128_CBC_SHA
    293             = new CipherSuite("TLS_DH_anon_WITH_AES_128_CBC_SHA",
    294                               false,
    295                               KEY_EXCHANGE_DH_anon,
    296                               "DH",
    297                               "AES_128",
    298                               "SHA",
    299                               CODE_TLS_DH_anon_WITH_AES_128_CBC_SHA);
    300     static final CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA
    301             = new CipherSuite("TLS_RSA_WITH_AES_256_CBC_SHA",
    302                               false,
    303                               KEY_EXCHANGE_RSA,
    304                               "RSA",
    305                               "AES_256",
    306                               "SHA",
    307                               CODE_TLS_RSA_WITH_AES_256_CBC_SHA);
    308     static final CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_SHA
    309             = new CipherSuite("TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
    310                               false,
    311                               KEY_EXCHANGE_DHE_DSS,
    312                               "DSA",
    313                               "AES_256",
    314                               "SHA",
    315                               CODE_TLS_DHE_DSS_WITH_AES_256_CBC_SHA);
    316     static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_SHA
    317             = new CipherSuite("TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
    318                               false,
    319                               KEY_EXCHANGE_DHE_RSA,
    320                               "RSA",
    321                               "AES_256",
    322                               "SHA",
    323                               CODE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA);
    324     static final CipherSuite TLS_DH_anon_WITH_AES_256_CBC_SHA
    325             = new CipherSuite("TLS_DH_anon_WITH_AES_256_CBC_SHA",
    326                               false,
    327                               KEY_EXCHANGE_DH_anon,
    328                               "DH",
    329                               "AES_256",
    330                               "SHA",
    331                               CODE_TLS_DH_anon_WITH_AES_256_CBC_SHA);
    332 
    333     // array for quick access to cipher suite by code
    334     private static final CipherSuite[] SUITES_BY_CODE = {
    335         // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
    336         SSL_NULL_WITH_NULL_NULL,                        // { 0x00, 0x00 };
    337         SSL_RSA_WITH_NULL_MD5,                          // { 0x00, 0x01 };
    338         SSL_RSA_WITH_NULL_SHA,                          // { 0x00, 0x02 };
    339         SSL_RSA_EXPORT_WITH_RC4_40_MD5,                 // { 0x00, 0x03 };
    340         SSL_RSA_WITH_RC4_128_MD5,                       // { 0x00, 0x04 };
    341         SSL_RSA_WITH_RC4_128_SHA,                       // { 0x00, 0x05 };
    342         // BEGIN android-changed
    343         null, // SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,    // { 0x00, 0x06 };
    344         null, // TLS_RSA_WITH_IDEA_CBC_SHA,             // { 0x00, 0x07 };
    345         // END android-changed
    346         SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,              // { 0x00, 0x08 };
    347         SSL_RSA_WITH_DES_CBC_SHA,                       // { 0x00, 0x09 };
    348         SSL_RSA_WITH_3DES_EDE_CBC_SHA,                  // { 0x00, 0x0a };
    349         // BEGIN android-changed
    350         null, // SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA   // { 0x00, 0x0b };
    351         null, // SSL_DH_DSS_WITH_DES_CBC_SHA,           // { 0x00, 0x0c };
    352         null, // SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA,      // { 0x00, 0x0d };
    353         null, // SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,  // { 0x00, 0x0e };
    354         null, // SSL_DH_RSA_WITH_DES_CBC_SHA,           // { 0x00, 0x0f };
    355         null, // SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,      // { 0x00, 0x10 };
    356         // END android-changed
    357         SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,          // { 0x00, 0x11 };
    358         SSL_DHE_DSS_WITH_DES_CBC_SHA,                   // { 0x00, 0x12 };
    359         SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,              // { 0x00, 0x13 };
    360         SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,          // { 0x00, 0x14 };
    361         SSL_DHE_RSA_WITH_DES_CBC_SHA,                   // { 0x00, 0x15 };
    362         SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,              // { 0x00, 0x16 };
    363         SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,             // { 0x00, 0x17 };
    364         SSL_DH_anon_WITH_RC4_128_MD5,                   // { 0x00, 0x18 };
    365         SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA,          // { 0x00, 0x19 };
    366         SSL_DH_anon_WITH_DES_CBC_SHA,                   // { 0x00, 0x1A };
    367         SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,              // { 0x00, 0x1B };
    368         // BEGIN android-added
    369         null, // SSL_FORTEZZA_KEA_WITH_NULL_SHA         // { 0x00, 0x1C };
    370         null, // SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA // { 0x00, 0x1D };
    371         null, // TLS_KRB5_WITH_DES_CBC_SHA              // { 0x00, 0x1E };
    372         null, // TLS_KRB5_WITH_3DES_EDE_CBC_SHA         // { 0x00, 0x1F };
    373         null, // TLS_KRB5_WITH_RC4_128_SHA              // { 0x00, 0x20 };
    374         null, // TLS_KRB5_WITH_IDEA_CBC_SHA             // { 0x00, 0x21 };
    375         null, // TLS_KRB5_WITH_DES_CBC_MD5              // { 0x00, 0x22 };
    376         null, // TLS_KRB5_WITH_3DES_EDE_CBC_MD5         // { 0x00, 0x23 };
    377         null, // TLS_KRB5_WITH_RC4_128_MD5              // { 0x00, 0x24 };
    378         null, // TLS_KRB5_WITH_IDEA_CBC_MD5             // { 0x00, 0x25 };
    379         null, // TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA    // { 0x00, 0x26 };
    380         null, // TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA    // { 0x00, 0x27 };
    381         null, // TLS_KRB5_EXPORT_WITH_RC4_40_SHA        // { 0x00, 0x28 };
    382         null, // TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5    // { 0x00, 0x29 };
    383         null, // TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5    // { 0x00, 0x2A };
    384         null, // TLS_KRB5_EXPORT_WITH_RC4_40_MD5        // { 0x00, 0x2B };
    385         null, // TLS_PSK_WITH_NULL_SHA                  // { 0x00, 0x2C };
    386         null, // TLS_DHE_PSK_WITH_NULL_SHA              // { 0x00, 0x2D };
    387         null, // TLS_RSA_PSK_WITH_NULL_SHA              // { 0x00, 0x2E };
    388         TLS_RSA_WITH_AES_128_CBC_SHA,                   // { 0x00, 0x2F };
    389         null, // TLS_DH_DSS_WITH_AES_128_CBC_SHA        // { 0x00, 0x30 };
    390         null, // TLS_DH_RSA_WITH_AES_128_CBC_SHA        // { 0x00, 0x31 };
    391         TLS_DHE_DSS_WITH_AES_128_CBC_SHA,               // { 0x00, 0x32 };
    392         TLS_DHE_RSA_WITH_AES_128_CBC_SHA,               // { 0x00, 0x33 };
    393         TLS_DH_anon_WITH_AES_128_CBC_SHA,               // { 0x00, 0x34 };
    394         TLS_RSA_WITH_AES_256_CBC_SHA,                   // { 0x00, 0x35 };
    395         null, // TLS_DH_DSS_WITH_AES_256_CBC_SHA,       // { 0x00, 0x36 };
    396         null, // TLS_DH_RSA_WITH_AES_256_CBC_SHA,       // { 0x00, 0x37 };
    397         TLS_DHE_DSS_WITH_AES_256_CBC_SHA,               // { 0x00, 0x38 };
    398         TLS_DHE_RSA_WITH_AES_256_CBC_SHA,               // { 0x00, 0x39 };
    399         TLS_DH_anon_WITH_AES_256_CBC_SHA,               // { 0x00, 0x3A };
    400         // END android-added
    401     };
    402 
    403     // hash for quick access to cipher suite by name
    404     private static final Hashtable<String, CipherSuite> SUITES_BY_NAME;
    405 
    406     /**
    407      * array of supported cipher suites.
    408      * Set of supported suites is defined at the moment provider's start
    409      */
    410     //  TODO Dynamically supported suites: new providers may be dynamically
    411     //  added/removed and the set of supported suites may be changed
    412     static final CipherSuite[] SUPPORTED_CIPHER_SUITES;
    413 
    414     /**
    415      * array of supported cipher suites names
    416      */
    417     static final String[] SUPPORTED_CIPHER_SUITE_NAMES;
    418 
    419     /**
    420      * default cipher suites
    421      */
    422     static final CipherSuite[] DEFAULT_CIPHER_SUITES;
    423 
    424     static {
    425         int count = 0;
    426         SUITES_BY_NAME = new Hashtable<String, CipherSuite>();
    427         for (int i = 0; i < SUITES_BY_CODE.length; i++) {
    428             if (SUITES_BY_CODE[i] == SSL_NULL_WITH_NULL_NULL) {
    429                 continue;
    430             }
    431             if (SUITES_BY_CODE[i] == null) {
    432                 continue;
    433             }
    434             SUITES_BY_NAME.put(SUITES_BY_CODE[i].getName(), SUITES_BY_CODE[i]);
    435             if (SUITES_BY_CODE[i].supported) {
    436                 count++;
    437             }
    438         }
    439         SUPPORTED_CIPHER_SUITES = new CipherSuite[count];
    440         SUPPORTED_CIPHER_SUITE_NAMES = new String[count];
    441         count = 0;
    442         for (int i = 0; i < SUITES_BY_CODE.length; i++) {
    443             if (SUITES_BY_CODE[i] == SSL_NULL_WITH_NULL_NULL) {
    444                 continue;
    445             }
    446             if (SUITES_BY_CODE[i] == null) {
    447                 continue;
    448             }
    449             if (SUITES_BY_CODE[i].supported) {
    450                 SUPPORTED_CIPHER_SUITES[count] = SUITES_BY_CODE[i];
    451                 SUPPORTED_CIPHER_SUITE_NAMES[count] = SUPPORTED_CIPHER_SUITES[count].getName();
    452                 count++;
    453             }
    454         }
    455 
    456         CipherSuite[] defaultCipherSuites = {
    457                 SSL_RSA_WITH_RC4_128_MD5,
    458                 SSL_RSA_WITH_RC4_128_SHA,
    459                 TLS_RSA_WITH_AES_128_CBC_SHA,
    460                 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
    461                 TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
    462                 SSL_RSA_WITH_3DES_EDE_CBC_SHA,
    463                 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
    464                 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
    465                 SSL_RSA_WITH_DES_CBC_SHA,
    466                 SSL_DHE_RSA_WITH_DES_CBC_SHA,
    467                 SSL_DHE_DSS_WITH_DES_CBC_SHA,
    468                 SSL_RSA_EXPORT_WITH_RC4_40_MD5,
    469                 SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
    470                 SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
    471                 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
    472                 };
    473         count = 0;
    474         for (int i = 0; i < defaultCipherSuites.length; i++) {
    475             if (defaultCipherSuites[i].supported) {
    476                 count++;
    477             }
    478         }
    479         DEFAULT_CIPHER_SUITES = new CipherSuite[count];
    480         count = 0;
    481         for (int i = 0; i < defaultCipherSuites.length; i++) {
    482             if (defaultCipherSuites[i].supported) {
    483                 DEFAULT_CIPHER_SUITES[count++] = defaultCipherSuites[i];
    484             }
    485         }
    486     }
    487 
    488     /**
    489      * Returns CipherSuite by name
    490      */
    491     public static CipherSuite getByName(String name) {
    492         return SUITES_BY_NAME.get(name);
    493     }
    494 
    495     /**
    496      * Returns CipherSuite based on TLS CipherSuite code
    497      * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., A.5. The CipherSuite</a>
    498      */
    499     public static CipherSuite getByCode(byte b1, byte b2) {
    500         if (b1 != 0 || (b2 & 0xFF) > SUITES_BY_CODE.length) {
    501             // Unknown
    502             return new CipherSuite("UNKNOWN_" + b1 + "_" + b2, false, 0, null,
    503                     null, null, new byte[] { b1, b2 });
    504         }
    505         return SUITES_BY_CODE[b2];
    506     }
    507 
    508     /**
    509      * Returns CipherSuite based on V2CipherSpec code
    510      * as described in TLS 1.0 spec., E. Backward Compatibility With SSL
    511      */
    512     public static CipherSuite getByCode(byte b1, byte b2, byte b3) {
    513         if (b1 == 0 && b2 == 0) {
    514             if ((b3 & 0xFF) <= SUITES_BY_CODE.length) {
    515                 return SUITES_BY_CODE[b3];
    516             }
    517         }
    518         // as TLSv1 equivalent of V2CipherSpec should be included in
    519         // V2ClientHello, ignore V2CipherSpec
    520         return new CipherSuite("UNKNOWN_" + b1 + "_" + b2 + "_" + b3, false, 0,
    521                 null, null, null, new byte[] { b1, b2, b3 });
    522     }
    523 
    524     /**
    525      * Creates CipherSuite
    526      */
    527     public CipherSuite(String name, boolean isExportable, int keyExchange,
    528             String authType, String cipherName, String hash, byte[] code) {
    529         this.name = name;
    530         this.keyExchange = keyExchange;
    531         this.authType = authType;
    532         this.isExportable = isExportable;
    533         if (cipherName == null) {
    534             this.cipherName = null;
    535             keyMaterial = 0;
    536             expandedKeyMaterial = 0;
    537             effectiveKeyBytes = 0;
    538             ivSize = 0;
    539             blockSize = 0;
    540         // BEGIN android-removed
    541         // } else if ("IDEA_CBC".equals(cipherName)) {
    542         //     this.cipherName = "IDEA/CBC/NoPadding";
    543         //     keyMaterial = 16;
    544         //     expandedKeyMaterial = 16;
    545         //     effectiveKeyBytes = 16;
    546         //     ivSize = 8;
    547         //     blockSize = 8;
    548         // } else if ("RC2_CBC_40".equals(cipherName)) {
    549         //     this.cipherName = "RC2/CBC/NoPadding";
    550         //     keyMaterial = 5;
    551         //     expandedKeyMaterial = 16;
    552         //     effectiveKeyBytes = 5;
    553         //     ivSize = 8;
    554         //     blockSize = 8;
    555         // END android-removed
    556         } else if ("RC4_40".equals(cipherName)) {
    557             this.cipherName = "RC4";
    558             keyMaterial = 5;
    559             expandedKeyMaterial = 16;
    560             effectiveKeyBytes = 5;
    561             ivSize = 0;
    562             blockSize = 0;
    563         } else if ("RC4_128".equals(cipherName)) {
    564             this.cipherName = "RC4";
    565             keyMaterial = 16;
    566             expandedKeyMaterial = 16;
    567             effectiveKeyBytes = 16;
    568             ivSize = 0;
    569             blockSize = 0;
    570         } else if ("DES40_CBC".equals(cipherName)) {
    571             this.cipherName = "DES/CBC/NoPadding";
    572             keyMaterial = 5;
    573             expandedKeyMaterial = 8;
    574             effectiveKeyBytes = 5;
    575             ivSize = 8;
    576             blockSize = 8;
    577         } else if ("DES_CBC".equals(cipherName)) {
    578             this.cipherName = "DES/CBC/NoPadding";
    579             keyMaterial = 8;
    580             expandedKeyMaterial = 8;
    581             effectiveKeyBytes = 7;
    582             ivSize = 8;
    583             blockSize = 8;
    584         } else if ("3DES_EDE_CBC".equals(cipherName)) {
    585             this.cipherName = "DESede/CBC/NoPadding";
    586             keyMaterial = 24;
    587             expandedKeyMaterial = 24;
    588             effectiveKeyBytes = 24;
    589             ivSize = 8;
    590             blockSize = 8;
    591         } else if ("AES_128".equals(cipherName)) {
    592             this.cipherName = "AES/CBC/NoPadding";
    593             keyMaterial = 16;
    594             expandedKeyMaterial = 16;
    595             effectiveKeyBytes = 16;
    596             ivSize = 16;
    597             blockSize = 16;
    598         } else if ("AES_256".equals(cipherName)) {
    599             this.cipherName = "AES/CBC/NoPadding";
    600             keyMaterial = 32;
    601             expandedKeyMaterial = 32;
    602             effectiveKeyBytes = 32;
    603             ivSize = 16;
    604             blockSize = 16;
    605         } else {
    606             this.cipherName = cipherName;
    607             keyMaterial = 0;
    608             expandedKeyMaterial = 0;
    609             effectiveKeyBytes = 0;
    610             ivSize = 0;
    611             blockSize = 0;
    612         }
    613 
    614         if ("MD5".equals(hash)) {
    615             this.hmacName = "HmacMD5";
    616             this.hashName = "MD5";
    617             hashSize = 16;
    618         } else if ("SHA".equals(hash)) {
    619             this.hmacName = "HmacSHA1";
    620             this.hashName = "SHA-1";
    621             hashSize = 20;
    622         } else {
    623             this.hmacName = null;
    624             this.hashName = null;
    625             hashSize = 0;
    626         }
    627 
    628         cipherSuiteCode = code;
    629 
    630         if (this.cipherName != null) {
    631             try {
    632                 Cipher.getInstance(this.cipherName);
    633             } catch (GeneralSecurityException e) {
    634                 supported = false;
    635             }
    636         }
    637 
    638     }
    639 
    640     /**
    641      * Returns true if cipher suite is anonymous
    642      * @return
    643      */
    644     public boolean isAnonymous() {
    645         if (keyExchange == KEY_EXCHANGE_DH_anon
    646                 || keyExchange == KEY_EXCHANGE_DH_anon_EXPORT) {
    647             return true;
    648         }
    649         return false;
    650     }
    651 
    652     /**
    653      * Returns array of supported CipherSuites
    654      * @return
    655      */
    656     public static CipherSuite[] getSupported() {
    657         return SUPPORTED_CIPHER_SUITES;
    658     }
    659 
    660     /**
    661      * Returns array of supported cipher suites names
    662      * @return
    663      */
    664     public static String[] getSupportedCipherSuiteNames() {
    665         return SUPPORTED_CIPHER_SUITE_NAMES.clone();
    666     }
    667 
    668     /**
    669      * Returns cipher suite name
    670      * @return
    671      */
    672     public String getName() {
    673         return name;
    674     }
    675 
    676     /**
    677      * Returns cipher suite code as byte array
    678      * @return
    679      */
    680     public byte[] toBytes() {
    681         return cipherSuiteCode;
    682     }
    683 
    684     /**
    685      * Returns cipher suite description
    686      */
    687     @Override
    688     public String toString() {
    689         return name + ": " + cipherSuiteCode[0] + " " + cipherSuiteCode[1];
    690     }
    691 
    692     /**
    693      * Compares this cipher suite to the specified object.
    694      */
    695     @Override
    696     public boolean equals(Object obj) {
    697         if (obj instanceof CipherSuite
    698                 && this.cipherSuiteCode[0] == ((CipherSuite) obj).cipherSuiteCode[0]
    699                 && this.cipherSuiteCode[1] == ((CipherSuite) obj).cipherSuiteCode[1]) {
    700             return true;
    701         }
    702         return false;
    703     }
    704 
    705     /**
    706      * Returns cipher algorithm name
    707      * @return
    708      */
    709     public String getBulkEncryptionAlgorithm() {
    710         return cipherName;
    711     }
    712 
    713     /**
    714      * Returns cipher block size
    715      * @return
    716      */
    717     public int getBlockSize() {
    718         return blockSize;
    719     }
    720 
    721     /**
    722      * Returns MAC algorithm name
    723      * @return
    724      */
    725     public String getHmacName() {
    726         return hmacName;
    727     }
    728 
    729     /**
    730      * Returns hash algorithm name
    731      * @return
    732      */
    733     public String getHashName() {
    734         return hashName;
    735     }
    736 
    737     /**
    738      * Returns hash size
    739      * @return
    740      */
    741     public int getMACLength() {
    742         return hashSize;
    743     }
    744 
    745     /**
    746      * Indicates whether this cipher suite is exportable
    747      * @return
    748      */
    749     public boolean isExportable() {
    750         return isExportable;
    751     }
    752 
    753 }
    754 
    755