📄 createcert.c
字号:
}
i = MultiByteToWideChar(0, 0, szProvider, -1, szwProvider, 260);
if (i == 0)
{
printf("MultiByteToWideChar failed with %d\n", GetLastError());
__leave;
}
// Open Certificate store
hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,
ENCODING,
0, dwSubjectFlags, (LPVOID)szwStore);
if (!hStore)
{
printf("CertOpenStore failed with %x\n", GetLastError());
__leave;
}
// Place Certificate in store
bResult = CertAddEncodedCertificateToStore(hStore, X509_ASN_ENCODING,
bpEncodedCert, dwSize,
CERT_STORE_ADD_REPLACE_EXISTING,
&pCertContext);
if (!bResult)
{
printf("CertAddEncodedCertificateToStore failed with %x\n", GetLastError());
__leave;
}
// Convert container to unicode
i = MultiByteToWideChar(0, 0, szContainer, -1, szwContainer, 160);
if (i == 0)
{
printf("MultiByteToWideChar failed with %d\n", GetLastError());
__leave;
}
// Initialize CRYPT_KEY_PROV_INFO structure
ZeroMemory(&CryptKeyProvInfo, sizeof(CryptKeyProvInfo));
CryptKeyProvInfo.pwszContainerName = szwContainer;
CryptKeyProvInfo.pwszProvName = szwProvider;
CryptKeyProvInfo.dwProvType = dwProviderType;
CryptKeyProvInfo.dwKeySpec = dwKeyType;
// Set Certificate's Key Provider info
bResult = CertSetCertificateContextProperty(pCertContext,
CERT_KEY_PROV_INFO_PROP_ID,
0, (LPVOID)&CryptKeyProvInfo);
if (!bResult)
{
printf("CertSetCertificateContextProperty failed with %x\n", GetLastError());
__leave;
}
bReturn = TRUE;
printf("Certificate created successfully and installed\n");
}
}
_finally
{
// Clean up
if (pbNameBlob) HeapFree(hHeap, 0, pbNameBlob);
if (CertEnhKeyUsage.rgpszUsageIdentifier)
HeapFree(hHeap, 0, CertEnhKeyUsage.rgpszUsageIdentifier);
if (PublicKeyInfo) HeapFree(hHeap, 0, PublicKeyInfo);
if (pbKeyIdentifier) HeapFree(hHeap, 0, pbKeyIdentifier);
if (SubjectKeyIdentifier) HeapFree(hHeap, 0, SubjectKeyIdentifier);
if (pbKeyUsage) HeapFree(hHeap, 0, pbKeyUsage);
if (pbEnhKeyUsage) HeapFree(hHeap, 0, pbEnhKeyUsage);
if (pbBasicConstraints) HeapFree(hHeap, 0, pbBasicConstraints);
if (KeyId) HeapFree(hHeap, 0, KeyId);
if (pbAuthorityKeyId) HeapFree(hHeap, 0, pbAuthorityKeyId);
if (bpEncodedCert) HeapFree(hHeap, 0, bpEncodedCert);
if (pbExportedKey) HeapFree(hHeap, 0, pbExportedKey);
if (szContainer) RpcStringFree(&szContainer);
if (hCertFile) CloseHandle(hCertFile);
if (hKeyFile) CloseHandle(hKeyFile);
if (hPubKey) CryptDestroyKey(hPubKey);
if (hSessionKey) CryptDestroyKey(hSessionKey);
if (hHash) CryptDestroyHash(hHash);
if (hProv) CryptReleaseContext(hProv, 0);
if (hIssuerProv) CryptReleaseContext(hIssuerProv, 0);
if (pIssuerCert) CertFreeCertificateContext(pIssuerCert);
if (pCertContext) CertFreeCertificateContext(pCertContext);
if (hStore) CertCloseStore(hStore, 0);
}
return bReturn;
}
//
// Find Certificate with szCertName in the Subject name
//
PCCERT_CONTEXT FindCertificate(LPSTR szCertName, LPSTR szStore,
DWORD dwFlags, PCRYPT_DATA_BLOB *KeyId,
HCRYPTPROV *hProv, LPDWORD dwKeyType)
{
HANDLE hHeap = GetProcessHeap();
PCRYPT_KEY_PROV_INFO KeyProvInfo;
PCCERT_CONTEXT pCertContext = NULL;
PCERT_EXTENSION pExtension = NULL;
HCERTSTORE hStore = 0;
WCHAR szwStore[20];
CHAR szContainer[160];
CHAR szProvider[160];
BOOL bResult, bSuccess = FALSE;
DWORD dwSize, dwAcquireFlags = 0;
int i;
__try
{
*KeyId = NULL;
*hProv = 0;
if (dwFlags == CERT_SYSTEM_STORE_LOCAL_MACHINE)
dwAcquireFlags = CRYPT_MACHINE_KEYSET;
// Convert Store string to Unicode
i = MultiByteToWideChar(0, 0, szStore, -1, szwStore, 20);
if (i == 0)
{
__leave;
}
// Open Certificate store
hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,
ENCODING,
0, dwFlags, (LPVOID)szwStore);
if (!hStore)
{
__leave;
}
// Find Certificate with Subject name
pCertContext = CertFindCertificateInStore(hStore,
ENCODING,
0, CERT_FIND_SUBJECT_STR_A,
(LPVOID)szCertName, NULL);
if (pCertContext)
{
// Get Key Provider Info size
bResult = CertGetCertificateContextProperty(pCertContext,
CERT_KEY_PROV_INFO_PROP_ID,
NULL,
&dwSize);
if (!bResult)
{
__leave;
}
// Allocate Key Provider Info
KeyProvInfo = (PCRYPT_KEY_PROV_INFO)HeapAlloc(hHeap, 0, dwSize);
if (!KeyProvInfo)
{
__leave;
}
// Get Key Provider Info
bResult = CertGetCertificateContextProperty(pCertContext,
CERT_KEY_PROV_INFO_PROP_ID,
(LPVOID)KeyProvInfo,
&dwSize);
if (!bResult)
{
__leave;
}
// Convert Container Name to ANSI
i = WideCharToMultiByte(0, 0, KeyProvInfo->pwszContainerName,
-1, szContainer, 160, NULL, NULL);
if (i == 0)
{
__leave;
}
// Convert Provider Name to ANSI
i = WideCharToMultiByte(0, 0, KeyProvInfo->pwszProvName, -1,
szProvider, 160, NULL, NULL);
if (i == 0)
{
__leave;
}
// Get Crypto Context of Certificate
bResult = CryptAcquireContext(hProv, szContainer, szProvider,
KeyProvInfo->dwProvType, dwAcquireFlags);
if (!bResult)
{
__leave;
}
// Return Key Spec
*dwKeyType = KeyProvInfo->dwKeySpec;
bSuccess = TRUE;
// Find Subject Key Identifier Extension
pExtension = CertFindExtension(szOID_SUBJECT_KEY_IDENTIFIER,
pCertContext->pCertInfo->cExtension,
pCertContext->pCertInfo->rgExtension);
// If Subject Key Identifier Extension Exists
if (pExtension)
{
// Get Size of Data Blob
bResult = CryptDecodeObject(ENCODING,
szOID_SUBJECT_KEY_IDENTIFIER,
pExtension->Value.pbData,
pExtension->Value.cbData,
0, NULL, &dwSize);
if (!bResult)
{
__leave;
}
// Allocate Data Blob
*KeyId = (PCRYPT_DATA_BLOB)HeapAlloc(hHeap, 0, dwSize);
if (!(*KeyId))
{
__leave;
}
// Get Key Identifier Data Blob
bResult = CryptDecodeObject(ENCODING,
szOID_SUBJECT_KEY_IDENTIFIER,
pExtension->Value.pbData,
pExtension->Value.cbData,
0, (LPVOID)*KeyId, &dwSize);
if (!bResult)
{
__leave;
}
}
}
else
{
__leave;
}
bSuccess = TRUE;
}
__finally
{
// Clean up
if (hStore) CertCloseStore(hStore, 0);
if (KeyProvInfo) HeapFree(hHeap, 0, KeyProvInfo);
if (!bSuccess)
{
if (pCertContext) CertFreeCertificateContext(pCertContext);
pCertContext = NULL;
if (*KeyId) HeapFree(hHeap, 0, *KeyId);
*KeyId = NULL;
}
}
return pCertContext;
}
//
// Implement this is CryptEnumProviders is unavailble
//
BOOL WINAPI MyCryptEnumProviders(DWORD dwIndex, LPDWORD Res, DWORD dwFlags, LPDWORD pdwProvType,
LPTSTR szProvName, LPDWORD pcbProvName)
{
static LPTSTR szKeyPath = TEXT("SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider");
BOOL bResult = TRUE;
DWORD dwNumKeys;
HKEY hKey = NULL;
HKEY hSubKey = NULL;
LONG lResult;
FILETIME ft;
__try
{
// Open registry provider registry key
lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyPath, 0, KEY_READ, &hKey);
if (lResult != ERROR_SUCCESS)
{
bResult = FALSE;
__leave;
}
if (szProvName == NULL)
{
// Query for Number of Keys and Size maximum size of
// provider
lResult = RegQueryInfoKey(hKey, NULL, NULL, NULL, &dwNumKeys, pcbProvName,
NULL, NULL, NULL, NULL, NULL, NULL);
if (lResult != ERROR_SUCCESS)
{
bResult = FALSE;
__leave;
}
// return Size of Provider Name
*pcbProvName = (*pcbProvName + 1) * sizeof(TCHAR);
if (dwIndex >= dwNumKeys) return FALSE;
}
else
{
DWORD dwSize;
DWORD dwType;
// Get Provider by Index
dwSize = *pcbProvName/sizeof(TCHAR);
lResult = RegEnumKeyEx(hKey, dwIndex, szProvName, &dwSize, NULL, NULL, NULL, &ft);
if (lResult != ERROR_SUCCESS)
{
bResult = FALSE;
__leave;
}
*pcbProvName = (dwSize + 1) * sizeof(TCHAR);
// Open the Provider Registry Key
lResult = RegOpenKeyEx(hKey, szProvName, 0, KEY_READ, &hSubKey);
if (lResult != ERROR_SUCCESS)
{
bResult = FALSE;
__leave;
}
// Get Provider Type
dwSize = sizeof(DWORD);
lResult = RegQueryValueEx(hSubKey, TEXT("Type"), NULL, &dwType, (LPBYTE)pdwProvType, &dwSize);
if (lResult != ERROR_SUCCESS)
{
bResult = FALSE;
__leave;
}
}
}
__finally
{
// Clean up
if (hKey != NULL) RegCloseKey(hKey);
if (hSubKey != NULL) RegCloseKey(hSubKey);
}
return bResult;
}
//
// Print Usage
//
void PrintUsage(void)
{
DWORD nIndex = 0;
DWORD dwProvType, dwSize;
CHAR szProvider[160];
printf("\nUsage: CreateCert [Import option] <X509 Name> [Options]\n");
printf("\n[Import option] : If this option is present, everything else is ignored\n");
printf("\t-i <cert file> <public key file> <password> <store> <u>ser|<m>achine <provider num>\n");
printf("\n<X509 Name> (eg. CN=Certificate)\n");
printf("\n[Options]\n");
printf("Type of Certificate:\n");
printf("\t-p <provider number> - default: MS_DEF_PROV\n");
printf("\t-k <e>xchange key | <s>ignature key - default:exchange\n");
printf("\t-s <sha>|<md5> - default:sha\n");
printf("\t-m <number of months of validity>\n");
printf("\t-ca - indicates that the certificate is to be a CA. True for selfsigned\n");
printf("\t-u <enhanced key usage number> - add following numbers\n");
printf("\t\tServer Authentication : 1\n");
printf("\t\tClient Authentication : 2\n");
printf("\t\tCode Signing : 4\n");
printf("\t\tEmail Protection : 8\n");
printf("\t\tTime Stamping : 16\n");
printf("\nLocation of Certificate:\n");
printf("\t-sl <store> <u>ser|<m>achine - default:my u\n");
printf("\t\tor\n");
printf("\t-ex <cert file> <public key file> <password>\n");
printf("\nSigner of the certificate - defaults to self-signed if -is is not present\n");
printf("\t-is <CommonName or substring> <store> <u>ser|<m>achine\n");
printf("\nProviders:\n");
dwSize = 160;
while (MyCryptEnumProviders(nIndex, NULL, 0, &dwProvType, szProvider, &dwSize))
{
printf("\t%d : %s\n", nIndex, szProvider);
dwSize = 160;
nIndex++;
}
printf("\nSelf-Signed Certificates create a file called SelfSigned.cer\n");
printf("Non Self-Signed Certificates create a file called Certificate.cer\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -