IAIK CMS/SMIME Toolkit Demo API Documentation
Version 6.1

demo.cms.basic
Class CMSDemo

java.lang.Object
  extended by demo.cms.basic.CMSDemo

public class CMSDemo
extends java.lang.Object

This class shows some CMS examples where the content types are wrapped into a ContentInfo.

All keys and certificates are read from a keystore created by the SetupCMSKeyStore program.

This class demonstrates how to wrap the several CMS types into ContentInfos:

Additionally, a SignedAndEncryptedData test is performed, which is a sequential combination of signed and enveloped data content types.

All sub-tests use the same proceeding: A test message is properly processed to give the requested content type object, which subsequently is encoded to be "sent" to some recipient, who parses it for the inherent structures.


Constructor Summary
CMSDemo()
          Setup the demo certificate chains.
 
Method Summary
 byte[] createAuthenticatedData(byte[] message, boolean includeAuthAttrs, int mode)
          Creates a CMS AuthenticatedData for the given message message.
 byte[] createAuthenticatedDataStream(byte[] message, boolean includeAuthAttrs, int mode)
          Creates a CMS AuthenticatedDataStream for the given message message.
 byte[] createData(byte[] message)
          Creates a CMS Data object.
 byte[] createDataStream(byte[] message)
          Creates a CMS Data object and wraps it into a ContentInfo.
 byte[] createDigestedData(byte[] message, int mode)
          Creates a CMS DigestedData object.
 byte[] createDigestedDataStream(byte[] message, int mode)
          Creates a CMS DigestedData object.
 byte[] createEncryptedData(byte[] message, iaik.asn1.structures.AlgorithmID pbeAlgorithm, char[] password)
          Creates a CMS EncryptedData message.
 byte[] createEncryptedDataStream(byte[] message, iaik.asn1.structures.AlgorithmID pbeAlgorithm, char[] password)
          Creates a CMS EncryptedDataStream message.
 byte[] createEnvelopedData(byte[] message)
          Creates a CMS EnvelopedData message and wraps it into a ContentInfo.
 byte[] createEnvelopedDataStream(byte[] message)
          Creates a CMS EnvelopedData and wraps it into a ContentInfo.
 byte[] createSignedAndEncryptedData(byte[] message)
          Creates a SignedAndEncrypted (i.e. sequential combination of SignedData and EnvelopedData) object.
 byte[] createSignedAndEncryptedDataStream(byte[] message)
          Creates a SignedAndEncrypted (i.e. sequential combination of SignedData and EnvelopedData).
 byte[] createSignedData(byte[] message, int mode)
          Creates a CMS SignedData object and wraps it into a ContentInfo.
 byte[] createSignedDataStream(byte[] message, int mode)
          Creates a CMS SignedData object ans wraps it into a ContentInfo.
 byte[] getAuthenticatedData(byte[] encoding, byte[] message, java.security.PrivateKey key, int recipientInfoIndex)
          Decrypts the encrypted MAC key for the recipient identified by its index into the recipientInfos field and uses the MAC key to verify the authenticated data.
 byte[] getAuthenticatedDataStream(byte[] encoding, byte[] message, java.security.PrivateKey key, int recipientInfoIndex)
          Decrypts the encrypted MAC key for the recipient identified by its index into the recipientInfos field and uses the MAC key to verify the authenticated data.
 byte[] getData(byte[] encoding)
          Parses a CMS Data object.
 byte[] getDataStream(byte[] data)
          Parses a CMS Data object.
 byte[] getDigestedData(byte[] encoding, byte[] message)
          Parses a CMS DigestedData object and verifies the hash value.
 byte[] getDigestedDataStream(byte[] digestedData, byte[] message)
          Parses a CMS DigestedData object and verifies the hash.
 byte[] getEncryptedData(byte[] encoding, char[] password)
          Decrypts the PBE-encrypted content of the given EncryptedData object using the specified password and returns the decrypted (= original) message.
 byte[] getEncryptedDataStream(byte[] encoding, char[] password)
          Decrypts the PBE-encrypted content of the given EncryptedData object using the specified password and returns the decrypted (= original) message.
 byte[] getEnvelopedData(byte[] encoding, java.security.PrivateKey privateKey, int recipientInfoIndex)
          Decrypts the encrypted content of the given EnvelopedData object for the specified recipient and returns the decrypted (= original) message.
 byte[] getEnvelopedDataStream(byte[] encoding, java.security.PrivateKey privateKey, int recipientInfoIndex)
          Decrypts the encrypted content of the given EnvelopedData object for the specified recipient and returns the decrypted (= original) message.
 byte[] getSignedAndEncryptedData(byte[] encoding)
          Recovers the original message and verifies the signature.
 byte[] getSignedAndEncryptedDataStream(byte[] in)
          Recovers the original message and verifies the signature.
 byte[] getSignedData(byte[] encoding, byte[] message)
          Parses a CMS SignedData object and verifies the signatures for all participated signers.
 byte[] getSignedDataStream(byte[] signedData, byte[] message)
          Parses a CMS SignedData object and verifies the signatures for all participated signers.
static void main(java.lang.String[] argv)
          Starts the CMS content type implementation tests.
 void start()
          Tests the CMS content type implementations Data, EnvelopedData, SignedData, DigestedData, EncryptedData.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

CMSDemo

public CMSDemo()
        throws java.io.IOException
Setup the demo certificate chains. Keys and certificate are retrieved from the demo KeyStore.

Throws:
java.io.IOException - if an file read error occurs
Method Detail

createDataStream

public byte[] createDataStream(byte[] message)
                        throws iaik.cms.CMSException,
                               java.io.IOException
Creates a CMS Data object and wraps it into a ContentInfo.

Parameters:
message - the message to be sent, as byte representation
Returns:
the encoded ContentInfo containing the Data object just created
Throws:
iaik.cms.CMSException - if the Data object cannot be created
java.io.IOException - if an I/O error occurs

getDataStream

public byte[] getDataStream(byte[] data)
                     throws iaik.cms.CMSException,
                            java.io.IOException
Parses a CMS Data object.

Parameters:
data - the encoded ContentInfo holding the Data
Returns:
the inherent message as byte array
Throws:
iaik.cms.CMSException - if an parsing exception occurs
java.io.IOException - if an I/O error occurs

createEnvelopedDataStream

public byte[] createEnvelopedDataStream(byte[] message)
                                 throws iaik.cms.CMSException,
                                        java.io.IOException
Creates a CMS EnvelopedData and wraps it into a ContentInfo.

Parameters:
message - the message to be enveloped, as byte representation
Returns:
the encoded ContentInfo containing the EnvelopedData object just created
Throws:
iaik.cms.CMSException - if the EnvelopedData object cannot be created
java.io.IOException - if an I/O error occurs

getEnvelopedDataStream

public byte[] getEnvelopedDataStream(byte[] encoding,
                                     java.security.PrivateKey privateKey,
                                     int recipientInfoIndex)
                              throws iaik.cms.CMSException,
                                     java.io.IOException
Decrypts the encrypted content of the given EnvelopedData object for the specified recipient and returns the decrypted (= original) message.

Parameters:
encoding - the encoded ContentInfo containing an EnvelopedData object
privateKey - the private key to decrypt the message
recipientInfoIndex - the index into the RecipientInfo array to which the specified private key belongs
Returns:
the recovered message, as byte array
Throws:
iaik.cms.CMSException - if the message cannot be recovered
java.io.IOException - if an I/O error occurs

createSignedDataStream

public byte[] createSignedDataStream(byte[] message,
                                     int mode)
                              throws iaik.cms.CMSException,
                                     java.io.IOException
Creates a CMS SignedData object ans wraps it into a ContentInfo.

Parameters:
message - the message to be signed, as byte representation
mode - the mode indicating whether to include the content (SignedDataStream.IMPLICIT) or not (SignedDataStream.EXPLICIT)
Returns:
the encoding of the ContentInfo holding the SignedData object just created
Throws:
iaik.cms.CMSException - if the SignedData object cannot be created
java.io.IOException - if an I/O error occurs

getSignedDataStream

public byte[] getSignedDataStream(byte[] signedData,
                                  byte[] message)
                           throws iaik.cms.CMSException,
                                  java.io.IOException
Parses a CMS SignedData object and verifies the signatures for all participated signers.

Parameters:
signedData - the ContentInfo with inherent SignedData, as BER encoded byte array
message - the the message which was transmitted out-of-band (explicit signed)
Returns:
the inherent message as byte array, or null if there is no message included into the supplied SignedData object
Throws:
iaik.cms.CMSException - if any signature does not verify
java.io.IOException - if an I/O error occurs

createSignedAndEncryptedDataStream

public byte[] createSignedAndEncryptedDataStream(byte[] message)
                                          throws iaik.cms.CMSException,
                                                 java.io.IOException
Creates a SignedAndEncrypted (i.e. sequential combination of SignedData and EnvelopedData).

Parameters:
message - the message to be signed and encrypted, as byte representation
Returns:
the encoded ContentInfo holding the signed and encrypted message object just created
Throws:
iaik.cms.CMSException - if the the SignedData or EnvelopedData object cannot be created
java.io.IOException - if an I/O error occurs

getSignedAndEncryptedDataStream

public byte[] getSignedAndEncryptedDataStream(byte[] in)
                                       throws iaik.cms.CMSException,
                                              java.io.IOException
Recovers the original message and verifies the signature.

Parameters:
in - the encoded CMS object
Returns:
the recovered message, as byte array
Throws:
iaik.cms.CMSException - if the message cannot be recovered
java.io.IOException - if an I/O error occurs

createDigestedDataStream

public byte[] createDigestedDataStream(byte[] message,
                                       int mode)
                                throws iaik.cms.CMSException,
                                       java.io.IOException
Creates a CMS DigestedData object.

Parameters:
message - the message to be digested, as byte representation
Returns:
the encoded ContentInfo containing the DigestedData object just created
Throws:
iaik.cms.CMSException - if the DigestedData object cannot be created
java.io.IOException - if an I/O error occurs

getDigestedDataStream

public byte[] getDigestedDataStream(byte[] digestedData,
                                    byte[] message)
                             throws iaik.cms.CMSException,
                                    java.io.IOException
Parses a CMS DigestedData object and verifies the hash.

Parameters:
digestedData - the encoded ContentInfo holding a DigestedData object
message - the the message which was transmitted out-of-band
Returns:
the inherent message as byte array, or null if there is no message included into the supplied DigestedData object
Throws:
iaik.cms.CMSException - if any signature does not verify
java.io.IOException - if an I/O error occurs

createEncryptedDataStream

public byte[] createEncryptedDataStream(byte[] message,
                                        iaik.asn1.structures.AlgorithmID pbeAlgorithm,
                                        char[] password)
                                 throws iaik.cms.CMSException,
                                        java.io.IOException
Creates a CMS EncryptedDataStream message.

The supplied content is PBE-encrypted using the specified password.

Parameters:
message - the message to be encrypted, as byte representation
pbeAlgorithm - the PBE algorithm to be used
password - the password
Returns:
the DER encoding of the ContentInfo holding the EncryptedData object just created
Throws:
iaik.cms.CMSException - if the EncryptedData object cannot be created
java.io.IOException - if an I/O error occurs

getEncryptedDataStream

public byte[] getEncryptedDataStream(byte[] encoding,
                                     char[] password)
                              throws iaik.cms.CMSException,
                                     java.io.IOException
Decrypts the PBE-encrypted content of the given EncryptedData object using the specified password and returns the decrypted (= original) message.

Parameters:
encoding - the encoded ContentInfo holding an EncryptedData object
password - the password to decrypt the message
Returns:
the recovered message, as byte array
Throws:
iaik.cms.CMSException - if the message cannot be recovered
java.io.IOException - if an I/O error occurs

createAuthenticatedDataStream

public byte[] createAuthenticatedDataStream(byte[] message,
                                            boolean includeAuthAttrs,
                                            int mode)
                                     throws iaik.cms.CMSException,
                                            java.io.IOException
Creates a CMS AuthenticatedDataStream for the given message message.

Attention: This AuthenticatedData demo uses RSA as key management technique. In practice (see RFC 5652) a key management technique that provides data origin authentication should be used like, for instance, Static-Static Diffie-Hellman when both the originator and recipient public keys are bound to appropriate identities in X.509 certificates, see, for instance, AuthenticatedDataDemo.

Parameters:
message - the message to be authenticated, as byte representation
includeAuthAttrs - whether to include authenticated attributes
mode - the mode indicating whether to include the content (AuthenticatedDataStream.IMPLICIT) or not (AuthenticatedDataStream.EXPLICIT)
Returns:
the BER encoding of the AuthenticatedData object, wrapped in a ContentInfo
Throws:
iaik.cms.CMSException - if the AuthenticatedData object cannot be created
java.io.IOException - if an I/O error occurs

getAuthenticatedDataStream

public byte[] getAuthenticatedDataStream(byte[] encoding,
                                         byte[] message,
                                         java.security.PrivateKey key,
                                         int recipientInfoIndex)
                                  throws iaik.cms.CMSException,
                                         java.io.IOException
Decrypts the encrypted MAC key for the recipient identified by its index into the recipientInfos field and uses the MAC key to verify the authenticated data.

This way of decrypting the MAC key and verifying the content may be used for any type of RecipientInfo (KeyTransRecipientInfo, KeyAgreeRecipientInfo, KEKRecipientInfo), but requires to know at what index of the recipientInfos field the RecipientInfo for the particular recipient in mind can be found. If the recipient in mind uses a RecipientInfo of type KeyAgreeRecipientInfo some processing overhead may take place because a KeyAgreeRecipientInfo may contain encrypted mac keys for more than only one recipient; since the recipientInfoIndex only specifies the RecipientInfo but not the encrypted mac key -- if there are more than only one -- repeated decryption runs may be required as long as the decryption process completes successfully.

Attention: This AuthenticatedData demo uses RSA as key management technique. In practice (see RFC 5652) a key management technique that provides data origin authentication should be used like, for instance, Static-Static Diffie-Hellman when both the originator and recipient public keys are bound to appropriate identities in X.509 certificates, see, for instance, AuthenticatedDataDemo.

Parameters:
encoding - the BER encoded ContentInfo holding the AuthenticatedData object
message - the content message, if transmitted by other means (explicit mode)
key - the key to decrypt the mac key
recipientInfoIndex - the index of the right RecipientInfo to which the given key belongs
Returns:
the verified message, as byte array
Throws:
iaik.cms.CMSException - if the authenticated data cannot be verified
java.io.IOException - if a stream read/write error occurs

createData

public byte[] createData(byte[] message)
                  throws iaik.cms.CMSException
Creates a CMS Data object.

Parameters:
message - the message to be sent, as byte representation
Returns:
the DER encoded ContentInfo holding the Data object just created
Throws:
iaik.cms.CMSException - if the Data object cannot be created

getData

public byte[] getData(byte[] encoding)
               throws iaik.cms.CMSException,
                      java.io.IOException
Parses a CMS Data object.

Parameters:
encoding - the DER encoded ContentInfo holding with inherent Data
Returns:
the inherent message as byte array
Throws:
iaik.cms.CMSException - if an parsing exception occurs
java.io.IOException - if an I/O related error occurs

createEnvelopedData

public byte[] createEnvelopedData(byte[] message)
                           throws iaik.cms.CMSException
Creates a CMS EnvelopedData message and wraps it into a ContentInfo.

Parameters:
message - the message to be enveloped, as byte representation
Returns:
the DER encoded ContentInfo holding the EnvelopedData object just created
Throws:
iaik.cms.CMSException - if the EnvelopedData object cannot be created

getEnvelopedData

public byte[] getEnvelopedData(byte[] encoding,
                               java.security.PrivateKey privateKey,
                               int recipientInfoIndex)
                        throws iaik.cms.CMSException,
                               java.io.IOException
Decrypts the encrypted content of the given EnvelopedData object for the specified recipient and returns the decrypted (= original) message.

Parameters:
encoding - the DER encoded ContentInfo holding an EnvelopedData
privateKey - the private key to decrypt the message
recipientInfoIndex - the index into the RecipientInfo array to which the specified private key belongs
Returns:
the recovered message, as byte array
Throws:
iaik.cms.CMSException - if the message cannot be recovered
java.io.IOException

createSignedData

public byte[] createSignedData(byte[] message,
                               int mode)
                        throws iaik.cms.CMSException
Creates a CMS SignedData object and wraps it into a ContentInfo.

Parameters:
message - the message to be signed, as byte representation
mode - the mode indicating whether to include the content (SignedDataStream.IMPLICIT) or not (SignedDataStream.EXPLICIT)
Returns:
the DER encoded ContentInfo holding the SignedData object just created
Throws:
iaik.cms.CMSException - if the SignedData object cannot be created

getSignedData

public byte[] getSignedData(byte[] encoding,
                            byte[] message)
                     throws iaik.cms.CMSException,
                            java.io.IOException
Parses a CMS SignedData object and verifies the signatures for all participated signers.

Parameters:
encoding - the ContentInfo with inherent SignedData object, as DER encoding
message - the the message which was transmitted out-of-band (explicit signed)
Returns:
the inherent message as byte array, or null if there is no message included into the supplied SignedData object
Throws:
iaik.cms.CMSException - if any signature does not verify
java.io.IOException - if an I/O error occurs

createSignedAndEncryptedData

public byte[] createSignedAndEncryptedData(byte[] message)
                                    throws iaik.cms.CMSException
Creates a SignedAndEncrypted (i.e. sequential combination of SignedData and EnvelopedData) object.

Parameters:
message - the message to be signed and encrypted, as byte representation
Returns:
the DER encoded ContentInfo holding the signed and encrypted message object just created
Throws:
iaik.cms.CMSException - if the the SignedData or EnvelopedData object cannot be created

getSignedAndEncryptedData

public byte[] getSignedAndEncryptedData(byte[] encoding)
                                 throws iaik.cms.CMSException,
                                        java.io.IOException
Recovers the original message and verifies the signature.

Parameters:
encoding - the DER encoded ContentInfo holding a SignedAndEnryptedData object
Returns:
the recovered message, as byte array
Throws:
iaik.cms.CMSException - if the message cannot be recovered
java.io.IOException - if an I/O error occurs

createDigestedData

public byte[] createDigestedData(byte[] message,
                                 int mode)
                          throws iaik.cms.CMSException
Creates a CMS DigestedData object.

Parameters:
message - the message to be digested, as byte representation
Returns:
the DigestedData wrapped into a ContentInfo, as DER encoding
Throws:
iaik.cms.CMSException - if the DigestedData object cannot be created

getDigestedData

public byte[] getDigestedData(byte[] encoding,
                              byte[] message)
                       throws iaik.cms.CMSException,
                              java.io.IOException
Parses a CMS DigestedData object and verifies the hash value.

Parameters:
encoding - the ContentInfo holding a DigestedData, as DER encoding
message - the the message which was transmitted out-of-band (explicit digested)
Returns:
the message
Throws:
iaik.cms.CMSException - if some parsing exception occurs
java.io.IOException - if an I/O error occurs

createEncryptedData

public byte[] createEncryptedData(byte[] message,
                                  iaik.asn1.structures.AlgorithmID pbeAlgorithm,
                                  char[] password)
                           throws iaik.cms.CMSException
Creates a CMS EncryptedData message.

The supplied content is PBE-encrypted using the specified password.

Parameters:
message - the message to be encrypted, as byte representation
pbeAlgorithm - the PBE algorithm to be used
password - the password
Returns:
the EncryptedData object wrapped into a ContentInfo, as DER encoding
Throws:
iaik.cms.CMSException - if the EncryptedData object cannot be created

getEncryptedData

public byte[] getEncryptedData(byte[] encoding,
                               char[] password)
                        throws iaik.cms.CMSException,
                               java.io.IOException
Decrypts the PBE-encrypted content of the given EncryptedData object using the specified password and returns the decrypted (= original) message.

Parameters:
encoding - the DER encoded ContentInfo holding the EncryptedData object
password - the password to decrypt the message
Returns:
the recovered message, as byte array
Throws:
iaik.cms.CMSException - if the message cannot be recovered
java.io.IOException - if an I/O error occurs

createAuthenticatedData

public byte[] createAuthenticatedData(byte[] message,
                                      boolean includeAuthAttrs,
                                      int mode)
                               throws iaik.cms.CMSException,
                                      java.io.IOException
Creates a CMS AuthenticatedData for the given message message.

Attention: This AuthenticatedData demo uses RSA as key management technique. In practice (see RFC 5652) a key management technique that provides data origin authentication should be used like, for instance, Static-Static Diffie-Hellman when both the originator and recipient public keys are bound to appropriate identities in X.509 certificates, see, for instance, AuthenticatedDataDemo.

Parameters:
message - the message to be authenticated, as byte representation
includeAuthAttrs - whether to include authenticated attributes
mode - the mode indicating whether to include the content (AuthenticatedData.IMPLICIT) or not (AuthenticatedDatam.EXPLICIT)
Returns:
the BER encoding of the AuthenticatedData object, wrapped in a ContentInfo
Throws:
iaik.cms.CMSException - if the AuthenticatedData object cannot be created
java.io.IOException - if an I/O error occurs

getAuthenticatedData

public byte[] getAuthenticatedData(byte[] encoding,
                                   byte[] message,
                                   java.security.PrivateKey key,
                                   int recipientInfoIndex)
                            throws iaik.cms.CMSException,
                                   java.io.IOException
Decrypts the encrypted MAC key for the recipient identified by its index into the recipientInfos field and uses the MAC key to verify the authenticated data.

This way of decrypting the MAC key and verifying the content may be used for any type of RecipientInfo (KeyTransRecipientInfo, KeyAgreeRecipientInfo, KEKRecipientInfo), but requires to know at what index of the recipientInfos field the RecipientInfo for the particular recipient in mind can be found. If the recipient in mind uses a RecipientInfo of type KeyAgreeRecipientInfo some processing overhead may take place because a KeyAgreeRecipientInfo may contain encrypted mac keys for more than only one recipient; since the recipientInfoIndex only specifies the RecipientInfo but not the encrypted mac key -- if there are more than only one -- repeated decryption runs may be required as long as the decryption process completes successfully.

Attention: This AuthenticatedData demo uses RSA as key management technique. In practice (see RFC 5652) a key management technique that provides data origin authentication should be used like, for instance, Static-Static Diffie-Hellman when both the originator and recipient public keys are bound to appropriate identities in X.509 certificates, see, for instance, AuthenticatedDataDemo.

Parameters:
encoding - the DER encoded ContentInfo holding the AuthenticatedData object
message - the content message, if transmitted by other means (explicit mode)
key - the key to decrypt the mac key
recipientInfoIndex - the index of the right RecipientInfo to which the given key belongs
Returns:
the verified message, as byte array
Throws:
iaik.cms.CMSException - if the authenticated data cannot be verified
java.io.IOException - if a IO read/write error occurs

start

public void start()
Tests the CMS content type implementations Data, EnvelopedData, SignedData, DigestedData, EncryptedData. An additional SignedAndEncryptedData test sequentially combines signed and enveloped data.


main

public static void main(java.lang.String[] argv)
                 throws java.lang.Exception
Starts the CMS content type implementation tests.

Throws:
java.lang.Exception - if some error occurs

IAIK CMS/SMIME Toolkit Demo API Documentation
Version 6.1

v6.1
(c) 2002 IAIK, (c) 2003 - 2025 SIC