提交 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -45,15 +45,28 @@ import sun.security.jca.GetInstance.Instance;
* one of the static <code>getInstance</code> methods, passing in the
* algorithm name of the <code>CertPathBuilder</code> desired and optionally
* 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
* passing it an algorithm-specific set of parameters. If successful, the
* result (including the <code>CertPath</code> that was built) is returned
* in an object that implements the <code>CertPathBuilderResult</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 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:
* <ul>
* <li><tt>PKIX</tt></li>
......@@ -96,10 +109,9 @@ public class CertPathBuilder {
* </pre>
*/
private static final String CPB_TYPE = "certpathbuilder.type";
private static final Debug debug = Debug.getInstance("certpath");
private CertPathBuilderSpi builderSpi;
private Provider provider;
private String algorithm;
private final CertPathBuilderSpi builderSpi;
private final Provider provider;
private final String algorithm;
/**
* Creates a <code>CertPathBuilder</code> object of the given algorithm,
......@@ -290,15 +302,30 @@ public class CertPathBuilder {
* if no such property exists.
*/
public final static String getDefaultType() {
String cpbtype;
cpbtype = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return Security.getProperty(CPB_TYPE);
}
});
if (cpbtype == null) {
cpbtype = "PKIX";
}
return cpbtype;
String cpbtype =
AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return Security.getProperty(CPB_TYPE);
}
});
return (cpbtype == null) ? "PKIX" : 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -72,4 +72,25 @@ public abstract class CertPathBuilderSpi {
*/
public abstract CertPathBuilderResult engineBuild(CertPathParameters params)
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -46,15 +46,29 @@ import sun.security.jca.GetInstance.Instance;
* call one of the static <code>getInstance</code> methods, passing in the
* algorithm name of the <code>CertPathValidator</code> desired and
* 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
* validate} method and passing it the <code>CertPath</code> to be validated
* and an algorithm-specific set of parameters. If successful, the result is
* returned in an object that implements the
* <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:
* <ul>
* <li><tt>PKIX</tt></li>
......@@ -96,10 +110,9 @@ public class CertPathValidator {
* </pre>
*/
private static final String CPV_TYPE = "certpathvalidator.type";
private static final Debug debug = Debug.getInstance("certpath");
private CertPathValidatorSpi validatorSpi;
private Provider provider;
private String algorithm;
private final CertPathValidatorSpi validatorSpi;
private final Provider provider;
private final String algorithm;
/**
* Creates a <code>CertPathValidator</code> object of the given algorithm,
......@@ -301,15 +314,30 @@ public class CertPathValidator {
* if no such property exists.
*/
public final static String getDefaultType() {
String cpvtype;
cpvtype = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return Security.getProperty(CPV_TYPE);
}
});
if (cpvtype == null) {
cpvtype = "PKIX";
}
return cpvtype;
String cpvtype =
AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return Security.getProperty(CPV_TYPE);
}
});
return (cpvtype == null) ? "PKIX" : 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -82,4 +82,25 @@ public abstract class CertPathValidatorSpi {
public abstract CertPathValidatorResult
engineValidate(CertPath certPath, CertPathParameters params)
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -87,7 +87,8 @@ import java.util.Set;
* @author Yassir Elley
* @author Sean Mullan
*/
public abstract class PKIXCertPathChecker implements Cloneable {
public abstract class PKIXCertPathChecker
implements CertPathChecker, Cloneable {
/**
* Default constructor.
......@@ -111,6 +112,7 @@ public abstract class PKIXCertPathChecker implements Cloneable {
* the specified order; it should never be thrown if the forward flag
* is false since reverse checking must be supported
*/
@Override
public abstract void init(boolean forward)
throws CertPathValidatorException;
......@@ -123,6 +125,7 @@ public abstract class PKIXCertPathChecker implements Cloneable {
* @return <code>true</code> if forward checking is supported,
* <code>false</code> otherwise
*/
@Override
public abstract boolean isForwardCheckingSupported();
/**
......@@ -162,6 +165,17 @@ public abstract class PKIXCertPathChecker implements Cloneable {
Collection<String> unresolvedCritExts)
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>
* method.
......@@ -170,6 +184,7 @@ public abstract class PKIXCertPathChecker implements Cloneable {
*
* @return a copy of this <code>PKIXCertPathChecker</code>
*/
@Override
public Object clone() {
try {
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.
This code is free software; you can redistribute it and/or modify it
......@@ -38,8 +38,10 @@ certificates and X.509 v2 CRLs.
<li><a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
<b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
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
<li>RFC 2560: X.509 Internet Public Key Infrastructure Online Certificate
Status Protocol - OCSP
<li><a href="{@docRoot}/../technotes/guides/security/StandardNames.html">
<b>Java<FONT SIZE=-2><SUP>TM</SUP></FONT>
Cryptography Architecture Standard Algorithm Name
......@@ -50,8 +52,8 @@ certificates and X.509 v2 CRLs.
For information about X.509 certificates and CRLs, please see:
<ul>
<li><a href="http://www.ietf.org/rfc/rfc3280.txt">
http://www.ietf.org/rfc/rfc3280.txt</a>
<li><a href="http://www.ietf.org/rfc/rfc5280.txt">
http://www.ietf.org/rfc/rfc5280.txt</a>
<li><a href=
"{@docRoot}/../technotes/guides/security/certpath/CertPathProgGuide.html">
<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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -24,13 +24,11 @@
*/
package sun.security.provider.certpath;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* An AdjacencyList is used to store the history of certification paths
* attempted in constructing a path from an initiator to a target. The
......@@ -123,124 +121,117 @@ public class AdjacencyList {
* at the start.
*/
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
// from the global list. So, we have to start by getting the list
// that contains the set of Vertexes we're considering.
List<Vertex> l = theList.get(index);
try {
// we're interested in the case where all indexes are -1...
boolean allNegOne = true;
// ...and in the case where every entry has a Throwable
boolean allXcps = true;
// we're interested in the case where all indexes are -1...
boolean allNegOne = true;
// ...and in the case where every entry has a Throwable
boolean allXcps = true;
for (Vertex v : l) {
if (v.getIndex() != -1) {
// count an empty list the same as an index of -1...this
// is to patch a bug somewhere in the builder
if (theList.get(v.getIndex()).size() != 0)
allNegOne = false;
}
else
if (v.getThrowable() == null)
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));
for (Vertex v : l) {
if (v.getIndex() != -1) {
// count an empty list the same as an index of -1...this
// is to patch a bug somewhere in the builder
if (theList.get(v.getIndex()).size() != 0)
allNegOne = false;
} else {
if (v.getThrowable() == null)
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));
}
if (allNegOne) {
// There are two cases that we could be looking at here. We
// may need to back up, or the build may have succeeded at
// this point. This is based on whether or not any
// exceptions were found in the list.
if (allXcps) {
// we need to go back...see if this is the last one
if (follow == null)
mStepList.add(new BuildStep(null, BuildStep.FAIL));
else
mStepList.add(new BuildStep(follow.getVertex(),
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 (allNegOne) {
// There are two cases that we could be looking at here. We
// may need to back up, or the build may have succeeded at
// this point. This is based on whether or not any
// exceptions were found in the list.
if (allXcps) {
// we need to go back...see if this is the last one
if (follow == null)
mStepList.add(new BuildStep(null, BuildStep.FAIL));
else
mStepList.add(new BuildStep(follow.getVertex(),
BuildStep.BACK));
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));
}
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<>();
for (Vertex v : l) {
if (v.getThrowable() == null)
possibles.add(v);
}
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
// looking at the last possible path, so we don't need to
// consider success in the while loop
// Note that we'll only find a SUCCEED case when we're
// looking at the last possible path, so we don't need to
// consider success in the while loop
if (v.getIndex() != -1) {
if (theList.get(v.getIndex()).size() != 0) {
// If the entry we're looking at doesn't have an
// index of -1, and doesn't lead to an empty list,
// then it's something we follow!
BuildStep bs = new BuildStep(v, BuildStep.FOLLOW);
mStepList.add(bs);
success = buildList(theList, v.getIndex(), bs);
}
if (v.getIndex() != -1) {
if (theList.get(v.getIndex()).size() != 0) {
// If the entry we're looking at doesn't have an
// index of -1, and doesn't lead to an empty list,
// then it's something we follow!
BuildStep bs = new BuildStep(v, BuildStep.FOLLOW);
mStepList.add(bs);
success = buildList(theList, v.getIndex(), bs);
}
}
}
if (success) {
// We're already finished!
return true;
} else {
// We failed, and we've exhausted all the paths that we
// could take. The only choice is to back ourselves out.
if (follow == null)
mStepList.add(new BuildStep(null, BuildStep.FAIL));
else
mStepList.add(new BuildStep(follow.getVertex(),
BuildStep.BACK));
if (success) {
// We're already finished!
return true;
} else {
// We failed, and we've exhausted all the paths that we
// could take. The only choice is to back ourselves out.
if (follow == null)
mStepList.add(new BuildStep(null, BuildStep.FAIL));
else
mStepList.add(new BuildStep(follow.getVertex(),
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 {
*
* @return String representation
*/
@Override
public String toString() {
String out = "[\n";
StringBuilder sb = new StringBuilder("[\n");
int i = 0;
for (List<Vertex> l : mOrigList) {
out = out + "LinkedList[" + i++ + "]:\n";
sb.append("LinkedList[").append(i++).append("]:\n");
for (Vertex step : l) {
try {
out = out + step.toString();
out = out + "\n";
}
catch (Exception e) { out = out + "No Such Element\n"; }
sb.append(step.toString()).append("\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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -62,7 +62,7 @@ class BasicChecker extends PKIXCertPathChecker {
private static final Debug debug = Debug.getInstance("certpath");
private final PublicKey trustedPubKey;
private final X500Principal caName;
private final Date testDate;
private final Date date;
private final String sigProvider;
private final boolean sigOnly;
private X500Principal prevSubject;
......@@ -73,14 +73,13 @@ class BasicChecker extends PKIXCertPathChecker {
*
* @param anchor the anchor selected to validate the target 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 sigOnly true if only signature checking is to be done;
* if false, all checks are done
*/
BasicChecker(TrustAnchor anchor, Date testDate, String sigProvider,
boolean sigOnly) throws CertPathValidatorException
{
BasicChecker(TrustAnchor anchor, Date date, String sigProvider,
boolean sigOnly) {
if (anchor.getTrustedCert() != null) {
this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
this.caName = anchor.getTrustedCert().getSubjectX500Principal();
......@@ -88,16 +87,16 @@ class BasicChecker extends PKIXCertPathChecker {
this.trustedPubKey = anchor.getCAPublicKey();
this.caName = anchor.getCA();
}
this.testDate = testDate;
this.date = date;
this.sigProvider = sigProvider;
this.sigOnly = sigOnly;
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) {
prevPubKey = trustedPubKey;
......@@ -108,10 +107,12 @@ class BasicChecker extends PKIXCertPathChecker {
}
}
@Override
public boolean isForwardCheckingSupported() {
return false;
}
@Override
public Set<String> getSupportedExtensions() {
return null;
}
......@@ -124,33 +125,31 @@ class BasicChecker extends PKIXCertPathChecker {
* @param cert the Certificate
* @param unresolvedCritExts a Collection of the unresolved critical
* extensions
* @exception CertPathValidatorException Exception thrown if certificate
* does not verify.
* @throws CertPathValidatorException if certificate does not verify
*/
@Override
public void check(Certificate cert, Collection<String> unresolvedCritExts)
throws CertPathValidatorException
{
X509Certificate currCert = (X509Certificate) cert;
X509Certificate currCert = (X509Certificate)cert;
if (!sigOnly) {
verifyTimestamp(currCert, testDate);
verifyNameChaining(currCert, prevSubject);
verifyTimestamp(currCert);
verifyNameChaining(currCert);
}
verifySignature(currCert, prevPubKey, sigProvider);
verifySignature(currCert);
updateState(currCert);
}
/**
* Verifies the signature on the certificate using the previous public key
* @param cert the Certificate
* @param prevPubKey the previous PublicKey
* @param sigProvider a String containing the signature provider
* @exception CertPathValidatorException Exception thrown if certificate
* does not verify.
* Verifies the signature on the certificate using the previous public key.
*
* @param cert the X509Certificate
* @throws CertPathValidatorException if certificate does not verify
*/
private void verifySignature(X509Certificate cert, PublicKey prevPubKey,
String sigProvider) throws CertPathValidatorException
private void verifySignature(X509Certificate cert)
throws CertPathValidatorException
{
String msg = "signature";
if (debug != null)
......@@ -162,7 +161,7 @@ class BasicChecker extends PKIXCertPathChecker {
throw new CertPathValidatorException
(msg + " check failed", e, null, -1,
BasicReason.INVALID_SIGNATURE);
} catch (Exception e) {
} catch (GeneralSecurityException e) {
throw new CertPathValidatorException(msg + " check failed", e);
}
......@@ -173,7 +172,7 @@ class BasicChecker extends PKIXCertPathChecker {
/**
* Internal method to verify the timestamp on a certificate
*/
private void verifyTimestamp(X509Certificate cert, Date date)
private void verifyTimestamp(X509Certificate cert)
throws CertPathValidatorException
{
String msg = "timestamp";
......@@ -197,8 +196,8 @@ class BasicChecker extends PKIXCertPathChecker {
/**
* Internal method to check that cert has a valid DN to be next in a chain
*/
private void verifyNameChaining(X509Certificate cert,
X500Principal prevSubject) throws CertPathValidatorException
private void verifyNameChaining(X509Certificate cert)
throws CertPathValidatorException
{
if (prevSubject != null) {
......@@ -207,8 +206,8 @@ class BasicChecker extends PKIXCertPathChecker {
debug.println("---checking " + msg + "...");
X500Principal currIssuer = cert.getIssuerX500Principal();
// reject null or empty issuer DNs
// reject null or empty issuer DNs
if (X500Name.asX500Name(currIssuer).isEmpty()) {
throw new CertPathValidatorException
(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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,7 +25,6 @@
package sun.security.provider.certpath;
import sun.security.util.Debug;
import java.security.cert.X509Certificate;
/**
......@@ -39,7 +38,6 @@ import java.security.cert.X509Certificate;
*/
public class BuildStep {
private static final Debug debug = Debug.getInstance("certpath");
private Vertex vertex;
private X509Certificate cert;
private Throwable throwable;
......@@ -86,7 +84,7 @@ public class BuildStep {
public BuildStep(Vertex vtx, int res) {
vertex = vtx;
if (vertex != null) {
cert = (X509Certificate)vertex.getCertificate();
cert = vertex.getCertificate();
throwable = vertex.getThrowable();
}
result = res;
......@@ -117,7 +115,7 @@ public class BuildStep {
* @returns String form of issuer name or null, if no certificate.
*/
public String getIssuerName() {
return (cert == null ? null : cert.getIssuerX500Principal().toString());
return getIssuerName(null);
}
/**
......@@ -142,7 +140,7 @@ public class BuildStep {
* @returns String form of subject name or null, if no certificate.
*/
public String getSubjectName() {
return (cert == null ? null : cert.getSubjectX500Principal().toString());
return getSubjectName(null);
}
/**
......@@ -191,21 +189,21 @@ public class BuildStep {
public String resultToString(int res) {
String resultString = "";
switch (res) {
case BuildStep.POSSIBLE:
case POSSIBLE:
resultString = "Certificate to be tried.\n";
break;
case BuildStep.BACK:
case BACK:
resultString = "Certificate backed out since path does not "
+ "satisfy build requirements.\n";
break;
case BuildStep.FOLLOW:
case FOLLOW:
resultString = "Certificate satisfies conditions.\n";
break;
case BuildStep.FAIL:
case FAIL:
resultString = "Certificate backed out since path does not "
+ "satisfy conditions.\n";
break;
case BuildStep.SUCCEED:
case SUCCEED:
resultString = "Certificate satisfies conditions.\n";
break;
default:
......@@ -220,6 +218,7 @@ public class BuildStep {
*
* @returns String
*/
@Override
public String toString() {
String out = "Internal Error\n";
switch (result) {
......@@ -273,8 +272,6 @@ public class BuildStep {
* @returns String
*/
public String fullToString() {
String out = resultToString(getResult());
out = out + vertex.toString();
return out;
return resultToString(getResult()) + vertex.toString();
}
}
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -31,9 +31,8 @@ import java.security.GeneralSecurityException;
import java.security.cert.*;
import java.util.*;
import javax.security.auth.x500.X500Principal;
import sun.security.action.GetBooleanAction;
import sun.security.provider.certpath.PKIX.BuilderParams;
import sun.security.util.Debug;
import sun.security.x509.GeneralNames;
import sun.security.x509.GeneralNameInterface;
......@@ -56,9 +55,7 @@ public abstract class Builder {
private static final Debug debug = Debug.getInstance("certpath");
private Set<String> matchingPolicies;
final PKIXBuilderParameters buildParams;
final X500Principal targetSubjectDN;
final Date date;
final BuilderParams buildParams;
final X509CertSelector targetCertConstraints;
/**
......@@ -74,14 +71,10 @@ public abstract class Builder {
*
* @param params the parameter set used to build a certification path
*/
Builder(PKIXBuilderParameters buildParams, X500Principal targetSubjectDN) {
Builder(BuilderParams 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 =
(X509CertSelector) buildParams.getTargetCertConstraints();
(X509CertSelector)buildParams.targetCertConstraints();
}
/**
......@@ -104,7 +97,8 @@ public abstract class Builder {
* @param certPathList the certPathList generated thus far
*/
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.
......@@ -123,7 +117,7 @@ public abstract class Builder {
* @param certPathList the certification path list
*/
abstract void addCertToPath(X509Certificate cert,
LinkedList<X509Certificate> certPathList);
LinkedList<X509Certificate> certPathList);
/**
* Removes final certificate from the certPathList
......@@ -147,7 +141,8 @@ public abstract class Builder {
* is a grandparent, etc.
*/
static int distance(GeneralNameInterface base,
GeneralNameInterface test, int incomparable) {
GeneralNameInterface test, int incomparable)
{
switch (base.constrains(test)) {
case GeneralNameInterface.NAME_DIFF_TYPE:
if (debug != null) {
......@@ -192,7 +187,8 @@ public abstract class Builder {
* some number of down hops.
*/
static int hops(GeneralNameInterface base, GeneralNameInterface test,
int incomparable) {
int incomparable)
{
int baseRtest = base.constrains(test);
switch (baseRtest) {
case GeneralNameInterface.NAME_DIFF_TYPE:
......@@ -282,9 +278,9 @@ public abstract class Builder {
* @throws IOException if certificate does not get closer
*/
static int targetDistance(NameConstraintsExtension constraints,
X509Certificate cert, GeneralNameInterface target)
throws IOException {
X509Certificate cert, GeneralNameInterface target)
throws IOException
{
/* ensure that certificate satisfies existing name constraints */
if (constraints != null && !constraints.verify(cert)) {
throw new IOException("certificate does not satisfy existing name "
......@@ -295,7 +291,7 @@ public abstract class Builder {
try {
certImpl = X509CertImpl.toImpl(cert);
} catch (CertificateException e) {
throw (IOException)new IOException("Invalid certificate").initCause(e);
throw new IOException("Invalid certificate", e);
}
/* see if certificate subject matches target */
X500Name subject = X500Name.asX500Name(certImpl.getSubjectX500Principal());
......@@ -398,13 +394,13 @@ public abstract class Builder {
*/
Set<String> getMatchingPolicies() {
if (matchingPolicies != null) {
Set<String> initialPolicies = buildParams.getInitialPolicies();
Set<String> initialPolicies = buildParams.initialPolicies();
if ((!initialPolicies.isEmpty()) &&
(!initialPolicies.contains(PolicyChecker.ANY_POLICY)) &&
(buildParams.isPolicyMappingInhibited()))
(buildParams.policyMappingInhibited()))
{
initialPolicies.add(PolicyChecker.ANY_POLICY);
matchingPolicies = initialPolicies;
matchingPolicies = new HashSet<>(initialPolicies);
matchingPolicies.add(PolicyChecker.ANY_POLICY);
} else {
// we just return an empty set to make sure that there is
// at least a certificate policies extension in the cert
......@@ -429,13 +425,15 @@ public abstract class Builder {
* Returns true iff resultCerts changed (a cert was added to the collection)
*/
boolean addMatchingCerts(X509CertSelector selector,
Collection<CertStore> certStores,
Collection<X509Certificate> resultCerts, boolean checkAll) {
Collection<CertStore> certStores,
Collection<X509Certificate> resultCerts,
boolean checkAll)
{
X509Certificate targetCert = selector.getCertificate();
if (targetCert != null) {
// no need to search CertStores
if (selector.match(targetCert) && !X509CertImpl.isSelfSigned
(targetCert, buildParams.getSigProvider())) {
(targetCert, buildParams.sigProvider())) {
if (debug != null) {
debug.println("Builder.addMatchingCerts: adding target cert");
}
......@@ -450,7 +448,7 @@ public abstract class Builder {
store.getCertificates(selector);
for (Certificate cert : certs) {
if (!X509CertImpl.isSelfSigned
((X509Certificate)cert, buildParams.getSigProvider())) {
((X509Certificate)cert, buildParams.sigProvider())) {
if (resultCerts.add((X509Certificate)cert)) {
add = true;
}
......@@ -471,16 +469,4 @@ public abstract class Builder {
}
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -83,9 +83,8 @@ public abstract class CertStoreHelper {
= (CertStoreHelper)c.newInstance();
cache.put(type, csh);
return csh;
} catch (InstantiationException e) {
throw new AssertionError(e);
} catch (IllegalAccessException e) {
} catch (InstantiationException |
IllegalAccessException 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -31,7 +31,6 @@ import java.security.cert.CRL;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.HashSet;
import java.util.Iterator;
import java.security.cert.CertSelector;
import java.security.cert.CertStore;
import java.security.cert.CertStoreException;
......@@ -114,6 +113,7 @@ public class CollectionCertStore extends CertStoreSpi {
* match the specified selector
* @throws CertStoreException if an exception occurs
*/
@Override
public Collection<Certificate> engineGetCertificates
(CertSelector selector) throws CertStoreException {
if (coll == null) {
......@@ -122,18 +122,15 @@ public class CollectionCertStore extends CertStoreSpi {
// Tolerate a few ConcurrentModificationExceptions
for (int c = 0; c < 10; c++) {
try {
HashSet<Certificate> result = new HashSet<Certificate>();
Iterator<?> i = coll.iterator();
HashSet<Certificate> result = new HashSet<>();
if (selector != null) {
while (i.hasNext()) {
Object o = i.next();
for (Object o : coll) {
if ((o instanceof Certificate) &&
selector.match((Certificate) o))
result.add((Certificate)o);
}
} else {
while (i.hasNext()) {
Object o = i.next();
for (Object o : coll) {
if (o instanceof Certificate)
result.add((Certificate)o);
}
......@@ -157,6 +154,7 @@ public class CollectionCertStore extends CertStoreSpi {
* match the specified selector
* @throws CertStoreException if an exception occurs
*/
@Override
public Collection<CRL> engineGetCRLs(CRLSelector selector)
throws CertStoreException
{
......@@ -166,22 +164,19 @@ public class CollectionCertStore extends CertStoreSpi {
// Tolerate a few ConcurrentModificationExceptions
for (int c = 0; c < 10; c++) {
try {
HashSet<CRL> result = new HashSet<CRL>();
Iterator<?> i = coll.iterator();
HashSet<CRL> result = new HashSet<>();
if (selector != null) {
while (i.hasNext()) {
Object o = i.next();
for (Object o : coll) {
if ((o instanceof CRL) && selector.match((CRL) o))
result.add((CRL)o);
}
} else {
while (i.hasNext()) {
Object o = i.next();
for (Object o : coll) {
if (o instanceof CRL)
result.add((CRL)o);
}
}
return(result);
return result;
} catch (ConcurrentModificationException e) { }
}
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,19 +25,20 @@
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.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException;
import java.security.cert.X509Certificate;
import java.security.cert.PKIXCertPathChecker;
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.x509.PKIXExtensions;
import static sun.security.x509.PKIXExtensions.*;
import sun.security.x509.NameConstraintsExtension;
import sun.security.x509.X509CertImpl;
......@@ -66,13 +67,12 @@ class ConstraintsChecker extends PKIXCertPathChecker {
* Creates a ConstraintsChecker.
*
* @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;
init(false);
}
@Override
public void init(boolean forward) throws CertPathValidatorException {
if (!forward) {
i = 0;
......@@ -84,15 +84,17 @@ class ConstraintsChecker extends PKIXCertPathChecker {
}
}
@Override
public boolean isForwardCheckingSupported() {
return false;
}
@Override
public Set<String> getSupportedExtensions() {
if (supportedExts == null) {
supportedExts = new HashSet<String>();
supportedExts.add(PKIXExtensions.BasicConstraints_Id.toString());
supportedExts.add(PKIXExtensions.NameConstraints_Id.toString());
supportedExts = new HashSet<String>(2);
supportedExts.add(BasicConstraints_Id.toString());
supportedExts.add(NameConstraints_Id.toString());
supportedExts = Collections.unmodifiableSet(supportedExts);
}
return supportedExts;
......@@ -104,14 +106,15 @@ class ConstraintsChecker extends PKIXCertPathChecker {
*
* @param cert the <code>Certificate</code> to be checked
* @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
* does not pass the check
* does not pass the check
*/
@Override
public void check(Certificate cert, Collection<String> unresCritExts)
throws CertPathValidatorException
{
X509Certificate currCert = (X509Certificate) cert;
X509Certificate currCert = (X509Certificate)cert;
i++;
// MUST run NC check second, since it depends on BC check to
......@@ -120,8 +123,8 @@ class ConstraintsChecker extends PKIXCertPathChecker {
verifyNameConstraints(currCert);
if (unresCritExts != null && !unresCritExts.isEmpty()) {
unresCritExts.remove(PKIXExtensions.BasicConstraints_Id.toString());
unresCritExts.remove(PKIXExtensions.NameConstraints_Id.toString());
unresCritExts.remove(BasicConstraints_Id.toString());
unresCritExts.remove(NameConstraints_Id.toString());
}
}
......@@ -166,9 +169,9 @@ class ConstraintsChecker extends PKIXCertPathChecker {
/**
* Helper to fold sets of name constraints together
*/
static NameConstraintsExtension
mergeNameConstraints(X509Certificate currCert,
NameConstraintsExtension prevNC) throws CertPathValidatorException
static NameConstraintsExtension mergeNameConstraints(
X509Certificate currCert, NameConstraintsExtension prevNC)
throws CertPathValidatorException
{
X509CertImpl currCertImpl;
try {
......@@ -197,7 +200,7 @@ class ConstraintsChecker extends PKIXCertPathChecker {
// Make sure we do a clone here, because we're probably
// going to modify this object later and we don't want to
// be sharing it with a Certificate object!
return (NameConstraintsExtension) newConstraints.clone();
return (NameConstraintsExtension)newConstraints.clone();
}
} else {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -27,14 +27,14 @@ package sun.security.provider.certpath;
import java.io.*;
import java.net.URI;
import java.util.*;
import java.security.*;
import java.security.cert.*;
import javax.security.auth.x500.X500Principal;
import java.util.*;
import sun.security.action.GetBooleanAction;
import sun.security.util.Debug;
import sun.security.util.DerOutputStream;
import static sun.security.x509.PKIXExtensions.*;
import sun.security.x509.*;
/**
......@@ -57,45 +57,24 @@ class DistributionPointFetcher {
private static final boolean[] ALL_REASONS =
{true, true, true, true, true, true, true, true, true};
/**
* Flag indicating whether support for the CRL distribution point
* extension shall be enabled. Currently disabled by default for
* compatibility and legal reasons.
*/
private final static boolean USE_CRLDP = AccessController.doPrivileged
(new GetBooleanAction("com.sun.security.enableCRLDP"));
// singleton instance
private static final DistributionPointFetcher INSTANCE =
new DistributionPointFetcher();
/**
* Private instantiation only.
*/
private DistributionPointFetcher() {}
/**
* Return a DistributionPointFetcher instance.
*/
static DistributionPointFetcher getInstance() {
return INSTANCE;
}
/**
* Return the X509CRLs matching this selector. The selector must be
* an X509CRLSelector with certificateChecking set.
*
* If CRLDP support is disabled, this method always returns an
* empty set.
*/
Collection<X509CRL> getCRLs(X509CRLSelector selector, boolean signFlag,
PublicKey prevKey, String provider, List<CertStore> certStores,
boolean[] reasonsMask, Set<TrustAnchor> trustAnchors,
Date validity) throws CertStoreException {
if (USE_CRLDP == false) {
return Collections.emptySet();
}
static Collection<X509CRL> getCRLs(X509CRLSelector selector,
boolean signFlag, PublicKey prevKey,
String provider,
List<CertStore> certStores,
boolean[] reasonsMask,
Set<TrustAnchor> trustAnchors,
Date validity)
throws CertStoreException
{
X509Certificate cert = selector.getCertificateChecking();
if (cert == null) {
return Collections.emptySet();
......@@ -116,7 +95,7 @@ class DistributionPointFetcher {
}
List<DistributionPoint> points =
ext.get(CRLDistributionPointsExtension.POINTS);
Set<X509CRL> results = new HashSet<X509CRL>();
Set<X509CRL> results = new HashSet<>();
for (Iterator<DistributionPoint> t = points.iterator();
t.hasNext() && !Arrays.equals(reasonsMask, ALL_REASONS); ) {
DistributionPoint point = t.next();
......@@ -129,9 +108,7 @@ class DistributionPointFetcher {
debug.println("Returning " + results.size() + " CRLs");
}
return results;
} catch (CertificateException e) {
return Collections.emptySet();
} catch (IOException e) {
} catch (CertificateException | IOException e) {
return Collections.emptySet();
}
}
......@@ -140,7 +117,7 @@ class DistributionPointFetcher {
* Download CRLs from the given distribution point, verify and return them.
* See the top of the class for current limitations.
*/
private Collection<X509CRL> getCRLs(X509CRLSelector selector,
private static Collection<X509CRL> getCRLs(X509CRLSelector selector,
X509CertImpl certImpl, DistributionPoint point, boolean[] reasonsMask,
boolean signFlag, PublicKey prevKey, String provider,
List<CertStore> certStores, Set<TrustAnchor> trustAnchors,
......@@ -200,7 +177,7 @@ class DistributionPointFetcher {
certStores, validity)) {
crls.add(crl);
}
} catch (Exception e) {
} catch (IOException | CRLException e) {
// don't add the CRL
if (debug != null) {
debug.println("Exception verifying CRL: " + e.getMessage());
......@@ -214,7 +191,7 @@ class DistributionPointFetcher {
/**
* Download CRL from given URI.
*/
private X509CRL getCRL(URIName name) {
private static X509CRL getCRL(URIName name) {
URI uri = name.getURI();
if (debug != null) {
debug.println("Trying to fetch CRL from DP " + uri);
......@@ -240,7 +217,7 @@ class DistributionPointFetcher {
/**
* Fetch CRLs from certStores.
*/
private Collection<X509CRL> getCRLs(X500Name name,
private static Collection<X509CRL> getCRLs(X500Name name,
X500Principal certIssuer, List<CertStore> certStores)
{
if (debug != null) {
......@@ -249,7 +226,7 @@ class DistributionPointFetcher {
X509CRLSelector xcs = new X509CRLSelector();
xcs.addIssuer(name.asX500Principal());
xcs.addIssuer(certIssuer);
Collection<X509CRL> crls = new ArrayList<X509CRL>();
Collection<X509CRL> crls = new ArrayList<>();
for (CertStore store : certStores) {
try {
for (CRL crl : store.getCRLs(xcs)) {
......@@ -285,7 +262,7 @@ class DistributionPointFetcher {
* certification path should be determined
* @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,
PublicKey prevKey, String provider,
Set<TrustAnchor> trustAnchors, List<CertStore> certStores,
......@@ -340,9 +317,9 @@ class DistributionPointFetcher {
} else {
// in case of self-issued indirect CRL issuer.
byte[] certAKID = certImpl.getExtensionValue(
PKIXExtensions.AuthorityKey_Id.toString());
AuthorityKey_Id.toString());
byte[] crlAKID = crlImpl.getExtensionValue(
PKIXExtensions.AuthorityKey_Id.toString());
AuthorityKey_Id.toString());
if (certAKID == null || crlAKID == null) {
// cannot recognize indirect CRL without AKID
......@@ -539,7 +516,7 @@ class DistributionPointFetcher {
// verify that interim reasons mask includes one or more reasons
// not included in the reasons mask
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]) {
oneOrMore = true;
}
......@@ -615,7 +592,7 @@ class DistributionPointFetcher {
PKIXCertPathBuilderResult result =
(PKIXCertPathBuilderResult) builder.build(params);
prevKey = result.getPublicKey();
} catch (Exception e) {
} catch (GeneralSecurityException e) {
throw new CRLException(e);
}
}
......@@ -633,7 +610,7 @@ class DistributionPointFetcher {
// validate the signature on the CRL
try {
crl.verify(prevKey, provider);
} catch (Exception e) {
} catch (GeneralSecurityException e) {
if (debug != null) {
debug.println("CRL signature failed to verify");
}
......@@ -644,22 +621,21 @@ class DistributionPointFetcher {
Set<String> unresCritExts = crl.getCriticalExtensionOIDs();
// remove any that we have processed
if (unresCritExts != null) {
unresCritExts.remove
(PKIXExtensions.IssuingDistributionPoint_Id.toString());
unresCritExts.remove(IssuingDistributionPoint_Id.toString());
if (!unresCritExts.isEmpty()) {
if (debug != null) {
debug.println("Unrecognized critical extension(s) in CRL: "
+ unresCritExts);
Iterator<String> i = unresCritExts.iterator();
while (i.hasNext())
debug.println(i.next());
for (String ext : unresCritExts) {
debug.println(ext);
}
}
return false;
}
}
// update reasonsMask
for (int i=0; i < interimReasonsMask.length; i++) {
for (int i = 0; i < interimReasonsMask.length; i++) {
if (!reasonsMask[i] && interimReasonsMask[i]) {
reasonsMask[i] = true;
}
......@@ -671,9 +647,10 @@ class DistributionPointFetcher {
* Append relative name to the issuer name and return a new
* GeneralNames object.
*/
private GeneralNames getFullNames(X500Name issuer, RDN rdn)
throws IOException {
List<RDN> rdns = new ArrayList<RDN>(issuer.rdns());
private static GeneralNames getFullNames(X500Name issuer, RDN rdn)
throws IOException
{
List<RDN> rdns = new ArrayList<>(issuer.rdns());
rdns.add(rdn);
X500Name fullName = new X500Name(rdns.toArray(new RDN[0]));
GeneralNames fullNames = new GeneralNames();
......@@ -681,15 +658,16 @@ class DistributionPointFetcher {
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 crl the CRL to be verified
* @param provider the name of the signature provider
*/
private static boolean issues(X509CertImpl cert, X509CRLImpl crl,
String provider) throws IOException {
String provider) throws IOException
{
boolean matched = false;
AdaptableX509CertSelector issuerSelector =
......@@ -727,7 +705,7 @@ class DistributionPointFetcher {
try {
crl.verify(cert.getPublicKey(), provider);
matched = true;
} catch (Exception e) {
} catch (GeneralSecurityException e) {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -26,10 +26,9 @@
package sun.security.provider.certpath;
import java.io.IOException;
import java.util.*;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException;
import java.security.cert.PKIXReason;
......@@ -40,12 +39,14 @@ import java.security.cert.PKIXCertPathChecker;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.security.cert.X509CertSelector;
import java.util.*;
import javax.security.auth.x500.X500Principal;
import sun.security.provider.certpath.PKIX.BuilderParams;
import sun.security.util.Debug;
import sun.security.x509.AccessDescription;
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.X500Name;
import sun.security.x509.X509CertImpl;
......@@ -72,21 +73,17 @@ class ForwardBuilder extends Builder {
TrustAnchor trustAnchor;
private Comparator<X509Certificate> comparator;
private boolean searchAllCertStores = true;
private boolean onlyEECert = false;
/**
* Initialize the builder with the input parameters.
*
* @param params the parameter set used to build a certification path
*/
ForwardBuilder(PKIXBuilderParameters buildParams,
X500Principal targetSubjectDN, boolean searchAllCertStores,
boolean onlyEECert)
{
super(buildParams, targetSubjectDN);
ForwardBuilder(BuilderParams buildParams, boolean searchAllCertStores) {
super(buildParams);
// populate sets of trusted certificates and subject DNs
trustAnchors = buildParams.getTrustAnchors();
trustAnchors = buildParams.trustAnchors();
trustedCerts = new HashSet<X509Certificate>(trustAnchors.size());
trustedSubjectDNs = new HashSet<X500Principal>(trustAnchors.size());
for (TrustAnchor anchor : trustAnchors) {
......@@ -100,7 +97,6 @@ class ForwardBuilder extends Builder {
}
comparator = new PKIXCertComparator(trustedSubjectDNs);
this.searchAllCertStores = searchAllCertStores;
this.onlyEECert = onlyEECert;
}
/**
......@@ -112,8 +108,9 @@ class ForwardBuilder extends Builder {
* Must be an instance of <code>ForwardState</code>
* @param certStores list of CertStores
*/
Collection<X509Certificate> getMatchingCerts
(State currentState, List<CertStore> certStores)
@Override
Collection<X509Certificate> getMatchingCerts(State currentState,
List<CertStore> certStores)
throws CertStoreException, CertificateException, IOException
{
if (debug != null) {
......@@ -127,7 +124,7 @@ class ForwardBuilder extends Builder {
* As each cert is added, it is sorted based on the PKIXCertComparator
* algorithm.
*/
Set<X509Certificate> certs = new TreeSet<X509Certificate>(comparator);
Set<X509Certificate> certs = new TreeSet<>(comparator);
/*
* Only look for EE certs if search has just started.
......@@ -145,9 +142,10 @@ class ForwardBuilder extends Builder {
* and requirements specified in the parameters and PKIX state.
*/
private void getMatchingEECerts(ForwardState currentState,
List<CertStore> certStores, Collection<X509Certificate> eeCerts)
throws IOException {
List<CertStore> certStores,
Collection<X509Certificate> eeCerts)
throws IOException
{
if (debug != null) {
debug.println("ForwardBuilder.getMatchingEECerts()...");
}
......@@ -165,12 +163,12 @@ class ForwardBuilder extends Builder {
/*
* Match on certificate validity date
*/
eeSelector.setCertificateValid(date);
eeSelector.setCertificateValid(buildParams.date());
/*
* Policy processing optimizations
*/
if (buildParams.isExplicitPolicyRequired()) {
if (buildParams.explicitPolicyRequired()) {
eeSelector.setPolicy(getMatchingPolicies());
}
/*
......@@ -188,9 +186,10 @@ class ForwardBuilder extends Builder {
* and requirements specified in the parameters and PKIX state.
*/
private void getMatchingCACerts(ForwardState currentState,
List<CertStore> certStores, Collection<X509Certificate> caCerts)
throws IOException {
List<CertStore> certStores,
Collection<X509Certificate> caCerts)
throws IOException
{
if (debug != null) {
debug.println("ForwardBuilder.getMatchingCACerts()...");
}
......@@ -216,8 +215,8 @@ class ForwardBuilder extends Builder {
}
if (caTargetSelector == null) {
caTargetSelector = (X509CertSelector)
targetCertConstraints.clone();
caTargetSelector =
(X509CertSelector) targetCertConstraints.clone();
/*
* Since we don't check the validity period of trusted
......@@ -229,7 +228,7 @@ class ForwardBuilder extends Builder {
/*
* Policy processing optimizations
*/
if (buildParams.isExplicitPolicyRequired())
if (buildParams.explicitPolicyRequired())
caTargetSelector.setPolicy(getMatchingPolicies());
}
......@@ -249,7 +248,7 @@ class ForwardBuilder extends Builder {
/*
* Policy processing optimizations
*/
if (buildParams.isExplicitPolicyRequired())
if (buildParams.explicitPolicyRequired())
caSelector.setPolicy(getMatchingPolicies());
}
......@@ -278,7 +277,7 @@ class ForwardBuilder extends Builder {
* check the validity period
*/
caSelector.setValidityPeriod(currentState.cert.getNotBefore(),
currentState.cert.getNotAfter());
currentState.cert.getNotAfter());
sel = caSelector;
}
......@@ -307,7 +306,7 @@ class ForwardBuilder extends Builder {
* The trusted certificate matching is completed. We need to match
* on certificate validity date.
*/
sel.setCertificateValid(date);
sel.setCertificateValid(buildParams.date());
/*
* Require CA certs with a pathLenConstraint that allows
......@@ -323,11 +322,12 @@ class ForwardBuilder extends Builder {
* certificate pairs.
*/
if (currentState.isInitial() ||
(buildParams.getMaxPathLength() == -1) ||
(buildParams.getMaxPathLength() > currentState.traversedCACerts))
(buildParams.maxPathLength() == -1) ||
(buildParams.maxPathLength() > currentState.traversedCACerts))
{
if (addMatchingCerts(sel, certStores,
caCerts, searchAllCertStores) && !searchAllCertStores) {
caCerts, searchAllCertStores)
&& !searchAllCertStores) {
return;
}
}
......@@ -356,7 +356,8 @@ class ForwardBuilder extends Builder {
// because of the selector, so the cast is safe
@SuppressWarnings("unchecked")
private boolean getCerts(AuthorityInfoAccessExtension aiaExt,
Collection<X509Certificate> certs) {
Collection<X509Certificate> certs)
{
if (Builder.USE_AIA == false) {
return false;
}
......@@ -449,6 +450,7 @@ class ForwardBuilder extends Builder {
* @throws ClassCastException if either argument is not of type
* X509Certificate
*/
@Override
public int compare(X509Certificate oCert1, X509Certificate oCert2) {
// if certs are the same, return 0
......@@ -651,8 +653,10 @@ class ForwardBuilder extends Builder {
* @param currentState the current state against which the cert is verified
* @param certPathList the certPathList generated thus far
*/
@Override
void verifyCert(X509Certificate cert, State currentState,
List<X509Certificate> certPathList) throws GeneralSecurityException
List<X509Certificate> certPathList)
throws GeneralSecurityException
{
if (debug != null) {
debug.println("ForwardBuilder.verifyCert(SN: "
......@@ -683,7 +687,7 @@ class ForwardBuilder extends Builder {
debug.println("policyMappingFound = " + policyMappingFound);
}
if (cert.equals(cpListCert)) {
if ((buildParams.isPolicyMappingInhibited()) ||
if ((buildParams.policyMappingInhibited()) ||
(!policyMappingFound)) {
if (debug != null) {
debug.println("loop detected!!");
......@@ -718,7 +722,7 @@ class ForwardBuilder extends Builder {
* all extensions that all user checkers are capable of
* processing.
*/
for (PKIXCertPathChecker checker : buildParams.getCertPathCheckers()) {
for (PKIXCertPathChecker checker : buildParams.certPathCheckers()) {
if (!checker.isForwardCheckingSupported()) {
Set<String> supportedExts = checker.getSupportedExtensions();
if (supportedExts != null) {
......@@ -732,23 +736,15 @@ class ForwardBuilder extends Builder {
* to check. If there are any left, throw an exception!
*/
if (!unresCritExts.isEmpty()) {
unresCritExts.remove(
PKIXExtensions.BasicConstraints_Id.toString());
unresCritExts.remove(
PKIXExtensions.NameConstraints_Id.toString());
unresCritExts.remove(
PKIXExtensions.CertificatePolicies_Id.toString());
unresCritExts.remove(
PKIXExtensions.PolicyMappings_Id.toString());
unresCritExts.remove(
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());
unresCritExts.remove(BasicConstraints_Id.toString());
unresCritExts.remove(NameConstraints_Id.toString());
unresCritExts.remove(CertificatePolicies_Id.toString());
unresCritExts.remove(PolicyMappings_Id.toString());
unresCritExts.remove(PolicyConstraints_Id.toString());
unresCritExts.remove(InhibitAnyPolicy_Id.toString());
unresCritExts.remove(SubjectAlternativeName_Id.toString());
unresCritExts.remove(KeyUsage_Id.toString());
unresCritExts.remove(ExtendedKeyUsage_Id.toString());
if (!unresCritExts.isEmpty())
throw new CertPathValidatorException
......@@ -785,32 +781,13 @@ class ForwardBuilder extends Builder {
* 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
* encountered.
*/
if (!currState.keyParamsNeeded()) {
(currState.cert).verify(cert.getPublicKey(),
buildParams.getSigProvider());
buildParams.sigProvider());
}
}
......@@ -826,6 +803,7 @@ class ForwardBuilder extends Builder {
* @param cert the certificate to test
* @return a boolean value indicating whether the cert completes the path.
*/
@Override
boolean isPathCompleted(X509Certificate cert) {
for (TrustAnchor anchor : trustAnchors) {
if (anchor.getTrustedCert() != null) {
......@@ -837,7 +815,7 @@ class ForwardBuilder extends Builder {
}
} else {
X500Principal principal = anchor.getCA();
java.security.PublicKey publicKey = anchor.getCAPublicKey();
PublicKey publicKey = anchor.getCAPublicKey();
if (principal != null && publicKey != null &&
principal.equals(cert.getSubjectX500Principal())) {
......@@ -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
*/
......@@ -879,18 +842,17 @@ class ForwardBuilder extends Builder {
// parameters, yet there is no key to inherit the parameters
// from. This is probably such a rare case that it is not worth
// trying to detect the situation earlier.
cert.verify(anchor.getCAPublicKey(),
buildParams.getSigProvider());
cert.verify(anchor.getCAPublicKey(), buildParams.sigProvider());
} catch (InvalidKeyException ike) {
if (debug != null) {
debug.println("ForwardBuilder.isPathCompleted() invalid "
+ "DSA key found");
+ "DSA key found");
}
continue;
} catch (Exception e){
} catch (GeneralSecurityException e){
if (debug != null) {
debug.println("ForwardBuilder.isPathCompleted() " +
"unexpected exception");
"unexpected exception");
e.printStackTrace();
}
continue;
......@@ -908,8 +870,10 @@ class ForwardBuilder extends Builder {
* @param cert the certificate to be added
* @param certPathList the certification path list
*/
@Override
void addCertToPath(X509Certificate cert,
LinkedList<X509Certificate> certPathList) {
LinkedList<X509Certificate> certPathList)
{
certPathList.addFirst(cert);
}
......@@ -917,6 +881,7 @@ class ForwardBuilder extends Builder {
*
* @param certPathList the certification path list
*/
@Override
void removeFinalCertFromPath(LinkedList<X509Certificate> certPathList) {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -34,7 +34,6 @@ import java.security.cert.X509Certificate;
import java.security.interfaces.DSAPublicKey;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import javax.security.auth.x500.X500Principal;
......@@ -76,9 +75,6 @@ class ForwardState implements State {
/* Flag indicating if state is initial (path is just starting) */
private boolean init = true;
/* the checker used for revocation status */
public CrlRevocationChecker crlChecker;
/* The list of user-defined checkers that support forward checking */
ArrayList<PKIXCertPathChecker> forwardCheckers;
......@@ -93,6 +89,7 @@ class ForwardState implements State {
*
* @return boolean flag indicating if the state is initial (just starting)
*/
@Override
public boolean isInitial() {
return init;
}
......@@ -104,6 +101,7 @@ class ForwardState implements State {
* @return boolean true if key needing to inherit parameters has been
* encountered; false otherwise.
*/
@Override
public boolean keyParamsNeeded() {
return keyParamsNeededFlag;
}
......@@ -111,23 +109,18 @@ class ForwardState implements State {
/**
* Display state for debugging purposes
*/
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
try {
sb.append("State [");
sb.append("\n issuerDN of last cert: " + issuerDN);
sb.append("\n traversedCACerts: " + traversedCACerts);
sb.append("\n init: " + String.valueOf(init));
sb.append("\n keyParamsNeeded: "
+ String.valueOf(keyParamsNeededFlag));
sb.append("\n subjectNamesTraversed: \n" + subjectNamesTraversed);
sb.append("]\n");
} catch (Exception e) {
if (debug != null) {
debug.println("ForwardState.toString() unexpected exception");
e.printStackTrace();
}
}
StringBuilder sb = new StringBuilder();
sb.append("State [");
sb.append("\n issuerDN of last cert: ").append(issuerDN);
sb.append("\n traversedCACerts: ").append(traversedCACerts);
sb.append("\n init: ").append(String.valueOf(init));
sb.append("\n keyParamsNeeded: ").append
(String.valueOf(keyParamsNeededFlag));
sb.append("\n subjectNamesTraversed: \n").append
(subjectNamesTraversed);
sb.append("]\n");
return sb.toString();
}
......@@ -147,12 +140,10 @@ class ForwardState implements State {
* that supports forward checking and initialize the forwardCheckers
*/
forwardCheckers = new ArrayList<PKIXCertPathChecker>();
if (certPathCheckers != null) {
for (PKIXCertPathChecker checker : certPathCheckers) {
if (checker.isForwardCheckingSupported()) {
checker.init(true);
forwardCheckers.add(checker);
}
for (PKIXCertPathChecker checker : certPathCheckers) {
if (checker.isForwardCheckingSupported()) {
checker.init(true);
forwardCheckers.add(checker);
}
}
......@@ -164,6 +155,7 @@ class ForwardState implements State {
*
* @param cert the certificate which is used to update the state
*/
@Override
public void updateState(X509Certificate cert)
throws CertificateException, IOException, CertPathValidatorException {
......@@ -208,13 +200,11 @@ class ForwardState implements State {
if (subjAltNameExt != null) {
GeneralNames gNames = subjAltNameExt.get(
SubjectAlternativeNameExtension.SUBJECT_NAME);
for (Iterator<GeneralName> t = gNames.iterator();
t.hasNext(); ) {
GeneralNameInterface gName = t.next().getName();
subjectNamesTraversed.add(gName);
for (GeneralName gName : gNames.names()) {
subjectNamesTraversed.add(gName.getName());
}
}
} catch (Exception e) {
} catch (IOException e) {
if (debug != null) {
debug.println("ForwardState.updateState() unexpected "
+ "exception");
......@@ -236,6 +226,7 @@ class ForwardState implements State {
* because some of them will
* not have their contents modified by subsequent calls to updateState.
*/
@Override
@SuppressWarnings("unchecked") // Safe casts assuming clone() works correctly
public Object clone() {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -180,7 +180,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
if (cert.equals(oldEntry)) {
return;
}
List<X509Certificate> list = new ArrayList<X509Certificate>(2);
List<X509Certificate> list = new ArrayList<>(2);
list.add(cert);
list.add((X509Certificate)oldEntry);
certSubjects.put(subject, list);
......@@ -206,7 +206,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
if (crl.equals(oldEntry)) {
return;
}
List<X509CRL> list = new ArrayList<X509CRL>(2);
List<X509CRL> list = new ArrayList<>(2);
list.add(crl);
list.add((X509CRL)oldEntry);
crlIssuers.put(issuer, list);
......@@ -234,19 +234,20 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
* match the specified selector
* @throws CertStoreException if an exception occurs
*/
@Override
public Collection<? extends Certificate> engineGetCertificates(CertSelector selector)
throws CertStoreException {
// no selector means match all
if (selector == null) {
Set<Certificate> matches = new HashSet<Certificate>();
Set<Certificate> matches = new HashSet<>();
matchX509Certs(new X509CertSelector(), matches);
matches.addAll(otherCertificates);
return matches;
}
if (selector instanceof X509CertSelector == false) {
Set<Certificate> matches = new HashSet<Certificate>();
Set<Certificate> matches = new HashSet<>();
matchX509Certs(selector, matches);
for (Certificate cert : otherCertificates) {
if (selector.match(cert)) {
......@@ -285,7 +286,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
// See certSubjects javadoc.
@SuppressWarnings("unchecked")
List<X509Certificate> list = (List<X509Certificate>)entry;
Set<X509Certificate> matches = new HashSet<X509Certificate>(16);
Set<X509Certificate> matches = new HashSet<>(16);
for (X509Certificate cert : list) {
if (x509Selector.match(cert)) {
matches.add(cert);
......@@ -295,7 +296,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
}
}
// cannot use index, iterate all
Set<Certificate> matches = new HashSet<Certificate>(16);
Set<Certificate> matches = new HashSet<>(16);
matchX509Certs(x509Selector, matches);
return matches;
}
......@@ -338,18 +339,19 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
* match the specified selector
* @throws CertStoreException if an exception occurs
*/
@Override
public Collection<CRL> engineGetCRLs(CRLSelector selector)
throws CertStoreException {
if (selector == null) {
Set<CRL> matches = new HashSet<CRL>();
Set<CRL> matches = new HashSet<>();
matchX509CRLs(new X509CRLSelector(), matches);
matches.addAll(otherCRLs);
return matches;
}
if (selector instanceof X509CRLSelector == false) {
Set<CRL> matches = new HashSet<CRL>();
Set<CRL> matches = new HashSet<>();
matchX509CRLs(selector, matches);
for (CRL crl : otherCRLs) {
if (selector.match(crl)) {
......@@ -366,7 +368,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
// see if the issuer is specified
Collection<X500Principal> issuers = x509Selector.getIssuers();
if (issuers != null) {
HashSet<CRL> matches = new HashSet<CRL>(16);
HashSet<CRL> matches = new HashSet<>(16);
for (X500Principal issuer : issuers) {
Object entry = crlIssuers.get(issuer);
if (entry == null) {
......@@ -390,7 +392,7 @@ public class IndexedCollectionCertStore extends CertStoreSpi {
return matches;
}
// cannot use index, iterate all
Set<CRL> matches = new HashSet<CRL>(16);
Set<CRL> matches = new HashSet<>(16);
matchX509CRLs(x509Selector, 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -30,7 +30,7 @@ import java.security.cert.*;
import java.security.cert.PKIXReason;
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
......@@ -45,33 +45,29 @@ import sun.security.x509.PKIXExtensions;
class KeyChecker extends PKIXCertPathChecker {
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 CertSelector targetConstraints;
private final CertSelector targetConstraints;
private int remainingCerts;
private Set<String> supportedExts;
/**
* Default Constructor
* Creates a KeyChecker.
*
* @param certPathLen allowable cert path length
* @param targetCertSel a CertSelector object specifying the constraints
* on the target certificate
*/
KeyChecker(int certPathLen, CertSelector targetCertSel)
throws CertPathValidatorException
{
KeyChecker(int certPathLen, CertSelector targetCertSel) {
this.certPathLen = certPathLen;
this.targetConstraints = targetCertSel;
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 = certPathLen;
......@@ -81,16 +77,18 @@ class KeyChecker extends PKIXCertPathChecker {
}
}
public final boolean isForwardCheckingSupported() {
@Override
public boolean isForwardCheckingSupported() {
return false;
}
@Override
public Set<String> getSupportedExtensions() {
if (supportedExts == null) {
supportedExts = new HashSet<String>();
supportedExts.add(PKIXExtensions.KeyUsage_Id.toString());
supportedExts.add(PKIXExtensions.ExtendedKeyUsage_Id.toString());
supportedExts.add(PKIXExtensions.SubjectAlternativeName_Id.toString());
supportedExts = new HashSet<String>(3);
supportedExts.add(KeyUsage_Id.toString());
supportedExts.add(ExtendedKeyUsage_Id.toString());
supportedExts.add(SubjectAlternativeName_Id.toString());
supportedExts = Collections.unmodifiableSet(supportedExts);
}
return supportedExts;
......@@ -102,20 +100,20 @@ class KeyChecker extends PKIXCertPathChecker {
*
* @param cert the Certificate
* @param unresolvedCritExts the unresolved critical extensions
* @exception CertPathValidatorException Exception thrown if certificate
* does not verify
* @throws CertPathValidatorException if certificate does not verify
*/
@Override
public void check(Certificate cert, Collection<String> unresCritExts)
throws CertPathValidatorException
{
X509Certificate currCert = (X509Certificate) cert;
X509Certificate currCert = (X509Certificate)cert;
remainingCerts--;
// if final certificate, check that target constraints are satisfied
if (remainingCerts == 0) {
if ((targetConstraints != null) &&
(targetConstraints.match(currCert) == false)) {
if (targetConstraints != null &&
targetConstraints.match(currCert) == false) {
throw new CertPathValidatorException("target certificate " +
"constraints check failed");
}
......@@ -126,25 +124,26 @@ class KeyChecker extends PKIXCertPathChecker {
// remove the extensions that we have checked
if (unresCritExts != null && !unresCritExts.isEmpty()) {
unresCritExts.remove(PKIXExtensions.KeyUsage_Id.toString());
unresCritExts.remove(PKIXExtensions.ExtendedKeyUsage_Id.toString());
unresCritExts.remove(
PKIXExtensions.SubjectAlternativeName_Id.toString());
unresCritExts.remove(KeyUsage_Id.toString());
unresCritExts.remove(ExtendedKeyUsage_Id.toString());
unresCritExts.remove(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
* extension in a CA cert. The key usage extension, if present, must
* assert the keyCertSign bit. The extended key usage extension, if
* present, must include anyExtendedKeyUsage.
* Verifies the key usage extension in a CA cert.
* The key usage extension, if present, must assert the keyCertSign bit.
* The extended key usage extension is not checked (see CR 4776794 for
* more information).
*/
static void verifyCAKeyUsage(X509Certificate cert)
throws CertPathValidatorException {
String msg = "CA key usage";
if (debug != null) {
debug.println("KeyChecker.verifyCAKeyUsage() ---checking " + msg
+ "...");
+ "...");
}
boolean[] keyUsageBits = cert.getKeyUsage();
......@@ -156,7 +155,7 @@ class KeyChecker extends PKIXCertPathChecker {
}
// throw an exception if the keyCertSign bit is not set
if (!keyUsageBits[keyCertSign]) {
if (!keyUsageBits[KEY_CERT_SIGN]) {
throw new CertPathValidatorException
(msg + " check failed: keyCertSign bit is not set", null,
null, -1, PKIXReason.INVALID_KEY_USAGE);
......@@ -164,7 +163,7 @@ class KeyChecker extends PKIXCertPathChecker {
if (debug != null) {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -43,6 +43,7 @@ import java.util.Map;
import static sun.security.provider.certpath.OCSPResponse.*;
import sun.security.util.Debug;
import sun.security.util.ObjectIdentifier;
import sun.security.x509.AccessDescription;
import sun.security.x509.AuthorityInfoAccessExtension;
import sun.security.x509.GeneralName;
......@@ -62,6 +63,9 @@ import sun.security.x509.X509CertImpl;
*/
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 int CONNECT_TIMEOUT = 15000; // 15 seconds
......@@ -83,7 +87,7 @@ public final class OCSP {
* encoding the OCSP Request or validating the OCSP Response
*/
public static RevocationStatus check(X509Certificate cert,
X509Certificate issuerCert)
X509Certificate issuerCert)
throws IOException, CertPathValidatorException {
CertId certId = null;
URI responderURI = null;
......@@ -95,16 +99,13 @@ public final class OCSP {
("No OCSP Responder URI in certificate");
}
certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
} catch (CertificateException ce) {
throw new CertPathValidatorException
("Exception while encoding OCSPRequest", ce);
} catch (IOException ioe) {
} catch (CertificateException | IOException e) {
throw new CertPathValidatorException
("Exception while encoding OCSPRequest", ioe);
("Exception while encoding OCSPRequest", e);
}
OCSPResponse ocspResponse = check(Collections.singletonList(certId),
responderURI, issuerCert, null);
return (RevocationStatus) ocspResponse.getSingleResponse(certId);
responderURI, issuerCert, null, Collections.<Extension>emptyList());
return (RevocationStatus)ocspResponse.getSingleResponse(certId);
}
/**
......@@ -123,22 +124,34 @@ public final class OCSP {
* encoding the OCSP Request or validating the OCSP Response
*/
public static RevocationStatus check(X509Certificate cert,
X509Certificate issuerCert, URI responderURI, X509Certificate
responderCert, Date date)
throws IOException, CertPathValidatorException {
X509Certificate issuerCert,
URI responderURI,
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;
try {
X509CertImpl certImpl = X509CertImpl.toImpl(cert);
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
("Exception while encoding OCSPRequest", ioe);
("Exception while encoding OCSPRequest", e);
}
OCSPResponse ocspResponse = check(Collections.singletonList(certId),
responderURI, responderCert, date);
responderURI, responderCert, date, extensions);
return (RevocationStatus) ocspResponse.getSingleResponse(certId);
}
......@@ -157,12 +170,14 @@ public final class OCSP {
* encoding the OCSP Request or validating the OCSP Response
*/
static OCSPResponse check(List<CertId> certIds, URI responderURI,
X509Certificate responderCert, Date date)
throws IOException, CertPathValidatorException {
X509Certificate responderCert, Date date,
List<Extension> extensions)
throws IOException, CertPathValidatorException
{
byte[] bytes = null;
OCSPRequest request = null;
try {
OCSPRequest request = new OCSPRequest(certIds);
request = new OCSPRequest(certIds, extensions);
bytes = request.encodeBytes();
} catch (IOException ioe) {
throw new CertPathValidatorException
......@@ -214,6 +229,8 @@ public final class OCSP {
}
}
response = Arrays.copyOf(response, total);
} catch (IOException ioe) {
throw new NetworkFailureException(ioe);
} finally {
if (in != null) {
try {
......@@ -233,33 +250,15 @@ public final class OCSP {
OCSPResponse ocspResponse = null;
try {
ocspResponse = new OCSPResponse(response, date, responderCert);
ocspResponse = new OCSPResponse(response);
} catch (IOException ioe) {
// response decoding exception
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
// certs that were supplied in the request
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());
}
}
// verify the response
ocspResponse.verify(certIds, responderCert, date, request.getNonce());
return ocspResponse;
}
......@@ -271,6 +270,7 @@ public final class OCSP {
* @param cert the certificate
* @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) {
try {
return getResponderURI(X509CertImpl.toImpl(cert));
......@@ -330,4 +330,12 @@ public final class OCSP {
*/
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -26,8 +26,10 @@
package sun.security.provider.certpath;
import java.io.IOException;
import java.security.cert.Extension;
import java.util.Collections;
import java.util.List;
import sun.misc.HexDumpEncoder;
import sun.security.util.*;
......@@ -74,22 +76,29 @@ import sun.security.util.*;
class OCSPRequest {
private static final Debug debug = Debug.getInstance("certpath");
private static final boolean dump = false;
// List of request CertIds
private final List<CertId> certIds;
private final List<Extension> extensions;
private byte[] nonce;
/*
* Constructs an OCSPRequest. This constructor is used
* to construct an unsigned OCSP Request for a single user cert.
*/
OCSPRequest(CertId certId) {
this.certIds = Collections.singletonList(certId);
this(Collections.singletonList(certId));
}
OCSPRequest(List<CertId> 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 {
......@@ -104,7 +113,20 @@ class OCSPRequest {
}
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();
tbsRequest.write(DerValue.tag_Sequence, tmp);
......@@ -126,4 +148,8 @@ class OCSPRequest {
List<CertId> getCertIds() {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,55 +25,38 @@
package sun.security.provider.certpath;
import java.security.AccessController;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.cert.CertPath;
import java.security.cert.CertPathParameters;
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 java.security.cert.*;
import java.util.*;
import sun.security.provider.certpath.PKIX.ValidatorParams;
import sun.security.x509.X509CertImpl;
import sun.security.util.Debug;
/**
* This class implements the PKIX validation algorithm for certification
* paths consisting exclusively of <code>X509Certificates</code>. It uses
* 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
* @author Yassir Elley
*/
public class PKIXCertPathValidator extends CertPathValidatorSpi {
public final class PKIXCertPathValidator extends CertPathValidatorSpi {
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.
*/
public PKIXCertPathValidator() {}
@Override
public CertPathChecker engineGetRevocationChecker() {
return new RevocationChecker();
}
/**
* Validates a certification path consisting exclusively of
* <code>X509Certificate</code>s using the PKIX validation algorithm,
......@@ -81,98 +64,70 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
* The input parameter set must be a <code>PKIXParameters</code> object.
*
* @param cp the X509 certification path
* @param param the input PKIX parameter set
* @param params the input PKIX parameter set
* @return the result
* @exception CertPathValidatorException Exception thrown if cert path
* does not validate.
* @exception InvalidAlgorithmParameterException if the specified
* parameters are inappropriate for this certification path validator
* @throws CertPathValidatorException if cert path does not validate.
* @throws InvalidAlgorithmParameterException if the specified
* parameters are inappropriate for this CertPathValidator
*/
@Override
public CertPathValidatorResult engineValidate(CertPath cp,
CertPathParameters param)
CertPathParameters params)
throws CertPathValidatorException, InvalidAlgorithmParameterException
{
ValidatorParams valParams = PKIX.checkParams(cp, params);
return validate(valParams);
}
private static PKIXCertPathValidatorResult validate(ValidatorParams params)
throws CertPathValidatorException
{
if (debug != null)
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
// (to be used later in pre-screening)
X509Certificate firstCert = null;
AdaptableX509CertSelector selector = null;
List<X509Certificate> certList = params.certificates();
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;
// We iterate through the set of trust anchors until we find
// one that works at which time we stop iterating
for (TrustAnchor anchor : anchors) {
for (TrustAnchor anchor : params.trustAnchors()) {
X509Certificate trustedCert = anchor.getTrustedCert();
if (trustedCert != null) {
if (debug != null) {
debug.println("PKIXCertPathValidator.engineValidate() "
+ "anchor.getTrustedCert() != null");
}
// if this trust anchor is not worth trying,
// 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;
}
if (debug != null) {
debug.println("YES - try this trustedCert");
debug.println("anchor.getTrustedCert()."
+ "getSubjectX500Principal() = "
+ trustedCert.getSubjectX500Principal());
......@@ -185,14 +140,7 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
}
try {
PolicyNodeImpl rootNode = new PolicyNodeImpl(null,
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());
return validate(anchor, params);
} catch (CertPathValidatorException cpe) {
// remember this exception
lastException = cpe;
......@@ -210,144 +158,59 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
null, null, -1, PKIXReason.NO_TRUST_ANCHOR);
}
/**
* Internal method to do some simple checks to see if a given cert is
* worth trying to validate in the chain.
*/
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)
private static PKIXCertPathValidatorResult validate(TrustAnchor anchor,
ValidatorParams params)
throws CertPathValidatorException
{
// default value for testDate is current time
testDate = pkixParam.getDate();
if (testDate == null) {
testDate = new Date(System.currentTimeMillis());
}
userCheckers = pkixParam.getCertPathCheckers();
sigProvider = pkixParam.getSigProvider();
int certPathLen = params.certificates().size();
if (pkixParam.isRevocationEnabled()) {
// Examine OCSP security property
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>();
// create PKIXCertPathCheckers
List<PKIXCertPathChecker> certPathCheckers = new ArrayList<>();
// add standard checkers that we will be using
certPathCheckers.add(algorithmChecker);
certPathCheckers.add(keyChecker);
certPathCheckers.add(constraintsChecker);
certPathCheckers.add(policyChecker);
certPathCheckers.add(basicChecker);
// only add a revocationChecker if revocation is enabled
if (pkixParam.isRevocationEnabled()) {
// Use OCSP if it has been enabled
if (ocspEnabled) {
OCSPChecker ocspChecker =
new OCSPChecker(cpOriginal, pkixParam, onlyEECert);
certPathCheckers.add(ocspChecker);
certPathCheckers.add(new AlgorithmChecker(anchor));
certPathCheckers.add(new KeyChecker(certPathLen,
params.targetCertConstraints()));
certPathCheckers.add(new ConstraintsChecker(certPathLen));
PolicyNodeImpl rootNode =
new PolicyNodeImpl(null, PolicyChecker.ANY_POLICY, null, false,
Collections.singleton(PolicyChecker.ANY_POLICY),
false);
PolicyChecker pc = new PolicyChecker(params.initialPolicies(),
certPathLen,
params.explicitPolicyRequired(),
params.policyMappingInhibited(),
params.anyPolicyInhibited(),
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
certPathCheckers.addAll(userCheckers);
PKIXMasterCertPathValidator masterValidator =
new PKIXMasterCertPathValidator(certPathCheckers);
certPathCheckers.addAll(checkers);
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -30,10 +30,8 @@ import sun.security.util.Debug;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.security.cert.CertificateRevokedException;
import java.security.cert.CertPath;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.PKIXCertPathChecker;
import java.security.cert.PKIXReason;
import java.security.cert.X509Certificate;
......@@ -49,32 +47,22 @@ import java.security.cert.X509Certificate;
class PKIXMasterCertPathValidator {
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
* <code>X509Certificate</code>s using the
* <code>PKIXCertPathChecker</code>s specified
* in the constructor. It is assumed that the
* <code>X509Certificate</code>s using the specified
* <code>PKIXCertPathChecker</code>s. It is assumed that the
* <code>PKIXCertPathChecker</code>s
* have been initialized with any input parameters they may need.
*
* @param cpOriginal the original X509 CertPath passed in by the user
* @param reversedCertList the reversed X509 CertPath (as a List)
* @exception CertPathValidatorException Exception thrown if cert
* path does not validate.
* @param certPathCheckers the PKIXCertPathCheckers
* @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
{
// we actually process reversedCertList, but we keep cpOriginal because
......@@ -104,20 +92,18 @@ class PKIXMasterCertPathValidator {
debug.println("Checking cert" + (i+1) + " ...");
X509Certificate currCert = reversedCertList.get(i);
Set<String> unresolvedCritExts =
currCert.getCriticalExtensionOIDs();
if (unresolvedCritExts == null) {
unresolvedCritExts = Collections.<String>emptySet();
Set<String> unresCritExts = currCert.getCriticalExtensionOIDs();
if (unresCritExts == null) {
unresCritExts = Collections.<String>emptySet();
}
if (debug != null && !unresolvedCritExts.isEmpty()) {
if (debug != null && !unresCritExts.isEmpty()) {
debug.println("Set of critical extensions:");
for (String oid : unresolvedCritExts) {
for (String oid : unresCritExts) {
debug.println(oid);
}
}
CertPathValidatorException ocspCause = null;
for (int j = 0; j < certPathCheckers.size(); j++) {
PKIXCertPathChecker currChecker = certPathCheckers.get(j);
......@@ -130,65 +116,21 @@ class PKIXMasterCertPathValidator {
currChecker.init(false);
try {
currChecker.check(currCert, unresolvedCritExts);
// 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;
currChecker.check(currCert, unresCritExts);
// Otherwise, failover to CRLs
if (debug != null) {
debug.println(cpve.getMessage());
debug.println(
"preparing to failover (from OCSP to CRLs)");
debug.println("-checker" + (j + 1) +
" validation succeeded");
}
}
if (debug != null)
debug.println("-checker" + (j+1) + " validation succeeded");
} catch (CertPathValidatorException cpve) {
throw new CertPathValidatorException(cpve.getMessage(),
cpve.getCause(), cpOriginal, cpSize - (i + 1),
cpve.getReason());
}
}
if (debug != null)
debug.println("checking for unresolvedCritExts");
if (!unresolvedCritExts.isEmpty()) {
if (!unresCritExts.isEmpty()) {
throw new CertPathValidatorException("unrecognized " +
"critical extension(s)", null, cpOriginal, cpSize-(i+1),
PKIXReason.UNRECOGNIZED_CRIT_EXT);
......@@ -200,26 +142,9 @@ class PKIXMasterCertPathValidator {
if (debug != null) {
debug.println("Cert path validation succeeded. (PKIX validation "
+ "algorithm)");
+ "algorithm)");
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,9 +25,8 @@
package sun.security.provider.certpath;
import java.util.*;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException;
......@@ -36,13 +35,14 @@ import java.security.cert.PKIXReason;
import java.security.cert.PolicyNode;
import java.security.cert.PolicyQualifierInfo;
import java.security.cert.X509Certificate;
import java.util.*;
import sun.security.util.Debug;
import sun.security.x509.CertificatePoliciesExtension;
import sun.security.x509.PolicyConstraintsExtension;
import sun.security.x509.PolicyMappingsExtension;
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.X509CertImpl;
import sun.security.x509.InhibitAnyPolicyExtension;
......@@ -88,7 +88,7 @@ class PolicyChecker extends PKIXCertPathChecker {
PolicyChecker(Set<String> initialPolicies, int certPathLen,
boolean expPolicyRequired, boolean polMappingInhibited,
boolean anyPolicyInhibited, boolean rejectPolicyQualifiers,
PolicyNodeImpl rootNode) throws CertPathValidatorException
PolicyNodeImpl rootNode)
{
if (initialPolicies.isEmpty()) {
// if no initialPolicies are specified by user, set
......@@ -104,18 +104,18 @@ class PolicyChecker extends PKIXCertPathChecker {
this.anyPolicyInhibited = anyPolicyInhibited;
this.rejectPolicyQualifiers = rejectPolicyQualifiers;
this.rootNode = rootNode;
init(false);
}
/**
* Initializes the internal state of the checker from parameters
* specified in the constructor
*
* @param forward a boolean indicating whether this checker should
* be initialized capable of building in the forward direction
* @exception CertPathValidatorException Exception thrown if user
* wants to enable forward checking and forward checking is not supported.
* @param forward a boolean indicating whether this checker should be
* initialized capable of building in the forward direction
* @throws CertPathValidatorException if user wants to enable forward
* checking and forward checking is not supported.
*/
@Override
public void init(boolean forward) throws CertPathValidatorException {
if (forward) {
throw new CertPathValidatorException
......@@ -136,6 +136,7 @@ class PolicyChecker extends PKIXCertPathChecker {
*
* @return true if forward checking is supported, false otherwise
*/
@Override
public boolean isForwardCheckingSupported() {
return false;
}
......@@ -150,13 +151,14 @@ class PolicyChecker extends PKIXCertPathChecker {
* @return the Set of extensions supported by this PKIXCertPathChecker,
* or null if no extensions are supported
*/
@Override
public Set<String> getSupportedExtensions() {
if (supportedExts == null) {
supportedExts = new HashSet<String>();
supportedExts.add(PKIXExtensions.CertificatePolicies_Id.toString());
supportedExts.add(PKIXExtensions.PolicyMappings_Id.toString());
supportedExts.add(PKIXExtensions.PolicyConstraints_Id.toString());
supportedExts.add(PKIXExtensions.InhibitAnyPolicy_Id.toString());
supportedExts = new HashSet<String>(4);
supportedExts.add(CertificatePolicies_Id.toString());
supportedExts.add(PolicyMappings_Id.toString());
supportedExts.add(PolicyConstraints_Id.toString());
supportedExts.add(InhibitAnyPolicy_Id.toString());
supportedExts = Collections.unmodifiableSet(supportedExts);
}
return supportedExts;
......@@ -168,9 +170,9 @@ class PolicyChecker extends PKIXCertPathChecker {
*
* @param cert the Certificate to be processed
* @param unresCritExts the unresolved critical extensions
* @exception CertPathValidatorException Exception thrown if
* the certificate does not verify.
* @throws CertPathValidatorException if the certificate does not verify
*/
@Override
public void check(Certificate cert, Collection<String> unresCritExts)
throws CertPathValidatorException
{
......@@ -178,10 +180,10 @@ class PolicyChecker extends PKIXCertPathChecker {
checkPolicy((X509Certificate) cert);
if (unresCritExts != null && !unresCritExts.isEmpty()) {
unresCritExts.remove(PKIXExtensions.CertificatePolicies_Id.toString());
unresCritExts.remove(PKIXExtensions.PolicyMappings_Id.toString());
unresCritExts.remove(PKIXExtensions.PolicyConstraints_Id.toString());
unresCritExts.remove(PKIXExtensions.InhibitAnyPolicy_Id.toString());
unresCritExts.remove(CertificatePolicies_Id.toString());
unresCritExts.remove(PolicyMappings_Id.toString());
unresCritExts.remove(PolicyConstraints_Id.toString());
unresCritExts.remove(InhibitAnyPolicy_Id.toString());
}
}
......@@ -290,7 +292,7 @@ class PolicyChecker extends PKIXCertPathChecker {
if (require == 0)
explicitPolicy = require;
}
} catch (Exception e) {
} catch (IOException e) {
if (debug != null) {
debug.println("PolicyChecker.mergeExplicitPolicy "
+ "unexpected exception");
......@@ -339,7 +341,7 @@ class PolicyChecker extends PKIXCertPathChecker {
policyMapping = inhibit;
}
}
} catch (Exception e) {
} catch (IOException e) {
if (debug != null) {
debug.println("PolicyChecker.mergePolicyMapping "
+ "unexpected exception");
......@@ -372,7 +374,7 @@ class PolicyChecker extends PKIXCertPathChecker {
try {
InhibitAnyPolicyExtension inhAnyPolExt = (InhibitAnyPolicyExtension)
currCert.getExtension(PKIXExtensions.InhibitAnyPolicy_Id);
currCert.getExtension(InhibitAnyPolicy_Id);
if (inhAnyPolExt == null)
return inhibitAnyPolicy;
......@@ -387,7 +389,7 @@ class PolicyChecker extends PKIXCertPathChecker {
inhibitAnyPolicy = skipCerts;
}
}
} catch (Exception e) {
} catch (IOException e) {
if (debug != null) {
debug.println("PolicyChecker.mergeInhibitAnyPolicy "
+ "unexpected exception");
......@@ -429,7 +431,7 @@ class PolicyChecker extends PKIXCertPathChecker {
boolean policiesCritical = false;
List<PolicyInformation> policyInfo;
PolicyNodeImpl rootNode = null;
Set<PolicyQualifierInfo> anyQuals = new HashSet<PolicyQualifierInfo>();
Set<PolicyQualifierInfo> anyQuals = new HashSet<>();
if (origRootNode == null)
rootNode = null;
......@@ -600,7 +602,7 @@ class PolicyChecker extends PKIXCertPathChecker {
PolicyNodeImpl parentNode = (PolicyNodeImpl)anyNode.getParent();
parentNode.deleteChild(anyNode);
// 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)) {
initial.remove(node.getValidPolicy());
}
......@@ -697,7 +699,7 @@ class PolicyChecker extends PKIXCertPathChecker {
}
}
Set<String> expPols = new HashSet<String>();
Set<String> expPols = new HashSet<>();
expPols.add(curParExpPol);
curNode = new PolicyNodeImpl
......@@ -762,8 +764,7 @@ class PolicyChecker extends PKIXCertPathChecker {
}
boolean childDeleted = false;
for (int j = 0; j < maps.size(); j++) {
CertificatePolicyMap polMap = maps.get(j);
for (CertificatePolicyMap polMap : maps) {
String issuerDomain
= polMap.getIssuerIdentifier().getIdentifier().toString();
String subjectDomain
......@@ -816,7 +817,7 @@ class PolicyChecker extends PKIXCertPathChecker {
PolicyNodeImpl curAnyNodeParent =
(PolicyNodeImpl) curAnyNode.getParent();
Set<String> expPols = new HashSet<String>();
Set<String> expPols = new HashSet<>();
expPols.add(subjectDomain);
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -134,30 +134,37 @@ final class PolicyNodeImpl implements PolicyNode {
node.mCriticalityIndicator, node.mExpectedPolicySet, false);
}
@Override
public PolicyNode getParent() {
return mParent;
}
@Override
public Iterator<PolicyNodeImpl> getChildren() {
return Collections.unmodifiableSet(mChildren).iterator();
}
@Override
public int getDepth() {
return mDepth;
}
@Override
public String getValidPolicy() {
return mValidPolicy;
}
@Override
public Set<PolicyQualifierInfo> getPolicyQualifiers() {
return Collections.unmodifiableSet(mQualifierSet);
}
@Override
public Set<String> getExpectedPolicies() {
return Collections.unmodifiableSet(mExpectedPolicySet);
}
@Override
public boolean isCritical() {
return mCriticalityIndicator;
}
......@@ -169,12 +176,12 @@ final class PolicyNodeImpl implements PolicyNode {
*
* @return a String describing the contents of the Policy Node
*/
@Override
public String toString() {
StringBuffer buffer = new StringBuffer(this.asString());
StringBuilder buffer = new StringBuilder(this.asString());
Iterator<PolicyNodeImpl> it = getChildren();
while (it.hasNext()) {
buffer.append(it.next());
for (PolicyNodeImpl node : mChildren) {
buffer.append(node);
}
return buffer.toString();
}
......@@ -293,7 +300,7 @@ final class PolicyNodeImpl implements PolicyNode {
* @return a <code>Set</code> of all nodes at the specified depth
*/
Set<PolicyNodeImpl> getPolicyNodes(int depth) {
Set<PolicyNodeImpl> set = new HashSet<PolicyNodeImpl>();
Set<PolicyNodeImpl> set = new HashSet<>();
getPolicyNodes(depth, set);
return set;
}
......@@ -337,7 +344,7 @@ final class PolicyNodeImpl implements PolicyNode {
private Set<PolicyNodeImpl> getPolicyNodesExpectedHelper(int depth,
String expectedOID, boolean matchAny) {
HashSet<PolicyNodeImpl> set = new HashSet<PolicyNodeImpl>();
HashSet<PolicyNodeImpl> set = new HashSet<>();
if (mDepth < depth) {
for (PolicyNodeImpl node : mChildren) {
......@@ -367,7 +374,7 @@ final class PolicyNodeImpl implements PolicyNode {
* @return a Set of matched <code>PolicyNode</code>s
*/
Set<PolicyNodeImpl> getPolicyNodesValid(int depth, String validOID) {
HashSet<PolicyNodeImpl> set = new HashSet<PolicyNodeImpl>();
HashSet<PolicyNodeImpl> set = new HashSet<>();
if (mDepth < depth) {
for (PolicyNodeImpl node : mChildren) {
......@@ -396,7 +403,7 @@ final class PolicyNodeImpl implements PolicyNode {
if (mParent == null) {
return "anyPolicy ROOT\n";
} else {
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder();
for (int i = 0, n = getDepth(); i < n; i++) {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,12 +25,11 @@
package sun.security.provider.certpath;
import java.util.Set;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.*;
import java.util.Set;
/**
* This class specifies the set of parameters used as input for the Sun
......@@ -120,8 +119,9 @@ public class SunCertPathBuilderParameters extends PKIXBuilderParameters {
*
* @return a formatted string describing the parameters.
*/
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder();
sb.append("[\n");
sb.append(super.toString());
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -213,6 +213,7 @@ class URICertStore extends CertStoreSpi {
* match the specified selector
* @throws CertStoreException if an exception occurs
*/
@Override
@SuppressWarnings("unchecked")
public synchronized Collection<X509Certificate> engineGetCertificates
(CertSelector selector) throws CertStoreException {
......@@ -322,6 +323,7 @@ class URICertStore extends CertStoreSpi {
* match the specified selector
* @throws CertStoreException if an exception occurs
*/
@Override
@SuppressWarnings("unchecked")
public synchronized Collection<X509CRL> engineGetCRLs(CRLSelector selector)
throws CertStoreException {
......@@ -418,14 +420,14 @@ class URICertStore extends CertStoreSpi {
URICertStoreParameters(URI uri) {
this.uri = uri;
}
public boolean equals(Object obj) {
@Override public boolean equals(Object obj) {
if (!(obj instanceof URICertStoreParameters)) {
return false;
}
URICertStoreParameters params = (URICertStoreParameters) obj;
return uri.equals(params.uri);
}
public int hashCode() {
@Override public int hashCode() {
if (hashCode == 0) {
int result = 17;
result = 37*result + uri.hashCode();
......@@ -433,7 +435,7 @@ class URICertStore extends CertStoreSpi {
}
return hashCode;
}
public Object clone() {
@Override public Object clone() {
try {
return super.clone();
} 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -33,9 +33,10 @@ import java.security.cert.CertificateEncodingException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
import java.util.*;
import java.security.cert.CertPath;
import sun.security.pkcs.ContentInfo;
import sun.security.pkcs.PKCS7;
import sun.security.pkcs.SignerInfo;
......@@ -44,7 +45,6 @@ import sun.security.util.DerValue;
import sun.security.util.DerOutputStream;
import sun.security.util.DerInputStream;
/**
* A {@link java.security.cert.CertPath CertPath} (certification path)
* consisting exclusively of
......@@ -83,7 +83,7 @@ public class X509CertPath extends CertPath {
private static final Collection<String> encodingList;
static {
List<String> list = new ArrayList<String>(2);
List<String> list = new ArrayList<>(2);
list.add(PKIPATH_ENCODING);
list.add(PKCS7_ENCODING);
encodingList = Collections.unmodifiableCollection(list);
......@@ -272,6 +272,7 @@ public class X509CertPath extends CertPath {
* @return the encoded bytes
* @exception CertificateEncodingException if an encoding error occurs
*/
@Override
public byte[] getEncoded() throws CertificateEncodingException {
// @@@ Should cache the encoded form
return encodePKIPATH();
......@@ -342,6 +343,7 @@ public class X509CertPath extends CertPath {
* @exception CertificateEncodingException if an encoding error occurs or
* the encoding requested is not supported
*/
@Override
public byte[] getEncoded(String encoding)
throws CertificateEncodingException {
switch (encoding) {
......@@ -376,6 +378,7 @@ public class X509CertPath extends CertPath {
* @return an <code>Iterator</code> over the names of the supported
* encodings (as Strings)
*/
@Override
public Iterator<String> getEncodings() {
return getEncodingsStatic();
}
......@@ -387,6 +390,7 @@ public class X509CertPath extends CertPath {
* @return an immutable <code>List</code> of <code>X509Certificate</code>s
* (may be empty, but not null)
*/
@Override
public List<X509Certificate> getCertificates() {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -207,13 +207,14 @@ public class X509CertificatePair {
*
* @return A String describing the contents of the pair.
*/
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder();
sb.append("X.509 Certificate Pair: [\n");
if (forward != null)
sb.append(" Forward: " + forward + "\n");
sb.append(" Forward: ").append(forward).append("\n");
if (reverse != null)
sb.append(" Reverse: " + reverse + "\n");
sb.append(" Reverse: ").append(reverse).append("\n");
sb.append("]");
return sb.toString();
}
......
......@@ -31,6 +31,7 @@ import java.security.cert.CRLReason;
import java.security.cert.X509CRLEntry;
import java.math.BigInteger;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
......@@ -500,6 +501,9 @@ public class X509CRLEntryImpl extends X509CRLEntry {
}
public Map<String, java.security.cert.Extension> getExtensions() {
if (extensions == null) {
return Collections.emptyMap();
}
Collection<Extension> exts = extensions.getAllExtensions();
HashMap<String, java.security.cert.Extension> map =
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.
先完成此消息的编辑!
想要评论请 注册