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

Unified · Split

java/pkg/sun/security/provider/certpath/AlgorithmChecker.java+367−0
@@ -0,0 +1,367 @@
1/*
2 * Copyright (c) 2009, 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.security.AlgorithmConstraints;
29import java.security.CryptoPrimitive;
30import java.util.Collection;
31import java.util.Collections;
32import java.util.Set;
33import java.util.EnumSet;
34import java.util.HashSet;
35import java.math.BigInteger;
36import java.security.PublicKey;
37import java.security.KeyFactory;
38import java.security.AlgorithmParameters;
39import java.security.NoSuchAlgorithmException;
40import java.security.GeneralSecurityException;
41import java.security.cert.Certificate;
42import java.security.cert.X509CRL;
43import java.security.cert.X509Certificate;
44import java.security.cert.PKIXCertPathChecker;
45import java.security.cert.TrustAnchor;
46import java.security.cert.CRLException;
47import java.security.cert.CertificateException;
48import java.security.cert.CertPathValidatorException;
49import java.security.cert.CertPathValidatorException.BasicReason;
50import java.security.cert.PKIXReason;
51import java.io.IOException;
52import java.security.interfaces.*;
53import java.security.spec.*;
54
55import sun.security.util.DisabledAlgorithmConstraints;
56import sun.security.x509.X509CertImpl;
57import sun.security.x509.X509CRLImpl;
58import sun.security.x509.AlgorithmId;
59
60/**
61 * A <code>PKIXCertPathChecker</code> implementation to check whether a
62 * specified certificate contains the required algorithm constraints.
63 * <p>
64 * Certificate fields such as the subject public key, the signature
65 * algorithm, key usage, extended key usage, etc. need to conform to
66 * the specified algorithm constraints.
67 *
68 * @see PKIXCertPathChecker
69 * @see PKIXParameters
70 */
71final public class AlgorithmChecker extends PKIXCertPathChecker {
72
73 private final AlgorithmConstraints constraints;
74 private final PublicKey trustedPubKey;
75 private PublicKey prevPubKey;
76
77 private final static Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
78 EnumSet.of(CryptoPrimitive.SIGNATURE);
79
80 private final static DisabledAlgorithmConstraints
81 certPathDefaultConstraints = new DisabledAlgorithmConstraints(
82 DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
83
84 /**
85 * Create a new <code>AlgorithmChecker</code> with the algorithm
86 * constraints specified in security property
87 * "jdk.certpath.disabledAlgorithms".
88 *
89 * @param anchor the trust anchor selected to validate the target
90 * certificate
91 */
92 public AlgorithmChecker(TrustAnchor anchor) {
93 this(anchor, certPathDefaultConstraints);
94 }
95
96 /**
97 * Create a new <code>AlgorithmChecker</code> with the
98 * given {@code AlgorithmConstraints}.
99 * <p>
100 * Note that this constructor will be used to check a certification
101 * path where the trust anchor is unknown, or a certificate list which may
102 * contain the trust anchor. This constructor is used by SunJSSE.
103 *
104 * @param constraints the algorithm constraints (or null)
105 */
106 public AlgorithmChecker(AlgorithmConstraints constraints) {
107 this.prevPubKey = null;
108 this.trustedPubKey = null;
109 this.constraints = constraints;
110 }
111
112 /**
113 * Create a new <code>AlgorithmChecker</code> with the
114 * given <code>TrustAnchor</code> and <code>AlgorithmConstraints</code>.
115 *
116 * @param anchor the trust anchor selected to validate the target
117 * certificate
118 * @param constraints the algorithm constraints (or null)
119 *
120 * @throws IllegalArgumentException if the <code>anchor</code> is null
121 */
122 public AlgorithmChecker(TrustAnchor anchor,
123 AlgorithmConstraints constraints) {
124
125 if (anchor == null) {
126 throw new IllegalArgumentException(
127 "The trust anchor cannot be null");
128 }
129
130 if (anchor.getTrustedCert() != null) {
131 this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
132 } else {
133 this.trustedPubKey = anchor.getCAPublicKey();
134 }
135
136 this.prevPubKey = trustedPubKey;
137 this.constraints = constraints;
138 }
139
140 @Override
141 public void init(boolean forward) throws CertPathValidatorException {
142 // Note that this class does not support forward mode.
143 if (!forward) {
144 if (trustedPubKey != null) {
145 prevPubKey = trustedPubKey;
146 } else {
147 prevPubKey = null;
148 }
149 } else {
150 throw new
151 CertPathValidatorException("forward checking not supported");
152 }
153 }
154
155 @Override
156 public boolean isForwardCheckingSupported() {
157 // Note that as this class does not support forward mode, the method
158 // will always returns false.
159 return false;
160 }
161
162 @Override
163 public Set<String> getSupportedExtensions() {
164 return null;
165 }
166
167 @Override
168 public void check(Certificate cert,
169 Collection<String> unresolvedCritExts)
170 throws CertPathValidatorException {
171
172 if (!(cert instanceof X509Certificate) || constraints == null) {
173 // ignore the check for non-x.509 certificate or null constraints
174 return;
175 }
176
177 X509CertImpl x509Cert = null;
178 try {
179 x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
180 } catch (CertificateException ce) {
181 throw new CertPathValidatorException(ce);
182 }
183
184 PublicKey currPubKey = x509Cert.getPublicKey();
185 String currSigAlg = x509Cert.getSigAlgName();
186
187 AlgorithmId algorithmId = null;
188 try {
189 algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
190 } catch (CertificateException ce) {
191 throw new CertPathValidatorException(ce);
192 }
193
194 AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
195
196 // Check the current signature algorithm
197 if (!constraints.permits(
198 SIGNATURE_PRIMITIVE_SET,
199 currSigAlg, currSigAlgParams)) {
200 throw new CertPathValidatorException(
201 "Algorithm constraints check failed: " + currSigAlg,
202 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
203 }
204
205 // check the key usage and key size
206 boolean[] keyUsage = x509Cert.getKeyUsage();
207 if (keyUsage != null && keyUsage.length < 9) {
208 throw new CertPathValidatorException(
209 "incorrect KeyUsage extension",
210 null, null, -1, PKIXReason.INVALID_KEY_USAGE);
211 }
212
213 if (keyUsage != null) {
214 Set<CryptoPrimitive> primitives =
215 EnumSet.noneOf(CryptoPrimitive.class);
216
217 if (keyUsage[0] || keyUsage[1] || keyUsage[5] || keyUsage[6]) {
218 // keyUsage[0]: KeyUsage.digitalSignature
219 // keyUsage[1]: KeyUsage.nonRepudiation
220 // keyUsage[5]: KeyUsage.keyCertSign
221 // keyUsage[6]: KeyUsage.cRLSign
222 primitives.add(CryptoPrimitive.SIGNATURE);
223 }
224
225 if (keyUsage[2]) { // KeyUsage.keyEncipherment
226 primitives.add(CryptoPrimitive.KEY_ENCAPSULATION);
227 }
228
229 if (keyUsage[3]) { // KeyUsage.dataEncipherment
230 primitives.add(CryptoPrimitive.PUBLIC_KEY_ENCRYPTION);
231 }
232
233 if (keyUsage[4]) { // KeyUsage.keyAgreement
234 primitives.add(CryptoPrimitive.KEY_AGREEMENT);
235 }
236
237 // KeyUsage.encipherOnly and KeyUsage.decipherOnly are
238 // undefined in the absence of the keyAgreement bit.
239
240 if (!primitives.isEmpty()) {
241 if (!constraints.permits(primitives, currPubKey)) {
242 throw new CertPathValidatorException(
243 "algorithm constraints check failed",
244 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
245 }
246 }
247 }
248
249 // Check with previous cert for signature algorithm and public key
250 if (prevPubKey != null) {
251 if (currSigAlg != null) {
252 if (!constraints.permits(
253 SIGNATURE_PRIMITIVE_SET,
254 currSigAlg, prevPubKey, currSigAlgParams)) {
255 throw new CertPathValidatorException(
256 "Algorithm constraints check failed: " + currSigAlg,
257 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
258 }
259 }
260
261 // Inherit key parameters from previous key
262 if (currPubKey instanceof DSAPublicKey &&
263 ((DSAPublicKey)currPubKey).getParams() == null) {
264 // Inherit DSA parameters from previous key
265 if (!(prevPubKey instanceof DSAPublicKey)) {
266 throw new CertPathValidatorException("Input key is not " +
267 "of a appropriate type for inheriting parameters");
268 }
269
270 DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
271 if (params == null) {
272 throw new CertPathValidatorException(
273 "Key parameters missing");
274 }
275
276 try {
277 BigInteger y = ((DSAPublicKey)currPubKey).getY();
278 KeyFactory kf = KeyFactory.getInstance("DSA");
279 DSAPublicKeySpec ks = new DSAPublicKeySpec(y,
280 params.getP(),
281 params.getQ(),
282 params.getG());
283 currPubKey = kf.generatePublic(ks);
284 } catch (GeneralSecurityException e) {
285 throw new CertPathValidatorException("Unable to generate " +
286 "key with inherited parameters: " + e.getMessage(), e);
287 }
288 }
289 }
290
291 // reset the previous public key
292 prevPubKey = currPubKey;
293
294 // check the extended key usage, ignore the check now
295 // List<String> extendedKeyUsages = x509Cert.getExtendedKeyUsage();
296
297 // DO NOT remove any unresolved critical extensions
298 }
299
300 /**
301 * Try to set the trust anchor of the checker.
302 * <p>
303 * If there is no trust anchor specified and the checker has not started,
304 * set the trust anchor.
305 *
306 * @param anchor the trust anchor selected to validate the target
307 * certificate
308 */
309 void trySetTrustAnchor(TrustAnchor anchor) {
310 // Don't bother if the check has started or trust anchor has already
311 // specified.
312 if (prevPubKey == null) {
313 if (anchor == null) {
314 throw new IllegalArgumentException(
315 "The trust anchor cannot be null");
316 }
317
318 // Don't bother to change the trustedPubKey.
319 if (anchor.getTrustedCert() != null) {
320 prevPubKey = anchor.getTrustedCert().getPublicKey();
321 } else {
322 prevPubKey = anchor.getCAPublicKey();
323 }
324 }
325 }
326
327 /**
328 * Check the signature algorithm with the specified public key.
329 *
330 * @param key the public key to verify the CRL signature
331 * @param crl the target CRL
332 */
333 static void check(PublicKey key, X509CRL crl)
334 throws CertPathValidatorException {
335
336 X509CRLImpl x509CRLImpl = null;
337 try {
338 x509CRLImpl = X509CRLImpl.toImpl(crl);
339 } catch (CRLException ce) {
340 throw new CertPathValidatorException(ce);
341 }
342
343 AlgorithmId algorithmId = x509CRLImpl.getSigAlgId();
344 check(key, algorithmId);
345 }
346
347 /**
348 * Check the signature algorithm with the specified public key.
349 *
350 * @param key the public key to verify the CRL signature
351 * @param crl the target CRL
352 */
353 static void check(PublicKey key, AlgorithmId algorithmId)
354 throws CertPathValidatorException {
355 String sigAlgName = algorithmId.getName();
356 AlgorithmParameters sigAlgParams = algorithmId.getParameters();
357
358 if (!certPathDefaultConstraints.permits(
359 SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
360 throw new CertPathValidatorException(
361 "algorithm check failed: " + sigAlgName + " is disabled",
362 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
363 }
364 }
365
366}
367