Last active
December 18, 2015 13:48
-
-
Save siddontang/5792247 to your computer and use it in GitHub Desktop.
windows csp, rsa, certificate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "rsa.h" | |
#include <stdio.h> | |
#include <conio.h> | |
#include <windows.h> | |
#include <wincrypt.h> | |
#include "base64.h" | |
#pragma comment(lib, "crypt32.lib") | |
#define CERT_PERSONAL_STORE_NAME L"MY" | |
#define MY_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) | |
void ReverseBuffer(char *buf, int len) | |
{ | |
char temp; | |
for(int i = 0; i < len / 2; i++) | |
{ | |
temp = buf[i]; | |
buf[i] = buf[len- i - 1]; | |
buf[len - i - 1] = temp; | |
} | |
} | |
int WINAPI rsa_sign(const wchar_t* subjectName, const char* srcData, int srcLen, char* destData, int* destLen) | |
{ | |
HCERTSTORE hStoreHandle = NULL; | |
PCCERT_CONTEXT pSignerCert = NULL; | |
HCRYPTPROV hCryptProv = NULL; | |
DWORD dwKeySpec = 0; | |
HCRYPTHASH hHash = NULL; | |
BOOL bResult = FALSE; | |
BOOL bFreeKeyProv; | |
DWORD errCode = 0; | |
int i = 0; | |
// Open the certificate store. | |
hStoreHandle = CertOpenStore( | |
CERT_STORE_PROV_SYSTEM, | |
0, | |
NULL, | |
CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, | |
CERT_PERSONAL_STORE_NAME | |
); | |
if(!hStoreHandle) | |
{ | |
//open store error | |
return GetLastError(); | |
} | |
pSignerCert = CertFindCertificateInStore( | |
hStoreHandle, | |
MY_TYPE, | |
0, | |
CERT_FIND_SUBJECT_STR, | |
subjectName, | |
pSignerCert | |
); | |
if(!pSignerCert) | |
{ | |
errCode = GetLastError(); | |
//find singer cert error | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
// Get the CSP, and check if we can sign with the private key | |
bResult = CryptAcquireCertificatePrivateKey( | |
pSignerCert, | |
0, | |
NULL, | |
&hCryptProv, | |
&dwKeySpec, | |
&bFreeKeyProv | |
); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
// Create the hash object. | |
bResult = CryptCreateHash( | |
hCryptProv, | |
CALG_SHA1, | |
0, | |
0, | |
&hHash | |
); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
//create hash error | |
if(bFreeKeyProv) | |
{ | |
CryptReleaseContext(hCryptProv, 0); | |
} | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
bResult = CryptHashData( | |
hHash, | |
(const BYTE*)srcData, | |
srcLen, | |
0 | |
); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CryptDestroyHash(hHash); | |
if(bFreeKeyProv) | |
{ | |
CryptReleaseContext(hCryptProv, 0); | |
} | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
// Sign the hash object | |
bResult = CryptSignHash( | |
hHash, | |
dwKeySpec, | |
NULL, | |
0, | |
(BYTE*)destData, | |
(DWORD*)destLen | |
); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CryptDestroyHash(hHash); | |
if(bFreeKeyProv) | |
{ | |
CryptReleaseContext(hCryptProv, 0); | |
} | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
ReverseBuffer(destData, *destLen); | |
CryptDestroyHash(hHash); | |
if(bFreeKeyProv) | |
{ | |
CryptReleaseContext(hCryptProv, 0); | |
} | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return 0; | |
} | |
int WINAPI rsa_verify(const wchar_t* subjectName, const char* srcData, int srcLen, char* signData, int signLen) | |
{ | |
HCERTSTORE hStoreHandle = NULL; | |
PCCERT_CONTEXT pSignerCert = NULL; | |
HCRYPTPROV hCryptProv = NULL; | |
HCRYPTHASH hHash = NULL; | |
BOOL bResult = FALSE; | |
HCRYPTKEY hPubKey = NULL; | |
char* signBuffer = NULL; | |
DWORD errCode; | |
hStoreHandle = CertOpenStore( | |
CERT_STORE_PROV_SYSTEM, | |
0, | |
NULL, | |
CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, | |
CERT_PERSONAL_STORE_NAME | |
); | |
if(!hStoreHandle) | |
{ | |
errCode = GetLastError(); | |
return errCode; | |
} | |
pSignerCert = CertFindCertificateInStore( | |
hStoreHandle, | |
MY_TYPE, | |
0, | |
CERT_FIND_SUBJECT_STR, | |
subjectName, | |
pSignerCert | |
); | |
if(!pSignerCert) | |
{ | |
errCode = GetLastError(); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
bResult = CryptAcquireContext( | |
&hCryptProv, | |
NULL, | |
NULL, | |
PROV_RSA_FULL, | |
CRYPT_VERIFYCONTEXT | |
); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
bResult = CryptCreateHash( | |
hCryptProv, | |
CALG_SHA1, | |
0, | |
0, | |
&hHash | |
); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CryptReleaseContext(hCryptProv, 0); | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
bResult = CryptHashData( | |
hHash, | |
(const BYTE*)srcData, | |
srcLen, | |
0 | |
); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CryptDestroyHash(hHash); | |
CryptReleaseContext(hCryptProv, 0); | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
bResult = CryptImportPublicKeyInfo( | |
hCryptProv, | |
MY_TYPE, | |
&pSignerCert->pCertInfo->SubjectPublicKeyInfo, | |
&hPubKey | |
); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CryptDestroyHash(hHash); | |
CryptReleaseContext(hCryptProv, 0); | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
signBuffer = (char*)malloc(signLen); | |
memcpy(signBuffer, signData, signLen); | |
ReverseBuffer(signBuffer, signLen); | |
bResult = CryptVerifySignature( | |
hHash, | |
(const BYTE*)signBuffer, | |
signLen, | |
hPubKey, | |
NULL, | |
0 | |
); | |
free(signBuffer); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CryptDestroyHash(hHash); | |
CryptReleaseContext(hCryptProv, 0); | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
CryptDestroyHash(hHash); | |
CryptReleaseContext(hCryptProv, 0); | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return 0; | |
} | |
int WINAPI rsa_encrypt(const wchar_t* subjectName, const char* srcData, int srcLen, char* destData, int* destLen) | |
{ | |
HCERTSTORE hStoreHandle = NULL; | |
PCCERT_CONTEXT pSignerCert = NULL; | |
HCRYPTPROV hCryptProv = NULL; | |
HCRYPTHASH hHash = NULL; | |
BOOL bResult = FALSE; | |
HCRYPTKEY hCryptKey = NULL; | |
DWORD errCode; | |
hStoreHandle = CertOpenStore( | |
CERT_STORE_PROV_SYSTEM, | |
0, | |
NULL, | |
CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, | |
CERT_PERSONAL_STORE_NAME | |
); | |
if(!hStoreHandle) | |
{ | |
errCode = GetLastError(); | |
return errCode; | |
} | |
pSignerCert = CertFindCertificateInStore( | |
hStoreHandle, | |
MY_TYPE, | |
0, | |
CERT_FIND_SUBJECT_STR, | |
subjectName, | |
pSignerCert | |
); | |
if(!pSignerCert) | |
{ | |
errCode = GetLastError(); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
bResult = CryptAcquireContext( | |
&hCryptProv, | |
NULL, | |
NULL, | |
PROV_RSA_FULL, | |
0 | |
); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
bResult = CryptImportPublicKeyInfo( | |
hCryptProv, | |
MY_TYPE, | |
&pSignerCert->pCertInfo->SubjectPublicKeyInfo, | |
&hCryptKey | |
); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CryptReleaseContext(hCryptProv, 0); | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
memcpy(destData, srcData, srcLen); | |
*destLen = srcLen; | |
bResult = CryptEncrypt(hCryptKey, NULL, TRUE, 0, (BYTE*)destData, (DWORD*)destLen, 128); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CryptDestroyKey(hCryptKey); | |
CryptReleaseContext(hCryptProv, 0); | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
ReverseBuffer(destData, *destLen); | |
CryptDestroyKey(hCryptKey); | |
CryptReleaseContext(hCryptProv, 0); | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return 0; | |
} | |
int WINAPI rsa_decrypt(const wchar_t* subjectName, const char* srcData, int srcLen, char* destData, int* destLen) | |
{ | |
HCERTSTORE hStoreHandle = NULL; | |
PCCERT_CONTEXT pSignerCert = NULL; | |
HCRYPTPROV hCryptProv = NULL; | |
HCRYPTHASH hHash = NULL; | |
BOOL bResult = FALSE; | |
HCRYPTKEY hCryptKey = NULL; | |
BOOL bFreeKeyProv; | |
DWORD dwKeySpec = 0; | |
DWORD errCode; | |
hStoreHandle = CertOpenStore( | |
CERT_STORE_PROV_SYSTEM, | |
0, | |
NULL, | |
CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, | |
CERT_PERSONAL_STORE_NAME | |
); | |
if(!hStoreHandle) | |
{ | |
errCode = GetLastError(); | |
return errCode; | |
} | |
pSignerCert = CertFindCertificateInStore( | |
hStoreHandle, | |
MY_TYPE, | |
0, | |
CERT_FIND_SUBJECT_STR, | |
subjectName, | |
pSignerCert | |
); | |
if(!pSignerCert) | |
{ | |
errCode = GetLastError(); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
bResult = CryptAcquireCertificatePrivateKey( | |
pSignerCert, | |
0, | |
NULL, | |
&hCryptProv, | |
&dwKeySpec, | |
&bFreeKeyProv | |
); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
bResult = CryptGetUserKey(hCryptProv, AT_KEYEXCHANGE, &hCryptKey); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
if(bFreeKeyProv) | |
{ | |
CryptReleaseContext(hCryptProv, 0); | |
} | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
memcpy(destData, srcData, srcLen); | |
*destLen = srcLen; | |
ReverseBuffer(destData, *destLen); | |
bResult = CryptDecrypt(hCryptKey, NULL, TRUE, 0, (BYTE*)destData, (DWORD*)destLen); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CryptDestroyKey(hCryptKey); | |
if(bFreeKeyProv) | |
{ | |
CryptReleaseContext(hCryptProv, 0); | |
} | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
CryptDestroyKey(hCryptKey); | |
if(bFreeKeyProv) | |
{ | |
CryptReleaseContext(hCryptProv, 0); | |
} | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return 0; | |
} | |
int WINAPI rsa_b64_sign(const wchar_t* subjectName, const char* srcB64Data, char* destB64Data) | |
{ | |
int srcB64Len = (int)strlen(srcB64Data); | |
int srcLen = base64_decoded_length(srcB64Len); | |
char* srcData = (char*)malloc(srcLen); | |
char* destData = NULL; | |
int destLen = 1024; | |
int destB64Len = 0; | |
int i = 0; | |
int hr = decode_base64((const unsigned char*)srcB64Data, srcB64Len, (unsigned char*)srcData, &srcLen); | |
if(hr != 0) | |
{ | |
free(srcData); | |
return -1; | |
} | |
destData = (char*)malloc(destLen); | |
hr = rsa_sign(subjectName, srcData, srcLen, destData, &destLen); | |
if(hr == 0) | |
{ | |
encode_base64((const unsigned char*)destData, destLen, (unsigned char*)destB64Data, &destB64Len); | |
destB64Data[destB64Len] = '\0'; | |
} | |
free(destData); | |
free(srcData); | |
return hr; | |
} | |
int WINAPI rsa_b64_verify(const wchar_t* subjectName, const char* srcB64Data, const char* signB64Data) | |
{ | |
int srcB64Len = (int)strlen(srcB64Data); | |
int srcLen = base64_decoded_length(srcB64Len); | |
char* srcData = NULL; | |
int signB64Len = (int)strlen(signB64Data); | |
int signLen = base64_decoded_length(signB64Len); | |
char* signData = NULL; | |
int hr = 0; | |
srcData = (char*)malloc(srcLen); | |
hr = decode_base64((const unsigned char*)srcB64Data, srcB64Len, (unsigned char*)srcData, &srcLen); | |
if(hr != 0) | |
{ | |
free(srcData); | |
return -1; | |
} | |
signData = (char*)malloc(signLen); | |
hr = decode_base64((const unsigned char*)signB64Data, signB64Len, (unsigned char*)signData, &signLen); | |
if(hr != 0) | |
{ | |
free(srcData); | |
free(signData); | |
return -1; | |
} | |
hr = rsa_verify(subjectName, srcData, srcLen, signData, signLen); | |
free(srcData); | |
free(signData); | |
return hr; | |
} | |
int WINAPI rsa_b64_encrypt(const wchar_t* subjectName, const char* srcB64Data, char* destB64Data) | |
{ | |
int srcB64Len = (int)strlen(srcB64Data); | |
int srcLen = base64_decoded_length(srcB64Len); | |
char* srcData = NULL; | |
char* destData = NULL; | |
int destLen = 1024; | |
int destB64Len = 0; | |
int hr = 0; | |
srcData = (char*)malloc(srcLen); | |
hr = decode_base64((const unsigned char*)srcB64Data, srcB64Len, (unsigned char*)srcData, &srcLen); | |
if(hr != 0) | |
{ | |
free(srcData); | |
return -1; | |
} | |
destData = (char*)malloc(destLen); | |
hr = rsa_encrypt(subjectName, srcData, srcLen, destData, &destLen); | |
if(hr == 0) | |
{ | |
encode_base64((const unsigned char*)destData, destLen, (unsigned char*)destB64Data, &destB64Len); | |
destB64Data[destB64Len] = '\0'; | |
} | |
free(srcData); | |
free(destData); | |
return hr; | |
} | |
int WINAPI rsa_b64_decrypt(const wchar_t* subjectName, const char* srcB64Data, char* destB64Data) | |
{ | |
int srcB64Len = (int)strlen(srcB64Data); | |
int srcLen = base64_decoded_length(srcB64Len); | |
char* srcData = NULL; | |
char* destData = NULL; | |
int destLen = 1024; | |
int destB64Len = 0; | |
int hr = 0; | |
srcData = (char*)malloc(srcLen); | |
hr = decode_base64((const unsigned char*)srcB64Data, srcB64Len, (unsigned char*)srcData, &srcLen); | |
if(hr != 0) | |
{ | |
free(srcData); | |
return -1; | |
} | |
destData = (char*)malloc(destLen); | |
hr = rsa_decrypt(subjectName, srcData, srcLen, destData, &destLen); | |
if(hr == 0) | |
{ | |
encode_base64((const unsigned char*)destData, destLen, (unsigned char*)destB64Data, &destB64Len); | |
destB64Data[destB64Len] = '\0'; | |
} | |
free(srcData); | |
free(destData); | |
return hr; | |
} | |
int WINAPI cert_add(const wchar_t* subjectName, const char* certData, int certLen) | |
{ | |
HCERTSTORE hStoreHandle = NULL; | |
BOOL bResult = FALSE; | |
DWORD errCode; | |
PCCERT_CONTEXT hContext = NULL; | |
HCERTSTORE hMemoryStore = NULL; | |
CRYPT_DATA_BLOB blob; | |
blob.pbData = (BYTE*)certData; | |
blob.cbData = certLen; | |
hMemoryStore = PFXImportCertStore(&blob, L"", CRYPT_EXPORTABLE | CRYPT_USER_KEYSET); | |
if(!hMemoryStore) | |
{ | |
errCode = GetLastError(); | |
return errCode; | |
} | |
hStoreHandle = CertOpenStore( | |
CERT_STORE_PROV_SYSTEM, | |
0, | |
NULL, | |
CERT_SYSTEM_STORE_CURRENT_USER, | |
CERT_PERSONAL_STORE_NAME | |
); | |
if(!hStoreHandle) | |
{ | |
errCode = GetLastError(); | |
CertCloseStore(hMemoryStore, 0); | |
return errCode; | |
} | |
while(hContext = CertEnumCertificatesInStore(hMemoryStore, hContext)) | |
{ | |
bResult = CertAddCertificateContextToStore(hStoreHandle, hContext, | |
CERT_STORE_ADD_REPLACE_EXISTING, NULL); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CertCloseStore(hMemoryStore, 0); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
} | |
CertCloseStore(hMemoryStore, 0); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return 0; | |
} | |
int WINAPI cert_b64_add(const wchar_t* subjectName, const char* certB64Data) | |
{ | |
int certB64Len = (int)strlen(certB64Data); | |
int certLen = base64_decoded_length(certB64Len); | |
char* certData = NULL; | |
int hr = 0; | |
certData = (char*)malloc(certLen); | |
hr = decode_base64((const unsigned char*)certB64Data, certB64Len, (unsigned char*)certData, &certLen); | |
if(hr != 0) | |
{ | |
free(certData); | |
return -1; | |
} | |
hr = cert_add(subjectName, certData, certLen); | |
free(certData); | |
return hr; | |
} | |
int WINAPI cert_del(const wchar_t* subjectName) | |
{ | |
HCERTSTORE hStoreHandle = NULL; | |
PCCERT_CONTEXT pSignerCert = NULL; | |
BOOL bResult = FALSE; | |
DWORD errCode; | |
hStoreHandle = CertOpenStore( | |
CERT_STORE_PROV_SYSTEM, | |
0, | |
NULL, | |
CERT_SYSTEM_STORE_CURRENT_USER, | |
CERT_PERSONAL_STORE_NAME | |
); | |
if(!hStoreHandle) | |
{ | |
errCode = GetLastError(); | |
return errCode; | |
} | |
while(pSignerCert = CertFindCertificateInStore( | |
hStoreHandle, | |
MY_TYPE, | |
0, | |
CERT_FIND_SUBJECT_STR, | |
subjectName, | |
pSignerCert)) | |
{ | |
if(!pSignerCert) | |
{ | |
break; | |
} | |
bResult = CertDeleteCertificateFromStore(pSignerCert); | |
if(!bResult) | |
{ | |
errCode = GetLastError(); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return errCode; | |
} | |
pSignerCert = NULL; | |
} | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return 0; | |
} | |
int WINAPI cert_exists(const wchar_t* subjectName) | |
{ | |
HCERTSTORE hStoreHandle = NULL; | |
PCCERT_CONTEXT pSignerCert = NULL; | |
BOOL bResult = FALSE; | |
DWORD errCode; | |
int exists = 0; | |
hStoreHandle = CertOpenStore( | |
CERT_STORE_PROV_SYSTEM, | |
0, | |
NULL, | |
CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, | |
CERT_PERSONAL_STORE_NAME | |
); | |
if(!hStoreHandle) | |
{ | |
errCode = GetLastError(); | |
return errCode; | |
} | |
pSignerCert = CertFindCertificateInStore( | |
hStoreHandle, | |
MY_TYPE, | |
0, | |
CERT_FIND_SUBJECT_STR, | |
subjectName, | |
pSignerCert | |
); | |
exists = pSignerCert ? 1 : 0; | |
CertFreeCertificateContext(pSignerCert); | |
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG); | |
return exists; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment