blob: f712d112da83c66f275fcceaf4f5a3fb59ee9b6b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.harmony.xnet.provider.jsse;
import java.security.GeneralSecurityException;
import java.util.Hashtable;
import javax.crypto.Cipher;
/**
* Represents Cipher Suite as defined in TLS 1.0 spec.,
* A.5. The CipherSuite;
* C. CipherSuite definitions.
* @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec.</a>
*
*/
public class CipherSuite {
/**
* true if this cipher suite is supported
*/
boolean supported = true;
/**
* cipher suite key exchange
*/
final int keyExchange;
/**
* algorithm used for authentication ("RSA", "DSA", "DH", null for anonymous)
*/
final String authType;
/**
* cipher
*/
final String cipherName;
/**
* Cipher information
*/
final int keyMaterial;
final int expandedKeyMaterial;
final int effectiveKeyBytes;
final int ivSize;
final private int blockSize;
// cipher suite code
private final byte[] cipherSuiteCode;
// cipher suite name
private final String name;
// true if cipher suite is exportable
private final boolean isExportable;
// Hash algorithm
final private String hashName;
// MAC algorithm
final private String hmacName;
// Hash size
final private int hashSize;
/**
* key exchange values
*/
static final int KEY_EXCHANGE_RSA = 1;
static final int KEY_EXCHANGE_RSA_EXPORT = 2;
static final int KEY_EXCHANGE_DHE_DSS = 3;
static final int KEY_EXCHANGE_DHE_DSS_EXPORT = 4;
static final int KEY_EXCHANGE_DHE_RSA = 5;
static final int KEY_EXCHANGE_DHE_RSA_EXPORT = 6;
static final int KEY_EXCHANGE_DH_DSS = 7;
static final int KEY_EXCHANGE_DH_RSA = 8;
static final int KEY_EXCHANGE_DH_anon = 9;
static final int KEY_EXCHANGE_DH_anon_EXPORT = 10;
static final int KEY_EXCHANGE_DH_DSS_EXPORT = 11;
static final int KEY_EXCHANGE_DH_RSA_EXPORT = 12;
/**
* TLS cipher suite codes
*/
static final byte[] CODE_SSL_NULL_WITH_NULL_NULL = { 0x00, 0x00 };
static final byte[] CODE_SSL_RSA_WITH_NULL_MD5 = { 0x00, 0x01 };
static final byte[] CODE_SSL_RSA_WITH_NULL_SHA = { 0x00, 0x02 };
static final byte[] CODE_SSL_RSA_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x03 };
static final byte[] CODE_SSL_RSA_WITH_RC4_128_MD5 = { 0x00, 0x04 };
static final byte[] CODE_SSL_RSA_WITH_RC4_128_SHA = { 0x00, 0x05 };
static final byte[] CODE_SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00, 0x06 };
// BEGIN android-removed
// static final byte[] CODE_TLS_RSA_WITH_IDEA_CBC_SHA = { 0x00, 0x07 };
// END android-removed
static final byte[] CODE_SSL_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x08 };
static final byte[] CODE_SSL_RSA_WITH_DES_CBC_SHA = { 0x00, 0x09 };
static final byte[] CODE_SSL_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x0A };
// BEGIN android-removed
// static final byte[] CODE_SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0B };
// static final byte[] CODE_SSL_DH_DSS_WITH_DES_CBC_SHA = { 0x00, 0x0C };
// static final byte[] CODE_SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x0D };
// static final byte[] CODE_SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0E };
// static final byte[] CODE_SSL_DH_RSA_WITH_DES_CBC_SHA = { 0x00, 0x0F };
// static final byte[] CODE_SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x10 };
// END android-removed
static final byte[] CODE_SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x11 };
static final byte[] CODE_SSL_DHE_DSS_WITH_DES_CBC_SHA = { 0x00, 0x12 };
static final byte[] CODE_SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x13 };
static final byte[] CODE_SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x14 };
static final byte[] CODE_SSL_DHE_RSA_WITH_DES_CBC_SHA = { 0x00, 0x15 };
static final byte[] CODE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x16 };
static final byte[] CODE_SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x17 };
static final byte[] CODE_SSL_DH_anon_WITH_RC4_128_MD5 = { 0x00, 0x18 };
static final byte[] CODE_SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x19 };
static final byte[] CODE_SSL_DH_anon_WITH_DES_CBC_SHA = { 0x00, 0x1A };
static final byte[] CODE_SSL_DH_anon_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x1B };
// AES Cipher Suites from RFC 3268 - http://www.ietf.org/rfc/rfc3268.txt
static final byte[] CODE_TLS_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x2F };
//static final byte[] CODE_TLS_DH_DSS_WITH_AES_128_CBC_SHA = { 0x00, 0x30 };
//static final byte[] CODE_TLS_DH_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x31 };
static final byte[] CODE_TLS_DHE_DSS_WITH_AES_128_CBC_SHA = { 0x00, 0x32 };
static final byte[] CODE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x33 };
static final byte[] CODE_TLS_DH_anon_WITH_AES_128_CBC_SHA = { 0x00, 0x34 };
static final byte[] CODE_TLS_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x35 };
//static final byte[] CODE_TLS_DH_DSS_WITH_AES_256_CBC_SHA = { 0x00, 0x36 };
//static final byte[] CODE_TLS_DH_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x37 };
static final byte[] CODE_TLS_DHE_DSS_WITH_AES_256_CBC_SHA = { 0x00, 0x38 };
static final byte[] CODE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x39 };
static final byte[] CODE_TLS_DH_anon_WITH_AES_256_CBC_SHA = { 0x00, 0x3A };
static final CipherSuite SSL_NULL_WITH_NULL_NULL = new CipherSuite(
"SSL_NULL_WITH_NULL_NULL", true, 0, null, null, null,
CODE_SSL_NULL_WITH_NULL_NULL);
static final CipherSuite SSL_RSA_WITH_NULL_MD5 = new CipherSuite(
"SSL_RSA_WITH_NULL_MD5", true, KEY_EXCHANGE_RSA, "RSA", null, "MD5",
CODE_SSL_RSA_WITH_NULL_MD5);
static final CipherSuite SSL_RSA_WITH_NULL_SHA = new CipherSuite(
"SSL_RSA_WITH_NULL_SHA", true, KEY_EXCHANGE_RSA, "RSA", null, "SHA",
CODE_SSL_RSA_WITH_NULL_SHA);
static final CipherSuite SSL_RSA_EXPORT_WITH_RC4_40_MD5 = new CipherSuite(
"SSL_RSA_EXPORT_WITH_RC4_40_MD5", true, KEY_EXCHANGE_RSA_EXPORT,
"RSA", "RC4_40", "MD5", CODE_SSL_RSA_EXPORT_WITH_RC4_40_MD5);
static final CipherSuite SSL_RSA_WITH_RC4_128_MD5 = new CipherSuite(
"SSL_RSA_WITH_RC4_128_MD5", false, KEY_EXCHANGE_RSA, "RSA", "RC4_128",
"MD5", CODE_SSL_RSA_WITH_RC4_128_MD5);
static final CipherSuite SSL_RSA_WITH_RC4_128_SHA = new CipherSuite(
"SSL_RSA_WITH_RC4_128_SHA", false, KEY_EXCHANGE_RSA, "RSA", "RC4_128",
"SHA", CODE_SSL_RSA_WITH_RC4_128_SHA);
static final CipherSuite SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = new CipherSuite(
"SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", true, KEY_EXCHANGE_RSA_EXPORT,
"RSA", "RC2_CBC_40", "MD5", CODE_SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5);
// BEGIN android-removed
// static final CipherSuite TLS_RSA_WITH_IDEA_CBC_SHA = new CipherSuite(
// "TLS_RSA_WITH_IDEA_CBC_SHA", false, KEY_EXCHANGE_RSA, "RSA", "IDEA_CBC",
// "SHA", CODE_TLS_RSA_WITH_IDEA_CBC_SHA);
// END android-removed
static final CipherSuite SSL_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", true, KEY_EXCHANGE_RSA_EXPORT,
"RSA", "DES40_CBC", "SHA", CODE_SSL_RSA_EXPORT_WITH_DES40_CBC_SHA);
static final CipherSuite SSL_RSA_WITH_DES_CBC_SHA = new CipherSuite(
"SSL_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_RSA, "RSA", "DES_CBC",
"SHA", CODE_SSL_RSA_WITH_DES_CBC_SHA);
static final CipherSuite SSL_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
"SSL_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_RSA,
"RSA", "3DES_EDE_CBC", "SHA", CODE_SSL_RSA_WITH_3DES_EDE_CBC_SHA);
// BEGIN android-removed
// static final CipherSuite SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
// "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", true,
// KEY_EXCHANGE_DH_DSS_EXPORT, "DH", "DES40_CBC", "SHA",
// CODE_SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA);
//
// static final CipherSuite SSL_DH_DSS_WITH_DES_CBC_SHA = new CipherSuite(
// "SSL_DH_DSS_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_DSS,
// "DH", "DES_CBC", "SHA", CODE_SSL_DH_DSS_WITH_DES_CBC_SHA);
//
// static final CipherSuite SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
// "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_DSS,
// "DH", "3DES_EDE_CBC", "SHA", CODE_SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA);
//
// static final CipherSuite SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
// "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", true,
// KEY_EXCHANGE_DH_RSA_EXPORT, "DH", "DES40_CBC", "SHA",
// CODE_SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA);
//
// static final CipherSuite SSL_DH_RSA_WITH_DES_CBC_SHA = new CipherSuite(
// "SSL_DH_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_RSA,
// "DH", "DES_CBC", "SHA", CODE_SSL_DH_RSA_WITH_DES_CBC_SHA);
//
// static final CipherSuite SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
// "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_RSA,
// "DH", "3DES_EDE_CBC", "SHA", CODE_SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA);
// END android-removed
static final CipherSuite SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
"SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", true,
KEY_EXCHANGE_DHE_DSS_EXPORT, "DSA", "DES40_CBC", "SHA",
CODE_SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA);
static final CipherSuite SSL_DHE_DSS_WITH_DES_CBC_SHA = new CipherSuite(
"SSL_DHE_DSS_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DHE_DSS,
"DSA", "DES_CBC", "SHA", CODE_SSL_DHE_DSS_WITH_DES_CBC_SHA);
static final CipherSuite SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
"SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DHE_DSS,
"DSA", "3DES_EDE_CBC", "SHA", CODE_SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA);
static final CipherSuite SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", true,
KEY_EXCHANGE_DHE_RSA_EXPORT, "RSA", "DES40_CBC", "SHA",
CODE_SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA);
static final CipherSuite SSL_DHE_RSA_WITH_DES_CBC_SHA = new CipherSuite(
"SSL_DHE_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DHE_RSA,
"RSA", "DES_CBC", "SHA", CODE_SSL_DHE_RSA_WITH_DES_CBC_SHA);
static final CipherSuite SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
"SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DHE_RSA,
"RSA", "3DES_EDE_CBC", "SHA", CODE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA);
static final CipherSuite SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 = new CipherSuite(
"SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", true,
KEY_EXCHANGE_DH_anon_EXPORT, "DH", "RC4_40", "MD5",
CODE_SSL_DH_anon_EXPORT_WITH_RC4_40_MD5);
static final CipherSuite SSL_DH_anon_WITH_RC4_128_MD5 = new CipherSuite(
"SSL_DH_anon_WITH_RC4_128_MD5", false, KEY_EXCHANGE_DH_anon,
"DH", "RC4_128", "MD5", CODE_SSL_DH_anon_WITH_RC4_128_MD5);
static final CipherSuite SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", true,
KEY_EXCHANGE_DH_anon_EXPORT, "DH", "DES40_CBC", "SHA",
CODE_SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA);
static final CipherSuite SSL_DH_anon_WITH_DES_CBC_SHA = new CipherSuite(
"SSL_DH_anon_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_anon,
"DH", "DES_CBC", "SHA", CODE_SSL_DH_anon_WITH_DES_CBC_SHA);
static final CipherSuite SSL_DH_anon_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
"SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_anon,
"DH", "3DES_EDE_CBC", "SHA", CODE_SSL_DH_anon_WITH_3DES_EDE_CBC_SHA);
static final CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA
= new CipherSuite("TLS_RSA_WITH_AES_128_CBC_SHA",
false,
KEY_EXCHANGE_RSA,
"RSA",
"AES_128",
"SHA",
CODE_TLS_RSA_WITH_AES_128_CBC_SHA);
static final CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_SHA
= new CipherSuite("TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
false,
KEY_EXCHANGE_DHE_DSS,
"DSA",
"AES_128",
"SHA",
CODE_TLS_DHE_DSS_WITH_AES_128_CBC_SHA);
static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA
= new CipherSuite("TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
false,
KEY_EXCHANGE_DHE_RSA,
"RSA",
"AES_128",
"SHA",
CODE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
static final CipherSuite TLS_DH_anon_WITH_AES_128_CBC_SHA
= new CipherSuite("TLS_DH_anon_WITH_AES_128_CBC_SHA",
false,
KEY_EXCHANGE_DH_anon,
"DH",
"AES_128",
"SHA",
CODE_TLS_DH_anon_WITH_AES_128_CBC_SHA);
static final CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA
= new CipherSuite("TLS_RSA_WITH_AES_256_CBC_SHA",
false,
KEY_EXCHANGE_RSA,
"RSA",
"AES_256",
"SHA",
CODE_TLS_RSA_WITH_AES_256_CBC_SHA);
static final CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_SHA
= new CipherSuite("TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
false,
KEY_EXCHANGE_DHE_DSS,
"DSA",
"AES_256",
"SHA",
CODE_TLS_DHE_DSS_WITH_AES_256_CBC_SHA);
static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_SHA
= new CipherSuite("TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
false,
KEY_EXCHANGE_DHE_RSA,
"RSA",
"AES_256",
"SHA",
CODE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA);
static final CipherSuite TLS_DH_anon_WITH_AES_256_CBC_SHA
= new CipherSuite("TLS_DH_anon_WITH_AES_256_CBC_SHA",
false,
KEY_EXCHANGE_DH_anon,
"DH",
"AES_256",
"SHA",
CODE_TLS_DH_anon_WITH_AES_256_CBC_SHA);
// array for quick access to cipher suite by code
private static final CipherSuite[] SUITES_BY_CODE = {
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
SSL_NULL_WITH_NULL_NULL, // { 0x00, 0x00 };
SSL_RSA_WITH_NULL_MD5, // { 0x00, 0x01 };
SSL_RSA_WITH_NULL_SHA, // { 0x00, 0x02 };
SSL_RSA_EXPORT_WITH_RC4_40_MD5, // { 0x00, 0x03 };
SSL_RSA_WITH_RC4_128_MD5, // { 0x00, 0x04 };
SSL_RSA_WITH_RC4_128_SHA, // { 0x00, 0x05 };
// BEGIN android-changed
null, // SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, // { 0x00, 0x06 };
null, // TLS_RSA_WITH_IDEA_CBC_SHA, // { 0x00, 0x07 };
// END android-changed
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x08 };
SSL_RSA_WITH_DES_CBC_SHA, // { 0x00, 0x09 };
SSL_RSA_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x0a };
// BEGIN android-changed
null, // SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA // { 0x00, 0x0b };
null, // SSL_DH_DSS_WITH_DES_CBC_SHA, // { 0x00, 0x0c };
null, // SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x0d };
null, // SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x0e };
null, // SSL_DH_RSA_WITH_DES_CBC_SHA, // { 0x00, 0x0f };
null, // SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x10 };
// END android-changed
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x11 };
SSL_DHE_DSS_WITH_DES_CBC_SHA, // { 0x00, 0x12 };
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x13 };
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x14 };
SSL_DHE_RSA_WITH_DES_CBC_SHA, // { 0x00, 0x15 };
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x16 };
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, // { 0x00, 0x17 };
SSL_DH_anon_WITH_RC4_128_MD5, // { 0x00, 0x18 };
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x19 };
SSL_DH_anon_WITH_DES_CBC_SHA, // { 0x00, 0x1A };
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x1B };
// BEGIN android-added
null, // SSL_FORTEZZA_KEA_WITH_NULL_SHA // { 0x00, 0x1C };
null, // SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA // { 0x00, 0x1D };
null, // TLS_KRB5_WITH_DES_CBC_SHA // { 0x00, 0x1E };
null, // TLS_KRB5_WITH_3DES_EDE_CBC_SHA // { 0x00, 0x1F };
null, // TLS_KRB5_WITH_RC4_128_SHA // { 0x00, 0x20 };
null, // TLS_KRB5_WITH_IDEA_CBC_SHA // { 0x00, 0x21 };
null, // TLS_KRB5_WITH_DES_CBC_MD5 // { 0x00, 0x22 };
null, // TLS_KRB5_WITH_3DES_EDE_CBC_MD5 // { 0x00, 0x23 };
null, // TLS_KRB5_WITH_RC4_128_MD5 // { 0x00, 0x24 };
null, // TLS_KRB5_WITH_IDEA_CBC_MD5 // { 0x00, 0x25 };
null, // TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA // { 0x00, 0x26 };
null, // TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA // { 0x00, 0x27 };
null, // TLS_KRB5_EXPORT_WITH_RC4_40_SHA // { 0x00, 0x28 };
null, // TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 // { 0x00, 0x29 };
null, // TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 // { 0x00, 0x2A };
null, // TLS_KRB5_EXPORT_WITH_RC4_40_MD5 // { 0x00, 0x2B };
null, // TLS_PSK_WITH_NULL_SHA // { 0x00, 0x2C };
null, // TLS_DHE_PSK_WITH_NULL_SHA // { 0x00, 0x2D };
null, // TLS_RSA_PSK_WITH_NULL_SHA // { 0x00, 0x2E };
TLS_RSA_WITH_AES_128_CBC_SHA, // { 0x00, 0x2F };
null, // TLS_DH_DSS_WITH_AES_128_CBC_SHA // { 0x00, 0x30 };
null, // TLS_DH_RSA_WITH_AES_128_CBC_SHA // { 0x00, 0x31 };
TLS_DHE_DSS_WITH_AES_128_CBC_SHA, // { 0x00, 0x32 };
TLS_DHE_RSA_WITH_AES_128_CBC_SHA, // { 0x00, 0x33 };
TLS_DH_anon_WITH_AES_128_CBC_SHA, // { 0x00, 0x34 };
TLS_RSA_WITH_AES_256_CBC_SHA, // { 0x00, 0x35 };
null, // TLS_DH_DSS_WITH_AES_256_CBC_SHA, // { 0x00, 0x36 };
null, // TLS_DH_RSA_WITH_AES_256_CBC_SHA, // { 0x00, 0x37 };
TLS_DHE_DSS_WITH_AES_256_CBC_SHA, // { 0x00, 0x38 };
TLS_DHE_RSA_WITH_AES_256_CBC_SHA, // { 0x00, 0x39 };
TLS_DH_anon_WITH_AES_256_CBC_SHA, // { 0x00, 0x3A };
// END android-added
};
// hash for quick access to cipher suite by name
private static final Hashtable<String, CipherSuite> SUITES_BY_NAME;
/**
* array of supported cipher suites.
* Set of supported suites is defined at the moment provider's start
*/
// TODO Dynamically supported suites: new providers may be dynamically
// added/removed and the set of supported suites may be changed
static final CipherSuite[] SUPPORTED_CIPHER_SUITES;
/**
* array of supported cipher suites names
*/
static final String[] SUPPORTED_CIPHER_SUITE_NAMES;
/**
* default cipher suites
*/
static final CipherSuite[] DEFAULT_CIPHER_SUITES;
static {
int count = 0;
SUITES_BY_NAME = new Hashtable<String, CipherSuite>();
for (int i = 0; i < SUITES_BY_CODE.length; i++) {
if (SUITES_BY_CODE[i] == SSL_NULL_WITH_NULL_NULL) {
continue;
}
if (SUITES_BY_CODE[i] == null) {
continue;
}
SUITES_BY_NAME.put(SUITES_BY_CODE[i].getName(), SUITES_BY_CODE[i]);
if (SUITES_BY_CODE[i].supported) {
count++;
}
}
SUPPORTED_CIPHER_SUITES = new CipherSuite[count];
SUPPORTED_CIPHER_SUITE_NAMES = new String[count];
count = 0;
for (int i = 0; i < SUITES_BY_CODE.length; i++) {
if (SUITES_BY_CODE[i] == SSL_NULL_WITH_NULL_NULL) {
continue;
}
if (SUITES_BY_CODE[i] == null) {
continue;
}
if (SUITES_BY_CODE[i].supported) {
SUPPORTED_CIPHER_SUITES[count] = SUITES_BY_CODE[i];
SUPPORTED_CIPHER_SUITE_NAMES[count] = SUPPORTED_CIPHER_SUITES[count].getName();
count++;
}
}
CipherSuite[] defaultCipherSuites = {
SSL_RSA_WITH_RC4_128_MD5,
SSL_RSA_WITH_RC4_128_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
SSL_RSA_WITH_3DES_EDE_CBC_SHA,
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
SSL_RSA_WITH_DES_CBC_SHA,
SSL_DHE_RSA_WITH_DES_CBC_SHA,
SSL_DHE_DSS_WITH_DES_CBC_SHA,
SSL_RSA_EXPORT_WITH_RC4_40_MD5,
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
};
count = 0;
for (int i = 0; i < defaultCipherSuites.length; i++) {
if (defaultCipherSuites[i].supported) {
count++;
}
}
DEFAULT_CIPHER_SUITES = new CipherSuite[count];
count = 0;
for (int i = 0; i < defaultCipherSuites.length; i++) {
if (defaultCipherSuites[i].supported) {
DEFAULT_CIPHER_SUITES[count++] = defaultCipherSuites[i];
}
}
}
/**
* Returns CipherSuite by name
*/
public static CipherSuite getByName(String name) {
return SUITES_BY_NAME.get(name);
}
/**
* Returns CipherSuite based on TLS CipherSuite code
* @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., A.5. The CipherSuite</a>
*/
public static CipherSuite getByCode(byte b1, byte b2) {
if (b1 != 0 || (b2 & 0xFF) > SUITES_BY_CODE.length) {
// Unknown
return new CipherSuite("UNKNOWN_" + b1 + "_" + b2, false, 0, null,
null, null, new byte[] { b1, b2 });
}
return SUITES_BY_CODE[b2];
}
/**
* Returns CipherSuite based on V2CipherSpec code
* as described in TLS 1.0 spec., E. Backward Compatibility With SSL
*/
public static CipherSuite getByCode(byte b1, byte b2, byte b3) {
if (b1 == 0 && b2 == 0) {
if ((b3 & 0xFF) <= SUITES_BY_CODE.length) {
return SUITES_BY_CODE[b3];
}
}
// as TLSv1 equivalent of V2CipherSpec should be included in
// V2ClientHello, ignore V2CipherSpec
return new CipherSuite("UNKNOWN_" + b1 + "_" + b2 + "_" + b3, false, 0,
null, null, null, new byte[] { b1, b2, b3 });
}
/**
* Creates CipherSuite
*/
public CipherSuite(String name, boolean isExportable, int keyExchange,
String authType, String cipherName, String hash, byte[] code) {
this.name = name;
this.keyExchange = keyExchange;
this.authType = authType;
this.isExportable = isExportable;
if (cipherName == null) {
this.cipherName = null;
keyMaterial = 0;
expandedKeyMaterial = 0;
effectiveKeyBytes = 0;
ivSize = 0;
blockSize = 0;
// BEGIN android-removed
// } else if ("IDEA_CBC".equals(cipherName)) {
// this.cipherName = "IDEA/CBC/NoPadding";
// keyMaterial = 16;
// expandedKeyMaterial = 16;
// effectiveKeyBytes = 16;
// ivSize = 8;
// blockSize = 8;
// } else if ("RC2_CBC_40".equals(cipherName)) {
// this.cipherName = "RC2/CBC/NoPadding";
// keyMaterial = 5;
// expandedKeyMaterial = 16;
// effectiveKeyBytes = 5;
// ivSize = 8;
// blockSize = 8;
// END android-removed
} else if ("RC4_40".equals(cipherName)) {
this.cipherName = "RC4";
keyMaterial = 5;
expandedKeyMaterial = 16;
effectiveKeyBytes = 5;
ivSize = 0;
blockSize = 0;
} else if ("RC4_128".equals(cipherName)) {
this.cipherName = "RC4";
keyMaterial = 16;
expandedKeyMaterial = 16;
effectiveKeyBytes = 16;
ivSize = 0;
blockSize = 0;
} else if ("DES40_CBC".equals(cipherName)) {
this.cipherName = "DES/CBC/NoPadding";
keyMaterial = 5;
expandedKeyMaterial = 8;
effectiveKeyBytes = 5;
ivSize = 8;
blockSize = 8;
} else if ("DES_CBC".equals(cipherName)) {
this.cipherName = "DES/CBC/NoPadding";
keyMaterial = 8;
expandedKeyMaterial = 8;
effectiveKeyBytes = 7;
ivSize = 8;
blockSize = 8;
} else if ("3DES_EDE_CBC".equals(cipherName)) {
this.cipherName = "DESede/CBC/NoPadding";
keyMaterial = 24;
expandedKeyMaterial = 24;
effectiveKeyBytes = 24;
ivSize = 8;
blockSize = 8;
} else if ("AES_128".equals(cipherName)) {
this.cipherName = "AES/CBC/NoPadding";
keyMaterial = 16;
expandedKeyMaterial = 16;
effectiveKeyBytes = 16;
ivSize = 16;
blockSize = 16;
} else if ("AES_256".equals(cipherName)) {
this.cipherName = "AES/CBC/NoPadding";
keyMaterial = 32;
expandedKeyMaterial = 32;
effectiveKeyBytes = 32;
ivSize = 16;
blockSize = 16;
} else {
this.cipherName = cipherName;
keyMaterial = 0;
expandedKeyMaterial = 0;
effectiveKeyBytes = 0;
ivSize = 0;
blockSize = 0;
}
if ("MD5".equals(hash)) {
this.hmacName = "HmacMD5";
this.hashName = "MD5";
hashSize = 16;
} else if ("SHA".equals(hash)) {
this.hmacName = "HmacSHA1";
this.hashName = "SHA-1";
hashSize = 20;
} else {
this.hmacName = null;
this.hashName = null;
hashSize = 0;
}
cipherSuiteCode = code;
if (this.cipherName != null) {
try {
Cipher.getInstance(this.cipherName);
} catch (GeneralSecurityException e) {
supported = false;
}
}
}
/**
* Returns true if cipher suite is anonymous
* @return
*/
public boolean isAnonymous() {
if (keyExchange == KEY_EXCHANGE_DH_anon
|| keyExchange == KEY_EXCHANGE_DH_anon_EXPORT) {
return true;
}
return false;
}
/**
* Returns array of supported CipherSuites
* @return
*/
public static CipherSuite[] getSupported() {
return SUPPORTED_CIPHER_SUITES;
}
/**
* Returns array of supported cipher suites names
* @return
*/
public static String[] getSupportedCipherSuiteNames() {
return SUPPORTED_CIPHER_SUITE_NAMES.clone();
}
/**
* Returns cipher suite name
* @return
*/
public String getName() {
return name;
}
/**
* Returns cipher suite code as byte array
* @return
*/
public byte[] toBytes() {
return cipherSuiteCode;
}
/**
* Returns cipher suite description
*/
@Override
public String toString() {
return name + ": " + cipherSuiteCode[0] + " " + cipherSuiteCode[1];
}
/**
* Compares this cipher suite to the specified object.
*/
@Override
public boolean equals(Object obj) {
if (obj instanceof CipherSuite
&& this.cipherSuiteCode[0] == ((CipherSuite) obj).cipherSuiteCode[0]
&& this.cipherSuiteCode[1] == ((CipherSuite) obj).cipherSuiteCode[1]) {
return true;
}
return false;
}
/**
* Returns cipher algorithm name
* @return
*/
public String getBulkEncryptionAlgorithm() {
return cipherName;
}
/**
* Returns cipher block size
* @return
*/
public int getBlockSize() {
return blockSize;
}
/**
* Returns MAC algorithm name
* @return
*/
public String getHmacName() {
return hmacName;
}
/**
* Returns hash algorithm name
* @return
*/
public String getHashName() {
return hashName;
}
/**
* Returns hash size
* @return
*/
public int getMACLength() {
return hashSize;
}
/**
* Indicates whether this cipher suite is exportable
* @return
*/
public boolean isExportable() {
return isExportable;
}
}