#include <folly/io/IOBuf.h>
#include <folly/io/Cursor.h>
-using folly::io::Cursor;
-using std::unique_ptr;
-
namespace folly {
class SSLException: public folly::AsyncSocketException {
class AsyncSSLSocket : public virtual AsyncSocket {
public:
typedef std::unique_ptr<AsyncSSLSocket, Destructor> UniquePtr;
+ using X509_deleter = folly::static_function_deleter<X509, &X509_free>;
class HandshakeCB {
public:
/**
* Initiate an SSL connection on the socket
- * THe callback will be invoked and uninstalled when an SSL connection
+ * The callback will be invoked and uninstalled when an SSL connection
* has been establshed on the underlying socket.
- * The verification option verifyPeer is applied if its passed explicitly.
- * If its not, the options in SSLContext set on the underying SSLContext
+ * The verification option verifyPeer is applied if it's passed explicitly.
+ * If it's not, the options in SSLContext set on the underlying SSLContext
* are applied.
*
* @param callback callback object to invoke on success/failure
handshakeTimeout_.detachEventBase();
}
+ virtual bool isDetachable() const override {
+ return AsyncSocket::isDetachable() && !handshakeTimeout_.isScheduled();
+ }
+
virtual void attachTimeoutManager(TimeoutManager* manager) {
handshakeTimeout_.attachTimeoutManager(manager);
}
return clientHelloInfo_.get();
}
+ /**
+ * Returns the time taken to complete a handshake.
+ */
+ std::chrono::nanoseconds getHandshakeTime() const {
+ return handshakeEndTime_ - handshakeStartTime_;
+ }
+
void setMinWriteSize(size_t minWriteSize) {
minWriteSize_ = minWriteSize;
}
void setReadCB(ReadCallback* callback) override;
+ /**
+ * Returns the peer certificate, or nullptr if no peer certificate received.
+ */
+ std::unique_ptr<X509, X509_deleter> getPeerCert() const {
+ if (!ssl_) {
+ return nullptr;
+ }
+
+ X509* cert = SSL_get_peer_certificate(ssl_);
+ return std::unique_ptr<X509, X509_deleter>(cert);
+ }
+
private:
void init();
// Inherit error handling methods from AsyncSocket, plus the following.
void failHandshake(const char* fn, const AsyncSocketException& ex);
+ void invokeHandshakeErr(const AsyncSocketException& ex);
void invokeHandshakeCB();
static void sslInfoCallback(const SSL *ssl, int type, int val);
static int sslVerifyCallback(int preverifyOk, X509_STORE_CTX* ctx);
bool parseClientHello_{false};
- unique_ptr<ClientHelloInfo> clientHelloInfo_;
+ std::unique_ptr<ClientHelloInfo> clientHelloInfo_;
+
+ // Time taken to complete the ssl handshake.
+ std::chrono::steady_clock::time_point handshakeStartTime_;
+ std::chrono::steady_clock::time_point handshakeEndTime_;
};
} // namespace