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