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
26package sun.security.provider.certpath;
27
28import java.util.Collection;
29import java.util.Collections;
30import java.util.Set;
31import java.util.HashSet;
32import java.io.IOException;
33import java.security.cert.Certificate;
34import java.security.cert.CertificateException;
35import java.security.cert.CertPathValidatorException;
36import java.security.cert.X509Certificate;
37import java.security.cert.PKIXCertPathChecker;
38import java.security.cert.PKIXReason;
39import sun.security.util.Debug;
40import sun.security.x509.PKIXExtensions;
41import sun.security.x509.NameConstraintsExtension;
42import 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 */
52class 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}