範例 C 程式:憑證存放區作業
下列範例示範一些常見的 憑證存放區 作業,以及下列工作和 CryptoAPI 函式:
- 使用 CertOpenStore 和 CertCloseStore 開啟和關閉記憶體和系統存放 區。
- 使用 CertDuplicateStore複製開啟的存放區。
- 使用 CertFindCertificateInStore尋找符合某些準則的憑證。
- 使用 CertCreateCertificateCoNtext,從現有憑證的編碼部分建立新的憑證內容。
- 使用 CertAddCertificateCoNtextToStore將擷取的憑證新增至記憶體中的存放區。
- 使用 CertAddCertificateLinkToStore將憑證的連結新增至存放區。
- 將存放區儲存在記憶體中至磁片上的檔案。
- 開啟和關閉以檔案為基礎的憑證存放區。
此範例會使用 MyHandleError函式。 此函式的程式碼隨附于範例中。 此函式和其他輔助函式的程式碼也會列在常規用途 Functions底下。
此範例使用 CreateMyDACL 函式,定義于建立 DACL 主題中,以確保使用適當的 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