예제 C 프로그램: 인증서 저장소 작업
다음 예제에서는 일반적인 인증서 저장소 작업과 다음 작업 및 CryptoAPI 함수를 보여 줍니다.
- CertOpenStore 및 CertCloseStore를 사용하여 메모리 및 시스템 저장소를 열고 닫습니다.
- CertDuplicateStore를 사용하여 열린 저장소 복제
- CertFindCertificateInStore를 사용하여 몇 가지 조건을 충족하는 인증서를 저장합니다.
- CertCreateCertificateContext를 사용하여 기존 인증서의 인코딩된 부분에서 새 인증서 컨텍스트를 만듭니다.
- CertAddCertificateContextToStore를 사용하여 검색된 인증서를 메모리의 저장소에 추가합니다.
- CertAddCertificateLinkToStore를 사용하여 인증서에 대한 링크를 저장소에 추가합니다.
- 메모리의 저장소를 디스크의 파일에 저장합니다.
- 파일 기반 인증서 저장소 열기 및 닫기
이 예제에서는 MyHandleError 함수를 사용합니다. 이 함수의 코드는 샘플에 포함되어 있습니다. 이 함수 및 기타 보조 함수에 대한 코드도 범용 Functions 아래에 나열됩니다.
이 예제에서는 DACL 만들기 항목에 정의된 CreateMyDACL 함수를 사용하여 열려 있는 파일이 적절한 DACL로 생성되도록 합니다.
이 예제에서는 메모리에 인증서 저장소를 만듭니다. 시스템 저장소가 열리고 중복됩니다. 시스템 저장소에서 인증서를 검색합니다. 검색된 인증서의 인코딩된 부분에서 새 인증서가 만들어집니다. 검색된 인증서가 메모리 저장소에 추가됩니다. 두 번째 인증서는 내 저장소에서 검색되고 해당 인증서에 대한 링크가 메모리 저장소에 추가됩니다. 그런 다음 인증서와 링크가 메모리 저장소에서 검색되고 메모리가 디스크에 저장됩니다. 모든 저장소와 파일이 닫힙니다. 다음으로 파일 저장소가 다시 열리고 인증서 링크에 대한 검색이 수행됩니다. 이 프로그램의 성공은 사용 가능한 내 저장소에 따라 달라집니다. 해당 저장소에는 제목이 "Insert_cert_subject_name1"인 인증서와 "Insert_cert_subject_name2"라는 제목의 두 번째 인증서가 포함되어야 합니다. 주체의 이름은 내 저장소에 있는 것으로 알려진 인증서 주체의 이름으로 변경해야 합니다.
#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.
HCERTSTORE hSystemStore; // System store handle
HCERTSTORE hMemoryStore; // Memory store handle
HCERTSTORE hDuplicateStore; // Handle for a store to be
// created
// as a duplicate of an open
// store
PCCERT_CONTEXT pDesiredCert = NULL; // Set to NULL for the first
// call to
// CertFindCertificateInStore
PCCERT_CONTEXT pCertContext;
HANDLE hStoreFileHandle ; // Output file handle
LPWSTR pszFileName = L"TestStor.sto"; // Output file name
SECURITY_ATTRIBUTES sa; // For DACL
//-------------------------------------------------------------------
// Open a new certificate store in memory.
if(hMemoryStore = CertOpenStore(
CERT_STORE_PROV_MEMORY, // Memory store
0, // Encoding type
// not used with a memory store
NULL, // Use the default provider
0, // No flags
NULL)) // Not needed
{
printf("Opened a memory store. \n");
}
else
{
MyHandleError( "Error opening a memory store.");
}
//-------------------------------------------------------------------
// Open the My system store using CertOpenStore.
if(hSystemStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM, // System store will be a
// virtual store
0, // Encoding type not needed
// with this PROV
NULL, // Accept the default HCRYPTPROV
CERT_SYSTEM_STORE_CURRENT_USER,
// Set the system store location in the
// registry
L"MY")) // Could have used other predefined
// system stores
// including Trust, CA, or Root
{
printf("Opened the MY system store. \n");
}
else
{
MyHandleError( "Could not open the MY system store.");
}
//-------------------------------------------------------------------
// Create a duplicate of the My store.
if(hDuplicateStore = CertDuplicateStore(hSystemStore))
{
printf("The MY store is duplicated.\n");
}
else
{
printf("Duplication of the MY store failed.\n.");
}
//-------------------------------------------------------------------
// Close the duplicate store.
if(hDuplicateStore)
CertCloseStore(
hDuplicateStore,
CERT_CLOSE_STORE_CHECK_FLAG);
//-------------------------------------------------------------------
// Get a certificate that has the string "Insert_cert_subject_name1"
// in its subject.
if(pDesiredCert=CertFindCertificateInStore(
hSystemStore,
MY_ENCODING_TYPE, // Use X509_ASN_ENCODING
0, // No dwFlags needed
CERT_FIND_SUBJECT_STR, // Find a certificate with a
// subject that matches the
// string in the next parameter
L"Insert_cert_subject_name1", // The Unicode string to be found
// in a certificate's subject
NULL)) // NULL for the first call to the
// function
// In all subsequent
// calls, it is the last pointer
// returned by the function
{
printf("The desired certificate was found. \n");
}
else
{
MyHandleError("Could not find the desired certificate.");
}
//-------------------------------------------------------------------
// pDesiredCert is a pointer to a certificate with a subject that
// includes the string "Insert_cert_subject_name1", the string is
// passed as parameter #5 to the function.
//------------------------------------------------------------------
// Create a new certificate from the encoded part of
// an available certificate.
if(pCertContext = CertCreateCertificateContext(
MY_ENCODING_TYPE , // Encoding type
pDesiredCert->pbCertEncoded, // Encoded data from
// the certificate retrieved
pDesiredCert->cbCertEncoded)) // Length of the encoded data
{
printf("A new certificate has been created.\n");
}
else
{
MyHandleError("A new certificate could not be created.");
}
//-------------------------------------------------------------------
// Add the certificate from the My store to the new memory store.
if(CertAddCertificateContextToStore(
hMemoryStore, // Store handle
pDesiredCert, // Pointer to a certificate
CERT_STORE_ADD_USE_EXISTING,
NULL))
{
printf("Certificate added to the memory store. \n");
}
else
{
MyHandleError("Could not add the certificate "
"to the memory store.");
}
//-------------------------------------------------------------------
// Find a different certificate in the My store, and add to it a link
// to the memory store.
//-------------------------------------------------------------------
// Find the certificate context just added to the memory store.
if(pDesiredCert)
CertFreeCertificateContext(pDesiredCert);
if(pDesiredCert=CertFindCertificateInStore(
hSystemStore,
MY_ENCODING_TYPE, // Use X509_ASN_ENCODING
0, // no dwFlags needed
CERT_FIND_SUBJECT_STR, // Find a certificate with a
// subject that matches the
// string in the next parameter
L"Insert_cert_subject_name2",// The Unicode string to be found
// in a certificate's subject
NULL)) // NULL for the first call to the
// function
// In all subsequent
// calls, it is the last pointer
// returned by the function
{
printf("The second certificate was found. \n");
}
else
{
MyHandleError("Could not find the second certificate.");
}
//-------------------------------------------------------------------
// Add a link to the second certificate from the My store to
// the new memory store.
if(CertAddCertificateLinkToStore(
hMemoryStore, // Store handle
pDesiredCert, // Pointer to a certificate
CERT_STORE_ADD_USE_EXISTING,
NULL))
{
printf("Certificate link added to the memory store. \n");
}
else
{
MyHandleError("Could not add the certificate link to the "
"memory store.");
}
//--------------------------------------------------------------------
// Find the first certificate in the memory store.
if(pDesiredCert)
CertFreeCertificateContext(pDesiredCert);
if(pDesiredCert=CertFindCertificateInStore(
hMemoryStore,
MY_ENCODING_TYPE, // Use X509_ASN_ENCODING
0, // No dwFlags needed
CERT_FIND_SUBJECT_STR, // Find a certificate with a
// subject that matches the string
// in the next parameter
L"Insert_cert_subject_name1",// The Unicode string to be found
// in a certificate's subject
NULL)) // NULL for the first call to the
// function
// In all subsequent
// calls, it is the last pointer
// returned by the function
{
printf("The desired certificate was found in the "
"memory store. \n");
}
else
{
printf("Certificate not in the memory store.\n");
}
//-------------------------------------------------------------------
// Find the certificate link in the memory store.
if(pDesiredCert)
CertFreeCertificateContext(pDesiredCert);
if(pDesiredCert=CertFindCertificateInStore(
hMemoryStore,
MY_ENCODING_TYPE, // Use X509_ASN_ENCODING
0, // No dwFlags needed
CERT_FIND_SUBJECT_STR, // Find a certificate with a
// subject that matches the
// string in the next parameter
L"Insert_cert_subject_name1",// The Unicode string to be found
// in a certificate's subject
NULL)) // NULL for the first call to the
// function
// In all subsequent
// calls, it is the last pointer
// returned by the function
{
printf("The certificate link was found in the memory store. \n");
}
else
{
printf("The certificate link was not in the memory store.\n");
}
//-------------------------------------------------------------------
// Create a file in which to save the new store and certificate.
// Create a DACL for the file.
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
// Call the function to set the DACL. The DACL
// is set in the SECURITY_ATTRIBUTES
// lpSecurityDescriptor member.
// if !CreateMyDACL(&sa), call MyHandleError("CreateMyDACL failed.");
if(hStoreFileHandle = CreateFile(
pszFileName, // File path
GENERIC_WRITE, // Access mode
0, // Share mode
&sa, // Security
CREATE_ALWAYS, // How to create the file
FILE_ATTRIBUTE_NORMAL,
// File attributes
NULL)) // Template
{
printf("Created a new file on disk. \n");
}
else
{
MyHandleError("Could not create a file on disk.");
}
//-------------------------------------------------------------------
// hStoreFileHandle is the output file handle.
// Save the memory store and its certificate to the output file.
if( CertSaveStore(
hMemoryStore, // Store handle
0, // Encoding type not needed here
CERT_STORE_SAVE_AS_STORE,
CERT_STORE_SAVE_TO_FILE,
hStoreFileHandle, // This is the handle of an open disk file
0)) // dwFlags
// No flags needed here
{
printf("Saved the memory store to disk. \n");
}
else
{
MyHandleError("Could not save the memory store to disk.");
}
//-------------------------------------------------------------------
// Close the stores and the file. Reopen the file store,
// and check its contents.
if(hMemoryStore)
CertCloseStore(
hMemoryStore,
CERT_CLOSE_STORE_CHECK_FLAG);
if(hSystemStore)
CertCloseStore(
hSystemStore,
CERT_CLOSE_STORE_CHECK_FLAG);
if(hStoreFileHandle)
CloseHandle(hStoreFileHandle);
printf("All of the stores and files are closed. \n");
//-------------------------------------------------------------------
// Reopen the file store.
if(hMemoryStore = CertOpenStore(
CERT_STORE_PROV_FILENAME, // Store provider type
MY_ENCODING_TYPE, // If needed, use the usual
// encoding types
NULL, // Use the default HCRYPTPROV
0, // Accept the default for all
// dwFlags
L"TestStor.sto" )) // The name of an existing file
// as a Unicode string
{
printf("The file store has been reopened. \n");
}
else
{
printf("The file store could not be reopened. \n");
}
//-------------------------------------------------------------------
// Find the certificate link in the reopened file store.
if(pDesiredCert)
CertFreeCertificateContext(pDesiredCert);
if(pDesiredCert=CertFindCertificateInStore(
hMemoryStore,
MY_ENCODING_TYPE, // Use X509_ASN_ENCODING
0, // No dwFlags needed
CERT_FIND_SUBJECT_STR, // Find a certificate with a
// subject that matches the string
// in the next parameter
L"Insert_cert_subject_name1",// The Unicode string to be found
// in a certificate's subject
NULL)) // NULL for the first call to the
// function
// In all subsequent
// calls, it is the last pointer
// returned by the function
{
printf("The certificate link was found in the file store. \n");
}
else
{
printf("The certificate link was not in the file store.\n");
}
//-------------------------------------------------------------------
// Clean up memory and end.
if(pDesiredCert)
CertFreeCertificateContext(pDesiredCert);
if(hMemoryStore)
CertCloseStore(
hMemoryStore,
CERT_CLOSE_STORE_CHECK_FLAG);
if(hSystemStore)
CertCloseStore(
hSystemStore,
CERT_CLOSE_STORE_CHECK_FLAG);
if(hStoreFileHandle)
CloseHandle(hStoreFileHandle);
printf("All of the stores and files are closed. \n");
return;
} // 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