iaik.cms
Class AuthenticatedData

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

public class AuthenticatedData
extends AuthenticatedDataStream
implements Content

This class implements 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 AuthenticatedData object an application has to decide whether the to-be-authenticated content shall be included (IMPLICIT mode) into the AuthenticatedData message or shall be transmitted by other means (EXPLICIT mode):

 int mode = AuthenticatedData.IMPLICIT; // include content
 
or
 int mode = AuthenticatedData.EXPLICIT; // do not include content
 
However, in both cases the content data has to be supplied when creating the AuthenticatedData object, because it is needed for the MAC computation:
 byte[] content = ...; // the content data to be authenticated
 
Together with transmission mode and content data the following values have to be specified when creating an AuthenticatedData 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 to be authenticated
 byte[] content = ...;
 // the mac algorithm to be used
 AlgorithmID macAlgorithm = (AlgorithmID)AlgorithmID.hMAC_SHA256.clone();
 // the length of the mac key to be generated
 int macKeyLength = 32;
 // 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.sha256.clone();
 // the transmission mode (either AuthenticatedData.IMPLICIT or AuthenticatedData.EXPLICIT)
 int mode = ...;
 // create the AuthenticatedData object:
 AuthenticatedData authenticatedData = new AuthenticatedData(contentType,
                                                             content, 
                                                             macAlgorithm,
                                                             macKeyLength,
                                                             macParams,
                                                             digestAlgorithm,
                                                             mode);
 
For providing origin authentication we use Static-Staic (EC)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).

Finally the AuthenticatedData object has to be prepared for transmission by transforming it into an ASN1Object or immediately encoding it. The former is done by calling method toASN1Object, the latter by using method getEncoded method:

 ASN1Object asn1AuthData = authenticatedData.toASN1Object();
 
or
 byte[] encoding = authenticatedData.getEncoded();
 
You alternatively may use a proper writeTo method of the parent AuthenticatedDataStream class for immediately encoding this AuthenticatedData object to an output stream. When using writeTo in implicit mode, you additionally have the possibility of specifying a particular blockSize for forcing an indefinite constructed encoding of the inherent content data bytes, instead of of the default definite primitive encoding, e.g:
 0x24 0x80
           0x04 0x02 0x01 0xAB
           0x04 0x02 0x23 0x7F
           0x04 0x01 0xCA
 0x00 0x00 
 
instead of:
 0x04 0x05 0x01 0xAB 0x23 0x7F 0xCA
 
for encoding the five data bytes 0x01 0xAB 0x23 0x7F 0xCA. Of course, this only might be useful when having to handle big amounts of data.


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

 // the input stream supplying the encoded AuthenticatedData
 InputStream encodedStream = ...;
 // parse the AuthenticatedData
 AuthenticatedData authenticatedData = new AuthenticatedData(encodedStream);
 
If the content has been transmitted by other means (EXPLICIT mode) it now has to be supplied by calling method setContent since it is required for MAC computation (verification):
 if (authenticatedData.getMode() == AuthenticatedData.EXPLICIT) {
   // in explicit mode explicitly supply the content for hash/mac computation 
   byte[] content = ...; // the content received by other means
   authenticatedData.setContent(content);
 }
 
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 both recipients have used the key agreement technique, a private key is required 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 MAC value can be verified by calling method verifyMac:
 // 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!");
 
Finally (in implicit mode) the content may be accessed by calling method getContent:
 byte[] content = authenticatedData.getContent();
 
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, KeyTransRecipientInfo

Field Summary
 
Fields inherited from class iaik.cms.AuthenticatedDataStream
EXPLICIT, IMPLICIT
 
Constructor Summary
protected AuthenticatedData()
          Default constructor for dynamic object creation in ContentInfoStream.
  AuthenticatedData(java.io.InputStream is)
          Creates an AuthenticatedData from an encoded AutheticatedData object which is read from the given InputStream.
  AuthenticatedData(java.io.InputStream is, SecurityProvider securityProvider)
          Creates an AuthenticatedData from an encoded AutheticatedData object which is read from the given InputStream.
  AuthenticatedData(ObjectID contentType, byte[] content, AlgorithmID macAlg, byte[] mac, AlgorithmID digestAlg, int mode)
          Creates an AuthenticatedData from an already calculated MAC value.
  AuthenticatedData(ObjectID contentType, byte[] content, AlgorithmID macAlg, int macKeyLength, java.security.spec.AlgorithmParameterSpec macParams, AlgorithmID digestAlg, int mode)
          Creates a new AuthenticatedData where the to-be-authenticated content data is supplied from an byte array.
  AuthenticatedData(ObjectID contentType, byte[] content, AlgorithmID macAlg, int macKeyLength, java.security.spec.AlgorithmParameterSpec macParams, AlgorithmID digestAlg, int mode, SecurityProvider securityProvider)
          Creates a new AuthenticatedData where the to-be-authenticated content data is supplied from an byte array.
  AuthenticatedData(ObjectID contentType, byte[] content, AlgorithmID macAlg, int macKeyLength, java.security.spec.AlgorithmParameterSpec macParams, int mode)
          Creates a new AuthenticatedData where the to-be-authenticated content data is supplied from an byte array.
  AuthenticatedData(ObjectID contentType, byte[] content, AlgorithmID macAlg, int macKeyLength, java.security.spec.AlgorithmParameterSpec macParams, int mode, SecurityProvider securityProvider)
          Creates a new AuthenticatedData where the to-be-authenticated content data is supplied from an byte array.
 
Method Summary
 void decode(ASN1Object obj)
          Reads and parses an AutheticatedData from the given ASN.1 representation.
 void decode(java.io.InputStream is)
          Reads and decodes an encoded AutheticatedData from the given input stream.
 byte[] getContent()
          Returns the content.
 byte[] getEncoded()
          Returns the BER encoding of this AuthenticatedData object as byte array.
 java.io.InputStream getInputStream()
          Returns an InputStream from where the content data can be read.
 void setContent(byte[] content)
          Sets the content data to be authenticated.
 void setInputStream(java.io.InputStream is)
          Sets the input stream that supplies the content data to be autenticated.
 void setupMac(javax.crypto.SecretKey macKey)
          Uses the given symmetric mac key to setup the mac calculation to verify the message authentication code when parsing an AuthenticatedData object .
protected  ASN1Object toASN1Object(int blockSize)
          Returns this AutheticatedData as ASN1Object.
 boolean verifyMac()
          Verifies the message authentication code.
 
Methods inherited from class iaik.cms.AuthenticatedDataStream
addRecipientInfo, encodeCalled, getAuthenticatedAttribute, getAuthenticatedAttributes, getAuthenticatedDigest, getBlockSize, getContentType, getDigestAlgorithm, getEncapsulatedContentType, getMac, getMacAlgorithm, getMode, getOriginatorInfo, getRecipientInfo, getRecipientInfo, getRecipientInfos, getRecipientInfos, getSecurityProvider, getUnauthenticatedAttribute, getUnauthenticatedAttributes, getVersion, notifyEOF, setAuthenticatedAttributes, setBlockSize, setOriginatorInfo, setRecipientInfos, setSecurityProvider, setUnauthenticatedAttributes, setupMac, setupMac, setupMac, 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
getBlockSize, getContentType, setBlockSize, toASN1Object, toString
 

Constructor Detail

AuthenticatedData

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


AuthenticatedData

public AuthenticatedData(ObjectID contentType,
                         byte[] content,
                         AlgorithmID macAlg,
                         int macKeyLength,
                         java.security.spec.AlgorithmParameterSpec macParams,
                         int mode)
                  throws java.security.NoSuchAlgorithmException
Creates a new AuthenticatedData where the to-be-authenticated content data is supplied from an byte array. The MAC value will be computed immediately from the content.

Parameters:
contentType - the type of the authenticated content (e.g. ObjectID.cms_data)
content - 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

AuthenticatedData

public AuthenticatedData(ObjectID contentType,
                         byte[] content,
                         AlgorithmID macAlg,
                         int macKeyLength,
                         java.security.spec.AlgorithmParameterSpec macParams,
                         int mode,
                         SecurityProvider securityProvider)
                  throws java.security.NoSuchAlgorithmException
Creates a new AuthenticatedData where the to-be-authenticated content data is supplied from an byte array. The MAC value will be computed immediately from the content.

Parameters:
contentType - the type of the authenticated content (e.g. ObjectID.cms_data)
content - 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

AuthenticatedData

public AuthenticatedData(ObjectID contentType,
                         byte[] content,
                         AlgorithmID macAlg,
                         int macKeyLength,
                         java.security.spec.AlgorithmParameterSpec macParams,
                         AlgorithmID digestAlg,
                         int mode)
                  throws java.security.NoSuchAlgorithmException
Creates a new AuthenticatedData where the to-be-authenticated content data is supplied from an byte array. This constructor generates a symmetric MAC key. If the digestAlg parameter is not null authenticated attributes have to be set by calling method setAuthenticatedAttributes and the MAC value will be 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, the MAC value will be computed immediately from the content.

Parameters:
contentType - the type of the authenticated content (e.g. ObjectID.cms_data)
content - 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

AuthenticatedData

public AuthenticatedData(ObjectID contentType,
                         byte[] content,
                         AlgorithmID macAlg,
                         int macKeyLength,
                         java.security.spec.AlgorithmParameterSpec macParams,
                         AlgorithmID digestAlg,
                         int mode,
                         SecurityProvider securityProvider)
                  throws java.security.NoSuchAlgorithmException
Creates a new AuthenticatedData where the to-be-authenticated content data is supplied from an byte array. This constructor generates a symmetric MAC key. If the digestAlg parameter is not null authenticated attributes have to be set by calling method setAuthenticatedAttributes and the MAC value will be 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, the MAC value will be computed immediately from the content.

Parameters:
contentType - the type of the authenticated content (e.g. ObjectID.cms_data)
content - 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

AuthenticatedData

public AuthenticatedData(ObjectID contentType,
                         byte[] content,
                         AlgorithmID macAlg,
                         byte[] mac,
                         AlgorithmID digestAlg,
                         int mode)
                  throws java.security.NoSuchAlgorithmException
Creates an AuthenticatedData from an already calculated MAC value. No mac or digest calculation is performed. If setAuthenticatedAttributes are supplied, they already have to contain the MessageDigest attribute. Any RecipientInfo added to this AuthenticatedData object 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)
content - 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
Throws:
java.security.NoSuchAlgorithmException

AuthenticatedData

public AuthenticatedData(java.io.InputStream is)
                  throws CMSParsingException,
                         java.io.IOException
Creates an AuthenticatedData from an 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 an 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

AuthenticatedData

public AuthenticatedData(java.io.InputStream is,
                         SecurityProvider securityProvider)
                  throws CMSParsingException,
                         java.io.IOException
Creates an AuthenticatedData from an 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 an 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

decode

public void decode(ASN1Object obj)
            throws CMSParsingException
Reads and parses an AutheticatedData from the given ASN.1 representation. The ASN.1 AutheticatedData may (or may not) be wrapped into a ContentInfo.

Specified by:
decode in interface Content
Parameters:
obj - the ASN.1 AutheticatedData object
Throws:
CMSParsingException - if an error occurs while parsing the ASN.1 object

decode

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

Specified by:
decode in interface ContentStream
Overrides:
decode in class AuthenticatedDataStream
Parameters:
is - the InputStream holding an 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

setupMac

public void setupMac(javax.crypto.SecretKey macKey)
Uses the given symmetric mac 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 when verifying the mac, e.g.:

 // the input stream supplying the encoded AuthenticatedData
 InputStream encodedStream = ...;
 // parse the AuthenticatedData
 AuthenticatedData authenticatedData = new AuthenticatedData(encodedStream);
 if (authenticatedData.getMode() == AuthenticatedDataStream.EXPLICIT) {
   // in explicit mode explicitly supply the content for hash/mac computation 
   byte[] content = ...; // the content received by other means
   authenticatedData.setContent(content);
 }
 // supply the may key
 Key macKey = ...;
 autenticatedData.setupMac(macKey);
 // 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!");
 // in implicit mode get the content
 byte[] content = authenticatedData.getContent();
 

Overrides:
setupMac in class AuthenticatedDataStream
Parameters:
macKey - the temporary symmetric key that has been used to calculate the message authentication code

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:

 // the input stream supplying the encoded AuthenticatedData
 InputStream encodedStream = ...;
 // parse the AuthenticatedData
 AuthenticatedData authenticatedData = new AuthenticatedData(encodedStream);
 if (authenticatedData.getMode() == AuthenticatedDataStream.EXPLICIT) {
   // in explicit mode explicitly supply the content for hash/mac computation 
   byte[] content = ...; // the content received by other means
   authenticatedData.setContent(content);
 }
 // the recipient certificate:
 X509Certificate recipientCert = ...; 
 // the corresponding private key
 PrivateKey recipientPrivateKey = ...;
 // setup the MAC by decrypting the secret MAC key
 autenticatedData.setupMac(recipientPrivateKey, recipientCert);
 // 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!");
 // in implicit mode get the content
 byte[] content = authenticatedData.getContent();
 

Overrides:
verifyMac in class AuthenticatedDataStream
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)

getContent

public byte[] getContent()
Returns the content.

Returns:
the content as byte array

getInputStream

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

Overrides:
getInputStream in class AuthenticatedDataStream
Returns:
an InputStream for reading the content data

setInputStream

public void setInputStream(java.io.InputStream is)
Sets the input stream that supplies the content data to be autenticated. This method entirely reads the supplied stream.

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

setContent

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

Parameters:
content - the content data to authenticated

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 inherent content data. This method actually will perform the encryption of the symmetric mac key for each participated recipient.

Overrides:
toASN1Object in class AuthenticatedDataStream
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 cannot not be created

getEncoded

public byte[] getEncoded()
                  throws CMSException
Returns the BER encoding of this AuthenticatedData object as byte array. If no positive blocksize has been yet set, any inherent content data bytes (implicit mode) will be encoded as primitive definite octet string. Otherwise the encoding of the inherent data will be indefinite constructed (may be forced by using the writeTo(OutputStream os, int blockSize) method of the parent AuthenticatedDataStream class.

Returns:
the BER encoding of this AuthenticatedData
Throws:
CMSException - if an encoding error occurs

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