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