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

Unified · Split

java/pkg/sun/security/provider/certpath/BasicChecker.java+299−0
@@ -0,0 +1,299 @@
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.math.BigInteger;
29+import java.util.Collection;
30+import java.util.Date;
31+import java.util.Set;
32+import java.security.GeneralSecurityException;
33+import java.security.KeyFactory;
34+import java.security.PublicKey;
35+import java.security.SignatureException;
36+import java.security.cert.Certificate;
37+import java.security.cert.CertificateExpiredException;
38+import java.security.cert.CertificateNotYetValidException;
39+import java.security.cert.CertPathValidatorException;
40+import java.security.cert.CertPathValidatorException.BasicReason;
41+import java.security.cert.X509Certificate;
42+import java.security.cert.PKIXCertPathChecker;
43+import java.security.cert.PKIXReason;
44+import java.security.cert.TrustAnchor;
45+import java.security.interfaces.DSAParams;
46+import java.security.interfaces.DSAPublicKey;
47+import java.security.spec.DSAPublicKeySpec;
48+import javax.security.auth.x500.X500Principal;
49+import sun.security.x509.X500Name;
50+import sun.security.util.Debug;
51+
52+/**
53+ * BasicChecker is a PKIXCertPathChecker that checks the basic information
54+ * on a PKIX certificate, namely the signature, timestamp, and subject/issuer
55+ * name chaining.
56+ *
57+ * @since 1.4
58+ * @author Yassir Elley
59+ */
60+class BasicChecker extends PKIXCertPathChecker {
61+
62+ private static final Debug debug = Debug.getInstance("certpath");
63+ private final PublicKey trustedPubKey;
64+ private final X500Principal caName;
65+ private final Date testDate;
66+ private final String sigProvider;
67+ private final boolean sigOnly;
68+ private X500Principal prevSubject;
69+ private PublicKey prevPubKey;
70+
71+ /**
72+ * Constructor that initializes the input parameters.
73+ *
74+ * @param anchor the anchor selected to validate the target certificate
75+ * @param testDate the time for which the validity of the certificate
76+ * should be determined
77+ * @param sigProvider the name of the signature provider
78+ * @param sigOnly true if only signature checking is to be done;
79+ * if false, all checks are done
80+ */
81+ BasicChecker(TrustAnchor anchor, Date testDate, String sigProvider,
82+ boolean sigOnly) throws CertPathValidatorException
83+ {
84+ if (anchor.getTrustedCert() != null) {
85+ this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
86+ this.caName = anchor.getTrustedCert().getSubjectX500Principal();
87+ } else {
88+ this.trustedPubKey = anchor.getCAPublicKey();
89+ this.caName = anchor.getCA();
90+ }
91+ this.testDate = testDate;
92+ this.sigProvider = sigProvider;
93+ this.sigOnly = sigOnly;
94+ init(false);
95+ }
96+
97+ /**
98+ * Initializes the internal state of the checker from parameters
99+ * specified in the constructor.
100+ */
101+ public void init(boolean forward) throws CertPathValidatorException {
102+ if (!forward) {
103+ prevPubKey = trustedPubKey;
104+ prevSubject = caName;
105+ } else {
106+ throw new
107+ CertPathValidatorException("forward checking not supported");
108+ }
109+ }
110+
111+ public boolean isForwardCheckingSupported() {
112+ return false;
113+ }
114+
115+ public Set<String> getSupportedExtensions() {
116+ return null;
117+ }
118+
119+ /**
120+ * Performs the signature, timestamp, and subject/issuer name chaining
121+ * checks on the certificate using its internal state. This method does
122+ * not remove any critical extensions from the Collection.
123+ *
124+ * @param cert the Certificate
125+ * @param unresolvedCritExts a Collection of the unresolved critical
126+ * extensions
127+ * @exception CertPathValidatorException Exception thrown if certificate
128+ * does not verify.
129+ */
130+ public void check(Certificate cert, Collection<String> unresolvedCritExts)
131+ throws CertPathValidatorException
132+ {
133+ X509Certificate currCert = (X509Certificate) cert;
134+
135+ if (!sigOnly) {
136+ verifyTimestamp(currCert, testDate);
137+ verifyNameChaining(currCert, prevSubject);
138+ }
139+ verifySignature(currCert, prevPubKey, sigProvider);
140+
141+ updateState(currCert);
142+ }
143+
144+ /**
145+ * Verifies the signature on the certificate using the previous public key
146+ * @param cert the Certificate
147+ * @param prevPubKey the previous PublicKey
148+ * @param sigProvider a String containing the signature provider
149+ * @exception CertPathValidatorException Exception thrown if certificate
150+ * does not verify.
151+ */
152+ private void verifySignature(X509Certificate cert, PublicKey prevPubKey,
153+ String sigProvider) throws CertPathValidatorException
154+ {
155+ String msg = "signature";
156+ if (debug != null)
157+ debug.println("---checking " + msg + "...");
158+
159+ try {
160+ cert.verify(prevPubKey, sigProvider);
161+ } catch (SignatureException e) {
162+ throw new CertPathValidatorException
163+ (msg + " check failed", e, null, -1,
164+ BasicReason.INVALID_SIGNATURE);
165+ } catch (Exception e) {
166+ throw new CertPathValidatorException(msg + " check failed", e);
167+ }
168+
169+ if (debug != null)
170+ debug.println(msg + " verified.");
171+ }
172+
173+ /**
174+ * Internal method to verify the timestamp on a certificate
175+ */
176+ private void verifyTimestamp(X509Certificate cert, Date date)
177+ throws CertPathValidatorException
178+ {
179+ String msg = "timestamp";
180+ if (debug != null)
181+ debug.println("---checking " + msg + ":" + date.toString() + "...");
182+
183+ try {
184+ cert.checkValidity(date);
185+ } catch (CertificateExpiredException e) {
186+ throw new CertPathValidatorException
187+ (msg + " check failed", e, null, -1, BasicReason.EXPIRED);
188+ } catch (CertificateNotYetValidException e) {
189+ throw new CertPathValidatorException
190+ (msg + " check failed", e, null, -1, BasicReason.NOT_YET_VALID);
191+ }
192+
193+ if (debug != null)
194+ debug.println(msg + " verified.");
195+ }
196+
197+ /**
198+ * Internal method to check that cert has a valid DN to be next in a chain
199+ */
200+ private void verifyNameChaining(X509Certificate cert,
201+ X500Principal prevSubject) throws CertPathValidatorException
202+ {
203+ if (prevSubject != null) {
204+
205+ String msg = "subject/issuer name chaining";
206+ if (debug != null)
207+ debug.println("---checking " + msg + "...");
208+
209+ X500Principal currIssuer = cert.getIssuerX500Principal();
210+ // reject null or empty issuer DNs
211+
212+ if (X500Name.asX500Name(currIssuer).isEmpty()) {
213+ throw new CertPathValidatorException
214+ (msg + " check failed: " +
215+ "empty/null issuer DN in certificate is invalid", null,
216+ null, -1, PKIXReason.NAME_CHAINING);
217+ }
218+
219+ if (!(currIssuer.equals(prevSubject))) {
220+ throw new CertPathValidatorException
221+ (msg + " check failed", null, null, -1,
222+ PKIXReason.NAME_CHAINING);
223+ }
224+
225+ if (debug != null)
226+ debug.println(msg + " verified.");
227+ }
228+ }
229+
230+ /**
231+ * Internal method to manage state information at each iteration
232+ */
233+ private void updateState(X509Certificate currCert)
234+ throws CertPathValidatorException
235+ {
236+ PublicKey cKey = currCert.getPublicKey();
237+ if (debug != null) {
238+ debug.println("BasicChecker.updateState issuer: " +
239+ currCert.getIssuerX500Principal().toString() + "; subject: " +
240+ currCert.getSubjectX500Principal() + "; serial#: " +
241+ currCert.getSerialNumber().toString());
242+ }
243+ if (cKey instanceof DSAPublicKey &&
244+ ((DSAPublicKey)cKey).getParams() == null) {
245+ //cKey needs to inherit DSA parameters from prev key
246+ cKey = makeInheritedParamsKey(cKey, prevPubKey);
247+ if (debug != null) debug.println("BasicChecker.updateState Made " +
248+ "key with inherited params");
249+ }
250+ prevPubKey = cKey;
251+ prevSubject = currCert.getSubjectX500Principal();
252+ }
253+
254+ /**
255+ * Internal method to create a new key with inherited key parameters
256+ *
257+ * @param keyValueKey key from which to obtain key value
258+ * @param keyParamsKey key from which to obtain key parameters
259+ * @return new public key having value and parameters
260+ * @throws CertPathValidatorException if keys are not appropriate types
261+ * for this operation
262+ */
263+ static PublicKey makeInheritedParamsKey(PublicKey keyValueKey,
264+ PublicKey keyParamsKey) throws CertPathValidatorException
265+ {
266+ PublicKey usableKey;
267+ if (!(keyValueKey instanceof DSAPublicKey) ||
268+ !(keyParamsKey instanceof DSAPublicKey))
269+ throw new CertPathValidatorException("Input key is not " +
270+ "appropriate type for " +
271+ "inheriting parameters");
272+ DSAParams params = ((DSAPublicKey)keyParamsKey).getParams();
273+ if (params == null)
274+ throw new CertPathValidatorException("Key parameters missing");
275+ try {
276+ BigInteger y = ((DSAPublicKey)keyValueKey).getY();
277+ KeyFactory kf = KeyFactory.getInstance("DSA");
278+ DSAPublicKeySpec ks = new DSAPublicKeySpec(y,
279+ params.getP(),
280+ params.getQ(),
281+ params.getG());
282+ usableKey = kf.generatePublic(ks);
283+ } catch (GeneralSecurityException e) {
284+ throw new CertPathValidatorException("Unable to generate key with" +
285+ " inherited parameters: " +
286+ e.getMessage(), e);
287+ }
288+ return usableKey;
289+ }
290+
291+ /**
292+ * return the public key associated with the last certificate processed
293+ *
294+ * @return PublicKey the last public key processed
295+ */
296+ PublicKey getPublicKey() {
297+ return prevPubKey;
298+ }
299+}