Beispiel-C-Programm: Konvertieren von Namen aus Zertifikaten in ASN.1 und Zurück
Im folgenden Beispiel werden die Zertifikate in einem Zertifikatspeicher aufgelistet, der Antragsteller und der Benutzer jedes Zertifikats angezeigt und der Antragstellername aus jedem Zertifikat in die asn.1-codierte Form der abstrakten Syntax notation One (ASN.1) konvertiert und dann wieder in die decodierte Form konvertiert.
Dieses Beispiel zeigt die folgenden Aufgaben und CryptoAPI-Funktionen :
- Öffnen eines Systemspeichers mit CertOpenSystemStore.
- Verwenden von CertEnumCertificatesInStore zum Abrufen des ersten Zertifikats aus dem geöffneten Speicher.
- Verwenden von CertGetNameString zum Abrufen des Antragstellernamens und des Benutzernamens aus dem Zertifikat.
- Verwenden von CertNameToStr zum Konvertieren des Antragstellernamens aus dem Zertifikat in die ASN.1-codierte Form.
- Verwenden von CertStrToName zum Konvertieren einer ASN.1-codierten Zeichenfolge in ihre decodierte Form.
- Schließen eines Zertifikatspeichers mithilfe von CertCloseStore mit dem flag CERT_CLOSE_STORE_CHECK_FLAG .
#pragma comment(lib, "crypt32.lib")
//-------------------------------------------------------------------
// Example C Program:
// Converting a name from a certificate to an ASN.1 encoded string
// and back.
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <Wincrypt.h>
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define MY_STRING_TYPE (CERT_OID_NAME_STR)
//-------------------------------------------------------------------
// Declare auxiliary functions
void MyHandleError(LPTSTR);
void Local_wait();
void main(void)
{
HCERTSTORE hCertStore;
PCCERT_CONTEXT pCertContext;
//---------------------------------------------------------------
// Begin Processing by opening a certificate store.
if(!(hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
MY_ENCODING_TYPE,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY")))
{
MyHandleError(TEXT("The MY system store did not open."));
}
//---------------------------------------------------------------
// Loop through the certificates in the store.
// For each certificate,
// get and print the name of the
// certificate subject and issuer.
// convert the subject name from the certificate
// to an ASN.1 encoded string and print the
// octets from that string.
// convert the encoded string back into its form
// in the certificate.
pCertContext = NULL;
while(pCertContext = CertEnumCertificatesInStore(
hCertStore,
pCertContext))
{
LPTSTR pszString;
LPTSTR pszName;
DWORD cbSize;
CERT_BLOB blobEncodedName;
//-----------------------------------------------------------
// Get and display
// the name of subject of the certificate.
if(!(cbSize = CertGetNameString(
pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
0,
NULL,
NULL,
0)))
{
MyHandleError(TEXT("CertGetName 1 failed."));
}
if(!(pszName = (LPTSTR)malloc(cbSize * sizeof(TCHAR))))
{
MyHandleError(TEXT("Memory allocation failed."));
}
if(CertGetNameString(
pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
0,
NULL,
pszName,
cbSize))
{
_tprintf(TEXT("\nSubject -> %s.\n"), pszName);
//-------------------------------------------------------
// Free the memory allocated for the string.
free(pszName);
}
else
{
MyHandleError(TEXT("CertGetName failed."));
}
//-----------------------------------------------------------
// Get and display
// the name of Issuer of the certificate.
if(!(cbSize = CertGetNameString(
pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
CERT_NAME_ISSUER_FLAG,
NULL,
NULL,
0)))
{
MyHandleError(TEXT("CertGetName 1 failed."));
}
if(!(pszName = (LPTSTR)malloc(cbSize * sizeof(TCHAR))))
{
MyHandleError(TEXT("Memory allocation failed."));
}
if(CertGetNameString(
pCertContext,
CERT_NAME_SIMPLE_DISPLAY_TYPE,
CERT_NAME_ISSUER_FLAG,
NULL,
pszName,
cbSize))
{
_tprintf(TEXT("Issuer -> %s.\n"), pszName);
//-------------------------------------------------------
// Free the memory allocated for the string.
free(pszName);
}
else
{
MyHandleError(TEXT("CertGetName failed."));
}
//-----------------------------------------------------------
// Convert the subject name to an ASN.1 encoded
// string and print the octets in that string.
// First : Get the number of bytes that must
// be allocated for the string.
cbSize = CertNameToStr(
pCertContext->dwCertEncodingType,
&(pCertContext->pCertInfo->Subject),
MY_STRING_TYPE,
NULL,
0);
//-----------------------------------------------------------
// The function CertNameToStr returns the number
// of bytes needed for a string to hold the
// converted name, including the null terminator.
// If it returns one, the name is an empty string.
if (1 == cbSize)
{
MyHandleError(TEXT("Subject name is an empty string."));
}
//-----------------------------------------------------------
// Allocated the needed buffer. Note that this
// memory must be freed inside the loop or the
// application will leak memory.
if(!(pszString = (LPTSTR)malloc(cbSize * sizeof(TCHAR))))
{
MyHandleError(TEXT("Memory allocation failed."));
}
//-----------------------------------------------------------
// Call the function again to get the string.
cbSize = CertNameToStr(
pCertContext->dwCertEncodingType,
&(pCertContext->pCertInfo->Subject),
MY_STRING_TYPE,
pszString,
cbSize);
//-----------------------------------------------------------
// The function CertNameToStr returns the number
// of bytes in the string, including the null terminator.
// If it returns 1, the name is an empty string.
if (1 == cbSize)
{
MyHandleError(TEXT("Subject name is an empty string."));
}
//-----------------------------------------------------------
// Get the length needed to convert the string back
// back into the name as it was in the certificate.
if(!(CertStrToName(
MY_ENCODING_TYPE,
pszString,
MY_STRING_TYPE,
NULL,
NULL, // NULL to get the number of bytes
// needed for the buffer.
&cbSize, // Pointer to a DWORD to hold the
// number of bytes needed for the
// buffer
NULL ))) // Optional address of a pointer to
// old the location for an error in the
// input string.
{
MyHandleError(
TEXT("Could not get the length of the BLOB."));
}
if (!(blobEncodedName.pbData = (LPBYTE)malloc(cbSize)))
{
MyHandleError(
TEXT("Memory Allocation for the BLOB failed."));
}
blobEncodedName.cbData = cbSize;
if(CertStrToName(
MY_ENCODING_TYPE,
pszString,
MY_STRING_TYPE,
NULL,
blobEncodedName.pbData,
&blobEncodedName.cbData,
NULL))
{
_tprintf(TEXT("CertStrToName created the BLOB.\n"));
}
else
{
MyHandleError(TEXT("Could not create the BLOB."));
}
//-----------------------------------------------------------
// Free the memory.
free(blobEncodedName.pbData);
free(pszString);
//-----------------------------------------------------------
// Pause before information on the next certificate
// is displayed.
Local_wait();
} // End of while loop
_tprintf(
TEXT("\nThere are no more certificates in the store. \n"));
//---------------------------------------------------------------
// Close the MY store.
if(CertCloseStore(
hCertStore,
CERT_CLOSE_STORE_CHECK_FLAG))
{
_tprintf(TEXT("The store is closed. ")
TEXT("All certificates are released.\n"));
}
else
{
_tprintf(TEXT("The store was closed, ")
TEXT("but certificates still in use.\n"));
}
_tprintf(TEXT("This demonstration program ran to completion ")
TEXT("without error.\n"));
Local_wait();
} // End of main
//-------------------------------------------------------------------
// This example uses the function MyHandleError, a simple error
// handling function, to print an error message to the standard
// error (stderr) file and exit the program.
// For most applications, replace this function with one
// that does more extensive error reporting.
void MyHandleError(LPTSTR psz)
{
_ftprintf(stderr,
TEXT("An error occurred in running the program. \n"));
_ftprintf(stderr, TEXT("%s\n"), psz);
_ftprintf(stderr, TEXT("Error number %x.\n"), GetLastError());
_ftprintf(stderr, TEXT("Program terminating. \n"));
exit(1);
} // End of MyHandleError
void Local_wait()
{
//-------------------------------------------------------------------
// This function prints a prompt string
// and wait for the user to hit enter.
// It provides a pause with its length controlled by the user.
_tprintf(TEXT("Hit Enter to continue : "));
getchar();
}