diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index bdf69c8049b9f7993504342f8140dcc1aa6adc60..0c69239c7cb05f1d7ea54301e31a0d47b0e54592 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -75,6 +75,8 @@ set( qtsflphone_LIB_SRCS
   audiosettingsmodel.cpp
   ringtonemodel.cpp
   lastusednumbermodel.cpp
+  securityvalidationmodel.cpp
+  certificate.cpp
 
   #Communication
   dbus/configurationmanager.cpp
@@ -126,6 +128,8 @@ set( qtsflphone_LIB_HDRS
   audiosettingsmodel.h
   ringtonemodel.h
   lastusednumbermodel.h
+  securityvalidationmodel.h
+  certificate.h
 )
 
 set( qtsflphone_extra_LIB_HDRS
diff --git a/src/account.cpp b/src/account.cpp
index 14ad4f36cdcbf82f5355317abaed064e83ff85f4..4ec4916c98ef1ed3dad8905240d2a4b86feb202a 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -33,6 +33,7 @@
 #include "dbus/callmanager.h"
 #include "dbus/videomanager.h"
 #include "visitors/accountlistcolorvisitor.h"
+#include "certificate.h"
 #include "accountlistmodel.h"
 #include "credentialmodel.h"
 #include "audiocodecmodel.h"
@@ -41,6 +42,7 @@
 #include "phonenumber.h"
 #include "phonedirectorymodel.h"
 #include "presencestatusmodel.h"
+#include "securityvalidationmodel.h"
 #define TO_BOOL ?"true":"false"
 #define IS_TRUE == "true"
 
@@ -58,7 +60,7 @@ const account_function Account::stateMachineActionsOnState[6][7] = {
 ///Constructors
 Account::Account():QObject(AccountListModel::instance()),m_pCredentials(nullptr),m_pAudioCodecs(nullptr),m_CurrentState(AccountEditState::READY),
 m_pVideoCodecs(nullptr),m_LastErrorCode(-1),m_VoiceMailCount(0),m_pRingToneModel(nullptr),m_pAccountNumber(nullptr),
-m_pKeyExchangeModel(nullptr)
+m_pKeyExchangeModel(nullptr),m_pSecurityValidationModel(nullptr),m_pCaCert(nullptr),m_pTlsCert(nullptr),m_pPrivateKey(nullptr)
 {
 }
 
@@ -312,6 +314,14 @@ KeyExchangeModel* Account::keyExchangeModel() const
    return m_pKeyExchangeModel;
 }
 
+SecurityValidationModel* Account::securityValidationModel() const
+{
+   if (!m_pSecurityValidationModel) {
+      const_cast<Account*>(this)->m_pSecurityValidationModel = new SecurityValidationModel(const_cast<Account*>(this));
+   }
+   return m_pSecurityValidationModel;
+}
+
 void Account::setAlias(const QString& detail)
 {
    bool accChanged = detail != alias();
@@ -371,7 +381,7 @@ QString Account::password() const
 
 ///
 bool Account::isDisplaySasOnce() const
-{ 
+{
    return accountDetail(Account::MapField::ZRTP::DISPLAY_SAS_ONCE) IS_TRUE;
 }
 
@@ -454,21 +464,30 @@ int Account::tlsListenerPort() const
 }
 
 ///Return the account TLS certificate authority list file
-QString Account::tlsCaListFile() const
+Certificate* Account::tlsCaListCertificate() const
 {
-   return accountDetail(Account::MapField::TLS::CA_LIST_FILE);
+   if (!m_pCaCert)
+      const_cast<Account*>(this)->m_pCaCert = new Certificate(Certificate::Type::AUTHORITY,this);
+   const_cast<Account*>(this)->m_pCaCert->setPath(accountDetail(Account::MapField::TLS::CA_LIST_FILE));
+   return m_pCaCert;
 }
 
 ///Return the account TLS certificate
-QString Account::tlsCertificateFile() const
+Certificate* Account::tlsCertificate() const
 {
-   return accountDetail(Account::MapField::TLS::CERTIFICATE_FILE);
+   if (!m_pTlsCert)
+      const_cast<Account*>(this)->m_pTlsCert = new Certificate(Certificate::Type::USER,this);
+   const_cast<Account*>(this)->m_pTlsCert->setPath(accountDetail(Account::MapField::TLS::CERTIFICATE_FILE));
+   return m_pTlsCert;
 }
 
 ///Return the account private key
-QString Account::tlsPrivateKeyFile() const
+Certificate* Account::tlsPrivateKeyCertificate() const
 {
-   return accountDetail(Account::MapField::TLS::PRIVATE_KEY_FILE);
+   if (!m_pPrivateKey)
+      const_cast<Account*>(this)->m_pPrivateKey = new Certificate(Certificate::Type::PRIVATE_KEY,this);
+   const_cast<Account*>(this)->m_pPrivateKey->setPath(accountDetail(Account::MapField::TLS::PRIVATE_KEY_FILE));
+   return m_pPrivateKey;
 }
 
 ///Return the account cipher
@@ -643,12 +662,12 @@ QVariant Account::roleData(int role) const
 //          return accountPassword();
       case Account::Role::TlsPassword:
          return tlsPassword();
-      case Account::Role::TlsCaListFile:
-         return tlsCaListFile();
-      case Account::Role::TlsCertificateFile:
-         return tlsCertificateFile();
-      case Account::Role::TlsPrivateKeyFile:
-         return tlsPrivateKeyFile();
+      case Account::Role::TlsCaListCertificate:
+         return tlsCaListCertificate()->path().toLocalFile();
+      case Account::Role::TlsCertificate:
+         return tlsCertificate()->path().toLocalFile();
+      case Account::Role::TlsPrivateKeyCertificate:
+         return tlsPrivateKeyCertificate()->path().toLocalFile();
       case Account::Role::TlsCiphers:
          return tlsCiphers();
       case Account::Role::TlsServerName:
@@ -835,21 +854,21 @@ void Account::setTlsPassword(const QString& detail)
 }
 
 ///Set the certificate authority list file
-void Account::setTlsCaListFile(const QString& detail)
+void Account::setTlsCaListCertificate(Certificate* cert)
 {
-   setAccountDetail(Account::MapField::TLS::CA_LIST_FILE, detail);
+   setAccountDetail(Account::MapField::TLS::CA_LIST_FILE, cert?cert->path().toLocalFile():QString());
 }
 
 ///Set the certificate
-void Account::setTlsCertificateFile(const QString& detail)
+void Account::setTlsCertificate(Certificate* cert)
 {
-   setAccountDetail(Account::MapField::TLS::CERTIFICATE_FILE, detail);
+   setAccountDetail(Account::MapField::TLS::CERTIFICATE_FILE, cert?cert->path().toLocalFile():QString());
 }
 
 ///Set the private key
-void Account::setTlsPrivateKeyFile(const QString& detail)
+void Account::setTlsPrivateKeyCertificate(Certificate* cert)
 {
-   setAccountDetail(Account::MapField::TLS::PRIVATE_KEY_FILE, detail);
+   setAccountDetail(Account::MapField::TLS::PRIVATE_KEY_FILE, cert?cert->path().toLocalFile():QString());
 }
 
 ///Set the TLS cipher
@@ -1053,92 +1072,142 @@ void Account::setRoleData(int role, const QVariant& value)
    switch(role) {
       case Account::Role::Alias:
          setAlias(value.toString());
+         break;
       case Account::Role::Proto: {
          const int proto = value.toInt();
          setProtocol((proto>=0&&proto<=1)?static_cast<Account::Protocol>(proto):Account::Protocol::SIP);
+         break;
       }
       case Account::Role::Hostname:
          setHostname(value.toString());
+         break;
       case Account::Role::Username:
          setUsername(value.toString());
+         break;
       case Account::Role::Mailbox:
          setMailbox(value.toString());
+         break;
       case Account::Role::Proxy:
          setProxy(value.toString());
+         break;
 //       case Password:
 //          accountPassword();
       case Account::Role::TlsPassword:
          setTlsPassword(value.toString());
-      case Account::Role::TlsCaListFile:
-         setTlsCaListFile(value.toString());
-      case Account::Role::TlsCertificateFile:
-         setTlsCertificateFile(value.toString());
-      case Account::Role::TlsPrivateKeyFile:
-         setTlsPrivateKeyFile(value.toString());
+         break;
+      case Account::Role::TlsCaListCertificate: {
+         const QString path = value.toString();
+         if ((tlsCaListCertificate() && tlsCaListCertificate()->path() != QUrl(path)) || !tlsCaListCertificate()) {
+            tlsCaListCertificate()->setPath(path);
+         }
+         break;
+      }
+      case Account::Role::TlsCertificate: {
+         const QString path = value.toString();
+         if ((tlsCertificate() && tlsCertificate()->path() != QUrl(path)) || !tlsCertificate())
+            tlsCertificate()->setPath(path);
+      }
+         break;
+      case Account::Role::TlsPrivateKeyCertificate: {
+         const QString path = value.toString();
+         if ((tlsPrivateKeyCertificate() && tlsPrivateKeyCertificate()->path() != QUrl(path)) || !tlsPrivateKeyCertificate())
+            tlsPrivateKeyCertificate()->setPath(path);
+      }
+         break;
       case Account::Role::TlsCiphers:
          setTlsCiphers(value.toString());
+         break;
       case Account::Role::TlsServerName:
          setTlsServerName(value.toString());
+         break;
       case Account::Role::SipStunServer:
          setSipStunServer(value.toString());
+         break;
       case Account::Role::PublishedAddress:
          setPublishedAddress(value.toString());
+         break;
       case Account::Role::LocalInterface:
          setLocalInterface(value.toString());
+         break;
       case Account::Role::RingtonePath:
          setRingtonePath(value.toString());
+         break;
       case Account::Role::TlsMethod: {
          const int method = value.toInt();
          setTlsMethod(method<=TlsMethodModel::instance()->rowCount()?static_cast<TlsMethodModel::Type>(method):TlsMethodModel::Type::DEFAULT);
+         break;
       }
       case Account::Role::KeyExchange: {
          const int method = value.toInt();
          setKeyExchange(method<=keyExchangeModel()->rowCount()?static_cast<KeyExchangeModel::Type>(method):KeyExchangeModel::Type::NONE);
+         break;
       }
       case Account::Role::RegistrationExpire:
          setRegistrationExpire(value.toInt());
+         break;
       case Account::Role::TlsNegotiationTimeoutSec:
          setTlsNegotiationTimeoutSec(value.toInt());
+         break;
       case Account::Role::TlsNegotiationTimeoutMsec:
          setTlsNegotiationTimeoutMsec(value.toInt());
+         break;
       case Account::Role::LocalPort:
          setLocalPort(value.toInt());
+         break;
       case Account::Role::TlsListenerPort:
          setTlsListenerPort(value.toInt());
+         break;
       case Account::Role::PublishedPort:
          setPublishedPort(value.toInt());
+         break;
       case Account::Role::Enabled:
          setEnabled(value.toBool());
+         break;
       case Account::Role::AutoAnswer:
          setAutoAnswer(value.toBool());
+         break;
       case Account::Role::TlsVerifyServer:
          setTlsVerifyServer(value.toBool());
+         break;
       case Account::Role::TlsVerifyClient:
          setTlsVerifyClient(value.toBool());
+         break;
       case Account::Role::TlsRequireClientCertificate:
          setTlsRequireClientCertificate(value.toBool());
+         break;
       case Account::Role::TlsEnable:
          setTlsEnable(value.toBool());
+         break;
       case Account::Role::DisplaySasOnce:
          setDisplaySasOnce(value.toBool());
+         break;
       case Account::Role::SrtpRtpFallback:
          setSrtpRtpFallback(value.toBool());
+         break;
       case Account::Role::ZrtpDisplaySas:
          setZrtpDisplaySas(value.toBool());
+         break;
       case Account::Role::ZrtpNotSuppWarning:
          setZrtpNotSuppWarning(value.toBool());
+         break;
       case Account::Role::ZrtpHelloHash:
          setZrtpHelloHash(value.toBool());
+         break;
       case Account::Role::SipStunEnabled:
          setSipStunEnabled(value.toBool());
+         break;
       case Account::Role::PublishedSameAsLocal:
          setPublishedSameAsLocal(value.toBool());
+         break;
       case Account::Role::RingtoneEnabled:
          setRingtoneEnabled(value.toBool());
+         break;
       case Account::Role::dTMFType:
          setDTMFType((DtmfType)value.toInt());
+         break;
       case Account::Role::Id:
          setId(value.toString());
+         break;
    }
 }
 
diff --git a/src/account.h b/src/account.h
index e9a9de3a463f0140eb4181461f432ecd02697ae3..cf896c8135566f995c937858d90c173482487073 100644
--- a/src/account.h
+++ b/src/account.h
@@ -37,6 +37,8 @@ class AudioCodecModel;
 class VideoCodecModel;
 class RingToneModel  ;
 class PhoneNumber    ;
+class SecurityValidationModel;
+class Certificate    ;
 
 const QString& account_state_name(const QString& s);
 
@@ -66,9 +68,9 @@ class LIB_EXPORT Account : public QObject {
    Q_PROPERTY(QString        mailbox                      READ mailbox                       WRITE setMailbox                     )
    Q_PROPERTY(QString        proxy                        READ proxy                         WRITE setProxy                       )
    Q_PROPERTY(QString        tlsPassword                  READ tlsPassword                   WRITE setTlsPassword                 )
-   Q_PROPERTY(QString        tlsCaListFile                READ tlsCaListFile                 WRITE setTlsCaListFile               )
-   Q_PROPERTY(QString        tlsCertificateFile           READ tlsCertificateFile            WRITE setTlsCertificateFile          )
-   Q_PROPERTY(QString        tlsPrivateKeyFile            READ tlsPrivateKeyFile             WRITE setTlsPrivateKeyFile           )
+//    Q_PROPERTY(QString        tlsCaListFile                READ tlsCaListFile                 WRITE setTlsCaListFile               )
+//    Q_PROPERTY(QString        tlsCertificateFile           READ tlsCertificateFile            WRITE setTlsCertificateFile          )
+//    Q_PROPERTY(QString        tlsPrivateKeyFile            READ tlsPrivateKeyFile             WRITE setTlsPrivateKeyFile           )
    Q_PROPERTY(QString        tlsCiphers                   READ tlsCiphers                    WRITE setTlsCiphers                  )
    Q_PROPERTY(QString        tlsServerName                READ tlsServerName                 WRITE setTlsServerName               )
    Q_PROPERTY(QString        sipStunServer                READ sipStunServer                 WRITE setSipStunServer               )
@@ -159,9 +161,9 @@ class LIB_EXPORT Account : public QObject {
          Mailbox                     = 104,
          Proxy                       = 105,
          TlsPassword                 = 107,
-         TlsCaListFile               = 108,
-         TlsCertificateFile          = 109,
-         TlsPrivateKeyFile           = 110,
+         TlsCaListCertificate        = 108,
+         TlsCertificate              = 109,
+         TlsPrivateKeyCertificate    = 110,
          TlsCiphers                  = 111,
          TlsServerName               = 112,
          SipStunServer               = 113,
@@ -306,6 +308,7 @@ class LIB_EXPORT Account : public QObject {
       Q_INVOKABLE VideoCodecModel*  videoCodecModel () const;
       Q_INVOKABLE RingToneModel*    ringToneModel   () const;
       Q_INVOKABLE KeyExchangeModel* keyExchangeModel() const;
+      Q_INVOKABLE SecurityValidationModel* securityValidationModel() const;
 
       //Getters
       QString hostname                     () const;
@@ -329,9 +332,9 @@ class LIB_EXPORT Account : public QObject {
       int     publishedPort                () const;
       QString tlsPassword                  () const;
       int     tlsListenerPort              () const;
-      QString tlsCaListFile                () const;
-      QString tlsCertificateFile           () const;
-      QString tlsPrivateKeyFile            () const;
+      Certificate* tlsCaListCertificate    () const;
+      Certificate* tlsCertificate          () const;
+      Certificate* tlsPrivateKeyCertificate() const;
       QString tlsCiphers                   () const;
       QString tlsServerName                () const;
       int     tlsNegotiationTimeoutSec     () const;
@@ -369,9 +372,9 @@ class LIB_EXPORT Account : public QObject {
       void setProxy                         (const QString& detail );
       void setPassword                      (const QString& detail );
       void setTlsPassword                   (const QString& detail );
-      void setTlsCaListFile                 (const QString& detail );
-      void setTlsCertificateFile            (const QString& detail );
-      void setTlsPrivateKeyFile             (const QString& detail );
+      void setTlsCaListCertificate          (Certificate* cert     );
+      void setTlsCertificate                (Certificate* cert     );
+      void setTlsPrivateKeyCertificate      (Certificate* cert     );
       void setTlsCiphers                    (const QString& detail );
       void setTlsServerName                 (const QString& detail );
       void setSipStunServer                 (const QString& detail );
@@ -457,6 +460,7 @@ class LIB_EXPORT Account : public QObject {
       VideoCodecModel*  m_pVideoCodecs     ;
       RingToneModel*    m_pRingToneModel   ;
       KeyExchangeModel* m_pKeyExchangeModel;
+      SecurityValidationModel* m_pSecurityValidationModel;
       AccountEditState m_CurrentState;
       static const account_function stateMachineActionsOnState[6][7];
 
@@ -465,6 +469,9 @@ class LIB_EXPORT Account : public QObject {
       QString m_LastErrorMessage;
       int     m_LastErrorCode;
       int     m_VoiceMailCount;
+      Certificate* m_pCaCert;
+      Certificate* m_pTlsCert;
+      Certificate* m_pPrivateKey;
 
 
    Q_SIGNALS:
diff --git a/src/accountlistmodel.cpp b/src/accountlistmodel.cpp
index e55af067b69ece56bd68b5b481d07a7931ae3944..decb231addf3fd93c01b9f105d939263f12603f3 100644
--- a/src/accountlistmodel.cpp
+++ b/src/accountlistmodel.cpp
@@ -100,9 +100,9 @@ void AccountListModel::setupRoleName()
    roles.insert(Account::Role::Mailbox                  ,QByteArray("mailbox"                       ));
    roles.insert(Account::Role::Proxy                    ,QByteArray("proxy"                         ));
    roles.insert(Account::Role::TlsPassword              ,QByteArray("tlsPassword"                   ));
-   roles.insert(Account::Role::TlsCaListFile            ,QByteArray("tlsCaListFile"                 ));
-   roles.insert(Account::Role::TlsCertificateFile       ,QByteArray("tlsCertificateFile"            ));
-   roles.insert(Account::Role::TlsPrivateKeyFile        ,QByteArray("tlsPrivateKeyFile"             ));
+   roles.insert(Account::Role::TlsCaListCertificate     ,QByteArray("tlsCaListCertificate"          ));
+   roles.insert(Account::Role::TlsCertificate           ,QByteArray("tlsCertificate"                ));
+   roles.insert(Account::Role::TlsPrivateKeyCertificate ,QByteArray("tlsPrivateKeyCertificate"      ));
    roles.insert(Account::Role::TlsCiphers               ,QByteArray("tlsCiphers"                    ));
    roles.insert(Account::Role::TlsServerName            ,QByteArray("tlsServerName"                 ));
    roles.insert(Account::Role::SipStunServer            ,QByteArray("sipStunServer"                 ));
diff --git a/src/certificate.cpp b/src/certificate.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b40f76c3fb309265a7d2e5d38aa2cb47a950daae
--- /dev/null
+++ b/src/certificate.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+ *   Copyright (C) 2014 by Savoir-Faire Linux                               *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library is distributed in the hope that it will be useful,        *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#include "certificate.h"
+
+#include <QtCore/QFile>
+
+
+Certificate::Certificate(Certificate::Type type, const QObject* parent) : QObject(const_cast<QObject*>(parent)),m_Type(type)
+{
+   
+}
+
+bool Certificate::exist() const
+{
+   return QFile::exists(m_Path.toLocalFile());
+}
+
+QUrl Certificate::path() const
+{
+   return m_Path;
+}
+
+void Certificate::setPath(const QUrl& path)
+{
+   m_Path = path;
+}
+
+bool Certificate::isExpired() const
+{
+   return true; //TODO
+}
+
+bool Certificate::isSelfSigned() const
+{
+   return true; //TODO
+}
+
+bool Certificate::hasPrivateKey() const
+{
+   return false; //TODO
+}
+
+bool Certificate::hasProtectedPrivateKey() const
+{
+   return false; //TODO
+}
+
+bool Certificate::hasRightPermissions() const
+{
+   return false; //TODO
+}
+
+bool Certificate::hasRightFolderPermissions() const
+{
+   return false; //TODO
+}
+
+bool Certificate::isLocationSecure() const
+{
+   return false; //TODO
+}
+
+Certificate::Type Certificate::type() const
+{
+   return m_Type;
+}
diff --git a/src/certificate.h b/src/certificate.h
new file mode 100644
index 0000000000000000000000000000000000000000..005942648caaff7d75a50f13e7c52ce88d53beb7
--- /dev/null
+++ b/src/certificate.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+ *   Copyright (C) 2014 by Savoir-Faire Linux                               *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library is distributed in the hope that it will be useful,        *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#ifndef CERTIFICATE_H
+#define CERTIFICATE_H
+
+#include "typedefs.h"
+
+//Qt
+#include <QUrl>
+
+class LIB_EXPORT Certificate : public QObject {
+   Q_OBJECT
+public:
+
+   //Structures
+   enum class Type {
+      AUTHORITY  ,
+      USER       ,
+      PRIVATE_KEY,
+      NONE       ,
+   };
+
+   Certificate(Certificate::Type type ,const QObject* parent = nullptr);
+
+   //Getter
+   QUrl path() const;
+   Certificate::Type type() const;
+
+   //Setter
+   void setPath(const QUrl& path);
+
+   //Validation
+   bool exist                    () const;
+   bool isExpired                () const;
+   bool isSelfSigned             () const;
+   bool hasPrivateKey            () const;
+   bool hasProtectedPrivateKey   () const;
+   bool hasRightPermissions      () const;
+   bool hasRightFolderPermissions() const;
+   bool isLocationSecure         () const;
+
+private:
+   QUrl m_Path;
+   Certificate::Type m_Type;
+   //TODO
+};
+Q_DECLARE_METATYPE(Certificate*)
+
+#endif
\ No newline at end of file
diff --git a/src/securityvalidationmodel.cpp b/src/securityvalidationmodel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a16af6db33eee7f1a63edc2047e49fcb31cc9517
--- /dev/null
+++ b/src/securityvalidationmodel.cpp
@@ -0,0 +1,188 @@
+/****************************************************************************
+ *   Copyright (C) 2013-2014 by Savoir-Faire Linux                           *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library is distributed in the hope that it will be useful,        *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#include "securityvalidationmodel.h"
+#include "account.h"
+#include "visitors/pixmapmanipulationvisitor.h"
+
+const QString SecurityValidationModel::messages[static_cast<const int>(SecurityFlaw::COUNT)] = {
+   QObject::tr("Your communication negotation is secured, but not the media stream, please enable ZRTP or SDES"),
+   QObject::tr("TLS is disabled, the negotiation wont be encrypted. Your communication will be vulnerable to "
+   "snooping"),
+   QObject::tr("Your certificate is expired, please contact your system administrator."),
+   QObject::tr("Your certificate is self signed. This break the chain of trust."),
+   QObject::tr("CA_CERTIFICATE_MISSING         "),
+   QObject::tr("END_CERTIFICATE_MISSING        "),
+   QObject::tr("None of your certificate provide a private key, this is required. Please select a private key"
+   " or use a certificate with one built-in"),
+   QObject::tr("CERTIFICATE_MISMATCH           "),
+   QObject::tr("CERTIFICATE_STORAGE_PERMISSION "),
+   QObject::tr("CERTIFICATE_STORAGE_FOLDER     "),
+   QObject::tr("CERTIFICATE_STORAGE_LOCATION   "),
+   QObject::tr("OUTGOING_SERVER_MISMATCH       "),
+   QObject::tr("VERIFY_INCOMING_DISABLED       "),
+   QObject::tr("VERIFY_ANSWER_DISABLED         "),
+   QObject::tr("REQUIRE_CERTIFICATE_DISABLED   "),
+};
+
+const TypedStateMachine< SecurityValidationModel::SecurityLevel , SecurityValidationModel::SecurityFlaw >
+SecurityValidationModel::maximumSecurityLevel = {{
+   /* SRTP_DISABLED                  */ SecurityLevel::WEAK       ,
+   /* TLS_DISABLED                   */ SecurityLevel::WEAK       ,
+   /* CERTIFICATE_EXPIRED            */ SecurityLevel::MEDIUM     ,
+   /* CERTIFICATE_SELF_SIGNED        */ SecurityLevel::MEDIUM     ,
+   /* CA_CERTIFICATE_MISSING         */ SecurityLevel::PARTIAL    ,
+   /* END_CERTIFICATE_MISSING        */ SecurityLevel::PARTIAL    ,
+   /* PRIVATE_KEY_MISSING            */ SecurityLevel::PARTIAL    ,
+   /* CERTIFICATE_MISMATCH           */ SecurityLevel::NONE       ,
+   /* CERTIFICATE_STORAGE_PERMISSION */ SecurityLevel::ACCEPTABLE ,
+   /* CERTIFICATE_STORAGE_FOLDER     */ SecurityLevel::ACCEPTABLE ,
+   /* CERTIFICATE_STORAGE_LOCATION   */ SecurityLevel::ACCEPTABLE ,
+   /* OUTGOING_SERVER_MISMATCH       */ SecurityLevel::ACCEPTABLE ,
+   /* VERIFY_INCOMING_DISABLED       */ SecurityLevel::PARTIAL    ,
+   /* VERIFY_ANSWER_DISABLED         */ SecurityLevel::PARTIAL    ,
+   /* REQUIRE_CERTIFICATE_DISABLED   */ SecurityLevel::PARTIAL    ,
+   /* MISSING_CERTIFICATE            */ SecurityLevel::NONE       ,
+   /* MISSING_AUTHORITY              */ SecurityLevel::WEAK       ,
+}};
+
+const TypedStateMachine< SecurityValidationModel::Severity , SecurityValidationModel::SecurityFlaw >
+SecurityValidationModel::flawSeverity = {{
+   /* SRTP_DISABLED                  */ Severity::ISSUE   ,
+   /* TLS_DISABLED                   */ Severity::ISSUE   ,
+   /* CERTIFICATE_EXPIRED            */ Severity::WARNING ,
+   /* CERTIFICATE_SELF_SIGNED        */ Severity::WARNING ,
+   /* CA_CERTIFICATE_MISSING         */ Severity::ISSUE   ,
+   /* END_CERTIFICATE_MISSING        */ Severity::ISSUE   ,
+   /* PRIVATE_KEY_MISSING            */ Severity::ERROR   ,
+   /* CERTIFICATE_MISMATCH           */ Severity::ERROR   ,
+   /* CERTIFICATE_STORAGE_PERMISSION */ Severity::WARNING ,
+   /* CERTIFICATE_STORAGE_FOLDER     */ Severity::INFORMATION ,
+   /* CERTIFICATE_STORAGE_LOCATION   */ Severity::INFORMATION ,
+   /* OUTGOING_SERVER_MISMATCH       */ Severity::WARNING ,
+   /* VERIFY_INCOMING_DISABLED       */ Severity::ISSUE   ,
+   /* VERIFY_ANSWER_DISABLED         */ Severity::ISSUE   ,
+   /* REQUIRE_CERTIFICATE_DISABLED   */ Severity::ISSUE   ,
+   /* MISSING_CERTIFICATE            */ Severity::ERROR   ,
+   /* MISSING_AUTHORITY              */ Severity::ERROR   ,
+}};
+
+
+SecurityValidationModel::SecurityValidationModel(Account* account) : QAbstractListModel(account), m_pAccount(account)
+{
+   
+}
+
+SecurityValidationModel::~SecurityValidationModel()
+{
+   
+}
+
+QVariant SecurityValidationModel::data( const QModelIndex& index, int role) const
+{
+   if (index.isValid())  {
+      if (role == Qt::DisplayRole) {
+         return messages[static_cast<int>( m_lCurrentFlaws[index.row()].flaw )];
+      }
+      else if (role == Role::SeverityRole) {
+         return static_cast<int>(m_lCurrentFlaws[index.row()].severity);
+      }
+      else if (role == Qt::DecorationRole) {
+         return PixmapManipulationVisitor::instance()->serurityIssueIcon(index);
+      }
+   }
+   return QVariant();
+}
+
+int SecurityValidationModel::rowCount( const QModelIndex& parent) const
+{
+   Q_UNUSED(parent)
+   return m_lCurrentFlaws.size();
+}
+
+Qt::ItemFlags SecurityValidationModel::flags( const QModelIndex& index) const
+{
+   if (!index.isValid()) return Qt::NoItemFlags;
+   return Qt::ItemIsEnabled|Qt::ItemIsSelectable;
+}
+
+bool SecurityValidationModel::setData( const QModelIndex& index, const QVariant &value, int role)
+{
+   Q_UNUSED(index)
+   Q_UNUSED(value)
+   Q_UNUSED(role )
+   return false;
+}
+
+void SecurityValidationModel::update()
+{
+   m_lCurrentFlaws.clear();
+
+   /**********************************
+    *     Check general issues       *
+    *********************************/
+
+   /* If TLS is not enabled, everything else is worthless */
+   if (!m_pAccount->isTlsEnable()) {
+      m_lCurrentFlaws << Flaw(SecurityFlaw::TLS_DISABLED);
+   }
+
+   /* Check if the media stream is encrypted, it is something users
+    * may care about if they get this far ;) */
+   if (!m_pAccount->isSrtpEnabled()) {
+      m_lCurrentFlaws << Flaw(SecurityFlaw::SRTP_DISABLED);
+   }
+
+   /* The user certificate need to have a private key, otherwise it wont
+    * be possible to encrypt anything */
+   if ((! m_pAccount->tlsCertificate()->hasPrivateKey()) && (!m_pAccount->tlsPrivateKeyCertificate()->exist())) {
+      m_lCurrentFlaws << Flaw(SecurityFlaw::PRIVATE_KEY_MISSING,m_pAccount->tlsPrivateKeyCertificate()->type());
+   }
+
+   /**********************************
+    *      Certificates issues       *
+    *********************************/
+   QList<Certificate*> certs;
+   certs << m_pAccount->tlsCaListCertificate() << m_pAccount->tlsCertificate() << m_pAccount->tlsPrivateKeyCertificate();
+   foreach (Certificate* cert, certs) {
+      if (! cert->exist()) {
+         m_lCurrentFlaws << Flaw(SecurityFlaw::END_CERTIFICATE_MISSING,cert->type());
+      }
+      if (! cert->isExpired()) {
+         m_lCurrentFlaws << Flaw(SecurityFlaw::CERTIFICATE_EXPIRED,cert->type());
+      }
+      if (! cert->isSelfSigned()) {
+         m_lCurrentFlaws << Flaw(SecurityFlaw::CERTIFICATE_SELF_SIGNED,cert->type());
+      }
+      if (! cert->hasProtectedPrivateKey()) {
+         m_lCurrentFlaws << Flaw(SecurityFlaw::CERTIFICATE_STORAGE_PERMISSION,cert->type());
+      }
+      if (! cert->hasRightPermissions()) {
+         m_lCurrentFlaws << Flaw(SecurityFlaw::CERTIFICATE_STORAGE_PERMISSION),cert->type();
+      }
+      if (! cert->hasRightFolderPermissions()) {
+         m_lCurrentFlaws << Flaw(SecurityFlaw::CERTIFICATE_STORAGE_FOLDER,cert->type());
+      }
+      if (! cert->isLocationSecure()) {
+         m_lCurrentFlaws << Flaw(SecurityFlaw::CERTIFICATE_STORAGE_LOCATION,cert->type());
+      }
+   }
+
+   emit layoutChanged();
+}
+
+
diff --git a/src/securityvalidationmodel.h b/src/securityvalidationmodel.h
new file mode 100644
index 0000000000000000000000000000000000000000..2ef6b85f9a68e7c78a302e8fc82a00796323441f
--- /dev/null
+++ b/src/securityvalidationmodel.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+ *   Copyright (C) 2013-2014 by Savoir-Faire Linux                         ***
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library is distributed in the hope that it will be useful,        *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#ifndef SECURITYVALIDATIONMODEL_H
+#define SECURITYVALIDATIONMODEL_H
+#include <QAbstractListModel>
+
+//SFLPhone
+#include "certificate.h"
+#include "typedefs.h"
+
+
+//SFLPhone
+class Account;
+
+class LIB_EXPORT SecurityValidationModel : public QAbstractListModel {
+   Q_OBJECT
+public:
+   /*
+    * This class evaluate the overall security of an account.
+    * It does so by checking various potential flaws, then create
+    * a metric called SecurityLevel. This model should be used to:
+    * 
+    * 1) List all potential flaws
+    * 2) Decide if an account can be considered secure
+    * 3) Decide if a call can be considered secure
+    * 
+    * End users should not have to be security gurus to setup SFLphone. It is our
+    * job to do as much as we can to make security configuration as transparent as
+    * possible.
+    * 
+    * The SecurityLevel is computed by checking all possible flaw. The level cannot be
+    * higher than a flaw maximum security level. If there is 2 (or more) flaw in the same
+    * maximum level, the maximum level will be decreased by one (recursively).
+    * 
+    * A flaw severity is used by the client to display the right icon ( (i), /!\, [x] ).
+    */
+
+   ///Give the user an overview of the current security state
+   enum class SecurityLevel {
+      NONE        = 0, /* Security is not functional or severely defective              */
+      WEAK        = 1, /* There is some security, but way too many flaws                */
+      PARTIAL     = 2, /* There is some security, but there is too many flaws           */
+      MEDIUM      = 3, /* The security is probably good enough, but there is issues     */
+      ACCEPTABLE  = 4, /* The security is most probably good enough, only minor issues  */
+      STRONG      = 5, /* All the non-information items are correct                     */
+      VERY_STRONG = 6, /* Everything, even the recommendations, are correct             */
+   };
+
+   ///The severity of a given flaw
+   enum class Severity {
+      INFORMATION  , /* Tip and tricks to have better security                          */
+      WARNING      , /* It is a problem, but it wont have other side effects            */
+      ISSUE        , /* The security is compromised                                     */
+      ERROR        , /* It simply wont work (REGISTER)                                  */
+      FATAL_WARNING, /* Registration may work, but it render everything else useless    */
+   };
+
+   ///Every supported flaws
+   enum class SecurityFlaw {
+      SRTP_DISABLED                  ,
+      TLS_DISABLED                   ,
+      CERTIFICATE_EXPIRED            ,
+      CERTIFICATE_SELF_SIGNED        ,
+      CA_CERTIFICATE_MISSING         ,
+      END_CERTIFICATE_MISSING        ,
+      PRIVATE_KEY_MISSING            ,
+      CERTIFICATE_MISMATCH           ,
+      CERTIFICATE_STORAGE_PERMISSION ,
+      CERTIFICATE_STORAGE_FOLDER     ,
+      CERTIFICATE_STORAGE_LOCATION   ,
+      OUTGOING_SERVER_MISMATCH       ,
+      VERIFY_INCOMING_DISABLED       ,
+      VERIFY_ANSWER_DISABLED         ,
+      REQUIRE_CERTIFICATE_DISABLED   ,
+      MISSING_CERTIFICATE            ,
+      MISSING_AUTHORITY              ,
+      COUNT
+   };
+
+   ///Role for the model
+   enum Role {
+      SeverityRole = 100
+   };
+
+   ///Messages to show to the end user
+   static const QString messages[static_cast<const int>(SecurityFlaw::COUNT)];
+
+   ///A flaw representation
+   struct Flaw {
+      Flaw(SecurityFlaw f,Certificate::Type type = Certificate::Type::NONE)
+      : flaw(f),certType(type)
+      {
+         severity = flawSeverity[f];
+      }
+      SecurityFlaw flaw;
+      Severity severity;
+      Certificate::Type certType;
+   };
+
+   //Constructor
+   SecurityValidationModel(Account* account);
+   virtual ~SecurityValidationModel();
+
+
+   //Model functions
+   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const;
+   int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const;
+   Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
+   virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
+
+   //Mutator
+   void update();
+
+private:
+   //Attributes
+   QList<Flaw>   m_lCurrentFlaws       ;
+   SecurityLevel m_CurrentSecurityLevel;
+   Account*      m_pAccount            ;
+
+private:
+   //Static mapping
+   static const TypedStateMachine< SecurityLevel , SecurityFlaw > maximumSecurityLevel;
+   static const TypedStateMachine< Severity      , SecurityFlaw > flawSeverity        ;
+};
+Q_DECLARE_METATYPE(SecurityValidationModel*)
+
+#endif
\ No newline at end of file
diff --git a/src/visitors/pixmapmanipulationvisitor.cpp b/src/visitors/pixmapmanipulationvisitor.cpp
index da3a7978fb9005f78a2f68549232a493253c1fb1..04a7ce41a4040e288c97caa128dbd30bd963d68a 100644
--- a/src/visitors/pixmapmanipulationvisitor.cpp
+++ b/src/visitors/pixmapmanipulationvisitor.cpp
@@ -62,3 +62,9 @@ PixmapManipulationVisitor* PixmapManipulationVisitor::instance()
 {
    return m_spInstance;
 }
+
+QVariant PixmapManipulationVisitor::serurityIssueIcon(const QModelIndex& index)
+{
+   Q_UNUSED(index)
+   return QVariant();
+}
diff --git a/src/visitors/pixmapmanipulationvisitor.h b/src/visitors/pixmapmanipulationvisitor.h
index de6b9a71f96626a0a82d9fa8798c21df308756b8..83e1fa2a0b4895d249351b7426ba64a91d6cb0f6 100644
--- a/src/visitors/pixmapmanipulationvisitor.h
+++ b/src/visitors/pixmapmanipulationvisitor.h
@@ -21,6 +21,7 @@
 
 //Qt
 #include <QtCore/QVariant>
+#include <QtCore/QModelIndex>
 
 //SFLPhone
 class Contact    ;
@@ -45,6 +46,7 @@ public:
    virtual QVariant callPhoto(Call* c, const QSize& size, bool displayPresence = true);
    virtual QVariant callPhoto(const PhoneNumber* n, const QSize& size, bool displayPresence = true);
    virtual QVariant numberCategoryIcon(const QPixmap* p, const QSize& size, bool displayPresence = false, bool isPresent = false);
+   virtual QVariant serurityIssueIcon(const QModelIndex& index);
 
    //Singleton
    static PixmapManipulationVisitor* instance();