/* * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.security.provider.certpath; import java.io.*;import java.net.URI;import java.util.*;import java.security.*;import java.security.cert.*;import javax.security.auth.x500.X500Principal; import sun.security.action.GetBooleanAction;import sun.security.util.Debug;import sun.security.util.DerOutputStream;import sun.security.x509.*; /** * Class to obtain CRLs via the CRLDistributionPoints extension. * Note that the functionality of this class must be explicitly enabled * via a system property, see the USE_CRLDP variable below. * * This class uses the URICertStore class to fetch CRLs. The URICertStore * class also implements CRL caching: see the class description for more * information. * * @author Andreas Sterbenz * @author Sean Mullan * @since 1.4.2 */class DistributionPointFetcher { private static final Debug debug = Debug.getInstance("certpath"); private static final boolean[] ALL_REASONS = {true, true, true, true, true, true, true, true, true}; /** * Flag indicating whether support for the CRL distribution point * extension shall be enabled. Currently disabled by default for * compatibility and legal reasons. */ private final static boolean USE_CRLDP = AccessController.doPrivileged (new GetBooleanAction("com.sun.security.enableCRLDP")); // singleton instance private static final DistributionPointFetcher INSTANCE = new DistributionPointFetcher(); /** * Private instantiation only. */ private DistributionPointFetcher() {} /** * Return a DistributionPointFetcher instance. */ static DistributionPointFetcher getInstance() { return INSTANCE; } /** * Return the X509CRLs matching this selector. The selector must be * an X509CRLSelector with certificateChecking set. * * If CRLDP support is disabled, this method always returns an * empty set. */ Collection<X509CRL> getCRLs(X509CRLSelector selector, boolean signFlag, PublicKey prevKey, String provider, List<CertStore> certStores, boolean[] reasonsMask, Set<TrustAnchor> trustAnchors, Date validity) throws CertStoreException { if (USE_CRLDP == false) { return Collections.emptySet(); } X509Certificate cert = selector.getCertificateChecking(); if (cert == null) { return Collections.emptySet(); } try { X509CertImpl certImpl = X509CertImpl.toImpl(cert); if (debug != null) { debug.println("DistributionPointFetcher.getCRLs: Checking " + "CRLDPs for " + certImpl.getSubjectX500Principal()); } CRLDistributionPointsExtension ext = certImpl.getCRLDistributionPointsExtension(); if (ext == null) { if (debug != null) { debug.println("No CRLDP ext"); } return Collections.emptySet(); } List<DistributionPoint> points = (List<DistributionPoint>)ext.get( CRLDistributionPointsExtension.POINTS); Set<X509CRL> results = new HashSet<X509CRL>(); for (Iterator<DistributionPoint> t = points.iterator(); t.hasNext() && !Arrays.equals(reasonsMask, ALL_REASONS); ) { DistributionPoint point = t.next(); Collection<X509CRL> crls = getCRLs(selector, certImpl, point, reasonsMask, signFlag, prevKey, provider, certStores, trustAnchors, validity); results.addAll(crls); } if (debug != null) { debug.println("Returning " + results.size() + " CRLs"); } return results; } catch (CertificateException e) { return Collections.emptySet(); } catch (IOException e) { return Collections.emptySet(); } } /** * Download CRLs from the given distribution point, verify and return them. * See the top of the class for current limitations. */ private Collection<X509CRL> getCRLs(X509CRLSelector selector, X509CertImpl certImpl, DistributionPoint point, boolean[] reasonsMask, boolean signFlag, PublicKey prevKey, String provider, List<CertStore> certStores, Set<TrustAnchor> trustAnchors, Date validity) { // check for full name GeneralNames fullName = point.getFullName(); if (fullName == null) { // check for relative name RDN relativeName = point.getRelativeName(); if (relativeName == null) { return Collections.emptySet(); } try { GeneralNames crlIssuers = point.getCRLIssuer(); if (crlIssuers == null) { fullName = getFullNames ((X500Name) certImpl.getIssuerDN(), relativeName); } else { // should only be one CRL Issuer if (crlIssuers.size() != 1) { return Collections.emptySet(); } else { fullName = getFullNames ((X500Name) crlIssuers.get(0).getName(), relativeName); } } } catch (IOException ioe) { return Collections.emptySet(); } } Collection<X509CRL> possibleCRLs = new ArrayList<X509CRL>(); Collection<X509CRL> crls = new ArrayList<X509CRL>(2); for (Iterator<GeneralName> t = fullName.iterator(); t.hasNext(); ) { GeneralName name = t.next(); if (name.getType() == GeneralNameInterface.NAME_DIRECTORY) { X500Name x500Name = (X500Name) name.getName(); possibleCRLs.addAll( getCRLs(x500Name, certImpl.getIssuerX500Principal(), certStores)); } else if (name.getType() == GeneralNameInterface.NAME_URI) { URIName uriName = (URIName)name.getName(); X509CRL crl = getCRL(uriName); if (crl != null) { possibleCRLs.add(crl); } } } for (X509CRL crl : possibleCRLs) { try { // make sure issuer is not set // we check the issuer in verifyCRLs method selector.setIssuerNames(null); if (selector.match(crl) && verifyCRL(certImpl, point, crl, reasonsMask, signFlag, prevKey, provider, trustAnchors, certStores, validity)) { crls.add(crl); } } catch (Exception e) { // don't add the CRL if (debug != null) { debug.println("Exception verifying CRL: " + e.getMessage()); e.printStackTrace(); } } } return crls; } /** * Download CRL from given URI. */ private X509CRL getCRL(URIName name) { URI uri = name.getURI(); if (debug != null) { debug.println("Trying to fetch CRL from DP " + uri); } try { CertStore ucs = URICertStore.getInstance (new URICertStore.URICertStoreParameters(uri)); Collection<? extends CRL> crls = ucs.getCRLs(null); if (crls.isEmpty()) { return null; } else { return (X509CRL) crls.iterator().next(); } } catch (Exception e) { if (debug != null) { debug.println("Exception getting CRL from CertStore: " + e); e.printStackTrace(); } } return null; } /** * Fetch CRLs from certStores. */ private Collection<X509CRL> getCRLs(X500Name name, X500Principal certIssuer, List<CertStore> certStores) { if (debug != null) { debug.println("Trying to fetch CRL from DP " + name); } X509CRLSelector xcs = new X509CRLSelector(); xcs.addIssuer(name.asX500Principal()); xcs.addIssuer(certIssuer); Collection<X509CRL> crls = new ArrayList<X509CRL>(); for (CertStore store : certStores) { try { for (CRL crl : store.getCRLs(xcs)) { crls.add((X509CRL)crl); } } catch (CertStoreException cse) { // don't add the CRL if (debug != null) { debug.println("Non-fatal exception while retrieving " + "CRLs: " + cse); cse.printStackTrace(); } } } return crls; } /** * Verifies a CRL for the given certificate's Distribution Point to * ensure it is appropriate for checking the revocation status. * * @param certImpl the certificate whose revocation status is being checked * @param point one of the distribution points of the certificate * @param crl the CRL * @param reasonsMask the interim reasons mask * @param signFlag true if prevKey can be used to verify the CRL * @param prevKey the public key that verifies the certificate's signature * @param provider the Signature provider to use * @param trustAnchors a {@code Set} of {@code TrustAnchor}s * @param certStores a {@code List} of {@code CertStore}s to be used in * finding certificates and CRLs * @param validity the time for which the validity of the CRL issuer's * certification path should be determined * @return true if ok, false if not */ boolean verifyCRL(X509CertImpl certImpl, DistributionPoint point, X509CRL crl, boolean[] reasonsMask, boolean signFlag, PublicKey prevKey, String provider, Set<TrustAnchor> trustAnchors, List<CertStore> certStores, Date validity) throws CRLException, IOException { boolean indirectCRL = false; X509CRLImpl crlImpl = X509CRLImpl.toImpl(crl); IssuingDistributionPointExtension idpExt = crlImpl.getIssuingDistributionPointExtension(); X500Name certIssuer = (X500Name) certImpl.getIssuerDN(); X500Name crlIssuer = (X500Name) crlImpl.getIssuerDN(); // if crlIssuer is set, verify that it matches the issuer of the // CRL and the CRL contains an IDP extension with the indirectCRL // boolean asserted. Otherwise, verify that the CRL issuer matches the // certificate issuer. GeneralNames pointCrlIssuers = point.getCRLIssuer(); X500Name pointCrlIssuer = null; if (pointCrlIssuers != null) { if (idpExt == null || ((Boolean) idpExt.get (IssuingDistributionPointExtension.INDIRECT_CRL)).equals (Boolean.FALSE)) { return false; } boolean match = false; for (Iterator<GeneralName> t = pointCrlIssuers.iterator(); !match && t.hasNext(); ) { GeneralNameInterface name = t.next().getName(); if (crlIssuer.equals(name) == true) { pointCrlIssuer = (X500Name) name; match = true; } } if (match == false) { return false; } // we accept the case that a CRL issuer provide status // information for itself. if (issues(certImpl, crlImpl, provider)) { // reset the public key used to verify the CRL's signature prevKey = certImpl.getPublicKey(); } else { indirectCRL = true; } } else if (crlIssuer.equals(certIssuer) == false) { if (debug != null) { debug.println("crl issuer does not equal cert issuer"); } return false; } else { // in case of self-issued indirect CRL issuer. byte[] certAKID = certImpl.getExtensionValue( PKIXExtensions.AuthorityKey_Id.toString()); byte[] crlAKID = crlImpl.getExtensionValue( PKIXExtensions.AuthorityKey_Id.toString()); if (certAKID == null || crlAKID == null) { // cannot recognize indirect CRL without AKID // we accept the case that a CRL issuer provide status // information for itself. if (issues(certImpl, crlImpl, provider)) { // reset the public key used to verify the CRL's signature prevKey = certImpl.getPublicKey(); } } else if (!Arrays.equals(certAKID, crlAKID)) { // we accept the case that a CRL issuer provide status // information for itself. if (issues(certImpl, crlImpl, provider)) { // reset the public key used to verify the CRL's signature prevKey = certImpl.getPublicKey(); } else { indirectCRL = true; } } } if (!indirectCRL && !signFlag) { // cert's key cannot be used to verify the CRL return false; } if (idpExt != null) { DistributionPointName idpPoint = (DistributionPointName) idpExt.get(IssuingDistributionPointExtension.POINT); if (idpPoint != null) { GeneralNames idpNames = idpPoint.getFullName(); if (idpNames == null) { RDN relativeName = idpPoint.getRelativeName(); if (relativeName == null) { if (debug != null) { debug.println("IDP must be relative or full DN"); } return false; } if (debug != null) { debug.println("IDP relativeName:" + relativeName); } idpNames = getFullNames(crlIssuer, relativeName); } // if the DP name is present in the IDP CRL extension and the // DP field is present in the DP, then verify that one of the // names in the IDP matches one of the names in the DP if (point.getFullName() != null || point.getRelativeName() != null) { GeneralNames pointNames = point.getFullName(); if (pointNames == null) { RDN relativeName = point.getRelativeName(); if (relativeName == null) { if (debug != null) { debug.println("DP must be relative or full DN"); } return false; } if (debug != null) { debug.println("DP relativeName:" + relativeName); } if (indirectCRL) { if (pointCrlIssuers.size() != 1) { // RFC 3280: there must be only 1 CRL issuer // name when relativeName is present if (debug != null) { debug.println("must only be one CRL " + "issuer when relative name present"); } return false; } pointNames = getFullNames (pointCrlIssuer, relativeName); } else { pointNames = getFullNames(certIssuer, relativeName); } } boolean match = false; for (Iterator<GeneralName> i = idpNames.iterator(); !match && i.hasNext(); ) { GeneralNameInterface idpName = i.next().getName(); if (debug != null) { debug.println("idpName: " + idpName); } for (Iterator<GeneralName> p = pointNames.iterator(); !match && p.hasNext(); ) { GeneralNameInterface pointName = p.next().getName(); if (debug != null) { debug.println("pointName: " + pointName); } match = idpName.equals(pointName); } } if (!match) { if (debug != null) { debug.println("IDP name does not match DP name"); } return false; } // if the DP name is present in the IDP CRL extension and the // DP field is absent from the DP, then verify that one of the // names in the IDP matches one of the names in the crlIssuer // field of the DP } else { // verify that one of the names in the IDP matches one of // the names in the cRLIssuer of the cert's DP boolean match = false; for (Iterator<GeneralName> t = pointCrlIssuers.iterator(); !match && t.hasNext(); ) { GeneralNameInterface crlIssuerName = t.next().getName(); for (Iterator<GeneralName> i = idpNames.iterator(); !match && i.hasNext(); ) { GeneralNameInterface idpName = i.next().getName(); match = crlIssuerName.equals(idpName); } } if (!match) { return false; } } } // if the onlyContainsUserCerts boolean is asserted, verify that the // cert is not a CA cert Boolean b = (Boolean) idpExt.get(IssuingDistributionPointExtension.ONLY_USER_CERTS); if (b.equals(Boolean.TRUE) && certImpl.getBasicConstraints() != -1) { if (debug != null) { debug.println("cert must be a EE cert"); } return false; } // if the onlyContainsCACerts boolean is asserted, verify that the // cert is a CA cert b = (Boolean) idpExt.get(IssuingDistributionPointExtension.ONLY_CA_CERTS); if (b.equals(Boolean.TRUE) && certImpl.getBasicConstraints() == -1) { if (debug != null) { debug.println("cert must be a CA cert"); } return false; } // verify that the onlyContainsAttributeCerts boolean is not // asserted b = (Boolean) idpExt.get (IssuingDistributionPointExtension.ONLY_ATTRIBUTE_CERTS); if (b.equals(Boolean.TRUE)) { if (debug != null) { debug.println("cert must not be an AA cert"); } return false; }Lines 1–500 of 736. Load more
/* * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.security.provider.certpath; import java.io.*; import java.net.URI; import java.util.*; import java.security.*; import java.security.cert.*; import javax.security.auth.x500.X500Principal; import sun.security.action.GetBooleanAction; import sun.security.util.Debug; import sun.security.util.DerOutputStream; import sun.security.x509.*; /** * Class to obtain CRLs via the CRLDistributionPoints extension. * Note that the functionality of this class must be explicitly enabled * via a system property, see the USE_CRLDP variable below. * * This class uses the URICertStore class to fetch CRLs. The URICertStore * class also implements CRL caching: see the class description for more * information. * * @author Andreas Sterbenz * @author Sean Mullan * @since 1.4.2 */ class DistributionPointFetcher { private static final Debug debug = Debug.getInstance("certpath"); private static final boolean[] ALL_REASONS = {true, true, true, true, true, true, true, true, true}; /** * Flag indicating whether support for the CRL distribution point * extension shall be enabled. Currently disabled by default for * compatibility and legal reasons. */ private final static boolean USE_CRLDP = AccessController.doPrivileged (new GetBooleanAction("com.sun.security.enableCRLDP")); // singleton instance private static final DistributionPointFetcher INSTANCE = new DistributionPointFetcher(); /** * Private instantiation only. */ private DistributionPointFetcher() {} /** * Return a DistributionPointFetcher instance. */ static DistributionPointFetcher getInstance() { return INSTANCE; } /** * Return the X509CRLs matching this selector. The selector must be * an X509CRLSelector with certificateChecking set. * * If CRLDP support is disabled, this method always returns an * empty set. */ Collection<X509CRL> getCRLs(X509CRLSelector selector, boolean signFlag, PublicKey prevKey, String provider, List<CertStore> certStores, boolean[] reasonsMask, Set<TrustAnchor> trustAnchors, Date validity) throws CertStoreException { if (USE_CRLDP == false) { return Collections.emptySet(); } X509Certificate cert = selector.getCertificateChecking(); if (cert == null) { return Collections.emptySet(); } try { X509CertImpl certImpl = X509CertImpl.toImpl(cert); if (debug != null) { debug.println("DistributionPointFetcher.getCRLs: Checking " + "CRLDPs for " + certImpl.getSubjectX500Principal()); } CRLDistributionPointsExtension ext = certImpl.getCRLDistributionPointsExtension(); if (ext == null) { if (debug != null) { debug.println("No CRLDP ext"); } return Collections.emptySet(); } List<DistributionPoint> points = (List<DistributionPoint>)ext.get( CRLDistributionPointsExtension.POINTS); Set<X509CRL> results = new HashSet<X509CRL>(); for (Iterator<DistributionPoint> t = points.iterator(); t.hasNext() && !Arrays.equals(reasonsMask, ALL_REASONS); ) { DistributionPoint point = t.next(); Collection<X509CRL> crls = getCRLs(selector, certImpl, point, reasonsMask, signFlag, prevKey, provider, certStores, trustAnchors, validity); results.addAll(crls); } if (debug != null) { debug.println("Returning " + results.size() + " CRLs"); } return results; } catch (CertificateException e) { return Collections.emptySet(); } catch (IOException e) { return Collections.emptySet(); } } /** * Download CRLs from the given distribution point, verify and return them. * See the top of the class for current limitations. */ private Collection<X509CRL> getCRLs(X509CRLSelector selector, X509CertImpl certImpl, DistributionPoint point, boolean[] reasonsMask, boolean signFlag, PublicKey prevKey, String provider, List<CertStore> certStores, Set<TrustAnchor> trustAnchors, Date validity) { // check for full name GeneralNames fullName = point.getFullName(); if (fullName == null) { // check for relative name RDN relativeName = point.getRelativeName(); if (relativeName == null) { return Collections.emptySet(); } try { GeneralNames crlIssuers = point.getCRLIssuer(); if (crlIssuers == null) { fullName = getFullNames ((X500Name) certImpl.getIssuerDN(), relativeName); } else { // should only be one CRL Issuer if (crlIssuers.size() != 1) { return Collections.emptySet(); } else { fullName = getFullNames ((X500Name) crlIssuers.get(0).getName(), relativeName); } } } catch (IOException ioe) { return Collections.emptySet(); } } Collection<X509CRL> possibleCRLs = new ArrayList<X509CRL>(); Collection<X509CRL> crls = new ArrayList<X509CRL>(2); for (Iterator<GeneralName> t = fullName.iterator(); t.hasNext(); ) { GeneralName name = t.next(); if (name.getType() == GeneralNameInterface.NAME_DIRECTORY) { X500Name x500Name = (X500Name) name.getName(); possibleCRLs.addAll( getCRLs(x500Name, certImpl.getIssuerX500Principal(), certStores)); } else if (name.getType() == GeneralNameInterface.NAME_URI) { URIName uriName = (URIName)name.getName(); X509CRL crl = getCRL(uriName); if (crl != null) { possibleCRLs.add(crl); } } } for (X509CRL crl : possibleCRLs) { try { // make sure issuer is not set // we check the issuer in verifyCRLs method selector.setIssuerNames(null); if (selector.match(crl) && verifyCRL(certImpl, point, crl, reasonsMask, signFlag, prevKey, provider, trustAnchors, certStores, validity)) { crls.add(crl); } } catch (Exception e) { // don't add the CRL if (debug != null) { debug.println("Exception verifying CRL: " + e.getMessage()); e.printStackTrace(); } } } return crls; } /** * Download CRL from given URI. */ private X509CRL getCRL(URIName name) { URI uri = name.getURI(); if (debug != null) { debug.println("Trying to fetch CRL from DP " + uri); } try { CertStore ucs = URICertStore.getInstance (new URICertStore.URICertStoreParameters(uri)); Collection<? extends CRL> crls = ucs.getCRLs(null); if (crls.isEmpty()) { return null; } else { return (X509CRL) crls.iterator().next(); } } catch (Exception e) { if (debug != null) { debug.println("Exception getting CRL from CertStore: " + e); e.printStackTrace(); } } return null; } /** * Fetch CRLs from certStores. */ private Collection<X509CRL> getCRLs(X500Name name, X500Principal certIssuer, List<CertStore> certStores) { if (debug != null) { debug.println("Trying to fetch CRL from DP " + name); } X509CRLSelector xcs = new X509CRLSelector(); xcs.addIssuer(name.asX500Principal()); xcs.addIssuer(certIssuer); Collection<X509CRL> crls = new ArrayList<X509CRL>(); for (CertStore store : certStores) { try { for (CRL crl : store.getCRLs(xcs)) { crls.add((X509CRL)crl); } } catch (CertStoreException cse) { // don't add the CRL if (debug != null) { debug.println("Non-fatal exception while retrieving " + "CRLs: " + cse); cse.printStackTrace(); } } } return crls; } /** * Verifies a CRL for the given certificate's Distribution Point to * ensure it is appropriate for checking the revocation status. * * @param certImpl the certificate whose revocation status is being checked * @param point one of the distribution points of the certificate * @param crl the CRL * @param reasonsMask the interim reasons mask * @param signFlag true if prevKey can be used to verify the CRL * @param prevKey the public key that verifies the certificate's signature * @param provider the Signature provider to use * @param trustAnchors a {@code Set} of {@code TrustAnchor}s * @param certStores a {@code List} of {@code CertStore}s to be used in * finding certificates and CRLs * @param validity the time for which the validity of the CRL issuer's * certification path should be determined * @return true if ok, false if not */ boolean verifyCRL(X509CertImpl certImpl, DistributionPoint point, X509CRL crl, boolean[] reasonsMask, boolean signFlag, PublicKey prevKey, String provider, Set<TrustAnchor> trustAnchors, List<CertStore> certStores, Date validity) throws CRLException, IOException { boolean indirectCRL = false; X509CRLImpl crlImpl = X509CRLImpl.toImpl(crl); IssuingDistributionPointExtension idpExt = crlImpl.getIssuingDistributionPointExtension(); X500Name certIssuer = (X500Name) certImpl.getIssuerDN(); X500Name crlIssuer = (X500Name) crlImpl.getIssuerDN(); // if crlIssuer is set, verify that it matches the issuer of the // CRL and the CRL contains an IDP extension with the indirectCRL // boolean asserted. Otherwise, verify that the CRL issuer matches the // certificate issuer. GeneralNames pointCrlIssuers = point.getCRLIssuer(); X500Name pointCrlIssuer = null; if (pointCrlIssuers != null) { if (idpExt == null || ((Boolean) idpExt.get (IssuingDistributionPointExtension.INDIRECT_CRL)).equals (Boolean.FALSE)) { return false; } boolean match = false; for (Iterator<GeneralName> t = pointCrlIssuers.iterator(); !match && t.hasNext(); ) { GeneralNameInterface name = t.next().getName(); if (crlIssuer.equals(name) == true) { pointCrlIssuer = (X500Name) name; match = true; } } if (match == false) { return false; } // we accept the case that a CRL issuer provide status // information for itself. if (issues(certImpl, crlImpl, provider)) { // reset the public key used to verify the CRL's signature prevKey = certImpl.getPublicKey(); } else { indirectCRL = true; } } else if (crlIssuer.equals(certIssuer) == false) { if (debug != null) { debug.println("crl issuer does not equal cert issuer"); } return false; } else { // in case of self-issued indirect CRL issuer. byte[] certAKID = certImpl.getExtensionValue( PKIXExtensions.AuthorityKey_Id.toString()); byte[] crlAKID = crlImpl.getExtensionValue( PKIXExtensions.AuthorityKey_Id.toString()); if (certAKID == null || crlAKID == null) { // cannot recognize indirect CRL without AKID // we accept the case that a CRL issuer provide status // information for itself. if (issues(certImpl, crlImpl, provider)) { // reset the public key used to verify the CRL's signature prevKey = certImpl.getPublicKey(); } } else if (!Arrays.equals(certAKID, crlAKID)) { // we accept the case that a CRL issuer provide status // information for itself. if (issues(certImpl, crlImpl, provider)) { // reset the public key used to verify the CRL's signature prevKey = certImpl.getPublicKey(); } else { indirectCRL = true; } } } if (!indirectCRL && !signFlag) { // cert's key cannot be used to verify the CRL return false; } if (idpExt != null) { DistributionPointName idpPoint = (DistributionPointName) idpExt.get(IssuingDistributionPointExtension.POINT); if (idpPoint != null) { GeneralNames idpNames = idpPoint.getFullName(); if (idpNames == null) { RDN relativeName = idpPoint.getRelativeName(); if (relativeName == null) { if (debug != null) { debug.println("IDP must be relative or full DN"); } return false; } if (debug != null) { debug.println("IDP relativeName:" + relativeName); } idpNames = getFullNames(crlIssuer, relativeName); } // if the DP name is present in the IDP CRL extension and the // DP field is present in the DP, then verify that one of the // names in the IDP matches one of the names in the DP if (point.getFullName() != null || point.getRelativeName() != null) { GeneralNames pointNames = point.getFullName(); if (pointNames == null) { RDN relativeName = point.getRelativeName(); if (relativeName == null) { if (debug != null) { debug.println("DP must be relative or full DN"); } return false; } if (debug != null) { debug.println("DP relativeName:" + relativeName); } if (indirectCRL) { if (pointCrlIssuers.size() != 1) { // RFC 3280: there must be only 1 CRL issuer // name when relativeName is present if (debug != null) { debug.println("must only be one CRL " + "issuer when relative name present"); } return false; } pointNames = getFullNames (pointCrlIssuer, relativeName); } else { pointNames = getFullNames(certIssuer, relativeName); } } boolean match = false; for (Iterator<GeneralName> i = idpNames.iterator(); !match && i.hasNext(); ) { GeneralNameInterface idpName = i.next().getName(); if (debug != null) { debug.println("idpName: " + idpName); } for (Iterator<GeneralName> p = pointNames.iterator(); !match && p.hasNext(); ) { GeneralNameInterface pointName = p.next().getName(); if (debug != null) { debug.println("pointName: " + pointName); } match = idpName.equals(pointName); } } if (!match) { if (debug != null) { debug.println("IDP name does not match DP name"); } return false; } // if the DP name is present in the IDP CRL extension and the // DP field is absent from the DP, then verify that one of the // names in the IDP matches one of the names in the crlIssuer // field of the DP } else { // verify that one of the names in the IDP matches one of // the names in the cRLIssuer of the cert's DP boolean match = false; for (Iterator<GeneralName> t = pointCrlIssuers.iterator(); !match && t.hasNext(); ) { GeneralNameInterface crlIssuerName = t.next().getName(); for (Iterator<GeneralName> i = idpNames.iterator(); !match && i.hasNext(); ) { GeneralNameInterface idpName = i.next().getName(); match = crlIssuerName.equals(idpName); } } if (!match) { return false; } } } // if the onlyContainsUserCerts boolean is asserted, verify that the // cert is not a CA cert Boolean b = (Boolean) idpExt.get(IssuingDistributionPointExtension.ONLY_USER_CERTS); if (b.equals(Boolean.TRUE) && certImpl.getBasicConstraints() != -1) { if (debug != null) { debug.println("cert must be a EE cert"); } return false; } // if the onlyContainsCACerts boolean is asserted, verify that the // cert is a CA cert b = (Boolean) idpExt.get(IssuingDistributionPointExtension.ONLY_CA_CERTS); if (b.equals(Boolean.TRUE) && certImpl.getBasicConstraints() == -1) { if (debug != null) { debug.println("cert must be a CA cert"); } return false; } // verify that the onlyContainsAttributeCerts boolean is not // asserted b = (Boolean) idpExt.get (IssuingDistributionPointExtension.ONLY_ATTRIBUTE_CERTS); if (b.equals(Boolean.TRUE)) { if (debug != null) { debug.println("cert must not be an AA cert"); } return false; }