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