1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.ssl; 27 28 import java.util.HashSet; 29 import java.util.Set; 30 import sun.security.util.AlgorithmDecomposer; 31 import static sun.security.ssl.CipherSuite.*; 32 import static sun.security.ssl.CipherSuite.KeyExchange.*; 33 34 /** 35 * The class decomposes standard SSL/TLS cipher suites into sub-elements. 36 */ 37 class SSLAlgorithmDecomposer extends AlgorithmDecomposer { 38 39 // indicates that only certification path algorithms need to be used 40 private final boolean onlyX509; 41 42 SSLAlgorithmDecomposer(boolean onlyX509) { 43 this.onlyX509 = onlyX509; 44 } 45 46 SSLAlgorithmDecomposer() { 47 this(false); 48 } 49 50 private Set<String> decomposes(CipherSuite.KeyExchange keyExchange) { 51 Set<String> components = new HashSet<>(); 52 switch (keyExchange) { 53 case K_NULL: 54 if (!onlyX509) { 55 components.add("K_NULL"); 56 } 57 break; 58 case K_RSA: 59 components.add("RSA"); 60 break; 61 case K_RSA_EXPORT: 62 components.add("RSA"); 63 components.add("RSA_EXPORT"); 64 break; 65 case K_DH_RSA: 66 components.add("RSA"); 67 components.add("DH"); 68 components.add("DiffieHellman"); 69 components.add("DH_RSA"); 70 break; 71 case K_DH_DSS: 72 components.add("DSA"); 73 components.add("DSS"); 74 components.add("DH"); 75 components.add("DiffieHellman"); 76 components.add("DH_DSS"); 77 break; 78 case K_DHE_DSS: 79 components.add("DSA"); 80 components.add("DSS"); 81 components.add("DH"); 82 components.add("DHE"); 83 components.add("DiffieHellman"); 84 components.add("DHE_DSS"); 85 break; 86 case K_DHE_RSA: 87 components.add("RSA"); 88 components.add("DH"); 89 components.add("DHE"); 90 components.add("DiffieHellman"); 91 components.add("DHE_RSA"); 92 break; 93 case K_DH_ANON: 94 if (!onlyX509) { 95 components.add("ANON"); 96 components.add("DH"); 97 components.add("DiffieHellman"); 98 components.add("DH_ANON"); 99 } 100 break; 101 case K_ECDH_ECDSA: 102 components.add("ECDH"); 103 components.add("ECDSA"); 104 components.add("ECDH_ECDSA"); 105 break; 106 case K_ECDH_RSA: 107 components.add("ECDH"); 108 components.add("RSA"); 109 components.add("ECDH_RSA"); 110 break; 111 case K_ECDHE_ECDSA: 112 components.add("ECDHE"); 113 components.add("ECDSA"); 114 components.add("ECDHE_ECDSA"); 115 break; 116 case K_ECDHE_RSA: 117 components.add("ECDHE"); 118 components.add("RSA"); 119 components.add("ECDHE_RSA"); 120 break; 121 case K_ECDH_ANON: 122 if (!onlyX509) { 123 components.add("ECDH"); 124 components.add("ANON"); 125 components.add("ECDH_ANON"); 126 } 127 break; 128 case K_KRB5: 129 if (!onlyX509) { 130 components.add("KRB5"); 131 } 132 break; 133 case K_KRB5_EXPORT: 134 if (!onlyX509) { 135 components.add("KRB5_EXPORT"); 136 } 137 break; 138 default: 139 // ignore 140 } 141 142 return components; 143 } 144 145 private Set<String> decomposes(CipherSuite.BulkCipher bulkCipher) { 146 Set<String> components = new HashSet<>(); 147 148 if (bulkCipher.transformation != null) { 149 components.addAll(super.decompose(bulkCipher.transformation)); 150 } 151 152 if (bulkCipher == B_NULL) { 153 components.add("C_NULL"); 154 } else if (bulkCipher == B_RC2_40) { 155 components.add("RC2_CBC_40"); 156 } else if (bulkCipher == B_RC4_40) { 157 components.add("RC4_40"); 158 } else if (bulkCipher == B_RC4_128) { 159 components.add("RC4_128"); 160 } else if (bulkCipher == B_DES_40) { 161 components.add("DES40_CBC"); 162 components.add("DES_CBC_40"); 163 } else if (bulkCipher == B_DES) { 164 components.add("DES_CBC"); 165 } else if (bulkCipher == B_3DES) { 166 components.add("3DES_EDE_CBC"); 167 } else if (bulkCipher == B_AES_128) { 168 components.add("AES_128_CBC"); 169 } else if (bulkCipher == B_AES_256) { 170 components.add("AES_256_CBC"); 171 } else if (bulkCipher == B_AES_128_GCM) { 172 components.add("AES_128_GCM"); 173 } else if (bulkCipher == B_AES_256_GCM) { 174 components.add("AES_256_GCM"); 175 } 176 177 return components; 178 } 179 180 private Set<String> decomposes(CipherSuite.MacAlg macAlg, 181 BulkCipher cipher) { 182 Set<String> components = new HashSet<>(); 183 184 if (macAlg == M_NULL 185 && cipher.cipherType != CipherType.AEAD_CIPHER) { 186 components.add("M_NULL"); 187 } else if (macAlg == M_MD5) { 188 components.add("MD5"); 189 components.add("HmacMD5"); 190 } else if (macAlg == M_SHA) { 191 components.add("SHA1"); 192 components.add("SHA-1"); 193 components.add("HmacSHA1"); 194 } else if (macAlg == M_SHA256) { 195 components.add("SHA256"); 196 components.add("SHA-256"); 197 components.add("HmacSHA256"); 198 } else if (macAlg == M_SHA384) { 199 components.add("SHA384"); 200 components.add("SHA-384"); 201 components.add("HmacSHA384"); 202 } 203 204 return components; 205 } 206 207 private Set<String> decompose(KeyExchange keyExchange, BulkCipher cipher, 208 MacAlg macAlg) { 209 Set<String> components = new HashSet<>(); 210 211 if (keyExchange != null) { 212 components.addAll(decomposes(keyExchange)); 213 } 214 215 if (onlyX509) { 216 // Certification path algorithm constraints do not apply 217 // to cipher and macAlg. 218 return components; 219 } 220 221 if (cipher != null) { 222 components.addAll(decomposes(cipher)); 223 } 224 225 if (macAlg != null) { 226 components.addAll(decomposes(macAlg, cipher)); 227 } 228 229 return components; 230 } 231 232 @Override 233 public Set<String> decompose(String algorithm) { 234 if (algorithm.startsWith("SSL_") || algorithm.startsWith("TLS_")) { 235 CipherSuite cipherSuite = null; 236 try { 237 cipherSuite = CipherSuite.valueOf(algorithm); 238 } catch (IllegalArgumentException iae) { 239 // ignore: unknown or unsupported ciphersuite 240 } 241 242 if (cipherSuite != null) { 243 return decompose(cipherSuite.keyExchange, cipherSuite.cipher, 244 cipherSuite.macAlg); 245 } 246 } 247 248 return super.decompose(algorithm); 249 } 250 251 }