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