5 Oracle S/MIME

Oracle S/MIME API is a java solution, which includes classes, interfaces, and methods to work with S/MIME objects.

We provide a survey of the classes and features of Oracle S/MIME:

5.1 Oracle S/MIME Features and Benefits

Oracle S/MIME API is a java solution with support for X.509 certificate and private key encryption.

It has the following features:

  • Full support for X.509 Version 3 certificates with extensions, including certificate parsing and verification

  • Support for X.509 certificate chains in PKCS #7 and PKCS #12 formats

  • Private key encryption using PKCS #5, PKCS #8, and PKCS #12

  • An integrated ASN.1 library for input and output of data in ASN.1 DER/BER format

5.2 Setting Up Your Oracle S/MIME Environment

The Oracle Security Developer Tools are installed with Oracle WebLogic Server in ORACLE_HOME. In order to use Oracle S/MIME, your system must have the Java Development Kit (JDK) version 1.6 or higher. Your CLASSPATH environment variable must contain the full path and file names to all of the required jar and class files.

Oracle S/MIME also requires:

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

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.

    Note:

    Java Activation Framework is included in JDK 1.6.

For example:

setenv CLASSPATH $CLASSPATH:
$ORACLE_HOME/modules/oracle.osdt_11.1.1/osdt_core.jar:
$ORACLE_HOME/modules/oracle.osdt_11.1.1/osdt_cert.jar:
$ORACLE_HOME/modules/oracle.osdt_11.1.1/osdt_cms.jar:
$ORACLE_HOME/modules/oracle.osdt_11.1.1/osdt_smime.jar:
/usr/lib/jaf-1.1/activation.jar:
/usr/lib/javamail-1.4.1/mail.jar

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.

5.3 Developing Applications with Oracle S/MIME

You can develop applications by using the core and supporting classes and interfaces in Oracle S/MIME API and the methods therein.

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

5.3.1 Core Classes and Interfaces of Oracle S/MIME

Oracle S/MIME API consists of multiple 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.

Core classes and interfaces include:

5.3.1.1 Using 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.

5.3.1.2 Using 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
(java.security.cert.X509Certificate signerCert)

Returns the EquivalentLabels if present or null.

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

Returns the ESSSecurityLabel if present or null.

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

Returns the MLExpansionHistory attribute if present or null.

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

Returns the ReceiptRequest attribute if present or null.

oracle.security.crypto.smime.ess.SigningCertificate getSigningCertificate(
 java.security.cert.X509Certificate 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 (java.security.cert.X509Certificate signerCert)

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

The method can throw a SignatureException, if no signature exists corresponding to the given certificate.

5.3.1.3 Using 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 (java.security.PrivateKey signerKey,
    java.security.cert.X509Certificate 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 (java.security.PrivateKey signerKey,
 java.security.cert.X509Certificate signerCert,
 oracle.security.crypto.core.AlgorithmIdentifier digestAlgID,
      java.util.Date timeStamp)

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

void addSignature (java.security.PrivateKey signerKey,
    java.security.cert.X509Certificate 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 compression 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);
5.3.1.4 Using 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 (java.security.cert.X509Certificate 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 (
 java.security.PrivateKey recipientKey,
 java.security.cert.X509Certificate 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);
5.3.1.5 Using 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 at http://www.oracle.com/technetwork/java/index-138643.html for more details.)

void addSignature (java.security.PrivateKey signerKey,
    java.security.cert.X509Certificate signerCert)

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

void addSignature (java.security.PrivateKey signerKey,
    java.security.cert.X509Certificate signerCert, java.util.Date timeStamp)

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

void addSignature (java.security.PrivateKey signerKey,
    java.security.cert.X509Certificate 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);
5.3.1.6 Using 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
X509Certificate 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
X509Certificate 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);
5.3.1.7 Using 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 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);

//           -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);

5.3.2 Supporting Classes and Interfaces

Oracle S/MIME contains supporting interface that defines constants such as algorithm identifiers, content type identifiers, and attribute identifiers. It contains supporting classes that contains static utility methods, verify signatures on signed S/MIME objects, and encapsulate capabilities for an S/MIME object.

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

5.3.2.1 Using 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.

5.3.2.2 Using 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.

5.3.2.3 Using 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.

5.3.2.4 Using 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.

5.3.2.5 Using 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.

5.3.2.6 Using the oracle.security.crypto.smime.ess Package

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

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

Class Description

ContentHints

Content hints

ContentReference

Content reference

EquivalentLabels

ESS EquivalentLabels

ESSSecurityLabel

An ESS security label

MLData

Represents the MLData element which is used in the MLExpansionHistory attribute

MLExpansionHistory

Mailing list expansion history

ReceiptRequest

An ESS Receipt Request

ReceiptRequest.AllOrFirstTier

An 'AllOrFirstTier' is a part of the 'ReceiptsFrom' field of a ReceiptRequest

SigningCertificate

An ESS Signing Certificate

5.3.3 Using the Oracle S/MIME Classes

You can use the Oracle S/MIME SDK to work with multi-part signed messages, sign messages and authenticate signed messages, create and open digital envelopes, and implement Enhanced Security Services (ESS).

It covers these topics:

5.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

  • SmimeMultipartSigned

  • SmimeSignedReceipt, and

  • SmimeCompressed

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"

5.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.

5.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"
5.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);

You may add any number of envelope recipients by making repeated calls to addRecipient.

5.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

This example shows how to create a signed-data object:

X509Certificate 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.

5.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

5.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 X509Certificate object

If verification fails, the verifySignature method throws either a SignatureException 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 X509Certificate 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();
5.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 X509Certificate 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.

5.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();
5.3.3.9.1 Requesting a Signed Receipt with ESS

oracle.security.crypto.smime.ess.ReceiptRequest supports the receipt request service.

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);
5.3.3.9.2 Attaching a Security Label with ESS

oracle.security.crypto.smime.ess.ESSSecurityLabel provides the security label service.

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);
5.3.3.9.3 Attaching a Signing Certificate with ESS

oracle.security.crypto.smime.ess.SigningCertificate enables you to attach a signing certificate.

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.

5.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.

5.4 The Oracle S/MIME Java API Reference

The Oracle Fusion Middleware Java API Reference for Oracle Security Developer Tools guide explains the classes and methods available in Oracle S/MIME.