rippled
Loading...
Searching...
No Matches
RegisterSSLCerts.cpp
1#include <xrpl/net/RegisterSSLCerts.h>
2
3#if BOOST_OS_WINDOWS
4#include <boost/asio/ssl/error.hpp>
5#include <boost/system/error_code.hpp>
6
7#include <openssl/err.h>
8#include <openssl/ssl.h>
9#include <openssl/x509.h>
10
11#include <wincrypt.h>
12
13#include <memory>
14#endif
15
16namespace xrpl {
17
18void
19registerSSLCerts(boost::asio::ssl::context& ctx, boost::system::error_code& ec, beast::Journal j)
20{
21#if BOOST_OS_WINDOWS
22 auto certStoreDelete = [](void* h) {
23 if (h != nullptr)
24 CertCloseStore(h, 0);
25 };
26 std::unique_ptr<void, decltype(certStoreDelete)> hStore{CertOpenSystemStore(0, "ROOT"), certStoreDelete};
27
28 if (!hStore)
29 {
30 ec = boost::system::error_code(GetLastError(), boost::system::system_category());
31 return;
32 }
33
34 ERR_clear_error();
35
36 std::unique_ptr<X509_STORE, decltype(X509_STORE_free)*> store{X509_STORE_new(), X509_STORE_free};
37
38 if (!store)
39 {
40 ec = boost::system::error_code(static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category());
41 return;
42 }
43
44 auto warn = [&](std::string const& msg) {
45 // Buffer based on asio recommended size
46 char buf[256];
47 ::ERR_error_string_n(ec.value(), buf, sizeof(buf));
48 JLOG(j.warn()) << msg << " " << buf;
49 ::ERR_clear_error();
50 };
51
52 PCCERT_CONTEXT pContext = NULL;
53 while ((pContext = CertEnumCertificatesInStore(hStore.get(), pContext)) != NULL)
54 {
55 unsigned char const* pbCertEncoded = pContext->pbCertEncoded;
56 std::unique_ptr<X509, decltype(X509_free)*> x509{
57 d2i_X509(NULL, &pbCertEncoded, pContext->cbCertEncoded), X509_free};
58 if (!x509)
59 {
60 warn("Error decoding certificate");
61 continue;
62 }
63
64 if (X509_STORE_add_cert(store.get(), x509.get()) != 1)
65 {
66 warn("Error adding certificate");
67 }
68 else
69 {
70 // Successfully adding to the store took ownership
71 x509.release();
72 }
73 }
74
75 // This takes ownership of the store
76 SSL_CTX_set_cert_store(ctx.native_handle(), store.release());
77
78#else
79 ctx.set_default_verify_paths(ec);
80#endif
81}
82
83} // namespace xrpl
84
85// There is a very unpleasant interaction between <wincrypt> and
86// openssl x509 types (namely the former has macros that stomp
87// on the latter), these undefs allow this TU to be safely used in
88// unity builds without messing up subsequent TUs. Although we
89// no longer use unity builds, leaving the undefs here does no harm.
90#if BOOST_OS_WINDOWS
91#undef X509_NAME
92#undef X509_EXTENSIONS
93#undef X509_CERT_PAIR
94#undef PKCS7_ISSUER_AND_SERIAL
95#undef OCSP_REQUEST
96#undef OCSP_RESPONSE
97#endif
A generic endpoint for log messages.
Definition Journal.h:40
Stream warn() const
Definition Journal.h:312
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
void registerSSLCerts(boost::asio::ssl::context &, boost::system::error_code &, beast::Journal j)
Register default SSL certificates.