I am trying to add certificate to store, but I am new in it. I've been searching for information about how to install certificate to store without finding certificate context from store (I have no certificate in store). Everything I found I've been used in code below. But it seems like it doesn't work, and I can't find certificate in store even after message that certificate was installed.
static HCRYPTPROV hProv = 0;
static HCRYPTKEY hKey = 0;
static unsigned char *pbKeyBlob = nullptr;
static unsigned int cbKeyBlob;
static unsigned int cbCertBlob;
static unsigned char *pbCertBlob = nullptr;
LPCSTR szCont = "myCont";
if(CryptAcquireContext(&hProv, szCont, nullptr, PROV_GOST_2012_256, 0))
{
qDebug() << "The key container \"%s\" has been acquired.\n" << szCont;
}
else
{
HandleError("Error during CryptAcquireContext.");
}
if(CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey))
{
qDebug() << "The public key has been acquired. \n";
}
else
{
HandleError("Error during CryptGetUserKey public key.");
}
if(CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, nullptr, &cbKeyBlob))
{
qDebug() << "Size of the BLOB for the public key determined. \n";
}
else
{
HandleError("Error computing BLOB length.");
}
pbKeyBlob = static_cast<unsigned char*>(malloc(cbKeyBlob));
if(!pbKeyBlob)
{
HandleError("Out of memory. \n");
}
if(CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, pbKeyBlob, &cbKeyBlob))
{
qDebug() << "Contents have been written to the BLOB. \n";
}
else
{
HandleError("Error during CryptExportKey.");
}
if(CryptGetKeyParam(hKey, KP_CERTIFICATE, nullptr, &cbCertBlob, 0))
{
pbCertBlob = static_cast<unsigned char*>(malloc(cbCertBlob));
if(!pbCertBlob)
{
HandleError("Out of memory. \n");
}
szFileName = static_cast<char*>(malloc((strlen(szCont) + 5) * sizeof(char)));
if(!szFileName)
{
HandleError("Out of memory. \n");
}
if(CryptGetKeyParam(hKey, KP_CERTIFICATE, pbCertBlob, &cbCertBlob, 0))
{
qDebug() << "Got certificate from container.\n";
}
else
{
HandleError("Error during CryptGetKeyParam.");
}
strcpy(szFileName, szCont);
strcat(szFileName, ".cer");
WriteBlobToFile(Cert, pbCertBlob, cbCertBlob);
pDesiredCert = CertCreateCertificateContext(MY_ENCODING_TYPE, pbCertBlob, cbCertBlob);
hCertStore = CertOpenSystemStore(0, "mRoot");
Here I didn't get any error and it even seems like it successfully installed, but I found nothing in certificate store.
if (!CertAddEncodedCertificateToStore(hCertStore, MY_ENCODING_TYPE, pDesiredCert->pbCertEncoded, pDesiredCert->cbCertEncoded, CERT_STORE_ADD_NEW, &pDesiredCert))
{
qDebug() << "Cartificate installing failed.";
}
else
{
qDebug() << "Certificate was installed successfully to mRoot store.";
}
It is better to create certificate with dedicated tools such as makecert, openssl, etc. Afterward, According to Serializing Certificates you can add it into a certificate store.
Edit:
makecert.exe -$ individual -n "CN=Test Signing Cert" -r C:\Users\public_v2.crt
Then
#pragma comment(lib, "crypt32.lib")
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void MyHandleError(const char* s);
int main()
{
// usage: CertExtract certpath
char keyFile[] = "C:\\Users\\public_v2.crt";
BYTE lp[65536];
SECURITY_ATTRIBUTES sa;
HANDLE hKeyFile;
DWORD bytes;
HCERTSTORE hFileStore;
PCCERT_CONTEXT certContext;
HCERTSTORE hSystemStore;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = FALSE;
hKeyFile = CreateFile(keyFile, GENERIC_READ, FILE_SHARE_READ, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hKeyFile) {
if (ReadFile(hKeyFile, lp, GetFileSize(hKeyFile, NULL), &bytes, NULL) && bytes > 0) {
certContext = CertCreateCertificateContext(X509_ASN_ENCODING, lp, bytes);
if (certContext) {
printf("yay!");
/*if (hFileStore = CertOpenStore(
CERT_STORE_PROV_FILENAME,
MY_ENCODING_TYPE,
NULL,
0,
L"testStor.sto"))
{
printf("The file store is open. Continue.\n");
}
else
{
MyHandleError("The file store did not open.");
}*/
if (hSystemStore = CertOpenSystemStore(
0,
"CA"))
{
printf("The CA system store is open. Continue.\n");
}
else
{
MyHandleError("The first system store did not open.");
}
if (CertAddEncodedCertificateToStore(
hSystemStore,
MY_ENCODING_TYPE,
certContext->pbCertEncoded,
certContext->cbCertEncoded,
CERT_STORE_ADD_NEW,
&certContext))
{
printf("Another certificate is added to the file store.\n");
}
else
{
MyHandleError("The new certificate was not added to the "
"file store.");
}
/*if (CertSaveStore(
hFileStore,
MY_ENCODING_TYPE,
CERT_STORE_SAVE_AS_PKCS7,
CERT_STORE_SAVE_TO_FILENAME,
(void*)L"testStor.sto",
0))
{
printf("Another certificate is saved to the file store.\n");
}
else
{
MyHandleError("The new certificate was not added to the "
"file store.");
}*/
//-------------------------------------------------------------------
// Free memory.
CertCloseStore(hSystemStore, 0);
//CertCloseStore(hFileStore, 0);
printf("The program ran without error to the end.\n");
CertFreeCertificateContext(certContext);
}
else {
printf("Could not convert certificate to internal form\n");
}
}
else {
printf("Failed to read key file: %s\n", keyFile);
}
}
else {
printf("Failed to open key file: %s\n", keyFile);
}
CloseHandle(hKeyFile);
return 0;
}
//-------------------------------------------------------------------
// 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(const 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 of MyHandleError