2 * Copyright (c) 2015, Facebook, Inc.
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
12 #include <folly/io/async/EventBase.h>
13 #include <folly/io/async/SSLContext.h>
15 #include <glog/logging.h>
18 #include <folly/wangle/ssl/SSLContextConfig.h>
19 #include <folly/wangle/ssl/SSLSessionCacheManager.h>
20 #include <folly/wangle/ssl/TLSTicketKeySeeds.h>
21 #include <folly/wangle/acceptor/DomainNameMisc.h>
28 class ClientHelloExtStats;
29 struct SSLCacheOptions;
31 class TLSTicketKeyManager;
32 struct TLSTicketKeySeeds;
34 class SSLContextManager {
37 explicit SSLContextManager(EventBase* eventBase,
38 const std::string& vipName, bool strict,
40 virtual ~SSLContextManager();
43 * Add a new X509 to SSLContextManager. The details of a X509
44 * is passed as a SSLContextConfig object.
46 * @param ctxConfig Details of a X509, its private key, password, etc.
47 * @param cacheOptions Options for how to do session caching.
48 * @param ticketSeeds If non-null, the initial ticket key seeds to use.
49 * @param vipAddress Which VIP are the X509(s) used for? It is only for
50 * for user friendly log message
51 * @param externalCache Optional external provider for the session cache;
54 void addSSLContextConfig(
55 const SSLContextConfig& ctxConfig,
56 const SSLCacheOptions& cacheOptions,
57 const TLSTicketKeySeeds* ticketSeeds,
58 const folly::SocketAddress& vipAddress,
59 const std::shared_ptr<SSLCacheProvider> &externalCache);
62 * Get the default SSL_CTX for a VIP
64 std::shared_ptr<SSLContext>
65 getDefaultSSLCtx() const;
68 * Search by the _one_ level up subdomain
70 std::shared_ptr<SSLContext>
71 getSSLCtxBySuffix(const DNString& dnstr) const;
74 * Search by the full-string domain name
76 std::shared_ptr<SSLContext>
77 getSSLCtx(const DNString& dnstr) const;
80 * Insert a SSLContext by domain name.
82 void insertSSLCtxByDomainName(
85 std::shared_ptr<SSLContext> sslCtx);
87 void insertSSLCtxByDomainNameImpl(
90 std::shared_ptr<SSLContext> sslCtx);
92 void reloadTLSTicketKeys(const std::vector<std::string>& oldSeeds,
93 const std::vector<std::string>& currentSeeds,
94 const std::vector<std::string>& newSeeds);
97 * SSLContextManager only collects SNI stats now
100 void setClientHelloExtStats(ClientHelloExtStats* stats) {
101 clientHelloTLSExtStats_ = stats;
105 virtual void enableAsyncCrypto(
106 const std::shared_ptr<SSLContext>& sslCtx) {
107 LOG(FATAL) << "Unsupported in base SSLContextManager";
109 SSLStats* stats_{nullptr};
112 SSLContextManager(const SSLContextManager&) = delete;
114 void ctxSetupByOpensslFeature(
115 std::shared_ptr<SSLContext> sslCtx,
116 const SSLContextConfig& ctxConfig);
119 * Callback function from openssl to find the right X509 to
120 * use during SSL handshake
122 #if OPENSSL_VERSION_NUMBER >= 0x1000105fL && \
123 !defined(OPENSSL_NO_TLSEXT) && \
124 defined(SSL_CTRL_SET_TLSEXT_SERVERNAME_CB)
125 # define PROXYGEN_HAVE_SERVERNAMECALLBACK
126 SSLContext::ServerNameCallbackResult
127 serverNameCallback(SSL* ssl);
131 * The following functions help to maintain the data structure for
132 * domain name matching in SNI. Some notes:
134 * 1. It is a best match.
136 * 2. It allows wildcard CN and wildcard subject alternative name in a X509.
137 * The wildcard name must be _prefixed_ by '*.'. It errors out whenever
138 * it sees '*' in any other locations.
140 * 3. It uses one std::unordered_map<DomainName, SSL_CTX> object to
141 * do this. For wildcard name like "*.facebook.com", ".facebook.com"
142 * is used as the key.
144 * 4. After getting tlsext_hostname from the client hello message, it
145 * will do a full string search first and then try one level up to
146 * match any wildcard name (if any) in the X509.
147 * [Note, browser also only looks one level up when matching the requesting
148 * domain name with the wildcard name in the server X509].
152 std::shared_ptr<SSLContext> sslCtx,
153 std::unique_ptr<SSLSessionCacheManager> cmanager,
154 std::unique_ptr<TLSTicketKeyManager> tManager,
155 bool defaultFallback);
158 * Container to own the SSLContext, SSLSessionCacheManager and
159 * TLSTicketKeyManager.
161 std::vector<std::shared_ptr<SSLContext>> ctxs_;
162 std::vector<std::unique_ptr<SSLSessionCacheManager>>
163 sessionCacheManagers_;
164 std::vector<std::unique_ptr<TLSTicketKeyManager>> ticketManagers_;
166 std::shared_ptr<SSLContext> defaultCtx_;
169 * Container to store the (DomainName -> SSL_CTX) mapping
173 std::shared_ptr<SSLContext>,
174 DNStringHash> dnMap_;
176 EventBase* eventBase_;
177 ClientHelloExtStats* clientHelloTLSExtStats_{nullptr};
178 SSLContextConfig::SNINoMatchFn noMatchFn_;