uriBaba
uriBaba

Reputation: 63

how to automaticaly export windows root certificates to a file?

On a windows machine, I want to create a c++ code that exports windows root certificates to .pem \ .crt file (just like certmgr.msc tool allows me to do manually). currently digging in windows' cryptoAPI docs but didn't find something.

Edit: after using the soltuion below the PEM certificates are created in the following format (unnecary newline between lines and an extra character at the end) : -----BEGIN CERTIFICATE-----

MIICvDCCAiUCEEoZ0jiMglkcpV1zXxVd3KMwDQYJKoZIhvcNAQEEBQAwgZ4xHzAd

BgNVBAoTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxFzAVBgNVBAsTDlZlcmlTaWdu

....

Rj1QNAufcFb2jip/F87lY795aQdzLrCVKIr17aqp0l3NCsoQCY/Os68olsR5KYSS

3P+6Z0JIppAQ5L9h+JxT5ZPRcz/4/Z1PhKxV0f0RY2M=

-----END CERTIFICATE-----

i don't believe it will be accepted by openSSL, what is the cause for this?

Upvotes: 4

Views: 1465

Answers (1)

plstryagain
plstryagain

Reputation: 726

What you're looking for is CertEnumCertificatesInStore function. Also if you want to save certificate in PEM you will need CryptBinaryToString.

#include <Windows.h>
#include <wincrypt.h>
#include <string>
#include <fstream>
#include <vector>

#pragma comment(lib, "crypt32.lib")

int _tmain(int argc, _TCHAR* argv[])
{
    DWORD num = 1;
    /* open root certificate store */
    HCERTSTORE hCertStore = CertOpenSystemStore(NULL, L"ROOT");

    PCCERT_CONTEXT pCert = nullptr;
    while (pCert = CertEnumCertificatesInStore(hCertStore, pCert))
    {
        /* if you need save certificate in PEM */
        DWORD size = 0;
        CryptBinaryToString(pCert->pbCertEncoded, pCert->cbCertEncoded, CRYPT_STRING_BASE64HEADER, nullptr, &size);
        std::vector<wchar_t> pem(size);
        CryptBinaryToString(pCert->pbCertEncoded, pCert->cbCertEncoded, CRYPT_STRING_BASE64HEADER,
            pem.data(), &size);

        std::wstring pem_cert = std::to_wstring(num) + L".pem";
        std::wofstream pem_cert_file(pem_cert, std::ios::binary | std::ios::out);
        pem_cert_file.write(pem.data(), pem.size() - 1);


        /* or if you need save certificate in binary form (DER encoding)*/
        std::string der_cert = std::to_string(num) + ".cer";
        std::ofstream der_cert_file(der_cert, std::ios::binary | std::ios::out);
        der_cert_file.write(reinterpret_cast<char*>(pCert->pbCertEncoded), pCert->cbCertEncoded);
        ++num;
    }

    CertCloseStore(hCertStore, 0);
    return 0;
}

Upvotes: 8

Related Questions