iaik.smime
Class AuthEncryptedContent

java.lang.Object
  extended by iaik.smime.SMimeContent
      extended by iaik.smime.EncryptedContent
          extended by iaik.smime.AuthEncryptedContent
All Implemented Interfaces:
CryptoContent

public class AuthEncryptedContent
extends EncryptedContent

This class can be used to create and parse authenticated encrypted S/MIME messages in combination with the JavaMailTM API (javax.mail).

S/MIME (Secure/Multipurpose Internet Mail Extensions, RFC 8551) enhances the MIME standard(s) about the following cryptographic security services for electronic messaging applications: authentication, message integrity, and non-repudiation of origin (using digital signatures), and data confidentiality (using encryption).

This class supports the creation, handling and parsing of authenticated encrypted S/MIME messages in combination with the javax.mail architecture. Encrypting (enveloping) a MIME message provides data confidentiality, authenticated encrypting (enveloping) a MIME message adds data integrity protection, but does not provide proof of origination (which can be achieved when signing a message).

S/MIME v4 (Secure/Multipurpose Internet Mail Extensions) specifies the application/pkcs7-mime (smime-type "authEnveloped-data") type for authenticated data enveloping (encrypting). The whole (prepared) MIME entity to be authenticated enveloped is encrypted and packed into a CMS (RFC 5083) object of type AuthEnvelopedData which subsequently is inserted into an application/pkcs7-mime MIME entity. The smime-type parameter for enveloped messages is "authEnveloped-data", the file extension is ".p7m" (see S/MIME Version 4 Message Specification). The "Content-" headers of a sample message would look like:

 Content-Type: application/pkcs7-mime; smime-type=authEnveloped-data;
     name="smime.p7m"
 Content-Transfer-Encoding: base64
 Content-Disposition: attachment; filename="smime.p7m"

 MIIDWQYLKoZIhvcNAQ...

 
For creating a new AuthEncryptedContent to be sent, first use a proper constructor, and subsequently supply the content by means of a setContent, setText, or setDataHandler method. Recipients are added by calling a proper addRecipient method, depending on which CMS key management technique to be used. When setting the content encryption algorithm by means of the setEncryptionAlgorithm method, optionally the key length for the temporary symmetric content encryption key to be generated may be specified. The S/MIME Version 4 Message Specification recommends AES-256 GCM to be used as content encryption algorithm.

Before actually sending the message with the authenticated encrypted content, the setHeaders method shall be called for properly updating some message headers (Content-Transfer-Encoding, Content-Disposition). When not calling method setHeaders JavaMail may run method writeTo twice to itself determine the content transfer encoding to be used.

Typical usage (when using RSA key transport):

 // create a MimeMessage for the current mail session
 MimeMessage msg = new MimeMessage(session);
 ...
 // create an EncryptedContent object
 AuthEncryptedContent ec = new AuthEncryptedContent();
 // set the content to be authenticated encrypted
 ec.setContent(...);
 // the encryption certificate of the recipient:
 X509Certificate recipientCertificate = ...;
 ec.addRecipient(recipientCertificate, AlgorithmID.rsaEncryption);
 // the sender also wants to be able to decrypt the message
 X509Certificate senderCertificate = ...;
 ec.addRecipient(senderCertificate, AlgorithmID.rsaEncryption);
 // we use the AES-GCM algorithm
 AlgorithmID contentEncryptionAlg = (AlgorithmID)AlgorithmID.aes256_GCM.clone();
 int keyLength = 256;
 ec.setEncryptionAlgorithm(contentEncryptionAlg, keyLength);
 // set the AuthEncryptedContent as message content
 msg.setContent(ec, ec.getContentType());
 // update message headers
 ec.setHeaders(msg);
 // send message
 Transport.send(msg);
 
A recipient uses a proper decryptSymmetricKey method for decrypting the encrypted content encryption key with her/his (private) key encryption key, and subsequently reads the content thereby decrypting it and verifying the integrity of data, e.g.:
 // the message to be parsed
 MimeMessage msg = ...;
 // get the AuthEncryptedContent
 AuthEncryptedContent ec = (AuthEncryptedContent)msg.getContent();
 // private key of the recipient
 PrivateKey recipientKey = ...;
 // certificate of the recipient 
 ec.decryptSymmetricKey(recipientKey, 0);
 // get the (decrypted, original) content
 Object content = ec.getContent();
 ...
 
The decryptSymmetricKey method used in the sample above requires that the recipient knows the index of the RecipientInfo that belongs to her/his key. Alternatively you may use the recipient certificate or her/his KeyIdentifier to find the right RecipientInfo and decrypt the symmetric content encryption key.

For more information about the JavaMail architecture, and how to handling MIME messages, consult the JavaMail specification.

For using the IAIK-CMS S/MIME library, you also will need the following packages:

The JAF assignment between MIME-types and content handlers is done by means of a RFC 1524 mailcap file which is included in the IAIK-CMS distribution. It defines the following classes as content handlers for the corresponding MIME types:
 #
 # IAIK 'mailcap' file entries
 #
 multipart/signed;;               x-java-content-handler=iaik.smime.signed_content
 application/x-pkcs7-signature;;  x-java-content-handler=iaik.smime.signed_content
 application/x-pkcs7-mime;;       x-java-content-handler=iaik.smime.encrypted_content
 application/x-pkcs10;;           x-java-content-handler=iaik.smime.pkcs10_content
 application/pkcs7-signature;;    x-java-content-handler=iaik.smime.signed_content
 application/pkcs7-mime;;         x-java-content-handler=iaik.smime.encrypted_content
 application/pkcs10;;             x-java-content-handler=iaik.smime.pkcs10_content
 
The content handlers are registered by copying the mailcap file into the lib directory of your JDK (/lib). Alternatively you may register the IAIK-S/MIME mailcap file dynamically by using the default command map:
 String mailcapFileName = ...;
 MailcapCommandMap mc = new MailcapCommandMap(mailcapFileName);
 CommandMap.setDefaultCommandMap(mc);
 
Or you may add the IAIK mailcap entries to the default mailcap command map, e.g.:
 MailcapCommandMap mc = (MailcapCommandMap)CommandMap.getDefaultCommandMap();
 mc.addMailcap("multipart/signed;; x-java-content-handler=iaik.smime.signed_content");
 mc.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=iaik.smime.signed_content");
 mc.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=iaik.smime.encrypted_content");
 mc.addMailcap("application/pkcs7-signature;; x-java-content-handler=iaik.smime.signed_content");
 mc.addMailcap("application/pkcs7-mime;; x-java-content-handler=iaik.smime.encrypted_content");
 mc.addMailcap("application/x-pkcs10;; x-java-content-handler=iaik.smime.pkcs10_content");
 mc.addMailcap("application/pkcs10;; x-java-content-handler=iaik.smime.pkcs10_content");
 CommandMap.setDefaultCommandMap(mc);
 
For a more detailed description of mailcap handling consult the Javadoc of the Activation Framework.

When creating a new AuthEncryptedContent to be sent per default the new S/MIME content types (application/pkcs7-mime) are used. For using the old types (application/x-pkcs7-mime) call the static useNewContentTypes method of the SMimeParameters class before creating a new AuthEncryptedContent object, e.g.:

 //switch to old content types
 SMimeParameters.useNewContentTypes(false);
 //create a SignedContent
 EncryptedContent sc = new EncryptedContent();
 ...
 

See Also:
SMimeEncrypted

Constructor Summary
AuthEncryptedContent()
          Creates a new AuthEncryptedContent object.
AuthEncryptedContent(CryptoContent cryptoContent)
          Creates a new S/MIME authenticated encrypted and signed content.
AuthEncryptedContent(javax.activation.DataSource dataSource)
          Constructs an AuthEncryptedContent object from the given data source.
AuthEncryptedContent(java.io.InputStream in)
          Constructs an AuthEncryptedContent object from the given input stream.
 
Method Summary
 java.lang.String getSMimeType()
          Returns the smime-type parameter ("authEnveloped-data").
 void setAuthenticatedAttributes(Attribute[] attributes)
          Sets a set of authenticated attributes.
 void setUnauthenticatedAttributes(Attribute[] attributes)
          Sets a set of unauthenticated attributes.
static void setUseEncryptedContentInfoStream(boolean useEncryptedContentInfoStream)
          Whether to use the stream based EncryptedContentInfoStream implementation when parsing an authEnveloped-data message.
 
Methods inherited from class iaik.smime.EncryptedContent
addRecipient, addRecipient, addRecipient, addRecipient, decryptSymmetricKey, decryptSymmetricKey, decryptSymmetricKey, getContentInputStream, getDataHandler, getEncryptionAlgorithm, getOriginatorInfo, getRecipientInfoIndex, getRecipientInfos, setEncryptionAlgorithm, setEncryptionAlgorithm, setHeaders, setOriginatorInfo, setRecipients, setSMimeType, setupCipher, writeTo
 
Methods inherited from class iaik.smime.SMimeContent
getContent, getContentType, getInputStream, setBlockSize, setContent, setContent, setContentContentHeaders, setContentContentTransferEncoding, setDataHandler, setText
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

AuthEncryptedContent

public AuthEncryptedContent()
Creates a new AuthEncryptedContent object.

Use a proper setContent, setText, or setDataHandler method for supplying the content to be authenticated enveloped. Recipients are added by calling a proper addRecipient method thereby specifying the recipient certificate, and the key management algorithm to be used. When setting the content encryption algorithm by means of the setEncryptionAlgorithm method, optionally the key length may be specified. The S/MIME Version 4 Message Specification recommends AES-256 GCM to be used as content encryption algorithm. Before actually sending the Message with the encrypted content, the setHeaders method shall be called for properly updating the message headers. Typical usage (for RSA key transport):

 MimeMessage msg = new MimeMessage(session);
 ...
 AuthEncryptedContent ec = new AuthEncryptedContent();
 ec.setContent(...);
 ec.addRecipient(recipientCertificate, AlgorithmID.rsaEncryption);
 ec.setEncryptionAlgorithm(algorithm, keyLength);
 ec.setHeaders(msg);

 msg.setContent(ec, ec.getContentType());
 Transport.send(msg);
 
When using this constructor the smime-type parameter will be set to "authEnveloped-data".


AuthEncryptedContent

public AuthEncryptedContent(CryptoContent cryptoContent)
                     throws javax.mail.MessagingException
Creates a new S/MIME authenticated encrypted and signed content. When using this constructor the smime-type parameter will be set to "authEnveloped-data".

Parameters:
cryptoContent - the (signed or compressed) content to be authenticated encrypted
Throws:
if - an error occurs when setting the content
javax.mail.MessagingException

AuthEncryptedContent

public AuthEncryptedContent(javax.activation.DataSource dataSource)
                     throws java.io.IOException
Constructs an AuthEncryptedContent object from the given data source. The given data source is expected to supply a BER encoded CMS ContentInfo object holding the authenticated enveloped data. During a mail session this constructor may not be called directly. Rather it is called by a proper data content handler encrypted_content supplying the data source.

For more information on data handling using the javax.activation.DataSource for "MIME type based" data access, see the JavaBeans Activation Framework (JAF) specification.

Parameters:
dataSource - the DataSource supplying the enveloped data
Throws:
java.io.IOException - if an I/O error occurs during reading the object

AuthEncryptedContent

public AuthEncryptedContent(java.io.InputStream in)
                     throws java.io.IOException
Constructs an AuthEncryptedContent object from the given input stream. The given input stream is expected to supply a BER encoded CMS ContentInfo object holding the enveloped data.

Parameters:
in - the input stream supplying the enveloped data
Throws:
java.io.IOException - if an I/O error occurs during parsing the stream
Method Detail

setUseEncryptedContentInfoStream

public static void setUseEncryptedContentInfoStream(boolean useEncryptedContentInfoStream)
Whether to use the stream based EncryptedContentInfoStream implementation when parsing an authEnveloped-data message. (default: true).

Parameters:
useEncryptedContentInfoStream - whether to use the stream based EncryptedContentInfoStream implementation when parsing an authEnveloped-data message (default: true)

getSMimeType

public java.lang.String getSMimeType()
Returns the smime-type parameter ("authEnveloped-data").

Specified by:
getSMimeType in interface CryptoContent
Overrides:
getSMimeType in class EncryptedContent
Returns:
the smime-type parameter ("authEnveloped-data")

setAuthenticatedAttributes

public void setAuthenticatedAttributes(Attribute[] attributes)
Sets a set of authenticated attributes. These attributed will be authenticated only, but not encrypted.

Parameters:
attributes - the authenticated attributes to be set

setUnauthenticatedAttributes

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

Parameters:
attributes - the unauthenticated attributes to be set

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