예제 C 프로그램: 인증서 저장소에서 인증서 삭제
다음 예제에서는 시스템 인증서 저장소의 인증서를 나열하여 각 인증서의 주체 이름을 표시하며 사용자가 저장소에서 인증서를 삭제하도록 선택할 수 있습니다. 이 예제에서는 사용자로부터 인증서 저장소의 이름을 가져오므로 시스템 인증서 저장소의 콘텐츠를 유지하는 데 사용할 수 있습니다.
이 예제에서는 다음 작업 및 CryptoAPI 함수를 보여 줍니다.
- CertOpenSystemStore를 사용하여 시스템 인증서 저장소를 엽니다.
- CertEnumCertificatesInStore를 사용하여 인증서 저장소에 인증서를 나열합니다.
- CertGetNameString을 사용하여 인증서 주체의 이름을 가져옵니다.
- 인증서 주체의 이름을 CertCompareCertificateName을 사용하여 인증서 발급자의 이름과 비교합니다.
- CertComparePublicKeyInfo를 사용하여 현재 인증서의 공개 키가 이전 인증서의 공개 키와 일치하는지 확인합니다.
- CertDuplicateCertificateContext를 사용하여 인증서 컨텍스트에 대한 포인터 복제
- CertCompareCertificate를 사용하여 각 인증서의 CERT_INFO 멤버 비교
- CertDeleteCertificateFromStore를 사용하여 저장소에서 인증서를 삭제합니다.
- 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(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