public class CMSSignedDataParser extends CMSContentInfoParser
Note: that because we are in a streaming mode only one signer can be tried and it is important that the methods on the parser are called in the appropriate order.
A simple example of usage for an encapsulated signature.
Two notes: first, in the example below the validity of the certificate isn't verified, just the fact that one of the certs matches the given signer, and, second, because we are in a streaming mode the order of the operations is important.
CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), encapSigData);
sp.getSignedContent().drain();
Store certStore = sp.getCertificates();
SignerInformationStore signers = sp.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();
System.out.println("verify returns: " + signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)));
}
Note also: this class does not introduce buffering - if you are processing large files you should create
the parser with:
CMSSignedDataParser ep = new CMSSignedDataParser(new BufferedInputStream(encapSigData, bufSize));
where bufSize is a suitably large buffer size.
Stream handling note:
getSignedContent().drain()) before
calling getSignerInfos() so the running digests can be finalized.CMSContentInfoParser.close() on this parser (inherited from
CMSContentInfoParser) to close the underlying InputStream, or close
it yourself._contentInfo, _data| Constructor and Description |
|---|
CMSSignedDataParser(DigestCalculatorProvider digestCalculatorProvider,
byte[] sigBlock) |
CMSSignedDataParser(DigestCalculatorProvider digestCalculatorProvider,
CMSTypedStream signedContent,
byte[] sigBlock) |
CMSSignedDataParser(DigestCalculatorProvider digestCalculatorProvider,
CMSTypedStream signedContent,
java.io.InputStream sigData)
base constructor
|
CMSSignedDataParser(DigestCalculatorProvider digestCalculatorProvider,
java.io.InputStream sigData)
base constructor - with encapsulated content
|
| Modifier and Type | Method and Description |
|---|---|
org.bouncycastle.util.Store |
getAttributeCertificates()
Return any X.509 attribute certificate objects in this SignedData structure as a Store of X509AttributeCertificateHolder objects.
|
org.bouncycastle.util.Store |
getCertificates()
Return any X.509 certificate objects in this SignedData structure as a Store of X509CertificateHolder objects.
|
org.bouncycastle.asn1.ASN1Set |
getCertificateSet()
Return the raw
certificates field as parsed from the wire,
preserving every choice (X.509 SEQUENCE, attribute certificate
[1], other [2]) in original encoding order. |
org.bouncycastle.util.Store |
getCRLs()
Return any X.509 CRL objects in this SignedData structure as a Store of X509CRLHolder objects.
|
org.bouncycastle.asn1.ASN1Set |
getCRLSet()
Return the raw
crls field as parsed from the wire,
preserving every choice (CertificateList, other revocation info
[1]) in original encoding order. |
java.util.Set<org.bouncycastle.asn1.x509.AlgorithmIdentifier> |
getDigestAlgorithmIDs()
Return the digest algorithm identifiers for the SignedData object
|
org.bouncycastle.asn1.ASN1Set |
getDigestAlgorithmsSet()
Return the
digestAlgorithms field as parsed from the wire:
a BERSet if the field used the indefinite-length (BER) method,
a DLSet otherwise, with the algorithm identifiers in their
original wire order. |
org.bouncycastle.util.Store |
getOtherRevocationInfo(org.bouncycastle.asn1.ASN1ObjectIdentifier otherRevocationInfoFormat)
Return any OtherRevocationInfo OtherRevInfo objects of the type indicated by otherRevocationInfoFormat in
this SignedData structure.
|
CMSTypedStream |
getSignedContent() |
java.lang.String |
getSignedContentTypeOID()
Return the a string representation of the OID associated with the
encapsulated content info structure carried in the signed data.
|
SignerInformationStore |
getSignerInfos()
return the collection of signers that are associated with the
signatures for the message.
|
int |
getVersion()
Return the version number for the SignedData object
|
boolean |
isContentBEREncoded()
Return true if the
eContent OCTET STRING of the
encapsulated content used a constructed/indefinite-length (BER)
encoding, false if it was a primitive definite-length OCTET STRING
(DL/DER), or if the signed data was detached (no eContent present). |
static java.io.OutputStream |
replaceCertificatesAndCRLs(java.io.InputStream original,
org.bouncycastle.util.Store certs,
org.bouncycastle.util.Store crls,
org.bouncycastle.util.Store attrCerts,
java.io.OutputStream out)
Replace the certificate and CRL information associated with this
CMSSignedData object with the new one passed in.
|
static java.io.OutputStream |
replaceSigners(java.io.InputStream original,
SignerInformationStore signerInformationStore,
java.io.OutputStream out)
Replace the signerinformation store associated with the passed
in message contained in the stream original with the new one passed in.
|
static java.io.OutputStream |
replaceSignersPreservingEncoding(java.io.InputStream original,
SignerInformationStore signerInformationStore,
java.io.OutputStream out)
Replace the signers of the message contained in the stream
original with the store passed in, preserving the original
wire encoding of everything an ETSI archive-time-stamp imprint covers
(ETSI TS 101 733 Annex A, id-aa-ets-archiveTimestampV2). |
close, isBEREncodedpublic CMSSignedDataParser(DigestCalculatorProvider digestCalculatorProvider, byte[] sigBlock) throws CMSException
CMSExceptionpublic CMSSignedDataParser(DigestCalculatorProvider digestCalculatorProvider, CMSTypedStream signedContent, byte[] sigBlock) throws CMSException
CMSExceptionpublic CMSSignedDataParser(DigestCalculatorProvider digestCalculatorProvider, java.io.InputStream sigData) throws CMSException
CMSExceptionpublic CMSSignedDataParser(DigestCalculatorProvider digestCalculatorProvider, CMSTypedStream signedContent, java.io.InputStream sigData) throws CMSException
digestCalculatorProvider - for generating accumulating digestssignedContent - the content that was signed.sigData - the signature object stream.CMSExceptionpublic int getVersion()
public java.util.Set<org.bouncycastle.asn1.x509.AlgorithmIdentifier> getDigestAlgorithmIDs()
public org.bouncycastle.asn1.ASN1Set getDigestAlgorithmsSet()
digestAlgorithms field as parsed from the wire:
a BERSet if the field used the indefinite-length (BER) method,
a DLSet otherwise, with the algorithm identifiers in their
original wire order. Use this when the original coding needs to be
reproduced (e.g. re-emitting a SignedData covered by an
ETSI archive-time-stamp); otherwise prefer
getDigestAlgorithmIDs() (which de-duplicates and does not
preserve order).public boolean isContentBEREncoded()
eContent OCTET STRING of the
encapsulated content used a constructed/indefinite-length (BER)
encoding, false if it was a primitive definite-length OCTET STRING
(DL/DER), or if the signed data was detached (no eContent present).
Together with CMSContentInfoParser.isBEREncoded() this exposes the original coding
of the signed content without a second pass over the stream
(see github #1983).public SignerInformationStore getSignerInfos() throws CMSException
CMSExceptionpublic org.bouncycastle.util.Store getCertificates()
throws CMSException
CMSExceptionpublic org.bouncycastle.util.Store getCRLs()
throws CMSException
CMSExceptionpublic org.bouncycastle.util.Store getAttributeCertificates()
throws CMSException
CMSExceptionpublic org.bouncycastle.util.Store getOtherRevocationInfo(org.bouncycastle.asn1.ASN1ObjectIdentifier otherRevocationInfoFormat)
throws CMSException
otherRevocationInfoFormat - OID of the format type been looked for.CMSExceptionpublic org.bouncycastle.asn1.ASN1Set getCertificateSet()
throws CMSException
certificates field as parsed from the wire,
preserving every choice (X.509 SEQUENCE, attribute certificate
[1], other [2]) in original encoding order.
Null if the field was absent. Forces a populate of the cert/CRL sets
(which is harmless to call multiple times). Use this when the wire
order or non-X.509 choices matter; otherwise prefer getCertificates().CMSExceptionpublic org.bouncycastle.asn1.ASN1Set getCRLSet()
throws CMSException
crls field as parsed from the wire,
preserving every choice (CertificateList, other revocation info
[1]) in original encoding order. Null if the field was
absent. Forces a populate of the cert/CRL sets. Use this when the
wire order or non-CertificateList choices matter; otherwise prefer
getCRLs() or getOtherRevocationInfo(org.bouncycastle.asn1.ASN1ObjectIdentifier).CMSExceptionpublic java.lang.String getSignedContentTypeOID()
public CMSTypedStream getSignedContent()
public static java.io.OutputStream replaceSigners(java.io.InputStream original,
SignerInformationStore signerInformationStore,
java.io.OutputStream out)
throws CMSException,
java.io.IOException
The output stream is returned unclosed.
original - the signed data stream to be used as a base.signerInformationStore - the new signer information store to use.out - the stream to write the new signed data object to.CMSExceptionjava.io.IOExceptionpublic static java.io.OutputStream replaceSignersPreservingEncoding(java.io.InputStream original,
SignerInformationStore signerInformationStore,
java.io.OutputStream out)
throws CMSException,
java.io.IOException
original with the store passed in, preserving the original
wire encoding of everything an ETSI archive-time-stamp imprint covers
(ETSI TS 101 733 Annex A, id-aa-ets-archiveTimestampV2).
Unlike replaceSigners(InputStream, SignerInformationStore, OutputStream),
which re-encodes as it goes (recomputed digestAlgorithms,
re-chunked BER content, DER-sorted signerInfos), this method copies the
version, digestAlgorithms,
encapContentInfo, certificates and
crls elements verbatim, byte for byte, from the
original stream — the encapsulated content is piped, not buffered, so
the method is suitable for content larger than a byte array. Only the
signerInfos field is rebuilt: it is written as a
definite-length SET containing the signers in store order, unsorted
(a DER SET would sort, changing the wire order the imprint depends on).
The outer ContentInfo / SignedData framing is re-emitted using the
indefinite-length (BER) method, as with the other streaming generators;
the framing is outside the archive-time-stamp imprint.
The intended use is unsigned-attribute augmentation (e.g. attaching an
archive-time-stamp): because digestAlgorithms is copied
as-is, the replacement signers must not require digest algorithms beyond
those already present in the original message.
The output stream is returned unclosed.
original - the signed data stream to be used as a base.signerInformationStore - the new signer information store to use.out - the stream to write the new signed data object to.CMSExceptionjava.io.IOExceptionpublic static java.io.OutputStream replaceCertificatesAndCRLs(java.io.InputStream original,
org.bouncycastle.util.Store certs,
org.bouncycastle.util.Store crls,
org.bouncycastle.util.Store attrCerts,
java.io.OutputStream out)
throws CMSException,
java.io.IOException
The output stream is returned unclosed.
original - the signed data stream to be used as a base.certs - new certificates to be used, if any.crls - new CRLs to be used, if any.attrCerts - new attribute certificates to be used, if any.out - the stream to write the new signed data object to.CMSException - if there is an error processing the CertStorejava.io.IOException