1 /* 2 * Copyright (c) 2010, 2011, 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.security.AlgorithmConstraints; 29 import java.security.CryptoPrimitive; 30 import java.security.AlgorithmParameters; 31 32 import javax.net.ssl.*; 33 34 import java.security.Key; 35 36 import java.util.Set; 37 import java.util.HashSet; 38 39 import sun.security.util.DisabledAlgorithmConstraints; 40 import sun.security.ssl.CipherSuite.*; 41 42 /** 43 * Algorithm constraints for disabled algorithms property 44 * 45 * See the "jdk.certpath.disabledAlgorithms" specification in java.security 46 * for the syntax of the disabled algorithm string. 47 */ 48 final class SSLAlgorithmConstraints implements AlgorithmConstraints { 49 private final static AlgorithmConstraints tlsDisabledAlgConstraints = 50 new TLSDisabledAlgConstraints(); 51 private final static AlgorithmConstraints x509DisabledAlgConstraints = 52 new X509DisabledAlgConstraints(); 53 private AlgorithmConstraints userAlgConstraints = null; 54 private AlgorithmConstraints peerAlgConstraints = null; 55 56 private boolean enabledX509DisabledAlgConstraints = true; 57 SSLAlgorithmConstraints(AlgorithmConstraints algorithmConstraints)58 SSLAlgorithmConstraints(AlgorithmConstraints algorithmConstraints) { 59 userAlgConstraints = algorithmConstraints; 60 } 61 SSLAlgorithmConstraints(SSLSocket socket, boolean withDefaultCertPathConstraints)62 SSLAlgorithmConstraints(SSLSocket socket, 63 boolean withDefaultCertPathConstraints) { 64 if (socket != null) { 65 userAlgConstraints = 66 socket.getSSLParameters().getAlgorithmConstraints(); 67 } 68 69 if (!withDefaultCertPathConstraints) { 70 enabledX509DisabledAlgConstraints = false; 71 } 72 } 73 SSLAlgorithmConstraints(SSLEngine engine, boolean withDefaultCertPathConstraints)74 SSLAlgorithmConstraints(SSLEngine engine, 75 boolean withDefaultCertPathConstraints) { 76 if (engine != null) { 77 userAlgConstraints = 78 engine.getSSLParameters().getAlgorithmConstraints(); 79 } 80 81 if (!withDefaultCertPathConstraints) { 82 enabledX509DisabledAlgConstraints = false; 83 } 84 } 85 SSLAlgorithmConstraints(SSLSocket socket, String[] supportedAlgorithms, boolean withDefaultCertPathConstraints)86 SSLAlgorithmConstraints(SSLSocket socket, String[] supportedAlgorithms, 87 boolean withDefaultCertPathConstraints) { 88 if (socket != null) { 89 userAlgConstraints = 90 socket.getSSLParameters().getAlgorithmConstraints(); 91 peerAlgConstraints = 92 new SupportedSignatureAlgorithmConstraints(supportedAlgorithms); 93 } 94 95 if (!withDefaultCertPathConstraints) { 96 enabledX509DisabledAlgConstraints = false; 97 } 98 } 99 SSLAlgorithmConstraints(SSLEngine engine, String[] supportedAlgorithms, boolean withDefaultCertPathConstraints)100 SSLAlgorithmConstraints(SSLEngine engine, String[] supportedAlgorithms, 101 boolean withDefaultCertPathConstraints) { 102 if (engine != null) { 103 userAlgConstraints = 104 engine.getSSLParameters().getAlgorithmConstraints(); 105 peerAlgConstraints = 106 new SupportedSignatureAlgorithmConstraints(supportedAlgorithms); 107 } 108 109 if (!withDefaultCertPathConstraints) { 110 enabledX509DisabledAlgConstraints = false; 111 } 112 } 113 permits(Set<CryptoPrimitive> primitives, String algorithm, AlgorithmParameters parameters)114 public boolean permits(Set<CryptoPrimitive> primitives, 115 String algorithm, AlgorithmParameters parameters) { 116 117 boolean permitted = true; 118 119 if (peerAlgConstraints != null) { 120 permitted = peerAlgConstraints.permits( 121 primitives, algorithm, parameters); 122 } 123 124 if (permitted && userAlgConstraints != null) { 125 permitted = userAlgConstraints.permits( 126 primitives, algorithm, parameters); 127 } 128 129 if (permitted) { 130 permitted = tlsDisabledAlgConstraints.permits( 131 primitives, algorithm, parameters); 132 } 133 134 if (permitted && enabledX509DisabledAlgConstraints) { 135 permitted = x509DisabledAlgConstraints.permits( 136 primitives, algorithm, parameters); 137 } 138 139 return permitted; 140 } 141 permits(Set<CryptoPrimitive> primitives, Key key)142 public boolean permits(Set<CryptoPrimitive> primitives, Key key) { 143 144 boolean permitted = true; 145 146 if (peerAlgConstraints != null) { 147 permitted = peerAlgConstraints.permits(primitives, key); 148 } 149 150 if (permitted && userAlgConstraints != null) { 151 permitted = userAlgConstraints.permits(primitives, key); 152 } 153 154 if (permitted) { 155 permitted = tlsDisabledAlgConstraints.permits(primitives, key); 156 } 157 158 if (permitted && enabledX509DisabledAlgConstraints) { 159 permitted = x509DisabledAlgConstraints.permits(primitives, key); 160 } 161 162 return permitted; 163 } 164 permits(Set<CryptoPrimitive> primitives, String algorithm, Key key, AlgorithmParameters parameters)165 public boolean permits(Set<CryptoPrimitive> primitives, 166 String algorithm, Key key, AlgorithmParameters parameters) { 167 168 boolean permitted = true; 169 170 if (peerAlgConstraints != null) { 171 permitted = peerAlgConstraints.permits( 172 primitives, algorithm, key, parameters); 173 } 174 175 if (permitted && userAlgConstraints != null) { 176 permitted = userAlgConstraints.permits( 177 primitives, algorithm, key, parameters); 178 } 179 180 if (permitted) { 181 permitted = tlsDisabledAlgConstraints.permits( 182 primitives, algorithm, key, parameters); 183 } 184 185 if (permitted && enabledX509DisabledAlgConstraints) { 186 permitted = x509DisabledAlgConstraints.permits( 187 primitives, algorithm, key, parameters); 188 } 189 190 return permitted; 191 } 192 193 194 static private class SupportedSignatureAlgorithmConstraints 195 implements AlgorithmConstraints { 196 // supported signature algorithms 197 private String[] supportedAlgorithms; 198 SupportedSignatureAlgorithmConstraints(String[] supportedAlgorithms)199 SupportedSignatureAlgorithmConstraints(String[] supportedAlgorithms) { 200 if (supportedAlgorithms != null) { 201 this.supportedAlgorithms = supportedAlgorithms.clone(); 202 } else { 203 this.supportedAlgorithms = null; 204 } 205 } 206 permits(Set<CryptoPrimitive> primitives, String algorithm, AlgorithmParameters parameters)207 public boolean permits(Set<CryptoPrimitive> primitives, 208 String algorithm, AlgorithmParameters parameters) { 209 210 if (algorithm == null || algorithm.length() == 0) { 211 throw new IllegalArgumentException( 212 "No algorithm name specified"); 213 } 214 215 if (primitives == null || primitives.isEmpty()) { 216 throw new IllegalArgumentException( 217 "No cryptographic primitive specified"); 218 } 219 220 if (supportedAlgorithms == null || 221 supportedAlgorithms.length == 0) { 222 return false; 223 } 224 225 // trim the MGF part: <digest>with<encryption>and<mgf> 226 int position = algorithm.indexOf("and"); 227 if (position > 0) { 228 algorithm = algorithm.substring(0, position); 229 } 230 231 for (String supportedAlgorithm : supportedAlgorithms) { 232 if (algorithm.equalsIgnoreCase(supportedAlgorithm)) { 233 return true; 234 } 235 } 236 237 return false; 238 } 239 permits(Set<CryptoPrimitive> primitives, Key key)240 final public boolean permits(Set<CryptoPrimitive> primitives, Key key) { 241 return true; 242 } 243 permits(Set<CryptoPrimitive> primitives, String algorithm, Key key, AlgorithmParameters parameters)244 final public boolean permits(Set<CryptoPrimitive> primitives, 245 String algorithm, Key key, AlgorithmParameters parameters) { 246 247 if (algorithm == null || algorithm.length() == 0) { 248 throw new IllegalArgumentException( 249 "No algorithm name specified"); 250 } 251 252 return permits(primitives, algorithm, parameters); 253 } 254 } 255 256 static private class BasicDisabledAlgConstraints 257 extends DisabledAlgorithmConstraints { BasicDisabledAlgConstraints(String propertyName)258 BasicDisabledAlgConstraints(String propertyName) { 259 super(propertyName); 260 } 261 decomposes(KeyExchange keyExchange, boolean forCertPathOnly)262 protected Set<String> decomposes(KeyExchange keyExchange, 263 boolean forCertPathOnly) { 264 Set<String> components = new HashSet<>(); 265 switch (keyExchange) { 266 case K_NULL: 267 if (!forCertPathOnly) { 268 components.add("NULL"); 269 } 270 break; 271 case K_RSA: 272 components.add("RSA"); 273 break; 274 case K_RSA_EXPORT: 275 components.add("RSA"); 276 components.add("RSA_EXPORT"); 277 break; 278 case K_DH_RSA: 279 components.add("RSA"); 280 components.add("DH"); 281 components.add("DiffieHellman"); 282 components.add("DH_RSA"); 283 break; 284 case K_DH_DSS: 285 components.add("DSA"); 286 components.add("DSS"); 287 components.add("DH"); 288 components.add("DiffieHellman"); 289 components.add("DH_DSS"); 290 break; 291 case K_DHE_DSS: 292 components.add("DSA"); 293 components.add("DSS"); 294 components.add("DH"); 295 components.add("DHE"); 296 components.add("DiffieHellman"); 297 components.add("DHE_DSS"); 298 break; 299 case K_DHE_RSA: 300 components.add("RSA"); 301 components.add("DH"); 302 components.add("DHE"); 303 components.add("DiffieHellman"); 304 components.add("DHE_RSA"); 305 break; 306 case K_DH_ANON: 307 if (!forCertPathOnly) { 308 components.add("ANON"); 309 components.add("DH"); 310 components.add("DiffieHellman"); 311 components.add("DH_ANON"); 312 } 313 break; 314 case K_ECDH_ECDSA: 315 components.add("ECDH"); 316 components.add("ECDSA"); 317 components.add("ECDH_ECDSA"); 318 break; 319 case K_ECDH_RSA: 320 components.add("ECDH"); 321 components.add("RSA"); 322 components.add("ECDH_RSA"); 323 break; 324 case K_ECDHE_ECDSA: 325 components.add("ECDHE"); 326 components.add("ECDSA"); 327 components.add("ECDHE_ECDSA"); 328 break; 329 case K_ECDHE_RSA: 330 components.add("ECDHE"); 331 components.add("RSA"); 332 components.add("ECDHE_RSA"); 333 break; 334 case K_ECDH_ANON: 335 if (!forCertPathOnly) { 336 components.add("ECDH"); 337 components.add("ANON"); 338 components.add("ECDH_ANON"); 339 } 340 break; 341 case K_KRB5: 342 if (!forCertPathOnly) { 343 components.add("KRB5"); 344 } 345 break; 346 case K_KRB5_EXPORT: 347 if (!forCertPathOnly) { 348 components.add("KRB5_EXPORT"); 349 } 350 break; 351 default: 352 // ignore 353 } 354 355 return components; 356 } 357 decomposes(BulkCipher bulkCipher)358 protected Set<String> decomposes(BulkCipher bulkCipher) { 359 Set<String> components = new HashSet<>(); 360 361 if (bulkCipher.transformation != null) { 362 components.addAll(super.decomposes(bulkCipher.transformation)); 363 } 364 365 return components; 366 } 367 decomposes(MacAlg macAlg)368 protected Set<String> decomposes(MacAlg macAlg) { 369 Set<String> components = new HashSet<>(); 370 371 if (macAlg == CipherSuite.M_MD5) { 372 components.add("MD5"); 373 components.add("HmacMD5"); 374 } else if (macAlg == CipherSuite.M_SHA) { 375 components.add("SHA1"); 376 components.add("SHA-1"); 377 components.add("HmacSHA1"); 378 } else if (macAlg == CipherSuite.M_SHA256) { 379 components.add("SHA256"); 380 components.add("SHA-256"); 381 components.add("HmacSHA256"); 382 } else if (macAlg == CipherSuite.M_SHA384) { 383 components.add("SHA384"); 384 components.add("SHA-384"); 385 components.add("HmacSHA384"); 386 } 387 388 return components; 389 } 390 } 391 392 static private class TLSDisabledAlgConstraints 393 extends BasicDisabledAlgConstraints { 394 TLSDisabledAlgConstraints()395 TLSDisabledAlgConstraints() { 396 super(DisabledAlgorithmConstraints.PROPERTY_TLS_DISABLED_ALGS); 397 } 398 399 @Override decomposes(String algorithm)400 protected Set<String> decomposes(String algorithm) { 401 if (algorithm.startsWith("SSL_") || algorithm.startsWith("TLS_")) { 402 CipherSuite cipherSuite = null; 403 try { 404 cipherSuite = CipherSuite.valueOf(algorithm); 405 } catch (IllegalArgumentException iae) { 406 // ignore: unknown or unsupported ciphersuite 407 } 408 409 if (cipherSuite != null) { 410 Set<String> components = new HashSet<>(); 411 412 if(cipherSuite.keyExchange != null) { 413 components.addAll( 414 decomposes(cipherSuite.keyExchange, false)); 415 } 416 417 if (cipherSuite.cipher != null) { 418 components.addAll(decomposes(cipherSuite.cipher)); 419 } 420 421 if (cipherSuite.macAlg != null) { 422 components.addAll(decomposes(cipherSuite.macAlg)); 423 } 424 425 return components; 426 } 427 } 428 429 return super.decomposes(algorithm); 430 } 431 } 432 433 static private class X509DisabledAlgConstraints 434 extends BasicDisabledAlgConstraints { 435 X509DisabledAlgConstraints()436 X509DisabledAlgConstraints() { 437 super(DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS); 438 } 439 440 @Override decomposes(String algorithm)441 protected Set<String> decomposes(String algorithm) { 442 if (algorithm.startsWith("SSL_") || algorithm.startsWith("TLS_")) { 443 CipherSuite cipherSuite = null; 444 try { 445 cipherSuite = CipherSuite.valueOf(algorithm); 446 } catch (IllegalArgumentException iae) { 447 // ignore: unknown or unsupported ciphersuite 448 } 449 450 if (cipherSuite != null) { 451 Set<String> components = new HashSet<>(); 452 453 if(cipherSuite.keyExchange != null) { 454 components.addAll( 455 decomposes(cipherSuite.keyExchange, true)); 456 } 457 458 // Certification path algorithm constraints do not apply 459 // to cipherSuite.cipher and cipherSuite.macAlg. 460 461 return components; 462 } 463 } 464 465 return super.decomposes(algorithm); 466 } 467 } 468 } 469 470