CPAcquireContext

The CPAcquireContext function is used to acquire a handle to the key container specified by the pszContainer parameter.

BOOL CPAcquireContext(
  HCRYPTPROV *phProv,       // out
  CHAR *pszContainer,       // in, out
  DWORD dwFlags,            // in
  PVTableProvStruc pVTable  // in
);
 

Parameters

phProv
Address to which the function copies a handle to the CSP.
pszContainer
Key container name. This is a zero-terminated string, of typically no more than MAX_PATH characters, including the terminator. pszContainer is to be set to NULL when dwFlags is set to CRYPT_VERIFYCONTEXT.

If this parameter is NULL, then a default key container name will be used. For example, the Microsoft® RSA Base Provider uses the logon name of the user currently logged on as the key container name in this situation.

dwFlags

Flag values. This parameter is normally zero, but the following flags are allowed:

CRYPT_VERIFYCONTEXT
If this flag is set, then the application will have no access to the private keys and the pszContainer parameter must be set to NULL.

This option is intended to be used with applications that will not be using private keys.

When CryptAcquireContext (in the CryptoAPI) is called, many CSPs will require input from the owning user before granting access to the private keys in the key container. For example, the private keys may be encrypted, requiring a password from the user before they can be used. However, if the CRYPT_VERIFYCONTEXT flag is specified, access to the private keys is not required and the user interface can be bypassed.

CRYPT_NEWKEYSET
If this flag is set, then a new key container will be created with the name specified by pszContainer. If pszContainer is NULL, then a key container with the default name will be created.

The CSP is not required to create any key pairs at this point. Instead, the key pairs are typically generated later via the CPGenKey function. However, the CSP may generate key pairs during the CPAcquireContext function call at the CSP author's discretion.

CRYPT_MACHINE_KEYSET
By default keys are stored in the HKEY_CURRENT_USER portion of the registry. The CRYPT_MACHINE_KEYSET flag may be used when calling CryptAcquireContext (in the CryptoAPI) with the CRYPT_NEW_KEYSET or CRYPT_DELETE_KEYSET flag and, in this case, the keys will be stored in the HKEY_LOCAL_MACHINE portion of the registry.

Note that CRYPT MACHINE KEYSET applies specifically to the Microsoft Provider Types. Other provider types may store keys differently and should ignore this flag.

For CSPs to be compatible with the Microsoft Cryptograpic Providers, they should implement the CRYPT MACHINE KEYSET flag. In the case of many CSPs, this may mean just ignoring this flag. This flag is used for keys that are machine keys, which means these keys need to be accessible to applications that are not associated with a user account. It is generally not good practice to have a UI associated with these keys because these keys could easily be used by an unattended server application. Microsoft Providers store keys in the registry and the machine keys are stored in the HKEY_LOCAL_MACHINE portion of the registry. In addition, with the Microsoft Providers, ACLs may be set on these keys by using CPGetProvParam and CPSetProvParam with the PP_KEYSET_SEC_DESCR value. CSP writers may want to consider allowing the setting of Microsoft Windows NT® ACLs on keys as well.

Note  When key containers are created, most CSPs will not automatically create any public/private key pairs. These keys must be created as a separate step by using the CryptGenKey function (in the CryptoAPI).

CRYPT_DELETEKEYSET.
If this flag is set, then the key container specified by pszContainer is deleted. If pszContainer is NULL, then the key container with the default name is deleted. All key pairs in the key container are also destroyed.

When the CRYPT_DELETEKEYSET flag is set, the value returned in phProv is undefined and, thus, the CryptReleaseContext function (in the CryptoAPI) need not be called afterwards.

pVTable
Pointer to a VTableProvStruct structure that contains a list of functions provided by the operating system for use by the CSP.

This is discussed further in the Remarks section.

Return Values

If the function succeeds, TRUE should be returned; otherwise, return FALSE. When FALSE is returned, the appropriate error code (see the following table) must be set via SetLastError.

Error Description
NTE_BAD_FLAGS The dwFlags parameter has an illegal value.
NTE_BAD_KEYSET The key container could not be opened, and may not exist.
NTE_BAD_KEYSET_PARAM The pszContainer parameter is set to an illegal value.
NTE_BAD_SIGNATURE The digital signature of an auxiliary DLL did not verify correctly. Either the DLL or the digital signature has been tampered with.
NTE_EXISTS The dwFlags parameter is CRYPT_NEWKEYSET, but the key container already exists.
NTE_KEYSET_ENTRY_BAD The registry entry for the pszContainer key container was found but is corrupt
NTE_KEYSET_NOT_DEF The key container specified by pszContainer does not exist.
NTE_NO_MEMORY The CSP ran out of memory during the operation.
NTE_PROVIDER_DLL_FAIL An auxiliary DLL file could not be loaded, and may not exist. If it exists, the file is not a valid DLL.

Remarks

The VTableProvStruc structure and the function pointers that it contains are defined as:

typedef struct _VTableProvStruc {
    DWORD   Version;
    FARPROC FuncVerifyImage;
    FARPROC FuncReturnhWnd;
    DWORD   dwProvType;
    BYTE *pbContextInfo;
    DWORD cbContextInfo;
} VTableProvStruc, *PVTableProvStruc;
BOOL FuncVerifyImage(LPCSTR lpszImage, BYTE *pSigData);
BOOL FuncReturnhWnd(DWORD *phWnd);
 

The Version field is currently always set to 2. The value of this field will be incremented as additional function pointers are added to the structure, or as other changes are made.

All auxiliary DLLs that your CSP makes function calls into must be signed, in the same manner (and with the same key) as is the primary CSP DLL. To make this work properly, the auxiliary DLLs must be loaded dynamically, via the LoadLib function. But before the LoadLib function is called, the signature of the DLL must be verified. The CSP does this verification by calling the FuncVerifyImage function, as illustrated in the following code fragment.

BOOL (FARPROC *ProvVerifyImage)(LPCSTR lpszImage, BYTE *pSigData);
BYTE bSignature[72];

// "ProvVerifyImage" has been set to "pVTable->FuncVerifyImage"
// within the CPAcquireContext function.

// Load the c:\winnt40\system32\winfoo.sig file into the 
// bSignature buffer. During development, this file is created 
// with the sign.exe utility.
...

// Verify the signature on the c:\winnt40\system32\winfoo.dll file.
if(RCRYPT_FAILED(ProvVerifyImage("c:\\winnt40\\system32\\winfoo.dll",
                                 bSignature)) {
    SetLastError(NTE_BAD_SIGNATURE);
    return CRYPT_FAILED;
}

// Load the DLL with the LoadLib function, then acquire pointers to 
// the member functions with the GetProcAddress function.
...
 

The FuncReturnWnd entry in the VTableProvStruc structure can be called by CSPs to retrieve a window handle that it is to use when interacting directly with the user via Microsoft Win32®. CSPs that do not communicate directly with the user (and ones that use dedicated hardware for this purpose) can ignore this entry. This window handle is zero by default, but some applications will set it to a different value by using the CryptSetProvParam function (in the CryptoAPI).

The dwProvType field specifies the type of provider to acquire. The following provider types are predefined, and are discussed in detail in Interoperability with RSA CSPs.

The pbContextInfo and cbContextInfo fields specifiy the information set when performing a CPSetProvParam with the PP_CONTEXT_INFO parameter number specified.

See Also

CPReleaseContext, CryptAcquireContext, CryptSetProvParam