1 /* 2 * Copyright (c) 2010, 2018, 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.AlgorithmParameters; 30 import java.security.CryptoPrimitive; 31 import java.security.Key; 32 import java.util.Set; 33 import javax.net.ssl.*; 34 import sun.security.util.DisabledAlgorithmConstraints; 35 import static sun.security.util.DisabledAlgorithmConstraints.*; 36 37 /** 38 * Algorithm constraints for disabled algorithms property 39 * 40 * See the "jdk.certpath.disabledAlgorithms" specification in java.security 41 * for the syntax of the disabled algorithm string. 42 */ 43 final class SSLAlgorithmConstraints implements AlgorithmConstraints { 44 45 private static final AlgorithmConstraints tlsDisabledAlgConstraints = 46 new DisabledAlgorithmConstraints(PROPERTY_TLS_DISABLED_ALGS, 47 new SSLAlgorithmDecomposer()); 48 49 private static final AlgorithmConstraints x509DisabledAlgConstraints = 50 new DisabledAlgorithmConstraints(PROPERTY_CERTPATH_DISABLED_ALGS, 51 new SSLAlgorithmDecomposer(true)); 52 53 private final AlgorithmConstraints userSpecifiedConstraints; 54 private final AlgorithmConstraints peerSpecifiedConstraints; 55 56 private final boolean enabledX509DisabledAlgConstraints; 57 58 // the default algorithm constraints 59 static final AlgorithmConstraints DEFAULT = 60 new SSLAlgorithmConstraints(null); 61 62 // the default SSL only algorithm constraints 63 static final AlgorithmConstraints DEFAULT_SSL_ONLY = 64 new SSLAlgorithmConstraints((SSLSocket)null, false); 65 SSLAlgorithmConstraints(AlgorithmConstraints userSpecifiedConstraints)66 SSLAlgorithmConstraints(AlgorithmConstraints userSpecifiedConstraints) { 67 this.userSpecifiedConstraints = userSpecifiedConstraints; 68 this.peerSpecifiedConstraints = null; 69 this.enabledX509DisabledAlgConstraints = true; 70 } 71 SSLAlgorithmConstraints(SSLSocket socket, boolean withDefaultCertPathConstraints)72 SSLAlgorithmConstraints(SSLSocket socket, 73 boolean withDefaultCertPathConstraints) { 74 this.userSpecifiedConstraints = getUserSpecifiedConstraints(socket); 75 this.peerSpecifiedConstraints = null; 76 this.enabledX509DisabledAlgConstraints = withDefaultCertPathConstraints; 77 } 78 SSLAlgorithmConstraints(SSLEngine engine, boolean withDefaultCertPathConstraints)79 SSLAlgorithmConstraints(SSLEngine engine, 80 boolean withDefaultCertPathConstraints) { 81 this.userSpecifiedConstraints = getUserSpecifiedConstraints(engine); 82 this.peerSpecifiedConstraints = null; 83 this.enabledX509DisabledAlgConstraints = withDefaultCertPathConstraints; 84 } 85 SSLAlgorithmConstraints(SSLSocket socket, String[] supportedAlgorithms, boolean withDefaultCertPathConstraints)86 SSLAlgorithmConstraints(SSLSocket socket, String[] supportedAlgorithms, 87 boolean withDefaultCertPathConstraints) { 88 this.userSpecifiedConstraints = getUserSpecifiedConstraints(socket); 89 this.peerSpecifiedConstraints = 90 new SupportedSignatureAlgorithmConstraints(supportedAlgorithms); 91 this.enabledX509DisabledAlgConstraints = withDefaultCertPathConstraints; 92 } 93 SSLAlgorithmConstraints(SSLEngine engine, String[] supportedAlgorithms, boolean withDefaultCertPathConstraints)94 SSLAlgorithmConstraints(SSLEngine engine, String[] supportedAlgorithms, 95 boolean withDefaultCertPathConstraints) { 96 this.userSpecifiedConstraints = getUserSpecifiedConstraints(engine); 97 this.peerSpecifiedConstraints = 98 new SupportedSignatureAlgorithmConstraints(supportedAlgorithms); 99 this.enabledX509DisabledAlgConstraints = withDefaultCertPathConstraints; 100 } 101 getUserSpecifiedConstraints( SSLEngine engine)102 private static AlgorithmConstraints getUserSpecifiedConstraints( 103 SSLEngine engine) { 104 if (engine != null) { 105 // Note that the KeyManager or TrustManager implementation may be 106 // not implemented in the same provider as SSLSocket/SSLEngine. 107 // Please check the instance before casting to use SSLEngineImpl. 108 if (engine instanceof SSLEngineImpl) { 109 HandshakeContext hc = 110 ((SSLEngineImpl)engine).conContext.handshakeContext; 111 if (hc != null) { 112 return hc.sslConfig.userSpecifiedAlgorithmConstraints; 113 } 114 } 115 116 return engine.getSSLParameters().getAlgorithmConstraints(); 117 } 118 119 return null; 120 } 121 getUserSpecifiedConstraints( SSLSocket socket)122 private static AlgorithmConstraints getUserSpecifiedConstraints( 123 SSLSocket socket) { 124 if (socket != null) { 125 // Note that the KeyManager or TrustManager implementation may be 126 // not implemented in the same provider as SSLSocket/SSLEngine. 127 // Please check the instance before casting to use SSLSocketImpl. 128 if (socket instanceof SSLSocketImpl) { 129 HandshakeContext hc = 130 ((SSLSocketImpl)socket).conContext.handshakeContext; 131 if (hc != null) { 132 return hc.sslConfig.userSpecifiedAlgorithmConstraints; 133 } 134 } 135 136 return socket.getSSLParameters().getAlgorithmConstraints(); 137 } 138 139 return null; 140 } 141 142 @Override permits(Set<CryptoPrimitive> primitives, String algorithm, AlgorithmParameters parameters)143 public boolean permits(Set<CryptoPrimitive> primitives, 144 String algorithm, AlgorithmParameters parameters) { 145 146 boolean permitted = true; 147 148 if (peerSpecifiedConstraints != null) { 149 permitted = peerSpecifiedConstraints.permits( 150 primitives, algorithm, parameters); 151 } 152 153 if (permitted && userSpecifiedConstraints != null) { 154 permitted = userSpecifiedConstraints.permits( 155 primitives, algorithm, parameters); 156 } 157 158 if (permitted) { 159 permitted = tlsDisabledAlgConstraints.permits( 160 primitives, algorithm, parameters); 161 } 162 163 if (permitted && enabledX509DisabledAlgConstraints) { 164 permitted = x509DisabledAlgConstraints.permits( 165 primitives, algorithm, parameters); 166 } 167 168 return permitted; 169 } 170 171 @Override permits(Set<CryptoPrimitive> primitives, Key key)172 public boolean permits(Set<CryptoPrimitive> primitives, Key key) { 173 174 boolean permitted = true; 175 176 if (peerSpecifiedConstraints != null) { 177 permitted = peerSpecifiedConstraints.permits(primitives, key); 178 } 179 180 if (permitted && userSpecifiedConstraints != null) { 181 permitted = userSpecifiedConstraints.permits(primitives, key); 182 } 183 184 if (permitted) { 185 permitted = tlsDisabledAlgConstraints.permits(primitives, key); 186 } 187 188 if (permitted && enabledX509DisabledAlgConstraints) { 189 permitted = x509DisabledAlgConstraints.permits(primitives, key); 190 } 191 192 return permitted; 193 } 194 195 @Override permits(Set<CryptoPrimitive> primitives, String algorithm, Key key, AlgorithmParameters parameters)196 public boolean permits(Set<CryptoPrimitive> primitives, 197 String algorithm, Key key, AlgorithmParameters parameters) { 198 199 boolean permitted = true; 200 201 if (peerSpecifiedConstraints != null) { 202 permitted = peerSpecifiedConstraints.permits( 203 primitives, algorithm, key, parameters); 204 } 205 206 if (permitted && userSpecifiedConstraints != null) { 207 permitted = userSpecifiedConstraints.permits( 208 primitives, algorithm, key, parameters); 209 } 210 211 if (permitted) { 212 permitted = tlsDisabledAlgConstraints.permits( 213 primitives, algorithm, key, parameters); 214 } 215 216 if (permitted && enabledX509DisabledAlgConstraints) { 217 permitted = x509DisabledAlgConstraints.permits( 218 primitives, algorithm, key, parameters); 219 } 220 221 return permitted; 222 } 223 224 225 private static class SupportedSignatureAlgorithmConstraints 226 implements AlgorithmConstraints { 227 // supported signature algorithms 228 private String[] supportedAlgorithms; 229 SupportedSignatureAlgorithmConstraints(String[] supportedAlgorithms)230 SupportedSignatureAlgorithmConstraints(String[] supportedAlgorithms) { 231 if (supportedAlgorithms != null) { 232 this.supportedAlgorithms = supportedAlgorithms.clone(); 233 } else { 234 this.supportedAlgorithms = null; 235 } 236 } 237 238 @Override permits(Set<CryptoPrimitive> primitives, String algorithm, AlgorithmParameters parameters)239 public boolean permits(Set<CryptoPrimitive> primitives, 240 String algorithm, AlgorithmParameters parameters) { 241 242 if (algorithm == null || algorithm.isEmpty()) { 243 throw new IllegalArgumentException( 244 "No algorithm name specified"); 245 } 246 247 if (primitives == null || primitives.isEmpty()) { 248 throw new IllegalArgumentException( 249 "No cryptographic primitive specified"); 250 } 251 252 if (supportedAlgorithms == null || 253 supportedAlgorithms.length == 0) { 254 return false; 255 } 256 257 // trim the MGF part: <digest>with<encryption>and<mgf> 258 int position = algorithm.indexOf("and"); 259 if (position > 0) { 260 algorithm = algorithm.substring(0, position); 261 } 262 263 for (String supportedAlgorithm : supportedAlgorithms) { 264 if (algorithm.equalsIgnoreCase(supportedAlgorithm)) { 265 return true; 266 } 267 } 268 269 return false; 270 } 271 272 @Override permits(Set<CryptoPrimitive> primitives, Key key)273 public final boolean permits(Set<CryptoPrimitive> primitives, Key key) { 274 return true; 275 } 276 277 @Override permits(Set<CryptoPrimitive> primitives, String algorithm, Key key, AlgorithmParameters parameters)278 public final boolean permits(Set<CryptoPrimitive> primitives, 279 String algorithm, Key key, AlgorithmParameters parameters) { 280 281 if (algorithm == null || algorithm.isEmpty()) { 282 throw new IllegalArgumentException( 283 "No algorithm name specified"); 284 } 285 286 return permits(primitives, algorithm, parameters); 287 } 288 } 289 } 290