History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/provider/certpath/PKIXCertPathValidator.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/provider/certpath/PKIXCertPathValidator.java+353−0
@@ -0,0 +1,353 @@
1/*
2 * Copyright (c) 2000, 2011, 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
26package sun.security.provider.certpath;
27
28import java.io.IOException;
29import java.security.AccessController;
30import java.security.InvalidAlgorithmParameterException;
31import java.security.cert.CertPath;
32import java.security.cert.CertPathParameters;
33import java.security.cert.CertPathValidatorException;
34import java.security.cert.CertPathValidatorSpi;
35import java.security.cert.CertPathValidatorResult;
36import java.security.cert.PKIXCertPathChecker;
37import java.security.cert.PKIXCertPathValidatorResult;
38import java.security.cert.PKIXParameters;
39import java.security.cert.PKIXReason;
40import java.security.cert.PolicyNode;
41import java.security.cert.TrustAnchor;
42import java.security.cert.X509Certificate;
43import java.security.cert.X509CertSelector;
44import java.util.Collections;
45import java.util.List;
46import java.util.ArrayList;
47import java.util.Date;
48import java.util.Set;
49import javax.security.auth.x500.X500Principal;
50import sun.security.action.GetBooleanSecurityPropertyAction;
51import sun.security.util.Debug;
52
53import sun.security.x509.X509CertImpl;
54
55
56/**
57 * This class implements the PKIX validation algorithm for certification
58 * paths consisting exclusively of <code>X509Certificates</code>. It uses
59 * the specified input parameter set (which must be a
60 * <code>PKIXParameters</code> object) and signature provider (if any).
61 *
62 * @since 1.4
63 * @author Yassir Elley
64 */
65public class PKIXCertPathValidator extends CertPathValidatorSpi {
66
67 private static final Debug debug = Debug.getInstance("certpath");
68 private Date testDate;
69 private List<PKIXCertPathChecker> userCheckers;
70 private String sigProvider;
71 private BasicChecker basicChecker;
72 private boolean ocspEnabled = false;
73 private boolean onlyEECert = false;
74
75 /**
76 * Default constructor.
77 */
78 public PKIXCertPathValidator() {}
79
80 /**
81 * Validates a certification path consisting exclusively of
82 * <code>X509Certificate</code>s using the PKIX validation algorithm,
83 * which uses the specified input parameter set.
84 * The input parameter set must be a <code>PKIXParameters</code> object.
85 *
86 * @param cp the X509 certification path
87 * @param param the input PKIX parameter set
88 * @return the result
89 * @exception CertPathValidatorException Exception thrown if cert path
90 * does not validate.
91 * @exception InvalidAlgorithmParameterException if the specified
92 * parameters are inappropriate for this certification path validator
93 */
94 public CertPathValidatorResult engineValidate(CertPath cp,
95 CertPathParameters param)
96 throws CertPathValidatorException, InvalidAlgorithmParameterException
97 {
98 if (debug != null)
99 debug.println("PKIXCertPathValidator.engineValidate()...");
100
101 if (!(param instanceof PKIXParameters)) {
102 throw new InvalidAlgorithmParameterException("inappropriate "
103 + "parameters, must be an instance of PKIXParameters");
104 }
105
106 if (!cp.getType().equals("X.509") && !cp.getType().equals("X509")) {
107 throw new InvalidAlgorithmParameterException("inappropriate "
108 + "certification path type specified, must be X.509 or X509");
109 }
110
111 PKIXParameters pkixParam = (PKIXParameters) param;
112
113 // Make sure that none of the trust anchors include name constraints
114 // (not supported).
115 Set<TrustAnchor> anchors = pkixParam.getTrustAnchors();
116 for (TrustAnchor anchor : anchors) {
117 if (anchor.getNameConstraints() != null) {
118 throw new InvalidAlgorithmParameterException
119 ("name constraints in trust anchor not supported");
120 }
121 }
122
123 // the certpath which has been passed in (cp)
124 // has the target cert as the first certificate - we
125 // need to keep this cp so we can return it
126 // in case of an exception and for policy qualifier
127 // processing - however, for certpath validation,
128 // we need to create a reversed path, where we reverse the
129 // ordering so that the target cert is the last certificate
130
131 // Must copy elements of certList into a new modifiable List before
132 // calling Collections.reverse().
133 ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>
134 ((List<X509Certificate>)cp.getCertificates());
135 if (debug != null) {
136 if (certList.isEmpty()) {
137 debug.println("PKIXCertPathValidator.engineValidate() "
138 + "certList is empty");
139 }
140 debug.println("PKIXCertPathValidator.engineValidate() "
141 + "reversing certpath...");
142 }
143 Collections.reverse(certList);
144
145 // now certList has the target cert as the last cert and we
146 // can proceed with normal validation
147
148 populateVariables(pkixParam);
149
150 // Retrieve the first certificate in the certpath
151 // (to be used later in pre-screening)
152 X509Certificate firstCert = null;
153 if (!certList.isEmpty()) {
154 firstCert = certList.get(0);
155 }
156
157 CertPathValidatorException lastException = null;
158
159 // We iterate through the set of trust anchors until we find
160 // one that works at which time we stop iterating
161 for (TrustAnchor anchor : anchors) {
162 X509Certificate trustedCert = anchor.getTrustedCert();
163 if (trustedCert != null) {
164 if (debug != null) {
165 debug.println("PKIXCertPathValidator.engineValidate() "
166 + "anchor.getTrustedCert() != null");
167 }
168
169 // if this trust anchor is not worth trying,
170 // we move on to the next one
171 if (!isWorthTrying(trustedCert, firstCert)) {
172 continue;
173 }
174
175 if (debug != null) {
176 debug.println("anchor.getTrustedCert()."
177 + "getSubjectX500Principal() = "
178 + trustedCert.getSubjectX500Principal());
179 }
180 } else {
181 if (debug != null) {
182 debug.println("PKIXCertPathValidator.engineValidate(): "
183 + "anchor.getTrustedCert() == null");
184 }
185 }
186
187 try {
188 PolicyNodeImpl rootNode = new PolicyNodeImpl(null,
189 PolicyChecker.ANY_POLICY, null, false,
190 Collections.singleton(PolicyChecker.ANY_POLICY), false);
191 PolicyNode policyTree =
192 doValidate(anchor, cp, certList, pkixParam, rootNode);
193 // if this anchor works, return success
194 return new PKIXCertPathValidatorResult(anchor, policyTree,
195 basicChecker.getPublicKey());
196 } catch (CertPathValidatorException cpe) {
197 // remember this exception
198 lastException = cpe;
199 }
200 }
201
202 // could not find a trust anchor that verified
203 // (a) if we did a validation and it failed, use that exception
204 if (lastException != null) {
205 throw lastException;
206 }
207 // (b) otherwise, generate new exception
208 throw new CertPathValidatorException
209 ("Path does not chain with any of the trust anchors",
210 null, null, -1, PKIXReason.NO_TRUST_ANCHOR);
211 }
212
213 /**
214 * Internal method to do some simple checks to see if a given cert is
215 * worth trying to validate in the chain.
216 */
217 private boolean isWorthTrying(X509Certificate trustedCert,
218 X509Certificate firstCert) {
219
220 boolean worthy = false;
221
222 if (debug != null) {
223 debug.println("PKIXCertPathValidator.isWorthTrying() checking "
224 + "if this trusted cert is worth trying ...");
225 }
226
227 if (firstCert == null) {
228 return true;
229 }
230
231 AdaptableX509CertSelector issuerSelector =
232 new AdaptableX509CertSelector();
233
234 // check trusted certificate's subject
235 issuerSelector.setSubject(firstCert.getIssuerX500Principal());
236
237 // check the validity period
238 issuerSelector.setValidityPeriod(firstCert.getNotBefore(),
239 firstCert.getNotAfter());
240
241 /*
242 * Facilitate certification path construction with authority
243 * key identifier and subject key identifier.
244 */
245 try {
246 X509CertImpl firstCertImpl = X509CertImpl.toImpl(firstCert);
247 issuerSelector.parseAuthorityKeyIdentifierExtension(
248 firstCertImpl.getAuthorityKeyIdentifierExtension());
249
250 worthy = issuerSelector.match(trustedCert);
251 } catch (Exception e) {
252 // It is not worth trying.
253 }
254
255 if (debug != null) {
256 if (worthy) {
257 debug.println("YES - try this trustedCert");
258 } else {
259 debug.println("NO - don't try this trustedCert");
260 }
261 }
262
263 return worthy;
264 }
265
266 /**
267 * Internal method to setup the internal state
268 */
269 private void populateVariables(PKIXParameters pkixParam)
270 {
271 // default value for testDate is current time
272 testDate = pkixParam.getDate();
273 if (testDate == null) {
274 testDate = new Date(System.currentTimeMillis());
275 }
276
277 userCheckers = pkixParam.getCertPathCheckers();
278 sigProvider = pkixParam.getSigProvider();
279
280 if (pkixParam.isRevocationEnabled()) {
281 // Examine OCSP security property
282 ocspEnabled = AccessController.doPrivileged(
283 new GetBooleanSecurityPropertyAction
284 (OCSPChecker.OCSP_ENABLE_PROP));
285 onlyEECert = AccessController.doPrivileged(
286 new GetBooleanSecurityPropertyAction
287 ("com.sun.security.onlyCheckRevocationOfEECert"));
288 }
289 }
290
291 /**
292 * Internal method to actually validate a constructed path.
293 *
294 * @return the valid policy tree
295 */
296 private PolicyNode doValidate(
297 TrustAnchor anchor, CertPath cpOriginal,
298 ArrayList<X509Certificate> certList, PKIXParameters pkixParam,
299 PolicyNodeImpl rootNode) throws CertPathValidatorException
300 {
301 int certPathLen = certList.size();
302
303 basicChecker = new BasicChecker(anchor, testDate, sigProvider, false);
304 AlgorithmChecker algorithmChecker = new AlgorithmChecker(anchor);
305 KeyChecker keyChecker = new KeyChecker(certPathLen,
306 pkixParam.getTargetCertConstraints());
307 ConstraintsChecker constraintsChecker =
308 new ConstraintsChecker(certPathLen);
309
310 PolicyChecker policyChecker =
311 new PolicyChecker(pkixParam.getInitialPolicies(), certPathLen,
312 pkixParam.isExplicitPolicyRequired(),
313 pkixParam.isPolicyMappingInhibited(),
314 pkixParam.isAnyPolicyInhibited(),
315 pkixParam.getPolicyQualifiersRejected(),
316 rootNode);
317
318 ArrayList<PKIXCertPathChecker> certPathCheckers =
319 new ArrayList<PKIXCertPathChecker>();
320 // add standard checkers that we will be using
321 certPathCheckers.add(algorithmChecker);
322 certPathCheckers.add(keyChecker);
323 certPathCheckers.add(constraintsChecker);
324 certPathCheckers.add(policyChecker);
325 certPathCheckers.add(basicChecker);
326
327 // only add a revocationChecker if revocation is enabled
328 if (pkixParam.isRevocationEnabled()) {
329
330 // Use OCSP if it has been enabled
331 if (ocspEnabled) {
332 OCSPChecker ocspChecker =
333 new OCSPChecker(cpOriginal, pkixParam, onlyEECert);
334 certPathCheckers.add(ocspChecker);
335 }
336
337 // Always use CRLs
338 CrlRevocationChecker revocationChecker = new
339 CrlRevocationChecker(anchor, pkixParam, certList, onlyEECert);
340 certPathCheckers.add(revocationChecker);
341 }
342
343 // add user-specified checkers
344 certPathCheckers.addAll(userCheckers);
345
346 PKIXMasterCertPathValidator masterValidator =
347 new PKIXMasterCertPathValidator(certPathCheckers);
348
349 masterValidator.validate(cpOriginal, certList);
350
351 return policyChecker.getPolicyTree();
352 }
353}