diff options
Diffstat (limited to 'repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java')
-rw-r--r-- | repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java | 454 |
1 files changed, 454 insertions, 0 deletions
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java new file mode 100644 index 00000000..825f8294 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/operator/jcajce/JcaContentVerifierProviderBuilder.java @@ -0,0 +1,454 @@ +/* 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); + } + } + } +}
\ No newline at end of file |