public class SignedDataStream extends java.lang.Object implements ContentStream, EOFListener
SignedData.
Each CMS content type is associated with a specific object identifier, derived from PKCS#7:
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 CMS Cryptographic Message Syntax
(RFC 2630) 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 RFC 2630):
SignedData ::= SEQUENCE {
version CMSVersion,
digestAlgorithms DigestAlgorithmIdentifiers,
encapContentInfo EncapsulatedContentInfo,
certificates [0] IMPLICIT CertificateSet OPTIONAL,
crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
signerInfos SignerInfos }
DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
CertificateSet ::= SET OF CertificateChoices
CertificateChoices ::= CHOICE {
certificate Certificate, -- See X.509
extendedCertificate [0] IMPLICIT ExtendedCertificate, -- Obsolete
attrCert [1] IMPLICIT AttributeCertificate } -- See X.509 & X9.57
}
CertificateRevocationLists ::= SET OF CertificateList
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; also attribute
certificates maybe included. 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 including 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 according to the signature algorithm used (rsaEncryption or DSA).
For more information consult the RSA RFC 2630.
When creating a SignedDataStream object for the content to be signed by using
the SignedDataStream(InputStream is, int mode)
constructor, the transimission mode has to be specified. You may use an alternative
constructor for additionally
specifying the content type of the inherent EncapsulatedContentInfo; default is
id-data. If the mode is set to SignedDataStream.IMPLICIT the content 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 content data has to be supplied when creating the
SignedDataStream object, because it is needed for the digest computation:
InputSrteam[] data_stream = ...; // the content 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 CMS 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 as followed (to simplify matters, we will assume not to include
certificate revocation lists):
SignedDataStream object thereby supplying the content 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 instances
iaik.x509.X509Certificate (and iaik.x509.attr.AttributeCertificate):
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 can be specified, because it is the intended purpose of this stream-supporting
SignedData implementation to handle large amounts of data. When no block size is
specified whole the content data is encoded as one primitive definite octet string, which
advantageously may be done when using the non-stream supporting
SignedData implementation.
When a positve block size is specified for encoding the SignedData to a stream,
the content 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 0x00
instead of:
0x04 0x05 0x01 0xAB 0x23 0x7F 0xCA
for encoding the five data bytes 0x01 0xAB 0x23 0x7F 0xCA. The indefinte
constrcuted 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 content 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 content 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 content 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 content data for the
digest algorithms of all participated signers. Later, during signature verification the
digest value computaion is finished and the results are used for checking the signatures
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 content data and
digest algorithms for hash computation (assuming that two hash algorithms
are used: SHA and MD5):
AlgorithmID[] algIDs = { AlgorithmID.sha1, AlgorithmID.md5 };
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
for (int i=0; i < signer_infos.length; 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 |
blockSize_
The block size for block oriented stream encoding.
|
protected CertificateSet |
certSet_
Repository for the signer certificates.
|
protected ObjectID |
contentType_
The content type.
|
protected X509CRL[] |
crls_
Repository for any included CRLs.
|
protected EncapsulatedContentInfoStream |
encapContentInfo_
The inherent EncapsualtedContentInfo.
|
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 |
inputStream_
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 SecurityProvider |
securityProvider_
The SecurityProvider to be used.
|
protected java.util.Vector |
signerInfos_
Repository for the SignerInfos.
|
protected DerInputStream |
thisObject_
An InputStream from which a DER encoded SignedData object is read.
|
protected int |
version_
The version number, default 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(java.io.InputStream data_is,
ObjectID contentType,
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.
|
AttributeCertificate[] |
getAttributeCertificates()
Returns the attribute certificates included in this SignedData.
|
int |
getBlockSize()
Gets the block size defining the length of each definite primitive
encoded octet string component.
|
X509Certificate |
getCertificate(CertificateIdentifier signerIdentifier)
Tries to find the signer certificate specified by the given CertificateIdentidier.
|
java.security.cert.Certificate[] |
getCertificates()
Returns all certificates included.
|
CertificateSet |
getCertificateSet()
Gets the certificateSet holding all certificates included in this SignedData.
|
ObjectID |
getContentType()
Returns the content type this class implements.
|
X509CRL[] |
getCRLs()
Returns all the cerificate-revocation lists included in this
SignedData object. |
AlgorithmID[] |
getDigestAlgorithms()
Returns a collection of message-digest algorithm identifiers.
|
ObjectID |
getEncapsulatedContentType()
Returns the content type the inherent EncapsulatetContentInfo represents.
|
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 (1 or 3).
|
X509Certificate[] |
getX509Certificates()
Returns the X.509 public key certificates included.
|
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(java.security.cert.Certificate[] certificates)
Sets the certificates of the several signers.
|
void |
setCertificateSet(CertificateSet certSet)
Sets the certificateSet to be included.
|
void |
setCRLs(X509CRL[] crls)
Sets a set of cerificate-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 SignedData 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.
|
X509Certificate |
verifyAndValidate(int signerInfoIndex,
CertVerifier certVerifier)
Verifies and validates the SignerInfo structure that exists in this
SignedDataStream object at the indicated index. |
SignerInfo |
verifyAndValidate(X509Certificate signerCert,
CertVerifier certVerifier)
Verifies and validates the SignerInfo structure that exists in this
SignedDataStream object and corresponds to the indicated
signer 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 contentType_
protected EncapsulatedContentInfoStream encapContentInfo_
protected CertificateSet certSet_
protected X509CRL[] crls_
protected java.util.Vector signerInfos_
protected DerInputStream thisObject_
protected java.io.InputStream inputStream_
protected int mode_
protected int blockSize_
protected SecurityProvider securityProvider_
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 signIMPLICIT - if the message shall be included in the DER encoding,
EXPLICIT otherwisepublic SignedDataStream(java.io.InputStream data_is,
ObjectID contentType,
int mode)
Use this constructor for signing content having any other type than CMS (PKCS#7) id-data.
In such cases typically the given InputStream will supply the DER encoding of a particular
content object to be signed. The PKIX Time Stamp protocol, for instance, defines a
TSTInfo structure to be signed by using a CMS SignedData object. Assuming to
read a DER encoded TSTInfo from an input stream it may be
supplied to a SignedDataStream-object in a way similar to:
// the input stream supplying the DER encoded TSTInfo: InputStream encodedTSTInfo = ...; // now sign the TSTInfo: ObjectID oid = ObjectID.tstInfo; int mode = SignedDataStream.IMPLICIT; SignedDataStream signedData = new SignedDataStream(enodedTSTInfo, oid, mode); ...
data_is - a stream holding the data to signcontentType - the contentType for the inherent EncapsulatedContentInfoIMPLICIT - if the message shall be included in the DER encoding,
EXPLICIT otherwisepublic SignedDataStream(java.io.InputStream is)
throws CMSParsingException,
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 exisiting 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) or
SignedDataStream(InputStream data_is, ObjectID contentType, int mode)
constructors 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 content data (implicit mode).
To initialize a SignedDataStream object for parsing an explicit SignedData message where the
content 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 CMS SignedData objectjava.io.IOException - if an I/O error occurs during reading from the InputStreamCMSParsingException - 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 content data is not included. The initialization is done by wrapping a digest
stream around the supplied content 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 computaion 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 content 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,
CMSParsingException
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 content data is
included.
This method has to be explicitly called for decoding a received explicit
SignedDataStream object where the content 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 upadating 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 ContentStreamis - the InputStream holding a DER encoded CMS SignedData objectjava.io.IOException - if an I/O error occurs during reading from the InputStreamCMSParsingException - if an error occurs while parsing the objectpublic void notifyEOF()
throws java.io.IOException
iaik.utils.NotifyEOFInputStream
is wrapped around this content data stream
for indicating that the parsing procedure is to be notified when the stream actually
has been read. At that point, the programm exceuting 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 EOFListenerjava.io.IOException - if an error occurs while parsing the streamEOFListener,
NotifyEOFInputStreampublic int getMode()
IMPLICIT or EXPLICITpublic 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 finshes 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
digestAlgorithm - the hash algorithm for which the digest shall be setdigest - the new value for the messsage digestjava.security.NoSuchAlgorithmException - if there is no message digest for the specified algorithmpublic 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 ContentStreamblockSize - for defining the encoding scheme and setting the octet
string component length, if positiveOCTET_STRINGpublic 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 ContentStreamOCTET_STRINGpublic void setInputStream(java.io.InputStream is)
is - InputSteam holding the content to signpublic java.io.InputStream getInputStream()
public ObjectID getContentType()
getContentType in interface ContentStreamObjectID.cms_signedDatapublic ObjectID getEncapsulatedContentType()
public void setCertificates(java.security.cert.Certificate[] certificates)
Attention! Only X.509 public key certificates (instances of
iaik.x509.X509Certificate) or X.509 attribute certificates
(instances of iaik.x509.attr.AttributeCertificate) can be
added to this SignedData object; PKCS#6 extended certificates are obsolete
and therefore not supported.
certificates - the certificates to be setjava.lang.IllegalArgumentException - if any of the supplied certificates
is not a iaik.x509.X509Certificate or
iaik.x509.attr.AttributeCertificate objectpublic void setCertificateSet(CertificateSet certSet)
CertificateSet that may hold any
number of X.509 public key and/or attribute certificates.
iaik.x509.X509Certificate) or X.509 attribute certificates
(instances of iaik.x509.attr.AttributeCertificate) can be
included in the given CertificateSet; PKCS#6 extended certificates are obsolete
and therefore not supported.certSet - the certificate set to be addedpublic 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 cerificate-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 signerInfoSignerInfopublic 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 algortihm 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 signerInfoSignerInfopublic 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 java.security.cert.Certificate[] getCertificates()
Any certificate returned by this method either may be an
X.509 public key certificate (iaik.x509.X509Certificate)
or an X.509 attribute certificate (iaik.x509.attr.AttributeCertificate).
PKCS#6 extended certificates are obsolete and therefore not supported.
null if no certificates are
includedpublic X509Certificate[] getX509Certificates()
null
if no X.509 certificates are includedpublic AttributeCertificate[] getAttributeCertificates()
null if no attribute certificates are
includedpublic CertificateSet getCertificateSet()
null, however the retrieved
certificateSet maybe empty. If not empty, the CertificateSet returned
may contain X.509 public key certificate (iaik.x509.X509Certificate
objects) and/or or an X.509 attribute certificate (iaik.x509.attr.AttributeCertificate
objects); PKCS#6 extended certificates are obsolete and therefore not supported.public 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[] signerInfos_ = signed_data.getSignerInfos();
for (int i=0; i<signerInfos_.length; 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(signerInfos_[i].getIssuerAndSerialNumber()).getSubjectDN());
}
}
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 incorrect or the certifcatepublic 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 certificate or the certifcatepublic byte[] getSignedDigest(int signerInfoIndex)
throws CMSException
signerInfoIndex - the index into the SignerInfos array for identifying the
SignerInfo belonging to the signer whose message digest
shall be returnedCMSExceptionpublic X509Certificate getCertificate(CertificateIdentifier signerIdentifier) throws CMSException
This method searches the certificates field of this SignedData
for a certificate identified by the given SignerIdentifier (either an
IssuerAndSerialNumber or SubjectKeyIdentifier). If you additionally want to check
if the certificate found is identified as signer certificate by means of
a SigningCertificate attribute,
you may use method isSignerCertificate of class SignerInfo,
e.g.:
try {
SignerInfo signerInfo = signedData.getSignerInfos()[0];
X509Certificate signerCert = signedData.getCertificate(signerIdentifier);
if (signerInfo.isSigningCertificate(signerCert)) {
System.out.println("Signer certificate: " + signerCert);
} else {
System.out.pritnln("Signer certificate not included!");
}
} catch (CMSException ex) {
System.out.println("Signer certificate not included!");
}
signerIdentifier - the signerIdentifier IssuerAndSerialNumber or SubjectKeyIdentifier)
identifying the certificate to search forCMSException - 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 CMSException
toASN1Object in interface ContentStreamCMSException - if the ASN1Object could not be createdprotected ASN1Object toASN1Object(int blockSize) throws CMSException
blockSize - the block size defining the encoding scheme - and specifying the
length of each primitive encoded octet string component, if positiveCMSException - 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 0x00
If 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.Objectpublic java.lang.String toString(boolean detailed)
SignedDataStream object.toString in interface ContentStreamdetailed - - whether or not to give detailed informationpublic X509Certificate verifyAndValidate(int signerInfoIndex, CertVerifier certVerifier) throws java.security.SignatureException, CertificationException, TimeStampException, RevocationWarningException
SignedDataStream object at the indicated index.
First the signature is verified to ensure that the data has not been tampered since it was signed. Then, if the signature does not contain a time-stamp, the signer's certificate is validated at the present time. However, if the signature does contain a time-stamp, the time-stamp token is decoded, verified and validated, and then the signer's certificate is validated at the time specified in the time-stamp.
In order to verify a signature contained in a SignerInfo structure, the
corresponding signer certificate must be located. Using the signer
identifer from the SignerInfo structure, the signer certificate is
located by searching the 'certificates' included in the
SignedDataStream and then searching the trusted certificates
contained in the certificate validation mechanism.
When validating the signer's certificate at the time specified by the
time-stamp, a revocation warning can occur. This happens when the signer's
certificate has been revoked, but was revoked after the time specified in
the time-stamp. When this occurs, the signer's certificate can still be
considered valid, depending on the policy surrounding time-stamping and the
reason it was revoked. In this case, a
RevocationWarningException exception will be thrown; it is then
up to the caller to decide whether the warning should be ignored, or acted
upon.
signerInfoIndex - the index of the SignerInfo structure to be verified/validatedcertVerifier - the certificate validation mechansim; used to validate the signer's
certificatejava.security.SignatureException - thrown if the signature has been tampered, or a SignerInfo structure
with the specified index does not exist, or the corresponding signer
certificate could not be foundCertificateException - thrown if the signature cannot be trustedTimeStampException - thrown if the signature is time-stamped, but the time-stamp is invalid
or cannot be trustedRevocationWarningException - thrown if the signer's certificate was revoked, but was revoked
after the time specified in the time-stamp; the caller must then
decided if the signature can be trustedCertificationExceptionpublic SignerInfo verifyAndValidate(X509Certificate signerCert, CertVerifier certVerifier) throws java.security.SignatureException, CertificationException, TimeStampException, RevocationWarningException
SignedDataStream object and corresponds to the indicated
signer certificate.
First the signature is verified to ensure that the data has not been tampered since it was signed. Then, if the signature does not contain a time-stamp, the signer's certificate is validated at the present time. However, if the signature does contain a time-stamp, the time-stamp token is decoded, verified and validated, and then the signer's certificate is validated at the time specified in the time-stamp.
When validating the signer's certificate at the time specified by the
time-stamp, a revocation warning can occur. This happens when the signer's
certificate has been revoked, but was revoked after the the time specified
in the time-stamp. When this occurs, the signer's certificate can still be
considered valid, depending on the policy surrounding time-stamping and the
reason it was revoked. In this case, a
RevocationWarningException exception will be thrown; it is then
up to the caller to decide whether the warning should be ignored, or acted
upon.
signerCert - the certificate that corresponds the SignerInfo structure to be
verified/validated; used to verify the signaturecertVerifier - the certificate validation mechansim; used to validate the signer's
certificatejava.security.SignatureException - thrown if the signature has been tampered or the SignerInfo structure
that corresponds to the signer's certificate could not be foundCertificateException - thrown if the signature cannot be trustedTimeStampException - thrown if the signature is time-stamped, but the time-stamp is invalid
or cannot be trustedRevocationWarningException - thrown if the signer's certificate was revoked, but was revoked
after the time specified in the time-stamp; the caller must then
decided if the signature can be trustedCertificationException