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 gets and sets certificate properties, and illustrates the following tasks and CryptoAPI functions.
- Opening a system store by using CertOpenSystemStore.
- Using CertEnumCertificatesInStore to list all of the certificates in the open store.
- Retrieving and printing the subject name from the certificate by using CertGetNameString.
- Setting the enhanced key usage property on certificates by using the CertAddEnhancedKeyUsageIdentifier function.
- Setting the display name property on the certificate by using CertSetCertificateContextProperty.
- Retrieving a certificate's properties by using CertGetCertificateContextProperty.
- Closing a certificate store by using CertCloseStore with the CERT_CLOSE_STORE_CHECK_FLAG flag.
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#pragma comment(lib, "crypt32.lib")
//--------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Declare functions MyHandleError and My_Wait.
// These functions are defined at the end of the file.
void MyHandleError(char *s );
void My_Wait();
//--------------------------------------------------------------------
// Begin main.
void main (void)
{
//--------------------------------------------------------------------
// This program shows all of the certificates in a
// certificate store and lists all of the property ID numbers of all
// of the certificate contexts.
// It also adds an enhanced key usage identifier to every other
// certificate.
//--------------------------------------------------------------------
// Declare and initialize local variables.
HANDLE hCertStore;
PCCERT_CONTEXT pCertContext=NULL;
CRYPT_KEY_PROV_INFO *pCryptKeyProvInfo;
char pszNameString[256];
char pszStoreName[256];
char fResponse;
char fExtra;
BYTE *pName = (BYTE *)"Temp Name.";
CRYPT_DATA_BLOB Friendly_Name_Blob={32,pName};
void* pvData;
DWORD cbData;
DWORD dwFlags = CERT_STORE_NO_CRYPT_RELEASE_FLAG;
DWORD dwPropId = 0; // 0 must be used on the first
// call to the function. After that,
// the last returned property ID is
// passed.
LPCSTR pszUsageIdentifier = szOID_RSA_RC4;
int count = 0;
fprintf(stderr,"Please enter the store name :");
scanf_s("%s",pszStoreName);
fprintf(stderr,"The store name is %s .\n",pszStoreName);
My_Wait();
//--------------------------------------------------------------------
// Open the named system certificate store.
if (!( hCertStore = CertOpenSystemStore(
NULL,
pszStoreName)))
{
MyHandleError("Store not opened.");
}
//--------------------------------------------------------------------
// The file is open. Continue.
// In a loop, use CertEnumCertificatesInStore to get the each
// certificate in the store.
while(pCertContext= CertEnumCertificatesInStore(
hCertStore,
pCertContext))
{
//--------------------------------------------------------------------
// First, retrieve and print the subject name from the certificate.
if(CertGetNameString(
pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
0,
NULL,
pszNameString,
128))
{
printf("\nNew Cert for %s \n",pszNameString);
}
else
{
printf("The get name failed.\n");
}
//--------------------------------------------------------------------
// Set the enhanced key usage property on every other certificate.
if(count == 0)
{
count++;
if(CertAddEnhancedKeyUsageIdentifier(
pCertContext,
pszUsageIdentifier))
{
printf("Enhanced key usage set.\n");
}
else
{
printf("Enhanced key usage was not set.\n");
}
}
else
//--------------------------------------------------------------------
// Do not set the usage, but reset the counter so that the property
// will be set on the next certificate.
// Ask if the user would like to set a display name.
{
printf("Would you like to set the display name ?");
scanf_s("%c%c",&fResponse,&fExtra);
if(fResponse == 'y')
{
if(CertSetCertificateContextProperty(
pCertContext,
CERT_FRIENDLY_NAME_PROP_ID,
0,
&Friendly_Name_Blob))
{
printf("A name has been set.\n");
}
else
{
printf("The display name was not set.\n");
}
}
count = 0;
}
//--------------------------------------------------------------------
// In a loop, find all of the property IDs for the given certificate.
// The loop continues until the CertEnumCertificateContextProperties
// returns 0.
while(dwPropId = CertEnumCertificateContextProperties(
pCertContext, // the context whose properties are to be listed.
dwPropId)) // number of the last property found. Must be
// 0 to find the first property ID.
{
//--------------------------------------------------------------------
// Each time through the loop, a property ID has been found.
// Print the property number and information about the property.
printf("Property # %d found->", dwPropId);
switch(dwPropId)
{
case CERT_FRIENDLY_NAME_PROP_ID:
{
//--------------------------------------------------------------------
// Retrieve the actual display name certificate property.
// First, get the length of the property setting the
// pvData parameter to NULL to get a value for cbData
// to be used to allocate memory for the pvData buffer.
printf("FRIENDLY_NAME_PROP_ID ");
if(!(CertGetCertificateContextProperty(
pCertContext,
dwPropId,
NULL,
&cbData)))
{
MyHandleError("Call #1 to property length failed.");
}
//--------------------------------------------------------------------
// The call succeeded. Use the size to allocate memory for the
// property.
if(!(pvData = (void*)malloc(cbData)))
{
MyHandleError("Memory allocation failed.");
}
//--------------------------------------------------------------------
// Allocation succeeded. Retrieve the property data.
if(!(CertGetCertificateContextProperty(
pCertContext,
dwPropId,
pvData,
&cbData)))
{
MyHandleError("Call #2 getting the data failed.");
}
else
{
printf("\n The display name is -> %s.", pvData);
free(pvData);
}
break;
}
case CERT_SIGNATURE_HASH_PROP_ID:
{
printf("Signature hash ID. ");
break;
}
case CERT_KEY_PROV_HANDLE_PROP_ID:
{
printf("KEY PROVE HANDLE.");
break;
}
case CERT_KEY_PROV_INFO_PROP_ID:
{
printf("KEY PROV INFO PROP ID.");
if(!(CertGetCertificateContextProperty(
pCertContext, // A pointer to the certificate
// where the property will be set.
dwPropId, // An identifier of the property to get.
// In this case,
// CERT_KEY_PROV_INFO_PROP_ID
NULL, // NULL on the first call to get the
// length.
&cbData))) // The number of bytes that must be
// allocated for the structure.
{
MyHandleError("The property length was not retrieved.");
}
if(!(pCryptKeyProvInfo =
(CRYPT_KEY_PROV_INFO *)malloc(cbData)))
{
MyHandleError("Error in allocation of memory.");
}
if(CertGetCertificateContextProperty(
pCertContext,
dwPropId,
pCryptKeyProvInfo,
&cbData))
{
printf("\n The current key container is %S.",
pCryptKeyProvInfo->pwszContainerName);
free(pCryptKeyProvInfo);
}
else
{
free(pCryptKeyProvInfo);
MyHandleError("The property was not retrieved.");
}
break;
}
case CERT_SHA1_HASH_PROP_ID:
{
printf("SHA1 HASH id.");
break;
}
case CERT_MD5_HASH_PROP_ID:
{
printf("md5 hash id. ");
break;
}
case CERT_KEY_CONTEXT_PROP_ID:
{
printf("KEY CONTEXT PROP id.");
break;
}
case CERT_KEY_SPEC_PROP_ID:
{
printf("KEY SPEC PROP id.");
break;
}
case CERT_ENHKEY_USAGE_PROP_ID:
{
printf("ENHKEY USAGE PROP id.");
break;
}
case CERT_NEXT_UPDATE_LOCATION_PROP_ID:
{
printf("NEXT UPDATE LOCATION PROP id.");
break;
}
case CERT_PVK_FILE_PROP_ID:
{
printf("PVK FILE PROP id. ");
break;
}
case CERT_DESCRIPTION_PROP_ID:
{
printf("DESCRIPTION PROP id. ");
break;
}
case CERT_ACCESS_STATE_PROP_ID:
{
printf("ACCESS STATE PROP id. ");
break;
}
case CERT_SMART_CARD_DATA_PROP_ID:
{
printf("SMAART_CARD DATA PROP id. ");
break;
}
case CERT_EFS_PROP_ID:
{
printf("EFS PROP id. ");
break;
}
case CERT_FORTEZZA_DATA_PROP_ID:
{
printf("FORTEZZA DATA PROP id.");
break;
}
case CERT_ARCHIVED_PROP_ID:
{
printf("ARCHIVED PROP id.");
break;
}
case CERT_KEY_IDENTIFIER_PROP_ID:
{
printf("KEY IDENTIFIER PROP id. ");
break;
}
case CERT_AUTO_ENROLL_PROP_ID:
{
printf("AUTO ENROLL id. ");
break;
}
} // end switch
printf("\n");
} // end the inner while loop. This is the end of the display of
// a single property of a single certificate.
My_Wait();
} // end the outer while loop. Move on to the next certificate.
//--------------------------------------------------------------------
// Free Memory and close the open store.
if(pCertContext)
{
CertFreeCertificateContext(pCertContext);
}
CertCloseStore(hCertStore,0);
printf("The function completed successfully.\n");
}
//--------------------------------------------------------------------
// Define functions MyHandleError and My_Wait.
void MyHandleError( char *s)
{
printf("%s\n",s);
exit(1);
}
void My_Wait()
{
printf("Hit enter to continue.");
getchar();
}