iaik.cms
Class AuthEnvelopedData

java.lang.Object
  extended by iaik.cms.AuthEnvelopedDataStream
      extended by iaik.cms.AuthEnvelopedData
All Implemented Interfaces:
EncodeListener, Content, ContentStream, EOFListener, java.util.EventListener

public class AuthEnvelopedData
extends AuthEnvelopedDataStream
implements Content

This class represents the non-stream supporting implementation of the CMS content type AuthEnvelopedData as defined in RFC 5083.

The AuthEnvelopedData content type is identified by the following object identifier (see RFC 5083):

 id-ct-authEnvelopedData OBJECT IDENTIFIER ::= { iso(1)
      member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
      smime(16) ct(1) 23 }
 
which corresponds to the OID string "1.2.840.113549.1.9.16.1.23".

RFC 5083 specifies the AuthEnvelopedData content type for use with authenticated cipher modes like AES-CCM or AES-GCM (RFC 5084). RFC 8103 specifies the AuthEnvelopedData content type for use with the ChaCha20-Poly1305 authenticated encryption algorithm (RFC 7539).
Using authenticated encryption the data is not only encrypted but also integrity protected by a message authentication code. Similar to the EnvelopedData and AuthenticatedData types content of any type may be authenticated enveloped for any number of recipients in parallel. For each recipient, a commonly at random generated content-authenticated-encryption key is encrypted with the particular recipient key and - together with recipient-specific information - collected into a RecipientInfo value. Using a authenticated encryption method the content is authenticated and encrypted with the content-authenticated-encryption key. All RecipientInfo values are collected together with the authenticated encrypted content into an AuthEnvelopedData object to be sent to each intended recipients. The AuthEnvelopedData may also contain authenticated attributes (which are authenticated but not encrypted) and unauthenticated attributes (which are neither encrypted nor authenticated), (see RFC 5083:

 AuthEnvelopedData ::= SEQUENCE {
      version CMSVersion,
      originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
      recipientInfos RecipientInfos,
      authEncryptedContentInfo EncryptedContentInfo,
      authAttrs [1] IMPLICIT AuthAttributes OPTIONAL,
      mac MessageAuthenticationCode,
      unauthAttrs [2] IMPLICIT UnauthAttributes OPTIONAL }

 

The recipientInfos field is a non-empty collection of per-recipient information. The authEncryptedContentInfo field specifies the type of the content being authenticated encrypted, the content-authenticated-encryption algorithm (the same for all recipients) used for authenticated encrypting the content, and the result of the content authenticated encryption.
CMS provides five alternatives for authenticated encrypting the content depending on the key management algorithm used to protect the content-authenticated-encryption key for a specific recipient:

The optional originatorInfo field may be used to include certificate/crl information about the originator if required by the key managemant protocol. The unauthAttrs field may contain some attributes that are authenticated but not encrypted, the unauthAttrs may provide some attributes that are not protected.

A recipient, when receiving the AuthEnvelopedData message, decrypts the corresponding encrypted content-authenticated-encryption key with his/her key according the right key management protocol for subsequently decrypting the encrypted content and verifying the mac value using the content-authenticated-encryption key just recovered. The recipient's key is referenced by proper KeyIdentifier included in the corresponding RecipientInfo object.

See RFC 5652 for more information.


When creating a new AuthEnvelopedData object for the data to be authenticated enveloped the symmetric algorithm has to be specified to be used for content-authenticated-encryption. After setting the recipients, the AuthEnvelopedData object may be encoded to be sent to the intended recipient(s), e.g.:

  1. Create a new AuthEnvelopedData object and specify the content authenticated encryption algorithm to be used by means of the AuthEnvelopedData(byte[] content, AlgorithmID contentAuthEncAlg) constructor. When using this constructor automatically a temporary symmetric key for authenticated content encryption will be generated. If you want to use a content-authenticated-encryption algorithm allowing keys of different size, you may specify the key length by using the AuthEnvelopedData(byte[] content, AlgorithmID contentAuthEncAlg, int keyLength) constructor.
         //the data to be auth-enveloped supplied by an byte array:
         byte[] data = ...;
         //use AES-GCM mode for authenticated encrypting the content
         AuthEnvelopedData authEnvelopedData = new AuthEnvelopedData(data, (AlgorithmID)AlgorithmID.aes256_GCM.clone());
         
  2. For each intended recipient, create a RecipientInfo object of requested type (KeyTransRecipientInfo, KeyAgreeRecipientInfo, or KEKRecipientInfo), and add all RecipientInfos to the AuthEnvelopedData object by calling the setRecipientInfos method, e.g. (assuming to use KeyTransRecipientInfos for two recipients with corresponding certificates cert1 and cert2):
         RecipientInfo[] recipients = new RecipientInfo[2];
         recipients[0] = new KeyTransRecipientInfo(cert1, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
         recipients[1] = new KeyTransRecipientInfo(cert2, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
         authEnvelopedData.setRecipientInfos(recipients);
         
  3. Use a proper writeTo or encoded method for BER encoding the AuthEnvelopedData object. This step also will perform generation and encryption of the symmetric content-authenticated-encryption key for each participated recipient:
         byte[] encoding = authEnvelopedData();
         
A recipient, when receiving an AuthEnvelopedData encoding, uses the AuthEnvelopedData(InputStream is) constructor for parsing the internal structure. Before getting the recovered content by means of the getContent method, the cipher has to be initialized for decryption and mac verification with the particular recipient key by calling one of the following setupCipher methods: Since in our example both recipients use a RecipientInfo of type KeyTransRecipientInfo, we can use any of the setupCipher methods to setup the cipher for decrypting the encrypted content-authenticated-encryption key, decrypting the encrypted content and verifying the message authenitication code:
  1. Create an AuthEnvelopedData structure from the supplied encoding, decode and parse the internal structure:
         InputStream encodedStream = ...;
         AuthEnvelopedData authEnvelopedData = new AuthEnvelopedData(encodedStream);
         
  2. Get information about the inherent EncryptedContentInfo:
         EncryptedContentInfo eci = (EncryptedContentInfo)authEnvelopedData.getEncryptedContentInfo();
         System.out.println("Content type: "+eci.getContentType().getName());
         System.out.println("content authenticated encryption algorithm: "+eci.getContentEncryptionAlgorithm().getName());
         
  3. Get information about the included RecipientInfos:
         RecipientInfo[] recipients = authEnvelopedData.getRecipientInfos();
         System.out.println("Included RecipientInfos:");
         for (int i=0; i < recipients.length; i++) {
            System.out.print("Recipient "+(i+1)+":");
            System.out.println(recipients[i]);
         }
         
  4. Use some recipient specific key to decrypt the inherent encrypted secret key to be used for initializing the cipher for encrypted-content decryption and mac verification:
         // the private key of recipient 1:
         Key privateKey = ...;
         //setup cipher for recipient 1:
         int recipientInfoIndex = 0;
         authEnvelopedData.setupCipher(privateKey, recipientInfoIndex);
         
    Unlike the stream supporting AuthEnvelopedDataStream class where the setupCipher method only initializes the cipher for decryption, whole the encrypted-content decryption already is performed inside the setupCipher method of this class.

  5. Get the recovered content:
         byte[] content = authEnvelopedData.getContent();
         

Note: RFC 5084 specifies the usage of the AuthEnvelopedData type for the AES-CCM and AES-GCM authenticated encryption algorithms, both are supported by this implementation when used with IAIK-JCE, version > 3.17.

Note: This class does not provide a verifyMac method. For authenticated encryption algorithms like AES-CCM and AES-GCM (see RFC 5084) Mac verification is part of the decryption/verification procedure. When using some other content authentication encryption method that follows a different verification strategy, be sure to implement corresponding authentication cipher engines.

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

Field Summary
 
Fields inherited from class iaik.cms.AuthEnvelopedDataStream
encryptedContentInfo_, EXPLICIT, IMPLICIT
 
Constructor Summary
protected AuthEnvelopedData()
          Default constructor for dynamic object creation in ContentInfo.
  AuthEnvelopedData(ASN1Object obj)
          Creates a CMS AuthEnvelopedData from an ASN1Object.
  AuthEnvelopedData(ASN1Object obj, SecurityProvider securityProvider)
          Creates a CMS AuthEnvelopedData from an ASN1Object.
  AuthEnvelopedData(byte[] content, AlgorithmID contentAuthEncAlg)
          Creates a new CMS AuthEnvelopedData object where the raw data is supplied as byte array.
  AuthEnvelopedData(byte[] content, AlgorithmID contentAuthEncAlg, int keyLength)
          Creates a new CMS AuthEnvelopedData object where the raw data is supplied as byte array.
  AuthEnvelopedData(java.io.InputStream is)
          Creates a new AuthEnvelopedData from a DER encoded AuthEnvelopedData object which is read from the given InputStream.
  AuthEnvelopedData(java.io.InputStream is, SecurityProvider securityProvider)
          Creates a new AuthEnvelopedData from a DER encoded AuthEnvelopedData object which is read from the given InputStream.
  AuthEnvelopedData(ObjectID contentType, byte[] content, AlgorithmID contentAuthEncAlg)
          Creates a new CMS AuthEnvelopedData object where the raw data is supplied as byte array.
  AuthEnvelopedData(ObjectID contentType, byte[] content, AlgorithmID contentAuthEncAlg, int keyLength)
          Creates a new CMS AuthEnvelopedData object where the raw data is supplied as byte array.
  AuthEnvelopedData(ObjectID contentType, byte[] content, AlgorithmID contentAuthEncAlg, int keyLength, SecurityProvider securityProvider)
          Creates a new CMS AuthEnvelopedData object where the raw data is supplied as byte array.
  AuthEnvelopedData(RecipientInfo[] recipients, EncryptedContentInfo encryptedContentInfo)
          Constructs a CMS AuthEnvelopedData type with an already created EncryptedContentInfo.
 
Method Summary
 void decode(ASN1Object obj)
          Decodes the given AuthEnvelopedData ASN1 object.
 byte[] getContent()
          Returns the content as byte array.
 byte[] getEncoded()
          Returns the DER encoding of this AuthEnvelopedData in a byte array.
 void setContent(byte[] content)
          Sets the content data to be authenticated encrypted.
 void setInputStream(java.io.InputStream is)
          Sets the input stream that supplies the content data to be authenticated encrypted.
 
Methods inherited from class iaik.cms.AuthEnvelopedDataStream
addRecipientInfo, decode, decode, encodeCalled, getAuthenticatedAttribute, getAuthenticatedAttributes, getBlockSize, getContentType, getEncryptedContentInfo, getInputLength, getInputStream, getMac, getMode, getOriginatorInfo, getRecipientInfo, getRecipientInfo, getRecipientInfos, getRecipientInfos, getSecurityProvider, getUnauthenticatedAttribute, getUnauthenticatedAttributes, getVersion, notifyEOF, setAuthenticatedAttributes, setBlockSize, setInputLength, setMac, setMode, setOriginatorInfo, setRecipientInfos, setSecurityProvider, setUnauthenticatedAttributes, setupCipher, setupCipher, setupCipher, setupCipher, toASN1Object, toASN1Object, toString, toString, writeTo, writeTo
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface iaik.cms.ContentStream
decode, getBlockSize, getContentType, setBlockSize, toASN1Object, toString
 

Constructor Detail

AuthEnvelopedData

protected AuthEnvelopedData()
Default constructor for dynamic object creation in ContentInfo. The block size is set to -1 to enforce definite primitive encoding.


AuthEnvelopedData

public AuthEnvelopedData(byte[] content,
                         AlgorithmID contentAuthEncAlg)
Creates a new CMS AuthEnvelopedData object where the raw data is supplied as byte array.
The content type is set to CMS Data.

When using this constructor, automatically a temporary symmetric key for authenticated content encryption will be generated. If you want to use a content-authenticated-encryption algorithm allowing keys of different size, you may specify the key length by using the AuthEnvelopedData(byte[] content, AlgorithmID contentAuthEncAlg, int keyLength) constructor.
Note that the supplied contentAuthEncAlg AlgorithmID internally is cloned.

Parameters:
content - the byte array containing the data to be authenticated enveloped
contentAuthEncAlg - the id of the content-authenticated encryption algorithm

AuthEnvelopedData

public AuthEnvelopedData(ObjectID contentType,
                         byte[] content,
                         AlgorithmID contentAuthEncAlg)
Creates a new CMS AuthEnvelopedData object where the raw data is supplied as byte array.

When using this constructor, automatically a temporary symmetric key for authenticated content encryption will be generated. If you want to use a content-authenticated-encryption algorithm allowing keys of different size, you may specify the key length by using the AuthEnvelopedData(ObjectID contentType, byte[] content, AlgorithmID contentAuthEncAlg, int keyLength) constructor.
Note that the supplied contentAuthEncAlg AlgorithmID internally is cloned.

Parameters:
contentType - the content type of the content to be authenticated enveloped
content - the byte array containing the data to be authenticated enveloped
contentAuthEncAlg - the id of the content-authenticated encryption algorithm

AuthEnvelopedData

public AuthEnvelopedData(byte[] content,
                         AlgorithmID contentAuthEncAlg,
                         int keyLength)
Creates a new CMS AuthEnvelopedData object where the raw data is supplied as byte array.
The content type is set to CMS Data.

When using this constructor, automatically a symmetric key for authenticated content encryption will be generated. If the specified content authenticated 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. If the algorithm only works with keys of fixed-size length, the keyLength parameter may be set to -1 or the AuthEnvelopedData(byte[] content, AlgorithmID contentAuthEncAlg) constructor may be used.
Note that the supplied contentAuthEncAlg AlgorithmID internally is cloned.

Parameters:
content - the byte array containing the data to be authenticated enveloped
contentAuthEncAlg - the id of the content-authenticated encryption algorithm
keyLength - the length of the content-authenticated-encryption key to be generated (when using a content-authenticated-encryption algorithm that supports variable key lengths)

AuthEnvelopedData

public AuthEnvelopedData(ObjectID contentType,
                         byte[] content,
                         AlgorithmID contentAuthEncAlg,
                         int keyLength)
Creates a new CMS AuthEnvelopedData object where the raw data is supplied as byte array.

When using this constructor, automatically a symmetric key for authenticated content encryption is generated. If the specified content authenticated 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. If the algorithm only works with keys of fixed-size length, the keyLength parameter may be set to -1 or the AuthEnvelopedData(ObjectID contentType, byte[] content, AlgorithmID contentAuthEncAlg) constructor may be used.
Note that the supplied contentAuthEncAlg AlgorithmID internally is cloned.

Parameters:
contentType - the content type of the content to be authenticated enveloped
content - the byte array containing the data to be authenticated enveloped
contentAuthEncAlg - the id of the content-authenticated encryption algorithm
keyLength - the length of the content-authenticated-encryption key to be generated (when using a content-authenticated-encryption algorithm that supports variable key lengths)

AuthEnvelopedData

public AuthEnvelopedData(ObjectID contentType,
                         byte[] content,
                         AlgorithmID contentAuthEncAlg,
                         int keyLength,
                         SecurityProvider securityProvider)
Creates a new CMS AuthEnvelopedData object where the raw data is supplied as byte array.

When using this constructor, automatically a symmetric key for authenticated content encryption is generated. If the specified content authenticated 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. If the algorithm only works with keys of fixed-size length, the keyLength parameter may be set to -1 or the AuthEnvelopedData(ObjectID contentType, byte[] content, AlgorithmID contentAuthEncAlg) constructor may be used.
Note that the supplied contentAuthEncAlg AlgorithmID internally is cloned.

Parameters:
contentType - the content type of the content to be authenticated enveloped
content - the byte array containing the data to be authenticated enveloped
contentAuthEncAlg - the id of the content-authenticated encryption algorithm
keyLength - the length of the content-authenticated-encryption key to be generated (when using a content-authenticated-encryption algorithm that supports variable key lengths)
securityProvider - the security provider to be used; if null the default system-wide SecurityProvider is used

AuthEnvelopedData

public AuthEnvelopedData(RecipientInfo[] recipients,
                         EncryptedContentInfo encryptedContentInfo)
Constructs a CMS AuthEnvelopedData type with an already created EncryptedContentInfo. The given array of RecipientInfo specifies a collection of per-recipient information, and the given EncryptedContentInfo is responsible for authentictad content encryption.

Parameters:
recipients - information about the recipients
encryptedContentInfo - the EncryptedContentInfo

AuthEnvelopedData

public AuthEnvelopedData(ASN1Object obj)
                  throws CMSParsingException
Creates a CMS AuthEnvelopedData from an ASN1Object. The ASN.1 AuthEnvelopedData may (or may not) be wrapped into a ContentInfo. The ASN1Object supplied to this constructor represents an already exisiting AuthEnvelopedData object that may have been created by calling toASN1Object.

Use the AuthEnvelopedData(byte[] content, AlgorithmID contentAuthEncAlg) constructor for supplying the content to be authenticated enveloped when creating a new AuthEnvelopedData object.

Parameters:
obj - the AuthEnvelopedData as ASN1Object
Throws:
CMSParsingException - if the object can not be parsed

AuthEnvelopedData

public AuthEnvelopedData(ASN1Object obj,
                         SecurityProvider securityProvider)
                  throws CMSParsingException
Creates a CMS AuthEnvelopedData from an ASN1Object. The ASN.1 AuthEnvelopedData may (or may not) be wrapped into a ContentInfo. The ASN1Object supplied to this constructor represents an already exisiting AuthEnvelopedData object that may have been created by calling toASN1Object.

Use the AuthEnvelopedData(byte[] content, AlgorithmID contentAuthEncAlg) constructor for supplying the content to be authenticated enveloped when creating a new AuthEnvelopedData object.

Parameters:
obj - the AuthEnvelopedData as ASN1Object
securityProvider - the security provider to be used; if null the default system-wide SecurityProvider is used
Throws:
CMSParsingException - if the object can not be parsed

AuthEnvelopedData

public AuthEnvelopedData(java.io.InputStream is)
                  throws CMSParsingException,
                         java.io.IOException
Creates a new AuthEnvelopedData from a DER encoded AuthEnvelopedData object which is read from the given InputStream. The encoded AuthEnvelopedData may (or may not) be wrapped into a ContentInfo.

Parameters:
is - the InputStream supplying a DER encoded AuthEnvelopedData object
Throws:
java.io.IOException - if an I/O error occurs during reading from the InputStream
CMSParsingException - if an error occurs while parsing the object

AuthEnvelopedData

public AuthEnvelopedData(java.io.InputStream is,
                         SecurityProvider securityProvider)
                  throws CMSParsingException,
                         java.io.IOException
Creates a new AuthEnvelopedData from a DER encoded AuthEnvelopedData object which is read from the given InputStream. The encoded AuthEnvelopedData may (or may not) be wrapped into a ContentInfo.

Parameters:
is - the InputStream supplying a DER encoded AuthEnvelopedData object
securityProvider - the security provider to be used; if null the default system-wide SecurityProvider is used
Throws:
java.io.IOException - if an I/O error occurs during reading from the InputStream
CMSParsingException - if an error occurs while parsing the object
Method Detail

decode

public void decode(ASN1Object obj)
            throws CMSParsingException
Decodes the given AuthEnvelopedData ASN1 object. The ASN.1 AuthEnvelopedData may (or may not) be wrapped into a ContentInfo.

Specified by:
decode in interface Content
Parameters:
obj - the ASN1Object representing an already exisiting AuthEnvelopedData object
Throws:
CMSParsingException - if an error occurs when parsing the given ASN1Object

getContent

public byte[] getContent()
Returns the content as byte array.

The returned content depends on whether creating a new AuthEnvelopedData or parsing an existing one:

Returns:
a byte array holding the content

setInputStream

public void setInputStream(java.io.InputStream is)
Sets the input stream that supplies the content data to be authenticated encrypted. This method already reads the data from the stream.

Overrides:
setInputStream in class AuthEnvelopedDataStream
Parameters:
is - the input stream holding the content data to authenticated encrypt

setContent

public void setContent(byte[] content)
Sets the content data to be authenticated encrypted.

Parameters:
content - the content data to autenticated encrypt.

getEncoded

public byte[] getEncoded()
                  throws CMSException
Returns the DER encoding of this AuthEnvelopedData in a byte array.

Returns:
a byte array holding the DER encoding of this AuthEnvelopedData
Throws:
CMSException

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