diff --git a/src/security/certstore.cpp b/src/security/certstore.cpp
index dd2e3893757017cf475beff5ba1684ade72acc71..c3a8a9b9cd1da4274b13ad1badc1eb7db3d58ce8 100644
--- a/src/security/certstore.cpp
+++ b/src/security/certstore.cpp
@@ -40,41 +40,56 @@ CertificateStore::instance()
 }
 
 CertificateStore::CertificateStore()
-    : certPath_(fileutils::get_data_dir()+DIR_SEPARATOR_CH+"certificates")
+    : certPath_(fileutils::get_data_dir()+DIR_SEPARATOR_CH+"certificates"),
+      crlPath_(fileutils::get_data_dir()+DIR_SEPARATOR_CH+"crls")
 {
     fileutils::check_dir(certPath_.c_str());
-    loadLocalCertificates(certPath_);
+    fileutils::check_dir(crlPath_.c_str());
+    loadLocalCertificates();
 }
 
 unsigned
-CertificateStore::loadLocalCertificates(const std::string& path)
+CertificateStore::loadLocalCertificates()
 {
     std::lock_guard<std::mutex> l(lock_);
 
-    auto dir_content = fileutils::readDirectory(path);
+    auto dir_content = fileutils::readDirectory(certPath_);
     unsigned n = 0;
     for (const auto& f : dir_content) {
         try {
-            auto crt = std::make_shared<crypto::Certificate>(fileutils::loadFile(path+DIR_SEPARATOR_CH+f));
+            auto crt = std::make_shared<crypto::Certificate>(fileutils::loadFile(certPath_+DIR_SEPARATOR_CH+f));
             auto id = crt->getId().toString();
             if (id != f)
                 throw std::logic_error({});
-            certs_.emplace(id, crt);
-            ++n;
-            crt = crt->issuer;
             while (crt) {
-                certs_.emplace(crt->getId().toString(), crt);
+                auto id_str = crt->getId().toString();
+                certs_.emplace(id_str, crt);
+                loadRevocations(*crt);
                 crt = crt->issuer;
                 ++n;
             }
         } catch (const std::exception& e) {
-            remove((path+DIR_SEPARATOR_CH+f).c_str());
+            remove((certPath_+DIR_SEPARATOR_CH+f).c_str());
         }
     }
     RING_DBG("CertificateStore: loaded %u local certificates.", n);
     return n;
 }
 
+void
+CertificateStore::loadRevocations(crypto::Certificate& crt)
+{
+    auto dir = crlPath_+DIR_SEPARATOR_CH+crt.getId().toString();
+    auto crl_dir_content = fileutils::readDirectory(dir);
+    for (const auto& crl : crl_dir_content) {
+        try {
+            crt.addRevocationList(std::make_shared<crypto::RevocationList>(fileutils::loadFile(dir+DIR_SEPARATOR_CH+crl)));
+        } catch (const std::exception& e) {
+            RING_WARN("Can't load revocation list: %s", e.what());
+        }
+    }
+}
+
 std::vector<std::string>
 CertificateStore::getPinnedCertificates() const
 {
@@ -156,13 +171,13 @@ CertificateStore::findIssuer(std::shared_ptr<crypto::Certificate> crt) const
 }
 
 static std::vector<crypto::Certificate>
-readCertificates(const std::string& path)
+readCertificates(const std::string& path, const std::string& crl_path)
 {
     std::vector<crypto::Certificate> ret;
     if (fileutils::isDirectory(path)) {
         auto files = fileutils::readDirectory(path);
         for (const auto& file : files) {
-            auto certs = readCertificates(path+"/"+file);
+            auto certs = readCertificates(path+DIR_SEPARATOR_CH+file, crl_path);
             ret.insert(std::end(ret),
                        std::make_move_iterator(std::begin(certs)),
                        std::make_move_iterator(std::end(certs)));
@@ -185,7 +200,7 @@ void
 CertificateStore::pinCertificatePath(const std::string& path, std::function<void(const std::vector<std::string>&)> cb)
 {
     ThreadPool::instance().run([&, path, cb]() {
-        auto certs = readCertificates(path);
+        auto certs = readCertificates(path, crlPath_);
         std::vector<std::string> ids;
         std::vector<std::weak_ptr<crypto::Certificate>> scerts;
         ids.reserve(certs.size());
@@ -245,8 +260,7 @@ CertificateStore::pinCertificate(crypto::Certificate&& cert, bool local)
 }
 
 std::vector<std::string>
-CertificateStore::pinCertificate(std::shared_ptr<crypto::Certificate> cert,
-                                 bool local)
+CertificateStore::pinCertificate(std::shared_ptr<crypto::Certificate> cert, bool local)
 {
     bool sig {false};
     std::vector<std::string> ids {};
@@ -258,12 +272,20 @@ CertificateStore::pinCertificate(std::shared_ptr<crypto::Certificate> cert,
             auto id = c->getId().toString();
             decltype(certs_)::iterator it;
             std::tie(it, inserted) = certs_.emplace(id, c);
+            if (not inserted)
+                it->second = c;
+            if (local) {
+                for (const auto& crl : c->getRevocationLists())
+                    pinRevocationList(id, *crl);
+            }
             ids.emplace_back(id);
             c = c->issuer;
             sig |= inserted;
         }
-        if (sig and local)
-            fileutils::saveFile(certPath_+DIR_SEPARATOR_CH+ids.front(), cert->getPacked());
+        if (local) {
+            if (sig)
+                fileutils::saveFile(certPath_+DIR_SEPARATOR_CH+ids.front(), cert->getPacked());
+        }
     }
     for (const auto& id : ids)
         emitSignal<DRing::ConfigurationSignal::CertificatePinned>(id);
@@ -311,6 +333,31 @@ CertificateStore::getTrustedCertificates() const
     return crts;
 }
 
+void
+CertificateStore::pinRevocationList(const std::string& id, const std::shared_ptr<dht::crypto::RevocationList>& crl)
+{
+    try {
+        if (auto c = getCertificate(id))
+            c->addRevocationList(crl);
+        pinRevocationList(id, *crl);
+    } catch (...) {
+        RING_WARN("Can't add revocation list");
+    }
+}
+
+void
+CertificateStore::pinRevocationList(const std::string& id, const dht::crypto::RevocationList& crl)
+{
+    auto v = crl.getNumber();
+    std::stringstream ss;
+    ss << std::hex;
+    for (const auto& b : v)
+        ss << (unsigned)b;
+
+    fileutils::check_dir((crlPath_+DIR_SEPARATOR_CH+id).c_str());
+    fileutils::saveFile(crlPath_+DIR_SEPARATOR_CH+id+DIR_SEPARATOR_CH+ss.str(), crl.getPacked());
+}
+
 TrustStore::PermissionStatus
 TrustStore::statusFromStr(const char* str)
 {
@@ -367,6 +414,15 @@ TrustStore::~TrustStore()
     gnutls_x509_trust_list_deinit(allowed_, false);
 }
 
+bool
+TrustStore::addRevocationList(dht::crypto::RevocationList&& crl)
+{
+    auto packed = crl.getPacked();
+    revokedList_.emplace_back(std::forward<dht::crypto::RevocationList>(crl));
+    auto crlp = crl.get();
+    return gnutls_x509_trust_list_add_crls(allowed_, &crlp, 1, GNUTLS_TL_VERIFY_CRL, 0) > 0;
+}
+
 bool
 TrustStore::setCertificateStatus(const std::string& cert_id,
                                  const TrustStore::PermissionStatus status)
@@ -510,6 +566,7 @@ TrustStore::getTrustedCertificates() const
 bool
 TrustStore::matchTrustStore(std::vector<gnutls_x509_crt_t>&& crts, gnutls_x509_trust_list_st* store)
 {
+    RING_ERR("TrustStore::matchTrustStore: %lu", crts.size());
     unsigned result = 0;
 
 #if GNUTLS_VERSION_NUMBER > 0x030308
@@ -547,6 +604,17 @@ getChain(const crypto::Certificate& crt)
     return crts;
 }
 
+std::vector<gnutls_x509_crl_t>
+getRevocationList(const crypto::Certificate& crt)
+{
+    std::vector<gnutls_x509_crl_t> crls_ret;
+    const auto& crls = crt.getRevocationLists();
+    crls_ret.reserve(crls.size());
+    for (const auto& crl : crls)
+        crls_ret.emplace_back(crl->get());
+    return crls_ret;
+}
+
 void
 TrustStore::updateKnownCerts()
 {
@@ -567,8 +635,13 @@ TrustStore::setStoreCertStatus(const crypto::Certificate& crt, TrustStore::Permi
     if (not crt.isCA())
         return;
 
-    if (status == PermissionStatus::ALLOWED)
+    if (status == PermissionStatus::ALLOWED) {
         gnutls_x509_trust_list_add_cas(allowed_, &crt.cert, 1, 0);
+        auto crls = getRevocationList(crt);
+        if (not crls.empty())
+            if (gnutls_x509_trust_list_add_crls(allowed_, crls.data(), crls.size(), GNUTLS_TL_VERIFY_CRL, 0) == 0)
+                RING_WARN("No CRLs where added");
+    }
     else
         gnutls_x509_trust_list_remove_cas(allowed_, &crt.cert, 1);
 
diff --git a/src/security/certstore.h b/src/security/certstore.h
index 2a62ae68ecf68cc325774331826a88067c415421..e8be5ca0c4a21413391ce2e0a964211fc1bc8b02 100644
--- a/src/security/certstore.h
+++ b/src/security/certstore.h
@@ -74,12 +74,21 @@ public:
     bool setTrustedCertificate(const std::string& id, TrustStatus status);
     std::vector<gnutls_x509_crt_t> getTrustedCertificates() const;
 
+    void pinRevocationList(const std::string& id, const std::shared_ptr<dht::crypto::RevocationList>& crl);
+    void pinRevocationList(const std::string& id, dht::crypto::RevocationList&& crl) {
+        pinRevocationList(id, std::make_shared<dht::crypto::RevocationList>(std::forward<dht::crypto::RevocationList>(crl)));
+    }
+
+    void loadRevocations(crypto::Certificate& crt);
+
 private:
     NON_COPYABLE(CertificateStore);
 
-    unsigned loadLocalCertificates(const std::string& path);
+    unsigned loadLocalCertificates();
+    void pinRevocationList(const std::string& id, const dht::crypto::RevocationList& crl);
 
     const std::string certPath_;
+    const std::string crlPath_;
 
     mutable std::mutex lock_;
     std::map<std::string, std::shared_ptr<crypto::Certificate>> certs_;
@@ -111,6 +120,8 @@ public:
     static PermissionStatus statusFromStr(const char* str);
     static const char* statusToStr(PermissionStatus s);
 
+    bool addRevocationList(dht::crypto::RevocationList&& crl);
+
     bool setCertificateStatus(const std::string& cert_id, const PermissionStatus status);
     bool setCertificateStatus(const std::shared_ptr<crypto::Certificate>& cert, PermissionStatus status, bool local = true);
 
@@ -142,9 +153,11 @@ private:
     // unknown certificates with known status
     std::map<std::string, Status> unknownCertStatus_;
     std::map<std::string, std::pair<std::shared_ptr<crypto::Certificate>, Status>> certStatus_;
+    std::vector<dht::crypto::RevocationList> revokedList_;
     gnutls_x509_trust_list_st* allowed_;
 };
 
 std::vector<gnutls_x509_crt_t> getChain(const crypto::Certificate& crt);
+std::vector<gnutls_x509_crl_t> getRevocationList(const crypto::Certificate& crt);
 
 }} // namespace ring::tls