提交 03612b02 编写于 作者: M mullan

6854712: Revocation checking enhancements (JEP-124)

6637288: Add OCSP support to PKIX CertPathBuilder implementation
7126011: ReverseBuilder.getMatchingCACerts may throws NPE
Reviewed-by: xuelei
上级 f0352f09
/* /*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -45,15 +45,28 @@ import sun.security.jca.GetInstance.Instance; ...@@ -45,15 +45,28 @@ import sun.security.jca.GetInstance.Instance;
* one of the static <code>getInstance</code> methods, passing in the * one of the static <code>getInstance</code> methods, passing in the
* algorithm name of the <code>CertPathBuilder</code> desired and optionally * algorithm name of the <code>CertPathBuilder</code> desired and optionally
* the name of the provider desired. * the name of the provider desired.
* <p> *
* Once a <code>CertPathBuilder</code> object has been created, certification * <p>Once a <code>CertPathBuilder</code> object has been created, certification
* paths can be constructed by calling the {@link #build build} method and * paths can be constructed by calling the {@link #build build} method and
* passing it an algorithm-specific set of parameters. If successful, the * passing it an algorithm-specific set of parameters. If successful, the
* result (including the <code>CertPath</code> that was built) is returned * result (including the <code>CertPath</code> that was built) is returned
* in an object that implements the <code>CertPathBuilderResult</code> * in an object that implements the <code>CertPathBuilderResult</code>
* interface. * interface.
* *
* <p> Every implementation of the Java platform is required to support the * <p>The {@link #getRevocationChecker} method allows an application to specify
* additional algorithm-specific parameters and options used by the
* {@code CertPathBuilder} when checking the revocation status of certificates.
* Here is an example demonstrating how it is used with the PKIX algorithm:
*
* <pre>
* CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
* PKIXRevocationChecker rc = (PKIXRevocationChecker)cpb.getRevocationChecker();
* rc.setOptions(EnumSet.of(Option.PREFER_CRLS));
* params.addCertPathChecker(rc);
* CertPathBuilderResult cpbr = cpb.build(params);
* </pre>
*
* <p>Every implementation of the Java platform is required to support the
* following standard <code>CertPathBuilder</code> algorithm: * following standard <code>CertPathBuilder</code> algorithm:
* <ul> * <ul>
* <li><tt>PKIX</tt></li> * <li><tt>PKIX</tt></li>
...@@ -96,10 +109,9 @@ public class CertPathBuilder { ...@@ -96,10 +109,9 @@ public class CertPathBuilder {
* </pre> * </pre>
*/ */
private static final String CPB_TYPE = "certpathbuilder.type"; private static final String CPB_TYPE = "certpathbuilder.type";
private static final Debug debug = Debug.getInstance("certpath"); private final CertPathBuilderSpi builderSpi;
private CertPathBuilderSpi builderSpi; private final Provider provider;
private Provider provider; private final String algorithm;
private String algorithm;
/** /**
* Creates a <code>CertPathBuilder</code> object of the given algorithm, * Creates a <code>CertPathBuilder</code> object of the given algorithm,
...@@ -290,15 +302,30 @@ public class CertPathBuilder { ...@@ -290,15 +302,30 @@ public class CertPathBuilder {
* if no such property exists. * if no such property exists.
*/ */
public final static String getDefaultType() { public final static String getDefaultType() {
String cpbtype; String cpbtype =
cpbtype = AccessController.doPrivileged(new PrivilegedAction<String>() { AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() { public String run() {
return Security.getProperty(CPB_TYPE); return Security.getProperty(CPB_TYPE);
} }
}); });
if (cpbtype == null) { return (cpbtype == null) ? "PKIX" : cpbtype;
cpbtype = "PKIX"; }
}
return cpbtype; /**
* Returns a {@code CertPathChecker} that the encapsulated
* {@code CertPathBuilderSpi} implementation uses to check the revocation
* status of certificates. A PKIX implementation returns objects of
* type {@code PKIXRevocationChecker}.
*
* <p>The primary purpose of this method is to allow callers to specify
* additional input parameters and options specific to revocation checking.
* See the class description for an example.
*
* @throws UnsupportedOperationException if the service provider does not
* support this method
* @since 1.8
*/
public final CertPathChecker getRevocationChecker() {
return builderSpi.engineGetRevocationChecker();
} }
} }
/* /*
* Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -72,4 +72,25 @@ public abstract class CertPathBuilderSpi { ...@@ -72,4 +72,25 @@ public abstract class CertPathBuilderSpi {
*/ */
public abstract CertPathBuilderResult engineBuild(CertPathParameters params) public abstract CertPathBuilderResult engineBuild(CertPathParameters params)
throws CertPathBuilderException, InvalidAlgorithmParameterException; throws CertPathBuilderException, InvalidAlgorithmParameterException;
/**
* Returns a {@code CertPathChecker} that this implementation uses to
* check the revocation status of certificates. A PKIX implementation
* returns objects of type {@code PKIXRevocationChecker}.
*
* <p>The primary purpose of this method is to allow callers to specify
* additional input parameters and options specific to revocation checking.
* See the class description of {@code CertPathBuilder} for an example.
*
* <p>This method was added to version 1.8 of the Java Platform Standard
* Edition. In order to maintain backwards compatibility with existing
* service providers, this method cannot be abstract and by default throws
* an {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException if this method is not supported
* @since 1.8
*/
public CertPathChecker engineGetRevocationChecker() {
throw new UnsupportedOperationException();
}
} }
/*
* Copyright (c) 2012, 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 java.security.cert;
/**
* <p>Performs one or more checks on each {@code Certificate} of a
* {@code CertPath}.
*
* <p>A {@code CertPathChecker} implementation is typically created to extend
* a certification path validation algorithm. For example, an implementation
* may check for and process a critical private extension of each certificate
* in a certification path.
*
* @since 1.8
*/
public interface CertPathChecker {
/**
* Initializes the internal state of this {@code CertPathChecker}.
*
* <p>The {@code forward} flag specifies the order that certificates will
* be passed to the {@link #check check} method (forward or reverse).
*
* @param forward the order that certificates are presented to the
* {@code check} method. If {@code true}, certificates are
* presented from target to trust anchor (forward); if
* {@code false}, from trust anchor to target (reverse).
* @throws CertPathValidatorException if this {@code CertPathChecker} is
* unable to check certificates in the specified order
*/
void init(boolean forward) throws CertPathValidatorException;
/**
* Indicates if forward checking is supported. Forward checking refers
* to the ability of the {@code CertPathChecker} to perform its checks
* when certificates are presented to the {@code check} method in the
* forward direction (from target to trust anchor).
*
* @return {@code true} if forward checking is supported, {@code false}
* otherwise
*/
boolean isForwardCheckingSupported();
/**
* Performs the check(s) on the specified certificate using its internal
* state. The certificates are presented in the order specified by the
* {@code init} method.
*
* @param cert the {@code Certificate} to be checked
* @throws CertPathValidatorException if the specified certificate does
* not pass the check
*/
void check(Certificate cert) throws CertPathValidatorException;
}
/* /*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -46,15 +46,29 @@ import sun.security.jca.GetInstance.Instance; ...@@ -46,15 +46,29 @@ import sun.security.jca.GetInstance.Instance;
* call one of the static <code>getInstance</code> methods, passing in the * call one of the static <code>getInstance</code> methods, passing in the
* algorithm name of the <code>CertPathValidator</code> desired and * algorithm name of the <code>CertPathValidator</code> desired and
* optionally the name of the provider desired. * optionally the name of the provider desired.
* <p> *
* Once a <code>CertPathValidator</code> object has been created, it can * <p>Once a <code>CertPathValidator</code> object has been created, it can
* be used to validate certification paths by calling the {@link #validate * be used to validate certification paths by calling the {@link #validate
* validate} method and passing it the <code>CertPath</code> to be validated * validate} method and passing it the <code>CertPath</code> to be validated
* and an algorithm-specific set of parameters. If successful, the result is * and an algorithm-specific set of parameters. If successful, the result is
* returned in an object that implements the * returned in an object that implements the
* <code>CertPathValidatorResult</code> interface. * <code>CertPathValidatorResult</code> interface.
* *
* <p> Every implementation of the Java platform is required to support the * <p>The {@link #getRevocationChecker} method allows an application to specify
* additional algorithm-specific parameters and options used by the
* {@code CertPathValidator} when checking the revocation status of
* certificates. Here is an example demonstrating how it is used with the PKIX
* algorithm:
*
* <pre>
* CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
* PKIXRevocationChecker rc = (PKIXRevocationChecker)cpv.getRevocationChecker();
* rc.setOptions(EnumSet.of(Option.SOFT_FAIL));
* params.addCertPathChecker(rc);
* CertPathValidatorResult cpvr = cpv.validate(path, params);
* </pre>
*
* <p>Every implementation of the Java platform is required to support the
* following standard <code>CertPathValidator</code> algorithm: * following standard <code>CertPathValidator</code> algorithm:
* <ul> * <ul>
* <li><tt>PKIX</tt></li> * <li><tt>PKIX</tt></li>
...@@ -96,10 +110,9 @@ public class CertPathValidator { ...@@ -96,10 +110,9 @@ public class CertPathValidator {
* </pre> * </pre>
*/ */
private static final String CPV_TYPE = "certpathvalidator.type"; private static final String CPV_TYPE = "certpathvalidator.type";
private static final Debug debug = Debug.getInstance("certpath"); private final CertPathValidatorSpi validatorSpi;
private CertPathValidatorSpi validatorSpi; private final Provider provider;
private Provider provider; private final String algorithm;
private String algorithm;
/** /**
* Creates a <code>CertPathValidator</code> object of the given algorithm, * Creates a <code>CertPathValidator</code> object of the given algorithm,
...@@ -301,15 +314,30 @@ public class CertPathValidator { ...@@ -301,15 +314,30 @@ public class CertPathValidator {
* if no such property exists. * if no such property exists.
*/ */
public final static String getDefaultType() { public final static String getDefaultType() {
String cpvtype; String cpvtype =
cpvtype = AccessController.doPrivileged(new PrivilegedAction<String>() { AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() { public String run() {
return Security.getProperty(CPV_TYPE); return Security.getProperty(CPV_TYPE);
} }
}); });
if (cpvtype == null) { return (cpvtype == null) ? "PKIX" : cpvtype;
cpvtype = "PKIX"; }
}
return cpvtype; /**
* Returns a {@code CertPathChecker} that the encapsulated
* {@code CertPathValidatorSpi} implementation uses to check the revocation
* status of certificates. A PKIX implementation returns objects of
* type {@code PKIXRevocationChecker}.
*
* <p>The primary purpose of this method is to allow callers to specify
* additional input parameters and options specific to revocation checking.
* See the class description for an example.
*
* @throws UnsupportedOperationException if the service provider does not
* support this method
* @since 1.8
*/
public final CertPathChecker getRevocationChecker() {
return validatorSpi.engineGetRevocationChecker();
} }
} }
/* /*
* Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -82,4 +82,25 @@ public abstract class CertPathValidatorSpi { ...@@ -82,4 +82,25 @@ public abstract class CertPathValidatorSpi {
public abstract CertPathValidatorResult public abstract CertPathValidatorResult
engineValidate(CertPath certPath, CertPathParameters params) engineValidate(CertPath certPath, CertPathParameters params)
throws CertPathValidatorException, InvalidAlgorithmParameterException; throws CertPathValidatorException, InvalidAlgorithmParameterException;
/**
* Returns a {@code CertPathChecker} that this implementation uses to
* check the revocation status of certificates. A PKIX implementation
* returns objects of type {@code PKIXRevocationChecker}.
*
* <p>The primary purpose of this method is to allow callers to specify
* additional input parameters and options specific to revocation checking.
* See the class description of {@code CertPathValidator} for an example.
*
* <p>This method was added to version 1.8 of the Java Platform Standard
* Edition. In order to maintain backwards compatibility with existing
* service providers, this method cannot be abstract and by default throws
* an {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException if this method is not supported
* @since 1.8
*/
public CertPathChecker engineGetRevocationChecker() {
throw new UnsupportedOperationException();
}
} }
/* /*
* Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -87,7 +87,8 @@ import java.util.Set; ...@@ -87,7 +87,8 @@ import java.util.Set;
* @author Yassir Elley * @author Yassir Elley
* @author Sean Mullan * @author Sean Mullan
*/ */
public abstract class PKIXCertPathChecker implements Cloneable { public abstract class PKIXCertPathChecker
implements CertPathChecker, Cloneable {
/** /**
* Default constructor. * Default constructor.
...@@ -111,6 +112,7 @@ public abstract class PKIXCertPathChecker implements Cloneable { ...@@ -111,6 +112,7 @@ public abstract class PKIXCertPathChecker implements Cloneable {
* the specified order; it should never be thrown if the forward flag * the specified order; it should never be thrown if the forward flag
* is false since reverse checking must be supported * is false since reverse checking must be supported
*/ */
@Override
public abstract void init(boolean forward) public abstract void init(boolean forward)
throws CertPathValidatorException; throws CertPathValidatorException;
...@@ -123,6 +125,7 @@ public abstract class PKIXCertPathChecker implements Cloneable { ...@@ -123,6 +125,7 @@ public abstract class PKIXCertPathChecker implements Cloneable {
* @return <code>true</code> if forward checking is supported, * @return <code>true</code> if forward checking is supported,
* <code>false</code> otherwise * <code>false</code> otherwise
*/ */
@Override
public abstract boolean isForwardCheckingSupported(); public abstract boolean isForwardCheckingSupported();
/** /**
...@@ -162,6 +165,17 @@ public abstract class PKIXCertPathChecker implements Cloneable { ...@@ -162,6 +165,17 @@ public abstract class PKIXCertPathChecker implements Cloneable {
Collection<String> unresolvedCritExts) Collection<String> unresolvedCritExts)
throws CertPathValidatorException; throws CertPathValidatorException;
/**
* {@inheritDoc}
*
* <p>This implementation calls
* {@code check(cert, java.util.Collections.<String>emptySet())}.
*/
@Override
public void check(Certificate cert) throws CertPathValidatorException {
check(cert, java.util.Collections.<String>emptySet());
}
/** /**
* Returns a clone of this object. Calls the <code>Object.clone()</code> * Returns a clone of this object. Calls the <code>Object.clone()</code>
* method. * method.
...@@ -170,6 +184,7 @@ public abstract class PKIXCertPathChecker implements Cloneable { ...@@ -170,6 +184,7 @@ public abstract class PKIXCertPathChecker implements Cloneable {
* *
* @return a copy of this <code>PKIXCertPathChecker</code> * @return a copy of this <code>PKIXCertPathChecker</code>
*/ */
@Override
public Object clone() { public Object clone() {
try { try {
return super.clone(); return super.clone();
......
/*
* Copyright (c) 2012, 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 java.security.cert;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* A {@code PKIXCertPathChecker} for checking the revocation status of
* certificates with the PKIX algorithm.
*
* <p>A {@code PKIXRevocationChecker} checks the revocation status of
* certificates with the Online Certificate Status Protocol (OCSP) or
* Certificate Revocation Lists (CRLs). OCSP is described in RFC 2560 and
* is a network protocol for determining the status of a certificate. A CRL
* is a time-stamped list identifying revoked certificates, and RFC 5280
* describes an algorithm for determining the revocation status of certificates
* using CRLs.
*
* <p>Each {@code PKIXRevocationChecker} must be able to check the revocation
* status of certificates with OCSP and CRLs. By default, OCSP is the
* preferred mechanism for checking revocation status, with CRLs as the
* fallback mechanism. However, this preference can be switched to CRLs with
* the {@link Option.PREFER_CRLS} option.
*
* <p>A {@code PKIXRevocationChecker} is obtained by calling the
* {@link CertPathValidator#getRevocationChecker getRevocationChecker} method
* of a PKIX {@code CertPathValidator}. Additional parameters and options
* specific to revocation can be set (by calling {@link #setOCSPResponder}
* method for instance). The {@code PKIXRevocationChecker} is added to
* a {@code PKIXParameters} object using the
* {@link PKIXParameters#addCertPathChecker addCertPathChecker}
* or {@link PKIXParameters#setCertPathCheckers setCertPathCheckers} method,
* and then the {@code PKIXParameters} is passed along with the {@code CertPath}
* to be validated to the {@link CertPathValidator#validate validate} method
* of a PKIX {@code CertPathValidator}. When supplying a revocation checker in
* this manner, do not enable the default revocation checking mechanism (by
* calling {@link PKIXParameters#setRevocationEnabled}.
*
* <p>Note that when a {@code PKIXRevocationChecker} is added to
* {@code PKIXParameters}, it clones the {@code PKIXRevocationChecker};
* thus any subsequent modifications to the {@code PKIXRevocationChecker}
* have no effect.
*
* <p>Any parameter that is not set (or is set to {@code null}) will be set to
* the default value for that parameter.
*
* <p><b>Concurrent Access</b>
*
* <p>Unless otherwise specified, the methods defined in this class are not
* thread-safe. Multiple threads that need to access a single object
* concurrently should synchronize amongst themselves and provide the
* necessary locking. Multiple threads each manipulating separate objects
* need not synchronize.
*
* @since 1.8
*/
public abstract class PKIXRevocationChecker extends PKIXCertPathChecker {
private URI ocspResponder;
private X509Certificate ocspResponderCert;
private List<Extension> ocspExtensions = Collections.<Extension>emptyList();
private Map<X509Certificate, byte[]> ocspStapled = Collections.emptyMap();
private Set<Option> options = Collections.emptySet();
protected PKIXRevocationChecker() {}
/**
* Sets the URI that identifies the location of the OCSP responder. This
* overrides the {@code ocsp.responderURL} security property and any
* responder specified in a certificate's Authority Information Access
* Extension, as defined in RFC 5280.
*
* @param uri the responder URI
*/
public void setOCSPResponder(URI uri) {
this.ocspResponder = uri;
}
/**
* Gets the URI that identifies the location of the OCSP responder. This
* overrides the {@code ocsp.responderURL} security property. If this
* parameter or the {@code ocsp.responderURL} property is not set, the
* location is determined from the certificate's Authority Information
* Access Extension, as defined in RFC 5280.
*
* @return the responder URI, or {@code null} if not set
*/
public URI getOCSPResponder() {
return ocspResponder;
}
/**
* Sets the OCSP responder's certificate. This overrides the
* {@code ocsp.responderCertSubjectName},
* {@code ocsp.responderCertIssuerName},
* and {@code ocsp.responderCertSerialNumber} security properties.
*
* @param cert the responder's certificate
*/
public void setOCSPResponderCert(X509Certificate cert) {
this.ocspResponderCert = cert;
}
/**
* Gets the OCSP responder's certificate. This overrides the
* {@code ocsp.responderCertSubjectName},
* {@code ocsp.responderCertIssuerName},
* and {@code ocsp.responderCertSerialNumber} security properties. If this
* parameter or the aforementioned properties are not set, then the
* responder's certificate is determined as specified in RFC 2560.
*
* @return the responder's certificate, or {@code null} if not set
*/
public X509Certificate getOCSPResponderCert() {
return ocspResponderCert;
}
// request extensions; single extensions not supported
/**
* Sets the optional OCSP request extensions.
*
* @param extensions a list of extensions. The list is copied to protect
* against subsequent modification.
*/
public void setOCSPExtensions(List<Extension> extensions)
{
this.ocspExtensions = (extensions == null)
? Collections.<Extension>emptyList()
: new ArrayList<Extension>(extensions);
}
/**
* Gets the optional OCSP request extensions.
*
* @return an unmodifiable list of extensions. Returns an empty list if no
* extensions have been specified.
*/
public List<Extension> getOCSPExtensions() {
return Collections.unmodifiableList(ocspExtensions);
}
/**
* Sets the stapled OCSP responses. These responses are used to determine
* the revocation status of the specified certificates when OCSP is used.
*
* @param responses a map of stapled OCSP responses. Each key is an
* {@code X509Certificate} that maps to the corresponding
* DER-encoded OCSP response for that certificate. A deep copy of
* the map is performed to protect against subsequent modification.
*/
public void setOCSPStapledResponses(Map<X509Certificate, byte[]> responses)
{
if (responses == null) {
this.ocspStapled = Collections.<X509Certificate, byte[]>emptyMap();
} else {
Map<X509Certificate, byte[]> copy = new HashMap<>(responses.size());
for (Map.Entry<X509Certificate, byte[]> e : responses.entrySet()) {
copy.put(e.getKey(), e.getValue().clone());
}
this.ocspStapled = copy;
}
}
/**
* Gets the stapled OCSP responses. These responses are used to determine
* the revocation status of the specified certificates when OCSP is used.
*
* @return a map of stapled OCSP responses. Each key is an
* {@code X509Certificate} that maps to the corresponding
* DER-encoded OCSP response for that certificate. A deep copy of
* the map is returned to protect against subsequent modification.
* Returns an empty map if no responses have been specified.
*/
public Map<X509Certificate, byte[]> getOCSPStapledResponses() {
Map<X509Certificate, byte[]> copy = new HashMap<>(ocspStapled.size());
for (Map.Entry<X509Certificate, byte[]> e : ocspStapled.entrySet()) {
copy.put(e.getKey(), e.getValue().clone());
}
return copy;
}
/**
* Sets the revocation options.
*
* @param options a set of revocation options. The set is copied to protect
* against subsequent modification.
*/
public void setOptions(Set<Option> options) {
this.options = (options == null)
? Collections.<Option>emptySet()
: new HashSet<Option>(options);
}
/**
* Gets the revocation options.
*
* @return an unmodifiable set of revocation options, or an empty set if
* none are specified
*/
public Set<Option> getOptions() {
return Collections.unmodifiableSet(options);
}
@Override
public Object clone() {
PKIXRevocationChecker copy = (PKIXRevocationChecker)super.clone();
copy.ocspExtensions = new ArrayList<>(ocspExtensions);
copy.ocspStapled = new HashMap<>(ocspStapled);
// deep-copy the encoded stapled responses, since they are mutable
for (Map.Entry<X509Certificate, byte[]> entry :
copy.ocspStapled.entrySet())
{
byte[] encoded = entry.getValue();
entry.setValue(encoded.clone());
}
copy.options = new HashSet<>(options);
return copy;
}
/**
* Various revocation options that can be specified for the revocation
* checking mechanism.
*/
public enum Option {
/**
* Only check the revocation status of end-entity certificates.
*/
ONLY_END_ENTITY,
/**
* Prefer CRLs to OSCP. The default behavior is to prefer OCSP. Each
* PKIX implementation should document further details of their
* specific preference rules and fallback policies.
*/
PREFER_CRLS,
/**
* Ignore network failures. The default behavior is to consider it a
* failure if the revocation status of a certificate cannot be obtained
* due to a network error. This option applies to both OCSP and CRLs.
*/
SOFT_FAIL
}
}
<!-- <!--
Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it This code is free software; you can redistribute it and/or modify it
...@@ -38,8 +38,10 @@ certificates and X.509 v2 CRLs. ...@@ -38,8 +38,10 @@ certificates and X.509 v2 CRLs.
<li><a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html"> <li><a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
<b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT> <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
Cryptography Architecture (JCA) Reference Guide</b></a> Cryptography Architecture (JCA) Reference Guide</b></a>
<li>RFC 3280: Internet X.509 Public Key Infrastructure Certificate and <li>RFC 5280: Internet X.509 Public Key Infrastructure Certificate and
Certificate Revocation List (CRL) Profile Certificate Revocation List (CRL) Profile
<li>RFC 2560: X.509 Internet Public Key Infrastructure Online Certificate
Status Protocol - OCSP
<li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html"> <li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html">
<b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT> <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
Cryptography Architecture Standard Algorithm Name Cryptography Architecture Standard Algorithm Name
...@@ -50,8 +52,8 @@ certificates and X.509 v2 CRLs. ...@@ -50,8 +52,8 @@ certificates and X.509 v2 CRLs.
For information about X.509 certificates and CRLs, please see: For information about X.509 certificates and CRLs, please see:
<ul> <ul>
<li><a href="http://www.ietf.org/rfc/rfc3280.txt"> <li><a href="http://www.ietf.org/rfc/rfc5280.txt">
http://www.ietf.org/rfc/rfc3280.txt</a> http://www.ietf.org/rfc/rfc5280.txt</a>
<li><a href= <li><a href=
"{@docRoot}/../technotes/guides/security/certpath/CertPathProgGuide.html"> "{@docRoot}/../technotes/guides/security/certpath/CertPathProgGuide.html">
<b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT> <b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
......
/* /*
* Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,13 +24,11 @@ ...@@ -24,13 +24,11 @@
*/ */
package sun.security.provider.certpath; package sun.security.provider.certpath;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
/** /**
* An AdjacencyList is used to store the history of certification paths * An AdjacencyList is used to store the history of certification paths
* attempted in constructing a path from an initiator to a target. The * attempted in constructing a path from an initiator to a target. The
...@@ -123,124 +121,117 @@ public class AdjacencyList { ...@@ -123,124 +121,117 @@ public class AdjacencyList {
* at the start. * at the start.
*/ */
private boolean buildList(List<List<Vertex>> theList, int index, private boolean buildList(List<List<Vertex>> theList, int index,
BuildStep follow) { BuildStep follow) {
// Each time this method is called, we're examining a new list // Each time this method is called, we're examining a new list
// from the global list. So, we have to start by getting the list // from the global list. So, we have to start by getting the list
// that contains the set of Vertexes we're considering. // that contains the set of Vertexes we're considering.
List<Vertex> l = theList.get(index); List<Vertex> l = theList.get(index);
try { // we're interested in the case where all indexes are -1...
// we're interested in the case where all indexes are -1... boolean allNegOne = true;
boolean allNegOne = true; // ...and in the case where every entry has a Throwable
// ...and in the case where every entry has a Throwable boolean allXcps = true;
boolean allXcps = true;
for (Vertex v : l) { for (Vertex v : l) {
if (v.getIndex() != -1) { if (v.getIndex() != -1) {
// count an empty list the same as an index of -1...this // count an empty list the same as an index of -1...this
// is to patch a bug somewhere in the builder // is to patch a bug somewhere in the builder
if (theList.get(v.getIndex()).size() != 0) if (theList.get(v.getIndex()).size() != 0)
allNegOne = false; allNegOne = false;
} } else {
else if (v.getThrowable() == null)
if (v.getThrowable() == null) allXcps = false;
allXcps = false;
// every entry, regardless of the final use for it, is always
// entered as a possible step before we take any actions
mStepList.add(new BuildStep(v, BuildStep.POSSIBLE));
} }
// every entry, regardless of the final use for it, is always
// entered as a possible step before we take any actions
mStepList.add(new BuildStep(v, BuildStep.POSSIBLE));
}
if (allNegOne) { if (allNegOne) {
// There are two cases that we could be looking at here. We // There are two cases that we could be looking at here. We
// may need to back up, or the build may have succeeded at // may need to back up, or the build may have succeeded at
// this point. This is based on whether or not any // this point. This is based on whether or not any
// exceptions were found in the list. // exceptions were found in the list.
if (allXcps) { if (allXcps) {
// we need to go back...see if this is the last one // we need to go back...see if this is the last one
if (follow == null) if (follow == null)
mStepList.add(new BuildStep(null, BuildStep.FAIL)); mStepList.add(new BuildStep(null, BuildStep.FAIL));
else else
mStepList.add(new BuildStep(follow.getVertex(), mStepList.add(new BuildStep(follow.getVertex(),
BuildStep.BACK)); BuildStep.BACK));
return false;
} else {
// we succeeded...now the only question is which is the
// successful step? If there's only one entry without
// a throwable, then that's the successful step. Otherwise,
// we'll have to make some guesses...
List<Vertex> possibles = new ArrayList<Vertex>();
for (Vertex v : l) {
if (v.getThrowable() == null)
possibles.add(v);
}
if (possibles.size() == 1) { return false;
// real easy...we've found the final Vertex } else {
mStepList.add(new BuildStep(possibles.get(0), // we succeeded...now the only question is which is the
BuildStep.SUCCEED)); // successful step? If there's only one entry without
} else { // a throwable, then that's the successful step. Otherwise,
// ok...at this point, there is more than one Cert // we'll have to make some guesses...
// which might be the succeed step...how do we know List<Vertex> possibles = new ArrayList<>();
// which it is? I'm going to assume that our builder for (Vertex v : l) {
// algorithm is good enough to know which is the if (v.getThrowable() == null)
// correct one, and put it first...but a FIXME goes possibles.add(v);
// here anyway, and we should be comparing to the }
// target/initiator Cert...
mStepList.add(new BuildStep(possibles.get(0),
BuildStep.SUCCEED));
}
return true; if (possibles.size() == 1) {
// real easy...we've found the final Vertex
mStepList.add(new BuildStep(possibles.get(0),
BuildStep.SUCCEED));
} else {
// ok...at this point, there is more than one Cert
// which might be the succeed step...how do we know
// which it is? I'm going to assume that our builder
// algorithm is good enough to know which is the
// correct one, and put it first...but a FIXME goes
// here anyway, and we should be comparing to the
// target/initiator Cert...
mStepList.add(new BuildStep(possibles.get(0),
BuildStep.SUCCEED));
} }
} else {
// There's at least one thing that we can try before we give
// up and go back. Run through the list now, and enter a new
// BuildStep for each path that we try to follow. If none of
// the paths we try produce a successful end, we're going to
// have to back out ourselves.
boolean success = false;
for (Vertex v : l) { return true;
}
} else {
// There's at least one thing that we can try before we give
// up and go back. Run through the list now, and enter a new
// BuildStep for each path that we try to follow. If none of
// the paths we try produce a successful end, we're going to
// have to back out ourselves.
boolean success = false;
for (Vertex v : l) {
// Note that we'll only find a SUCCEED case when we're // Note that we'll only find a SUCCEED case when we're
// looking at the last possible path, so we don't need to // looking at the last possible path, so we don't need to
// consider success in the while loop // consider success in the while loop
if (v.getIndex() != -1) { if (v.getIndex() != -1) {
if (theList.get(v.getIndex()).size() != 0) { if (theList.get(v.getIndex()).size() != 0) {
// If the entry we're looking at doesn't have an // If the entry we're looking at doesn't have an
// index of -1, and doesn't lead to an empty list, // index of -1, and doesn't lead to an empty list,
// then it's something we follow! // then it's something we follow!
BuildStep bs = new BuildStep(v, BuildStep.FOLLOW); BuildStep bs = new BuildStep(v, BuildStep.FOLLOW);
mStepList.add(bs); mStepList.add(bs);
success = buildList(theList, v.getIndex(), bs); success = buildList(theList, v.getIndex(), bs);
}
} }
} }
}
if (success) { if (success) {
// We're already finished! // We're already finished!
return true; return true;
} else { } else {
// We failed, and we've exhausted all the paths that we // We failed, and we've exhausted all the paths that we
// could take. The only choice is to back ourselves out. // could take. The only choice is to back ourselves out.
if (follow == null) if (follow == null)
mStepList.add(new BuildStep(null, BuildStep.FAIL)); mStepList.add(new BuildStep(null, BuildStep.FAIL));
else else
mStepList.add(new BuildStep(follow.getVertex(), mStepList.add(new BuildStep(follow.getVertex(),
BuildStep.BACK)); BuildStep.BACK));
return false; return false;
}
} }
} }
catch (Exception e) {}
// we'll never get here, but you know java...
return false;
} }
/** /**
...@@ -248,23 +239,20 @@ public class AdjacencyList { ...@@ -248,23 +239,20 @@ public class AdjacencyList {
* *
* @return String representation * @return String representation
*/ */
@Override
public String toString() { public String toString() {
String out = "[\n"; StringBuilder sb = new StringBuilder("[\n");
int i = 0; int i = 0;
for (List<Vertex> l : mOrigList) { for (List<Vertex> l : mOrigList) {
out = out + "LinkedList[" + i++ + "]:\n"; sb.append("LinkedList[").append(i++).append("]:\n");
for (Vertex step : l) { for (Vertex step : l) {
try { sb.append(step.toString()).append("\n");
out = out + step.toString();
out = out + "\n";
}
catch (Exception e) { out = out + "No Such Element\n"; }
} }
} }
out = out + "]\n"; sb.append("]\n");
return out; return sb.toString();
} }
} }
/* /*
* Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -62,7 +62,7 @@ class BasicChecker extends PKIXCertPathChecker { ...@@ -62,7 +62,7 @@ class BasicChecker extends PKIXCertPathChecker {
private static final Debug debug = Debug.getInstance("certpath"); private static final Debug debug = Debug.getInstance("certpath");
private final PublicKey trustedPubKey; private final PublicKey trustedPubKey;
private final X500Principal caName; private final X500Principal caName;
private final Date testDate; private final Date date;
private final String sigProvider; private final String sigProvider;
private final boolean sigOnly; private final boolean sigOnly;
private X500Principal prevSubject; private X500Principal prevSubject;
...@@ -73,14 +73,13 @@ class BasicChecker extends PKIXCertPathChecker { ...@@ -73,14 +73,13 @@ class BasicChecker extends PKIXCertPathChecker {
* *
* @param anchor the anchor selected to validate the target certificate * @param anchor the anchor selected to validate the target certificate
* @param testDate the time for which the validity of the certificate * @param testDate the time for which the validity of the certificate
* should be determined * should be determined
* @param sigProvider the name of the signature provider * @param sigProvider the name of the signature provider
* @param sigOnly true if only signature checking is to be done; * @param sigOnly true if only signature checking is to be done;
* if false, all checks are done * if false, all checks are done
*/ */
BasicChecker(TrustAnchor anchor, Date testDate, String sigProvider, BasicChecker(TrustAnchor anchor, Date date, String sigProvider,
boolean sigOnly) throws CertPathValidatorException boolean sigOnly) {
{
if (anchor.getTrustedCert() != null) { if (anchor.getTrustedCert() != null) {
this.trustedPubKey = anchor.getTrustedCert().getPublicKey(); this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
this.caName = anchor.getTrustedCert().getSubjectX500Principal(); this.caName = anchor.getTrustedCert().getSubjectX500Principal();
...@@ -88,16 +87,16 @@ class BasicChecker extends PKIXCertPathChecker { ...@@ -88,16 +87,16 @@ class BasicChecker extends PKIXCertPathChecker {
this.trustedPubKey = anchor.getCAPublicKey(); this.trustedPubKey = anchor.getCAPublicKey();
this.caName = anchor.getCA(); this.caName = anchor.getCA();
} }
this.testDate = testDate; this.date = date;
this.sigProvider = sigProvider; this.sigProvider = sigProvider;
this.sigOnly = sigOnly; this.sigOnly = sigOnly;
init(false);
} }
/** /**
* Initializes the internal state of the checker from parameters * Initializes the internal state of the checker from parameters
* specified in the constructor. * specified in the constructor.
*/ */
@Override
public void init(boolean forward) throws CertPathValidatorException { public void init(boolean forward) throws CertPathValidatorException {
if (!forward) { if (!forward) {
prevPubKey = trustedPubKey; prevPubKey = trustedPubKey;
...@@ -108,10 +107,12 @@ class BasicChecker extends PKIXCertPathChecker { ...@@ -108,10 +107,12 @@ class BasicChecker extends PKIXCertPathChecker {
} }
} }
@Override
public boolean isForwardCheckingSupported() { public boolean isForwardCheckingSupported() {
return false; return false;
} }
@Override
public Set<String> getSupportedExtensions() { public Set<String> getSupportedExtensions() {
return null; return null;
} }
...@@ -124,33 +125,31 @@ class BasicChecker extends PKIXCertPathChecker { ...@@ -124,33 +125,31 @@ class BasicChecker extends PKIXCertPathChecker {
* @param cert the Certificate * @param cert the Certificate
* @param unresolvedCritExts a Collection of the unresolved critical * @param unresolvedCritExts a Collection of the unresolved critical
* extensions * extensions
* @exception CertPathValidatorException Exception thrown if certificate * @throws CertPathValidatorException if certificate does not verify
* does not verify.
*/ */
@Override
public void check(Certificate cert, Collection<String> unresolvedCritExts) public void check(Certificate cert, Collection<String> unresolvedCritExts)
throws CertPathValidatorException throws CertPathValidatorException
{ {
X509Certificate currCert = (X509Certificate) cert; X509Certificate currCert = (X509Certificate)cert;
if (!sigOnly) { if (!sigOnly) {
verifyTimestamp(currCert, testDate); verifyTimestamp(currCert);
verifyNameChaining(currCert, prevSubject); verifyNameChaining(currCert);
} }
verifySignature(currCert, prevPubKey, sigProvider); verifySignature(currCert);
updateState(currCert); updateState(currCert);
} }
/** /**
* Verifies the signature on the certificate using the previous public key * Verifies the signature on the certificate using the previous public key.
* @param cert the Certificate *
* @param prevPubKey the previous PublicKey * @param cert the X509Certificate
* @param sigProvider a String containing the signature provider * @throws CertPathValidatorException if certificate does not verify
* @exception CertPathValidatorException Exception thrown if certificate
* does not verify.
*/ */
private void verifySignature(X509Certificate cert, PublicKey prevPubKey, private void verifySignature(X509Certificate cert)
String sigProvider) throws CertPathValidatorException throws CertPathValidatorException
{ {
String msg = "signature"; String msg = "signature";
if (debug != null) if (debug != null)
...@@ -162,7 +161,7 @@ class BasicChecker extends PKIXCertPathChecker { ...@@ -162,7 +161,7 @@ class BasicChecker extends PKIXCertPathChecker {
throw new CertPathValidatorException throw new CertPathValidatorException
(msg + " check failed", e, null, -1, (msg + " check failed", e, null, -1,
BasicReason.INVALID_SIGNATURE); BasicReason.INVALID_SIGNATURE);
} catch (Exception e) { } catch (GeneralSecurityException e) {
throw new CertPathValidatorException(msg + " check failed", e); throw new CertPathValidatorException(msg + " check failed", e);
} }
...@@ -173,7 +172,7 @@ class BasicChecker extends PKIXCertPathChecker { ...@@ -173,7 +172,7 @@ class BasicChecker extends PKIXCertPathChecker {
/** /**
* Internal method to verify the timestamp on a certificate * Internal method to verify the timestamp on a certificate
*/ */
private void verifyTimestamp(X509Certificate cert, Date date) private void verifyTimestamp(X509Certificate cert)
throws CertPathValidatorException throws CertPathValidatorException
{ {
String msg = "timestamp"; String msg = "timestamp";
...@@ -197,8 +196,8 @@ class BasicChecker extends PKIXCertPathChecker { ...@@ -197,8 +196,8 @@ class BasicChecker extends PKIXCertPathChecker {
/** /**
* Internal method to check that cert has a valid DN to be next in a chain * Internal method to check that cert has a valid DN to be next in a chain
*/ */
private void verifyNameChaining(X509Certificate cert, private void verifyNameChaining(X509Certificate cert)
X500Principal prevSubject) throws CertPathValidatorException throws CertPathValidatorException
{ {
if (prevSubject != null) { if (prevSubject != null) {
...@@ -207,8 +206,8 @@ class BasicChecker extends PKIXCertPathChecker { ...@@ -207,8 +206,8 @@ class BasicChecker extends PKIXCertPathChecker {
debug.println("---checking " + msg + "..."); debug.println("---checking " + msg + "...");
X500Principal currIssuer = cert.getIssuerX500Principal(); X500Principal currIssuer = cert.getIssuerX500Principal();
// reject null or empty issuer DNs
// reject null or empty issuer DNs
if (X500Name.asX500Name(currIssuer).isEmpty()) { if (X500Name.asX500Name(currIssuer).isEmpty()) {
throw new CertPathValidatorException throw new CertPathValidatorException
(msg + " check failed: " + (msg + " check failed: " +
......
/* /*
* Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
package sun.security.provider.certpath; package sun.security.provider.certpath;
import sun.security.util.Debug;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
/** /**
...@@ -39,7 +38,6 @@ import java.security.cert.X509Certificate; ...@@ -39,7 +38,6 @@ import java.security.cert.X509Certificate;
*/ */
public class BuildStep { public class BuildStep {
private static final Debug debug = Debug.getInstance("certpath");
private Vertex vertex; private Vertex vertex;
private X509Certificate cert; private X509Certificate cert;
private Throwable throwable; private Throwable throwable;
...@@ -86,7 +84,7 @@ public class BuildStep { ...@@ -86,7 +84,7 @@ public class BuildStep {
public BuildStep(Vertex vtx, int res) { public BuildStep(Vertex vtx, int res) {
vertex = vtx; vertex = vtx;
if (vertex != null) { if (vertex != null) {
cert = (X509Certificate)vertex.getCertificate(); cert = vertex.getCertificate();
throwable = vertex.getThrowable(); throwable = vertex.getThrowable();
} }
result = res; result = res;
...@@ -117,7 +115,7 @@ public class BuildStep { ...@@ -117,7 +115,7 @@ public class BuildStep {
* @returns String form of issuer name or null, if no certificate. * @returns String form of issuer name or null, if no certificate.
*/ */
public String getIssuerName() { public String getIssuerName() {
return (cert == null ? null : cert.getIssuerX500Principal().toString()); return getIssuerName(null);
} }
/** /**
...@@ -142,7 +140,7 @@ public class BuildStep { ...@@ -142,7 +140,7 @@ public class BuildStep {
* @returns String form of subject name or null, if no certificate. * @returns String form of subject name or null, if no certificate.
*/ */
public String getSubjectName() { public String getSubjectName() {
return (cert == null ? null : cert.getSubjectX500Principal().toString()); return getSubjectName(null);
} }
/** /**
...@@ -191,21 +189,21 @@ public class BuildStep { ...@@ -191,21 +189,21 @@ public class BuildStep {
public String resultToString(int res) { public String resultToString(int res) {
String resultString = ""; String resultString = "";
switch (res) { switch (res) {
case BuildStep.POSSIBLE: case POSSIBLE:
resultString = "Certificate to be tried.\n"; resultString = "Certificate to be tried.\n";
break; break;
case BuildStep.BACK: case BACK:
resultString = "Certificate backed out since path does not " resultString = "Certificate backed out since path does not "
+ "satisfy build requirements.\n"; + "satisfy build requirements.\n";
break; break;
case BuildStep.FOLLOW: case FOLLOW:
resultString = "Certificate satisfies conditions.\n"; resultString = "Certificate satisfies conditions.\n";
break; break;
case BuildStep.FAIL: case FAIL:
resultString = "Certificate backed out since path does not " resultString = "Certificate backed out since path does not "
+ "satisfy conditions.\n"; + "satisfy conditions.\n";
break; break;
case BuildStep.SUCCEED: case SUCCEED:
resultString = "Certificate satisfies conditions.\n"; resultString = "Certificate satisfies conditions.\n";
break; break;
default: default:
...@@ -220,6 +218,7 @@ public class BuildStep { ...@@ -220,6 +218,7 @@ public class BuildStep {
* *
* @returns String * @returns String
*/ */
@Override
public String toString() { public String toString() {
String out = "Internal Error\n"; String out = "Internal Error\n";
switch (result) { switch (result) {
...@@ -273,8 +272,6 @@ public class BuildStep { ...@@ -273,8 +272,6 @@ public class BuildStep {
* @returns String * @returns String
*/ */
public String fullToString() { public String fullToString() {
String out = resultToString(getResult()); return resultToString(getResult()) + vertex.toString();
out = out + vertex.toString();
return out;
} }
} }
/* /*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -31,9 +31,8 @@ import java.security.GeneralSecurityException; ...@@ -31,9 +31,8 @@ import java.security.GeneralSecurityException;
import java.security.cert.*; import java.security.cert.*;
import java.util.*; import java.util.*;
import javax.security.auth.x500.X500Principal;
import sun.security.action.GetBooleanAction; import sun.security.action.GetBooleanAction;
import sun.security.provider.certpath.PKIX.BuilderParams;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.x509.GeneralNames; import sun.security.x509.GeneralNames;
import sun.security.x509.GeneralNameInterface; import sun.security.x509.GeneralNameInterface;
...@@ -56,9 +55,7 @@ public abstract class Builder { ...@@ -56,9 +55,7 @@ public abstract class Builder {
private static final Debug debug = Debug.getInstance("certpath"); private static final Debug debug = Debug.getInstance("certpath");
private Set<String> matchingPolicies; private Set<String> matchingPolicies;
final PKIXBuilderParameters buildParams; final BuilderParams buildParams;
final X500Principal targetSubjectDN;
final Date date;
final X509CertSelector targetCertConstraints; final X509CertSelector targetCertConstraints;
/** /**
...@@ -74,14 +71,10 @@ public abstract class Builder { ...@@ -74,14 +71,10 @@ public abstract class Builder {
* *
* @param params the parameter set used to build a certification path * @param params the parameter set used to build a certification path
*/ */
Builder(PKIXBuilderParameters buildParams, X500Principal targetSubjectDN) { Builder(BuilderParams buildParams) {
this.buildParams = buildParams; this.buildParams = buildParams;
this.targetSubjectDN = targetSubjectDN;
// Initialize date if not specified
Date paramsDate = buildParams.getDate();
this.date = paramsDate != null ? paramsDate : new Date();
this.targetCertConstraints = this.targetCertConstraints =
(X509CertSelector) buildParams.getTargetCertConstraints(); (X509CertSelector)buildParams.targetCertConstraints();
} }
/** /**
...@@ -104,7 +97,8 @@ public abstract class Builder { ...@@ -104,7 +97,8 @@ public abstract class Builder {
* @param certPathList the certPathList generated thus far * @param certPathList the certPathList generated thus far
*/ */
abstract void verifyCert(X509Certificate cert, State currentState, abstract void verifyCert(X509Certificate cert, State currentState,
List<X509Certificate> certPathList) throws GeneralSecurityException; List<X509Certificate> certPathList)
throws GeneralSecurityException;
/** /**
* Verifies whether the input certificate completes the path. * Verifies whether the input certificate completes the path.
...@@ -123,7 +117,7 @@ public abstract class Builder { ...@@ -123,7 +117,7 @@ public abstract class Builder {
* @param certPathList the certification path list * @param certPathList the certification path list
*/ */
abstract void addCertToPath(X509Certificate cert, abstract void addCertToPath(X509Certificate cert,
LinkedList<X509Certificate> certPathList); LinkedList<X509Certificate> certPathList);
/** /**
* Removes final certificate from the certPathList * Removes final certificate from the certPathList
...@@ -147,7 +141,8 @@ public abstract class Builder { ...@@ -147,7 +141,8 @@ public abstract class Builder {
* is a grandparent, etc. * is a grandparent, etc.
*/ */
static int distance(GeneralNameInterface base, static int distance(GeneralNameInterface base,
GeneralNameInterface test, int incomparable) { GeneralNameInterface test, int incomparable)
{
switch (base.constrains(test)) { switch (base.constrains(test)) {
case GeneralNameInterface.NAME_DIFF_TYPE: case GeneralNameInterface.NAME_DIFF_TYPE:
if (debug != null) { if (debug != null) {
...@@ -192,7 +187,8 @@ public abstract class Builder { ...@@ -192,7 +187,8 @@ public abstract class Builder {
* some number of down hops. * some number of down hops.
*/ */
static int hops(GeneralNameInterface base, GeneralNameInterface test, static int hops(GeneralNameInterface base, GeneralNameInterface test,
int incomparable) { int incomparable)
{
int baseRtest = base.constrains(test); int baseRtest = base.constrains(test);
switch (baseRtest) { switch (baseRtest) {
case GeneralNameInterface.NAME_DIFF_TYPE: case GeneralNameInterface.NAME_DIFF_TYPE:
...@@ -282,9 +278,9 @@ public abstract class Builder { ...@@ -282,9 +278,9 @@ public abstract class Builder {
* @throws IOException if certificate does not get closer * @throws IOException if certificate does not get closer
*/ */
static int targetDistance(NameConstraintsExtension constraints, static int targetDistance(NameConstraintsExtension constraints,
X509Certificate cert, GeneralNameInterface target) X509Certificate cert, GeneralNameInterface target)
throws IOException { throws IOException
{
/* ensure that certificate satisfies existing name constraints */ /* ensure that certificate satisfies existing name constraints */
if (constraints != null && !constraints.verify(cert)) { if (constraints != null && !constraints.verify(cert)) {
throw new IOException("certificate does not satisfy existing name " throw new IOException("certificate does not satisfy existing name "
...@@ -295,7 +291,7 @@ public abstract class Builder { ...@@ -295,7 +291,7 @@ public abstract class Builder {
try { try {
certImpl = X509CertImpl.toImpl(cert); certImpl = X509CertImpl.toImpl(cert);
} catch (CertificateException e) { } catch (CertificateException e) {
throw (IOException)new IOException("Invalid certificate").initCause(e); throw new IOException("Invalid certificate", e);
} }
/* see if certificate subject matches target */ /* see if certificate subject matches target */
X500Name subject = X500Name.asX500Name(certImpl.getSubjectX500Principal()); X500Name subject = X500Name.asX500Name(certImpl.getSubjectX500Principal());
...@@ -398,13 +394,13 @@ public abstract class Builder { ...@@ -398,13 +394,13 @@ public abstract class Builder {
*/ */
Set<String> getMatchingPolicies() { Set<String> getMatchingPolicies() {
if (matchingPolicies != null) { if (matchingPolicies != null) {
Set<String> initialPolicies = buildParams.getInitialPolicies(); Set<String> initialPolicies = buildParams.initialPolicies();
if ((!initialPolicies.isEmpty()) && if ((!initialPolicies.isEmpty()) &&
(!initialPolicies.contains(PolicyChecker.ANY_POLICY)) && (!initialPolicies.contains(PolicyChecker.ANY_POLICY)) &&
(buildParams.isPolicyMappingInhibited())) (buildParams.policyMappingInhibited()))
{ {
initialPolicies.add(PolicyChecker.ANY_POLICY); matchingPolicies = new HashSet<>(initialPolicies);
matchingPolicies = initialPolicies; matchingPolicies.add(PolicyChecker.ANY_POLICY);
} else { } else {
// we just return an empty set to make sure that there is // we just return an empty set to make sure that there is
// at least a certificate policies extension in the cert // at least a certificate policies extension in the cert
...@@ -429,13 +425,15 @@ public abstract class Builder { ...@@ -429,13 +425,15 @@ public abstract class Builder {
* Returns true iff resultCerts changed (a cert was added to the collection) * Returns true iff resultCerts changed (a cert was added to the collection)
*/ */
boolean addMatchingCerts(X509CertSelector selector, boolean addMatchingCerts(X509CertSelector selector,
Collection<CertStore> certStores, Collection<CertStore> certStores,
Collection<X509Certificate> resultCerts, boolean checkAll) { Collection<X509Certificate> resultCerts,
boolean checkAll)
{
X509Certificate targetCert = selector.getCertificate(); X509Certificate targetCert = selector.getCertificate();
if (targetCert != null) { if (targetCert != null) {
// no need to search CertStores // no need to search CertStores
if (selector.match(targetCert) && !X509CertImpl.isSelfSigned if (selector.match(targetCert) && !X509CertImpl.isSelfSigned
(targetCert, buildParams.getSigProvider())) { (targetCert, buildParams.sigProvider())) {
if (debug != null) { if (debug != null) {
debug.println("Builder.addMatchingCerts: adding target cert"); debug.println("Builder.addMatchingCerts: adding target cert");
} }
...@@ -450,7 +448,7 @@ public abstract class Builder { ...@@ -450,7 +448,7 @@ public abstract class Builder {
store.getCertificates(selector); store.getCertificates(selector);
for (Certificate cert : certs) { for (Certificate cert : certs) {
if (!X509CertImpl.isSelfSigned if (!X509CertImpl.isSelfSigned
((X509Certificate)cert, buildParams.getSigProvider())) { ((X509Certificate)cert, buildParams.sigProvider())) {
if (resultCerts.add((X509Certificate)cert)) { if (resultCerts.add((X509Certificate)cert)) {
add = true; add = true;
} }
...@@ -471,16 +469,4 @@ public abstract class Builder { ...@@ -471,16 +469,4 @@ public abstract class Builder {
} }
return add; return add;
} }
/**
* Returns true if CertStore is local. Currently, returns true if
* type is Collection or if it has been initialized with
* CollectionCertStoreParameters. A new API method should be added
* to CertStore that returns local or remote.
*/
static boolean isLocalCertStore(CertStore certStore) {
return (certStore.getType().equals("Collection") ||
certStore.getCertStoreParameters() instanceof
CollectionCertStoreParameters);
}
} }
/* /*
* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -83,9 +83,8 @@ public abstract class CertStoreHelper { ...@@ -83,9 +83,8 @@ public abstract class CertStoreHelper {
= (CertStoreHelper)c.newInstance(); = (CertStoreHelper)c.newInstance();
cache.put(type, csh); cache.put(type, csh);
return csh; return csh;
} catch (InstantiationException e) { } catch (InstantiationException |
throw new AssertionError(e); IllegalAccessException e) {
} catch (IllegalAccessException e) {
throw new AssertionError(e); throw new AssertionError(e);
} }
} }
......
/* /*
* Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -31,7 +31,6 @@ import java.security.cert.CRL; ...@@ -31,7 +31,6 @@ import java.security.cert.CRL;
import java.util.Collection; import java.util.Collection;
import java.util.ConcurrentModificationException; import java.util.ConcurrentModificationException;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.security.cert.CertSelector; import java.security.cert.CertSelector;
import java.security.cert.CertStore; import java.security.cert.CertStore;
import java.security.cert.CertStoreException; import java.security.cert.CertStoreException;
...@@ -114,6 +113,7 @@ public class CollectionCertStore extends CertStoreSpi { ...@@ -114,6 +113,7 @@ public class CollectionCertStore extends CertStoreSpi {
* match the specified selector * match the specified selector
* @throws CertStoreException if an exception occurs * @throws CertStoreException if an exception occurs
*/ */
@Override
public Collection<Certificate> engineGetCertificates public Collection<Certificate> engineGetCertificates
(CertSelector selector) throws CertStoreException { (CertSelector selector) throws CertStoreException {
if (coll == null) { if (coll == null) {
...@@ -122,18 +122,15 @@ public class CollectionCertStore extends CertStoreSpi { ...@@ -122,18 +122,15 @@ public class CollectionCertStore extends CertStoreSpi {
// Tolerate a few ConcurrentModificationExceptions // Tolerate a few ConcurrentModificationExceptions
for (int c = 0; c < 10; c++) { for (int c = 0; c < 10; c++) {
try { try {
HashSet<Certificate> result = new HashSet<Certificate>(); HashSet<Certificate> result = new HashSet<>();
Iterator<?> i = coll.iterator();
if (selector != null) { if (selector != null) {
while (i.hasNext()) { for (Object o : coll) {
Object o = i.next();
if ((o instanceof Certificate) && if ((o instanceof Certificate) &&
selector.match((Certificate) o)) selector.match((Certificate) o))
result.add((Certificate)o); result.add((Certificate)o);
} }
} else { } else {
while (i.hasNext()) { for (Object o : coll) {
Object o = i.next();
if (o instanceof Certificate) if (o instanceof Certificate)
result.add((Certificate)o); result.add((Certificate)o);
} }
...@@ -157,6 +154,7 @@ public class CollectionCertStore extends CertStoreSpi { ...@@ -157,6 +154,7 @@ public class CollectionCertStore extends CertStoreSpi {
* match the specified selector * match the specified selector
* @throws CertStoreException if an exception occurs * @throws CertStoreException if an exception occurs
*/ */
@Override
public Collection<CRL> engineGetCRLs(CRLSelector selector) public Collection<CRL> engineGetCRLs(CRLSelector selector)
throws CertStoreException throws CertStoreException
{ {
...@@ -166,22 +164,19 @@ public class CollectionCertStore extends CertStoreSpi { ...@@ -166,22 +164,19 @@ public class CollectionCertStore extends CertStoreSpi {
// Tolerate a few ConcurrentModificationExceptions // Tolerate a few ConcurrentModificationExceptions
for (int c = 0; c < 10; c++) { for (int c = 0; c < 10; c++) {
try { try {
HashSet<CRL> result = new HashSet<CRL>(); HashSet<CRL> result = new HashSet<>();
Iterator<?> i = coll.iterator();
if (selector != null) { if (selector != null) {
while (i.hasNext()) { for (Object o : coll) {
Object o = i.next();
if ((o instanceof CRL) && selector.match((CRL) o)) if ((o instanceof CRL) && selector.match((CRL) o))
result.add((CRL)o); result.add((CRL)o);
} }
} else { } else {
while (i.hasNext()) { for (Object o : coll) {
Object o = i.next();
if (o instanceof CRL) if (o instanceof CRL)
result.add((CRL)o); result.add((CRL)o);
} }
} }
return(result); return result;
} catch (ConcurrentModificationException e) { } } catch (ConcurrentModificationException e) { }
} }
throw new ConcurrentModificationException("Too many " throw new ConcurrentModificationException("Too many "
......
/* /*
* Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,19 +25,20 @@ ...@@ -25,19 +25,20 @@
package sun.security.provider.certpath; package sun.security.provider.certpath;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.HashSet;
import java.io.IOException; import java.io.IOException;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException;
import java.security.cert.X509Certificate;
import java.security.cert.PKIXCertPathChecker; import java.security.cert.PKIXCertPathChecker;
import java.security.cert.PKIXReason; import java.security.cert.PKIXReason;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.x509.PKIXExtensions; import static sun.security.x509.PKIXExtensions.*;
import sun.security.x509.NameConstraintsExtension; import sun.security.x509.NameConstraintsExtension;
import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertImpl;
...@@ -66,13 +67,12 @@ class ConstraintsChecker extends PKIXCertPathChecker { ...@@ -66,13 +67,12 @@ class ConstraintsChecker extends PKIXCertPathChecker {
* Creates a ConstraintsChecker. * Creates a ConstraintsChecker.
* *
* @param certPathLength the length of the certification path * @param certPathLength the length of the certification path
* @throws CertPathValidatorException if the checker cannot be initialized
*/ */
ConstraintsChecker(int certPathLength) throws CertPathValidatorException { ConstraintsChecker(int certPathLength) {
this.certPathLength = certPathLength; this.certPathLength = certPathLength;
init(false);
} }
@Override
public void init(boolean forward) throws CertPathValidatorException { public void init(boolean forward) throws CertPathValidatorException {
if (!forward) { if (!forward) {
i = 0; i = 0;
...@@ -84,15 +84,17 @@ class ConstraintsChecker extends PKIXCertPathChecker { ...@@ -84,15 +84,17 @@ class ConstraintsChecker extends PKIXCertPathChecker {
} }
} }
@Override
public boolean isForwardCheckingSupported() { public boolean isForwardCheckingSupported() {
return false; return false;
} }
@Override
public Set<String> getSupportedExtensions() { public Set<String> getSupportedExtensions() {
if (supportedExts == null) { if (supportedExts == null) {
supportedExts = new HashSet<String>(); supportedExts = new HashSet<String>(2);
supportedExts.add(PKIXExtensions.BasicConstraints_Id.toString()); supportedExts.add(BasicConstraints_Id.toString());
supportedExts.add(PKIXExtensions.NameConstraints_Id.toString()); supportedExts.add(NameConstraints_Id.toString());
supportedExts = Collections.unmodifiableSet(supportedExts); supportedExts = Collections.unmodifiableSet(supportedExts);
} }
return supportedExts; return supportedExts;
...@@ -104,14 +106,15 @@ class ConstraintsChecker extends PKIXCertPathChecker { ...@@ -104,14 +106,15 @@ class ConstraintsChecker extends PKIXCertPathChecker {
* *
* @param cert the <code>Certificate</code> to be checked * @param cert the <code>Certificate</code> to be checked
* @param unresCritExts a <code>Collection</code> of OID strings * @param unresCritExts a <code>Collection</code> of OID strings
* representing the current set of unresolved critical extensions * representing the current set of unresolved critical extensions
* @throws CertPathValidatorException if the specified certificate * @throws CertPathValidatorException if the specified certificate
* does not pass the check * does not pass the check
*/ */
@Override
public void check(Certificate cert, Collection<String> unresCritExts) public void check(Certificate cert, Collection<String> unresCritExts)
throws CertPathValidatorException throws CertPathValidatorException
{ {
X509Certificate currCert = (X509Certificate) cert; X509Certificate currCert = (X509Certificate)cert;
i++; i++;
// MUST run NC check second, since it depends on BC check to // MUST run NC check second, since it depends on BC check to
...@@ -120,8 +123,8 @@ class ConstraintsChecker extends PKIXCertPathChecker { ...@@ -120,8 +123,8 @@ class ConstraintsChecker extends PKIXCertPathChecker {
verifyNameConstraints(currCert); verifyNameConstraints(currCert);
if (unresCritExts != null && !unresCritExts.isEmpty()) { if (unresCritExts != null && !unresCritExts.isEmpty()) {
unresCritExts.remove(PKIXExtensions.BasicConstraints_Id.toString()); unresCritExts.remove(BasicConstraints_Id.toString());
unresCritExts.remove(PKIXExtensions.NameConstraints_Id.toString()); unresCritExts.remove(NameConstraints_Id.toString());
} }
} }
...@@ -166,9 +169,9 @@ class ConstraintsChecker extends PKIXCertPathChecker { ...@@ -166,9 +169,9 @@ class ConstraintsChecker extends PKIXCertPathChecker {
/** /**
* Helper to fold sets of name constraints together * Helper to fold sets of name constraints together
*/ */
static NameConstraintsExtension static NameConstraintsExtension mergeNameConstraints(
mergeNameConstraints(X509Certificate currCert, X509Certificate currCert, NameConstraintsExtension prevNC)
NameConstraintsExtension prevNC) throws CertPathValidatorException throws CertPathValidatorException
{ {
X509CertImpl currCertImpl; X509CertImpl currCertImpl;
try { try {
...@@ -197,7 +200,7 @@ class ConstraintsChecker extends PKIXCertPathChecker { ...@@ -197,7 +200,7 @@ class ConstraintsChecker extends PKIXCertPathChecker {
// Make sure we do a clone here, because we're probably // Make sure we do a clone here, because we're probably
// going to modify this object later and we don't want to // going to modify this object later and we don't want to
// be sharing it with a Certificate object! // be sharing it with a Certificate object!
return (NameConstraintsExtension) newConstraints.clone(); return (NameConstraintsExtension)newConstraints.clone();
} }
} else { } else {
try { try {
......
/* /*
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,14 +27,14 @@ package sun.security.provider.certpath; ...@@ -27,14 +27,14 @@ package sun.security.provider.certpath;
import java.io.*; import java.io.*;
import java.net.URI; import java.net.URI;
import java.util.*;
import java.security.*; import java.security.*;
import java.security.cert.*; import java.security.cert.*;
import javax.security.auth.x500.X500Principal; import javax.security.auth.x500.X500Principal;
import java.util.*;
import sun.security.action.GetBooleanAction;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.util.DerOutputStream; import sun.security.util.DerOutputStream;
import static sun.security.x509.PKIXExtensions.*;
import sun.security.x509.*; import sun.security.x509.*;
/** /**
...@@ -57,45 +57,24 @@ class DistributionPointFetcher { ...@@ -57,45 +57,24 @@ class DistributionPointFetcher {
private static final boolean[] ALL_REASONS = private static final boolean[] ALL_REASONS =
{true, true, true, true, true, true, true, true, true}; {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 instantiation only.
*/ */
private DistributionPointFetcher() {} private DistributionPointFetcher() {}
/**
* Return a DistributionPointFetcher instance.
*/
static DistributionPointFetcher getInstance() {
return INSTANCE;
}
/** /**
* Return the X509CRLs matching this selector. The selector must be * Return the X509CRLs matching this selector. The selector must be
* an X509CRLSelector with certificateChecking set. * an X509CRLSelector with certificateChecking set.
*
* If CRLDP support is disabled, this method always returns an
* empty set.
*/ */
Collection<X509CRL> getCRLs(X509CRLSelector selector, boolean signFlag, static Collection<X509CRL> getCRLs(X509CRLSelector selector,
PublicKey prevKey, String provider, List<CertStore> certStores, boolean signFlag, PublicKey prevKey,
boolean[] reasonsMask, Set<TrustAnchor> trustAnchors, String provider,
Date validity) throws CertStoreException { List<CertStore> certStores,
boolean[] reasonsMask,
if (USE_CRLDP == false) { Set<TrustAnchor> trustAnchors,
return Collections.emptySet(); Date validity)
} throws CertStoreException
{
X509Certificate cert = selector.getCertificateChecking(); X509Certificate cert = selector.getCertificateChecking();
if (cert == null) { if (cert == null) {
return Collections.emptySet(); return Collections.emptySet();
...@@ -116,7 +95,7 @@ class DistributionPointFetcher { ...@@ -116,7 +95,7 @@ class DistributionPointFetcher {
} }
List<DistributionPoint> points = List<DistributionPoint> points =
ext.get(CRLDistributionPointsExtension.POINTS); ext.get(CRLDistributionPointsExtension.POINTS);
Set<X509CRL> results = new HashSet<X509CRL>(); Set<X509CRL> results = new HashSet<>();
for (Iterator<DistributionPoint> t = points.iterator(); for (Iterator<DistributionPoint> t = points.iterator();
t.hasNext() && !Arrays.equals(reasonsMask, ALL_REASONS); ) { t.hasNext() && !Arrays.equals(reasonsMask, ALL_REASONS); ) {
DistributionPoint point = t.next(); DistributionPoint point = t.next();
...@@ -129,9 +108,7 @@ class DistributionPointFetcher { ...@@ -129,9 +108,7 @@ class DistributionPointFetcher {
debug.println("Returning " + results.size() + " CRLs"); debug.println("Returning " + results.size() + " CRLs");
} }
return results; return results;
} catch (CertificateException e) { } catch (CertificateException | IOException e) {
return Collections.emptySet();
} catch (IOException e) {
return Collections.emptySet(); return Collections.emptySet();
} }
} }
...@@ -140,7 +117,7 @@ class DistributionPointFetcher { ...@@ -140,7 +117,7 @@ class DistributionPointFetcher {
* Download CRLs from the given distribution point, verify and return them. * Download CRLs from the given distribution point, verify and return them.
* See the top of the class for current limitations. * See the top of the class for current limitations.
*/ */
private Collection<X509CRL> getCRLs(X509CRLSelector selector, private static Collection<X509CRL> getCRLs(X509CRLSelector selector,
X509CertImpl certImpl, DistributionPoint point, boolean[] reasonsMask, X509CertImpl certImpl, DistributionPoint point, boolean[] reasonsMask,
boolean signFlag, PublicKey prevKey, String provider, boolean signFlag, PublicKey prevKey, String provider,
List<CertStore> certStores, Set<TrustAnchor> trustAnchors, List<CertStore> certStores, Set<TrustAnchor> trustAnchors,
...@@ -200,7 +177,7 @@ class DistributionPointFetcher { ...@@ -200,7 +177,7 @@ class DistributionPointFetcher {
certStores, validity)) { certStores, validity)) {
crls.add(crl); crls.add(crl);
} }
} catch (Exception e) { } catch (IOException | CRLException e) {
// don't add the CRL // don't add the CRL
if (debug != null) { if (debug != null) {
debug.println("Exception verifying CRL: " + e.getMessage()); debug.println("Exception verifying CRL: " + e.getMessage());
...@@ -214,7 +191,7 @@ class DistributionPointFetcher { ...@@ -214,7 +191,7 @@ class DistributionPointFetcher {
/** /**
* Download CRL from given URI. * Download CRL from given URI.
*/ */
private X509CRL getCRL(URIName name) { private static X509CRL getCRL(URIName name) {
URI uri = name.getURI(); URI uri = name.getURI();
if (debug != null) { if (debug != null) {
debug.println("Trying to fetch CRL from DP " + uri); debug.println("Trying to fetch CRL from DP " + uri);
...@@ -240,7 +217,7 @@ class DistributionPointFetcher { ...@@ -240,7 +217,7 @@ class DistributionPointFetcher {
/** /**
* Fetch CRLs from certStores. * Fetch CRLs from certStores.
*/ */
private Collection<X509CRL> getCRLs(X500Name name, private static Collection<X509CRL> getCRLs(X500Name name,
X500Principal certIssuer, List<CertStore> certStores) X500Principal certIssuer, List<CertStore> certStores)
{ {
if (debug != null) { if (debug != null) {
...@@ -249,7 +226,7 @@ class DistributionPointFetcher { ...@@ -249,7 +226,7 @@ class DistributionPointFetcher {
X509CRLSelector xcs = new X509CRLSelector(); X509CRLSelector xcs = new X509CRLSelector();
xcs.addIssuer(name.asX500Principal()); xcs.addIssuer(name.asX500Principal());
xcs.addIssuer(certIssuer); xcs.addIssuer(certIssuer);
Collection<X509CRL> crls = new ArrayList<X509CRL>(); Collection<X509CRL> crls = new ArrayList<>();
for (CertStore store : certStores) { for (CertStore store : certStores) {
try { try {
for (CRL crl : store.getCRLs(xcs)) { for (CRL crl : store.getCRLs(xcs)) {
...@@ -285,7 +262,7 @@ class DistributionPointFetcher { ...@@ -285,7 +262,7 @@ class DistributionPointFetcher {
* certification path should be determined * certification path should be determined
* @return true if ok, false if not * @return true if ok, false if not
*/ */
boolean verifyCRL(X509CertImpl certImpl, DistributionPoint point, static boolean verifyCRL(X509CertImpl certImpl, DistributionPoint point,
X509CRL crl, boolean[] reasonsMask, boolean signFlag, X509CRL crl, boolean[] reasonsMask, boolean signFlag,
PublicKey prevKey, String provider, PublicKey prevKey, String provider,
Set<TrustAnchor> trustAnchors, List<CertStore> certStores, Set<TrustAnchor> trustAnchors, List<CertStore> certStores,
...@@ -340,9 +317,9 @@ class DistributionPointFetcher { ...@@ -340,9 +317,9 @@ class DistributionPointFetcher {
} else { } else {
// in case of self-issued indirect CRL issuer. // in case of self-issued indirect CRL issuer.
byte[] certAKID = certImpl.getExtensionValue( byte[] certAKID = certImpl.getExtensionValue(
PKIXExtensions.AuthorityKey_Id.toString()); AuthorityKey_Id.toString());
byte[] crlAKID = crlImpl.getExtensionValue( byte[] crlAKID = crlImpl.getExtensionValue(
PKIXExtensions.AuthorityKey_Id.toString()); AuthorityKey_Id.toString());
if (certAKID == null || crlAKID == null) { if (certAKID == null || crlAKID == null) {
// cannot recognize indirect CRL without AKID // cannot recognize indirect CRL without AKID
...@@ -539,7 +516,7 @@ class DistributionPointFetcher { ...@@ -539,7 +516,7 @@ class DistributionPointFetcher {
// verify that interim reasons mask includes one or more reasons // verify that interim reasons mask includes one or more reasons
// not included in the reasons mask // not included in the reasons mask
boolean oneOrMore = false; boolean oneOrMore = false;
for (int i=0; i < interimReasonsMask.length && !oneOrMore; i++) { for (int i = 0; i < interimReasonsMask.length && !oneOrMore; i++) {
if (!reasonsMask[i] && interimReasonsMask[i]) { if (!reasonsMask[i] && interimReasonsMask[i]) {
oneOrMore = true; oneOrMore = true;
} }
...@@ -615,7 +592,7 @@ class DistributionPointFetcher { ...@@ -615,7 +592,7 @@ class DistributionPointFetcher {
PKIXCertPathBuilderResult result = PKIXCertPathBuilderResult result =
(PKIXCertPathBuilderResult) builder.build(params); (PKIXCertPathBuilderResult) builder.build(params);
prevKey = result.getPublicKey(); prevKey = result.getPublicKey();
} catch (Exception e) { } catch (GeneralSecurityException e) {
throw new CRLException(e); throw new CRLException(e);
} }
} }
...@@ -633,7 +610,7 @@ class DistributionPointFetcher { ...@@ -633,7 +610,7 @@ class DistributionPointFetcher {
// validate the signature on the CRL // validate the signature on the CRL
try { try {
crl.verify(prevKey, provider); crl.verify(prevKey, provider);
} catch (Exception e) { } catch (GeneralSecurityException e) {
if (debug != null) { if (debug != null) {
debug.println("CRL signature failed to verify"); debug.println("CRL signature failed to verify");
} }
...@@ -644,22 +621,21 @@ class DistributionPointFetcher { ...@@ -644,22 +621,21 @@ class DistributionPointFetcher {
Set<String> unresCritExts = crl.getCriticalExtensionOIDs(); Set<String> unresCritExts = crl.getCriticalExtensionOIDs();
// remove any that we have processed // remove any that we have processed
if (unresCritExts != null) { if (unresCritExts != null) {
unresCritExts.remove unresCritExts.remove(IssuingDistributionPoint_Id.toString());
(PKIXExtensions.IssuingDistributionPoint_Id.toString());
if (!unresCritExts.isEmpty()) { if (!unresCritExts.isEmpty()) {
if (debug != null) { if (debug != null) {
debug.println("Unrecognized critical extension(s) in CRL: " debug.println("Unrecognized critical extension(s) in CRL: "
+ unresCritExts); + unresCritExts);
Iterator<String> i = unresCritExts.iterator(); for (String ext : unresCritExts) {
while (i.hasNext()) debug.println(ext);
debug.println(i.next()); }
} }
return false; return false;
} }
} }
// update reasonsMask // update reasonsMask
for (int i=0; i < interimReasonsMask.length; i++) { for (int i = 0; i < interimReasonsMask.length; i++) {
if (!reasonsMask[i] && interimReasonsMask[i]) { if (!reasonsMask[i] && interimReasonsMask[i]) {
reasonsMask[i] = true; reasonsMask[i] = true;
} }
...@@ -671,9 +647,10 @@ class DistributionPointFetcher { ...@@ -671,9 +647,10 @@ class DistributionPointFetcher {
* Append relative name to the issuer name and return a new * Append relative name to the issuer name and return a new
* GeneralNames object. * GeneralNames object.
*/ */
private GeneralNames getFullNames(X500Name issuer, RDN rdn) private static GeneralNames getFullNames(X500Name issuer, RDN rdn)
throws IOException { throws IOException
List<RDN> rdns = new ArrayList<RDN>(issuer.rdns()); {
List<RDN> rdns = new ArrayList<>(issuer.rdns());
rdns.add(rdn); rdns.add(rdn);
X500Name fullName = new X500Name(rdns.toArray(new RDN[0])); X500Name fullName = new X500Name(rdns.toArray(new RDN[0]));
GeneralNames fullNames = new GeneralNames(); GeneralNames fullNames = new GeneralNames();
...@@ -681,15 +658,16 @@ class DistributionPointFetcher { ...@@ -681,15 +658,16 @@ class DistributionPointFetcher {
return fullNames; return fullNames;
} }
/** Verifies whether a CRL is issued by a certain certificate /**
* Verifies whether a CRL is issued by a certain certificate
* *
* @param cert the certificate * @param cert the certificate
* @param crl the CRL to be verified * @param crl the CRL to be verified
* @param provider the name of the signature provider * @param provider the name of the signature provider
*/ */
private static boolean issues(X509CertImpl cert, X509CRLImpl crl, private static boolean issues(X509CertImpl cert, X509CRLImpl crl,
String provider) throws IOException { String provider) throws IOException
{
boolean matched = false; boolean matched = false;
AdaptableX509CertSelector issuerSelector = AdaptableX509CertSelector issuerSelector =
...@@ -727,7 +705,7 @@ class DistributionPointFetcher { ...@@ -727,7 +705,7 @@ class DistributionPointFetcher {
try { try {
crl.verify(cert.getPublicKey(), provider); crl.verify(cert.getPublicKey(), provider);
matched = true; matched = true;
} catch (Exception e) { } catch (GeneralSecurityException e) {
matched = false; matched = false;
} }
} }
......
/* /*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,10 +26,9 @@ ...@@ -26,10 +26,9 @@
package sun.security.provider.certpath; package sun.security.provider.certpath;
import java.io.IOException; import java.io.IOException;
import java.util.*;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.PublicKey;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException;
import java.security.cert.PKIXReason; import java.security.cert.PKIXReason;
...@@ -40,12 +39,14 @@ import java.security.cert.PKIXCertPathChecker; ...@@ -40,12 +39,14 @@ import java.security.cert.PKIXCertPathChecker;
import java.security.cert.TrustAnchor; import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.security.cert.X509CertSelector; import java.security.cert.X509CertSelector;
import java.util.*;
import javax.security.auth.x500.X500Principal; import javax.security.auth.x500.X500Principal;
import sun.security.provider.certpath.PKIX.BuilderParams;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.x509.AccessDescription; import sun.security.x509.AccessDescription;
import sun.security.x509.AuthorityInfoAccessExtension; import sun.security.x509.AuthorityInfoAccessExtension;
import sun.security.x509.PKIXExtensions; import static sun.security.x509.PKIXExtensions.*;
import sun.security.x509.PolicyMappingsExtension; import sun.security.x509.PolicyMappingsExtension;
import sun.security.x509.X500Name; import sun.security.x509.X500Name;
import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertImpl;
...@@ -72,21 +73,17 @@ class ForwardBuilder extends Builder { ...@@ -72,21 +73,17 @@ class ForwardBuilder extends Builder {
TrustAnchor trustAnchor; TrustAnchor trustAnchor;
private Comparator<X509Certificate> comparator; private Comparator<X509Certificate> comparator;
private boolean searchAllCertStores = true; private boolean searchAllCertStores = true;
private boolean onlyEECert = false;
/** /**
* Initialize the builder with the input parameters. * Initialize the builder with the input parameters.
* *
* @param params the parameter set used to build a certification path * @param params the parameter set used to build a certification path
*/ */
ForwardBuilder(PKIXBuilderParameters buildParams, ForwardBuilder(BuilderParams buildParams, boolean searchAllCertStores) {
X500Principal targetSubjectDN, boolean searchAllCertStores, super(buildParams);
boolean onlyEECert)
{
super(buildParams, targetSubjectDN);
// populate sets of trusted certificates and subject DNs // populate sets of trusted certificates and subject DNs
trustAnchors = buildParams.getTrustAnchors(); trustAnchors = buildParams.trustAnchors();
trustedCerts = new HashSet<X509Certificate>(trustAnchors.size()); trustedCerts = new HashSet<X509Certificate>(trustAnchors.size());
trustedSubjectDNs = new HashSet<X500Principal>(trustAnchors.size()); trustedSubjectDNs = new HashSet<X500Principal>(trustAnchors.size());
for (TrustAnchor anchor : trustAnchors) { for (TrustAnchor anchor : trustAnchors) {
...@@ -100,7 +97,6 @@ class ForwardBuilder extends Builder { ...@@ -100,7 +97,6 @@ class ForwardBuilder extends Builder {
} }
comparator = new PKIXCertComparator(trustedSubjectDNs); comparator = new PKIXCertComparator(trustedSubjectDNs);
this.searchAllCertStores = searchAllCertStores; this.searchAllCertStores = searchAllCertStores;
this.onlyEECert = onlyEECert;
} }
/** /**
...@@ -112,8 +108,9 @@ class ForwardBuilder extends Builder { ...@@ -112,8 +108,9 @@ class ForwardBuilder extends Builder {
* Must be an instance of <code>ForwardState</code> * Must be an instance of <code>ForwardState</code>
* @param certStores list of CertStores * @param certStores list of CertStores
*/ */
Collection<X509Certificate> getMatchingCerts @Override
(State currentState, List<CertStore> certStores) Collection<X509Certificate> getMatchingCerts(State currentState,
List<CertStore> certStores)
throws CertStoreException, CertificateException, IOException throws CertStoreException, CertificateException, IOException
{ {
if (debug != null) { if (debug != null) {
...@@ -127,7 +124,7 @@ class ForwardBuilder extends Builder { ...@@ -127,7 +124,7 @@ class ForwardBuilder extends Builder {
* As each cert is added, it is sorted based on the PKIXCertComparator * As each cert is added, it is sorted based on the PKIXCertComparator
* algorithm. * algorithm.
*/ */
Set<X509Certificate> certs = new TreeSet<X509Certificate>(comparator); Set<X509Certificate> certs = new TreeSet<>(comparator);
/* /*
* Only look for EE certs if search has just started. * Only look for EE certs if search has just started.
...@@ -145,9 +142,10 @@ class ForwardBuilder extends Builder { ...@@ -145,9 +142,10 @@ class ForwardBuilder extends Builder {
* and requirements specified in the parameters and PKIX state. * and requirements specified in the parameters and PKIX state.
*/ */
private void getMatchingEECerts(ForwardState currentState, private void getMatchingEECerts(ForwardState currentState,
List<CertStore> certStores, Collection<X509Certificate> eeCerts) List<CertStore> certStores,
throws IOException { Collection<X509Certificate> eeCerts)
throws IOException
{
if (debug != null) { if (debug != null) {
debug.println("ForwardBuilder.getMatchingEECerts()..."); debug.println("ForwardBuilder.getMatchingEECerts()...");
} }
...@@ -165,12 +163,12 @@ class ForwardBuilder extends Builder { ...@@ -165,12 +163,12 @@ class ForwardBuilder extends Builder {
/* /*
* Match on certificate validity date * Match on certificate validity date
*/ */
eeSelector.setCertificateValid(date); eeSelector.setCertificateValid(buildParams.date());
/* /*
* Policy processing optimizations * Policy processing optimizations
*/ */
if (buildParams.isExplicitPolicyRequired()) { if (buildParams.explicitPolicyRequired()) {
eeSelector.setPolicy(getMatchingPolicies()); eeSelector.setPolicy(getMatchingPolicies());
} }
/* /*
...@@ -188,9 +186,10 @@ class ForwardBuilder extends Builder { ...@@ -188,9 +186,10 @@ class ForwardBuilder extends Builder {
* and requirements specified in the parameters and PKIX state. * and requirements specified in the parameters and PKIX state.
*/ */
private void getMatchingCACerts(ForwardState currentState, private void getMatchingCACerts(ForwardState currentState,
List<CertStore> certStores, Collection<X509Certificate> caCerts) List<CertStore> certStores,
throws IOException { Collection<X509Certificate> caCerts)
throws IOException
{
if (debug != null) { if (debug != null) {
debug.println("ForwardBuilder.getMatchingCACerts()..."); debug.println("ForwardBuilder.getMatchingCACerts()...");
} }
...@@ -216,8 +215,8 @@ class ForwardBuilder extends Builder { ...@@ -216,8 +215,8 @@ class ForwardBuilder extends Builder {
} }
if (caTargetSelector == null) { if (caTargetSelector == null) {
caTargetSelector = (X509CertSelector) caTargetSelector =
targetCertConstraints.clone(); (X509CertSelector) targetCertConstraints.clone();
/* /*
* Since we don't check the validity period of trusted * Since we don't check the validity period of trusted
...@@ -229,7 +228,7 @@ class ForwardBuilder extends Builder { ...@@ -229,7 +228,7 @@ class ForwardBuilder extends Builder {
/* /*
* Policy processing optimizations * Policy processing optimizations
*/ */
if (buildParams.isExplicitPolicyRequired()) if (buildParams.explicitPolicyRequired())
caTargetSelector.setPolicy(getMatchingPolicies()); caTargetSelector.setPolicy(getMatchingPolicies());
} }
...@@ -249,7 +248,7 @@ class ForwardBuilder extends Builder { ...@@ -249,7 +248,7 @@ class ForwardBuilder extends Builder {
/* /*
* Policy processing optimizations * Policy processing optimizations
*/ */
if (buildParams.isExplicitPolicyRequired()) if (buildParams.explicitPolicyRequired())
caSelector.setPolicy(getMatchingPolicies()); caSelector.setPolicy(getMatchingPolicies());
} }
...@@ -278,7 +277,7 @@ class ForwardBuilder extends Builder { ...@@ -278,7 +277,7 @@ class ForwardBuilder extends Builder {
* check the validity period * check the validity period
*/ */
caSelector.setValidityPeriod(currentState.cert.getNotBefore(), caSelector.setValidityPeriod(currentState.cert.getNotBefore(),
currentState.cert.getNotAfter()); currentState.cert.getNotAfter());
sel = caSelector; sel = caSelector;
} }
...@@ -307,7 +306,7 @@ class ForwardBuilder extends Builder { ...@@ -307,7 +306,7 @@ class ForwardBuilder extends Builder {
* The trusted certificate matching is completed. We need to match * The trusted certificate matching is completed. We need to match
* on certificate validity date. * on certificate validity date.
*/ */
sel.setCertificateValid(date); sel.setCertificateValid(buildParams.date());
/* /*
* Require CA certs with a pathLenConstraint that allows * Require CA certs with a pathLenConstraint that allows
...@@ -323,11 +322,12 @@ class ForwardBuilder extends Builder { ...@@ -323,11 +322,12 @@ class ForwardBuilder extends Builder {
* certificate pairs. * certificate pairs.
*/ */
if (currentState.isInitial() || if (currentState.isInitial() ||
(buildParams.getMaxPathLength() == -1) || (buildParams.maxPathLength() == -1) ||
(buildParams.getMaxPathLength() > currentState.traversedCACerts)) (buildParams.maxPathLength() > currentState.traversedCACerts))
{ {
if (addMatchingCerts(sel, certStores, if (addMatchingCerts(sel, certStores,
caCerts, searchAllCertStores) && !searchAllCertStores) { caCerts, searchAllCertStores)
&& !searchAllCertStores) {
return; return;
} }
} }
...@@ -356,7 +356,8 @@ class ForwardBuilder extends Builder { ...@@ -356,7 +356,8 @@ class ForwardBuilder extends Builder {
// because of the selector, so the cast is safe // because of the selector, so the cast is safe
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private boolean getCerts(AuthorityInfoAccessExtension aiaExt, private boolean getCerts(AuthorityInfoAccessExtension aiaExt,
Collection<X509Certificate> certs) { Collection<X509Certificate> certs)
{
if (Builder.USE_AIA == false) { if (Builder.USE_AIA == false) {
return false; return false;
} }
...@@ -449,6 +450,7 @@ class ForwardBuilder extends Builder { ...@@ -449,6 +450,7 @@ class ForwardBuilder extends Builder {
* @throws ClassCastException if either argument is not of type * @throws ClassCastException if either argument is not of type
* X509Certificate * X509Certificate
*/ */
@Override
public int compare(X509Certificate oCert1, X509Certificate oCert2) { public int compare(X509Certificate oCert1, X509Certificate oCert2) {
// if certs are the same, return 0 // if certs are the same, return 0
...@@ -651,8 +653,10 @@ class ForwardBuilder extends Builder { ...@@ -651,8 +653,10 @@ class ForwardBuilder extends Builder {
* @param currentState the current state against which the cert is verified * @param currentState the current state against which the cert is verified
* @param certPathList the certPathList generated thus far * @param certPathList the certPathList generated thus far
*/ */
@Override
void verifyCert(X509Certificate cert, State currentState, void verifyCert(X509Certificate cert, State currentState,
List<X509Certificate> certPathList) throws GeneralSecurityException List<X509Certificate> certPathList)
throws GeneralSecurityException
{ {
if (debug != null) { if (debug != null) {
debug.println("ForwardBuilder.verifyCert(SN: " debug.println("ForwardBuilder.verifyCert(SN: "
...@@ -683,7 +687,7 @@ class ForwardBuilder extends Builder { ...@@ -683,7 +687,7 @@ class ForwardBuilder extends Builder {
debug.println("policyMappingFound = " + policyMappingFound); debug.println("policyMappingFound = " + policyMappingFound);
} }
if (cert.equals(cpListCert)) { if (cert.equals(cpListCert)) {
if ((buildParams.isPolicyMappingInhibited()) || if ((buildParams.policyMappingInhibited()) ||
(!policyMappingFound)) { (!policyMappingFound)) {
if (debug != null) { if (debug != null) {
debug.println("loop detected!!"); debug.println("loop detected!!");
...@@ -718,7 +722,7 @@ class ForwardBuilder extends Builder { ...@@ -718,7 +722,7 @@ class ForwardBuilder extends Builder {
* all extensions that all user checkers are capable of * all extensions that all user checkers are capable of
* processing. * processing.
*/ */
for (PKIXCertPathChecker checker : buildParams.getCertPathCheckers()) { for (PKIXCertPathChecker checker : buildParams.certPathCheckers()) {
if (!checker.isForwardCheckingSupported()) { if (!checker.isForwardCheckingSupported()) {
Set<String> supportedExts = checker.getSupportedExtensions(); Set<String> supportedExts = checker.getSupportedExtensions();
if (supportedExts != null) { if (supportedExts != null) {
...@@ -732,23 +736,15 @@ class ForwardBuilder extends Builder { ...@@ -732,23 +736,15 @@ class ForwardBuilder extends Builder {
* to check. If there are any left, throw an exception! * to check. If there are any left, throw an exception!
*/ */
if (!unresCritExts.isEmpty()) { if (!unresCritExts.isEmpty()) {
unresCritExts.remove( unresCritExts.remove(BasicConstraints_Id.toString());
PKIXExtensions.BasicConstraints_Id.toString()); unresCritExts.remove(NameConstraints_Id.toString());
unresCritExts.remove( unresCritExts.remove(CertificatePolicies_Id.toString());
PKIXExtensions.NameConstraints_Id.toString()); unresCritExts.remove(PolicyMappings_Id.toString());
unresCritExts.remove( unresCritExts.remove(PolicyConstraints_Id.toString());
PKIXExtensions.CertificatePolicies_Id.toString()); unresCritExts.remove(InhibitAnyPolicy_Id.toString());
unresCritExts.remove( unresCritExts.remove(SubjectAlternativeName_Id.toString());
PKIXExtensions.PolicyMappings_Id.toString()); unresCritExts.remove(KeyUsage_Id.toString());
unresCritExts.remove( unresCritExts.remove(ExtendedKeyUsage_Id.toString());
PKIXExtensions.PolicyConstraints_Id.toString());
unresCritExts.remove(
PKIXExtensions.InhibitAnyPolicy_Id.toString());
unresCritExts.remove(
PKIXExtensions.SubjectAlternativeName_Id.toString());
unresCritExts.remove(PKIXExtensions.KeyUsage_Id.toString());
unresCritExts.remove(
PKIXExtensions.ExtendedKeyUsage_Id.toString());
if (!unresCritExts.isEmpty()) if (!unresCritExts.isEmpty())
throw new CertPathValidatorException throw new CertPathValidatorException
...@@ -785,32 +781,13 @@ class ForwardBuilder extends Builder { ...@@ -785,32 +781,13 @@ class ForwardBuilder extends Builder {
* in order to verify a previous cert * in order to verify a previous cert
*/ */
/*
* Check revocation for the previous cert
*/
if (buildParams.isRevocationEnabled()) {
// first off, see if this cert can authorize revocation...
if (CrlRevocationChecker.certCanSignCrl(cert)) {
// And then check to be sure no key requiring key parameters
// has been encountered
if (!currState.keyParamsNeeded())
// If all that checks out, we can check the
// revocation status of the cert. Otherwise,
// we'll just wait until the end.
currState.crlChecker.check(currState.cert,
cert.getPublicKey(),
true);
}
}
/* /*
* Check signature only if no key requiring key parameters has been * Check signature only if no key requiring key parameters has been
* encountered. * encountered.
*/ */
if (!currState.keyParamsNeeded()) { if (!currState.keyParamsNeeded()) {
(currState.cert).verify(cert.getPublicKey(), (currState.cert).verify(cert.getPublicKey(),
buildParams.getSigProvider()); buildParams.sigProvider());
} }
} }
...@@ -826,6 +803,7 @@ class ForwardBuilder extends Builder { ...@@ -826,6 +803,7 @@ class ForwardBuilder extends Builder {
* @param cert the certificate to test * @param cert the certificate to test
* @return a boolean value indicating whether the cert completes the path. * @return a boolean value indicating whether the cert completes the path.
*/ */
@Override
boolean isPathCompleted(X509Certificate cert) { boolean isPathCompleted(X509Certificate cert) {
for (TrustAnchor anchor : trustAnchors) { for (TrustAnchor anchor : trustAnchors) {
if (anchor.getTrustedCert() != null) { if (anchor.getTrustedCert() != null) {
...@@ -837,7 +815,7 @@ class ForwardBuilder extends Builder { ...@@ -837,7 +815,7 @@ class ForwardBuilder extends Builder {
} }
} else { } else {
X500Principal principal = anchor.getCA(); X500Principal principal = anchor.getCA();
java.security.PublicKey publicKey = anchor.getCAPublicKey(); PublicKey publicKey = anchor.getCAPublicKey();
if (principal != null && publicKey != null && if (principal != null && publicKey != null &&
principal.equals(cert.getSubjectX500Principal())) { principal.equals(cert.getSubjectX500Principal())) {
...@@ -856,21 +834,6 @@ class ForwardBuilder extends Builder { ...@@ -856,21 +834,6 @@ class ForwardBuilder extends Builder {
} }
} }
/* Check revocation if it is enabled */
if (buildParams.isRevocationEnabled()) {
try {
CrlRevocationChecker crlChecker = new CrlRevocationChecker
(anchor, buildParams, null, onlyEECert);
crlChecker.check(cert, anchor.getCAPublicKey(), true);
} catch (CertPathValidatorException cpve) {
if (debug != null) {
debug.println("ForwardBuilder.isPathCompleted() cpve");
cpve.printStackTrace();
}
continue;
}
}
/* /*
* Check signature * Check signature
*/ */
...@@ -879,18 +842,17 @@ class ForwardBuilder extends Builder { ...@@ -879,18 +842,17 @@ class ForwardBuilder extends Builder {
// parameters, yet there is no key to inherit the parameters // parameters, yet there is no key to inherit the parameters
// from. This is probably such a rare case that it is not worth // from. This is probably such a rare case that it is not worth
// trying to detect the situation earlier. // trying to detect the situation earlier.
cert.verify(anchor.getCAPublicKey(), cert.verify(anchor.getCAPublicKey(), buildParams.sigProvider());
buildParams.getSigProvider());
} catch (InvalidKeyException ike) { } catch (InvalidKeyException ike) {
if (debug != null) { if (debug != null) {
debug.println("ForwardBuilder.isPathCompleted() invalid " debug.println("ForwardBuilder.isPathCompleted() invalid "
+ "DSA key found"); + "DSA key found");
} }
continue; continue;
} catch (Exception e){ } catch (GeneralSecurityException e){
if (debug != null) { if (debug != null) {
debug.println("ForwardBuilder.isPathCompleted() " + debug.println("ForwardBuilder.isPathCompleted() " +
"unexpected exception"); "unexpected exception");
e.printStackTrace(); e.printStackTrace();
} }
continue; continue;
...@@ -908,8 +870,10 @@ class ForwardBuilder extends Builder { ...@@ -908,8 +870,10 @@ class ForwardBuilder extends Builder {
* @param cert the certificate to be added * @param cert the certificate to be added
* @param certPathList the certification path list * @param certPathList the certification path list
*/ */
@Override
void addCertToPath(X509Certificate cert, void addCertToPath(X509Certificate cert,
LinkedList<X509Certificate> certPathList) { LinkedList<X509Certificate> certPathList)
{
certPathList.addFirst(cert); certPathList.addFirst(cert);
} }
...@@ -917,6 +881,7 @@ class ForwardBuilder extends Builder { ...@@ -917,6 +881,7 @@ class ForwardBuilder extends Builder {
* *
* @param certPathList the certification path list * @param certPathList the certification path list
*/ */
@Override
void removeFinalCertFromPath(LinkedList<X509Certificate> certPathList) { void removeFinalCertFromPath(LinkedList<X509Certificate> certPathList) {
certPathList.removeFirst(); certPathList.removeFirst();
} }
......
/* /*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -34,7 +34,6 @@ import java.security.cert.X509Certificate; ...@@ -34,7 +34,6 @@ import java.security.cert.X509Certificate;
import java.security.interfaces.DSAPublicKey; import java.security.interfaces.DSAPublicKey;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import javax.security.auth.x500.X500Principal; import javax.security.auth.x500.X500Principal;
...@@ -76,9 +75,6 @@ class ForwardState implements State { ...@@ -76,9 +75,6 @@ class ForwardState implements State {
/* Flag indicating if state is initial (path is just starting) */ /* Flag indicating if state is initial (path is just starting) */
private boolean init = true; private boolean init = true;
/* the checker used for revocation status */
public CrlRevocationChecker crlChecker;
/* The list of user-defined checkers that support forward checking */ /* The list of user-defined checkers that support forward checking */
ArrayList<PKIXCertPathChecker> forwardCheckers; ArrayList<PKIXCertPathChecker> forwardCheckers;
...@@ -93,6 +89,7 @@ class ForwardState implements State { ...@@ -93,6 +89,7 @@ class ForwardState implements State {
* *
* @return boolean flag indicating if the state is initial (just starting) * @return boolean flag indicating if the state is initial (just starting)
*/ */
@Override
public boolean isInitial() { public boolean isInitial() {
return init; return init;
} }
...@@ -104,6 +101,7 @@ class ForwardState implements State { ...@@ -104,6 +101,7 @@ class ForwardState implements State {
* @return boolean true if key needing to inherit parameters has been * @return boolean true if key needing to inherit parameters has been
* encountered; false otherwise. * encountered; false otherwise.
*/ */
@Override
public boolean keyParamsNeeded() { public boolean keyParamsNeeded() {
return keyParamsNeededFlag; return keyParamsNeededFlag;
} }
...@@ -111,23 +109,18 @@ class ForwardState implements State { ...@@ -111,23 +109,18 @@ class ForwardState implements State {
/** /**
* Display state for debugging purposes * Display state for debugging purposes
*/ */
@Override
public String toString() { public String toString() {
StringBuffer sb = new StringBuffer(); StringBuilder sb = new StringBuilder();
try { sb.append("State [");
sb.append("State ["); sb.append("\n issuerDN of last cert: ").append(issuerDN);
sb.append("\n issuerDN of last cert: " + issuerDN); sb.append("\n traversedCACerts: ").append(traversedCACerts);
sb.append("\n traversedCACerts: " + traversedCACerts); sb.append("\n init: ").append(String.valueOf(init));
sb.append("\n init: " + String.valueOf(init)); sb.append("\n keyParamsNeeded: ").append
sb.append("\n keyParamsNeeded: " (String.valueOf(keyParamsNeededFlag));
+ String.valueOf(keyParamsNeededFlag)); sb.append("\n subjectNamesTraversed: \n").append
sb.append("\n subjectNamesTraversed: \n" + subjectNamesTraversed); (subjectNamesTraversed);
sb.append("]\n"); sb.append("]\n");
} catch (Exception e) {
if (debug != null) {
debug.println("ForwardState.toString() unexpected exception");
e.printStackTrace();
}
}
return sb.toString(); return sb.toString();
} }
...@@ -147,12 +140,10 @@ class ForwardState implements State { ...@@ -147,12 +140,10 @@ class ForwardState implements State {
* that supports forward checking and initialize the forwardCheckers * that supports forward checking and initialize the forwardCheckers
*/ */
forwardCheckers = new ArrayList<PKIXCertPathChecker>(); forwardCheckers = new ArrayList<PKIXCertPathChecker>();
if (certPathCheckers != null) { for (PKIXCertPathChecker checker : certPathCheckers) {
for (PKIXCertPathChecker checker : certPathCheckers) { if (checker.isForwardCheckingSupported()) {
if (checker.isForwardCheckingSupported()) { checker.init(true);
checker.init(true); forwardCheckers.add(checker);
forwardCheckers.add(checker);
}
} }
} }
...@@ -164,6 +155,7 @@ class ForwardState implements State { ...@@ -164,6 +155,7 @@ class ForwardState implements State {
* *
* @param cert the certificate which is used to update the state * @param cert the certificate which is used to update the state
*/ */
@Override
public void updateState(X509Certificate cert) public void updateState(X509Certificate cert)
throws CertificateException, IOException, CertPathValidatorException { throws CertificateException, IOException, CertPathValidatorException {
...@@ -208,13 +200,11 @@ class ForwardState implements State { ...@@ -208,13 +200,11 @@ class ForwardState implements State {
if (subjAltNameExt != null) { if (subjAltNameExt != null) {
GeneralNames gNames = subjAltNameExt.get( GeneralNames gNames = subjAltNameExt.get(
SubjectAlternativeNameExtension.SUBJECT_NAME); SubjectAlternativeNameExtension.SUBJECT_NAME);
for (Iterator<GeneralName> t = gNames.iterator(); for (GeneralName gName : gNames.names()) {
t.hasNext(); ) { subjectNamesTraversed.add(gName.getName());
GeneralNameInterface gName = t.next().getName();
subjectNamesTraversed.add(gName);
} }
} }
} catch (Exception e) { } catch (IOException e) {
if (debug != null) { if (debug != null) {
debug.println("ForwardState.updateState() unexpected " debug.println("ForwardState.updateState() unexpected "
+ "exception"); + "exception");
...@@ -236,6 +226,7 @@ class ForwardState implements State { ...@@ -236,6 +226,7 @@ class ForwardState implements State {
* because some of them will * because some of them will
* not have their contents modified by subsequent calls to updateState. * not have their contents modified by subsequent calls to updateState.
*/ */
@Override
@SuppressWarnings("unchecked") // Safe casts assuming clone() works correctly @SuppressWarnings("unchecked") // Safe casts assuming clone() works correctly
public Object clone() { public Object clone() {
try { try {
......
/* /*
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -180,7 +180,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi { ...@@ -180,7 +180,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
if (cert.equals(oldEntry)) { if (cert.equals(oldEntry)) {
return; return;
} }
List<X509Certificate> list = new ArrayList<X509Certificate>(2); List<X509Certificate> list = new ArrayList<>(2);
list.add(cert); list.add(cert);
list.add((X509Certificate)oldEntry); list.add((X509Certificate)oldEntry);
certSubjects.put(subject, list); certSubjects.put(subject, list);
...@@ -206,7 +206,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi { ...@@ -206,7 +206,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
if (crl.equals(oldEntry)) { if (crl.equals(oldEntry)) {
return; return;
} }
List<X509CRL> list = new ArrayList<X509CRL>(2); List<X509CRL> list = new ArrayList<>(2);
list.add(crl); list.add(crl);
list.add((X509CRL)oldEntry); list.add((X509CRL)oldEntry);
crlIssuers.put(issuer, list); crlIssuers.put(issuer, list);
...@@ -234,19 +234,20 @@ public class IndexedCollectionCertStore extends CertStoreSpi { ...@@ -234,19 +234,20 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
* match the specified selector * match the specified selector
* @throws CertStoreException if an exception occurs * @throws CertStoreException if an exception occurs
*/ */
@Override
public Collection<? extends Certificate> engineGetCertificates(CertSelector selector) public Collection<? extends Certificate> engineGetCertificates(CertSelector selector)
throws CertStoreException { throws CertStoreException {
// no selector means match all // no selector means match all
if (selector == null) { if (selector == null) {
Set<Certificate> matches = new HashSet<Certificate>(); Set<Certificate> matches = new HashSet<>();
matchX509Certs(new X509CertSelector(), matches); matchX509Certs(new X509CertSelector(), matches);
matches.addAll(otherCertificates); matches.addAll(otherCertificates);
return matches; return matches;
} }
if (selector instanceof X509CertSelector == false) { if (selector instanceof X509CertSelector == false) {
Set<Certificate> matches = new HashSet<Certificate>(); Set<Certificate> matches = new HashSet<>();
matchX509Certs(selector, matches); matchX509Certs(selector, matches);
for (Certificate cert : otherCertificates) { for (Certificate cert : otherCertificates) {
if (selector.match(cert)) { if (selector.match(cert)) {
...@@ -285,7 +286,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi { ...@@ -285,7 +286,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
// See certSubjects javadoc. // See certSubjects javadoc.
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<X509Certificate> list = (List<X509Certificate>)entry; List<X509Certificate> list = (List<X509Certificate>)entry;
Set<X509Certificate> matches = new HashSet<X509Certificate>(16); Set<X509Certificate> matches = new HashSet<>(16);
for (X509Certificate cert : list) { for (X509Certificate cert : list) {
if (x509Selector.match(cert)) { if (x509Selector.match(cert)) {
matches.add(cert); matches.add(cert);
...@@ -295,7 +296,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi { ...@@ -295,7 +296,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
} }
} }
// cannot use index, iterate all // cannot use index, iterate all
Set<Certificate> matches = new HashSet<Certificate>(16); Set<Certificate> matches = new HashSet<>(16);
matchX509Certs(x509Selector, matches); matchX509Certs(x509Selector, matches);
return matches; return matches;
} }
...@@ -338,18 +339,19 @@ public class IndexedCollectionCertStore extends CertStoreSpi { ...@@ -338,18 +339,19 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
* match the specified selector * match the specified selector
* @throws CertStoreException if an exception occurs * @throws CertStoreException if an exception occurs
*/ */
@Override
public Collection<CRL> engineGetCRLs(CRLSelector selector) public Collection<CRL> engineGetCRLs(CRLSelector selector)
throws CertStoreException { throws CertStoreException {
if (selector == null) { if (selector == null) {
Set<CRL> matches = new HashSet<CRL>(); Set<CRL> matches = new HashSet<>();
matchX509CRLs(new X509CRLSelector(), matches); matchX509CRLs(new X509CRLSelector(), matches);
matches.addAll(otherCRLs); matches.addAll(otherCRLs);
return matches; return matches;
} }
if (selector instanceof X509CRLSelector == false) { if (selector instanceof X509CRLSelector == false) {
Set<CRL> matches = new HashSet<CRL>(); Set<CRL> matches = new HashSet<>();
matchX509CRLs(selector, matches); matchX509CRLs(selector, matches);
for (CRL crl : otherCRLs) { for (CRL crl : otherCRLs) {
if (selector.match(crl)) { if (selector.match(crl)) {
...@@ -366,7 +368,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi { ...@@ -366,7 +368,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
// see if the issuer is specified // see if the issuer is specified
Collection<X500Principal> issuers = x509Selector.getIssuers(); Collection<X500Principal> issuers = x509Selector.getIssuers();
if (issuers != null) { if (issuers != null) {
HashSet<CRL> matches = new HashSet<CRL>(16); HashSet<CRL> matches = new HashSet<>(16);
for (X500Principal issuer : issuers) { for (X500Principal issuer : issuers) {
Object entry = crlIssuers.get(issuer); Object entry = crlIssuers.get(issuer);
if (entry == null) { if (entry == null) {
...@@ -390,7 +392,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi { ...@@ -390,7 +392,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
return matches; return matches;
} }
// cannot use index, iterate all // cannot use index, iterate all
Set<CRL> matches = new HashSet<CRL>(16); Set<CRL> matches = new HashSet<>(16);
matchX509CRLs(x509Selector, matches); matchX509CRLs(x509Selector, matches);
return matches; return matches;
} }
......
/* /*
* Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -30,7 +30,7 @@ import java.security.cert.*; ...@@ -30,7 +30,7 @@ import java.security.cert.*;
import java.security.cert.PKIXReason; import java.security.cert.PKIXReason;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.x509.PKIXExtensions; import static sun.security.x509.PKIXExtensions.*;
/** /**
* KeyChecker is a <code>PKIXCertPathChecker</code> that checks that the * KeyChecker is a <code>PKIXCertPathChecker</code> that checks that the
...@@ -45,33 +45,29 @@ import sun.security.x509.PKIXExtensions; ...@@ -45,33 +45,29 @@ import sun.security.x509.PKIXExtensions;
class KeyChecker extends PKIXCertPathChecker { class KeyChecker extends PKIXCertPathChecker {
private static final Debug debug = Debug.getInstance("certpath"); private static final Debug debug = Debug.getInstance("certpath");
// the index of keyCertSign in the boolean KeyUsage array
private static final int keyCertSign = 5;
private final int certPathLen; private final int certPathLen;
private CertSelector targetConstraints; private final CertSelector targetConstraints;
private int remainingCerts; private int remainingCerts;
private Set<String> supportedExts; private Set<String> supportedExts;
/** /**
* Default Constructor * Creates a KeyChecker.
* *
* @param certPathLen allowable cert path length * @param certPathLen allowable cert path length
* @param targetCertSel a CertSelector object specifying the constraints * @param targetCertSel a CertSelector object specifying the constraints
* on the target certificate * on the target certificate
*/ */
KeyChecker(int certPathLen, CertSelector targetCertSel) KeyChecker(int certPathLen, CertSelector targetCertSel) {
throws CertPathValidatorException
{
this.certPathLen = certPathLen; this.certPathLen = certPathLen;
this.targetConstraints = targetCertSel; this.targetConstraints = targetCertSel;
init(false);
} }
/** /**
* Initializes the internal state of the checker from parameters * Initializes the internal state of the checker from parameters
* specified in the constructor * specified in the constructor
*/ */
@Override
public void init(boolean forward) throws CertPathValidatorException { public void init(boolean forward) throws CertPathValidatorException {
if (!forward) { if (!forward) {
remainingCerts = certPathLen; remainingCerts = certPathLen;
...@@ -81,16 +77,18 @@ class KeyChecker extends PKIXCertPathChecker { ...@@ -81,16 +77,18 @@ class KeyChecker extends PKIXCertPathChecker {
} }
} }
public final boolean isForwardCheckingSupported() { @Override
public boolean isForwardCheckingSupported() {
return false; return false;
} }
@Override
public Set<String> getSupportedExtensions() { public Set<String> getSupportedExtensions() {
if (supportedExts == null) { if (supportedExts == null) {
supportedExts = new HashSet<String>(); supportedExts = new HashSet<String>(3);
supportedExts.add(PKIXExtensions.KeyUsage_Id.toString()); supportedExts.add(KeyUsage_Id.toString());
supportedExts.add(PKIXExtensions.ExtendedKeyUsage_Id.toString()); supportedExts.add(ExtendedKeyUsage_Id.toString());
supportedExts.add(PKIXExtensions.SubjectAlternativeName_Id.toString()); supportedExts.add(SubjectAlternativeName_Id.toString());
supportedExts = Collections.unmodifiableSet(supportedExts); supportedExts = Collections.unmodifiableSet(supportedExts);
} }
return supportedExts; return supportedExts;
...@@ -102,20 +100,20 @@ class KeyChecker extends PKIXCertPathChecker { ...@@ -102,20 +100,20 @@ class KeyChecker extends PKIXCertPathChecker {
* *
* @param cert the Certificate * @param cert the Certificate
* @param unresolvedCritExts the unresolved critical extensions * @param unresolvedCritExts the unresolved critical extensions
* @exception CertPathValidatorException Exception thrown if certificate * @throws CertPathValidatorException if certificate does not verify
* does not verify
*/ */
@Override
public void check(Certificate cert, Collection<String> unresCritExts) public void check(Certificate cert, Collection<String> unresCritExts)
throws CertPathValidatorException throws CertPathValidatorException
{ {
X509Certificate currCert = (X509Certificate) cert; X509Certificate currCert = (X509Certificate)cert;
remainingCerts--; remainingCerts--;
// if final certificate, check that target constraints are satisfied // if final certificate, check that target constraints are satisfied
if (remainingCerts == 0) { if (remainingCerts == 0) {
if ((targetConstraints != null) && if (targetConstraints != null &&
(targetConstraints.match(currCert) == false)) { targetConstraints.match(currCert) == false) {
throw new CertPathValidatorException("target certificate " + throw new CertPathValidatorException("target certificate " +
"constraints check failed"); "constraints check failed");
} }
...@@ -126,25 +124,26 @@ class KeyChecker extends PKIXCertPathChecker { ...@@ -126,25 +124,26 @@ class KeyChecker extends PKIXCertPathChecker {
// remove the extensions that we have checked // remove the extensions that we have checked
if (unresCritExts != null && !unresCritExts.isEmpty()) { if (unresCritExts != null && !unresCritExts.isEmpty()) {
unresCritExts.remove(PKIXExtensions.KeyUsage_Id.toString()); unresCritExts.remove(KeyUsage_Id.toString());
unresCritExts.remove(PKIXExtensions.ExtendedKeyUsage_Id.toString()); unresCritExts.remove(ExtendedKeyUsage_Id.toString());
unresCritExts.remove( unresCritExts.remove(SubjectAlternativeName_Id.toString());
PKIXExtensions.SubjectAlternativeName_Id.toString());
} }
} }
// the index of keyCertSign in the boolean KeyUsage array
private static final int KEY_CERT_SIGN = 5;
/** /**
* Static method to verify that the key usage and extended key usage * Verifies the key usage extension in a CA cert.
* extension in a CA cert. The key usage extension, if present, must * The key usage extension, if present, must assert the keyCertSign bit.
* assert the keyCertSign bit. The extended key usage extension, if * The extended key usage extension is not checked (see CR 4776794 for
* present, must include anyExtendedKeyUsage. * more information).
*/ */
static void verifyCAKeyUsage(X509Certificate cert) static void verifyCAKeyUsage(X509Certificate cert)
throws CertPathValidatorException { throws CertPathValidatorException {
String msg = "CA key usage"; String msg = "CA key usage";
if (debug != null) { if (debug != null) {
debug.println("KeyChecker.verifyCAKeyUsage() ---checking " + msg debug.println("KeyChecker.verifyCAKeyUsage() ---checking " + msg
+ "..."); + "...");
} }
boolean[] keyUsageBits = cert.getKeyUsage(); boolean[] keyUsageBits = cert.getKeyUsage();
...@@ -156,7 +155,7 @@ class KeyChecker extends PKIXCertPathChecker { ...@@ -156,7 +155,7 @@ class KeyChecker extends PKIXCertPathChecker {
} }
// throw an exception if the keyCertSign bit is not set // throw an exception if the keyCertSign bit is not set
if (!keyUsageBits[keyCertSign]) { if (!keyUsageBits[KEY_CERT_SIGN]) {
throw new CertPathValidatorException throw new CertPathValidatorException
(msg + " check failed: keyCertSign bit is not set", null, (msg + " check failed: keyCertSign bit is not set", null,
null, -1, PKIXReason.INVALID_KEY_USAGE); null, -1, PKIXReason.INVALID_KEY_USAGE);
...@@ -164,7 +163,7 @@ class KeyChecker extends PKIXCertPathChecker { ...@@ -164,7 +163,7 @@ class KeyChecker extends PKIXCertPathChecker {
if (debug != null) { if (debug != null) {
debug.println("KeyChecker.verifyCAKeyUsage() " + msg debug.println("KeyChecker.verifyCAKeyUsage() " + msg
+ " verified."); + " verified.");
} }
} }
} }
/* /*
* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -43,6 +43,7 @@ import java.util.Map; ...@@ -43,6 +43,7 @@ import java.util.Map;
import static sun.security.provider.certpath.OCSPResponse.*; import static sun.security.provider.certpath.OCSPResponse.*;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.util.ObjectIdentifier;
import sun.security.x509.AccessDescription; import sun.security.x509.AccessDescription;
import sun.security.x509.AuthorityInfoAccessExtension; import sun.security.x509.AuthorityInfoAccessExtension;
import sun.security.x509.GeneralName; import sun.security.x509.GeneralName;
...@@ -62,6 +63,9 @@ import sun.security.x509.X509CertImpl; ...@@ -62,6 +63,9 @@ import sun.security.x509.X509CertImpl;
*/ */
public final class OCSP { public final class OCSP {
static final ObjectIdentifier NONCE_EXTENSION_OID =
ObjectIdentifier.newInternal(new int[]{ 1, 3, 6, 1, 5, 5, 7, 48, 1, 2});
private static final Debug debug = Debug.getInstance("certpath"); private static final Debug debug = Debug.getInstance("certpath");
private static final int CONNECT_TIMEOUT = 15000; // 15 seconds private static final int CONNECT_TIMEOUT = 15000; // 15 seconds
...@@ -83,7 +87,7 @@ public final class OCSP { ...@@ -83,7 +87,7 @@ public final class OCSP {
* encoding the OCSP Request or validating the OCSP Response * encoding the OCSP Request or validating the OCSP Response
*/ */
public static RevocationStatus check(X509Certificate cert, public static RevocationStatus check(X509Certificate cert,
X509Certificate issuerCert) X509Certificate issuerCert)
throws IOException, CertPathValidatorException { throws IOException, CertPathValidatorException {
CertId certId = null; CertId certId = null;
URI responderURI = null; URI responderURI = null;
...@@ -95,16 +99,13 @@ public final class OCSP { ...@@ -95,16 +99,13 @@ public final class OCSP {
("No OCSP Responder URI in certificate"); ("No OCSP Responder URI in certificate");
} }
certId = new CertId(issuerCert, certImpl.getSerialNumberObject()); certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
} catch (CertificateException ce) { } catch (CertificateException | IOException e) {
throw new CertPathValidatorException
("Exception while encoding OCSPRequest", ce);
} catch (IOException ioe) {
throw new CertPathValidatorException throw new CertPathValidatorException
("Exception while encoding OCSPRequest", ioe); ("Exception while encoding OCSPRequest", e);
} }
OCSPResponse ocspResponse = check(Collections.singletonList(certId), OCSPResponse ocspResponse = check(Collections.singletonList(certId),
responderURI, issuerCert, null); responderURI, issuerCert, null, Collections.<Extension>emptyList());
return (RevocationStatus) ocspResponse.getSingleResponse(certId); return (RevocationStatus)ocspResponse.getSingleResponse(certId);
} }
/** /**
...@@ -123,22 +124,34 @@ public final class OCSP { ...@@ -123,22 +124,34 @@ public final class OCSP {
* encoding the OCSP Request or validating the OCSP Response * encoding the OCSP Request or validating the OCSP Response
*/ */
public static RevocationStatus check(X509Certificate cert, public static RevocationStatus check(X509Certificate cert,
X509Certificate issuerCert, URI responderURI, X509Certificate X509Certificate issuerCert,
responderCert, Date date) URI responderURI,
throws IOException, CertPathValidatorException { X509Certificate responderCert,
Date date)
throws IOException, CertPathValidatorException
{
return check(cert, issuerCert, responderURI, responderCert, date,
Collections.<Extension>emptyList());
}
// Called by com.sun.deploy.security.TrustDecider
public static RevocationStatus check(X509Certificate cert,
X509Certificate issuerCert,
URI responderURI,
X509Certificate responderCert,
Date date, List<Extension> extensions)
throws IOException, CertPathValidatorException
{
CertId certId = null; CertId certId = null;
try { try {
X509CertImpl certImpl = X509CertImpl.toImpl(cert); X509CertImpl certImpl = X509CertImpl.toImpl(cert);
certId = new CertId(issuerCert, certImpl.getSerialNumberObject()); certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
} catch (CertificateException ce) { } catch (CertificateException | IOException e) {
throw new CertPathValidatorException throw new CertPathValidatorException
("Exception while encoding OCSPRequest", ce); ("Exception while encoding OCSPRequest", e);
} catch (IOException ioe) {
throw new CertPathValidatorException
("Exception while encoding OCSPRequest", ioe);
} }
OCSPResponse ocspResponse = check(Collections.singletonList(certId), OCSPResponse ocspResponse = check(Collections.singletonList(certId),
responderURI, responderCert, date); responderURI, responderCert, date, extensions);
return (RevocationStatus) ocspResponse.getSingleResponse(certId); return (RevocationStatus) ocspResponse.getSingleResponse(certId);
} }
...@@ -157,12 +170,14 @@ public final class OCSP { ...@@ -157,12 +170,14 @@ public final class OCSP {
* encoding the OCSP Request or validating the OCSP Response * encoding the OCSP Request or validating the OCSP Response
*/ */
static OCSPResponse check(List<CertId> certIds, URI responderURI, static OCSPResponse check(List<CertId> certIds, URI responderURI,
X509Certificate responderCert, Date date) X509Certificate responderCert, Date date,
throws IOException, CertPathValidatorException { List<Extension> extensions)
throws IOException, CertPathValidatorException
{
byte[] bytes = null; byte[] bytes = null;
OCSPRequest request = null;
try { try {
OCSPRequest request = new OCSPRequest(certIds); request = new OCSPRequest(certIds, extensions);
bytes = request.encodeBytes(); bytes = request.encodeBytes();
} catch (IOException ioe) { } catch (IOException ioe) {
throw new CertPathValidatorException throw new CertPathValidatorException
...@@ -214,6 +229,8 @@ public final class OCSP { ...@@ -214,6 +229,8 @@ public final class OCSP {
} }
} }
response = Arrays.copyOf(response, total); response = Arrays.copyOf(response, total);
} catch (IOException ioe) {
throw new NetworkFailureException(ioe);
} finally { } finally {
if (in != null) { if (in != null) {
try { try {
...@@ -233,33 +250,15 @@ public final class OCSP { ...@@ -233,33 +250,15 @@ public final class OCSP {
OCSPResponse ocspResponse = null; OCSPResponse ocspResponse = null;
try { try {
ocspResponse = new OCSPResponse(response, date, responderCert); ocspResponse = new OCSPResponse(response);
} catch (IOException ioe) { } catch (IOException ioe) {
// response decoding exception // response decoding exception
throw new CertPathValidatorException(ioe); throw new CertPathValidatorException(ioe);
} }
if (ocspResponse.getResponseStatus() != ResponseStatus.SUCCESSFUL) {
throw new CertPathValidatorException
("OCSP response error: " + ocspResponse.getResponseStatus());
}
// Check that the response includes a response for all of the // verify the response
// certs that were supplied in the request ocspResponse.verify(certIds, responderCert, date, request.getNonce());
for (CertId certId : certIds) {
SingleResponse sr = ocspResponse.getSingleResponse(certId);
if (sr == null) {
if (debug != null) {
debug.println("No response found for CertId: " + certId);
}
throw new CertPathValidatorException(
"OCSP response does not include a response for a " +
"certificate supplied in the OCSP request");
}
if (debug != null) {
debug.println("Status of certificate (with serial number " +
certId.getSerialNumber() + ") is: " + sr.getCertStatus());
}
}
return ocspResponse; return ocspResponse;
} }
...@@ -271,6 +270,7 @@ public final class OCSP { ...@@ -271,6 +270,7 @@ public final class OCSP {
* @param cert the certificate * @param cert the certificate
* @return the URI of the OCSP Responder, or null if not specified * @return the URI of the OCSP Responder, or null if not specified
*/ */
// Called by com.sun.deploy.security.TrustDecider
public static URI getResponderURI(X509Certificate cert) { public static URI getResponderURI(X509Certificate cert) {
try { try {
return getResponderURI(X509CertImpl.toImpl(cert)); return getResponderURI(X509CertImpl.toImpl(cert));
...@@ -330,4 +330,12 @@ public final class OCSP { ...@@ -330,4 +330,12 @@ public final class OCSP {
*/ */
Map<String, Extension> getSingleExtensions(); Map<String, Extension> getSingleExtensions();
} }
static class NetworkFailureException extends CertPathValidatorException {
private static final long serialVersionUID = 0l;
private NetworkFailureException(IOException ioe) {
super(ioe);
}
}
} }
/*
* Copyright (c) 2003, 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.math.BigInteger;
import java.util.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.Security;
import java.security.cert.*;
import java.security.cert.CertPathValidatorException.BasicReason;
import java.net.URI;
import java.net.URISyntaxException;
import javax.security.auth.x500.X500Principal;
import static sun.security.provider.certpath.OCSP.*;
import sun.security.util.Debug;
import sun.security.x509.*;
/**
* OCSPChecker is a <code>PKIXCertPathChecker</code> that uses the
* Online Certificate Status Protocol (OCSP) as specified in RFC 2560
* <a href="http://www.ietf.org/rfc/rfc2560.txt">
* http://www.ietf.org/rfc/rfc2560.txt</a>.
*
* @author Ram Marti
*/
class OCSPChecker extends PKIXCertPathChecker {
static final String OCSP_ENABLE_PROP = "ocsp.enable";
static final String OCSP_URL_PROP = "ocsp.responderURL";
static final String OCSP_CERT_SUBJECT_PROP =
"ocsp.responderCertSubjectName";
static final String OCSP_CERT_ISSUER_PROP = "ocsp.responderCertIssuerName";
static final String OCSP_CERT_NUMBER_PROP =
"ocsp.responderCertSerialNumber";
private static final String HEX_DIGITS = "0123456789ABCDEFabcdef";
private static final Debug DEBUG = Debug.getInstance("certpath");
private static final boolean dump = false;
private int remainingCerts;
private X509Certificate[] certs;
private CertPath cp;
private PKIXParameters pkixParams;
private boolean onlyEECert = false;
/**
* Default Constructor
*
* @param certPath the X509 certification path
* @param pkixParams the input PKIX parameter set
* @throws CertPathValidatorException if OCSPChecker can not be created
*/
OCSPChecker(CertPath certPath, PKIXParameters pkixParams)
throws CertPathValidatorException {
this(certPath, pkixParams, false);
}
OCSPChecker(CertPath certPath, PKIXParameters pkixParams, boolean onlyEECert)
throws CertPathValidatorException {
this.cp = certPath;
this.pkixParams = pkixParams;
this.onlyEECert = onlyEECert;
List<? extends Certificate> tmp = cp.getCertificates();
certs = tmp.toArray(new X509Certificate[tmp.size()]);
init(false);
}
/**
* Initializes the internal state of the checker from parameters
* specified in the constructor
*/
@Override
public void init(boolean forward) throws CertPathValidatorException {
if (!forward) {
remainingCerts = certs.length + 1;
} else {
throw new CertPathValidatorException(
"Forward checking not supported");
}
}
@Override public boolean isForwardCheckingSupported() {
return false;
}
@Override public Set<String> getSupportedExtensions() {
return Collections.<String>emptySet();
}
/**
* Sends an OCSPRequest for the certificate to the OCSP Server and
* processes the response back from the OCSP Server.
*
* @param cert the Certificate
* @param unresolvedCritExts the unresolved critical extensions
* @exception CertPathValidatorException Exception is thrown if the
* certificate has been revoked.
*/
@Override
public void check(Certificate cert, Collection<String> unresolvedCritExts)
throws CertPathValidatorException {
// Decrement the certificate counter
remainingCerts--;
X509CertImpl currCertImpl = null;
try {
currCertImpl = X509CertImpl.toImpl((X509Certificate)cert);
} catch (CertificateException ce) {
throw new CertPathValidatorException(ce);
}
if (onlyEECert && currCertImpl.getBasicConstraints() != -1) {
if (DEBUG != null) {
DEBUG.println("Skipping revocation check, not end entity cert");
}
return;
}
/*
* OCSP security property values, in the following order:
* 1. ocsp.responderURL
* 2. ocsp.responderCertSubjectName
* 3. ocsp.responderCertIssuerName
* 4. ocsp.responderCertSerialNumber
*/
// should cache these properties to avoid calling every time?
String[] properties = getOCSPProperties();
// Check whether OCSP is feasible before seeking cert information
URI uri = getOCSPServerURI(currCertImpl, properties[0]);
// When responder's subject name is set then the issuer/serial
// properties are ignored
X500Principal responderSubjectName = null;
X500Principal responderIssuerName = null;
BigInteger responderSerialNumber = null;
if (properties[1] != null) {
responderSubjectName = new X500Principal(properties[1]);
} else if (properties[2] != null && properties[3] != null) {
responderIssuerName = new X500Principal(properties[2]);
// remove colon or space separators
String value = stripOutSeparators(properties[3]);
responderSerialNumber = new BigInteger(value, 16);
} else if (properties[2] != null || properties[3] != null) {
throw new CertPathValidatorException(
"Must specify both ocsp.responderCertIssuerName and " +
"ocsp.responderCertSerialNumber properties");
}
// If the OCSP responder cert properties are set then the
// identified cert must be located in the trust anchors or
// in the cert stores.
boolean seekResponderCert = false;
if (responderSubjectName != null || responderIssuerName != null) {
seekResponderCert = true;
}
// Set the issuer certificate to the next cert in the chain
// (unless we're processing the final cert).
X509Certificate issuerCert = null;
boolean seekIssuerCert = true;
X509Certificate responderCert = null;
if (remainingCerts < certs.length) {
issuerCert = certs[remainingCerts];
seekIssuerCert = false; // done
// By default, the OCSP responder's cert is the same as the
// issuer of the cert being validated.
if (!seekResponderCert) {
responderCert = issuerCert;
if (DEBUG != null) {
DEBUG.println("Responder's certificate is the same " +
"as the issuer of the certificate being validated");
}
}
}
// Check anchor certs for:
// - the issuer cert (of the cert being validated)
// - the OCSP responder's cert
if (seekIssuerCert || seekResponderCert) {
if (DEBUG != null && seekResponderCert) {
DEBUG.println("Searching trust anchors for responder's " +
"certificate");
}
// Extract the anchor certs
Iterator<TrustAnchor> anchors
= pkixParams.getTrustAnchors().iterator();
if (!anchors.hasNext()) {
throw new CertPathValidatorException(
"Must specify at least one trust anchor");
}
X500Principal certIssuerName =
currCertImpl.getIssuerX500Principal();
while (anchors.hasNext() && (seekIssuerCert || seekResponderCert)) {
TrustAnchor anchor = anchors.next();
X509Certificate anchorCert = anchor.getTrustedCert();
X500Principal anchorSubjectName =
anchorCert.getSubjectX500Principal();
if (dump) {
System.out.println("Issuer DN is " + certIssuerName);
System.out.println("Subject DN is " + anchorSubjectName);
}
// Check if anchor cert is the issuer cert
if (seekIssuerCert &&
certIssuerName.equals(anchorSubjectName)) {
issuerCert = anchorCert;
seekIssuerCert = false; // done
// By default, the OCSP responder's cert is the same as
// the issuer of the cert being validated.
if (!seekResponderCert && responderCert == null) {
responderCert = anchorCert;
if (DEBUG != null) {
DEBUG.println("Responder's certificate is the" +
" same as the issuer of the certificate " +
"being validated");
}
}
}
// Check if anchor cert is the responder cert
if (seekResponderCert) {
// Satisfy the responder subject name property only, or
// satisfy the responder issuer name and serial number
// properties only
if ((responderSubjectName != null &&
responderSubjectName.equals(anchorSubjectName)) ||
(responderIssuerName != null &&
responderSerialNumber != null &&
responderIssuerName.equals(
anchorCert.getIssuerX500Principal()) &&
responderSerialNumber.equals(
anchorCert.getSerialNumber()))) {
responderCert = anchorCert;
seekResponderCert = false; // done
}
}
}
if (issuerCert == null) {
throw new CertPathValidatorException(
"No trusted certificate for " + currCertImpl.getIssuerDN());
}
// Check cert stores if responder cert has not yet been found
if (seekResponderCert) {
if (DEBUG != null) {
DEBUG.println("Searching cert stores for responder's " +
"certificate");
}
X509CertSelector filter = null;
if (responderSubjectName != null) {
filter = new X509CertSelector();
filter.setSubject(responderSubjectName);
} else if (responderIssuerName != null &&
responderSerialNumber != null) {
filter = new X509CertSelector();
filter.setIssuer(responderIssuerName);
filter.setSerialNumber(responderSerialNumber);
}
if (filter != null) {
List<CertStore> certStores = pkixParams.getCertStores();
for (CertStore certStore : certStores) {
Iterator<? extends Certificate> i = null;
try {
i = certStore.getCertificates(filter).iterator();
} catch (CertStoreException cse) {
// ignore and try next certStore
if (DEBUG != null) {
DEBUG.println("CertStore exception:" + cse);
}
continue;
}
if (i.hasNext()) {
responderCert = (X509Certificate) i.next();
seekResponderCert = false; // done
break;
}
}
}
}
}
// Could not find the certificate identified in the OCSP properties
if (seekResponderCert) {
throw new CertPathValidatorException(
"Cannot find the responder's certificate " +
"(set using the OCSP security properties).");
}
// The algorithm constraints of the OCSP trusted responder certificate
// does not need to be checked in this code. The constraints will be
// checked when the responder's certificate is validated.
CertId certId = null;
OCSPResponse response = null;
try {
certId = new CertId
(issuerCert, currCertImpl.getSerialNumberObject());
response = OCSP.check(Collections.singletonList(certId), uri,
responderCert, pkixParams.getDate());
} catch (Exception e) {
if (e instanceof CertPathValidatorException) {
throw (CertPathValidatorException) e;
} else {
// Wrap exceptions in CertPathValidatorException so that
// we can fallback to CRLs, if enabled.
throw new CertPathValidatorException(e);
}
}
RevocationStatus rs = (RevocationStatus) response.getSingleResponse(certId);
RevocationStatus.CertStatus certStatus = rs.getCertStatus();
if (certStatus == RevocationStatus.CertStatus.REVOKED) {
Throwable t = new CertificateRevokedException(
rs.getRevocationTime(), rs.getRevocationReason(),
responderCert.getSubjectX500Principal(),
rs.getSingleExtensions());
throw new CertPathValidatorException(t.getMessage(), t,
null, -1, BasicReason.REVOKED);
} else if (certStatus == RevocationStatus.CertStatus.UNKNOWN) {
throw new CertPathValidatorException(
"Certificate's revocation status is unknown", null, cp,
remainingCerts, BasicReason.UNDETERMINED_REVOCATION_STATUS);
}
}
/*
* The OCSP security property values are in the following order:
* 1. ocsp.responderURL
* 2. ocsp.responderCertSubjectName
* 3. ocsp.responderCertIssuerName
* 4. ocsp.responderCertSerialNumber
*/
private static URI getOCSPServerURI(X509CertImpl currCertImpl,
String responderURL) throws CertPathValidatorException {
if (responderURL != null) {
try {
return new URI(responderURL);
} catch (URISyntaxException e) {
throw new CertPathValidatorException(e);
}
}
// Examine the certificate's AuthorityInfoAccess extension
AuthorityInfoAccessExtension aia =
currCertImpl.getAuthorityInfoAccessExtension();
if (aia == null) {
throw new CertPathValidatorException(
"Must specify the location of an OCSP Responder");
}
List<AccessDescription> descriptions = aia.getAccessDescriptions();
for (AccessDescription description : descriptions) {
if (description.getAccessMethod().equals((Object)
AccessDescription.Ad_OCSP_Id)) {
GeneralName generalName = description.getAccessLocation();
if (generalName.getType() == GeneralNameInterface.NAME_URI) {
URIName uri = (URIName) generalName.getName();
return uri.getURI();
}
}
}
throw new CertPathValidatorException(
"Cannot find the location of the OCSP Responder");
}
/*
* Retrieves the values of the OCSP security properties.
*/
private static String[] getOCSPProperties() {
final String[] properties = new String[4];
AccessController.doPrivileged(
new PrivilegedAction<Void>() {
public Void run() {
properties[0] = Security.getProperty(OCSP_URL_PROP);
properties[1] =
Security.getProperty(OCSP_CERT_SUBJECT_PROP);
properties[2] =
Security.getProperty(OCSP_CERT_ISSUER_PROP);
properties[3] =
Security.getProperty(OCSP_CERT_NUMBER_PROP);
return null;
}
});
return properties;
}
/*
* Removes any non-hexadecimal characters from a string.
*/
private static String stripOutSeparators(String value) {
char[] chars = value.toCharArray();
StringBuilder hexNumber = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
if (HEX_DIGITS.indexOf(chars[i]) != -1) {
hexNumber.append(chars[i]);
}
}
return hexNumber.toString();
}
}
/* /*
* Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,8 +26,10 @@ ...@@ -26,8 +26,10 @@
package sun.security.provider.certpath; package sun.security.provider.certpath;
import java.io.IOException; import java.io.IOException;
import java.security.cert.Extension;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import sun.misc.HexDumpEncoder; import sun.misc.HexDumpEncoder;
import sun.security.util.*; import sun.security.util.*;
...@@ -74,22 +76,29 @@ import sun.security.util.*; ...@@ -74,22 +76,29 @@ import sun.security.util.*;
class OCSPRequest { class OCSPRequest {
private static final Debug debug = Debug.getInstance("certpath");
private static final boolean dump = false; private static final boolean dump = false;
// List of request CertIds // List of request CertIds
private final List<CertId> certIds; private final List<CertId> certIds;
private final List<Extension> extensions;
private byte[] nonce;
/* /*
* Constructs an OCSPRequest. This constructor is used * Constructs an OCSPRequest. This constructor is used
* to construct an unsigned OCSP Request for a single user cert. * to construct an unsigned OCSP Request for a single user cert.
*/ */
OCSPRequest(CertId certId) { OCSPRequest(CertId certId) {
this.certIds = Collections.singletonList(certId); this(Collections.singletonList(certId));
} }
OCSPRequest(List<CertId> certIds) { OCSPRequest(List<CertId> certIds) {
this.certIds = certIds; this.certIds = certIds;
this.extensions = Collections.<Extension>emptyList();
}
OCSPRequest(List<CertId> certIds, List<Extension> extensions) {
this.certIds = certIds;
this.extensions = extensions;
} }
byte[] encodeBytes() throws IOException { byte[] encodeBytes() throws IOException {
...@@ -104,7 +113,20 @@ class OCSPRequest { ...@@ -104,7 +113,20 @@ class OCSPRequest {
} }
tmp.write(DerValue.tag_Sequence, requestsOut); tmp.write(DerValue.tag_Sequence, requestsOut);
// No extensions supported if (!extensions.isEmpty()) {
DerOutputStream extOut = new DerOutputStream();
for (Extension ext : extensions) {
ext.encode(extOut);
if (ext.getId().equals(OCSP.NONCE_EXTENSION_OID.toString())) {
nonce = ext.getValue();
}
}
DerOutputStream extsOut = new DerOutputStream();
extsOut.write(DerValue.tag_Sequence, extOut);
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte)2), extsOut);
}
DerOutputStream tbsRequest = new DerOutputStream(); DerOutputStream tbsRequest = new DerOutputStream();
tbsRequest.write(DerValue.tag_Sequence, tmp); tbsRequest.write(DerValue.tag_Sequence, tmp);
...@@ -126,4 +148,8 @@ class OCSPRequest { ...@@ -126,4 +148,8 @@ class OCSPRequest {
List<CertId> getCertIds() { List<CertId> getCertIds() {
return certIds; return certIds;
} }
byte[] getNonce() {
return nonce;
}
} }
/*
* Copyright (c) 2012, 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.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.cert.*;
import java.util.*;
import javax.security.auth.x500.X500Principal;
import sun.security.util.Debug;
/**
* Common utility methods and classes used by the PKIX CertPathValidator and
* CertPathBuilder implementation.
*/
class PKIX {
private static final Debug debug = Debug.getInstance("certpath");
private PKIX() { }
static ValidatorParams checkParams(CertPath cp, CertPathParameters params)
throws InvalidAlgorithmParameterException
{
if (!(params instanceof PKIXParameters)) {
throw new InvalidAlgorithmParameterException("inappropriate "
+ "params, must be an instance of PKIXParameters");
}
return new ValidatorParams(cp, (PKIXParameters)params);
}
static BuilderParams checkBuilderParams(CertPathParameters params)
throws InvalidAlgorithmParameterException
{
if (!(params instanceof PKIXBuilderParameters)) {
throw new InvalidAlgorithmParameterException("inappropriate "
+ "params, must be an instance of PKIXBuilderParameters");
}
return new BuilderParams((PKIXBuilderParameters)params);
}
/**
* PKIXParameters that are shared by the PKIX CertPathValidator
* implementation. Provides additional functionality and avoids
* unnecessary cloning.
*/
static class ValidatorParams {
private final PKIXParameters params;
private CertPath certPath;
private List<PKIXCertPathChecker> checkers;
private List<CertStore> stores;
private boolean gotDate;
private Date date;
private Set<String> policies;
private boolean gotConstraints;
private CertSelector constraints;
private Set<TrustAnchor> anchors;
private List<X509Certificate> certs;
ValidatorParams(CertPath cp, PKIXParameters params)
throws InvalidAlgorithmParameterException
{
this(params);
if (!cp.getType().equals("X.509") && !cp.getType().equals("X509")) {
throw new InvalidAlgorithmParameterException("inappropriate "
+ "CertPath type specified, must be X.509 or X509");
}
this.certPath = cp;
}
ValidatorParams(PKIXParameters params)
throws InvalidAlgorithmParameterException
{
this.anchors = params.getTrustAnchors();
// Make sure that none of the trust anchors include name constraints
// (not supported).
for (TrustAnchor anchor : this.anchors) {
if (anchor.getNameConstraints() != null) {
throw new InvalidAlgorithmParameterException
("name constraints in trust anchor not supported");
}
}
this.params = params;
}
CertPath certPath() {
return certPath;
}
// called by CertPathBuilder after path has been built
void setCertPath(CertPath cp) {
this.certPath = cp;
}
List<X509Certificate> certificates() {
if (certs == null) {
if (certPath == null) {
certs = Collections.emptyList();
} else {
// Reverse the ordering for validation so that the target
// cert is the last certificate
@SuppressWarnings("unchecked")
List<X509Certificate> xc = new ArrayList<>
((List<X509Certificate>)certPath.getCertificates());
Collections.reverse(xc);
certs = xc;
}
}
return certs;
}
List<PKIXCertPathChecker> certPathCheckers() {
if (checkers == null)
checkers = params.getCertPathCheckers();
return checkers;
}
List<CertStore> certStores() {
if (stores == null)
stores = params.getCertStores();
return stores;
}
Date date() {
if (!gotDate) {
date = params.getDate();
if (date == null)
date = new Date();
gotDate = true;
}
return date;
}
Set<String> initialPolicies() {
if (policies == null)
policies = params.getInitialPolicies();
return policies;
}
CertSelector targetCertConstraints() {
if (!gotConstraints) {
constraints = params.getTargetCertConstraints();
gotConstraints = true;
}
return constraints;
}
Set<TrustAnchor> trustAnchors() {
return anchors;
}
boolean revocationEnabled() {
return params.isRevocationEnabled();
}
boolean policyMappingInhibited() {
return params.isPolicyMappingInhibited();
}
boolean explicitPolicyRequired() {
return params.isExplicitPolicyRequired();
}
boolean policyQualifiersRejected() {
return params.getPolicyQualifiersRejected();
}
String sigProvider() { return params.getSigProvider(); }
boolean anyPolicyInhibited() { return params.isAnyPolicyInhibited(); }
// in rare cases we need access to the original params, for example
// in order to clone CertPathCheckers before building a new chain
PKIXParameters getPKIXParameters() {
return params;
}
}
static class BuilderParams extends ValidatorParams {
private PKIXBuilderParameters params;
private boolean buildForward = true;
private List<CertStore> stores;
private X500Principal targetSubject;
BuilderParams(PKIXBuilderParameters params)
throws InvalidAlgorithmParameterException
{
super(params);
checkParams(params);
}
private void checkParams(PKIXBuilderParameters params)
throws InvalidAlgorithmParameterException
{
CertSelector sel = targetCertConstraints();
if (!(sel instanceof X509CertSelector)) {
throw new InvalidAlgorithmParameterException("the "
+ "targetCertConstraints parameter must be an "
+ "X509CertSelector");
}
if (params instanceof SunCertPathBuilderParameters) {
buildForward =
((SunCertPathBuilderParameters)params).getBuildForward();
}
this.params = params;
this.targetSubject = getTargetSubject(
certStores(), (X509CertSelector)targetCertConstraints());
}
@Override List<CertStore> certStores() {
if (stores == null) {
// reorder CertStores so that local CertStores are tried first
stores = new ArrayList<>(params.getCertStores());
Collections.sort(stores, new CertStoreComparator());
}
return stores;
}
int maxPathLength() { return params.getMaxPathLength(); }
boolean buildForward() { return buildForward; }
PKIXBuilderParameters params() { return params; }
X500Principal targetSubject() { return targetSubject; }
/**
* Returns the target subject DN from the first X509Certificate that
* is fetched that matches the specified X509CertSelector.
*/
private static X500Principal getTargetSubject(List<CertStore> stores,
X509CertSelector sel)
throws InvalidAlgorithmParameterException
{
X500Principal subject = sel.getSubject();
if (subject != null) {
return subject;
}
X509Certificate cert = sel.getCertificate();
if (cert != null) {
subject = cert.getSubjectX500Principal();
}
if (subject != null) {
return subject;
}
for (CertStore store : stores) {
try {
Collection<? extends Certificate> certs =
(Collection<? extends Certificate>)
store.getCertificates(sel);
if (!certs.isEmpty()) {
X509Certificate xc =
(X509Certificate)certs.iterator().next();
return xc.getSubjectX500Principal();
}
} catch (CertStoreException e) {
// ignore but log it
if (debug != null) {
debug.println("BuilderParams.getTargetSubjectDN: " +
"non-fatal exception retrieving certs: " + e);
e.printStackTrace();
}
}
}
throw new InvalidAlgorithmParameterException
("Could not determine unique target subject");
}
}
/**
* Comparator that orders CertStores so that local CertStores come before
* remote CertStores.
*/
private static class CertStoreComparator implements Comparator<CertStore> {
@Override
public int compare(CertStore store1, CertStore store2) {
if (store1.getType().equals("Collection") ||
store1.getCertStoreParameters() instanceof
CollectionCertStoreParameters) {
return -1;
} else {
return 1;
}
}
}
}
/* /*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,55 +25,38 @@ ...@@ -25,55 +25,38 @@
package sun.security.provider.certpath; package sun.security.provider.certpath;
import java.security.AccessController; import java.io.IOException;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.cert.CertPath; import java.security.cert.*;
import java.security.cert.CertPathParameters; import java.util.*;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorSpi;
import java.security.cert.CertPathValidatorResult;
import java.security.cert.PKIXCertPathChecker;
import java.security.cert.PKIXCertPathValidatorResult;
import java.security.cert.PKIXParameters;
import java.security.cert.PKIXReason;
import java.security.cert.PolicyNode;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
import java.util.Set;
import sun.security.action.GetBooleanSecurityPropertyAction;
import sun.security.util.Debug;
import sun.security.provider.certpath.PKIX.ValidatorParams;
import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertImpl;
import sun.security.util.Debug;
/** /**
* This class implements the PKIX validation algorithm for certification * This class implements the PKIX validation algorithm for certification
* paths consisting exclusively of <code>X509Certificates</code>. It uses * paths consisting exclusively of <code>X509Certificates</code>. It uses
* the specified input parameter set (which must be a * the specified input parameter set (which must be a
* <code>PKIXParameters</code> object) and signature provider (if any). * <code>PKIXParameters</code> object).
* *
* @since 1.4 * @since 1.4
* @author Yassir Elley * @author Yassir Elley
*/ */
public class PKIXCertPathValidator extends CertPathValidatorSpi { public final class PKIXCertPathValidator extends CertPathValidatorSpi {
private static final Debug debug = Debug.getInstance("certpath"); private static final Debug debug = Debug.getInstance("certpath");
private Date testDate;
private List<PKIXCertPathChecker> userCheckers;
private String sigProvider;
private BasicChecker basicChecker;
private boolean ocspEnabled = false;
private boolean onlyEECert = false;
/** /**
* Default constructor. * Default constructor.
*/ */
public PKIXCertPathValidator() {} public PKIXCertPathValidator() {}
@Override
public CertPathChecker engineGetRevocationChecker() {
return new RevocationChecker();
}
/** /**
* Validates a certification path consisting exclusively of * Validates a certification path consisting exclusively of
* <code>X509Certificate</code>s using the PKIX validation algorithm, * <code>X509Certificate</code>s using the PKIX validation algorithm,
...@@ -81,98 +64,70 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi { ...@@ -81,98 +64,70 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
* The input parameter set must be a <code>PKIXParameters</code> object. * The input parameter set must be a <code>PKIXParameters</code> object.
* *
* @param cp the X509 certification path * @param cp the X509 certification path
* @param param the input PKIX parameter set * @param params the input PKIX parameter set
* @return the result * @return the result
* @exception CertPathValidatorException Exception thrown if cert path * @throws CertPathValidatorException if cert path does not validate.
* does not validate. * @throws InvalidAlgorithmParameterException if the specified
* @exception InvalidAlgorithmParameterException if the specified * parameters are inappropriate for this CertPathValidator
* parameters are inappropriate for this certification path validator
*/ */
@Override
public CertPathValidatorResult engineValidate(CertPath cp, public CertPathValidatorResult engineValidate(CertPath cp,
CertPathParameters param) CertPathParameters params)
throws CertPathValidatorException, InvalidAlgorithmParameterException throws CertPathValidatorException, InvalidAlgorithmParameterException
{
ValidatorParams valParams = PKIX.checkParams(cp, params);
return validate(valParams);
}
private static PKIXCertPathValidatorResult validate(ValidatorParams params)
throws CertPathValidatorException
{ {
if (debug != null) if (debug != null)
debug.println("PKIXCertPathValidator.engineValidate()..."); debug.println("PKIXCertPathValidator.engineValidate()...");
if (!(param instanceof PKIXParameters)) {
throw new InvalidAlgorithmParameterException("inappropriate "
+ "parameters, must be an instance of PKIXParameters");
}
if (!cp.getType().equals("X.509") && !cp.getType().equals("X509")) {
throw new InvalidAlgorithmParameterException("inappropriate "
+ "certification path type specified, must be X.509 or X509");
}
PKIXParameters pkixParam = (PKIXParameters) param;
// Make sure that none of the trust anchors include name constraints
// (not supported).
Set<TrustAnchor> anchors = pkixParam.getTrustAnchors();
for (TrustAnchor anchor : anchors) {
if (anchor.getNameConstraints() != null) {
throw new InvalidAlgorithmParameterException
("name constraints in trust anchor not supported");
}
}
// the certpath which has been passed in (cp)
// has the target cert as the first certificate - we
// need to keep this cp so we can return it
// in case of an exception and for policy qualifier
// processing - however, for certpath validation,
// we need to create a reversed path, where we reverse the
// ordering so that the target cert is the last certificate
// Must copy elements of certList into a new modifiable List before
// calling Collections.reverse().
// If cp is not an X.509 or X509 certpath, an
// InvalidAlgorithmParameterException will have been thrown by now.
@SuppressWarnings("unchecked")
ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>
((List<X509Certificate>)cp.getCertificates());
if (debug != null) {
if (certList.isEmpty()) {
debug.println("PKIXCertPathValidator.engineValidate() "
+ "certList is empty");
}
debug.println("PKIXCertPathValidator.engineValidate() "
+ "reversing certpath...");
}
Collections.reverse(certList);
// now certList has the target cert as the last cert and we
// can proceed with normal validation
populateVariables(pkixParam);
// Retrieve the first certificate in the certpath // Retrieve the first certificate in the certpath
// (to be used later in pre-screening) // (to be used later in pre-screening)
X509Certificate firstCert = null; AdaptableX509CertSelector selector = null;
List<X509Certificate> certList = params.certificates();
if (!certList.isEmpty()) { if (!certList.isEmpty()) {
firstCert = certList.get(0); selector = new AdaptableX509CertSelector();
X509Certificate firstCert = certList.get(0);
// check trusted certificate's subject
selector.setSubject(firstCert.getIssuerX500Principal());
// check the validity period
selector.setValidityPeriod(firstCert.getNotBefore(),
firstCert.getNotAfter());
/*
* Facilitate certification path construction with authority
* key identifier and subject key identifier.
*/
try {
X509CertImpl firstCertImpl = X509CertImpl.toImpl(firstCert);
selector.parseAuthorityKeyIdentifierExtension(
firstCertImpl.getAuthorityKeyIdentifierExtension());
} catch (CertificateException | IOException e) {
// ignore
}
} }
CertPathValidatorException lastException = null; CertPathValidatorException lastException = null;
// We iterate through the set of trust anchors until we find // We iterate through the set of trust anchors until we find
// one that works at which time we stop iterating // one that works at which time we stop iterating
for (TrustAnchor anchor : anchors) { for (TrustAnchor anchor : params.trustAnchors()) {
X509Certificate trustedCert = anchor.getTrustedCert(); X509Certificate trustedCert = anchor.getTrustedCert();
if (trustedCert != null) { if (trustedCert != null) {
if (debug != null) {
debug.println("PKIXCertPathValidator.engineValidate() "
+ "anchor.getTrustedCert() != null");
}
// if this trust anchor is not worth trying, // if this trust anchor is not worth trying,
// we move on to the next one // we move on to the next one
if (!isWorthTrying(trustedCert, firstCert)) { if (selector != null && !selector.match(trustedCert)) {
if (debug != null) {
debug.println("NO - don't try this trustedCert");
}
continue; continue;
} }
if (debug != null) { if (debug != null) {
debug.println("YES - try this trustedCert");
debug.println("anchor.getTrustedCert()." debug.println("anchor.getTrustedCert()."
+ "getSubjectX500Principal() = " + "getSubjectX500Principal() = "
+ trustedCert.getSubjectX500Principal()); + trustedCert.getSubjectX500Principal());
...@@ -185,14 +140,7 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi { ...@@ -185,14 +140,7 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
} }
try { try {
PolicyNodeImpl rootNode = new PolicyNodeImpl(null, return validate(anchor, params);
PolicyChecker.ANY_POLICY, null, false,
Collections.singleton(PolicyChecker.ANY_POLICY), false);
PolicyNode policyTree =
doValidate(anchor, cp, certList, pkixParam, rootNode);
// if this anchor works, return success
return new PKIXCertPathValidatorResult(anchor, policyTree,
basicChecker.getPublicKey());
} catch (CertPathValidatorException cpe) { } catch (CertPathValidatorException cpe) {
// remember this exception // remember this exception
lastException = cpe; lastException = cpe;
...@@ -210,144 +158,59 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi { ...@@ -210,144 +158,59 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
null, null, -1, PKIXReason.NO_TRUST_ANCHOR); null, null, -1, PKIXReason.NO_TRUST_ANCHOR);
} }
/** private static PKIXCertPathValidatorResult validate(TrustAnchor anchor,
* Internal method to do some simple checks to see if a given cert is ValidatorParams params)
* worth trying to validate in the chain. throws CertPathValidatorException
*/
private boolean isWorthTrying(X509Certificate trustedCert,
X509Certificate firstCert) {
boolean worthy = false;
if (debug != null) {
debug.println("PKIXCertPathValidator.isWorthTrying() checking "
+ "if this trusted cert is worth trying ...");
}
if (firstCert == null) {
return true;
}
AdaptableX509CertSelector issuerSelector =
new AdaptableX509CertSelector();
// check trusted certificate's subject
issuerSelector.setSubject(firstCert.getIssuerX500Principal());
// check the validity period
issuerSelector.setValidityPeriod(firstCert.getNotBefore(),
firstCert.getNotAfter());
/*
* Facilitate certification path construction with authority
* key identifier and subject key identifier.
*/
try {
X509CertImpl firstCertImpl = X509CertImpl.toImpl(firstCert);
issuerSelector.parseAuthorityKeyIdentifierExtension(
firstCertImpl.getAuthorityKeyIdentifierExtension());
worthy = issuerSelector.match(trustedCert);
} catch (Exception e) {
// It is not worth trying.
}
if (debug != null) {
if (worthy) {
debug.println("YES - try this trustedCert");
} else {
debug.println("NO - don't try this trustedCert");
}
}
return worthy;
}
/**
* Internal method to setup the internal state
*/
private void populateVariables(PKIXParameters pkixParam)
{ {
// default value for testDate is current time int certPathLen = params.certificates().size();
testDate = pkixParam.getDate();
if (testDate == null) {
testDate = new Date(System.currentTimeMillis());
}
userCheckers = pkixParam.getCertPathCheckers();
sigProvider = pkixParam.getSigProvider();
if (pkixParam.isRevocationEnabled()) { // create PKIXCertPathCheckers
// Examine OCSP security property List<PKIXCertPathChecker> certPathCheckers = new ArrayList<>();
ocspEnabled = AccessController.doPrivileged(
new GetBooleanSecurityPropertyAction
(OCSPChecker.OCSP_ENABLE_PROP));
onlyEECert = AccessController.doPrivileged(
new GetBooleanSecurityPropertyAction
("com.sun.security.onlyCheckRevocationOfEECert"));
}
}
/**
* Internal method to actually validate a constructed path.
*
* @return the valid policy tree
*/
private PolicyNode doValidate(
TrustAnchor anchor, CertPath cpOriginal,
ArrayList<X509Certificate> certList, PKIXParameters pkixParam,
PolicyNodeImpl rootNode) throws CertPathValidatorException
{
int certPathLen = certList.size();
basicChecker = new BasicChecker(anchor, testDate, sigProvider, false);
AlgorithmChecker algorithmChecker = new AlgorithmChecker(anchor);
KeyChecker keyChecker = new KeyChecker(certPathLen,
pkixParam.getTargetCertConstraints());
ConstraintsChecker constraintsChecker =
new ConstraintsChecker(certPathLen);
PolicyChecker policyChecker =
new PolicyChecker(pkixParam.getInitialPolicies(), certPathLen,
pkixParam.isExplicitPolicyRequired(),
pkixParam.isPolicyMappingInhibited(),
pkixParam.isAnyPolicyInhibited(),
pkixParam.getPolicyQualifiersRejected(),
rootNode);
ArrayList<PKIXCertPathChecker> certPathCheckers =
new ArrayList<PKIXCertPathChecker>();
// add standard checkers that we will be using // add standard checkers that we will be using
certPathCheckers.add(algorithmChecker); certPathCheckers.add(new AlgorithmChecker(anchor));
certPathCheckers.add(keyChecker); certPathCheckers.add(new KeyChecker(certPathLen,
certPathCheckers.add(constraintsChecker); params.targetCertConstraints()));
certPathCheckers.add(policyChecker); certPathCheckers.add(new ConstraintsChecker(certPathLen));
certPathCheckers.add(basicChecker); PolicyNodeImpl rootNode =
new PolicyNodeImpl(null, PolicyChecker.ANY_POLICY, null, false,
// only add a revocationChecker if revocation is enabled Collections.singleton(PolicyChecker.ANY_POLICY),
if (pkixParam.isRevocationEnabled()) { false);
PolicyChecker pc = new PolicyChecker(params.initialPolicies(),
// Use OCSP if it has been enabled certPathLen,
if (ocspEnabled) { params.explicitPolicyRequired(),
OCSPChecker ocspChecker = params.policyMappingInhibited(),
new OCSPChecker(cpOriginal, pkixParam, onlyEECert); params.anyPolicyInhibited(),
certPathCheckers.add(ocspChecker); params.policyQualifiersRejected(),
rootNode);
certPathCheckers.add(pc);
// default value for date is current time
BasicChecker bc = new BasicChecker(anchor, params.date(),
params.sigProvider(), false);
certPathCheckers.add(bc);
boolean revCheckerAdded = false;
List<PKIXCertPathChecker> checkers = params.certPathCheckers();
for (PKIXCertPathChecker checker : checkers) {
if (checker instanceof PKIXRevocationChecker) {
revCheckerAdded = true;
// if it's our own, initialize it
if (checker instanceof RevocationChecker)
((RevocationChecker)checker).init(anchor, params);
} }
// Always use CRLs
CrlRevocationChecker revocationChecker = new
CrlRevocationChecker(anchor, pkixParam, certList, onlyEECert);
certPathCheckers.add(revocationChecker);
} }
// only add a RevocationChecker if revocation is enabled and
// a PKIXRevocationChecker has not already been added
if (params.revocationEnabled() && !revCheckerAdded) {
certPathCheckers.add(new RevocationChecker(anchor, params));
}
// add user-specified checkers // add user-specified checkers
certPathCheckers.addAll(userCheckers); certPathCheckers.addAll(checkers);
PKIXMasterCertPathValidator masterValidator =
new PKIXMasterCertPathValidator(certPathCheckers);
masterValidator.validate(cpOriginal, certList); PKIXMasterCertPathValidator.validate(params.certPath(),
params.certificates(),
certPathCheckers);
return policyChecker.getPolicyTree(); return new PKIXCertPathValidatorResult(anchor, pc.getPolicyTree(),
bc.getPublicKey());
} }
} }
/* /*
* Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -30,10 +30,8 @@ import sun.security.util.Debug; ...@@ -30,10 +30,8 @@ import sun.security.util.Debug;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.security.cert.CertificateRevokedException;
import java.security.cert.CertPath; import java.security.cert.CertPath;
import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.PKIXCertPathChecker; import java.security.cert.PKIXCertPathChecker;
import java.security.cert.PKIXReason; import java.security.cert.PKIXReason;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
...@@ -49,32 +47,22 @@ import java.security.cert.X509Certificate; ...@@ -49,32 +47,22 @@ import java.security.cert.X509Certificate;
class PKIXMasterCertPathValidator { class PKIXMasterCertPathValidator {
private static final Debug debug = Debug.getInstance("certpath"); private static final Debug debug = Debug.getInstance("certpath");
private List<PKIXCertPathChecker> certPathCheckers;
/**
* Initializes the list of PKIXCertPathCheckers whose checks
* will be performed on each certificate in the certpath.
*
* @param certPathCheckers a List of checkers to use
*/
PKIXMasterCertPathValidator(List<PKIXCertPathChecker> certPathCheckers) {
this.certPathCheckers = certPathCheckers;
}
/** /**
* Validates a certification path consisting exclusively of * Validates a certification path consisting exclusively of
* <code>X509Certificate</code>s using the * <code>X509Certificate</code>s using the specified
* <code>PKIXCertPathChecker</code>s specified * <code>PKIXCertPathChecker</code>s. It is assumed that the
* in the constructor. It is assumed that the
* <code>PKIXCertPathChecker</code>s * <code>PKIXCertPathChecker</code>s
* have been initialized with any input parameters they may need. * have been initialized with any input parameters they may need.
* *
* @param cpOriginal the original X509 CertPath passed in by the user * @param cpOriginal the original X509 CertPath passed in by the user
* @param reversedCertList the reversed X509 CertPath (as a List) * @param reversedCertList the reversed X509 CertPath (as a List)
* @exception CertPathValidatorException Exception thrown if cert * @param certPathCheckers the PKIXCertPathCheckers
* path does not validate. * @throws CertPathValidatorException if cert path does not validate
*/ */
void validate(CertPath cpOriginal, List<X509Certificate> reversedCertList) static void validate(CertPath cpOriginal,
List<X509Certificate> reversedCertList,
List<PKIXCertPathChecker> certPathCheckers)
throws CertPathValidatorException throws CertPathValidatorException
{ {
// we actually process reversedCertList, but we keep cpOriginal because // we actually process reversedCertList, but we keep cpOriginal because
...@@ -104,20 +92,18 @@ class PKIXMasterCertPathValidator { ...@@ -104,20 +92,18 @@ class PKIXMasterCertPathValidator {
debug.println("Checking cert" + (i+1) + " ..."); debug.println("Checking cert" + (i+1) + " ...");
X509Certificate currCert = reversedCertList.get(i); X509Certificate currCert = reversedCertList.get(i);
Set<String> unresolvedCritExts = Set<String> unresCritExts = currCert.getCriticalExtensionOIDs();
currCert.getCriticalExtensionOIDs(); if (unresCritExts == null) {
if (unresolvedCritExts == null) { unresCritExts = Collections.<String>emptySet();
unresolvedCritExts = Collections.<String>emptySet();
} }
if (debug != null && !unresolvedCritExts.isEmpty()) { if (debug != null && !unresCritExts.isEmpty()) {
debug.println("Set of critical extensions:"); debug.println("Set of critical extensions:");
for (String oid : unresolvedCritExts) { for (String oid : unresCritExts) {
debug.println(oid); debug.println(oid);
} }
} }
CertPathValidatorException ocspCause = null;
for (int j = 0; j < certPathCheckers.size(); j++) { for (int j = 0; j < certPathCheckers.size(); j++) {
PKIXCertPathChecker currChecker = certPathCheckers.get(j); PKIXCertPathChecker currChecker = certPathCheckers.get(j);
...@@ -130,65 +116,21 @@ class PKIXMasterCertPathValidator { ...@@ -130,65 +116,21 @@ class PKIXMasterCertPathValidator {
currChecker.init(false); currChecker.init(false);
try { try {
currChecker.check(currCert, unresolvedCritExts); currChecker.check(currCert, unresCritExts);
// OCSP has validated the cert so skip the CRL check
if (isRevocationCheck(currChecker, j, certPathCheckers)) {
if (debug != null) {
debug.println("-checker" + (j + 1) +
" validation succeeded");
}
j++;
continue; // skip
}
} catch (CertPathValidatorException cpve) {
// Throw the saved OCSP exception unless the CRL
// checker has determined that the cert is revoked
if (ocspCause != null &&
currChecker instanceof CrlRevocationChecker) {
if (cpve.getReason() == BasicReason.REVOKED) {
throw cpve;
} else {
throw ocspCause;
}
}
/*
* Handle failover from OCSP to CRLs
*/
CertPathValidatorException currentCause =
new CertPathValidatorException(cpve.getMessage(),
cpve.getCause(), cpOriginal, cpSize - (i + 1),
cpve.getReason());
// Check if OCSP has confirmed that the cert was revoked
if (cpve.getReason() == BasicReason.REVOKED) {
throw currentCause;
}
// Check if it is appropriate to failover
if (! isRevocationCheck(currChecker, j, certPathCheckers)) {
// no failover
throw currentCause;
}
// Save the current exception
// (in case the CRL check also fails)
ocspCause = currentCause;
// Otherwise, failover to CRLs
if (debug != null) { if (debug != null) {
debug.println(cpve.getMessage()); debug.println("-checker" + (j + 1) +
debug.println( " validation succeeded");
"preparing to failover (from OCSP to CRLs)");
} }
}
if (debug != null) } catch (CertPathValidatorException cpve) {
debug.println("-checker" + (j+1) + " validation succeeded"); throw new CertPathValidatorException(cpve.getMessage(),
cpve.getCause(), cpOriginal, cpSize - (i + 1),
cpve.getReason());
}
} }
if (debug != null) if (!unresCritExts.isEmpty()) {
debug.println("checking for unresolvedCritExts");
if (!unresolvedCritExts.isEmpty()) {
throw new CertPathValidatorException("unrecognized " + throw new CertPathValidatorException("unrecognized " +
"critical extension(s)", null, cpOriginal, cpSize-(i+1), "critical extension(s)", null, cpOriginal, cpSize-(i+1),
PKIXReason.UNRECOGNIZED_CRIT_EXT); PKIXReason.UNRECOGNIZED_CRIT_EXT);
...@@ -200,26 +142,9 @@ class PKIXMasterCertPathValidator { ...@@ -200,26 +142,9 @@ class PKIXMasterCertPathValidator {
if (debug != null) { if (debug != null) {
debug.println("Cert path validation succeeded. (PKIX validation " debug.println("Cert path validation succeeded. (PKIX validation "
+ "algorithm)"); + "algorithm)");
debug.println("-------------------------------------------------" debug.println("-------------------------------------------------"
+ "-------------"); + "-------------");
}
}
/*
* Examines the list of PKIX cert path checkers to determine whether
* both the current checker and the next checker are revocation checkers.
* OCSPChecker and CrlRevocationChecker are both revocation checkers.
*/
private static boolean isRevocationCheck(PKIXCertPathChecker checker,
int index, List<PKIXCertPathChecker> checkers) {
if (checker instanceof OCSPChecker && index + 1 < checkers.size()) {
PKIXCertPathChecker nextChecker = checkers.get(index + 1);
if (nextChecker instanceof CrlRevocationChecker) {
return true;
}
} }
return false;
} }
} }
/* /*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,9 +25,8 @@ ...@@ -25,9 +25,8 @@
package sun.security.provider.certpath; package sun.security.provider.certpath;
import java.util.*;
import java.io.IOException; import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException;
...@@ -36,13 +35,14 @@ import java.security.cert.PKIXReason; ...@@ -36,13 +35,14 @@ import java.security.cert.PKIXReason;
import java.security.cert.PolicyNode; import java.security.cert.PolicyNode;
import java.security.cert.PolicyQualifierInfo; import java.security.cert.PolicyQualifierInfo;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.*;
import sun.security.util.Debug; import sun.security.util.Debug;
import sun.security.x509.CertificatePoliciesExtension; import sun.security.x509.CertificatePoliciesExtension;
import sun.security.x509.PolicyConstraintsExtension; import sun.security.x509.PolicyConstraintsExtension;
import sun.security.x509.PolicyMappingsExtension; import sun.security.x509.PolicyMappingsExtension;
import sun.security.x509.CertificatePolicyMap; import sun.security.x509.CertificatePolicyMap;
import sun.security.x509.PKIXExtensions; import static sun.security.x509.PKIXExtensions.*;
import sun.security.x509.PolicyInformation; import sun.security.x509.PolicyInformation;
import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertImpl;
import sun.security.x509.InhibitAnyPolicyExtension; import sun.security.x509.InhibitAnyPolicyExtension;
...@@ -88,7 +88,7 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -88,7 +88,7 @@ class PolicyChecker extends PKIXCertPathChecker {
PolicyChecker(Set<String> initialPolicies, int certPathLen, PolicyChecker(Set<String> initialPolicies, int certPathLen,
boolean expPolicyRequired, boolean polMappingInhibited, boolean expPolicyRequired, boolean polMappingInhibited,
boolean anyPolicyInhibited, boolean rejectPolicyQualifiers, boolean anyPolicyInhibited, boolean rejectPolicyQualifiers,
PolicyNodeImpl rootNode) throws CertPathValidatorException PolicyNodeImpl rootNode)
{ {
if (initialPolicies.isEmpty()) { if (initialPolicies.isEmpty()) {
// if no initialPolicies are specified by user, set // if no initialPolicies are specified by user, set
...@@ -104,18 +104,18 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -104,18 +104,18 @@ class PolicyChecker extends PKIXCertPathChecker {
this.anyPolicyInhibited = anyPolicyInhibited; this.anyPolicyInhibited = anyPolicyInhibited;
this.rejectPolicyQualifiers = rejectPolicyQualifiers; this.rejectPolicyQualifiers = rejectPolicyQualifiers;
this.rootNode = rootNode; this.rootNode = rootNode;
init(false);
} }
/** /**
* Initializes the internal state of the checker from parameters * Initializes the internal state of the checker from parameters
* specified in the constructor * specified in the constructor
* *
* @param forward a boolean indicating whether this checker should * @param forward a boolean indicating whether this checker should be
* be initialized capable of building in the forward direction * initialized capable of building in the forward direction
* @exception CertPathValidatorException Exception thrown if user * @throws CertPathValidatorException if user wants to enable forward
* wants to enable forward checking and forward checking is not supported. * checking and forward checking is not supported.
*/ */
@Override
public void init(boolean forward) throws CertPathValidatorException { public void init(boolean forward) throws CertPathValidatorException {
if (forward) { if (forward) {
throw new CertPathValidatorException throw new CertPathValidatorException
...@@ -136,6 +136,7 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -136,6 +136,7 @@ class PolicyChecker extends PKIXCertPathChecker {
* *
* @return true if forward checking is supported, false otherwise * @return true if forward checking is supported, false otherwise
*/ */
@Override
public boolean isForwardCheckingSupported() { public boolean isForwardCheckingSupported() {
return false; return false;
} }
...@@ -150,13 +151,14 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -150,13 +151,14 @@ class PolicyChecker extends PKIXCertPathChecker {
* @return the Set of extensions supported by this PKIXCertPathChecker, * @return the Set of extensions supported by this PKIXCertPathChecker,
* or null if no extensions are supported * or null if no extensions are supported
*/ */
@Override
public Set<String> getSupportedExtensions() { public Set<String> getSupportedExtensions() {
if (supportedExts == null) { if (supportedExts == null) {
supportedExts = new HashSet<String>(); supportedExts = new HashSet<String>(4);
supportedExts.add(PKIXExtensions.CertificatePolicies_Id.toString()); supportedExts.add(CertificatePolicies_Id.toString());
supportedExts.add(PKIXExtensions.PolicyMappings_Id.toString()); supportedExts.add(PolicyMappings_Id.toString());
supportedExts.add(PKIXExtensions.PolicyConstraints_Id.toString()); supportedExts.add(PolicyConstraints_Id.toString());
supportedExts.add(PKIXExtensions.InhibitAnyPolicy_Id.toString()); supportedExts.add(InhibitAnyPolicy_Id.toString());
supportedExts = Collections.unmodifiableSet(supportedExts); supportedExts = Collections.unmodifiableSet(supportedExts);
} }
return supportedExts; return supportedExts;
...@@ -168,9 +170,9 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -168,9 +170,9 @@ class PolicyChecker extends PKIXCertPathChecker {
* *
* @param cert the Certificate to be processed * @param cert the Certificate to be processed
* @param unresCritExts the unresolved critical extensions * @param unresCritExts the unresolved critical extensions
* @exception CertPathValidatorException Exception thrown if * @throws CertPathValidatorException if the certificate does not verify
* the certificate does not verify.
*/ */
@Override
public void check(Certificate cert, Collection<String> unresCritExts) public void check(Certificate cert, Collection<String> unresCritExts)
throws CertPathValidatorException throws CertPathValidatorException
{ {
...@@ -178,10 +180,10 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -178,10 +180,10 @@ class PolicyChecker extends PKIXCertPathChecker {
checkPolicy((X509Certificate) cert); checkPolicy((X509Certificate) cert);
if (unresCritExts != null && !unresCritExts.isEmpty()) { if (unresCritExts != null && !unresCritExts.isEmpty()) {
unresCritExts.remove(PKIXExtensions.CertificatePolicies_Id.toString()); unresCritExts.remove(CertificatePolicies_Id.toString());
unresCritExts.remove(PKIXExtensions.PolicyMappings_Id.toString()); unresCritExts.remove(PolicyMappings_Id.toString());
unresCritExts.remove(PKIXExtensions.PolicyConstraints_Id.toString()); unresCritExts.remove(PolicyConstraints_Id.toString());
unresCritExts.remove(PKIXExtensions.InhibitAnyPolicy_Id.toString()); unresCritExts.remove(InhibitAnyPolicy_Id.toString());
} }
} }
...@@ -290,7 +292,7 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -290,7 +292,7 @@ class PolicyChecker extends PKIXCertPathChecker {
if (require == 0) if (require == 0)
explicitPolicy = require; explicitPolicy = require;
} }
} catch (Exception e) { } catch (IOException e) {
if (debug != null) { if (debug != null) {
debug.println("PolicyChecker.mergeExplicitPolicy " debug.println("PolicyChecker.mergeExplicitPolicy "
+ "unexpected exception"); + "unexpected exception");
...@@ -339,7 +341,7 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -339,7 +341,7 @@ class PolicyChecker extends PKIXCertPathChecker {
policyMapping = inhibit; policyMapping = inhibit;
} }
} }
} catch (Exception e) { } catch (IOException e) {
if (debug != null) { if (debug != null) {
debug.println("PolicyChecker.mergePolicyMapping " debug.println("PolicyChecker.mergePolicyMapping "
+ "unexpected exception"); + "unexpected exception");
...@@ -372,7 +374,7 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -372,7 +374,7 @@ class PolicyChecker extends PKIXCertPathChecker {
try { try {
InhibitAnyPolicyExtension inhAnyPolExt = (InhibitAnyPolicyExtension) InhibitAnyPolicyExtension inhAnyPolExt = (InhibitAnyPolicyExtension)
currCert.getExtension(PKIXExtensions.InhibitAnyPolicy_Id); currCert.getExtension(InhibitAnyPolicy_Id);
if (inhAnyPolExt == null) if (inhAnyPolExt == null)
return inhibitAnyPolicy; return inhibitAnyPolicy;
...@@ -387,7 +389,7 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -387,7 +389,7 @@ class PolicyChecker extends PKIXCertPathChecker {
inhibitAnyPolicy = skipCerts; inhibitAnyPolicy = skipCerts;
} }
} }
} catch (Exception e) { } catch (IOException e) {
if (debug != null) { if (debug != null) {
debug.println("PolicyChecker.mergeInhibitAnyPolicy " debug.println("PolicyChecker.mergeInhibitAnyPolicy "
+ "unexpected exception"); + "unexpected exception");
...@@ -429,7 +431,7 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -429,7 +431,7 @@ class PolicyChecker extends PKIXCertPathChecker {
boolean policiesCritical = false; boolean policiesCritical = false;
List<PolicyInformation> policyInfo; List<PolicyInformation> policyInfo;
PolicyNodeImpl rootNode = null; PolicyNodeImpl rootNode = null;
Set<PolicyQualifierInfo> anyQuals = new HashSet<PolicyQualifierInfo>(); Set<PolicyQualifierInfo> anyQuals = new HashSet<>();
if (origRootNode == null) if (origRootNode == null)
rootNode = null; rootNode = null;
...@@ -600,7 +602,7 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -600,7 +602,7 @@ class PolicyChecker extends PKIXCertPathChecker {
PolicyNodeImpl parentNode = (PolicyNodeImpl)anyNode.getParent(); PolicyNodeImpl parentNode = (PolicyNodeImpl)anyNode.getParent();
parentNode.deleteChild(anyNode); parentNode.deleteChild(anyNode);
// see if there are any initialPolicies not represented by leaf nodes // see if there are any initialPolicies not represented by leaf nodes
Set<String> initial = new HashSet<String>(initPolicies); Set<String> initial = new HashSet<>(initPolicies);
for (PolicyNodeImpl node : rootNode.getPolicyNodes(certIndex)) { for (PolicyNodeImpl node : rootNode.getPolicyNodes(certIndex)) {
initial.remove(node.getValidPolicy()); initial.remove(node.getValidPolicy());
} }
...@@ -697,7 +699,7 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -697,7 +699,7 @@ class PolicyChecker extends PKIXCertPathChecker {
} }
} }
Set<String> expPols = new HashSet<String>(); Set<String> expPols = new HashSet<>();
expPols.add(curParExpPol); expPols.add(curParExpPol);
curNode = new PolicyNodeImpl curNode = new PolicyNodeImpl
...@@ -762,8 +764,7 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -762,8 +764,7 @@ class PolicyChecker extends PKIXCertPathChecker {
} }
boolean childDeleted = false; boolean childDeleted = false;
for (int j = 0; j < maps.size(); j++) { for (CertificatePolicyMap polMap : maps) {
CertificatePolicyMap polMap = maps.get(j);
String issuerDomain String issuerDomain
= polMap.getIssuerIdentifier().getIdentifier().toString(); = polMap.getIssuerIdentifier().getIdentifier().toString();
String subjectDomain String subjectDomain
...@@ -816,7 +817,7 @@ class PolicyChecker extends PKIXCertPathChecker { ...@@ -816,7 +817,7 @@ class PolicyChecker extends PKIXCertPathChecker {
PolicyNodeImpl curAnyNodeParent = PolicyNodeImpl curAnyNodeParent =
(PolicyNodeImpl) curAnyNode.getParent(); (PolicyNodeImpl) curAnyNode.getParent();
Set<String> expPols = new HashSet<String>(); Set<String> expPols = new HashSet<>();
expPols.add(subjectDomain); expPols.add(subjectDomain);
PolicyNodeImpl curNode = new PolicyNodeImpl PolicyNodeImpl curNode = new PolicyNodeImpl
......
/* /*
* Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -134,30 +134,37 @@ final class PolicyNodeImpl implements PolicyNode { ...@@ -134,30 +134,37 @@ final class PolicyNodeImpl implements PolicyNode {
node.mCriticalityIndicator, node.mExpectedPolicySet, false); node.mCriticalityIndicator, node.mExpectedPolicySet, false);
} }
@Override
public PolicyNode getParent() { public PolicyNode getParent() {
return mParent; return mParent;
} }
@Override
public Iterator<PolicyNodeImpl> getChildren() { public Iterator<PolicyNodeImpl> getChildren() {
return Collections.unmodifiableSet(mChildren).iterator(); return Collections.unmodifiableSet(mChildren).iterator();
} }
@Override
public int getDepth() { public int getDepth() {
return mDepth; return mDepth;
} }
@Override
public String getValidPolicy() { public String getValidPolicy() {
return mValidPolicy; return mValidPolicy;
} }
@Override
public Set<PolicyQualifierInfo> getPolicyQualifiers() { public Set<PolicyQualifierInfo> getPolicyQualifiers() {
return Collections.unmodifiableSet(mQualifierSet); return Collections.unmodifiableSet(mQualifierSet);
} }
@Override
public Set<String> getExpectedPolicies() { public Set<String> getExpectedPolicies() {
return Collections.unmodifiableSet(mExpectedPolicySet); return Collections.unmodifiableSet(mExpectedPolicySet);
} }
@Override
public boolean isCritical() { public boolean isCritical() {
return mCriticalityIndicator; return mCriticalityIndicator;
} }
...@@ -169,12 +176,12 @@ final class PolicyNodeImpl implements PolicyNode { ...@@ -169,12 +176,12 @@ final class PolicyNodeImpl implements PolicyNode {
* *
* @return a String describing the contents of the Policy Node * @return a String describing the contents of the Policy Node
*/ */
@Override
public String toString() { public String toString() {
StringBuffer buffer = new StringBuffer(this.asString()); StringBuilder buffer = new StringBuilder(this.asString());
Iterator<PolicyNodeImpl> it = getChildren(); for (PolicyNodeImpl node : mChildren) {
while (it.hasNext()) { buffer.append(node);
buffer.append(it.next());
} }
return buffer.toString(); return buffer.toString();
} }
...@@ -293,7 +300,7 @@ final class PolicyNodeImpl implements PolicyNode { ...@@ -293,7 +300,7 @@ final class PolicyNodeImpl implements PolicyNode {
* @return a <code>Set</code> of all nodes at the specified depth * @return a <code>Set</code> of all nodes at the specified depth
*/ */
Set<PolicyNodeImpl> getPolicyNodes(int depth) { Set<PolicyNodeImpl> getPolicyNodes(int depth) {
Set<PolicyNodeImpl> set = new HashSet<PolicyNodeImpl>(); Set<PolicyNodeImpl> set = new HashSet<>();
getPolicyNodes(depth, set); getPolicyNodes(depth, set);
return set; return set;
} }
...@@ -337,7 +344,7 @@ final class PolicyNodeImpl implements PolicyNode { ...@@ -337,7 +344,7 @@ final class PolicyNodeImpl implements PolicyNode {
private Set<PolicyNodeImpl> getPolicyNodesExpectedHelper(int depth, private Set<PolicyNodeImpl> getPolicyNodesExpectedHelper(int depth,
String expectedOID, boolean matchAny) { String expectedOID, boolean matchAny) {
HashSet<PolicyNodeImpl> set = new HashSet<PolicyNodeImpl>(); HashSet<PolicyNodeImpl> set = new HashSet<>();
if (mDepth < depth) { if (mDepth < depth) {
for (PolicyNodeImpl node : mChildren) { for (PolicyNodeImpl node : mChildren) {
...@@ -367,7 +374,7 @@ final class PolicyNodeImpl implements PolicyNode { ...@@ -367,7 +374,7 @@ final class PolicyNodeImpl implements PolicyNode {
* @return a Set of matched <code>PolicyNode</code>s * @return a Set of matched <code>PolicyNode</code>s
*/ */
Set<PolicyNodeImpl> getPolicyNodesValid(int depth, String validOID) { Set<PolicyNodeImpl> getPolicyNodesValid(int depth, String validOID) {
HashSet<PolicyNodeImpl> set = new HashSet<PolicyNodeImpl>(); HashSet<PolicyNodeImpl> set = new HashSet<>();
if (mDepth < depth) { if (mDepth < depth) {
for (PolicyNodeImpl node : mChildren) { for (PolicyNodeImpl node : mChildren) {
...@@ -396,7 +403,7 @@ final class PolicyNodeImpl implements PolicyNode { ...@@ -396,7 +403,7 @@ final class PolicyNodeImpl implements PolicyNode {
if (mParent == null) { if (mParent == null) {
return "anyPolicy ROOT\n"; return "anyPolicy ROOT\n";
} else { } else {
StringBuffer sb = new StringBuffer(); StringBuilder sb = new StringBuilder();
for (int i = 0, n = getDepth(); i < n; i++) { for (int i = 0, n = getDepth(); i < n; i++) {
sb.append(" "); sb.append(" ");
} }
......
/* /*
* Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,12 +25,11 @@ ...@@ -25,12 +25,11 @@
package sun.security.provider.certpath; package sun.security.provider.certpath;
import java.util.Set;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.cert.*; import java.security.cert.*;
import java.util.Set;
/** /**
* This class specifies the set of parameters used as input for the Sun * This class specifies the set of parameters used as input for the Sun
...@@ -120,8 +119,9 @@ public class SunCertPathBuilderParameters extends PKIXBuilderParameters { ...@@ -120,8 +119,9 @@ public class SunCertPathBuilderParameters extends PKIXBuilderParameters {
* *
* @return a formatted string describing the parameters. * @return a formatted string describing the parameters.
*/ */
@Override
public String toString() { public String toString() {
StringBuffer sb = new StringBuffer(); StringBuilder sb = new StringBuilder();
sb.append("[\n"); sb.append("[\n");
sb.append(super.toString()); sb.append(super.toString());
sb.append(" Build Forward Flag: " + String.valueOf(buildForward) + "\n"); sb.append(" Build Forward Flag: " + String.valueOf(buildForward) + "\n");
......
/* /*
* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -213,6 +213,7 @@ class URICertStore extends CertStoreSpi { ...@@ -213,6 +213,7 @@ class URICertStore extends CertStoreSpi {
* match the specified selector * match the specified selector
* @throws CertStoreException if an exception occurs * @throws CertStoreException if an exception occurs
*/ */
@Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public synchronized Collection<X509Certificate> engineGetCertificates public synchronized Collection<X509Certificate> engineGetCertificates
(CertSelector selector) throws CertStoreException { (CertSelector selector) throws CertStoreException {
...@@ -322,6 +323,7 @@ class URICertStore extends CertStoreSpi { ...@@ -322,6 +323,7 @@ class URICertStore extends CertStoreSpi {
* match the specified selector * match the specified selector
* @throws CertStoreException if an exception occurs * @throws CertStoreException if an exception occurs
*/ */
@Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public synchronized Collection<X509CRL> engineGetCRLs(CRLSelector selector) public synchronized Collection<X509CRL> engineGetCRLs(CRLSelector selector)
throws CertStoreException { throws CertStoreException {
...@@ -418,14 +420,14 @@ class URICertStore extends CertStoreSpi { ...@@ -418,14 +420,14 @@ class URICertStore extends CertStoreSpi {
URICertStoreParameters(URI uri) { URICertStoreParameters(URI uri) {
this.uri = uri; this.uri = uri;
} }
public boolean equals(Object obj) { @Override public boolean equals(Object obj) {
if (!(obj instanceof URICertStoreParameters)) { if (!(obj instanceof URICertStoreParameters)) {
return false; return false;
} }
URICertStoreParameters params = (URICertStoreParameters) obj; URICertStoreParameters params = (URICertStoreParameters) obj;
return uri.equals(params.uri); return uri.equals(params.uri);
} }
public int hashCode() { @Override public int hashCode() {
if (hashCode == 0) { if (hashCode == 0) {
int result = 17; int result = 17;
result = 37*result + uri.hashCode(); result = 37*result + uri.hashCode();
...@@ -433,7 +435,7 @@ class URICertStore extends CertStoreSpi { ...@@ -433,7 +435,7 @@ class URICertStore extends CertStoreSpi {
} }
return hashCode; return hashCode;
} }
public Object clone() { @Override public Object clone() {
try { try {
return super.clone(); return super.clone();
} catch (CloneNotSupportedException e) { } catch (CloneNotSupportedException e) {
......
/* /*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -33,9 +33,10 @@ import java.security.cert.CertificateEncodingException; ...@@ -33,9 +33,10 @@ import java.security.cert.CertificateEncodingException;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.*; import java.util.*;
import java.security.cert.CertPath;
import sun.security.pkcs.ContentInfo; import sun.security.pkcs.ContentInfo;
import sun.security.pkcs.PKCS7; import sun.security.pkcs.PKCS7;
import sun.security.pkcs.SignerInfo; import sun.security.pkcs.SignerInfo;
...@@ -44,7 +45,6 @@ import sun.security.util.DerValue; ...@@ -44,7 +45,6 @@ import sun.security.util.DerValue;
import sun.security.util.DerOutputStream; import sun.security.util.DerOutputStream;
import sun.security.util.DerInputStream; import sun.security.util.DerInputStream;
/** /**
* A {@link java.security.cert.CertPath CertPath} (certification path) * A {@link java.security.cert.CertPath CertPath} (certification path)
* consisting exclusively of * consisting exclusively of
...@@ -83,7 +83,7 @@ public class X509CertPath extends CertPath { ...@@ -83,7 +83,7 @@ public class X509CertPath extends CertPath {
private static final Collection<String> encodingList; private static final Collection<String> encodingList;
static { static {
List<String> list = new ArrayList<String>(2); List<String> list = new ArrayList<>(2);
list.add(PKIPATH_ENCODING); list.add(PKIPATH_ENCODING);
list.add(PKCS7_ENCODING); list.add(PKCS7_ENCODING);
encodingList = Collections.unmodifiableCollection(list); encodingList = Collections.unmodifiableCollection(list);
...@@ -272,6 +272,7 @@ public class X509CertPath extends CertPath { ...@@ -272,6 +272,7 @@ public class X509CertPath extends CertPath {
* @return the encoded bytes * @return the encoded bytes
* @exception CertificateEncodingException if an encoding error occurs * @exception CertificateEncodingException if an encoding error occurs
*/ */
@Override
public byte[] getEncoded() throws CertificateEncodingException { public byte[] getEncoded() throws CertificateEncodingException {
// @@@ Should cache the encoded form // @@@ Should cache the encoded form
return encodePKIPATH(); return encodePKIPATH();
...@@ -342,6 +343,7 @@ public class X509CertPath extends CertPath { ...@@ -342,6 +343,7 @@ public class X509CertPath extends CertPath {
* @exception CertificateEncodingException if an encoding error occurs or * @exception CertificateEncodingException if an encoding error occurs or
* the encoding requested is not supported * the encoding requested is not supported
*/ */
@Override
public byte[] getEncoded(String encoding) public byte[] getEncoded(String encoding)
throws CertificateEncodingException { throws CertificateEncodingException {
switch (encoding) { switch (encoding) {
...@@ -376,6 +378,7 @@ public class X509CertPath extends CertPath { ...@@ -376,6 +378,7 @@ public class X509CertPath extends CertPath {
* @return an <code>Iterator</code> over the names of the supported * @return an <code>Iterator</code> over the names of the supported
* encodings (as Strings) * encodings (as Strings)
*/ */
@Override
public Iterator<String> getEncodings() { public Iterator<String> getEncodings() {
return getEncodingsStatic(); return getEncodingsStatic();
} }
...@@ -387,6 +390,7 @@ public class X509CertPath extends CertPath { ...@@ -387,6 +390,7 @@ public class X509CertPath extends CertPath {
* @return an immutable <code>List</code> of <code>X509Certificate</code>s * @return an immutable <code>List</code> of <code>X509Certificate</code>s
* (may be empty, but not null) * (may be empty, but not null)
*/ */
@Override
public List<X509Certificate> getCertificates() { public List<X509Certificate> getCertificates() {
return certs; return certs;
} }
......
/* /*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -207,13 +207,14 @@ public class X509CertificatePair { ...@@ -207,13 +207,14 @@ public class X509CertificatePair {
* *
* @return A String describing the contents of the pair. * @return A String describing the contents of the pair.
*/ */
@Override
public String toString() { public String toString() {
StringBuffer sb = new StringBuffer(); StringBuilder sb = new StringBuilder();
sb.append("X.509 Certificate Pair: [\n"); sb.append("X.509 Certificate Pair: [\n");
if (forward != null) if (forward != null)
sb.append(" Forward: " + forward + "\n"); sb.append(" Forward: ").append(forward).append("\n");
if (reverse != null) if (reverse != null)
sb.append(" Reverse: " + reverse + "\n"); sb.append(" Reverse: ").append(reverse).append("\n");
sb.append("]"); sb.append("]");
return sb.toString(); return sb.toString();
} }
......
...@@ -31,6 +31,7 @@ import java.security.cert.CRLReason; ...@@ -31,6 +31,7 @@ import java.security.cert.CRLReason;
import java.security.cert.X509CRLEntry; import java.security.cert.X509CRLEntry;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
...@@ -500,6 +501,9 @@ public class X509CRLEntryImpl extends X509CRLEntry { ...@@ -500,6 +501,9 @@ public class X509CRLEntryImpl extends X509CRLEntry {
} }
public Map<String, java.security.cert.Extension> getExtensions() { public Map<String, java.security.cert.Extension> getExtensions() {
if (extensions == null) {
return Collections.emptyMap();
}
Collection<Extension> exts = extensions.getAllExtensions(); Collection<Extension> exts = extensions.getAllExtensions();
HashMap<String, java.security.cert.Extension> map = HashMap<String, java.security.cert.Extension> map =
new HashMap<String, java.security.cert.Extension>(exts.size()); new HashMap<String, java.security.cert.Extension>(exts.size());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册