1 /*
   2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package sun.security.validator;
  26 
  27 import java.security.AccessController;
  28 import java.security.PrivilegedAction;
  29 import java.security.Security;
  30 import java.security.cert.X509Certificate;
  31 import java.util.EnumSet;
  32 
  33 import sun.security.util.Debug;
  34 
  35 /**
  36  * Policies for distrusting a certificate authority (CA). See the
  37  * jdk.security.caDistrustPolicies security property for more information.
  38  */
  39 enum CADistrustPolicy {
  40     /**
  41      * Distrust TLS Server certificates anchored by a Symantec root CA and
  42      * issued after April 16, 2019 (with exceptions for a couple of subordinate
  43      * CAs, see the jdk.security.caDistrustPolicies definition in the
  44      * java.security file for more details). If enabled, this policy is
  45      * currently enforced by the PKIX and SunX509 TrustManager implementations
  46      * of the SunJSSE provider implementation.
  47      */
  48     SYMANTEC_TLS {
  49         void checkDistrust(String variant, X509Certificate[] chain)
  50                            throws ValidatorException {
  51             if (!variant.equals(Validator.VAR_TLS_SERVER)) {
  52                 return;
  53             }
  54             SymantecTLSPolicy.checkDistrust(chain);
  55         }
  56     };
  57 
  58     /**
  59      * Checks if the end-entity certificate is distrusted.
  60      *
  61      * @param variant the type of certificate being checked
  62      * @param chain the end-entity's certificate chain. The end entity cert
  63      *              is at index 0, the trust anchor at index n-1.
  64      * @throws ValidatorException if the end-entity certificate is distrusted
  65      */
  66     abstract void checkDistrust(String variant,
  67                                 X509Certificate[] chain)
  68                                 throws ValidatorException;
  69 
  70     // The policies set in the jdk.security.caDistrustPolicies property.
  71     static final EnumSet<CADistrustPolicy> POLICIES = parseProperty();
  72     private static EnumSet<CADistrustPolicy> parseProperty() {
  73         String property = AccessController.doPrivileged(
  74             new PrivilegedAction<String>() {
  75                 @Override
  76                 public String run() {
  77                     return Security.getProperty(
  78                         "jdk.security.caDistrustPolicies");
  79                 }
  80             });
  81         EnumSet<CADistrustPolicy> set = EnumSet.noneOf(CADistrustPolicy.class);
  82         // if property is null or empty, the restrictions are not enforced
  83         if (property == null || property.isEmpty()) {
  84             return set;
  85         }
  86         String[] policies = property.split(",");
  87         for (String policy : policies) {
  88             policy = policy.trim();
  89             try {
  90                 CADistrustPolicy caPolicy =
  91                     Enum.valueOf(CADistrustPolicy.class, policy);
  92                 set.add(caPolicy);
  93             } catch (IllegalArgumentException iae) {
  94                 // ignore unknown values but log it
  95                 Debug debug = Debug.getInstance("certpath");
  96                 if (debug != null) {
  97                     debug.println("Unknown value for the " +
  98                                   "jdk.security.caDistrustPolicies property: "
  99                                   + policy);
 100                 }
 101             }
 102         }
 103         return set;
 104     }
 105 }