blob: a21ad1c489fcac5cda483dd52e4f0b3545b20045 [file] [log] [blame]
package org.bouncycastle.cert.path.validations;
import java.io.IOException;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Null;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.CertException;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509ContentVerifierProviderBuilder;
import org.bouncycastle.cert.path.CertPathValidation;
import org.bouncycastle.cert.path.CertPathValidationContext;
import org.bouncycastle.cert.path.CertPathValidationException;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.util.Memoable;
public class ParentCertIssuedValidation
implements CertPathValidation
{
private X509ContentVerifierProviderBuilder contentVerifierProvider;
private X500Name workingIssuerName;
private SubjectPublicKeyInfo workingPublicKey;
private AlgorithmIdentifier workingAlgId;
public ParentCertIssuedValidation(X509ContentVerifierProviderBuilder contentVerifierProvider)
{
this.contentVerifierProvider = contentVerifierProvider;
}
public void validate(CertPathValidationContext context, X509CertificateHolder certificate)
throws CertPathValidationException
{
if (workingIssuerName != null)
{
if (!workingIssuerName.equals(certificate.getIssuer()))
{
throw new CertPathValidationException("Certificate issue does not match parent");
}
}
if (workingPublicKey != null)
{
try
{
SubjectPublicKeyInfo validatingKeyInfo;
if (workingPublicKey.getAlgorithm().equals(workingAlgId))
{
validatingKeyInfo = workingPublicKey;
}
else
{
validatingKeyInfo = new SubjectPublicKeyInfo(workingAlgId, workingPublicKey.parsePublicKey());
}
if (!certificate.isSignatureValid(contentVerifierProvider.build(validatingKeyInfo)))
{
throw new CertPathValidationException("Certificate signature not for public key in parent");
}
}
catch (OperatorCreationException e)
{
throw new CertPathValidationException("Unable to create verifier: " + e.getMessage(), e);
}
catch (CertException e)
{
throw new CertPathValidationException("Unable to validate signature: " + e.getMessage(), e);
}
catch (IOException e)
{
throw new CertPathValidationException("Unable to build public key: " + e.getMessage(), e);
}
}
workingIssuerName = certificate.getSubject();
workingPublicKey = certificate.getSubjectPublicKeyInfo();
if (workingAlgId != null)
{
// check for inherited parameters
if (workingPublicKey.getAlgorithm().getAlgorithm().equals(workingAlgId.getAlgorithm()))
{
if (!isNull(workingPublicKey.getAlgorithm().getParameters()))
{
workingAlgId = workingPublicKey.getAlgorithm();
}
}
else
{
workingAlgId = workingPublicKey.getAlgorithm();
}
}
else
{
workingAlgId = workingPublicKey.getAlgorithm();
}
}
private boolean isNull(ASN1Encodable obj)
{
return obj == null || obj instanceof ASN1Null;
}
public Memoable copy()
{
ParentCertIssuedValidation v = new ParentCertIssuedValidation(contentVerifierProvider);
v.workingAlgId = this.workingAlgId;
v.workingIssuerName = this.workingIssuerName;
v.workingPublicKey = this.workingPublicKey;
return v;
}
public void reset(Memoable other)
{
ParentCertIssuedValidation v = (ParentCertIssuedValidation)other;
this.contentVerifierProvider = v.contentVerifierProvider;
this.workingAlgId = v.workingAlgId;
this.workingIssuerName = v.workingIssuerName;
this.workingPublicKey = v.workingPublicKey;
}
}