jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java
changeset 43701 fe8c324ba97c
parent 41956 69deb06bb8f1
child 44158 49deb8a1ed3f
equal deleted inserted replaced
43700:ee6b5bd26bf9 43701:fe8c324ba97c
     1 /*
     1 /*
     2  * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package sun.security.util;
    26 package sun.security.util;
    27 
    27 
       
    28 import sun.security.validator.Validator;
       
    29 
    28 import java.security.CryptoPrimitive;
    30 import java.security.CryptoPrimitive;
    29 import java.security.AlgorithmParameters;
    31 import java.security.AlgorithmParameters;
    30 import java.security.Key;
    32 import java.security.Key;
    31 import java.security.cert.CertPathValidatorException;
    33 import java.security.cert.CertPathValidatorException;
    32 import java.security.cert.CertPathValidatorException.BasicReason;
    34 import java.security.cert.CertPathValidatorException.BasicReason;
    33 import java.security.cert.X509Certificate;
    35 import java.security.cert.X509Certificate;
    34 import java.text.SimpleDateFormat;
    36 import java.text.SimpleDateFormat;
       
    37 import java.util.ArrayList;
    35 import java.util.Calendar;
    38 import java.util.Calendar;
    36 import java.util.Date;
    39 import java.util.Date;
    37 import java.util.HashMap;
    40 import java.util.HashMap;
    38 import java.util.HashSet;
    41 import java.util.HashSet;
       
    42 import java.util.List;
    39 import java.util.Locale;
    43 import java.util.Locale;
    40 import java.util.Map;
    44 import java.util.Map;
    41 import java.util.Set;
    45 import java.util.Set;
    42 import java.util.StringTokenizer;
    46 import java.util.StringTokenizer;
    43 import java.util.TimeZone;
    47 import java.util.TimeZone;
    98      * there are keysize or other limit, this method allow the algorithm.
   102      * there are keysize or other limit, this method allow the algorithm.
    99      */
   103      */
   100     @Override
   104     @Override
   101     public final boolean permits(Set<CryptoPrimitive> primitives,
   105     public final boolean permits(Set<CryptoPrimitive> primitives,
   102             String algorithm, AlgorithmParameters parameters) {
   106             String algorithm, AlgorithmParameters parameters) {
   103 
       
   104         if (primitives == null || primitives.isEmpty()) {
       
   105             throw new IllegalArgumentException(
       
   106                         "No cryptographic primitive specified");
       
   107         }
       
   108 
       
   109         return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
   107         return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
   110     }
   108     }
   111 
   109 
   112     /*
   110     /*
   113      * Checks if the key algorithm has been disabled or constraints have been
   111      * Checks if the key algorithm has been disabled or constraints have been
   129         if (algorithm == null || algorithm.length() == 0) {
   127         if (algorithm == null || algorithm.length() == 0) {
   130             throw new IllegalArgumentException("No algorithm name specified");
   128             throw new IllegalArgumentException("No algorithm name specified");
   131         }
   129         }
   132 
   130 
   133         return checkConstraints(primitives, algorithm, key, parameters);
   131         return checkConstraints(primitives, algorithm, key, parameters);
       
   132     }
       
   133 
       
   134     public final void permits(ConstraintsParameters cp)
       
   135             throws CertPathValidatorException {
       
   136         permits(cp.getAlgorithm(), cp);
       
   137     }
       
   138 
       
   139     public final void permits(String algorithm, Key key,
       
   140             AlgorithmParameters params, String variant)
       
   141             throws CertPathValidatorException {
       
   142         permits(algorithm, new ConstraintsParameters(algorithm, params, key,
       
   143                 (variant == null) ? Validator.VAR_GENERIC : variant));
   134     }
   144     }
   135 
   145 
   136     /*
   146     /*
   137      * Check if a x509Certificate object is permitted.  Check if all
   147      * Check if a x509Certificate object is permitted.  Check if all
   138      * algorithms are allowed, certificate constraints, and the
   148      * algorithms are allowed, certificate constraints, and the
   139      * public key against key constraints.
   149      * public key against key constraints.
   140      *
   150      *
   141      * Uses new style permit() which throws exceptions.
   151      * Uses new style permit() which throws exceptions.
   142      */
   152      */
   143     public final void permits(Set<CryptoPrimitive> primitives,
   153 
   144             CertConstraintParameters cp) throws CertPathValidatorException {
   154     public final void permits(String algorithm, ConstraintsParameters cp)
   145         checkConstraints(primitives, cp);
   155             throws CertPathValidatorException {
   146     }
   156         algorithmConstraints.permits(algorithm, cp);
   147 
       
   148     /*
       
   149      * Check if Certificate object is within the constraints.
       
   150      * Uses new style permit() which throws exceptions.
       
   151      */
       
   152     public final void permits(Set<CryptoPrimitive> primitives,
       
   153             X509Certificate cert) throws CertPathValidatorException {
       
   154         checkConstraints(primitives, new CertConstraintParameters(cert));
       
   155     }
   157     }
   156 
   158 
   157     // Check if a string is contained inside the property
   159     // Check if a string is contained inside the property
   158     public boolean checkProperty(String param) {
   160     public boolean checkProperty(String param) {
   159         param = param.toLowerCase(Locale.ENGLISH);
   161         param = param.toLowerCase(Locale.ENGLISH);
   172         // check the key parameter, it cannot be null.
   174         // check the key parameter, it cannot be null.
   173         if (key == null) {
   175         if (key == null) {
   174             throw new IllegalArgumentException("The key cannot be null");
   176             throw new IllegalArgumentException("The key cannot be null");
   175         }
   177         }
   176 
   178 
   177         // check the signature algorithm
   179         // check the signature algorithm with parameters
   178         if (algorithm != null && algorithm.length() != 0) {
   180         if (algorithm != null && algorithm.length() != 0) {
   179             if (!permits(primitives, algorithm, parameters)) {
   181             if (!permits(primitives, algorithm, parameters)) {
   180                 return false;
   182                 return false;
   181             }
   183             }
   182         }
   184         }
   188 
   190 
   189         // check the key constraints
   191         // check the key constraints
   190         return algorithmConstraints.permits(key);
   192         return algorithmConstraints.permits(key);
   191     }
   193     }
   192 
   194 
   193     /*
       
   194      * Check algorithm constraints with Certificate
       
   195      * Uses new style permit() which throws exceptions.
       
   196      */
       
   197     private void checkConstraints(Set<CryptoPrimitive> primitives,
       
   198             CertConstraintParameters cp) throws CertPathValidatorException {
       
   199 
       
   200         X509Certificate cert = cp.getCertificate();
       
   201         String algorithm = cert.getSigAlgName();
       
   202 
       
   203         // Check signature algorithm is not disabled
       
   204         if (!permits(primitives, algorithm, null)) {
       
   205             throw new CertPathValidatorException(
       
   206                     "Algorithm constraints check failed on disabled "+
       
   207                             "signature algorithm: " + algorithm,
       
   208                     null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
       
   209         }
       
   210 
       
   211         // Check key algorithm is not disabled
       
   212         if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) {
       
   213             throw new CertPathValidatorException(
       
   214                     "Algorithm constraints check failed on disabled "+
       
   215                             "public key algorithm: " + algorithm,
       
   216                     null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
       
   217         }
       
   218 
       
   219         // Check the certificate and key constraints
       
   220         algorithmConstraints.permits(cp);
       
   221 
       
   222     }
       
   223 
   195 
   224     /**
   196     /**
   225      * Key and Certificate Constraints
   197      * Key and Certificate Constraints
   226      *
   198      *
   227      * The complete disabling of an algorithm is not handled by Constraints or
   199      * The complete disabling of an algorithm is not handled by Constraints or
   232      * same as the interface class AlgorithmConstraints.permit().  This is to
   204      * same as the interface class AlgorithmConstraints.permit().  This is to
   233      * maintain compatibility:
   205      * maintain compatibility:
   234      * 'true' means the operation is allowed.
   206      * 'true' means the operation is allowed.
   235      * 'false' means it failed the constraints and is disallowed.
   207      * 'false' means it failed the constraints and is disallowed.
   236      *
   208      *
   237      * When passing CertConstraintParameters through permit(), an exception
   209      * When passing ConstraintsParameters through permit(), an exception
   238      * will be thrown on a failure to better identify why the operation was
   210      * will be thrown on a failure to better identify why the operation was
   239      * disallowed.
   211      * disallowed.
   240      */
   212      */
   241 
   213 
   242     private static class Constraints {
   214     private static class Constraints {
   243         private Map<String, Set<Constraint>> constraintsMap = new HashMap<>();
   215         private Map<String, List<Constraint>> constraintsMap = new HashMap<>();
   244 
   216 
   245         private static class Holder {
   217         private static class Holder {
   246             private static final Pattern DENY_AFTER_PATTERN = Pattern.compile(
   218             private static final Pattern DENY_AFTER_PATTERN = Pattern.compile(
   247                     "denyAfter\\s+(\\d{4})-(\\d{2})-(\\d{2})");
   219                     "denyAfter\\s+(\\d{4})-(\\d{2})-(\\d{2})");
   248         }
   220         }
   258                     debug.println("Constraints: " + constraintEntry);
   230                     debug.println("Constraints: " + constraintEntry);
   259                 }
   231                 }
   260 
   232 
   261                 // Check if constraint is a complete disabling of an
   233                 // Check if constraint is a complete disabling of an
   262                 // algorithm or has conditions.
   234                 // algorithm or has conditions.
   263                 String algorithm;
       
   264                 String policy;
       
   265                 int space = constraintEntry.indexOf(' ');
   235                 int space = constraintEntry.indexOf(' ');
   266                 if (space > 0) {
   236                 String algorithm = AlgorithmDecomposer.hashName(
   267                     algorithm = AlgorithmDecomposer.hashName(
   237                         ((space > 0 ? constraintEntry.substring(0, space) :
   268                             constraintEntry.substring(0, space).
   238                                 constraintEntry).
   269                                     toUpperCase(Locale.ENGLISH));
   239                                 toUpperCase(Locale.ENGLISH)));
   270                     policy = constraintEntry.substring(space + 1);
   240                 List<Constraint> constraintList =
   271                 } else {
   241                         constraintsMap.getOrDefault(algorithm,
   272                     algorithm = constraintEntry.toUpperCase(Locale.ENGLISH);
   242                                 new ArrayList<>(1));
   273                     if (!constraintsMap.containsKey(algorithm)) {
   243                 constraintsMap.putIfAbsent(algorithm, constraintList);
   274                         constraintsMap.putIfAbsent(algorithm,
   244                 if (space <= 0) {
   275                                 new HashSet<>());
   245                     constraintList.add(new DisabledConstraint(algorithm));
   276                     }
       
   277                     continue;
   246                     continue;
   278                 }
   247                 }
       
   248 
       
   249                 String policy = constraintEntry.substring(space + 1);
   279 
   250 
   280                 // Convert constraint conditions into Constraint classes
   251                 // Convert constraint conditions into Constraint classes
   281                 Constraint c, lastConstraint = null;
   252                 Constraint c, lastConstraint = null;
   282                 // Allow only one jdkCA entry per constraint entry
   253                 // Allow only one jdkCA entry per constraint entry
   283                 boolean jdkCALimit = false;
   254                 boolean jdkCALimit = false;
   313                                     "Constraint: " + constraintEntry);
   284                                     "Constraint: " + constraintEntry);
   314                         }
   285                         }
   315                         c = new jdkCAConstraint(algorithm);
   286                         c = new jdkCAConstraint(algorithm);
   316                         jdkCALimit = true;
   287                         jdkCALimit = true;
   317 
   288 
   318                     } else if(entry.startsWith("denyAfter") &&
   289                     } else if (entry.startsWith("denyAfter") &&
   319                             (matcher = Holder.DENY_AFTER_PATTERN.matcher(entry))
   290                             (matcher = Holder.DENY_AFTER_PATTERN.matcher(entry))
   320                                     .matches()) {
   291                                     .matches()) {
   321                         if (debug != null) {
   292                         if (debug != null) {
   322                             debug.println("Constraints set to denyAfter");
   293                             debug.println("Constraints set to denyAfter");
   323                         }
   294                         }
   330                         int month = Integer.parseInt(matcher.group(2));
   301                         int month = Integer.parseInt(matcher.group(2));
   331                         int day = Integer.parseInt(matcher.group(3));
   302                         int day = Integer.parseInt(matcher.group(3));
   332                         c = new DenyAfterConstraint(algorithm, year, month,
   303                         c = new DenyAfterConstraint(algorithm, year, month,
   333                                 day);
   304                                 day);
   334                         denyAfterLimit = true;
   305                         denyAfterLimit = true;
       
   306                     } else if (entry.startsWith("usage")) {
       
   307                         String s[] = (entry.substring(5)).trim().split(" ");
       
   308                         c = new UsageConstraint(algorithm, s);
       
   309                         if (debug != null) {
       
   310                             debug.println("Constraints usage length is " + s.length);
       
   311                         }
   335                     } else {
   312                     } else {
   336                         throw new IllegalArgumentException("Error in security" +
   313                         throw new IllegalArgumentException("Error in security" +
   337                                 " property. Constraint unknown: " + entry);
   314                                 " property. Constraint unknown: " + entry);
   338                     }
   315                     }
   339 
   316 
   340                     // Link multiple conditions for a single constraint
   317                     // Link multiple conditions for a single constraint
   341                     // into a linked list.
   318                     // into a linked list.
   342                     if (lastConstraint == null) {
   319                     if (lastConstraint == null) {
   343                         if (!constraintsMap.containsKey(algorithm)) {
   320                         constraintList.add(c);
   344                             constraintsMap.putIfAbsent(algorithm,
       
   345                                     new HashSet<>());
       
   346                         }
       
   347                         constraintsMap.get(algorithm).add(c);
       
   348                     } else {
   321                     } else {
   349                         lastConstraint.nextConstraint = c;
   322                         lastConstraint.nextConstraint = c;
   350                     }
   323                     }
   351                     lastConstraint = c;
   324                     lastConstraint = c;
   352                 }
   325                 }
   353             }
   326             }
   354         }
   327         }
   355 
   328 
   356         // Get applicable constraints based off the signature algorithm
   329         // Get applicable constraints based off the signature algorithm
   357         private Set<Constraint> getConstraints(String algorithm) {
   330         private List<Constraint> getConstraints(String algorithm) {
   358             return constraintsMap.get(algorithm);
   331             return constraintsMap.get(algorithm);
   359         }
   332         }
   360 
   333 
   361         // Check if KeySizeConstraints permit the specified key
   334         // Check if KeySizeConstraints permit the specified key
   362         public boolean permits(Key key) {
   335         public boolean permits(Key key) {
   363             Set<Constraint> set = getConstraints(key.getAlgorithm());
   336             List<Constraint> list = getConstraints(key.getAlgorithm());
   364             if (set == null) {
   337             if (list == null) {
   365                 return true;
   338                 return true;
   366             }
   339             }
   367             for (Constraint constraint : set) {
   340             for (Constraint constraint : list) {
   368                 if (!constraint.permits(key)) {
   341                 if (!constraint.permits(key)) {
   369                     if (debug != null) {
   342                     if (debug != null) {
   370                         debug.println("keySizeConstraint: failed key " +
   343                         debug.println("keySizeConstraint: failed key " +
   371                                 "constraint check " + KeyUtil.getKeySize(key));
   344                                 "constraint check " + KeyUtil.getKeySize(key));
   372                     }
   345                     }
   375             }
   348             }
   376             return true;
   349             return true;
   377         }
   350         }
   378 
   351 
   379         // Check if constraints permit this cert.
   352         // Check if constraints permit this cert.
   380         public void permits(CertConstraintParameters cp)
   353         public void permits(String algorithm, ConstraintsParameters cp)
   381                 throws CertPathValidatorException {
   354                 throws CertPathValidatorException {
   382             X509Certificate cert = cp.getCertificate();
   355             X509Certificate cert = cp.getCertificate();
   383 
   356 
   384             if (debug != null) {
   357             if (debug != null) {
   385                 debug.println("Constraints.permits(): " + cert.getSigAlgName());
   358                 debug.println("Constraints.permits(): " + algorithm +
       
   359                         " Variant: " + cp.getVariant());
   386             }
   360             }
   387 
   361 
   388             // Get all signature algorithms to check for constraints
   362             // Get all signature algorithms to check for constraints
   389             Set<String> algorithms =
   363             Set<String> algorithms = new HashSet<>();
   390                     AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName());
   364             if (algorithm != null) {
   391             if (algorithms == null || algorithms.isEmpty()) {
   365                 algorithms.addAll(AlgorithmDecomposer.decomposeOneHash(algorithm));
   392                 return;
   366             }
   393             }
   367 
   394 
   368             // Attempt to add the public key algorithm if cert provided
   395             // Attempt to add the public key algorithm to the set
   369             if (cert != null) {
   396             algorithms.add(cert.getPublicKey().getAlgorithm());
   370                 algorithms.add(cert.getPublicKey().getAlgorithm());
   397 
   371             }
       
   372             if (cp.getPublicKey() != null) {
       
   373                 algorithms.add(cp.getPublicKey().getAlgorithm());
       
   374             }
   398             // Check all applicable constraints
   375             // Check all applicable constraints
   399             for (String algorithm : algorithms) {
   376             for (String alg : algorithms) {
   400                 Set<Constraint> set = getConstraints(algorithm);
   377                 List<Constraint> list = getConstraints(alg);
   401                 if (set == null) {
   378                 if (list == null) {
   402                     continue;
   379                     continue;
   403                 }
   380                 }
   404                 for (Constraint constraint : set) {
   381                 for (Constraint constraint : list) {
   405                     constraint.permits(cp);
   382                     constraint.permits(cp);
   406                 }
   383                 }
   407             }
   384             }
   408         }
   385         }
   409     }
   386     }
   465             return true;
   442             return true;
   466         }
   443         }
   467 
   444 
   468         /**
   445         /**
   469          * Check if an algorithm constraint is permitted with a given
   446          * Check if an algorithm constraint is permitted with a given
   470          * CertConstraintParameters.
   447          * ConstraintsParameters.
   471          *
   448          *
   472          * If the check inside of {@code permits()} fails, it must call
   449          * If the check inside of {@code permits()} fails, it must call
   473          * {@code next()} with the same {@code CertConstraintParameters}
   450          * {@code next()} with the same {@code ConstraintsParameters}
   474          * parameter passed if multiple constraints need to be checked.
   451          * parameter passed if multiple constraints need to be checked.
   475          *
   452          *
   476          * @param cp CertConstraintParameter containing certificate info
   453          * @param cp CertConstraintParameter containing certificate info
   477          * @throws CertPathValidatorException if constraint disallows.
   454          * @throws CertPathValidatorException if constraint disallows.
   478          *
   455          *
   479          */
   456          */
   480         public abstract void permits(CertConstraintParameters cp)
   457         public abstract void permits(ConstraintsParameters cp)
   481                 throws CertPathValidatorException;
   458                 throws CertPathValidatorException;
   482 
   459 
   483         /**
   460         /**
   484          * Recursively check if the constraints are allowed.
   461          * Recursively check if the constraints are allowed.
   485          *
   462          *
   489          * {@code permits()} is allowed, this method will exit this and any
   466          * {@code permits()} is allowed, this method will exit this and any
   490          * recursive next() calls, returning 'true'.  If the constraints called
   467          * recursive next() calls, returning 'true'.  If the constraints called
   491          * were disallowed, the last constraint will throw
   468          * were disallowed, the last constraint will throw
   492          * {@code CertPathValidatorException}.
   469          * {@code CertPathValidatorException}.
   493          *
   470          *
   494          * @param cp CertConstraintParameters
   471          * @param cp ConstraintsParameters
   495          * @return 'true' if constraint allows the operation, 'false' if
   472          * @return 'true' if constraint allows the operation, 'false' if
   496          * we are at the end of the constraint list or,
   473          * we are at the end of the constraint list or,
   497          * {@code nextConstraint} is null.
   474          * {@code nextConstraint} is null.
   498          */
   475          */
   499         boolean next(CertConstraintParameters cp)
   476         boolean next(ConstraintsParameters cp)
   500                 throws CertPathValidatorException {
   477                 throws CertPathValidatorException {
   501             if (nextConstraint != null) {
   478             if (nextConstraint != null) {
   502                 nextConstraint.permits(cp);
   479                 nextConstraint.permits(cp);
   503                 return true;
   480                 return true;
   504             }
   481             }
   523             if (nextConstraint != null && nextConstraint.permits(key)) {
   500             if (nextConstraint != null && nextConstraint.permits(key)) {
   524                 return true;
   501                 return true;
   525             }
   502             }
   526             return false;
   503             return false;
   527         }
   504         }
       
   505 
       
   506         String extendedMsg(ConstraintsParameters cp) {
       
   507             return (cp.getCertificate() == null ? "." :
       
   508                     " used with certificate: " +
       
   509                             cp.getCertificate().getSubjectX500Principal() +
       
   510                     (cp.getVariant() != Validator.VAR_GENERIC ?
       
   511                             ".  Usage was " + cp.getVariant() : "."));
       
   512         }
   528     }
   513     }
   529 
   514 
   530     /*
   515     /*
   531      * This class contains constraints dealing with the certificate chain
   516      * This class contains constraints dealing with the certificate chain
   532      * of the certificate.
   517      * of the certificate.
   535         jdkCAConstraint(String algo) {
   520         jdkCAConstraint(String algo) {
   536             algorithm = algo;
   521             algorithm = algo;
   537         }
   522         }
   538 
   523 
   539         /*
   524         /*
   540          * Check if CertConstraintParameters has a trusted match, if it does
   525          * Check if ConstraintsParameters has a trusted match, if it does
   541          * call next() for any following constraints. If it does not, exit
   526          * call next() for any following constraints. If it does not, exit
   542          * as this constraint(s) does not restrict the operation.
   527          * as this constraint(s) does not restrict the operation.
   543          */
   528          */
   544         public void permits(CertConstraintParameters cp)
   529         public void permits(ConstraintsParameters cp)
   545                 throws CertPathValidatorException {
   530                 throws CertPathValidatorException {
   546             if (debug != null) {
   531             if (debug != null) {
   547                 debug.println("jdkCAConstraints.permits(): " + algorithm);
   532                 debug.println("jdkCAConstraints.permits(): " + algorithm);
   548             }
   533             }
   549 
   534 
   552                 if (next(cp)) {
   537                 if (next(cp)) {
   553                     return;
   538                     return;
   554                 }
   539                 }
   555                 throw new CertPathValidatorException(
   540                 throw new CertPathValidatorException(
   556                         "Algorithm constraints check failed on certificate " +
   541                         "Algorithm constraints check failed on certificate " +
   557                                 "anchor limits. " + algorithm + " used with " +
   542                         "anchor limits. " + algorithm + extendedMsg(cp),
   558                                 cp.getCertificate().getSubjectX500Principal(),
       
   559                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
   543                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
   560             }
   544             }
   561         }
   545         }
   562     }
   546     }
   563 
   547 
   613           *
   597           *
   614           * If the constraint disallows, call next() for any following
   598           * If the constraint disallows, call next() for any following
   615           * constraints. Throw an exception if this is the last constraint.
   599           * constraints. Throw an exception if this is the last constraint.
   616           */
   600           */
   617          @Override
   601          @Override
   618          public void permits(CertConstraintParameters cp)
   602          public void permits(ConstraintsParameters cp)
   619                  throws CertPathValidatorException {
   603                  throws CertPathValidatorException {
   620              Date currentDate;
   604              Date currentDate;
   621              String errmsg;
   605              String errmsg;
   622 
   606 
   623              if (cp.getJARTimestamp() != null) {
   607              if (cp.getJARTimestamp() != null) {
   626              } else if (cp.getPKIXParamDate() != null) {
   610              } else if (cp.getPKIXParamDate() != null) {
   627                  currentDate = cp.getPKIXParamDate();
   611                  currentDate = cp.getPKIXParamDate();
   628                  errmsg = "PKIXParameter date: ";
   612                  errmsg = "PKIXParameter date: ";
   629              } else {
   613              } else {
   630                  currentDate = new Date();
   614                  currentDate = new Date();
   631                  errmsg = "Certificate date: ";
   615                  errmsg = "Current date: ";
   632              }
   616              }
   633 
   617 
   634              if (!denyAfterDate.after(currentDate)) {
   618              if (!denyAfterDate.after(currentDate)) {
   635                  if (next(cp)) {
   619                  if (next(cp)) {
   636                      return;
   620                      return;
   637                  }
   621                  }
   638                  throw new CertPathValidatorException(
   622                  throw new CertPathValidatorException(
   639                          "denyAfter constraint check failed: " + algorithm +
   623                          "denyAfter constraint check failed: " + algorithm +
   640                                  " used with Constraint date: " +
   624                          " used with Constraint date: " +
   641                                  dateFormat.format(denyAfterDate) + "; "
   625                          dateFormat.format(denyAfterDate) + "; " + errmsg +
   642                                  + errmsg + dateFormat.format(currentDate),
   626                          dateFormat.format(currentDate) + extendedMsg(cp),
   643                          null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
   627                          null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
   644              }
   628              }
   645          }
   629          }
   646 
   630 
   647          /*
   631          /*
   657              }
   641              }
   658 
   642 
   659              return denyAfterDate.after(new Date());
   643              return denyAfterDate.after(new Date());
   660          }
   644          }
   661      }
   645      }
       
   646 
       
   647     /*
       
   648      * The usage constraint is for the "usage" keyword.  It checks against the
       
   649      * variant value in ConstraintsParameters.
       
   650      */
       
   651     private static class UsageConstraint extends Constraint {
       
   652         String[] usages;
       
   653 
       
   654         UsageConstraint(String algorithm, String[] usages) {
       
   655             this.algorithm = algorithm;
       
   656             this.usages = usages;
       
   657         }
       
   658 
       
   659         public void permits(ConstraintsParameters cp)
       
   660                 throws CertPathValidatorException {
       
   661             for (String usage : usages) {
       
   662 
       
   663                 String v = null;
       
   664                 if (usage.compareToIgnoreCase("TLSServer") == 0) {
       
   665                     v = Validator.VAR_TLS_SERVER;
       
   666                 } else if (usage.compareToIgnoreCase("TLSClient") == 0) {
       
   667                     v = Validator.VAR_TLS_CLIENT;
       
   668                 } else if (usage.compareToIgnoreCase("SignedJAR") == 0) {
       
   669                     v = Validator.VAR_PLUGIN_CODE_SIGNING;
       
   670                 }
       
   671 
       
   672                 if (debug != null) {
       
   673                     debug.println("Checking if usage constraint " + v +
       
   674                             " matches " + cp.getVariant());
       
   675                 }
       
   676                 if (cp.getVariant().compareTo(v) == 0) {
       
   677                     if (next(cp)) {
       
   678                         return;
       
   679                     }
       
   680                     throw new CertPathValidatorException("Usage constraint " +
       
   681                             usage + " check failed: " + algorithm +
       
   682                             extendedMsg(cp),
       
   683                             null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
       
   684                 }
       
   685             }
       
   686         }
       
   687     }
   662 
   688 
   663     /*
   689     /*
   664      * This class contains constraints dealing with the key size
   690      * This class contains constraints dealing with the key size
   665      * support limits per algorithm.   e.g.  "keySize <= 1024"
   691      * support limits per algorithm.   e.g.  "keySize <= 1024"
   666      */
   692      */
   711          *
   737          *
   712          * Check if each constraint fails and check if there is a linked
   738          * Check if each constraint fails and check if there is a linked
   713          * constraint  Any permitted constraint will exit the linked list
   739          * constraint  Any permitted constraint will exit the linked list
   714          * to allow the operation.
   740          * to allow the operation.
   715          */
   741          */
   716         public void permits(CertConstraintParameters cp)
   742         public void permits(ConstraintsParameters cp)
   717                 throws CertPathValidatorException {
   743                 throws CertPathValidatorException {
   718             if (!permitsImpl(cp.getCertificate().getPublicKey())) {
   744             Key key = null;
       
   745             if (cp.getPublicKey() != null) {
       
   746                 key = cp.getPublicKey();
       
   747             } else if (cp.getCertificate() != null) {
       
   748                 key = cp.getCertificate().getPublicKey();
       
   749             }
       
   750             if (key != null && !permitsImpl(key)) {
   719                 if (nextConstraint != null) {
   751                 if (nextConstraint != null) {
   720                     nextConstraint.permits(cp);
   752                     nextConstraint.permits(cp);
   721                     return;
   753                     return;
   722                 }
   754                 }
   723                 throw new CertPathValidatorException(
   755                 throw new CertPathValidatorException(
   724                         "Algorithm constraints check failed on keysize limits. "
   756                         "Algorithm constraints check failed on keysize limits. "
   725                                 + algorithm + " " + size + "bit key used with "
   757                         + algorithm + " " + size + "bit key" + extendedMsg(cp),
   726                                 + cp.getCertificate().getSubjectX500Principal(),
       
   727                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
   758                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
   728             }
   759             }
   729         }
   760         }
   730 
   761 
   731 
   762 
   760                 // please don't disable such keys.
   791                 // please don't disable such keys.
   761 
   792 
   762             return true;
   793             return true;
   763         }
   794         }
   764     }
   795     }
       
   796 
       
   797     /*
       
   798      * This constraint is used for the complete disabling of the algorithm.
       
   799      */
       
   800     private static class DisabledConstraint extends Constraint {
       
   801         DisabledConstraint(String algo) {
       
   802             algorithm = algo;
       
   803         }
       
   804 
       
   805         public void permits(ConstraintsParameters cp)
       
   806                 throws CertPathValidatorException {
       
   807             throw new CertPathValidatorException(
       
   808                     "Algorithm constraints check failed on disabled " +
       
   809                             "algorithm: " + algorithm + extendedMsg(cp),
       
   810                     null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
       
   811         }
       
   812 
       
   813         public boolean permits(Key key) {
       
   814             return false;
       
   815         }
       
   816     }
   765 }
   817 }
   766 
   818