Following Exporting PFX file from windows certificates store
I am trying to export from windows key store a pfx file which contains both certificate and private key and dump it to PEM format file which shall be read by openssl.
The private key was marked as exportable during import the file into WCS
I dig into most of the questions here which deals with extracting certificate but none of them deals with pfx file which includes also private key or they use tool e.g. mmc etc and I have to code it as part of the application in C++.
The main issue after exporting the certificate from WCS is to separate between the certificate and the private key section before converting them from binary format to base64 encoding (section header and trailer should be added) and probably also converting from pfx to PEM.
In MS example which my code is based on certificate was serialized but in other examples here it wasn't.
I was also advised to import exported certificate into new "virtual" store but I don't understand why.
What is important for me is to export both certificate and private key from WCS to format and place which openssl can import them from.
If someone has other way to do it I shall be thankful for any information. Thanks in advance for all comments / answers.
My code:
//-----------------------------------------
#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(char *s);
char *base64_encode(const unsigned char *data,
size_t input_length,
size_t *output_length);
void main(void)
{
//-------------------------------------------------------------------
// Declare and initialize variables.
HCERTSTORE hSystemStore;
PCCERT_CONTEXT pCertContext = NULL;
char pszStoreName[256] = "root";
char pszNameString[256] = "CARootTest";
char* pbElement;
size_t cbElement;
//-------------------------------------------------------------------
// Open a system certificate store.
if(hSystemStore = CertOpenSystemStore(
0,
pszStoreName))
{
printf("The %s system store is open. Continue.\n", pszStoreName );
}
else
{
MyHandleError("The first system store did not open.");
}
//-------------------------------------------------------------------
// Get a certificate that has the desired friendly name.
if(pCertContext=CertFindCertificateInStore(
hSystemStore,
MY_ENCODING_TYPE, // Use X509_ASN_ENCODING
0, // No dwFlags needed
CERT_NAME_FRIENDLY_DISPLAY_TYPE, // Find a certificate
pszNameString, // The Unicode string to be found
// in a certificate's subject
NULL)) // NULL for the first call
{
printf("The %s certificate was found. \n", pszNameString);
}
else
{
MyHandleError("Could not find the %s certificate.");
}
pbElement = base64_encode(pCertContext->pbCertEncoded,
sizeof (pCertContext->pbCertEncoded),
&cbElement);
/*
//-------------------------------------------------------------------
// pbElement could be written to a file ??
FILE *fp;
errno_t err;
if ((err = fopen_s(&fp, "cert.p12", "w")) != 0)
printf("File was not opened\n");
else
fprintf(fp, "%s", pbElement);
fclose(fp);
//-------------------------------------------------------------------
// Free memory.
free(pbElement);
CertCloseStore(hSystemStore,0);
printf("The program ran without error to the end.\n");
} // End of main
//-------------------------------------------------------------------
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 of MyHandleError