Note

Access to this page requires authorization. You can try signing in or .

Access to this page requires authorization. You can try .

Example C Program: Setting and Getting Certificate Store Properties

The following example sets and gets a certificate store property, the localized store name. This property is not persisted when the store is closed.

This example illustrates the following tasks and CryptoAPI functions:

//-------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Example C program.
// This program demonstrates the use of the following functions:
// CreateEvent
// CertOpenStore
// CertSetStoreProperty
// CertGetStoreProperty
// CryptFindLocalizedName 
// CertSaveStore
// CryptGetMessageSignerCount
// CryptGetMessageCertificates
// CryptHashMessage
// CertControlStore
// WaitForSingleObjectEx
// CertCloseStore
#pragma comment(lib, "crypt32.lib")

#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void MyHandleError(char *s);

void main()
{
//-------------------------------------------------------------------
// Declare and initialize variables.

HCERTSTORE hCertStore; // Original certificate store
HCERTSTORE hNewStore; // Store to be created 
 // from a PKCS #7 message 
HANDLE hEvent;
void *pvData;
DWORD cbData;
DWORD dwSignerCount;
CRYPT_DATA_BLOB Property_Name_Blob; // BLOB to hold store property
CRYPT_DATA_BLOB Save_Store_Blob; // BLOB to hold the PKCS #7 
 // message
CRYPT_HASH_MESSAGE_PARA HashPara; // Data structure used
 // to hash a message
const BYTE* rgpbToBeHashed[1]; 
DWORD rgcbToBeHashed[1]; 
 // Arrays of messages to be
 // hashed
BYTE *pbHashedBlob;

DWORD cbHashedBlob;
 // Length of the hash BLOB
CRYPT_ALGORITHM_IDENTIFIER AlgId; // Data structure to hold the
 // hash algorithm identifier
BOOL fSignal;

//-------------------------------------------------------------------
// Initialize an event.

if(hEvent = CreateEvent(
 NULL,
 FALSE, // Manual reset is FALSE.
 FALSE, // The initial state of the event is FALSE.
 NULL))
{
 printf("An event has been created.\n");
}
else
{
 MyHandleError("The event was not created.");
}

//-------------------------------------------------------------------
// Open the MY certificate store. 

if ( hCertStore = CertOpenStore(
 CERT_STORE_PROV_SYSTEM,
 0,
 NULL,
 CERT_SYSTEM_STORE_CURRENT_USER,
 L"MY"))
{
 printf("The MY store is open.\n");
}
else
{
 MyHandleError("The MY store did not open.");
}

//-------------------------------------------------------------------
// Prepare a data structure to set a store property.
// Initialize the members of the CRYPT_DATA_BLOB.

Property_Name_Blob.pbData =(BYTE *) L"The Local MY Store";
Property_Name_Blob.cbData = 
 (wcslen((LPWSTR)Property_Name_Blob.pbData)+1) * sizeof(WCHAR);

//-------------------------------------------------------------------
// Set the store's localized name property.

if (CertSetStoreProperty(
 hCertStore,
 CERT_STORE_LOCALIZED_NAME_PROP_ID,
 0,
 &Property_Name_Blob))
{
 printf("The name of the store has been set. Continue. \n");
}
else
{
 MyHandleError("Setting the store's localized name failed.");
}
//-------------------------------------------------------------------
// Call CertGetStoreProperty a first time
// to get the length of the store name string to be returned.

if(CertGetStoreProperty(
 hCertStore,
 CERT_STORE_LOCALIZED_NAME_PROP_ID,
 NULL, // NULL on the first call 
 // to establish the length of the string to
 // to be returned
 &cbData))
{
 printf("The length of the property is %d. \n",cbData);
}
else
{
 MyHandleError("The length of the property was not calculated.");
}

//-------------------------------------------------------------------
// cbData is the length of a string to be allocated. 
// Allocate the space for the string, and call the function a 
// the second time.

if(pvData = malloc(cbData))
{
 printf("%d bytes of memory allocated.\n",cbData);
}
else
{
 MyHandleError("Memory was not allocated.");
}
if(CertGetStoreProperty(
 hCertStore,
 CERT_STORE_LOCALIZED_NAME_PROP_ID,
 pvData,
 &cbData))
{
 printf("The localized name is %S.\n",pvData);
}
else
{
 MyHandleError("CertGetStoreProperty failed.");
}
//-------------------------------------------------------------------
// Find and print the predefined localized name for the MY store.
// Note that changing the localized store name property does not 
// change the predefined localized store name.

printf("The predefined localized name of the MY "
 "store is still %S.\n", CryptFindLocalizedName(L"my"));

//-------------------------------------------------------------------
// Save the store to a PKCS #7 message in a file.

if(CertSaveStore(
 hCertStore,
 MY_ENCODING_TYPE,
 CERT_STORE_SAVE_AS_PKCS7,
 CERT_STORE_SAVE_TO_FILENAME_A,
 "pkcsseven.dat",
 0))
{
 printf("The store has been saved to a PKCS #7 message file.\n");
}
else
{
 MyHandleError("The store has not been saved.");
}

//-------------------------------------------------------------------
// Save the store to a PKCS #7 message in a file.
// Initialize the BLOB.

Save_Store_Blob.cbData=0;
Save_Store_Blob.pbData=NULL;

if(CertSaveStore(
 hCertStore,
 MY_ENCODING_TYPE,
 CERT_STORE_SAVE_AS_PKCS7,
 CERT_STORE_SAVE_TO_MEMORY,
 (void *)&Save_Store_Blob,
 0))
{
 printf("The store length, %d, has been determined.\n",
 Save_Store_Blob.cbData);
}
else
{
 MyHandleError("The store length could not be determined.");
}

if(Save_Store_Blob.pbData=(BYTE *) malloc(Save_Store_Blob.cbData))
{
 printf("Memory has been allocated.\n");
}
else
{
 MyHandleError("Memory allocation failure.");
}

if(CertSaveStore(
 hCertStore,
 MY_ENCODING_TYPE,
 CERT_STORE_SAVE_AS_PKCS7,
 CERT_STORE_SAVE_TO_MEMORY,
 (void *)&Save_Store_Blob,
 0))
{
 printf("The store has been saved to memory.\n");
}
else
{
 MyHandleError("The store was not saved to memory.");
}
//-------------------------------------------------------------------
// Retrieve the number of signers of the PKCS #7 message.

if ( dwSignerCount = CryptGetMessageSignerCount(
 MY_ENCODING_TYPE,
 Save_Store_Blob.pbData,
 Save_Store_Blob.cbData))
{
 printf("The number of signers is %d.\n",dwSignerCount);
}
else
{
 printf("The number of signers is zero or could not"
 "be found.\n");
}
//-------------------------------------------------------------------
// Open a certificate store from the PKCS #7 message stored to 
// memory.

if(hNewStore=CryptGetMessageCertificates(
 MY_ENCODING_TYPE,
 NULL,
 0,
 Save_Store_Blob.pbData,
 Save_Store_Blob.cbData))
{
 printf("A new store has been opened from a PKCS #7.\n");
}
else
{
 MyHandleError("Opening the store from the PKCS #7 "
 "message failed.");
}
//-------------------------------------------------------------------
// Next, hash the message.
// Store the message and its length in the appropriate arrays.

rgpbToBeHashed[0]=Save_Store_Blob.pbData;
rgcbToBeHashed[0]=Save_Store_Blob.cbData;

//-------------------------------------------------------------------
// Initialize the CRYPT_ALGORITHM_IDENTIFIER data structure.

AlgId.pszObjId=szOID_RSA_MD5;
AlgId.Parameters.cbData=0;

//-------------------------------------------------------------------
// Initialize the CRYPT_HASH_MESSAGE_PARA data structure.

HashPara.cbSize = sizeof(CRYPT_HASH_MESSAGE_PARA);
HashPara.dwMsgEncodingType=MY_ENCODING_TYPE;
HashPara.hCryptProv=NULL;
HashPara.HashAlgorithm=AlgId;
HashPara.pvHashAuxInfo= NULL;

//-------------------------------------------------------------------
// Calculate the size of the hashed and encoded message. 

if(CryptHashMessage(
 &HashPara,
 FALSE,
 1,
 rgpbToBeHashed,
 rgcbToBeHashed,
 NULL,
 &cbHashedBlob,
 NULL,
 NULL))
{
 printf("The size of the hashed, encoded message is %d.\n",
 cbHashedBlob);
}
else
{
 MyHandleError("The size of the hash could not be determined.");
}

//-------------------------------------------------------------------
// Allocated memory for the hashed, encoded BLOB.

if(pbHashedBlob = (BYTE*)malloc(cbHashedBlob))
{
 printf("Memory allocated for the hashed, encoded BLOB.\n");
}
else
{
 MyHandleError("Memory allocation failed.");
};

//-------------------------------------------------------------------
// Hash and encode the message.

if(CryptHashMessage(
 &HashPara,
 FALSE,
 1,
 rgpbToBeHashed,
 rgcbToBeHashed,
 pbHashedBlob,
 &cbHashedBlob,
 NULL,
 NULL))
{
 printf("The message has been hashed and encoded.\n");
}
else
{
 MyHandleError("The message was not hashed. ");
}

//-------------------------------------------------------------------
// Call CertControlStore the first time with 
// CERT_CONTROL_STORE_NOTIFY_CHANGE.

if(CertControlStore(
 hCertStore, // The store to be controlled
 0, // Not used 
 CERT_STORE_CTRL_NOTIFY_CHANGE, // Control action type
 &hEvent)) // Points to the event handle.
 // When a change is detected,
 // a signal is written to the 
 // space pointed to by
 // hHandle.
{
 printf("Notify change worked \n");
}
else
{
 MyHandleError("Notify change failed. \n");
}
//-------------------------------------------------------------------
// Wait for the store to change.

fSignal =(WAIT_OBJECT_0 == WaitForSingleObjectEx(
 hEvent,
 1000 , // Number of milliseconds to wait.
 // Use INFINITE to wait indefinitely for
 // a change.
 FALSE));

if (fSignal)
//-------------------------------------------------------------------
// The store has changed.
// Call the function a second time with CERT_STORE_CTRL_RESYNC.
 
 if(CertControlStore(
 hCertStore, // in, the store to be controlled
 0, // in, not used.
 CERT_STORE_CTRL_RESYNC, // in, control action type
 &hEvent)) // in, the handle of the event 
 // to be rearmed.
 printf("Resynchronization worked. \n");
 else
 MyHandleError("Resynchronization failed.");
else
{
 printf("The store was not changed. \n");
 printf("Resynchronization was not needed. \n");
}

// Free memory.

free (pbHashedBlob);

if(pvData)
 free(pvData);
if(CertCloseStore(
 hCertStore, 
 CERT_CLOSE_STORE_FORCE_FLAG))
{
 printf("The store has been closed. \n");
}
else
{
 MyHandleError("The store could not be closed.");
}
printf("The program ran to completion without error. \n");
} // End main

//-------------------------------------------------------------------
// This example uses the function MyHandleError, a simple error
// handling function, to print an error message to 
// the standard error (stderr) file and exit the program. 
// For most applications, replace this function with one 
// that does more extensive error reporting.

void MyHandleError(char *s)
{
 fprintf(stderr,"An error occurred in running the program.\n");
 fprintf(stderr,"%s\n",s);
 fprintf(stderr,"Error number %x.\n",GetLastError());
 fprintf(stderr,"Program terminating.\n");
 exit(1);
} // End of MyHandleError

Feedback

Was this page helpful?

Additional resources