1 /*
2 * Copyright (c) 2010, 2017, 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
43 import java.util.HashSet;
44 import java.util.List;
45 import java.util.Locale;
46 import java.util.Map;
47 import java.util.Set;
48 import java.util.Collection;
49 import java.util.StringTokenizer;
50 import java.util.TimeZone;
51 import java.util.regex.Pattern;
52 import java.util.regex.Matcher;
53
54 /**
55 * Algorithm constraints for disabled algorithms property
56 *
57 * See the "jdk.certpath.disabledAlgorithms" specification in java.security
58 * for the syntax of the disabled algorithm string.
59 */
60 public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
61 private static final Debug debug = Debug.getInstance("certpath");
62
63 // the known security property, jdk.certpath.disabledAlgorithms
64 public static final String PROPERTY_CERTPATH_DISABLED_ALGS =
65 "jdk.certpath.disabledAlgorithms";
66
67 // the known security property, jdk.tls.disabledAlgorithms
68 public static final String PROPERTY_TLS_DISABLED_ALGS =
69 "jdk.tls.disabledAlgorithms";
70
71 // the known security property, jdk.jar.disabledAlgorithms
72 public static final String PROPERTY_JAR_DISABLED_ALGS =
73 "jdk.jar.disabledAlgorithms";
74
75 private final String[] disabledAlgorithms;
76 private final Constraints algorithmConstraints;
77
78 /**
79 * Initialize algorithm constraints with the specified security property.
80 *
81 * @param propertyName the security property name that define the disabled
82 * algorithm constraints
83 */
84 public DisabledAlgorithmConstraints(String propertyName) {
85 this(propertyName, new AlgorithmDecomposer());
86 }
87
88 /**
89 * Initialize algorithm constraints with the specified security property
90 * for a specific usage type.
91 *
92 * @param propertyName the security property name that define the disabled
93 * algorithm constraints
94 * @param decomposer an alternate AlgorithmDecomposer.
95 */
96 public DisabledAlgorithmConstraints(String propertyName,
97 AlgorithmDecomposer decomposer) {
98 super(decomposer);
99 disabledAlgorithms = getAlgorithms(propertyName);
100 algorithmConstraints = new Constraints(disabledAlgorithms);
101 }
102
103 /*
104 * This only checks if the algorithm has been completely disabled. If
105 * there are keysize or other limit, this method allow the algorithm.
106 */
107 @Override
108 public final boolean permits(Set<CryptoPrimitive> primitives,
109 String algorithm, AlgorithmParameters parameters) {
110 if (!checkAlgorithm(disabledAlgorithms, algorithm, decomposer)) {
111 return false;
112 }
113
114 if (parameters != null) {
115 return algorithmConstraints.permits(algorithm, parameters);
116 }
117
118 return true;
119 }
147 permits(cp.getAlgorithm(), cp);
148 }
149
150 public final void permits(String algorithm, Key key,
151 AlgorithmParameters params, String variant)
152 throws CertPathValidatorException {
153 permits(algorithm, new ConstraintsParameters(algorithm, params, key,
154 (variant == null) ? Validator.VAR_GENERIC : variant));
155 }
156
157 /*
158 * Check if a x509Certificate object is permitted. Check if all
159 * algorithms are allowed, certificate constraints, and the
160 * public key against key constraints.
161 *
162 * Uses new style permit() which throws exceptions.
163 */
164
165 public final void permits(String algorithm, ConstraintsParameters cp)
166 throws CertPathValidatorException {
167 algorithmConstraints.permits(algorithm, cp);
168 }
169
170 // Check if a string is contained inside the property
171 public boolean checkProperty(String param) {
172 param = param.toLowerCase(Locale.ENGLISH);
173 for (String block : disabledAlgorithms) {
174 if (block.toLowerCase(Locale.ENGLISH).indexOf(param) >= 0) {
175 return true;
176 }
177 }
178 return false;
179 }
180
181 // Check algorithm constraints with key and algorithm
182 private boolean checkConstraints(Set<CryptoPrimitive> primitives,
183 String algorithm, Key key, AlgorithmParameters parameters) {
184
185 // check the key parameter, it cannot be null.
186 if (key == null) {
187 throw new IllegalArgumentException("The key cannot be null");
188 }
189
190 // check the signature algorithm with parameters
191 if (algorithm != null && algorithm.length() != 0) {
192 if (!permits(primitives, algorithm, parameters)) {
193 return false;
194 }
195 }
196
197 // check the key algorithm
198 if (!permits(primitives, key.getAlgorithm(), null)) {
199 return false;
200 }
201
202 // check the key constraints
203 return algorithmConstraints.permits(key);
204 }
205
206
207 /**
208 * Key and Certificate Constraints
209 *
210 * The complete disabling of an algorithm is not handled by Constraints or
211 * Constraint classes. That is addressed with
212 * permit(Set<CryptoPrimitive>, String, AlgorithmParameters)
213 *
214 * When passing a Key to permit(), the boolean return values follow the
215 * same as the interface class AlgorithmConstraints.permit(). This is to
216 * maintain compatibility:
217 * 'true' means the operation is allowed.
218 * 'false' means it failed the constraints and is disallowed.
219 *
220 * When passing ConstraintsParameters through permit(), an exception
221 * will be thrown on a failure to better identify why the operation was
222 * disallowed.
223 */
224
225 private static class Constraints {
226 private Map<String, List<Constraint>> constraintsMap = new HashMap<>();
227
228 private static class Holder {
229 private static final Pattern DENY_AFTER_PATTERN = Pattern.compile(
230 "denyAfter\\s+(\\d{4})-(\\d{2})-(\\d{2})");
231 }
232
233 public Constraints(String[] constraintArray) {
234 for (String constraintEntry : constraintArray) {
235 if (constraintEntry == null || constraintEntry.isEmpty()) {
236 continue;
237 }
238
239 constraintEntry = constraintEntry.trim();
240 if (debug != null) {
241 debug.println("Constraints: " + constraintEntry);
242 }
243
244 // Check if constraint is a complete disabling of an
245 // algorithm or has conditions.
246 int space = constraintEntry.indexOf(' ');
247 String algorithm = AlgorithmDecomposer.hashName(
248 ((space > 0 ? constraintEntry.substring(0, space) :
249 constraintEntry)));
250 List<Constraint> constraintList =
251 constraintsMap.getOrDefault(
252 algorithm.toUpperCase(Locale.ENGLISH),
253 new ArrayList<>(1));
254
255 // Consider the impact of algorithm aliases.
256 for (String alias : AlgorithmDecomposer.getAliases(algorithm)) {
257 constraintsMap.putIfAbsent(
258 alias.toUpperCase(Locale.ENGLISH), constraintList);
259 }
260
261 if (space <= 0) {
262 constraintList.add(new DisabledConstraint(algorithm));
263 continue;
264 }
265
266 String policy = constraintEntry.substring(space + 1);
267
268 // Convert constraint conditions into Constraint classes
269 Constraint c, lastConstraint = null;
270 // Allow only one jdkCA entry per constraint entry
271 boolean jdkCALimit = false;
272 // Allow only one denyAfter entry per constraint entry
273 boolean denyAfterLimit = false;
274
275 for (String entry : policy.split("&")) {
276 entry = entry.trim();
277
278 Matcher matcher;
279 if (entry.startsWith("keySize")) {
280 if (debug != null) {
281 debug.println("Constraints set to keySize: " +
340 }
341 lastConstraint = c;
342 }
343 }
344 }
345
346 // Get applicable constraints based off the signature algorithm
347 private List<Constraint> getConstraints(String algorithm) {
348 return constraintsMap.get(algorithm.toUpperCase(Locale.ENGLISH));
349 }
350
351 // Check if KeySizeConstraints permit the specified key
352 public boolean permits(Key key) {
353 List<Constraint> list = getConstraints(key.getAlgorithm());
354 if (list == null) {
355 return true;
356 }
357 for (Constraint constraint : list) {
358 if (!constraint.permits(key)) {
359 if (debug != null) {
360 debug.println("keySizeConstraint: failed key " +
361 "constraint check " + KeyUtil.getKeySize(key));
362 }
363 return false;
364 }
365 }
366 return true;
367 }
368
369 // Check if constraints permit this AlgorithmParameters.
370 public boolean permits(String algorithm, AlgorithmParameters aps) {
371 List<Constraint> list = getConstraints(algorithm);
372 if (list == null) {
373 return true;
374 }
375
376 for (Constraint constraint : list) {
377 if (!constraint.permits(aps)) {
378 if (debug != null) {
379 debug.println("keySizeConstraint: failed algorithm " +
380 "parameters constraint check " + aps);
381 }
382
383 return false;
384 }
385 }
386
387 return true;
388 }
389
390 // Check if constraints permit this cert.
391 public void permits(String algorithm, ConstraintsParameters cp)
392 throws CertPathValidatorException {
393 X509Certificate cert = cp.getCertificate();
394
395 if (debug != null) {
396 debug.println("Constraints.permits(): " + algorithm +
397 " Variant: " + cp.getVariant());
398 }
399
400 // Get all signature algorithms to check for constraints
401 Set<String> algorithms = new HashSet<>();
402 if (algorithm != null) {
403 algorithms.addAll(AlgorithmDecomposer.decomposeOneHash(algorithm));
404 algorithms.add(algorithm);
405 }
406
407 // Attempt to add the public key algorithm if cert provided
408 if (cert != null) {
409 algorithms.add(cert.getPublicKey().getAlgorithm());
410 }
411 if (cp.getPublicKey() != null) {
412 algorithms.add(cp.getPublicKey().getAlgorithm());
413 }
414 // Check all applicable constraints
415 for (String alg : algorithms) {
416 List<Constraint> list = getConstraints(alg);
417 if (list == null) {
418 continue;
419 }
420 for (Constraint constraint : list) {
421 constraint.permits(cp);
422 }
423 }
424 }
425 }
426
427 /**
428 * This abstract Constraint class for algorithm-based checking
429 * may contain one or more constraints. If the '&' on the {@Security}
430 * property is used, multiple constraints have been grouped together
431 * requiring all the constraints to fail for the check to be disallowed.
432 *
531 return true;
532 }
533 return false;
534 }
535
536 /**
537 * Recursively check if this constraint is allowed,
538 *
539 * If {@code nextConstraint} is non-null, this method will
540 * call {@code nextConstraint}'s {@code permit()} to check if the
541 * constraint is allowed or denied. If the constraint's
542 * {@code permit()} is allowed, this method will exit this and any
543 * recursive next() calls, returning 'true'. If the constraints
544 * called were disallowed the check will exit with 'false'.
545 *
546 * @param key Public key
547 * @return 'true' if constraint allows the operation, 'false' if
548 * the constraint denies the operation.
549 */
550 boolean next(Key key) {
551 if (nextConstraint != null && nextConstraint.permits(key)) {
552 return true;
553 }
554 return false;
555 }
556
557 String extendedMsg(ConstraintsParameters cp) {
558 return (cp.getCertificate() == null ? "." :
559 " used with certificate: " +
560 cp.getCertificate().getSubjectX500Principal() +
561 (cp.getVariant() != Validator.VAR_GENERIC ?
562 ". Usage was " + cp.getVariant() : "."));
563 }
564 }
565
566 /*
567 * This class contains constraints dealing with the certificate chain
568 * of the certificate.
569 */
570 private static class jdkCAConstraint extends Constraint {
571 jdkCAConstraint(String algo) {
572 algorithm = algo;
573 }
574
786 this.maxSize = length > 1 ? (length - 1) : 0;
787 break;
788 default:
789 // unlikely to happen
790 this.minSize = Integer.MAX_VALUE;
791 this.maxSize = -1;
792 }
793 }
794
795 /*
796 * If we are passed a certificate, extract the public key and use it.
797 *
798 * Check if each constraint fails and check if there is a linked
799 * constraint Any permitted constraint will exit the linked list
800 * to allow the operation.
801 */
802 @Override
803 public void permits(ConstraintsParameters cp)
804 throws CertPathValidatorException {
805 Key key = null;
806 if (cp.getPublicKey() != null) {
807 key = cp.getPublicKey();
808 } else if (cp.getCertificate() != null) {
809 key = cp.getCertificate().getPublicKey();
810 }
811 if (key != null && !permitsImpl(key)) {
812 if (nextConstraint != null) {
813 nextConstraint.permits(cp);
814 return;
815 }
816 throw new CertPathValidatorException(
817 "Algorithm constraints check failed on keysize limits. " +
818 algorithm + " " + KeyUtil.getKeySize(key) + "bit key" +
819 extendedMsg(cp),
820 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
821 }
822 }
823
824
825 // Check if key constraint disable the specified key
826 // Uses old style permit()
827 @Override
|
1 /*
2 * Copyright (c) 2010, 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
43 import java.util.HashSet;
44 import java.util.List;
45 import java.util.Locale;
46 import java.util.Map;
47 import java.util.Set;
48 import java.util.Collection;
49 import java.util.StringTokenizer;
50 import java.util.TimeZone;
51 import java.util.regex.Pattern;
52 import java.util.regex.Matcher;
53
54 /**
55 * Algorithm constraints for disabled algorithms property
56 *
57 * See the "jdk.certpath.disabledAlgorithms" specification in java.security
58 * for the syntax of the disabled algorithm string.
59 */
60 public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
61 private static final Debug debug = Debug.getInstance("certpath");
62
63 // Disabled algorithm security property for certificate path
64 public static final String PROPERTY_CERTPATH_DISABLED_ALGS =
65 "jdk.certpath.disabledAlgorithms";
66
67 // Disabled algorithm security property for TLS
68 public static final String PROPERTY_TLS_DISABLED_ALGS =
69 "jdk.tls.disabledAlgorithms";
70
71 // Disabled algorithm security property for jar
72 public static final String PROPERTY_JAR_DISABLED_ALGS =
73 "jdk.jar.disabledAlgorithms";
74
75 // Property for disabled EC named curves
76 private static final String PROPERTY_DISABLED_EC_CURVES =
77 "jdk.disabled.namedCurves";
78
79 private final List<String> disabledAlgorithms;
80 private final Constraints algorithmConstraints;
81
82 /**
83 * Initialize algorithm constraints with the specified security property.
84 *
85 * @param propertyName the security property name that define the disabled
86 * algorithm constraints
87 */
88 public DisabledAlgorithmConstraints(String propertyName) {
89 this(propertyName, new AlgorithmDecomposer());
90 }
91
92 /**
93 * Initialize algorithm constraints with the specified security property
94 * for a specific usage type.
95 *
96 * @param propertyName the security property name that define the disabled
97 * algorithm constraints
98 * @param decomposer an alternate AlgorithmDecomposer.
99 */
100 public DisabledAlgorithmConstraints(String propertyName,
101 AlgorithmDecomposer decomposer) {
102 super(decomposer);
103 disabledAlgorithms = getAlgorithms(propertyName);
104
105 // Check for alias
106 int ecindex = -1, i = 0;
107 for (String s : disabledAlgorithms) {
108 if (s.regionMatches(true, 0,"include ", 0, 8)) {
109 if (s.regionMatches(true, 8, PROPERTY_DISABLED_EC_CURVES, 0,
110 PROPERTY_DISABLED_EC_CURVES.length())) {
111 ecindex = i;
112 break;
113 }
114 }
115 i++;
116 }
117 if (ecindex > -1) {
118 disabledAlgorithms.remove(ecindex);
119 disabledAlgorithms.addAll(ecindex,
120 getAlgorithms(PROPERTY_DISABLED_EC_CURVES));
121 }
122 algorithmConstraints = new Constraints(disabledAlgorithms);
123 }
124
125 /*
126 * This only checks if the algorithm has been completely disabled. If
127 * there are keysize or other limit, this method allow the algorithm.
128 */
129 @Override
130 public final boolean permits(Set<CryptoPrimitive> primitives,
131 String algorithm, AlgorithmParameters parameters) {
132 if (!checkAlgorithm(disabledAlgorithms, algorithm, decomposer)) {
133 return false;
134 }
135
136 if (parameters != null) {
137 return algorithmConstraints.permits(algorithm, parameters);
138 }
139
140 return true;
141 }
169 permits(cp.getAlgorithm(), cp);
170 }
171
172 public final void permits(String algorithm, Key key,
173 AlgorithmParameters params, String variant)
174 throws CertPathValidatorException {
175 permits(algorithm, new ConstraintsParameters(algorithm, params, key,
176 (variant == null) ? Validator.VAR_GENERIC : variant));
177 }
178
179 /*
180 * Check if a x509Certificate object is permitted. Check if all
181 * algorithms are allowed, certificate constraints, and the
182 * public key against key constraints.
183 *
184 * Uses new style permit() which throws exceptions.
185 */
186
187 public final void permits(String algorithm, ConstraintsParameters cp)
188 throws CertPathValidatorException {
189
190 // Check if named curves in the ConstraintParameters are disabled.
191 if (cp.getNamedCurve() != null) {
192 for (String curve : cp.getNamedCurve()) {
193 if (!checkAlgorithm(disabledAlgorithms, curve, decomposer)) {
194 throw new CertPathValidatorException(
195 "Algorithm constraints check failed on disabled " +
196 "algorithm: " + curve,
197 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
198 }
199 }
200 }
201
202 algorithmConstraints.permits(algorithm, cp);
203 }
204
205 // Check if a string is contained inside the property
206 public boolean checkProperty(String param) {
207 param = param.toLowerCase(Locale.ENGLISH);
208 for (String block : disabledAlgorithms) {
209 if (block.toLowerCase(Locale.ENGLISH).indexOf(param) >= 0) {
210 return true;
211 }
212 }
213 return false;
214 }
215
216 // Check algorithm constraints with key and algorithm
217 private boolean checkConstraints(Set<CryptoPrimitive> primitives,
218 String algorithm, Key key, AlgorithmParameters parameters) {
219
220 // check the key parameter, it cannot be null.
221 if (key == null) {
222 throw new IllegalArgumentException("The key cannot be null");
223 }
224
225 // check the signature algorithm with parameters
226 if (algorithm != null && algorithm.length() != 0) {
227 if (!permits(primitives, algorithm, parameters)) {
228 return false;
229 }
230 }
231
232 // check the key algorithm
233 if (!permits(primitives, key.getAlgorithm(), null)) {
234 return false;
235 }
236
237 // If this is an elliptic curve, check disabled the named curve.
238 for (String curve : ConstraintsParameters.getNamedCurveFromKey(key)) {
239 if (!permits(primitives, curve, null)) {
240 return false;
241 }
242 }
243
244 // check the key constraints
245 return algorithmConstraints.permits(key);
246 }
247
248
249 /**
250 * Key and Certificate Constraints
251 *
252 * The complete disabling of an algorithm is not handled by Constraints or
253 * Constraint classes. That is addressed with
254 * permit(Set<CryptoPrimitive>, String, AlgorithmParameters)
255 *
256 * When passing a Key to permit(), the boolean return values follow the
257 * same as the interface class AlgorithmConstraints.permit(). This is to
258 * maintain compatibility:
259 * 'true' means the operation is allowed.
260 * 'false' means it failed the constraints and is disallowed.
261 *
262 * When passing ConstraintsParameters through permit(), an exception
263 * will be thrown on a failure to better identify why the operation was
264 * disallowed.
265 */
266
267 private static class Constraints {
268 private Map<String, List<Constraint>> constraintsMap = new HashMap<>();
269
270 private static class Holder {
271 private static final Pattern DENY_AFTER_PATTERN = Pattern.compile(
272 "denyAfter\\s+(\\d{4})-(\\d{2})-(\\d{2})");
273 }
274
275 public Constraints(List<String> constraintArray) {
276 for (String constraintEntry : constraintArray) {
277 if (constraintEntry == null || constraintEntry.isEmpty()) {
278 continue;
279 }
280
281 constraintEntry = constraintEntry.trim();
282 if (debug != null) {
283 debug.println("Constraints: " + constraintEntry);
284 }
285
286 // Check if constraint is a complete disabling of an
287 // algorithm or has conditions.
288 int space = constraintEntry.indexOf(' ');
289 String algorithm = AlgorithmDecomposer.hashName(
290 ((space > 0 ? constraintEntry.substring(0, space) :
291 constraintEntry)));
292 List<Constraint> constraintList =
293 constraintsMap.getOrDefault(
294 algorithm.toUpperCase(Locale.ENGLISH),
295 new ArrayList<>(1));
296
297 // Consider the impact of algorithm aliases.
298 for (String alias : AlgorithmDecomposer.getAliases(algorithm)) {
299 constraintsMap.putIfAbsent(
300 alias.toUpperCase(Locale.ENGLISH), constraintList);
301 }
302
303 // If there is no whitespace, it is a algorithm name; however,
304 // if there is a whitespace, could be a multi-word EC curve too.
305 if (space <= 0 || CurveDB.lookup(constraintEntry) != null) {
306 constraintList.add(new DisabledConstraint(algorithm));
307 continue;
308 }
309
310 String policy = constraintEntry.substring(space + 1);
311
312 // Convert constraint conditions into Constraint classes
313 Constraint c, lastConstraint = null;
314 // Allow only one jdkCA entry per constraint entry
315 boolean jdkCALimit = false;
316 // Allow only one denyAfter entry per constraint entry
317 boolean denyAfterLimit = false;
318
319 for (String entry : policy.split("&")) {
320 entry = entry.trim();
321
322 Matcher matcher;
323 if (entry.startsWith("keySize")) {
324 if (debug != null) {
325 debug.println("Constraints set to keySize: " +
384 }
385 lastConstraint = c;
386 }
387 }
388 }
389
390 // Get applicable constraints based off the signature algorithm
391 private List<Constraint> getConstraints(String algorithm) {
392 return constraintsMap.get(algorithm.toUpperCase(Locale.ENGLISH));
393 }
394
395 // Check if KeySizeConstraints permit the specified key
396 public boolean permits(Key key) {
397 List<Constraint> list = getConstraints(key.getAlgorithm());
398 if (list == null) {
399 return true;
400 }
401 for (Constraint constraint : list) {
402 if (!constraint.permits(key)) {
403 if (debug != null) {
404 debug.println("Constraints: failed key size" +
405 "constraint check " + KeyUtil.getKeySize(key));
406 }
407 return false;
408 }
409 }
410 return true;
411 }
412
413 // Check if constraints permit this AlgorithmParameters.
414 public boolean permits(String algorithm, AlgorithmParameters aps) {
415 List<Constraint> list = getConstraints(algorithm);
416 if (list == null) {
417 return true;
418 }
419
420 for (Constraint constraint : list) {
421 if (!constraint.permits(aps)) {
422 if (debug != null) {
423 debug.println("Constraints: failed algorithm " +
424 "parameters constraint check " + aps);
425 }
426
427 return false;
428 }
429 }
430
431 return true;
432 }
433
434 // Check if constraints permit this cert.
435 public void permits(String algorithm, ConstraintsParameters cp)
436 throws CertPathValidatorException {
437 X509Certificate cert = cp.getCertificate();
438
439 if (debug != null) {
440 debug.println("Constraints.permits(): " + cp.toString());
441 }
442
443 // Get all signature algorithms to check for constraints
444 Set<String> algorithms = new HashSet<>();
445 if (algorithm != null) {
446 algorithms.addAll(AlgorithmDecomposer.decomposeOneHash(algorithm));
447 algorithms.add(algorithm);
448 }
449
450 // Attempt to add the public key algorithm if cert provided
451 if (cert != null) {
452 algorithms.add(cert.getPublicKey().getAlgorithm());
453 }
454 if (cp.getKey() != null) {
455 algorithms.add(cp.getKey().getAlgorithm());
456 }
457 // Check all applicable constraints
458 for (String alg : algorithms) {
459 List<Constraint> list = getConstraints(alg);
460 if (list == null) {
461 continue;
462 }
463 for (Constraint constraint : list) {
464 constraint.permits(cp);
465 }
466 }
467 }
468 }
469
470 /**
471 * This abstract Constraint class for algorithm-based checking
472 * may contain one or more constraints. If the '&' on the {@Security}
473 * property is used, multiple constraints have been grouped together
474 * requiring all the constraints to fail for the check to be disallowed.
475 *
574 return true;
575 }
576 return false;
577 }
578
579 /**
580 * Recursively check if this constraint is allowed,
581 *
582 * If {@code nextConstraint} is non-null, this method will
583 * call {@code nextConstraint}'s {@code permit()} to check if the
584 * constraint is allowed or denied. If the constraint's
585 * {@code permit()} is allowed, this method will exit this and any
586 * recursive next() calls, returning 'true'. If the constraints
587 * called were disallowed the check will exit with 'false'.
588 *
589 * @param key Public key
590 * @return 'true' if constraint allows the operation, 'false' if
591 * the constraint denies the operation.
592 */
593 boolean next(Key key) {
594 return nextConstraint != null && nextConstraint.permits(key);
595 }
596
597 String extendedMsg(ConstraintsParameters cp) {
598 return (cp.getCertificate() == null ? "." :
599 " used with certificate: " +
600 cp.getCertificate().getSubjectX500Principal() +
601 (cp.getVariant() != Validator.VAR_GENERIC ?
602 ". Usage was " + cp.getVariant() : "."));
603 }
604 }
605
606 /*
607 * This class contains constraints dealing with the certificate chain
608 * of the certificate.
609 */
610 private static class jdkCAConstraint extends Constraint {
611 jdkCAConstraint(String algo) {
612 algorithm = algo;
613 }
614
826 this.maxSize = length > 1 ? (length - 1) : 0;
827 break;
828 default:
829 // unlikely to happen
830 this.minSize = Integer.MAX_VALUE;
831 this.maxSize = -1;
832 }
833 }
834
835 /*
836 * If we are passed a certificate, extract the public key and use it.
837 *
838 * Check if each constraint fails and check if there is a linked
839 * constraint Any permitted constraint will exit the linked list
840 * to allow the operation.
841 */
842 @Override
843 public void permits(ConstraintsParameters cp)
844 throws CertPathValidatorException {
845 Key key = null;
846 if (cp.getKey() != null) {
847 key = cp.getKey();
848 } else if (cp.getCertificate() != null) {
849 key = cp.getCertificate().getPublicKey();
850 }
851 if (key != null && !permitsImpl(key)) {
852 if (nextConstraint != null) {
853 nextConstraint.permits(cp);
854 return;
855 }
856 throw new CertPathValidatorException(
857 "Algorithm constraints check failed on keysize limits. " +
858 algorithm + " " + KeyUtil.getKeySize(key) + "bit key" +
859 extendedMsg(cp),
860 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
861 }
862 }
863
864
865 // Check if key constraint disable the specified key
866 // Uses old style permit()
867 @Override
|