xrpld
Loading...
Searching...
No Matches
HTTPClientSSLContext.h
1#pragma once
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/contract.h>
5#include <xrpl/beast/utility/Journal.h>
6#include <xrpl/net/RegisterSSLCerts.h>
7
8#include <boost/asio.hpp>
9#include <boost/asio/ip/tcp.hpp>
10#include <boost/asio/ssl.hpp>
11#include <boost/format.hpp>
12
13namespace xrpl {
14
16{
17public:
19 std::string const& sslVerifyDir,
20 std::string const& sslVerifyFile,
21 bool sslVerify,
23 boost::asio::ssl::context_base::method method = boost::asio::ssl::context::sslv23)
24 : sslContext_{method}, j_(j), verify_{sslVerify}
25 {
26 boost::system::error_code ec;
27
28 if (sslVerifyFile.empty())
29 {
30 registerSSLCerts(sslContext_, ec, j_);
31
32 if (ec && sslVerifyDir.empty())
33 {
34 Throw<std::runtime_error>(boost::str(
35 boost::format("Failed to set_default_verify_paths: %s") % ec.message()));
36 }
37 }
38 else
39 {
40 sslContext_.load_verify_file(sslVerifyFile);
41 }
42
43 if (!sslVerifyDir.empty())
44 {
45 sslContext_.add_verify_path(sslVerifyDir, ec);
46
47 if (ec)
48 {
49 Throw<std::runtime_error>(
50 boost::str(boost::format("Failed to add verify path: %s") % ec.message()));
51 }
52 }
53 }
54
55 boost::asio::ssl::context&
57 {
58 return sslContext_;
59 }
60
61 [[nodiscard]] bool
62 sslVerify() const
63 {
64 return verify_;
65 }
66
79 template <
80 class T,
81 class = std::enable_if_t<
84 boost::system::error_code
85 preConnectVerify(T& strm, std::string const& host)
86 {
87 boost::system::error_code ec;
88 if (!SSL_set_tlsext_host_name(strm.native_handle(), host.c_str()))
89 {
90 ec.assign(static_cast<int>(::ERR_get_error()), boost::asio::error::get_ssl_category());
91 }
92 else if (!sslVerify())
93 {
94 strm.set_verify_mode(boost::asio::ssl::verify_none, ec);
95 }
96 return ec;
97 }
98
99 template <
100 class T,
101 class = std::enable_if_t<
111 boost::system::error_code
112 postConnectVerify(T& strm, std::string const& host)
113 {
114 boost::system::error_code ec;
115
116 if (sslVerify())
117 {
118 strm.set_verify_mode(boost::asio::ssl::verify_peer, ec);
119 if (!ec)
120 {
121 strm.set_verify_callback(
122 std::bind(
123 &rfc6125Verify, host, std::placeholders::_1, std::placeholders::_2, j_),
124 ec);
125 }
126 }
127
128 return ec;
129 }
130
140 static bool
142 std::string const& domain,
143 bool preverified,
144 boost::asio::ssl::verify_context& ctx,
146 {
147 if (boost::asio::ssl::host_name_verification(domain)(preverified, ctx))
148 return true;
149
150 JLOG(j.warn()) << "Outbound SSL connection to " << domain
151 << " fails certificate verification";
152 return false;
153 }
154
155private:
156 boost::asio::ssl::context sslContext_;
158 bool const verify_;
159};
160
161} // namespace xrpl
T bind(T... args)
T c_str(T... args)
A generic endpoint for log messages.
Definition Journal.h:38
Stream warn() const
Definition Journal.h:309
boost::system::error_code preConnectVerify(T &strm, std::string const &host)
invoked before connect/async_connect on an ssl stream to setup name verification.
boost::system::error_code postConnectVerify(T &strm, std::string const &host)
invoked after connect/async_connect but before sending data on an ssl stream - to setup name verifica...
static bool rfc6125Verify(std::string const &domain, bool preverified, boost::asio::ssl::verify_context &ctx, beast::Journal j)
callback invoked for name verification - just passes through to the asio host_name_verification (rfc6...
boost::asio::ssl::context sslContext_
HTTPClientSSLContext(std::string const &sslVerifyDir, std::string const &sslVerifyFile, bool sslVerify, beast::Journal j, boost::asio::ssl::context_base::method method=boost::asio::ssl::context::sslv23)
boost::asio::ssl::context & context()
T empty(T... args)
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5