diff --git a/smp-angular/src/app/user/user-controller.ts b/smp-angular/src/app/user/user-controller.ts
index 48e7ef542756ee63971ff87e59fb0b0fe04c7258..eb60cff81a33c318584f6b35f9a20d0258965db4 100644
--- a/smp-angular/src/app/user/user-controller.ts
+++ b/smp-angular/src/app/user/user-controller.ts
@@ -12,9 +12,15 @@ import {CertificateRo} from "./certificate-ro.model";
 
 export class UserController implements SearchTableController {
 
-  nullCert = this.newCertificateRo();
+  nullCert:CertificateRo;
+
+
+  compareUserProperties = ["username","password","emailAddress","active","role","certificate"];
+  compareCertProperties = ["certificateId","subject","issuer","serialNumber","crlUrl","validFrom","validTo"];
+
 
   constructor(protected http: HttpClient, protected lookups: GlobalLookups, public dialog: MatDialog) {
+    this.nullCert = this.newCertificateRo();
   }
 
   public showDetails(row: any) {
@@ -81,31 +87,41 @@ export class UserController implements SearchTableController {
   }
 
   isCertificateChanged(oldCert, newCert): boolean {
-    if (!this.isNotNull(oldCert) && !this.isNotNull(newCert)) {
+    if (this.isNull(oldCert) && this.isNull(newCert)) {
+      console.log("both null return false! ");
       return false;
     }
 
-    if (!this.isNotNull(oldCert)) {
+    if (this.isNull(oldCert)) {
       oldCert = this.nullCert;
     }
 
-    if (!this.isNotNull(newCert)) {
+    if (this.isNull(newCert)) {
       newCert = this.nullCert;
     }
-    return this.isRecordChanged(oldCert, newCert);
-  }
 
+    return this.propertyChanged(oldCert, newCert, this.compareCertProperties);
+  }
 
   isRecordChanged(oldModel, newModel): boolean {
+    return this.propertyChanged(oldModel, newModel, this.compareUserProperties);
+  }
+
+  propertyChanged(oldModel, newModel, arrayProperties): boolean {
+
+
+    let propSize = arrayProperties.length;
+    for (let i = 0; i < propSize; i++) {
 
-    for (var property in oldModel) {
-      if (property === 'certificate') {
-        if (this.isCertificateChanged(newModel[property], oldModel[property])) {
+      let property = arrayProperties[i];
+     if (property === 'certificate') {
+        if (this.isCertificateChanged(oldModel[property], newModel[property])) {
           return true; // Property has changed
         }
       } else {
         const isEqual = this.isEqual(newModel[property], oldModel[property]);
         if (!isEqual) {
+          console.log("property "+property+" is changed! ");
           return true; // Property has changed
         }
       }
@@ -122,8 +138,8 @@ export class UserController implements SearchTableController {
     return (!str || 0 === str.length);
   }
 
-  isNotNull(obj): boolean {
-    return typeof obj != 'undefined' && obj
+  isNull(obj): boolean {
+    return !obj
   }
 
 
diff --git a/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.html b/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.html
index 55333aa40a3738ed5bc392617d07f0813629cc8e..12a771bafe04c3fa5bc5d866f35c9f0b8b957c7e 100644
--- a/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.html
+++ b/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.html
@@ -157,7 +157,7 @@
     <tr>
       <td>
         <button mat-raised-button color="primary" [mat-dialog-close]="true" (click)="submitForm()"
-                [disabled]="!userForm.valid || this.current && this.current.certificate && this.current.certificate.invalid">
+                [disabled]="!userForm.valid ">
           <mat-icon>check_circle</mat-icon>
           <span>OK</span>
         </button>
diff --git a/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts b/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts
index 6c3fe712a760179e5127364106d0ef818513d84d..983157c0ad7f1027cc95eb88d65d97724b0d43af 100644
--- a/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts
+++ b/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts
@@ -68,10 +68,8 @@ export class UserDetailsDialogComponent {
     const validTo = control.get('validTo');
     const issuer = control.get('issuer');
     const serialNumber = control.get('serialNumber');
-    const isValid = control.get('isCertificateValid');
     return certificateToggle && subject && validFrom && validTo && issuer && serialNumber
     && certificateToggle.value
-    && isValid
     && !(subject.value && validFrom.value && validTo.value && issuer.value && serialNumber.value) ? {certificateDetailsRequired: true} : null;
   };
 
@@ -129,9 +127,10 @@ export class UserDetailsDialogComponent {
     this.current = this.editMode
       ? {
         ...data.row,
+
         password: '', // ensures the user password is cleared before editing
         confirmation: '',
-        certificate: data.row.certificate || this.newCertificateRo()
+        certificate: data.row.certificate? {...data.row.certificate}  : this.newCertificateRo()
       } : {
         active: true,
         username: '',
@@ -208,6 +207,10 @@ export class UserDetailsDialogComponent {
     this.userForm.controls['certificateId'].setValue(this.current.certificate.certificateId);
     this.userForm.controls['isCertificateValid'].setValue(!this.current.certificate.invalid);
 
+
+    this.certificateValidationMessage =this.current.certificate.invalidReason;
+    this.isCertificateInvalid= this.current.certificate.invalid;
+
     // if edit mode and user is given - toggle is disabled
     // username should not be changed.!
     if (this.editMode && bUserPasswordAuthentication) {
@@ -229,7 +232,8 @@ export class UserDetailsDialogComponent {
             'validTo': res.validTo,
             'issuer': res.issuer,
             'serialNumber': res.serialNumber,
-            'certificateId': res.certificateId
+            'certificateId': res.certificateId,
+            'isCertificateValid': !res.invalid
           });
           this.certificateValidationMessage = res.invalidReason;
           this.isCertificateInvalid = res.invalid;
@@ -329,6 +333,8 @@ export class UserDetailsDialogComponent {
       this.current.certificate.serialNumber = this.userForm.controls['serialNumber'].value;
       this.current.certificate.validFrom = this.userForm.controls['validFrom'].value;
       this.current.certificate.validTo = this.userForm.controls['validTo'].value;
+      this.current.certificate.invalid = this.isCertificateInvalid;
+      this.current.certificate.invalidReason = this.certificateValidationMessage;
     } else {
       this.current.certificate = null;
     }
diff --git a/smp-angular/src/app/user/user.component.css b/smp-angular/src/app/user/user.component.css
index 1e2c4567531ce54920b3da930aeb44ed2c39f44e..59f0dc732eb4567f498a4f8d1f0ced45fc390789 100644
--- a/smp-angular/src/app/user/user.component.css
+++ b/smp-angular/src/app/user/user.component.css
@@ -11,3 +11,24 @@
 #hiddenButtonId {
   position: fixed;
 }
+/deep/ .invalidCertificate {
+  text-decoration: line-through !important;
+  font-weight: bold;
+  color:red;
+}
+
+/deep/ .deleted  {
+  text-decoration: line-through !important;
+  font-weight: bold;
+}
+/deep/ .table-row-new  {
+
+  color: darkgreen !important;
+  font-weight: bold;
+}
+/deep/ .table-row-updated  {
+  font-weight: bold;
+}
+/deep/ .table-row  {
+  font-weight: normal;
+}
diff --git a/smp-angular/src/app/user/user.component.html b/smp-angular/src/app/user/user.component.html
index 159a84fd03a3119bae4304f0918c7b218203f217..164e42ec6b31449a85d29ee607188a2862788f2e 100644
--- a/smp-angular/src/app/user/user.component.html
+++ b/smp-angular/src/app/user/user.component.html
@@ -14,6 +14,12 @@
 
   <ng-template #roleCellTemplate let-value="value" ngx-datatable-cell-template>{{getRoleLabel(value)}}</ng-template>
 
+  <ng-template #certificateTemplate let-row="row"  ngx-datatable-cell-template>
+    <span [class]='certCssClass(row)'
+          matTooltip="{{row.certificate?.invalidReason}}"
+    >{{row.certificate?.certificateId}}</span>
+  </ng-template>
+
   <ng-template #additionalToolButtons >
     <span style="width: 2px;background-color: deepskyblue;">&nbsp;</span>
 
diff --git a/smp-angular/src/app/user/user.component.ts b/smp-angular/src/app/user/user.component.ts
index d8ee84c7501c20271e79e34e0daad7e7cb237d4b..54a15810aeed69df947f1bcc14551808eb0d1546 100644
--- a/smp-angular/src/app/user/user.component.ts
+++ b/smp-angular/src/app/user/user.component.ts
@@ -8,6 +8,7 @@ import {SearchTableComponent} from "../common/search-table/search-table.componen
 import {SecurityService} from "../security/security.service";
 import {GlobalLookups} from "../common/global-lookups";
 import {TruststoreEditDialogComponent} from "./truststore-edit-dialog/truststore-edit-dialog.component";
+import {SearchTableEntityStatus} from "../common/search-table/search-table-entity-status.model";
 
 @Component({
   templateUrl:'./user.component.html',
@@ -19,6 +20,7 @@ export class UserComponent implements OnInit {
   @ViewChild('rowExtensionAction') rowExtensionAction: TemplateRef<any>;
   @ViewChild('rowActions') rowActions: TemplateRef<any>;
   @ViewChild('searchTable') searchTable: SearchTableComponent;
+  @ViewChild('certificateTemplate') certificateTemplate: TemplateRef<any>;
 
   columnPicker: ColumnPicker = new ColumnPicker();
   userController: UserController;
@@ -42,7 +44,7 @@ export class UserComponent implements OnInit {
       },
       {
         name: 'Certificate',
-        prop: 'certificate.certificateId',
+        cellTemplate: this.certificateTemplate,
         canAutoResize: true
       },
       {
@@ -62,6 +64,21 @@ export class UserComponent implements OnInit {
     }
   }
 
+  certCssClass(row) {
+
+     if (row.certificate && row.certificate.invalid) {
+      return 'invalidCertificate';
+    } else if (row.status === SearchTableEntityStatus.NEW) {
+       return 'table-row-new';
+     } else if (row.status === SearchTableEntityStatus.UPDATED) {
+       return 'table-row-updated';
+     } else if (row.status === SearchTableEntityStatus.REMOVED) {
+       return 'deleted';
+     }else  {
+       return 'table-row';
+     }
+  }
+
   details(row: any) {
     this.userController.showDetails(row);
   }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/CertificateRO.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/CertificateRO.java
index 61772e949a11a38bba3321073f5770365e021711..b09b32e022d28760a21092faa949b3dae3a9a836 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/CertificateRO.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/CertificateRO.java
@@ -17,6 +17,7 @@ public class CertificateRO extends BaseRO {
     private String subject;
     private String issuer;
     private String serialNumber;
+    private String crlUrl;
     private String encodedValue;
     private String blueCoatHeader;
     private boolean isInvalid;
@@ -107,6 +108,14 @@ public class CertificateRO extends BaseRO {
         this.blueCoatHeader = blueCoatHeader;
     }
 
+    public String getCrlUrl() {
+        return crlUrl;
+    }
+
+    public void setCrlUrl(String crlUrl) {
+        this.crlUrl = crlUrl;
+    }
+
     public boolean isInvalid() {
         return isInvalid;
     }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java
index caa8333761f25c52f80c733983834d453003bc14..db0b62f62aa3947fa3fbe9e29d49262a030f6ee2 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java
@@ -4,6 +4,7 @@ import eu.europa.ec.edelivery.smp.data.ui.CertificateRO;
 import eu.europa.ec.edelivery.smp.exceptions.CertificateNotTrustedException;
 import eu.europa.ec.edelivery.smp.logging.SMPLogger;
 import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory;
+import eu.europa.ec.edelivery.smp.logging.SMPMessageCode;
 import eu.europa.ec.edelivery.smp.services.CRLVerifierService;
 import eu.europa.ec.edelivery.smp.services.ConfigurationService;
 import eu.europa.ec.edelivery.smp.utils.X509CertificateUtils;
@@ -13,6 +14,7 @@ import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.convert.ConversionService;
+import org.springframework.security.authentication.AuthenticationServiceException;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.PostConstruct;
@@ -20,19 +22,25 @@ import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
 import java.io.*;
-import java.nio.file.Paths;
 import java.security.*;
 import java.security.cert.Certificate;
 import java.security.cert.*;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
 import java.util.*;
 
 import static java.util.Collections.list;
+import static java.util.Locale.US;
 
 @Service
 public class UITruststoreService {
 
     private static final SMPLogger LOG = SMPLoggerFactory.getLogger(UITruststoreService.class);
 
+    private static final ThreadLocal<DateFormat> dateFormatLocal = ThreadLocal.withInitial(() -> {
+        return new SimpleDateFormat("MMM d hh:mm:ss yyyy zzz", US);
+    });
+
     @Autowired
     private ConfigurationService configurationService;
 
@@ -158,14 +166,14 @@ public class UITruststoreService {
         return cro;
     }
 
-    public void checkFullCertificateValidity(X509Certificate cert) throws CertificateException{
+    public void checkFullCertificateValidity(X509Certificate cert) throws CertificateException {
         // test if certificate is valid
         cert.checkValidity();
         // check if certificate or its issuer is on trusted list
         // check only issuer because using bluecoat Client-cert we do not have whole chain.
         // if the truststore is empty then truststore validation is ignored
         // backward compatibility
-        if ( !normalizedTrustedList.isEmpty()  &&  !(isSubjectOnTrustedList(cert.getSubjectX500Principal().getName())
+        if (!normalizedTrustedList.isEmpty() && !(isSubjectOnTrustedList(cert.getSubjectX500Principal().getName())
                 || isSubjectOnTrustedList(cert.getIssuerDN().getName()))) {
 
             throw new CertificateNotTrustedException("Certificate is not trusted!");
@@ -174,10 +182,50 @@ public class UITruststoreService {
         crlVerifierService.verifyCertificateCRLs(cert);
     }
 
+    public void checkFullCertificateValidity(CertificateRO cert) throws CertificateException {
+        // trust data in database
+        Date currentDate = Calendar.getInstance().getTime();
+        if (cert.getValidFrom() != null && currentDate.before(cert.getValidFrom())) {
+            throw new CertificateNotYetValidException("Certificate: " + cert.getCertificateId() + " is valid from: "
+                    + dateFormatLocal.get().format(cert.getValidFrom()) + ".");
+
+        }
+        if (cert.getValidTo() != null && currentDate.after(cert.getValidTo())) {
+            throw new CertificateExpiredException("Certificate: " + cert.getCertificateId() + " was valid to: "
+                    + dateFormatLocal.get().format(cert.getValidTo()) + ".");
+        }
+        // if trusted list is not empty and exists issuer or subject then validate
+        if (!normalizedTrustedList.isEmpty() && (
+                !StringUtils.isBlank(cert.getIssuer()) || !StringUtils.isBlank(cert.getSubject()))) {
+
+            if (!isSubjectOnTrustedList(cert.getIssuer()) && !isSubjectOnTrustedList(cert.getSubject())) {
+                throw new CertificateNotTrustedException("Certificate is not trusted!");
+            }
+
+        }
+
+        // Check crl list
+        String url = cert.getCrlUrl();
+        if (!StringUtils.isBlank(url) && !StringUtils.isBlank(cert.getSerialNumber())) {
+            try {
+                crlVerifierService.verifyCertificateCRLs(cert.getSerialNumber(), url);
+            } catch (CertificateRevokedException ex) {
+                String msg = "Certificate: '" + cert.getCertificateId() + "'" +
+                        " is revoked!";
+                LOG.securityWarn(SMPMessageCode.SEC_USER_CERT_INVALID, cert.getCertificateId(), msg);
+                throw new AuthenticationServiceException(msg);
+            } catch (Throwable th) {
+                String msg = "Error occurred while validating CRL for certificate!";
+                LOG.error(SMPLogger.SECURITY_MARKER, msg + "Err: " + ExceptionUtils.getRootCauseMessage(th), th);
+                throw new AuthenticationServiceException(msg);
+            }
+        }
+    }
+
     boolean isTruststoreChanged() {
         File file = getTruststoreFile();
         return !Objects.equals(lastUpdateTrustStoreFile, file) ||
-                file!=null && file.lastModified() != lastUpdateTrustoreFileTime;
+                file != null && file.lastModified() != lastUpdateTrustoreFileTime;
     }
 
     public File getTruststoreFile() {
@@ -186,7 +234,7 @@ public class UITruststoreService {
 
     private KeyStore loadTruststore(File truststoreFile) {
 
-        if (truststoreFile==null) {
+        if (truststoreFile == null) {
             LOG.error("Truststore file is not configured! Update SMP configuration!");
             return null;
         }
diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java
index 8d2a70de65d9ee6761ea359f467bdb868dae43d5..bdcfdc1ff5874ec39eaebefd57885473930019f9 100644
--- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java
+++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java
@@ -22,6 +22,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.io.StringWriter;
+import java.security.cert.CertificateException;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.List;
@@ -37,6 +38,10 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
     @Autowired
     private ConversionService conversionService;
 
+    @Autowired
+    private UITruststoreService truststoreService;
+
+
     @Override
     protected BaseDao<DBUser> getDatabaseDao() {
         return userDao;
@@ -55,10 +60,26 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> {
     @Transactional
     public ServiceResult<UserRO> getTableList(int page, int pageSize, String sortField, String sortOrder, Object filter) {
         ServiceResult<UserRO> resUsers = super.getTableList(page, pageSize, sortField, sortOrder, filter);
-        resUsers.getServiceEntities().forEach(usr -> usr.setPassword(null));
+        resUsers.getServiceEntities().forEach(this::updateUserStatus);
         return resUsers;
     }
 
+        protected  void updateUserStatus(UserRO user){
+        // never return password even if is hashed...
+        user.setPassword(null);
+        if (user.getCertificate()!=null && !StringUtils.isBlank(user.getCertificate().getCertificateId())){
+            // validate certificate
+            try {
+                truststoreService.checkFullCertificateValidity(user.getCertificate());
+            } catch (CertificateException e) {
+                LOG.warn("Set invalid cert status: " + user.getCertificate().getCertificateId() + " reason: " +e.getMessage());
+                user.getCertificate().setInvalid(true);
+                user.getCertificate().setInvalidReason(e.getMessage());
+            }
+        }
+
+    }
+
     @Transactional
     public void updateUserList(List<UserRO> lst, LocalDateTime passwordChange) {
         for (UserRO userRO : lst) {