Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Im folgenden Beispiel wird ein nicht standardmäßiges Zertifikatkettenmodul erstellt und installiert. Das Modul wird verwendet, um Zertifikatketten für jedes der Zertifikate in einem Zertifikatspeicherzu erstellen.
In diesem Beispiel werden die folgenden Aufgaben und CryptoAPI--Funktionen veranschaulicht:
- Vorbereiten der Erstellung eines nicht standardmäßigen Zertifikatkettenmoduls durch Deklarieren und Initialisieren einer CERT_CHAIN_ENGINE_CONFIG Datenstruktur.
- Erstellen der Suchmaschine mit CertCreateCertificateChainEngine.
- Verwenden sie CertOpenSystemStore, um den "Mein Systemspeicher" zu öffnen.
- Abrufen aller Zertifikate aus dem geöffneten Speicher mithilfe von CertEnumCertificatesInStore- in einer Schleife.
- Rufen Sie für jedes Zertifikat im geöffneten Speicher den Antragstellernamen aus dem Zertifikat mithilfe CertGetNameString-ab.
- Erstellen einer Zertifikatkette für jedes Zertifikat mithilfe von CertGetCertificateChain.
- Erstellen eines Duplikats der Zertifikatkette mithilfe von CertDuplicateCertificateChain.
- Verwenden von CertFreeCertificateChain, um jede Kette freizugeben, bevor die nächste Kette erstellt wird.
#pragma comment(lib, "crypt32.lib")
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
void MyHandleError(char *s);
void main(void)
{
//---------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Declare and initialize variables.
HCERTCHAINENGINE hChainEngine;
CERT_CHAIN_ENGINE_CONFIG ChainConfig;
PCCERT_CHAIN_CONTEXT pChainContext;
PCCERT_CHAIN_CONTEXT pDupContext;
HCERTSTORE hCertStore;
PCCERT_CONTEXT pCertContext = NULL;
CERT_ENHKEY_USAGE EnhkeyUsage;
CERT_USAGE_MATCH CertUsage;
CERT_CHAIN_PARA ChainPara;
DWORD dwFlags=0;
LPWSTR pszNameString;
//---------------------------------------------------------
// Initialize data structures.
if(!(pszNameString=(LPWSTR)malloc(256)))
MyHandleError("Memory allocation failed.");
EnhkeyUsage.cUsageIdentifier = 0;
EnhkeyUsage.rgpszUsageIdentifier=NULL;
CertUsage.dwType = USAGE_MATCH_TYPE_AND;
CertUsage.Usage = EnhkeyUsage;
ChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
ChainPara.RequestedUsage=CertUsage;
ChainConfig.cbSize = sizeof(CERT_CHAIN_ENGINE_CONFIG);
ChainConfig.hRestrictedRoot= NULL ;
ChainConfig.hRestrictedTrust= NULL ;
ChainConfig.hRestrictedOther= NULL ;
ChainConfig.cAdditionalStore=0 ;
ChainConfig.rghAdditionalStore = NULL ;
ChainConfig.dwFlags = CERT_CHAIN_CACHE_END_CERT;
ChainConfig.dwUrlRetrievalTimeout= 0 ;
ChainConfig.MaximumCachedCertificates=0 ;
ChainConfig.CycleDetectionModulus = 0;
//---------------------------------------------------------
// Create the nondefault certificate chain engine.
if(CertCreateCertificateChainEngine(
&ChainConfig,
&hChainEngine))
{
printf("A chain engine has been created.\n");
}
else
{
MyHandleError("The engine creation function failed.");
}
// Open the My system store.
if(hCertStore=CertOpenSystemStore(NULL,L"MY"))
{
printf("The MY Store is open.\n");
}
else
{
MyHandleError("The MY system store did not open.");
}
//-------------------------------------------------------
// Loop through the certificates in the store,
// and create a chain for each.
while(pCertContext = CertEnumCertificatesInStore(
hCertStore,
pCertContext))
{
//-------------------------------------------------------------------
// Get and display the name of subject of the certificate.
if(CertGetNameString(
pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
0,
NULL,
pszNameString,
128))
{
printf("\nCertificate for %s found.\n",pszNameString);
}
else
{
MyHandleError("CertGetName failed.");
}
//-------------------------------------------------------------------
// Build a chain using CertGetCertificateChain
// and the certificate retrieved.
if(CertGetCertificateChain(
NULL, // use the default chain engine
pCertContext, // pointer to the end certificate
NULL, // use the default time
NULL, // search no additional stores
&ChainPara, // use AND logic and enhanced key usage
// as indicated in the ChainPara
// data structure
dwFlags,
NULL, // currently reserved
&pChainContext)) // return a pointer to the chain created
{
printf("The chain has been created. \n");
}
else
{
MyHandleError("The chain could not be created.");
}
//---------------------------------------------------------------
// Display some of the contents of the chain.
printf("The size of the chain context "
"is %d. \n",pChainContext->cbSize);
printf("%d simple chains found.\n",pChainContext->cChain);
printf("\nError status for the chain:\n");
DWORD errorStatus = pChainContext->TrustStatus->dwErrorStatus;
if((errorStatus & CERT_TRUST_IS_NOT_TIME_VALID) != 0)
{
printf("This certificate or one of the certificates in the "
"certificate chain is not time-valid.\n");
}
if((errorStatus & CERT_TRUST_IS_REVOKED) != 0)
{
printf("Trust for this certificate or one of the certificates "
"in the certificate chain has been revoked.\n");
}
if((errorStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID) != 0)
{
printf("The certificate or one of the certificates in the "
"certificate chain does not have a valid signature.\n");
}
if((errorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE) != 0)
{
printf("The certificate or certificate chain is not valid "
"in its proposed usage.\n");
}
if((errorStatus & CERT_TRUST_IS_UNTRUSTED_ROOT) != 0)
{
printf("The certificate or certificate chain is based "
"on an untrusted root.\n");
}
if((errorStatus & CERT_TRUST_REVOCATION_STATUS_UNKNOWN) != 0)
{
printf("The revocation status of the certificate or one of the"
"certificates in the certificate chain is unknown.\n");
}
if((errorStatus & CERT_TRUST_IS_CYCLIC) != 0)
{
printf("One of the certificates in the chain was issued by a "
"certification authority that the original certificate "
"had certified.\n");
}
if((errorStatus & CERT_TRUST_IS_PARTIAL_CHAIN) != 0)
{
printf("The certificate chain is not complete.\n");
}
if((errorStatus & CERT_TRUST_CTL_IS_NOT_TIME_VALID) != 0)
{
printf("A CTL used to create this chain was not time-valid.\n");
}
if((errorStatus & CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID) != 0)
{
printf("A CTL used to create this chain did not have a valid "
"signature.\n");
}
if((errorStatus & CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE) != 0)
{
printf("A CTL used to create this chain did not have a valid "
"signature.\n");
}
else // CERT_TRUST_NO_ERROR
{
printf("No error found for this certificate or chain.\n");
}
printf("\nInfo status for the chain:\n");
DWORD infoStatus = pChainContext->TrustStatus.dwInfoStatus;
if((infoStatus & CERT_TRUST_HAS_EXACT_MATCH_ISSUER) != 0)
{
printf("An exact match issuer certificate has been found for "
"this certificate.\n");
}
if((infoStatus & CERT_TRUST_HAS_KEY_MATCH_ISSUER) != 0)
{
printf("A key match issuer certificate has been found for this "
"certificate.\n");
}
if((infoStatus & CERT_TRUST_HAS_NAME_MATCH_ISSUER) != 0)
{
printf("A name match issuer certificate has been found for this "
"certificate.\n");
}
if((infoStatus & CERT_TRUST_IS_SELF_SIGNED) != 0)
{
printf("This certificate is self-signed.\n");
}
if((infoStatus & CERT_TRUST_IS_COMPLEX_CHAIN) != 0)
{
printf("The certificate chain created is a complex chain.\n");
}
else // No dwInfoStatus bits set
{
printf("No information status reported.\n");
}
//-------------------------------------------------------------------
// Duplicate the original chain.
if(pDupContext = CertDuplicateCertificateChain(
pChainContext ))
{
printf("Duplicated the chain.\n");
}
else
{
printf("Duplication failed.\n");
}
//-------------------------------------------------------------------
// Free both chains.
CertFreeCertificateChain(pDupContext);
printf("The duplicate chains is free.\n");
CertFreeCertificateChain(pChainContext);
printf("The Original chain is free.\n");
printf("\nPress Enter to continue.");
getchar();
} // end while loop
printf("\nThere are no more certificates in the store. \n");
//---------------------------------------------------------
// Free the chain engine.
CertFreeCertificateChainEngine(hChainEngine);
printf("The chain engine has been released.\n");
// Free memory for pszNameString.
if(pszNameString)
free(pszNameString);
printf("The demo program ran to completion without error.\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