Share via


Rights Management for E-Mail Messages

This topic describes how to create restricted-permission e-mail messages that can be opened with the Rights Management Add-on for Internet Explorer. A restricted-permission message can only be viewed by the intended recipient and is subject to restrictions on printing, editing, or copying much like a rights-managed HTML file. Some e-mail clients such as Microsoft Office Outlook 2003 can interact directly with restricted-permission messages. Because the restricted-permission message is included as an e-mail attachment, e-mail clients that cannot interact directly with a restricted-permission message allow the attachment to be opened with the Rights Management Add-on.

Note   Although Outlook 2003 can open restricted-permission messages, the specific file format described in this document cannot be opened by Outlook 2003. These files can be opened with the Rights Management Add-on.

 

This topic contains the following sections.

  • Generating the Message Compound File
    • Message Storage Information Stream
    • Text or HTML Message Stream
    • HTML Representation of Text Stream
    • Attachment List Storage
    • Attachment Information Stream
    • Attachment Storages
    • Creating an Example Message
  • Protecting the Message
    • Compress the Message
    • Encrypt the Message
    • Store the Encrypted Message
    • Write the Data Spaces Storage
    • Compress the Resulting Compound File
    • Prefix and Save the File
  • Related topics

Generating the Message Compound File

The message in a rights-protected message is a compound file with a specific set of stream and storage that the Rights Management Add-on can use. The compound file contains as many as three streams: a message storage information stream for internal use, a text or HTML message stream, and a stream containing a copy of the text stream wrapped in HTML. Additionally, the message can contain attachments with an optional attachment list storage.

The message compound file contains: message storage info stream, text or HTML message stream, HTML representation of text stream, rich text message stream, message format stream, and the attachments storage. The attachments storage contains an attachments information stream, and one or more attachment storages. The following image shows the structure of the message compound file.

Each of the streams and storages in the message compound file is described in detail in the following sections.

Message Storage Information Stream

This required stream is named RpmsgStorageInfo. It is reserved for use by e-mail clients. Do not place any data in this stream.

Text or HTML Message Stream

This required stream is named BodyPT-HTML. It contains the text or HTML that makes up the e-mail message, depending on the message format. Although required, this stream is not used if the BodyPTAsHTML stream is present.

HTML Representation of Text Stream

This stream, required when the message format is text, is named BodyPTAsHTML. For text messages, the text itself is placed in BodyPT-HTML, and the same text inside an HTML element must be placed in the BodyPTAsHTML stream. When this stream is present, the Rights Management Add-on displays its contents as the e-mail message. The Rights Management Add-on cannot display a text message if it is not represented in this stream as HTML.

Attachment List Storage

This optional storage is named Attachment List. It describes any attachments for this e-mail. The attachment list storage contains a stream named Attachment Info and one or more e-mail attachment storages.

Many of the fields in the following streams are length-prefixed strings. The length-prefixed strings used in this file begin with an unsigned 1-byte value indicating the length, in characters, of the string or wide-character string. If the length of the string exceeds 254 characters, then this 1-byte value is set to 255 and it is followed by an unsigned 2-byte value that indicates the length of the string in characters. Length prefixed strings cannot exceed 65535 characters in length. You can specify 0x00 to indicate a length-prefixed string with zero characters.

Attachment Information Stream

The attachment information stream indicates the number and names of e-mail attachments. The attachment information stream contains: attachment count (4-bytes), a names length (1 or 3-bytes), and a pipe delimited list of attachment names. The following image shows the structure of the attachment information stream.

The first value in this stream is a 4-byte integer specifying the number of e-mail attachments. The next value is a length-prefixed, wide-character stream. This string contains the attachment names delimited by the pipe character. Each name in this list must correspond to the name of a substorage of the attachment list storage.

Attachment Storages

Each e-mail attachment is contained in its own substorage of the attachment list storage. The name of an attachment storage is one of the names specified in the attachment information stream. An attachment storage contains two streams: an attachment description stream and an attachment contents stream.

The attachment description stream is named AttachDesc. The following table shows the fields in the attachment description stream along with their type, whether or not they are used by the Rights Management Add-on, and a brief description.

Note   You must include fields even if they are not used by the Rights Management Add-on. Software components that read or update this stream must be prepared for the reserved, length-prefixed strings to have values other than 0x00.

 

Field Type Used by Rights Management Add-on Description
Identifier Unsigned 16-bit integer Yes Must be 0x202 or 0x203.
Reserved Length-prefixed string No Reserved. Set to 0x00.
Reserved Length-prefixed string No Reserved. Set to 0x00.
Reserved Length-prefixed string No Reserved. Set to 0x00.
Reserved Length-prefixed string No Reserved. Set to 0x00.
Reserved Length-prefixed string No Reserved. Set to 0x00.
Reserved Length-prefixed string No Reserved. Set to 0x00.
Reserved 64-bit value No Reserved. Set to 0x00.
Reserved 64-bit value No Reserved. Set to 0x00.
Attach method Unsigned 32-bit integer Yes Must be 0x01.
Content ID Length-prefixed, wide-character string Yes For inline attachments, this is an ID that can be used to reference this attachment.For example, if the content ID is MyContent then the body of the message could contain the following.
<img src="cid:MyContent" />
Reserved Length-prefixed, wide-character string No Reserved. Set to 0x00.
Path name Length-prefixed, wide-character string Yes Reserved. Set to 0x00.
Reserved Length-prefixed, wide-character string No Reserved. Set to 0x00.
Display name Length-prefixed, wide-character string Yes Name displayed in e-mail client.
Reserved Length-prefixed, wide-character string No Reserved. Set to 0x00.
Reserved Length-prefixed, wide-character string No Reserved. Set to 0x00.
Extension Length-prefixed, wide-character string Yes Attachment file name extension. Must begin with a period.

 

The attachment contents stream is named AttachContents. It contains the text or binary data of the attachment.

Creating an Example Message

The following example shows how to generate a simple compound file message with no attachments.

HRESULT hResult = NULL;
IStorage *pStorage = NULL;
IStorage *pAttachmentListStorage = NULL;
IStorage *pAttachmentStorage = NULL;
IStream  *pStream = NULL;

// Create a compound file to store an e-mail message.
hResult = StgCreateStorageEx( L"test.msg", 
                              STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_CREATE, 
                              STGFMT_STORAGE, 
                              0,              
                              NULL,           
                              0,              
                              IID_IStorage,   
                              (void **)&pStorage); 
CHECK_STG_ERROR("StgCreateStorageEx",hResult);

// Write an empty stream named RpmsgStorageInfo.
hResult = pStorage->CreateStream( L"RpmsgStorageInfo", 
                                  STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
                                  0,          
                                  0,         
                                  &pStream);  
CHECK_STG_ERROR("IStorage::CreateStream",hResult);
pStream->Release();

// Write a stream named BodyPT-HTML containing the HTML message.
hResult = pStorage->CreateStream( L"BodyPT-HTML", 
                                  STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
                                  0,          
                                  0,         
                                  &pStream);  
CHECK_STG_ERROR("IStorage::CreateStream",hResult);
LPWSTR Message = L"<HTML><BODY><B>Test</B> E-Mail</BODY></HTML>";
pStream->Write(Message, wcslen(Message)*sizeof(WCHAR), NULL);
pStream->Release();

// Commit changes to root storage.
pStorage->Commit(STGC_DEFAULT);
pStorage->Release(); 

Protecting the Message

With only minor variations, an e-mail message is protected in much the same way that MIME Encapsulation of Aggregate HTML Documents (MHTML) is protected when generating a rights-managed HTML file. (See Creating Rights-Managed HTML Files.)

To create a restricted-permission message file from content in a compound file, complete the following steps.

  • Compress the Message
  • Encrypt the Message
  • Store the Encrypted Message
  • Write the Data Spaces Storage
  • Compress the Resulting Compound File
  • Prefix and Save the File

Compress the Message

Compressing the message content is an optional step that can reduce the overall size of the resulting restricted-permission message file. If content is compressed, compression should be done prior to encryption. After encryption, the data cannot be compressed as efficiently as it can before encryption.

Before compressing the content, add a storage under transforminfo and an entry in the data space map stream that refers to the new storage.

Note   Content compressed with this compression transform must use a compression level of 9, and a window size of 32768 bytes.

 

Then, compress the content. The restricted-permission message format supports the compression method used in zlib. The zlib public library is available from http://www.gzip.org.

For compressed streams in the restricted-permission message format, the uncompressed content is divided into segments of 4096 bytes. Each block of the compressed stream contains the following:

Type Name Description
ULONG marker Must be 0x0FA0.
ULONG OriginalSize Size of the uncompressed data. Usually 4096. The last block may be less.
ULONG CompressedSize The size of the compressed data.
BYTE[] CompressedData The compressed data segment.

 

Encrypt the Message

Encrypt the message content, or the compressed message content, using the Windows Rights Management (RM) client software development kit (SDK). In addition to the encrypted content itself, maintain references to the signed issuance license and the content owner's end-user license. Both of these are used when creating the data spaces storage.

Store the Encrypted Message

Place the encrypted message content in a stream in the root storage of the compound file. This stream must be named \0x09DRMContent. (Note, this stream name is different than MHTML content: \0x09DRMViewerContent.)

Write the Data Spaces Storage

Write the data spaces storage as described in Data Spaces Structure for Rights-Managed Content.

  • The signed issuance license must be stored in the primary stream for the encryption transform definition.
  • Optionally, one or more end-user licenses can be placed in streams in the encryption transform definition storage. Typically, the end-user license for the content owner is stored here.
  • The data space map stream must include an entry that maps a data space to the \0x09DRMContent stream.

Compress the Resulting Compound File

The final step is to compress the resulting compound file with the compression method used in zlib (library available http://www.gzip.org). Even if you compress the message content before encryption, you can still recognize a reduced file size by compressing the compound file.

Note   Content compressed with this compression transform must use a compression level of 9, and a window size of 32768 bytes.

 

Note   Compression is mandatory for Azure Information Protection.

 

The uncompressed compound file is divided into segments of 4096 bytes. Each block of the compressed stream contains the following:

Type Name Description
ULONG marker Must be 0x0FA0.
ULONG OriginalSize Size of the uncompressed data. Usually 4096. The last block may be less.
ULONG CompressedSize The size of the compressed data.
BYTE[] CompressedData The compressed data segment.

 

Prefix and Save the File

Prefix the compressed file with the following 8 bytes to identify it as a compressed compound file.

0x76, 0xe8, 0x04, 0x60, 0xc4, 0x11, 0xe3, 0x86

The resulting compound file is a restricted-permission message and should be saved with the file name extension .rpmsg.

Best Practices for Delivering Rights-Managed Content