A question recently came to me about whether the security descriptor returned by CryptGetProvParam PP_KEYSET_SEC_DESCR is in self-relative or absolute format.  The answer is:  self-relative.  I took advantage of this learning opportunity and discovered that there were (at least) two ways to derive this information (aside from looking at the code, which is how I originally got the answer, of course).  I'll describe both ways.

First, recognize that Crypto API key containers are stored as files on disk, with appropriate ACLs applied.  The implementation of the PP_KEYSET_SEC_DESCR param is essentially just a call to GetFileSecurityW (or SetFileSecurityW for the CryptSet version of the API).  Per the documentation for GetFileSecurityW, the security descriptor (SD) is returned in self-relative format.  That's the first way.

The second way to answer our question is to write some code that probes the SD returned by CryptGetProvParam.  Briefly, the API to use is GetSecurityDescriptorControl.  Then check for the SE_SELF_RELATIVE bit in the returned control mask.  In the case of the SDs returned by Crypto API, the bit will be set.  That's the second way.

I'll include some sample code that I played with to learn about the above.  In addition to querying for SD control information, my sample code will also retrieve the Owner and DACL information and print it out in string form via the ConvertSecurityDescriptorToStringSecurityDescriptor API.  It would be wrong to describe the output SDDL strings as "friendly," but note that most of it consists of my logon SID.

Example output:

 Security descriptor is in self-relative format
 Owner security information - O:S-1-5-21-397955417-626881126-188441444-2812062
 DACL security information - D:(A;;GAGR;;;S-1-5-21-397955417-626881126-188441444-2812062)(A;;GAGR;;;SY)

Code listing:

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <sddl.h>
#include <stdlib.h>
#include <stdio.h>
#include <wincrypt.h>
//
// Query SD information for this container
//
DWORD GetSecurityDescriptorInfo(
    IN HCRYPTPROV hProv)
{
    PBYTE pbData = NULL;
    DWORD cbData = 0;
    DWORD dwSts = ERROR_SUCCESS;
    LPSTR szSD = NULL;
    SECURITY_DESCRIPTOR_CONTROL SdControl;
    DWORD dwRevision = 0;

    //
    // Query for the owner and Dacl info
    //

    if (FALSE == CryptGetProvParam(
        hProv,
        PP_KEYSET_SEC_DESCR,
        NULL,
        &cbData,
        OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
    {
        dwSts = GetLastError();
        goto Ret;
    }

    pbData = MyAlloc(cbData);
    if (NULL == pbData)
    {
        dwSts = ERROR_NOT_ENOUGH_MEMORY;
        goto Ret;
    }

    if (FALSE == CryptGetProvParam(
        hProv,
        PP_KEYSET_SEC_DESCR,
        pbData,
        &cbData,
        OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
    {
        dwSts = GetLastError();
        goto Ret;
    }

    //
    // Check that the SD is self-relative
    //

    if (FALSE == GetSecurityDescriptorControl(
        (PSECURITY_DESCRIPTOR) pbData,
        &SdControl,
        &dwRevision))
    {
        dwSts = GetLastError();
        goto Ret;
    }

    printf("\n");
    if (SE_SELF_RELATIVE & SdControl)
        printf(" Security descriptor is in self-relative format\n");
    else
        printf(" Security descriptor is in absolute format\n");

    //
    // Convert the SD owner to string form
    //

    if (FALSE == ConvertSecurityDescriptorToStringSecurityDescriptor(
        (PSECURITY_DESCRIPTOR) pbData,
        SDDL_REVISION_1,
        OWNER_SECURITY_INFORMATION,
        &szSD,
        NULL))
    {
        dwSts = GetLastError();
        goto Ret;
    }

    printf(" Owner security information - %s\n", szSD);
    LocalFree(szSD);
    szSD = NULL;

    //
    // Convert the SD DACL to string form
    //

    if (FALSE == ConvertSecurityDescriptorToStringSecurityDescriptor(
        (PSECURITY_DESCRIPTOR) pbData,
        SDDL_REVISION_1,
        DACL_SECURITY_INFORMATION,
        &szSD,
        NULL))
    {
        dwSts = GetLastError();
        goto Ret;
    }

    printf(" DACL security information - %s\n", szSD);
    printf("\n");

Ret:

    if (NULL != szSD)
        LocalFree(szSD);
    if (NULL != pbData)
        MyFree(pbData);

    return dwSts;
}

As you might expect - This posting is provided "AS IS" with no warranties, and confers no rights.