|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
package sun.security.provider.certpath; |
|
|
|
import java.security.InvalidAlgorithmParameterException; |
|
import java.security.PublicKey; |
|
import java.security.Timestamp; |
|
import java.security.cert.*; |
|
import java.security.interfaces.DSAPublicKey; |
|
import java.util.*; |
|
import javax.security.auth.x500.X500Principal; |
|
|
|
import sun.security.util.Debug; |
|
import sun.security.validator.Validator; |
|
|
|
|
|
|
|
|
|
*/ |
|
class PKIX { |
|
|
|
private static final Debug debug = Debug.getInstance("certpath"); |
|
|
|
private PKIX() { } |
|
|
|
static boolean isDSAPublicKeyWithoutParams(PublicKey publicKey) { |
|
return (publicKey instanceof DSAPublicKey && |
|
((DSAPublicKey)publicKey).getParams() == null); |
|
} |
|
|
|
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); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
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; |
|
private Timestamp timestamp; |
|
private String variant = Validator.VAR_GENERIC; |
|
|
|
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 |
|
{ |
|
if (params instanceof PKIXExtendedParameters) { |
|
timestamp = ((PKIXExtendedParameters) params).getTimestamp(); |
|
variant = ((PKIXExtendedParameters) params).getVariant(); |
|
} |
|
|
|
this.anchors = params.getTrustAnchors(); |
|
// Make sure that none of the trust anchors include name constraints |
|
|
|
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; |
|
} |
|
|
|
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 |
|
|
|
@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) { |
|
// use timestamp if checking signed code that is |
|
|
|
if (timestamp != null && |
|
(variant.equals(Validator.VAR_CODE_SIGNING) || |
|
variant.equals(Validator.VAR_PLUGIN_CODE_SIGNING))) { |
|
date = timestamp.getTimestamp(); |
|
} else { |
|
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 |
|
|
|
PKIXParameters getPKIXParameters() { |
|
return params; |
|
} |
|
|
|
String variant() { |
|
return variant; |
|
} |
|
} |
|
|
|
static class BuilderParams extends ValidatorParams { |
|
private PKIXBuilderParameters params; |
|
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"); |
|
} |
|
this.params = params; |
|
this.targetSubject = getTargetSubject( |
|
certStores(), (X509CertSelector)targetCertConstraints()); |
|
} |
|
@Override List<CertStore> certStores() { |
|
if (stores == null) { |
|
|
|
stores = new ArrayList<>(params.getCertStores()); |
|
Collections.sort(stores, new CertStoreComparator()); |
|
} |
|
return stores; |
|
} |
|
int maxPathLength() { return params.getMaxPathLength(); } |
|
PKIXBuilderParameters params() { return params; } |
|
X500Principal targetSubject() { return targetSubject; } |
|
|
|
|
|
|
|
|
|
*/ |
|
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) { |
|
|
|
if (debug != null) { |
|
debug.println("BuilderParams.getTargetSubjectDN: " + |
|
"non-fatal exception retrieving certs: " + e); |
|
e.printStackTrace(); |
|
} |
|
} |
|
} |
|
throw new InvalidAlgorithmParameterException |
|
("Could not determine unique target subject"); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
static class CertStoreTypeException extends CertStoreException { |
|
private static final long serialVersionUID = 7463352639238322556L; |
|
|
|
private final String type; |
|
|
|
CertStoreTypeException(String type, CertStoreException cse) { |
|
super(cse.getMessage(), cse.getCause()); |
|
this.type = type; |
|
} |
|
String getType() { |
|
return type; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
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; |
|
} |
|
} |
|
} |
|
} |