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+
26+package sun.security.provider.certpath;
27+
28+import java.io.IOException;
29+import java.security.AccessController;
30+import java.security.InvalidAlgorithmParameterException;
31+import java.security.cert.CertPath;
32+import java.security.cert.CertPathParameters;
33+import java.security.cert.CertPathValidatorException;
34+import java.security.cert.CertPathValidatorSpi;
35+import java.security.cert.CertPathValidatorResult;
36+import java.security.cert.PKIXCertPathChecker;
37+import java.security.cert.PKIXCertPathValidatorResult;
38+import java.security.cert.PKIXParameters;
39+import java.security.cert.PKIXReason;
40+import java.security.cert.PolicyNode;
41+import java.security.cert.TrustAnchor;
42+import java.security.cert.X509Certificate;
43+import java.security.cert.X509CertSelector;
44+import java.util.Collections;
45+import java.util.List;
46+import java.util.ArrayList;
47+import java.util.Date;
48+import java.util.Set;
49+import javax.security.auth.x500.X500Principal;
50+import sun.security.action.GetBooleanSecurityPropertyAction;
51+import sun.security.util.Debug;
52+
53+import 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+ */
65+public 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+}