iaik.cms
Class SDSEncodeListener

java.lang.Object
  extended by iaik.cms.SDSEncodeListener
Direct Known Subclasses:
DefaultSDSEncodeListener

public abstract class SDSEncodeListener
extends java.lang.Object

A listener allowing an application to update a SignedDataStream during it is encoded.

In some situations it may be useful to supply information to a SignedDataStream actually during encoding is performed. When implementing an SignedDataStream encode listener an application has the chance to update the SignedDataStream at two points during the encoding process: AFTER the content data has been processed and any digest has been calulated (= BEFORE any signature value is computed) and AFTER the signature values have been calculated. When doing so an application has to implement two abstract methods: beforeComputeSignature and afterComputeSignature (of course, an application may implement any of the two methods in a way to do actually nothing (if no functionality is required)).

An application may wish to update a SignedData object BEFORE the signature of any included SignerInfo is computed but AFTER the content data has been written and the digest value over the content has already been calculated. This may be useful to, for instance, add some attribute(s) to be signed by some signer where the value of some attribute depends on the digest of the content data (e.g. an optional time stamp proving that the data has existed before the signature has been calculated). Another example for implementing method beforeComputeSignature maybe to add some new SignerInfo to an existing implicit SignedData that should be encoded again. Since the content data again has to be included in the new encoding, but the signerInfos field is located behind the content any new SignerInfo may be added not before the content has been processed. However, since digest computation has to be initialized before the data is written, any digest algorithm not used by the already included SignerInfos has to be known in advance to can be announced when binding this SDSEncodeListener to a SignedDataStream object. For that reason any digest algorithm that is required by some SignerInfo to be added should be set setDigestAlgorithms for this SDSEncodeListener, e.g.:

 // A SignedDataStream encode listener allowing to add SignerInfos
 // during the encoding process after data has been processed and
 // digest calculation has been performed, but before signature
 // values have been computed
 public class MySDSEncodeListener extends SDSEncodeListener {
   ...
   // SignerInfos to be added during encoding
   protected SignerInfo[] signerInfos_;
   ...
   // certificates to be added during encoding
   protected Certificate[] certificates_;
   ...
   // crls to be added during encoding
   protected X509CRL[] crls_;

   ...
   
   // constructor
   public MySDSEncodeListener() {
     super();
   }
   
   ...
   // add methods allowing to set SignerInfos, certificates, crls,...
   ...

   // implements beforeComputeSignature to add any SignerInfos, certs, crls,...
   // Since method beforeComputeSignature is executed before
   // signature computation actually is performed, the signatureValue
   // field of the new SignerInfo may be left empty to let be set
   // automatically during the following signature computation process.
   protected void beforeComputeSignature(SignedDataStream signedData) 
     throws CMSException {
     
     signedData.addCertificates(certificates_);
     signedData.addCRLs(crls_);
     if (signerInfos_ != null) {
     try {  
       for (int i = 0; i < signerInfos_.length; i++) {
         signedData.addSignerInfo(signerInfos_[i]); 
       }
     } catch (Exception ex) {
       throw new CMSException("Error adding signer info: " + ex.toString()); 
     }  
   }    
   
   // implements afterComputeSignature to do just nothing (we assume that
   // we do not require this functionality here
   protected void afterComputeSignature(SignedDataStream signedData) 
     throws CMSException {
   }  
 }    

 // create a new encode listener:
 MySDSEncodeListener myListener = new MySDSEncodeListener();
 // supply any SignerInfos, certs, crls,...
 ...
 // supply the digest algorithm(s) to be announced when binding the
 // listener to a SignedDataStream object:
 AlgorithmID[] digestAlgIDs = ...;
 myListener.setDigestAlgorithms(digestAlgIDs);
 // bind the listener to a SignedDataStream object:
 signedDataStream.setSDSEncodeListener(myListener);
 
Note that IAIK-CMS includes a simple @link iaik.cms.DefaultSDSEncodeListener default} SignedDataStream encode listener implementation with exactly the same functionality as described in the sample above. Additionally the default SDS encode listener implements method afterComputeSignature to verify the signature of each SignerInfo included.

An application may wish to update a SignedData object AFTER the signature of any included SignerInfo has been computed. This may be useful to, for instance, add some unsigned attribute(s) to some SignerInfo where the value of some attribute depends on the signature value of the particular SignerInfo (e.g. a time stamp proving that the siganture value has existed at the date of the time stamp). Another example for implementing this method maybe to add an unsigned CounterSignature attribute to a SignerInfo of an existing implicit SignedData that should be encoded again making it desirable to first verify the signature of the SignerInfo to be counter signed.

An SDSEncodeListener may be supplied with an output stream to which the content of the SignedDataStream this SDSListener belongs to shall be written. Supplying an output stream may be useful when using an SDSEncodeListener during encoding an implicit SignedDataStream again just during parsing it: The content of the SignedDataStream just decoded cannot be read in the conventional way (except for using some buffer mechanism) since it is required during the new encoding procedure. When supplying an output stream to this SDSEncodeListener, the content is copied to this stream during encoding the SignedData object again:

 OutputStream os = ...;
 myListener.setOutputStream(os);
 

An application implementing an SignedDataStream encode listener may wish to have some final report what actually has happened during execution of method beforeComputeSignature or afterComputeSignature. If, for instance, an application has implemented method afterComputeSignature to add a CounterSignature attribute to the unsigned attributes field of a SignerInfo it first may wish to verify the signature of the SignerInfo in mind. The application may decide to implement method afterComputeSignature in a way to throw an exception (and stop program execution) if the verification fails, or it, for instance, may decide to continue processing without adding the CounterSignature. To be informed about the failed CounterSignature adding attempt, method afterComputeSignature may trigger some report that later may be obtained by calling method getReport. However, it is left to the application to implement an report utility satisfying its requirements. Per default no report is used and method getReport returns null.

See Also:
SignedDataStream, DefaultSDSEncodeListener

Field Summary
protected  AlgorithmID[] digestAlgorithms_
          Digest algorithms that may be required to initialize the digest computation for any SignerInfos that shall be added during execution of method beforeComputeSignature.
protected  java.io.OutputStream outputStream_
          An output stream to which the SignedData content may be written.
protected  java.lang.Object report_
          A general "logging" object.
 
Constructor Summary
SDSEncodeListener()
          Empty default constructor.
 
Method Summary
protected abstract  void afterComputeSignature(SignedDataStream signedData)
          Abstract method to be implemented for updating the given SignedDataStream after signature computation has been performed.
protected abstract  void beforeComputeSignature(SignedDataStream signedData)
          Abstract method to be implemented for updating the given SignedDataStream before signature computation is performed.
 AlgorithmID[] getDigestAlgorithms()
          Gets any digest algorithms that may be required to initialize the digest computation for any SignerInfo(s) that shall be added during execution of method beforeComputeSignature.
 java.io.OutputStream getOutputStream()
          Gets the output stream that may have been set to write the SignedData content to it.
 java.lang.Object getReport()
          Gets a report about the processing of this SDSEncodeListener.
 void setDigestAlgorithms(AlgorithmID[] digestAlgorithms)
          Sets any digest algorithms that may be required to initialize the digest computation for any SignerInfo(s) that shall be added during execution of method beforeComputeSignature.
 void setOutputStream(java.io.OutputStream outputStream)
          Sets an output stream to which the SignedData content shall be written.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

outputStream_

protected java.io.OutputStream outputStream_
An output stream to which the SignedData content may be written.

An SDSEncodeListener may be supplied with an output stream to which the content of the SignedDataStream this SDSListener belongs to shall be written. Supplying an output stream may be useful when using an SDSEncodeListener during encoding an implicit SignedDataStream again just during parsing it: The content of the SignedDataStream just decoded cannot be read in the conventional way (except for using some buffer mechanism) since it is required during the new encoding procedure. When supplying an output stream to this SDSEncodeListener, the content is copied to this stream during encoding the SignedData object again.


report_

protected java.lang.Object report_
A general "logging" object.

An application extending this class may wish to have some final report what actually has happened during execution of method beforeComputeSignature or afterComputeSignature. If, for instance, an application has implemented method afterComputeSignature to add a CounterSignature attribute to the unsigned attributes field of a SignerInfo it first may wish to verify the signature of the SignerInfo in mind. The application may decide to implement method afterComputeSignature in a way to throw an exception (and stop program execution) if the verification fails, or it, for instance, may decide to continue processing without adding the CounterSignature. To be informed about the failed CounterSignature adding attempt, method afterComputeSignature may trigger some report that later may be obtained by calling method getReport. However, it is left to the application to implement an report utility satisfying its requirements. Per default no report is used and method getReport returns null.


digestAlgorithms_

protected AlgorithmID[] digestAlgorithms_
Digest algorithms that may be required to initialize the digest computation for any SignerInfos that shall be added during execution of method beforeComputeSignature. When parsing an implicit SignedData object and encoding it again an application may wish to add some new SignerInfo(s). Since the signerInfos field is located behind the content data the SignerInfo SET can not be accessed before the content data is written to the new encoding stream. Since digest computation has to be initialized before the data is written, any digest algorithm not used by the already included SignerInfos has to be known in advance to can be announced when binding this SDSEncodeListener to a SignedDataStream object.

Constructor Detail

SDSEncodeListener

public SDSEncodeListener()
Empty default constructor.

Method Detail

setOutputStream

public void setOutputStream(java.io.OutputStream outputStream)
Sets an output stream to which the SignedData content shall be written.

This method may be used to set an output stream to which the content of the SignedDataStream this SDSListener belongs to shall be written. Setting an output stream may be useful when having to encode an implicit SignedDataStream again just during parsing it: The content of the SignedDataStream just decoded cannot be read in the conventional way (except for using some buffer mechanism) since it is required during the new encoding procedure. When setting an output stream to this SDSEncodeListener, the content is copied to this stream during encoding the SignedData object again. An application shall NOT override this method.

Parameters:
outputStream - an output stream to which to "copy" the content of the SignedDataStream to which this SDSEncodeListener is bound

getOutputStream

public java.io.OutputStream getOutputStream()
Gets the output stream that may have been set to write the SignedData content to it.

An SDSEncodeListener may be supplied with an output stream to which the content of the SignedDataStream this SDSListener belongs to shall be written. Supplying an output stream may be useful when using an SDSEncodeListener during encoding an implicit SignedDataStream again just during parsing it: The content of the SignedDataStream just decoded cannot be read in the conventional way (except for using some buffer mechanism) since it is required during the new encoding procedure. When supplying an output stream to this SDSEncodeListener, the content is copied to this stream during encoding the SignedData object again. This method may be used to access the output stream from outside, if required.

An application shall NOT override this method.

Returns:
an output stream that may have been set to "copy" the content of the SignedDataStream to which this SDSEncodeListener is bound

getReport

public java.lang.Object getReport()
Gets a report about the processing of this SDSEncodeListener.

An application extending this class may wish to have some final report what actually has happened during execution of method beforeComputeSignature or afterComputeSignature. If, for instance, an application has implemented method afterComputeSignature to add a CounterSignature attribute to the unsigned attributes field of a SignerInfo it first may wish to verify the signature of the SignerInfo in mind. The application may decide to implement method afterComputeSignature in a way to throw an exception (and stop program execution) if the verification fails, or it, for instance, may decide to continue processing without adding the CounterSignature. To be informed about the failed CounterSignature adding attempt, method afterComputeSignature may trigger some report that later may be obtained by calling this getReport method. However, it is left to the application to implement an report utility satisfying its requirements. Per default no report is used.

Returns:
a report about the processing of this SDSEncodeListener or null if the report feature is not used

setDigestAlgorithms

public void setDigestAlgorithms(AlgorithmID[] digestAlgorithms)
Sets any digest algorithms that may be required to initialize the digest computation for any SignerInfo(s) that shall be added during execution of method beforeComputeSignature.

When parsing an implicit SignedData object and encoding it again an application may wish to add some new SignerInfo(s). Since the signerInfos field is located behind the content data the SignerInfo SET can not be accessed before the content data is written to the new encoding stream. Since digest computation has to be initialized before the data is written, any digest algorithm not used by the already included SignerInfos has to be known in advance to can be announced when binding this SDSEncodeListener to a SignedDataStream object.

An application shall NOT override this method.

Parameters:
digestAlgorithms - digest algorithms that shall be announced when binding this SDSEncodeListener to a SignedDataStream

getDigestAlgorithms

public AlgorithmID[] getDigestAlgorithms()
Gets any digest algorithms that may be required to initialize the digest computation for any SignerInfo(s) that shall be added during execution of method beforeComputeSignature.

When parsing an implicit SignedData object and encoding it again an application may wish to add some new SignerInfo(s). Since the signerInfos field is located behind the content data the SignerInfo SET can not be accessed before the content data is written to the new encoding stream. Since digest computation has to be initialized before the data is written, any digest algorithm not used by the already included SignerInfos has to be known in advance and can be announced when binding this SDSEncodeListener to a SignedDataStream object.

An application shall NOT override this method.

Returns:
digest algorithms that shall be announced when binding this SDSEncodeListener to a SignedDataStream

beforeComputeSignature

protected abstract void beforeComputeSignature(SignedDataStream signedData)
                                        throws CMSException
Abstract method to be implemented for updating the given SignedDataStream before signature computation is performed.

An application may wish to update a SignedData object BEFORE the signature of any included SignerInfo is computed but AFTER the content data has been written and the digest value over the content has already been calculated. This may be useful to, for instance, add some attribute(s) to be signed by some signer where the value of some attribute depends on the digest of the content data (e.g. an optional time stamp proving that the data has existed before the signature has been calculated). Another example for implementing this method maybe to add some new SignerInfo to an existing implicit SignedData that should be encoded again. Since the content data again has to be included in the new encoding, but the signerInfos field is located behind the content any new SignerInfo may be added not before the content has been processed. However, since digest computation has to be initialized before the data is written, any digest algorithm not used by the already included SignerInfos has to be known in advance to can be announced when binding this SDSEncodeListener to a SignedDataStream object. For that reason any digest algorithm that is required by some SignerInfo to be added should be set setDigestAlgorithms for this SDSEncodeListener, e.g.:

 // A SignedDataStream encode listener allowing to add SignerInfos
 // during the encoding process after data has been processed and
 // digest calculation has been performed, but before signature
 // values have been computed
 public class MySDSEncodeListener extends SDSEncodeListener {
   ...
   // SignerInfos to be added during encoding
   protected SignerInfo[] signerInfos_;
   ...
   // certificates to be added during encoding
   protected Certificate[] certificates_;
   ...
   // crls to be added during encoding
   protected X509CRL[] crls_;

   ...
   
   // constructor
   public MySDSEncodeListener() {
     super();
   }
   
   ...
   // add methods allowing to set SignerInfos, certificates, crls,...
   ...

   // implements beforeComputeSignature to add any SignerInfos, certs, crls,...
   // Since method beforeComputeSignature is executed before
   // signature computation actually is performed, the signatureValue
   // field of the new SignerInfo may be left empty to let be set
   // automatically during the following signature computation process.
   protected void beforeComputeSignature(SignedDataStream signedData) 
     throws CMSException {
     
     signedData.addCertificates(certificates_);
     signedData.addCRLs(crls_);
     if (signerInfos_ != null) {
     try {  
       for (int i = 0; i < signerInfos_.length; i++) {
         signedData.addSignerInfo(signerInfos_[i]); 
       }
     } catch (Exception ex) {
       throw new CMSException("Error adding signer info: " + ex.toString()); 
     }  
   }    
   
   // implements afterComputeSignature to do just nothing (we assume that
   // we do not require this functionality here
   protected void afterComputeSignature(SignedDataStream signedData) 
     throws CMSException {
   }  
 }

 // create a new encode listener:
 MySDSEncodeListener myListener = new MySDSEncodeListener();
 // supply any SignerInfos, certs, crls,...
 ...
 // supply the digest algorithm(s) to be announced when binding the
 // listener to a SignedDataStream object:
 AlgorithmID[] digestAlgIDs = ...;
 myListener.setDigestAlgorithms(digestAlgIDs);
 // bind the listener to a SignedDataStream object:
 signedDataStream.setSDSEncodeListener(myListener);
 
Note that IAIK-CMS includes a simple @link iaik.cms.DefaultSDSEncodeListener default} SignedDataStream encode listener implementation with exactly the same functionality as described in the sample above. Additionally the default SDS encode listener implements method afterComputeSignature to verify the signature of each SignerInfo included.

Parameters:
signedData - the SignedDataStream to be updated before signature calculation (and after content data processing; digest calculation)
Throws:
CMSException - if an error occurs while executing this method

afterComputeSignature

protected abstract void afterComputeSignature(SignedDataStream signedData)
                                       throws CMSException
Abstract method to be implemented for updating the given SignedDataStream after signature computation has been performed.

An application may wish to update a SignedData object AFTER the signature of any included SignerInfo has been computed. This may be useful to, for instance, add some unsigned attribute(s) to some SignerInfo where the value of some attribute depends on the signature value of the particular SignerInfo (e.g. a time stamp proving that the siganture value has existed at the date of the time stamp). Another example for implementing this method maybe to add an unsigned CounterSignature attribute to a SignerInfo of an existing implicit SignedData that should be encoded again making it desirable to first verify the signature of the SignerInfo to be counter signed.

Parameters:
signedData - the SignedDataStream to be updated after signature calculation
Throws:
CMSException - if an error occurs while executing this method

This Javadoc may contain text parts from text parts from IETF Internet Standard specifications (see copyright note).

IAIK-CMS 5.1, (c) 2002 IAIK, (c) 2003 - 2010 SIC