Programma C di esempio: eliminazione di certificati da un archivio certificati
L'esempio seguente elenca i certificati in un archivio certificati di sistema, visualizzando il nome dell'oggetto di ogni certificato e consente all'utente di scegliere di eliminare tutti i certificati dall'archivio. L'esempio ottiene il nome dell'archivio certificati dall'utente e può quindi essere usato per mantenere il contenuto di qualsiasi archivio certificati di sistema.
Questo esempio illustra le attività e le funzioni CryptoAPI seguenti:
- Apertura di un archivio certificati di sistema tramite CertOpenSystemStore.
- Elenco dei certificati in un archivio certificati tramite CertEnumCertificatesInStore.
- Ottenere il nome dell'oggetto di un certificato usando CertGetNameString.
- Confronto tra il nome dell'oggetto del certificato e il nome dell'autorità emittente del certificato tramite CertCompareCertificateName.
- Verifica per determinare se la chiave pubblica del certificato corrente corrisponde alla chiave pubblica di un certificato precedente usando CertComparePublicKeyInfo.
- Duplicare un puntatore a un contesto di certificato usando CertDuplicateCertificateContext.
- Confronto tra i membri CERT_INFO di ogni certificato tramite CertCompareCertificate.
- Eliminazione di un certificato da un archivio tramite CertDeleteCertificateFromStore.
- Chiusura di un archivio certificati tramite CertCloseStore.
Questo esempio ottiene il nome di un archivio certificati di sistema dall'utente, apre tale archivio e passa attraverso i certificati in tale archivio. Per ogni certificato, viene visualizzato il nome dell'oggetto del certificato e all'utente viene assegnata un'opzione per eliminare il certificato.
#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(void)
{
//-------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Declare and initialize variables.
HANDLE hStoreHandle;
PCCERT_CONTEXT pCertContext=NULL;
PCCERT_CONTEXT pDupCertContext;
PCERT_PUBLIC_KEY_INFO pOldPubKey = NULL;
PCERT_PUBLIC_KEY_INFO pNewPubKey;
char pszStoreName[256];
char pszNameString[256];
char fResponse ='n';
char x;
//-------------------------------------------------------------------
// Get the name of the certificate store to open.
printf("This program maintains the contents of a certificate\n");
printf("store by allowing you to delete any excess certificates\n");
printf("from a store. \n\n");
printf("Please enter the name of the system store to maintain:");
fgets(pszStoreName, 255, stdin);
if (pszStoreName[strlen(pszStoreName) - 1] =='\n')
pszStoreName[strlen(pszStoreName) - 1] = '\0';
printf("Certificates will be deleted from "
"the %s store.\n",pszStoreName);
//-------------------------------------------------------------------
// Open a system certificate store.
if ( hStoreHandle = CertOpenSystemStore(
NULL,
pszStoreName))
{
printf("The %s store has been opened. \n", pszStoreName);
}
else
{
MyHandleError("The store was not opened.");
}
//-------------------------------------------------------------------
// Find the certificates in the system store.
while(pCertContext= CertEnumCertificatesInStore(
hStoreHandle,
pCertContext)) // on the first call to the function,
// this parameter is NULL
// on all subsequent
// calls, it is the last pointer returned by
// the function
{
//-------------------------------------------------------------------
// Get and display the name of the subject of the certificate.
if(CertGetNameString(
pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
0,
NULL,
pszNameString,
128))
{
printf("\nCertificate for %s \n",pszNameString);
}
else
{
MyHandleError("CertGetName failed.");
}
//-------------------------------------------------------------------
// Check to determine whether the issuer
// and the subject are the same.
if(CertCompareCertificateName(
MY_ENCODING_TYPE,
&(pCertContext->pCertInfo->Issuer),
&(pCertContext->pCertInfo->Subject)))
{
printf("The certificate subject and issuer are the same.\n");
}
else
{
printf("The certificate subject and issuer "
"are not the same.\n");
}
//--------------------------------------------------------------------
// Determine whether this certificate's public key matches
// the public key of the last certificate.
pNewPubKey = &(pCertContext->pCertInfo->SubjectPublicKeyInfo);
if(pOldPubKey)
if(CertComparePublicKeyInfo(
MY_ENCODING_TYPE,
pOldPubKey,
pNewPubKey))
{
printf("The public keys are the same.\n");
}
else
{
printf("This certificate has a different public key.\n");
}
//-------------------------------------------------------------------
// Reset the old key.
pOldPubKey = pNewPubKey;
//-------------------------------------------------------------------
// Determine whether this certificate is to be deleted.
printf("Would you like to delete this certificate? (y/n) ");
fResponse = getchar();
if(fResponse == 'y')
{
//----------------------------------------------------------------
// Create a duplicate pointer to the certificate to be
// deleted. In this way, the original pointer is not freed
// when the certificate is deleted from the store
// and the enumeration of the certificates in the store can
// continue. If the original pointer is used, after the
// certificate is deleted, the enumeration loop stops.
if(pDupCertContext = CertDuplicateCertificateContext(
pCertContext))
{
printf("A duplicate pointer was created. Continue. \n");
}
else
{
MyHandleError("Duplication of the certificate "
"pointer failed.");
}
//-------------------------------------------------------------------
// Compare the pCertInfo members of the two certificates
// to determine whether they are identical.
if(CertCompareCertificate(
X509_ASN_ENCODING,
pDupCertContext->pCertInfo,
pCertContext->pCertInfo))
{
printf("The two certificates are identical. \n");
}
else
{
printf("The two certificates are not identical. \n");
}
//-------------------------------------------------------------------
// Delete the certificate.
if(CertDeleteCertificateFromStore(
pDupCertContext))
{
printf("The certificate has been deleted. Continue. \n");
}
else
{
printf("The deletion of the certificate failed.\n");
}
} // end if
//-------------------------------------------------------------------
// Clear the input buffer.
x = getchar();
} // end while
//-------------------------------------------------------------------
// Clean up.
CertCloseStore(
hStoreHandle,
0);
printf("The program ran to completion successfully. \n");
} // end main
//-------------------------------------------------------------------
// This example uses the function MyHandleError, a simple error
// handling function to print an error message 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 MyHandleError