How to find size of the Root Certificate Store

  • Thread starter Thread starter DragonOsman2
  • Start date Start date
D

DragonOsman2

Guest
I have this code where I want to loop over the root certificate store using the handle returned from the call to CertOpenSystemStoreA(0, "ROOT"):

const auto store_handle = CertOpenSystemStoreA(0, "ROOT");
if (store_handle != NULL)
{

}


But I don't know how to get the size of the store so I can use it in the loop condition for the for-loop. Could someone please help me out here?


Edit: I found this: CertEnumCertificatesInStore function . The example uses "CA", but aside it should be what I need. So it's fine if I just replace "CA" with "ROOT", right? Though I want to use C++ instead of C.

Edit2: If I want to load all of the root certificates from the store into a Boost SSL context as a std::string, would this be okay to do that?


#ifndef ROOT_CERTIFICATE_H
#define ROOT_CERTIFICATE_H

#include <boost/asio/ssl.hpp>
#include "wincrypt.h"
#include <string>

namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>

namespace detail
{
// The template argument is gratuituous, to
// allow the implementation to be header-only.
//
template<class = void>
void load_root_certificates(ssl::context &ctx, boost::system::error_code &ec)
{
PCCERT_CONTEXT pcert_context = NULL;
const char *pzstore_name = "ROOT";
std::string cert;

// Try to open root certificate store
// If it succeeds, it'll return a handle to the certificate store
// If it fails, it'll return NULL
HANDLE hstore_handle = CertOpenSystemStoreA(NULL, pzstore_name);
if (hstore_handle != NULL)
{
// Extract the certificates from the store in a loop
while (pcert_context = CertEnumCertificatesInStore(hstore_handle, pcert_context))
{
// Concatenate certs to std::string cert variable
cert = std::string(std::strcat(cert.data(), pcert_context));
}
}

ctx.add_certificate_authority(boost::asio::buffer(cert.data(), cert.size()), ec);
if (ec)
{
return;
}
}
}

// Load the certificate into an SSL context
//
// This function is inline so that its easy to take
// the address and there's nothing weird like a
// gratuituous template argument; thus it appears
// like a "normal" function.
//

inline void load_root_certificates(ssl::context &ctx, boost::system::error_code &ec)
{
detail::load_root_certificates(ctx, ec);
}

inline void load_root_certificates(ssl::context &ctx)
{
boost::system::error_code ec;
detail::load_root_certificates(ctx, ec);
if (ec)
{
throw boost::system::system_error{ ec };
}
}

#endif

Thanks in advance for replies.


Edit: Okay, it doesn't compile. How do I load the cert contexts from the Windows root certificate store into the Boost.Asio SSL context?

Continue reading...
 
Back
Top