rippled
Loading...
Searching...
No Matches
RegisterSSLCerts.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2017 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/net/RegisterSSLCerts.h>
21
22#if BOOST_OS_WINDOWS
23#include <boost/asio/ssl/error.hpp>
24#include <boost/system/error_code.hpp>
25
26#include <openssl/err.h>
27#include <openssl/ssl.h>
28#include <openssl/x509.h>
29
30#include <wincrypt.h>
31
32#include <memory>
33#endif
34
35namespace ripple {
36
37void
39 boost::asio::ssl::context& ctx,
40 boost::system::error_code& ec,
42{
43#if BOOST_OS_WINDOWS
44 auto certStoreDelete = [](void* h) {
45 if (h != nullptr)
46 CertCloseStore(h, 0);
47 };
48 std::unique_ptr<void, decltype(certStoreDelete)> hStore{
49 CertOpenSystemStore(0, "ROOT"), certStoreDelete};
50
51 if (!hStore)
52 {
53 ec = boost::system::error_code(
54 GetLastError(), boost::system::system_category());
55 return;
56 }
57
58 ERR_clear_error();
59
60 std::unique_ptr<X509_STORE, decltype(X509_STORE_free)*> store{
61 X509_STORE_new(), X509_STORE_free};
62
63 if (!store)
64 {
65 ec = boost::system::error_code(
66 static_cast<int>(::ERR_get_error()),
67 boost::asio::error::get_ssl_category());
68 return;
69 }
70
71 auto warn = [&](std::string const& mesg) {
72 // Buffer based on asio recommended size
73 char buf[256];
74 ::ERR_error_string_n(ec.value(), buf, sizeof(buf));
75 JLOG(j.warn()) << mesg << " " << buf;
76 ::ERR_clear_error();
77 };
78
79 PCCERT_CONTEXT pContext = NULL;
80 while ((pContext = CertEnumCertificatesInStore(hStore.get(), pContext)) !=
81 NULL)
82 {
83 unsigned char const* pbCertEncoded = pContext->pbCertEncoded;
84 std::unique_ptr<X509, decltype(X509_free)*> x509{
85 d2i_X509(NULL, &pbCertEncoded, pContext->cbCertEncoded), X509_free};
86 if (!x509)
87 {
88 warn("Error decoding certificate");
89 continue;
90 }
91
92 if (X509_STORE_add_cert(store.get(), x509.get()) != 1)
93 {
94 warn("Error adding certificate");
95 }
96 else
97 {
98 // Successfully adding to the store took ownership
99 x509.release();
100 }
101 }
102
103 // This takes ownership of the store
104 SSL_CTX_set_cert_store(ctx.native_handle(), store.release());
105
106#else
107 ctx.set_default_verify_paths(ec);
108#endif
109}
110
111} // namespace ripple
112
113// There is a very unpleasant interaction between <wincrypt> and
114// openssl x509 types (namely the former has macros that stomp
115// on the latter), these undefs allow this TU to be safely used in
116// unity builds without messing up subsequent TUs.
117#if BOOST_OS_WINDOWS
118#undef X509_NAME
119#undef X509_EXTENSIONS
120#undef X509_CERT_PAIR
121#undef PKCS7_ISSUER_AND_SERIAL
122#undef OCSP_REQUEST
123#undef OCSP_RESPONSE
124#endif
A generic endpoint for log messages.
Definition Journal.h:60
Stream warn() const
Definition Journal.h:340
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
void registerSSLCerts(boost::asio::ssl::context &, boost::system::error_code &, beast::Journal j)
Register default SSL certificates.