The CryptGetProvParam function retrieves parameters that govern the operations of a CSP.
#include <wincrypt.h>
BOOL WINAPI CryptGetProvParam(
HCRYPTPROV hProv, // in
DWORD dwParam, // in
BYTE *pbData, // out
DWORD *pcbData, // in/out
DWORD dwFlags // in
);
This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see Common In/Out Parameter Conventions.
Note that when processing the data returned in the buffer, applications need to use the actual size of the data returned. The actual size may be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to insure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.
Note When one of the enumeration parameters (PP_ENUMALGS or PP_ENUMCONTAINERS) is being read, the pcbData parameter works somewhat differently. If pbData is NULL or the value pointed to by pcbData is too small, the value returned in this parameter is the size of the largest item in the enumeration list instead of the size of the item currently being read.
When one of the enumeration parameters is read and the pbData parameter is NULL, the CRYPT_FIRST flag must be specified in order for the size information to be correctly retrieved.
When one of the enumeration parameters (PP_ENUMALGS or PP_ENUMCONTAINERS) is being read, then the CRYPT_FIRST flag can be specified. When this flag is set, the first item in the enumeration list is returned. If this flag is not set, then the next item in the list is returned.
When the enumeration parameter PP_ENUMCONTAINERS is being read, then the CRYPT_MACHINE_KEYSET flag can be specified. This flag can be set if you want the enumeration to come from the HKEY_LOCAL_MACHINE portion of the registry rather than from the HKEY_CURRENT_USER portion of the registry (the default).
When the dwParam is PP_KEYSET_SEC_DESCR, the security descriptor on the registry key where the keys are stored is being retrieved. For this case, dwFlags is used to pass in the SECURITY_INFORMATION bit flags (can be combined with a bitwise OR operation), as defined in the Win32 Programmer's Reference, that indicates the requested security information. The following is specified there:
typedef DWORD SECURITY_INFORMATION;
Value | Meaning |
---|---|
OWNER_SECURITY_INFORMATION | Indicates the owner identifier of the object is being referenced. |
GROUP_SECURITY_INFORMATION | Indicates the primary group identifier of the object is being referenced. |
DACL_SECURITY_INFORMATION | Indicates the discretionary ACL of the object is being referenced. |
SACL_SECURITY_INFORMATION | Indicates the system ACL of the object is being referenced. |
If the function succeeds, the return value is TRUE. If it fails, the return value is FALSE. To retrieve extended error information, use the GetLastError function.
The following table lists the error codes most commonly returned by the GetLastError function. The error codes prefaced by "NTE" are generated by the particular CSP you are using.
Error code | Description |
---|---|
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle. |
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an illegal pointer. |
ERROR_MORE_DATA | If the buffer specified by the pbData parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbData. |
ERROR_NO_MORE_ITEMS | The end of the enumeration list has been reached. No valid data has been placed in the pbData buffer. This error is returned only when dwParam equals PP_ENUMALGS or PP_ENUMCONTAINERS. |
NTE_BAD_FLAGS | The dwFlags parameter is nonzero. |
NTE_BAD_TYPE | The dwParam parameter specifies an unknown parameter number. |
NTE_BAD_UID | The CSP context specified by hProv is invalid. |
The parameter number contained in the dwParam parameter can be set to one of the following values:
This string is exactly the same as the one passed in the pszContainer parameter of the CryptAcquireContext function in order to specify that the current key container be used. This parameter is often read in order to determine the name of the default key container.
The first time that the PP_ENUMALGS parameter is read, the CRYPT_FIRST flag should be specified. This will ensure that information about the first algorithm in the enumeration list is returned. The PP_ENUMALGS parameter can then be repeatedly read in order to retrieve the information about the rest of the algorithms. When the CryptGetProvParam function fails with ERROR_NO_MORE_ITEMS, then the end of the enumeration list has been reached. A code sample illustrating this is located in the "Example" section.
When calling CryptGetProvParam with the PP_ENUMALGS flag in the dwParam parameter the dwBits field should be changed to the length of the default key sizes.
The following code fragment indicates the format of the data that the function returns in the pbData buffer:
ALG_ID aiAlgid;
DWORD dwBits;
DWORD dwNameLen;
CHAR szName[dwNameLen];
The following table defines each of these fields.
Field | Description |
---|---|
aiAlgid | The algorithm identifier. This is the value that is passed to the CryptGenKey, CryptDeriveKey, or CryptCreateHash functions in order to specify that a particular algorithm be used. |
dwBits | The number of bits in the keys used by the algorithm. If this is a hash algorithm, this value indicates the number of bits in the hash values generated by this algorithm. |
dwNameLen | The number of characters in the algorithm name, including the terminating zero. |
szName | The zero-terminated name of the algorithm. |
These container names are enumerated in the same way as are the CSP's supported algorithms. Refer to the PP_ENUMALGS entry for more information.
This string is identical to the one passed in the pszProvider parameter of the CryptAcquireContext function in order to specify that the current CSP be used. For example, the Microsoft Base Cryptographic Provider will return "Microsoft Base Cryptographic Provider v1.0" when this parameter is read.
Version Information for
The Microsoft Base Cryptographic Provider and
The Microsoft Enhanced Cryptographic Provider:
To maintain backward compatibility with earlier versions of these providers, the name retains the "v1.0" designation in later versions. This can be seen in the wincrypt.h header file. Version 2.0 of this provider is currently shipping. To see which version of the provider you have, make a call to CryptGetProvParam with the dwParam argument set to PP_VERSION. For example, if 0x00000200 is returned in pbData, then you have version 2.0.
Note The PP_KEYSET_SEC_DESCR flag is not supported under Microsoft® Windows® 95.
The dwFlags parameter is used to pass in the SECURITY_INFORMATION bit flags that indicate the requested security information. The pointer to the security descriptor is returned in the pbData parameter and the length of the security descriptor is returned in the pcbData parameter. It may be helpful to look at the documentation on RegGetKeySecurity and RegSetKeySecurity (WIN32 calls).
When enumerating algorithms (dwParam == PP_ENUMALGS), your application may need to determine the class of a particular algorithm. For example, you may want to display a list of encryption algorithms to the user and disregard the rest. This can be done with the GET_ALG_CLASS(x) macro. This macro takes an algorithm identifier as an argument and returns a code indicating the general class of algorithm that the identifier belongs to. Possible return values include:
The following table lists the algorithms supported by the Microsoft Base Cryptographic Provider along with the class of each algorithm.
Name | Identifier | Class |
---|---|---|
"MD2" | CALG_MD2 | ALG_CLASS_HASH |
"MD5" | CALG_MD5 | ALG_CLASS_HASH |
"SHA" | CALG_SHA | ALG_CLASS_HASH |
"MAC" | CALG_MAC | ALG_CLASS_HASH |
"RSA_SIGN" | CALG_RSA_SIGN | ALG_CLASS_SIGNATURE |
"RSA_KEYX" | CALG_RSA_KEYX | ALG_CLASS_KEY_EXCHANGE |
"RC2" | CALG_RC2 | ALG_CLASS_DATA_ENCRYPT |
"RC4" | CALG_RC4 | ALG_CLASS_DATA_ENCRYPT |
If your application does not recognize an algorithm identifier, it is not recommended that you use the algorithm. Making use of an unknown cryptographic algorithm can sometimes produce unpredictable results.
This example shows how the list of algorithms supported by a particular CSP is accessed by an application:
HCRYPTPROV hProv; // Handle to CSP
DWORD dwAlgCount;
BYTE *ptr = NULL;
DWORD i;
ALG_ID aiAlgid;
DWORD dwBits;
DWORD dwNameLen;
CHAR szName[100]; // Often allocated dynamically
BYTE pbData[1000]; // Often allocated dynamically
DWORD cbData;
DWORD dwFlags;
CHAR *pszAlgType = NULL;
// Enumerate the supported algorithms.
for(i=0 ; ; i++) {
// Set the CRYPT_FIRST flag the first time through the loop.
if(i == 0) {
dwFlags = CRYPT_FIRST;
} else {
dwFlags = 0;
}
// Retrieve information about an algorithm.
cbData = 1000;
if(!CryptGetProvParam(hProv, PP_ENUMALGS, pbData, &cbData, dwFlags)) {
if(GetLastError() == ERROR_NO_MORE_ITEMS) {
// Exit the loop.
break;
} else {
printf("Error %x reading algorithm!\n", GetLastError());
return;
}
}
// Extract algorithm information from the 'pbData' buffer.
ptr = pbData;
aiAlgid = *(ALG_ID *)ptr;
ptr += sizeof(ALG_ID);
dwBits = *(DWORD *)ptr;
ptr += sizeof(DWORD);
dwNameLen = *(DWORD *)ptr;
ptr += sizeof(DWORD);
strncpy(szName, ptr, dwNameLen);
// Determine the algorithm type.
switch(GET_ALG_CLASS(aiAlgid)) {
case ALG_CLASS_DATA_ENCRYPT: pszAlgType = "Encrypt ";
break;
case ALG_CLASS_HASH: pszAlgType = "Hash ";
break;
case ALG_CLASS_KEY_EXCHANGE: pszAlgType = "Exchange ";
break;
case ALG_CLASS_SIGNATURE: pszAlgType = "Signature";
break;
default: pszAlgType = "Unknown ";
}
// Print information about the algorithm.
printf("Algid:%8.8xh, Bits:%-4d, Type:%s, NameLen:%-2d, Name:%s\n",
aiAlgid, dwBits, pszAlgType, dwNameLen, szName
);
}
Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 OSR2 or later (or Windows 95 with IE 3.02 or later).
Windows CE: Unsupported.
Header: Declared in wincrypt.h.
Import Library: Use advapi32.lib.
CryptAcquireContext, CryptCreateHash, CryptDeriveKey, CryptGenKey, CryptGetKeyParam, CryptSetProvParam