diff options
Diffstat (limited to 'repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms')
36 files changed, 4805 insertions, 0 deletions
diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAbsentContent.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAbsentContent.java new file mode 100644 index 00000000..78252a1c --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAbsentContent.java @@ -0,0 +1,51 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier; +import com.android.internal.org.bouncycastle.asn1.cms.CMSObjectIdentifiers; + +/** + * a class representing null or absent content. + * @hide This class is not part of the Android public SDK API + */ +public class CMSAbsentContent + implements CMSTypedData, CMSReadable +{ + private final ASN1ObjectIdentifier type; + + public CMSAbsentContent() + { + this(CMSObjectIdentifiers.data); + } + + public CMSAbsentContent( + ASN1ObjectIdentifier type) + { + this.type = type; + } + + public InputStream getInputStream() + { + return null; + } + + public void write(OutputStream zOut) + throws IOException, CMSException + { + // do nothing + } + + public Object getContent() + { + return null; + } + + public ASN1ObjectIdentifier getContentType() + { + return type; + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerationException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerationException.java new file mode 100644 index 00000000..7b82fc2f --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerationException.java @@ -0,0 +1,36 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class CMSAttributeTableGenerationException + extends CMSRuntimeException +{ + Exception e; + + public CMSAttributeTableGenerationException( + String name) + { + super(name); + } + + public CMSAttributeTableGenerationException( + String name, + Exception e) + { + super(name); + + this.e = e; + } + + public Exception getUnderlyingException() + { + return e; + } + + public Throwable getCause() + { + return e; + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerator.java new file mode 100644 index 00000000..ea92ba12 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSAttributeTableGenerator.java @@ -0,0 +1,23 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.util.Map; + +import com.android.internal.org.bouncycastle.asn1.cms.AttributeTable; + +/** + * Note: The SIGNATURE parameter is only available when generating unsigned attributes. + * @hide This class is not part of the Android public SDK API + */ +public interface CMSAttributeTableGenerator +{ + String CONTENT_TYPE = "contentType"; + String DIGEST = "digest"; + String SIGNATURE = "encryptedDigest"; + String DIGEST_ALGORITHM_IDENTIFIER = "digestAlgID"; + String MAC_ALGORITHM_IDENTIFIER = "macAlgID"; + String SIGNATURE_ALGORITHM_IDENTIFIER = "signatureAlgID"; + + AttributeTable getAttributes(Map parameters) + throws CMSAttributeTableGenerationException; +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSException.java new file mode 100644 index 00000000..03dcb2f9 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSException.java @@ -0,0 +1,36 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class CMSException + extends Exception +{ + Exception e; + + public CMSException( + String msg) + { + super(msg); + } + + public CMSException( + String msg, + Exception e) + { + super(msg); + + this.e = e; + } + + public Exception getUnderlyingException() + { + return e; + } + + public Throwable getCause() + { + return e; + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessable.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessable.java new file mode 100644 index 00000000..be5ecfe6 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessable.java @@ -0,0 +1,23 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Use CMSTypedData instead of this. See CMSProcessableFile/ByteArray for defaults. + * @hide This class is not part of the Android public SDK API + */ +public interface CMSProcessable +{ + /** + * generic routine to copy out the data we want processed - the OutputStream + * passed in will do the handling on it's own. + * <p> + * Note: this routine may be called multiple times. + */ + public void write(OutputStream out) + throws IOException, CMSException; + + public Object getContent(); +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessableByteArray.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessableByteArray.java new file mode 100644 index 00000000..57837488 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSProcessableByteArray.java @@ -0,0 +1,57 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier; +import com.android.internal.org.bouncycastle.asn1.cms.CMSObjectIdentifiers; +import com.android.internal.org.bouncycastle.util.Arrays; + +/** + * a holding class for a byte array of data to be processed. + * @hide This class is not part of the Android public SDK API + */ +public class CMSProcessableByteArray + implements CMSTypedData, CMSReadable +{ + private final ASN1ObjectIdentifier type; + private final byte[] bytes; + + public CMSProcessableByteArray( + byte[] bytes) + { + this(CMSObjectIdentifiers.data, bytes); + } + + public CMSProcessableByteArray( + ASN1ObjectIdentifier type, + byte[] bytes) + { + this.type = type; + this.bytes = bytes; + } + + public InputStream getInputStream() + { + return new ByteArrayInputStream(bytes); + } + + public void write(OutputStream zOut) + throws IOException, CMSException + { + zOut.write(bytes); + } + + public Object getContent() + { + return Arrays.clone(bytes); + } + + public ASN1ObjectIdentifier getContentType() + { + return type; + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSReadable.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSReadable.java new file mode 100644 index 00000000..ceedceea --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSReadable.java @@ -0,0 +1,11 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.io.IOException; +import java.io.InputStream; + +interface CMSReadable +{ + public InputStream getInputStream() + throws IOException, CMSException; +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSRuntimeException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSRuntimeException.java new file mode 100644 index 00000000..5fdd6502 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSRuntimeException.java @@ -0,0 +1,36 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class CMSRuntimeException + extends RuntimeException +{ + Exception e; + + public CMSRuntimeException( + String name) + { + super(name); + } + + public CMSRuntimeException( + String name, + Exception e) + { + super(name); + + this.e = e; + } + + public Exception getUnderlyingException() + { + return e; + } + + public Throwable getCause() + { + return e; + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureAlgorithmNameGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureAlgorithmNameGenerator.java new file mode 100644 index 00000000..d07820de --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureAlgorithmNameGenerator.java @@ -0,0 +1,19 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +/** + * @hide This class is not part of the Android public SDK API + */ +public interface CMSSignatureAlgorithmNameGenerator +{ + /** + * Return the digest algorithm using one of the standard string + * representations rather than the algorithm object identifier (if possible). + * + * @param digestAlg the digest algorithm id. + * @param encryptionAlg the encryption, or signing, algorithm id. + */ + String getSignatureName(AlgorithmIdentifier digestAlg, AlgorithmIdentifier encryptionAlg); +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java new file mode 100644 index 00000000..380a108c --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignatureEncryptionAlgorithmFinder.java @@ -0,0 +1,19 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +/** + * Finder which is used to look up the algorithm identifiers representing the encryption algorithms that + * are associated with a particular signature algorithm. + * @hide This class is not part of the Android public SDK API + */ +public interface CMSSignatureEncryptionAlgorithmFinder +{ + /** + * Return the encryption algorithm identifier associated with the passed in signatureAlgorithm + * @param signatureAlgorithm the algorithm identifier of the signature of interest + * @return the algorithm identifier to be associated with the encryption algorithm used in signature creation. + */ + AlgorithmIdentifier findEncryptionAlgorithm(AlgorithmIdentifier signatureAlgorithm); +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedData.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedData.java new file mode 100644 index 00000000..f42ea21e --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedData.java @@ -0,0 +1,636 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.android.internal.org.bouncycastle.asn1.ASN1Encodable; +import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector; +import com.android.internal.org.bouncycastle.asn1.ASN1InputStream; +import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier; +import com.android.internal.org.bouncycastle.asn1.ASN1OctetString; +import com.android.internal.org.bouncycastle.asn1.ASN1Sequence; +import com.android.internal.org.bouncycastle.asn1.ASN1Set; +import com.android.internal.org.bouncycastle.asn1.BERSequence; +import com.android.internal.org.bouncycastle.asn1.DERSet; +import com.android.internal.org.bouncycastle.asn1.DLSet; +import com.android.internal.org.bouncycastle.asn1.cms.ContentInfo; +import com.android.internal.org.bouncycastle.asn1.cms.SignedData; +import com.android.internal.org.bouncycastle.asn1.cms.SignerInfo; +import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import com.android.internal.org.bouncycastle.cert.X509AttributeCertificateHolder; +import com.android.internal.org.bouncycastle.cert.X509CRLHolder; +import com.android.internal.org.bouncycastle.cert.X509CertificateHolder; +import com.android.internal.org.bouncycastle.operator.OperatorCreationException; +import com.android.internal.org.bouncycastle.util.Encodable; +import com.android.internal.org.bouncycastle.util.Store; + +/** + * general class for handling a pkcs7-signature message. + * + * A simple example of usage - note, in the example below the validity of + * the certificate isn't verified, just the fact that one of the certs + * matches the given signer... + * + * <pre> + * Store certStore = s.getCertificates(); + * SignerInformationStore signers = s.getSignerInfos(); + * Collection c = signers.getSigners(); + * Iterator it = c.iterator(); + * + * while (it.hasNext()) + * { + * SignerInformation signer = (SignerInformation)it.next(); + * Collection certCollection = certStore.getMatches(signer.getSID()); + * + * Iterator certIt = certCollection.iterator(); + * X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); + * + * if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert))) + * { + * verified++; + * } + * } + * </pre> + * @hide This class is not part of the Android public SDK API + */ +public class CMSSignedData + implements Encodable +{ + private static final CMSSignedHelper HELPER = CMSSignedHelper.INSTANCE; + + SignedData signedData; + ContentInfo contentInfo; + CMSTypedData signedContent; + SignerInformationStore signerInfoStore; + + private Map hashes; + + private CMSSignedData( + CMSSignedData c) + { + this.signedData = c.signedData; + this.contentInfo = c.contentInfo; + this.signedContent = c.signedContent; + this.signerInfoStore = c.signerInfoStore; + } + + public CMSSignedData( + byte[] sigBlock) + throws CMSException + { + this(CMSUtils.readContentInfo(sigBlock)); + } + + public CMSSignedData( + CMSProcessable signedContent, + byte[] sigBlock) + throws CMSException + { + this(signedContent, CMSUtils.readContentInfo(sigBlock)); + } + + /** + * Content with detached signature, digests precomputed + * + * @param hashes a map of precomputed digests for content indexed by name of hash. + * @param sigBlock the signature object. + */ + public CMSSignedData( + Map hashes, + byte[] sigBlock) + throws CMSException + { + this(hashes, CMSUtils.readContentInfo(sigBlock)); + } + + /** + * base constructor - content with detached signature. + * + * @param signedContent the content that was signed. + * @param sigData the signature object. + */ + public CMSSignedData( + CMSProcessable signedContent, + InputStream sigData) + throws CMSException + { + this(signedContent, CMSUtils.readContentInfo(new ASN1InputStream(sigData))); + } + + /** + * base constructor - with encapsulated content + */ + public CMSSignedData( + InputStream sigData) + throws CMSException + { + this(CMSUtils.readContentInfo(sigData)); + } + + public CMSSignedData( + final CMSProcessable signedContent, + ContentInfo sigData) + throws CMSException + { + if (signedContent instanceof CMSTypedData) + { + this.signedContent = (CMSTypedData)signedContent; + } + else + { + this.signedContent = new CMSTypedData() + { + public ASN1ObjectIdentifier getContentType() + { + return signedData.getEncapContentInfo().getContentType(); + } + + public void write(OutputStream out) + throws IOException, CMSException + { + signedContent.write(out); + } + + public Object getContent() + { + return signedContent.getContent(); + } + }; + } + + this.contentInfo = sigData; + this.signedData = getSignedData(); + } + + public CMSSignedData( + Map hashes, + ContentInfo sigData) + throws CMSException + { + this.hashes = hashes; + this.contentInfo = sigData; + this.signedData = getSignedData(); + } + + public CMSSignedData( + ContentInfo sigData) + throws CMSException + { + this.contentInfo = sigData; + this.signedData = getSignedData(); + + // + // this can happen if the signed message is sent simply to send a + // certificate chain. + // + ASN1Encodable content = signedData.getEncapContentInfo().getContent(); + if (content != null) + { + if (content instanceof ASN1OctetString) + { + this.signedContent = new CMSProcessableByteArray(signedData.getEncapContentInfo().getContentType(), + ((ASN1OctetString)content).getOctets()); + } + else + { + this.signedContent = new PKCS7ProcessableObject(signedData.getEncapContentInfo().getContentType(), content); + } + } + else + { + this.signedContent = null; + } + } + + private SignedData getSignedData() + throws CMSException + { + try + { + return SignedData.getInstance(contentInfo.getContent()); + } + catch (ClassCastException e) + { + throw new CMSException("Malformed content.", e); + } + catch (IllegalArgumentException e) + { + throw new CMSException("Malformed content.", e); + } + } + + /** + * Return the version number for this object + */ + public int getVersion() + { + return signedData.getVersion().intValueExact(); + } + + /** + * return the collection of signers that are associated with the + * signatures for the message. + */ + public SignerInformationStore getSignerInfos() + { + if (signerInfoStore == null) + { + ASN1Set s = signedData.getSignerInfos(); + List signerInfos = new ArrayList(); + + for (int i = 0; i != s.size(); i++) + { + SignerInfo info = SignerInfo.getInstance(s.getObjectAt(i)); + ASN1ObjectIdentifier contentType = signedData.getEncapContentInfo().getContentType(); + + if (hashes == null) + { + signerInfos.add(new SignerInformation(info, contentType, signedContent, null)); + } + else + { + Object obj = hashes.keySet().iterator().next(); + byte[] hash = (obj instanceof String) ? (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm().getId()) : (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm()); + + signerInfos.add(new SignerInformation(info, contentType, null, hash)); + } + } + + signerInfoStore = new SignerInformationStore(signerInfos); + } + + return signerInfoStore; + } + + /** + * Return if this is object represents a detached signature. + * + * @return true if this message represents a detached signature, false otherwise. + */ + public boolean isDetachedSignature() + { + return signedData.getEncapContentInfo().getContent() == null && signedData.getSignerInfos().size() > 0; + } + + /** + * Return if this is object represents a certificate management message. + * + * @return true if the message has no signers or content, false otherwise. + */ + public boolean isCertificateManagementMessage() + { + return signedData.getEncapContentInfo().getContent() == null && signedData.getSignerInfos().size() == 0; + } + + /** + * Return any X.509 certificate objects in this SignedData structure as a Store of X509CertificateHolder objects. + * + * @return a Store of X509CertificateHolder objects. + */ + public Store<X509CertificateHolder> getCertificates() + { + return HELPER.getCertificates(signedData.getCertificates()); + } + + /** + * Return any X.509 CRL objects in this SignedData structure as a Store of X509CRLHolder objects. + * + * @return a Store of X509CRLHolder objects. + */ + public Store<X509CRLHolder> getCRLs() + { + return HELPER.getCRLs(signedData.getCRLs()); + } + + /** + * Return any X.509 attribute certificate objects in this SignedData structure as a Store of X509AttributeCertificateHolder objects. + * + * @return a Store of X509AttributeCertificateHolder objects. + */ + public Store<X509AttributeCertificateHolder> getAttributeCertificates() + { + return HELPER.getAttributeCertificates(signedData.getCertificates()); + } + + // BEGIN Android-removed: OtherRevocationInfoFormat isn't supported + /* + /** + * Return any OtherRevocationInfo OtherRevInfo objects of the type indicated by otherRevocationInfoFormat in + * this SignedData structure. + * + * @param otherRevocationInfoFormat OID of the format type been looked for. + * + * @return a Store of ASN1Encodable objects representing any objects of otherRevocationInfoFormat found. + * + public Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoFormat) + { + return HELPER.getOtherRevocationInfo(otherRevocationInfoFormat, signedData.getCRLs()); + } + */ + // END Android-removed: OtherRevocationInfoFormat isn't supported + + /** + * Return the digest algorithm identifiers for the SignedData object + * + * @return the set of digest algorithm identifiers + */ + public Set<AlgorithmIdentifier> getDigestAlgorithmIDs() + { + Set<AlgorithmIdentifier> digests = new HashSet<AlgorithmIdentifier>(signedData.getDigestAlgorithms().size()); + + for (Enumeration en = signedData.getDigestAlgorithms().getObjects(); en.hasMoreElements();) + { + digests.add(AlgorithmIdentifier.getInstance(en.nextElement())); + } + + return Collections.unmodifiableSet(digests); + } + + /** + * Return the a string representation of the OID associated with the + * encapsulated content info structure carried in the signed data. + * + * @return the OID for the content type. + */ + public String getSignedContentTypeOID() + { + return signedData.getEncapContentInfo().getContentType().getId(); + } + + public CMSTypedData getSignedContent() + { + return signedContent; + } + + /** + * return the ContentInfo + */ + public ContentInfo toASN1Structure() + { + return contentInfo; + } + + /** + * return the ASN.1 encoded representation of this object. + */ + public byte[] getEncoded() + throws IOException + { + return contentInfo.getEncoded(); + } + + // BEGIN Android-removed: Unknown reason + /* + /** + * return the ASN.1 encoded representation of this object using the specified encoding. + * + * @param encoding the ASN.1 encoding format to use ("BER", "DL", or "DER"). + */ + public byte[] getEncoded(String encoding) + throws IOException + { + return contentInfo.getEncoded(encoding); + } + + /** + * Verify all the SignerInformation objects and their associated counter signatures attached + * to this CMS SignedData object. + * + * @param verifierProvider a provider of SignerInformationVerifier objects. + * @return true if all verify, false otherwise. + * @throws CMSException if an exception occurs during the verification process. + * + public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider) + throws CMSException + { + return verifySignatures(verifierProvider, false); + } + + /** + * Verify all the SignerInformation objects and optionally their associated counter signatures attached + * to this CMS SignedData object. + * + * @param verifierProvider a provider of SignerInformationVerifier objects. + * @param ignoreCounterSignatures if true don't check counter signatures. If false check counter signatures as well. + * @return true if all verify, false otherwise. + * @throws CMSException if an exception occurs during the verification process. + * + public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider, boolean ignoreCounterSignatures) + throws CMSException + { + Collection signers = this.getSignerInfos().getSigners(); + + for (Iterator it = signers.iterator(); it.hasNext();) + { + SignerInformation signer = (SignerInformation)it.next(); + + try + { + SignerInformationVerifier verifier = verifierProvider.get(signer.getSID()); + + if (!signer.verify(verifier)) + { + return false; + } + + if (!ignoreCounterSignatures) + { + Collection counterSigners = signer.getCounterSignatures().getSigners(); + + for (Iterator cIt = counterSigners.iterator(); cIt.hasNext();) + { + if (!verifyCounterSignature((SignerInformation)cIt.next(), verifierProvider)) + { + return false; + } + } + } + } + catch (OperatorCreationException e) + { + throw new CMSException("failure in verifier provider: " + e.getMessage(), e); + } + } + + return true; + } + + private boolean verifyCounterSignature(SignerInformation counterSigner, SignerInformationVerifierProvider verifierProvider) + throws OperatorCreationException, CMSException + { + SignerInformationVerifier counterVerifier = verifierProvider.get(counterSigner.getSID()); + + if (!counterSigner.verify(counterVerifier)) + { + return false; + } + + Collection counterSigners = counterSigner.getCounterSignatures().getSigners(); + for (Iterator cIt = counterSigners.iterator(); cIt.hasNext();) + { + if (!verifyCounterSignature((SignerInformation)cIt.next(), verifierProvider)) + { + return false; + } + } + + return true; + } + */ + // END Android-removed: Unknown reason + + /** + * Replace the SignerInformation store associated with this + * CMSSignedData object with the new one passed in. You would + * probably only want to do this if you wanted to change the unsigned + * attributes associated with a signer, or perhaps delete one. + * + * @param signedData the signed data object to be used as a base. + * @param signerInformationStore the new signer information store to use. + * @return a new signed data object. + */ + public static CMSSignedData replaceSigners( + CMSSignedData signedData, + SignerInformationStore signerInformationStore) + { + // + // copy + // + CMSSignedData cms = new CMSSignedData(signedData); + + // + // replace the store + // + cms.signerInfoStore = signerInformationStore; + + // + // replace the signers in the SignedData object + // + ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); + ASN1EncodableVector vec = new ASN1EncodableVector(); + + Iterator it = signerInformationStore.getSigners().iterator(); + while (it.hasNext()) + { + SignerInformation signer = (SignerInformation)it.next(); + digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); + vec.add(signer.toASN1Structure()); + } + + ASN1Set digests = new DERSet(digestAlgs); + ASN1Set signers = new DLSet(vec); + ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive(); + + vec = new ASN1EncodableVector(); + + // + // signers are the last item in the sequence. + // + vec.add(sD.getObjectAt(0)); // version + vec.add(digests); + + for (int i = 2; i != sD.size() - 1; i++) + { + vec.add(sD.getObjectAt(i)); + } + + vec.add(signers); + + cms.signedData = SignedData.getInstance(new BERSequence(vec)); + + // + // replace the contentInfo with the new one + // + cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); + + return cms; + } + + /** + * Replace the certificate and CRL information associated with this + * CMSSignedData object with the new one passed in. + * + * @param signedData the signed data object to be used as a base. + * @param certificates the new certificates to be used. + * @param attrCerts the new attribute certificates to be used. + * @param revocations the new CRLs to be used - a collection of X509CRLHolder objects, OtherRevocationInfoFormat, or both. + * @return a new signed data object. + * @exception CMSException if there is an error processing the CertStore + */ + public static CMSSignedData replaceCertificatesAndCRLs( + CMSSignedData signedData, + Store certificates, + Store attrCerts, + Store revocations) + throws CMSException + { + // + // copy + // + CMSSignedData cms = new CMSSignedData(signedData); + + // + // replace the certs and revocations in the SignedData object + // + ASN1Set certSet = null; + ASN1Set crlSet = null; + + if (certificates != null || attrCerts != null) + { + List certs = new ArrayList(); + + if (certificates != null) + { + certs.addAll(CMSUtils.getCertificatesFromStore(certificates)); + } + if (attrCerts != null) + { + certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts)); + } + + ASN1Set set = CMSUtils.createBerSetFromList(certs); + + if (set.size() != 0) + { + certSet = set; + } + } + + if (revocations != null) + { + ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(revocations)); + + if (set.size() != 0) + { + crlSet = set; + } + } + + // + // replace the CMS structure. + // + cms.signedData = new SignedData(signedData.signedData.getDigestAlgorithms(), + signedData.signedData.getEncapContentInfo(), + certSet, + crlSet, + signedData.signedData.getSignerInfos()); + + // + // replace the contentInfo with the new one + // + cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); + + return cms; + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedDataGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedDataGenerator.java new file mode 100644 index 00000000..1fdaaa9d --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedDataGenerator.java @@ -0,0 +1,234 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector; +import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier; +import com.android.internal.org.bouncycastle.asn1.ASN1OctetString; +import com.android.internal.org.bouncycastle.asn1.ASN1Set; +import com.android.internal.org.bouncycastle.asn1.BEROctetString; +import com.android.internal.org.bouncycastle.asn1.DERSet; +import com.android.internal.org.bouncycastle.asn1.cms.CMSObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.cms.ContentInfo; +import com.android.internal.org.bouncycastle.asn1.cms.SignedData; +import com.android.internal.org.bouncycastle.asn1.cms.SignerInfo; + +/** + * general class for generating a pkcs7-signature message. + * <p> + * A simple example of usage, generating a detached signature. + * + * <pre> + * List certList = new ArrayList(); + * CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); + * + * certList.add(signCert); + * + * Store certs = new JcaCertStore(certList); + * + * CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); + * ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(signKP.getPrivate()); + * + * gen.addSignerInfoGenerator( + * new JcaSignerInfoGeneratorBuilder( + * new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) + * .build(sha1Signer, signCert)); + * + * gen.addCertificates(certs); + * + * CMSSignedData sigData = gen.generate(msg, false); + * </pre> + * @hide This class is not part of the Android public SDK API + */ +public class CMSSignedDataGenerator + extends CMSSignedGenerator +{ + private List signerInfs = new ArrayList(); + + /** + * base constructor + */ + public CMSSignedDataGenerator() + { + } + + /** + * Generate a CMS Signed Data object carrying a detached CMS signature. + * + * @param content the content to be signed. + */ + public CMSSignedData generate( + CMSTypedData content) + throws CMSException + { + return generate(content, false); + } + + /** + * Generate a CMS Signed Data object which can be carrying a detached CMS signature, or have encapsulated data, depending on the value + * of the encapsulated parameter. + * + * @param content the content to be signed. + * @param encapsulate true if the content should be encapsulated in the signature, false otherwise. + */ + public CMSSignedData generate( + // FIXME Avoid accessing more than once to support CMSProcessableInputStream + CMSTypedData content, + boolean encapsulate) + throws CMSException + { + if (!signerInfs.isEmpty()) + { + throw new IllegalStateException("this method can only be used with SignerInfoGenerator"); + } + + // TODO +// if (signerInfs.isEmpty()) +// { +// /* RFC 3852 5.2 +// * "In the degenerate case where there are no signers, the +// * EncapsulatedContentInfo value being "signed" is irrelevant. In this +// * case, the content type within the EncapsulatedContentInfo value being +// * "signed" MUST be id-data (as defined in section 4), and the content +// * field of the EncapsulatedContentInfo value MUST be omitted." +// */ +// if (encapsulate) +// { +// throw new IllegalArgumentException("no signers, encapsulate must be false"); +// } +// if (!DATA.equals(eContentType)) +// { +// throw new IllegalArgumentException("no signers, eContentType must be id-data"); +// } +// } +// +// if (!DATA.equals(eContentType)) +// { +// /* RFC 3852 5.3 +// * [The 'signedAttrs']... +// * field is optional, but it MUST be present if the content type of +// * the EncapsulatedContentInfo value being signed is not id-data. +// */ +// // TODO signedAttrs must be present for all signers +// } + + ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); + ASN1EncodableVector signerInfos = new ASN1EncodableVector(); + + digests.clear(); // clear the current preserved digest state + + // + // add the precalculated SignerInfo objects. + // + for (Iterator it = _signers.iterator(); it.hasNext();) + { + SignerInformation signer = (SignerInformation)it.next(); + digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); + + // TODO Verify the content type and calculated digest match the precalculated SignerInfo + signerInfos.add(signer.toASN1Structure()); + } + + // + // add the SignerInfo objects + // + ASN1ObjectIdentifier contentTypeOID = content.getContentType(); + + ASN1OctetString octs = null; + + if (content.getContent() != null) + { + ByteArrayOutputStream bOut = null; + + if (encapsulate) + { + bOut = new ByteArrayOutputStream(); + } + + OutputStream cOut = CMSUtils.attachSignersToOutputStream(signerGens, bOut); + + // Just in case it's unencapsulated and there are no signers! + cOut = CMSUtils.getSafeOutputStream(cOut); + + try + { + content.write(cOut); + + cOut.close(); + } + catch (IOException e) + { + throw new CMSException("data processing exception: " + e.getMessage(), e); + } + + if (encapsulate) + { + octs = new BEROctetString(bOut.toByteArray()); + } + } + + for (Iterator it = signerGens.iterator(); it.hasNext();) + { + SignerInfoGenerator sGen = (SignerInfoGenerator)it.next(); + SignerInfo inf = sGen.generate(contentTypeOID); + + digestAlgs.add(inf.getDigestAlgorithm()); + signerInfos.add(inf); + + byte[] calcDigest = sGen.getCalculatedDigest(); + + if (calcDigest != null) + { + digests.put(inf.getDigestAlgorithm().getAlgorithm().getId(), calcDigest); + } + } + + ASN1Set certificates = null; + + if (certs.size() != 0) + { + certificates = CMSUtils.createBerSetFromList(certs); + } + + ASN1Set certrevlist = null; + + if (crls.size() != 0) + { + certrevlist = CMSUtils.createBerSetFromList(crls); + } + + ContentInfo encInfo = new ContentInfo(contentTypeOID, octs); + + SignedData sd = new SignedData( + new DERSet(digestAlgs), + encInfo, + certificates, + certrevlist, + new DERSet(signerInfos)); + + ContentInfo contentInfo = new ContentInfo( + CMSObjectIdentifiers.signedData, sd); + + return new CMSSignedData(content, contentInfo); + } + + /** + * generate a set of one or more SignerInformation objects representing counter signatures on + * the passed in SignerInformation object. + * + * @param signer the signer to be countersigned + * @return a store containing the signers. + */ + public SignerInformationStore generateCounterSigners(SignerInformation signer) + throws CMSException + { + return this.generate(new CMSProcessableByteArray(null, signer.getSignature()), false).getSignerInfos(); + } +} + diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedGenerator.java new file mode 100644 index 00000000..eae4ff4b --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedGenerator.java @@ -0,0 +1,256 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.android.internal.org.bouncycastle.asn1.ASN1Encodable; +import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier; +import com.android.internal.org.bouncycastle.asn1.DERTaggedObject; +import com.android.internal.org.bouncycastle.asn1.cms.CMSObjectIdentifiers; +// Android-removed: Unsupported algorithms +// import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; +// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +// Android-removed: Unsupported algorithms +// import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import com.android.internal.org.bouncycastle.cert.X509AttributeCertificateHolder; +import com.android.internal.org.bouncycastle.cert.X509CRLHolder; +import com.android.internal.org.bouncycastle.cert.X509CertificateHolder; +import com.android.internal.org.bouncycastle.util.Arrays; +import com.android.internal.org.bouncycastle.util.Store; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class CMSSignedGenerator +{ + /** + * Default type for the signed data. + */ + public static final String DATA = CMSObjectIdentifiers.data.getId(); + + public static final String DIGEST_SHA1 = OIWObjectIdentifiers.idSHA1.getId(); + public static final String DIGEST_SHA224 = NISTObjectIdentifiers.id_sha224.getId(); + public static final String DIGEST_SHA256 = NISTObjectIdentifiers.id_sha256.getId(); + public static final String DIGEST_SHA384 = NISTObjectIdentifiers.id_sha384.getId(); + public static final String DIGEST_SHA512 = NISTObjectIdentifiers.id_sha512.getId(); + public static final String DIGEST_MD5 = PKCSObjectIdentifiers.md5.getId(); + // BEGIN Android-removed: Unsupported algorithms + // public static final String DIGEST_GOST3411 = CryptoProObjectIdentifiers.gostR3411.getId(); + // public static final String DIGEST_RIPEMD128 = TeleTrusTObjectIdentifiers.ripemd128.getId(); + // public static final String DIGEST_RIPEMD160 = TeleTrusTObjectIdentifiers.ripemd160.getId(); + // public static final String DIGEST_RIPEMD256 = TeleTrusTObjectIdentifiers.ripemd256.getId(); + // END Android-removed: Unsupported algorithms + + public static final String ENCRYPTION_RSA = PKCSObjectIdentifiers.rsaEncryption.getId(); + public static final String ENCRYPTION_DSA = X9ObjectIdentifiers.id_dsa_with_sha1.getId(); + public static final String ENCRYPTION_ECDSA = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); + public static final String ENCRYPTION_RSA_PSS = PKCSObjectIdentifiers.id_RSASSA_PSS.getId(); + // BEGIN Android-removed: Unsupported algorithms + // public static final String ENCRYPTION_GOST3410 = CryptoProObjectIdentifiers.gostR3410_94.getId(); + // public static final String ENCRYPTION_ECGOST3410 = CryptoProObjectIdentifiers.gostR3410_2001.getId(); + // public static final String ENCRYPTION_ECGOST3410_2012_256 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256.getId(); + // public static final String ENCRYPTION_ECGOST3410_2012_512 = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512.getId(); + // END Android-removed: Unsupported algorithms + + private static final String ENCRYPTION_ECDSA_WITH_SHA1 = X9ObjectIdentifiers.ecdsa_with_SHA1.getId(); + private static final String ENCRYPTION_ECDSA_WITH_SHA224 = X9ObjectIdentifiers.ecdsa_with_SHA224.getId(); + private static final String ENCRYPTION_ECDSA_WITH_SHA256 = X9ObjectIdentifiers.ecdsa_with_SHA256.getId(); + private static final String ENCRYPTION_ECDSA_WITH_SHA384 = X9ObjectIdentifiers.ecdsa_with_SHA384.getId(); + private static final String ENCRYPTION_ECDSA_WITH_SHA512 = X9ObjectIdentifiers.ecdsa_with_SHA512.getId(); + + private static final Set NO_PARAMS = new HashSet(); + private static final Map EC_ALGORITHMS = new HashMap(); + + static + { + NO_PARAMS.add(ENCRYPTION_DSA); + NO_PARAMS.add(ENCRYPTION_ECDSA); + NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA1); + NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA224); + NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA256); + NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA384); + NO_PARAMS.add(ENCRYPTION_ECDSA_WITH_SHA512); + + EC_ALGORITHMS.put(DIGEST_SHA1, ENCRYPTION_ECDSA_WITH_SHA1); + EC_ALGORITHMS.put(DIGEST_SHA224, ENCRYPTION_ECDSA_WITH_SHA224); + EC_ALGORITHMS.put(DIGEST_SHA256, ENCRYPTION_ECDSA_WITH_SHA256); + EC_ALGORITHMS.put(DIGEST_SHA384, ENCRYPTION_ECDSA_WITH_SHA384); + EC_ALGORITHMS.put(DIGEST_SHA512, ENCRYPTION_ECDSA_WITH_SHA512); + } + + protected List certs = new ArrayList(); + protected List crls = new ArrayList(); + protected List _signers = new ArrayList(); + protected List signerGens = new ArrayList(); + protected Map digests = new HashMap(); + + /** + * base constructor + */ + protected CMSSignedGenerator() + { + } + + protected Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash) + { + Map param = new HashMap(); + param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType); + param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId); + param.put(CMSAttributeTableGenerator.DIGEST, Arrays.clone(hash)); + return param; + } + + /** + * Add a certificate to the certificate set to be included with the generated SignedData message. + * + * @param certificate the certificate to be included. + * @throws CMSException if the certificate cannot be encoded for adding. + */ + public void addCertificate( + X509CertificateHolder certificate) + throws CMSException + { + certs.add(certificate.toASN1Structure()); + } + + /** + * Add the certificates in certStore to the certificate set to be included with the generated SignedData message. + * + * @param certStore the store containing the certificates to be included. + * @throws CMSException if the certificates cannot be encoded for adding. + */ + public void addCertificates( + Store certStore) + throws CMSException + { + certs.addAll(CMSUtils.getCertificatesFromStore(certStore)); + } + + /** + * Add a CRL to the CRL set to be included with the generated SignedData message. + * + * @param crl the CRL to be included. + */ + public void addCRL(X509CRLHolder crl) + { + crls.add(crl.toASN1Structure()); + } + + /** + * Add the CRLs in crlStore to the CRL set to be included with the generated SignedData message. + * + * @param crlStore the store containing the CRLs to be included. + * @throws CMSException if the CRLs cannot be encoded for adding. + */ + public void addCRLs( + Store crlStore) + throws CMSException + { + crls.addAll(CMSUtils.getCRLsFromStore(crlStore)); + } + + /** + * Add the attribute certificates in attrStore to the certificate set to be included with the generated SignedData message. + * + * @param attrCert the store containing the certificates to be included. + * @throws CMSException if the attribute certificate cannot be encoded for adding. + */ + public void addAttributeCertificate( + X509AttributeCertificateHolder attrCert) + throws CMSException + { + certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure())); + } + + /** + * Add the attribute certificates in attrStore to the certificate set to be included with the generated SignedData message. + * + * @param attrStore the store containing the certificates to be included. + * @throws CMSException if the attribute certificate cannot be encoded for adding. + */ + public void addAttributeCertificates( + Store attrStore) + throws CMSException + { + certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrStore)); + } + + // BEGIN Android-removed: OtherRevocationInfoFormat isn't supported + /* + /** + * Add a single instance of otherRevocationData to the CRL set to be included with the generated SignedData message. + * + * @param otherRevocationInfoFormat the OID specifying the format of the otherRevocationInfo data. + * @param otherRevocationInfo the otherRevocationInfo ASN.1 structure. + * + public void addOtherRevocationInfo( + ASN1ObjectIdentifier otherRevocationInfoFormat, + ASN1Encodable otherRevocationInfo) + { + crls.add(new DERTaggedObject(false, 1, new OtherRevocationInfoFormat(otherRevocationInfoFormat, otherRevocationInfo))); + } + + /** + * Add a Store of otherRevocationData to the CRL set to be included with the generated SignedData message. + * + * @param otherRevocationInfoFormat the OID specifying the format of the otherRevocationInfo data. + * @param otherRevocationInfos a Store of otherRevocationInfo data to add. + * + public void addOtherRevocationInfo( + ASN1ObjectIdentifier otherRevocationInfoFormat, + Store otherRevocationInfos) + { + crls.addAll(CMSUtils.getOthersFromStore(otherRevocationInfoFormat, otherRevocationInfos)); + } + */ + // END Android-removed: OtherRevocationInfoFormat isn't supported + + /** + * Add a store of pre-calculated signers to the generator. + * + * @param signerStore store of signers + */ + public void addSigners( + SignerInformationStore signerStore) + { + Iterator it = signerStore.getSigners().iterator(); + + while (it.hasNext()) + { + _signers.add(it.next()); + } + } + + /** + * Add a generator for a particular signer to this CMS SignedData generator. + * + * @param infoGen the generator representing the particular signer. + */ + public void addSignerInfoGenerator(SignerInfoGenerator infoGen) + { + signerGens.add(infoGen); + } + + /** + * Return a map of oids and byte arrays representing the digests calculated on the content during + * the last generate. + * + * @return a map of oids (as String objects) and byte[] representing digests. + */ + public Map getGeneratedDigests() + { + return new HashMap(digests); + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedHelper.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedHelper.java new file mode 100644 index 00000000..bd528bdb --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignedHelper.java @@ -0,0 +1,272 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.android.internal.org.bouncycastle.asn1.ASN1Encodable; +import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier; +import com.android.internal.org.bouncycastle.asn1.ASN1Primitive; +import com.android.internal.org.bouncycastle.asn1.ASN1Sequence; +import com.android.internal.org.bouncycastle.asn1.ASN1Set; +import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject; +import com.android.internal.org.bouncycastle.asn1.DERNull; +// Android-removed: Unsupported algorithms +// import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; +// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.eac.EACObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +// import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import com.android.internal.org.bouncycastle.asn1.x509.AttributeCertificate; +import com.android.internal.org.bouncycastle.asn1.x509.Certificate; +import com.android.internal.org.bouncycastle.asn1.x509.CertificateList; +import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import com.android.internal.org.bouncycastle.cert.X509AttributeCertificateHolder; +import com.android.internal.org.bouncycastle.cert.X509CRLHolder; +import com.android.internal.org.bouncycastle.cert.X509CertificateHolder; +import com.android.internal.org.bouncycastle.util.CollectionStore; +import com.android.internal.org.bouncycastle.util.Store; + +class CMSSignedHelper +{ + static final CMSSignedHelper INSTANCE = new CMSSignedHelper(); + + private static final Map encryptionAlgs = new HashMap(); + + private static void addEntries(ASN1ObjectIdentifier alias, String encryption) + { + encryptionAlgs.put(alias.getId(), encryption); + } + + static + { + addEntries(NISTObjectIdentifiers.dsa_with_sha224, "DSA"); + addEntries(NISTObjectIdentifiers.dsa_with_sha256, "DSA"); + addEntries(NISTObjectIdentifiers.dsa_with_sha384, "DSA"); + addEntries(NISTObjectIdentifiers.dsa_with_sha512, "DSA"); + // BEGIN Android-removed: Unsupported algorithms + /* + addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_224, "DSA"); + addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_256, "DSA"); + addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_384, "DSA"); + addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_512, "DSA"); + */ + // END Android-removed: Unsupported algorithms + addEntries(OIWObjectIdentifiers.dsaWithSHA1, "DSA"); + // BEGIN Android-removed: Unsupported algorithms + /* + addEntries(OIWObjectIdentifiers.md4WithRSA, "RSA"); + addEntries(OIWObjectIdentifiers.md4WithRSAEncryption, "RSA"); + */ + // END Android-removed: Unsupported algorithms + addEntries(OIWObjectIdentifiers.md5WithRSA, "RSA"); + addEntries(OIWObjectIdentifiers.sha1WithRSA, "RSA"); + // BEGIN Android-removed: Unsupported algorithms + /* + addEntries(PKCSObjectIdentifiers.md2WithRSAEncryption, "RSA"); + addEntries(PKCSObjectIdentifiers.md4WithRSAEncryption, "RSA"); + */ + // END Android-removed: Unsupported algorithms + addEntries(PKCSObjectIdentifiers.md5WithRSAEncryption, "RSA"); + addEntries(PKCSObjectIdentifiers.sha1WithRSAEncryption, "RSA"); + addEntries(PKCSObjectIdentifiers.sha224WithRSAEncryption, "RSA"); + addEntries(PKCSObjectIdentifiers.sha256WithRSAEncryption, "RSA"); + addEntries(PKCSObjectIdentifiers.sha384WithRSAEncryption, "RSA"); + addEntries(PKCSObjectIdentifiers.sha512WithRSAEncryption, "RSA"); + // BEGIN Android-removed: Unsupported algorithms + /* + addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224, "RSA"); + addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256, "RSA"); + addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384, "RSA"); + addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512, "RSA"); + */ + // END Android-removed: Unsupported algorithms + addEntries(X9ObjectIdentifiers.ecdsa_with_SHA1, "ECDSA"); + addEntries(X9ObjectIdentifiers.ecdsa_with_SHA224, "ECDSA"); + addEntries(X9ObjectIdentifiers.ecdsa_with_SHA256, "ECDSA"); + addEntries(X9ObjectIdentifiers.ecdsa_with_SHA384, "ECDSA"); + addEntries(X9ObjectIdentifiers.ecdsa_with_SHA512, "ECDSA"); + // BEGIN Android-removed: Unsupported algorithms + /* + addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_224, "ECDSA"); + addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_256, "ECDSA"); + addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_384, "ECDSA"); + addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_512, "ECDSA"); + */ + // END Android-removed: Unsupported algorithms + addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "DSA"); + addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "ECDSA"); + addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "ECDSA"); + addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "ECDSA"); + addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "ECDSA"); + addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "ECDSA"); + addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_1, "RSA"); + addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "RSA"); + addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "RSAandMGF1"); + addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "RSAandMGF1"); + + addEntries(X9ObjectIdentifiers.id_dsa, "DSA"); + addEntries(PKCSObjectIdentifiers.rsaEncryption, "RSA"); + addEntries(TeleTrusTObjectIdentifiers.teleTrusTRSAsignatureAlgorithm, "RSA"); + addEntries(X509ObjectIdentifiers.id_ea_rsa, "RSA"); + // BEGIN Android-removed: Unsupported algorithms + /* + addEntries(PKCSObjectIdentifiers.id_RSASSA_PSS, "RSAandMGF1"); + addEntries(CryptoProObjectIdentifiers.gostR3410_94, "GOST3410"); + addEntries(CryptoProObjectIdentifiers.gostR3410_2001, "ECGOST3410"); + addEntries(new ASN1ObjectIdentifier("1.3.6.1.4.1.5849.1.6.2"), "ECGOST3410"); + addEntries(new ASN1ObjectIdentifier("1.3.6.1.4.1.5849.1.1.5"), "GOST3410"); + addEntries(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256, "ECGOST3410-2012-256"); + addEntries(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512, "ECGOST3410-2012-512"); + addEntries(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "ECGOST3410"); + addEntries(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3410"); + addEntries(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, "ECGOST3410-2012-256"); + addEntries(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, "ECGOST3410-2012-512"); + */ + // END Android-removed: Unsupported algorithms + } + + + /** + * Return the digest encryption algorithm using one of the standard + * JCA string representations rather the the algorithm identifier (if + * possible). + */ + String getEncryptionAlgName( + String encryptionAlgOID) + { + String algName = (String)encryptionAlgs.get(encryptionAlgOID); + + if (algName != null) + { + return algName; + } + + return encryptionAlgOID; + } + + AlgorithmIdentifier fixAlgID(AlgorithmIdentifier algId) + { + if (algId.getParameters() == null) + { + return new AlgorithmIdentifier(algId.getAlgorithm(), DERNull.INSTANCE); + } + + return algId; + } + + void setSigningEncryptionAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName) + { + addEntries(oid, algorithmName); + } + + Store getCertificates(ASN1Set certSet) + { + if (certSet != null) + { + List certList = new ArrayList(certSet.size()); + + for (Enumeration en = certSet.getObjects(); en.hasMoreElements();) + { + ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); + + if (obj instanceof ASN1Sequence) + { + certList.add(new X509CertificateHolder(Certificate.getInstance(obj))); + } + } + + return new CollectionStore(certList); + } + + return new CollectionStore(new ArrayList()); + } + + Store getAttributeCertificates(ASN1Set certSet) + { + if (certSet != null) + { + List certList = new ArrayList(certSet.size()); + + for (Enumeration en = certSet.getObjects(); en.hasMoreElements();) + { + ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); + + if (obj instanceof ASN1TaggedObject) + { + certList.add(new X509AttributeCertificateHolder(AttributeCertificate.getInstance(((ASN1TaggedObject)obj).getObject()))); + } + } + + return new CollectionStore(certList); + } + + return new CollectionStore(new ArrayList()); + } + + Store getCRLs(ASN1Set crlSet) + { + if (crlSet != null) + { + List crlList = new ArrayList(crlSet.size()); + + for (Enumeration en = crlSet.getObjects(); en.hasMoreElements();) + { + ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); + + if (obj instanceof ASN1Sequence) + { + crlList.add(new X509CRLHolder(CertificateList.getInstance(obj))); + } + } + + return new CollectionStore(crlList); + } + + return new CollectionStore(new ArrayList()); + } + + // BEGIN Android-removed: OtherRevocationInfoFormat isn't supported + /* + Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoFormat, ASN1Set crlSet) + { + if (crlSet != null) + { + List crlList = new ArrayList(crlSet.size()); + + for (Enumeration en = crlSet.getObjects(); en.hasMoreElements();) + { + ASN1Primitive obj = ((ASN1Encodable)en.nextElement()).toASN1Primitive(); + + if (obj instanceof ASN1TaggedObject) + { + ASN1TaggedObject tObj = ASN1TaggedObject.getInstance(obj); + + if (tObj.getTagNo() == 1) + { + OtherRevocationInfoFormat other = OtherRevocationInfoFormat.getInstance(tObj, false); + + if (otherRevocationInfoFormat.equals(other.getInfoFormat())) + { + crlList.add(other.getInfo()); + } + } + } + } + + return new CollectionStore(crlList); + } + + return new CollectionStore(new ArrayList()); + } + */ + // END Android-removed: OtherRevocationInfoFormat isn't supported +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignerDigestMismatchException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignerDigestMismatchException.java new file mode 100644 index 00000000..53ae42e9 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSSignerDigestMismatchException.java @@ -0,0 +1,15 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class CMSSignerDigestMismatchException + extends CMSException +{ + public CMSSignerDigestMismatchException( + String msg) + { + super(msg); + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSTypedData.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSTypedData.java new file mode 100644 index 00000000..c589dc7b --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSTypedData.java @@ -0,0 +1,13 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier; + +/** + * @hide This class is not part of the Android public SDK API + */ +public interface CMSTypedData + extends CMSProcessable +{ + ASN1ObjectIdentifier getContentType(); +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSUtils.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSUtils.java new file mode 100644 index 00000000..a8032604 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSUtils.java @@ -0,0 +1,396 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import com.android.internal.org.bouncycastle.asn1.ASN1Encodable; +import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector; +import com.android.internal.org.bouncycastle.asn1.ASN1InputStream; +import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier; +import com.android.internal.org.bouncycastle.asn1.ASN1Set; +import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject; +import com.android.internal.org.bouncycastle.asn1.BEROctetStringGenerator; +import com.android.internal.org.bouncycastle.asn1.BERSet; +import com.android.internal.org.bouncycastle.asn1.DERNull; +import com.android.internal.org.bouncycastle.asn1.DERSet; +import com.android.internal.org.bouncycastle.asn1.DERTaggedObject; +import com.android.internal.org.bouncycastle.asn1.cms.CMSObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.cms.ContentInfo; +// Android-removed: Unsupported algorithms +// import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; +// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; +// import org.bouncycastle.asn1.ocsp.OCSPResponse; +// import org.bouncycastle.asn1.ocsp.OCSPResponseStatus; +// import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +// import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +// import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; +// import org.bouncycastle.asn1.sec.SECObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier; +// import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import com.android.internal.org.bouncycastle.cert.X509AttributeCertificateHolder; +import com.android.internal.org.bouncycastle.cert.X509CRLHolder; +import com.android.internal.org.bouncycastle.cert.X509CertificateHolder; +import com.android.internal.org.bouncycastle.operator.DigestCalculator; +import com.android.internal.org.bouncycastle.util.Store; +import com.android.internal.org.bouncycastle.util.Strings; +import com.android.internal.org.bouncycastle.util.io.Streams; +import com.android.internal.org.bouncycastle.util.io.TeeInputStream; +import com.android.internal.org.bouncycastle.util.io.TeeOutputStream; + +class CMSUtils +{ + private static final Set<String> des = new HashSet<String>(); + private static final Set mqvAlgs = new HashSet(); + private static final Set ecAlgs = new HashSet(); + private static final Set gostAlgs = new HashSet(); + + static + { + des.add("DES"); + des.add("DESEDE"); + // BEGIN Android-removed: Unsupported algorithms + /* + des.add(OIWObjectIdentifiers.desCBC.getId()); + des.add(PKCSObjectIdentifiers.des_EDE3_CBC.getId()); + des.add(PKCSObjectIdentifiers.des_EDE3_CBC.getId()); + des.add(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId()); + + mqvAlgs.add(X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme); + mqvAlgs.add(SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme); + mqvAlgs.add(SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme); + mqvAlgs.add(SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme); + mqvAlgs.add(SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme); + + ecAlgs.add(X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme); + ecAlgs.add(X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme); + ecAlgs.add(SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme); + + gostAlgs.add(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_ESDH); + gostAlgs.add(RosstandartObjectIdentifiers.id_tc26_agreement_gost_3410_12_256); + gostAlgs.add(RosstandartObjectIdentifiers.id_tc26_agreement_gost_3410_12_512); + */ + // END Android-removed: Unsupported algorithms + } + + static boolean isMQV(ASN1ObjectIdentifier algorithm) + { + return mqvAlgs.contains(algorithm); + } + + static boolean isEC(ASN1ObjectIdentifier algorithm) + { + return ecAlgs.contains(algorithm); + } + + static boolean isGOST(ASN1ObjectIdentifier algorithm) + { + return gostAlgs.contains(algorithm); + } + + // BEGIN Android-removed: Unsupported algorithms + /* + static boolean isRFC2631(ASN1ObjectIdentifier algorithm) + { + return algorithm.equals(PKCSObjectIdentifiers.id_alg_ESDH) || algorithm.equals(PKCSObjectIdentifiers.id_alg_SSDH); + } + */ + // END Android-removed: Unsupported algorithms + + static boolean isDES(String algorithmID) + { + String name = Strings.toUpperCase(algorithmID); + + return des.contains(name); + } + + static boolean isEquivalent(AlgorithmIdentifier algId1, AlgorithmIdentifier algId2) + { + if (algId1 == null || algId2 == null) + { + return false; + } + + if (!algId1.getAlgorithm().equals(algId2.getAlgorithm())) + { + return false; + } + + ASN1Encodable params1 = algId1.getParameters(); + ASN1Encodable params2 = algId2.getParameters(); + if (params1 != null) + { + return params1.equals(params2) || (params1.equals(DERNull.INSTANCE) && params2 == null); + } + + return params2 == null || params2.equals(DERNull.INSTANCE); + } + + static ContentInfo readContentInfo( + byte[] input) + throws CMSException + { + // enforce limit checking as from a byte array + return readContentInfo(new ASN1InputStream(input)); + } + + static ContentInfo readContentInfo( + InputStream input) + throws CMSException + { + // enforce some limit checking + return readContentInfo(new ASN1InputStream(input)); + } + + static List getCertificatesFromStore(Store certStore) + throws CMSException + { + List certs = new ArrayList(); + + try + { + for (Iterator it = certStore.getMatches(null).iterator(); it.hasNext(); ) + { + X509CertificateHolder c = (X509CertificateHolder)it.next(); + + certs.add(c.toASN1Structure()); + } + + return certs; + } + catch (ClassCastException e) + { + throw new CMSException("error processing certs", e); + } + } + + static List getAttributeCertificatesFromStore(Store attrStore) + throws CMSException + { + List certs = new ArrayList(); + + try + { + for (Iterator it = attrStore.getMatches(null).iterator(); it.hasNext(); ) + { + X509AttributeCertificateHolder attrCert = (X509AttributeCertificateHolder)it.next(); + + certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure())); + } + + return certs; + } + catch (ClassCastException e) + { + throw new CMSException("error processing certs", e); + } + } + + + static List getCRLsFromStore(Store crlStore) + throws CMSException + { + List crls = new ArrayList(); + + try + { + for (Iterator it = crlStore.getMatches(null).iterator(); it.hasNext(); ) + { + Object rev = it.next(); + + if (rev instanceof X509CRLHolder) + { + X509CRLHolder c = (X509CRLHolder)rev; + + crls.add(c.toASN1Structure()); + } + // BEGIN Android-removed: OtherRevocationInfoFormat isn't supported + // else if (rev instanceof OtherRevocationInfoFormat) + // { + // OtherRevocationInfoFormat infoFormat = OtherRevocationInfoFormat.getInstance(rev); + // + // validateInfoFormat(infoFormat); + // + // crls.add(new DERTaggedObject(false, 1, infoFormat)); + // } + // END Android-removed: OtherRevocationInfoFormat isn't supported + else if (rev instanceof ASN1TaggedObject) + { + crls.add(rev); + } + } + + return crls; + } + catch (ClassCastException e) + { + throw new CMSException("error processing certs", e); + } + } + + // BEGIN Android-removed: OtherRevocationInfoFormat isn't supported + /* + private static void validateInfoFormat(OtherRevocationInfoFormat infoFormat) + { + if (CMSObjectIdentifiers.id_ri_ocsp_response.equals(infoFormat.getInfoFormat())) + { + OCSPResponse resp = OCSPResponse.getInstance(infoFormat.getInfo()); + + if (OCSPResponseStatus.SUCCESSFUL != resp.getResponseStatus().getIntValue()) + { + throw new IllegalArgumentException("cannot add unsuccessful OCSP response to CMS SignedData"); + } + } + } + + static Collection getOthersFromStore(ASN1ObjectIdentifier otherRevocationInfoFormat, Store otherRevocationInfos) + { + List others = new ArrayList(); + + for (Iterator it = otherRevocationInfos.getMatches(null).iterator(); it.hasNext(); ) + { + ASN1Encodable info = (ASN1Encodable)it.next(); + OtherRevocationInfoFormat infoFormat = new OtherRevocationInfoFormat(otherRevocationInfoFormat, info); + + validateInfoFormat(infoFormat); + + others.add(new DERTaggedObject(false, 1, infoFormat)); + } + + return others; + } + */ + // END Android-removed: OtherRevocationInfoFormat isn't supported + + static ASN1Set createBerSetFromList(List derObjects) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + for (Iterator it = derObjects.iterator(); it.hasNext(); ) + { + v.add((ASN1Encodable)it.next()); + } + + return new BERSet(v); + } + + static ASN1Set createDerSetFromList(List derObjects) + { + ASN1EncodableVector v = new ASN1EncodableVector(); + + for (Iterator it = derObjects.iterator(); it.hasNext(); ) + { + v.add((ASN1Encodable)it.next()); + } + + return new DERSet(v); + } + + static OutputStream createBEROctetOutputStream(OutputStream s, + int tagNo, boolean isExplicit, int bufferSize) + throws IOException + { + BEROctetStringGenerator octGen = new BEROctetStringGenerator(s, tagNo, isExplicit); + + if (bufferSize != 0) + { + return octGen.getOctetOutputStream(new byte[bufferSize]); + } + + return octGen.getOctetOutputStream(); + } + + private static ContentInfo readContentInfo( + ASN1InputStream in) + throws CMSException + { + try + { + ContentInfo info = ContentInfo.getInstance(in.readObject()); + if (info == null) + { + throw new CMSException("No content found."); + } + + return info; + } + catch (IOException e) + { + throw new CMSException("IOException reading content.", e); + } + catch (ClassCastException e) + { + throw new CMSException("Malformed content.", e); + } + catch (IllegalArgumentException e) + { + throw new CMSException("Malformed content.", e); + } + } + + public static byte[] streamToByteArray( + InputStream in) + throws IOException + { + return Streams.readAll(in); + } + + public static byte[] streamToByteArray( + InputStream in, + int limit) + throws IOException + { + return Streams.readAllLimited(in, limit); + } + + static InputStream attachDigestsToInputStream(Collection digests, InputStream s) + { + InputStream result = s; + Iterator it = digests.iterator(); + while (it.hasNext()) + { + DigestCalculator digest = (DigestCalculator)it.next(); + result = new TeeInputStream(result, digest.getOutputStream()); + } + return result; + } + + static OutputStream attachSignersToOutputStream(Collection signers, OutputStream s) + { + OutputStream result = s; + Iterator it = signers.iterator(); + while (it.hasNext()) + { + SignerInfoGenerator signerGen = (SignerInfoGenerator)it.next(); + result = getSafeTeeOutputStream(result, signerGen.getCalculatingOutputStream()); + } + return result; + } + + static OutputStream getSafeOutputStream(OutputStream s) + { + return s == null ? new NullOutputStream() : s; + } + + static OutputStream getSafeTeeOutputStream(OutputStream s1, + OutputStream s2) + { + return s1 == null ? getSafeOutputStream(s2) + : s2 == null ? getSafeOutputStream(s1) : new TeeOutputStream( + s1, s2); + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSVerifierCertificateNotValidException.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSVerifierCertificateNotValidException.java new file mode 100644 index 00000000..3ad28616 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/CMSVerifierCertificateNotValidException.java @@ -0,0 +1,15 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class CMSVerifierCertificateNotValidException + extends CMSException +{ + public CMSVerifierCertificateNotValidException( + String msg) + { + super(msg); + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java new file mode 100644 index 00000000..45a401c4 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java @@ -0,0 +1,249 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.util.HashMap; +import java.util.Map; + +import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier; +// Android-removed: Unsupported algorithms +// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers; +// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.eac.EACObjectIdentifiers; +// import org.bouncycastle.asn1.gm.GMObjectIdentifiers; +// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +// import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import com.android.internal.org.bouncycastle.asn1.x509.X509ObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.x9.X9ObjectIdentifiers; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class DefaultCMSSignatureAlgorithmNameGenerator + implements CMSSignatureAlgorithmNameGenerator +{ + private final Map encryptionAlgs = new HashMap(); + private final Map digestAlgs = new HashMap(); + + private void addEntries(ASN1ObjectIdentifier alias, String digest, String encryption) + { + digestAlgs.put(alias, digest); + encryptionAlgs.put(alias, encryption); + } + + public DefaultCMSSignatureAlgorithmNameGenerator() + { + addEntries(NISTObjectIdentifiers.dsa_with_sha224, "SHA224", "DSA"); + addEntries(NISTObjectIdentifiers.dsa_with_sha256, "SHA256", "DSA"); + addEntries(NISTObjectIdentifiers.dsa_with_sha384, "SHA384", "DSA"); + addEntries(NISTObjectIdentifiers.dsa_with_sha512, "SHA512", "DSA"); + // BEGIN Android-removed: Unsupported algorithms + /* + addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_224, "SHA3-224", "DSA"); + addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_256, "SHA3-256", "DSA"); + addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_384, "SHA3-384", "DSA"); + addEntries(NISTObjectIdentifiers.id_dsa_with_sha3_512, "SHA3-512", "DSA"); + addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224, "SHA3-224", "RSA"); + addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256, "SHA3-256", "RSA"); + addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384, "SHA3-384", "RSA"); + addEntries(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512, "SHA3-512", "RSA"); + addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_224, "SHA3-224", "ECDSA"); + addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_256, "SHA3-256", "ECDSA"); + addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_384, "SHA3-384", "ECDSA"); + addEntries(NISTObjectIdentifiers.id_ecdsa_with_sha3_512, "SHA3-512", "ECDSA"); + */ + // END Android-removed: Unsupported algorithms + addEntries(OIWObjectIdentifiers.dsaWithSHA1, "SHA1", "DSA"); + // BEGIN Android-removed: Unsupported algorithms + // addEntries(OIWObjectIdentifiers.md4WithRSA, "MD4", "RSA"); + // addEntries(OIWObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA"); + // END Android-removed: Unsupported algorithms + addEntries(OIWObjectIdentifiers.md5WithRSA, "MD5", "RSA"); + addEntries(OIWObjectIdentifiers.sha1WithRSA, "SHA1", "RSA"); + // BEGIN Android-removed: Unsupported algorithms + // addEntries(PKCSObjectIdentifiers.md2WithRSAEncryption, "MD2", "RSA"); + // addEntries(PKCSObjectIdentifiers.md4WithRSAEncryption, "MD4", "RSA"); + // END Android-removed: Unsupported algorithms + addEntries(PKCSObjectIdentifiers.md5WithRSAEncryption, "MD5", "RSA"); + addEntries(PKCSObjectIdentifiers.sha1WithRSAEncryption, "SHA1", "RSA"); + addEntries(PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224", "RSA"); + addEntries(PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256", "RSA"); + addEntries(PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384", "RSA"); + addEntries(PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512", "RSA"); + + // BEGIN Android-removed: Unsupported algorithms + /* + addEntries(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, "RIPEMD128", "RSA"); + addEntries(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, "RIPEMD160", "RSA"); + addEntries(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, "RIPEMD256", "RSA"); + */ + // END Android-removed: Unsupported algorithms + + addEntries(X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1", "ECDSA"); + addEntries(X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224", "ECDSA"); + addEntries(X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256", "ECDSA"); + addEntries(X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384", "ECDSA"); + addEntries(X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512", "ECDSA"); + addEntries(X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1", "DSA"); + addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_1, "SHA1", "ECDSA"); + addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_224, "SHA224", "ECDSA"); + addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_256, "SHA256", "ECDSA"); + addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_384, "SHA384", "ECDSA"); + addEntries(EACObjectIdentifiers.id_TA_ECDSA_SHA_512, "SHA512", "ECDSA"); + addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_1, "SHA1", "RSA"); + addEntries(EACObjectIdentifiers.id_TA_RSA_v1_5_SHA_256, "SHA256", "RSA"); + addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_1, "SHA1", "RSAandMGF1"); + addEntries(EACObjectIdentifiers.id_TA_RSA_PSS_SHA_256, "SHA256", "RSAandMGF1"); + // BEGIN Android-removed: Unsupported algorithms + /* + addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA1, "SHA1", "PLAIN-ECDSA"); + addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA224, "SHA224", "PLAIN-ECDSA"); + addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA256, "SHA256", "PLAIN-ECDSA"); + addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA384, "SHA384", "PLAIN-ECDSA"); + addEntries(BSIObjectIdentifiers.ecdsa_plain_SHA512, "SHA512", "PLAIN-ECDSA"); + addEntries(BSIObjectIdentifiers.ecdsa_plain_RIPEMD160, "RIPEMD160", "PLAIN-ECDSA"); + + addEntries(GMObjectIdentifiers.sm2sign_with_rmd160, "RIPEMD160", "SM2"); + addEntries(GMObjectIdentifiers.sm2sign_with_sha1, "SHA1", "SM2"); + addEntries(GMObjectIdentifiers.sm2sign_with_sha224, "SHA224", "SM2"); + addEntries(GMObjectIdentifiers.sm2sign_with_sha256, "SHA256", "SM2"); + addEntries(GMObjectIdentifiers.sm2sign_with_sha384, "SHA384", "SM2"); + addEntries(GMObjectIdentifiers.sm2sign_with_sha512, "SHA512", "SM2"); + addEntries(GMObjectIdentifiers.sm2sign_with_sm3, "SM3", "SM2"); + */ + // END Android-removed: Unsupported algorithms + + encryptionAlgs.put(X9ObjectIdentifiers.id_dsa, "DSA"); + encryptionAlgs.put(PKCSObjectIdentifiers.rsaEncryption, "RSA"); + encryptionAlgs.put(TeleTrusTObjectIdentifiers.teleTrusTRSAsignatureAlgorithm, "RSA"); + encryptionAlgs.put(X509ObjectIdentifiers.id_ea_rsa, "RSA"); + encryptionAlgs.put(PKCSObjectIdentifiers.id_RSASSA_PSS, "RSAandMGF1"); + // BEGIN Android-removed: Unsupported algorithms + /* + encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_94, "GOST3410"); + encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3410_2001, "ECGOST3410"); + encryptionAlgs.put(new ASN1ObjectIdentifier("1.3.6.1.4.1.5849.1.6.2"), "ECGOST3410"); + encryptionAlgs.put(new ASN1ObjectIdentifier("1.3.6.1.4.1.5849.1.1.5"), "GOST3410"); + encryptionAlgs.put(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256, "ECGOST3410-2012-256"); + encryptionAlgs.put(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512, "ECGOST3410-2012-512"); + encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, "ECGOST3410"); + encryptionAlgs.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, "GOST3410"); + encryptionAlgs.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, "ECGOST3410-2012-256"); + encryptionAlgs.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, "ECGOST3410-2012-512"); + + digestAlgs.put(PKCSObjectIdentifiers.md2, "MD2"); + digestAlgs.put(PKCSObjectIdentifiers.md4, "MD4"); + */ + // END Android-removed: Unsupported algorithms + digestAlgs.put(PKCSObjectIdentifiers.md5, "MD5"); + digestAlgs.put(OIWObjectIdentifiers.idSHA1, "SHA1"); + digestAlgs.put(NISTObjectIdentifiers.id_sha224, "SHA224"); + digestAlgs.put(NISTObjectIdentifiers.id_sha256, "SHA256"); + digestAlgs.put(NISTObjectIdentifiers.id_sha384, "SHA384"); + digestAlgs.put(NISTObjectIdentifiers.id_sha512, "SHA512"); + // BEGIN Android-removed: Unsupported algorithms + /* + digestAlgs.put(NISTObjectIdentifiers.id_sha3_224, "SHA3-224"); + digestAlgs.put(NISTObjectIdentifiers.id_sha3_256, "SHA3-256"); + digestAlgs.put(NISTObjectIdentifiers.id_sha3_384, "SHA3-384"); + digestAlgs.put(NISTObjectIdentifiers.id_sha3_512, "SHA3-512"); + digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD128"); + digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD160"); + digestAlgs.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD256"); + digestAlgs.put(CryptoProObjectIdentifiers.gostR3411, "GOST3411"); + digestAlgs.put(new ASN1ObjectIdentifier("1.3.6.1.4.1.5849.1.2.1"), "GOST3411"); + digestAlgs.put(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_256, "GOST3411-2012-256"); + digestAlgs.put(RosstandartObjectIdentifiers.id_tc26_gost_3411_12_512, "GOST3411-2012-512"); + digestAlgs.put(GMObjectIdentifiers.sm3, "SM3"); + */ + // END Android-removed: Unsupported algorithms + } + + /** + * Return the digest algorithm using one of the standard JCA string + * representations rather than the algorithm identifier (if possible). + */ + private String getDigestAlgName( + ASN1ObjectIdentifier digestAlgOID) + { + String algName = (String)digestAlgs.get(digestAlgOID); + + if (algName != null) + { + return algName; + } + + return digestAlgOID.getId(); + } + + /** + * Return the digest encryption algorithm using one of the standard + * JCA string representations rather the the algorithm identifier (if + * possible). + */ + private String getEncryptionAlgName( + ASN1ObjectIdentifier encryptionAlgOID) + { + String algName = (String)encryptionAlgs.get(encryptionAlgOID); + + if (algName != null) + { + return algName; + } + + return encryptionAlgOID.getId(); + } + + /** + * Set the mapping for the encryption algorithm used in association with a SignedData generation + * or interpretation. + * + * @param oid object identifier to map. + * @param algorithmName algorithm name to use. + */ + protected void setSigningEncryptionAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName) + { + encryptionAlgs.put(oid, algorithmName); + } + + /** + * Set the mapping for the digest algorithm to use in conjunction with a SignedData generation + * or interpretation. + * + * @param oid object identifier to map. + * @param algorithmName algorithm name to use. + */ + protected void setSigningDigestAlgorithmMapping(ASN1ObjectIdentifier oid, String algorithmName) + { + digestAlgs.put(oid, algorithmName); + } + + public String getSignatureName(AlgorithmIdentifier digestAlg, AlgorithmIdentifier encryptionAlg) + { + // BEGIN Android-removed: unsupported algorithms + /* + if (EdECObjectIdentifiers.id_Ed25519.equals(encryptionAlg.getAlgorithm())) + { + return "Ed25519"; + } + if (EdECObjectIdentifiers.id_Ed448.equals(encryptionAlg.getAlgorithm())) + { + return "Ed448"; + } + */ + // END Android-removed: unsupported algorithms + + String digestName = getDigestAlgName(encryptionAlg.getAlgorithm()); + + if (!digestName.equals(encryptionAlg.getAlgorithm().getId())) + { + return digestName + "with" + getEncryptionAlgName(encryptionAlg.getAlgorithm()); + } + + return getDigestAlgName(digestAlg.getAlgorithm()) + "with" + getEncryptionAlgName(encryptionAlg.getAlgorithm()); + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java new file mode 100644 index 00000000..f82906b2 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java @@ -0,0 +1,75 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.android.internal.org.bouncycastle.asn1.DERNull; +// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +// import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class DefaultCMSSignatureEncryptionAlgorithmFinder + implements CMSSignatureEncryptionAlgorithmFinder +{ + private static final Set RSA_PKCS1d5 = new HashSet(); + private static final Map GOST_ENC = new HashMap(); + + static + { + // BEGIN Android-removed: Unsupported algorithms + // RSA_PKCS1d5.add(PKCSObjectIdentifiers.md2WithRSAEncryption); + // RSA_PKCS1d5.add(PKCSObjectIdentifiers.md4WithRSAEncryption); + // END Android-removed: Unsupported algorithms + RSA_PKCS1d5.add(PKCSObjectIdentifiers.md5WithRSAEncryption); + RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha1WithRSAEncryption); + // BEGIN Android-added: Add support for SHA-2 family signatures + RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha224WithRSAEncryption); + RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha256WithRSAEncryption); + RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha384WithRSAEncryption); + RSA_PKCS1d5.add(PKCSObjectIdentifiers.sha512WithRSAEncryption); + // END Android-added: Add support for SHA-2 family signatures + // BEGIN Android-removed: Unsupported algorithms + // RSA_PKCS1d5.add(OIWObjectIdentifiers.md4WithRSAEncryption); + // RSA_PKCS1d5.add(OIWObjectIdentifiers.md4WithRSA); + // END Android-removed: Unsupported algorithms + RSA_PKCS1d5.add(OIWObjectIdentifiers.md5WithRSA); + RSA_PKCS1d5.add(OIWObjectIdentifiers.sha1WithRSA); + // BEGIN Android-removed: Unsupported algorithms + /* + RSA_PKCS1d5.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); + RSA_PKCS1d5.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); + RSA_PKCS1d5.add(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); + GOST_ENC.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, + new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, DERNull.INSTANCE)); + GOST_ENC.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, + new AlgorithmIdentifier(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256, DERNull.INSTANCE)); + GOST_ENC.put(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, + new AlgorithmIdentifier(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512, DERNull.INSTANCE)); + */ + // END Android-removed: Unsupported algorithms + } + + public AlgorithmIdentifier findEncryptionAlgorithm(AlgorithmIdentifier signatureAlgorithm) + { + // RFC3370 section 3.2 with RFC 5754 update + if (RSA_PKCS1d5.contains(signatureAlgorithm.getAlgorithm())) + { + return new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE); + } + // GOST signature encryption algorithms + if (GOST_ENC.containsKey(signatureAlgorithm.getAlgorithm())) + { + return (AlgorithmIdentifier)GOST_ENC.get(signatureAlgorithm.getAlgorithm()); + } + return signatureAlgorithm; + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java new file mode 100644 index 00000000..ca171288 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java @@ -0,0 +1,133 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.util.Date; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Map; + +import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier; +import com.android.internal.org.bouncycastle.asn1.DEROctetString; +import com.android.internal.org.bouncycastle.asn1.DERSet; +import com.android.internal.org.bouncycastle.asn1.cms.Attribute; +import com.android.internal.org.bouncycastle.asn1.cms.AttributeTable; +import com.android.internal.org.bouncycastle.asn1.cms.CMSAlgorithmProtection; +import com.android.internal.org.bouncycastle.asn1.cms.CMSAttributes; +import com.android.internal.org.bouncycastle.asn1.cms.Time; +import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +/** + * Default signed attributes generator. + * @hide This class is not part of the Android public SDK API + */ +public class DefaultSignedAttributeTableGenerator + implements CMSAttributeTableGenerator +{ + private final Hashtable table; + + /** + * Initialise to use all defaults + */ + public DefaultSignedAttributeTableGenerator() + { + table = new Hashtable(); + } + + /** + * Initialise with some extra attributes or overrides. + * + * @param attributeTable initial attribute table to use. + */ + public DefaultSignedAttributeTableGenerator( + AttributeTable attributeTable) + { + if (attributeTable != null) + { + table = attributeTable.toHashtable(); + } + else + { + table = new Hashtable(); + } + } + + /** + * Create a standard attribute table from the passed in parameters - this will + * normally include contentType, signingTime, messageDigest, and CMS algorithm protection. + * If the constructor using an AttributeTable was used, entries in it for contentType, signingTime, and + * messageDigest will override the generated ones. + * + * @param parameters source parameters for table generation. + * + * @return a filled in Hashtable of attributes. + */ + protected Hashtable createStandardAttributeTable( + Map parameters) + { + Hashtable std = copyHashTable(table); + + if (!std.containsKey(CMSAttributes.contentType)) + { + ASN1ObjectIdentifier contentType = ASN1ObjectIdentifier.getInstance( + parameters.get(CMSAttributeTableGenerator.CONTENT_TYPE)); + + // contentType will be null if we're trying to generate a counter signature. + if (contentType != null) + { + Attribute attr = new Attribute(CMSAttributes.contentType, + new DERSet(contentType)); + std.put(attr.getAttrType(), attr); + } + } + + if (!std.containsKey(CMSAttributes.signingTime)) + { + Date signingTime = new Date(); + Attribute attr = new Attribute(CMSAttributes.signingTime, + new DERSet(new Time(signingTime))); + std.put(attr.getAttrType(), attr); + } + + if (!std.containsKey(CMSAttributes.messageDigest)) + { + byte[] messageDigest = (byte[])parameters.get( + CMSAttributeTableGenerator.DIGEST); + Attribute attr = new Attribute(CMSAttributes.messageDigest, + new DERSet(new DEROctetString(messageDigest))); + std.put(attr.getAttrType(), attr); + } + + if (!std.contains(CMSAttributes.cmsAlgorithmProtect)) + { + Attribute attr = new Attribute(CMSAttributes.cmsAlgorithmProtect, new DERSet(new CMSAlgorithmProtection( + (AlgorithmIdentifier)parameters.get(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER), + CMSAlgorithmProtection.SIGNATURE, (AlgorithmIdentifier)parameters.get(CMSAttributeTableGenerator.SIGNATURE_ALGORITHM_IDENTIFIER)))); + std.put(attr.getAttrType(), attr); + } + + return std; + } + + /** + * @param parameters source parameters + * @return the populated attribute table + */ + public AttributeTable getAttributes(Map parameters) + { + return new AttributeTable(createStandardAttributeTable(parameters)); + } + + private static Hashtable copyHashTable(Hashtable paramsMap) + { + Hashtable newTable = new Hashtable(); + + Enumeration keys = paramsMap.keys(); + while (keys.hasMoreElements()) + { + Object key = keys.nextElement(); + newTable.put(key, paramsMap.get(key)); + } + + return newTable; + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/NullOutputStream.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/NullOutputStream.java new file mode 100644 index 00000000..f434fd7c --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/NullOutputStream.java @@ -0,0 +1,29 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +/** + * + */ +package com.android.internal.org.bouncycastle.cms; + +import java.io.IOException; +import java.io.OutputStream; + +class NullOutputStream + extends OutputStream +{ + public void write(byte[] buf) + throws IOException + { + // do nothing + } + + public void write(byte[] buf, int off, int len) + throws IOException + { + // do nothing + } + + public void write(int b) throws IOException + { + // do nothing + } +}
\ No newline at end of file diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PKCS7ProcessableObject.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PKCS7ProcessableObject.java new file mode 100644 index 00000000..d836a68e --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PKCS7ProcessableObject.java @@ -0,0 +1,69 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; + +import com.android.internal.org.bouncycastle.asn1.ASN1Encodable; +import com.android.internal.org.bouncycastle.asn1.ASN1Encoding; +import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier; +import com.android.internal.org.bouncycastle.asn1.ASN1Sequence; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class PKCS7ProcessableObject + implements CMSTypedData +{ + private final ASN1ObjectIdentifier type; + private final ASN1Encodable structure; + + public PKCS7ProcessableObject( + ASN1ObjectIdentifier type, + ASN1Encodable structure) + { + this.type = type; + this.structure = structure; + } + + public ASN1ObjectIdentifier getContentType() + { + return type; + } + + public void write(OutputStream cOut) + throws IOException, CMSException + { + if (structure instanceof ASN1Sequence) + { + ASN1Sequence s = ASN1Sequence.getInstance(structure); + + for (Iterator it = s.iterator(); it.hasNext();) + { + ASN1Encodable enc = (ASN1Encodable)it.next(); + + cOut.write(enc.toASN1Primitive().getEncoded(ASN1Encoding.DER)); + } + } + else + { + byte[] encoded = structure.toASN1Primitive().getEncoded(ASN1Encoding.DER); + int index = 1; + + while ((encoded[index] & 0xff) > 127) + { + index++; + } + + index++; + + cOut.write(encoded, index, encoded.length - index); + } + } + + public Object getContent() + { + return structure; + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PasswordRecipient.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PasswordRecipient.java new file mode 100644 index 00000000..106dc9fe --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/PasswordRecipient.java @@ -0,0 +1,54 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import com.android.internal.org.bouncycastle.asn1.DERNull; +import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +/** + * @hide This class is not part of the Android public SDK API + */ +public interface PasswordRecipient + extends Recipient +{ + public static final int PKCS5_SCHEME2 = 0; + public static final int PKCS5_SCHEME2_UTF8 = 1; + + static final class PRF + { + public static final PRF HMacSHA1 = new PRF("HMacSHA1", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA1, DERNull.INSTANCE)); + public static final PRF HMacSHA224 = new PRF("HMacSHA224", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA224, DERNull.INSTANCE)); + public static final PRF HMacSHA256 = new PRF("HMacSHA256", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA256, DERNull.INSTANCE)); + public static final PRF HMacSHA384 = new PRF("HMacSHA384", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA384, DERNull.INSTANCE)); + public static final PRF HMacSHA512 = new PRF("HMacSHA512", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA512, DERNull.INSTANCE)); + + private final String hmac; + final AlgorithmIdentifier prfAlgID; + + private PRF(String hmac, AlgorithmIdentifier prfAlgID) + { + this.hmac = hmac; + this.prfAlgID = prfAlgID; + } + + public String getName() + { + return hmac; + } + + public AlgorithmIdentifier getAlgorithmID() + { + return prfAlgID; + } + } + + byte[] calculateDerivedKey(int schemeID, AlgorithmIdentifier derivationAlgorithm, int keySize) + throws CMSException; + + RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] derivedKey, byte[] encryptedEncryptedContentKey) + throws CMSException; + + int getPasswordConversionScheme(); + + char[] getPassword(); +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/Recipient.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/Recipient.java new file mode 100644 index 00000000..2b5ab03b --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/Recipient.java @@ -0,0 +1,9 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +/** + * @hide This class is not part of the Android public SDK API + */ +public interface Recipient +{ +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/RecipientOperator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/RecipientOperator.java new file mode 100644 index 00000000..6b3dff40 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/RecipientOperator.java @@ -0,0 +1,64 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.io.InputStream; +import java.io.OutputStream; + +// import org.bouncycastle.operator.InputAEADDecryptor; +import com.android.internal.org.bouncycastle.operator.InputDecryptor; +import com.android.internal.org.bouncycastle.operator.MacCalculator; +import com.android.internal.org.bouncycastle.util.io.TeeInputStream; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class RecipientOperator +{ + private final Object operator; + + public RecipientOperator(InputDecryptor decryptor) + { + this.operator = decryptor; + } + + public RecipientOperator(MacCalculator macCalculator) + { + this.operator = macCalculator; + } + + public InputStream getInputStream(InputStream dataIn) + { + if (operator instanceof InputDecryptor) + { + return ((InputDecryptor)operator).getInputStream(dataIn); + } + else + { + return new TeeInputStream(dataIn, ((MacCalculator)operator).getOutputStream()); + } + } + + // BEGIN Android-removed + /* + public boolean isAEADBased() + { + return operator instanceof InputAEADDecryptor; + } + + public OutputStream getAADStream() + { + return ((InputAEADDecryptor)operator).getAADStream(); + } + */ + // END Android-removed + + public boolean isMacBased() + { + return operator instanceof MacCalculator; + } + + public byte[] getMac() + { + return ((MacCalculator)operator).getMac(); + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerId.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerId.java new file mode 100644 index 00000000..f68e12c7 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerId.java @@ -0,0 +1,106 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.math.BigInteger; + +import com.android.internal.org.bouncycastle.asn1.x500.X500Name; +import com.android.internal.org.bouncycastle.cert.selector.X509CertificateHolderSelector; +import com.android.internal.org.bouncycastle.util.Selector; + +/** + * a basic index for a signer. + * @hide This class is not part of the Android public SDK API + */ +public class SignerId + implements Selector +{ + private X509CertificateHolderSelector baseSelector; + + private SignerId(X509CertificateHolderSelector baseSelector) + { + this.baseSelector = baseSelector; + } + + /** + * Construct a signer ID with the value of a public key's subjectKeyId. + * + * @param subjectKeyId a subjectKeyId + */ + public SignerId(byte[] subjectKeyId) + { + this(null, null, subjectKeyId); + } + + /** + * Construct a signer ID based on the issuer and serial number of the signer's associated + * certificate. + * + * @param issuer the issuer of the signer's associated certificate. + * @param serialNumber the serial number of the signer's associated certificate. + */ + public SignerId(X500Name issuer, BigInteger serialNumber) + { + this(issuer, serialNumber, null); + } + + /** + * Construct a signer ID based on the issuer and serial number of the signer's associated + * certificate. + * + * @param issuer the issuer of the signer's associated certificate. + * @param serialNumber the serial number of the signer's associated certificate. + * @param subjectKeyId the subject key identifier to use to match the signers associated certificate. + */ + public SignerId(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyId) + { + this(new X509CertificateHolderSelector(issuer, serialNumber, subjectKeyId)); + } + + public X500Name getIssuer() + { + return baseSelector.getIssuer(); + } + + public BigInteger getSerialNumber() + { + return baseSelector.getSerialNumber(); + } + + public byte[] getSubjectKeyIdentifier() + { + return baseSelector.getSubjectKeyIdentifier(); + } + + public int hashCode() + { + return baseSelector.hashCode(); + } + + public boolean equals( + Object o) + { + if (!(o instanceof SignerId)) + { + return false; + } + + SignerId id = (SignerId)o; + + return this.baseSelector.equals(id.baseSelector); + } + + public boolean match(Object obj) + { + if (obj instanceof SignerInformation) + { + return ((SignerInformation)obj).getSID().equals(this); + } + + return baseSelector.match(obj); + } + + public Object clone() + { + return new SignerId(this.baseSelector); + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGenerator.java new file mode 100644 index 00000000..b6d006a5 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGenerator.java @@ -0,0 +1,312 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import com.android.internal.org.bouncycastle.asn1.ASN1Encoding; +import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier; +import com.android.internal.org.bouncycastle.asn1.ASN1Set; +import com.android.internal.org.bouncycastle.asn1.DEROctetString; +import com.android.internal.org.bouncycastle.asn1.DERSet; +import com.android.internal.org.bouncycastle.asn1.cms.AttributeTable; +import com.android.internal.org.bouncycastle.asn1.cms.SignerIdentifier; +import com.android.internal.org.bouncycastle.asn1.cms.SignerInfo; +// import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; +// import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import com.android.internal.org.bouncycastle.cert.X509CertificateHolder; +import com.android.internal.org.bouncycastle.operator.ContentSigner; +import com.android.internal.org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; +import com.android.internal.org.bouncycastle.operator.DigestAlgorithmIdentifierFinder; +import com.android.internal.org.bouncycastle.operator.DigestCalculator; +import com.android.internal.org.bouncycastle.operator.DigestCalculatorProvider; +import com.android.internal.org.bouncycastle.operator.OperatorCreationException; +import com.android.internal.org.bouncycastle.util.Arrays; +import com.android.internal.org.bouncycastle.util.io.TeeOutputStream; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class SignerInfoGenerator +{ + private final SignerIdentifier signerIdentifier; + private final CMSAttributeTableGenerator sAttrGen; + private final CMSAttributeTableGenerator unsAttrGen; + private final ContentSigner signer; + private final DigestCalculator digester; + private final DigestAlgorithmIdentifierFinder digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder(); + private final CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder; + + private byte[] calculatedDigest = null; + private X509CertificateHolder certHolder; + + SignerInfoGenerator( + SignerIdentifier signerIdentifier, + ContentSigner signer, + DigestCalculatorProvider digesterProvider, + CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder) + throws OperatorCreationException + { + this(signerIdentifier, signer, digesterProvider, sigEncAlgFinder, false); + } + + SignerInfoGenerator( + SignerIdentifier signerIdentifier, + ContentSigner signer, + DigestCalculatorProvider digesterProvider, + CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder, + boolean isDirectSignature) + throws OperatorCreationException + { + this.signerIdentifier = signerIdentifier; + this.signer = signer; + + if (digesterProvider != null) + { + this.digester = digesterProvider.get(digAlgFinder.find(signer.getAlgorithmIdentifier())); + } + else + { + this.digester = null; + } + + if (isDirectSignature) + { + this.sAttrGen = null; + this.unsAttrGen = null; + } + else + { + this.sAttrGen = new DefaultSignedAttributeTableGenerator(); + this.unsAttrGen = null; + } + + this.sigEncAlgFinder = sigEncAlgFinder; + } + + public SignerInfoGenerator( + SignerInfoGenerator original, + CMSAttributeTableGenerator sAttrGen, + CMSAttributeTableGenerator unsAttrGen) + { + this.signerIdentifier = original.signerIdentifier; + this.signer = original.signer; + this.digester = original.digester; + this.sigEncAlgFinder = original.sigEncAlgFinder; + this.sAttrGen = sAttrGen; + this.unsAttrGen = unsAttrGen; + } + + SignerInfoGenerator( + SignerIdentifier signerIdentifier, + ContentSigner signer, + DigestCalculatorProvider digesterProvider, + CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder, + CMSAttributeTableGenerator sAttrGen, + CMSAttributeTableGenerator unsAttrGen) + throws OperatorCreationException + { + this.signerIdentifier = signerIdentifier; + this.signer = signer; + + if (digesterProvider != null) + { + this.digester = digesterProvider.get(digAlgFinder.find(signer.getAlgorithmIdentifier())); + } + else + { + this.digester = null; + } + + this.sAttrGen = sAttrGen; + this.unsAttrGen = unsAttrGen; + this.sigEncAlgFinder = sigEncAlgFinder; + } + + public SignerIdentifier getSID() + { + return signerIdentifier; + } + + public int getGeneratedVersion() + { + return signerIdentifier.isTagged() ? 3 : 1; + } + + public boolean hasAssociatedCertificate() + { + return certHolder != null; + } + + public X509CertificateHolder getAssociatedCertificate() + { + return certHolder; + } + + public AlgorithmIdentifier getDigestAlgorithm() + { + if (digester != null) + { + return digester.getAlgorithmIdentifier(); + } + + return digAlgFinder.find(signer.getAlgorithmIdentifier()); + } + + public OutputStream getCalculatingOutputStream() + { + if (digester != null) + { + if (sAttrGen == null) + { + return new TeeOutputStream(digester.getOutputStream(), signer.getOutputStream()); + } + return digester.getOutputStream(); + } + else + { + return signer.getOutputStream(); + } + } + + public SignerInfo generate(ASN1ObjectIdentifier contentType) + throws CMSException + { + try + { + /* RFC 3852 5.4 + * The result of the message digest calculation process depends on + * whether the signedAttrs field is present. When the field is absent, + * the result is just the message digest of the content as described + * + * above. When the field is present, however, the result is the message + * digest of the complete DER encoding of the SignedAttrs value + * contained in the signedAttrs field. + */ + ASN1Set signedAttr = null; + + AlgorithmIdentifier digestEncryptionAlgorithm = sigEncAlgFinder.findEncryptionAlgorithm(signer.getAlgorithmIdentifier()); + + AlgorithmIdentifier digestAlg = null; + + if (sAttrGen != null) + { + digestAlg = digester.getAlgorithmIdentifier(); + calculatedDigest = digester.getDigest(); + Map parameters = getBaseParameters(contentType, digester.getAlgorithmIdentifier(), digestEncryptionAlgorithm, calculatedDigest); + AttributeTable signed = sAttrGen.getAttributes(Collections.unmodifiableMap(parameters)); + + signedAttr = getAttributeSet(signed); + + // sig must be composed from the DER encoding. + OutputStream sOut = signer.getOutputStream(); + + sOut.write(signedAttr.getEncoded(ASN1Encoding.DER)); + + sOut.close(); + } + else + { + if (digester != null) + { + digestAlg = digester.getAlgorithmIdentifier(); + calculatedDigest = digester.getDigest(); + } + else + { + digestAlg = digAlgFinder.find(signer.getAlgorithmIdentifier()); + calculatedDigest = null; + } + } + + byte[] sigBytes = signer.getSignature(); + + ASN1Set unsignedAttr = null; + if (unsAttrGen != null) + { + Map parameters = getBaseParameters(contentType, digestAlg, digestEncryptionAlgorithm, calculatedDigest); + parameters.put(CMSAttributeTableGenerator.SIGNATURE, Arrays.clone(sigBytes)); + + AttributeTable unsigned = unsAttrGen.getAttributes(Collections.unmodifiableMap(parameters)); + + unsignedAttr = getAttributeSet(unsigned); + } + + if (sAttrGen == null) + { + // BEGIN Android-removed: Unsupported algorithms + /* + // RFC 8419, Section 3.2 - needs to be shake-256, not shake-256-len + if (EdECObjectIdentifiers.id_Ed448.equals(digestEncryptionAlgorithm.getAlgorithm())) + { + digestAlg = new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256); + } + */ + // END Android-removed: Unsupported algorithms + } + + return new SignerInfo(signerIdentifier, digestAlg, + signedAttr, digestEncryptionAlgorithm, new DEROctetString(sigBytes), unsignedAttr); + } + catch (IOException e) + { + throw new CMSException("encoding error.", e); + } + } + + void setAssociatedCertificate(X509CertificateHolder certHolder) + { + this.certHolder = certHolder; + } + + private ASN1Set getAttributeSet( + AttributeTable attr) + { + if (attr != null) + { + return new DERSet(attr.toASN1EncodableVector()); + } + + return null; + } + + private Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, AlgorithmIdentifier sigAlgId, byte[] hash) + { + Map param = new HashMap(); + + if (contentType != null) + { + param.put(CMSAttributeTableGenerator.CONTENT_TYPE, contentType); + } + + param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId); + param.put(CMSAttributeTableGenerator.SIGNATURE_ALGORITHM_IDENTIFIER, sigAlgId); + param.put(CMSAttributeTableGenerator.DIGEST, Arrays.clone(hash)); + + return param; + } + + public byte[] getCalculatedDigest() + { + if (calculatedDigest != null) + { + return Arrays.clone(calculatedDigest); + } + + return null; + } + + public CMSAttributeTableGenerator getSignedAttributeTableGenerator() + { + return sAttrGen; + } + + public CMSAttributeTableGenerator getUnsignedAttributeTableGenerator() + { + return unsAttrGen; + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java new file mode 100644 index 00000000..e6aea68b --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java @@ -0,0 +1,142 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import com.android.internal.org.bouncycastle.asn1.DEROctetString; +import com.android.internal.org.bouncycastle.asn1.cms.IssuerAndSerialNumber; +import com.android.internal.org.bouncycastle.asn1.cms.SignerIdentifier; +import com.android.internal.org.bouncycastle.cert.X509CertificateHolder; +import com.android.internal.org.bouncycastle.operator.ContentSigner; +import com.android.internal.org.bouncycastle.operator.DigestCalculatorProvider; +import com.android.internal.org.bouncycastle.operator.OperatorCreationException; + +/** + * Builder for SignerInfo generator objects. + * @hide This class is not part of the Android public SDK API + */ +public class SignerInfoGeneratorBuilder +{ + private DigestCalculatorProvider digestProvider; + private boolean directSignature; + private CMSAttributeTableGenerator signedGen; + private CMSAttributeTableGenerator unsignedGen; + private CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder; + + /** + * Base constructor. + * + * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations. + */ + public SignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider) + { + this(digestProvider, new DefaultCMSSignatureEncryptionAlgorithmFinder()); + } + + /** + * Base constructor with a particular finder for signature algorithms. + * + * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations. + * @param sigEncAlgFinder finder for algorithm IDs to store for the signature encryption/signature algorithm field. + */ + public SignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder) + { + this.digestProvider = digestProvider; + this.sigEncAlgFinder = sigEncAlgFinder; + } + + /** + * If the passed in flag is true, the signer signature will be based on the data, not + * a collection of signed attributes, and no signed attributes will be included. + * + * @return the builder object + */ + public SignerInfoGeneratorBuilder setDirectSignature(boolean hasNoSignedAttributes) + { + this.directSignature = hasNoSignedAttributes; + + return this; + } + + /** + * Provide a custom signed attribute generator. + * + * @param signedGen a generator of signed attributes. + * @return the builder object + */ + public SignerInfoGeneratorBuilder setSignedAttributeGenerator(CMSAttributeTableGenerator signedGen) + { + this.signedGen = signedGen; + + return this; + } + + /** + * Provide a generator of unsigned attributes. + * + * @param unsignedGen a generator for signed attributes. + * @return the builder object + */ + public SignerInfoGeneratorBuilder setUnsignedAttributeGenerator(CMSAttributeTableGenerator unsignedGen) + { + this.unsignedGen = unsignedGen; + + return this; + } + + /** + * Build a generator with the passed in certHolder issuer and serial number as the signerIdentifier. + * + * @param contentSigner operator for generating the final signature in the SignerInfo with. + * @param certHolder carrier for the X.509 certificate related to the contentSigner. + * @return a SignerInfoGenerator + * @throws OperatorCreationException if the generator cannot be built. + */ + public SignerInfoGenerator build(ContentSigner contentSigner, X509CertificateHolder certHolder) + throws OperatorCreationException + { + SignerIdentifier sigId = new SignerIdentifier(new IssuerAndSerialNumber(certHolder.toASN1Structure())); + + SignerInfoGenerator sigInfoGen = createGenerator(contentSigner, sigId); + + sigInfoGen.setAssociatedCertificate(certHolder); + + return sigInfoGen; + } + + /** + * Build a generator with the passed in subjectKeyIdentifier as the signerIdentifier. If used you should + * try to follow the calculation described in RFC 5280 section 4.2.1.2. + * + * @param contentSigner operator for generating the final signature in the SignerInfo with. + * @param subjectKeyIdentifier key identifier to identify the public key for verifying the signature. + * @return a SignerInfoGenerator + * @throws OperatorCreationException if the generator cannot be built. + */ + public SignerInfoGenerator build(ContentSigner contentSigner, byte[] subjectKeyIdentifier) + throws OperatorCreationException + { + SignerIdentifier sigId = new SignerIdentifier(new DEROctetString(subjectKeyIdentifier)); + + return createGenerator(contentSigner, sigId); + } + + private SignerInfoGenerator createGenerator(ContentSigner contentSigner, SignerIdentifier sigId) + throws OperatorCreationException + { + if (directSignature) + { + return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder, true); + } + + if (signedGen != null || unsignedGen != null) + { + if (signedGen == null) + { + signedGen = new DefaultSignedAttributeTableGenerator(); + } + + return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder, signedGen, unsignedGen); + } + + return new SignerInfoGenerator(sigId, contentSigner, digestProvider, sigEncAlgFinder); + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformation.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformation.java new file mode 100644 index 00000000..1f70626b --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformation.java @@ -0,0 +1,760 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; + +import com.android.internal.org.bouncycastle.asn1.ASN1Encodable; +import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector; +import com.android.internal.org.bouncycastle.asn1.ASN1Encoding; +import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier; +import com.android.internal.org.bouncycastle.asn1.ASN1OctetString; +import com.android.internal.org.bouncycastle.asn1.ASN1Primitive; +import com.android.internal.org.bouncycastle.asn1.ASN1Set; +import com.android.internal.org.bouncycastle.asn1.DERNull; +import com.android.internal.org.bouncycastle.asn1.DERSet; +import com.android.internal.org.bouncycastle.asn1.cms.Attribute; +import com.android.internal.org.bouncycastle.asn1.cms.AttributeTable; +import com.android.internal.org.bouncycastle.asn1.cms.CMSAlgorithmProtection; +import com.android.internal.org.bouncycastle.asn1.cms.CMSAttributes; +import com.android.internal.org.bouncycastle.asn1.cms.IssuerAndSerialNumber; +import com.android.internal.org.bouncycastle.asn1.cms.SignerIdentifier; +import com.android.internal.org.bouncycastle.asn1.cms.SignerInfo; +import com.android.internal.org.bouncycastle.asn1.cms.Time; +import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import com.android.internal.org.bouncycastle.asn1.x509.DigestInfo; +import com.android.internal.org.bouncycastle.cert.X509CertificateHolder; +import com.android.internal.org.bouncycastle.operator.ContentVerifier; +import com.android.internal.org.bouncycastle.operator.DigestCalculator; +import com.android.internal.org.bouncycastle.operator.OperatorCreationException; +import com.android.internal.org.bouncycastle.operator.RawContentVerifier; +import com.android.internal.org.bouncycastle.util.Arrays; +import com.android.internal.org.bouncycastle.util.io.TeeOutputStream; + +/** + * an expanded SignerInfo block from a CMS Signed message + * @hide This class is not part of the Android public SDK API + */ +public class SignerInformation +{ + private final SignerId sid; + private final CMSProcessable content; + private final byte[] signature; + private final ASN1ObjectIdentifier contentType; + private final boolean isCounterSignature; + + // Derived + private AttributeTable signedAttributeValues; + private AttributeTable unsignedAttributeValues; + private byte[] resultDigest; + + protected final SignerInfo info; + protected final AlgorithmIdentifier digestAlgorithm; + protected final AlgorithmIdentifier encryptionAlgorithm; + protected final ASN1Set signedAttributeSet; + protected final ASN1Set unsignedAttributeSet; + + SignerInformation( + SignerInfo info, + ASN1ObjectIdentifier contentType, + CMSProcessable content, + byte[] resultDigest) + { + this.info = info; + this.contentType = contentType; + this.isCounterSignature = contentType == null; + + SignerIdentifier s = info.getSID(); + + if (s.isTagged()) + { + ASN1OctetString octs = ASN1OctetString.getInstance(s.getId()); + + sid = new SignerId(octs.getOctets()); + } + else + { + IssuerAndSerialNumber iAnds = IssuerAndSerialNumber.getInstance(s.getId()); + + sid = new SignerId(iAnds.getName(), iAnds.getSerialNumber().getValue()); + } + + this.digestAlgorithm = info.getDigestAlgorithm(); + this.signedAttributeSet = info.getAuthenticatedAttributes(); + this.unsignedAttributeSet = info.getUnauthenticatedAttributes(); + this.encryptionAlgorithm = info.getDigestEncryptionAlgorithm(); + this.signature = info.getEncryptedDigest().getOctets(); + + this.content = content; + this.resultDigest = resultDigest; + } + + /** + * Protected constructor. In some cases clients have their own idea about how to encode + * the signed attributes and calculate the signature. This constructor is to allow developers + * to deal with that by extending off the class and overriding methods like getSignedAttributes(). + * + * @param baseInfo the SignerInformation to base this one on. + */ + protected SignerInformation(SignerInformation baseInfo) + { + this(baseInfo, baseInfo.info); + } + + /** + * Protected constructor. In some cases clients also have their own ideas about what + * goes in various SignerInfo fields. This constructor is to allow developers to deal with + * that by also tweaking the SignerInfo so that these issues can be dealt with. + * + * @param baseInfo the SignerInformation to base this one on. + * @param info the SignerInfo to associate with the existing baseInfo data. + */ + protected SignerInformation(SignerInformation baseInfo, SignerInfo info) + { + this.info = info; + this.contentType = baseInfo.contentType; + this.isCounterSignature = baseInfo.isCounterSignature(); + this.sid = baseInfo.getSID(); + this.digestAlgorithm = info.getDigestAlgorithm(); + this.signedAttributeSet = info.getAuthenticatedAttributes(); + this.unsignedAttributeSet = info.getUnauthenticatedAttributes(); + this.encryptionAlgorithm = info.getDigestEncryptionAlgorithm(); + this.signature = info.getEncryptedDigest().getOctets(); + this.content = baseInfo.content; + this.resultDigest = baseInfo.resultDigest; + this.signedAttributeValues = baseInfo.signedAttributeValues; + this.unsignedAttributeValues = baseInfo.unsignedAttributeValues; + } + + public boolean isCounterSignature() + { + return isCounterSignature; + } + + public ASN1ObjectIdentifier getContentType() + { + return this.contentType; + } + + private byte[] encodeObj( + ASN1Encodable obj) + throws IOException + { + if (obj != null) + { + return obj.toASN1Primitive().getEncoded(); + } + + return null; + } + + public SignerId getSID() + { + return sid; + } + + /** + * return the version number for this objects underlying SignerInfo structure. + */ + public int getVersion() + { + return info.getVersion().intValueExact(); + } + + public AlgorithmIdentifier getDigestAlgorithmID() + { + return digestAlgorithm; + } + + /** + * return the object identifier for the signature. + */ + public String getDigestAlgOID() + { + return digestAlgorithm.getAlgorithm().getId(); + } + + /** + * return the signature parameters, or null if there aren't any. + */ + public byte[] getDigestAlgParams() + { + try + { + return encodeObj(digestAlgorithm.getParameters()); + } + catch (Exception e) + { + throw new RuntimeException("exception getting digest parameters " + e); + } + } + + /** + * return the content digest that was calculated during verification. + */ + public byte[] getContentDigest() + { + if (resultDigest == null) + { + throw new IllegalStateException("method can only be called after verify."); + } + + return Arrays.clone(resultDigest); + } + + /** + * return the object identifier for the signature. + */ + public String getEncryptionAlgOID() + { + return encryptionAlgorithm.getAlgorithm().getId(); + } + + /** + * return the signature/encryption algorithm parameters, or null if + * there aren't any. + */ + public byte[] getEncryptionAlgParams() + { + try + { + return encodeObj(encryptionAlgorithm.getParameters()); + } + catch (Exception e) + { + throw new RuntimeException("exception getting encryption parameters " + e); + } + } + + /** + * return a table of the signed attributes - indexed by + * the OID of the attribute. + */ + public AttributeTable getSignedAttributes() + { + if (signedAttributeSet != null && signedAttributeValues == null) + { + signedAttributeValues = new AttributeTable(signedAttributeSet); + } + + return signedAttributeValues; + } + + /** + * return a table of the unsigned attributes indexed by + * the OID of the attribute. + */ + public AttributeTable getUnsignedAttributes() + { + if (unsignedAttributeSet != null && unsignedAttributeValues == null) + { + unsignedAttributeValues = new AttributeTable(unsignedAttributeSet); + } + + return unsignedAttributeValues; + } + + /** + * return the encoded signature + */ + public byte[] getSignature() + { + return Arrays.clone(signature); + } + + /** + * Return a SignerInformationStore containing the counter signatures attached to this + * signer. If no counter signatures are present an empty store is returned. + */ + public SignerInformationStore getCounterSignatures() + { + // TODO There are several checks implied by the RFC3852 comments that are missing + + /* + The countersignature attribute MUST be an unsigned attribute; it MUST + NOT be a signed attribute, an authenticated attribute, an + unauthenticated attribute, or an unprotected attribute. + */ + AttributeTable unsignedAttributeTable = getUnsignedAttributes(); + if (unsignedAttributeTable == null) + { + return new SignerInformationStore(new ArrayList(0)); + } + + List counterSignatures = new ArrayList(); + + /* + The UnsignedAttributes syntax is defined as a SET OF Attributes. The + UnsignedAttributes in a signerInfo may include multiple instances of + the countersignature attribute. + */ + ASN1EncodableVector allCSAttrs = unsignedAttributeTable.getAll(CMSAttributes.counterSignature); + + for (int i = 0; i < allCSAttrs.size(); ++i) + { + Attribute counterSignatureAttribute = (Attribute)allCSAttrs.get(i); + + /* + A countersignature attribute can have multiple attribute values. The + syntax is defined as a SET OF AttributeValue, and there MUST be one + or more instances of AttributeValue present. + */ + ASN1Set values = counterSignatureAttribute.getAttrValues(); + if (values.size() < 1) + { + // TODO Throw an appropriate exception? + } + + for (Enumeration en = values.getObjects(); en.hasMoreElements();) + { + /* + Countersignature values have the same meaning as SignerInfo values + for ordinary signatures, except that: + + 1. The signedAttributes field MUST NOT contain a content-type + attribute; there is no content type for countersignatures. + + 2. The signedAttributes field MUST contain a message-digest + attribute if it contains any other attributes. + + 3. The input to the message-digesting process is the contents + octets of the DER encoding of the signatureValue field of the + SignerInfo value with which the attribute is associated. + */ + SignerInfo si = SignerInfo.getInstance(en.nextElement()); + + counterSignatures.add(new SignerInformation(si, null, new CMSProcessableByteArray(getSignature()), null)); + } + } + + return new SignerInformationStore(counterSignatures); + } + + /** + * return the DER encoding of the signed attributes. + * @throws IOException if an encoding error occurs. + */ + public byte[] getEncodedSignedAttributes() + throws IOException + { + if (signedAttributeSet != null) + { + return signedAttributeSet.getEncoded(ASN1Encoding.DER); + } + + return null; + } + + private boolean doVerify( + SignerInformationVerifier verifier) + throws CMSException + { + String encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID()); + ContentVerifier contentVerifier; + + try + { + contentVerifier = verifier.getContentVerifier(encryptionAlgorithm, info.getDigestAlgorithm()); + } + catch (OperatorCreationException e) + { + throw new CMSException("can't create content verifier: " + e.getMessage(), e); + } + + try + { + OutputStream sigOut = contentVerifier.getOutputStream(); + + if (resultDigest == null) + { + DigestCalculator calc = verifier.getDigestCalculator(this.getDigestAlgorithmID()); + if (content != null) + { + OutputStream digOut = calc.getOutputStream(); + + if (signedAttributeSet == null) + { + if (contentVerifier instanceof RawContentVerifier) + { + content.write(digOut); + } + else + { + OutputStream cOut = new TeeOutputStream(digOut, sigOut); + + content.write(cOut); + + cOut.close(); + } + } + else + { + content.write(digOut); + sigOut.write(this.getEncodedSignedAttributes()); + } + + digOut.close(); + } + else if (signedAttributeSet != null) + { + sigOut.write(this.getEncodedSignedAttributes()); + } + else + { + // TODO Get rid of this exception and just treat content==null as empty not missing? + throw new CMSException("data not encapsulated in signature - use detached constructor."); + } + + resultDigest = calc.getDigest(); + } + else + { + if (signedAttributeSet == null) + { + if (content != null) + { + content.write(sigOut); + } + } + else + { + sigOut.write(this.getEncodedSignedAttributes()); + } + } + + sigOut.close(); + } + catch (IOException e) + { + throw new CMSException("can't process mime object to create signature.", e); + } + catch (OperatorCreationException e) + { + throw new CMSException("can't create digest calculator: " + e.getMessage(), e); + } + + // RFC 3852 11.1 Check the content-type attribute is correct + { + ASN1Primitive validContentType = getSingleValuedSignedAttribute( + CMSAttributes.contentType, "content-type"); + if (validContentType == null) + { + if (!isCounterSignature && signedAttributeSet != null) + { + throw new CMSException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data"); + } + } + else + { + if (isCounterSignature) + { + throw new CMSException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute"); + } + + if (!(validContentType instanceof ASN1ObjectIdentifier)) + { + throw new CMSException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'"); + } + + ASN1ObjectIdentifier signedContentType = (ASN1ObjectIdentifier)validContentType; + + if (!signedContentType.equals(contentType)) + { + throw new CMSException("content-type attribute value does not match eContentType"); + } + } + } + + AttributeTable signedAttrTable = this.getSignedAttributes(); + + // RFC 6211 Validate Algorithm Identifier protection attribute if present + { + AttributeTable unsignedAttrTable = this.getUnsignedAttributes(); + if (unsignedAttrTable != null && unsignedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect).size() > 0) + { + throw new CMSException("A cmsAlgorithmProtect attribute MUST be a signed attribute"); + } + if (signedAttrTable != null) + { + ASN1EncodableVector protectionAttributes = signedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect); + if (protectionAttributes.size() > 1) + { + throw new CMSException("Only one instance of a cmsAlgorithmProtect attribute can be present"); + } + + if (protectionAttributes.size() > 0) + { + Attribute attr = Attribute.getInstance(protectionAttributes.get(0)); + if (attr.getAttrValues().size() != 1) + { + throw new CMSException("A cmsAlgorithmProtect attribute MUST contain exactly one value"); + } + + CMSAlgorithmProtection algorithmProtection = CMSAlgorithmProtection.getInstance(attr.getAttributeValues()[0]); + + if (!CMSUtils.isEquivalent(algorithmProtection.getDigestAlgorithm(), info.getDigestAlgorithm())) + { + throw new CMSException("CMS Algorithm Identifier Protection check failed for digestAlgorithm"); + } + + if (!CMSUtils.isEquivalent(algorithmProtection.getSignatureAlgorithm(), info.getDigestEncryptionAlgorithm())) + { + throw new CMSException("CMS Algorithm Identifier Protection check failed for signatureAlgorithm"); + } + } + } + } + + // RFC 3852 11.2 Check the message-digest attribute is correct + { + ASN1Primitive validMessageDigest = getSingleValuedSignedAttribute( + CMSAttributes.messageDigest, "message-digest"); + if (validMessageDigest == null) + { + if (signedAttributeSet != null) + { + throw new CMSException("the message-digest signed attribute type MUST be present when there are any signed attributes present"); + } + } + else + { + if (!(validMessageDigest instanceof ASN1OctetString)) + { + throw new CMSException("message-digest attribute value not of ASN.1 type 'OCTET STRING'"); + } + + ASN1OctetString signedMessageDigest = (ASN1OctetString)validMessageDigest; + + if (!Arrays.constantTimeAreEqual(resultDigest, signedMessageDigest.getOctets())) + { + throw new CMSSignerDigestMismatchException("message-digest attribute value does not match calculated value"); + } + } + } + + // RFC 3852 11.4 Validate countersignature attribute(s) + { + if (signedAttrTable != null + && signedAttrTable.getAll(CMSAttributes.counterSignature).size() > 0) + { + throw new CMSException("A countersignature attribute MUST NOT be a signed attribute"); + } + + AttributeTable unsignedAttrTable = this.getUnsignedAttributes(); + if (unsignedAttrTable != null) + { + ASN1EncodableVector csAttrs = unsignedAttrTable.getAll(CMSAttributes.counterSignature); + for (int i = 0; i < csAttrs.size(); ++i) + { + Attribute csAttr = Attribute.getInstance(csAttrs.get(i)); + if (csAttr.getAttrValues().size() < 1) + { + throw new CMSException("A countersignature attribute MUST contain at least one AttributeValue"); + } + + // Note: We don't recursively validate the countersignature value + } + } + } + + try + { + if (signedAttributeSet == null && resultDigest != null) + { + if (contentVerifier instanceof RawContentVerifier) + { + RawContentVerifier rawVerifier = (RawContentVerifier)contentVerifier; + + if (encName.equals("RSA")) + { + DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(digestAlgorithm.getAlgorithm(), DERNull.INSTANCE), resultDigest); + + return rawVerifier.verify(digInfo.getEncoded(ASN1Encoding.DER), this.getSignature()); + } + + return rawVerifier.verify(resultDigest, this.getSignature()); + } + } + + return contentVerifier.verify(this.getSignature()); + } + catch (IOException e) + { + throw new CMSException("can't process mime object to create signature.", e); + } + } + + /** + * Verify that the given verifier can successfully verify the signature on + * this SignerInformation object. + * + * @param verifier a suitably configured SignerInformationVerifier. + * @return true if the signer information is verified, false otherwise. + * @throws com.android.internal.org.bouncycastle.cms.CMSVerifierCertificateNotValidException if the provider has an associated certificate and the certificate is not valid at the time given as the SignerInfo's signing time. + * @throws com.android.internal.org.bouncycastle.cms.CMSException if the verifier is unable to create a ContentVerifiers or DigestCalculators. + */ + public boolean verify(SignerInformationVerifier verifier) + throws CMSException + { + Time signingTime = getSigningTime(); // has to be validated if present. + + if (verifier.hasAssociatedCertificate()) + { + if (signingTime != null) + { + X509CertificateHolder dcv = verifier.getAssociatedCertificate(); + + if (!dcv.isValidOn(signingTime.getDate())) + { + throw new CMSVerifierCertificateNotValidException("verifier not valid at signingTime"); + } + } + } + + return doVerify(verifier); + } + + /** + * Return the underlying ASN.1 object defining this SignerInformation object. + * + * @return a SignerInfo. + */ + public SignerInfo toASN1Structure() + { + return info; + } + + private ASN1Primitive getSingleValuedSignedAttribute( + ASN1ObjectIdentifier attrOID, String printableName) + throws CMSException + { + AttributeTable unsignedAttrTable = this.getUnsignedAttributes(); + if (unsignedAttrTable != null + && unsignedAttrTable.getAll(attrOID).size() > 0) + { + throw new CMSException("The " + printableName + + " attribute MUST NOT be an unsigned attribute"); + } + + AttributeTable signedAttrTable = this.getSignedAttributes(); + if (signedAttrTable == null) + { + return null; + } + + ASN1EncodableVector v = signedAttrTable.getAll(attrOID); + switch (v.size()) + { + case 0: + return null; + case 1: + { + Attribute t = (Attribute)v.get(0); + ASN1Set attrValues = t.getAttrValues(); + if (attrValues.size() != 1) + { + throw new CMSException("A " + printableName + + " attribute MUST have a single attribute value"); + } + + return attrValues.getObjectAt(0).toASN1Primitive(); + } + default: + throw new CMSException("The SignedAttributes in a signerInfo MUST NOT include multiple instances of the " + + printableName + " attribute"); + } + } + + private Time getSigningTime() throws CMSException + { + ASN1Primitive validSigningTime = getSingleValuedSignedAttribute( + CMSAttributes.signingTime, "signing-time"); + + if (validSigningTime == null) + { + return null; + } + + try + { + return Time.getInstance(validSigningTime); + } + catch (IllegalArgumentException e) + { + throw new CMSException("signing-time attribute value not a valid 'Time' structure"); + } + } + + /** + * Return a signer information object with the passed in unsigned + * attributes replacing the ones that are current associated with + * the object passed in. + * + * @param signerInformation the signerInfo to be used as the basis. + * @param unsignedAttributes the unsigned attributes to add. + * @return a copy of the original SignerInformationObject with the changed attributes. + */ + public static SignerInformation replaceUnsignedAttributes( + SignerInformation signerInformation, + AttributeTable unsignedAttributes) + { + SignerInfo sInfo = signerInformation.info; + ASN1Set unsignedAttr = null; + + if (unsignedAttributes != null) + { + unsignedAttr = new DERSet(unsignedAttributes.toASN1EncodableVector()); + } + + return new SignerInformation( + new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(), + sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), unsignedAttr), + signerInformation.contentType, signerInformation.content, null); + } + + /** + * Return a signer information object with passed in SignerInformationStore representing counter + * signatures attached as an unsigned attribute. + * + * @param signerInformation the signerInfo to be used as the basis. + * @param counterSigners signer info objects carrying counter signature. + * @return a copy of the original SignerInformationObject with the changed attributes. + */ + public static SignerInformation addCounterSigners( + SignerInformation signerInformation, + SignerInformationStore counterSigners) + { + // TODO Perform checks from RFC 3852 11.4 + + SignerInfo sInfo = signerInformation.info; + AttributeTable unsignedAttr = signerInformation.getUnsignedAttributes(); + ASN1EncodableVector v; + + if (unsignedAttr != null) + { + v = unsignedAttr.toASN1EncodableVector(); + } + else + { + v = new ASN1EncodableVector(); + } + + ASN1EncodableVector sigs = new ASN1EncodableVector(); + + for (Iterator it = counterSigners.getSigners().iterator(); it.hasNext();) + { + sigs.add(((SignerInformation)it.next()).toASN1Structure()); + } + + v.add(new Attribute(CMSAttributes.counterSignature, new DERSet(sigs))); + + return new SignerInformation( + new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(), + sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), new DERSet(v)), + signerInformation.contentType, signerInformation.content, null); + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationStore.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationStore.java new file mode 100644 index 00000000..0f08e37e --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationStore.java @@ -0,0 +1,145 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.android.internal.org.bouncycastle.util.Iterable; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class SignerInformationStore + implements Iterable<SignerInformation> +{ + private List all = new ArrayList(); + private Map table = new HashMap(); + + /** + * Create a store containing a single SignerInformation object. + * + * @param signerInfo the signer information to contain. + */ + public SignerInformationStore( + SignerInformation signerInfo) + { + this.all = new ArrayList(1); + this.all.add(signerInfo); + + SignerId sid = signerInfo.getSID(); + + table.put(sid, all); + } + + /** + * Create a store containing a collection of SignerInformation objects. + * + * @param signerInfos a collection signer information objects to contain. + */ + public SignerInformationStore( + Collection<SignerInformation> signerInfos) + { + Iterator it = signerInfos.iterator(); + + while (it.hasNext()) + { + SignerInformation signer = (SignerInformation)it.next(); + SignerId sid = signer.getSID(); + + List list = (ArrayList)table.get(sid); + if (list == null) + { + list = new ArrayList(1); + table.put(sid, list); + } + + list.add(signer); + } + + this.all = new ArrayList(signerInfos); + } + + /** + * Return the first SignerInformation object that matches the + * passed in selector. Null if there are no matches. + * + * @param selector to identify a signer + * @return a single SignerInformation object. Null if none matches. + */ + public SignerInformation get( + SignerId selector) + { + Collection list = getSigners(selector); + + return list.size() == 0 ? null : (SignerInformation) list.iterator().next(); + } + + /** + * Return the number of signers in the collection. + * + * @return number of signers identified. + */ + public int size() + { + return all.size(); + } + + /** + * Return all signers in the collection + * + * @return a collection of signers. + */ + public Collection<SignerInformation> getSigners() + { + return new ArrayList(all); + } + + /** + * Return possible empty collection with signers matching the passed in SignerId + * + * @param selector a signer id to select against. + * @return a collection of SignerInformation objects. + */ + public Collection<SignerInformation> getSigners( + SignerId selector) + { + if (selector.getIssuer() != null && selector.getSubjectKeyIdentifier() != null) + { + List results = new ArrayList(); + + Collection match1 = getSigners(new SignerId(selector.getIssuer(), selector.getSerialNumber())); + + if (match1 != null) + { + results.addAll(match1); + } + + Collection match2 = getSigners(new SignerId(selector.getSubjectKeyIdentifier())); + + if (match2 != null) + { + results.addAll(match2); + } + + return results; + } + else + { + List list = (ArrayList)table.get(selector); + + return list == null ? new ArrayList() : new ArrayList(list); + } + } + + /** + * Support method for Iterable where available. + */ + public Iterator<SignerInformation> iterator() + { + return getSigners().iterator(); + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationVerifier.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationVerifier.java new file mode 100644 index 00000000..d73b2bbc --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SignerInformationVerifier.java @@ -0,0 +1,55 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import com.android.internal.org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import com.android.internal.org.bouncycastle.cert.X509CertificateHolder; +import com.android.internal.org.bouncycastle.operator.ContentVerifier; +import com.android.internal.org.bouncycastle.operator.ContentVerifierProvider; +import com.android.internal.org.bouncycastle.operator.DigestCalculator; +import com.android.internal.org.bouncycastle.operator.DigestCalculatorProvider; +import com.android.internal.org.bouncycastle.operator.OperatorCreationException; +import com.android.internal.org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class SignerInformationVerifier +{ + private ContentVerifierProvider verifierProvider; + private DigestCalculatorProvider digestProvider; + private SignatureAlgorithmIdentifierFinder sigAlgorithmFinder; + private CMSSignatureAlgorithmNameGenerator sigNameGenerator; + + public SignerInformationVerifier(CMSSignatureAlgorithmNameGenerator sigNameGenerator, SignatureAlgorithmIdentifierFinder sigAlgorithmFinder, ContentVerifierProvider verifierProvider, DigestCalculatorProvider digestProvider) + { + this.sigNameGenerator = sigNameGenerator; + this.sigAlgorithmFinder = sigAlgorithmFinder; + this.verifierProvider = verifierProvider; + this.digestProvider = digestProvider; + } + + public boolean hasAssociatedCertificate() + { + return verifierProvider.hasAssociatedCertificate(); + } + + public X509CertificateHolder getAssociatedCertificate() + { + return verifierProvider.getAssociatedCertificate(); + } + + public ContentVerifier getContentVerifier(AlgorithmIdentifier signingAlgorithm, AlgorithmIdentifier digestAlgorithm) + throws OperatorCreationException + { + String signatureName = sigNameGenerator.getSignatureName(digestAlgorithm, signingAlgorithm); + AlgorithmIdentifier baseAlgID = sigAlgorithmFinder.find(signatureName); + + return verifierProvider.get(new AlgorithmIdentifier(baseAlgID.getAlgorithm(), signingAlgorithm.getParameters())); + } + + public DigestCalculator getDigestCalculator(AlgorithmIdentifier algorithmIdentifier) + throws OperatorCreationException + { + return digestProvider.get(algorithmIdentifier); + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SimpleAttributeTableGenerator.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SimpleAttributeTableGenerator.java new file mode 100644 index 00000000..7b11d617 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/SimpleAttributeTableGenerator.java @@ -0,0 +1,27 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms; + +import com.android.internal.org.bouncycastle.asn1.cms.AttributeTable; + +import java.util.Map; + +/** + * Basic generator that just returns a preconstructed attribute table + * @hide This class is not part of the Android public SDK API + */ +public class SimpleAttributeTableGenerator + implements CMSAttributeTableGenerator +{ + private final AttributeTable attributes; + + public SimpleAttributeTableGenerator( + AttributeTable attributes) + { + this.attributes = attributes; + } + + public AttributeTable getAttributes(Map parameters) + { + return attributes; + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java new file mode 100644 index 00000000..e1b4fa58 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java @@ -0,0 +1,90 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms.jcajce; + +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; + +import com.android.internal.org.bouncycastle.cert.X509CertificateHolder; +import com.android.internal.org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; +import com.android.internal.org.bouncycastle.cms.CMSAttributeTableGenerator; +import com.android.internal.org.bouncycastle.cms.CMSSignatureEncryptionAlgorithmFinder; +import com.android.internal.org.bouncycastle.cms.DefaultCMSSignatureEncryptionAlgorithmFinder; +import com.android.internal.org.bouncycastle.cms.SignerInfoGenerator; +import com.android.internal.org.bouncycastle.cms.SignerInfoGeneratorBuilder; +import com.android.internal.org.bouncycastle.operator.ContentSigner; +import com.android.internal.org.bouncycastle.operator.DigestCalculatorProvider; +import com.android.internal.org.bouncycastle.operator.OperatorCreationException; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class JcaSignerInfoGeneratorBuilder +{ + private SignerInfoGeneratorBuilder builder; + + /** + * Base constructor. + * + * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations. + */ + public JcaSignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider) + { + this(digestProvider, new DefaultCMSSignatureEncryptionAlgorithmFinder()); + } + + /** + * Base constructor with a particular finder for signature algorithms. + * + * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations. + * @param sigEncAlgFinder finder for algorithm IDs to store for the signature encryption/signature algorithm field. + */ + public JcaSignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder) + { + builder = new SignerInfoGeneratorBuilder(digestProvider, sigEncAlgFinder); + } + + /** + * If the passed in flag is true, the signer signature will be based on the data, not + * a collection of signed attributes, and no signed attributes will be included. + * + * @return the builder object + */ + public JcaSignerInfoGeneratorBuilder setDirectSignature(boolean hasNoSignedAttributes) + { + builder.setDirectSignature(hasNoSignedAttributes); + + return this; + } + + public JcaSignerInfoGeneratorBuilder setSignedAttributeGenerator(CMSAttributeTableGenerator signedGen) + { + builder.setSignedAttributeGenerator(signedGen); + + return this; + } + + public JcaSignerInfoGeneratorBuilder setUnsignedAttributeGenerator(CMSAttributeTableGenerator unsignedGen) + { + builder.setUnsignedAttributeGenerator(unsignedGen); + + return this; + } + + public SignerInfoGenerator build(ContentSigner contentSigner, X509CertificateHolder certHolder) + throws OperatorCreationException + { + return builder.build(contentSigner, certHolder); + } + + public SignerInfoGenerator build(ContentSigner contentSigner, byte[] keyIdentifier) + throws OperatorCreationException + { + return builder.build(contentSigner, keyIdentifier); + } + + public SignerInfoGenerator build(ContentSigner contentSigner, X509Certificate certificate) + throws OperatorCreationException, CertificateEncodingException + { + return this.build(contentSigner, new JcaX509CertificateHolder(certificate)); + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java new file mode 100644 index 00000000..13512d32 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSignerInfoVerifierBuilder.java @@ -0,0 +1,184 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms.jcajce; + +import java.security.Provider; +import java.security.PublicKey; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import com.android.internal.org.bouncycastle.cert.X509CertificateHolder; +import com.android.internal.org.bouncycastle.cms.CMSSignatureAlgorithmNameGenerator; +import com.android.internal.org.bouncycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator; +import com.android.internal.org.bouncycastle.cms.SignerInformationVerifier; +import com.android.internal.org.bouncycastle.operator.ContentVerifierProvider; +import com.android.internal.org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; +import com.android.internal.org.bouncycastle.operator.DigestCalculatorProvider; +import com.android.internal.org.bouncycastle.operator.OperatorCreationException; +import com.android.internal.org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder; +import com.android.internal.org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; +import com.android.internal.org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class JcaSignerInfoVerifierBuilder +{ + private Helper helper = new Helper(); + private DigestCalculatorProvider digestProvider; + private CMSSignatureAlgorithmNameGenerator sigAlgNameGen = new DefaultCMSSignatureAlgorithmNameGenerator(); + private SignatureAlgorithmIdentifierFinder sigAlgIDFinder = new DefaultSignatureAlgorithmIdentifierFinder(); + + public JcaSignerInfoVerifierBuilder(DigestCalculatorProvider digestProvider) + { + this.digestProvider = digestProvider; + } + + public JcaSignerInfoVerifierBuilder setProvider(Provider provider) + { + this.helper = new ProviderHelper(provider); + + return this; + } + + public JcaSignerInfoVerifierBuilder setProvider(String providerName) + { + this.helper = new NamedHelper(providerName); + + return this; + } + + /** + * Override the default signature algorithm name generator. + * + * @param sigAlgNameGen the algorithm name generator to use. + * @return the current builder. + */ + public JcaSignerInfoVerifierBuilder setSignatureAlgorithmNameGenerator(CMSSignatureAlgorithmNameGenerator sigAlgNameGen) + { + this.sigAlgNameGen = sigAlgNameGen; + + return this; + } + + public JcaSignerInfoVerifierBuilder setSignatureAlgorithmFinder(SignatureAlgorithmIdentifierFinder sigAlgIDFinder) + { + this.sigAlgIDFinder = sigAlgIDFinder; + + return this; + } + + public SignerInformationVerifier build(X509CertificateHolder certHolder) + throws OperatorCreationException, CertificateException + { + return new SignerInformationVerifier(sigAlgNameGen, sigAlgIDFinder, helper.createContentVerifierProvider(certHolder), digestProvider); + } + + public SignerInformationVerifier build(X509Certificate certificate) + throws OperatorCreationException + { + return new SignerInformationVerifier(sigAlgNameGen, sigAlgIDFinder, helper.createContentVerifierProvider(certificate), digestProvider); + } + + public SignerInformationVerifier build(PublicKey pubKey) + throws OperatorCreationException + { + return new SignerInformationVerifier(sigAlgNameGen, sigAlgIDFinder, helper.createContentVerifierProvider(pubKey), digestProvider); + } + + private class Helper + { + ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey) + throws OperatorCreationException + { + return new JcaContentVerifierProviderBuilder().build(publicKey); + } + + ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate) + throws OperatorCreationException + { + return new JcaContentVerifierProviderBuilder().build(certificate); + } + + ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder) + throws OperatorCreationException, CertificateException + { + return new JcaContentVerifierProviderBuilder().build(certHolder); + } + + DigestCalculatorProvider createDigestCalculatorProvider() + throws OperatorCreationException + { + return new JcaDigestCalculatorProviderBuilder().build(); + } + } + + private class NamedHelper + extends Helper + { + private final String providerName; + + public NamedHelper(String providerName) + { + this.providerName = providerName; + } + + ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey) + throws OperatorCreationException + { + return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(publicKey); + } + + ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate) + throws OperatorCreationException + { + return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(certificate); + } + + DigestCalculatorProvider createDigestCalculatorProvider() + throws OperatorCreationException + { + return new JcaDigestCalculatorProviderBuilder().setProvider(providerName).build(); + } + + ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder) + throws OperatorCreationException, CertificateException + { + return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(certHolder); + } + } + + private class ProviderHelper + extends Helper + { + private final Provider provider; + + public ProviderHelper(Provider provider) + { + this.provider = provider; + } + + ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey) + throws OperatorCreationException + { + return new JcaContentVerifierProviderBuilder().setProvider(provider).build(publicKey); + } + + ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate) + throws OperatorCreationException + { + return new JcaContentVerifierProviderBuilder().setProvider(provider).build(certificate); + } + + DigestCalculatorProvider createDigestCalculatorProvider() + throws OperatorCreationException + { + return new JcaDigestCalculatorProviderBuilder().setProvider(provider).build(); + } + + ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder) + throws OperatorCreationException, CertificateException + { + return new JcaContentVerifierProviderBuilder().setProvider(provider).build(certHolder); + } + } +} diff --git a/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java new file mode 100644 index 00000000..b1e22fb1 --- /dev/null +++ b/repackaged_platform/bcpkix/src/main/java/com/android/internal/org/bouncycastle/cms/jcajce/JcaSimpleSignerInfoVerifierBuilder.java @@ -0,0 +1,154 @@ +/* GENERATED SOURCE. DO NOT MODIFY. */ +package com.android.internal.org.bouncycastle.cms.jcajce; + +import java.security.Provider; +import java.security.PublicKey; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import com.android.internal.org.bouncycastle.cert.X509CertificateHolder; +import com.android.internal.org.bouncycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator; +import com.android.internal.org.bouncycastle.cms.SignerInformationVerifier; +import com.android.internal.org.bouncycastle.operator.ContentVerifierProvider; +import com.android.internal.org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; +import com.android.internal.org.bouncycastle.operator.DigestCalculatorProvider; +import com.android.internal.org.bouncycastle.operator.OperatorCreationException; +import com.android.internal.org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; +import com.android.internal.org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; + +/** + * @hide This class is not part of the Android public SDK API + */ +public class JcaSimpleSignerInfoVerifierBuilder +{ + private Helper helper = new Helper(); + + public JcaSimpleSignerInfoVerifierBuilder setProvider(Provider provider) + { + this.helper = new ProviderHelper(provider); + + return this; + } + + public JcaSimpleSignerInfoVerifierBuilder setProvider(String providerName) + { + this.helper = new NamedHelper(providerName); + + return this; + } + + public SignerInformationVerifier build(X509CertificateHolder certHolder) + throws OperatorCreationException, CertificateException + { + return new SignerInformationVerifier(new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), helper.createContentVerifierProvider(certHolder), helper.createDigestCalculatorProvider()); + } + + public SignerInformationVerifier build(X509Certificate certificate) + throws OperatorCreationException + { + return new SignerInformationVerifier(new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), helper.createContentVerifierProvider(certificate), helper.createDigestCalculatorProvider()); + } + + public SignerInformationVerifier build(PublicKey pubKey) + throws OperatorCreationException + { + return new SignerInformationVerifier(new DefaultCMSSignatureAlgorithmNameGenerator(), new DefaultSignatureAlgorithmIdentifierFinder(), helper.createContentVerifierProvider(pubKey), helper.createDigestCalculatorProvider()); + } + + private class Helper + { + ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey) + throws OperatorCreationException + { + return new JcaContentVerifierProviderBuilder().build(publicKey); + } + + ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate) + throws OperatorCreationException + { + return new JcaContentVerifierProviderBuilder().build(certificate); + } + + ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder) + throws OperatorCreationException, CertificateException + { + return new JcaContentVerifierProviderBuilder().build(certHolder); + } + + DigestCalculatorProvider createDigestCalculatorProvider() + throws OperatorCreationException + { + return new JcaDigestCalculatorProviderBuilder().build(); + } + } + + private class NamedHelper + extends Helper + { + private final String providerName; + + public NamedHelper(String providerName) + { + this.providerName = providerName; + } + + ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey) + throws OperatorCreationException + { + return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(publicKey); + } + + ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate) + throws OperatorCreationException + { + return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(certificate); + } + + DigestCalculatorProvider createDigestCalculatorProvider() + throws OperatorCreationException + { + return new JcaDigestCalculatorProviderBuilder().setProvider(providerName).build(); + } + + ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder) + throws OperatorCreationException, CertificateException + { + return new JcaContentVerifierProviderBuilder().setProvider(providerName).build(certHolder); + } + } + + private class ProviderHelper + extends Helper + { + private final Provider provider; + + public ProviderHelper(Provider provider) + { + this.provider = provider; + } + + ContentVerifierProvider createContentVerifierProvider(PublicKey publicKey) + throws OperatorCreationException + { + return new JcaContentVerifierProviderBuilder().setProvider(provider).build(publicKey); + } + + ContentVerifierProvider createContentVerifierProvider(X509Certificate certificate) + throws OperatorCreationException + { + return new JcaContentVerifierProviderBuilder().setProvider(provider).build(certificate); + } + + DigestCalculatorProvider createDigestCalculatorProvider() + throws OperatorCreationException + { + return new JcaDigestCalculatorProviderBuilder().setProvider(provider).build(); + } + + ContentVerifierProvider createContentVerifierProvider(X509CertificateHolder certHolder) + throws OperatorCreationException, CertificateException + { + return new JcaContentVerifierProviderBuilder().setProvider(provider).build(certHolder); + } + } +} |