diff --git a/src/call.cpp b/src/call.cpp
index 03541aebdf24244cd9ea4e052e8aa940275e1783..cf89a3c289a457c5b2c41a94d4ca8371d8d0f651 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -332,7 +332,7 @@ Call* CallPrivate::buildExistingCall(const QString& callId)
 
    //Load the certificate if it's now available
    if (!call->certificate() && !details[DRing::Call::Details::TLS_PEER_CERT].isEmpty()) {
-      call->d_ptr->m_pCertificate = CertificateModel::instance()->getCertificateFromContent(details[DRing::Call::Details::TLS_PEER_CERT].toLatin1());
+      call->d_ptr->m_pCertificate = CertificateModel::instance()->getCertificateFromContent(details[DRing::Call::Details::TLS_PEER_CERT].toLatin1(),call->account());
    }
 
    return call;
@@ -370,7 +370,7 @@ Call* CallPrivate::buildIncomingCall(const QString& callId)
 
    //Load the certificate if it's now available
    if (!call->certificate() && !details[DRing::Call::Details::TLS_PEER_CERT].isEmpty()) {
-      call->d_ptr->m_pCertificate = CertificateModel::instance()->getCertificateFromContent(details[DRing::Call::Details::TLS_PEER_CERT].toLatin1());
+      call->d_ptr->m_pCertificate = CertificateModel::instance()->getCertificateFromContent(details[DRing::Call::Details::TLS_PEER_CERT].toLatin1(),call->account());
    }
 
    return call;
@@ -397,7 +397,7 @@ Call* CallPrivate::buildRingingCall(const QString & callId)
 
    //Load the certificate if it's now available
    if (!call->certificate() && !details[DRing::Call::Details::TLS_PEER_CERT].isEmpty()) {
-      call->d_ptr->m_pCertificate = CertificateModel::instance()->getCertificateFromContent(details[DRing::Call::Details::TLS_PEER_CERT].toLatin1());
+      call->d_ptr->m_pCertificate = CertificateModel::instance()->getCertificateFromContent(details[DRing::Call::Details::TLS_PEER_CERT].toLatin1(),call->account());
    }
 
    return call;
@@ -475,6 +475,11 @@ Call* Call::buildHistoryCall(const QMap<QString,QString>& hc)
       connect(call->peerContactMethod(),SIGNAL(rebased(ContactMethod*)),call->d_ptr,SLOT(updated()));
    }
 
+   //Check the certificate
+   if (!hc[Call::HistoryMapFields::CERT_PATH].isEmpty()) {
+      call->d_ptr->m_pCertificate = CertificateModel::instance()->getCertificate(QUrl(hc[Call::HistoryMapFields::CERT_PATH]),acc);
+   }
+
    return call;
 }
 
@@ -937,7 +942,7 @@ Call::State CallPrivate::stateChanged(const QString& newStateName)
 
       //Load the certificate if it's now available
       if (!q_ptr->certificate() && !details[DRing::Call::Details::TLS_PEER_CERT].isEmpty()) {
-         m_pCertificate = CertificateModel::instance()->getCertificateFromContent(details[DRing::Call::Details::TLS_PEER_CERT].toLatin1());
+         m_pCertificate = CertificateModel::instance()->getCertificateFromContent(details[DRing::Call::Details::TLS_PEER_CERT].toLatin1(),q_ptr->account());
       }
 
       try {
diff --git a/src/certificate.h b/src/certificate.h
index d29ec45c2a6ca65ca7614869f5cf9868a652a93c..d812316e248b3df4ae8d1365ba84493a6693733b 100644
--- a/src/certificate.h
+++ b/src/certificate.h
@@ -179,10 +179,10 @@ public:
    QVariant detailResult(Certificate::Details detail) const;
    QAbstractItemModel* model() const;
 
-   QString getName        (Certificate::Checks   check  );
-   QString getName        (Certificate::Details details );
-   QString getDescription (Certificate::Checks   check  );
-   QString getDescription (Certificate::Details details );
+   static QString getName        (Certificate::Checks   check  );
+   static QString getName        (Certificate::Details details );
+   static QString getDescription (Certificate::Checks   check  );
+   static QString getDescription (Certificate::Details details );
 
    //Checks
    CheckValues hasPrivateKey                       () const;
diff --git a/src/certificatemodel.cpp b/src/certificatemodel.cpp
index a17f308074598eaef4334a9fa91918c8b71aa8a6..d6ebf08cf75d4ec154888956fd89766894eb8c9a 100644
--- a/src/certificatemodel.cpp
+++ b/src/certificatemodel.cpp
@@ -31,6 +31,7 @@
 
 //Ring
 #include "certificate.h"
+#include "account.h"
 #include "delegates/certificateserializationdelegate.h"
 
 struct CertificateNode {
@@ -39,16 +40,17 @@ struct CertificateNode {
    void setStrings(const QString& col1, const QVariant& col2, const QString& tooltip);
 
    //Attributes
-   QVector<CertificateNode*>  m_lChildren   ;
-   CertificateNode*           m_pParent     ;
-   Certificate*               m_pCertificate;
-   CertificateModel::NodeType m_Level       ;
-   int                        m_Index       ;
-   QString                    m_Col1        ;
-   QVariant                   m_Col2        ;
-   QString                    m_ToolTip     ;
-   std::function<void()>      m_fLoader     ;
-   bool                       m_IsLoaded    ;
+   QVector<CertificateNode*>  m_lChildren      ;
+   CertificateNode*           m_pParent        ;
+   Certificate*               m_pCertificate   ;
+   CertificateModel::NodeType m_Level          ;
+   int                        m_Index          ;
+   QString                    m_Col1           ;
+   QVariant                   m_Col2           ;
+   QString                    m_ToolTip        ;
+   std::function<void()>      m_fLoader        ;
+   bool                       m_IsLoaded       ;
+   QHash<Account*,CertificateNode*> m_hSiblings;
 };
 
 class BackgroundLoader : public QThread
@@ -96,15 +98,19 @@ public:
 
    //Helper
    CertificateNode* defaultCategory();
+   CertificateNode* createCategory(const QString& name, const QString& col2, const QString& tooltip);
+   CertificateNode* createCategory(Account* a);
    CertificateNode* addToTree(Certificate* cert, CertificateNode* category = nullptr);
+   CertificateNode* addToTree(Certificate* cert, Account* a);
    QModelIndex      createIndex(int r ,int c , void* p);
    QAbstractItemModel* getModelCommon(CertificateNode* node);
 
    //Attributes
-   QVector<CertificateNode*>   m_lTopLevelNodes  ;
-   QHash<QString,Certificate*> m_hCertificates   ;
-   CertificateNode*            m_pDefaultCategory;
-   QMutex                      m_CertLoader      ;
+   QVector<CertificateNode*>        m_lTopLevelNodes   ;
+   QHash<Account*,CertificateNode*> m_hAccToCat        ;
+   QHash<QString,Certificate*>      m_hCertificates    ;
+   CertificateNode*                 m_pDefaultCategory ;
+   QMutex                           m_CertLoader       ;
    QHash<const Certificate*,CertificateNode*> m_hNodes ;
 
    //Singleton
@@ -151,6 +157,17 @@ CertificateModel::CertificateModel(QObject* parent) : QAbstractItemModel(parent)
  d_ptr(new CertificateModelPrivate(this))
 {
    setObjectName("CertificateModel");
+
+   //Load the stored certificates
+   BackgroundLoader* loader = new BackgroundLoader();
+   connect(loader, SIGNAL(finished()), loader, SLOT(deleteLater()));
+
+   /*if (!loader->isFinished())
+      connect(loader,&BackgroundLoader::finished,[loader](){
+         delete loader;
+      });*/
+
+   loader->start();
 }
 
 CertificateModel::~CertificateModel()
@@ -168,11 +185,11 @@ CertificateModel* CertificateModel::instance()
 void BackgroundLoader::run()
 {
    if (m_lIdList.isEmpty()) //WARNING potential race
-      QList<QByteArray> m_lIdList = CertificateSerializationDelegate::instance()->listCertificates();
+      m_lIdList = CertificateSerializationDelegate::instance()->listCertificates();
 
    QMutexLocker(&this->m_LoaderMutex);
    for(const QByteArray& id : m_lIdList) {
-      CertificateModel::instance()->getCertificateFromContent(loadCert(id),false);
+      CertificateModel::instance()->getCertificateFromContent(loadCert(id),nullptr,false);
    }
    exit(0);
 }
@@ -180,11 +197,23 @@ void BackgroundLoader::run()
 QHash<int,QByteArray> CertificateModel::roleNames() const
 {
    static QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
-   /*static bool initRoles = false;
+   static bool initRoles = false;
    if (!initRoles) {
       initRoles = true;
-
-   }*/
+      roles[static_cast<int>(Role::NodeType)] = "nodeType";
+
+      //Add all the details, this isn't safe because of tr(), but good enough for debugging
+      for (const Certificate::Details d :  EnumIterator<Certificate::Details>()) {
+         QString name = Certificate::getName(d).toLatin1();
+         while (name.indexOf(' ') != -1) {
+            const int idx = name.indexOf(' ')  ;
+            name          = name.remove(idx,1) ;
+            name[idx]     = name[idx].toUpper();
+            name[0  ]     = name[0].toLower  ();
+         }
+         roles[static_cast<int>(Role::DetailRoleBase)+static_cast<int>(d)] = name.toLatin1();
+      }
+   }
    return roles;
 }
 
@@ -195,17 +224,24 @@ void CertificateNode::setStrings(const QString& col1, const QVariant& col2, cons
    m_ToolTip = tooltip;
 }
 
-CertificateNode* CertificateModelPrivate::defaultCategory()
+CertificateNode* CertificateModelPrivate::createCategory(const QString& name, const QString& col2, const QString& tooltip )
 {
-   if (!m_pDefaultCategory) {
-      const int idx = m_hCertificates.size();
+   const int idx = m_hCertificates.size();
 
-      m_pDefaultCategory = new CertificateNode(idx, CertificateModel::NodeType::CATEGORY, nullptr, nullptr);
-      m_pDefaultCategory->setStrings(QObject::tr("Default"),QObject::tr("Certificate not associated with a group"),QString());
+   CertificateNode* n = new CertificateNode(idx, CertificateModel::NodeType::CATEGORY, nullptr, nullptr);
+   n->setStrings(name,col2,tooltip);
 
-      q_ptr->beginInsertRows(QModelIndex(), idx, idx);
-      m_lTopLevelNodes << m_pDefaultCategory;
-      q_ptr->endInsertRows();
+   q_ptr->beginInsertRows(QModelIndex(), idx, idx);
+   m_lTopLevelNodes << n;
+   q_ptr->endInsertRows();
+
+   return n;
+}
+
+CertificateNode* CertificateModelPrivate::defaultCategory()
+{
+   if (!m_pDefaultCategory) {
+      m_pDefaultCategory = createCategory(QObject::tr("Default"),QObject::tr("Certificate not associated with a group"),QString());
    }
 
    return m_pDefaultCategory;
@@ -216,6 +252,29 @@ QModelIndex CertificateModelPrivate::createIndex(int r ,int c , void* p)
    return q_ptr->createIndex(r,c,p);
 }
 
+CertificateNode* CertificateModelPrivate::createCategory(Account* a)
+{
+   CertificateNode* cat = m_hAccToCat[a];
+
+   if (!cat) {
+      cat = createCategory(a->alias(),QString(),QString());
+      m_hAccToCat[a] = cat;
+   }
+
+   return cat;
+}
+
+//For convenience
+CertificateNode* CertificateModelPrivate::addToTree(Certificate* cert, Account* a)
+{
+   if (!a)
+      return addToTree(cert);
+
+   CertificateNode* cat = createCategory(a);
+
+   return addToTree(cert,cat);
+}
+
 CertificateNode* CertificateModelPrivate::addToTree(Certificate* cert, CertificateNode* category)
 {
    QMutexLocker(&this->m_CertLoader);
@@ -292,15 +351,25 @@ QVariant CertificateModel::data( const QModelIndex& index, int role) const
    if (!index.isValid())
       return QVariant();
    const CertificateNode* node = static_cast<CertificateNode*>(index.internalPointer());
-      switch(role) {
-         case Qt::DisplayRole:
-         case Qt::EditRole:
-            return index.column()?node->m_Col2:node->m_Col1;
-         case Qt::ToolTipRole:
-            return node->m_ToolTip;
-         case static_cast<int>(Role::NodeType):
-            return QVariant::fromValue(node->m_Level);
-      };
+
+   switch(role) {
+      case Qt::DisplayRole:
+      case Qt::EditRole:
+         return index.column()?node->m_Col2:node->m_Col1;
+      case Qt::ToolTipRole:
+         return node->m_ToolTip;
+      case static_cast<int>(Role::NodeType):
+         return QVariant::fromValue(node->m_Level);
+   };
+
+   //Add the details as roles for certificates
+   if (node && node->m_Level == NodeType::CERTIFICATE && role >= static_cast<int>(Role::DetailRoleBase) && role < static_cast<int>(Role::DetailRoleBase)+enum_class_size<Certificate::Details>()) {
+      Certificate* cert = node->m_pCertificate;
+      if (cert) {
+         return cert->detailResult(static_cast<Certificate::Details>(role - static_cast<int>(Role::DetailRoleBase)));
+      }
+   }
+
    return QVariant();
 }
 
@@ -360,6 +429,34 @@ QVariant CertificateModel::headerData( int section, Qt::Orientation orientation,
    return QVariant();
 }
 
+Certificate* CertificateModel::getCertificate(const QUrl& path, Account* a)
+{
+   if (!a)
+      return getCertificate(path,Certificate::Type::CALL);
+
+   CertificateNode* cat  = d_ptr->createCategory(a);
+
+   Certificate* cert = d_ptr->m_hCertificates[path.path()];
+
+   if (!cert) {
+      cert = new Certificate(path);
+      d_ptr->m_hCertificates[path.toString().toLatin1()] = cert;
+
+      //Add it to the model
+      d_ptr->addToTree(cert,a);
+   }
+
+   CertificateNode* node = d_ptr->m_hNodes[cert];
+
+   if (node) {
+      if (node->m_pParent != cat) {
+         CertificateNode* node2 = d_ptr->addToTree(cert,cat);
+         node->m_hSiblings[a] = node2;
+      }
+   }
+   return cert;
+}
+
 Certificate* CertificateModel::getCertificate(const QUrl& path, Certificate::Type type)
 {
    Q_UNUSED(type)
@@ -379,7 +476,7 @@ Certificate* CertificateModel::getCertificate(const QUrl& path, Certificate::Typ
    return cert;
 }
 
-Certificate* CertificateModel::getCertificateFromContent(const QByteArray& rawContent, bool save)
+Certificate* CertificateModel::getCertificateFromContent(const QByteArray& rawContent, Account* a, bool save)
 {
    QCryptographicHash hash(QCryptographicHash::Sha1);
 
@@ -392,10 +489,11 @@ Certificate* CertificateModel::getCertificateFromContent(const QByteArray& rawCo
       cert = new Certificate(rawContent);
       d_ptr->m_hCertificates[id] = cert;
 
-      d_ptr->addToTree(cert);
+      d_ptr->addToTree(cert,a);
 
       if (save) {
-         CertificateSerializationDelegate::instance()->saveCertificate(id,rawContent);
+         const QUrl path = CertificateSerializationDelegate::instance()->saveCertificate(id,rawContent);
+         cert->setPath(path);
       }
    }
 
diff --git a/src/certificatemodel.h b/src/certificatemodel.h
index 737521b7201156d163e3131f89a24eade3177a58..a751c36663ce4a0e99b8a98bb1fe9c925f11b5e3 100644
--- a/src/certificatemodel.h
+++ b/src/certificatemodel.h
@@ -22,6 +22,8 @@
 
 #include "certificate.h"
 
+class Account;
+
 class CertificateModelPrivate;
 
 class LIB_EXPORT CertificateModel : public QAbstractItemModel
@@ -32,7 +34,8 @@ public:
    friend class CertificateNode;
 
    enum class Role {
-      NodeType = 100,
+      NodeType       = 100,
+      DetailRoleBase = 1000,
    };
 
    enum class Columns {
@@ -64,11 +67,12 @@ public:
 
    //Getters
    QAbstractItemModel* model(const Certificate* cert) const;
-   QAbstractItemModel* model(const QModelIndex& idx) const;
+   QAbstractItemModel* model(const QModelIndex& idx ) const;
 
    //Mutator
    Certificate* getCertificate(const QUrl& path, Certificate::Type type = Certificate::Type::NONE);
-   Certificate* getCertificateFromContent(const QByteArray& rawContent, bool save = true);
+   Certificate* getCertificate(const QUrl& path, Account* a);
+   Certificate* getCertificateFromContent(const QByteArray& rawContent, Account* a = nullptr, bool save = true);
 
    //Singleton
    static CertificateModel* instance();
diff --git a/src/useractionmodel.cpp b/src/useractionmodel.cpp
index f8bcbf7e674549cd44af124f1bdb04bac85a9aa7..537ea8ab461a536cd97b3f608a256cbd2a9fa4e9 100644
--- a/src/useractionmodel.cpp
+++ b/src/useractionmodel.cpp
@@ -110,7 +110,7 @@ const TypedStateMachine< TypedStateMachine< bool , Call::State > , UserActionMod
  /*MUTE_VIDEO      */ {{ false  , true ,  true ,  false, false, false, false,   false,     false,    false, false,  false,       false,           false}},
  /*SERVER_TRANSFER */ {{ false  , false,  true ,  false, true , false, false,   false,     false,    false, false,  false,       false,           false}},
  /*RECORD          */ {{ false  , true ,  true ,  false, true , false, false,   true ,     true ,    false, false,  true ,       true ,           false}},
- /*HANGUP          */ {{ true   , true ,  true ,  true , true , true , true ,   true ,     true ,    false, true ,  true ,       true ,           false}},
+ /*HANGUP          */ {{ true   , true ,  true ,  true , true , true , true ,   true ,     true ,    false, true ,  true ,       true ,           true }},
 
  /*JOIN            */ {{ false  , true ,  true ,  false, true , false, false,   true ,     true ,    false, false,  true ,       true ,           false }},
 }};