1 /* 2 * Copyright (c) 2015, 2019, 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.ssl.CipherSuite.HashAlg; 31 import sun.security.ssl.CipherSuite.KeyExchange; 32 import static sun.security.ssl.CipherSuite.KeyExchange.*; 33 import sun.security.ssl.CipherSuite.MacAlg; 34 import static sun.security.ssl.SSLCipher.*; 35 import sun.security.util.AlgorithmDecomposer; 36 37 /** 38 * The class decomposes standard SSL/TLS cipher suites into sub-elements. 39 */ 40 class SSLAlgorithmDecomposer extends AlgorithmDecomposer { 41 42 // indicates that only certification path algorithms need to be used 43 private final boolean onlyX509; 44 SSLAlgorithmDecomposer(boolean onlyX509)45 SSLAlgorithmDecomposer(boolean onlyX509) { 46 this.onlyX509 = onlyX509; 47 } 48 SSLAlgorithmDecomposer()49 SSLAlgorithmDecomposer() { 50 this(false); 51 } 52 decomposes(CipherSuite.KeyExchange keyExchange)53 private Set<String> decomposes(CipherSuite.KeyExchange keyExchange) { 54 Set<String> components = new HashSet<>(); 55 switch (keyExchange) { 56 case K_NULL: 57 if (!onlyX509) { 58 components.add("K_NULL"); 59 } 60 break; 61 case K_RSA: 62 components.add("RSA"); 63 break; 64 case K_RSA_EXPORT: 65 components.add("RSA"); 66 components.add("RSA_EXPORT"); 67 break; 68 case K_DH_RSA: 69 components.add("RSA"); 70 components.add("DH"); 71 components.add("DiffieHellman"); 72 components.add("DH_RSA"); 73 break; 74 case K_DH_DSS: 75 components.add("DSA"); 76 components.add("DSS"); 77 components.add("DH"); 78 components.add("DiffieHellman"); 79 components.add("DH_DSS"); 80 break; 81 case K_DHE_DSS: 82 components.add("DSA"); 83 components.add("DSS"); 84 components.add("DH"); 85 components.add("DHE"); 86 components.add("DiffieHellman"); 87 components.add("DHE_DSS"); 88 break; 89 case K_DHE_RSA: 90 components.add("RSA"); 91 components.add("DH"); 92 components.add("DHE"); 93 components.add("DiffieHellman"); 94 components.add("DHE_RSA"); 95 break; 96 case K_DH_ANON: 97 if (!onlyX509) { 98 components.add("ANON"); 99 components.add("DH"); 100 components.add("DiffieHellman"); 101 components.add("DH_ANON"); 102 } 103 break; 104 case K_ECDH_ECDSA: 105 components.add("ECDH"); 106 components.add("ECDSA"); 107 components.add("ECDH_ECDSA"); 108 break; 109 case K_ECDH_RSA: 110 components.add("ECDH"); 111 components.add("RSA"); 112 components.add("ECDH_RSA"); 113 break; 114 case K_ECDHE_ECDSA: 115 components.add("ECDHE"); 116 components.add("ECDSA"); 117 components.add("ECDHE_ECDSA"); 118 break; 119 case K_ECDHE_RSA: 120 components.add("ECDHE"); 121 components.add("RSA"); 122 components.add("ECDHE_RSA"); 123 break; 124 case K_ECDH_ANON: 125 if (!onlyX509) { 126 components.add("ECDH"); 127 components.add("ANON"); 128 components.add("ECDH_ANON"); 129 } 130 break; 131 default: 132 // otherwise ignore 133 } 134 135 return components; 136 } 137 decomposes(SSLCipher bulkCipher)138 private Set<String> decomposes(SSLCipher bulkCipher) { 139 Set<String> components = new HashSet<>(); 140 141 if (bulkCipher.transformation != null) { 142 components.addAll(super.decompose(bulkCipher.transformation)); 143 } 144 145 switch (bulkCipher) { 146 case B_NULL: 147 components.add("C_NULL"); 148 break; 149 case B_RC2_40: 150 components.add("RC2_CBC_40"); 151 break; 152 case B_RC4_40: 153 components.add("RC4_40"); 154 break; 155 case B_RC4_128: 156 components.add("RC4_128"); 157 break; 158 case B_DES_40: 159 components.add("DES40_CBC"); 160 components.add("DES_CBC_40"); 161 break; 162 case B_DES: 163 components.add("DES_CBC"); 164 break; 165 case B_3DES: 166 components.add("3DES_EDE_CBC"); 167 break; 168 case B_AES_128: 169 components.add("AES_128_CBC"); 170 break; 171 case B_AES_256: 172 components.add("AES_256_CBC"); 173 break; 174 case B_AES_128_GCM: 175 components.add("AES_128_GCM"); 176 break; 177 case B_AES_256_GCM: 178 components.add("AES_256_GCM"); 179 break; 180 } 181 182 return components; 183 } 184 decomposes(CipherSuite.MacAlg macAlg, SSLCipher cipher)185 private Set<String> decomposes(CipherSuite.MacAlg macAlg, 186 SSLCipher cipher) { 187 Set<String> components = new HashSet<>(); 188 189 if (macAlg == CipherSuite.MacAlg.M_NULL 190 && cipher.cipherType != CipherType.AEAD_CIPHER) { 191 components.add("M_NULL"); 192 } else if (macAlg == CipherSuite.MacAlg.M_MD5) { 193 components.add("MD5"); 194 components.add("HmacMD5"); 195 } else if (macAlg == CipherSuite.MacAlg.M_SHA) { 196 components.add("SHA1"); 197 components.add("SHA-1"); 198 components.add("HmacSHA1"); 199 } else if (macAlg == CipherSuite.MacAlg.M_SHA256) { 200 components.add("SHA256"); 201 components.add("SHA-256"); 202 components.add("HmacSHA256"); 203 } else if (macAlg == CipherSuite.MacAlg.M_SHA384) { 204 components.add("SHA384"); 205 components.add("SHA-384"); 206 components.add("HmacSHA384"); 207 } 208 209 return components; 210 } 211 decomposes(CipherSuite.HashAlg hashAlg)212 private Set<String> decomposes(CipherSuite.HashAlg hashAlg) { 213 Set<String> components = new HashSet<>(); 214 215 if (hashAlg == CipherSuite.HashAlg.H_SHA256) { 216 components.add("SHA256"); 217 components.add("SHA-256"); 218 components.add("HmacSHA256"); 219 } else if (hashAlg == CipherSuite.HashAlg.H_SHA384) { 220 components.add("SHA384"); 221 components.add("SHA-384"); 222 components.add("HmacSHA384"); 223 } 224 225 return components; 226 } 227 decompose(KeyExchange keyExchange, SSLCipher cipher, MacAlg macAlg, HashAlg hashAlg)228 private Set<String> decompose(KeyExchange keyExchange, 229 SSLCipher cipher, 230 MacAlg macAlg, 231 HashAlg hashAlg) { 232 Set<String> components = new HashSet<>(); 233 234 if (keyExchange != null) { 235 components.addAll(decomposes(keyExchange)); 236 } 237 238 if (onlyX509) { 239 // Certification path algorithm constraints do not apply 240 // to cipher and macAlg. 241 return components; 242 } 243 244 if (cipher != null) { 245 components.addAll(decomposes(cipher)); 246 } 247 248 if (macAlg != null) { 249 components.addAll(decomposes(macAlg, cipher)); 250 } 251 252 if (hashAlg != null) { 253 components.addAll(decomposes(hashAlg)); 254 } 255 256 return components; 257 } 258 259 @Override decompose(String algorithm)260 public Set<String> decompose(String algorithm) { 261 if (algorithm.startsWith("SSL_") || algorithm.startsWith("TLS_")) { 262 CipherSuite cipherSuite = null; 263 try { 264 cipherSuite = CipherSuite.nameOf(algorithm); 265 } catch (IllegalArgumentException iae) { 266 // ignore: unknown or unsupported ciphersuite 267 } 268 269 if (cipherSuite != null && 270 cipherSuite != CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) { 271 return decompose(cipherSuite.keyExchange, 272 cipherSuite.bulkCipher, 273 cipherSuite.macAlg, 274 cipherSuite.hashAlg); 275 } 276 } 277 278 return super.decompose(algorithm); 279 } 280 } 281