proxygen
SSLContext.h
Go to the documentation of this file.
1 /*
2  * Copyright 2014-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <list>
20 #include <map>
21 #include <memory>
22 #include <mutex>
23 #include <random>
24 #include <string>
25 #include <vector>
26 
27 #include <glog/logging.h>
28 
29 #ifndef FOLLY_NO_CONFIG
30 #include <folly/folly-config.h>
31 #endif
32 
33 #include <folly/Function.h>
34 #include <folly/Portability.h>
35 #include <folly/Range.h>
36 #include <folly/String.h>
41 
42 namespace folly {
43 
48  public:
49  virtual ~PasswordCollector() = default;
60  virtual void getPassword(std::string& password, int size) const = 0;
61 
65  virtual std::string describe() const = 0;
66 };
67 
72  public:
73  virtual ~SSLAcceptRunner() = default;
74 
80  virtual void run(Function<int()> acceptFunc, Function<void(int)> finallyFunc)
81  const {
82  finallyFunc(acceptFunc());
83  }
84 };
85 
89 class SSLContext {
90  public:
91  enum SSLVersion {
94  TLSv1, // support TLS 1.0+
95  TLSv1_2, // support for only TLS 1.2+
96  };
97 
102  // Used by AsyncSSLSocket to delegate to the SSLContext's setting
104  // For server side - request a client certificate and verify the
105  // certificate if it is sent. Does not fail if the client does not present
106  // a certificate.
107  // For client side - validates the server certificate or fails.
109  // For server side - same as VERIFY but will fail if no certificate
110  // is sent.
111  // For client side - same as VERIFY.
113  // No verification is done for both server and client side.
114  NO_VERIFY
115  };
116 
118  NextProtocolsItem(int wt, const std::list<std::string>& ptcls)
119  : weight(wt), protocols(ptcls) {}
120  int weight;
121  std::list<std::string> protocols;
122  };
123 
124  // Function that selects a client protocol given the server's list
125  using ClientProtocolFilterCallback = bool (*)(
126  unsigned char**,
127  unsigned int*,
128  const unsigned char*,
129  unsigned int);
130 
138  return getErrors(errno);
139  }
140 
146  explicit SSLContext(SSLVersion version = TLSv1);
147  virtual ~SSLContext();
148 
154  virtual void ciphers(const std::string& ciphers);
155 
160  virtual void setCiphersOrThrow(const std::string& ciphers);
161 
166  template <typename Iterator>
167  void setCipherList(Iterator ibegin, Iterator iend) {
168  if (ibegin != iend) {
169  std::string opensslCipherList;
170  folly::join(":", ibegin, iend, opensslCipherList);
171  setCiphersOrThrow(opensslCipherList);
172  }
173  }
174 
175  template <typename Container>
176  void setCipherList(const Container& cipherList) {
177  using namespace std;
178  setCipherList(begin(cipherList), end(cipherList));
179  }
180 
181  template <typename Value>
182  void setCipherList(const std::initializer_list<Value>& cipherList) {
183  setCipherList(cipherList.begin(), cipherList.end());
184  }
185 
191  template <typename Iterator>
192  void setSignatureAlgorithms(Iterator ibegin, Iterator iend) {
193  if (ibegin != iend) {
194 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL
195  std::string opensslSigAlgsList;
196  join(":", ibegin, iend, opensslSigAlgsList);
197  if (!SSL_CTX_set1_sigalgs_list(ctx_, opensslSigAlgsList.c_str())) {
198  throw std::runtime_error("SSL_CTX_set1_sigalgs_list " + getErrors());
199  }
200 #endif
201  }
202  }
203 
204  template <typename Container>
205  void setSignatureAlgorithms(const Container& sigalgs) {
206  using namespace std;
207  setSignatureAlgorithms(begin(sigalgs), end(sigalgs));
208  }
209 
210  template <typename Value>
211  void setSignatureAlgorithms(const std::initializer_list<Value>& sigalgs) {
212  setSignatureAlgorithms(sigalgs.begin(), sigalgs.end());
213  }
214 
220  void setClientECCurvesList(const std::vector<std::string>& ecCurves);
221 
227  void setServerECCurve(const std::string& curveName);
228 
232  void setX509VerifyParam(const ssl::X509VerifyParam& x509VerifyParam);
233 
240  virtual void setVerificationOption(const SSLVerifyPeerEnum& verifyPeer);
241 
248  virtual bool needsPeerVerification() {
249  return (
250  verifyPeer_ == SSLVerifyPeerEnum::VERIFY ||
251  verifyPeer_ == SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT);
252  }
253 
264  static int getVerificationMode(const SSLVerifyPeerEnum& verifyPeer);
265 
272  virtual int getVerificationMode();
273 
286  virtual void authenticate(
287  bool checkPeerCert,
288  bool checkPeerName,
289  const std::string& peerName = std::string());
296  virtual void loadCertificate(const char* path, const char* format = "PEM");
302  virtual void loadCertificateFromBufferPEM(folly::StringPiece cert);
303 
310  virtual void loadPrivateKey(const char* path, const char* format = "PEM");
316  virtual void loadPrivateKeyFromBufferPEM(folly::StringPiece pkey);
317 
325  virtual void loadCertKeyPairFromBufferPEM(
326  folly::StringPiece cert,
327  folly::StringPiece pkey);
328 
338  virtual void loadCertKeyPairFromFiles(
339  const char* certPath,
340  const char* keyPath,
341  const char* certFormat = "PEM",
342  const char* keyFormat = "PEM");
343 
350  virtual bool isCertKeyPairValid() const;
351 
357  virtual void loadTrustedCertificates(const char* path);
363  virtual void loadTrustedCertificates(X509_STORE* store);
367  virtual void loadClientCAList(const char* path);
373  virtual void passwordCollector(std::shared_ptr<PasswordCollector> collector);
379  virtual std::shared_ptr<PasswordCollector> passwordCollector() {
380  return collector_;
381  }
382 #if FOLLY_OPENSSL_HAS_SNI
383 
386  enum ServerNameCallbackResult {
387  SERVER_NAME_FOUND,
388  SERVER_NAME_NOT_FOUND,
389  SERVER_NAME_NOT_FOUND_ALERT_FATAL,
390  };
426  typedef std::function<ServerNameCallbackResult(SSL* ssl)> ServerNameCallback;
427  virtual void setServerNameCallback(const ServerNameCallback& cb);
428 
433  typedef std::function<void(SSL* ssl)> ClientHelloCallback;
434  virtual void addClientHelloCallback(const ClientHelloCallback& cb);
435 #endif // FOLLY_OPENSSL_HAS_SNI
436 
440  SSL* createSSL() const;
441 
445  void setSessionCacheContext(const std::string& context);
446 
450  void setOptions(long options);
451 
452 #if FOLLY_OPENSSL_HAS_ALPN
453 
468  bool setAdvertisedNextProtocols(const std::list<std::string>& protocols);
490  bool setRandomizedAdvertisedNextProtocols(
491  const std::list<NextProtocolsItem>& items);
492 
496  void unsetNextProtocols();
497  void deleteNextProtocolsStrings();
498 #endif // FOLLY_OPENSSL_HAS_ALPN
499 
503  SSL_CTX* getSSLCtx() const {
504  return ctx_;
505  }
506 
513  static std::string getErrors(int errnoCopy);
514 
515  bool checkPeerName() {
516  return checkPeerName_;
517  }
519  return peerFixedName_;
520  }
521 
522 #if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH)
523 
528  void enableFalseStart();
529 #endif
530 
535  void sslAcceptRunner(std::unique_ptr<SSLAcceptRunner> runner) {
536  if (nullptr == runner) {
537  LOG(ERROR) << "Ignore invalid runner";
538  return;
539  }
540  sslAcceptRunner_ = std::move(runner);
541  }
542 
544  return sslAcceptRunner_.get();
545  }
546 
550  static bool matchName(const char* host, const char* pattern, int size);
551 
552  [[deprecated("Use folly::ssl::init")]] static void initializeOpenSSL();
553 
554  protected:
555  SSL_CTX* ctx_;
556 
557  private:
558  SSLVerifyPeerEnum verifyPeer_{SSLVerifyPeerEnum::NO_VERIFY};
559 
562  std::shared_ptr<PasswordCollector> collector_;
563 #if FOLLY_OPENSSL_HAS_SNI
564  ServerNameCallback serverNameCb_;
565  std::vector<ClientHelloCallback> clientHelloCbs_;
566 #endif
567 
568  ClientProtocolFilterCallback clientProtoFilter_{nullptr};
569 
570  static bool initialized_;
571 
572  std::unique_ptr<SSLAcceptRunner> sslAcceptRunner_;
573 
574 #if FOLLY_OPENSSL_HAS_ALPN
575 
576  struct AdvertisedNextProtocolsItem {
577  unsigned char* protocols;
578  unsigned length;
579  };
580 
584  std::vector<AdvertisedNextProtocolsItem> advertisedNextProtocols_;
585  std::vector<int> advertisedNextProtocolWeights_;
586  std::discrete_distribution<int> nextProtocolDistribution_;
587 
588  static int advertisedNextProtocolCallback(
589  SSL* ssl,
590  const unsigned char** out,
591  unsigned int* outlen,
592  void* data);
593 
594  static int alpnSelectCallback(
595  SSL* ssl,
596  const unsigned char** out,
597  unsigned char* outlen,
598  const unsigned char* in,
599  unsigned int inlen,
600  void* data);
601 
602  size_t pickNextProtocols();
603 
604 #endif // FOLLY_OPENSSL_HAS_ALPN
605 
606  static int passwordCallback(char* password, int size, int, void* data);
607 
608 #if FOLLY_OPENSSL_HAS_SNI
609 
619  static int baseServerNameOpenSSLCallback(
620  SSL* ssl,
621  int* al /* alert (return value) */,
622  void* data);
623 #endif
624 
626 };
627 
628 typedef std::shared_ptr<SSLContext> SSLContextPtr;
629 
630 std::ostream& operator<<(
631  std::ostream& os,
632  const folly::PasswordCollector& collector);
633 
634 } // namespace folly
static std::string getErrors()
Definition: SSLContext.h:137
virtual std::shared_ptr< PasswordCollector > passwordCollector()
Definition: SSLContext.h:379
void setCipherList(const std::initializer_list< Value > &cipherList)
Definition: SSLContext.h:182
void setCipherList(Iterator ibegin, Iterator iend)
Definition: SSLContext.h:167
virtual void run(Function< int()> acceptFunc, Function< void(int)> finallyFunc) const
Definition: SSLContext.h:80
void setCipherList(const Container &cipherList)
Definition: SSLContext.h:176
NextProtocolsItem(int wt, const std::list< std::string > &ptcls)
Definition: SSLContext.h:118
const SSLAcceptRunner * sslAcceptRunner()
Definition: SSLContext.h:543
context
Definition: CMakeCache.txt:563
SSL_CTX * ctx_
Definition: SSLContext.h:555
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
STL namespace.
auto begin(TestAdlIterable &instance)
Definition: ForeachTest.cpp:56
bool checkPeerName()
Definition: SSLContext.h:515
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
void setSignatureAlgorithms(const std::initializer_list< Value > &sigalgs)
Definition: SSLContext.h:211
virtual ~PasswordCollector()=default
void sslAcceptRunner(std::unique_ptr< SSLAcceptRunner > runner)
Definition: SSLContext.h:535
std::shared_ptr< FizzServerContext > ctx_
std::shared_ptr< PasswordCollector > collector_
Definition: SSLContext.h:562
ProtocolVersion version
virtual void getPassword(std::string &password, int size) const =0
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
SSL_CTX * getSSLCtx() const
Definition: SSLContext.h:503
bool(*)(unsigned char **, unsigned int *, const unsigned char *, unsigned int) ClientProtocolFilterCallback
Definition: SSLContext.h:129
std::shared_ptr< SSLContext > SSLContextPtr
Definition: SSLContext.h:628
auto end(TestAdlIterable &instance)
Definition: ForeachTest.cpp:62
virtual std::string describe() const =0
constexpr auto data(C &c) -> decltype(c.data())
Definition: Access.h:71
void setSignatureAlgorithms(const Container &sigalgs)
Definition: SSLContext.h:205
void setSignatureAlgorithms(SSLContext &ctx)
Definition: SSLOptions.h:111
std::unique_ptr< SSLAcceptRunner > sslAcceptRunner_
Definition: SSLContext.h:572
virtual bool needsPeerVerification()
Definition: SSLContext.h:248
const char * string
Definition: Conv.cpp:212
void setSignatureAlgorithms(Iterator ibegin, Iterator iend)
Definition: SSLContext.h:192
std::string peerFixedName()
Definition: SSLContext.h:518
void join(const Delim &delimiter, Iterator begin, Iterator end, String &output)
Definition: String-inl.h:498
static int passwordCallback(char *password, int size, int, void *data)
Definition: FizzUtil.cpp:19
Formatter< false, Args... > format(StringPiece fmt, Args &&...args)
Definition: Format.h:271
static bool initialized_
Definition: SSLContext.h:570
std::list< std::string > protocols
Definition: SSLContext.h:121
std::unique_ptr< X509_VERIFY_PARAM, X509VerifyParamDeleter > X509VerifyParam
std::string peerFixedName_
Definition: SSLContext.h:561
std::string providedCiphersString_
Definition: SSLContext.h:625
std::ostream & operator<<(std::ostream &out, dynamic const &d)
Definition: dynamic-inl.h:1158