c ++ - Eksporterende PFX-fil fra Windows Certifikat butik

Indlæg af Hanne Mølgaard Plasc

Problem



Vores applikation bruger OpenSSL til at sikre kommunikation mellem klientenhed og server. Certifikaterne genereres af kunderne CA, og vi var nødt til at uploade servercertifikat og private nøgle til Windows OS-baseret maskine.


Indtil nu leder vi vores kunder til at gemme PEM-filer, som omfatter servercertifikat og private nøgle på specifikke mapper på serverfilsystemet, og vores applikation uploader den derfra. I det seneste blev vi bedt om af kunden at læse et PFX certifikat fra lokale vinduer certifikat butik.


Jeg kan tænke på 2 muligheder, som begge kombinerer brug af CAPI bibliotek til at eksportere PFX filen fra WCS (ifølge venligt navn), serialisere det og derefter uploade det ved hjælp af OpenSSL API.


Den første mulighed gemmer den som midlertidig fil på serverfilsystemet, og læs derefter som før med OpenSSL API.


Den anden mulighed bruger hukommelse, dvs. videresend pegerne i stedet for at bruge midlertidig fil.


Mit team brugte meget tid på at søge på internettet (hovedsageligt Stack Overflow) og prøvede kodestykker, men fandt ikke arbejdsløsning. Jeg forstod, at den private nøgle skal kunne eksporteres markeret under import af filen til WCS.


Da jeg forsøgte nedenstående kode for simpelt eksporterende certifikat og gemte det til fil (første halvdel af indstilling nr. 1 baseret på MS eksempelkode), skriver den kun ét tegn til fil.


Hvad savner jeg her? Skal jeg reformatere certifikat?


Enhver ide om hvad der er forkert, og hvad er den rigtige måde at gøre det på?


Kan den private nøgle uddrages på denne måde?


Tak på forhånd for enhver kommentar


//-----------------------------------------

#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);

void main(void)
{
//-------------------------------------------------------------------
// Declare and initialize variables.
HCERTSTORE         hSystemStore;
PCCERT\_CONTEXT     pCertContext = NULL;
Char pszStoreName[256] = "root";
char               pszNameString[256] = "CARootTest"; 
BYTE              pbElement[3000];
DWORD              cbElement;
//-------------------------------------------------------------------
// Open a system certificate store.
if(hSystemStore = CertOpenSystemStore(
    0,
    pszStoreName))
{
  printf("The \%s system store is open. Continue.
", 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. 
", pszNameString);
}
else
{
   MyHandleError("Could not find the \%s certificate.");
}
//-------------------------------------------------------------------
// Find out how much memory to allocate for the serialized element.

if(CertSerializeCertificateStoreElement(
    pCertContext,      // The existing certificate.
    0,                 // Accept default for dwFlags, 
    NULL,              // NULL for the first function call.
    &cbElement))       // Address where the length of the 
                       // serialized element will be placed.
{
     printf("The length of the serialized string is \%d.
",
         cbElement);
}
else
{
     MyHandleError("Finding the length of the serialized "
         "element failed.");
}
//-------------------------------------------------------------------
// Allocate memory for the serialized element.

if(pbElement = (BYTE*)malloc(cbElement+1))
{
     printf("Memory has been allocated. Continue.
");
}
else
{
     MyHandleError("The allocation of memory failed.");
}
//-------------------------------------------------------------------
// Create the serialized element from a certificate context.

if(CertSerializeCertificateStoreElement(
    pCertContext,        // The certificate context source for the 
                         // serialized element.
    0,                   // dwFlags. Accept the default.
    pbElement,           // A pointer to where the new element will
                         // be stored.
    &cbElement))         // The length of the serialized element,
{
     printf("The encoded element has been serialized. 
");
}
else
{
     MyHandleError("The element could not be serialized.");
}
//-------------------------------------------------------------------
//  pbElement could be written to a file ??

FILE *fp;
errno\_t err;
if ((err = fopen\_s(&fp, "cert.p12", "wb")) != 0)
    printf("File was not opened
");
else
    fprintf(fp, "\%s", pbElement);
fclose(fp);

//-------------------------------------------------------------------
// Free memory.

free(pbElement);
CertCloseStore(hSystemStore,0);
printf("The program ran without error to the end.
");
} // End of main

//-------------------------------------------------------------------
void MyHandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. 
");
    fprintf(stderr,"\%s
",s);
    fprintf(stderr, "Error number \%x.
", GetLastError());
    fprintf(stderr, "Program terminating. 
");
    exit(1);
} // End of MyHandleError

Bedste reference