Share via


Storing and Retrieving Licenses and Certificates

The Active Directory Rights Management Services (AD RMS) client provides a license storage tool called the license store. This store holds all the licenses and certificates that an application is likely to use, including the machine certificate, rights account certificate, end-user and issuance licenses, and revocation lists.

There are two license stores in AD RMS.

Store Description
Permanent license store Persistent storage area maintained by the AD RMS client.
Temporary license store Destroyed when the license storage session is destroyed by calling the DRMCloseSession function.

When enumerating the contents of the license store, both license stores are seen as a single entity by the application.

The license store is required to retrieve licenses acquired by asynchronous functions; however, it is not required that an application use the license store for certificate or license storage or management. Note that if an application does not use the license store, it will be responsible for storing all required licenses itself, and adding them each session by using the DRMAddLicense function.

Most licenses or certificates acquired asynchronously are automatically deposited into the temporary or permanent license store, from which they must be retrieved by using the DRMEnumerateLicense function. After the license or certificate is retrieved, an application can delete it from the store and manage the license itself. An application can now add a certificate or license to the permanent license store as well as the temporary license store. The temporary license store is destroyed when the DRMCloseSession function is called.

Note  In RMS client 1.0, an application cannot add licenses or certificates to the permanent license store. Licenses and certificates can only be added to the temporary license store.

The license store should periodically be checked for expired licenses or certificates. Delete expired licenses by using the DRMDeleteLicense function.

The following example shows retrieving a machine certificate by using the DRMEnumerateLicense function. The first call determines the required buffer size, and a second call to the method reads the license into memory allocated after the size is known.

// Find the length of the machine certificate.
 hr = DRMEnumerateLicense( 
    hClient,            // Client session.
    DRM_EL_MACHINE,
    0,                  // Index.
    &fShared,           
    &uiMachineCertLen,  // Size of license or certificate.
    NULL ); 
if(FAILED(hr))
{
    wprintf(L"\nDRMEnumerateLicense(DRM_EL_MACHINE) failed. hr = 0x%x\n", hr);
    goto e_Exit;
}

// Allocate space for the certificate.
wszMachineCert = (PWSTR)HeapAlloc( 
    GetProcessHeap(),
    0,
    sizeof(WCHAR) * (uiMachineCertLen + 1));
if (NULL == wszMachineCert)
{
     hr = E_OUTOFMEMORY;
     goto e_Exit;
}
 
// Get the machine certificate.
hr = DRMEnumerateLicense( 
    hClient,            // Client session.
    DRM_EL_MACHINE,
    0,                  // Index.
    &fShared,
    &uiMachineCertLen,  // Size of license or certificate.
    wszMachineCert ); 
if(FAILED(hr))
{
    wprintf(L"\nDRMEnumerateLicense(DRM_EL_MACHINE) failed. hr = 0x%x\n", hr);
    goto e_Exit;
}

The process of retrieving a rights account certificate (RAC) is somewhat more complicated because a computer may hold several rights account certificates for the current user. When retrieving a rights account certificate to bind to a license, you must ensure that the following four items in the rights account certificate match the corresponding items in the issuance license:

  1. The name of the user
  2. The type of rights account certificate (Passport or Windows)
  3. The root issuer (Pre-production or Production)
  4. The issuer

If all four of these items do not match, the bind will not succeed.

The simplest way to determine whether you have retrieved the proper rights account certificate for a license bind is to enumerate all rights account certificates and attempt to bind by using each, trapping E_DRM_BIND_INDICATED_PRINCIPAL_MISSING, which indicates that the wrong rights account certificate is being used. However, binding to a license is somewhat resource intensive. If you want to be more selective in rights account certificates you use to bind, the following pseudocode shows how to find a matching rights account certificate for a license.

wszLicense = the license you want to match
wszLicenseRoot = issuer of root certificate of license
wszLicenseIssuer = issuer of leaf certificate in license
wszLicenseType = "Windows" or "Passport"

Enumerate and delete all expired licenses.

// Enumerate all RACs for the current user.
i = 0;
hr = DRMEnumerateLicense(
    hSession, 
    DRM_EL_SPECIFIED_GROUPIDENTITY, 
    i, 
    &pfShared, 
    puLen, 
    wszRAC);
while (S_OK == hr)
{
    wszRACRoot = issuer of root certificate of wszRAC

    if (wszRACRoot == wszLicenseRoot)
        wszRACType = type of RAC

    if (wszLicenseType == wszRACType)
        wszRACIssuer = issuer of RAC

    if (wszLicenseIssuer == wszRACIssuer)
         return retrieved wszRAC;

    // Get next RAC from license store
    i++;
    hr = DRMEnumerateLicense(
        hSession, 
        DRM_EL_SPECIFIED_GROUPIDENTITY, 
        i, 
        &pfShared, 
        puLen, 
        wszRAC);
}

To get information from a certificate in the chain, you must first get that certificate from the chain. Use the DRMDeconstructCertificateChain function and pass in the index of the certificate you want. The leaf certificate is always index zero. The root certificate index is obtained by subtracting one from the result of the DRMGetCertificateChainCount function.

After you have the certificate, you can parse out the issuer or name by querying the license by using unbound license querying. For more information about querying certificates, see Querying Licenses.

To get the issuer of a certificate

  • Get the certificate and query using g_wszQUERY_ISSUEDPRINCIPAL to get the principal, then query using g_wszQUERY_OBJECTID to get the value.

To get the type (Windows or Passport)

  • Query the certificate using g_wszQUERY_ISSUER, then query using g_wszQUERY_OBJECTIDTYPE.

See Also

License Management
Methods Used by All Client Applications
Rights Account Certificates

Send comments about this topic to Microsoft

Build date: 3/13/2008