OpenSSL 1.1.0 compatibility
[folly.git] / folly / io / async / AsyncSSLSocket.cpp
1 /*
2  * Copyright 2017 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 #include <folly/io/async/AsyncSSLSocket.h>
18
19 #include <folly/io/async/EventBase.h>
20 #include <folly/portability/Sockets.h>
21
22 #include <boost/noncopyable.hpp>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <openssl/err.h>
26 #include <openssl/asn1.h>
27 #include <openssl/ssl.h>
28 #include <sys/types.h>
29 #include <chrono>
30
31 #include <folly/Bits.h>
32 #include <folly/SocketAddress.h>
33 #include <folly/SpinLock.h>
34 #include <folly/io/Cursor.h>
35 #include <folly/io/IOBuf.h>
36 #include <folly/portability/OpenSSL.h>
37
38 using folly::SocketAddress;
39 using folly::SSLContext;
40 using std::string;
41 using std::shared_ptr;
42
43 using folly::Endian;
44 using folly::IOBuf;
45 using folly::SpinLock;
46 using folly::SpinLockGuard;
47 using folly::io::Cursor;
48 using std::unique_ptr;
49 using std::bind;
50
51 namespace {
52 using folly::AsyncSocket;
53 using folly::AsyncSocketException;
54 using folly::AsyncSSLSocket;
55 using folly::Optional;
56 using folly::SSLContext;
57 // For OpenSSL portability API
58 using namespace folly::ssl;
59 using folly::ssl::OpenSSLUtils;
60
61
62 // We have one single dummy SSL context so that we can implement attach
63 // and detach methods in a thread safe fashion without modifying opnessl.
64 static SSLContext *dummyCtx = nullptr;
65 static SpinLock dummyCtxLock;
66
67 // If given min write size is less than this, buffer will be allocated on
68 // stack, otherwise it is allocated on heap
69 const size_t MAX_STACK_BUF_SIZE = 2048;
70
71 // This converts "illegal" shutdowns into ZERO_RETURN
72 inline bool zero_return(int error, int rc) {
73   return (error == SSL_ERROR_ZERO_RETURN || (rc == 0 && errno == 0));
74 }
75
76 class AsyncSSLSocketConnector: public AsyncSocket::ConnectCallback,
77                                 public AsyncSSLSocket::HandshakeCB {
78
79  private:
80   AsyncSSLSocket *sslSocket_;
81   AsyncSSLSocket::ConnectCallback *callback_;
82   int timeout_;
83   int64_t startTime_;
84
85  protected:
86   ~AsyncSSLSocketConnector() override {}
87
88  public:
89   AsyncSSLSocketConnector(AsyncSSLSocket *sslSocket,
90                            AsyncSocket::ConnectCallback *callback,
91                            int timeout) :
92       sslSocket_(sslSocket),
93       callback_(callback),
94       timeout_(timeout),
95       startTime_(std::chrono::duration_cast<std::chrono::milliseconds>(
96                    std::chrono::steady_clock::now().time_since_epoch()).count()) {
97   }
98
99   void connectSuccess() noexcept override {
100     VLOG(7) << "client socket connected";
101
102     int64_t timeoutLeft = 0;
103     if (timeout_ > 0) {
104       auto curTime = std::chrono::duration_cast<std::chrono::milliseconds>(
105         std::chrono::steady_clock::now().time_since_epoch()).count();
106
107       timeoutLeft = timeout_ - (curTime - startTime_);
108       if (timeoutLeft <= 0) {
109         AsyncSocketException ex(
110             AsyncSocketException::TIMED_OUT,
111             folly::sformat("SSL connect timed out after {}ms", timeout_));
112         fail(ex);
113         delete this;
114         return;
115       }
116     }
117     sslSocket_->sslConn(this, std::chrono::milliseconds(timeoutLeft));
118   }
119
120   void connectErr(const AsyncSocketException& ex) noexcept override {
121     VLOG(1) << "TCP connect failed: " << ex.what();
122     fail(ex);
123     delete this;
124   }
125
126   void handshakeSuc(AsyncSSLSocket* /* sock */) noexcept override {
127     VLOG(7) << "client handshake success";
128     if (callback_) {
129       callback_->connectSuccess();
130     }
131     delete this;
132   }
133
134   void handshakeErr(AsyncSSLSocket* /* socket */,
135                     const AsyncSocketException& ex) noexcept override {
136     VLOG(1) << "client handshakeErr: " << ex.what();
137     fail(ex);
138     delete this;
139   }
140
141   void fail(const AsyncSocketException &ex) {
142     // fail is a noop if called twice
143     if (callback_) {
144       AsyncSSLSocket::ConnectCallback *cb = callback_;
145       callback_ = nullptr;
146
147       cb->connectErr(ex);
148       sslSocket_->closeNow();
149       // closeNow can call handshakeErr if it hasn't been called already.
150       // So this may have been deleted, no member variable access beyond this
151       // point
152       // Note that closeNow may invoke writeError callbacks if the socket had
153       // write data pending connection completion.
154     }
155   }
156 };
157
158 void setup_SSL_CTX(SSL_CTX *ctx) {
159 #ifdef SSL_MODE_RELEASE_BUFFERS
160   SSL_CTX_set_mode(ctx,
161                    SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
162                    SSL_MODE_ENABLE_PARTIAL_WRITE
163                    | SSL_MODE_RELEASE_BUFFERS
164                    );
165 #else
166   SSL_CTX_set_mode(ctx,
167                    SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
168                    SSL_MODE_ENABLE_PARTIAL_WRITE
169                    );
170 #endif
171 // SSL_CTX_set_mode is a Macro
172 #ifdef SSL_MODE_WRITE_IOVEC
173   SSL_CTX_set_mode(ctx,
174                    SSL_CTX_get_mode(ctx)
175                    | SSL_MODE_WRITE_IOVEC);
176 #endif
177
178 }
179
180 // Note: This is a Leaky Meyer's Singleton. The reason we can't use a non-leaky
181 // thing is because we will be setting this BIO_METHOD* inside BIOs owned by
182 // various SSL objects which may get callbacks even during teardown. We may
183 // eventually try to fix this
184 static BIO_METHOD* getSSLBioMethod() {
185   static auto const instance = OpenSSLUtils::newSocketBioMethod().release();
186   return instance;
187 }
188
189 void* initsslBioMethod(void) {
190   auto sslBioMethod = getSSLBioMethod();
191   // override the bwrite method for MSG_EOR support
192   OpenSSLUtils::setCustomBioWriteMethod(sslBioMethod, AsyncSSLSocket::bioWrite);
193   OpenSSLUtils::setCustomBioReadMethod(sslBioMethod, AsyncSSLSocket::bioRead);
194
195   // Note that the sslBioMethod.type and sslBioMethod.name are not
196   // set here. openssl code seems to be checking ".type == BIO_TYPE_SOCKET" and
197   // then have specific handlings. The sslWriteBioWrite should be compatible
198   // with the one in openssl.
199
200   // Return something here to enable AsyncSSLSocket to call this method using
201   // a function-scoped static.
202   return nullptr;
203 }
204
205 } // anonymous namespace
206
207 namespace folly {
208
209 /**
210  * Create a client AsyncSSLSocket
211  */
212 AsyncSSLSocket::AsyncSSLSocket(const shared_ptr<SSLContext> &ctx,
213                                EventBase* evb, bool deferSecurityNegotiation) :
214     AsyncSocket(evb),
215     ctx_(ctx),
216     handshakeTimeout_(this, evb),
217     connectionTimeout_(this, evb) {
218   init();
219   if (deferSecurityNegotiation) {
220     sslState_ = STATE_UNENCRYPTED;
221   }
222 }
223
224 /**
225  * Create a server/client AsyncSSLSocket
226  */
227 AsyncSSLSocket::AsyncSSLSocket(
228     const shared_ptr<SSLContext>& ctx,
229     EventBase* evb,
230     int fd,
231     bool server,
232     bool deferSecurityNegotiation)
233     : AsyncSocket(evb, fd),
234       server_(server),
235       ctx_(ctx),
236       handshakeTimeout_(this, evb),
237       connectionTimeout_(this, evb) {
238   noTransparentTls_ = true;
239   init();
240   if (server) {
241     SSL_CTX_set_info_callback(
242         ctx_->getSSLCtx(), AsyncSSLSocket::sslInfoCallback);
243   }
244   if (deferSecurityNegotiation) {
245     sslState_ = STATE_UNENCRYPTED;
246   }
247 }
248
249 AsyncSSLSocket::AsyncSSLSocket(
250     const shared_ptr<SSLContext>& ctx,
251     AsyncSocket::UniquePtr oldAsyncSocket,
252     bool server,
253     bool deferSecurityNegotiation)
254     : AsyncSocket(std::move(oldAsyncSocket)),
255       server_(server),
256       ctx_(ctx),
257       handshakeTimeout_(this, AsyncSocket::getEventBase()),
258       connectionTimeout_(this, AsyncSocket::getEventBase()) {
259   noTransparentTls_ = true;
260   init();
261   if (server) {
262     SSL_CTX_set_info_callback(ctx_->getSSLCtx(),
263                               AsyncSSLSocket::sslInfoCallback);
264   }
265   if (deferSecurityNegotiation) {
266     sslState_ = STATE_UNENCRYPTED;
267   }
268 }
269
270 #if FOLLY_OPENSSL_HAS_SNI
271 /**
272  * Create a client AsyncSSLSocket and allow tlsext_hostname
273  * to be sent in Client Hello.
274  */
275 AsyncSSLSocket::AsyncSSLSocket(const shared_ptr<SSLContext> &ctx,
276                                  EventBase* evb,
277                                const std::string& serverName,
278                                bool deferSecurityNegotiation) :
279     AsyncSSLSocket(ctx, evb, deferSecurityNegotiation) {
280   tlsextHostname_ = serverName;
281 }
282
283 /**
284  * Create a client AsyncSSLSocket from an already connected fd
285  * and allow tlsext_hostname to be sent in Client Hello.
286  */
287 AsyncSSLSocket::AsyncSSLSocket(
288     const shared_ptr<SSLContext>& ctx,
289     EventBase* evb,
290     int fd,
291     const std::string& serverName,
292     bool deferSecurityNegotiation)
293     : AsyncSSLSocket(ctx, evb, fd, false, deferSecurityNegotiation) {
294   tlsextHostname_ = serverName;
295 }
296 #endif // FOLLY_OPENSSL_HAS_SNI
297
298 AsyncSSLSocket::~AsyncSSLSocket() {
299   VLOG(3) << "actual destruction of AsyncSSLSocket(this=" << this
300           << ", evb=" << eventBase_ << ", fd=" << fd_
301           << ", state=" << int(state_) << ", sslState="
302           << sslState_ << ", events=" << eventFlags_ << ")";
303 }
304
305 void AsyncSSLSocket::init() {
306   // Do this here to ensure we initialize this once before any use of
307   // AsyncSSLSocket instances and not as part of library load.
308   static const auto sslBioMethodInitializer = initsslBioMethod();
309   (void)sslBioMethodInitializer;
310
311   setup_SSL_CTX(ctx_->getSSLCtx());
312 }
313
314 void AsyncSSLSocket::closeNow() {
315   // Close the SSL connection.
316   if (ssl_ != nullptr && fd_ != -1) {
317     int rc = SSL_shutdown(ssl_);
318     if (rc == 0) {
319       rc = SSL_shutdown(ssl_);
320     }
321     if (rc < 0) {
322       ERR_clear_error();
323     }
324   }
325
326   if (sslSession_ != nullptr) {
327     SSL_SESSION_free(sslSession_);
328     sslSession_ = nullptr;
329   }
330
331   sslState_ = STATE_CLOSED;
332
333   if (handshakeTimeout_.isScheduled()) {
334     handshakeTimeout_.cancelTimeout();
335   }
336
337   DestructorGuard dg(this);
338
339   invokeHandshakeErr(
340       AsyncSocketException(
341         AsyncSocketException::END_OF_FILE,
342         "SSL connection closed locally"));
343
344   if (ssl_ != nullptr) {
345     SSL_free(ssl_);
346     ssl_ = nullptr;
347   }
348
349   // Close the socket.
350   AsyncSocket::closeNow();
351 }
352
353 void AsyncSSLSocket::shutdownWrite() {
354   // SSL sockets do not support half-shutdown, so just perform a full shutdown.
355   //
356   // (Performing a full shutdown here is more desirable than doing nothing at
357   // all.  The purpose of shutdownWrite() is normally to notify the other end
358   // of the connection that no more data will be sent.  If we do nothing, the
359   // other end will never know that no more data is coming, and this may result
360   // in protocol deadlock.)
361   close();
362 }
363
364 void AsyncSSLSocket::shutdownWriteNow() {
365   closeNow();
366 }
367
368 bool AsyncSSLSocket::good() const {
369   return (AsyncSocket::good() &&
370           (sslState_ == STATE_ACCEPTING || sslState_ == STATE_CONNECTING ||
371            sslState_ == STATE_ESTABLISHED || sslState_ == STATE_UNENCRYPTED));
372 }
373
374 // The TAsyncTransport definition of 'good' states that the transport is
375 // ready to perform reads and writes, so sslState_ == UNINIT must report !good.
376 // connecting can be true when the sslState_ == UNINIT because the AsyncSocket
377 // is connected but we haven't initiated the call to SSL_connect.
378 bool AsyncSSLSocket::connecting() const {
379   return (!server_ &&
380           (AsyncSocket::connecting() ||
381            (AsyncSocket::good() && (sslState_ == STATE_UNINIT ||
382                                      sslState_ == STATE_CONNECTING))));
383 }
384
385 std::string AsyncSSLSocket::getApplicationProtocol() noexcept {
386   const unsigned char* protoName = nullptr;
387   unsigned protoLength;
388   if (getSelectedNextProtocolNoThrow(&protoName, &protoLength)) {
389     return std::string(reinterpret_cast<const char*>(protoName), protoLength);
390   }
391   return "";
392 }
393
394 void AsyncSSLSocket::setEorTracking(bool track) {
395   if (isEorTrackingEnabled() != track) {
396     AsyncSocket::setEorTracking(track);
397     appEorByteNo_ = 0;
398     minEorRawByteNo_ = 0;
399   }
400 }
401
402 size_t AsyncSSLSocket::getRawBytesWritten() const {
403   // The bio(s) in the write path are in a chain
404   // each bio flushes to the next and finally written into the socket
405   // to get the rawBytesWritten on the socket,
406   // get the write bytes of the last bio
407   BIO *b;
408   if (!ssl_ || !(b = SSL_get_wbio(ssl_))) {
409     return 0;
410   }
411   BIO* next = BIO_next(b);
412   while (next != NULL) {
413     b = next;
414     next = BIO_next(b);
415   }
416
417   return BIO_number_written(b);
418 }
419
420 size_t AsyncSSLSocket::getRawBytesReceived() const {
421   BIO *b;
422   if (!ssl_ || !(b = SSL_get_rbio(ssl_))) {
423     return 0;
424   }
425
426   return BIO_number_read(b);
427 }
428
429
430 void AsyncSSLSocket::invalidState(HandshakeCB* callback) {
431   LOG(ERROR) << "AsyncSSLSocket(this=" << this << ", fd=" << fd_
432              << ", state=" << int(state_) << ", sslState=" << sslState_ << ", "
433              << "events=" << eventFlags_ << ", server=" << short(server_)
434              << "): " << "sslAccept/Connect() called in invalid "
435              << "state, handshake callback " << handshakeCallback_
436              << ", new callback " << callback;
437   assert(!handshakeTimeout_.isScheduled());
438   sslState_ = STATE_ERROR;
439
440   AsyncSocketException ex(AsyncSocketException::INVALID_STATE,
441                          "sslAccept() called with socket in invalid state");
442
443   handshakeEndTime_ = std::chrono::steady_clock::now();
444   if (callback) {
445     callback->handshakeErr(this, ex);
446   }
447
448   failHandshake(__func__, ex);
449 }
450
451 void AsyncSSLSocket::sslAccept(
452     HandshakeCB* callback,
453     std::chrono::milliseconds timeout,
454     const SSLContext::SSLVerifyPeerEnum& verifyPeer) {
455   DestructorGuard dg(this);
456   assert(eventBase_->isInEventBaseThread());
457   verifyPeer_ = verifyPeer;
458
459   // Make sure we're in the uninitialized state
460   if (!server_ || (sslState_ != STATE_UNINIT &&
461                    sslState_ != STATE_UNENCRYPTED) ||
462       handshakeCallback_ != nullptr) {
463     return invalidState(callback);
464   }
465
466   // Cache local and remote socket addresses to keep them available
467   // after socket file descriptor is closed.
468   if (cacheAddrOnFailure_ && -1 != getFd()) {
469     cacheLocalPeerAddr();
470   }
471
472   handshakeStartTime_ = std::chrono::steady_clock::now();
473   // Make end time at least >= start time.
474   handshakeEndTime_ = handshakeStartTime_;
475
476   sslState_ = STATE_ACCEPTING;
477   handshakeCallback_ = callback;
478
479   if (timeout > std::chrono::milliseconds::zero()) {
480     handshakeTimeout_.scheduleTimeout(timeout);
481   }
482
483   /* register for a read operation (waiting for CLIENT HELLO) */
484   updateEventRegistration(EventHandler::READ, EventHandler::WRITE);
485
486   checkForImmediateRead();
487 }
488
489 void AsyncSSLSocket::attachSSLContext(
490   const std::shared_ptr<SSLContext>& ctx) {
491
492   // Check to ensure we are in client mode. Changing a server's ssl
493   // context doesn't make sense since clients of that server would likely
494   // become confused when the server's context changes.
495   DCHECK(!server_);
496   DCHECK(!ctx_);
497   DCHECK(ctx);
498   DCHECK(ctx->getSSLCtx());
499   ctx_ = ctx;
500
501   // It's possible this could be attached before ssl_ is set up
502   if (!ssl_) {
503     return;
504   }
505
506   // In order to call attachSSLContext, detachSSLContext must have been
507   // previously called.
508   // We need to update the initial_ctx if necessary
509   auto sslCtx = ctx->getSSLCtx();
510   SSL_CTX_up_ref(sslCtx);
511
512   // The 'initial_ctx' inside an SSL* points to the context that it was created
513   // with, which is also where session callbacks and servername callbacks
514   // happen.
515   // When we switch to a different SSL_CTX, we want to update the initial_ctx as
516   // well so that any callbacks don't go to a different object
517   // NOTE: this will only work if we have access to ssl_ internals, so it may
518   // not work on
519   // OpenSSL version >= 1.1.0
520   OpenSSLUtils::setSSLInitialCtx(ssl_, sslCtx);
521   // Detach sets the socket's context to the dummy context. Thus we must acquire
522   // this lock.
523   SpinLockGuard guard(dummyCtxLock);
524   SSL_set_SSL_CTX(ssl_, sslCtx);
525 }
526
527 void AsyncSSLSocket::detachSSLContext() {
528   DCHECK(ctx_);
529   ctx_.reset();
530   // It's possible for this to be called before ssl_ has been
531   // set up
532   if (!ssl_) {
533     return;
534   }
535   // The 'initial_ctx' inside an SSL* points to the context that it was created
536   // with, which is also where session callbacks and servername callbacks
537   // happen.
538   // Detach the initial_ctx as well.  It will be reattached in attachSSLContext
539   // it is used for session info.
540   // NOTE: this will only work if we have access to ssl_ internals, so it may
541   // not work on
542   // OpenSSL version >= 1.1.0
543   SSL_CTX* initialCtx = OpenSSLUtils::getSSLInitialCtx(ssl_);
544   if (initialCtx) {
545     SSL_CTX_free(initialCtx);
546     OpenSSLUtils::setSSLInitialCtx(ssl_, nullptr);
547   }
548
549   SpinLockGuard guard(dummyCtxLock);
550   if (nullptr == dummyCtx) {
551     // We need to lazily initialize the dummy context so we don't
552     // accidentally override any programmatic settings to openssl
553     dummyCtx = new SSLContext;
554   }
555   // We must remove this socket's references to its context right now
556   // since this socket could get passed to any thread. If the context has
557   // had its locking disabled, just doing a set in attachSSLContext()
558   // would not be thread safe.
559   SSL_set_SSL_CTX(ssl_, dummyCtx->getSSLCtx());
560 }
561
562 #if FOLLY_OPENSSL_HAS_SNI
563 void AsyncSSLSocket::switchServerSSLContext(
564   const std::shared_ptr<SSLContext>& handshakeCtx) {
565   CHECK(server_);
566   if (sslState_ != STATE_ACCEPTING) {
567     // We log it here and allow the switch.
568     // It should not affect our re-negotiation support (which
569     // is not supported now).
570     VLOG(6) << "fd=" << getFd()
571             << " renegotation detected when switching SSL_CTX";
572   }
573
574   setup_SSL_CTX(handshakeCtx->getSSLCtx());
575   SSL_CTX_set_info_callback(handshakeCtx->getSSLCtx(),
576                             AsyncSSLSocket::sslInfoCallback);
577   handshakeCtx_ = handshakeCtx;
578   SSL_set_SSL_CTX(ssl_, handshakeCtx->getSSLCtx());
579 }
580
581 bool AsyncSSLSocket::isServerNameMatch() const {
582   CHECK(!server_);
583
584   if (!ssl_) {
585     return false;
586   }
587
588   SSL_SESSION *ss = SSL_get_session(ssl_);
589   if (!ss) {
590     return false;
591   }
592
593   auto tlsextHostname = SSL_SESSION_get0_hostname(ss);
594   return (tlsextHostname && !tlsextHostname_.compare(tlsextHostname));
595 }
596
597 void AsyncSSLSocket::setServerName(std::string serverName) noexcept {
598   tlsextHostname_ = std::move(serverName);
599 }
600
601 #endif // FOLLY_OPENSSL_HAS_SNI
602
603 void AsyncSSLSocket::timeoutExpired(
604     std::chrono::milliseconds timeout) noexcept {
605   if (state_ == StateEnum::ESTABLISHED &&
606       (sslState_ == STATE_CACHE_LOOKUP || sslState_ == STATE_ASYNC_PENDING)) {
607     sslState_ = STATE_ERROR;
608     // We are expecting a callback in restartSSLAccept.  The cache lookup
609     // and rsa-call necessarily have pointers to this ssl socket, so delay
610     // the cleanup until he calls us back.
611   } else if (state_ == StateEnum::CONNECTING) {
612     assert(sslState_ == STATE_CONNECTING);
613     DestructorGuard dg(this);
614     AsyncSocketException ex(AsyncSocketException::TIMED_OUT,
615                            "Fallback connect timed out during TFO");
616     failHandshake(__func__, ex);
617   } else {
618     assert(state_ == StateEnum::ESTABLISHED &&
619            (sslState_ == STATE_CONNECTING || sslState_ == STATE_ACCEPTING));
620     DestructorGuard dg(this);
621     AsyncSocketException ex(
622         AsyncSocketException::TIMED_OUT,
623         folly::sformat(
624             "SSL {} timed out after {}ms",
625             (sslState_ == STATE_CONNECTING) ? "connect" : "accept",
626             timeout.count()));
627     failHandshake(__func__, ex);
628   }
629 }
630
631 int AsyncSSLSocket::getSSLExDataIndex() {
632   static auto index = SSL_get_ex_new_index(
633       0, (void*)"AsyncSSLSocket data index", nullptr, nullptr, nullptr);
634   return index;
635 }
636
637 AsyncSSLSocket* AsyncSSLSocket::getFromSSL(const SSL *ssl) {
638   return static_cast<AsyncSSLSocket *>(SSL_get_ex_data(ssl,
639       getSSLExDataIndex()));
640 }
641
642 void AsyncSSLSocket::failHandshake(const char* /* fn */,
643                                    const AsyncSocketException& ex) {
644   startFail();
645   if (handshakeTimeout_.isScheduled()) {
646     handshakeTimeout_.cancelTimeout();
647   }
648   invokeHandshakeErr(ex);
649   finishFail();
650 }
651
652 void AsyncSSLSocket::invokeHandshakeErr(const AsyncSocketException& ex) {
653   handshakeEndTime_ = std::chrono::steady_clock::now();
654   if (handshakeCallback_ != nullptr) {
655     HandshakeCB* callback = handshakeCallback_;
656     handshakeCallback_ = nullptr;
657     callback->handshakeErr(this, ex);
658   }
659 }
660
661 void AsyncSSLSocket::invokeHandshakeCB() {
662   handshakeEndTime_ = std::chrono::steady_clock::now();
663   if (handshakeTimeout_.isScheduled()) {
664     handshakeTimeout_.cancelTimeout();
665   }
666   if (handshakeCallback_) {
667     HandshakeCB* callback = handshakeCallback_;
668     handshakeCallback_ = nullptr;
669     callback->handshakeSuc(this);
670   }
671 }
672
673 void AsyncSSLSocket::cacheLocalPeerAddr() {
674   SocketAddress address;
675   try {
676     getLocalAddress(&address);
677     getPeerAddress(&address);
678   } catch (const std::system_error& e) {
679     // The handle can be still valid while the connection is already closed.
680     if (e.code() != std::error_code(ENOTCONN, std::system_category())) {
681       throw;
682     }
683   }
684 }
685
686 void AsyncSSLSocket::connect(
687     ConnectCallback* callback,
688     const folly::SocketAddress& address,
689     int timeout,
690     const OptionMap& options,
691     const folly::SocketAddress& bindAddr) noexcept {
692   auto timeoutChrono = std::chrono::milliseconds(timeout);
693   connect(callback, address, timeoutChrono, timeoutChrono, options, bindAddr);
694 }
695
696 void AsyncSSLSocket::connect(
697     ConnectCallback* callback,
698     const folly::SocketAddress& address,
699     std::chrono::milliseconds connectTimeout,
700     std::chrono::milliseconds totalConnectTimeout,
701     const OptionMap& options,
702     const folly::SocketAddress& bindAddr) noexcept {
703   assert(!server_);
704   assert(state_ == StateEnum::UNINIT);
705   assert(sslState_ == STATE_UNINIT);
706   noTransparentTls_ = true;
707   totalConnectTimeout_ = totalConnectTimeout;
708   AsyncSSLSocketConnector* connector =
709       new AsyncSSLSocketConnector(this, callback, totalConnectTimeout.count());
710   AsyncSocket::connect(
711       connector, address, connectTimeout.count(), options, bindAddr);
712 }
713
714 bool AsyncSSLSocket::needsPeerVerification() const {
715   if (verifyPeer_ == SSLContext::SSLVerifyPeerEnum::USE_CTX) {
716     return ctx_->needsPeerVerification();
717   }
718   return (
719       verifyPeer_ == SSLContext::SSLVerifyPeerEnum::VERIFY ||
720       verifyPeer_ == SSLContext::SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT);
721 }
722
723 void AsyncSSLSocket::applyVerificationOptions(SSL * ssl) {
724   // apply the settings specified in verifyPeer_
725   if (verifyPeer_ == SSLContext::SSLVerifyPeerEnum::USE_CTX) {
726     if(ctx_->needsPeerVerification()) {
727       SSL_set_verify(ssl, ctx_->getVerificationMode(),
728         AsyncSSLSocket::sslVerifyCallback);
729     }
730   } else {
731     if (verifyPeer_ == SSLContext::SSLVerifyPeerEnum::VERIFY ||
732         verifyPeer_ == SSLContext::SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT) {
733       SSL_set_verify(ssl, SSLContext::getVerificationMode(verifyPeer_),
734         AsyncSSLSocket::sslVerifyCallback);
735     }
736   }
737 }
738
739 bool AsyncSSLSocket::setupSSLBio() {
740   auto sslBio = BIO_new(getSSLBioMethod());
741
742   if (!sslBio) {
743     return false;
744   }
745
746   OpenSSLUtils::setBioAppData(sslBio, this);
747   OpenSSLUtils::setBioFd(sslBio, fd_, BIO_NOCLOSE);
748   SSL_set_bio(ssl_, sslBio, sslBio);
749   return true;
750 }
751
752 void AsyncSSLSocket::sslConn(
753     HandshakeCB* callback,
754     std::chrono::milliseconds timeout,
755     const SSLContext::SSLVerifyPeerEnum& verifyPeer) {
756   DestructorGuard dg(this);
757   assert(eventBase_->isInEventBaseThread());
758
759   // Cache local and remote socket addresses to keep them available
760   // after socket file descriptor is closed.
761   if (cacheAddrOnFailure_ && -1 != getFd()) {
762     cacheLocalPeerAddr();
763   }
764
765   verifyPeer_ = verifyPeer;
766
767   // Make sure we're in the uninitialized state
768   if (server_ || (sslState_ != STATE_UNINIT && sslState_ !=
769                   STATE_UNENCRYPTED) ||
770       handshakeCallback_ != nullptr) {
771     return invalidState(callback);
772   }
773
774   sslState_ = STATE_CONNECTING;
775   handshakeCallback_ = callback;
776
777   try {
778     ssl_ = ctx_->createSSL();
779   } catch (std::exception &e) {
780     sslState_ = STATE_ERROR;
781     AsyncSocketException ex(AsyncSocketException::INTERNAL_ERROR,
782                            "error calling SSLContext::createSSL()");
783     LOG(ERROR) << "AsyncSSLSocket::sslConn(this=" << this << ", fd="
784             << fd_ << "): " << e.what();
785     return failHandshake(__func__, ex);
786   }
787
788   if (!setupSSLBio()) {
789     sslState_ = STATE_ERROR;
790     AsyncSocketException ex(
791         AsyncSocketException::INTERNAL_ERROR, "error creating SSL bio");
792     return failHandshake(__func__, ex);
793   }
794
795   applyVerificationOptions(ssl_);
796
797   if (sslSession_ != nullptr) {
798     sessionResumptionAttempted_ = true;
799     SSL_set_session(ssl_, sslSession_);
800     SSL_SESSION_free(sslSession_);
801     sslSession_ = nullptr;
802   }
803 #if FOLLY_OPENSSL_HAS_SNI
804   if (tlsextHostname_.size()) {
805     SSL_set_tlsext_host_name(ssl_, tlsextHostname_.c_str());
806   }
807 #endif
808
809   SSL_set_ex_data(ssl_, getSSLExDataIndex(), this);
810
811   handshakeConnectTimeout_ = timeout;
812   startSSLConnect();
813 }
814
815 // This could be called multiple times, during normal ssl connections
816 // and after TFO fallback.
817 void AsyncSSLSocket::startSSLConnect() {
818   handshakeStartTime_ = std::chrono::steady_clock::now();
819   // Make end time at least >= start time.
820   handshakeEndTime_ = handshakeStartTime_;
821   if (handshakeConnectTimeout_ > std::chrono::milliseconds::zero()) {
822     handshakeTimeout_.scheduleTimeout(handshakeConnectTimeout_);
823   }
824   handleConnect();
825 }
826
827 SSL_SESSION *AsyncSSLSocket::getSSLSession() {
828   if (ssl_ != nullptr && sslState_ == STATE_ESTABLISHED) {
829     return SSL_get1_session(ssl_);
830   }
831
832   return sslSession_;
833 }
834
835 const SSL* AsyncSSLSocket::getSSL() const {
836   return ssl_;
837 }
838
839 void AsyncSSLSocket::setSSLSession(SSL_SESSION *session, bool takeOwnership) {
840   sslSession_ = session;
841   if (!takeOwnership && session != nullptr) {
842     // Increment the reference count
843     // This API exists in BoringSSL and OpenSSL 1.1.0
844     SSL_SESSION_up_ref(session);
845   }
846 }
847
848 void AsyncSSLSocket::getSelectedNextProtocol(
849     const unsigned char** protoName,
850     unsigned* protoLen,
851     SSLContext::NextProtocolType* protoType) const {
852   if (!getSelectedNextProtocolNoThrow(protoName, protoLen, protoType)) {
853     throw AsyncSocketException(AsyncSocketException::NOT_SUPPORTED,
854                               "NPN not supported");
855   }
856 }
857
858 bool AsyncSSLSocket::getSelectedNextProtocolNoThrow(
859     const unsigned char** protoName,
860     unsigned* protoLen,
861     SSLContext::NextProtocolType* protoType) const {
862   *protoName = nullptr;
863   *protoLen = 0;
864 #if FOLLY_OPENSSL_HAS_ALPN
865   SSL_get0_alpn_selected(ssl_, protoName, protoLen);
866   if (*protoLen > 0) {
867     if (protoType) {
868       *protoType = SSLContext::NextProtocolType::ALPN;
869     }
870     return true;
871   }
872 #endif
873 #ifdef OPENSSL_NPN_NEGOTIATED
874   SSL_get0_next_proto_negotiated(ssl_, protoName, protoLen);
875   if (protoType) {
876     *protoType = SSLContext::NextProtocolType::NPN;
877   }
878   return true;
879 #else
880   (void)protoType;
881   return false;
882 #endif
883 }
884
885 bool AsyncSSLSocket::getSSLSessionReused() const {
886   if (ssl_ != nullptr && sslState_ == STATE_ESTABLISHED) {
887     return SSL_session_reused(ssl_);
888   }
889   return false;
890 }
891
892 const char *AsyncSSLSocket::getNegotiatedCipherName() const {
893   return (ssl_ != nullptr) ? SSL_get_cipher_name(ssl_) : nullptr;
894 }
895
896 /* static */
897 const char* AsyncSSLSocket::getSSLServerNameFromSSL(SSL* ssl) {
898   if (ssl == nullptr) {
899     return nullptr;
900   }
901 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
902   return SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
903 #else
904   return nullptr;
905 #endif
906 }
907
908 const char *AsyncSSLSocket::getSSLServerName() const {
909 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
910   return getSSLServerNameFromSSL(ssl_);
911 #else
912   throw AsyncSocketException(AsyncSocketException::NOT_SUPPORTED,
913                              "SNI not supported");
914 #endif
915 }
916
917 const char *AsyncSSLSocket::getSSLServerNameNoThrow() const {
918   return getSSLServerNameFromSSL(ssl_);
919 }
920
921 int AsyncSSLSocket::getSSLVersion() const {
922   return (ssl_ != nullptr) ? SSL_version(ssl_) : 0;
923 }
924
925 const char *AsyncSSLSocket::getSSLCertSigAlgName() const {
926   X509 *cert = (ssl_ != nullptr) ? SSL_get_certificate(ssl_) : nullptr;
927   if (cert) {
928     int nid = X509_get_signature_nid(cert);
929     return OBJ_nid2ln(nid);
930   }
931   return nullptr;
932 }
933
934 int AsyncSSLSocket::getSSLCertSize() const {
935   int certSize = 0;
936   X509 *cert = (ssl_ != nullptr) ? SSL_get_certificate(ssl_) : nullptr;
937   if (cert) {
938     EVP_PKEY *key = X509_get_pubkey(cert);
939     certSize = EVP_PKEY_bits(key);
940     EVP_PKEY_free(key);
941   }
942   return certSize;
943 }
944
945 const X509* AsyncSSLSocket::getSelfCert() const {
946   return (ssl_ != nullptr) ? SSL_get_certificate(ssl_) : nullptr;
947 }
948
949 bool AsyncSSLSocket::willBlock(int ret,
950                                int* sslErrorOut,
951                                unsigned long* errErrorOut) noexcept {
952   *errErrorOut = 0;
953   int error = *sslErrorOut = SSL_get_error(ssl_, ret);
954   if (error == SSL_ERROR_WANT_READ) {
955     // Register for read event if not already.
956     updateEventRegistration(EventHandler::READ, EventHandler::WRITE);
957     return true;
958   } else if (error == SSL_ERROR_WANT_WRITE) {
959     VLOG(3) << "AsyncSSLSocket(fd=" << fd_
960             << ", state=" << int(state_) << ", sslState="
961             << sslState_ << ", events=" << eventFlags_ << "): "
962             << "SSL_ERROR_WANT_WRITE";
963     // Register for write event if not already.
964     updateEventRegistration(EventHandler::WRITE, EventHandler::READ);
965     return true;
966 #ifdef SSL_ERROR_WANT_SESS_CACHE_LOOKUP
967   } else if (error == SSL_ERROR_WANT_SESS_CACHE_LOOKUP) {
968     // We will block but we can't register our own socket.  The callback that
969     // triggered this code will re-call handleAccept at the appropriate time.
970
971     // We can only get here if the linked libssl.so has support for this feature
972     // as well, otherwise SSL_get_error cannot return our error code.
973     sslState_ = STATE_CACHE_LOOKUP;
974
975     // Unregister for all events while blocked here
976     updateEventRegistration(EventHandler::NONE,
977                             EventHandler::READ | EventHandler::WRITE);
978
979     // The timeout (if set) keeps running here
980     return true;
981 #endif
982   } else if (0
983 #ifdef SSL_ERROR_WANT_RSA_ASYNC_PENDING
984       || error == SSL_ERROR_WANT_RSA_ASYNC_PENDING
985 #endif
986 #ifdef SSL_ERROR_WANT_ECDSA_ASYNC_PENDING
987       || error == SSL_ERROR_WANT_ECDSA_ASYNC_PENDING
988 #endif
989       ) {
990     // Our custom openssl function has kicked off an async request to do
991     // rsa/ecdsa private key operation.  When that call returns, a callback will
992     // be invoked that will re-call handleAccept.
993     sslState_ = STATE_ASYNC_PENDING;
994
995     // Unregister for all events while blocked here
996     updateEventRegistration(
997       EventHandler::NONE,
998       EventHandler::READ | EventHandler::WRITE
999     );
1000
1001     // The timeout (if set) keeps running here
1002     return true;
1003   } else {
1004     unsigned long lastError = *errErrorOut = ERR_get_error();
1005     VLOG(6) << "AsyncSSLSocket(fd=" << fd_ << ", "
1006             << "state=" << state_ << ", "
1007             << "sslState=" << sslState_ << ", "
1008             << "events=" << std::hex << eventFlags_ << "): "
1009             << "SSL error: " << error << ", "
1010             << "errno: " << errno << ", "
1011             << "ret: " << ret << ", "
1012             << "read: " << BIO_number_read(SSL_get_rbio(ssl_)) << ", "
1013             << "written: " << BIO_number_written(SSL_get_wbio(ssl_)) << ", "
1014             << "func: " << ERR_func_error_string(lastError) << ", "
1015             << "reason: " << ERR_reason_error_string(lastError);
1016     return false;
1017   }
1018 }
1019
1020 void AsyncSSLSocket::checkForImmediateRead() noexcept {
1021   // openssl may have buffered data that it read from the socket already.
1022   // In this case we have to process it immediately, rather than waiting for
1023   // the socket to become readable again.
1024   if (ssl_ != nullptr && SSL_pending(ssl_) > 0) {
1025     AsyncSocket::handleRead();
1026   } else {
1027     AsyncSocket::checkForImmediateRead();
1028   }
1029 }
1030
1031 void
1032 AsyncSSLSocket::restartSSLAccept()
1033 {
1034   VLOG(3) << "AsyncSSLSocket::restartSSLAccept() this=" << this
1035           << ", fd=" << fd_ << ", state=" << int(state_) << ", "
1036           << "sslState=" << sslState_ << ", events=" << eventFlags_;
1037   DestructorGuard dg(this);
1038   assert(
1039     sslState_ == STATE_CACHE_LOOKUP ||
1040     sslState_ == STATE_ASYNC_PENDING ||
1041     sslState_ == STATE_ERROR ||
1042     sslState_ == STATE_CLOSED);
1043   if (sslState_ == STATE_CLOSED) {
1044     // I sure hope whoever closed this socket didn't delete it already,
1045     // but this is not strictly speaking an error
1046     return;
1047   }
1048   if (sslState_ == STATE_ERROR) {
1049     // go straight to fail if timeout expired during lookup
1050     AsyncSocketException ex(
1051         AsyncSocketException::TIMED_OUT, "SSL accept timed out");
1052     failHandshake(__func__, ex);
1053     return;
1054   }
1055   sslState_ = STATE_ACCEPTING;
1056   this->handleAccept();
1057 }
1058
1059 void
1060 AsyncSSLSocket::handleAccept() noexcept {
1061   VLOG(3) << "AsyncSSLSocket::handleAccept() this=" << this
1062           << ", fd=" << fd_ << ", state=" << int(state_) << ", "
1063           << "sslState=" << sslState_ << ", events=" << eventFlags_;
1064   assert(server_);
1065   assert(state_ == StateEnum::ESTABLISHED &&
1066          sslState_ == STATE_ACCEPTING);
1067   if (!ssl_) {
1068     /* lazily create the SSL structure */
1069     try {
1070       ssl_ = ctx_->createSSL();
1071     } catch (std::exception &e) {
1072       sslState_ = STATE_ERROR;
1073       AsyncSocketException ex(AsyncSocketException::INTERNAL_ERROR,
1074                              "error calling SSLContext::createSSL()");
1075       LOG(ERROR) << "AsyncSSLSocket::handleAccept(this=" << this
1076                  << ", fd=" << fd_ << "): " << e.what();
1077       return failHandshake(__func__, ex);
1078     }
1079
1080     if (!setupSSLBio()) {
1081       sslState_ = STATE_ERROR;
1082       AsyncSocketException ex(
1083           AsyncSocketException::INTERNAL_ERROR, "error creating write bio");
1084       return failHandshake(__func__, ex);
1085     }
1086
1087     SSL_set_ex_data(ssl_, getSSLExDataIndex(), this);
1088
1089     applyVerificationOptions(ssl_);
1090   }
1091
1092   if (server_ && parseClientHello_) {
1093     SSL_set_msg_callback(ssl_, &AsyncSSLSocket::clientHelloParsingCallback);
1094     SSL_set_msg_callback_arg(ssl_, this);
1095   }
1096
1097   int ret = SSL_accept(ssl_);
1098   if (ret <= 0) {
1099     int sslError;
1100     unsigned long errError;
1101     int errnoCopy = errno;
1102     if (willBlock(ret, &sslError, &errError)) {
1103       return;
1104     } else {
1105       sslState_ = STATE_ERROR;
1106       SSLException ex(sslError, errError, ret, errnoCopy);
1107       return failHandshake(__func__, ex);
1108     }
1109   }
1110
1111   handshakeComplete_ = true;
1112   updateEventRegistration(0, EventHandler::READ | EventHandler::WRITE);
1113
1114   // Move into STATE_ESTABLISHED in the normal case that we are in
1115   // STATE_ACCEPTING.
1116   sslState_ = STATE_ESTABLISHED;
1117
1118   VLOG(3) << "AsyncSSLSocket " << this << ": fd " << fd_
1119           << " successfully accepted; state=" << int(state_)
1120           << ", sslState=" << sslState_ << ", events=" << eventFlags_;
1121
1122   // Remember the EventBase we are attached to, before we start invoking any
1123   // callbacks (since the callbacks may call detachEventBase()).
1124   EventBase* originalEventBase = eventBase_;
1125
1126   // Call the accept callback.
1127   invokeHandshakeCB();
1128
1129   // Note that the accept callback may have changed our state.
1130   // (set or unset the read callback, called write(), closed the socket, etc.)
1131   // The following code needs to handle these situations correctly.
1132   //
1133   // If the socket has been closed, readCallback_ and writeReqHead_ will
1134   // always be nullptr, so that will prevent us from trying to read or write.
1135   //
1136   // The main thing to check for is if eventBase_ is still originalEventBase.
1137   // If not, we have been detached from this event base, so we shouldn't
1138   // perform any more operations.
1139   if (eventBase_ != originalEventBase) {
1140     return;
1141   }
1142
1143   AsyncSocket::handleInitialReadWrite();
1144 }
1145
1146 void
1147 AsyncSSLSocket::handleConnect() noexcept {
1148   VLOG(3) <<  "AsyncSSLSocket::handleConnect() this=" << this
1149           << ", fd=" << fd_ << ", state=" << int(state_) << ", "
1150           << "sslState=" << sslState_ << ", events=" << eventFlags_;
1151   assert(!server_);
1152   if (state_ < StateEnum::ESTABLISHED) {
1153     return AsyncSocket::handleConnect();
1154   }
1155
1156   assert(
1157       (state_ == StateEnum::FAST_OPEN || state_ == StateEnum::ESTABLISHED) &&
1158       sslState_ == STATE_CONNECTING);
1159   assert(ssl_);
1160
1161   auto originalState = state_;
1162   int ret = SSL_connect(ssl_);
1163   if (ret <= 0) {
1164     int sslError;
1165     unsigned long errError;
1166     int errnoCopy = errno;
1167     if (willBlock(ret, &sslError, &errError)) {
1168       // We fell back to connecting state due to TFO
1169       if (state_ == StateEnum::CONNECTING) {
1170         DCHECK_EQ(StateEnum::FAST_OPEN, originalState);
1171         if (handshakeTimeout_.isScheduled()) {
1172           handshakeTimeout_.cancelTimeout();
1173         }
1174       }
1175       return;
1176     } else {
1177       sslState_ = STATE_ERROR;
1178       SSLException ex(sslError, errError, ret, errnoCopy);
1179       return failHandshake(__func__, ex);
1180     }
1181   }
1182
1183   handshakeComplete_ = true;
1184   updateEventRegistration(0, EventHandler::READ | EventHandler::WRITE);
1185
1186   // Move into STATE_ESTABLISHED in the normal case that we are in
1187   // STATE_CONNECTING.
1188   sslState_ = STATE_ESTABLISHED;
1189
1190   VLOG(3) << "AsyncSSLSocket " << this << ": "
1191           << "fd " << fd_ << " successfully connected; "
1192           << "state=" << int(state_) << ", sslState=" << sslState_
1193           << ", events=" << eventFlags_;
1194
1195   // Remember the EventBase we are attached to, before we start invoking any
1196   // callbacks (since the callbacks may call detachEventBase()).
1197   EventBase* originalEventBase = eventBase_;
1198
1199   // Call the handshake callback.
1200   invokeHandshakeCB();
1201
1202   // Note that the connect callback may have changed our state.
1203   // (set or unset the read callback, called write(), closed the socket, etc.)
1204   // The following code needs to handle these situations correctly.
1205   //
1206   // If the socket has been closed, readCallback_ and writeReqHead_ will
1207   // always be nullptr, so that will prevent us from trying to read or write.
1208   //
1209   // The main thing to check for is if eventBase_ is still originalEventBase.
1210   // If not, we have been detached from this event base, so we shouldn't
1211   // perform any more operations.
1212   if (eventBase_ != originalEventBase) {
1213     return;
1214   }
1215
1216   AsyncSocket::handleInitialReadWrite();
1217 }
1218
1219 void AsyncSSLSocket::invokeConnectErr(const AsyncSocketException& ex) {
1220   connectionTimeout_.cancelTimeout();
1221   AsyncSocket::invokeConnectErr(ex);
1222   if (sslState_ == SSLStateEnum::STATE_CONNECTING) {
1223     if (handshakeTimeout_.isScheduled()) {
1224       handshakeTimeout_.cancelTimeout();
1225     }
1226     // If we fell back to connecting state during TFO and the connection
1227     // failed, it would be an SSL failure as well.
1228     invokeHandshakeErr(ex);
1229   }
1230 }
1231
1232 void AsyncSSLSocket::invokeConnectSuccess() {
1233   connectionTimeout_.cancelTimeout();
1234   if (sslState_ == SSLStateEnum::STATE_CONNECTING) {
1235     assert(tfoAttempted_);
1236     // If we failed TFO, we'd fall back to trying to connect the socket,
1237     // to setup things like timeouts.
1238     startSSLConnect();
1239   }
1240   // still invoke the base class since it re-sets the connect time.
1241   AsyncSocket::invokeConnectSuccess();
1242 }
1243
1244 void AsyncSSLSocket::scheduleConnectTimeout() {
1245   if (sslState_ == SSLStateEnum::STATE_CONNECTING) {
1246     // We fell back from TFO, and need to set the timeouts.
1247     // We will not have a connect callback in this case, thus if the timer
1248     // expires we would have no-one to notify.
1249     // Thus we should reset even the connect timers to point to the handshake
1250     // timeouts.
1251     assert(connectCallback_ == nullptr);
1252     // We use a different connect timeout here than the handshake timeout, so
1253     // that we can disambiguate the 2 timers.
1254     if (connectTimeout_.count() > 0) {
1255       if (!connectionTimeout_.scheduleTimeout(connectTimeout_)) {
1256         throw AsyncSocketException(
1257             AsyncSocketException::INTERNAL_ERROR,
1258             withAddr("failed to schedule AsyncSSLSocket connect timeout"));
1259       }
1260     }
1261     return;
1262   }
1263   AsyncSocket::scheduleConnectTimeout();
1264 }
1265
1266 void AsyncSSLSocket::setReadCB(ReadCallback *callback) {
1267 #ifdef SSL_MODE_MOVE_BUFFER_OWNERSHIP
1268   // turn on the buffer movable in openssl
1269   if (bufferMovableEnabled_ && ssl_ != nullptr && !isBufferMovable_ &&
1270       callback != nullptr && callback->isBufferMovable()) {
1271     SSL_set_mode(ssl_, SSL_get_mode(ssl_) | SSL_MODE_MOVE_BUFFER_OWNERSHIP);
1272     isBufferMovable_ = true;
1273   }
1274 #endif
1275
1276   AsyncSocket::setReadCB(callback);
1277 }
1278
1279 void AsyncSSLSocket::setBufferMovableEnabled(bool enabled) {
1280   bufferMovableEnabled_ = enabled;
1281 }
1282
1283 void AsyncSSLSocket::prepareReadBuffer(void** buf, size_t* buflen) {
1284   CHECK(readCallback_);
1285   if (isBufferMovable_) {
1286     *buf = nullptr;
1287     *buflen = 0;
1288   } else {
1289     // buf is necessary for SSLSocket without SSL_MODE_MOVE_BUFFER_OWNERSHIP
1290     readCallback_->getReadBuffer(buf, buflen);
1291   }
1292 }
1293
1294 void
1295 AsyncSSLSocket::handleRead() noexcept {
1296   VLOG(5) << "AsyncSSLSocket::handleRead() this=" << this << ", fd=" << fd_
1297           << ", state=" << int(state_) << ", "
1298           << "sslState=" << sslState_ << ", events=" << eventFlags_;
1299   if (state_ < StateEnum::ESTABLISHED) {
1300     return AsyncSocket::handleRead();
1301   }
1302
1303
1304   if (sslState_ == STATE_ACCEPTING) {
1305     assert(server_);
1306     handleAccept();
1307     return;
1308   }
1309   else if (sslState_ == STATE_CONNECTING) {
1310     assert(!server_);
1311     handleConnect();
1312     return;
1313   }
1314
1315   // Normal read
1316   AsyncSocket::handleRead();
1317 }
1318
1319 AsyncSocket::ReadResult
1320 AsyncSSLSocket::performRead(void** buf, size_t* buflen, size_t* offset) {
1321   VLOG(4) << "AsyncSSLSocket::performRead() this=" << this << ", buf=" << *buf
1322           << ", buflen=" << *buflen;
1323
1324   if (sslState_ == STATE_UNENCRYPTED) {
1325     return AsyncSocket::performRead(buf, buflen, offset);
1326   }
1327
1328   int bytes = 0;
1329   if (!isBufferMovable_) {
1330     bytes = SSL_read(ssl_, *buf, int(*buflen));
1331   }
1332 #ifdef SSL_MODE_MOVE_BUFFER_OWNERSHIP
1333   else {
1334     bytes = SSL_read_buf(ssl_, buf, (int *) offset, (int *) buflen);
1335   }
1336 #endif
1337
1338   if (server_ && renegotiateAttempted_) {
1339     LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
1340                << ", sslstate=" << sslState_ << ", events=" << eventFlags_
1341                << "): client intitiated SSL renegotiation not permitted";
1342     return ReadResult(
1343         READ_ERROR,
1344         folly::make_unique<SSLException>(SSLError::CLIENT_RENEGOTIATION));
1345   }
1346   if (bytes <= 0) {
1347     int error = SSL_get_error(ssl_, bytes);
1348     if (error == SSL_ERROR_WANT_READ) {
1349       // The caller will register for read event if not already.
1350       if (errno == EWOULDBLOCK || errno == EAGAIN) {
1351         return ReadResult(READ_BLOCKING);
1352       } else {
1353         return ReadResult(READ_ERROR);
1354       }
1355     } else if (error == SSL_ERROR_WANT_WRITE) {
1356       // TODO: Even though we are attempting to read data, SSL_read() may
1357       // need to write data if renegotiation is being performed.  We currently
1358       // don't support this and just fail the read.
1359       LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
1360                  << ", sslState=" << sslState_ << ", events=" << eventFlags_
1361                  << "): unsupported SSL renegotiation during read";
1362       return ReadResult(
1363           READ_ERROR,
1364           folly::make_unique<SSLException>(SSLError::INVALID_RENEGOTIATION));
1365     } else {
1366       if (zero_return(error, bytes)) {
1367         return ReadResult(bytes);
1368       }
1369       auto errError = ERR_get_error();
1370       VLOG(6) << "AsyncSSLSocket(fd=" << fd_ << ", "
1371               << "state=" << state_ << ", "
1372               << "sslState=" << sslState_ << ", "
1373               << "events=" << std::hex << eventFlags_ << "): "
1374               << "bytes: " << bytes << ", "
1375               << "error: " << error << ", "
1376               << "errno: " << errno << ", "
1377               << "func: " << ERR_func_error_string(errError) << ", "
1378               << "reason: " << ERR_reason_error_string(errError);
1379       return ReadResult(
1380           READ_ERROR,
1381           folly::make_unique<SSLException>(error, errError, bytes, errno));
1382     }
1383   } else {
1384     appBytesReceived_ += bytes;
1385     return ReadResult(bytes);
1386   }
1387 }
1388
1389 void AsyncSSLSocket::handleWrite() noexcept {
1390   VLOG(5) << "AsyncSSLSocket::handleWrite() this=" << this << ", fd=" << fd_
1391           << ", state=" << int(state_) << ", "
1392           << "sslState=" << sslState_ << ", events=" << eventFlags_;
1393   if (state_ < StateEnum::ESTABLISHED) {
1394     return AsyncSocket::handleWrite();
1395   }
1396
1397   if (sslState_ == STATE_ACCEPTING) {
1398     assert(server_);
1399     handleAccept();
1400     return;
1401   }
1402
1403   if (sslState_ == STATE_CONNECTING) {
1404     assert(!server_);
1405     handleConnect();
1406     return;
1407   }
1408
1409   // Normal write
1410   AsyncSocket::handleWrite();
1411 }
1412
1413 AsyncSocket::WriteResult AsyncSSLSocket::interpretSSLError(int rc, int error) {
1414   if (error == SSL_ERROR_WANT_READ) {
1415     // Even though we are attempting to write data, SSL_write() may
1416     // need to read data if renegotiation is being performed.  We currently
1417     // don't support this and just fail the write.
1418     LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
1419                << ", sslState=" << sslState_ << ", events=" << eventFlags_
1420                << "): "
1421                << "unsupported SSL renegotiation during write";
1422     return WriteResult(
1423         WRITE_ERROR,
1424         folly::make_unique<SSLException>(SSLError::INVALID_RENEGOTIATION));
1425   } else {
1426     if (zero_return(error, rc)) {
1427       return WriteResult(0);
1428     }
1429     auto errError = ERR_get_error();
1430     VLOG(3) << "ERROR: AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
1431             << ", sslState=" << sslState_ << ", events=" << eventFlags_ << "): "
1432             << "SSL error: " << error << ", errno: " << errno
1433             << ", func: " << ERR_func_error_string(errError)
1434             << ", reason: " << ERR_reason_error_string(errError);
1435     return WriteResult(
1436         WRITE_ERROR,
1437         folly::make_unique<SSLException>(error, errError, rc, errno));
1438   }
1439 }
1440
1441 AsyncSocket::WriteResult AsyncSSLSocket::performWrite(
1442     const iovec* vec,
1443     uint32_t count,
1444     WriteFlags flags,
1445     uint32_t* countWritten,
1446     uint32_t* partialWritten) {
1447   if (sslState_ == STATE_UNENCRYPTED) {
1448     return AsyncSocket::performWrite(
1449       vec, count, flags, countWritten, partialWritten);
1450   }
1451   if (sslState_ != STATE_ESTABLISHED) {
1452     LOG(ERROR) << "AsyncSSLSocket(fd=" << fd_ << ", state=" << int(state_)
1453                << ", sslState=" << sslState_
1454                << ", events=" << eventFlags_ << "): "
1455                << "TODO: AsyncSSLSocket currently does not support calling "
1456                << "write() before the handshake has fully completed";
1457     return WriteResult(
1458         WRITE_ERROR, folly::make_unique<SSLException>(SSLError::EARLY_WRITE));
1459   }
1460
1461   // Declare a buffer used to hold small write requests.  It could point to a
1462   // memory block either on stack or on heap. If it is on heap, we release it
1463   // manually when scope exits
1464   char* combinedBuf{nullptr};
1465   SCOPE_EXIT {
1466     // Note, always keep this check consistent with what we do below
1467     if (combinedBuf != nullptr && minWriteSize_ > MAX_STACK_BUF_SIZE) {
1468       delete[] combinedBuf;
1469     }
1470   };
1471
1472   *countWritten = 0;
1473   *partialWritten = 0;
1474   ssize_t totalWritten = 0;
1475   size_t bytesStolenFromNextBuffer = 0;
1476   for (uint32_t i = 0; i < count; i++) {
1477     const iovec* v = vec + i;
1478     size_t offset = bytesStolenFromNextBuffer;
1479     bytesStolenFromNextBuffer = 0;
1480     size_t len = v->iov_len - offset;
1481     const void* buf;
1482     if (len == 0) {
1483       (*countWritten)++;
1484       continue;
1485     }
1486     buf = ((const char*)v->iov_base) + offset;
1487
1488     ssize_t bytes;
1489     uint32_t buffersStolen = 0;
1490     auto sslWriteBuf = buf;
1491     if ((len < minWriteSize_) && ((i + 1) < count)) {
1492       // Combine this buffer with part or all of the next buffers in
1493       // order to avoid really small-grained calls to SSL_write().
1494       // Each call to SSL_write() produces a separate record in
1495       // the egress SSL stream, and we've found that some low-end
1496       // mobile clients can't handle receiving an HTTP response
1497       // header and the first part of the response body in two
1498       // separate SSL records (even if those two records are in
1499       // the same TCP packet).
1500
1501       if (combinedBuf == nullptr) {
1502         if (minWriteSize_ > MAX_STACK_BUF_SIZE) {
1503           // Allocate the buffer on heap
1504           combinedBuf = new char[minWriteSize_];
1505         } else {
1506           // Allocate the buffer on stack
1507           combinedBuf = (char*)alloca(minWriteSize_);
1508         }
1509       }
1510       assert(combinedBuf != nullptr);
1511       sslWriteBuf = combinedBuf;
1512
1513       memcpy(combinedBuf, buf, len);
1514       do {
1515         // INVARIANT: i + buffersStolen == complete chunks serialized
1516         uint32_t nextIndex = i + buffersStolen + 1;
1517         bytesStolenFromNextBuffer = std::min(vec[nextIndex].iov_len,
1518                                              minWriteSize_ - len);
1519         if (bytesStolenFromNextBuffer > 0) {
1520           assert(vec[nextIndex].iov_base != nullptr);
1521           ::memcpy(
1522               combinedBuf + len,
1523               vec[nextIndex].iov_base,
1524               bytesStolenFromNextBuffer);
1525         }
1526         len += bytesStolenFromNextBuffer;
1527         if (bytesStolenFromNextBuffer < vec[nextIndex].iov_len) {
1528           // couldn't steal the whole buffer
1529           break;
1530         } else {
1531           bytesStolenFromNextBuffer = 0;
1532           buffersStolen++;
1533         }
1534       } while ((i + buffersStolen + 1) < count && (len < minWriteSize_));
1535     }
1536
1537     // Advance any empty buffers immediately after.
1538     if (bytesStolenFromNextBuffer == 0) {
1539       while ((i + buffersStolen + 1) < count &&
1540              vec[i + buffersStolen + 1].iov_len == 0) {
1541         buffersStolen++;
1542       }
1543     }
1544
1545     corkCurrentWrite_ =
1546         isSet(flags, WriteFlags::CORK) || (i + buffersStolen + 1 < count);
1547     bytes = eorAwareSSLWrite(
1548         ssl_,
1549         sslWriteBuf,
1550         int(len),
1551         (isSet(flags, WriteFlags::EOR) && i + buffersStolen + 1 == count));
1552
1553     if (bytes <= 0) {
1554       int error = SSL_get_error(ssl_, int(bytes));
1555       if (error == SSL_ERROR_WANT_WRITE) {
1556         // The caller will register for write event if not already.
1557         *partialWritten = uint32_t(offset);
1558         return WriteResult(totalWritten);
1559       }
1560       auto writeResult = interpretSSLError(int(bytes), error);
1561       if (writeResult.writeReturn < 0) {
1562         return writeResult;
1563       } // else fall through to below to correctly record totalWritten
1564     }
1565
1566     totalWritten += bytes;
1567
1568     if (bytes == (ssize_t)len) {
1569       // The full iovec is written.
1570       (*countWritten) += 1 + buffersStolen;
1571       i += buffersStolen;
1572       // continue
1573     } else {
1574       bytes += offset; // adjust bytes to account for all of v
1575       while (bytes >= (ssize_t)v->iov_len) {
1576         // We combined this buf with part or all of the next one, and
1577         // we managed to write all of this buf but not all of the bytes
1578         // from the next one that we'd hoped to write.
1579         bytes -= v->iov_len;
1580         (*countWritten)++;
1581         v = &(vec[++i]);
1582       }
1583       *partialWritten = uint32_t(bytes);
1584       return WriteResult(totalWritten);
1585     }
1586   }
1587
1588   return WriteResult(totalWritten);
1589 }
1590
1591 int AsyncSSLSocket::eorAwareSSLWrite(SSL *ssl, const void *buf, int n,
1592                                       bool eor) {
1593   if (eor && isEorTrackingEnabled()) {
1594     if (appEorByteNo_) {
1595       // cannot track for more than one app byte EOR
1596       CHECK(appEorByteNo_ == appBytesWritten_ + n);
1597     } else {
1598       appEorByteNo_ = appBytesWritten_ + n;
1599     }
1600
1601     // 1. It is fine to keep updating minEorRawByteNo_.
1602     // 2. It is _min_ in the sense that SSL record will add some overhead.
1603     minEorRawByteNo_ = getRawBytesWritten() + n;
1604   }
1605
1606   n = sslWriteImpl(ssl, buf, n);
1607   if (n > 0) {
1608     appBytesWritten_ += n;
1609     if (appEorByteNo_) {
1610       if (getRawBytesWritten() >= minEorRawByteNo_) {
1611         minEorRawByteNo_ = 0;
1612       }
1613       if(appBytesWritten_ == appEorByteNo_) {
1614         appEorByteNo_ = 0;
1615       } else {
1616         CHECK(appBytesWritten_ < appEorByteNo_);
1617       }
1618     }
1619   }
1620   return n;
1621 }
1622
1623 void AsyncSSLSocket::sslInfoCallback(const SSL* ssl, int where, int ret) {
1624   AsyncSSLSocket *sslSocket = AsyncSSLSocket::getFromSSL(ssl);
1625   if (sslSocket->handshakeComplete_ && (where & SSL_CB_HANDSHAKE_START)) {
1626     sslSocket->renegotiateAttempted_ = true;
1627   }
1628   if (where & SSL_CB_READ_ALERT) {
1629     const char* type = SSL_alert_type_string(ret);
1630     if (type) {
1631       const char* desc = SSL_alert_desc_string(ret);
1632       sslSocket->alertsReceived_.emplace_back(
1633           *type, StringPiece(desc, std::strlen(desc)));
1634     }
1635   }
1636 }
1637
1638 int AsyncSSLSocket::bioWrite(BIO* b, const char* in, int inl) {
1639   struct msghdr msg;
1640   struct iovec iov;
1641   AsyncSSLSocket* tsslSock;
1642
1643   iov.iov_base = const_cast<char*>(in);
1644   iov.iov_len = size_t(inl);
1645   memset(&msg, 0, sizeof(msg));
1646   msg.msg_iov = &iov;
1647   msg.msg_iovlen = 1;
1648
1649   auto appData = OpenSSLUtils::getBioAppData(b);
1650   CHECK(appData);
1651
1652   tsslSock = reinterpret_cast<AsyncSSLSocket*>(appData);
1653   CHECK(tsslSock);
1654
1655   WriteFlags flags = WriteFlags::NONE;
1656   if (tsslSock->isEorTrackingEnabled() && tsslSock->minEorRawByteNo_ &&
1657       tsslSock->minEorRawByteNo_ <= BIO_number_written(b) + inl) {
1658     flags |= WriteFlags::EOR;
1659   }
1660
1661   if (tsslSock->corkCurrentWrite_) {
1662     flags |= WriteFlags::CORK;
1663   }
1664
1665   int msg_flags = tsslSock->getSendMsgParamsCB()->getFlags(flags);
1666   msg.msg_controllen =
1667       tsslSock->getSendMsgParamsCB()->getAncillaryDataSize(flags);
1668   CHECK_GE(AsyncSocket::SendMsgParamsCallback::maxAncillaryDataSize,
1669            msg.msg_controllen);
1670   if (msg.msg_controllen != 0) {
1671     msg.msg_control = reinterpret_cast<char*>(alloca(msg.msg_controllen));
1672     tsslSock->getSendMsgParamsCB()->getAncillaryData(flags, msg.msg_control);
1673   }
1674
1675   auto result = tsslSock->sendSocketMessage(
1676       OpenSSLUtils::getBioFd(b, nullptr), &msg, msg_flags);
1677   BIO_clear_retry_flags(b);
1678   if (!result.exception && result.writeReturn <= 0) {
1679     if (OpenSSLUtils::getBioShouldRetryWrite(int(result.writeReturn))) {
1680       BIO_set_retry_write(b);
1681     }
1682   }
1683   return int(result.writeReturn);
1684 }
1685
1686 int AsyncSSLSocket::bioRead(BIO* b, char* out, int outl) {
1687   if (!out) {
1688     return 0;
1689   }
1690   BIO_clear_retry_flags(b);
1691
1692   auto appData = OpenSSLUtils::getBioAppData(b);
1693   CHECK(appData);
1694   auto sslSock = reinterpret_cast<AsyncSSLSocket*>(appData);
1695
1696   if (sslSock->preReceivedData_ && !sslSock->preReceivedData_->empty()) {
1697     VLOG(5) << "AsyncSSLSocket::bioRead() this=" << sslSock
1698             << ", reading pre-received data";
1699
1700     Cursor cursor(sslSock->preReceivedData_.get());
1701     auto len = cursor.pullAtMost(out, outl);
1702
1703     IOBufQueue queue;
1704     queue.append(std::move(sslSock->preReceivedData_));
1705     queue.trimStart(len);
1706     sslSock->preReceivedData_ = queue.move();
1707     return len;
1708   } else {
1709     auto result = recv(OpenSSLUtils::getBioFd(b, nullptr), out, outl, 0);
1710     if (result <= 0 && OpenSSLUtils::getBioShouldRetryWrite(result)) {
1711       BIO_set_retry_read(b);
1712     }
1713     return result;
1714   }
1715 }
1716
1717 int AsyncSSLSocket::sslVerifyCallback(
1718     int preverifyOk,
1719     X509_STORE_CTX* x509Ctx) {
1720   SSL* ssl = (SSL*) X509_STORE_CTX_get_ex_data(
1721     x509Ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1722   AsyncSSLSocket* self = AsyncSSLSocket::getFromSSL(ssl);
1723
1724   VLOG(3) <<  "AsyncSSLSocket::sslVerifyCallback() this=" << self << ", "
1725           << "fd=" << self->fd_ << ", preverifyOk=" << preverifyOk;
1726   return (self->handshakeCallback_) ?
1727     self->handshakeCallback_->handshakeVer(self, preverifyOk, x509Ctx) :
1728     preverifyOk;
1729 }
1730
1731 void AsyncSSLSocket::enableClientHelloParsing()  {
1732     parseClientHello_ = true;
1733     clientHelloInfo_.reset(new ssl::ClientHelloInfo());
1734 }
1735
1736 void AsyncSSLSocket::resetClientHelloParsing(SSL *ssl)  {
1737   SSL_set_msg_callback(ssl, nullptr);
1738   SSL_set_msg_callback_arg(ssl, nullptr);
1739   clientHelloInfo_->clientHelloBuf_.clear();
1740 }
1741
1742 void AsyncSSLSocket::clientHelloParsingCallback(int written,
1743                                                 int /* version */,
1744                                                 int contentType,
1745                                                 const void* buf,
1746                                                 size_t len,
1747                                                 SSL* ssl,
1748                                                 void* arg) {
1749   AsyncSSLSocket *sock = static_cast<AsyncSSLSocket*>(arg);
1750   if (written != 0) {
1751     sock->resetClientHelloParsing(ssl);
1752     return;
1753   }
1754   if (contentType != SSL3_RT_HANDSHAKE) {
1755     return;
1756   }
1757   if (len == 0) {
1758     return;
1759   }
1760
1761   auto& clientHelloBuf = sock->clientHelloInfo_->clientHelloBuf_;
1762   clientHelloBuf.append(IOBuf::wrapBuffer(buf, len));
1763   try {
1764     Cursor cursor(clientHelloBuf.front());
1765     if (cursor.read<uint8_t>() != SSL3_MT_CLIENT_HELLO) {
1766       sock->resetClientHelloParsing(ssl);
1767       return;
1768     }
1769
1770     if (cursor.totalLength() < 3) {
1771       clientHelloBuf.trimEnd(len);
1772       clientHelloBuf.append(IOBuf::copyBuffer(buf, len));
1773       return;
1774     }
1775
1776     uint32_t messageLength = cursor.read<uint8_t>();
1777     messageLength <<= 8;
1778     messageLength |= cursor.read<uint8_t>();
1779     messageLength <<= 8;
1780     messageLength |= cursor.read<uint8_t>();
1781     if (cursor.totalLength() < messageLength) {
1782       clientHelloBuf.trimEnd(len);
1783       clientHelloBuf.append(IOBuf::copyBuffer(buf, len));
1784       return;
1785     }
1786
1787     sock->clientHelloInfo_->clientHelloMajorVersion_ = cursor.read<uint8_t>();
1788     sock->clientHelloInfo_->clientHelloMinorVersion_ = cursor.read<uint8_t>();
1789
1790     cursor.skip(4); // gmt_unix_time
1791     cursor.skip(28); // random_bytes
1792
1793     cursor.skip(cursor.read<uint8_t>()); // session_id
1794
1795     uint16_t cipherSuitesLength = cursor.readBE<uint16_t>();
1796     for (int i = 0; i < cipherSuitesLength; i += 2) {
1797       sock->clientHelloInfo_->
1798         clientHelloCipherSuites_.push_back(cursor.readBE<uint16_t>());
1799     }
1800
1801     uint8_t compressionMethodsLength = cursor.read<uint8_t>();
1802     for (int i = 0; i < compressionMethodsLength; ++i) {
1803       sock->clientHelloInfo_->
1804         clientHelloCompressionMethods_.push_back(cursor.readBE<uint8_t>());
1805     }
1806
1807     if (cursor.totalLength() > 0) {
1808       uint16_t extensionsLength = cursor.readBE<uint16_t>();
1809       while (extensionsLength) {
1810         ssl::TLSExtension extensionType =
1811             static_cast<ssl::TLSExtension>(cursor.readBE<uint16_t>());
1812         sock->clientHelloInfo_->
1813           clientHelloExtensions_.push_back(extensionType);
1814         extensionsLength -= 2;
1815         uint16_t extensionDataLength = cursor.readBE<uint16_t>();
1816         extensionsLength -= 2;
1817         extensionsLength -= extensionDataLength;
1818
1819         if (extensionType == ssl::TLSExtension::SIGNATURE_ALGORITHMS) {
1820           cursor.skip(2);
1821           extensionDataLength -= 2;
1822           while (extensionDataLength) {
1823             ssl::HashAlgorithm hashAlg =
1824                 static_cast<ssl::HashAlgorithm>(cursor.readBE<uint8_t>());
1825             ssl::SignatureAlgorithm sigAlg =
1826                 static_cast<ssl::SignatureAlgorithm>(cursor.readBE<uint8_t>());
1827             extensionDataLength -= 2;
1828             sock->clientHelloInfo_->
1829               clientHelloSigAlgs_.emplace_back(hashAlg, sigAlg);
1830           }
1831         } else if (extensionType == ssl::TLSExtension::SUPPORTED_VERSIONS) {
1832           cursor.skip(1);
1833           extensionDataLength -= 1;
1834           while (extensionDataLength) {
1835             sock->clientHelloInfo_->clientHelloSupportedVersions_.push_back(
1836                 cursor.readBE<uint16_t>());
1837             extensionDataLength -= 2;
1838           }
1839         } else {
1840           cursor.skip(extensionDataLength);
1841         }
1842       }
1843     }
1844   } catch (std::out_of_range&) {
1845     // we'll use what we found and cleanup below.
1846     VLOG(4) << "AsyncSSLSocket::clientHelloParsingCallback(): "
1847       << "buffer finished unexpectedly." << " AsyncSSLSocket socket=" << sock;
1848   }
1849
1850   sock->resetClientHelloParsing(ssl);
1851 }
1852
1853 void AsyncSSLSocket::getSSLClientCiphers(
1854     std::string& clientCiphers,
1855     bool convertToString) const {
1856   std::string ciphers;
1857
1858   if (parseClientHello_ == false
1859       || clientHelloInfo_->clientHelloCipherSuites_.empty()) {
1860     clientCiphers = "";
1861     return;
1862   }
1863
1864   bool first = true;
1865   for (auto originalCipherCode : clientHelloInfo_->clientHelloCipherSuites_)
1866   {
1867     if (first) {
1868       first = false;
1869     } else {
1870       ciphers +=  ":";
1871     }
1872
1873     bool nameFound = convertToString;
1874
1875     if (convertToString) {
1876       const auto& name = OpenSSLUtils::getCipherName(originalCipherCode);
1877       if (name.empty()) {
1878         nameFound = false;
1879       } else {
1880         ciphers += name;
1881       }
1882     }
1883
1884     if (!nameFound) {
1885       folly::hexlify(
1886           std::array<uint8_t, 2>{{
1887               static_cast<uint8_t>((originalCipherCode >> 8) & 0xffL),
1888               static_cast<uint8_t>(originalCipherCode & 0x00ffL) }},
1889           ciphers,
1890           /* append to ciphers = */ true);
1891     }
1892   }
1893
1894   clientCiphers = std::move(ciphers);
1895 }
1896
1897 std::string AsyncSSLSocket::getSSLClientComprMethods() const {
1898   if (!parseClientHello_) {
1899     return "";
1900   }
1901   return folly::join(":", clientHelloInfo_->clientHelloCompressionMethods_);
1902 }
1903
1904 std::string AsyncSSLSocket::getSSLClientExts() const {
1905   if (!parseClientHello_) {
1906     return "";
1907   }
1908   return folly::join(":", clientHelloInfo_->clientHelloExtensions_);
1909 }
1910
1911 std::string AsyncSSLSocket::getSSLClientSigAlgs() const {
1912   if (!parseClientHello_) {
1913     return "";
1914   }
1915
1916   std::string sigAlgs;
1917   sigAlgs.reserve(clientHelloInfo_->clientHelloSigAlgs_.size() * 4);
1918   for (size_t i = 0; i < clientHelloInfo_->clientHelloSigAlgs_.size(); i++) {
1919     if (i) {
1920       sigAlgs.push_back(':');
1921     }
1922     sigAlgs.append(folly::to<std::string>(
1923         clientHelloInfo_->clientHelloSigAlgs_[i].first));
1924     sigAlgs.push_back(',');
1925     sigAlgs.append(folly::to<std::string>(
1926         clientHelloInfo_->clientHelloSigAlgs_[i].second));
1927   }
1928
1929   return sigAlgs;
1930 }
1931
1932 std::string AsyncSSLSocket::getSSLClientSupportedVersions() const {
1933   if (!parseClientHello_) {
1934     return "";
1935   }
1936   return folly::join(":", clientHelloInfo_->clientHelloSupportedVersions_);
1937 }
1938
1939 std::string AsyncSSLSocket::getSSLAlertsReceived() const {
1940   std::string ret;
1941
1942   for (const auto& alert : alertsReceived_) {
1943     if (!ret.empty()) {
1944       ret.append(",");
1945     }
1946     ret.append(folly::to<std::string>(alert.first, ": ", alert.second));
1947   }
1948
1949   return ret;
1950 }
1951
1952 void AsyncSSLSocket::setSSLCertVerificationAlert(std::string alert) {
1953   sslVerificationAlert_ = std::move(alert);
1954 }
1955
1956 std::string AsyncSSLSocket::getSSLCertVerificationAlert() const {
1957   return sslVerificationAlert_;
1958 }
1959
1960 void AsyncSSLSocket::getSSLSharedCiphers(std::string& sharedCiphers) const {
1961   char ciphersBuffer[1024];
1962   ciphersBuffer[0] = '\0';
1963   SSL_get_shared_ciphers(ssl_, ciphersBuffer, sizeof(ciphersBuffer) - 1);
1964   sharedCiphers = ciphersBuffer;
1965 }
1966
1967 void AsyncSSLSocket::getSSLServerCiphers(std::string& serverCiphers) const {
1968   serverCiphers = SSL_get_cipher_list(ssl_, 0);
1969   int i = 1;
1970   const char *cipher;
1971   while ((cipher = SSL_get_cipher_list(ssl_, i)) != nullptr) {
1972     serverCiphers.append(":");
1973     serverCiphers.append(cipher);
1974     i++;
1975   }
1976 }
1977
1978 } // namespace