rippled
Loading...
Searching...
No Matches
HTTPClientSSLContext.h
1#ifndef XRPL_NET_HTTPCLIENTSSLCONTEXT_H_INCLUDED
2#define XRPL_NET_HTTPCLIENTSSLCONTEXT_H_INCLUDED
3
4#include <xrpl/basics/Log.h>
5#include <xrpl/basics/contract.h>
6#include <xrpl/beast/utility/Journal.h>
7#include <xrpl/net/RegisterSSLCerts.h>
8
9#include <boost/asio.hpp>
10#include <boost/asio/ip/tcp.hpp>
11#include <boost/asio/ssl.hpp>
12#include <boost/format.hpp>
13
14namespace ripple {
15
17{
18public:
20 std::string const& sslVerifyDir,
21 std::string const& sslVerifyFile,
22 bool sslVerify,
24 boost::asio::ssl::context_base::method method =
25 boost::asio::ssl::context::sslv23)
26 : ssl_context_{method}, j_(j), verify_{sslVerify}
27 {
28 boost::system::error_code ec;
29
30 if (sslVerifyFile.empty())
31 {
33
34 if (ec && sslVerifyDir.empty())
35 Throw<std::runtime_error>(boost::str(
36 boost::format("Failed to set_default_verify_paths: %s") %
37 ec.message()));
38 }
39 else
40 {
41 ssl_context_.load_verify_file(sslVerifyFile);
42 }
43
44 if (!sslVerifyDir.empty())
45 {
46 ssl_context_.add_verify_path(sslVerifyDir, ec);
47
48 if (ec)
49 Throw<std::runtime_error>(boost::str(
50 boost::format("Failed to add verify path: %s") %
51 ec.message()));
52 }
53 }
54
55 boost::asio::ssl::context&
57 {
58 return ssl_context_;
59 }
60
61 bool
62 sslVerify() const
63 {
64 return verify_;
65 }
66
79 template <
80 class T,
81 class = std::enable_if_t<
83 T,
84 boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>::
85 value ||
87 T,
88 boost::asio::ssl::stream<boost::asio::ip::tcp::socket&>>::
89 value>>
90 boost::system::error_code
91 preConnectVerify(T& strm, std::string const& host)
92 {
93 boost::system::error_code ec;
94 if (!SSL_set_tlsext_host_name(strm.native_handle(), host.c_str()))
95 {
96 ec.assign(
97 static_cast<int>(::ERR_get_error()),
98 boost::asio::error::get_ssl_category());
99 }
100 else if (!sslVerify())
101 {
102 strm.set_verify_mode(boost::asio::ssl::verify_none, ec);
103 }
104 return ec;
105 }
106
107 template <
108 class T,
109 class = std::enable_if_t<
111 T,
112 boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>::
113 value ||
115 T,
116 boost::asio::ssl::stream<boost::asio::ip::tcp::socket&>>::
117 value>>
125 boost::system::error_code
126 postConnectVerify(T& strm, std::string const& host)
127 {
128 boost::system::error_code ec;
129
130 if (sslVerify())
131 {
132 strm.set_verify_mode(boost::asio::ssl::verify_peer, ec);
133 if (!ec)
134 {
135 strm.set_verify_callback(
136 std::bind(
138 host,
139 std::placeholders::_1,
140 std::placeholders::_2,
141 j_),
142 ec);
143 }
144 }
145
146 return ec;
147 }
148
158 static bool
160 std::string const& domain,
161 bool preverified,
162 boost::asio::ssl::verify_context& ctx,
164 {
165 if (boost::asio::ssl::host_name_verification(domain)(preverified, ctx))
166 return true;
167
168 JLOG(j.warn()) << "Outbound SSL connection to " << domain
169 << " fails certificate verification";
170 return false;
171 }
172
173private:
174 boost::asio::ssl::context ssl_context_;
176 bool const verify_;
177};
178
179} // namespace ripple
180
181#endif
T bind(T... args)
T c_str(T... args)
A generic endpoint for log messages.
Definition Journal.h:41
Stream warn() const
Definition Journal.h:321
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::system::error_code preConnectVerify(T &strm, std::string const &host)
invoked before connect/async_connect on an ssl stream to setup name verification.
boost::asio::ssl::context ssl_context_
static bool rfc6125_verify(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::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...
boost::asio::ssl::context & context()
T empty(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
void registerSSLCerts(boost::asio::ssl::context &, boost::system::error_code &, beast::Journal j)
Register default SSL certificates.