Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The following example demonstrates ways of working with key identifiers. This example illustrates the following tasks and CryptoAPI functions:
- Creating a key identifier using CryptCreateKeyIdentifierFromCSP.
- Setting a property on a key identifier using CryptSetKeyIdentifierProperty.
- Retrieving the contents of a key identifier property using CryptGetKeyIdentifierProperty.
- Listing the properties of a key identifier using CryptEnumKeyIdentifierProperties.
- Declaring, defining, and using a callback function.
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
//-------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// This program demonstrates the following Key Identifier functions:
// CryptCreateKeyIdentifierFromCSP
// CryptSetKeyIdentifierProperty
// CryptGetKeyIdentifierProperty
// CryptEnumKeyIdentifierProperties
// The callback function pfnEnum is also demonstrated.
//-------------------------------------------------------------------
// Declare the Callback function
static BOOL WINAPI pfnEnum (
const CRYPT_HASH_BLOB *pKeyIdentifier, // in- pKeyIdentifier
DWORD dwFlags, // in- Flag values
void *pvReserved, // Reserved
void *pvArg, // in- Pass-through argument
DWORD cProp, // in- cProp
DWORD *rgdwPropId, // in- array of PropIds
void **rgpvData, // in- array of
// CRYPT_KEY_PROV_INFO
// structures
DWORD *rgcbData // in- rgcbData
);
//-------------------------------------------------------------------
// Declare the MyHandleError function.
void MyHandleError(char *s);
void main(void)
{
//-------------------------------------------------------------------
// Declare and initialize variables.
PUBLICKEYSTRUC *pPubKeyStruc;
DWORD cbPubKeyStruc= sizeof(PUBLICKEYSTRUC);
if(!(pPubKeyStruc = (PUBLICKEYSTRUC *) malloc (cbPubKeyStruc)))
MyHandleError("Memory allocation failed.");
pPubKeyStruc->bType= PUBLICKEYBLOB;
pPubKeyStruc->bVersion= CUR_BLOB_VERSION;
pPubKeyStruc->reserved= 0;
pPubKeyStruc->aiKeyAlg= CALG_RSA_KEYX;
BYTE *pbHash;
DWORD cbHash;
PCRYPT_KEY_PROV_INFO pData;
CRYPT_HASH_BLOB KeyIdentifier;
DWORD cbData;
void *pvArg; // Pass through argument.
cbHash= 20; // define cbHash to the size of a SHA1
// string- there is no need for a 2 pass
// call to determine size of cbHash.
//-------------------------------------------------------------------
// Allocate memory for the pbHash buffer
if(!(pbHash= (BYTE *) malloc (cbHash))
MyHandleError("Memory allocation failed.");
//-------------------------------------------------------------------
// Create a Key Identifier
if(CryptCreateKeyIdentifierFromCSP(
X509_ASN_ENCODING, // dwCertEncodingType
NULL, // pszPubKeyOID- NULL to
// use default OID.
pPubKeyStruc, // pPubKeyStruc- defined above
cbPubKeyStruc, // cbPubKeyStruc
0, // dwFlags
NULL, // pvReserved
pbHash, // pbHash
&cbHash // pcbHash
))
{
printf("Call to CryptCreateKeyIdentifierFromCSP succeeded.\n");
}
else
{
MyHandleError("A key identifier was not created");
}
//-------------------------------------------------------------------
// Set the members of the key identifier.
KeyIdentifier.cbData= cbHash;
KeyIdentifier.pbData= (BYTE*) pbHash;
//-------------------------------------------------------------------
// Initialize the pdata structure.
if(!(pData= (CRYPT_KEY_PROV_INFO*) malloc
(sizeof(CRYPT_KEY_PROV_INFO))))
MyHandleError("Memory allocation failed.");
pData->pwszContainerName= L"New Key container name";
pData->pwszProvName= MS_ENHANCED_PROV_W;
pData->dwProvType= PROV_RSA_FULL;
pData->dwFlags= 0;
pData->cProvParam= 0;
pData->rgProvParam= NULL;
pData->dwKeySpec= AT_SIGNATURE;
//-------------------------------------------------------------------
// Set a property on the created key identifier.
if(CryptSetKeyIdentifierProperty(
&KeyIdentifier, // in- defined above
CERT_KEY_PROV_INFO_PROP_ID, // in- dwPropId
CRYPT_KEYID_MACHINE_FLAG, // in- dwFlags- use local computer
NULL, // in- pwszComputerName
NULL, // Reserved
pData // in- pointer to a
// CRYPT_KEY_PROV_INFO.
))
{
printf("A property is set on the key identifier.\n");
}
else
{
MyHandleError("Setting the property failed.");
}
//-------------------------------------------------------------------
// Call CryptGetKeyIdentifierProperty to set the size
// of the property to be retrieved.
if(CryptGetKeyIdentifierProperty(
&KeyIdentifier, // in- defined above
CERT_KEY_PROV_INFO_PROP_ID, // in- dwPropId
CRYPT_KEYID_MACHINE_FLAG, // in- dwFlags
NULL, // in, optional- pwszComputerName
NULL, // in, optional- pvReserved
NULL, // out- pvData
&cbData // in, out- pcbData
))
{
printf("First call to get property succeeded.\n");
}
else
{
MyHandleError("Call 1 to CryptGetKeyIdentifierProperty failed.");
}
//-------------------------------------------------------------------
// Free the memory allocated for pData,
free(pData);
//-------------------------------------------------------------------
// Allocate memory for the buffer to receive the property.
if(!(pData= (CRYPT_KEY_PROV_INFO*) malloc (cbData)))
MyHandleError("Memory allocation failed.");
//-------------------------------------------------------------------
// Call CryptGetKeyIdentifierProperty a second time
// To retrieve the property into the allocated buffer.
if(CryptGetKeyIdentifierProperty(
&KeyIdentifier, // pKeyIdentifier
CERT_KEY_PROV_INFO_PROP_ID, // dwPropId
CRYPT_KEYID_MACHINE_FLAG, // dwFlags
NULL, // pwszComputerName
NULL, // Reserved
pData, // pData
&cbData // pcbData
))
{
printf("The property has been retrieved.\n");
}
else
{
MyHandleError("Second call failed.");
}
//-------------------------------------------------------------------
// Print part of the retrieved property.
printf("Some of the properties obtained are;\n");
printf("container name= %S\n",pData->pwszContainerName);
printf("Provider name= %S\n", pData->pwszProvName);
printf("Provider type= %i\n", pData->dwProvType);
printf("length= %i\n\n", cbData);
//-------------------------------------------------------------------
// Set the pass through argument for the callback function.
pvArg= pPubKeyStruc;
//-------------------------------------------------------------------
// Call CryptEnumKeyIdentifierProperties.
printf("\nCalling CryptEnumKeyIdentifierProperties.\n");
if(CryptEnumKeyIdentifierProperties(
&KeyIdentifier, // in- pKeyIdentifier-
0, // in- dwPropId
CRYPT_KEYID_MACHINE_FLAG, // in- dwFlags, use LocalMachine.
NULL, // in, optional- pwszComputerName set
// to NULL to use LocalMachine.
NULL, // Reserved
pvArg, // in, optional- Pointer to the
// pass-through argument
(PFN_CRYPT_ENUM_KEYID_PROP )pfnEnum
// in- Callback function.
))
{
printf("The function call succeeded.\n");
}
else
{
MyHandleError("Call to CryptEnumKeyIdentifierProperties failed.");
}
//-------------------------------------------------------------------
// Free all allocated memory
free (pData);
free (pPubKeyStruc);
printf("all memory free\n");
printf("The program ran to completion without error.\n");
} // end main.
//-------------------------------------------------------------------
// Define the Callback function
static BOOL WINAPI pfnEnum (
const CRYPT_HASH_BLOB *pKeyIdentifier, // in- pKeyIdentifier
DWORD dwFlags, // in- Flag values
void *pvReserved, // Reserved
void *pvArg, // in- Pass-through argument
DWORD cProp, // in- cProp
DWORD *rgdwPropId, // in- rgdwPropId
void **rgpvData, // in- rgpvData- points to an
// array of
// CRYPT_KEY_PROV_INFO
// structures
DWORD *rgcbData // in- rgcbData
)
{
//-------------------------------------------------------------------
// Declare and initialize local variables.
PUBLICKEYSTRUC *pArg= (PUBLICKEYSTRUC *) pvArg;
//-------------------------------------------------------------------
// Begin processing
printf("The argument passed is a structure.\n");
printf("BLOB type= %x ", pArg->bType);
printf("Version= %x\n", pArg->bVersion);
printf("Algorithm= %x\n\n", pArg->aiKeyAlg);
return TRUE;
} // end callback function.
//-------------------------------------------------------------------
// Define MyHandleError
void MyHandleError(char *s)
{
printf("\n An error has occurred. \n");
printf("The error message is %s \n",s);
printf("Last error is %x \n",GetLastError());
exit(1);
} // end MyHandleError.