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 
     23 import javax.crypto.Cipher;
     24 
     25 /**
     26  * Represents Cipher Suite as defined in TLS 1.0 spec.,
     27  * A.5. The CipherSuite;
     28  * C. CipherSuite definitions.
     29  * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec.</a>
     30  *
     31  */
     32 public class CipherSuite {
     33 
     34     /**
     35      * true if this cipher suite is supported
     36      */
     37     boolean supported = true;
     38 
     39     /**
     40      * cipher suite key exchange
     41      */
     42     final int keyExchange;
     43 
     44     /**
     45      * cipher
     46      */
     47     final String cipherName;
     48 
     49     /**
     50      * Cipher information
     51      */
     52     final int keyMaterial;
     53     final int expandedKeyMaterial;
     54     final int effectiveKeyBytes;
     55     final int IVSize;
     56     final private int blockSize;
     57 
     58     // cipher suite code
     59     private final byte[] cipherSuiteCode;
     60 
     61     // cipher suite name
     62     private final String name;
     63 
     64     // true if cipher suite is exportable
     65     private final boolean isExportable;
     66 
     67     // Hash algorithm
     68     final private String hashName;
     69 
     70     // MAC algorithm
     71     final private String hmacName;
     72 
     73     // Hash size
     74     final private int hashSize;
     75 
     76     /**
     77      * key exchange values
     78      */
     79     static int KeyExchange_RSA = 1;
     80     static int KeyExchange_RSA_EXPORT = 2;
     81     static int KeyExchange_DHE_DSS = 3;
     82     static int KeyExchange_DHE_DSS_EXPORT = 4;
     83     static int KeyExchange_DHE_RSA = 5;
     84     static int KeyExchange_DHE_RSA_EXPORT = 6;
     85     static int KeyExchange_DH_DSS = 7;
     86     static int KeyExchange_DH_RSA = 8;
     87     static int KeyExchange_DH_anon = 9;
     88     static int KeyExchange_DH_anon_EXPORT = 10;
     89     static int KeyExchange_DH_DSS_EXPORT = 11;
     90     static int KeyExchange_DH_RSA_EXPORT = 12;
     91 
     92     /**
     93      * TLS cipher suite codes
     94      */
     95     static byte[] code_TLS_NULL_WITH_NULL_NULL = { 0x00, 0x00 };
     96     static byte[] code_TLS_RSA_WITH_NULL_MD5 = { 0x00, 0x01 };
     97     static byte[] code_TLS_RSA_WITH_NULL_SHA = { 0x00, 0x02 };
     98     static byte[] code_TLS_RSA_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x03 };
     99     static byte[] code_TLS_RSA_WITH_RC4_128_MD5 = { 0x00, 0x04 };
    100     static byte[] code_TLS_RSA_WITH_RC4_128_SHA = { 0x00, 0x05 };
    101     static byte[] code_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00, 0x06 };
    102     static byte[] code_TLS_RSA_WITH_IDEA_CBC_SHA = { 0x00, 0x07 };
    103     static byte[] code_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x08 };
    104     static byte[] code_TLS_RSA_WITH_DES_CBC_SHA = { 0x00, 0x09 };
    105     static byte[] code_TLS_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x0A };
    106     static byte[] code_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0B };
    107     static byte[] code_TLS_DH_DSS_WITH_DES_CBC_SHA = { 0x00, 0x0C };
    108     static byte[] code_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x0D };
    109     static byte[] code_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0E };
    110     static byte[] code_TLS_DH_RSA_WITH_DES_CBC_SHA = { 0x00, 0x0F };
    111     static byte[] code_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x10 };
    112     static byte[] code_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x11 };
    113     static byte[] code_TLS_DHE_DSS_WITH_DES_CBC_SHA = { 0x00, 0x12 };
    114     static byte[] code_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x13 };
    115     static byte[] code_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x14 };
    116     static byte[] code_TLS_DHE_RSA_WITH_DES_CBC_SHA = { 0x00, 0x15 };
    117     static byte[] code_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x16 };
    118     static byte[] code_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x17 };
    119     static byte[] code_TLS_DH_anon_WITH_RC4_128_MD5 = { 0x00, 0x18 };
    120     static byte[] code_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x19 };
    121     static byte[] code_TLS_DH_anon_WITH_DES_CBC_SHA = { 0x00, 0x1A };
    122     static byte[] code_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x1B };
    123 
    124     static CipherSuite TLS_NULL_WITH_NULL_NULL = new CipherSuite(
    125             "TLS_NULL_WITH_NULL_NULL", true, 0, null, null,
    126             code_TLS_NULL_WITH_NULL_NULL);
    127 
    128     static CipherSuite TLS_RSA_WITH_NULL_MD5 = new CipherSuite(
    129             "TLS_RSA_WITH_NULL_MD5", true, KeyExchange_RSA, null, "MD5",
    130             code_TLS_RSA_WITH_NULL_MD5);
    131 
    132     static CipherSuite TLS_RSA_WITH_NULL_SHA = new CipherSuite(
    133             "TLS_RSA_WITH_NULL_SHA", true, KeyExchange_RSA, null, "SHA",
    134             code_TLS_RSA_WITH_NULL_SHA);
    135 
    136     static CipherSuite TLS_RSA_EXPORT_WITH_RC4_40_MD5 = new CipherSuite(
    137             "TLS_RSA_EXPORT_WITH_RC4_40_MD5", true, KeyExchange_RSA_EXPORT,
    138             "RC4_40", "MD5", code_TLS_RSA_EXPORT_WITH_RC4_40_MD5);
    139 
    140     static CipherSuite TLS_RSA_WITH_RC4_128_MD5 = new CipherSuite(
    141             "TLS_RSA_WITH_RC4_128_MD5", false, KeyExchange_RSA, "RC4_128",
    142             "MD5", code_TLS_RSA_WITH_RC4_128_MD5);
    143 
    144     static CipherSuite TLS_RSA_WITH_RC4_128_SHA = new CipherSuite(
    145             "TLS_RSA_WITH_RC4_128_SHA", false, KeyExchange_RSA, "RC4_128",
    146             "SHA", code_TLS_RSA_WITH_RC4_128_SHA);
    147 
    148     static CipherSuite TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = new CipherSuite(
    149             "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5", true, KeyExchange_RSA_EXPORT,
    150             "RC2_CBC_40", "MD5", code_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5);
    151 
    152     static CipherSuite TLS_RSA_WITH_IDEA_CBC_SHA = new CipherSuite(
    153             "TLS_RSA_WITH_IDEA_CBC_SHA", false, KeyExchange_RSA, "IDEA_CBC",
    154             "SHA", code_TLS_RSA_WITH_IDEA_CBC_SHA);
    155 
    156     static CipherSuite TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
    157             "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA", true, KeyExchange_RSA_EXPORT,
    158             "DES40_CBC", "SHA", code_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA);
    159 
    160     static CipherSuite TLS_RSA_WITH_DES_CBC_SHA = new CipherSuite(
    161             "TLS_RSA_WITH_DES_CBC_SHA", false, KeyExchange_RSA, "DES_CBC",
    162             "SHA", code_TLS_RSA_WITH_DES_CBC_SHA);
    163 
    164     static CipherSuite TLS_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
    165             "TLS_RSA_WITH_3DES_EDE_CBC_SHA", false, KeyExchange_RSA,
    166             "3DES_EDE_CBC", "SHA", code_TLS_RSA_WITH_3DES_EDE_CBC_SHA);
    167 
    168     static CipherSuite TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
    169             "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", true,
    170             KeyExchange_DH_DSS_EXPORT, "DES40_CBC", "SHA",
    171             code_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA);
    172 
    173     static CipherSuite TLS_DH_DSS_WITH_DES_CBC_SHA = new CipherSuite(
    174             "TLS_DH_DSS_WITH_DES_CBC_SHA", false, KeyExchange_DH_DSS,
    175             "DES_CBC", "SHA", code_TLS_DH_DSS_WITH_DES_CBC_SHA);
    176 
    177     static CipherSuite TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
    178             "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", false, KeyExchange_DH_DSS,
    179             "3DES_EDE_CBC", "SHA", code_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA);
    180 
    181     static CipherSuite TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
    182             "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", true,
    183             KeyExchange_DH_RSA_EXPORT, "DES40_CBC", "SHA",
    184             code_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA);
    185 
    186     static CipherSuite TLS_DH_RSA_WITH_DES_CBC_SHA = new CipherSuite(
    187             "TLS_DH_RSA_WITH_DES_CBC_SHA", false, KeyExchange_DH_RSA,
    188             "DES_CBC", "SHA", code_TLS_DH_RSA_WITH_DES_CBC_SHA);
    189 
    190     static CipherSuite TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
    191             "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", false, KeyExchange_DH_RSA,
    192             "3DES_EDE_CBC", "SHA", code_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA);
    193 
    194     static CipherSuite TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
    195             "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", true,
    196             KeyExchange_DHE_DSS_EXPORT, "DES40_CBC", "SHA",
    197             code_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA);
    198 
    199     static CipherSuite TLS_DHE_DSS_WITH_DES_CBC_SHA = new CipherSuite(
    200             "TLS_DHE_DSS_WITH_DES_CBC_SHA", false, KeyExchange_DHE_DSS,
    201             "DES_CBC", "SHA", code_TLS_DHE_DSS_WITH_DES_CBC_SHA);
    202 
    203     static CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
    204             "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", false, KeyExchange_DHE_DSS,
    205             "3DES_EDE_CBC", "SHA", code_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA);
    206 
    207     static CipherSuite TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
    208             "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", true,
    209             KeyExchange_DHE_RSA_EXPORT, "DES40_CBC", "SHA",
    210             code_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA);
    211 
    212     static CipherSuite TLS_DHE_RSA_WITH_DES_CBC_SHA = new CipherSuite(
    213             "TLS_DHE_RSA_WITH_DES_CBC_SHA", false, KeyExchange_DHE_RSA,
    214             "DES_CBC", "SHA", code_TLS_DHE_RSA_WITH_DES_CBC_SHA);
    215 
    216     static CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
    217             "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", false, KeyExchange_DHE_RSA,
    218             "3DES_EDE_CBC", "SHA", code_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA);
    219 
    220     static CipherSuite TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = new CipherSuite(
    221             "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5", true,
    222             KeyExchange_DH_anon_EXPORT, "RC4_40", "MD5",
    223             code_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5);
    224 
    225     static CipherSuite TLS_DH_anon_WITH_RC4_128_MD5 = new CipherSuite(
    226             "TLS_DH_anon_WITH_RC4_128_MD5", false, KeyExchange_DH_anon,
    227             "RC4_128", "MD5", code_TLS_DH_anon_WITH_RC4_128_MD5);
    228 
    229     static CipherSuite TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
    230             "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA", true,
    231             KeyExchange_DH_anon_EXPORT, "DES40_CBC", "SHA",
    232             code_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA);
    233 
    234     static CipherSuite TLS_DH_anon_WITH_DES_CBC_SHA = new CipherSuite(
    235             "TLS_DH_anon_WITH_DES_CBC_SHA", false, KeyExchange_DH_anon,
    236             "DES_CBC", "SHA", code_TLS_DH_anon_WITH_DES_CBC_SHA);
    237 
    238     static CipherSuite TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
    239             "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA", false, KeyExchange_DH_anon,
    240             "3DES_EDE_CBC", "SHA", code_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA);
    241 
    242     // array for quick access to cipher suite by code
    243     private static CipherSuite[] cuitesByCode = {
    244             TLS_NULL_WITH_NULL_NULL,
    245             TLS_RSA_WITH_NULL_MD5,
    246             TLS_RSA_WITH_NULL_SHA,
    247             TLS_RSA_EXPORT_WITH_RC4_40_MD5,
    248             TLS_RSA_WITH_RC4_128_MD5,
    249             TLS_RSA_WITH_RC4_128_SHA,
    250             TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
    251             TLS_RSA_WITH_IDEA_CBC_SHA,
    252             TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
    253             TLS_RSA_WITH_DES_CBC_SHA,
    254             TLS_RSA_WITH_3DES_EDE_CBC_SHA,
    255             TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
    256             TLS_DH_DSS_WITH_DES_CBC_SHA,
    257             TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
    258             TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
    259             TLS_DH_RSA_WITH_DES_CBC_SHA,
    260             TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
    261             TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
    262             TLS_DHE_DSS_WITH_DES_CBC_SHA,
    263             TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
    264             TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
    265             TLS_DHE_RSA_WITH_DES_CBC_SHA,
    266             TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
    267             TLS_DH_anon_EXPORT_WITH_RC4_40_MD5,
    268             TLS_DH_anon_WITH_RC4_128_MD5,
    269             TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
    270             TLS_DH_anon_WITH_DES_CBC_SHA,
    271             TLS_DH_anon_WITH_3DES_EDE_CBC_SHA
    272             };
    273 
    274     // hash for quick access to cipher suite by name
    275     private static Hashtable<String, CipherSuite> cuitesByName;
    276 
    277     /**
    278      * array of supported cipher suites.
    279      * Set of supported suites is defined at the moment provider's start
    280      */
    281 //  TODO Dynamically supported suites: new providers may be dynamically
    282 //  added/removed and the set of supported suites may be changed
    283     static CipherSuite[] supportedCipherSuites;
    284 
    285     /**
    286      * array of supported cipher suites names
    287      */
    288     static String[] supportedCipherSuiteNames;
    289 
    290     /**
    291      * default cipher suites
    292      */
    293     static CipherSuite[] defaultCipherSuites;
    294 
    295     static {
    296         int count = 0;
    297         cuitesByName = new Hashtable<String, CipherSuite>();
    298         for (int i = 0; i < cuitesByCode.length; i++) {
    299             cuitesByName.put(cuitesByCode[i].getName(), cuitesByCode[i]);
    300             if (cuitesByCode[i].supported) {
    301                 count++;
    302             }
    303         }
    304         supportedCipherSuites = new CipherSuite[count];
    305         supportedCipherSuiteNames = new String[count];
    306         count = 0;
    307         for (int i = 0; i < cuitesByCode.length; i++) {
    308             if (cuitesByCode[i].supported) {
    309                 supportedCipherSuites[count] = cuitesByCode[i];
    310                 supportedCipherSuiteNames[count] = supportedCipherSuites[count].getName();
    311                 count++;
    312             }
    313         }
    314 
    315         CipherSuite[] defaultPretendent = {
    316                 TLS_RSA_WITH_RC4_128_MD5,
    317                 TLS_RSA_WITH_RC4_128_SHA,
    318                 // TLS_RSA_WITH_AES_128_CBC_SHA,
    319                 // TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
    320                 // LS_DHE_DSS_WITH_AES_128_CBC_SHA,
    321                 TLS_RSA_WITH_3DES_EDE_CBC_SHA,
    322                 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
    323                 TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_DES_CBC_SHA,
    324                 TLS_DHE_RSA_WITH_DES_CBC_SHA, TLS_DHE_DSS_WITH_DES_CBC_SHA,
    325                 TLS_RSA_EXPORT_WITH_RC4_40_MD5,
    326                 TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
    327                 TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
    328                 TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
    329                 };
    330         count = 0;
    331         for (int i = 0; i < defaultPretendent.length; i++) {
    332             if (defaultPretendent[i].supported) {
    333                 count++;
    334             }
    335         }
    336         defaultCipherSuites = new CipherSuite[count];
    337         count = 0;
    338         for (int i = 0; i < defaultPretendent.length; i++) {
    339             if (defaultPretendent[i].supported) {
    340                 defaultCipherSuites[count++] = defaultPretendent[i];
    341             }
    342         }
    343     }
    344 
    345     /**
    346      * Returns CipherSuite by name
    347      * @param name
    348      * @return
    349      */
    350     public static CipherSuite getByName(String name) {
    351         return cuitesByName.get(name);
    352     }
    353 
    354     /**
    355      * Returns CipherSuite based on TLS CipherSuite code
    356      * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., A.5. The CipherSuite</a>
    357      * @param b1
    358      * @param b2
    359      * @return
    360      */
    361     public static CipherSuite getByCode(byte b1, byte b2) {
    362         if (b1 != 0 || (b2 & 0xFF) > cuitesByCode.length) {
    363             // Unknown
    364             return new CipherSuite("UNKNOUN_" + b1 + "_" + b2, false, 0, "",
    365                     "", new byte[] { b1, b2 });
    366         }
    367         return cuitesByCode[b2];
    368     }
    369 
    370     /**
    371      * Returns CipherSuite based on V2CipherSpec code
    372      * as described in TLS 1.0 spec., E. Backward Compatibility With SSL
    373      *
    374      * @param b1
    375      * @param b2
    376      * @param b3
    377      * @return CipherSuite
    378      */
    379     public static CipherSuite getByCode(byte b1, byte b2, byte b3) {
    380         if (b1 == 0 && b2 == 0) {
    381             if ((b3 & 0xFF) <= cuitesByCode.length) {
    382                 return cuitesByCode[b3];
    383             }
    384         }
    385         // as TLSv1 equivalent of V2CipherSpec should be included in
    386         // V2ClientHello, ignore V2CipherSpec
    387         return new CipherSuite("UNKNOUN_" + b1 + "_" + b2 + "_" + b3, false, 0,
    388                 "", "", new byte[] { b1, b2, b3 });
    389     }
    390 
    391     /**
    392      * Creates CipherSuite
    393      * @param name
    394      * @param isExportable
    395      * @param keyExchange
    396      * @param cipherName
    397      * @param hash
    398      * @param code
    399      */
    400     public CipherSuite(String name, boolean isExportable, int keyExchange,
    401             String cipherName, String hash, byte[] code) {
    402         this.name = name;
    403         this.keyExchange = keyExchange;
    404         this.isExportable = isExportable;
    405         if (cipherName == null) {
    406             this.cipherName = null;
    407             keyMaterial = 0;
    408             expandedKeyMaterial = 0;
    409             effectiveKeyBytes = 0;
    410             IVSize = 0;
    411             blockSize = 0;
    412         } else if ("IDEA_CBC".equals(cipherName)) {
    413             this.cipherName = "IDEA/CBC/NoPadding";
    414             keyMaterial = 16;
    415             expandedKeyMaterial = 16;
    416             effectiveKeyBytes = 16;
    417             IVSize = 8;
    418             blockSize = 8;
    419         } else if ("RC2_CBC_40".equals(cipherName)) {
    420             this.cipherName = "RC2/CBC/NoPadding";
    421             keyMaterial = 5;
    422             expandedKeyMaterial = 16;
    423             effectiveKeyBytes = 5;
    424             IVSize = 8;
    425             blockSize = 8;
    426         } else if ("RC4_40".equals(cipherName)) {
    427             this.cipherName = "RC4";
    428             keyMaterial = 5;
    429             expandedKeyMaterial = 16;
    430             effectiveKeyBytes = 5;
    431             IVSize = 0;
    432             blockSize = 0;
    433         } else if ("RC4_128".equals(cipherName)) {
    434             this.cipherName = "RC4";
    435             keyMaterial = 16;
    436             expandedKeyMaterial = 16;
    437             effectiveKeyBytes = 16;
    438             IVSize = 0;
    439             blockSize = 0;
    440         } else if ("DES40_CBC".equals(cipherName)) {
    441             this.cipherName = "DES/CBC/NoPadding";
    442             keyMaterial = 5;
    443             expandedKeyMaterial = 8;
    444             effectiveKeyBytes = 5;
    445             IVSize = 8;
    446             blockSize = 8;
    447         } else if ("DES_CBC".equals(cipherName)) {
    448             this.cipherName = "DES/CBC/NoPadding";
    449             keyMaterial = 8;
    450             expandedKeyMaterial = 8;
    451             effectiveKeyBytes = 7;
    452             IVSize = 8;
    453             blockSize = 8;
    454         } else if ("3DES_EDE_CBC".equals(cipherName)) {
    455             this.cipherName = "DESede/CBC/NoPadding";
    456             keyMaterial = 24;
    457             expandedKeyMaterial = 24;
    458             effectiveKeyBytes = 24;
    459             IVSize = 8;
    460             blockSize = 8;
    461         } else {
    462             this.cipherName = cipherName;
    463             keyMaterial = 0;
    464             expandedKeyMaterial = 0;
    465             effectiveKeyBytes = 0;
    466             IVSize = 0;
    467             blockSize = 0;
    468         }
    469 
    470         if ("MD5".equals(hash)) {
    471             this.hmacName = "HmacMD5";
    472             this.hashName = "MD5";
    473             hashSize = 16;
    474         } else if ("SHA".equals(hash)) {
    475             this.hmacName = "HmacSHA1";
    476             this.hashName = "SHA-1";
    477             hashSize = 20;
    478         } else {
    479             this.hmacName = null;
    480             this.hashName = null;
    481             hashSize = 0;
    482         }
    483 
    484         cipherSuiteCode = code;
    485 
    486         if (this.cipherName != null) {
    487             try {
    488                 Cipher.getInstance(this.cipherName);
    489             } catch (GeneralSecurityException e) {
    490                 supported = false;
    491             }
    492         }
    493 
    494     }
    495 
    496     /**
    497      * Returns true if cipher suite is anonymous
    498      * @return
    499      */
    500     public boolean isAnonymous() {
    501         if (keyExchange == KeyExchange_DH_anon
    502                 || keyExchange == KeyExchange_DH_anon_EXPORT) {
    503             return true;
    504         }
    505         return false;
    506     }
    507 
    508     /**
    509      * Returns array of supported CipherSuites
    510      * @return
    511      */
    512     public static CipherSuite[] getSupported() {
    513         return supportedCipherSuites;
    514     }
    515 
    516     /**
    517      * Returns array of supported cipher suites names
    518      * @return
    519      */
    520     public static String[] getSupportedCipherSuiteNames() {
    521         return supportedCipherSuiteNames.clone();
    522     }
    523 
    524     /**
    525      * Returns cipher suite name
    526      * @return
    527      */
    528     public String getName() {
    529         return name;
    530     }
    531 
    532     /**
    533      * Returns cipher suite code as byte array
    534      * @return
    535      */
    536     public byte[] toBytes() {
    537         return cipherSuiteCode;
    538     }
    539 
    540     /**
    541      * Returns cipher suite description
    542      */
    543     @Override
    544     public String toString() {
    545         return name + ": " + cipherSuiteCode[0] + " " + cipherSuiteCode[1];
    546     }
    547 
    548     /**
    549      * Compares this cipher suite to the specified object.
    550      */
    551     @Override
    552     public boolean equals(Object obj) {
    553         if (obj instanceof CipherSuite
    554                 && this.cipherSuiteCode[0] == ((CipherSuite) obj).cipherSuiteCode[0]
    555                 && this.cipherSuiteCode[1] == ((CipherSuite) obj).cipherSuiteCode[1]) {
    556             return true;
    557         }
    558         return false;
    559     }
    560 
    561     /**
    562      * Returns cipher algorithm name
    563      * @return
    564      */
    565     public String getBulkEncryptionAlgorithm() {
    566         return cipherName;
    567     }
    568 
    569     /**
    570      * Returns cipher block size
    571      * @return
    572      */
    573     public int getBlockSize() {
    574         return blockSize;
    575     }
    576 
    577     /**
    578      * Returns MAC algorithm name
    579      * @return
    580      */
    581     public String getHmacName() {
    582         return hmacName;
    583     }
    584 
    585     /**
    586      * Returns hash algorithm name
    587      * @return
    588      */
    589     public String getHashName() {
    590         return hashName;
    591     }
    592 
    593     /**
    594      * Returns hash size
    595      * @return
    596      */
    597     public int getMACLength() {
    598         return hashSize;
    599     }
    600 
    601     /**
    602      * Indicates whether this cipher suite is exportable
    603      * @return
    604      */
    605     public boolean isExportable() {
    606         return isExportable;
    607     }
    608 
    609 }
    610 
    611