Skip Headers
Oracle® Security Developer Tools Reference
10g Release 2 (10.1.2)
B15975-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

6 Oracle S/MIME

This chapter provides an overview of Oracle S/MIME, describes key features and benefits, and explains how to set up and use Oracle S/MIME.

This chapter contains these topics:

6.1 Oracle S/MIME Features and Benefits

Oracle S/MIME is a pure Java solution which provides the following features:

6.2 Setting Up Your Oracle S/MIME Environment

The Oracle Security Developer Tools are installed with Oracle Application Server in ORACLE_HOME. This section explains how to set up your environment for Oracle S/MIME. It contains these topics:

6.2.1 System Requirements for Oracle S/MIME

In order to use Oracle S/MIME, your system must have the Java Development Kit (JDK) version 1.2.2 or higher. Oracle S/MIME also requires:

If you are using POP or IMAP, be sure to download Sun's POP3 (or IMAP) Provider, which is also available at the JavaMail page.

6.2.2 Setting the CLASSPATH Environment Variable

Your CLASSPATH environment variable must contain the full path and file names to all of the required jar and class files. Make sure the following items are included in your CLASSPATH:

  • osdt_core.jar file

  • osdt_cert.jar file

  • osdt_cms.jar file

  • osdt_smime.jar file

  • Your JAF (Java Activation Framework), JavaMail, and POP3 provider installations.

Any application using the Oracle S/MIME API must have all the neccessary MIME types registered in its command map.

Some applications, specifically those reading S/MIME entries from a FileDataSource, will need to register the S/MIME file types.

6.2.2.1 Setting the CLASSPATH on Windows

To set the CLASSPATH on Windows:

  1. In your Windows Control Panel, select System.

  2. In the System Properties dialog, select the Advanced tab.

  3. Click Environment Variables.

  4. In the User Variables section, click New to add a CLASSPATH environment variable for your user profile. If a CLASSPATH environment variable already exists, select it and click Edit.

  5. Add the full path and file names for all the required jar and class files to the CLASSPATH.

    For example, your CLASSPATH might look like this:

    %CLASSPATH%;C:\ORACLE_HOME\jlib\osdt_core.jar;
    C:\ORACLE_HOME\jlib\osdt_cert.jar;
    C:\ORACLE_HOME\jlib\osdt_cms.jar;C:\ORACLE_HOME\jlib\osdt_smime.jar;
    C:\jaf-1.0.2\activation.jar;C:\javamail-1.3.1\mail.jar;
    
    
  6. Click OK.

6.2.2.2 Setting the CLASSPATH on UNIX

On UNIX, set your CLASSPATH environment variable to include the full path and file names of all of the required jar and class files. For example:

setenv CLASSPATH $CLASSPATH:$ORACLE_HOME/jlib/osdt_core.jar:\
$ORACLE_HOME/jlib/osdt_cert.jar:\
$ORACLE_HOME/jlib/osdt_cms.jar:$ORACLE_HOME/jlib/osdt_smime.jar:\
/usr/lib/jaf-1.0.2/activation.jar:/usr/lib/javamail-1.3.1/mail.jar

6.3 Developing Applications with Oracle S/MIME

This section describes selected interfaces and classes in the Oracle S/MIME API and illustrates their use. It includes these topics:

Selected methods are described as appropriate.

6.3.1 Core Classes and Interfaces

This section describes core classes and interfaces in the Oracle S/MIME API, and explains how to create and parse S/MIME objects.

6.3.1.1 The oracle.security.crypto.smime.SmimeObject Interface

The oracle.security.crypto.smime.SmimeObject interface represents an S/MIME object. Classes that implement this interface include:

  • SmimeSigned

  • SmimeEnveloped

  • SmimeMultipartSigned

  • SmimeSignedReceipt

  • SmimeCompressed

Methods in this interface include:

String generateContentType ()

Returns the content type string for this S/MIME object. For example:

"application/pkcs7-mime; smime-type=signed-data"

String generateContentType (boolean useStandardContentTypes)

If the argument is true, returns the same as generateContentType(); if false, returns old-style (Netscape) content type string. For example: "application/x-pkcs7-mime; smime-type=signed-data"

void writeTo (java.io.OutputStream os, java.lang.String mimeType)

Outputs this object to the specified output stream.

6.3.1.2 The oracle.security.crypto.smime.SmimeSignedObject Interface

The oracle.security.crypto.smime.SmimeSignedObject interface extends SmimeObject, and specifies methods common to all S/MIME signed objects, including SmimeSigned and SmimeMultipartSigned.

Methods in this interface include:

Vector getCertificates ()

Returns the list of certificates included in this S/MIME object's signed content.

Vector getCRLs ()

Returns the list of certificate revocation lists in the S/MIME object's signed content.

javax.mail.internet.MimeBodyPart getEnclosedBodyPart ()

Returns the document which was signed.

oracle.security.crypto.smime.ess.EquivalentLabels getEquivalentLabels (oracle.security.crypto.cert.X509 signerCert)

Returns the EquivalentLabels if present or null.

oracle.security.crypto.smime.ess.ESSSecurityLabel getESSSecurityLabel (oracle.security.crypto.cert.X509 signerCert)

Returns the ESSSecurityLabel if present or null.

oracle.security.crypto.smime.ess.MLExpansionHistory getMLExpansionHistory(
 oracle.security.crypto.cert.X509 signerCert)

Returns the MLExpansionHistory attribute if present or null.

oracle.security.crypto.smime.ess.ReceiptRequest getReceiptRequest(
 oracle.security.crypto.cert.X509 signerCert)

Returns the ReceiptRequest attribute if present or null.

oracle.security.crypto.smime.ess.SigningCertificate getSigningCertificate(
 oracle.security.crypto.cert.X509 signerCert)

Returns the SigningCertificate.

void verify (oracle.security.crypto.cert.CertificateTrustPolicy trustPolicy)

Returns normally if the signed contents include at least one valid signature according to the specified trust policy, otherwise throws an AuthenticationException.

void verifySignature (oracle.security.crypto.cert.X509 signerCert)

Returns normally if the signed contents contain a signature which can be validated by the given certificate, otherwise throws an AuthenticationException.

6.3.1.3 The oracle.security.crypto.smime.SmimeSigned Class

The oracle.security.crypto.smime.SmimeSigned class represents an S/MIME signed message (.implements SmimeSignedObject). You may use this class to build a new message or parse an existing one.

Constructors and methods include:

SmimeSigned (javax.mail.internet.MimeBodyPart content)

Creates a new SmimeSigned object, using the specified MIME body part for the contents to be signed.

SmimeSigned ()

Creates a new empty SmimeSigned object, which is useful for building a "certificates-only" S/MIME message.

SmimeSigned (InputStream is)

Creates a new SmimeSigned object by reading its encoding from the specified input stream.

void addSignature (oracle.security.crypto.core.PrivateKey signerKey
    oracle.security.crypto.cert.X509 signerCert,
    oracle.security.crypto.core.AlgorithmIdentifier digestAlgID)

Adds a signature to the message, using the specified private key, certificate, and message digest algorithm.

void addSignature (oracle.security.crypto.core.PrivateKey signerKey,
 oracle.security.crypto.cert.X509 signerCert,
 oracle.security.crypto.core.AlgorithmIdentifier digestAlgID,
      java.util.Date timeStamp)

Adds a signature to the message, including a time stamp.

void addSignature (oracle.security.crypto.core.PrivateKey signerKey,
    oracle.security.crypto.cert.X509 signerCert,
    oracle.security.crypto.core.AlgorithmIdentifier digestAlgID,
    SmimeCapabilities smimeCaps)

Adds a signature to the message, including S/MIME capabilities.

javax.mail.internet.MimeBodyPart getEnclosedBodyPart ()

Returns the MIME body part that was signed.

To build a new message, use any of these three constructors:

// Create a new S/MIME Signed Message
SmimeSigned sig = new SmimeSigned();

//         -OR-
// Create a new S/MIME Signed Message with a specified MIME body part
MimeBodyPart bp = new MimeBodyPart();
bp.setText("Hello from SendSignedMsg!");
SmimeSigned sig1 = new SmimeSigned(bp);

//         -OR-
// Create a new S/MIME Signed Message with a specified MIME body part 
// and a flag switching comression on or off
MimeBodyPart bp = new MimeBodyPart();
bp.setText("Hello from SendSignedMsg!");
boolean useCompression = true;
SmimeSigned sig2 = new SmimeSigned(bp, useCompression);

To parse a message, use the constructor that takes a java.io.InputStream:

InputStream is = Input stream containing message to be parsed
SmimeSigned sig = new SmimeSigned(is);

6.3.1.4 The oracle.security.crypto.smime.SmimeEnveloped Class

The oracle.security.crypto.smime.SmimeEnveloped class represents an S/MIME enveloped message (implements SmimeObject), and may be used to build a new message or parse an existing one.

Constructors and methods include:

SmimeEnveloped (javax.mail.internet.MimeBodyPart content,
    oracle.security.crypto.core.AlgorithmIdentifier contentEncryptionAlgID)

Creates a new SmimeEnveloped object from the specified MIME body part, using the specified content encryption algorithm.

SmimeEnveloped (InputStream is)

Creates a new SmimeEnveloped object by reading its encoding from the specified input stream.

void addRecipient (oracle.security.crypto.cert.X509 cert)

Encrypts the message for the recipient using the given public key certificate.

byte[] getEncryptedContent ()

Returns the contents without decrypting.

javax.mail.internet.MimeBodyPart getEnclosedBodyPart (
 oracle.security.crypto.core.PrivateKey recipientKey,
 oracle.security.crypto.cert.X509 recipientCert)

Returns the MIME body part for the recipient specified by recipientCert, after decryption using the given recipient private key.

Use the following code to build a new message:

// Create a new S/MIME Enveloped Message with a specified MIME body part and a specified content
// encryption algorithm
MimeBodyPart bp = new MimeBodyPart();
bp.setText("Hello from SendSignedMsg!");
AlgorithmIdentifier algId = AlgID.aes256_CBC;
SmimeEnveloped env = new SmimeEnveloped(bp, algId);

To parse a message, use the constructor that takes a java.io.InputStream:

InputStream is = Input stream containing message to be parsed
    SmimeEnveloped env = new SmimeEnveloped(is);

6.3.1.5 The oracle.security.crypto.smime.SmimeMultipartSigned Class

The oracle.security.crypto.smime.SmimeMultipartSigned class represents an S/MIME multi-part signed message. A multipart signed message is intended for email clients that are not MIME-aware. This class can be used to build a new message or parse an existing one.

Constructors and methods include:

SmimeMultipartSigned (javax.mail.internet.MimeBodyPart bodyPart,
    oracle.security.crypto.core.AlgorithmIdentifier digestAlgID)

Creates a new SmimeMultipartSigned message, with the specified MIME body part and message digest algorithm.

void addBodyPart (javax.mail.BodyPart part)

Inherited from javax.mail.Multipart, adds the specified body part to this SmimeMultipartSigned object. (See the javax.mail API documentation for more details.)

void addSignature (oracle.security.crypto.core.PrivateKey signerKey,
    oracle.security.crypto.cert.X509 signerCert)

Adds a signature to the message, using the specified private key and certificate.

void addSignature (oracle.security.crypto.core.PrivateKey signerKey,
    oracle.security.crypto.cert.X509 signerCert, java.util.Date timeStamp)

Adds a signature to the message, using the specified private key and certificate plus a time stamp.

void addSignature (oracle.security.crypto.core.PrivateKey signerKey,
    oracle.security.crypto.cert.X509 signerCert, java.util.Date timeStamp,
    SmimeCapabilities smimeCaps)

Adds a signature to the message, using the specified private key and certificate, plus S/MIME capabilities.

javax.mail.internet.MimeBodyPart getEnclosedBodyPart ()

Returns the MIME body part that was signed.

Use the following code to build a new message:

// Create a new S/MIME Multipart Signed Message with a specified 
// MIME body part and a specified digest algorithm
MimeBodyPart bp = new MimeBodyPart();
bp.setText("Hello from SendSignedMsg!");
AlgorithmIdentifier algId = AlgID.sha1;
SmimeMutlipartSigned sig = new SmimeMultipartSigned(bp, algId);

To parse a message, use the constructor that takes a javax.activation.DataSource:

DataSource ds = Data source containing message to be parsed
SmimeMultipartSigned sig = new SmimeMultipartSigned(ds);

6.3.1.6 The oracle.security.crypto.smime.SmimeSignedReceipt Class

The oracle.security.crypto.smime.SmimeSignedReceipt class represents an S/MIME wrapped and signed receipt. You may use this class to build a new message or parse an existing one.

To build a new message, use any of these four constructors:

// Create a new S/MIME wrapped and signed receipt with the specified receipt,
// the specified digest of the message's signed attributes
// and the addresses of the receipt recipients
ESSReceipt receipt = ESS receipt to include in message
byte [] msgSigDigest = Digest of signed attributes to be included in message
Address [] addresses = Addresses of receipt recipients
SmimeSignedReceipt sig = new SmimeSigned(receipt, msgSigDigest, addresses);

 //         -OR-
// Create a new S/MIME wrapped and signed receipt 
// with a specified S/MIME Signed Message containing the receipt 
SmimeSignedObject sso = S/MIME signed message containing receipt
SmimeSignedReceipt sig1 = new SmimeSignedReceipt(sso);

//         -OR-
// Create a new S/MIME wrapped and signed receipt with a 
// specified S/MIME Signed Message containing the receipt,
// the signer's certificate and the addresses of the receipt recipients
SmimeSignedObject sso1 = S/MIME signed message containing receipt
X509 signerCert = The message signer's certificate
Address [] addresses1 = Addresses of receipt recipients
SmimeSignedReceipt sig2 = new SmimeSignedReceipt(sso1, signerCert, addresses1); 

//         -OR-

// Create a new S/MIME wrapped and signed receipt with a 
// specified S/MIME Signed Message containing the receipt,
// the signer's certificate, the addresses of the receipt recipients and
// a specified MLExpansionHistory attribute.
SmimeSignedObject sso1 = S/MIME signed message containing receipt
X509 signerCert = The message signer's certificate
Address [] addresses1 = Addresses of receipt recipients
MLExpansionHistory mlExpansionHistory = The MLExpansionHistory attribute
SmimeSignedReceipt sig2 = 
    new SmimeSignedReceipt(sso1, signerCert, addresses1, mlExpansionHistory);

To parse a message, use the constructor that takes a java.io.InputStream:

InputStream is = Input stream containing message to be parsed
SmimeSignedReceipt sig = new SmimeSignedReceipt(is);

6.3.1.7 The oracle.security.crypto.smime.SmimeCompressed Class

The oracle.security.crypto.smime.SmimeCompressed class represents an S/MIME compressed message as defined in RFC 3274. You can use this class to build a new message or parse an existing one.


Note:

A link to RFC 3274 is available in Appendix A, "References".

Use the following code to build a new message:

// Create a new S/MIME Compressed Message with a specified MIME body part
MimeBodyPart bp = new MimeBodyPart();
bp.setText("Hello from SendSignedMsg!");
SmimeCompressed comp = new SmimeCompressed(bp, algId);

//           -OR-
// Create a new S/MIME Compressed Message with a specified MIME body part
// and a specified compression algorithm
MimeBodyPart bp = new MimeBodyPart();
bp.setText("Hello from SendSignedMsg!");
AlgorithmIdentifier algId = Smime.id_alg_zlibCompress;
SmimeCompressed comp = new SmimeCompressed(bp, algId);

To parse a message, use the constructor that takes a java.io.InputStream:

InputStream is = Input stream containing message to be parsed
SmimeCompressed comp1 = new SmimeCompressed(is);

6.3.2 Supporting Classes and Interfaces

This section describes Oracle S/MIME supporting classes and interfaces.

6.3.2.1 The oracle.security.crypto.smime.Smime Interface

The oracle.security.crypto.smime.Smime interface defines constants such as algorithm identifiers, content type identifiers, and attribute identifiers.

6.3.2.2 The oracle.security.crypto.smime.SmimeUtils Class

The oracle.security.crypto.smime.SmimeUtils class contains static utility methods.

Methods of this class include:

public static FileDataSource createFileDataSource (File file,
    String contentTypeHeader)
public static FileDataSource createFileDataSource (String name,
    String contentTypeHeader)

For transparent handling of multipart or multipart/signed S/MIME types, use these methods instead of directly instantiating a javax.activation.FileDataSource.


Note:

The default javax.activation.FileDataSource included with JAF 1.0.1 does not handle multipart MIME boundaries when used with Javamail 1.1.x.

6.3.2.3 The oracle.security.crypto.smime.MailTrustPolicy Class

The oracle.security.crypto.smime.MailTrustPolicy class implements a certificate trust policy (oracle.security.crypto.cert.CertificateTrustPolicy) used to verify signatures on signed S/MIME objects.

6.3.2.4 The oracle.security.crypto.smime.SmimeCapabilities Class

The oracle.security.crypto.smime.SmimeCapabilities class encapsulates a set of capabilities for an S/MIME object including, for example, the supported encryption algorithms.

A useful method of this class is:

void addCapability(oracle.security.crypto.asn1.ASN1ObjectID capabilityID)

which adds the capability with the specified object ID to this set of S/MIME capabilities.

6.3.2.5 The oracle.security.crypto.smime.SmimeDataContentHandler Class

The oracle.security.crypto.smime.SmimeDataContentHandler class provides the DataContentHandler for S/MIME content types. It implements javax.activation.DataContentHandler.

6.3.2.6 The oracle.security.crypto.smime.ess Package

The oracle.security.crypto.smime.ess package contains the following classes:

Table 6-1 Classes in the oracle.security.crypto.smime.ess Package

Class Description
ContentHints Content hints
ContentReference Content reference
EquivalentLabels ESS EquivalentLabels
ESSCertID Represents the ESSCertID of a certificate which is used in the Signing Certificate Attribute
ESSSecurityLabel An ESS security label
GeneralNames The GeneralNames type, which is a SEQUENCE of the GeneralName type defined in RFC 2459 (a link to RFC 2459 is available in Appendix A, "References")
MLData Represents the MLData element which is used in the MLExpansionHistory attribute
MLExpansionHistory Mailing list expansion history
ReceiptRequest An ESS Receipt Request
ReceiptRequest.AllOrFirstTier A 'AllOrFirstTier' is a part of the 'ReceiptsFrom' field of a ReceiptRequest
SigningCertificate An ESS Signing Certificate

6.3.3 Using the Oracle S/MIME Classes

This section describes how to use the Oracle S/MIME SDK to work with multi-part signed messages, create and open digital envelopes, and implement Enhanced Security Services (ESS). It covers these topics:

6.3.3.1 Using the Abstract Class SmimeObject

SmimeObject is an abstract class representing a fundamental S/MIME message content entity. Subclasses of SmimeObject include SmimeSigned, SmimeEnveloped, and SmimeMultipartSigned.

One of the characteristics of SmimeObject implementations is that they "know their own MIME type" -- that is, they implement the generateContentType method. Thus, to place such an object inside a MIME message or body part, follow the same outline that was used in the SmimeSigned example:

  1. Create the object.

  2. Invoke generateContentType on the object to obtain a MIME type.

  3. Pass the object, together with the generated content type, to the setContent method of a MimeMessage or MimeBodyPart object.

The SmimeObject class provides another version of the generateContentType method, which takes a boolean parameter. When given true as a parameter, generateContentType behaves exactly as in the case of no argument. When given false as a parameter, generateContentType returns the older MIME types required by certain mail clients, including Netscape Communicator 4.0.4. Specifically:

  • "application/pkcs7-mime" becomes "application/x-pkcs7-mime"

  • "application/pkcs7-signature" becomes "application/x-pkcs7-signature"

6.3.3.2 Signing Messages

Create a signed message, or signed MIME body part, using these steps:

  1. Prepare an instance of MimeBodyPart which contains the content you wish to sign. This body part may have any content-type desired. In the following example we create a "text/plain" body part:

    MimeBodyPart doc = new MimeBodyPart();
    doc.setText("Example signed message.");
    
    
  2. Create an instance of SmimeSigned using the constructor which takes the MimeBodyPart created earlier as argument.

    SmimeSigned sig = new SmimeSigned (doc);
    
    
  3. Add all desired signatures. For each signature, you need to specify a private key, a certificate for the matching public key, and a message digest algorithm. For example:

    sig.addSignature (signatureKey, signatureCert, AlgID.sha1);
    

    In this example we specified the SHA-1 message digest algorithm. Alternatively, we could have specified the MD5 algorithm by passing AlgID.md5 as the argument.

  4. Place your SmimeSignedObject into a MimeMessage or MimeBodyPart, as appropriate. For example:

    MimeMessage m = new MimeMessage();
    m.setContent (sig, sig.generateContentType());
    
    

    or

    MimeBodyPart bp = new MimeBodyPart();
    bp.setContent (sig, sig.generateContentType());
    
    

The generateContentType method used in these examples returns a string identifying the appropriate MIME type for the object, which in this case is:

application/pkcs7-mime; smime-type=signed-data

With these simple steps, you can now transport the MIME message, place the body part containing S/MIME content into a MIME multipart object, or perform any other operation appropriate for these objects. See the JavaMail API for details.

6.3.3.3 Creating "Multipart/Signed" Entities

The SmimeMultipartSigned class provides an alternative way to create signed messages. These messages use the "multipart/signed" mime type instead of "application/pkcs7-mime". The advantage is that the content of the resulting message is readable with non-MIME enabled mail clients, although such clients will not, of course, be able to verify the signature.

Creating a multi-part/signed message is slightly different from creating a signed message. For example, to send a multi-part/signed text message:

// create the content text as a MIME body part
MimeBodyPart bp = new MimeBodyPart();
bp.setText("Example multipart/signed message.");
// the constructor takes the signature algorithm
SmimeMultipartSigned sig = new SmimeMultipartSigned(bp, AlgID.sha1);
// sign the content
sig.addSignature(signerKey, signerCert); 
// place the content in a MIME message
MimeMessage msg = new MimeMessage();
msg.setContent(sig, sig.generateContentType());

The reason for identifying the message digest in the SmimeMultipartSigned constructor is that, unlike the case of application/pkcs7-mime signed data objects, multipart/signed messages require that all signatures use the same message digest algorithm.

The generateContentType method returns the following string:

multipart/signed; protocol="application/pkcs7-signature"

6.3.3.4 Creating Digital Envelopes

An S/MIME digital envelope (encrypted message) is represented by the SmimeEnveloped class. This is a MIME entity which is formed by encrypting a MIME body part with some symmetric encryption algorithm (eg, Triple-Des or RC2) and a randomly generated session key, then encrypting the session key with the RSA public key for each intended message recipient.

In the following example, doc is an instance of MimeBodyPart, which is to be wrapped in an instance of SmimeEnveloped, and recipientCert is the recipient's certificate.

SmimeEnveloped env = new SmimeEnveloped(doc, Smime.dES_EDE3_CBC);
env.addRecipient (recipientCert);

Any number of envelope recipients may be added by making repeated calls to addRecipient.

6.3.3.5 Creating "Certificates-Only" Messages

It is possible to create an S/MIME signed-data object that contains neither content nor signatures; rather, it contains just certificates, or CRLs, or both. Such entities can be used as a certificate transport mechanism. They have the special content type:

application/pkcs7-mime; smime-type=certs-only

Here is an example:

X509 cert1, cert2;
SmimeSigned certBag = new SmimeSigned();
certBag.addCertificate(cert1);
certBag.addCertificate(cert2);

Now you can pass certBag to an appropriate setContent method. When generateContentType is invoked on certBag, it will automatically return a content type with the correct "certs-only" value for the smime-type parameter.

6.3.3.6 Reading Messages

The basic JavaMail API technique for extracting Java objects from MIME entities is to invoke the getContent() method on an instance of MimePart, an interface which models MIME entities and is implemented by the MimeMesage and MimeBodyPart classes.

The getContent method consults the currently installed default command map - which is part of the JavaBeans Activities Framework - to find a data content handler for the given MIME type, which is responsible for converting the content of the MIME entity into a Java object of the appropriate class.

The mailcap file provided with your distribution can be used to install the SmimeDataContentHandler class, which serves as a data content handler for the following types:

Content Type Returns Instance Of
application/pkcs7-mime SmimeSigned or Smime Enveloped
application/pkcs7-signature SmimeSigned
application/pkcs10 oracle.security.crypto.cert.CertificateRequest
multipart/signed SmimeMultipartSigned

6.3.3.7 Authenticating Signed Messages

Once you obtain an instance of SmimeSigned or SmimeMutlipartSigned from getContent(), you will naturally want to verify the attached signatures. To explain the available options for signature verification, it is neccessary to discuss the structure of an S/MIME signed message.

The content of a signed S/MIME message is a CMS object of type SignedData. Such an object itself has a content - the document to which the signatures are applied - which is the text encoding of a MIME entity. It also contains from zero to any number of signatures, and, optionally, a set of certificates, CRLs, or both, which the receiving party may use to validate the signatures.

The SmimeSigned and SmimeMultipartSigned classes encapsulate all of this information. They provide two authentication methods: verifyingSignature and verify.

To verify a particular signature with a certificate already in possession, ignoring any certificate and CRLs attached by the signer, use verifySignature. For example:

SmimeSignedObject sig =
    (SmimeSignedObject)msg.getContent(); // msg is a Message
sig.verifySignature(cert, msg.getFrom()); // cert is an X509 object

If verification fails, the verifySignature method throws either an UnknownSignerException or an AuthenticationException ; otherwise, it returns normally.

Use verify to verify that the content contains at least one valid signature; that is, there exists a valid certificate chain, starting from a trusted root CA, and terminating in a certificate for the private key which generated the signature. This method makes use of the attached certificate and CRLs in order to follow certificate chains.

For example, given a trusted certificate authority (CA) certificate already in hand:

TrustedCAPolicy trusts = new TrustedCAPolicy();
// if true, need CRL for each cert in chain
trusts.setRequireCRLs(false); 
// caCert is an X509 object with CA cert
trusts.addTrustedCA(caCert); 
SmimeSignedObject sig = (SmimeSignedObject)msg.getContent();
sig.verify(trusts, msg.getFrom());

Like verifySignature, verify throws an AuthenticationException if the signature cannot be verified; otherwise it returns normally. In either case you can recover the document that was signed, which is itself a MIME entity, by invoking getEnclosedBodyPart():

MimeBodyPart doc = sig.getEnclosedBodyPart();

6.3.3.8 Opening Digital Envelopes (Encrypted Messages)

An S/MIME digital envelope consists of:

  • A protected MIME body part, which has been encrypted with a symmetric key algorithm (for example, DES or RC2)

  • A randomly generated content encryption key

  • Information that allows one or more intended recipients to decrypt the content

For each recipient, this information consists of the content encryption key, itself encrypted with the recipient's public key.

To obtain the encrypted content from an SmimeEnveloped object, you need the recipient's private key and the corresponding certificate; the certificate is used as an index into the recipient information table contained in the envelope's data structure.

For example:

SmimeEnveloped env = (SmimeEnveloped)msg.getContent();
MimeBodyPart mbp = env.getEnclosedBodyPart(privKey, cert)
// privKey is a PrivateKey object
// cert is an X509 object

Passing the private key and the certificate to the getEnclosedBodyPart method returns the decrypted content as an instance of MimeBodyPart.

The getContent method can now be invoked on the MimeBodyPart object to retrieve the (now decrypted) content. This content may be a String (in the case of an encrypted text message), or any other object such as an SmimeSigned.

6.3.3.9 Adding Enhanced Security Services (ESS)

You can add the ESS services ReceiptRequests, SecurityLabels, and SigningCertificates to an S/MIME signed message by adding them to the signedAttributes of a signature.

// Create a Signed Message
SmimeSigned sig = new SmimeSigned(); 
    AttributeSet signedAttributes = new AttributeSet();

Receipt Request (oracle.security.crypto.smime.ess.ReceiptRequest)

To request a signed receipt from the recipient of a message, add a receiptRequest attribute to the signedAttributes field while adding a signature:

ReceiptRequest rr = new ReceiptRequest();
.........
signedAttributes.addAttribute(Smime.id_aa_receiptRequest, rr);

Security Label (oracle.security.crypto.smime.ess.ESSSecurityLabel)

To attach a security label to a message, add an ESSSecurityLabel attribute to the signedAttributes field while adding a signature:

ESSSecurityLabel sl = new ESSSecurityLabel();
    .........
    signedAttributes.addAttribute(Smime.id_aa_securityLabel, sl);

Signing Certificate (oracle.security.crypto.smime.ess.SigningCertificate)

To attach a signing certificate to a message, add a SigningCertificate attribute to the signedAttributes field while adding a signature:

SigningCertificate sc = new SigningCertificate();
    .........
    signedAttributes.addAttribute(Smime.id_aa_signingCertificate, sc);

Use the signedAttributes while adding a signature:

sig.addSignature(signerKey, signerCert, digestAlgID, signedAttributes);

The ESS signed receipts are generated using the SmimeSignedReceipt class in the oracle.security.crypto.smime package, in a manner similar to using a SmimeSigned class, except that the content that is signed is an oracle.security.crypto.cms.ESSReceipt object.

6.3.3.10 Processing Enhanced Security Services (ESS)

An S/MIME signed receipt must have correctly set content type parameters for the data content handlers to recognize it. If the content type parameters are missing, the signed receipt is treated as a signed message.

6.4 Oracle S/MIME Java API Reference

The Oracle S/MIME Java API Reference (Javadoc) is located at:

Oracle S/MIME Java API Reference