blob: 825f8294dc72c1fe19b81cedc0a1911cd4b33c5b [file] [log] [blame]
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.operator.jcajce;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.Provider;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import com.android.internal.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import com.android.internal.org.bouncycastle.cert.X509CertificateHolder;
import com.android.internal.org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import com.android.internal.org.bouncycastle.jcajce.CompositePublicKey;
import com.android.internal.org.bouncycastle.jcajce.io.OutputStreamFactory;
import com.android.internal.org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
import com.android.internal.org.bouncycastle.jcajce.util.NamedJcaJceHelper;
import com.android.internal.org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
import com.android.internal.org.bouncycastle.operator.ContentVerifier;
import com.android.internal.org.bouncycastle.operator.ContentVerifierProvider;
import com.android.internal.org.bouncycastle.operator.OperatorCreationException;
import com.android.internal.org.bouncycastle.operator.RawContentVerifier;
import com.android.internal.org.bouncycastle.operator.RuntimeOperatorException;
import com.android.internal.org.bouncycastle.util.io.TeeOutputStream;
/**
* @hide This class is not part of the Android public SDK API
*/
public class JcaContentVerifierProviderBuilder
{
private OperatorHelper helper = new OperatorHelper(new DefaultJcaJceHelper());
public JcaContentVerifierProviderBuilder()
{
}
public JcaContentVerifierProviderBuilder setProvider(Provider provider)
{
this.helper = new OperatorHelper(new ProviderJcaJceHelper(provider));
return this;
}
public JcaContentVerifierProviderBuilder setProvider(String providerName)
{
this.helper = new OperatorHelper(new NamedJcaJceHelper(providerName));
return this;
}
public ContentVerifierProvider build(X509CertificateHolder certHolder)
throws OperatorCreationException, CertificateException
{
return build(helper.convertCertificate(certHolder));
}
public ContentVerifierProvider build(final X509Certificate certificate)
throws OperatorCreationException
{
final X509CertificateHolder certHolder;
try
{
certHolder = new JcaX509CertificateHolder(certificate);
}
catch (CertificateEncodingException e)
{
throw new OperatorCreationException("cannot process certificate: " + e.getMessage(), e);
}
return new ContentVerifierProvider()
{
public boolean hasAssociatedCertificate()
{
return true;
}
public X509CertificateHolder getAssociatedCertificate()
{
return certHolder;
}
public ContentVerifier get(AlgorithmIdentifier algorithm)
throws OperatorCreationException
{
if (algorithm.getAlgorithm().equals(MiscObjectIdentifiers.id_alg_composite))
{
return createCompositeVerifier(algorithm, certificate.getPublicKey());
}
else
{
Signature sig;
try
{
sig = helper.createSignature(algorithm);
sig.initVerify(certificate.getPublicKey());
}
catch (GeneralSecurityException e)
{
throw new OperatorCreationException("exception on setup: " + e, e);
}
Signature rawSig = createRawSig(algorithm, certificate.getPublicKey());
if (rawSig != null)
{
return new RawSigVerifier(algorithm, sig, rawSig);
}
else
{
return new SigVerifier(algorithm, sig);
}
}
}
};
}
public ContentVerifierProvider build(final PublicKey publicKey)
throws OperatorCreationException
{
return new ContentVerifierProvider()
{
public boolean hasAssociatedCertificate()
{
return false;
}
public X509CertificateHolder getAssociatedCertificate()
{
return null;
}
public ContentVerifier get(AlgorithmIdentifier algorithm)
throws OperatorCreationException
{
if (algorithm.getAlgorithm().equals(MiscObjectIdentifiers.id_alg_composite))
{
return createCompositeVerifier(algorithm, publicKey);
}
if (publicKey instanceof CompositePublicKey)
{
List<PublicKey> keys = ((CompositePublicKey)publicKey).getPublicKeys();
for (int i = 0; i != keys.size(); i++)
{
try
{
Signature sig = createSignature(algorithm, (PublicKey)keys.get(i));
Signature rawSig = createRawSig(algorithm, (PublicKey)keys.get(i));
if (rawSig != null)
{
return new RawSigVerifier(algorithm, sig, rawSig);
}
else
{
return new SigVerifier(algorithm, sig);
}
}
catch (OperatorCreationException e)
{
// skip incorrect keys
}
}
throw new OperatorCreationException("no matching algorithm found for key");
}
else
{
Signature sig = createSignature(algorithm, publicKey);
Signature rawSig = createRawSig(algorithm, publicKey);
if (rawSig != null)
{
return new RawSigVerifier(algorithm, sig, rawSig);
}
else
{
return new SigVerifier(algorithm, sig);
}
}
}
};
}
public ContentVerifierProvider build(SubjectPublicKeyInfo publicKey)
throws OperatorCreationException
{
return this.build(helper.convertPublicKey(publicKey));
}
private ContentVerifier createCompositeVerifier(AlgorithmIdentifier compAlgId, PublicKey publicKey)
throws OperatorCreationException
{
if (publicKey instanceof CompositePublicKey)
{
List<PublicKey> pubKeys = ((CompositePublicKey)publicKey).getPublicKeys();
ASN1Sequence keySeq = ASN1Sequence.getInstance(compAlgId.getParameters());
Signature[] sigs = new Signature[keySeq.size()];
for (int i = 0; i != keySeq.size(); i++)
{
AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
if (pubKeys.get(i) != null)
{
sigs[i] = createSignature(sigAlg, (PublicKey)pubKeys.get(i));
}
else
{
sigs[i] = null;
}
}
return new CompositeVerifier(sigs);
}
else
{
ASN1Sequence keySeq = ASN1Sequence.getInstance(compAlgId.getParameters());
Signature[] sigs = new Signature[keySeq.size()];
for (int i = 0; i != keySeq.size(); i++)
{
AlgorithmIdentifier sigAlg = AlgorithmIdentifier.getInstance(keySeq.getObjectAt(i));
try
{
sigs[i] = createSignature(sigAlg, publicKey);
}
catch (Exception e)
{
sigs[i] = null;
// continue
}
}
return new CompositeVerifier(sigs);
}
}
private Signature createSignature(AlgorithmIdentifier algorithm, PublicKey publicKey)
throws OperatorCreationException
{
try
{
Signature sig = helper.createSignature(algorithm);
sig.initVerify(publicKey);
return sig;
}
catch (GeneralSecurityException e)
{
throw new OperatorCreationException("exception on setup: " + e, e);
}
}
private Signature createRawSig(AlgorithmIdentifier algorithm, PublicKey publicKey)
{
Signature rawSig;
try
{
rawSig = helper.createRawSignature(algorithm);
if (rawSig != null)
{
rawSig.initVerify(publicKey);
}
}
catch (Exception e)
{
rawSig = null;
}
return rawSig;
}
private class SigVerifier
implements ContentVerifier
{
private final AlgorithmIdentifier algorithm;
private final Signature signature;
protected final OutputStream stream;
SigVerifier(AlgorithmIdentifier algorithm, Signature signature)
{
this.algorithm = algorithm;
this.signature = signature;
this.stream = OutputStreamFactory.createStream(signature);
}
public AlgorithmIdentifier getAlgorithmIdentifier()
{
return algorithm;
}
public OutputStream getOutputStream()
{
if (stream == null)
{
throw new IllegalStateException("verifier not initialised");
}
return stream;
}
public boolean verify(byte[] expected)
{
try
{
return signature.verify(expected);
}
catch (SignatureException e)
{
throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e);
}
}
}
private class RawSigVerifier
extends SigVerifier
implements RawContentVerifier
{
private Signature rawSignature;
RawSigVerifier(AlgorithmIdentifier algorithm, Signature standardSig, Signature rawSignature)
{
super(algorithm, standardSig);
this.rawSignature = rawSignature;
}
public boolean verify(byte[] expected)
{
try
{
return super.verify(expected);
}
finally
{
// we need to do this as in some PKCS11 implementations the session associated with the init of the
// raw signature will not be freed if verify is not called on it.
try
{
rawSignature.verify(expected);
}
catch (Exception e)
{
// ignore
}
}
}
public boolean verify(byte[] digest, byte[] expected)
{
try
{
rawSignature.update(digest);
return rawSignature.verify(expected);
}
catch (SignatureException e)
{
throw new RuntimeOperatorException("exception obtaining raw signature: " + e.getMessage(), e);
}
finally
{
// we need to do this as in some PKCS11 implementations the session associated with the init of the
// standard signature will not be freed if verify is not called on it.
try
{
rawSignature.verify(expected);
}
catch (Exception e)
{
// ignore
}
}
}
}
private class CompositeVerifier
implements ContentVerifier
{
private Signature[] sigs;
private OutputStream stream;
public CompositeVerifier(Signature[] sigs)
throws OperatorCreationException
{
this.sigs = sigs;
int start = 0;
while (start < sigs.length && sigs[start] == null)
{
start++;
}
if (start == sigs.length)
{
throw new OperatorCreationException("no matching signature found in composite");
}
this.stream = OutputStreamFactory.createStream(sigs[start]);
for (int i = start + 1; i != sigs.length; i++)
{
if (sigs[i] != null)
{
this.stream = new TeeOutputStream(this.stream, OutputStreamFactory.createStream(sigs[i]));
}
}
}
public AlgorithmIdentifier getAlgorithmIdentifier()
{
return new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite);
}
public OutputStream getOutputStream()
{
return stream;
}
public boolean verify(byte[] expected)
{
try
{
ASN1Sequence sigSeq = ASN1Sequence.getInstance(expected);
boolean failed = false;
for (int i = 0; i != sigSeq.size(); i++)
{
if (sigs[i] != null)
{
if (!sigs[i].verify(DERBitString.getInstance(sigSeq.getObjectAt(i)).getBytes()))
{
failed = true;
}
}
}
return !failed;
}
catch (SignatureException e)
{
throw new RuntimeOperatorException("exception obtaining signature: " + e.getMessage(), e);
}
}
}
}