< prev index next >

src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 23,43 **** --- 23,54 ---- * questions. */ package sun.security.util; + import sun.security.validator.Validator; + + import java.io.ByteArrayOutputStream; + import java.io.PrintStream; import java.security.CryptoPrimitive; import java.security.AlgorithmParameters; import java.security.Key; import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException.BasicReason; import java.security.cert.X509Certificate; + import java.text.SimpleDateFormat; + import java.util.ArrayList; + import java.util.Calendar; + import java.util.Date; import java.util.HashMap; import java.util.HashSet; + import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; + import java.util.StringTokenizer; + import java.util.TimeZone; import java.util.regex.Pattern; import java.util.regex.Matcher; /** * Algorithm constraints for disabled algorithms property
*** 47,61 **** */ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { private static final Debug debug = Debug.getInstance("certpath"); // the known security property, jdk.certpath.disabledAlgorithms ! public final static String PROPERTY_CERTPATH_DISABLED_ALGS = "jdk.certpath.disabledAlgorithms"; // the known security property, jdk.tls.disabledAlgorithms ! public final static String PROPERTY_TLS_DISABLED_ALGS = "jdk.tls.disabledAlgorithms"; // the known security property, jdk.jar.disabledAlgorithms public static final String PROPERTY_JAR_DISABLED_ALGS = "jdk.jar.disabledAlgorithms"; --- 58,72 ---- */ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { private static final Debug debug = Debug.getInstance("certpath"); // the known security property, jdk.certpath.disabledAlgorithms ! public static final String PROPERTY_CERTPATH_DISABLED_ALGS = "jdk.certpath.disabledAlgorithms"; // the known security property, jdk.tls.disabledAlgorithms ! public static final String PROPERTY_TLS_DISABLED_ALGS = "jdk.tls.disabledAlgorithms"; // the known security property, jdk.jar.disabledAlgorithms public static final String PROPERTY_JAR_DISABLED_ALGS = "jdk.jar.disabledAlgorithms";
*** 91,154 **** /* * This only checks if the algorithm has been completely disabled. If * there are keysize or other limit, this method allow the algorithm. */ @Override ! final public boolean permits(Set<CryptoPrimitive> primitives, String algorithm, AlgorithmParameters parameters) { - - if (primitives == null || primitives.isEmpty()) { - throw new IllegalArgumentException( - "No cryptographic primitive specified"); - } - return checkAlgorithm(disabledAlgorithms, algorithm, decomposer); } /* * Checks if the key algorithm has been disabled or constraints have been * placed on the key. */ @Override ! final public boolean permits(Set<CryptoPrimitive> primitives, Key key) { return checkConstraints(primitives, "", key, null); } /* * Checks if the key algorithm has been disabled or if constraints have * been placed on the key. */ @Override ! final public boolean permits(Set<CryptoPrimitive> primitives, String algorithm, Key key, AlgorithmParameters parameters) { if (algorithm == null || algorithm.length() == 0) { throw new IllegalArgumentException("No algorithm name specified"); } return checkConstraints(primitives, algorithm, key, parameters); } /* * Check if a x509Certificate object is permitted. Check if all * algorithms are allowed, certificate constraints, and the * public key against key constraints. * * Uses new style permit() which throws exceptions. */ - public final void permits(Set<CryptoPrimitive> primitives, - CertConstraintParameters cp) throws CertPathValidatorException { - checkConstraints(primitives, cp); - } ! /* ! * Check if Certificate object is within the constraints. ! * Uses new style permit() which throws exceptions. ! */ ! public final void permits(Set<CryptoPrimitive> primitives, ! X509Certificate cert) throws CertPathValidatorException { ! checkConstraints(primitives, new CertConstraintParameters(cert)); } // Check if a string is contained inside the property public boolean checkProperty(String param) { param = param.toLowerCase(Locale.ENGLISH); --- 102,163 ---- /* * This only checks if the algorithm has been completely disabled. If * there are keysize or other limit, this method allow the algorithm. */ @Override ! public final boolean permits(Set<CryptoPrimitive> primitives, String algorithm, AlgorithmParameters parameters) { return checkAlgorithm(disabledAlgorithms, algorithm, decomposer); } /* * Checks if the key algorithm has been disabled or constraints have been * placed on the key. */ @Override ! public final boolean permits(Set<CryptoPrimitive> primitives, Key key) { return checkConstraints(primitives, "", key, null); } /* * Checks if the key algorithm has been disabled or if constraints have * been placed on the key. */ @Override ! public final boolean permits(Set<CryptoPrimitive> primitives, String algorithm, Key key, AlgorithmParameters parameters) { if (algorithm == null || algorithm.length() == 0) { throw new IllegalArgumentException("No algorithm name specified"); } return checkConstraints(primitives, algorithm, key, parameters); } + public final void permits(ConstraintsParameters cp) + throws CertPathValidatorException { + permits(cp.getAlgorithm(), cp); + } + + public final void permits(String algorithm, Key key, + AlgorithmParameters params, String variant) + throws CertPathValidatorException { + permits(algorithm, new ConstraintsParameters(algorithm, params, key, + (variant == null) ? Validator.VAR_GENERIC : variant)); + } + /* * Check if a x509Certificate object is permitted. Check if all * algorithms are allowed, certificate constraints, and the * public key against key constraints. * * Uses new style permit() which throws exceptions. */ ! public final void permits(String algorithm, ConstraintsParameters cp) ! throws CertPathValidatorException { ! algorithmConstraints.permits(algorithm, cp); } // Check if a string is contained inside the property public boolean checkProperty(String param) { param = param.toLowerCase(Locale.ENGLISH);
*** 167,177 **** // check the key parameter, it cannot be null. if (key == null) { throw new IllegalArgumentException("The key cannot be null"); } ! // check the signature algorithm if (algorithm != null && algorithm.length() != 0) { if (!permits(primitives, algorithm, parameters)) { return false; } } --- 176,186 ---- // check the key parameter, it cannot be null. if (key == null) { throw new IllegalArgumentException("The key cannot be null"); } ! // check the signature algorithm with parameters if (algorithm != null && algorithm.length() != 0) { if (!permits(primitives, algorithm, parameters)) { return false; } }
*** 183,222 **** // check the key constraints return algorithmConstraints.permits(key); } - /* - * Check algorithm constraints with Certificate - * Uses new style permit() which throws exceptions. - */ - private void checkConstraints(Set<CryptoPrimitive> primitives, - CertConstraintParameters cp) throws CertPathValidatorException { - - X509Certificate cert = cp.getCertificate(); - String algorithm = cert.getSigAlgName(); - - // Check signature algorithm is not disabled - if (!permits(primitives, algorithm, null)) { - throw new CertPathValidatorException( - "Algorithm constraints check failed on disabled "+ - "signature algorithm: " + algorithm, - null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); - } - - // Check key algorithm is not disabled - if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) { - throw new CertPathValidatorException( - "Algorithm constraints check failed on disabled "+ - "public key algorithm: " + algorithm, - null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); - } - - // Check the certificate and key constraints - algorithmConstraints.permits(cp); - - } /** * Key and Certificate Constraints * * The complete disabling of an algorithm is not handled by Constraints or --- 192,201 ----
*** 227,245 **** * same as the interface class AlgorithmConstraints.permit(). This is to * maintain compatibility: * 'true' means the operation is allowed. * 'false' means it failed the constraints and is disallowed. * ! * When passing CertConstraintParameters through permit(), an exception * will be thrown on a failure to better identify why the operation was * disallowed. */ private static class Constraints { ! private Map<String, Set<Constraint>> constraintsMap = new HashMap<>(); ! private static final Pattern keySizePattern = Pattern.compile( ! "keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)"); public Constraints(String[] constraintArray) { for (String constraintEntry : constraintArray) { if (constraintEntry == null || constraintEntry.isEmpty()) { continue; --- 206,227 ---- * same as the interface class AlgorithmConstraints.permit(). This is to * maintain compatibility: * 'true' means the operation is allowed. * 'false' means it failed the constraints and is disallowed. * ! * When passing ConstraintsParameters through permit(), an exception * will be thrown on a failure to better identify why the operation was * disallowed. */ private static class Constraints { ! private Map<String, List<Constraint>> constraintsMap = new HashMap<>(); ! ! private static class Holder { ! private static final Pattern DENY_AFTER_PATTERN = Pattern.compile( ! "denyAfter\\s+(\\d{4})-(\\d{2})-(\\d{2})"); ! } public Constraints(String[] constraintArray) { for (String constraintEntry : constraintArray) { if (constraintEntry == null || constraintEntry.isEmpty()) { continue;
*** 250,292 **** debug.println("Constraints: " + constraintEntry); } // Check if constraint is a complete disabling of an // algorithm or has conditions. - String algorithm; - String policy; int space = constraintEntry.indexOf(' '); ! if (space > 0) { ! algorithm = AlgorithmDecomposer.hashName( ! constraintEntry.substring(0, space). ! toUpperCase(Locale.ENGLISH)); ! policy = constraintEntry.substring(space + 1); ! } else { ! constraintsMap.putIfAbsent( ! constraintEntry.toUpperCase(Locale.ENGLISH), ! new HashSet<>()); continue; } // Convert constraint conditions into Constraint classes ! Constraint c = null; ! Constraint lastConstraint = null; // Allow only one jdkCA entry per constraint entry boolean jdkCALimit = false; for (String entry : policy.split("&")) { entry = entry.trim(); ! Matcher matcher = keySizePattern.matcher(entry); ! if (matcher.matches()) { if (debug != null) { debug.println("Constraints set to keySize: " + entry); } c = new KeySizeConstraint(algorithm, ! KeySizeConstraint.Operator.of(matcher.group(1)), ! Integer.parseInt(matcher.group(2))); } else if (entry.equalsIgnoreCase("jdkCA")) { if (debug != null) { debug.println("Constraints set to jdkCA."); } --- 232,282 ---- debug.println("Constraints: " + constraintEntry); } // Check if constraint is a complete disabling of an // algorithm or has conditions. int space = constraintEntry.indexOf(' '); ! String algorithm = AlgorithmDecomposer.hashName( ! ((space > 0 ? constraintEntry.substring(0, space) : ! constraintEntry). ! toUpperCase(Locale.ENGLISH))); ! List<Constraint> constraintList = ! constraintsMap.getOrDefault(algorithm, ! new ArrayList<>(1)); ! constraintsMap.putIfAbsent(algorithm, constraintList); ! if (space <= 0) { ! constraintList.add(new DisabledConstraint(algorithm)); continue; } + String policy = constraintEntry.substring(space + 1); + // Convert constraint conditions into Constraint classes ! Constraint c, lastConstraint = null; // Allow only one jdkCA entry per constraint entry boolean jdkCALimit = false; + // Allow only one denyAfter entry per constraint entry + boolean denyAfterLimit = false; for (String entry : policy.split("&")) { entry = entry.trim(); ! Matcher matcher; ! if (entry.startsWith("keySize")) { if (debug != null) { debug.println("Constraints set to keySize: " + entry); } + StringTokenizer tokens = new StringTokenizer(entry); + if (!"keySize".equals(tokens.nextToken())) { + throw new IllegalArgumentException("Error in " + + "security property. Constraint unknown: " + + entry); + } c = new KeySizeConstraint(algorithm, ! KeySizeConstraint.Operator.of(tokens.nextToken()), ! Integer.parseInt(tokens.nextToken())); } else if (entry.equalsIgnoreCase("jdkCA")) { if (debug != null) { debug.println("Constraints set to jdkCA."); }
*** 295,336 **** "jdkCA entry allowed in property. " + "Constraint: " + constraintEntry); } c = new jdkCAConstraint(algorithm); jdkCALimit = true; } // Link multiple conditions for a single constraint // into a linked list. if (lastConstraint == null) { ! if (!constraintsMap.containsKey(algorithm)) { ! constraintsMap.putIfAbsent(algorithm, ! new HashSet<>()); ! } ! if (c != null) { ! constraintsMap.get(algorithm).add(c); ! } } else { lastConstraint.nextConstraint = c; } lastConstraint = c; } } } // Get applicable constraints based off the signature algorithm ! private Set<Constraint> getConstraints(String algorithm) { return constraintsMap.get(algorithm); } // Check if KeySizeConstraints permit the specified key public boolean permits(Key key) { ! Set<Constraint> set = getConstraints(key.getAlgorithm()); ! if (set == null) { return true; } ! for (Constraint constraint : set) { if (!constraint.permits(key)) { if (debug != null) { debug.println("keySizeConstraint: failed key " + "constraint check " + KeyUtil.getKeySize(key)); } --- 285,347 ---- "jdkCA entry allowed in property. " + "Constraint: " + constraintEntry); } c = new jdkCAConstraint(algorithm); jdkCALimit = true; + + } else if (entry.startsWith("denyAfter") && + (matcher = Holder.DENY_AFTER_PATTERN.matcher(entry)) + .matches()) { + if (debug != null) { + debug.println("Constraints set to denyAfter"); + } + if (denyAfterLimit) { + throw new IllegalArgumentException("Only one " + + "denyAfter entry allowed in property. " + + "Constraint: " + constraintEntry); + } + int year = Integer.parseInt(matcher.group(1)); + int month = Integer.parseInt(matcher.group(2)); + int day = Integer.parseInt(matcher.group(3)); + c = new DenyAfterConstraint(algorithm, year, month, + day); + denyAfterLimit = true; + } else if (entry.startsWith("usage")) { + String s[] = (entry.substring(5)).trim().split(" "); + c = new UsageConstraint(algorithm, s); + if (debug != null) { + debug.println("Constraints usage length is " + s.length); + } + } else { + throw new IllegalArgumentException("Error in security" + + " property. Constraint unknown: " + entry); } // Link multiple conditions for a single constraint // into a linked list. if (lastConstraint == null) { ! constraintList.add(c); } else { lastConstraint.nextConstraint = c; } lastConstraint = c; } } } // Get applicable constraints based off the signature algorithm ! private List<Constraint> getConstraints(String algorithm) { return constraintsMap.get(algorithm); } // Check if KeySizeConstraints permit the specified key public boolean permits(Key key) { ! List<Constraint> list = getConstraints(key.getAlgorithm()); ! if (list == null) { return true; } ! for (Constraint constraint : list) { if (!constraint.permits(key)) { if (debug != null) { debug.println("keySizeConstraint: failed key " + "constraint check " + KeyUtil.getKeySize(key)); }
*** 339,380 **** } return true; } // Check if constraints permit this cert. ! public void permits(CertConstraintParameters cp) throws CertPathValidatorException { X509Certificate cert = cp.getCertificate(); if (debug != null) { ! debug.println("Constraints.permits(): " + cert.getSigAlgName()); } // Get all signature algorithms to check for constraints ! Set<String> algorithms = ! AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName()); ! if (algorithms == null || algorithms.isEmpty()) { ! return; } ! // Attempt to add the public key algorithm to the set algorithms.add(cert.getPublicKey().getAlgorithm()); ! // Check all applicable constraints ! for (String algorithm : algorithms) { ! Set<Constraint> set = getConstraints(algorithm); ! if (set == null) { continue; } ! for (Constraint constraint : set) { constraint.permits(cp); } } } } ! // Abstract class for algorithm constraint checking private abstract static class Constraint { String algorithm; Constraint nextConstraint = null; // operator --- 350,403 ---- } return true; } // Check if constraints permit this cert. ! public void permits(String algorithm, ConstraintsParameters cp) throws CertPathValidatorException { X509Certificate cert = cp.getCertificate(); if (debug != null) { ! debug.println("Constraints.permits(): " + algorithm + ! " Variant: " + cp.getVariant()); } // Get all signature algorithms to check for constraints ! Set<String> algorithms = new HashSet<>(); ! if (algorithm != null) { ! algorithms.addAll(AlgorithmDecomposer.decomposeOneHash(algorithm)); } ! // Attempt to add the public key algorithm if cert provided ! if (cert != null) { algorithms.add(cert.getPublicKey().getAlgorithm()); ! } ! if (cp.getPublicKey() != null) { ! algorithms.add(cp.getPublicKey().getAlgorithm()); ! } // Check all applicable constraints ! for (String alg : algorithms) { ! List<Constraint> list = getConstraints(alg); ! if (list == null) { continue; } ! for (Constraint constraint : list) { constraint.permits(cp); } } } } ! /** ! * This abstract Constraint class for algorithm-based checking ! * may contain one or more constraints. If the '&' on the {@Security} ! * property is used, multiple constraints have been grouped together ! * requiring all the constraints to fail for the check to be disallowed. ! * ! * If the class contains multiple constraints, the next constraint ! * is stored in {@code nextConstraint} in linked-list fashion. ! */ private abstract static class Constraint { String algorithm; Constraint nextConstraint = null; // operator
*** 406,431 **** "property. " + s + " is not a legal Operator"); } } /** ! * Check if an algorithm constraint permit this key to be used. * @param key Public key ! * @return true if constraints do not match */ public boolean permits(Key key) { return true; } /** ! * Check if an algorithm constraint is permit this certificate to ! * be used. ! * @param cp CertificateParameter containing certificate and state info ! * @return true if constraints do not match */ ! public abstract void permits(CertConstraintParameters cp) throws CertPathValidatorException; } /* * This class contains constraints dealing with the certificate chain * of the certificate. --- 429,519 ---- "property. " + s + " is not a legal Operator"); } } /** ! * Check if an algorithm constraint is permitted with a given key. ! * ! * If the check inside of {@code permit()} fails, it must call ! * {@code next()} with the same {@code Key} parameter passed if ! * multiple constraints need to be checked. ! * * @param key Public key ! * @return 'true' if constraint is allowed, 'false' if disallowed. */ public boolean permits(Key key) { return true; } /** ! * Check if an algorithm constraint is permitted with a given ! * ConstraintsParameters. ! * ! * If the check inside of {@code permits()} fails, it must call ! * {@code next()} with the same {@code ConstraintsParameters} ! * parameter passed if multiple constraints need to be checked. ! * ! * @param cp CertConstraintParameter containing certificate info ! * @throws CertPathValidatorException if constraint disallows. ! * */ ! public abstract void permits(ConstraintsParameters cp) throws CertPathValidatorException; + + /** + * Recursively check if the constraints are allowed. + * + * If {@code nextConstraint} is non-null, this method will + * call {@code nextConstraint}'s {@code permits()} to check if the + * constraint is allowed or denied. If the constraint's + * {@code permits()} is allowed, this method will exit this and any + * recursive next() calls, returning 'true'. If the constraints called + * were disallowed, the last constraint will throw + * {@code CertPathValidatorException}. + * + * @param cp ConstraintsParameters + * @return 'true' if constraint allows the operation, 'false' if + * we are at the end of the constraint list or, + * {@code nextConstraint} is null. + */ + boolean next(ConstraintsParameters cp) + throws CertPathValidatorException { + if (nextConstraint != null) { + nextConstraint.permits(cp); + return true; + } + return false; + } + + /** + * Recursively check if this constraint is allowed, + * + * If {@code nextConstraint} is non-null, this method will + * call {@code nextConstraint}'s {@code permit()} to check if the + * constraint is allowed or denied. If the constraint's + * {@code permit()} is allowed, this method will exit this and any + * recursive next() calls, returning 'true'. If the constraints + * called were disallowed the check will exit with 'false'. + * + * @param key Public key + * @return 'true' if constraint allows the operation, 'false' if + * the constraint denies the operation. + */ + boolean next(Key key) { + if (nextConstraint != null && nextConstraint.permits(key)) { + return true; + } + return false; + } + + String extendedMsg(ConstraintsParameters cp) { + return (cp.getCertificate() == null ? "." : + " used with certificate: " + + cp.getCertificate().getSubjectX500Principal() + + (cp.getVariant() != Validator.VAR_GENERIC ? + ". Usage was " + cp.getVariant() : ".")); + } } /* * This class contains constraints dealing with the certificate chain * of the certificate.
*** 434,477 **** jdkCAConstraint(String algo) { algorithm = algo; } /* ! * Check if each constraint fails and check if there is a linked ! * constraint Any permitted constraint will exit the linked list ! * to allow the operation. */ ! public void permits(CertConstraintParameters cp) throws CertPathValidatorException { if (debug != null) { debug.println("jdkCAConstraints.permits(): " + algorithm); } ! // Return false if the chain has a trust anchor in cacerts if (cp.isTrustedMatch()) { ! if (nextConstraint != null) { ! nextConstraint.permits(cp); return; } throw new CertPathValidatorException( "Algorithm constraints check failed on certificate " + ! "anchor limits", null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } } } /* * This class contains constraints dealing with the key size * support limits per algorithm. e.g. "keySize <= 1024" */ private static class KeySizeConstraint extends Constraint { private int minSize; // the minimal available key size private int maxSize; // the maximal available key size private int prohibitedSize = -1; // unavailable key sizes public KeySizeConstraint(String algo, Operator operator, int length) { algorithm = algo; switch (operator) { case EQ: // an unavailable key size --- 522,711 ---- jdkCAConstraint(String algo) { algorithm = algo; } /* ! * Check if ConstraintsParameters has a trusted match, if it does ! * call next() for any following constraints. If it does not, exit ! * as this constraint(s) does not restrict the operation. */ ! public void permits(ConstraintsParameters cp) throws CertPathValidatorException { if (debug != null) { debug.println("jdkCAConstraints.permits(): " + algorithm); } ! // Check chain has a trust anchor in cacerts if (cp.isTrustedMatch()) { ! if (next(cp)) { return; } throw new CertPathValidatorException( "Algorithm constraints check failed on certificate " + ! "anchor limits. " + algorithm + extendedMsg(cp), ! null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); ! } ! } ! } ! ! /* ! * This class handles the denyAfter constraint. The date is in the UTC/GMT ! * timezone. ! */ ! private static class DenyAfterConstraint extends Constraint { ! private Date denyAfterDate; ! private static final SimpleDateFormat dateFormat = ! new SimpleDateFormat("EEE, MMM d HH:mm:ss z yyyy"); ! ! DenyAfterConstraint(String algo, int year, int month, int day) { ! Calendar c; ! ! algorithm = algo; ! ! if (debug != null) { ! debug.println("DenyAfterConstraint read in as: year " + ! year + ", month = " + month + ", day = " + day); ! } ! ! c = new Calendar.Builder().setTimeZone(TimeZone.getTimeZone("GMT")) ! .setDate(year, month - 1, day).build(); ! ! if (year > c.getActualMaximum(Calendar.YEAR) || ! year < c.getActualMinimum(Calendar.YEAR)) { ! throw new IllegalArgumentException( ! "Invalid year given in constraint: " + year); ! } ! if ((month - 1) > c.getActualMaximum(Calendar.MONTH) || ! (month - 1) < c.getActualMinimum(Calendar.MONTH)) { ! throw new IllegalArgumentException( ! "Invalid month given in constraint: " + month); ! } ! if (day > c.getActualMaximum(Calendar.DAY_OF_MONTH) || ! day < c.getActualMinimum(Calendar.DAY_OF_MONTH)) { ! throw new IllegalArgumentException( ! "Invalid Day of Month given in constraint: " + day); ! } ! ! denyAfterDate = c.getTime(); ! if (debug != null) { ! debug.println("DenyAfterConstraint date set to: " + ! dateFormat.format(denyAfterDate)); ! } ! } ! ! /* ! * Checking that the provided date is not beyond the constraint date. ! * The provided date can be the PKIXParameter date if given, ! * otherwise it is the current date. ! * ! * If the constraint disallows, call next() for any following ! * constraints. Throw an exception if this is the last constraint. ! */ ! @Override ! public void permits(ConstraintsParameters cp) ! throws CertPathValidatorException { ! Date currentDate; ! String errmsg; ! ! if (cp.getJARTimestamp() != null) { ! currentDate = cp.getJARTimestamp().getTimestamp(); ! errmsg = "JAR Timestamp date: "; ! } else if (cp.getPKIXParamDate() != null) { ! currentDate = cp.getPKIXParamDate(); ! errmsg = "PKIXParameter date: "; ! } else { ! currentDate = new Date(); ! errmsg = "Current date: "; ! } ! ! if (!denyAfterDate.after(currentDate)) { ! if (next(cp)) { ! return; ! } ! throw new CertPathValidatorException( ! "denyAfter constraint check failed: " + algorithm + ! " used with Constraint date: " + ! dateFormat.format(denyAfterDate) + "; " + errmsg + ! dateFormat.format(currentDate) + extendedMsg(cp), null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } } + + /* + * Return result if the constraint's date is beyond the current date + * in UTC timezone. + */ + public boolean permits(Key key) { + if (next(key)) { + return true; + } + if (debug != null) { + debug.println("DenyAfterConstraints.permits(): " + algorithm); } + return denyAfterDate.after(new Date()); + } + } + + /* + * The usage constraint is for the "usage" keyword. It checks against the + * variant value in ConstraintsParameters. + */ + private static class UsageConstraint extends Constraint { + String[] usages; + + UsageConstraint(String algorithm, String[] usages) { + this.algorithm = algorithm; + this.usages = usages; + } + + public void permits(ConstraintsParameters cp) + throws CertPathValidatorException { + for (String usage : usages) { + + String v = null; + if (usage.compareToIgnoreCase("TLSServer") == 0) { + v = Validator.VAR_TLS_SERVER; + } else if (usage.compareToIgnoreCase("TLSClient") == 0) { + v = Validator.VAR_TLS_CLIENT; + } else if (usage.compareToIgnoreCase("SignedJAR") == 0) { + v = Validator.VAR_PLUGIN_CODE_SIGNING; + } + + if (debug != null) { + debug.println("Checking if usage constraint \"" + v + + "\" matches \"" + cp.getVariant() + "\""); + // Because usage checking can come from many places + // a stack trace is very helpful. + ByteArrayOutputStream ba = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(ba); + (new Exception()).printStackTrace(ps); + debug.println(ba.toString()); + } + if (cp.getVariant().compareTo(v) == 0) { + if (next(cp)) { + return; + } + throw new CertPathValidatorException("Usage constraint " + + usage + " check failed: " + algorithm + + extendedMsg(cp), + null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); + } + } + } + } /* * This class contains constraints dealing with the key size * support limits per algorithm. e.g. "keySize <= 1024" */ private static class KeySizeConstraint extends Constraint { private int minSize; // the minimal available key size private int maxSize; // the maximal available key size private int prohibitedSize = -1; // unavailable key sizes + private int size; public KeySizeConstraint(String algo, Operator operator, int length) { algorithm = algo; switch (operator) { case EQ: // an unavailable key size
*** 511,529 **** * * Check if each constraint fails and check if there is a linked * constraint Any permitted constraint will exit the linked list * to allow the operation. */ ! public void permits(CertConstraintParameters cp) throws CertPathValidatorException { ! if (!permitsImpl(cp.getCertificate().getPublicKey())) { if (nextConstraint != null) { nextConstraint.permits(cp); return; } throw new CertPathValidatorException( ! "Algorithm constraints check failed on keysize limits", null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } } --- 745,770 ---- * * Check if each constraint fails and check if there is a linked * constraint Any permitted constraint will exit the linked list * to allow the operation. */ ! public void permits(ConstraintsParameters cp) throws CertPathValidatorException { ! Key key = null; ! if (cp.getPublicKey() != null) { ! key = cp.getPublicKey(); ! } else if (cp.getCertificate() != null) { ! key = cp.getCertificate().getPublicKey(); ! } ! if (key != null && !permitsImpl(key)) { if (nextConstraint != null) { nextConstraint.permits(cp); return; } throw new CertPathValidatorException( ! "Algorithm constraints check failed on keysize limits. " ! + algorithm + " " + size + "bit key" + extendedMsg(cp), null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } }
*** 546,556 **** // Verify this constraint is for this public key algorithm if (algorithm.compareToIgnoreCase(key.getAlgorithm()) != 0) { return true; } ! int size = KeyUtil.getKeySize(key); if (size == 0) { return false; // we don't allow any key of size 0. } else if (size > 0) { return !((size < minSize) || (size > maxSize) || (prohibitedSize == size)); --- 787,797 ---- // Verify this constraint is for this public key algorithm if (algorithm.compareToIgnoreCase(key.getAlgorithm()) != 0) { return true; } ! size = KeyUtil.getKeySize(key); if (size == 0) { return false; // we don't allow any key of size 0. } else if (size > 0) { return !((size < minSize) || (size > maxSize) || (prohibitedSize == size));
*** 558,564 **** --- 799,826 ---- // please don't disable such keys. return true; } } + + /* + * This constraint is used for the complete disabling of the algorithm. + */ + private static class DisabledConstraint extends Constraint { + DisabledConstraint(String algo) { + algorithm = algo; + } + + public void permits(ConstraintsParameters cp) + throws CertPathValidatorException { + throw new CertPathValidatorException( + "Algorithm constraints check failed on disabled " + + "algorithm: " + algorithm + extendedMsg(cp), + null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); + } + + public boolean permits(Key key) { + return false; + } } + }
< prev index next >