diff --git a/lib/cpp/src/transport/TSSLServerSocket.cpp b/lib/cpp/src/transport/TSSLServerSocket.cpp
new file mode 100644
index 0000000..ed4b648
--- /dev/null
+++ b/lib/cpp/src/transport/TSSLServerSocket.cpp
@@ -0,0 +1,36 @@
+// Copyright (c) 2009- Facebook
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/
+
+#include "TSSLServerSocket.h"
+#include "TSSLSocket.h"
+
+namespace apache { namespace thrift { namespace transport {
+
+using namespace boost;
+
+/**
+ * SSL server socket implementation.
+ *
+ * @author Ping Li <pingli@facebook.com>
+ */
+TSSLServerSocket::TSSLServerSocket(int port,
+                                   shared_ptr<TSSLSocketFactory> factory):
+                                   TServerSocket(port), factory_(factory) {
+  factory_->server(true);
+}
+
+TSSLServerSocket::TSSLServerSocket(int port, int sendTimeout, int recvTimeout,
+                                   shared_ptr<TSSLSocketFactory> factory):
+                                   TServerSocket(port, sendTimeout, recvTimeout),
+                                   factory_(factory) {
+  factory_->server(true);
+}
+
+shared_ptr<TSocket> TSSLServerSocket::createSocket(int client) {
+  return factory_->createSocket(client);
+}
+
+}}}
diff --git a/lib/cpp/src/transport/TSSLServerSocket.h b/lib/cpp/src/transport/TSSLServerSocket.h
new file mode 100644
index 0000000..36f895c
--- /dev/null
+++ b/lib/cpp/src/transport/TSSLServerSocket.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2009- Facebook
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/
+
+#ifndef _THRIFT_TRANSPORT_TSSLSERVERSOCKET_H_
+#define _THRIFT_TRANSPORT_TSSLSERVERSOCKET_H_ 1
+
+#include <boost/shared_ptr.hpp>
+#include "TServerSocket.h"
+
+namespace apache { namespace thrift { namespace transport {
+
+class TSSLSocketFactory;
+
+/**
+ * Server socket that accepts SSL connections.
+ *
+ * @author Ping Li <pingli@facebook.com>
+ */
+class TSSLServerSocket: public TServerSocket {
+ public:
+  /**
+   * Constructor.
+   *
+   * @param port    Listening port
+   * @param factory SSL socket factory implementation
+   */
+  TSSLServerSocket(int port, boost::shared_ptr<TSSLSocketFactory> factory);
+  /**
+   * Constructor.
+   *
+   * @param port        Listening port
+   * @param sendTimeout Socket send timeout
+   * @param recvTimeout Socket receive timeout
+   * @param factory     SSL socket factory implementation
+   */
+  TSSLServerSocket(int port, int sendTimeout, int recvTimeout,
+                   boost::shared_ptr<TSSLSocketFactory> factory);
+ protected:
+  boost::shared_ptr<TSocket> createSocket(int socket);
+  boost::shared_ptr<TSSLSocketFactory> factory_;
+};
+
+}}}
+
+#endif
diff --git a/lib/cpp/src/transport/TSSLSocket.cpp b/lib/cpp/src/transport/TSSLSocket.cpp
new file mode 100644
index 0000000..f84f806
--- /dev/null
+++ b/lib/cpp/src/transport/TSSLSocket.cpp
@@ -0,0 +1,645 @@
+// Copyright (c) 2009- Facebook
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/
+
+#include <errno.h>
+#include <string>
+#include <arpa/inet.h>
+#include <boost/lexical_cast.hpp>
+#include <boost/shared_array.hpp>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/ssl.h>
+#include <openssl/x509v3.h>
+#include "concurrency/Mutex.h"
+#include "TSSLSocket.h"
+
+#define OPENSSL_VERSION_NO_THREAD_ID 0x10000000L
+
+using namespace std;
+using namespace boost;
+using namespace apache::thrift::concurrency;
+
+struct CRYPTO_dynlock_value {
+  Mutex mutex;
+};
+
+namespace apache { namespace thrift { namespace transport {
+
+
+static void buildErrors(string& message, int error = 0);
+static bool matchName(const char* host, const char* pattern, int size);
+static char uppercase(char c);
+
+// SSLContext implementation
+SSLContext::SSLContext() {
+  ctx_ = SSL_CTX_new(TLSv1_method());
+  if (ctx_ == NULL) {
+    string errors;
+    buildErrors(errors);
+    throw TSSLException("SSL_CTX_new: " + errors);
+  }
+  SSL_CTX_set_mode(ctx_, SSL_MODE_AUTO_RETRY);
+}
+
+SSLContext::~SSLContext() {
+  if (ctx_ != NULL) {
+    SSL_CTX_free(ctx_);
+    ctx_ = NULL;
+  }
+}
+
+SSL* SSLContext::createSSL() {
+  SSL* ssl = SSL_new(ctx_);
+  if (ssl == NULL) {
+    string errors;
+    buildErrors(errors);
+    throw TSSLException("SSL_new: " + errors);
+  }
+  return ssl;
+}
+
+// TSSLSocket implementation
+TSSLSocket::TSSLSocket(shared_ptr<SSLContext> ctx):
+  TSocket(), server_(false), ssl_(NULL), ctx_(ctx) {
+}
+
+TSSLSocket::TSSLSocket(shared_ptr<SSLContext> ctx, int socket):
+  TSocket(socket), server_(false), ssl_(NULL), ctx_(ctx) {
+}
+
+TSSLSocket::TSSLSocket(shared_ptr<SSLContext> ctx, string host, int port):
+  TSocket(host, port), server_(false), ssl_(NULL), ctx_(ctx) {
+}
+
+TSSLSocket::~TSSLSocket() {
+  close();
+}
+
+bool TSSLSocket::isOpen() {
+  if (ssl_ == NULL || !TSocket::isOpen()) {
+    return false;
+  }
+  int shutdown = SSL_get_shutdown(ssl_);
+  bool shutdownReceived = (shutdown & SSL_RECEIVED_SHUTDOWN);
+  bool shutdownSent     = (shutdown & SSL_SENT_SHUTDOWN);
+  if (shutdownReceived && shutdownSent) {
+    return false;
+  }
+  return true;
+}
+
+bool TSSLSocket::peek() {
+  if (!isOpen()) {
+    return false;
+  }
+  checkHandshake();
+  int rc;
+  uint8_t byte;
+  rc = SSL_peek(ssl_, &byte, 1);
+  if (rc < 0) {
+    int errno_copy = errno;
+    string errors;
+    buildErrors(errors, errno_copy);
+    throw TSSLException("SSL_peek: " + errors);
+  }
+  if (rc == 0) {
+    ERR_clear_error();
+  }
+  return (rc > 0);
+}
+
+void TSSLSocket::open() {
+  if (isOpen() || server()) {
+    throw TTransportException(TTransportException::BAD_ARGS);
+  }
+  TSocket::open();
+}
+
+void TSSLSocket::close() {
+  if (ssl_ != NULL) {
+    int rc = SSL_shutdown(ssl_);
+    if (rc == 0) {
+      rc = SSL_shutdown(ssl_);
+    }
+    if (rc < 0) {
+      int errno_copy = errno;
+      string errors;
+      buildErrors(errors, errno_copy);
+      GlobalOutput(("SSL_shutdown: " + errors).c_str());
+    }
+    SSL_free(ssl_);
+    ssl_ = NULL;
+    ERR_remove_state(0);
+  }
+  TSocket::close();
+}
+
+uint32_t TSSLSocket::read(uint8_t* buf, uint32_t len) {
+  checkHandshake();
+  int32_t bytes = 0;
+  for (int32_t retries = 0; retries < maxRecvRetries_; retries++){
+    bytes = SSL_read(ssl_, buf, len);
+    if (bytes >= 0)
+      break;
+    int errno_copy = errno;
+    if (SSL_get_error(ssl_, bytes) == SSL_ERROR_SYSCALL) {
+      if (ERR_get_error() == 0 && errno_copy == EINTR) {
+        continue;
+      }
+    }
+    string errors;
+    buildErrors(errors, errno_copy);
+    throw TSSLException("SSL_read: " + errors);
+  }
+  return bytes;
+}
+
+void TSSLSocket::write(const uint8_t* buf, uint32_t len) {
+  checkHandshake();
+  // loop in case SSL_MODE_ENABLE_PARTIAL_WRITE is set in SSL_CTX.
+  uint32_t written = 0;
+  while (written < len) {
+    int32_t bytes = SSL_write(ssl_, &buf[written], len - written);
+    if (bytes <= 0) {
+      int errno_copy = errno;
+      string errors;
+      buildErrors(errors, errno_copy);
+      throw TSSLException("SSL_write: " + errors);
+    }
+    written += bytes;
+  }
+}
+
+void TSSLSocket::flush() {
+  // Don't throw exception if not open. Thrift servers close socket twice.
+  if (ssl_ == NULL) {
+    return;
+  }
+  checkHandshake();
+  BIO* bio = SSL_get_wbio(ssl_);
+  if (bio == NULL) {
+    throw TSSLException("SSL_get_wbio returns NULL");
+  }
+  if (BIO_flush(bio) != 1) {
+    int errno_copy = errno;
+    string errors;
+    buildErrors(errors, errno_copy);
+    throw TSSLException("BIO_flush: " + errors);
+  }
+}
+
+void TSSLSocket::checkHandshake() {
+  if (!TSocket::isOpen()) {
+    throw TTransportException(TTransportException::NOT_OPEN);
+  }
+  if (ssl_ != NULL) {
+    return;
+  }
+  ssl_ = ctx_->createSSL();
+  SSL_set_fd(ssl_, socket_);
+  int rc;
+  if (server()) {
+    rc = SSL_accept(ssl_);
+  } else {
+    rc = SSL_connect(ssl_);
+  }
+  if (rc <= 0) {
+    int errno_copy = errno;
+    string fname(server() ? "SSL_accept" : "SSL_connect");
+    string errors;
+    buildErrors(errors, errno_copy);
+    throw TSSLException(fname + ": " + errors);
+  }
+  authorize();
+}
+
+void TSSLSocket::authorize() {
+  int rc = SSL_get_verify_result(ssl_);
+  if (rc != X509_V_OK) {  // verify authentication result
+    throw TSSLException(string("SSL_get_verify_result(), ") +
+                        X509_verify_cert_error_string(rc));
+  }
+
+  X509* cert = SSL_get_peer_certificate(ssl_);
+  if (cert == NULL) {
+    // certificate is not present
+    if (SSL_get_verify_mode(ssl_) & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
+      throw TSSLException("authorize: required certificate not present");
+    }
+    // certificate was optional: didn't intend to authorize remote
+    if (server() && access_ != NULL) {
+      throw TSSLException("authorize: certificate required for authorization");
+    }
+    return;
+  }
+  // certificate is present
+  if (access_ == NULL) {
+    X509_free(cert);
+    return;
+  }
+  // both certificate and access manager are present
+
+  string host;
+  sockaddr_storage sa = {};
+  socklen_t saLength = sizeof(sa);
+
+  if (getpeername(socket_, (sockaddr*)&sa, &saLength) != 0) {
+    sa.ss_family = AF_UNSPEC;
+  }
+
+  AccessManager::Decision decision = access_->verify(sa);
+
+  if (decision != AccessManager::SKIP) {
+    X509_free(cert);
+    if (decision != AccessManager::ALLOW) {
+      throw TSSLException("authorize: access denied based on remote IP");
+    }
+    return;
+  }
+
+  // extract subjectAlternativeName
+  STACK_OF(GENERAL_NAME)* alternatives = (STACK_OF(GENERAL_NAME)*)
+                       X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
+  if (alternatives != NULL) {
+    const int count = sk_GENERAL_NAME_num(alternatives);
+    for (int i = 0; decision == AccessManager::SKIP && i < count; i++) {
+      const GENERAL_NAME* name = sk_GENERAL_NAME_value(alternatives, i);
+      if (name == NULL) {
+        continue;
+      }
+      char* data = (char*)ASN1_STRING_data(name->d.ia5);
+      int length = ASN1_STRING_length(name->d.ia5);
+      switch (name->type) {
+        case GEN_DNS:
+          if (host.empty()) {
+            host = (server() ? getPeerHost() : getHost());
+          }
+          decision = access_->verify(host, data, length);
+          break;
+        case GEN_IPADD:
+          decision = access_->verify(sa, data, length);
+          break;
+      }
+    }
+    sk_GENERAL_NAME_pop_free(alternatives, GENERAL_NAME_free);
+  }
+
+  if (decision != AccessManager::SKIP) {
+    X509_free(cert);
+    if (decision != AccessManager::ALLOW) {
+      throw TSSLException("authorize: access denied");
+    }
+    return;
+  }
+
+  // extract commonName
+  X509_NAME* name = X509_get_subject_name(cert);
+  if (name != NULL) {
+    X509_NAME_ENTRY* entry;
+    unsigned char* utf8;
+    int last = -1;
+    while (decision == AccessManager::SKIP) {
+      last = X509_NAME_get_index_by_NID(name, NID_commonName, last);
+      if (last == -1)
+        break;
+      entry = X509_NAME_get_entry(name, last);
+      if (entry == NULL)
+        continue;
+      ASN1_STRING* common = X509_NAME_ENTRY_get_data(entry);
+      int size = ASN1_STRING_to_UTF8(&utf8, common);
+      if (host.empty()) {
+        host = (server() ? getHost() : getHost());
+      }
+      decision = access_->verify(host, (char*)utf8, size);
+      OPENSSL_free(utf8);
+    }
+  }
+  X509_free(cert);
+  if (decision != AccessManager::ALLOW) {
+    throw TSSLException("authorize: cannot authorize peer");
+  }
+}
+
+// TSSLSocketFactory implementation
+bool     TSSLSocketFactory::initialized = false;
+uint64_t TSSLSocketFactory::count_ = 0;
+Mutex    TSSLSocketFactory::mutex_;
+
+TSSLSocketFactory::TSSLSocketFactory(): server_(false) {
+  Guard guard(mutex_);
+  if (count_ == 0) {
+    initializeOpenSSL();
+    randomize();
+  }
+  count_++;
+  ctx_ = shared_ptr<SSLContext>(new SSLContext);
+}
+
+TSSLSocketFactory::~TSSLSocketFactory() {
+  Guard guard(mutex_);
+  count_--;
+  if (count_ == 0) {
+    cleanupOpenSSL();
+  }
+}
+
+shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket() {
+  shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_));
+  setup(ssl);
+  return ssl;
+}
+
+shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket(int socket) {
+  shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_, socket));
+  setup(ssl);
+  return ssl;
+}
+
+shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket(const string& host,
+                                                       int port) {
+  shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_, host, port));
+  setup(ssl);
+  return ssl;
+}
+
+void TSSLSocketFactory::setup(shared_ptr<TSSLSocket> ssl) {
+  ssl->server(server());
+  if (access_ == NULL && !server()) {
+    access_ = shared_ptr<AccessManager>(new DefaultClientAccessManager);
+  }
+  if (access_ != NULL) {
+    ssl->access(access_);
+  }
+}
+
+void TSSLSocketFactory::ciphers(const string& enable) {
+  int rc = SSL_CTX_set_cipher_list(ctx_->get(), enable.c_str());
+  if (ERR_peek_error() != 0) {
+    string errors;
+    buildErrors(errors);
+    throw TSSLException("SSL_CTX_set_cipher_list: " + errors);
+  }
+  if (rc == 0) {
+    throw TSSLException("None of specified ciphers are supported");
+  }
+}
+
+void TSSLSocketFactory::authenticate(bool required) {
+  int mode;
+  if (required) {
+    mode  = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE;
+  } else {
+    mode = SSL_VERIFY_NONE;
+  }
+  SSL_CTX_set_verify(ctx_->get(), mode, NULL);
+}
+
+void TSSLSocketFactory::loadCertificate(const char* path, const char* format) {
+  if (path == NULL || format == NULL) {
+    throw TTransportException(TTransportException::BAD_ARGS,
+         "loadCertificateChain: either <path> or <format> is NULL");
+  }
+  if (strcmp(format, "PEM") == 0) {
+    if (SSL_CTX_use_certificate_chain_file(ctx_->get(), path) == 0) {
+      int errno_copy = errno;
+      string errors;
+      buildErrors(errors, errno_copy);
+      throw TSSLException("SSL_CTX_use_certificate_chain_file: " + errors);
+    }
+  } else {
+    throw TSSLException("Unsupported certificate format: " + string(format));
+  }
+}
+
+void TSSLSocketFactory::loadPrivateKey(const char* path, const char* format) {
+  if (path == NULL || format == NULL) {
+    throw TTransportException(TTransportException::BAD_ARGS,
+         "loadPrivateKey: either <path> or <format> is NULL");
+  }
+  if (strcmp(format, "PEM") == 0) {
+    if (SSL_CTX_use_PrivateKey_file(ctx_->get(), path, SSL_FILETYPE_PEM) == 0) {
+      int errno_copy = errno;
+      string errors;
+      buildErrors(errors, errno_copy);
+      throw TSSLException("SSL_CTX_use_PrivateKey_file: " + errors);
+    }
+  }
+}
+
+void TSSLSocketFactory::loadTrustedCertificates(const char* path) {
+  if (path == NULL) {
+    throw TTransportException(TTransportException::BAD_ARGS,
+         "loadTrustedCertificates: <path> is NULL");
+  }
+  if (SSL_CTX_load_verify_locations(ctx_->get(), path, NULL) == 0) {
+    int errno_copy = errno;
+    string errors;
+    buildErrors(errors, errno_copy);
+    throw TSSLException("SSL_CTX_load_verify_locations: " + errors);
+  }
+}
+
+void TSSLSocketFactory::randomize() {
+  RAND_poll();
+}
+
+void TSSLSocketFactory::overrideDefaultPasswordCallback() {
+  SSL_CTX_set_default_passwd_cb(ctx_->get(), passwordCallback);
+  SSL_CTX_set_default_passwd_cb_userdata(ctx_->get(), this);
+}
+
+int TSSLSocketFactory::passwordCallback(char* password,
+                                        int size,
+                                        int,
+                                        void* data) {
+  TSSLSocketFactory* factory = (TSSLSocketFactory*)data;
+  string userPassword;
+  factory->getPassword(userPassword, size);
+  int length = userPassword.size();
+  if (length > size) {
+    length = size;
+  }
+  strncpy(password, userPassword.c_str(), length);
+  return length;
+}
+
+static shared_array<Mutex> mutexes;
+
+static void callbackLocking(int mode, int n, const char*, int) {
+  if (mode & CRYPTO_LOCK) {
+    mutexes[n].lock();
+  } else {
+    mutexes[n].unlock();
+  }
+}
+
+#if (OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_NO_THREAD_ID)
+static unsigned long callbackThreadID() {
+  return reinterpret_cast<unsigned long>(pthread_self());
+}
+#endif
+
+static CRYPTO_dynlock_value* dyn_create(const char*, int) {
+  return new CRYPTO_dynlock_value;
+}
+
+static void dyn_lock(int mode,
+                     struct CRYPTO_dynlock_value* lock,
+                     const char*, int) {
+  if (lock != NULL) {
+    if (mode & CRYPTO_LOCK) {
+      lock->mutex.lock();
+    } else {
+      lock->mutex.unlock();
+    }
+  }
+}
+
+static void dyn_destroy(struct CRYPTO_dynlock_value* lock, const char*, int) {
+  delete lock;
+}
+
+void TSSLSocketFactory::initializeOpenSSL() {
+  if (initialized) {
+    return;
+  }
+  initialized = true;
+  SSL_library_init();
+  SSL_load_error_strings();
+  // static locking
+  mutexes = shared_array<Mutex>(new Mutex[::CRYPTO_num_locks()]);
+  if (mutexes == NULL) {
+    throw TTransportException(TTransportException::INTERNAL_ERROR,
+          "initializeOpenSSL() failed, "
+          "out of memory while creating mutex array");
+  }
+#if (OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_NO_THREAD_ID)
+  CRYPTO_set_id_callback(callbackThreadID);
+#endif
+  CRYPTO_set_locking_callback(callbackLocking);
+  // dynamic locking
+  CRYPTO_set_dynlock_create_callback(dyn_create);
+  CRYPTO_set_dynlock_lock_callback(dyn_lock);
+  CRYPTO_set_dynlock_destroy_callback(dyn_destroy);
+}
+
+void TSSLSocketFactory::cleanupOpenSSL() {
+  if (!initialized) {
+    return;
+  }
+  initialized = false;
+#if (OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_NO_THREAD_ID)
+  CRYPTO_set_id_callback(NULL);
+#endif
+  CRYPTO_set_locking_callback(NULL);
+  CRYPTO_set_dynlock_create_callback(NULL);
+  CRYPTO_set_dynlock_lock_callback(NULL);
+  CRYPTO_set_dynlock_destroy_callback(NULL);
+  CRYPTO_cleanup_all_ex_data();
+  ERR_free_strings();
+  EVP_cleanup();
+  ERR_remove_state(0);
+  mutexes.reset();
+}
+
+// extract error messages from error queue
+void buildErrors(string& errors, int errno_copy) {
+  unsigned long  errorCode;
+  char   message[256];
+
+  errors.reserve(512);
+  while ((errorCode = ERR_get_error()) != 0) {
+    if (!errors.empty()) {
+      errors += "; ";
+    }
+    const char* reason = ERR_reason_error_string(errorCode);
+    if (reason == NULL) {
+      snprintf(message, sizeof(message) - 1, "SSL error # %lu", errorCode);
+      reason = message;
+    }
+    errors += reason;
+  }
+  if (errors.empty()) {
+    if (errno_copy != 0) {
+      errors += TOutput::strerror_s(errno_copy);
+    }
+  }
+  if (errors.empty()) {
+    errors = "error code: " + lexical_cast<string>(errno_copy);
+  }
+}
+
+/**
+ * Default implementation of AccessManager
+ */
+Decision DefaultClientAccessManager::verify(const sockaddr_storage& sa)
+  throw() { return SKIP; }
+
+Decision DefaultClientAccessManager::verify(const string& host,
+                                            const char* name,
+                                            int size) throw() {
+  if (host.empty() || name == NULL || size <= 0) {
+    return SKIP;
+  }
+  return (matchName(host.c_str(), name, size) ? ALLOW : SKIP);
+}
+
+Decision DefaultClientAccessManager::verify(const sockaddr_storage& sa,
+                                            const char* data,
+                                            int size) throw() {
+  bool match = false;
+  if (sa.ss_family == AF_INET && size == sizeof(in_addr)) {
+    match = (memcmp(&((sockaddr_in*)&sa)->sin_addr, data, size) == 0);
+  } else if (sa.ss_family == AF_INET6 && size == sizeof(in6_addr)) {
+    match = (memcmp(&((sockaddr_in6*)&sa)->sin6_addr, data, size) == 0);
+  }
+  return (match ? ALLOW : SKIP);
+}
+
+/**
+ * Match a name with a pattern. The pattern may include wildcard. A single
+ * wildcard "*" can match up to one component in the domain name.
+ *
+ * @param  host    Host name, typically the name of the remote host
+ * @param  pattern Name retrieved from certificate
+ * @param  size    Size of "pattern"
+ * @return True, if "host" matches "pattern". False otherwise.
+ */
+bool matchName(const char* host, const char* pattern, int size) {
+  bool match = false;
+  int i = 0, j = 0;
+  while (i < size && host[j] != '\0') {
+    if (uppercase(pattern[i]) == uppercase(host[j])) {
+      i++;
+      j++;
+      continue;
+    }
+    if (pattern[i] == '*') {
+      while (host[j] != '.' && host[j] != '\0') {
+        j++;
+      }
+      i++;
+      continue;
+    }
+    break;
+  }
+  if (i == size && host[j] == '\0') {
+    match = true;
+  }
+  return match;
+
+}
+
+// This is to work around the Turkish locale issue, i.e.,
+// toupper('i') != toupper('I') if locale is "tr_TR"
+char uppercase (char c) {
+  if ('a' <= c && c <= 'z') {
+    return c + ('A' - 'a');
+  }
+  return c;
+}
+
+}}}
diff --git a/lib/cpp/src/transport/TSSLSocket.h b/lib/cpp/src/transport/TSSLSocket.h
new file mode 100644
index 0000000..58e3934
--- /dev/null
+++ b/lib/cpp/src/transport/TSSLSocket.h
@@ -0,0 +1,304 @@
+// Copyright (c) 2009- Facebook
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/
+
+#ifndef _THRIFT_TRANSPORT_TSSLSOCKET_H_
+#define _THRIFT_TRANSPORT_TSSLSOCKET_H_ 1
+
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include <openssl/ssl.h>
+#include "concurrency/Mutex.h"
+#include "TSocket.h"
+
+namespace apache { namespace thrift { namespace transport {
+
+class AccessManager;
+class SSLContext;
+
+/**
+ * OpenSSL implementation for SSL socket interface.
+ *
+ * @author Ping Li <pingli@facebook.com>
+ */
+class TSSLSocket: public TSocket {
+ public:
+ ~TSSLSocket();
+  /**
+   * TTransport interface.
+   */
+  bool     isOpen();
+  bool     peek();
+  void     open();
+  void     close();
+  uint32_t read(uint8_t* buf, uint32_t len);
+  void     write(const uint8_t* buf, uint32_t len);
+  void     flush();
+   /**
+   * Set whether to use client or server side SSL handshake protocol.
+   *
+   * @param flag  Use server side handshake protocol if true.
+   */
+  void server(bool flag) { server_ = flag; }
+  /**
+   * Determine whether the SSL socket is server or client mode.
+   */
+  bool server() const { return server_; }
+  /**
+   * Set AccessManager.
+   *
+   * @param manager  Instance of AccessManager
+   */
+  virtual void access(boost::shared_ptr<AccessManager> manager) {
+    access_ = manager;
+  }
+protected:
+  /**
+   * Constructor.
+   */
+  TSSLSocket(boost::shared_ptr<SSLContext> ctx);
+  /**
+   * Constructor, create an instance of TSSLSocket given an existing socket.
+   *
+   * @param socket An existing socket
+   */
+  TSSLSocket(boost::shared_ptr<SSLContext> ctx, int socket);
+  /**
+   * Constructor.
+   *
+   * @param host  Remote host name
+   * @param port  Remote port number
+   */
+  TSSLSocket(boost::shared_ptr<SSLContext> ctx,
+                               std::string host,
+                                       int port);
+  /**
+   * Authorize peer access after SSL handshake completes.
+   */
+  virtual void authorize();
+  /**
+   * Initiate SSL handshake if not already initiated.
+   */
+  void checkHandshake();
+
+  bool server_;
+  SSL* ssl_;
+  boost::shared_ptr<SSLContext> ctx_;
+  boost::shared_ptr<AccessManager> access_;
+  friend class TSSLSocketFactory;
+};
+
+/**
+ * SSL socket factory. SSL sockets should be created via SSL factory.
+ */
+class TSSLSocketFactory {
+ public:
+  /**
+   * Constructor/Destructor
+   */
+  TSSLSocketFactory();
+  virtual ~TSSLSocketFactory();
+  /**
+   * Create an instance of TSSLSocket with a fresh new socket.
+   */
+  virtual boost::shared_ptr<TSSLSocket> createSocket();
+  /**
+   * Create an instance of TSSLSocket with the given socket.
+   *
+   * @param socket An existing socket.
+   */
+  virtual boost::shared_ptr<TSSLSocket> createSocket(int socket);
+   /**
+   * Create an instance of TSSLSocket.
+   *
+   * @param host  Remote host to be connected to
+   * @param port  Remote port to be connected to
+   */
+  virtual boost::shared_ptr<TSSLSocket> createSocket(const std::string& host,
+                                                     int port);
+  /**
+   * Set ciphers to be used in SSL handshake process.
+   *
+   * @param ciphers  A list of ciphers
+   */
+  virtual void ciphers(const std::string& enable);
+  /**
+   * Enable/Disable authentication.
+   *
+   * @param required Require peer to present valid certificate if true
+   */
+  virtual void authenticate(bool required);
+  /**
+   * Load server certificate.
+   *
+   * @param path   Path to the certificate file
+   * @param format Certificate file format
+   */
+  virtual void loadCertificate(const char* path, const char* format = "PEM");
+  /**
+   * Load private key.
+   *
+   * @param path   Path to the private key file
+   * @param format Private key file format
+   */
+  virtual void loadPrivateKey(const char* path, const char* format = "PEM");
+  /**
+   * Load trusted certificates from specified file.
+   *
+   * @param path Path to trusted certificate file
+   */
+  virtual void loadTrustedCertificates(const char* path);
+  /**
+   * Default randomize method.
+   */
+  virtual void randomize();
+  /**
+   * Override default OpenSSL password callback with getPassword().
+   */
+  void overrideDefaultPasswordCallback();
+  /**
+   * Set/Unset server mode.
+   *
+   * @param flag  Server mode if true
+   */
+  virtual void server(bool flag) { server_ = flag; }
+  /**
+   * Determine whether the socket is in server or client mode.
+   *
+   * @return true, if server mode, or, false, if client mode
+   */
+  virtual bool server() const { return server_; }
+  /**
+   * Set AccessManager.
+   *
+   * @param manager  The AccessManager instance
+   */
+  virtual void access(boost::shared_ptr<AccessManager> manager) {
+    access_ = manager;
+  }
+ protected:
+  boost::shared_ptr<SSLContext> ctx_;
+
+  static void initializeOpenSSL();
+  static void cleanupOpenSSL();
+  /**
+   * Override this method for custom password callback. It may be called
+   * multiple times at any time during a session as necessary.
+   *
+   * @param password Pass collected password to OpenSSL
+   * @param size     Maximum length of password including NULL character
+   */
+  virtual void getPassword(std::string& password, int size) { }
+ private:
+  bool server_;
+  boost::shared_ptr<AccessManager> access_;
+  static bool initialized;
+  static concurrency::Mutex mutex_;
+  static uint64_t count_;
+  void setup(boost::shared_ptr<TSSLSocket> ssl);
+  static int passwordCallback(char* password, int size, int, void* data);
+};
+
+/**
+ * SSL exception.
+ */
+class TSSLException: public TTransportException {
+ public:
+  TSSLException(const std::string& message):
+    TTransportException(TTransportException::INTERNAL_ERROR, message) {}
+
+  virtual const char* what() const throw() {
+    if (message_.empty()) {
+      return "TSSLException";
+    } else {
+      return message_.c_str();
+    }
+  }
+};
+
+/**
+ * Wrap OpenSSL SSL_CTX into a class.
+ */
+class SSLContext {
+ public:
+  SSLContext();
+  virtual ~SSLContext();
+  SSL* createSSL();
+  SSL_CTX* get() { return ctx_; }
+ private:
+  SSL_CTX* ctx_;
+};
+
+/**
+ * Callback interface for access control. It's meant to verify the remote host.
+ * It's constructed when application starts and set to TSSLSocketFactory
+ * instance. It's passed onto all TSSLSocket instances created by this factory
+ * object.
+ */
+class AccessManager {
+ public:
+  enum Decision {
+    DENY   = -1,    // deny access
+    SKIP   =  0,    // cannot make decision, move on to next (if any)
+    ALLOW  =  1,    // allow access
+  };
+ /**
+  * Destructor
+  */
+ virtual ~AccessManager() {}
+ /**
+  * Determine whether the peer should be granted access or not. It's called
+  * once after the SSL handshake completes successfully, before peer certificate
+  * is examined.
+  *
+  * If a valid decision (ALLOW or DENY) is returned, the peer certificate is
+  * not to be verified.
+  *
+  * @param  sa Peer IP address
+  * @return True if the peer is trusted, false otherwise
+  */
+ virtual Decision verify(const sockaddr_storage& sa) throw() { return DENY; }
+ /**
+  * Determine whether the peer should be granted access or not. It's called
+  * every time a DNS subjectAltName/common name is extracted from peer's
+  * certificate.
+  *
+  * @param  host Client mode: host name returned by TSocket::getHost()
+  *              Server mode: host name returned by TSocket::getPeerHost()
+  * @param  name SubjectAltName or common name extracted from peer certificate
+  * @param  size Length of name
+  * @return True if the peer is trusted, false otherwise
+  *
+  * Note: The "name" parameter may be UTF8 encoded.
+  */
+ virtual Decision verify(const std::string& host, const char* name, int size)
+   throw() { return DENY; }
+ /**
+  * Determine whether the peer should be granted access or not. It's called
+  * every time an IP subjectAltName is extracted from peer's certificate.
+  *
+  * @param  sa   Peer IP address retrieved from the underlying socket
+  * @param  data IP address extracted from certificate
+  * @param  size Length of the IP address
+  * @return True if the peer is trusted, false otherwise
+  */
+ virtual Decision verify(const sockaddr_storage& sa, const char* data, int size)
+   throw() { return DENY; }
+};
+
+typedef AccessManager::Decision Decision;
+
+class DefaultClientAccessManager: public AccessManager {
+ public:
+  // AccessManager interface
+  Decision verify(const sockaddr_storage& sa) throw();
+  Decision verify(const std::string& host, const char* name, int size) throw();
+  Decision verify(const sockaddr_storage& sa, const char* data, int size) throw();
+};
+
+
+}}}
+
+#endif
diff --git a/lib/cpp/src/transport/TServerSocket.cpp b/lib/cpp/src/transport/TServerSocket.cpp
index 8608898..276b060 100644
--- a/lib/cpp/src/transport/TServerSocket.cpp
+++ b/lib/cpp/src/transport/TServerSocket.cpp
@@ -386,7 +386,7 @@
     throw TTransportException(TTransportException::UNKNOWN, "fcntl(F_SETFL)", errno_copy);
   }
 
-  shared_ptr<TSocket> client(new TSocket(clientSocket));
+  shared_ptr<TSocket> client = createSocket(clientSocket);
   if (sendTimeout_ > 0) {
     client->setSendTimeout(sendTimeout_);
   }
@@ -398,6 +398,10 @@
   return client;
 }
 
+shared_ptr<TSocket> TServerSocket::createSocket(int clientSocket) {
+  return shared_ptr<TSocket>(new TSocket(clientSocket));
+}
+
 void TServerSocket::interrupt() {
   if (intSock1_ >= 0) {
     int8_t byte = 0;
diff --git a/lib/cpp/src/transport/TServerSocket.h b/lib/cpp/src/transport/TServerSocket.h
index 8cd521f..40a1148 100644
--- a/lib/cpp/src/transport/TServerSocket.h
+++ b/lib/cpp/src/transport/TServerSocket.h
@@ -56,6 +56,7 @@
 
  protected:
   boost::shared_ptr<TTransport> acceptImpl();
+  virtual boost::shared_ptr<TSocket> createSocket(int client);
 
  private:
   int port_;
diff --git a/lib/cpp/src/transport/TSocket.h b/lib/cpp/src/transport/TSocket.h
index e89059f..5521491 100644
--- a/lib/cpp/src/transport/TSocket.h
+++ b/lib/cpp/src/transport/TSocket.h
@@ -70,12 +70,12 @@
    *
    * @return Is the socket alive?
    */
-  bool isOpen();
+  virtual bool isOpen();
 
   /**
    * Calls select on the socket to see if there is more data available.
    */
-  bool peek();
+  virtual bool peek();
 
   /**
    * Creates and opens the UNIX socket.
@@ -92,12 +92,12 @@
   /**
    * Reads from the underlying socket.
    */
-  uint32_t read(uint8_t* buf, uint32_t len);
+  virtual uint32_t read(uint8_t* buf, uint32_t len);
 
   /**
    * Writes to the underlying socket.  Loops until done or fail.
    */
-  void write(const uint8_t* buf, uint32_t len);
+  virtual void write(const uint8_t* buf, uint32_t len);
 
   /**
    * Writes to the underlying socket.  Does single send() and returns result.
