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