iaik.cms
Class AuthenticatedDataStream

java.lang.Object
  extended by iaik.cms.AuthenticatedDataStream
All Implemented Interfaces:
EncodeListener, ContentStream, EOFListener, java.util.EventListener
Direct Known Subclasses:
AuthenticatedData

public class AuthenticatedDataStream
extends java.lang.Object
implements ContentStream, EncodeListener, EOFListener

This class represents the stream-supporting implementation of the CMS content type AutheticatedData.

Each CMS content type is associated with a specific object identifier. The object identifier for the AutheticatedData content type is defined as:

id-ct-authData OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1) 2 }

which corresponds to the OID string "1.2.840.113549.1.9.16.1.2".

The Cryptographic Message Syntax (CMS) (RFC 5652) specifies the AutheticatedData content type for providing a syntax for recipient-specific protecting the integrity of a message by means of a Message Authentication Code (MAC). Content of any type may be authenticated for any number of recipients in parallel. For each recipient a commonly at random generated symmetric mac key is encrypted with the particular recipient key and - together with recipient-specific information - collected into a RecipientInfo value. A message authentication code on the content is computed with the mac key and -- together with the RecipientInfos objects -- packed into a AuthenticedData message.

The AutheticatedData type is defined as ASN.1 SEQUENCE type containing the following components (see RFC 5652):

 AuthenticatedData ::= SEQUENCE {
   version CMSVersion,
   originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
   recipientInfos RecipientInfos,
   macAlgorithm MessageAuthenticationCodeAlgorithm,
   digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL,
   encapContentInfo EncapsulatedContentInfo,
   authAttrs [2] IMPLICIT AuthAttributes OPTIONAL,
   mac MessageAuthenticationCode,
   unauthAttrs [3] IMPLICIT UnauthAttributes OPTIONAL }

   AuthAttributes ::= SET SIZE (1..MAX) OF Attribute

   UnauthAttributes ::= SET SIZE (1..MAX) OF Attribute

   MessageAuthenticationCode ::= OCTET STRING
 

If the digestAlgorithm field is not null, authenticated attributes have to be present and the MAC value is calculated on the DER encoding of the authenticated attributes. In this case the MessageDigest attribute has to be included as authenticated attribute and has to contain a digest value computed on the content data. If no authenticated attributes are present, the MAC value is computed on the content itself.

A recipient, when receiving the AutheticatedData message, decrypts the corresponding encrypted mac key with his/her key and subsequently uses it to verify the message authentication code.

See RFC 5652 for more information.


When creating an AuthenticatedDataStream object an application has to decide whether the to-be-authenticated content shall be incldued (IMPLICIT mode) into the AuthenticatedData message or shall be transmitted by other means (EXPLICIT mode):

 int mode = AuthenticatedDataStream.IMPLICIT; // include content
 
or
 int mode = AuthenticatedDataStream.EXPLICIT; // do not include content
 
However, in both cases the content data has to be supplied when creating the AuthenticatedDataStream object, because it is needed for the MAC computation:
 InputSrteam[] dataStream = ...; // the content data supplying input stream
 
Together with transmission mode and content data the following values have to be specified when creating an AuthenticatedDataStream object, some of them are only optional: Optional originator information (if required by the key management technique in use) maybe set via method setOriginatorInfo, and authenticated or unauthenticated attributes maybe supplied by calling method setAuthenticatedAttributes or setUnauthenticatedAttributes, respectively, e.g.:
 // the content type
 ObjectID contentType = ObjectID.cms_data;
 // the content data supplying input stream:
 InputStream dataStream = ...;
 // the mac algorithm to be used
 AlgorithmID macAlgorithm = (AlgorithmID)AlgorithmID.hMAC_SHA512.clone();
 // the length of the mac key to be generated
 int macKeyLength = 64;
 // we do not need mac algorithm parameters
 AlgorithmParameterSpec macParams = null;
 // we want to include authenticated attributes and therefore need a digest algorithm
 AlgorithmID digestAlgorithm = (AlgorithmID)AlgorithmID.sha512.clone();
 // the transmission mode (either AuthenticatedDataStream.IMPLICIT or AuthenticatedDataStream.EXPLICIT)
 int mode = ...;
 // create the AuthenticatedDataStream object:
 AuthenticatedDataStream authenticatedData = new AuthenticatedDataStream(contentType,
                                                                         dataStream, 
                                                                         macAlgorithm,
                                                                         macKeyLength,
                                                                         macParams,
                                                                         digestAlgorithm,
                                                                         mode);
 
For providing origin authentication we use Static-Staic Diffie-Hellman as key management technique and include an OriginatorInfo containing the originator certificates:
 X509Certificate[] originatorCerts = ...;
 OriginatorInfo originator = new OriginatorInfo();
 originator.setCertificates(originatorCerts);
 authenticatedData.setOriginatorInfo(originator);
 
Just for demonstration we only add one authenticated attribute (ContentType):
 Attribute[] attributes = { new Attribute(new CMSContentType(contentType)) };
 authenticatedData.setAuthenticatedAttributes(attributes);
 
When authenticated attributes are present they at least must contain the ContentType and the (MessageDigest) attribute. It is not necessary for the application to provide the MessageDigest attribute since it is automatically calculated and set during the encoding procedure.
Recipient specific information is required to encrypt the secret mac key and may be supplied by calling method setRecipientInfos. In our example we add one RecipientInfo (containing recipient information for the sender who wants to be able to verify the MAC, too, and one for the final recipient). To provide origin authentication we use Static-Static ECDH with dhSinglePass-stdDH-sha256kdf-scheme as key management technique together with AES256-Wrap (RFC 3394) for encrypting (wrapping) the HMAC key:
 // the key encryption (key agreement) algorithm to use:
 AlgorithmID keyEA = (AlgorithmID)CMSAlgorithmID.dhSinglePass_stdDH_sha256kdf_scheme.clone();
 // the key wrap algorithm to use:
 AlgorithmID keyWrapAlg = (AlgorithmID)AlgorithmID.cms_aes256_wrap.clone();
 // the length of the key encryption key to be generated:
 int kekLength = 256;
 // in static-static mode we supply user keying material so that a different kek is generated
 SecureRandom random = ...;
 byte[] ukm = new byte[64];
 random.nextBytes(ukm);
 
 RecipientInfo[] recipients = new RecipientInfo[1];
 recipients[0] = new KeyAgreeRecipientInfo(originatorCert, 
                                           originatorPrivateKey,
                                           KeyIdentifier.ISSUER_AND_SERIALNUMBER,
                                           keyEA, 
                                           keyWrapAlg, 
                                           kekLength, 
                                           ukm);
 // add originator) as recipient, too
 ((KeyAgreeRecipientInfo)recipients[0]).addRecipient(originatorCert, CertificateIdentifier.ISSUER_AND_SERIALNUMBER);
 // add the final recipient (cert identified by RecipientKeyIdentifier for demonstration purposes)
 ((KeyAgreeRecipientInfo)recipients[0]).addRecipient(recipientCert, CertificateIdentifier.RECIPIENT_KEY_IDENTIFIER);
 // set the recipients of the authenticated message
 authenticatedData.setRecipientInfos(recipients);
 
Note that when using static-static DH the message should not be sent to more than only one final recipient (except for the sender) (see RFC 6278).

If the content shall not be included in the AuthenticatedData object (EXPLICIT mode) now it is time to read away the content to transmit it by other means. While reading the content from the stream it is piped through a InputStreamHashEngine (since authenticated attributes are present) to calculate and set the value of the MessageDigest attribute. Later, during the encoding procedure (when calling method writeTo) the mac value is calculated from the DER encoded authenticated attributes (if no authenticated attributes are set, an InputStreamMacEngine is used to immediately calculate the mac value from the content data), e.g.:

 // in explicit mode get the content and write it to any out-of-band place
 if (mode == AuthenticatedDataStream.EXPLICIT) {
   InputStream contentIs = authenticatedData.getInputStream();
   byte[] buf = new byte[2048];
   int r;
   while ((r = data_is.read(buf)) > 0) {
     // do something useful
   }  
 }
 
Finally method writeTo has to be called for BER encoding the AuthenticatedDataStream object and writing it to an output stream. It is recommended to specify a positive block size value for splitting the data encoding:
 int blockSize = ...; 
 authenticatedData.writeTo(output_stream, blockSize);
 
respectively
 authenticatedData.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 AuthenticatedData implementation to handle large amounts of data. When no block size is specified the whole content data is encoded as one primitive definite octet string, which advantageously may be done when using the non-stream supporting AuthenticatedData implementation. When a positive block size is specified for encoding the AuthenticatedData 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. (for some small data):
 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.


When receiving an AuthenticatedData message use the AuthenticatedDataStream(InputStream) constructor for parsing the AuthenticatedData from its BER encoding:

 // the input stream supplying the BER encoded AuthenticatedData
 InputStream encodedStream = ...;
 // parse the AuthenticatedData
 AuthenticatedDataStream authenticatedData = new AuthenticatedDataStream(encodedStream);
 
If the content has been transmitted by other means (EXPLICIT mode) it now has to be supplied by calling method setInputStream since it is required for MAC computation (verification):
 if (authenticatedData.getMode() == AuthenticatedDataStream.EXPLICIT) {
   // in explicit mode explicitly supply the content for hash/mac computation 
   InputStream contentIs = ...; // the content supplied from an input stream
   authenticatedData.setInputStream(contentIs);
 }
 
In order to decrypt the encrypted MAC key the recipient has to call a proper setupMac method thereby specifying her/his key encryption key which has to be suitable for the key management technique that has been used. Since in our example the recipients have used the Static-Static DH key agreement technique, the recipient private key is required derive the key encryption key which subsequently is used to decrypt the encrypted mac key. The right RecipientInfo maybe identified by the recipient certificate, e.g.:
 // the recipient certificate:
 X509Certificate recipientCert = ...; 
 // the corresponding private key
 PrivateKey recipientPrivateKey = ...;
 // setup the MAC by decrypting the secret MAC key
 autenticatedData.setupMac(recipientPrivateKey, recipientCert);
 
After decrypting the encrypted MAC key the data can be obtained and read to calculate and subsequently verify the MAC value:
 InputStream contentIs = authenticatedData.getInputStream();
 byte[] buf = new byte[2048];
 int r;
 while ((r = data_is.read(buf)) > 0) {
   // do something useful
 } 
 // verify the MAC  
 try {
   if (authenticatedData.verifyMac() == false) {
     System.out.println("Invalid MAC value!");
   }
 } catch (CMSMacException ex) {
   System.out.println("Mac verification error: " + ex.toString());
 }
 System.out.println("Mac successfully verified!");
 
Note that the example above uses Elliptic Curve DH. For that reason you would not only need iaik_cms.jar and iaik_jce_(full).jar (IAIK-JCE, https://jce.iaik.tugraz.at/products/core-crypto-toolkits/jca-jce/) in your classpath, but also iaik_eccelarate.jar (IAIK-ECCelerateTM, https://jce.iaik.tugraz.at/products/core-crypto-toolkits/eccelerate/).
Of course, you can also use AuthenticatedData with finite field DH and/or RSA. Have a look at the IAIK-CMS Demo library for AuthenticatedData examples.

See Also:
RecipientInfo, KeyAgreeRecipientInfo

Field Summary
static int EXPLICIT
          Denotes a mode where the content is not transmitted within the AuthenticatedData.
static int IMPLICIT
          Denotes a mode where the content is included in the AuthenticatedData.
 
Constructor Summary
protected AuthenticatedDataStream()
          Default constructor for dynamic object creation.
  AuthenticatedDataStream(java.io.InputStream is)
          Creates an AuthenticatedDataStream from a BER encoded AutheticatedData object which is read from the given InputStream.
  AuthenticatedDataStream(java.io.InputStream is, SecurityProvider securityProvider)
          Creates an AuthenticatedDataStream from a BER encoded AutheticatedData object which is read from the given InputStream.
  AuthenticatedDataStream(ObjectID contentType, java.io.InputStream is, AlgorithmID macAlg, byte[] mac, AlgorithmID digestAlg, int mode)
          Creates an AuthenticatedDataStream from an already calculated MAC value.
  AuthenticatedDataStream(ObjectID contentType, java.io.InputStream is, AlgorithmID macAlg, int macKeyLength, java.security.spec.AlgorithmParameterSpec macParams, AlgorithmID digestAlg, int mode)
          Creates a new AuthenticatedDataStream where the to-be-authenticated content data is supplied by an input stream.
  AuthenticatedDataStream(ObjectID contentType, java.io.InputStream is, AlgorithmID macAlg, int macKeyLength, java.security.spec.AlgorithmParameterSpec macParams, AlgorithmID digestAlg, int mode, SecurityProvider securityProvider)
          Creates a new AuthenticatedDataStream where the to-be-authenticated content data is supplied by an input stream.
  AuthenticatedDataStream(ObjectID contentType, java.io.InputStream is, AlgorithmID macAlg, int macKeyLength, java.security.spec.AlgorithmParameterSpec macParams, int mode)
          Creates a new AuthenticatedDataStream where the to-be-authenticated content data is supplied by an input stream.
  AuthenticatedDataStream(ObjectID contentType, java.io.InputStream is, AlgorithmID macAlg, int macKeyLength, java.security.spec.AlgorithmParameterSpec macParams, int mode, SecurityProvider securityProvider)
          Creates a new AuthenticatedDataStream where the to-be-authenticated content data is supplied by an input stream.
 
Method Summary
 void addRecipientInfo(RecipientInfo recipient)
          Adds one recipient to the list of recipient infos.
 void decode(java.io.InputStream is)
          Reads and decodes a BER encoded AutheticatedData from a the given input stream.
 void encodeCalled(ASN1Object obj, int id)
          This method implements the EncodeListener interface.
 Attribute getAuthenticatedAttribute(ObjectID oid)
          Returns the first authenticated attribute matching to the given ObjectID, if included in this AutheticatedData object.
 Attribute[] getAuthenticatedAttributes()
          Gets the authenticated attributes included in this AutheticatedData.
 byte[] getAuthenticatedDigest()
          Gets the value of the MessageDigest attribute, if included in the authenticated attributes.
 int getBlockSize()
          Gets the block size defining the length of each definite primitive encoded octet string component.
 ObjectID getContentType()
          Returns the content type this class implements.
 AlgorithmID getDigestAlgorithm()
          Gets the digest algorithm, if set.
 ObjectID getEncapsulatedContentType()
          Returns the content type the inherent EncapsulatetContentInfo represents.
 java.io.InputStream getInputStream()
          Returns an InputStream from where the content data can be read.
 byte[] getMac()
          Gets the MAC value.
 AlgorithmID getMacAlgorithm()
          Gets the MAC algorithm.
 int getMode()
          Returns the mode of this AuthenticatedData.
 OriginatorInfo getOriginatorInfo()
          Gets the OriginatorInfo, if included.
 RecipientInfo getRecipientInfo(KeyIdentifier recipientIdentifier)
          Returns the RecipientInfo belonging to the recipient identified by the given recipient identifier.
 RecipientInfo getRecipientInfo(X509Certificate recipientCertificate)
          Returns the recipient info matching to the supplied recipient certificate.
 RecipientInfo[] getRecipientInfos()
          Returns all the recipient infos included in this AutheticatedData object.
 RecipientInfo[] getRecipientInfos(int type)
          Returns all the recipient infos included in this AutheticatedData object that have the specified type.
 SecurityProvider getSecurityProvider()
          Gets the SecurityProvider installed for this AuthenticatedDataStream.
 Attribute getUnauthenticatedAttribute(ObjectID oid)
          Returns the first unauthenticated attribute matching to the given ObjectID, if included in this AutheticatedData object.
 Attribute[] getUnauthenticatedAttributes()
          Gets the unauthenticated attributes included in this AutheticatedData.
 int getVersion()
          Returns the syntax version number.
 void notifyEOF()
          This method implements the EOFListener interface for performing the final decoding.
 void setAuthenticatedAttributes(Attribute[] attributes)
          Sets a set of (authenticated) attributes.
 void setBlockSize(int blockSize)
          Sets the block size for defining the length of each definite primitive encoded octet string component.
 void setInputStream(java.io.InputStream is)
          Sets the content suppliyng input stream.
 void setOriginatorInfo(OriginatorInfo originatorInfo)
          Sets the optional OriginatorInfo.
 void setRecipientInfos(RecipientInfo[] recipients)
          Sets the recipient infos.
 void setSecurityProvider(SecurityProvider securityProvider)
          Sets the SecurityProvider for this AuthenticatedDataStream.
 void setUnauthenticatedAttributes(Attribute[] attributes)
          Sets a set of (unauthenticated) attributes.
 javax.crypto.SecretKey setupMac(java.security.Key recipientKey, int recipientInfoIndex)
          Uses the specified key for decrypting the mac key and setup the mac calculation for the requesting recipient, specified by its recipientInfoIndex.
 javax.crypto.SecretKey setupMac(java.security.Key recipientKey, KeyIdentifier recipientIdentifier)
          Uses the specified key for decrypting the mac key and setup the mac calculation for the requesting recipient, specified by the given recipient identifier.
 javax.crypto.SecretKey setupMac(java.security.Key recipientKey, X509Certificate recipientCertificate)
          Uses the specified key for decrypting the mac key and setup the mac calculation for the requesting recipient, specified by the given recipient certificate.
 void setupMac(javax.crypto.SecretKey macKey)
          Uses the given symmetric key to setup the mac calculation to verify the message authentication code when parsing an AuthenticatedData object .
 ASN1Object toASN1Object()
          Returns this AuthenticatedDataStream as ASN1Object.
protected  ASN1Object toASN1Object(int blockSize)
          Returns this AutheticatedData as ASN1Object.
 java.lang.String toString()
          Returns a string giving some information about this AutheticatedData object.
 java.lang.String toString(boolean detailed)
          Returns a string giving some - if requested - detailed information about this AutheticatedData object.
 boolean verifyMac()
          Verifies the message authentication code.
 void writeTo(java.io.OutputStream os)
          BER encodes this AutheticatedData and writes the encoding to the supplied output stream.
 void writeTo(java.io.OutputStream os, int blockSize)
          Writes the BER encoding of this AutheticatedData to the supplied output stream where a constructed OCTET STRING may be used for encoding the content.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

IMPLICIT

public static final int IMPLICIT
Denotes a mode where the content is included in the AuthenticatedData.

See Also:
Constant Field Values

EXPLICIT

public static final int EXPLICIT
Denotes a mode where the content is not transmitted within the AuthenticatedData.

See Also:
Constant Field Values
Constructor Detail

AuthenticatedDataStream

protected AuthenticatedDataStream()
Default constructor for dynamic object creation. The block size is set to 2048 to enforce indefinite constructed encoding.


AuthenticatedDataStream

public AuthenticatedDataStream(ObjectID contentType,
                               java.io.InputStream is,
                               AlgorithmID macAlg,
                               int macKeyLength,
                               java.security.spec.AlgorithmParameterSpec macParams,
                               int mode)
                        throws java.security.NoSuchAlgorithmException
Creates a new AuthenticatedDataStream where the to-be-authenticated content data is supplied by an input stream. This constructor generates a symmetric MAC key and uses an InputStreamMacEngine to wrap a mac calculating input stream around the data supplying input stream.

Parameters:
contentType - the type of the authenticated content (e.g. ObjectID.cms_data)
is - an input stream suppliyng the to-be-authenticated data
macAlg - the OID of the MAC algorithm to be used
macKeyLength - the length (in bytes) of the mac key to be generated; if not specified (-1), a default value will be used depending on the mac algorithm and the implementation of the SecurityProvider method generateKey. The IaikProvider tries to determine the block length of the mac algorithm in use; otherwise it uses the length of the underlying digest algorithm.
macParams - any parameters, if required by the mac algorithm
mode - the transmission mode; either IMPLICIT (to include the content) or EXPLICIT to transmit it by other means
Throws:
java.security.NoSuchAlgorithmException - if the requested digest or mac algorithm is not supported or the MAC key cannot be created

AuthenticatedDataStream

public AuthenticatedDataStream(ObjectID contentType,
                               java.io.InputStream is,
                               AlgorithmID macAlg,
                               int macKeyLength,
                               java.security.spec.AlgorithmParameterSpec macParams,
                               int mode,
                               SecurityProvider securityProvider)
                        throws java.security.NoSuchAlgorithmException
Creates a new AuthenticatedDataStream where the to-be-authenticated content data is supplied by an input stream. This constructor generates a symmetric MAC key and uses an InputStreamMacEngine to wrap a mac calculating input stream around the data supplying input stream.

Parameters:
contentType - the type of the authenticated content (e.g. ObjectID.cms_data)
is - an input stream suppliyng the to-be-authenticated data
macAlg - the OID of the MAC algorithm to be used
macKeyLength - the length (in bytes) of the mac key to be generated; if not specified (-1), a default value will be used depending on the mac algorithm and the implementation of the SecurityProvider method generateKey. The IaikProvider tries to determine the block length of the mac algorithm in use; otherwise it uses the length of the underlying digest algorithm.
macParams - any parameters, if required by the mac algorithm
mode - the transmission mode; either IMPLICIT (to include the content) or EXPLICIT to transmit it by other means
securityProvider - the SecurityProvider to be used for any required cryptographic operation
Throws:
java.security.NoSuchAlgorithmException - if the requested digest or mac algorithm is not supported or the MAC key cannot be created

AuthenticatedDataStream

public AuthenticatedDataStream(ObjectID contentType,
                               java.io.InputStream is,
                               AlgorithmID macAlg,
                               int macKeyLength,
                               java.security.spec.AlgorithmParameterSpec macParams,
                               AlgorithmID digestAlg,
                               int mode)
                        throws java.security.NoSuchAlgorithmException
Creates a new AuthenticatedDataStream where the to-be-authenticated content data is supplied by an input stream. This constructor generates a symmetric MAC key. If the digestAlg parameter is not null, an InputStreamHashEngine is used to wrap a hash calculating input stream around the data supplying input stream. In this case authenticated attributes have to be set by calling method setAuthenticatedAttributes and the MAC value is calculated from the DER encoded authenticated attributes which have to contain the -- (if not set) automatically calculated -- MessageDigest attribute. However, if the digestAlg parameter is null, an InputStreamMacEngine to wrap a MAC calculating input stream around the data supplying input stream for calculating the MAC value immediately from the content.

Parameters:
contentType - the type of the authenticated content (e.g. ObjectID.cms_data)
is - an input stream supplying the to-be-authenticated data
macAlg - the OID of the MAC algorithm to be used
macKeyLength - the length (in bytes) of the mac key to be generated; if not specified (-1), a default value will be used depending on the mac algorithm and the implementation of the SecurityProvider method generateKey. The IaikProvider tries to determine the block length of the mac algorithm in use; otherwise it uses the length of the underlying digest algorithm.
macParams - any parameters, if required by the mac algorithm
digestAlg - the OID of the digest algorithm to be used for hash computation if authenticated attributes are to be included
mode - the transmission mode; either IMPLICIT (to include the content) or EXPLICIT to transmit it by other means
Throws:
java.security.NoSuchAlgorithmException - if the requested digest or mac algorithm is not supported or the MAC key cannot be created

AuthenticatedDataStream

public AuthenticatedDataStream(ObjectID contentType,
                               java.io.InputStream is,
                               AlgorithmID macAlg,
                               int macKeyLength,
                               java.security.spec.AlgorithmParameterSpec macParams,
                               AlgorithmID digestAlg,
                               int mode,
                               SecurityProvider securityProvider)
                        throws java.security.NoSuchAlgorithmException
Creates a new AuthenticatedDataStream where the to-be-authenticated content data is supplied by an input stream. This constructor generates a symmetric MAC key. If the digestAlg parameter is not null, an InputStreamHashEngine is used to wrap a hash calculating input stream around the data supplying input stream. In this case authenticated attributes have to be set by calling method setAuthenticatedAttributes and the MAC value is calculated from the DER encoded authenticated attributes which have to contain the -- (if not set) automatically calculated -- MessageDigest attribute. However, if the digestAlg parameter is null, an InputStreamMacEngine to wrap a MAC calculating input stream around the data supplying input stream for calculating the MAC value immediately from the content.

Parameters:
contentType - the type of the authenticated content (e.g. ObjectID.cms_data)
is - an input stream suppliyng the to-be-authenticated data
macAlg - the OID of the MAC algorithm to be used
macKeyLength - the length (in bytes) of the mac key to be generated; if not specified (-1), a default value will be used depending on the mac algorithm and the implementation of the SecurityProvider method generateKey. The IaikProvider tries to determine the block length of the mac algorithm in use; otherwise it uses the length of the underlying digest algorithm.
macParams - any parameters, if required by the mac algorithm
digestAlg - the OID of the digest algorithm to be used for hash computation if authenticated attributes are to be included
mode - the transmission mode; either IMPLICIT (to include the content) or EXPLICIT to transmit it by other means
securityProvider - the SecurityProvider to be used for any required cryptographic operation
Throws:
java.security.NoSuchAlgorithmException - if the requested digest or mac algorithm is not supported or the MAC key cannot be created

AuthenticatedDataStream

public AuthenticatedDataStream(ObjectID contentType,
                               java.io.InputStream is,
                               AlgorithmID macAlg,
                               byte[] mac,
                               AlgorithmID digestAlg,
                               int mode)
Creates an AuthenticatedDataStream from an already calculated MAC value. No mac or digest calculation is initialized. If setAuthenticatedAttributes are supplied, they already have to contain the MessageDigest attribute. Any RecipientInfo added to this AuthenticatedDataStream already has to contain the encrypted mac key (i.e. no MAC key is generated and encrypted for each recipient).

Parameters:
contentType - the type of the authenticated content (e.g. ObjectID.cms_data)
is - an input stream suppliyng the to-be-authenticated data
macAlg - the OID of the MAC algorithm used for mac calculation
mac - the already calculated mac value
digestAlg - the OID of the digest algorithm used for hash calculation
mode - the transmission mode; either IMPLICIT (to include the content) or EXPLICIT to transmit it by other means

AuthenticatedDataStream

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

Parameters:
is - the InputStream supplying a BER encoded CMS AutheticatedData 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

AuthenticatedDataStream

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

Parameters:
is - the InputStream supplying a BER encoded CMS AutheticatedData 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

setSecurityProvider

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

This method allows to explicitly set a SecurityProvider for this AuthenticatedDataStream. 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 AutheticatedDataStream object. This may be necessary on the parsing side, and also when creating a new AutheticatedDataStream object for MAC key generation and hash/mac computation initialization.

Parameters:
securityProvider - the SecurityProvider to be set

getSecurityProvider

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

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

decode

public void decode(java.io.InputStream is)
            throws java.io.IOException,
                   CMSParsingException
Reads and decodes a BER encoded AutheticatedData from a the given input stream. The encoded AutheticatedData may (or may not) be wrapped into a ContentInfo.

Specified by:
decode in interface ContentStream
Parameters:
is - the InputStream holding a BER encoded AutheticatedData 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

getContentType

public ObjectID getContentType()
Returns the content type this class implements.

Use method getEncapsulatedContentType for getting the type of the inherent (authenticated) content.

Specified by:
getContentType in interface ContentStream
Returns:
ObjectID.cms_autheticatedData

getEncapsulatedContentType

public ObjectID getEncapsulatedContentType()
Returns the content type the inherent EncapsulatetContentInfo represents.

Returns:
the content type the inherent EncapsulatetContentInfo represents

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 symmetric mac key.

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 symmetric mac key.

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

setAuthenticatedAttributes

public void setAuthenticatedAttributes(Attribute[] attributes)
Sets a set of (authenticated) attributes. If authenticated attributes are present, the MAC value is calculated from the DER encoded authenticated attributes which have to contain the MessageDigest attribute. In this case the digestAlgorithm field is not allowed to be null since it identifies the algorithm to be used for calculating a digest value from the content and set it as MessageDigest attribute. If the MessageDigest attribute is not included in the set of attributes supplied to this methode, it is automatically calculated and set.

Parameters:
attributes - the authenticated attributes to be set
Throws:
java.lang.NullPointerException - if no digest algorithm has been specified when creating this AuthenticatedDataStream object

setUnauthenticatedAttributes

public void setUnauthenticatedAttributes(Attribute[] attributes)
Sets a set of (unauthenticated) attributes.

Parameters:
attributes - the unauthenticated attributes to be set

setBlockSize

public void setBlockSize(int blockSize)
Sets the block size for defining the length of each definite primitive encoded octet string component. If the value of blockSize is smaller or equal to zero the whole content data is encoded as definite primitive octet string, otherwise indefinite constructed encoding is used.

Specified by:
setBlockSize in interface ContentStream
Parameters:
blockSize - for defining the encoding scheme and setting the octet string component length, if positive

getBlockSize

public int getBlockSize()
Gets the block size defining the length of each definite primitive encoded octet string component. If the value of blockSize is smaller or equal to zero the whole data is encoded as definite primitive octet string, otherwise indefinite constructed encoding is used.

Specified by:
getBlockSize in interface ContentStream
Returns:
the block size defining the encoding scheme and setting the octet string component length, if positive

setupMac

public javax.crypto.SecretKey setupMac(java.security.Key recipientKey,
                                       int recipientInfoIndex)
                                throws CMSException,
                                       java.security.NoSuchAlgorithmException,
                                       java.security.InvalidKeyException
Uses the specified key for decrypting the mac key and setup the mac calculation for the requesting recipient, specified by its recipientInfoIndex.

This method first uses the given key for decrypting the encrypted temporary symmetric key obtained from the corresponding RecipientInfo structure, and subsequently uses this mac key to initialize the mac calculation.

The mac calculation actually is done during reading the data obtained by calling method getInputStream. So do not call method getInputStream before setting up the mac engine or behind verifying the mac, e.g.:

 // the input stream supplying the BER encoded AuthenticatedData
 InputStream encodedStream = ...;
 // parse the AuthenticatedData
 AuthenticatedDataStream authenticatedData = new AuthenticatedDataStream(encodedStream);
 if (authenticatedData.getMode() == AuthenticatedDataStream.EXPLICIT) {
   // in explicit mode explicitly supply the content for hash/mac computation 
   InputStream contentIs = ...; // the content supplied from an input stream
   authenticatedData.setInputStream(contentIs);
 }
 // the index into the recipientInfos field
 int recipientIndex = ...; 
 // the corresponding recipient key
 Key recipientKey = ...;
 // decrypt the encrypted MAC key with the private key of the recipient:
 autenticatedData.setupMac(recipientKey, recipientIndex);
 InputStream contentIs = authenticatedData.getInputStream();
 byte[] buf = new byte[2048];
 int r;
 while ((r = data_is.read(buf)) > 0) {
   // do something useful
 } 
 // verify the MAC  
 try {
   if (authenticatedData.verifyMac() == false) {
     System.out.println("Invalid MAC value!");
   }
 } catch (CMSMacException ex) {
   System.out.println("Mac verification error: " + ex.toString());
 }
 System.out.println("Mac successfully verified!");
 

Note that you have to know the right index into the recipientInfos field when using this method for setting up the mac calculation. You may search for the index by using one of the getRecipientInfo methods thereby identifying the recipient by its keyIdentifier or -- if suitable for the key management algorithm used -- certificate.
However, when having some recipient using a key agreement protocol the corresponding RecipientInfo is of type KeyAgreeRecipientInfo which may hold encrypted mac keys for more than only one recipients using the same key agreement algorithm with same domain parameters. Since this setupMac method only can get the KeyAgreeRecipientInfo with the given index (but not search for the right recipient in the KeyAgreeRecipientInfo), it will step through any recipient included in the KeyAgreeRecipientInfo trying to decrypt the encrypted mac key with the supplied key. This may give some overhead; so it might be appropriate to use another setupMac method allowing to immediately identify the particular recipient in mind by its #setupMac(Key, KeyIdentifier) keyIdentifier} or certificate.

Parameters:
recipientKey - the key of the recipient to be used for decrypting the encrypted mac key.
recipientInfoIndex - the index into the recipientInfos field
Returns:
the (decrypted) secret mac key
Throws:
CMSException - if there occurs an error while decrypting the mac key or setting up the mac calculation, or no RecipientInfo for the requested recipient is included
java.security.NoSuchAlgorithmException - if there is no implementation of the mac algorithm
java.security.InvalidKeyException - if the specified key is not valid

setupMac

public javax.crypto.SecretKey setupMac(java.security.Key recipientKey,
                                       KeyIdentifier recipientIdentifier)
                                throws CMSException,
                                       java.security.NoSuchAlgorithmException,
                                       java.security.InvalidKeyException
Uses the specified key for decrypting the mac key and setup the mac calculation for the requesting recipient, specified by the given recipient identifier.

This method first uses the given key for decrypting the encrypted temporary symmetric key obtained from the corresponding RecipientInfo structure, and subsequently uses this mac key to initialize the mac calculation.

The mac calculation actually is done during reading the data obtained by calling method getInputStream. So do not call method getInputStream before setting up the mac engine or behind verifying the mac, e.g.:

 // the input stream supplying the BER encoded AuthenticatedData
 InputStream encodedStream = ...;
 // parse the AuthenticatedData
 AuthenticatedDataStream authenticatedData = new AuthenticatedDataStream(encodedStream);
 if (authenticatedData.getMode() == AuthenticatedDataStream.EXPLICIT) {
   // in explicit mode explicitly supply the content for hash/mac computation 
   InputStream contentIs = ...; // the content supplied from an input stream
   authenticatedData.setInputStream(contentIs);
 }
 // the KeyIdentifier identifying the recipient key
 KeyIdentifier recipientIdentifier = ...; 
 // the corresponding recipient key
 Key recipientKey = ...;
 // decrypt the encrypted MAC key with the private key of the recipient:
 autenticatedData.setupMac(recipientKey, recipientIdentifier);
 InputStream contentIs = authenticatedData.getInputStream();
 byte[] buf = new byte[2048];
 int r;
 while ((r = data_is.read(buf)) > 0) {
   // do something useful
 } 
 // verify the MAC  
 try {
   if (authenticatedData.verifyMac() == false) {
     System.out.println("Invalid MAC value!");
   }
 } catch (CMSMacException ex) {
   System.out.println("Mac verification error: " + ex.toString());
 }
 System.out.println("Mac successfully verified!");
 

This setupMac method can be used to setup the mac engine any type of RecipientInfo. The supplied recipient identifier will be used for searching for the right RecipientInfo in the recipientInfos field.

Parameters:
recipientKey - the key of the recipient to be used for decrypting the encrypted mac key.
recipientIdentifier - specifies which RecipientInfo the given key belongs to
Returns:
the (decrypted) secret mac key
Throws:
CMSException - if there occurs an error while decrypting the mac key or setting up the mac calculation, or no RecipientInfo for the requested recipient is included
java.security.NoSuchAlgorithmException - if there is no implementation of the mac algorithm
java.security.InvalidKeyException - if the specified key is not valid

setupMac

public javax.crypto.SecretKey setupMac(java.security.Key recipientKey,
                                       X509Certificate recipientCertificate)
                                throws CMSException,
                                       java.security.NoSuchAlgorithmException,
                                       java.security.InvalidKeyException
Uses the specified key for decrypting the mac key and setup the mac calculation for the requesting recipient, specified by the given recipient certificate.

This method first uses the given key for decrypting the encrypted temporary symmetric key obtained from the corresponding RecipientInfo structure, and subsequently uses this mac key to initialize the mac calculation.

The mac calculation actually is done during reading the data obtained by calling method getInputStream. So do not call method getInputStream before setting up the mac engine or behind verifying the mac, e.g.:

 // the input stream supplying the BER encoded AuthenticatedData
 InputStream encodedStream = ...;
 // parse the AuthenticatedData
 AuthenticatedDataStream authenticatedData = new AuthenticatedDataStream(encodedStream);
 if (authenticatedData.getMode() == AuthenticatedDataStream.EXPLICIT) {
   // in explicit mode explicitly supply the content for hash/mac computation 
   InputStream contentIs = ...; // the content supplied from an input stream
   authenticatedData.setInputStream(contentIs);
 }
 // the recipient certificate:
 X509Certificate recipientCert = ...; 
 // the corresponding private key
 PrivateKey recipientPrivateKey = ...;
 // setup the MAC by decrypting the secret MAC key
 autenticatedData.setupMac(recipientPrivateKey, recipientCert);
 InputStream contentIs = authenticatedData.getInputStream();
 byte[] buf = new byte[2048];
 int r;
 while ((r = data_is.read(buf)) > 0) {
   // do something useful
 } 
 // verify the MAC  
 try {
   if (authenticatedData.verifyMac() == false) {
     System.out.println("Invalid MAC value!");
   }
 } catch (CMSMacException ex) {
   System.out.println("Mac verification error: " + ex.toString());
 }
 System.out.println("Mac successfully verified!");
 

Note that this method only can be used for decrypting the encrypted mac key if the recipient in mind has a RecipientInfo of type KeyTransRecipientInfo or KeyAgreeRecipientInfo using a public key from a certificate for its key management protocol.

Parameters:
recipientKey - the private key of the recipient to be used for decrypting the encrypted mac key.
recipientCertificate - the certificate of the recipient specifying which RecipientInfo the recipient private key belongs to
Returns:
the (decrypted) secret mac key
Throws:
CMSException - if there occurs an error while decrypting the mac key or setting up the mac calculation, or no RecipientInfo for the requested recipient is included
java.security.NoSuchAlgorithmException - if there is no implementation of the mac algorithm
java.security.InvalidKeyException - if the specified key is not valid

setupMac

public void setupMac(javax.crypto.SecretKey macKey)
              throws CMSException,
                     java.security.NoSuchAlgorithmException,
                     java.security.InvalidKeyException
Uses the given symmetric key to setup the mac calculation to verify the message authentication code when parsing an AuthenticatedData object .

The secret key supplied to this method has to be the already decrypted mac key.

The mac calculation actually is done during reading the data obtained by calling method getInputStream. So do not call method getInputStream before setting up the mac engine or behind verifying the mac, e.g.:

 // the input stream supplying the BER encoded AuthenticatedData
 InputStream encodedStream = ...;
 // parse the AuthenticatedData
 AuthenticatedDataStream authenticatedData = new AuthenticatedDataStream(encodedStream);
 if (authenticatedData.getMode() == AuthenticatedDataStream.EXPLICIT) {
   // in explicit mode explicitly supply the content for hash/mac computation 
   InputStream contentIs = ...; // the content supplied from an input stream
   authenticatedData.setInputStream(contentIs);
 }
 // the may key
 Key macKey = ...;
 // setup the MAC engine
 autenticatedData.setupMac(macKey);
 InputStream contentIs = authenticatedData.getInputStream();
 byte[] buf = new byte[2048];
 int r;
 while ((r = data_is.read(buf)) > 0) {
   // do something useful
 } 
 // verify the MAC  
 try {
   if (authenticatedData.verifyMac() == false) {
     System.out.println("Invalid MAC value!");
   }
 } catch (CMSMacException ex) {
   System.out.println("Mac verification error: " + ex.toString());
 }
 System.out.println("Mac successfully verified!");
 

Parameters:
macKey - the temporary symmetric key that has been used to calculate the message authentication code
Throws:
CMSException - if there occurs an error when setting up the mac calculation, or no RecipientInfo for the requested recipient is included
java.security.NoSuchAlgorithmException - if there is no implementation of the mac algorithm
java.security.InvalidKeyException - if the specified key is not valid

getAuthenticatedDigest

public byte[] getAuthenticatedDigest()
                              throws CMSException
Gets the value of the MessageDigest attribute, if included in the authenticated attributes.

Returns:
the message digest included in the authenticated attributes
Throws:
CMSException - if no message digest attribute is included

getMode

public int getMode()
Returns the mode of this AuthenticatedData.

Returns:
IMPLICIT or EXPLICIT

verifyMac

public boolean verifyMac()
                  throws CMSMacException
Verifies the message authentication code.

For verifying the MAC value first the mac calcualtion has to be set up by calling a proper setupMac method and the content data has to be get and entirely read:

 // the input stream supplying the BER encoded AuthenticatedData
 InputStream encodedStream = ...;
 // parse the AuthenticatedData
 AuthenticatedDataStream authenticatedData = new AuthenticatedDataStream(encodedStream);
 if (authenticatedData.getMode() == AuthenticatedDataStream.EXPLICIT) {
   // in explicit mode explicitly supply the content for hash/mac computation 
   InputStream contentIs = ...; // the content supplied from an input stream
   authenticatedData.setInputStream(contentIs);
 }
 // the recipient certificate:
 X509Certificate recipientCert = ...; 
 // the corresponding private key
 PrivateKey recipientPrivateKey = ...;
 // setup the MAC by decrypting the secret MAC key
 autenticatedData.setupMac(recipientPrivateKey, recipientCert);
 InputStream contentIs = authenticatedData.getInputStream();
 byte[] buf = new byte[2048];
 int r;
 while ((r = data_is.read(buf)) > 0) {
   // do something useful
 } 
 // verify the MAC  
 try {
   if (authenticatedData.verifyMac() == false) {
     System.out.println("Invalid MAC value!");
   }
 } catch (CMSMacException ex) {
   System.out.println("Mac verification error: " + ex.toString());
 }
 System.out.println("Mac successfully verified!");
 

Returns:
true if the MAC verifies, false if not
Throws:
CMSMacException - if the MAC verification process fails for some reason (e.g. the authenticated attributes (if incldued) cannot be parsed or the content hash does not match to value of the included MessageDigest attribute)

getInputStream

public java.io.InputStream getInputStream()
Returns an InputStream from where the content data can be read.

Attention! The stream only may be read once.

When having created a new AuthenticatedDataStream object to be encoded to a stream, this method should only be called in EXPLICT mode to get and read away the content to be transmitted by other means.
When having decoded and parsed a received AuthenticatedDataStream object coming from some stream, this method may be used for obtaining the raw (decrypted) data after having setup the mac engine for mac calculation/verifation, e.g.:

 // the input stream supplying the BER encoded AuthenticatedData
 InputStream encodedStream = ...;
 // parse the AuthenticatedData
 AuthenticatedDataStream authenticatedData = new AuthenticatedDataStream(encodedStream);
 if (authenticatedData.getMode() == AuthenticatedDataStream.EXPLICIT) {
   // in explicit mode explicitly supply the content for hash/mac computation 
   InputStream contentIs = ...; // the content supplied from an input stream
   authenticatedData.setInputStream(contentIs);
 }
 // setup the mac calculation
 autenticatedData.setupMac(...);
 // get and read the content data
 InputStream contentIs = authenticatedData.getInputStream();
 byte[] buf = new byte[2048];
 int r;
 while ((r = data_is.read(buf)) > 0) {
   // do something useful
 } 
 // verify the MAC  
 try {
   if (authenticatedData.verifyMac() == false) {
     System.out.println("Invalid MAC value!");
   }
 } catch (CMSMacException ex) {
   System.out.println("Mac verification error: " + ex.toString());
 }
 System.out.println("Mac successfully verified!");
 

Returns:
an InputStream for reading the content data

setInputStream

public void setInputStream(java.io.InputStream is)
Sets the content suppliyng input stream. When having created a new AuthenticatedDataStream object to be encoded to a stream, this method may be used to supply the content to be authenticated.
When having decoded and parsed a received AuthenticatedDataStream object coming from some stream, this method may be used for supplying the content transmitted by other means (EXPLICIT mode).

Parameters:
is - the input stream holding the content data to be authenticated

getVersion

public int getVersion()
Returns the syntax version number.

Returns:
the syntax version number

getOriginatorInfo

public OriginatorInfo getOriginatorInfo()
Gets the OriginatorInfo, if included.

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

Returns:
the originatorInfo, if included; otherwise null

getRecipientInfos

public RecipientInfo[] getRecipientInfos()
Returns all the recipient infos included in this AutheticatedData object.

Returns:
an array containing all the RecipientInfo objects included into this AutheticatedData

getRecipientInfos

public RecipientInfo[] getRecipientInfos(int type)
Returns all the recipient infos included in this AutheticatedData object that have the specified type.

Returns:
an array containing all the RecipientInfo objects included into this AutheticatedData that have the specified type (e.g. all KeyTransRecipientInfos); the array may be empty if no RecipientInfo with the requested type is included

getRecipientInfo

public RecipientInfo getRecipientInfo(X509Certificate recipientCertificate)
Returns the recipient info matching to the supplied recipient certificate.

This method may be used by a recipient for quering for the recipient info that holds the mac key encrypted with the public key of the given certificate.
Note that this method only can be used for searching for RecipientInfos of type KeyTransRecipientInfo or KeyAgreeRecipientInfo, but NOT for a RecipientInfo of type KEKRecipientInfo or PasswordRecipientInfo which does use a certificate.

Returns:
the RecipientInfo matching to the supplied recipient certificate, or null if no recipient info belonging to the given certificate can be found

getRecipientInfo

public RecipientInfo getRecipientInfo(KeyIdentifier recipientIdentifier)
Returns the RecipientInfo belonging to the recipient identified by the given recipient identifier.

Parameters:
recipientIdentifier - the recipient identifier identifying the recipient in mind
Returns:
the RecipientInfo matching to the supplied recipient identifier, or null if no recipient info belonging to the given recipient identifier can be found

getMacAlgorithm

public AlgorithmID getMacAlgorithm()
Gets the MAC algorithm.

Returns:
the MAC algorithm

getDigestAlgorithm

public AlgorithmID getDigestAlgorithm()
Gets the digest algorithm, if set.

Returns:
the digest algorithm, or null if no digest algorithm is set

getAuthenticatedAttributes

public Attribute[] getAuthenticatedAttributes()
Gets the authenticated attributes included in this AutheticatedData.

Returns:
the authenticated attributes; if included

getUnauthenticatedAttributes

public Attribute[] getUnauthenticatedAttributes()
Gets the unauthenticated attributes included in this AutheticatedData.

Returns:
the unauthenticated attributes; if included

getAuthenticatedAttribute

public Attribute getAuthenticatedAttribute(ObjectID oid)
Returns the first authenticated attribute matching to the given ObjectID, if included in this AutheticatedData object.

Returns:
the first authenticated attribute belonging to the given ObjectID or null if there is no attribute for the given OID.

getMac

public byte[] getMac()
Gets the MAC value.

Returns:
the MAC value.

getUnauthenticatedAttribute

public Attribute getUnauthenticatedAttribute(ObjectID oid)
Returns the first unauthenticated attribute matching to the given ObjectID, if included in this AutheticatedData object.

Returns:
the first unauthenticated attribute belonging to the given ObjectID or null if there is no attribute for the given OID.

toASN1Object

public ASN1Object toASN1Object()
                        throws CMSException
Returns this AuthenticatedDataStream as ASN1Object. The ASN.1 SEQUENCE returned by this method only will contain the first components (version, (originatorInfo), recipientInfos, macAlgorithm, (digestAlgorithm) and EncapsulatedContentInfo without content) of the ASN.1 AuthenticatedData. The remaining components (autenticated attributes, mac value autenticated attributes) are added later during the encoding procedure (when writeTo is called).

Specified by:
toASN1Object in interface ContentStream
Returns:
this AuthenticatedDataStream as ASN1Object.
Throws:
CMSException - if the ASN1Object could not be created

toASN1Object

protected ASN1Object toASN1Object(int blockSize)
                           throws CMSException
Returns this AutheticatedData as ASN1Object.

If is positive a constructed OCTET STRING is used for encoding the content data. This method actually will perform the encryption of the symmetric mac key for each participated recipient.

The ASN.1 SEQUENCE returned by this method only will contain the first components (version, (originatorInfo), recipientInfos, macAlgorithm, (digestAlgorithm) and EncapsulatedContentInfo without content) of the ASN.1 AuthenticatedData. The remaining components (autenticated attributes, mac value autenticated attributes) are added later during the encoding procedure (when writeTo is called).

Parameters:
blockSize - the block size defining the encoding scheme - and specifying the length of each primitive encoded octet string component; if positive
Returns:
this AutheticatedData as ASN1Object
Throws:
CMSException - if the ASN1Object could not be created

encodeCalled

public void encodeCalled(ASN1Object obj,
                         int id)
                  throws CodingException
This method implements the EncodeListener interface. During the encoding process the DerCoder calls this method when it actually is time for encoding the attribute and mac value components. The message digest or mac value over the content data cannot be computed before the content stream entirely has been read. Since the content stream actually is read during the encoding procedure, the AuthenticatedDataStream registers itself as encode listener for the SEQUENCE representing the final ASN.1 AuthenticatedData object. After the content stram has been read and before attributes and mac value are to be encoded, this class is notified by means of the IAIK-JCE EncodeListener utility.

This method shall not be called by an application!

Specified by:
encodeCalled in interface EncodeListener
Parameters:
obj - the SignedData SEQUENCE
id - the id identifying the SEQUENCE to be processed
Throws:
CodingException - if an error occurs when computing/signing the message digest

writeTo

public void writeTo(java.io.OutputStream os)
             throws java.io.IOException
BER encodes this AutheticatedData and writes the encoding to the supplied output stream.

Parameters:
os - the output stream to which this AutheticatedData shall be written
Throws:
java.io.IOException

writeTo

public void writeTo(java.io.OutputStream os,
                    int blockSize)
             throws java.io.IOException
Writes the BER encoding of this AutheticatedData to the supplied output stream where a constructed OCTET STRING may be used for encoding the content.

If the a positive blockSize value is specified, the content is encoded as indefinite constructed octet string being composed of a certain number of definite primitive encoded octet strings of blockSize length:

 0x24 0x80
           0x04 <blocksize> <first encrypted content block>
           0x04 <blocksize> <second encrypted content block>
           0x04 <blocksize> <third encrypted content block>
                ...
 0x00 0x00
 
Otherwise the whole content is encoded as definite primitive octet string:
  0x04 <length> <encrypted content>
 

Parameters:
os - the output stream to which this AuthenticatedData shall be written
blockSize - the block size defining the encoding scheme - and specifying the length of each primitive encoded octet string component, if positive
Throws:
java.io.IOException - if an error occurs during writing the object

notifyEOF

public void notifyEOF()
               throws java.io.IOException
This method implements the EOFListener interface for performing the final decoding. Since attributes and mac value, if present, are located at the end of an AutheticatedData structure, they only can be accessed after reading the content data located before the attributes/MAC value. For that reason, when starting the parsing of an AutheticatedData message only version, (originatorInfo), recipientInfos, macAlgorithm, (digestAlgorithm) and EncapsulatedContentInfo fields can be parsed before reading the content data. Since the data is supplied from an input stream, a 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 notifyEOF method for finishing the decoding by parsing the remaining authenticated and unauthenticated attributes, if present, and the mac value.
An application shall not call this method at all. This method only is qualified as public method since it implements the IAIK-JCE iaik.utils.EOFListener interface.

Specified by:
notifyEOF in interface EOFListener
Throws:
java.io.IOException - if an error occurs while parsing the stream

toString

public java.lang.String toString()
Returns a string giving some information about this AutheticatedData 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 AutheticatedData object.

Specified by:
toString in interface ContentStream
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