diff --git a/httplib.h b/httplib.h
index 5adfc2a..8b17b69 100644
--- a/httplib.h
+++ b/httplib.h
@@ -78,6 +78,7 @@ typedef int socket_t;
 #include <openssl/x509v3.h>
 
 #if OPENSSL_VERSION_NUMBER < 0x10100000L
+#include <openssl/crypto.h>
 inline const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *asn1) {
   return M_ASN1_STRING_data(asn1);
 }
@@ -2397,8 +2398,6 @@ namespace detail {
 template <typename U, typename V, typename T>
 inline bool
 read_and_close_socket_ssl(socket_t sock, size_t keep_alive_max_count,
-                          // TODO: OpenSSL 1.0.2 occasionally crashes...
-                          // The upcoming 1.1.0 is going to be thread safe.
                           SSL_CTX *ctx, std::mutex &ctx_mutex,
                           U SSL_connect_or_accept, V setup, T callback) {
   SSL *ssl = nullptr;
@@ -2461,6 +2460,32 @@ read_and_close_socket_ssl(socket_t sock, size_t keep_alive_max_count,
   return ret;
 }
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+class SSLThreadLocks {
+public:
+  SSLThreadLocks() {
+    CRYPTO_set_locking_callback(locking_callback);
+  }
+
+  ~SSLThreadLocks() {
+    CRYPTO_set_locking_callback(nullptr);
+  }
+
+private:
+  static void locking_callback(int mode, int type, const char * /*file*/, int /*line*/) {
+    if (mode & CRYPTO_LOCK) {
+      locks_[type].lock();
+    } else {
+      locks_[type].unlock();
+    }
+  }
+
+  static std::vector<std::mutex> locks_;
+};
+
+std::vector<std::mutex> SSLThreadLocks::locks_(CRYPTO_num_locks());
+#endif
+
 class SSLInit {
 public:
   SSLInit() {
@@ -2469,6 +2494,11 @@ public:
   }
 
   ~SSLInit() { ERR_free_strings(); }
+
+private:
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+  SSLThreadLocks thread_init_;
+#endif
 };
 
 static SSLInit sslinit_;