Share via


Obtaining a Signed Issuance License

After you create the issuance license, you need to get it signed by a license server. This signed issuance license contains all the information that has been defined by using the DRMCreateRight, DRMCreateUser, DRMAddRightWithUser, and DRMSetMetaData functions, plus a content key used to encrypt the content. You can sign your issuance license offline by using a certificate called a client licensor certificate, which allows you to obtain a signed issuance license without having to reach the server every time you want an issuance license signed. However, client licensor certificates must be obtained previously from your license server, and they have expiration times.

To get a signed issuance license online, create an issuance license and have it signed online by using the AcquireIssuanceLicense SOAP method as shown in Getting the Issuance License Signed. You can also use the DRMGetSignedIssuanceLicense function to obtain a signed issuance license online.

Your license store may hold several client licensor certificates. A robust application should enumerate the licensor certificates to be sure you are using the proper one.

The signed issuance license is returned in the pvParam parameter of the callback function. For more information about retrieving licenses in the callback function, see Callback Function and AD RMS Callback Function Reference. Your application must store this issuance license in a location and format known to the consuming application.

The following example shows how to get an issuance license signed online. To sign an issuance license online, you must know the URL of a license server, which is found by calling DRMGetServiceLocation. For more information about this step, see Finding an AD RMS Service. DRMGetSignedIssuanceLicense is an asynchronous function, so you may want to use an event handle to notify you of the function's progress.

// Publish online.
// You should check for E_DRM_INVALID_CLIENT_LICENSOR_CERTIFICATE 
// here and enumerate through all CLCs to be sure you have the 
// correct CLC from the license store.
hr = DRMGetSignedIssuanceLicense( 
    NULL,                // Environment handle not needed.
    hIssuanceLicense,    // Unsigned IL to be signed.
    DRM_SIGN_ONLINE,     // Use with bitwise or 
                         // (| DRM_AUTO_GENERATE_KEY) to 
                         // automatically generate key.
    g_bSymKey,           // Symmetric Key or NULL if using 
                         // DRM_AUTO_GENERATE_KEY  to get 
                         // symmetric key.
    sizeof(g_bSymKey),   // Length of symmetric key.or 
                         // NULL if using DRM_AUTO_GENERATE_KEY 
                         // to get symmetric key.
    L"AES",
    NULL,                // Client licensor certificate not used.
    &OnStatus,           // Your custom callback function.
    wszLicenseServerURL, // From DRMGetServiceLocation.
    NULL);               // Optional information for events.

if (hr == E_DRM_INVALID_CLIENT_LICENSOR_CERTIFICATE)
{ 
    // Enumerate next CLC
}

The following example shows how to obtain a signed issuance license offline, using the user's client licensor certificate. The code first shows how to obtain a client licensor certificate from a server, then retrieve it from the license store. However, this code does not show how to determine if the proper client licensor certificate was retrieved; a robust application should determine that the certificate is valid (and, if not, delete it). For more information about how to enumerate the license store, see Storing and Retrieving Licenses and Certificates.

// Publish offline.
// First, try to find the client licensor service URL.
hr = FindServiceLocation( 
    hClient, 
    DRM_SERVICE_TYPE_CLIENTLICENSOR, 
    &wszClientLicensorURL );
if(FAILED(hr))  
{
    // Handle error.
}

// For offline publishing, a client licensor certificate 
// (CLC) is required.
hr = DRMAcquireLicense( 
    hClient,               // Pass client session handle to get CLC. 
    NULL,                  // No flags.
    NULL,                  // No RAC needed for CLC.
    NULL,                  // Reserved.
    NULL,                  // No extra data.
    wszClientLicensorURL,  // Obtained previously.
    &hCLCAcquired );       // Holds the CLC.

if(FAILED(hr))
{ 
    // Handle error.
}

// Get the CLC from license store. Call once for buffer size, 
// then again for CLC. 
fShared = FALSE;    
hr = DRMEnumerateLicense(
    hClient,
    DRM_EL_SPECIFIED_CLIENTLICENSOR,
    0,
    &fShared,
    &uiClientLicensorCertLen,
    NULL );
if(FAILED(hr))
{
    // Handle error.
}

wszClientLicensorCert = (PWSTR)HeapAlloc(
    GetProcessHeap(), 
    HEAP_ZERO_MEMORY, 
    sizeof(WCHAR) * (uiClientLicensorCertLen  + 1));
if(NULL == wszClientLicensorCert)
{
    // Handle error.
}
hr = DRMEnumerateLicense(
    hClient,
    DRM_EL_SPECIFIED_CLIENTLICENSOR,
    0,
    &fShared,
    &uiClientLicensorCertLen,
    wszClientLicensorCert );

if(FAILED(hr))
{
    // Handle error.
}

// Now sign the issuance license with your IL. Use the 
// DRM_AUTO_GENERATE_KEY to automatically generate the 
// symmetric key instead. This example uses its own symmetric 
// key in the g_bSymKey variable.

hr = DRMGetSignedIssuanceLicense( 
        hEnv, 
        hIssuanceLicense,
        DRM_SIGN_OFFLINE,
        g_bSymKey, 
        sizeof(g_bSymKey),         // Length of symmetric key.
        L"AES",
        wszClientLicensorCert,     // Used for offline signing.
        &OnStatus,                 // Callback function.
        NULL,                      // No URL for offline signing.
        &hIssuanceLicenseAcquired);

if(FAILED(hr))
{
    // Handle error.
}

The signed issuance license must be packaged with the content in exactly the format and location that the consuming application expects. Otherwise, the consuming application will not be able to find and process the issuance license, and decrypt the content correctly. Therefore, you must either own the format of the secure document, or it must be an open format.

As an example, imagine an XYZ file format that holds a RM-protected file. The XYZ format is specified as encrypted ASCII text, followed by a license in Unicode format at the end, surrounded by a string of fifteen Unicode zeros. An application that can read a file named myfile.xyz must understand this file format in order to be able to open it.

See Also

Building a Publishing Application
Issuance Licenses

Send comments about this topic to Microsoft

Build date: 3/13/2008