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/ConstraintsChecker.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/provider/certpath/ConstraintsChecker.java+305−0
@@ -0,0 +1,305 @@
1+/*
2+ * Copyright (c) 2000, 2008, 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.util.Collection;
29+import java.util.Collections;
30+import java.util.Set;
31+import java.util.HashSet;
32+import java.io.IOException;
33+import java.security.cert.Certificate;
34+import java.security.cert.CertificateException;
35+import java.security.cert.CertPathValidatorException;
36+import java.security.cert.X509Certificate;
37+import java.security.cert.PKIXCertPathChecker;
38+import java.security.cert.PKIXReason;
39+import sun.security.util.Debug;
40+import sun.security.x509.PKIXExtensions;
41+import sun.security.x509.NameConstraintsExtension;
42+import sun.security.x509.X509CertImpl;
43+
44+/**
45+ * ConstraintsChecker is a <code>PKIXCertPathChecker</code> that checks
46+ * constraints information on a PKIX certificate, namely basic constraints
47+ * and name constraints.
48+ *
49+ * @since 1.4
50+ * @author Yassir Elley
51+ */
52+class ConstraintsChecker extends PKIXCertPathChecker {
53+
54+ private static final Debug debug = Debug.getInstance("certpath");
55+ /* length of cert path */
56+ private final int certPathLength;
57+ /* current maximum path length (as defined in PKIX) */
58+ private int maxPathLength;
59+ /* current index of cert */
60+ private int i;
61+ private NameConstraintsExtension prevNC;
62+
63+ private Set<String> supportedExts;
64+
65+ /**
66+ * Creates a ConstraintsChecker.
67+ *
68+ * @param certPathLength the length of the certification path
69+ * @throws CertPathValidatorException if the checker cannot be initialized
70+ */
71+ ConstraintsChecker(int certPathLength) throws CertPathValidatorException {
72+ this.certPathLength = certPathLength;
73+ init(false);
74+ }
75+
76+ public void init(boolean forward) throws CertPathValidatorException {
77+ if (!forward) {
78+ i = 0;
79+ maxPathLength = certPathLength;
80+ prevNC = null;
81+ } else {
82+ throw new CertPathValidatorException
83+ ("forward checking not supported");
84+ }
85+ }
86+
87+ public boolean isForwardCheckingSupported() {
88+ return false;
89+ }
90+
91+ public Set<String> getSupportedExtensions() {
92+ if (supportedExts == null) {
93+ supportedExts = new HashSet<String>();
94+ supportedExts.add(PKIXExtensions.BasicConstraints_Id.toString());
95+ supportedExts.add(PKIXExtensions.NameConstraints_Id.toString());
96+ supportedExts = Collections.unmodifiableSet(supportedExts);
97+ }
98+ return supportedExts;
99+ }
100+
101+ /**
102+ * Performs the basic constraints and name constraints
103+ * checks on the certificate using its internal state.
104+ *
105+ * @param cert the <code>Certificate</code> to be checked
106+ * @param unresCritExts a <code>Collection</code> of OID strings
107+ * representing the current set of unresolved critical extensions
108+ * @throws CertPathValidatorException if the specified certificate
109+ * does not pass the check
110+ */
111+ public void check(Certificate cert, Collection<String> unresCritExts)
112+ throws CertPathValidatorException
113+ {
114+ X509Certificate currCert = (X509Certificate) cert;
115+
116+ i++;
117+ // MUST run NC check second, since it depends on BC check to
118+ // update remainingCerts
119+ checkBasicConstraints(currCert);
120+ verifyNameConstraints(currCert);
121+
122+ if (unresCritExts != null && !unresCritExts.isEmpty()) {
123+ unresCritExts.remove(PKIXExtensions.BasicConstraints_Id.toString());
124+ unresCritExts.remove(PKIXExtensions.NameConstraints_Id.toString());
125+ }
126+ }
127+
128+ /**
129+ * Internal method to check the name constraints against a cert
130+ */
131+ private void verifyNameConstraints(X509Certificate currCert)
132+ throws CertPathValidatorException
133+ {
134+ String msg = "name constraints";
135+ if (debug != null) {
136+ debug.println("---checking " + msg + "...");
137+ }
138+
139+ // check name constraints only if there is a previous name constraint
140+ // and either the currCert is the final cert or the currCert is not
141+ // self-issued
142+ if (prevNC != null && ((i == certPathLength) ||
143+ !X509CertImpl.isSelfIssued(currCert))) {
144+ if (debug != null) {
145+ debug.println("prevNC = " + prevNC);
146+ debug.println("currDN = " + currCert.getSubjectX500Principal());
147+ }
148+
149+ try {
150+ if (!prevNC.verify(currCert)) {
151+ throw new CertPathValidatorException(msg + " check failed",
152+ null, null, -1, PKIXReason.INVALID_NAME);
153+ }
154+ } catch (IOException ioe) {
155+ throw new CertPathValidatorException(ioe);
156+ }
157+ }
158+
159+ // merge name constraints regardless of whether cert is self-issued
160+ prevNC = mergeNameConstraints(currCert, prevNC);
161+
162+ if (debug != null)
163+ debug.println(msg + " verified.");
164+ }
165+
166+ /**
167+ * Helper to fold sets of name constraints together
168+ */
169+ static NameConstraintsExtension
170+ mergeNameConstraints(X509Certificate currCert,
171+ NameConstraintsExtension prevNC) throws CertPathValidatorException
172+ {
173+ X509CertImpl currCertImpl;
174+ try {
175+ currCertImpl = X509CertImpl.toImpl(currCert);
176+ } catch (CertificateException ce) {
177+ throw new CertPathValidatorException(ce);
178+ }
179+
180+ NameConstraintsExtension newConstraints =
181+ currCertImpl.getNameConstraintsExtension();
182+
183+ if (debug != null) {
184+ debug.println("prevNC = " + prevNC);
185+ debug.println("newNC = " + String.valueOf(newConstraints));
186+ }
187+
188+ // if there are no previous name constraints, we just return the
189+ // new name constraints.
190+ if (prevNC == null) {
191+ if (debug != null) {
192+ debug.println("mergedNC = " + String.valueOf(newConstraints));
193+ }
194+ if (newConstraints == null) {
195+ return newConstraints;
196+ } else {
197+ // Make sure we do a clone here, because we're probably
198+ // going to modify this object later and we don't want to
199+ // be sharing it with a Certificate object!
200+ return (NameConstraintsExtension) newConstraints.clone();
201+ }
202+ } else {
203+ try {
204+ // after merge, prevNC should contain the merged constraints
205+ prevNC.merge(newConstraints);
206+ } catch (IOException ioe) {
207+ throw new CertPathValidatorException(ioe);
208+ }
209+ if (debug != null) {
210+ debug.println("mergedNC = " + prevNC);
211+ }
212+ return prevNC;
213+ }
214+ }
215+
216+ /**
217+ * Internal method to check that a given cert meets basic constraints.
218+ */
219+ private void checkBasicConstraints(X509Certificate currCert)
220+ throws CertPathValidatorException
221+ {
222+ String msg = "basic constraints";
223+ if (debug != null) {
224+ debug.println("---checking " + msg + "...");
225+ debug.println("i = " + i);
226+ debug.println("maxPathLength = " + maxPathLength);
227+ }
228+
229+ /* check if intermediate cert */
230+ if (i < certPathLength) {
231+ // RFC5280: If certificate i is a version 3 certificate, verify
232+ // that the basicConstraints extension is present and that cA is
233+ // set to TRUE. (If certificate i is a version 1 or version 2
234+ // certificate, then the application MUST either verify that
235+ // certificate i is a CA certificate through out-of-band means
236+ // or reject the certificate. Conforming implementations may
237+ // choose to reject all version 1 and version 2 intermediate
238+ // certificates.)
239+ //
240+ // We choose to reject all version 1 and version 2 intermediate
241+ // certificates except that it is self issued by the trust
242+ // anchor in order to support key rollover or changes in
243+ // certificate policies.
244+ int pathLenConstraint = -1;
245+ if (currCert.getVersion() < 3) { // version 1 or version 2
246+ if (i == 1) { // issued by a trust anchor
247+ if (X509CertImpl.isSelfIssued(currCert)) {
248+ pathLenConstraint = Integer.MAX_VALUE;
249+ }
250+ }
251+ } else {
252+ pathLenConstraint = currCert.getBasicConstraints();
253+ }
254+
255+ if (pathLenConstraint == -1) {
256+ throw new CertPathValidatorException
257+ (msg + " check failed: this is not a CA certificate",
258+ null, null, -1, PKIXReason.NOT_CA_CERT);
259+ }
260+
261+ if (!X509CertImpl.isSelfIssued(currCert)) {
262+ if (maxPathLength <= 0) {
263+ throw new CertPathValidatorException
264+ (msg + " check failed: pathLenConstraint violated - "
265+ + "this cert must be the last cert in the "
266+ + "certification path", null, null, -1,
267+ PKIXReason.PATH_TOO_LONG);
268+ }
269+ maxPathLength--;
270+ }
271+ if (pathLenConstraint < maxPathLength)
272+ maxPathLength = pathLenConstraint;
273+ }
274+
275+ if (debug != null) {
276+ debug.println("after processing, maxPathLength = " + maxPathLength);
277+ debug.println(msg + " verified.");
278+ }
279+ }
280+
281+ /**
282+ * Merges the specified maxPathLength with the pathLenConstraint
283+ * obtained from the certificate.
284+ *
285+ * @param cert the <code>X509Certificate</code>
286+ * @param maxPathLength the previous maximum path length
287+ * @return the new maximum path length constraint (-1 means no more
288+ * certificates can follow, Integer.MAX_VALUE means path length is
289+ * unconstrained)
290+ */
291+ static int mergeBasicConstraints(X509Certificate cert, int maxPathLength) {
292+
293+ int pathLenConstraint = cert.getBasicConstraints();
294+
295+ if (!X509CertImpl.isSelfIssued(cert)) {
296+ maxPathLength--;
297+ }
298+
299+ if (pathLenConstraint < maxPathLength) {
300+ maxPathLength = pathLenConstraint;
301+ }
302+
303+ return maxPathLength;
304+ }
305+}