< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 2010, 2015, 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.util;
  27 
  28 import java.security.CryptoPrimitive;
  29 import java.security.AlgorithmParameters;
  30 import java.security.Key;
  31 import java.util.Locale;
  32 import java.util.Set;
  33 import java.util.Collections;

  34 import java.util.HashSet;

  35 import java.util.Map;
  36 import java.util.HashMap;
  37 import java.util.regex.Pattern;
  38 import java.util.regex.Matcher;
  39 
  40 /**
  41  * Algorithm constraints for disabled algorithms property
  42  *
  43  * See the "jdk.certpath.disabledAlgorithms" specification in java.security
  44  * for the syntax of the disabled algorithm string.
  45  */
  46 public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {

  47 
  48     // the known security property, jdk.certpath.disabledAlgorithms
  49     public static final String PROPERTY_CERTPATH_DISABLED_ALGS =
  50             "jdk.certpath.disabledAlgorithms";
  51 
  52     // the known security property, jdk.tls.disabledAlgorithms
  53     public static final String PROPERTY_TLS_DISABLED_ALGS =
  54             "jdk.tls.disabledAlgorithms";
  55 
  56     private static final Map<String, String[]> disabledAlgorithmsMap =
  57                                                             new HashMap<>();
  58     private static final Map<String, KeySizeConstraints> keySizeConstraintsMap =
  59                                                             new HashMap<>();
  60 
  61     private final String[] disabledAlgorithms;
  62     private final KeySizeConstraints keySizeConstraints;
  63 
  64     /**
  65      * Initialize algorithm constraints with the specified security property.
  66      *
  67      * @param propertyName the security property name that define the disabled
  68      *        algorithm constraints
  69      */
  70     public DisabledAlgorithmConstraints(String propertyName) {
  71         this(propertyName, new AlgorithmDecomposer());
  72     }
  73 
  74     public DisabledAlgorithmConstraints(String propertyName,
  75             AlgorithmDecomposer decomposer) {
  76         super(decomposer);
  77         disabledAlgorithms = getAlgorithms(disabledAlgorithmsMap, propertyName);
  78         keySizeConstraints = getKeySizeConstraints(disabledAlgorithms,
  79                 propertyName);
  80     }
  81 




  82     @Override
  83     public final boolean permits(Set<CryptoPrimitive> primitives,
  84             String algorithm, AlgorithmParameters parameters) {
  85 
  86         if (primitives == null || primitives.isEmpty()) {
  87             throw new IllegalArgumentException(
  88                         "No cryptographic primitive specified");
  89         }
  90 
  91         return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
  92     }
  93 




  94     @Override
  95     public final boolean permits(Set<CryptoPrimitive> primitives, Key key) {
  96         return checkConstraints(primitives, "", key, null);
  97     }
  98 




  99     @Override
 100     public final boolean permits(Set<CryptoPrimitive> primitives,
 101             String algorithm, Key key, AlgorithmParameters parameters) {
 102 
 103         if (algorithm == null || algorithm.length() == 0) {
 104             throw new IllegalArgumentException("No algorithm name specified");
 105         }
 106 
 107         return checkConstraints(primitives, algorithm, key, parameters);
 108     }
 109 
 110     // Check algorithm constraints
































 111     private boolean checkConstraints(Set<CryptoPrimitive> primitives,
 112             String algorithm, Key key, AlgorithmParameters parameters) {
 113 
 114         // check the key parameter, it cannot be null.
 115         if (key == null) {
 116             throw new IllegalArgumentException("The key cannot be null");
 117         }
 118 
 119         // check the target algorithm
 120         if (algorithm != null && algorithm.length() != 0) {
 121             if (!permits(primitives, algorithm, parameters)) {
 122                 return false;
 123             }
 124         }
 125 
 126         // check the key algorithm
 127         if (!permits(primitives, key.getAlgorithm(), null)) {
 128             return false;
 129         }
 130 
 131         // check the key constraints
 132         if (keySizeConstraints.disables(key)) {
 133             return false;
 134         }
 135 
 136         return true;
 137     }




 138 
 139     private static KeySizeConstraints getKeySizeConstraints(
 140             String[] disabledAlgorithms, String propertyName) {
 141         synchronized (keySizeConstraintsMap) {
 142             if(!keySizeConstraintsMap.containsKey(propertyName)) {
 143                 // map the key constraints
 144                 KeySizeConstraints keySizeConstraints =
 145                         new KeySizeConstraints(disabledAlgorithms);
 146                 keySizeConstraintsMap.put(propertyName, keySizeConstraints);
 147             }
 148 
 149             return keySizeConstraintsMap.get(propertyName);













 150         }




 151     }
 152 
 153     /**
 154      * key constraints














 155      */
 156     private static class KeySizeConstraints {
 157         private static final Pattern pattern = Pattern.compile(
 158                 "(\\S+)\\s+keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
 159 
 160         private Map<String, Set<KeySizeConstraint>> constraintsMap =
 161             Collections.synchronizedMap(
 162                         new HashMap<String, Set<KeySizeConstraint>>());
 163 
 164         public KeySizeConstraints(String[] restrictions) {
 165             for (String restriction : restrictions) {
 166                 if (restriction == null || restriction.isEmpty()) {



















 167                     continue;
 168                 }
 169 
 170                 Matcher matcher = pattern.matcher(restriction);
 171                 if (matcher.matches()) {
 172                     String algorithm = matcher.group(1);
 173 
 174                     KeySizeConstraint.Operator operator =
 175                              KeySizeConstraint.Operator.of(matcher.group(2));
 176                     int length = Integer.parseInt(matcher.group(3));
 177 
 178                     algorithm = algorithm.toLowerCase(Locale.ENGLISH);
 179 
 180                     synchronized (constraintsMap) {





















 181                         if (!constraintsMap.containsKey(algorithm)) {
 182                             constraintsMap.put(algorithm,
 183                                 new HashSet<KeySizeConstraint>());
 184                         }
 185 
 186                         Set<KeySizeConstraint> constraintSet =
 187                             constraintsMap.get(algorithm);
 188                         KeySizeConstraint constraint =
 189                             new KeySizeConstraint(operator, length);
 190                         constraintSet.add(constraint);
 191                     }
 192                 }
 193             }




 194         }
 195 
 196         // Does this KeySizeConstraints disable the specified key?
 197         public boolean disables(Key key) {
 198             String algorithm = key.getAlgorithm().toLowerCase(Locale.ENGLISH);
 199             synchronized (constraintsMap) {
 200                 if (constraintsMap.containsKey(algorithm)) {
 201                     Set<KeySizeConstraint> constraintSet =
 202                                         constraintsMap.get(algorithm);
 203                     for (KeySizeConstraint constraint : constraintSet) {
 204                         if (constraint.disables(key)) {
 205                             return true;
 206                         }





 207                     }

 208                 }
 209             }


 210 
 211             return false;






 212         }






 213     }
 214 
 215     /**
 216      * Key size constraint.
 217      *
 218      * e.g.  "keysize <= 1024"
 219      */
 220     private static class KeySizeConstraint {















 221         // operator
 222         static enum Operator {
 223             EQ,         // "=="
 224             NE,         // "!="
 225             LT,         // "<"
 226             LE,         // "<="
 227             GT,         // ">"
 228             GE;         // ">="
 229 
 230             static Operator of(String s) {
 231                 switch (s) {
 232                     case "==":
 233                         return EQ;
 234                     case "!=":
 235                         return NE;
 236                     case "<":
 237                         return LT;
 238                     case "<=":
 239                         return LE;
 240                     case ">":
 241                         return GT;
 242                     case ">=":
 243                         return GE;
 244                 }
 245 
 246                 throw new IllegalArgumentException(
 247                         s + " is not a legal Operator");






















































 248             }
 249         }
 250 







 251         private int minSize;            // the minimal available key size
 252         private int maxSize;            // the maximal available key size
 253         private int prohibitedSize = -1;    // unavailable key sizes
 254 
 255         public KeySizeConstraint(Operator operator, int length) {

 256             switch (operator) {
 257                 case EQ:      // an unavailable key size
 258                     this.minSize = 0;
 259                     this.maxSize = Integer.MAX_VALUE;
 260                     prohibitedSize = length;
 261                     break;
 262                 case NE:
 263                     this.minSize = length;
 264                     this.maxSize = length;
 265                     break;
 266                 case LT:
 267                     this.minSize = length;
 268                     this.maxSize = Integer.MAX_VALUE;
 269                     break;
 270                 case LE:
 271                     this.minSize = length + 1;
 272                     this.maxSize = Integer.MAX_VALUE;
 273                     break;
 274                 case GT:
 275                     this.minSize = 0;
 276                     this.maxSize = length;
 277                     break;
 278                 case GE:
 279                     this.minSize = 0;
 280                     this.maxSize = length > 1 ? (length - 1) : 0;
 281                     break;
 282                 default:
 283                     // unlikely to happen
 284                     this.minSize = Integer.MAX_VALUE;
 285                     this.maxSize = -1;
 286             }
 287         }
 288 
 289         // Does this key constraint disable the specified key?
 290         public boolean disables(Key key) {
 291             int size = KeyUtil.getKeySize(key);

















 292 






















 293             if (size == 0) {
 294                 return true;    // we don't allow any key of size 0.
 295             } else if (size > 0) {
 296                 return ((size < minSize) || (size > maxSize) ||
 297                     (prohibitedSize == size));
 298             }   // Otherwise, the key size is not accessible. Conservatively,
 299                 // please don't disable such keys.
 300 
 301             return false;
 302         }
 303     }
 304 
 305 }
 306 
   1 /*
   2  * Copyright (c) 2010, 2016, 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.util;
  27 
  28 import java.security.CryptoPrimitive;
  29 import java.security.AlgorithmParameters;
  30 import java.security.Key;
  31 import java.security.cert.CertPathValidatorException;
  32 import java.security.cert.CertPathValidatorException.BasicReason;
  33 import java.security.cert.X509Certificate;
  34 import java.util.HashMap;
  35 import java.util.HashSet;
  36 import java.util.Locale;
  37 import java.util.Map;
  38 import java.util.Set;
  39 import java.util.regex.Pattern;
  40 import java.util.regex.Matcher;
  41 
  42 /**
  43  * Algorithm constraints for disabled algorithms property
  44  *
  45  * See the "jdk.certpath.disabledAlgorithms" specification in java.security
  46  * for the syntax of the disabled algorithm string.
  47  */
  48 public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
  49     private static final Debug debug = Debug.getInstance("certpath");
  50 
  51     // the known security property, jdk.certpath.disabledAlgorithms
  52     public static final String PROPERTY_CERTPATH_DISABLED_ALGS =
  53             "jdk.certpath.disabledAlgorithms";
  54 
  55     // the known security property, jdk.tls.disabledAlgorithms
  56     public static final String PROPERTY_TLS_DISABLED_ALGS =
  57             "jdk.tls.disabledAlgorithms";
  58 





  59     private final String[] disabledAlgorithms;
  60     private final Constraints algorithmConstraints;
  61 
  62     /**
  63      * Initialize algorithm constraints with the specified security property.
  64      *
  65      * @param propertyName the security property name that define the disabled
  66      *        algorithm constraints
  67      */
  68     public DisabledAlgorithmConstraints(String propertyName) {
  69         this(propertyName, new AlgorithmDecomposer());
  70     }
  71 
  72     public DisabledAlgorithmConstraints(String propertyName,
  73             AlgorithmDecomposer decomposer) {
  74         super(decomposer);
  75         disabledAlgorithms = getAlgorithms(propertyName);
  76         algorithmConstraints = new Constraints(disabledAlgorithms);

  77     }
  78 
  79     /*
  80      * This only checks if the algorithm has been completely disabled.  If
  81      * there are keysize or other limit, this method allow the algorithm.
  82      */
  83     @Override
  84     public final boolean permits(Set<CryptoPrimitive> primitives,
  85             String algorithm, AlgorithmParameters parameters) {
  86 
  87         if (primitives == null || primitives.isEmpty()) {
  88             throw new IllegalArgumentException(
  89                         "No cryptographic primitive specified");
  90         }
  91 
  92         return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
  93     }
  94 
  95     /*
  96      * Checks if the key algorithm has been disabled or constraints have been
  97      * placed on the key.
  98      */
  99     @Override
 100     public final boolean permits(Set<CryptoPrimitive> primitives, Key key) {
 101         return checkConstraints(primitives, "", key, null);
 102     }
 103 
 104     /*
 105      * Checks if the key algorithm has been disabled or if constraints have
 106      * been placed on the key.
 107      */
 108     @Override
 109     public final boolean permits(Set<CryptoPrimitive> primitives,
 110             String algorithm, Key key, AlgorithmParameters parameters) {
 111 
 112         if (algorithm == null || algorithm.length() == 0) {
 113             throw new IllegalArgumentException("No algorithm name specified");
 114         }
 115 
 116         return checkConstraints(primitives, algorithm, key, parameters);
 117     }
 118 
 119     /*
 120      * Check if a x509Certificate object is permitted.  Check if all
 121      * algorithms are allowed, certificate constraints, and the
 122      * public key against key constraints.
 123      *
 124      * Uses new style permit() which throws exceptions.
 125      */
 126     public final void permits(Set<CryptoPrimitive> primitives,
 127             CertConstraintParameters cp) throws CertPathValidatorException {
 128         checkConstraints(primitives, cp);
 129     }
 130 
 131     /*
 132      * Check if Certificate object is within the constraints.
 133      * Uses new style permit() which throws exceptions.
 134      */
 135     public final void permits(Set<CryptoPrimitive> primitives,
 136             X509Certificate cert) throws CertPathValidatorException {
 137         checkConstraints(primitives, new CertConstraintParameters(cert));
 138     }
 139 
 140     // Check if a string is contained inside the property
 141     public boolean checkProperty(String param) {
 142         param = param.toLowerCase(Locale.ENGLISH);
 143         for (String block : disabledAlgorithms) {
 144             if (block.toLowerCase(Locale.ENGLISH).indexOf(param) >= 0) {
 145                 return true;
 146             }
 147         }
 148         return false;
 149     }
 150 
 151     // Check algorithm constraints with key and algorithm
 152     private boolean checkConstraints(Set<CryptoPrimitive> primitives,
 153             String algorithm, Key key, AlgorithmParameters parameters) {
 154 
 155         // check the key parameter, it cannot be null.
 156         if (key == null) {
 157             throw new IllegalArgumentException("The key cannot be null");
 158         }
 159 
 160         // check the signature algorithm
 161         if (algorithm != null && algorithm.length() != 0) {
 162             if (!permits(primitives, algorithm, parameters)) {
 163                 return false;
 164             }
 165         }
 166 
 167         // check the key algorithm
 168         if (!permits(primitives, key.getAlgorithm(), null)) {
 169             return false;
 170         }
 171 
 172         // check the key constraints
 173         return algorithmConstraints.permits(key);

 174     }
 175 
 176     /*
 177      * Check algorithm constraints with Certificate
 178      * Uses new style permit() which throws exceptions.
 179      */
 180     private void checkConstraints(Set<CryptoPrimitive> primitives,
 181             CertConstraintParameters cp) throws CertPathValidatorException {
 182 
 183         X509Certificate cert = cp.getCertificate();
 184         String algorithm = cert.getSigAlgName();







 185 
 186         // Check signature algorithm is not disabled
 187         if (!permits(primitives, algorithm, null)) {
 188             throw new CertPathValidatorException(
 189                     "Algorithm constraints check failed on disabled "+
 190                             "signature algorithm: " + algorithm,
 191                     null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 192         }
 193 
 194         // Check key algorithm is not disabled
 195         if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) {
 196             throw new CertPathValidatorException(
 197                     "Algorithm constraints check failed on disabled "+
 198                             "public key algorithm: " + algorithm,
 199                     null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 200         }
 201 
 202         // Check the certificate and key constraints
 203         algorithmConstraints.permits(cp);
 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 CertConstraintParameters 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, Set<Constraint>> constraintsMap = new HashMap<>();
 227         private static final Pattern keySizePattern = Pattern.compile(
 228                 "keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
 229 
 230         public Constraints(String[] constraintArray) {
 231             for (String constraintEntry : constraintArray) {
 232                 if (constraintEntry == null || constraintEntry.isEmpty()) {
 233                     continue;
 234                 }
 235                 constraintEntry = constraintEntry.trim();
 236                 if (debug != null) {
 237                     debug.println("Constraints: " + constraintEntry);
 238                 }
 239 
 240                 // Check if constraint is a complete disabling of an
 241                 // algorithm or has conditions.
 242                 String algorithm;
 243                 String policy;
 244                 int space = constraintEntry.indexOf(' ');
 245                 if (space > 0) {
 246                     algorithm = AlgorithmDecomposer.hashName(
 247                             constraintEntry.substring(0, space).
 248                                     toUpperCase(Locale.ENGLISH));
 249                     policy = constraintEntry.substring(space + 1);
 250                 } else {
 251                     constraintsMap.computeIfAbsent(
 252                             constraintEntry.toUpperCase(Locale.ENGLISH),
 253                             k -> new HashSet<>());
 254                     continue;
 255                 }
 256 
 257                 // Convert constraint conditions into Constraint classes
 258                 Constraint c, lastConstraint = null;
 259                 for (String entry : policy.split("&")) {
 260                     entry = entry.trim();





 261 
 262                     Matcher matcher = keySizePattern.matcher(entry);
 263                     if (matcher.matches()) {
 264                         if (debug != null) {
 265                             debug.println("Constraints set to keySize: " +
 266                                     entry);
 267                         }
 268                         c = new KeySizeConstraint(algorithm,
 269                                 KeySizeConstraint.Operator.of(matcher.group(1)),
 270                                 Integer.parseInt(matcher.group(2)));
 271                     } else if (entry.equalsIgnoreCase("jdkCA")) {
 272                         if (debug != null) {
 273                             debug.println("Constraints set to Cert: " + entry);
 274                         }
 275                         c = new CertConstraint(algorithm);
 276                     } else {
 277                         throw new IllegalArgumentException("Error in security" +
 278                                 " property. Constraint unknown: " + entry);
 279                     }
 280 
 281                     // Link multiple conditions for a single constraint
 282                     // into a linked list.
 283                     if (lastConstraint == null) {
 284                         if (!constraintsMap.containsKey(algorithm)) {
 285                             constraintsMap.putIfAbsent(algorithm,
 286                                     new HashSet<>());
 287                         }
 288                         constraintsMap.get(algorithm).add(c);
 289                     } else {
 290                         lastConstraint.nextConstraint = c;
 291                     }
 292                     lastConstraint = c;

 293                 }
 294             }
 295         }
 296 
 297         // Get applicable constraints based off the signature algorithm
 298         private Set<Constraint> getConstraints(String algorithm) {
 299             return constraintsMap.get(algorithm);
 300         }
 301 
 302         // Check if KeySizeConstraints permit the specified key
 303         public boolean permits(Key key) {
 304             Set<Constraint> set = getConstraints(key.getAlgorithm());
 305             if (set == null) {





 306                 return true;
 307             }
 308             for (Constraint constraint : set) {
 309                 if (!constraint.permits(key)) {
 310                     if (debug != null) {
 311                         debug.println("keySizeConstraint: failed key " +
 312                                 "constraint check " + KeyUtil.getKeySize(key));
 313                     }
 314                     return false;
 315                 }
 316             }
 317             return true;
 318         }
 319 
 320         // Check if constraints permit this cert.
 321         public void permits(CertConstraintParameters cp)
 322                 throws CertPathValidatorException {
 323             X509Certificate cert = cp.getCertificate();
 324 
 325             if (debug != null) {
 326                 debug.println("Constraints.permits(): " + cert.getSigAlgName());
 327             }
 328 
 329             // Get all signature algorithms to check for constraints
 330             Set<String> algorithms =
 331                     AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName());
 332             if (algorithms == null || algorithms.isEmpty()) {
 333                 return;
 334             }
 335 
 336             // Attempt to add the public key algorithm to the set
 337             algorithms.add(cert.getPublicKey().getAlgorithm());
 338 
 339             // Check all applicable constraints
 340             for (String algorithm : algorithms) {
 341                 Set<Constraint> set = getConstraints(algorithm);
 342                 if (set == null) {
 343                     continue;
 344                 }
 345                 for (Constraint constraint : set) {
 346                     constraint.permits(cp);
 347                 }
 348             }
 349         }
 350     }
 351 
 352     // Abstract class for algorithm constraint checking
 353     private abstract static class Constraint {
 354         String algorithm;
 355         Constraint nextConstraint = null;
 356 
 357         // operator
 358         enum Operator {
 359             EQ,         // "=="
 360             NE,         // "!="
 361             LT,         // "<"
 362             LE,         // "<="
 363             GT,         // ">"
 364             GE;         // ">="
 365 
 366             static Operator of(String s) {
 367                 switch (s) {
 368                     case "==":
 369                         return EQ;
 370                     case "!=":
 371                         return NE;
 372                     case "<":
 373                         return LT;
 374                     case "<=":
 375                         return LE;
 376                     case ">":
 377                         return GT;
 378                     case ">=":
 379                         return GE;
 380                 }
 381 
 382                 throw new IllegalArgumentException("Error in security " +
 383                         "property. " + s + " is not a legal Operator");
 384             }
 385         }
 386 
 387         /**
 388          * Check if an algorithm constraint permit this key to be used.
 389          * @param key Public key
 390          * @return true if constraints do not match
 391          */
 392         public boolean permits(Key key) {
 393             return true;
 394         }
 395 
 396         /**
 397          * Check if an algorithm constraint is permit this certificate to
 398          * be used.
 399          * @param cp CertificateParameter containing certificate and state info
 400          * @return true if constraints do not match
 401          */
 402         public abstract void permits(CertConstraintParameters cp)
 403                 throws CertPathValidatorException;
 404     }
 405 
 406     /*
 407      * This class contains constraints dealing with the certificate chain
 408      * of the certificate.
 409      */
 410     private static class CertConstraint extends Constraint {
 411 
 412         CertConstraint(String algo) {
 413             algorithm = algo;
 414         }
 415 
 416         /*
 417          * Check if each constraint fails and check if there is a linked
 418          * constraint  Any permitted constraint will exit the linked list
 419          * to allow the operation.
 420          */
 421         public void permits(CertConstraintParameters cp)
 422                 throws CertPathValidatorException {
 423             if (debug != null) {
 424                 debug.println("CertConstraints.permits(): " + algorithm);
 425             }
 426 
 427             // Return false if the chain has a cacerts trust anchor.
 428             if (cp.isTrustedMatch()) {
 429                 if (nextConstraint != null) {
 430                     nextConstraint.permits(cp);
 431                     return;
 432                 }
 433                 throw new CertPathValidatorException(
 434                         "Algorithm constraints check failed on certificate " +
 435                                 "anchor limits",
 436                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 437             }
 438         }
 439     }
 440 
 441 
 442     /*
 443      * This class contains constraints dealing with the key size
 444      * support limits per algorithm.   e.g.  "keySize <= 1024"
 445      */
 446     private static class KeySizeConstraint extends Constraint {
 447 
 448         private int minSize;            // the minimal available key size
 449         private int maxSize;            // the maximal available key size
 450         private int prohibitedSize = -1;    // unavailable key sizes
 451 
 452         public KeySizeConstraint(String algo, Operator operator, int length) {
 453             algorithm = algo;
 454             switch (operator) {
 455                 case EQ:      // an unavailable key size
 456                     this.minSize = 0;
 457                     this.maxSize = Integer.MAX_VALUE;
 458                     prohibitedSize = length;
 459                     break;
 460                 case NE:
 461                     this.minSize = length;
 462                     this.maxSize = length;
 463                     break;
 464                 case LT:
 465                     this.minSize = length;
 466                     this.maxSize = Integer.MAX_VALUE;
 467                     break;
 468                 case LE:
 469                     this.minSize = length + 1;
 470                     this.maxSize = Integer.MAX_VALUE;
 471                     break;
 472                 case GT:
 473                     this.minSize = 0;
 474                     this.maxSize = length;
 475                     break;
 476                 case GE:
 477                     this.minSize = 0;
 478                     this.maxSize = length > 1 ? (length - 1) : 0;
 479                     break;
 480                 default:
 481                     // unlikely to happen
 482                     this.minSize = Integer.MAX_VALUE;
 483                     this.maxSize = -1;
 484             }
 485         }
 486 
 487         /*
 488          * If we are passed a certificate, extract the public key and use it.
 489          *
 490          * Check if each constraint fails and check if there is a linked
 491          * constraint  Any permitted constraint will exit the linked list
 492          * to allow the operation.
 493          */
 494         public void permits(CertConstraintParameters cp)
 495                 throws CertPathValidatorException {
 496             if (!permitsImpl(cp.getCertificate().getPublicKey())) {
 497                 if (nextConstraint != null) {
 498                     nextConstraint.permits(cp);
 499                     return;
 500                 }
 501                 throw new CertPathValidatorException(
 502                         "Algorithm constraints check failed on keysize limits",
 503                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 504             }
 505         }
 506 
 507 
 508         // Check if key constraint disable the specified key
 509         // Uses old style permit()
 510         public boolean permits(Key key) {
 511             // If we recursively find a constraint that permits us to use
 512             // this key, return true and skip any other constraint checks.
 513             if (nextConstraint != null && nextConstraint.permits(key)) {
 514                 return true;
 515             }
 516             if (debug != null) {
 517                 debug.println("KeySizeConstraints.permits(): " + algorithm);
 518             }
 519 
 520             return permitsImpl(key);
 521         }
 522 
 523         private boolean permitsImpl(Key key) {
 524             // Verify this constraint is for this public key algorithm
 525             if (algorithm.compareToIgnoreCase(key.getAlgorithm()) != 0) {
 526                 return true;
 527             }
 528 
 529             int size = KeyUtil.getKeySize(key);
 530             if (size == 0) {
 531                 return false;    // we don't allow any key of size 0.
 532             } else if (size > 0) {
 533                 return !((size < minSize) || (size > maxSize) ||
 534                     (prohibitedSize == size));
 535             }   // Otherwise, the key size is not accessible. Conservatively,
 536                 // please don't disable such keys.
 537 
 538             return true;
 539         }
 540     }

 541 }
 542 
< prev index next >