Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java
38830 views
/*1* Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.util;2627import sun.security.validator.Validator;2829import java.io.ByteArrayOutputStream;30import java.io.PrintStream;31import java.security.AlgorithmParameters;32import java.security.CryptoPrimitive;33import java.security.Key;34import java.security.cert.CertPathValidatorException;35import java.security.cert.CertPathValidatorException.BasicReason;36import java.security.interfaces.ECKey;37import java.security.spec.AlgorithmParameterSpec;38import java.security.spec.InvalidParameterSpecException;39import java.security.spec.MGF1ParameterSpec;40import java.security.spec.PSSParameterSpec;41import java.text.SimpleDateFormat;42import java.util.ArrayList;43import java.util.Arrays;44import java.util.Calendar;45import java.util.Date;46import java.util.HashMap;47import java.util.HashSet;48import java.util.List;49import java.util.Locale;50import java.util.Map;51import java.util.Set;52import java.util.Collection;53import java.util.Collections;54import java.util.StringTokenizer;55import java.util.TimeZone;56import java.util.regex.Pattern;57import java.util.regex.Matcher;5859/**60* Algorithm constraints for disabled algorithms property61*62* See the "jdk.certpath.disabledAlgorithms" specification in java.security63* for the syntax of the disabled algorithm string.64*/65public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {66private static final Debug debug = Debug.getInstance("certpath");6768// Disabled algorithm security property for certificate path69public static final String PROPERTY_CERTPATH_DISABLED_ALGS =70"jdk.certpath.disabledAlgorithms";7172// Legacy algorithm security property for certificate path and jar73public static final String PROPERTY_SECURITY_LEGACY_ALGS =74"jdk.security.legacyAlgorithms";7576// Disabled algorithm security property for TLS77public static final String PROPERTY_TLS_DISABLED_ALGS =78"jdk.tls.disabledAlgorithms";7980// Disabled algorithm security property for jar81public static final String PROPERTY_JAR_DISABLED_ALGS =82"jdk.jar.disabledAlgorithms";8384// Property for disabled EC named curves85private static final String PROPERTY_DISABLED_EC_CURVES =86"jdk.disabled.namedCurves";8788private static class CertPathHolder {89static final DisabledAlgorithmConstraints CONSTRAINTS =90new DisabledAlgorithmConstraints(PROPERTY_CERTPATH_DISABLED_ALGS);91}9293private static class JarHolder {94static final DisabledAlgorithmConstraints CONSTRAINTS =95new DisabledAlgorithmConstraints(PROPERTY_JAR_DISABLED_ALGS);96}9798private final List<String> disabledAlgorithms;99private final Constraints algorithmConstraints;100101public static DisabledAlgorithmConstraints certPathConstraints() {102return CertPathHolder.CONSTRAINTS;103}104105public static DisabledAlgorithmConstraints jarConstraints() {106return JarHolder.CONSTRAINTS;107}108109/**110* Initialize algorithm constraints with the specified security property.111*112* @param propertyName the security property name that define the disabled113* algorithm constraints114*/115public DisabledAlgorithmConstraints(String propertyName) {116this(propertyName, new AlgorithmDecomposer());117}118119/**120* Initialize algorithm constraints with the specified security property121* for a specific usage type.122*123* @param propertyName the security property name that define the disabled124* algorithm constraints125* @param decomposer an alternate AlgorithmDecomposer.126*/127public DisabledAlgorithmConstraints(String propertyName,128AlgorithmDecomposer decomposer) {129super(decomposer);130disabledAlgorithms = getAlgorithms(propertyName);131132// Check for alias133int ecindex = -1, i = 0;134for (String s : disabledAlgorithms) {135if (s.regionMatches(true, 0,"include ", 0, 8)) {136if (s.regionMatches(true, 8, PROPERTY_DISABLED_EC_CURVES, 0,137PROPERTY_DISABLED_EC_CURVES.length())) {138ecindex = i;139break;140}141}142i++;143}144if (ecindex > -1) {145disabledAlgorithms.remove(ecindex);146disabledAlgorithms.addAll(ecindex,147getAlgorithms(PROPERTY_DISABLED_EC_CURVES));148}149algorithmConstraints = new Constraints(propertyName, disabledAlgorithms);150}151152/*153* This only checks if the algorithm has been completely disabled. If154* there are keysize or other limit, this method allow the algorithm.155*/156@Override157public final boolean permits(Set<CryptoPrimitive> primitives,158String algorithm, AlgorithmParameters parameters) {159if (!checkAlgorithm(disabledAlgorithms, algorithm, decomposer)) {160return false;161}162163if (parameters != null) {164return algorithmConstraints.permits(algorithm, parameters);165}166167return true;168}169170/*171* Checks if the key algorithm has been disabled or constraints have been172* placed on the key.173*/174@Override175public final boolean permits(Set<CryptoPrimitive> primitives, Key key) {176return checkConstraints(primitives, "", key, null);177}178179/*180* Checks if the key algorithm has been disabled or if constraints have181* been placed on the key.182*/183@Override184public final boolean permits(Set<CryptoPrimitive> primitives,185String algorithm, Key key, AlgorithmParameters parameters) {186187if (algorithm == null || algorithm.length() == 0) {188throw new IllegalArgumentException("No algorithm name specified");189}190191return checkConstraints(primitives, algorithm, key, parameters);192}193194public final void permits(String algorithm, AlgorithmParameters ap,195ConstraintsParameters cp) throws CertPathValidatorException {196197permits(algorithm, cp);198if (ap != null) {199permits(ap, cp);200}201}202203private void permits(AlgorithmParameters ap, ConstraintsParameters cp)204throws CertPathValidatorException {205206switch (ap.getAlgorithm().toUpperCase(Locale.ENGLISH)) {207case "RSASSA-PSS":208permitsPSSParams(ap, cp);209break;210default:211// unknown algorithm, just ignore212}213}214215private void permitsPSSParams(AlgorithmParameters ap,216ConstraintsParameters cp) throws CertPathValidatorException {217218try {219PSSParameterSpec pssParams =220ap.getParameterSpec(PSSParameterSpec.class);221String digestAlg = pssParams.getDigestAlgorithm();222permits(digestAlg, cp);223AlgorithmParameterSpec mgfParams = pssParams.getMGFParameters();224if (mgfParams instanceof MGF1ParameterSpec) {225String mgfDigestAlg =226((MGF1ParameterSpec)mgfParams).getDigestAlgorithm();227if (!mgfDigestAlg.equalsIgnoreCase(digestAlg)) {228permits(mgfDigestAlg, cp);229}230}231} catch (InvalidParameterSpecException ipse) {232// ignore233}234}235236public final void permits(String algorithm, ConstraintsParameters cp)237throws CertPathValidatorException {238239// Check if named curves in the key are disabled.240for (Key key : cp.getKeys()) {241for (String curve : getNamedCurveFromKey(key)) {242if (!checkAlgorithm(disabledAlgorithms, curve, decomposer)) {243throw new CertPathValidatorException(244"Algorithm constraints check failed on disabled " +245"algorithm: " + curve,246null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);247}248}249}250251algorithmConstraints.permits(algorithm, cp);252}253254private static List<String> getNamedCurveFromKey(Key key) {255if (key instanceof ECKey) {256NamedCurve nc = CurveDB.lookup(((ECKey)key).getParams());257return (nc == null ? Collections.emptyList()258: Arrays.asList(CurveDB.getNamesByOID(nc.getObjectId())));259} else {260return Collections.emptyList();261}262}263264// Check algorithm constraints with key and algorithm265private boolean checkConstraints(Set<CryptoPrimitive> primitives,266String algorithm, Key key, AlgorithmParameters parameters) {267268// check the key parameter, it cannot be null.269if (key == null) {270throw new IllegalArgumentException("The key cannot be null");271}272273// check the signature algorithm with parameters274if (algorithm != null && algorithm.length() != 0) {275if (!permits(primitives, algorithm, parameters)) {276return false;277}278}279280// check the key algorithm281if (!permits(primitives, key.getAlgorithm(), null)) {282return false;283}284285// If this is an elliptic curve, check if it is disabled286for (String curve : getNamedCurveFromKey(key)) {287if (!permits(primitives, curve, null)) {288return false;289}290}291292// check the key constraints293return algorithmConstraints.permits(key);294}295296297/**298* Key and Certificate Constraints299*300* The complete disabling of an algorithm is not handled by Constraints or301* Constraint classes. That is addressed with302* permit(Set<CryptoPrimitive>, String, AlgorithmParameters)303*304* When passing a Key to permit(), the boolean return values follow the305* same as the interface class AlgorithmConstraints.permit(). This is to306* maintain compatibility:307* 'true' means the operation is allowed.308* 'false' means it failed the constraints and is disallowed.309*310* When passing ConstraintsParameters through permit(), an exception311* will be thrown on a failure to better identify why the operation was312* disallowed.313*/314315private static class Constraints {316private Map<String, List<Constraint>> constraintsMap = new HashMap<>();317318private static class Holder {319private static final Pattern DENY_AFTER_PATTERN = Pattern.compile(320"denyAfter\\s+(\\d{4})-(\\d{2})-(\\d{2})");321}322323public Constraints(String propertyName, List<String> constraintArray) {324for (String constraintEntry : constraintArray) {325if (constraintEntry == null || constraintEntry.isEmpty()) {326continue;327}328329constraintEntry = constraintEntry.trim();330if (debug != null) {331debug.println("Constraints: " + constraintEntry);332}333334// Check if constraint is a complete disabling of an335// algorithm or has conditions.336int space = constraintEntry.indexOf(' ');337String algorithm = AlgorithmDecomposer.hashName(338((space > 0 ? constraintEntry.substring(0, space) :339constraintEntry)));340List<Constraint> constraintList =341constraintsMap.getOrDefault(342algorithm.toUpperCase(Locale.ENGLISH),343new ArrayList<>(1));344345// Consider the impact of algorithm aliases.346for (String alias : AlgorithmDecomposer.getAliases(algorithm)) {347constraintsMap.putIfAbsent(348alias.toUpperCase(Locale.ENGLISH), constraintList);349}350351// If there is no whitespace, it is a algorithm name; however,352// if there is a whitespace, could be a multi-word EC curve too.353if (space <= 0 || CurveDB.lookup(constraintEntry) != null) {354constraintList.add(new DisabledConstraint(algorithm));355continue;356}357358String policy = constraintEntry.substring(space + 1);359360// Convert constraint conditions into Constraint classes361Constraint c, lastConstraint = null;362// Allow only one jdkCA entry per constraint entry363boolean jdkCALimit = false;364// Allow only one denyAfter entry per constraint entry365boolean denyAfterLimit = false;366367for (String entry : policy.split("&")) {368entry = entry.trim();369370Matcher matcher;371if (entry.startsWith("keySize")) {372if (debug != null) {373debug.println("Constraints set to keySize: " +374entry);375}376StringTokenizer tokens = new StringTokenizer(entry);377if (!"keySize".equals(tokens.nextToken())) {378throw new IllegalArgumentException("Error in " +379"security property. Constraint unknown: " +380entry);381}382c = new KeySizeConstraint(algorithm,383KeySizeConstraint.Operator.of(tokens.nextToken()),384Integer.parseInt(tokens.nextToken()));385386} else if (entry.equalsIgnoreCase("jdkCA")) {387if (debug != null) {388debug.println("Constraints set to jdkCA.");389}390if (jdkCALimit) {391throw new IllegalArgumentException("Only one " +392"jdkCA entry allowed in property. " +393"Constraint: " + constraintEntry);394}395c = new jdkCAConstraint(algorithm);396jdkCALimit = true;397398} else if (entry.startsWith("denyAfter") &&399(matcher = Holder.DENY_AFTER_PATTERN.matcher(entry))400.matches()) {401if (debug != null) {402debug.println("Constraints set to denyAfter");403}404if (denyAfterLimit) {405throw new IllegalArgumentException("Only one " +406"denyAfter entry allowed in property. " +407"Constraint: " + constraintEntry);408}409int year = Integer.parseInt(matcher.group(1));410int month = Integer.parseInt(matcher.group(2));411int day = Integer.parseInt(matcher.group(3));412c = new DenyAfterConstraint(algorithm, year, month,413day);414denyAfterLimit = true;415} else if (entry.startsWith("usage")) {416String s[] = (entry.substring(5)).trim().split(" ");417c = new UsageConstraint(algorithm, s);418if (debug != null) {419debug.println("Constraints usage length is " + s.length);420}421} else {422throw new IllegalArgumentException("Error in security" +423" property. Constraint unknown: " + entry);424}425426// Link multiple conditions for a single constraint427// into a linked list.428if (lastConstraint == null) {429constraintList.add(c);430} else {431lastConstraint.nextConstraint = c;432}433lastConstraint = c;434}435}436}437438// Get applicable constraints based off the algorithm439private List<Constraint> getConstraints(String algorithm) {440return constraintsMap.get(algorithm.toUpperCase(Locale.ENGLISH));441}442443// Check if KeySizeConstraints permit the specified key444public boolean permits(Key key) {445List<Constraint> list = getConstraints(key.getAlgorithm());446if (list == null) {447return true;448}449for (Constraint constraint : list) {450if (!constraint.permits(key)) {451if (debug != null) {452debug.println("Constraints: failed key size" +453"constraint check " + KeyUtil.getKeySize(key));454}455return false;456}457}458return true;459}460461// Check if constraints permit this AlgorithmParameters.462public boolean permits(String algorithm, AlgorithmParameters aps) {463List<Constraint> list = getConstraints(algorithm);464if (list == null) {465return true;466}467468for (Constraint constraint : list) {469if (!constraint.permits(aps)) {470if (debug != null) {471debug.println("Constraints: failed algorithm " +472"parameters constraint check " + aps);473}474475return false;476}477}478479return true;480}481482public void permits(String algorithm, ConstraintsParameters cp)483throws CertPathValidatorException {484485if (debug != null) {486debug.println("Constraints.permits(): " + algorithm + ", "487+ cp.toString());488}489490// Get all signature algorithms to check for constraints491Set<String> algorithms = new HashSet<>();492if (algorithm != null) {493algorithms.addAll(AlgorithmDecomposer.decomposeOneHash(algorithm));494algorithms.add(algorithm);495}496497for (Key key : cp.getKeys()) {498algorithms.add(key.getAlgorithm());499}500501// Check all applicable constraints502for (String alg : algorithms) {503List<Constraint> list = getConstraints(alg);504if (list == null) {505continue;506}507for (Constraint constraint : list) {508constraint.permits(cp);509}510}511}512}513514/**515* This abstract Constraint class for algorithm-based checking516* may contain one or more constraints. If the '&' on the {@Security}517* property is used, multiple constraints have been grouped together518* requiring all the constraints to fail for the check to be disallowed.519*520* If the class contains multiple constraints, the next constraint521* is stored in {@code nextConstraint} in linked-list fashion.522*/523private abstract static class Constraint {524String algorithm;525Constraint nextConstraint = null;526527// operator528enum Operator {529EQ, // "=="530NE, // "!="531LT, // "<"532LE, // "<="533GT, // ">"534GE; // ">="535536static Operator of(String s) {537switch (s) {538case "==":539return EQ;540case "!=":541return NE;542case "<":543return LT;544case "<=":545return LE;546case ">":547return GT;548case ">=":549return GE;550}551552throw new IllegalArgumentException("Error in security " +553"property. " + s + " is not a legal Operator");554}555}556557/**558* Check if an algorithm constraint is permitted with a given key.559*560* If the check inside of {@code permit()} fails, it must call561* {@code next()} with the same {@code Key} parameter passed if562* multiple constraints need to be checked.563*564* @param key Public key565* @return 'true' if constraint is allowed, 'false' if disallowed.566*/567public boolean permits(Key key) {568return true;569}570571/**572* Check if the algorithm constraint permits a given cryptographic573* parameters.574*575* @param parameters the cryptographic parameters576* @return 'true' if the cryptographic parameters is allowed,577* 'false' ortherwise.578*/579public boolean permits(AlgorithmParameters parameters) {580return true;581}582583/**584* Check if an algorithm constraint is permitted with a given585* ConstraintsParameters.586*587* If the check inside of {@code permits()} fails, it must call588* {@code next()} with the same {@code ConstraintsParameters}589* parameter passed if multiple constraints need to be checked.590*591* @param cp ConstraintsParameter containing certificate info592* @throws CertPathValidatorException if constraint disallows.593*594*/595public abstract void permits(ConstraintsParameters cp)596throws CertPathValidatorException;597598/**599* Recursively check if the constraints are allowed.600*601* If {@code nextConstraint} is non-null, this method will602* call {@code nextConstraint}'s {@code permits()} to check if the603* constraint is allowed or denied. If the constraint's604* {@code permits()} is allowed, this method will exit this and any605* recursive next() calls, returning 'true'. If the constraints called606* were disallowed, the last constraint will throw607* {@code CertPathValidatorException}.608*609* @param cp ConstraintsParameters610* @return 'true' if constraint allows the operation, 'false' if611* we are at the end of the constraint list or,612* {@code nextConstraint} is null.613*/614boolean next(ConstraintsParameters cp)615throws CertPathValidatorException {616if (nextConstraint != null) {617nextConstraint.permits(cp);618return true;619}620return false;621}622623/**624* Recursively check if this constraint is allowed,625*626* If {@code nextConstraint} is non-null, this method will627* call {@code nextConstraint}'s {@code permit()} to check if the628* constraint is allowed or denied. If the constraint's629* {@code permit()} is allowed, this method will exit this and any630* recursive next() calls, returning 'true'. If the constraints631* called were disallowed the check will exit with 'false'.632*633* @param key Public key634* @return 'true' if constraint allows the operation, 'false' if635* the constraint denies the operation.636*/637boolean next(Key key) {638return nextConstraint != null && nextConstraint.permits(key);639}640}641642/*643* This class contains constraints dealing with the certificate chain644* of the certificate.645*/646private static class jdkCAConstraint extends Constraint {647jdkCAConstraint(String algo) {648algorithm = algo;649}650651/*652* Check if ConstraintsParameters has a trusted match, if it does653* call next() for any following constraints. If it does not, exit654* as this constraint(s) does not restrict the operation.655*/656@Override657public void permits(ConstraintsParameters cp)658throws CertPathValidatorException {659if (debug != null) {660debug.println("jdkCAConstraints.permits(): " + algorithm);661}662663// Check if any certs chain back to at least one trust anchor in664// cacerts665if (cp.anchorIsJdkCA()) {666if (next(cp)) {667return;668}669throw new CertPathValidatorException(670"Algorithm constraints check failed on certificate " +671"anchor limits. " + algorithm + cp.extendedExceptionMsg(),672null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);673}674}675}676677/*678* This class handles the denyAfter constraint. The date is in the UTC/GMT679* timezone.680*/681private static class DenyAfterConstraint extends Constraint {682private Date denyAfterDate;683private static final SimpleDateFormat dateFormat =684new SimpleDateFormat("EEE, MMM d HH:mm:ss z yyyy");685686DenyAfterConstraint(String algo, int year, int month, int day) {687Calendar c;688689algorithm = algo;690691if (debug != null) {692debug.println("DenyAfterConstraint read in as: year " +693year + ", month = " + month + ", day = " + day);694}695696c = new Calendar.Builder().setTimeZone(TimeZone.getTimeZone("GMT"))697.setDate(year, month - 1, day).build();698699if (year > c.getActualMaximum(Calendar.YEAR) ||700year < c.getActualMinimum(Calendar.YEAR)) {701throw new IllegalArgumentException(702"Invalid year given in constraint: " + year);703}704if ((month - 1) > c.getActualMaximum(Calendar.MONTH) ||705(month - 1) < c.getActualMinimum(Calendar.MONTH)) {706throw new IllegalArgumentException(707"Invalid month given in constraint: " + month);708}709if (day > c.getActualMaximum(Calendar.DAY_OF_MONTH) ||710day < c.getActualMinimum(Calendar.DAY_OF_MONTH)) {711throw new IllegalArgumentException(712"Invalid Day of Month given in constraint: " + day);713}714715denyAfterDate = c.getTime();716if (debug != null) {717debug.println("DenyAfterConstraint date set to: " +718dateFormat.format(denyAfterDate));719}720}721722/*723* Checking that the provided date is not beyond the constraint date.724* The provided date can be the PKIXParameter date if given,725* otherwise it is the current date.726*727* If the constraint disallows, call next() for any following728* constraints. Throw an exception if this is the last constraint.729*/730@Override731public void permits(ConstraintsParameters cp)732throws CertPathValidatorException {733Date currentDate;734String errmsg;735736if (cp.getDate() != null) {737currentDate = cp.getDate();738} else {739currentDate = new Date();740}741742if (!denyAfterDate.after(currentDate)) {743if (next(cp)) {744return;745}746throw new CertPathValidatorException(747"denyAfter constraint check failed: " + algorithm +748" used with Constraint date: " +749dateFormat.format(denyAfterDate) + "; params date: " +750dateFormat.format(currentDate) + cp.extendedExceptionMsg(),751null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);752}753}754755/*756* Return result if the constraint's date is beyond the current date757* in UTC timezone.758*/759@Override760public boolean permits(Key key) {761if (next(key)) {762return true;763}764if (debug != null) {765debug.println("DenyAfterConstraints.permits(): " + algorithm);766}767768return denyAfterDate.after(new Date());769}770}771772/*773* The usage constraint is for the "usage" keyword. It checks against the774* variant value in ConstraintsParameters.775*/776private static class UsageConstraint extends Constraint {777String[] usages;778779UsageConstraint(String algorithm, String[] usages) {780this.algorithm = algorithm;781this.usages = usages;782}783784@Override785public void permits(ConstraintsParameters cp)786throws CertPathValidatorException {787String variant = cp.getVariant();788for (String usage : usages) {789790boolean match = false;791switch (usage.toLowerCase()) {792case "tlsserver":793match = variant.equals(Validator.VAR_TLS_SERVER);794break;795case "tlsclient":796match = variant.equals(Validator.VAR_TLS_CLIENT);797break;798case "signedjar":799match =800variant.equals(Validator.VAR_PLUGIN_CODE_SIGNING) ||801variant.equals(Validator.VAR_CODE_SIGNING) ||802variant.equals(Validator.VAR_TSA_SERVER);803break;804}805806if (debug != null) {807debug.println("Checking if usage constraint \"" + usage +808"\" matches \"" + cp.getVariant() + "\"");809// Because usage checking can come from many places810// a stack trace is very helpful.811ByteArrayOutputStream ba = new ByteArrayOutputStream();812PrintStream ps = new PrintStream(ba);813(new Exception()).printStackTrace(ps);814debug.println(ba.toString());815}816if (match) {817if (next(cp)) {818return;819}820throw new CertPathValidatorException("Usage constraint " +821usage + " check failed: " + algorithm +822cp.extendedExceptionMsg(),823null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);824}825}826}827}828829/*830* This class contains constraints dealing with the key size831* support limits per algorithm. e.g. "keySize <= 1024"832*/833private static class KeySizeConstraint extends Constraint {834835private int minSize; // the minimal available key size836private int maxSize; // the maximal available key size837private int prohibitedSize = -1; // unavailable key sizes838private int size;839840public KeySizeConstraint(String algo, Operator operator, int length) {841algorithm = algo;842switch (operator) {843case EQ: // an unavailable key size844this.minSize = 0;845this.maxSize = Integer.MAX_VALUE;846prohibitedSize = length;847break;848case NE:849this.minSize = length;850this.maxSize = length;851break;852case LT:853this.minSize = length;854this.maxSize = Integer.MAX_VALUE;855break;856case LE:857this.minSize = length + 1;858this.maxSize = Integer.MAX_VALUE;859break;860case GT:861this.minSize = 0;862this.maxSize = length;863break;864case GE:865this.minSize = 0;866this.maxSize = length > 1 ? (length - 1) : 0;867break;868default:869// unlikely to happen870this.minSize = Integer.MAX_VALUE;871this.maxSize = -1;872}873}874875/*876* For each key, check if each constraint fails and check if there is877* a linked constraint. Any permitted constraint will exit the linked878* list to allow the operation.879*/880@Override881public void permits(ConstraintsParameters cp)882throws CertPathValidatorException {883for (Key key : cp.getKeys()) {884if (!permitsImpl(key)) {885if (nextConstraint != null) {886nextConstraint.permits(cp);887continue;888}889throw new CertPathValidatorException(890"Algorithm constraints check failed on keysize limits: " +891algorithm + " " + KeyUtil.getKeySize(key) + " bit key" +892cp.extendedExceptionMsg(),893null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);894}895}896}897898899// Check if key constraint disable the specified key900// Uses old style permit()901@Override902public boolean permits(Key key) {903// If we recursively find a constraint that permits us to use904// this key, return true and skip any other constraint checks.905if (nextConstraint != null && nextConstraint.permits(key)) {906return true;907}908if (debug != null) {909debug.println("KeySizeConstraints.permits(): " + algorithm);910}911912return permitsImpl(key);913}914915@Override916public boolean permits(AlgorithmParameters parameters) {917String paramAlg = parameters.getAlgorithm();918if (!algorithm.equalsIgnoreCase(parameters.getAlgorithm())) {919// Consider the impact of the algorithm aliases.920Collection<String> aliases =921AlgorithmDecomposer.getAliases(algorithm);922if (!aliases.contains(paramAlg)) {923return true;924}925}926927int keySize = KeyUtil.getKeySize(parameters);928if (keySize == 0) {929return false;930} else if (keySize > 0) {931return !((keySize < minSize) || (keySize > maxSize) ||932(prohibitedSize == keySize));933} // Otherwise, the key size is not accessible or determined.934// Conservatively, please don't disable such keys.935936return true;937}938939private boolean permitsImpl(Key key) {940// Verify this constraint is for this public key algorithm941if (algorithm.compareToIgnoreCase(key.getAlgorithm()) != 0) {942return true;943}944945size = KeyUtil.getKeySize(key);946if (size == 0) {947return false; // we don't allow any key of size 0.948} else if (size > 0) {949return !((size < minSize) || (size > maxSize) ||950(prohibitedSize == size));951} // Otherwise, the key size is not accessible. Conservatively,952// please don't disable such keys.953954return true;955}956}957958/*959* This constraint is used for the complete disabling of the algorithm.960*/961private static class DisabledConstraint extends Constraint {962DisabledConstraint(String algo) {963algorithm = algo;964}965966@Override967public void permits(ConstraintsParameters cp)968throws CertPathValidatorException {969throw new CertPathValidatorException(970"Algorithm constraints check failed on disabled " +971"algorithm: " + algorithm + cp.extendedExceptionMsg(),972null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);973}974975@Override976public boolean permits(Key key) {977return false;978}979}980}981982983