public class SignedDataStream extends java.lang.Object implements ContentStream, EOFListener
SignedData
.
Each PKCS#7 content type is associated with a specific object identifier, derived from:
pkcs-7 OBJECT IDENTIFIER ::= { iso(1) member-body(2) US(840) rsadsi(113549) pkcs(1) 7 }
The object identifier for the SignedData
content type is defined
as:
signedData OBJECT IDENTIFIER ::= { pkcs-7 2 }
which corresponds to the OID string "1.2.840.1.113549.1.7.2".
The PKCS#7
Cryptographic Message Standard specifies the SignedData
content type for providing a syntax for building digital signatures. Content
of any type may be signed by any number of signers in parallel. For each
signer, a message digest is computed on the content (and any additional
authenticating information) with a signer-specific message-digest algorithm.
Subsequently, again for each signer, the corresponding message digest from
the previous step is encrypted with the particular signer's private key and -
together with some signer-specific information - collected into a
SignerInfo
value. Finally all created SignerInfo
values
are collected together with the content for forming a SignedData
structure.
This class implements the SignedData
structure resulting from
the last step described above. The SignedData
type is defined as
ASN.1 SEQUENCE type containing the following components (see PKCS#7 specification,
Version 1.5; notice that the ASN.1 module printed below not fully agrees
with the SignedData definition of Version 1.5, since the certificates
field is interpreted as SET OF pure X.509 certificates, whereas
Version 1.5 also allows PKCS#6 extended certificates!):
SignedData ::= SEQUENCE { version Version, digestAlgorithms DigestAlgorithmIdentifiers, contentInfo ContentInfo, certificates [0] IMPLICIT Certificates OPTIONAL, crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, signerInfos SignerInfos }
DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
Certificates ::= SET OF Certificate -- X.509
CertificateRevocationLists ::= SET OF CertificateRevocationList
SignerInfos ::= SET OF SignerInfo
The digestAlgorithms
field contains the object identifiers of
the message digest algorithms used by the several signers for digesting the
content that is supplied in the contentInfo
field. The optional
certificates
field shall contain certificate chains for all the
signers of the signerInfos
field. The optional crls
field may supply information about the revocation status of the certificates
specified in the certificates
field. And finally, the
signerInfos
field collects per-signer information for all
parciticipated signers including the encrypted digests of the content (i.e.
the signer-specific digital signatures of the content).
If there are no signers on the content, the signed-data content type may be used for disseminating certificates and certificate-revocation lists.
Verifying some received signature(s) is done by decrypting the encrypted message digests for each signer with the signer's public key and comparing the results with independently computed message digests on the original content.
For more information consult the RSA PKCS#7 specification.
The SignedData
version implemented by this class complies with
the SignedData structure as used by the S/MIME protocol. In this way, the
digest is calculated on only the content octets of the DER encoding of the
content field of the inherent ContentInfo structure. At this point it is
important to note that currently IAIK-JCE only supports SignedData structures
to be used for signing content values of the PKCS#7 Data content type!
When creating a SignedDataStream
object for the content to be
signed by using the SignedDataStream(InputStream is, int mode)
constructor, additionally the
transmission mode has to be specified. If the mode is set to
SignedDataStream.IMPLICIT the raw data will be included in the
SignedData
message to be transmitted, but it will be not
included if the mode is set to SignedDataStream.EXPLICIT. However, in
both cases the raw data has to be supplied when creating the
SignedDataStream
object, because it is needed for the digest
computation:
InputSrteam[] data_stream = ...; // the raw data supplying input stream SignedDataStream signed_data = new SignedDataStream(data_stream, SignedDataStream.IMPLICIT);respectively
SignedDataStream signed_data_stream = new SignedDataStream(data_stream, SignedDataStream.EXPLICIT);In contrast to the non-stream-variant of the PKCS#7 SignedData type (implemented by the
SignedData
class),
where explicit and implicit mode can be handled in the same way when creating
a SignedData object, they require a different proceeding for the
stream-supporting SignedDataStream
class. In this way, the steps
for creating a SignedDataStream
object and preparing it for
transmission can be summarized in the following way (to simplify matters, we
will assume not to include certificate revocation lists):
SignedDataStream
object thereby supplying the
raw data to be signed as input stream and specifying the transmission mode to
be used (either SignedDataStream.IMPLICIT or
SignedDataStream.EXPLICIT):
InputStream data_stream = ...; int mode = ...; SignedDataStream signed_data = new SignedDataStream(data_stream, mode);
setCertificates
method. The
certificates are supplied as array of X509Certificate
s and shall contain chains from a known top-level CA to all
the signers in the SignerInfo
field:
signed_data.setCertificates(certificates);
SignerInfo
object, optionally supply it with attributes, and add it to the
SignedDataStream structure by calling the addSignerInfo
method:
SignerInfo signer1 = ...; signed_data.addSignerInfo(signer1); SignerInfo signer2 = ...; signed_data.addSignerInfo(signer2); ...You alternatively may collectively add all signers by utilizing the
setSignerInfos
method.
if (mode == SignedDataStream.EXPLICIT) { InputStream data_is = signed_data.getInputStream(); byte[] buf = new byte[1024]; int r; while ((r = data_is.read(buf)) > 0) { // do something useful } }When using the implicit mode, do not explicitly read data from the input stream at all! This will be done automatically during the last step when performing the encoding.
writeTo
method for BER
encoding the the SignedDataStream object and writing it to an output stream.
You optionally may specify a particular block size for splitting the data
encoding:
int blockSize = ...; signed_data.writeTo(output_stream, blockSize);respectively
signed_data.writeTo(output_stream);It is recommended only to use the
writeTo
method where a
particular block size (default 2048) can be specified, because it is the
intended purpose of this stream-supporting SignedData implementation to
handle large amounts of data. When a positive block size is specified for
encoding the SignedData to a stream, the raw data is BER encoded as
indefinite constructed octet string being composed of a series of definite
primitive encoded octet strings of blockSize
length, e.g.:
0x24 0x80 0x04 0x02 0x01 0xAB 0x04 0x02 0x23 0x7F 0x04 0x01 0xCA 0x00 0x00instead of:
0x04 0x05 0x01 0xAB 0x23 0x7F 0xCAfor encoding the five data bytes
0x01 0xAB 0x23 0x7F 0xCA
. The
indefinite constructed encoding scheme also may be preferable when intending
to be compatible to the encoding practice of some particular application (for
instance some versions of Netscape Navigator).
Again, it has to be distinguished between IMPLICIT and EXPLICIT mode when
using the
SignedDataStream
implementation for parsing a received SignedData
message. When operating in IMPLICIT mode, the raw data is included in the
received SignedData object, and so the parsing immediately may be performed
when creating a SignedDataStream
object from the DER encoded
SignedData object by calling the SignedDataStream(InputStream is)
constructor. On the other side, when the
raw data has been transmitted outside the SignedData message (EXPLICIT mode),
the SignedDataStream(InputStream data_is, AlgorithmID[] hashAlgorithms)
constructor has to be used for initializing the new SignedDataStream object
with raw data and hash algorithms to be used for digest computation; and the
decoding has to be performed explicitly by calling the
decode
method. The initialization is necessary
for preparing the digest computation on the raw data for the digest
algorithms of all participated signers. Later, during signature verification
the digest value computation is finished and the results are compared against
the hash values resulting from decrypting the encrypted digests with the
signer's public keys.
The individual steps necessary for parsing a received SignedData message and
verifying the signatures may be summarized as follows:
SignedDataStream(InputStream is)
constructor for creating a SignedDataStream
object and implicitly performing the decoding:
SignedDataStream signedData = new SignedDataStream(encoded_stream);On the other hand, if the BER encoding represents an explicit SignedData object, use the
SignedDataStream(InputStream data_is, AlgorithmID[] hashAlgorithms)
constructor for initializing a new SignedDataStream object with raw data and
digest algorithms for hash computation (assuming that two hash algorithms are
used: SHA and RIPEMD160):
AlgorithmID[] algIDs = { ... }; SignedDataStream signedData = new SignedDataStream(data_is, algIDs);
InputStream dataIs = signedData.getInputStream(); byte[] buf = new byte[1024]; int r; while ((r = dataIs.read(buf)) > 0) { // do something useful }
decode
method:
signedData.decode(encoded_stream);
// get the signer infos SignerInfo[] signer_infos = signed_data.getSignerInfos(); // verify the signatures int numberOfSignerInfos = signer_infos.length; if (numberOfSignerInfos == 0) { System.out.println("Warning: Unsigned message (no SignerInfo included)!"); } else { for (int i = 0; i < numberOfSignerInfos; i++) { try { // verify the signature for SignerInfo at index i X509Certificate signer_cert = signed_data.verify(i); // if the signature is OK the certificate of the signer is returned System.out.println("Signature OK from signer: " + signer_cert.getSubjectDN()); } catch (SignatureException ex) { // if the signature is not OK a SignatureException is thrown System.out.println("Signature ERROR from signer: " + signed_data .getCertificate(signer_infos[i].getIssuerAndSerialNumber()) .getSubjectDN()); } } }
ContentStream
,
ContentInfoStream
,
SignerInfo
,
SignedData
Modifier and Type | Field and Description |
---|---|
protected int |
block_size
The block size for block oriented stream encoding.
|
protected X509Certificate[] |
certificates
Repository for the signer certificates.
|
protected ContentInfoStream |
content_info
The inherent ContentInfo.
|
protected ObjectID |
content_type
The content type.
|
protected X509CRL[] |
crls
Repository for any included CRLs.
|
static int |
EXPLICIT
Denotes a mode where the signed message is not transported within the
Signature
|
static int |
IMPLICIT
Denotes a mode where the signed message is included in the Signature
|
protected java.io.InputStream |
input_stream
An InputStream holding the data.
|
protected int |
mode
The mode specifying if the signed message is included in the Signature
(IMPLICIT), or if is not transported within the Signature (EXPLICIT).
|
protected java.util.Vector |
signer_infos
Repository for the SignerInfos.
|
protected DerInputStream |
this_object
An InputStream from which a DER encoded SignedData object is read.
|
protected int |
version
The version number, currently 1.
|
Modifier | Constructor and Description |
---|---|
protected |
SignedDataStream()
Default constructor for dynamic object creation in ContentInfo.
|
|
SignedDataStream(java.io.InputStream is)
Creates a new SignedDataStream where the DER encoded data is read from the
given InputStream.
|
|
SignedDataStream(java.io.InputStream data_is,
AlgorithmID[] hashAlgorithms)
Creates a new SignedDataStream from an InputStream holding the content that
has been transmitted by other means, and an array specifying the hash
algorithms to be used for digesting.
|
|
SignedDataStream(java.io.InputStream data_is,
int mode)
Creates a SignedDataStream object from an input stream supplying the data
to be signed.
|
|
SignedDataStream(ObjectID contentType)
Creates a new SignedDataStream object without any content.
|
Modifier and Type | Method and Description |
---|---|
void |
addSignerInfo(SignerInfo signerInfo)
Adds a SignerInfo object to this SignedData.
|
void |
decode(java.io.InputStream is)
Reads and decodes the SignedDataStream from a DerInputStream.
|
int |
getBlockSize()
Gets the block size defining the length of each definite primitive encoded
octet string component.
|
X509Certificate |
getCertificate(IssuerAndSerialNumber issuer)
Tries to find the certificate specified by an IssuerAndSerialNumber.
|
X509Certificate[] |
getCertificates()
Returns the certificates of the signers.
|
ObjectID |
getContentType()
Returns the content type this class implements.
|
X509CRL[] |
getCRLs()
Returns all the certificate-revocation lists included in this
SignedData object. |
AlgorithmID[] |
getDigestAlgorithms()
Returns a collection of message-digest algorithm identifiers.
|
java.io.InputStream |
getInputStream()
Returns an InputStream from where the signed content can be read.
|
byte[] |
getMessageDigest(AlgorithmID digestAlgorithm)
Returns the message digest calculated for a specific algorithm.
|
int |
getMode()
Returns the mode of this SignedData.
|
byte[] |
getSignedDigest(int signerInfoIndex)
Returns the message digest included in the authenticated attributes.
|
SignerInfo[] |
getSignerInfos()
Returns all the signer infos included in this
SignedData
object. |
int |
getVersion()
Returns the syntax version number.
|
void |
notifyEOF()
This method implements the EOFListener interface for performing the final
decoding.
|
void |
setBlockSize(int blockSize)
Sets the block size for defining the length of each definite primitive
encoded octet string component.
|
void |
setCertificates(X509Certificate[] certificates)
Sets the certificates of the several signers.
|
void |
setCRLs(X509CRL[] crls)
Sets a set of certificate-revocation lists.
|
void |
setInputStream(java.io.InputStream is)
Sets the InputStream which holds the content to sign.
|
void |
setMessageDigest(AlgorithmID digestAlgorithm,
byte[] digest)
This method can be used to set an externally calculated MessageDigest.
|
void |
setSignerInfos(SignerInfo[] signerInfos)
Sets a collection of per-signer information.
|
ASN1Object |
toASN1Object()
Returns this SignedDataStream as ASN1Object.
|
protected ASN1Object |
toASN1Object(int blockSize)
Returns this SignedData as ASN1Object where a constructed OCTET STRING is
used for encoding the content.
|
java.lang.String |
toString()
Returns a string giving some information about this
SignedDataStream object. |
java.lang.String |
toString(boolean detailed)
Returns a string giving some - if requested - detailed information about
this
SignedDataStream object. |
X509Certificate |
verify(int signerInfoIndex)
Verifies the signature that has been created by the
signerInfoIndex 'th signer. |
void |
verify(java.security.PublicKey publicKey,
int signerInfoIndex)
Uses the provided public key for verifying the signature that has been
created by the
signerInfoIndex 'th signer. |
SignerInfo |
verify(X509Certificate signerCertificate)
Uses the provided signer certificate for verifying the signature that has
been created by the signer being owner of the certificate.
|
void |
writeTo(java.io.OutputStream os)
DER encodes and writes this object to the supplied output stream.
|
void |
writeTo(java.io.OutputStream os,
int blockSize)
Writes this object to the supplied output stream where a constructed OCTET
STRING is used for encoding the content.
|
public static final int IMPLICIT
public static final int EXPLICIT
protected int version
protected ObjectID content_type
protected ContentInfoStream content_info
protected X509Certificate[] certificates
protected X509CRL[] crls
protected java.util.Vector signer_infos
protected DerInputStream this_object
protected java.io.InputStream input_stream
protected int mode
protected int block_size
protected SignedDataStream()
public SignedDataStream(ObjectID contentType)
contentType
- the contentType of the datapublic SignedDataStream(java.io.InputStream data_is, int mode)
data_is
- a stream holding the data to signmode
- IMPLICIT if the message shall be included in the DER encoding,
EXPLICIT otherwisepublic SignedDataStream(java.io.InputStream is) throws PKCSParsingException, java.io.IOException
Do not use this constructor for supplying the content data to
be signed. This constructor may be used by the recipient for parsing an
already existing SignedDataStream
object, supplied as DER
encoding from an input stream, and may have been created by one of the
writeTo
methods.
Use the SignedDataStream(InputStream data_is, int mode)
constructor for supplying
the content data to be signed when creating a SignedDataStream
object.
This constructor only shall be used for decoding a SignedData object
with included raw data (implicit mode).
To initialize a SignedDataStream object for parsing an explicit SignedData
message where the raw data is not included, use the
SignedDataStream(InputStream data_is, AlgorithmID[] hashAlgorithms)
constructor, and perform the decoding explicitly by calling the
decode
method.
is
- the InputStream holding a DER encoded PKCS#7 SignedData objectjava.io.IOException
- if an I/O error occurs during reading from the InputStreamPKCSParsingException
- if an error occurs while parsing the objectpublic SignedDataStream(java.io.InputStream data_is, AlgorithmID[] hashAlgorithms) throws java.io.IOException
Do not use this constructor for supplying the content value
to be signed. This constructor may be used by the recipient for
initializing the digest computation for an already existing explicit
SignedDataStream message where the raw data is not included. The
initialization is done by wrapping a digest stream around the supplied raw
data stream for any specified hash algorithm. Subsequently the hash values
will be updated when reading the stream thereby piping the data through the
digest streams. Later, during signature verification the digest computation
is finished and the results are compared with the hash values derived from
decrypting the encrypted digests with the signer's public keys.
For an explicit message the actual decoding has to be performed by calling
the decode
method just after reading the data:
// initialize for hash computation: SignedDataStream signedData = new SignedDataStream(data_is, hashAlgorithms); // read the stream thereby updating the hash values: InputStream dataIs = signed_data.getInputStream(); byte[] buf = new byte[1024]; int r; while ((r = dataIs.read(buf)) > 0) { // do something useful } // explicitly perform the decoding signedData.decode(encoded_stream);
A sender shall use the SignedDataStream(InputStream data_is, int mode)
constructor for supplying
the content to be signed when creating a SignedDataStream
object.
For decoding an implicit SignedDataStream message, use the
SignedDataStream(InputStream is)
constructor.
data_is
- the InputStream supplying the raw data which has been transmitted
by other meanshashAlgorithms
- the hash algorithms used by the participated signers for digesting
the content datajava.io.IOException
- if there is no implementation for the specified hash algorithmpublic void decode(java.io.InputStream is) throws java.io.IOException, PKCSParsingException
DerInputStream
, internally a
DerInputStream is created before parsing the data.
This method implicitly is called from inside the corresponding constructor
for decoding an received implicit SignedDataStream object where the raw
data is included. This method has to be explicitly called for decoding a
received explicit SignedDataStream object where the raw data is not
included. Before calling this method for decoding an explicit message, a
new SignedDataStream object has to be created by means of the
SignedDataStream(InputStream data_is, AlgorithmID[] hashAlgorithms)
constructor for initializing it for hash computation, and the data has to
be read from the stream for updating the hash values:
// initialize for hash computation: SignedDataStream signedData = new SignedDataStream(data_is, hashAlgorithms); // read the stream thereby updating the hash values: InputStream dataIs = signed_data.getInputStream(); byte[] buf = new byte[1024]; int r; while ((r = dataIs.read(buf)) > 0) { // do something useful } // explicitly perform the decoding signedData.decode(encoded_stream);
decode
in interface ContentStream
is
- the InputStream holding a DER encoded PKCS#7 SignedData objectjava.io.IOException
- if an I/O error occurs during reading from the InputStreamPKCSParsingException
- if an error occurs while parsing the objectpublic void notifyEOF() throws java.io.IOException
iaik.utils.NotifyEOFInputStream
is wrapped around this raw data stream for
indicating that the parsing procedure is to be notified when the stream
actually has been read. At that point, the program executing automatically
jumps to the actual notifyEOF
method for finishing the
decoding by parsing the remaining certificates, crls and signerInfos
fields. iaik.utils.EOFListener
interface.notifyEOF
in interface EOFListener
java.io.IOException
- if an error occurs while parsing the streamEOFListener
,
NotifyEOFInputStream
public int getMode()
IMPLICIT
or EXPLICIT
public byte[] getMessageDigest(AlgorithmID digestAlgorithm) throws java.security.NoSuchAlgorithmException
DigestProvider
interface, and therefore has to be qualified as public method.
However, there should be no necessity for an application to utilize this
method. This method only is called from inside the
SignerInfo
class for obtaining the
digest calculated on the content for the specified hash algorithm.
It is strongly recommended not to explicitly call this method,
since it actually finishes the digest computation for all hash values
resulting from piping the data through the digest streams. This only has to
be performed once and is done from inside the SignerInfo
class!
digestAlgorithm
- the hash algorithm to be used for digest computationjava.security.NoSuchAlgorithmException
- if there is no message digest for the specified algorithmpublic void setMessageDigest(AlgorithmID digestAlgorithm, byte[] digest) throws java.security.NoSuchAlgorithmException
added
the
SignerInfos. If none of the SignerInfos uses the specified digest algorithm
a NoSuchAlgorithmException is thrown and the digest cannot be added. On the
parsing side a digest value can be set for any of the digest algorithms
that are parsed from the digestAlgorithms field.digestAlgorithm
- the hash algorithm for which the digest shall be setdigest
- the new value for the message digestjava.security.NoSuchAlgorithmException
- if the specified digest algorithm is not by any of the
SignerInfos of this SignedDatapublic void setBlockSize(int blockSize)
blockSize
is
smaller or equal to zero the whole data is encoded as definite primitive
octet string. This method may be used for enforcing block encoding when
wrapping the SignedData into a ContentInfo.setBlockSize
in interface ContentStream
blockSize
- for defining the encoding scheme and setting the octet string
component length, if positiveOCTET_STRING
public int getBlockSize()
blockSize
is smaller
or equal to zero the whole data is encoded as definite primitive octet
string. This method may be used for enforcing block encoding when wrapping
the EncryptedData into a ContentInfo.getBlockSize
in interface ContentStream
OCTET_STRING
public void setInputStream(java.io.InputStream is)
is
- InputSteam holding the content to signpublic java.io.InputStream getInputStream()
public ObjectID getContentType()
getContentType
in interface ContentStream
ObjectID.pkcs7_signedData
public void setCertificates(X509Certificate[] certificates)
It is intended that the set be sufficient to contain chains from a recognized "root" to all of the signers in the signerInfo field.
certificates
- the certificates of the signers as array of X509Certificatepublic void setCRLs(X509CRL[] crls)
The given CRLs supply information about the revocation status of the
certificates specified in the certificates
field.
crls
- a set of certificate-revocation lists as array of X509CRLspublic void setSignerInfos(SignerInfo[] signerInfos) throws java.security.NoSuchAlgorithmException
There may be any number of elements in the collection, including zero.
signerInfos
- a collection of per-signer informationjava.security.NoSuchAlgorithmException
- if there is no implementation for the message digest algorithm
specified in one signerInfoSignerInfo
public void addSignerInfo(SignerInfo signerInfo) throws java.security.NoSuchAlgorithmException
This method not only adds the given SignerInfo, but also initializes the hash computation by wrapping a digest stream for the signer's hash algorithm around the data carrying input stream.
signerInfo
- the SignerInfo to addjava.security.NoSuchAlgorithmException
- if there is no implementation for the message digest algorithm
specified in the signerInfoSignerInfo
public int getVersion()
public AlgorithmID[] getDigestAlgorithms()
There may be any number of elements in the collection, including zero. The returned OIDs identify the digest algorithms used by the several signers.
public X509Certificate[] getCertificates()
null
if no
certificates are includedpublic void verify(java.security.PublicKey publicKey, int signerInfoIndex) throws java.security.SignatureException
signerInfoIndex
'th signer.
Note that this method does not perform any certificate verification.
signerInfoIndex
- the index into the SignerInfos array for identifying the
SignerInfo belonging to the signer whose signature has to be
verifiedpublicKey
- the public key of the signer to verify the messagejava.security.SignatureException
- if the signature turns out to be incorrectpublic X509Certificate verify(int signerInfoIndex) throws java.security.SignatureException
signerInfoIndex
'th signer.
The signature is verified by using the specified signer's public key, which
is get from the signer's certificate, derived from the certificates
field.
Verifying the signatures of all the signer's included into some specific SignedData object may be done by "looping" through all the included SignerInfos, e.g.:
SignerInfo[] signer_infos = signed_data.getSignerInfos(); int numberOfSignerInfos = signer_infos.length; if (numberOfSignerInfos == 0) { System.out.println("Warning: Unsigned message (no SignerInfo included)!"); } else { for (int i = 0; i < numberOfSignerInfos; i++) { try { // verify the signed data using the SignerInfo at index i X509Certificate signer_cert = signed_data.verify(i); // if the signature is OK the certificate of the signer is returned System.out.println("Signature OK from signer: " + signer_cert.getSubjectDN()); } catch (SignatureException ex) { // if the signature is not OK a SignatureException is thrown System.out.println("Signature ERROR from signer: " + signed_data .getCertificate(signer_infos[i].getIssuerAndSerialNumber()) .getSubjectDN()); } } }The simple example above verifies the correctness of the signature value(s) and dumps the result to System.out. In practice an application will require some more sophisticated error processing.
Note that this method does not perform any certificate verification.
signerInfoIndex
- the index into the SignerInfos array for identifying the
SignerInfo belonging to the signer whose signature has to be
verifiedjava.security.SignatureException
- if the signature turns out to be incorrectpublic SignerInfo verify(X509Certificate signerCertificate) throws java.security.SignatureException
certificate
is not empty. However, take in
mind that you should not step through the entries of the
certificates
field for calling verify(cert)
for
any certificate presented there since there also may (shall) be included
issuer certificates and certificate chains leading to some trusted root.
Note that this method does not perform any certificate verification.
signerCertificate
- the certificate of the signer whose signature should be verifiedjava.security.SignatureException
- if the signature turns out to be incorrect or there is no
signer with the given certificatepublic byte[] getSignedDigest(int signerInfoIndex) throws PKCSException
signerInfoIndex
- the index into the SignerInfos array for identifying the
SignerInfo belonging to the signer whose message digest shall be
returnedPKCSException
public X509Certificate getCertificate(IssuerAndSerialNumber issuer) throws PKCSException
issuer
- the IssuerAndSerialNumber identifying the certificate to search
forPKCSException
- if the requested certificate cannot be foundpublic X509CRL[] getCRLs()
SignedData
object.null
if there are no CRLs
includedsetCRLs(iaik.x509.X509CRL[])
public SignerInfo[] getSignerInfos()
SignedData
object.SignerInfo
objects
included into this SignedData
, or null
if
there are no signers specifiedpublic ASN1Object toASN1Object() throws PKCSException
toASN1Object
in interface ContentStream
PKCSException
- if the ASN1Object could not be createdprotected ASN1Object toASN1Object(int blockSize) throws PKCSException
blockSize
- the block size defining the encoding scheme - and specifying the
length of each primitive encoded octet string component, if
positivePKCSException
- if the ASN1Object could not be createdpublic void writeTo(java.io.OutputStream os) throws java.io.IOException
0x04 <length> <data>
os
- the output stream to which this SignedDataStream shall be encodedjava.io.IOException
- if an error occurs when writing to the streampublic void writeTo(java.io.OutputStream os, int blockSize) throws java.io.IOException
0x24 0x80 0x04 <blocksize> <data> 0x04 <blocksize> <data> 0x04 <blocksize> <data> ... 0x00 0x00If the block size is not positive, whole the inherent data is encoded as one single primitive definite octet string:
0x04 <length> <data>
os
- the output stream to which this SignedData shall be writtenblockSize
- the block size defining the encoding scheme - and specifying the
length of each primitive encoded octet string component, if
positivejava.io.IOException
- if an error occurs during writing the objectpublic java.lang.String toString()
SignedDataStream
object.toString
in class java.lang.Object
public java.lang.String toString(boolean detailed)
SignedDataStream
object.toString
in interface ContentStream
detailed
- - whether or not to give detailed information