AsyncSSLSocket.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971
  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. #pragma once
  17. #include <iomanip>
  18. #include <folly/Optional.h>
  19. #include <folly/String.h>
  20. #include <folly/io/Cursor.h>
  21. #include <folly/io/IOBuf.h>
  22. #include <folly/io/async/AsyncPipe.h>
  23. #include <folly/io/async/AsyncSocket.h>
  24. #include <folly/io/async/AsyncTimeout.h>
  25. #include <folly/io/async/SSLContext.h>
  26. #include <folly/io/async/TimeoutManager.h>
  27. #include <folly/io/async/ssl/OpenSSLUtils.h>
  28. #include <folly/io/async/ssl/SSLErrors.h>
  29. #include <folly/io/async/ssl/TLSDefinitions.h>
  30. #include <folly/lang/Bits.h>
  31. #include <folly/portability/OpenSSL.h>
  32. #include <folly/portability/Sockets.h>
  33. #include <folly/ssl/OpenSSLPtrTypes.h>
  34. namespace folly {
  35. /**
  36. * A class for performing asynchronous I/O on an SSL connection.
  37. *
  38. * AsyncSSLSocket allows users to asynchronously wait for data on an
  39. * SSL connection, and to asynchronously send data.
  40. *
  41. * The APIs for reading and writing are intentionally asymmetric.
  42. * Waiting for data to read is a persistent API: a callback is
  43. * installed, and is notified whenever new data is available. It
  44. * continues to be notified of new events until it is uninstalled.
  45. *
  46. * AsyncSSLSocket does not provide read timeout functionality,
  47. * because it typically cannot determine when the timeout should be
  48. * active. Generally, a timeout should only be enabled when
  49. * processing is blocked waiting on data from the remote endpoint.
  50. * For server connections, the timeout should not be active if the
  51. * server is currently processing one or more outstanding requests for
  52. * this connection. For client connections, the timeout should not be
  53. * active if there are no requests pending on the connection.
  54. * Additionally, if a client has multiple pending requests, it will
  55. * ususally want a separate timeout for each request, rather than a
  56. * single read timeout.
  57. *
  58. * The write API is fairly intuitive: a user can request to send a
  59. * block of data, and a callback will be informed once the entire
  60. * block has been transferred to the kernel, or on error.
  61. * AsyncSSLSocket does provide a send timeout, since most callers
  62. * want to give up if the remote end stops responding and no further
  63. * progress can be made sending the data.
  64. */
  65. class AsyncSSLSocket : public virtual AsyncSocket {
  66. public:
  67. typedef std::unique_ptr<AsyncSSLSocket, Destructor> UniquePtr;
  68. using X509_deleter = folly::static_function_deleter<X509, &X509_free>;
  69. class HandshakeCB {
  70. public:
  71. virtual ~HandshakeCB() = default;
  72. /**
  73. * handshakeVer() is invoked during handshaking to give the
  74. * application chance to validate it's peer's certificate.
  75. *
  76. * Note that OpenSSL performs only rudimentary internal
  77. * consistency verification checks by itself. Any other validation
  78. * like whether or not the certificate was issued by a trusted CA.
  79. * The default implementation of this callback mimics what what
  80. * OpenSSL does internally if SSL_VERIFY_PEER is set with no
  81. * verification callback.
  82. *
  83. * See the passages on verify_callback in SSL_CTX_set_verify(3)
  84. * for more details.
  85. */
  86. virtual bool handshakeVer(
  87. AsyncSSLSocket* /*sock*/,
  88. bool preverifyOk,
  89. X509_STORE_CTX* /*ctx*/) noexcept {
  90. return preverifyOk;
  91. }
  92. /**
  93. * handshakeSuc() is called when a new SSL connection is
  94. * established, i.e., after SSL_accept/connect() returns successfully.
  95. *
  96. * The HandshakeCB will be uninstalled before handshakeSuc()
  97. * is called.
  98. *
  99. * @param sock SSL socket on which the handshake was initiated
  100. */
  101. virtual void handshakeSuc(AsyncSSLSocket* sock) noexcept = 0;
  102. /**
  103. * handshakeErr() is called if an error occurs while
  104. * establishing the SSL connection.
  105. *
  106. * The HandshakeCB will be uninstalled before handshakeErr()
  107. * is called.
  108. *
  109. * @param sock SSL socket on which the handshake was initiated
  110. * @param ex An exception representing the error.
  111. */
  112. virtual void handshakeErr(
  113. AsyncSSLSocket* sock,
  114. const AsyncSocketException& ex) noexcept = 0;
  115. };
  116. class Timeout : public AsyncTimeout {
  117. public:
  118. Timeout(AsyncSSLSocket* sslSocket, EventBase* eventBase)
  119. : AsyncTimeout(eventBase), sslSocket_(sslSocket) {}
  120. bool scheduleTimeout(TimeoutManager::timeout_type timeout) {
  121. timeout_ = timeout;
  122. return AsyncTimeout::scheduleTimeout(timeout);
  123. }
  124. bool scheduleTimeout(uint32_t timeoutMs) {
  125. return scheduleTimeout(std::chrono::milliseconds{timeoutMs});
  126. }
  127. TimeoutManager::timeout_type getTimeout() {
  128. return timeout_;
  129. }
  130. void timeoutExpired() noexcept override {
  131. sslSocket_->timeoutExpired(timeout_);
  132. }
  133. private:
  134. AsyncSSLSocket* sslSocket_;
  135. TimeoutManager::timeout_type timeout_;
  136. };
  137. /**
  138. * A class to wait for asynchronous operations with OpenSSL 1.1.0
  139. */
  140. class DefaultOpenSSLAsyncFinishCallback : public ReadCallback {
  141. public:
  142. DefaultOpenSSLAsyncFinishCallback(
  143. AsyncPipeReader::UniquePtr reader,
  144. AsyncSSLSocket* sslSocket,
  145. DestructorGuard dg)
  146. : pipeReader_(std::move(reader)),
  147. sslSocket_(sslSocket),
  148. dg_(std::move(dg)) {}
  149. ~DefaultOpenSSLAsyncFinishCallback() {
  150. pipeReader_->setReadCB(nullptr);
  151. sslSocket_->setAsyncOperationFinishCallback(nullptr);
  152. }
  153. void readDataAvailable(size_t len) noexcept override {
  154. CHECK_EQ(len, 1);
  155. sslSocket_->restartSSLAccept();
  156. pipeReader_->setReadCB(nullptr);
  157. sslSocket_->setAsyncOperationFinishCallback(nullptr);
  158. }
  159. void getReadBuffer(void** bufReturn, size_t* lenReturn) noexcept override {
  160. *bufReturn = &byte_;
  161. *lenReturn = 1;
  162. }
  163. void readEOF() noexcept override {}
  164. void readErr(const folly::AsyncSocketException&) noexcept override {}
  165. private:
  166. uint8_t byte_{0};
  167. AsyncPipeReader::UniquePtr pipeReader_;
  168. AsyncSSLSocket* sslSocket_{nullptr};
  169. DestructorGuard dg_;
  170. };
  171. /**
  172. * Create a client AsyncSSLSocket
  173. */
  174. AsyncSSLSocket(
  175. const std::shared_ptr<folly::SSLContext>& ctx,
  176. EventBase* evb,
  177. bool deferSecurityNegotiation = false);
  178. /**
  179. * Create a server/client AsyncSSLSocket from an already connected
  180. * socket file descriptor.
  181. *
  182. * Note that while AsyncSSLSocket enables TCP_NODELAY for sockets it creates
  183. * when connecting, it does not change the socket options when given an
  184. * existing file descriptor. If callers want TCP_NODELAY enabled when using
  185. * this version of the constructor, they need to explicitly call
  186. * setNoDelay(true) after the constructor returns.
  187. *
  188. * @param ctx SSL context for this connection.
  189. * @param evb EventBase that will manage this socket.
  190. * @param fd File descriptor to take over (should be a connected socket).
  191. * @param server Is socket in server mode?
  192. * @param deferSecurityNegotiation
  193. * unencrypted data can be sent before sslConn/Accept
  194. */
  195. AsyncSSLSocket(
  196. const std::shared_ptr<folly::SSLContext>& ctx,
  197. EventBase* evb,
  198. int fd,
  199. bool server = true,
  200. bool deferSecurityNegotiation = false);
  201. /**
  202. * Create a server/client AsyncSSLSocket from an already connected
  203. * AsyncSocket.
  204. */
  205. AsyncSSLSocket(
  206. const std::shared_ptr<folly::SSLContext>& ctx,
  207. AsyncSocket::UniquePtr oldAsyncSocket,
  208. bool server = true,
  209. bool deferSecurityNegotiation = false);
  210. /**
  211. * Helper function to create a server/client shared_ptr<AsyncSSLSocket>.
  212. */
  213. static std::shared_ptr<AsyncSSLSocket> newSocket(
  214. const std::shared_ptr<folly::SSLContext>& ctx,
  215. EventBase* evb,
  216. int fd,
  217. bool server = true,
  218. bool deferSecurityNegotiation = false) {
  219. return std::shared_ptr<AsyncSSLSocket>(
  220. new AsyncSSLSocket(ctx, evb, fd, server, deferSecurityNegotiation),
  221. Destructor());
  222. }
  223. /**
  224. * Helper function to create a client shared_ptr<AsyncSSLSocket>.
  225. */
  226. static std::shared_ptr<AsyncSSLSocket> newSocket(
  227. const std::shared_ptr<folly::SSLContext>& ctx,
  228. EventBase* evb,
  229. bool deferSecurityNegotiation = false) {
  230. return std::shared_ptr<AsyncSSLSocket>(
  231. new AsyncSSLSocket(ctx, evb, deferSecurityNegotiation), Destructor());
  232. }
  233. #if FOLLY_OPENSSL_HAS_SNI
  234. /**
  235. * Create a client AsyncSSLSocket with tlsext_servername in
  236. * the Client Hello message.
  237. */
  238. AsyncSSLSocket(
  239. const std::shared_ptr<folly::SSLContext>& ctx,
  240. EventBase* evb,
  241. const std::string& serverName,
  242. bool deferSecurityNegotiation = false);
  243. /**
  244. * Create a client AsyncSSLSocket from an already connected
  245. * socket file descriptor.
  246. *
  247. * Note that while AsyncSSLSocket enables TCP_NODELAY for sockets it creates
  248. * when connecting, it does not change the socket options when given an
  249. * existing file descriptor. If callers want TCP_NODELAY enabled when using
  250. * this version of the constructor, they need to explicitly call
  251. * setNoDelay(true) after the constructor returns.
  252. *
  253. * @param ctx SSL context for this connection.
  254. * @param evb EventBase that will manage this socket.
  255. * @param fd File descriptor to take over (should be a connected socket).
  256. * @param serverName tlsext_hostname that will be sent in ClientHello.
  257. */
  258. AsyncSSLSocket(
  259. const std::shared_ptr<folly::SSLContext>& ctx,
  260. EventBase* evb,
  261. int fd,
  262. const std::string& serverName,
  263. bool deferSecurityNegotiation = false);
  264. static std::shared_ptr<AsyncSSLSocket> newSocket(
  265. const std::shared_ptr<folly::SSLContext>& ctx,
  266. EventBase* evb,
  267. const std::string& serverName,
  268. bool deferSecurityNegotiation = false) {
  269. return std::shared_ptr<AsyncSSLSocket>(
  270. new AsyncSSLSocket(ctx, evb, serverName, deferSecurityNegotiation),
  271. Destructor());
  272. }
  273. #endif // FOLLY_OPENSSL_HAS_SNI
  274. /**
  275. * TODO: implement support for SSL renegotiation.
  276. *
  277. * This involves proper handling of the SSL_ERROR_WANT_READ/WRITE
  278. * code as a result of SSL_write/read(), instead of returning an
  279. * error. In that case, the READ/WRITE event should be registered,
  280. * and a flag (e.g., writeBlockedOnRead) should be set to indiciate
  281. * the condition. In the next invocation of read/write callback, if
  282. * the flag is on, performWrite()/performRead() should be called in
  283. * addition to the normal call to performRead()/performWrite(), and
  284. * the flag should be reset.
  285. */
  286. // Inherit TAsyncTransport methods from AsyncSocket except the
  287. // following.
  288. // See the documentation in TAsyncTransport.h
  289. // TODO: implement graceful shutdown in close()
  290. // TODO: implement detachSSL() that returns the SSL connection
  291. void closeNow() override;
  292. void shutdownWrite() override;
  293. void shutdownWriteNow() override;
  294. bool good() const override;
  295. bool connecting() const override;
  296. std::string getApplicationProtocol() const noexcept override;
  297. std::string getSecurityProtocol() const override {
  298. if (sslState_ == STATE_UNENCRYPTED) {
  299. return "";
  300. }
  301. return "TLS";
  302. }
  303. void setEorTracking(bool track) override;
  304. size_t getRawBytesWritten() const override;
  305. size_t getRawBytesReceived() const override;
  306. void enableClientHelloParsing();
  307. /**
  308. * Accept an SSL connection on the socket.
  309. *
  310. * The callback will be invoked and uninstalled when an SSL
  311. * connection has been established on the underlying socket.
  312. * The value of verifyPeer determines the client verification method.
  313. * By default, its set to use the value in the underlying context
  314. *
  315. * @param callback callback object to invoke on success/failure
  316. * @param timeout timeout for this function in milliseconds, or 0 for no
  317. * timeout
  318. * @param verifyPeer SSLVerifyPeerEnum uses the options specified in the
  319. * context by default, can be set explcitly to override the
  320. * method in the context
  321. */
  322. virtual void sslAccept(
  323. HandshakeCB* callback,
  324. std::chrono::milliseconds timeout = std::chrono::milliseconds::zero(),
  325. const folly::SSLContext::SSLVerifyPeerEnum& verifyPeer =
  326. folly::SSLContext::SSLVerifyPeerEnum::USE_CTX);
  327. /**
  328. * Invoke SSL accept following an asynchronous session cache lookup
  329. */
  330. void restartSSLAccept();
  331. /**
  332. * Connect to the given address, invoking callback when complete or on error
  333. *
  334. * Note timeout applies to TCP + SSL connection time
  335. */
  336. void connect(
  337. ConnectCallback* callback,
  338. const folly::SocketAddress& address,
  339. int timeout = 0,
  340. const OptionMap& options = emptyOptionMap,
  341. const folly::SocketAddress& bindAddr = anyAddress()) noexcept override;
  342. /**
  343. * A variant of connect that allows the caller to specify
  344. * the timeout for the regular connect and the ssl connect
  345. * separately.
  346. * connectTimeout is specified as the time to establish a TCP
  347. * connection.
  348. * totalConnectTimeout defines the
  349. * time it takes from starting the TCP connection to the time
  350. * the ssl connection is established. The reason the timeout is
  351. * defined this way is because user's rarely need to specify the SSL
  352. * timeout independently of the connect timeout. It allows us to
  353. * bound the time for a connect and SSL connection in
  354. * a finer grained manner than if timeout was just defined
  355. * independently for SSL.
  356. */
  357. virtual void connect(
  358. ConnectCallback* callback,
  359. const folly::SocketAddress& address,
  360. std::chrono::milliseconds connectTimeout,
  361. std::chrono::milliseconds totalConnectTimeout,
  362. const OptionMap& options = emptyOptionMap,
  363. const folly::SocketAddress& bindAddr = anyAddress()) noexcept;
  364. using AsyncSocket::connect;
  365. /**
  366. * Initiate an SSL connection on the socket
  367. * The callback will be invoked and uninstalled when an SSL connection
  368. * has been establshed on the underlying socket.
  369. * The verification option verifyPeer is applied if it's passed explicitly.
  370. * If it's not, the options in SSLContext set on the underlying SSLContext
  371. * are applied.
  372. *
  373. * @param callback callback object to invoke on success/failure
  374. * @param timeout timeout for this function in milliseconds, or 0 for no
  375. * timeout
  376. * @param verifyPeer SSLVerifyPeerEnum uses the options specified in the
  377. * context by default, can be set explcitly to override the
  378. * method in the context. If verification is turned on sets
  379. * SSL_VERIFY_PEER and invokes
  380. * HandshakeCB::handshakeVer().
  381. */
  382. virtual void sslConn(
  383. HandshakeCB* callback,
  384. std::chrono::milliseconds timeout = std::chrono::milliseconds::zero(),
  385. const folly::SSLContext::SSLVerifyPeerEnum& verifyPeer =
  386. folly::SSLContext::SSLVerifyPeerEnum::USE_CTX);
  387. enum SSLStateEnum {
  388. STATE_UNINIT,
  389. STATE_UNENCRYPTED,
  390. STATE_ACCEPTING,
  391. STATE_CACHE_LOOKUP,
  392. STATE_ASYNC_PENDING,
  393. STATE_CONNECTING,
  394. STATE_ESTABLISHED,
  395. STATE_REMOTE_CLOSED, /// remote end closed; we can still write
  396. STATE_CLOSING, ///< close() called, but waiting on writes to complete
  397. /// close() called with pending writes, before connect() has completed
  398. STATE_CONNECTING_CLOSING,
  399. STATE_CLOSED,
  400. STATE_ERROR
  401. };
  402. SSLStateEnum getSSLState() const {
  403. return sslState_;
  404. }
  405. /**
  406. * Get a handle to the negotiated SSL session. This increments the session
  407. * refcount and must be deallocated by the caller.
  408. */
  409. SSL_SESSION* getSSLSession();
  410. /**
  411. * Get a handle to the SSL struct.
  412. */
  413. const SSL* getSSL() const;
  414. /**
  415. * Set the SSL session to be used during sslConn. AsyncSSLSocket will
  416. * hold a reference to the session until it is destroyed or released by the
  417. * underlying SSL structure.
  418. *
  419. * @param takeOwnership if true, AsyncSSLSocket will assume the caller's
  420. * reference count to session.
  421. */
  422. void setSSLSession(SSL_SESSION* session, bool takeOwnership = false);
  423. /**
  424. * Get the name of the protocol selected by the client during
  425. * Application Layer Protocol Negotiation (ALPN)
  426. *
  427. * Throw an exception if openssl does not support NPN
  428. *
  429. * @param protoName Name of the protocol (not guaranteed to be
  430. * null terminated); will be set to nullptr if
  431. * the client did not negotiate a protocol.
  432. * Note: the AsyncSSLSocket retains ownership
  433. * of this string.
  434. * @param protoNameLen Length of the name.
  435. * @param protoType Whether this was an NPN or ALPN negotiation
  436. */
  437. virtual void getSelectedNextProtocol(
  438. const unsigned char** protoName,
  439. unsigned* protoLen) const;
  440. /**
  441. * Get the name of the protocol selected by the client during
  442. * Next Protocol Negotiation (NPN) or Application Layer Protocol Negotiation
  443. * (ALPN)
  444. *
  445. * @param protoName Name of the protocol (not guaranteed to be
  446. * null terminated); will be set to nullptr if
  447. * the client did not negotiate a protocol.
  448. * Note: the AsyncSSLSocket retains ownership
  449. * of this string.
  450. * @param protoNameLen Length of the name.
  451. * @param protoType Whether this was an NPN or ALPN negotiation
  452. * @return false if openssl does not support NPN
  453. */
  454. virtual bool getSelectedNextProtocolNoThrow(
  455. const unsigned char** protoName,
  456. unsigned* protoLen) const;
  457. /**
  458. * Determine if the session specified during setSSLSession was reused
  459. * or if the server rejected it and issued a new session.
  460. */
  461. virtual bool getSSLSessionReused() const;
  462. /**
  463. * true if the session was resumed using session ID
  464. */
  465. bool sessionIDResumed() const {
  466. return sessionIDResumed_;
  467. }
  468. void setSessionIDResumed(bool resumed) {
  469. sessionIDResumed_ = resumed;
  470. }
  471. /**
  472. * Get the negociated cipher name for this SSL connection.
  473. * Returns the cipher used or the constant value "NONE" when no SSL session
  474. * has been established.
  475. */
  476. virtual const char* getNegotiatedCipherName() const;
  477. /**
  478. * Get the server name for this SSL connection.
  479. * Returns the server name used or the constant value "NONE" when no SSL
  480. * session has been established.
  481. * If openssl has no SNI support, throw TTransportException.
  482. */
  483. const char* getSSLServerName() const;
  484. /**
  485. * Get the server name for this SSL connection.
  486. * Returns the server name used or the constant value "NONE" when no SSL
  487. * session has been established.
  488. * If openssl has no SNI support, return "NONE"
  489. */
  490. const char* getSSLServerNameNoThrow() const;
  491. /**
  492. * Get the SSL version for this connection.
  493. * Possible return values are SSL2_VERSION, SSL3_VERSION, TLS1_VERSION,
  494. * with hexa representations 0x200, 0x300, 0x301,
  495. * or 0 if no SSL session has been established.
  496. */
  497. int getSSLVersion() const;
  498. /**
  499. * Get the signature algorithm used in the cert that is used for this
  500. * connection.
  501. */
  502. const char* getSSLCertSigAlgName() const;
  503. /**
  504. * Get the certificate size used for this SSL connection.
  505. */
  506. int getSSLCertSize() const;
  507. /**
  508. * Get the certificate used for this SSL connection. May be null
  509. */
  510. const X509* getSelfCert() const override;
  511. void attachEventBase(EventBase* eventBase) override {
  512. AsyncSocket::attachEventBase(eventBase);
  513. handshakeTimeout_.attachEventBase(eventBase);
  514. connectionTimeout_.attachEventBase(eventBase);
  515. }
  516. void detachEventBase() override {
  517. AsyncSocket::detachEventBase();
  518. handshakeTimeout_.detachEventBase();
  519. connectionTimeout_.detachEventBase();
  520. }
  521. bool isDetachable() const override {
  522. return AsyncSocket::isDetachable() && !handshakeTimeout_.isScheduled();
  523. }
  524. virtual void attachTimeoutManager(TimeoutManager* manager) {
  525. handshakeTimeout_.attachTimeoutManager(manager);
  526. }
  527. virtual void detachTimeoutManager() {
  528. handshakeTimeout_.detachTimeoutManager();
  529. }
  530. #if OPENSSL_VERSION_NUMBER >= 0x009080bfL
  531. /**
  532. * This function will set the SSL context for this socket to the
  533. * argument. This should only be used on client SSL Sockets that have
  534. * already called detachSSLContext();
  535. */
  536. void attachSSLContext(const std::shared_ptr<folly::SSLContext>& ctx);
  537. /**
  538. * Detaches the SSL context for this socket.
  539. */
  540. void detachSSLContext();
  541. #endif
  542. /**
  543. * Returns the original folly::SSLContext associated with this socket.
  544. *
  545. * Suitable for use in AsyncSSLSocket constructor to construct a new
  546. * AsyncSSLSocket using an existing socket's context.
  547. *
  548. * switchServerSSLContext() does not affect this return value.
  549. */
  550. const std::shared_ptr<folly::SSLContext>& getSSLContext() const {
  551. return ctx_;
  552. }
  553. #if FOLLY_OPENSSL_HAS_SNI
  554. /**
  555. * Switch the SSLContext to continue the SSL handshake.
  556. * It can only be used in server mode.
  557. */
  558. void switchServerSSLContext(
  559. const std::shared_ptr<folly::SSLContext>& handshakeCtx);
  560. /**
  561. * Did server recognize/support the tlsext_hostname in Client Hello?
  562. * It can only be used in client mode.
  563. *
  564. * @return true - tlsext_hostname is matched by the server
  565. * false - tlsext_hostname is not matched or
  566. * is not supported by server
  567. */
  568. bool isServerNameMatch() const;
  569. /**
  570. * Set the SNI hostname that we'll advertise to the server in the
  571. * ClientHello message.
  572. */
  573. void setServerName(std::string serverName) noexcept;
  574. #endif // FOLLY_OPENSSL_HAS_SNI
  575. void timeoutExpired(std::chrono::milliseconds timeout) noexcept;
  576. /**
  577. * Get the list of supported ciphers sent by the client in the client's
  578. * preference order.
  579. */
  580. void getSSLClientCiphers(
  581. std::string& clientCiphers,
  582. bool convertToString = true) const;
  583. /**
  584. * Get the list of compression methods sent by the client in TLS Hello.
  585. */
  586. std::string getSSLClientComprMethods() const;
  587. /**
  588. * Get the list of TLS extensions sent by the client in the TLS Hello.
  589. */
  590. std::string getSSLClientExts() const;
  591. std::string getSSLClientSigAlgs() const;
  592. /**
  593. * Get the list of versions in the supported versions extension (used to
  594. * negotiate TLS 1.3).
  595. */
  596. std::string getSSLClientSupportedVersions() const;
  597. std::string getSSLAlertsReceived() const;
  598. /*
  599. * Save an optional alert message generated during certificate verify
  600. */
  601. void setSSLCertVerificationAlert(std::string alert);
  602. std::string getSSLCertVerificationAlert() const;
  603. /**
  604. * Get the list of shared ciphers between the server and the client.
  605. * Works well for only SSLv2, not so good for SSLv3 or TLSv1.
  606. */
  607. void getSSLSharedCiphers(std::string& sharedCiphers) const;
  608. /**
  609. * Get the list of ciphers supported by the server in the server's
  610. * preference order.
  611. */
  612. void getSSLServerCiphers(std::string& serverCiphers) const;
  613. /**
  614. * Method to check if peer verfication is set.
  615. *
  616. * @return true if peer verification is required.
  617. */
  618. bool needsPeerVerification() const;
  619. static int getSSLExDataIndex();
  620. static AsyncSSLSocket* getFromSSL(const SSL* ssl);
  621. static int bioWrite(BIO* b, const char* in, int inl);
  622. static int bioRead(BIO* b, char* out, int outl);
  623. void resetClientHelloParsing(SSL* ssl);
  624. static void clientHelloParsingCallback(
  625. int write_p,
  626. int version,
  627. int content_type,
  628. const void* buf,
  629. size_t len,
  630. SSL* ssl,
  631. void* arg);
  632. static const char* getSSLServerNameFromSSL(SSL* ssl);
  633. // For unit-tests
  634. ssl::ClientHelloInfo* getClientHelloInfo() const {
  635. return clientHelloInfo_.get();
  636. }
  637. /**
  638. * Returns the time taken to complete a handshake.
  639. */
  640. virtual std::chrono::nanoseconds getHandshakeTime() const {
  641. return handshakeEndTime_ - handshakeStartTime_;
  642. }
  643. void setMinWriteSize(size_t minWriteSize) {
  644. minWriteSize_ = minWriteSize;
  645. }
  646. size_t getMinWriteSize() const {
  647. return minWriteSize_;
  648. }
  649. void setReadCB(ReadCallback* callback) override;
  650. /**
  651. * Tries to enable the buffer movable experimental feature in openssl.
  652. * This is not guaranteed to succeed in case openssl does not have
  653. * the experimental feature built in.
  654. */
  655. void setBufferMovableEnabled(bool enabled);
  656. const AsyncTransportCertificate* getPeerCertificate() const override;
  657. const AsyncTransportCertificate* getSelfCertificate() const override;
  658. /**
  659. * Returns the peer certificate, or nullptr if no peer certificate received.
  660. */
  661. ssl::X509UniquePtr getPeerCert() const override {
  662. auto peerCert = getPeerCertificate();
  663. if (!peerCert) {
  664. return nullptr;
  665. }
  666. return peerCert->getX509();
  667. }
  668. /**
  669. * Force AsyncSSLSocket object to cache local and peer socket addresses.
  670. * If called with "true" before connect() this function forces full local
  671. * and remote socket addresses to be cached in the socket object and available
  672. * through getLocalAddress()/getPeerAddress() methods even after the socket is
  673. * closed.
  674. */
  675. void forceCacheAddrOnFailure(bool force) {
  676. cacheAddrOnFailure_ = force;
  677. }
  678. const std::string& getSessionKey() const {
  679. return sessionKey_;
  680. }
  681. void setSessionKey(std::string sessionKey) {
  682. sessionKey_ = std::move(sessionKey);
  683. }
  684. void setCertCacheHit(bool hit) {
  685. certCacheHit_ = hit;
  686. }
  687. bool getCertCacheHit() const {
  688. return certCacheHit_;
  689. }
  690. bool sessionResumptionAttempted() const {
  691. return sessionResumptionAttempted_;
  692. }
  693. /**
  694. * If the SSL socket was used to connect as well
  695. * as establish an SSL connection, this gives the total
  696. * timeout for the connect + SSL connection that was
  697. * set.
  698. */
  699. std::chrono::milliseconds getTotalConnectTimeout() const {
  700. return totalConnectTimeout_;
  701. }
  702. // This can be called for OpenSSL 1.1.0 async operation finishes
  703. void setAsyncOperationFinishCallback(std::unique_ptr<ReadCallback> cb) {
  704. asyncOperationFinishCallback_ = std::move(cb);
  705. }
  706. private:
  707. /**
  708. * Handle the return from invoking SSL_accept
  709. */
  710. void handleReturnFromSSLAccept(int ret);
  711. void init();
  712. protected:
  713. /**
  714. * Protected destructor.
  715. *
  716. * Users of AsyncSSLSocket must never delete it directly. Instead, invoke
  717. * destroy() instead. (See the documentation in DelayedDestruction.h for
  718. * more details.)
  719. */
  720. ~AsyncSSLSocket() override;
  721. // Inherit event notification methods from AsyncSocket except
  722. // the following.
  723. void prepareReadBuffer(void** buf, size_t* buflen) override;
  724. void handleRead() noexcept override;
  725. void handleWrite() noexcept override;
  726. void handleAccept() noexcept;
  727. void handleConnect() noexcept override;
  728. void invalidState(HandshakeCB* callback);
  729. bool
  730. willBlock(int ret, int* sslErrorOut, unsigned long* errErrorOut) noexcept;
  731. void checkForImmediateRead() noexcept override;
  732. // AsyncSocket calls this at the wrong time for SSL
  733. void handleInitialReadWrite() noexcept override {}
  734. WriteResult interpretSSLError(int rc, int error);
  735. ReadResult performRead(void** buf, size_t* buflen, size_t* offset) override;
  736. WriteResult performWrite(
  737. const iovec* vec,
  738. uint32_t count,
  739. WriteFlags flags,
  740. uint32_t* countWritten,
  741. uint32_t* partialWritten) override;
  742. ssize_t performWriteIovec(
  743. const iovec* vec,
  744. uint32_t count,
  745. WriteFlags flags,
  746. uint32_t* countWritten,
  747. uint32_t* partialWritten);
  748. // This virtual wrapper around SSL_write exists solely for testing/mockability
  749. virtual int sslWriteImpl(SSL* ssl, const void* buf, int n) {
  750. return SSL_write(ssl, buf, n);
  751. }
  752. /**
  753. * Apply verification options passed to sslConn/sslAccept or those set
  754. * in the underlying SSLContext object.
  755. *
  756. * @param ssl pointer to the SSL object on which verification options will be
  757. * applied. If verifyPeer_ was explicitly set either via sslConn/sslAccept,
  758. * those options override the settings in the underlying SSLContext.
  759. */
  760. void applyVerificationOptions(const ssl::SSLUniquePtr& ssl);
  761. /**
  762. * Sets up SSL with a custom write bio which intercepts all writes.
  763. *
  764. * @return true, if succeeds and false if there is an error creating the bio.
  765. */
  766. bool setupSSLBio();
  767. /**
  768. * A SSL_write wrapper that understand EOR
  769. *
  770. * @param ssl: SSL pointer
  771. * @param buf: Buffer to be written
  772. * @param n: Number of bytes to be written
  773. * @param eor: Does the last byte (buf[n-1]) have the app-last-byte?
  774. * @return: The number of app bytes successfully written to the socket
  775. */
  776. int eorAwareSSLWrite(
  777. const ssl::SSLUniquePtr& ssl,
  778. const void* buf,
  779. int n,
  780. bool eor);
  781. // Inherit error handling methods from AsyncSocket, plus the following.
  782. void failHandshake(const char* fn, const AsyncSocketException& ex);
  783. void invokeHandshakeErr(const AsyncSocketException& ex);
  784. void invokeHandshakeCB();
  785. void invokeConnectErr(const AsyncSocketException& ex) override;
  786. void invokeConnectSuccess() override;
  787. void scheduleConnectTimeout() override;
  788. void startSSLConnect();
  789. static void sslInfoCallback(const SSL* ssl, int type, int val);
  790. // Whether the current write to the socket should use MSG_MORE.
  791. bool corkCurrentWrite_{false};
  792. // SSL related members.
  793. bool server_{false};
  794. // Used to prevent client-initiated renegotiation. Note that AsyncSSLSocket
  795. // doesn't fully support renegotiation, so we could just fail all attempts
  796. // to enforce this. Once it is supported, we should make it an option
  797. // to disable client-initiated renegotiation.
  798. bool handshakeComplete_{false};
  799. bool renegotiateAttempted_{false};
  800. SSLStateEnum sslState_{STATE_UNINIT};
  801. std::shared_ptr<folly::SSLContext> ctx_;
  802. // Callback for SSL_accept() or SSL_connect()
  803. HandshakeCB* handshakeCallback_{nullptr};
  804. ssl::SSLUniquePtr ssl_;
  805. SSL_SESSION* sslSession_{nullptr};
  806. Timeout handshakeTimeout_;
  807. Timeout connectionTimeout_;
  808. // The app byte num that we are tracking for the MSG_EOR
  809. // Only one app EOR byte can be tracked.
  810. size_t appEorByteNo_{0};
  811. // Try to avoid calling SSL_write() for buffers smaller than this.
  812. // It doesn't take effect when it is 0.
  813. size_t minWriteSize_{1500};
  814. // When openssl is about to sendmsg() across the minEorRawBytesNo_,
  815. // it will pass MSG_EOR to sendmsg().
  816. size_t minEorRawByteNo_{0};
  817. #if FOLLY_OPENSSL_HAS_SNI
  818. std::shared_ptr<folly::SSLContext> handshakeCtx_;
  819. std::string tlsextHostname_;
  820. #endif
  821. // a key that can be used for caching the established session
  822. std::string sessionKey_;
  823. folly::SSLContext::SSLVerifyPeerEnum verifyPeer_{
  824. folly::SSLContext::SSLVerifyPeerEnum::USE_CTX};
  825. // Callback for SSL_CTX_set_verify()
  826. static int sslVerifyCallback(int preverifyOk, X509_STORE_CTX* ctx);
  827. bool parseClientHello_{false};
  828. bool cacheAddrOnFailure_{false};
  829. bool bufferMovableEnabled_{false};
  830. bool certCacheHit_{false};
  831. std::unique_ptr<ssl::ClientHelloInfo> clientHelloInfo_;
  832. std::vector<std::pair<char, StringPiece>> alertsReceived_;
  833. // Time taken to complete the ssl handshake.
  834. std::chrono::steady_clock::time_point handshakeStartTime_;
  835. std::chrono::steady_clock::time_point handshakeEndTime_;
  836. std::chrono::milliseconds handshakeConnectTimeout_{0};
  837. std::chrono::milliseconds totalConnectTimeout_{0};
  838. std::string sslVerificationAlert_;
  839. bool sessionResumptionAttempted_{false};
  840. // whether the SSL session was resumed using session ID or not
  841. bool sessionIDResumed_{false};
  842. // This can be called for OpenSSL 1.1.0 async operation finishes
  843. std::unique_ptr<ReadCallback> asyncOperationFinishCallback_;
  844. };
  845. } // namespace folly