diff --git a/src/http.cpp b/src/http.cpp
index ad1981a99395018626c4886314ee81a7b521ec1a..23005c741975094b319ff961031d3c43d41946d4 100644
--- a/src/http.cpp
+++ b/src/http.cpp
@@ -26,6 +26,14 @@
 #include <http_parser.h>
 #include <json/json.h>
 
+#include <openssl/ocsp.h>
+#include <openssl/ssl.h>
+#include <openssl/asn1.h>
+
+#define MAXAGE_SEC (14*24*60*60)
+#define JITTER_SEC (60)
+#define OCSP_MAX_RESPONSE_SIZE (20480)
+
 namespace dht {
 namespace http {
 
@@ -184,6 +192,253 @@ Connection::is_ssl() const
     return ssl_ctx_ ? true : false;
 }
 
+static time_t
+parse_ocsp_time(ASN1_GENERALIZEDTIME* gt)
+{
+    struct tm tm;
+    time_t rv = -1;
+
+    if (gt == nullptr)
+        return -1;
+    // RFC 6960 specifies that all times in OCSP must be GENERALIZEDTIME
+    if (ASN1_time_parse((const char*)gt->data, gt->length, &tm, V_ASN1_GENERALIZEDTIME) == -1)
+        return -1;
+    if ((rv = timegm(&tm)) == -1)
+        return -1;
+    return rv;
+}
+
+static inline X509*
+cert_from_chain(STACK_OF(X509)* fullchain)
+{
+    return sk_X509_value(fullchain, 0);
+}
+
+static X509*
+issuer_from_chain(STACK_OF(X509)* fullchain)
+{
+    X509 *cert, *issuer;
+    X509_NAME *issuer_name;
+
+    cert = cert_from_chain(fullchain);
+    if ((issuer_name = X509_get_issuer_name(cert)) == nullptr)
+        return nullptr;
+
+    issuer = X509_find_by_subject(fullchain, issuer_name);
+    return issuer;
+}
+
+using OscpRequestPtr = std::unique_ptr<OCSP_REQUEST, decltype(&OCSP_REQUEST_free)>;
+struct OscpRequestInfo {
+    OscpRequestPtr req {nullptr, &OCSP_REQUEST_free};
+    std::vector<uint8_t> data;
+    std::string url;
+};
+
+static std::unique_ptr<OscpRequestInfo>
+ocspRequestFromCert(STACK_OF(X509)* fullchain, const std::shared_ptr<Logger>& logger, bool nonce = false)
+{
+    if (fullchain == nullptr)
+        return {};
+
+    if (sk_X509_num(fullchain) <= 1) {
+        if (logger)
+            logger->e("Cert does not contain a cert chain");
+        return {};
+    }
+    X509* cert = cert_from_chain(fullchain);
+    if (cert == nullptr) {
+        if (logger)
+            logger->e("No certificate found");
+        return {};
+    }
+    X509* issuer = issuer_from_chain(fullchain);
+    if (issuer == nullptr) {
+        if (logger)
+            logger->e("Unable to find issuer for cert");
+        return {};
+    }
+
+    auto urls = X509_get1_ocsp(cert);
+    if (urls == nullptr || sk_OPENSSL_STRING_num(urls) <= 0) {
+        if (logger)
+            logger->e("Certificate contains no OCSP url");
+        return {};
+    }
+    auto url = sk_OPENSSL_STRING_value(urls, 0);
+    if (url == nullptr)
+        return {};
+
+    auto request = std::make_unique<OscpRequestInfo>();
+    request->req = OscpRequestPtr(OCSP_REQUEST_new(), &OCSP_REQUEST_free);
+    request->url = strdup(url);
+    X509_email_free(urls);
+
+    OCSP_CERTID* id = OCSP_cert_to_id(EVP_sha1(), cert, issuer);
+    if (id == nullptr) {
+        if (logger)
+            logger->e("Unable to get certificate id from cert");
+        return {};
+    }
+    if (OCSP_request_add0_id(request->req.get(), id) == nullptr) {
+        if (logger)
+            logger->e("Unable to add certificate id to request");
+        return {};
+    }
+
+    if (nonce)
+        OCSP_request_add1_nonce(request->req.get(), nullptr, -1);
+
+    int size;
+    uint8_t* data {nullptr};
+    if ((size = i2d_OCSP_REQUEST(request->req.get(), &data)) <= 0) {
+        if (logger)
+            logger->e("Unable to encode ocsp request");
+        return {};
+    }
+    if (data == nullptr) {
+        if (logger)
+            logger->e("Unable to allocte memory");
+        return {};
+    }
+    request->data = std::vector<uint8_t>(data, data+size);
+    free(data);
+    return request;
+}
+
+bool
+ocspValidateResponse(const OscpRequestInfo& info, STACK_OF(X509)* fullchain, const std::string& response, X509_STORE *store, const std::shared_ptr<Logger>& logger)
+{
+    ASN1_GENERALIZEDTIME *revtime = nullptr, *thisupd = nullptr, *nextupd = nullptr;
+    const uint8_t* p = (const uint8_t*)response.data();
+    int status, cert_status=0, crl_reason=0;
+    time_t now, rev_t = -1, this_t, next_t;
+    OCSP_RESPONSE *resp;
+    OCSP_BASICRESP *bresp;
+    OCSP_CERTID *cid;
+
+    X509* cert = cert_from_chain(fullchain);
+    if (cert == nullptr) {
+        if (logger)
+            logger->e("No certificate found");
+        return false;
+    }
+    X509* issuer = issuer_from_chain(fullchain);
+    if (issuer == nullptr) {
+        if (logger)
+            logger->e("Unable to find issuer for cert");
+        return false;
+    }
+    if ((cid = OCSP_cert_to_id(nullptr, cert, issuer)) == nullptr) {
+        if (logger)
+            logger->e("Unable to get issuer cert/CID");
+        return false;
+    }
+
+    if ((resp = d2i_OCSP_RESPONSE(nullptr, &p, response.size())) == nullptr) {
+        if (logger)
+            logger->e("OCSP response unserializable");
+        return false;
+    }
+
+    if ((bresp = OCSP_response_get1_basic(resp)) == nullptr) {
+        if (logger)
+            logger->e("Failed to load OCSP response");
+        return false;
+    }
+
+    if (OCSP_basic_verify(bresp, fullchain, store, OCSP_TRUSTOTHER) != 1) {
+        if (logger)
+            logger->w("OCSP verify failed");
+        return false;
+    }
+    printf("OCSP response signature validated\n");
+
+    status = OCSP_response_status(resp);
+    if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+        if (logger)
+            logger->w("OCSP Failure: code %d (%s)", status, OCSP_response_status_str(status));
+        return false;
+    }
+
+    // Check the nonce if we sent one
+    if (OCSP_check_nonce(info.req.get(), bresp) <= 0) {
+        if (logger)
+            logger->w("No OCSP nonce, or mismatch");
+        return false;
+    }
+
+    if (OCSP_resp_find_status(bresp, cid, &cert_status, &crl_reason,
+        &revtime, &thisupd, &nextupd) != 1) {
+        if (logger)
+            logger->w("OCSP verify failed: no result for cert");
+        return false;
+    }
+
+    if (revtime && (rev_t = parse_ocsp_time(revtime)) == -1) {
+        if (logger)
+            logger->w("Unable to parse revocation time in OCSP reply");
+        return false;
+    }
+    // Belt and suspenders, Treat it as revoked if there is either
+    // a revocation time, or status revoked.
+    if (rev_t != -1 || cert_status == V_OCSP_CERTSTATUS_REVOKED) {
+        if (logger)
+            logger->w("Invalid OCSP reply: certificate is revoked");
+        if (rev_t != -1) {
+            if (logger)
+                logger->w("Certificate revoked at: %s", ctime(&rev_t));
+        }
+        return false;
+    }
+    if ((this_t = parse_ocsp_time(thisupd)) == -1) {
+        if (logger)
+            logger->w("unable to parse this update time in OCSP reply");
+        return false;
+    }
+    if ((next_t = parse_ocsp_time(nextupd)) == -1) {
+        if (logger)
+            logger->w("unable to parse next update time in OCSP reply");
+        return false;
+    }
+
+    // Don't allow this update to precede next update
+    if (this_t >= next_t) {
+        if (logger)
+            logger->w("Invalid OCSP reply: this update >= next update");
+        return false;
+    }
+
+    now = time(nullptr);
+    // Check that this update is not more than JITTER seconds in the future.
+    if (this_t > now + JITTER_SEC) {
+        if (logger)
+            logger->e("Invalid OCSP reply: this update is in the future (%s)", ctime(&this_t));
+        return false;
+    }
+
+    // Check that this update is not more than MAXSEC in the past.
+    if (this_t < now - MAXAGE_SEC) {
+        if (logger)
+            logger->e("Invalid OCSP reply: this update is too old (%s)", ctime(&this_t));
+        return false;
+    }
+
+    // Check that next update is still valid
+    if (next_t < now - JITTER_SEC) {
+        if (logger)
+            logger->w("Invalid OCSP reply: reply has expired (%s)", ctime(&next_t));
+        return false;
+    }
+
+    if (logger) {
+        logger->d("OCSP response validated");
+        logger->d("	   This Update: %s", ctime(&this_t));
+        logger->d("	   Next Update: %s", ctime(&next_t));
+    }
+    return true;
+}
+
 void
 Connection::set_ssl_verification(const std::string& hostname, const asio::ssl::verify_mode verify_mode)
 {
@@ -196,9 +451,9 @@ Connection::set_ssl_verification(const std::string& hostname, const asio::ssl::v
             ssl_socket_->asio_ssl_stream().set_verify_callback([
                     id = id_, logger = logger_, hostname
                 ] (bool preverified, asio::ssl::verify_context& ctx) -> bool {
+                    X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
                     if (logger) {
                         char subject_name[1024];
-                        X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
                         X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 1024);
                         logger->d("[connection:%i] verify %s compliance to RFC 2818:\n%s", id, hostname.c_str(), subject_name);
                     }
@@ -208,6 +463,29 @@ Connection::set_ssl_verification(const std::string& hostname, const asio::ssl::v
                     auto verify_ec = X509_STORE_CTX_get_error(ctx.native_handle());
                     if (verify_ec != 0 /*X509_V_OK*/ and logger)
                         logger->e("[http::connection:%i] ssl verification error=%i %d", id, verify_ec, verified);
+                    if (verified) {
+                        auto chain = X509_STORE_CTX_get1_chain(ctx.native_handle());
+                        if (auto ocspInfo = ocspRequestFromCert(chain, logger)) {
+                            if (logger)
+                                logger->w("[http::connection:%i] TLS OCSP server: %s, request size: %zu", id, ocspInfo->url.c_str(), ocspInfo->data.size());
+                            bool ocspVerified = false;
+                            asio::io_context io_ctx;
+                            auto ocspReq = std::make_shared<Request>(io_ctx, ocspInfo->url, [&](const Response& ocspResp){
+                                if (ocspResp.status_code == 200) {
+                                    ocspVerified = ocspValidateResponse(*ocspInfo, chain, ocspResp.body, ctx.native_handle()->ctx, logger);
+                                } else {
+                                    if (logger)
+                                        logger->w("[http::connection:%i] TLS OCSP check error", id);
+                                }
+                            }, logger);
+                            ocspReq->set_method(restinio::http_method_post());
+                            ocspReq->set_body({ocspInfo->data.begin(), ocspInfo->data.end()});
+                            ocspReq->send();
+                            io_ctx.run();
+                            if (not ocspVerified)
+                                return false;
+                        }
+                    }
                     return verified;
                 }
             );
@@ -274,6 +552,8 @@ Connection::async_handshake(HandlerCb cb)
                         this_.logger_->d("[connection:%i] self-signed certificate in handshake: %i", this_.id_, verify_ec);
                     else if (verify_ec != X509_V_OK)
                         this_.logger_->e("[connection:%i] verify handshake error: %i", this_.id_, verify_ec);
+                    else
+                        this_.logger_->e("[connection:%i] verify handshake success", this_.id_);
                 }
             }
             if (cb)
@@ -818,12 +1098,7 @@ Request::connect(std::vector<asio::ip::tcp::endpoint>&& endpoints, HandlerCb cb)
             conn_ = std::make_shared<Connection>(ctx_, server_ca_, client_identity_, logger_);
         else
             conn_ = std::make_shared<Connection>(ctx_, true/*ssl*/, logger_);
-#if !defined(LINUX) || defined(__ANDROID__)
-        conn_->set_ssl_verification(get_url().host, asio::ssl::verify_none);
-#else
-        conn_->set_ssl_verification(get_url().host, asio::ssl::verify_peer
-                                                    | asio::ssl::verify_fail_if_no_peer_cert);
-#endif
+        conn_->set_ssl_verification(get_url().host, asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert);
     }
     else
         conn_ = std::make_shared<Connection>(ctx_, false/*ssl*/, logger_);