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