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...
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...