iaik.smime
Class SMimeParameters

java.lang.Object
  extended by iaik.smime.SMimeParameters

public class SMimeParameters
extends java.lang.Object

Class for deciding whether to use old or new S/MIME content types and defining a specific canonicalization scheme. For switching between old/new content types use method useNewContentTypes(boolean newType). Calling this method only is meaningful when creating a new message. If newType is set to false the old types are used (application/x-pkcs7-signature respectively application/x-pkcs7-mime). If newType is set to false the new types are used (application/pkcs7-signature respectively application/pkcs7-mime).

Per default the new types are used. For changing the types, useNewContentTypes has to be called before creating a SignedContent or EncryptedContent object, e.g.:

 //switch to new content types
 SMimeParameters.useNewContentTypes(true);
 //create a SignedContent
 boolean implicit = ...;
 SignedContent sc = new SignedContent(implicit, SignedContent.SIGNED_DATA);
 
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.

For setting a new Canonicalizer to be used for all canonicalization, use method setCanonicalizer.


Method Summary
static boolean deleteTempDirectory()
          Tries to delete the "iaiksmime" sub-directory (and all its contents) of the directory that has been set as temp directory for temporarily writing message contents to it.
static Canonicalizer getCanonicalizer()
          Gets the canonicalizer used the message canonicalization.
static boolean getCheckForSMimeParts()
          Looks if SMimeMultipart/SMimeBodyPart control is turned on or off when building the content of a signed message.
static javax.activation.CommandMap getCommandMap()
          Gets the Mailcap CommandMap to be used.
static int getMaxBufSize()
          Gets the maximum buf size to be used for buffering message contents.
static boolean getNewContentTypes()
          Returns whether new or old content types are used when creating a new S/Mime message.
static java.lang.String getTempDirectory()
          Gets the name of the directory to be used for temporary message contents storage.
static void setCanonicalizer(Canonicalizer canonicalizer)
          Sets the canonicalizer to be used message canonicalization.
static void setCheckForSMimeParts(boolean checkForSMimeParts)
          Turns on/off control to use SMimeMultiparts and SMimeBodyParts insteadof MimeMultipatrs and MimeBodyParts when building the content for a signed message.
static void setCommandMap(javax.activation.MailcapCommandMap commandMap)
          Sets the Mailcap CommandMap to be used.
static void setDataHandlerCommandMap(javax.activation.DataHandler dataHandler)
          Sets the registered Mailcap CommandMap for the given DataHandler.
static void setTempDirectory(java.lang.String tmpDir, int maxBufSize)
          Specifies a temporary directory in the File System to which message contents shall be temporarily written.
static void useNewContentTypes(boolean newType)
          Decides whether to use old or new S/MIME content types.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

useNewContentTypes

public static void useNewContentTypes(boolean newType)
Decides whether to use old or new S/MIME content types. This method only is meaningful when creating a new message. If newType is set to false the old types are used (application/x-pkcs7-signature respectively application/x-pkcs7-mime). If newType is set to false the new types are used (application/pkcs7-signature respectively application/pkcs7-mime). Per default the new types are used.

Parameters:
newType - true for using new types, false if not

getNewContentTypes

public static boolean getNewContentTypes()
Returns whether new or old content types are used when creating a new S/Mime message.

Returns:
true if new types (application/pkcs7-signature respectively application/pkcs7-mime), and false if the old types (application/x-pkcs7-signature respectively application/x-pkcs7-mime) are used

setCanonicalizer

public static void setCanonicalizer(Canonicalizer canonicalizer)
Sets the canonicalizer to be used message canonicalization.

Parameters:
canonicalizer - the canonicalizer to be used

getCanonicalizer

public static Canonicalizer getCanonicalizer()
Gets the canonicalizer used the message canonicalization.

Returns:
the canonicalizer used for canonicalization

setCheckForSMimeParts

public static void setCheckForSMimeParts(boolean checkForSMimeParts)
Turns on/off control to use SMimeMultiparts and SMimeBodyParts insteadof MimeMultipatrs and MimeBodyParts when building the content for a signed message. Especially when creating a signed message of type multipart/signed ("clear-signed") care has to be taken to properly canonicalize -- in particular text -- messages to give the same unique representation on the sender side where the signature is created and on the recipient side where the signature is verified.
The content of a signed message may be composed of MimeMultiparts consiting theirselves of several MimeBodyParts. To ensure that these body parts are canonicalized, they have to be modelled as SMimeBodyPart objects rather than using plain MimeBodyParts. When building a multipart entity from several body parts, the SMimeBodyParts have to be inserted into a SMimeMultipart object instead of using a plain MimeMultipart.
To avoid verification problems due to usage of not canonicalized parts, IAIK-CMS by default checks if SMimeMultiparts and SMimeBodyParts are used when creating a signed message. An exception is thrown if only plain MimeBodyParts and MimeMultiparts are used. However, when signing an already canonicalized entity (e.g. the content of a message just parsed) this check for SMimeMultiparts/SMimeBodyParts may not be required. In this case it might give some processing overhead to convert any MimeMultipart and MimeBodyPart to the required SMimeMultipart respectively SMimeBodyPart. For that reason it is possible to turn off the SMimePart check for a particular SignedContent, SMimeMultipart and/or SMimeBodyPart object or generally disable the SMimeBodyPart check throughout the whole application environment. When choosing the latter option by calling
 SMimeParameters.setCheckForSMimeParts(false);
 
take care to continue to use SMimeBodyParts and SMimeMultiparts when signing a newly created yet not canoinicalized content.

Parameters:
checkForSMimeParts - whether to turn on/off SMimePart checking

getCheckForSMimeParts

public static boolean getCheckForSMimeParts()
Looks if SMimeMultipart/SMimeBodyPart control is turned on or off when building the content of a signed message. Especially when creating a signed message of type multipart/signed ("clear-signed") care has to be taken to properly canonicalize -- in particular text -- messages to give the same unique representation on the sender side where the signature is created and on the recipient side where the signature is verified.
The content of a signed message may be composed of MimeMultiparts consiting theirselves of several MimeBodyParts. To ensure that these body parts are canonicalized, they have to be modelled as SMimeBodyPart objects rather than using plain MimeBodyParts. When building a multipart entity from several body parts, the SMimeBodyParts have to be inserted into a SMimeMultipart object instead of using a plain MimeMultipart.
To avoid verification problems due to usage of not canonicalized parts, IAIK-CMS by default checks if SMimeMultiparts and SMimeBodyParts are used when creating a signed message. An exception is thrown if only plain MimeBodyParts and MimeMultiparts are used. However, when signing an already canonicalized entity (e.g. the content of a message just parsed) this check for SMimeMultiparts/SMimeBodyParts may not be required. In this case it might give some processing overhead to convert any MimeMultipart and MimeBodyPart to the required SMimeMultipart respectively SMimeBodyPart. For that reason it is possible to turn off the SMimePart check for a particular SignedContent, SMimeMultipart and/or SMimeBodyPart object or generally disable the SMimeBodyPart check throughout the whole application environment. When choosing the latter option by calling
 SMimeParameters.setCheckForSMimeParts(false);
 
take care to continue to use SMimeBodyParts and SMimeMultiparts when signing a newly created yet not canoinicalized content.

Returns:
true if SMimePart control is enabled, false if it is disabled

setTempDirectory

public static void setTempDirectory(java.lang.String tmpDir,
                                    int maxBufSize)
Specifies a temporary directory in the File System to which message contents shall be temporarily written. If a temporary directory is specified, a sub directory &qout;iaiksmime" will be created and used to temporarily store message contents while parsing the message. This maybe useful when parsing big messages and accessing the content of a signed or encrypted message by calling method getContent. Note that alternatively you may use method getContentInputStream. Note also that temporary files may hold decrypted content of an encrypted message. Generally each temporary content file is deleted after it is no more required. However, if some temporary file(s) cannot be deleted for some reason you may call method deleteTempDirectory when you exit your application which tries to delete all temporary files (and the "iaiksmime" sub-directory itself) that have not been deleted so far. Anyway you may check the temporary directory after program execution if all temporary files (and the temporary directory) have been successfully deleted.
Using temporary files for handling large message contents may only be useful if the message has not already been read into memory, for instance, if you use a SharedFileInputStream and read the message from a file. If you, e.g., download a message from a POP server, the JavaMail POP3 provider already buffers the message in memory. Thus in this case it it might bring no benefit to use temporary file storage.

The maxBufSize parameter can be used to specify the maximum internal buffer size to be used. Only message contents of size > maxBufSize will be temporarily written to a file. Message contents <= maxBufSize will be internally buffered.
The default size is (64 * 1024) meaning that contents up to 64 kb will be internally buffered, but contents of more than 64 kb bytes will be written to a temporary file.

Parameters:
tmpDir - the name of a directory to be used for temporarily message contents storage; if null message contents will not be temporarily stored into files
maxBufSize - the max buf size (in bytes) to be used (default 64 * 1024); if <=0 the default size of 64 * 1024 will be used

getTempDirectory

public static java.lang.String getTempDirectory()
Gets the name of the directory to be used for temporary message contents storage. If a temporary directory is specified it will be used to temporarily store message contents while parsing the message. This maybe useful when parsing big messages and accessing the content of a signed or encrypted message by calling method getContent. Note that alternatively you may use method getContentInputStream. Note also that temporary files may hold decrypted content of an encrypted message. Generally each temporary content file is deleted after it is no more required. However, if some temporary file(s) cannot be deleted for some reason you may call method deleteTempDirectory when you exit your application which tries to delete all temporary files (and the "iaiksmime" sub-directory itself) that have not been deleted so far. Anyway you may check the temporary directory after program execution if all temporary files (and the temporary directory) have been successfully deleted.
Using temporary files for handling large message contents may only be useful if the message has not already been read into memory, for instance, if you use a SharedFileInputStream and read the message from a file. If you, e.g., download a message from a POP server, the JavaMail POP3 provider already buffers the message in memory. Thus in this case it it might bring no benefit to use temporary file storage.

Returns:
tmpDir the name of a directory used for temporarily message contents storage, or null if message contents is not temporarily stored into files
See Also:
setTempDirectory(String, int)

getMaxBufSize

public static int getMaxBufSize()
Gets the maximum buf size to be used for buffering message contents. Only meaningful if a temporary directory is set for temporarily buffering message contents into files. In this case only message contents of sice > maxBufSize will be temporarily written to a file. Message contents <= maxBufSize will be internally buffered.
The default size is (64 * 1024) meaning that contents up to 64 kb will be internally buffered, but contents of more than 64 kb bytes will be written to a temporary file.

Returns:
the max size (in bytes) of the internal buffer to be used when message contents shall be buffered to files

deleteTempDirectory

public static boolean deleteTempDirectory()
Tries to delete the "iaiksmime" sub-directory (and all its contents) of the directory that has been set as temp directory for temporarily writing message contents to it.

Generally each temporary content file is deleted after it is no more required. However, if some temporary file(s) cannot be deleted you may call this method when you exit your application to delete all temporary files in the "<tmpDir>/iaiksmime" directory that have not been deleted so far. After having deleted all files this method also tries to delete the "iaiksmime" sub-directory itself. Anyway you may check the temporary directory after program execution if all temporary files (and the temporary directory) have been successfully deleted.

Returns:
true if the "<tmpDir>/iaiksmime" sub-directory (and all it files) have been successfully deleted; false if the directory has not been deleted (or if no temp directory has been specified so far)

setCommandMap

public static void setCommandMap(javax.activation.MailcapCommandMap commandMap)
Sets the Mailcap CommandMap to be used.

This method allows to set a MailcapCommandCap for locale use without changing the system-wide default command map. A MailcapCommandMap set by this method is used only within the scope of this IAIK S/MIME library. However, you will have to be aware about the following guidelines:

  1. Set the locale CommandMap, e.g.:
            MailcapCommandMap mc = new MailcapCommandMap();
            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");
            SMimeParameters.setCommandMap(mc);
            
  2. Use msg.setDataHandler() instead of msg.setContent() for setting the crypto content of a message. Set the CommandMap for the DataHandler, e.g.:
            MimeMessage msg = ...;
            SignedContent signedContent = ...;
            ...
            DataHandler dh = new DataHandler(signedContent, signedContent.getContentType());
            SMimeParameters.setCommandMap(dh);
            msg.setDataHandler(dh);
            
  3. Use part.getDataHandler() instead of part.getContent() when parsing the content of a part. Set the CommandMap for the DataHandler, e.g.:
            ...
            Object o = ...;
            if (o instanceof Part) {
              System.out.println("CONTENT-TYPE: "+((Part)o).getContentType());
              DataHandler dh = ((Part)o).getDataHandler();
              SMimeParameters.setCommandMap(dh);
              o = dh.getContent();
            }
            ...
            

Parameters:
commandMap - the Mailcap CommandMap to be used

getCommandMap

public static javax.activation.CommandMap getCommandMap()
Gets the Mailcap CommandMap to be used.

Returns:
the Mailcap CommandMap to be used, or null if no Mailcap CommandMap has been set

setDataHandlerCommandMap

public static void setDataHandlerCommandMap(javax.activation.DataHandler dataHandler)
Sets the registered Mailcap CommandMap for the given DataHandler.
If no Mailcap CommandMap has been registered, no CommandMap is set for the given DataHandler.

Parameters:
dataHandler - the DataHandler for which to set the Mailcap CommandMap

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