Path: blob/master/src/java.base/share/classes/sun/security/provider/certpath/KeyChecker.java
41161 views
/*1* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.provider.certpath;2627import java.util.*;28import java.security.cert.*;29import java.security.cert.PKIXReason;3031import sun.security.util.Debug;32import static sun.security.x509.PKIXExtensions.*;3334/**35* KeyChecker is a <code>PKIXCertPathChecker</code> that checks that the36* keyCertSign bit is set in the keyUsage extension in an intermediate CA37* certificate. It also checks whether the final certificate in a38* certification path meets the specified target constraints specified as39* a CertSelector in the PKIXParameters passed to the CertPathValidator.40*41* @since 1.442* @author Yassir Elley43*/44class KeyChecker extends PKIXCertPathChecker {4546private static final Debug debug = Debug.getInstance("certpath");47private final int certPathLen;48private final CertSelector targetConstraints;49private int remainingCerts;5051private Set<String> supportedExts;5253/**54* Creates a KeyChecker.55*56* @param certPathLen allowable cert path length57* @param targetCertSel a CertSelector object specifying the constraints58* on the target certificate59*/60KeyChecker(int certPathLen, CertSelector targetCertSel) {61this.certPathLen = certPathLen;62this.targetConstraints = targetCertSel;63}6465/**66* Initializes the internal state of the checker from parameters67* specified in the constructor68*/69@Override70public void init(boolean forward) throws CertPathValidatorException {71if (!forward) {72remainingCerts = certPathLen;73} else {74throw new CertPathValidatorException75("forward checking not supported");76}77}7879@Override80public boolean isForwardCheckingSupported() {81return false;82}8384@Override85public Set<String> getSupportedExtensions() {86if (supportedExts == null) {87supportedExts = new HashSet<String>(3);88supportedExts.add(KeyUsage_Id.toString());89supportedExts.add(ExtendedKeyUsage_Id.toString());90supportedExts.add(SubjectAlternativeName_Id.toString());91supportedExts = Collections.unmodifiableSet(supportedExts);92}93return supportedExts;94}9596/**97* Checks that keyUsage and target constraints are satisfied by98* the specified certificate.99*100* @param cert the Certificate101* @param unresolvedCritExts the unresolved critical extensions102* @throws CertPathValidatorException if certificate does not verify103*/104@Override105public void check(Certificate cert, Collection<String> unresCritExts)106throws CertPathValidatorException107{108X509Certificate currCert = (X509Certificate)cert;109110remainingCerts--;111112// if final certificate, check that target constraints are satisfied113if (remainingCerts == 0) {114if (targetConstraints != null &&115targetConstraints.match(currCert) == false) {116throw new CertPathValidatorException("target certificate " +117"constraints check failed");118}119} else {120// otherwise, verify that keyCertSign bit is set in CA certificate121verifyCAKeyUsage(currCert);122}123124// remove the extensions that we have checked125if (unresCritExts != null && !unresCritExts.isEmpty()) {126unresCritExts.remove(KeyUsage_Id.toString());127unresCritExts.remove(ExtendedKeyUsage_Id.toString());128unresCritExts.remove(SubjectAlternativeName_Id.toString());129}130}131132// the index of keyCertSign in the boolean KeyUsage array133private static final int KEY_CERT_SIGN = 5;134/**135* Verifies the key usage extension in a CA cert.136* The key usage extension, if present, must assert the keyCertSign bit.137* The extended key usage extension is not checked (see CR 4776794 for138* more information).139*/140static void verifyCAKeyUsage(X509Certificate cert)141throws CertPathValidatorException {142String msg = "CA key usage";143if (debug != null) {144debug.println("KeyChecker.verifyCAKeyUsage() ---checking " + msg145+ "...");146}147148boolean[] keyUsageBits = cert.getKeyUsage();149150// getKeyUsage returns null if the KeyUsage extension is not present151// in the certificate - in which case there is nothing to check152if (keyUsageBits == null) {153return;154}155156// throw an exception if the keyCertSign bit is not set157if (!keyUsageBits[KEY_CERT_SIGN]) {158throw new CertPathValidatorException159(msg + " check failed: keyCertSign bit is not set", null,160null, -1, PKIXReason.INVALID_KEY_USAGE);161}162163if (debug != null) {164debug.println("KeyChecker.verifyCAKeyUsage() " + msg165+ " verified.");166}167}168}169170171