1 /* 2 * Copyright (c) 2012, 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 java.security.cert; 26 27 import java.net.URI; 28 import java.util.ArrayList; 29 import java.util.Collections; 30 import java.util.HashMap; 31 import java.util.HashSet; 32 import java.util.List; 33 import java.util.Map; 34 import java.util.Map.Entry; 35 import java.util.Set; 36 37 /** 38 * A {@code PKIXCertPathChecker} for checking the revocation status of 39 * certificates with the PKIX algorithm. 40 * 41 * <p>A {@code PKIXRevocationChecker} checks the revocation status of 42 * certificates with the Online Certificate Status Protocol (OCSP) or 43 * Certificate Revocation Lists (CRLs). OCSP is described in RFC 2560 and 44 * is a network protocol for determining the status of a certificate. A CRL 45 * is a time-stamped list identifying revoked certificates, and RFC 5280 46 * describes an algorithm for determining the revocation status of certificates 47 * using CRLs. 48 * 49 * <p>Each {@code PKIXRevocationChecker} must be able to check the revocation 50 * status of certificates with OCSP and CRLs. By default, OCSP is the 51 * preferred mechanism for checking revocation status, with CRLs as the 52 * fallback mechanism. However, this preference can be switched to CRLs with 53 * the {@link Option#PREFER_CRLS PREFER_CRLS} option. 54 * 55 * <p>A {@code PKIXRevocationChecker} is obtained by calling the 56 * {@link CertPathValidator#getRevocationChecker getRevocationChecker} method 57 * of a PKIX {@code CertPathValidator}. Additional parameters and options 58 * specific to revocation can be set (by calling {@link #setOCSPResponder} 59 * method for instance). The {@code PKIXRevocationChecker} is added to 60 * a {@code PKIXParameters} object using the 61 * {@link PKIXParameters#addCertPathChecker addCertPathChecker} 62 * or {@link PKIXParameters#setCertPathCheckers setCertPathCheckers} method, 63 * and then the {@code PKIXParameters} is passed along with the {@code CertPath} 64 * to be validated to the {@link CertPathValidator#validate validate} method 65 * of a PKIX {@code CertPathValidator}. When supplying a revocation checker in 66 * this manner, do not enable the default revocation checking mechanism (by 67 * calling {@link PKIXParameters#setRevocationEnabled}. 68 * 69 * <p>Note that when a {@code PKIXRevocationChecker} is added to 70 * {@code PKIXParameters}, it clones the {@code PKIXRevocationChecker}; 71 * thus any subsequent modifications to the {@code PKIXRevocationChecker} 72 * have no effect. 73 * 74 * <p>Any parameter that is not set (or is set to {@code null}) will be set to 75 * the default value for that parameter. 76 * 77 * <p><b>Concurrent Access</b> 78 * 79 * <p>Unless otherwise specified, the methods defined in this class are not 80 * thread-safe. Multiple threads that need to access a single object 81 * concurrently should synchronize amongst themselves and provide the 82 * necessary locking. Multiple threads each manipulating separate objects 83 * need not synchronize. 84 * 85 * @since 1.8 86 */ 87 public abstract class PKIXRevocationChecker extends PKIXCertPathChecker { 88 private URI ocspResponder; 89 private X509Certificate ocspResponderCert; 90 private List<Extension> ocspExtensions = Collections.<Extension>emptyList(); 91 private Map<X509Certificate, byte[]> ocspStapled = Collections.emptyMap(); 92 private Set<Option> options = Collections.emptySet(); 93 94 protected PKIXRevocationChecker() {} 95 96 /** 97 * Sets the URI that identifies the location of the OCSP responder. This 98 * overrides the {@code ocsp.responderURL} security property and any 99 * responder specified in a certificate's Authority Information Access 100 * Extension, as defined in RFC 5280. 101 * 102 * @param uri the responder URI 103 */ 104 public void setOCSPResponder(URI uri) { 105 this.ocspResponder = uri; 106 } 107 108 /** 109 * Gets the URI that identifies the location of the OCSP responder. This 110 * overrides the {@code ocsp.responderURL} security property. If this 111 * parameter or the {@code ocsp.responderURL} property is not set, the 112 * location is determined from the certificate's Authority Information 113 * Access Extension, as defined in RFC 5280. 114 * 115 * @return the responder URI, or {@code null} if not set 116 */ 117 public URI getOCSPResponder() { 118 return ocspResponder; 119 } 120 121 /** 122 * Sets the OCSP responder's certificate. This overrides the 123 * {@code ocsp.responderCertSubjectName}, 124 * {@code ocsp.responderCertIssuerName}, 125 * and {@code ocsp.responderCertSerialNumber} security properties. 126 * 127 * @param cert the responder's certificate 128 */ 129 public void setOCSPResponderCert(X509Certificate cert) { 130 this.ocspResponderCert = cert; 131 } 132 133 /** 134 * Gets the OCSP responder's certificate. This overrides the 135 * {@code ocsp.responderCertSubjectName}, 136 * {@code ocsp.responderCertIssuerName}, 137 * and {@code ocsp.responderCertSerialNumber} security properties. If this 138 * parameter or the aforementioned properties are not set, then the 139 * responder's certificate is determined as specified in RFC 2560. 140 * 141 * @return the responder's certificate, or {@code null} if not set 142 */ 143 public X509Certificate getOCSPResponderCert() { 144 return ocspResponderCert; 145 } 146 147 // request extensions; single extensions not supported 148 /** 149 * Sets the optional OCSP request extensions. 150 * 151 * @param extensions a list of extensions. The list is copied to protect 152 * against subsequent modification. 153 */ 154 public void setOCSPExtensions(List<Extension> extensions) 155 { 156 this.ocspExtensions = (extensions == null) 157 ? Collections.<Extension>emptyList() 158 : new ArrayList<Extension>(extensions); 159 } 160 161 /** 162 * Gets the optional OCSP request extensions. 163 * 164 * @return an unmodifiable list of extensions. Returns an empty list if no 165 * extensions have been specified. 166 */ 167 public List<Extension> getOCSPExtensions() { 168 return Collections.unmodifiableList(ocspExtensions); 169 } 170 171 /** 172 * Sets the stapled OCSP responses. These responses are used to determine 173 * the revocation status of the specified certificates when OCSP is used. 174 * 175 * @param responses a map of stapled OCSP responses. Each key is an 176 * {@code X509Certificate} that maps to the corresponding 177 * DER-encoded OCSP response for that certificate. A deep copy of 178 * the map is performed to protect against subsequent modification. 179 */ 180 public void setOCSPStapledResponses(Map<X509Certificate, byte[]> responses) 181 { 182 if (responses == null) { 183 this.ocspStapled = Collections.<X509Certificate, byte[]>emptyMap(); 184 } else { 185 Map<X509Certificate, byte[]> copy = new HashMap<>(responses.size()); 186 for (Map.Entry<X509Certificate, byte[]> e : responses.entrySet()) { 187 copy.put(e.getKey(), e.getValue().clone()); 188 } 189 this.ocspStapled = copy; 190 } 191 } 192 193 /** 194 * Gets the stapled OCSP responses. These responses are used to determine 195 * the revocation status of the specified certificates when OCSP is used. 196 * 197 * @return a map of stapled OCSP responses. Each key is an 198 * {@code X509Certificate} that maps to the corresponding 199 * DER-encoded OCSP response for that certificate. A deep copy of 200 * the map is returned to protect against subsequent modification. 201 * Returns an empty map if no responses have been specified. 202 */ 203 public Map<X509Certificate, byte[]> getOCSPStapledResponses() { 204 Map<X509Certificate, byte[]> copy = new HashMap<>(ocspStapled.size()); 205 for (Map.Entry<X509Certificate, byte[]> e : ocspStapled.entrySet()) { 206 copy.put(e.getKey(), e.getValue().clone()); 207 } 208 return copy; 209 } 210 211 /** 212 * Sets the revocation options. 213 * 214 * @param options a set of revocation options. The set is copied to protect 215 * against subsequent modification. 216 */ 217 public void setOptions(Set<Option> options) { 218 this.options = (options == null) 219 ? Collections.<Option>emptySet() 220 : new HashSet<Option>(options); 221 } 222 223 /** 224 * Gets the revocation options. 225 * 226 * @return an unmodifiable set of revocation options, or an empty set if 227 * none are specified 228 */ 229 public Set<Option> getOptions() { 230 return Collections.unmodifiableSet(options); 231 } 232 233 @Override 234 public Object clone() { 235 PKIXRevocationChecker copy = (PKIXRevocationChecker)super.clone(); 236 copy.ocspExtensions = new ArrayList<>(ocspExtensions); 237 copy.ocspStapled = new HashMap<>(ocspStapled); 238 // deep-copy the encoded stapled responses, since they are mutable 239 for (Map.Entry<X509Certificate, byte[]> entry : 240 copy.ocspStapled.entrySet()) 241 { 242 byte[] encoded = entry.getValue(); 243 entry.setValue(encoded.clone()); 244 } 245 copy.options = new HashSet<>(options); 246 return copy; 247 } 248 249 /** 250 * Various revocation options that can be specified for the revocation 251 * checking mechanism. 252 */ 253 public enum Option { 254 /** 255 * Only check the revocation status of end-entity certificates. 256 */ 257 ONLY_END_ENTITY, 258 /** 259 * Prefer CRLs to OSCP. The default behavior is to prefer OCSP. Each 260 * PKIX implementation should document further details of their 261 * specific preference rules and fallback policies. 262 */ 263 PREFER_CRLS, 264 /** 265 * Ignore network failures. The default behavior is to consider it a 266 * failure if the revocation status of a certificate cannot be obtained 267 * due to a network error. This option applies to both OCSP and CRLs. 268 */ 269 SOFT_FAIL 270 } 271 }