iaik.cms
Class EnvelopedDataOutputStream

java.lang.Object
  extended by java.io.OutputStream
      extended by iaik.cms.EnvelopedDataOutputStream
All Implemented Interfaces:
java.io.Closeable, java.io.Flushable

public class EnvelopedDataOutputStream
extends java.io.OutputStream

This is an OutputStream implementation of the CMS (RFC 5652) EnvelopedData structure. It supports a hybrid type encryption where the content data is encrypted using symmetric cryptography and the symmetric key is transported via other means, e.g. using RSA encryption based on a X.509 certificate.

This stream version will encode the encrypted content as a constructed OCTET STRING. Each write operation to this stream will result in an OCTET STRING block within this constructed OCTET STRING provided that the input data is at least as large as the block size of the employed (block) cipher. Calling close() will finish the encryption, i.e. it will do the padding and finish writing the resulting EnvelopedData strucure. Consequently, if a block cipher is used, the size of a block in the OCTET STRING will be a multiple of the block size of the cipher (e.g. 16 Byte for AES).

The recipient infos must be added before the application starts writing data to this stream. RecipientInfo objects which are added later will not be included.

The typical usage of this class looks like the following example for creating a CMS EnvelopedData structure and writing it to an output stream:

  // the certificate of the recipient
  X509Certificate recipientCert = ...
  // the input stream from which to read the data to be encrypted
  InputStream dataInputStream = ...
  // the output stream to which to write the EnvelopedData
  OutputStream resultStream = ...
  
  // create enveloped data stream (in this sample we use AES as content encryption algorithm)
  AlgorithmID contentEncAlg = (AlgorithmID)AlgorithmID.aes256_CBC.clone();
  EnvelopedDataOutputStream envelopingStream = 
    new EnvelopedDataOutputStream(resultStream, contentEncAlg);
  // use RSA for encrypting the content encryption key  
  RecipientInfo recipientInfo = 
    new KeyTransRecipientInfo(recipientCert, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
  envelopingStream.addRecipientInfo(recipientInfo);
  ...
  // add any further recipients (if required)
  ...
  
  // write in the data to be encrypted
  byte[] buffer = new byte[2048];
  int bytesRead;
  while ((bytesRead = dataInputStream.read(buffer)) != -1) {
    envelopingStream.write(buffer, 0, bytesRead);
  }
  // closing the stream finishes encryption and closes the underlying stream
  envelopingStream.close();
 
If you want to encapsulate the EnvelopedData into a ContentInfo you first must wrap a ContentInfoOutputStream around the final output stream (the ContentInfoStream has to write its headers to the stream at first, thus it must be created at the "lowest" level):
  ContentInfoOutputStream contentInfoStream = 
    new ContentInfoOutputStream(ObjectID.cms_envelopedData, resultStream);
  // now create EnvelopedDataOutputStream for the ContentInfoStream:
  EnvelopedDataOutputStream envelopingStream = 
    new EnvelopedDataOutputStream(contentInfoStream, contentEncAlg);  
    
  // the further proceeding is same as above 
  RecipientInfo recipientInfo = 
    new KeyTransRecipientInfo(recipientCert, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
  envelopingStream.addRecipientInfo(recipientInfo);
  
  // write in the data to be encrypted
  byte[] buffer = new byte[2048];
  int bytesRead;
  while ((bytesRead = dataInputStream.read(buffer)) != -1) {
    envelopingStream.write(buffer, 0, bytesRead);
  }
  // closing the stream finishes encryption and closes the underlying stream
  envelopingStream.close();  
 
Use class EnvelopedDataStream to read in and parse the encoded EnvelopedData and decrypt the content.

See Also:
RecipientInfo, KeyTransRecipientInfo, KeyAgreeRecipientInfo, KEKRecipientInfo, PasswordRecipientInfo, OtherRecipientInfo, EnvelopedDataStream

Constructor Summary
EnvelopedDataOutputStream(ObjectID contentType, java.io.OutputStream out, AlgorithmID contentEA)
          Creates a new EnvelopedDataOutputStream object where the content to be enveloped is later written to the given output stream (e.g.
EnvelopedDataOutputStream(ObjectID contentType, java.io.OutputStream out, AlgorithmID contentEA, int keyLength)
          Creates a new EnvelopedDataOutputStream object where the content to be enveloped is later written to the given output stream (e.g.
EnvelopedDataOutputStream(ObjectID contentType, java.io.OutputStream out, AlgorithmID contentEA, int keyLength, SecurityProvider securityProvider)
          Creates a new EnvelopedDataOutputStream object where the content to be enveloped is later written to the given output stream (e.g.
EnvelopedDataOutputStream(java.io.OutputStream out, AlgorithmID contentEA)
          Creates a new EnvelopedDataOutputStream object where the content to be enveloped is later written to the given output stream (e.g.
EnvelopedDataOutputStream(java.io.OutputStream out, AlgorithmID contentEA, int keyLength)
          Creates a new EnvelopedDataOutputStream object where the content to be enveloped is later written to the given output stream (e.g.
 
Method Summary
 void addRecipientInfo(RecipientInfo recipient)
          Adds one recipient to the list of recipient infos.
 void close()
          Finishes the encoding and writes any unprotected attributes (if set) to the underlying stream.
 void flush()
          Flushes any internal data and calls flush of the underlying stream.
 SecurityProvider getSecurityProvider()
          Gets the SecurityProvider installed for this EncryptedDataStream.
 int getVersion()
          Returns the syntax version number.
 boolean isPassThroughClose()
          Checks whether a call to close() will call close of the underlying output stream
 void setOriginatorInfo(OriginatorInfo originatorInfo)
          Sets the optional OriginatorInfo.
 void setPassThroughClose(boolean passThroughClose)
          Setting this to true will cause close() to call close of the underlying output stream.
 void setRecipientInfos(RecipientInfo[] recipients)
          Sets the recipient infos.
 void setSecurityProvider(SecurityProvider securityProvider)
          Sets the SecurityProvider for this EnvelopedDataOutputStream.
 void setUnprotectedAttributes(Attribute[] attributes)
          Sets a set of (unprotected) attributes.
 java.lang.String toString()
          Returns a string giving some information about this EnvelopedData object.
 java.lang.String toString(boolean detailed)
          Returns a string giving some - if requested - detailed information about this EnvelopedData object.
 void write(byte[] b)
          Encrypts, encodes and writes the given data to the output stream.
 void write(byte[] b, int off, int len)
          Encrypts, encodes and writes the given data to the output stream.
 void write(int b)
          Encrypts, encodes and writes the given data byte to the output stream.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

EnvelopedDataOutputStream

public EnvelopedDataOutputStream(java.io.OutputStream out,
                                 AlgorithmID contentEA)
                          throws java.security.NoSuchAlgorithmException
Creates a new EnvelopedDataOutputStream object where the content to be enveloped is later written to the given output stream (e.g. write(byte[])).

The content type is set to CMS Data.

When using this constructor, automatically a temporary symmetric key for content encryption is generated. If using a content-encryption algorithm allowing keys of different size, you may specify the key length by using the EnvelopedDataOutputStream(OutputStream, AlgorithmID, int) constructor.
Note that the supplied contentEA AlgorithmID internally is cloned.

Parameters:
out - the OutputStream receiving the enveloped data
contentEA - the content encryption algorithm for encrypting the content
Throws:
java.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithm

EnvelopedDataOutputStream

public EnvelopedDataOutputStream(ObjectID contentType,
                                 java.io.OutputStream out,
                                 AlgorithmID contentEA)
                          throws java.security.NoSuchAlgorithmException
Creates a new EnvelopedDataOutputStream object where the content to be enveloped is later written to the given output stream (e.g. write(byte[])).

When using this constructor, automatically a temporary symmetric key for content encryption is generated. If using a content-encryption algorithm allowing keys of different size, you may specify the key length by using the EnvelopedDataOutputStream(ObjectID, OutputStream, AlgorithmID, int) constructor.
Note that the supplied contentEA AlgorithmID internally is cloned.

Parameters:
contentType - the content type of the content to be enveloped
out - the OutputStream receiving the enveloped data
contentEA - the content encryption algorithm for encrypting the content
Throws:
java.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithm

EnvelopedDataOutputStream

public EnvelopedDataOutputStream(java.io.OutputStream out,
                                 AlgorithmID contentEA,
                                 int keyLength)
                          throws java.security.NoSuchAlgorithmException
Creates a new EnvelopedDataOutputStream object where the content to be enveloped is later written to the given output stream (e.g. write(byte[])).
The content type is set to CMS Data.

When using this constructor, automatically a symmetric key for content encryption is generated. If the specified content encryption algorithm supports variable key lengths, a particular key length may be set by means of the keyLength parameter. If no length is specified, the defined default key length will be used.
Note that the supplied contentEA AlgorithmID internally is cloned.

Parameters:
out - the OutputStream receiving the enveloped data
contentEA - the content encryption algorithm for encrypting the content
keyLength - the key length that may be set when using a content encryption algorithm that supports variable key lengths
Throws:
java.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithm

EnvelopedDataOutputStream

public EnvelopedDataOutputStream(ObjectID contentType,
                                 java.io.OutputStream out,
                                 AlgorithmID contentEA,
                                 int keyLength)
                          throws java.security.NoSuchAlgorithmException
Creates a new EnvelopedDataOutputStream object where the content to be enveloped is later written to the given output stream (e.g. write(byte[])).

When using this constructor, automatically a symmetric key for content encryption is generated. If the specified content encryption algorithm supports variable key lengths, a particular key length may be set by means of the keyLength parameter. If no length is specified, the defined default key length will be used. constructor may be used.
Note that the supplied contentEA AlgorithmID internally is cloned.

Parameters:
contentType - the content type of the content to be enveloped
out - the OutputStream receiving the enveloped data
contentEA - the content encryption algorithm for encrypting the content
keyLength - the key length that may be set when using a content encryption algorithm that supports variable key lengths
Throws:
java.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithm

EnvelopedDataOutputStream

public EnvelopedDataOutputStream(ObjectID contentType,
                                 java.io.OutputStream out,
                                 AlgorithmID contentEA,
                                 int keyLength,
                                 SecurityProvider securityProvider)
                          throws java.security.NoSuchAlgorithmException
Creates a new EnvelopedDataOutputStream object where the content to be enveloped is later written to the given output stream (e.g. write(byte[])).

When using this constructor, automatically a symmetric key for content encryption is generated. If the specified content encryption algorithm supports variable key lengths, a particular key length may be set by means of the keyLength parameter. If no length is specified, the defined default key length will be used.
Note that the supplied contentEA AlgorithmID is cloned internally.

Parameters:
contentType - the content type of the content to be enveloped
out - the OutputStream receiving the enveloped data
contentEA - the content encryption algorithm for encrypting the content
keyLength - the key length that may be set when using a content encryption algorithm that supports variable key lengths
securityProvider - the security provider to be used; if null the default system-wide SecurityProvider is used
Throws:
java.security.NoSuchAlgorithmException - if there is no implementation for the specified algorithm
Method Detail

write

public void write(byte[] b,
                  int off,
                  int len)
           throws java.io.IOException
Encrypts, encodes and writes the given data to the output stream.

Overrides:
write in class java.io.OutputStream
Parameters:
b - The data to be encrypted
off - The start offset in b.
len - The number of bytes to write.
Throws:
java.io.IOException - If an I/O error occurs.

write

public void write(byte[] b)
           throws java.io.IOException
Encrypts, encodes and writes the given data to the output stream.

Overrides:
write in class java.io.OutputStream
Parameters:
b - The data to be encrypted.
Throws:
java.io.IOException - If an I/O error occurs.

write

public void write(int b)
           throws java.io.IOException
Encrypts, encodes and writes the given data byte to the output stream.

Specified by:
write in class java.io.OutputStream
Parameters:
b - The data byte to be encrypted.
Throws:
java.io.IOException - If an I/O error occurs.

flush

public void flush()
           throws java.io.IOException
Flushes any internal data and calls flush of the underlying stream.

Specified by:
flush in interface java.io.Flushable
Overrides:
flush in class java.io.OutputStream
Throws:
java.io.IOException - If flushing the stream fails.

close

public void close()
           throws java.io.IOException
Finishes the encoding and writes any unprotected attributes (if set) to the underlying stream.

Specified by:
close in interface java.io.Closeable
Overrides:
close in class java.io.OutputStream
Throws:
java.io.IOException - if an I/O error occurs when writing to the stream

isPassThroughClose

public boolean isPassThroughClose()
Checks whether a call to close() will call close of the underlying output stream

Returns:
true if a call to close() will call close of the underlying output stream; false if a call to close() will not close the underlying stream.

setPassThroughClose

public void setPassThroughClose(boolean passThroughClose)
Setting this to true will cause close() to call close of the underlying output stream. If false, a call to close() will not close the underlying stream.

Parameters:
passThroughClose - true to pass through close() calls. false to not pass them through.

setSecurityProvider

public void setSecurityProvider(SecurityProvider securityProvider)
Sets the SecurityProvider for this EnvelopedDataOutputStream.

This method allows to explicitly set a SecurityProvider for this EnvelopedDataOutputStream. If no explicit SecurityProvider is set, the default system wide installed SecurityProvider will be used for the required cryptographic operations.

This class uses the following method(s) of the SecurityProvider, which may be overriden by an application, if required:

An application may supply the SecurityProvider immediately when creating an EnvelopedDataOutputStream object (for using this SecurityProvider to create the content encryption key).

Parameters:
securityProvider - the SecurityProvider to be set

getSecurityProvider

public SecurityProvider getSecurityProvider()
Gets the SecurityProvider installed for this EncryptedDataStream.

This class uses the following method(s) of the SecurityProvider, which may be overriden by an application, if required:

If no explicit SecurityProvider has been set for this object, the default system wide installed SecurityProvider will be used for the required cryptographic operations. However, this method will return null if it does not have its own SecurityProvider.

Returns:
the SecurityProvider explicitly installed for this object, or null if this object does not have its own SecurityProvider

setOriginatorInfo

public void setOriginatorInfo(OriginatorInfo originatorInfo)
Sets the optional OriginatorInfo.

The originatorInfo may be set for including certificates and/or certificate revocation lists for the originator if required by the key management algorithm used.

Parameters:
originatorInfo - the OriginatorInfo to be set

setRecipientInfos

public void setRecipientInfos(RecipientInfo[] recipients)
Sets the recipient infos.

Any RecipientInfo added supplies recipient-specific information used for identifying the key of the recipient to be used for en/decrypting the content.

Parameters:
recipients - a collection of per-recipient information
See Also:
RecipientInfo, KeyTransRecipientInfo, KeyAgreeRecipientInfo, KEKRecipientInfo, PasswordRecipientInfo, OtherRecipientInfo

addRecipientInfo

public void addRecipientInfo(RecipientInfo recipient)
Adds one recipient to the list of recipient infos.

Any RecipientInfo added supplies recipient-specific information used for identifying the key of the recipient to be used for en/decrypting the content.

Parameters:
recipient - the RecipientInfo to be added
See Also:
RecipientInfo, KeyTransRecipientInfo, KeyAgreeRecipientInfo, KEKRecipientInfo, PasswordRecipientInfo, OtherRecipientInfo

setUnprotectedAttributes

public void setUnprotectedAttributes(Attribute[] attributes)
Sets a set of (unprotected) attributes.

Parameters:
attributes - the unprotected attributes to be set

getVersion

public int getVersion()
Returns the syntax version number.

Returns:
the syntax version number

toString

public java.lang.String toString()
Returns a string giving some information about this EnvelopedData object.

Overrides:
toString in class java.lang.Object
Returns:
the string representation

toString

public java.lang.String toString(boolean detailed)
Returns a string giving some - if requested - detailed information about this EnvelopedData object.

Parameters:
detailed - - whether or not to give detailed information
Returns:
the string representation

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

IAIK-CMS 6.0, (c) 2002 IAIK, (c) 2003, 2023 SIC