Repository: kaikramer/keystore-explorer
Pull request #540: Add Reason to CRL tables
Author: login: jonwltn
Created: 2025-03-13T23:35:36Z | Merged: 2025-03-29T16:56:23Z

Added certificate revocation reason to CRL tables. Fixes #414.

Linked issue #414: [GUI] Display `Reason Code` of revoked certificates in `CRL view` or `Sign CRL view`
Hi all,

- Would it be possible to see _[directly]_ the `Reason Code` field of revoked certificates in the screens related to the CRLs?
[Especially on `CRL view` or `Sign CRL` screens]
_[To Avoid to click to Extension...]_

Impacted code:
- [DViewCrl](https://github.com/kaikramer/keystore-explorer/blob/main/kse/src/org/kse/gui/dialogs/DViewCrl.java)
  - [RevokedCertsTableModel](https://github.com/kaikramer/keystore-explorer/blob/master/kse/src/org/kse/gui/dialogs/RevokedCertsTableModel.java)
  - [RevokedCertsTableCellRend](https://github.com/kaikramer/keystore-explorer/blob/master/kse/src/org/kse/gui/dialogs/RevokedCertsTableCellRend.java)
  - [RevokedCertsTableHeadRend](https://github.com/kaikramer/keystore-explorer/blob/master/kse/src/org/kse/gui/dialogs/RevokedCertsTableHeadRend.java)
- [DSignCrl](https://github.com/kaikramer/keystore-explorer/blob/main/kse/src/org/kse/gui/dialogs/sign/DSignCrl.java) 
  - [JRevokedCerts](https://github.com/kaikramer/keystore-explorer/blob/master/kse/src/org/kse/gui/dialogs/sign/JRevokedCerts.java)
  - [RevokedCertsTableModel](https://github.com/kaikramer/keystore-explorer/blob/master/kse/src/org/kse/gui/dialogs/sign/RevokedCertsTableModel.java)
  - [RevokedCertsTableCellRend](https://github.com/kaikramer/keystore-explorer/blob/master/kse/src/org/kse/gui/dialogs/sign/RevokedCertsTableCellRend.java)
  - [RevokedCertsTableHeadRend](https://github.com/kaikramer/keystore-explorer/blob/master/kse/src/org/kse/gui/dialogs/sign/RevokedCertsTableHeadRend.java)

Maybe also factor these parts of code... (`RevokedCerts`...) _to suppress redundancy between the two directories..._

Screenshot _(see green rectangle)_ with where to add the `Reason Code`  column:
- On  `CRL view` or `CRL details`: 
![2023-02-05 18_26_55-CRL Details for CRL File](https://user-images.githubusercontent.com/86879521/216838929-efaf7dfa-cdce-4755-910b-4688fff4140c.png)
- On `Sign CRL`:
![2023-02-05 18_36_05-Sign CRL](https://user-images.githubusercontent.com/86879521/216838935-6afa7a66-3de4-439d-888a-8306833d12fe.png)

Version of KSE: 5.5.2
Ref. or linked to _[initial PR]_:
- #276

Regards,
Th.
Linked issue comments: user: login: jonwltn
created_at: 2025-03-13T00:10:54Z
body: I'll tackle this one. Should I also remove the Extensions button below the list of revoked certs? It's fine as it is, but it is superfluous. 

![Image](https://github.com/user-attachments/assets/668e0168-5276-45d0-b03f-02d91586fa69)
author_association: CONTRIBUTOR
user: login: kaikramer
created_at: 2025-03-13T11:46:29Z
body: > I'll tackle this one. Should I also remove the Extensions button below the list of revoked certs? It's fine as it is, but it is superfluous.

Oh that's great, thanks! 

The "Extensions" button at the top is for displaying the global CRL extensions and the button at the bottom is for showing the extensions of the selected CRL entry (each entry can have additional extensions). 

author_association: OWNER
user: login: kaikramer
created_at: 2025-03-13T11:50:56Z
body: If you think having two buttons with the same name is too confusing, then feel free to change it.
author_association: OWNER
user: login: kaikramer
created_at: 2025-03-15T21:50:39Z
body: > Should I also remove the Extensions button below the list of revoked certs? It's fine as it is, but it is superfluous.

I think I know now what you mean. KSE can currently only add the reason code extension to CRL entries, but in general there are other extensions for CRL entries. The most common is the certificate issuer extension. If we removed the button, we would have to add more columns to the table and I think that's not a good idea.
author_association: OWNER
user: login: jonwltn
created_at: 2025-03-16T04:57:48Z
body: Got it. I've kept the button.
author_association: CONTRIBUTOR

Diff:
diff --git a/kse/src/main/java/org/kse/crypto/x509/X509Ext.java b/kse/src/main/java/org/kse/crypto/x509/X509Ext.java
index 17437f4e1..417114356 100644
--- a/kse/src/main/java/org/kse/crypto/x509/X509Ext.java
+++ b/kse/src/main/java/org/kse/crypto/x509/X509Ext.java
@@ -854,29 +854,7 @@ private static String getReasonCodeStringValue(byte[] value) throws IOException
 
         long crlReasonLong = crlReason.getValue().longValue();
 
-        if (crlReasonLong == CRLReason.unspecified) {
-            sb.append(res.getString("UnspecifiedCrlReason"));
-        } else if (crlReasonLong == CRLReason.keyCompromise) {
-            sb.append(res.getString("KeyCompromiseCrlReason"));
-        } else if (crlReasonLong == CRLReason.cACompromise) {
-            sb.append(res.getString("CaCompromiseCrlReason"));
-        } else if (crlReasonLong == CRLReason.affiliationChanged) {
-            sb.append(res.getString("AffiliationChangedCrlReason"));
-        } else if (crlReasonLong == CRLReason.superseded) {
-            sb.append(res.getString("SupersededCrlReason"));
-        } else if (crlReasonLong == CRLReason.cessationOfOperation) {
-            sb.append(res.getString("CessationOfOperationCrlReason"));
-        } else if (crlReasonLong == CRLReason.certificateHold) {
-            sb.append(res.getString("CertificateHoldCrlReason"));
-        } else if (crlReasonLong == CRLReason.removeFromCRL) {
-            sb.append(res.getString("RemoveFromCrlCrlReason"));
-        } else if (crlReasonLong == CRLReason.privilegeWithdrawn) {
-            sb.append(res.getString("PrivilegeWithdrawnCrlReason"));
-        } else
-        // CRLReason.aACompromise
-        {
-            sb.append(res.getString("AaCompromiseCrlReason"));
-        }
+        sb.append(res.getString("CrlReason." + crlReasonLong + ".text"));
 
         sb.append(NEWLINE);
 
diff --git a/kse/src/main/java/org/kse/gui/actions/SignCrlAction.java b/kse/src/main/java/org/kse/gui/actions/SignCrlAction.java
index 44fd77f00..3c690f84e 100644
--- a/kse/src/main/java/org/kse/gui/actions/SignCrlAction.java
+++ b/kse/src/main/java/org/kse/gui/actions/SignCrlAction.java
@@ -191,7 +191,7 @@ private X509CRL signCrl(BigInteger number, Date effectiveDate, Date nextUpdate,
 
             for (Map.Entry<BigInteger, RevokedEntry> pair : mapRevokedCertificate.entrySet()) {
                 RevokedEntry entry = pair.getValue();
-                crlGen.addCRLEntry(entry.getUserCertificateSerial(), entry.getRevocationDate(), entry.getReason());
+                crlGen.addCRLEntry(entry.getUserCertificateSerial(), entry.getRevocationDate(), entry.getReason().ordinal());
             }
         }
         JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
diff --git a/kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableCellRend.java b/kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableCellRend.java
index f5080b734..af1f64855 100644
--- a/kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableCellRend.java
+++ b/kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableCellRend.java
@@ -17,6 +17,7 @@
  * You should have received a copy of the GNU General Public License
  * along with KeyStore Explorer.  If not, see <http://www.gnu.org/licenses/>.
  */
+
 package org.kse.gui.dialogs;
 
 import java.awt.Component;
@@ -55,10 +56,16 @@ public Component getTableCellRendererComponent(JTable jtRevokedCerts, Object val
         JLabel cell = (JLabel) super.getTableCellRendererComponent(jtRevokedCerts, value, isSelected, hasFocus, row,
                                                                    col);
 
-        if (col == 0) {
-            cell.setText(HexUtil.getHexString((BigInteger) value, "0x", 4, 0));
-        } else {
-            cell.setText(StringUtils.formatDate((Date) value));
+        switch (col) {
+            case RevokedCertsTableModel.COL_SERIAL_NUMBER:
+                cell.setText(HexUtil.getHexString((BigInteger) value, "0x", 4, 0));
+                break;
+            case RevokedCertsTableModel.COL_REVOCATION_DATE:
+                cell.setText(StringUtils.formatDate((Date) value));
+                break;
+            case RevokedCertsTableModel.COL_REASON:
+                cell.setText((String) value);
+                break;
         }
 
         cell.setBorder(new EmptyBorder(0, 5, 0, 5));
diff --git a/kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableHeadRend.java b/kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableHeadRend.java
index 4790af76d..0e6aee4b3 100644
--- a/kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableHeadRend.java
+++ b/kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableHeadRend.java
@@ -17,6 +17,7 @@
  * You should have received a copy of the GNU General Public License
  * along with KeyStore Explorer.  If not, see <http://www.gnu.org/licenses/>.
  */
+
 package org.kse.gui.dialogs;
 
 import java.awt.Component;
@@ -37,6 +38,11 @@ public class RevokedCertsTableHeadRend extends DefaultTableCellRenderer {
 
     private TableCellRenderer delegate;
 
+    /**
+     * Construct a new RevokedCertsTableHeadRend.
+     *
+     * @param delegate
+     */
     public RevokedCertsTableHeadRend(TableCellRenderer delegate) {
         this.delegate = delegate;
     }
@@ -61,10 +67,16 @@ public Component getTableCellRendererComponent(JTable jTable, Object value, bool
         if (c instanceof JLabel) {
             JLabel header = (JLabel) c;
 
-            if (col == 0) {
-                header.setToolTipText(res.getString("RevokedCertsTableHeadRend.SerialNumberColumn.tooltip"));
-            } else {
-                header.setToolTipText(res.getString("RevokedCertsTableHeadRend.RevocationDateColumn.tooltip"));
+            switch (col) {
+                case RevokedCertsTableModel.COL_SERIAL_NUMBER:
+                    header.setToolTipText(res.getString("RevokedCertsTableHeadRend.SerialNumberColumn.tooltip"));
+                    break;
+                case RevokedCertsTableModel.COL_REVOCATION_DATE:
+                    header.setToolTipText(res.getString("RevokedCertsTableHeadRend.RevocationDateColumn.tooltip"));
+                    break;
+                case RevokedCertsTableModel.COL_REASON:
+                    header.setToolTipText(res.getString("RevokedCertsTableHeadRend.ReasonColumn.tooltip"));
+                    break;
             }
         }
 
diff --git a/kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableModel.java b/kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableModel.java
index 50adfb6b9..91945c5bf 100644
--- a/kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableModel.java
+++ b/kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableModel.java
@@ -17,9 +17,11 @@
  * You should have received a copy of the GNU General Public License
  * along with KeyStore Explorer.  If not, see <http://www.gnu.org/licenses/>.
  */
+
 package org.kse.gui.dialogs;
 
 import java.math.BigInteger;
+import java.security.cert.CRLReason;
 import java.security.cert.X509CRLEntry;
 import java.util.Date;
 import java.util.Iterator;
@@ -29,6 +31,8 @@
 
 import javax.swing.table.AbstractTableModel;
 
+import org.kse.gui.dialogs.sign.RevokedEntry;
+
 /**
  * The table model used to display an array of X.509 CRL entries sorted by
  * serial number.
@@ -36,7 +40,13 @@
 public class RevokedCertsTableModel extends AbstractTableModel {
     private static final long serialVersionUID = 1L;
 
+    static final int COL_SERIAL_NUMBER = 0;
+    static final int COL_REVOCATION_DATE = 1;
+    static final int COL_REASON = 2;
+    private static final int COLUMN_COUNT = 3;
+
     private static ResourceBundle res = ResourceBundle.getBundle("org/kse/gui/dialogs/resources");
+    private static ResourceBundle resCryptoX509 = ResourceBundle.getBundle("org/kse/crypto/x509/resources");
 
     private String[] columnNames;
     private Object[][] data;
@@ -45,9 +55,10 @@ public class RevokedCertsTableModel extends AbstractTableModel {
      * Construct a new RevokedCertsTableModel.
      */
     public RevokedCertsTableModel() {
-        columnNames = new String[2];
-        columnNames[0] = res.getString("RevokedCertsTableModel.SerialNumberColumn");
-        columnNames[1] = res.getString("RevokedCertsTableModel.RevocationDateColumn");
+        columnNames = new String[COLUMN_COUNT];
+        columnNames[COL_SERIAL_NUMBER] = res.getString("RevokedCertsTableModel.SerialNumberColumn");
+        columnNames[COL_REVOCATION_DATE] = res.getString("RevokedCertsTableModel.RevocationDateColumn");
+        columnNames[COL_REASON] = res.getString("RevokedCertsTableModel.ReasonColumn");
 
         data = new Object[0][0];
     }
@@ -64,19 +75,47 @@ public void load(X509CRLEntry[] revokedCerts) {
             sortedRevokedCerts.put(revokedCert.getSerialNumber(), revokedCert);
         }
 
-        data = new Object[sortedRevokedCerts.size()][2];
+        data = new Object[sortedRevokedCerts.size()][COLUMN_COUNT];
 
         int i = 0;
         for (Iterator<?> itr = sortedRevokedCerts.entrySet().iterator(); itr.hasNext(); i++) {
             X509CRLEntry x509CrlEntry = (X509CRLEntry) ((Map.Entry<?, ?>) itr.next()).getValue();
 
-            data[i][0] = x509CrlEntry.getSerialNumber();
-            data[i][1] = x509CrlEntry.getRevocationDate();
+            data[i][COL_SERIAL_NUMBER] = x509CrlEntry.getSerialNumber();
+            data[i][COL_REVOCATION_DATE] = x509CrlEntry.getRevocationDate();
+            data[i][COL_REASON] = getReasonString(x509CrlEntry.getRevocationReason());
         }
 
         fireTableDataChanged();
     }
 
+    /**
+     * Load the RevokedCertsTableModel with a map of RevokedEntry.
+     *
+     * @param mapRevokedEntry The X.509 CRL entries
+     */
+    public void load(Map<BigInteger, RevokedEntry> mapRevokedEntry) {
+        data = new Object[mapRevokedEntry.size()][COLUMN_COUNT];
+
+        int i = 0;
+        for (Map.Entry<BigInteger, RevokedEntry> pair : mapRevokedEntry.entrySet()) {
+            RevokedEntry entry = pair.getValue();
+            data[i][COL_SERIAL_NUMBER] = entry.getUserCertificateSerial();
+            data[i][COL_REVOCATION_DATE] = entry.getRevocationDate();
+            data[i][COL_REASON] = getReasonString(entry.getReason());
+            i++;
+        }
+        fireTableDataChanged();
+    }
+
+    private String getReasonString(CRLReason reason) {
+        String reasonString = "";
+        if (reason != null) {
+            reasonString = resCryptoX509.getString("CrlReason." + reason.ordinal() + ".text");
+        }
+        return reasonString;
+    }
+
     /**
      * Get the number of columns in the table.
      *
@@ -128,11 +167,15 @@ public Object getValueAt(int row, int col) {
      */
     @Override
     public Class<?> getColumnClass(int col) {
-        if (col == 0) {
-            return BigInteger.class;
-        } else {
-            return Date.class;
+        switch (col) {
+            case COL_SERIAL_NUMBER:
+                return BigInteger.class;
+            case COL_REVOCATION_DATE:
+                return Date.class;
+            case COL_REASON:
+                return String.class;
         }
+        throw new IndexOutOfBoundsException(String.valueOf(col));
     }
 
     /**
diff --git a/kse/src/main/java/org/kse/gui/dialogs/sign/DCrlReason.java b/kse/src/main/java/org/kse/gui/dialogs/sign/DCrlReason.java
index c21d94b89..ba45ef782 100644
--- a/kse/src/main/java/org/kse/gui/dialogs/sign/DCrlReason.java
+++ b/kse/src/main/java/org/kse/gui/dialogs/sign/DCrlReason.java
@@ -24,6 +24,7 @@
 import java.awt.Dialog;
 import java.awt.HeadlessException;
 import java.awt.event.KeyEvent;
+import java.security.cert.CRLReason;
 import java.security.cert.X509Certificate;
 import java.util.Date;
 import java.util.ResourceBundle;
@@ -39,7 +40,6 @@
 import javax.swing.KeyStroke;
 import javax.swing.UnsupportedLookAndFeelException;
 
-import org.bouncycastle.asn1.x509.CRLReason;
 import org.kse.crypto.x509.X500NameUtils;
 import org.kse.gui.components.JEscDialog;
 import org.kse.gui.PlatformUtil;
@@ -56,6 +56,7 @@ public class DCrlReason extends JEscDialog {
 
     private static final long serialVersionUID = 1L;
     private static ResourceBundle res = ResourceBundle.getBundle("org/kse/gui/dialogs/sign/resources");
+    private static ResourceBundle resCryptoX509 = ResourceBundle.getBundle("org/kse/crypto/x509/resources");
     private static final String CANCEL_KEY = "CANCEL_KEY";
 
     private JLabel jlSubject;
@@ -77,7 +78,7 @@ public class DCrlReason extends JEscDialog {
     private JButton jbOK;
     private JButton jbCancel;
 
-    private int reason;
+    private CRLReason reason;
     private boolean ok = false;
     private Date revocationDate;
     private X509Certificate cert;
@@ -108,35 +109,35 @@ private void initComponents() {
 
         jlReason = new JLabel(res.getString("DCrlReason.jlReason.text"));
 
-        jrbUnspecified = new JRadioButton(res.getString("DCrlReason.jrbUnspecified.text"));
-        jrbUnspecified.setToolTipText(res.getString("DCrlReason.jrbUnspecified.tooltip"));
+        jrbUnspecified = new JRadioButton(getCrlReasonText(CRLReason.UNSPECIFIED));
+        jrbUnspecified.setToolTipText(getCrlReasonTooltip(CRLReason.UNSPECIFIED));
 
-        jrbKeyCompromise = new JRadioButton(res.getString("DCrlReason.jrbKeyCompromise.text"));
-        jrbKeyCompromise.setToolTipText(res.getString("DCrlReason.jrbKeyCompromise.tooltip"));
+        jrbKeyCompromise = new JRadioButton(getCrlReasonText(CRLReason.KEY_COMPROMISE));
+        jrbKeyCompromise.setToolTipText(getCrlReasonTooltip(CRLReason.KEY_COMPROMISE));
 
-        jrbCACompromise = new JRadioButton(res.getString("DCrlReason.jrbCACompromise.text"));
-        jrbCACompromise.setToolTipText(res.getString("DCrlReason.jrbCACompromise.tooltip"));
+        jrbCACompromise = new JRadioButton(getCrlReasonText(CRLReason.CA_COMPROMISE));
+        jrbCACompromise.setToolTipText(getCrlReasonTooltip(CRLReason.CA_COMPROMISE));
 
-        jrbAffiliationChanged = new JRadioButton(res.getString("DCrlReason.jrbAffiliationChanged.text"));
-        jrbAffiliationChanged.setToolTipText(res.getString("DCrlReason.jrbAffiliationChanged.tooltip"));
+        jrbAffiliationChanged = new JRadioButton(getCrlReasonText(CRLReason.AFFILIATION_CHANGED));
+        jrbAffiliationChanged.setToolTipText(getCrlReasonTooltip(CRLReason.AFFILIATION_CHANGED));
 
-        jrbSuperseded = new JRadioButton(res.getString("DCrlReason.jrbSuperseded.text"));
-        jrbSuperseded.setToolTipText(res.getString("DCrlReason.jrbSuperseded.tooltip"));
+        jrbSuperseded = new JRadioButton(getCrlReasonText(CRLReason.SUPERSEDED));
+        jrbSuperseded.setToolTipText(getCrlReasonTooltip(CRLReason.SUPERSEDED));
 
-        jrbCessationOfOperation = new JRadioButton(res.getString("DCrlReason.jrbCessationOfOperation.text"));
-        jrbCessationOfOperation.setToolTipText(res.getString("DCrlReason.jrbCessationOfOperation.tooltip"));
+        jrbCessationOfOperation = new JRadioButton(getCrlReasonText(CRLReason.CESSATION_OF_OPERATION));
+        jrbCessationOfOperation.setToolTipText(getCrlReasonTooltip(CRLReason.CESSATION_OF_OPERATION));
 
-        jrbCertificateHold = new JRadioButton(res.getString("DCrlReason.jrbCertificateHold.text"));
-        jrbCertificateHold.setToolTipText(res.getString("DCrlReason.jrbCertificateHold.tooltip"));
+        jrbCertificateHold = new JRadioButton(getCrlReasonText(CRLReason.CERTIFICATE_HOLD));
+        jrbCertificateHold.setToolTipText(getCrlReasonTooltip(CRLReason.CERTIFICATE_HOLD));
 
-        jrbRemoveFromCR = new JRadioButton(res.getString("DCrlReason.jrbRemoveFromCR.text"));
-        jrbRemoveFromCR.setToolTipText(res.getString("DCrlReason.jrbRemoveFromCR.tooltip"));
+        jrbRemoveFromCR = new JRadioButton(getCrlReasonText(CRLReason.REMOVE_FROM_CRL));
+        jrbRemoveFromCR.setToolTipText(getCrlReasonTooltip(CRLReason.REMOVE_FROM_CRL));
 
-        jrbPrivilegeWithdrawn = new JRadioButton(res.getString("DCrlReason.jrbPrivilegeWithdrawn.text"));
-        jrbPrivilegeWithdrawn.setToolTipText(res.getString("DCrlReason.jrbPrivilegeWithdrawn.tooltip"));
+        jrbPrivilegeWithdrawn = new JRadioButton(getCrlReasonText(CRLReason.PRIVILEGE_WITHDRAWN));
+        jrbPrivilegeWithdrawn.setToolTipText(getCrlReasonTooltip(CRLReason.PRIVILEGE_WITHDRAWN));
 
-        jrbAACompromise = new JRadioButton(res.getString("DCrlReason.jrbAACompromise.text"));
-        jrbAACompromise.setToolTipText(res.getString("DCrlReason.jrbAACompromise.tooltip"));
+        jrbAACompromise = new JRadioButton(getCrlReasonText(CRLReason.AA_COMPROMISE));
+        jrbAACompromise.setToolTipText(getCrlReasonTooltip(CRLReason.AA_COMPROMISE));
 
         ButtonGroup buttonGroup = new ButtonGroup();
         buttonGroup.add(jrbUnspecified);
@@ -191,6 +192,14 @@ private void initComponents() {
         pack();
     }
 
+    private String getCrlReasonText(CRLReason reason) {
+        return resCryptoX509.getString("CrlReason." + reason.ordinal() + ".text");
+    }
+
+    private String getCrlReasonTooltip(CRLReason reason) {
+        return resCryptoX509.getString("CrlReason." + reason.ordinal() + ".tooltip");
+    }
+
     private void populate() {
         if (cert != null) {
             jdnSubject.setDistinguishedName(X500NameUtils.x500PrincipalToX500Name(cert.getSubjectX500Principal()));
@@ -208,32 +217,32 @@ private void closeDialog() {
 
     private void okPressed() {
         if (jrbUnspecified.isSelected()) {
-            reason = CRLReason.unspecified;
+            reason = CRLReason.UNSPECIFIED;
         } else if (jrbKeyCompromise.isSelected()) {
-            reason = CRLReason.keyCompromise;
+            reason = CRLReason.KEY_COMPROMISE;
         } else if (jrbCACompromise.isSelected()) {
-            reason = CRLReason.cACompromise;
+            reason = CRLReason.CA_COMPROMISE;
         } else if (jrbAffiliationChanged.isSelected()) {
-            reason = CRLReason.affiliationChanged;
+            reason = CRLReason.AFFILIATION_CHANGED;
         } else if (jrbSuperseded.isSelected()) {
-            reason = CRLReason.superseded;
+            reason = CRLReason.SUPERSEDED;
         } else if (jrbCessationOfOperation.isSelected()) {
-            reason = CRLReason.cessationOfOperation;
+            reason = CRLReason.CESSATION_OF_OPERATION;
         } else if (jrbCertificateHold.isSelected()) {
-            reason = CRLReason.certificateHold;
+            reason = CRLReason.CERTIFICATE_HOLD;
         } else if (jrbRemoveFromCR.isSelected()) {
-            reason = CRLReason.removeFromCRL;
+            reason = CRLReason.REMOVE_FROM_CRL;
         } else if (jrbPrivilegeWithdrawn.isSelected()) {
-            reason = CRLReason.privilegeWithdrawn;
+            reason = CRLReason.PRIVILEGE_WITHDRAWN;
         } else if (jrbAACompromise.isSelected()) {
-            reason = CRLReason.aACompromise;
+            reason = CRLReason.AA_COMPROMISE;
         }
         revocationDate = jdtRevocationDate.getDateTime();
         ok = true;
         closeDialog();
     }
 
-    public int getReason() {
+    public CRLReason getReason() {
         return reason;
     }
 
diff --git a/kse/src/main/java/org/kse/gui/dialogs/sign/JRevokedCerts.java b/kse/src/main/java/org/kse/gui/dialogs/sign/JRevokedCerts.java
index 06bf2264c..23fde1518 100644
--- a/kse/src/main/java/org/kse/gui/dialogs/sign/JRevokedCerts.java
+++ b/kse/src/main/java/org/kse/gui/dialogs/sign/JRevokedCerts.java
@@ -32,6 +32,7 @@
 import java.security.NoSuchProviderException;
 import java.security.SignatureException;
 import java.security.cert.CRLException;
+import java.security.cert.CRLReason;
 import java.security.cert.CertificateException;
 import java.security.cert.X509CRL;
 import java.security.cert.X509CRLEntry;
@@ -64,7 +65,6 @@
 
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
-import org.bouncycastle.asn1.x509.CRLReason;
 import org.kse.crypto.CryptoException;
 import org.kse.crypto.filetype.CryptoFileType;
 import org.kse.crypto.filetype.CryptoFileUtil;
@@ -74,6 +74,9 @@
 import org.kse.gui.JKseTable;
 import org.kse.gui.KseFrame;
 import org.kse.gui.PlatformUtil;
+import org.kse.gui.dialogs.RevokedCertsTableCellRend;
+import org.kse.gui.dialogs.RevokedCertsTableHeadRend;
+import org.kse.gui.dialogs.RevokedCertsTableModel;
 import org.kse.gui.error.DProblem;
 import org.kse.gui.error.Problem;
 
@@ -201,11 +204,11 @@ private void populate() {
                 if (entry.getRevocationReason() == null) {
                     mapRevokedEntry.put(entry.getSerialNumber(),
                                         new RevokedEntry(entry.getSerialNumber(), entry.getRevocationDate(),
-                                                         CRLReason.unspecified));
+                                                         CRLReason.UNSPECIFIED));
                 } else {
                     mapRevokedEntry.put(entry.getSerialNumber(),
                                         new RevokedEntry(entry.getSerialNumber(), entry.getRevocationDate(),
-                                                         entry.getRevocationReason().ordinal()));
+                                                         entry.getRevocationReason()));
                 }
             }
             RevokedCertsTableModel revokedCertsTableModel = (RevokedCertsTableModel) jtRevokedCerts.getModel();
@@ -238,7 +241,7 @@ private void insertCertificateTable(X509Certificate cerRev) {
                 dCRLReason.setLocationRelativeTo(parent);
                 dCRLReason.setVisible(true);
                 if (dCRLReason.isOk()) {
-                    int reason = dCRLReason.getReason();
+                    CRLReason reason = dCRLReason.getReason();
                     Date revocationDate = dCRLReason.getRevocationDate();
                     mapRevokedEntry.put(cerRev.getSerialNumber(),
                                         new RevokedEntry(cerRev.getSerialNumber(), revocationDate, reason));
diff --git a/kse/src/main/java/org/kse/gui/dialogs/sign/RevokedCertsTableCellRend.java b/kse/src/main/java/org/kse/gui/dialogs/sign/RevokedCertsTableCellRend.java
deleted file mode 100644
index 613ddd1f3..000000000
--- a/kse/src/main/java/org/kse/gui/dialogs/sign/RevokedCertsTableCellRend.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2004 - 2013 Wayne Grant
- *           2013 - 2025 Kai Kramer
- *
- * This file is part of KeyStore Explorer.
- *
- * KeyStore Explorer is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KeyStore Explorer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KeyStore Explorer.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.kse.gui.dialogs.sign;
-
-import java.awt.Component;
-import java.math.BigInteger;
-import java.util.Date;
-
-import javax.swing.JLabel;
-import javax.swing.JTable;
-import javax.swing.border.EmptyBorder;
-import javax.swing.table.DefaultTableCellRenderer;
-
-import org.kse.utilities.StringUtils;
-
-/**
- * Custom cell renderer for the cells of the RevokedCerts table of DViewCrl.
- */
-public class RevokedCertsTableCellRend extends DefaultTableCellRenderer {
-
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * Returns the rendered cell.
-     *
-     * @param jtRevokedCerts The JTable
-     * @param value          The value to assign to the cell
-     * @param isSelected     True if cell is selected
-     * @param row            The row of the cell to render
-     * @param col            The column of the cell to render
-     * @param hasFocus       If true, render cell appropriately
-     * @return The rendered cell
-     */
-    @Override
-    public Component getTableCellRendererComponent(JTable jtRevokedCerts, Object value, boolean isSelected,
-                                                   boolean hasFocus, int row, int col) {
-        JLabel cell = (JLabel) super.getTableCellRendererComponent(jtRevokedCerts, value, isSelected, hasFocus, row,
-                                                                   col);
-
-        if (col == 0) {
-            cell.setText(formatSerialNumberAsHexString((BigInteger) value));
-        } else {
-            cell.setText(StringUtils.formatDate((Date) value));
-        }
-
-        cell.setBorder(new EmptyBorder(0, 5, 0, 5));
-
-        return cell;
-    }
-
-    private String formatSerialNumberAsHexString(BigInteger serialNumber) {
-        // The string is divided by spaces into groups of four hex characters.
-        String hexSerialNumber = serialNumber.toString(16).toUpperCase();
-
-        StringBuilder strBuff = new StringBuilder();
-
-        strBuff.append("0x");
-
-        for (int i = 0; i < hexSerialNumber.length(); i++) {
-            strBuff.append(hexSerialNumber.charAt(i));
-
-            if ((i + 1) % 4 == 0 && i + 1 != hexSerialNumber.length()) {
-                strBuff.append(' ');
-            }
-        }
-
-        return strBuff.toString();
-    }
-}
diff --git a/kse/src/main/java/org/kse/gui/dialogs/sign/RevokedCertsTableHeadRend.java b/kse/src/main/java/org/kse/gui/dialogs/sign/RevokedCertsTableHeadRend.java
deleted file mode 100644
index 9291cf4f3..000000000
--- a/kse/src/main/java/org/kse/gui/dialogs/sign/RevokedCertsTableHeadRend.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2004 - 2013 Wayne Grant
- *           2013 - 2025 Kai Kramer
- *
- * This file is part of KeyStore Explorer.
- *
- * KeyStore Explorer is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KeyStore Explorer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KeyStore Explorer.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.kse.gui.dialogs.sign;
-
-import java.awt.Component;
-import java.util.ResourceBundle;
-
-import javax.swing.JLabel;
-import javax.swing.JTable;
-import javax.swing.table.DefaultTableCellRenderer;
-import javax.swing.table.TableCellRenderer;
-
-/**
- * Custom cell renderer for the headers of the RevokedCerts table of DViewCrl.
- */
-public class RevokedCertsTableHeadRend extends DefaultTableCellRenderer {
-    private static final long serialVersionUID = 1L;
-
-    private static ResourceBundle res = ResourceBundle.getBundle("org/kse/gui/dialogs/resources");
-
-    private TableCellRenderer delegate;
-
-    /**
-     * Construct a new RevokedCertsTableHeadRend.
-     *
-     * @param delegate
-     */
-    public RevokedCertsTableHeadRend(TableCellRenderer delegate) {
-        this.delegate = delegate;
-    }
-
-    /**
-     * Returns the rendered header cell for the supplied value and column.
-     *
-     * @param jTable     The JTable
-     * @param value      The value to assign to the cell
-     * @param isSelected True if cell is selected
-     * @param hasFocus   If true, render cell appropriately
-     * @param row        The row of the cell to render
-     * @param col        The column of the cell to render
-     * @return The rendered cell
-     */
-    @Override
-    public Component getTableCellRendererComponent(JTable jTable, Object value, boolean isSelected, boolean hasFocus,
-                                                   int row, int col) {
-
-        Component c = delegate.getTableCellRendererComponent(jTable, value, isSelected, hasFocus, row, col);
-
-        if (c instanceof JLabel) {
-            JLabel header = (JLabel) c;
-
-            if (col == 0) {
-                header.setToolTipText(res.getString("RevokedCertsTableHeadRend.SerialNumberColumn.tooltip"));
-            } else {
-                header.setToolTipText(res.getString("RevokedCertsTableHeadRend.RevocationDateColumn.tooltip"));
-            }
-        }
-
-        return c;
-    }
-}
diff --git a/kse/src/main/java/org/kse/gui/dialogs/sign/RevokedCertsTableModel.java b/kse/src/main/java/org/kse/gui/dialogs/sign/RevokedCertsTableModel.java
deleted file mode 100644
index 29bd6412c..000000000
--- a/kse/src/main/java/org/kse/gui/dialogs/sign/RevokedCertsTableModel.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright 2004 - 2013 Wayne Grant
- *           2013 - 2025 Kai Kramer
- *
- * This file is part of KeyStore Explorer.
- *
- * KeyStore Explorer is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * KeyStore Explorer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with KeyStore Explorer.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.kse.gui.dialogs.sign;
-
-import java.math.BigInteger;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.ResourceBundle;
-
-import javax.swing.table.AbstractTableModel;
-
-/**
- * The table model used to display a map of RevokedEntry sorted by
- * serial number.
- */
-public class RevokedCertsTableModel extends AbstractTableModel {
-    private static final long serialVersionUID = 1L;
-
-    private static ResourceBundle res = ResourceBundle.getBundle("org/kse/gui/dialogs/resources");
-
-    private String[] columnNames;
-    private Object[][] data;
-
-    /**
-     * Construct a new RevokedCertsTableModel.
-     */
-    public RevokedCertsTableModel() {
-        columnNames = new String[2];
-        columnNames[0] = res.getString("RevokedCertsTableModel.SerialNumberColumn");
-        columnNames[1] = res.getString("RevokedCertsTableModel.RevocationDateColumn");
-
-        data = new Object[0][0];
-    }
-
-    /**
-     * Load the RevokedCertsTableModel with a map of RevokedEntry.
-     *
-     * @param mapRevokedEntry The X.509 CRL entries
-     */
-    public void load(Map<BigInteger, RevokedEntry> mapRevokedEntry) {
-        data = new Object[mapRevokedEntry.size()][2];
-
-        int i = 0;
-        for (Map.Entry<BigInteger, RevokedEntry> pair : mapRevokedEntry.entrySet()) {
-            RevokedEntry entry = pair.getValue();
-            data[i][0] = entry.getUserCertificateSerial();
-            data[i][1] = entry.getRevocationDate();
-            i++;
-        }
-        fireTableDataChanged();
-    }
-
-    /**
-     * Get the number of columns in the table.
-     *
-     * @return The number of columns
-     */
-    @Override
-    public int getColumnCount() {
-        return columnNames.length;
-    }
-
-    /**
-     * Get the number of rows in the table.
-     *
-     * @return The number of rows
-     */
-    @Override
-    public int getRowCount() {
-        return data.length;
-    }
-
-    /**
-     * Get the name of the column at the given position.
-     *
-     * @param col The column position
-     * @return The column name
-     */
-    @Override
-    public String getColumnName(int col) {
-        return columnNames[col];
-    }
-
-    /**
-     * Get the cell value at the given row and column position.
-     *
-     * @param row The row position
-     * @param col The column position
-     * @return The cell value
-     */
-    @Override
-    public Object getValueAt(int row, int col) {
-        return data[row][col];
-    }
-
-    /**
-     * Get the class at of the cells at the given column position.
-     *
-     * @param col The column position
-     * @return The column cells' class
-     */
-    @Override
-    public Class<?> getColumnClass(int col) {
-        if (col == 0) {
-            return BigInteger.class;
-        } else {
-            return Date.class;
-        }
-    }
-
-    /**
-     * Is the cell at the given row and column position editable?
-     *
-     * @param row The row position
-     * @param col The column position
-     * @return True if the cell is editable, false otherwise
-     */
-    @Override
-    public boolean isCellEditable(int row, int col) {
-        return false;
-    }
-}
diff --git a/kse/src/main/java/org/kse/gui/dialogs/sign/RevokedEntry.java b/kse/src/main/java/org/kse/gui/dialogs/sign/RevokedEntry.java
index d95a764bb..565e3e84a 100644
--- a/kse/src/main/java/org/kse/gui/dialogs/sign/RevokedEntry.java
+++ b/kse/src/main/java/org/kse/gui/dialogs/sign/RevokedEntry.java
@@ -21,6 +21,7 @@
 package org.kse.gui.dialogs.sign;
 
 import java.math.BigInteger;
+import java.security.cert.CRLReason;
 import java.util.Date;
 
 /**
@@ -30,7 +31,7 @@ public class RevokedEntry {
 
     private BigInteger userCertificateSerial;
     private Date revocationDate;
-    private int reason;
+    private CRLReason reason;
 
     /**
      * Construct a new RevokedEntry.
@@ -39,7 +40,7 @@ public class RevokedEntry {
      * @param revocationDate        Revocation date
      * @param reason                Reason why a certificate is revoked
      */
-    public RevokedEntry(BigInteger userCertificateSerial, Date revocationDate, int reason) {
+    public RevokedEntry(BigInteger userCertificateSerial, Date revocationDate, CRLReason reason) {
         super();
         this.userCertificateSerial = userCertificateSerial;
         this.revocationDate = revocationDate;
@@ -69,7 +70,7 @@ public Date getRevocationDate() {
      *
      * @return reason.
      */
-    public int getReason() {
+    public CRLReason getReason() {
         return reason;
     }
 
diff --git a/kse/src/main/resources/org/kse/crypto/x509/resources.properties b/kse/src/main/resources/org/kse/crypto/x509/resources.properties
index be03aef98..5cecf00c6 100644
--- a/kse/src/main/resources/org/kse/crypto/x509/resources.properties
+++ b/kse/src/main/resources/org/kse/crypto/x509/resources.properties
@@ -1,6 +1,4 @@
 
-AaCompromiseCrlReason = AA Compromise (10)
-
 AaCompromiseReasonFlag = AA Compromise
 
 AcceptableCertificatePoliciesCertExt = Acceptable Certificate Policies
@@ -28,8 +26,6 @@ Admission.RegistrationNumber  = Registration Number: {0}
 
 AdobePDFSigningExtKeyUsage = Adobe PDF Signing (1.2.840.113583.1.1.5)
 
-AffiliationChangedCrlReason = Affiliation Changed (3)
-
 AffiliationChangedReasonFlag = Affiliation Changed
 
 AnyExtendedKeyUsageExtKeyUsage = Any Extended Key Usage (2.5.29.37.0)
@@ -72,8 +68,6 @@ BiometricInfo.HashAlgorithm       = Hash Algorithm: {0}
 BiometricInfo.SourceDataUri       = Source Data URI: {0}
 BiometricInfo.TypeOfBiometricData = Type: {0}
 
-CaCompromiseCrlReason = CA Compromise (2)
-
 CaCompromiseReasonFlag = CA Compromise
 
 CaIssuersAccessMethod = CA Issuers (1.3.6.1.5.5.7.48.2)
@@ -82,8 +76,6 @@ CaRepositoryAccessMethod = CA Repository (1.3.6.1.5.5.7.48.5)
 
 CertificateGenFailed.exception.message = Certificate generation failed.
 
-CertificateHoldCrlReason = Certificate Hold (6)
-
 CertificateHoldReasonFlag = Certificate Hold
 
 CertificateIssuer = Certificate Issuer:
@@ -98,8 +90,6 @@ CertificatePolicy = Certificate Policy [{0}]:
 
 CertificateSerialNumber = Certificate Serial Number: {0}
 
-CessationOfOperationCrlReason = Cessation of Operation (5)
-
 CessationOfOperationReasonFlag = Cessation of Operation
 
 ChainModel = Chain Model
@@ -126,6 +116,28 @@ CrlDistributionPointsObsCertExt = CRL Distribution Points (obsolete extension)
 
 CrlNumberCertExt = CRL Number
 
+CrlReason.0.text = Unspecified (0)
+CrlReason.0.tooltip = This reason indicates that it is unspecified as to why the certificate has been revoked.
+CrlReason.1.text = Key Compromise (1)
+CrlReason.1.tooltip = This reason indicates that it is known or suspected that the certificate subject's private key has been compromised.
+CrlReason.2.text = CA Compromise (2)
+CrlReason.2.tooltip = This reason indicates that it is known or suspected that the CA's private key has been compromised.
+CrlReason.3.text = Affiliation Changed (3)
+CrlReason.3.tooltip = This reason indicates that the subject's name or other information in the certificate has changed.
+CrlReason.4.text = Superseded (4)
+CrlReason.4.tooltip = This reason indicates that the certificate has been superseded.
+CrlReason.5.text = Cessation of Operation (5)
+CrlReason.5.tooltip = This reason indicates that the certificate is no longer needed.
+CrlReason.6.text = Certificate Hold (6)
+CrlReason.6.tooltip = This reason indicates that the certificate has been put on hold.
+#CrlReason 7 is unknown - not used
+CrlReason.8.text = Remove from CRL (8)
+CrlReason.8.tooltip = This reason indicates that the certificate was previously on hold and should be removed from the CRL.
+CrlReason.9.text = Privilege Withdrawn (9)
+CrlReason.9.tooltip = This reason indicates that the privileges granted to the subject of the certificate have been withdrawn.
+CrlReason.10.text = AA Compromise (10)
+CrlReason.10.tooltip = This reason indicates that it is known or suspected that the AA's (Attribute Authority) private key has been compromised.
+
 CrlScopeCertExt = CRL Scope
 
 CrlSignKeyUsage = CRL Signing
@@ -250,8 +262,6 @@ KeyAgreementKeyUsage = Key Agreement
 
 KeyCertSignKeyUsage = Certificate Signing
 
-KeyCompromiseCrlReason = Key Compromise (1)
-
 KeyCompromiseReasonFlag = Key Compromise
 
 KeyEnciphermentKeyUsage = Key Encipherment
@@ -423,8 +433,6 @@ PrimaryKeyUsageRestrictionObsCertExt = Primary Key Usage Restriction (obsolete e
 
 PrivateKeyUsagePeriodCertExt = Private Key Usage Period
 
-PrivilegeWithdrawnCrlReason = Privilege Withdrawn (9)
-
 PrivilegeWithdrawnReasonFlag = Privilege Withdrawn
 
 Procuration = Procuration
@@ -471,8 +479,6 @@ QCType.Web  = Web
 
 ReasonCodeCertExt = Reason Code
 
-RemoveFromCrlCrlReason = Remove from CRL (8)
-
 RequireExplicitPolicy = Require Explicit Policy Skip Certificates: {0}
 
 ReservedNetscapeCertificateType = Reserved
@@ -552,8 +558,6 @@ SubjectKeyIdentifierCertExt = Subject Key Identifier (SKI)
 
 SubtreesConstraintObsCertExt = Subtrees Constraint (obsolete extension)
 
-SupersededCrlReason = Superseded (4)
-
 SupersededReasonFlag = Superseded
 
 TSLSignExtKeyUsage = Trusted-service Status List (TSL) Signing (0.4.0.2231.3.0)
@@ -568,8 +572,6 @@ TimeStampingExtKeyUsage = Time Stamping (1.3.6.1.5.5.7.3.8)
 
 TitleAttributeType = TITLE
 
-UnspecifiedCrlReason = Unspecified (0)
-
 UnstructuredAddressAttributeType = UNSTRUCTUREDADDRESS
 
 UnstructuredNameAttributeType = UNSTRUCTUREDNAME
diff --git a/kse/src/main/resources/org/kse/crypto/x509/resources_de.properties b/kse/src/main/resources/org/kse/crypto/x509/resources_de.properties
index 5e6287e73..92166d37e 100644
--- a/kse/src/main/resources/org/kse/crypto/x509/resources_de.properties
+++ b/kse/src/main/resources/org/kse/crypto/x509/resources_de.properties
@@ -1,7 +1,5 @@
 #Generated by ResourceBundle Editor (http://essiembre.github.io/eclipse-rbe/)
 
-AaCompromiseCrlReason = Authorit\u00E4tsattribut kompromittiert (10)
-
 AaCompromiseReasonFlag = Authorit\u00E4tsattribut kompromittiert
 
 AcceptableCertificatePoliciesCertExt = Zul\u00E4ssige Zertifikats-Richtlinien
@@ -29,8 +27,6 @@ Admission.RegistrationNumber  = Registrierungsnummer: {0}
 
 AdobePDFSigningExtKeyUsage = Adobe PDF Signierung (1.2.840.113583.1.1.5)
 
-AffiliationChangedCrlReason = Zugeh\u00F6rigkeit ge\u00E4ndert (3)
-
 AffiliationChangedReasonFlag = Zugeh\u00F6rigkeit ge\u00E4ndert
 
 AnyExtendedKeyUsageExtKeyUsage = Jede erweiterte Schl\u00FCsselverwendung (2.5.29.37.0)
@@ -67,8 +63,6 @@ BiometricInfo.HashAlgorithm       = Hash-Algorithmus: {0}
 BiometricInfo.SourceDataUri       = URI der Quelldaten: {0}
 BiometricInfo.TypeOfBiometricData = Typ: {0}
 
-CaCompromiseCrlReason = CA Kompromittierung (2)
-
 CaCompromiseReasonFlag = CA Kompromittierung
 
 CaIssuersAccessMethod = CA Aussteller (1.3.6.1.5.5.7.48.2)
@@ -77,8 +71,6 @@ CaRepositoryAccessMethod = CA Verzeichnis (1.3.6.1.5.5.7.48.5)
 
 CertificateGenFailed.exception.message = Zertifikaterstellung fehlgeschlagen.
 
-CertificateHoldCrlReason = Zertifikat On Hold (6)
-
 CertificateHoldReasonFlag = Zertifikat On Hold
 
 CertificateIssuer = Zertifikataussteller:
@@ -93,8 +85,6 @@ CertificatePolicy = Zertifikatsrichtlinie [{0}]:
 
 CertificateSerialNumber = Seriennummer des Zertifikats: {0}
 
-CessationOfOperationCrlReason = Betrieb eingestellt (5)
-
 CessationOfOperationReasonFlag = Betrieb eingestellt
 
 ChainModel = Kettenmodell
@@ -121,6 +111,28 @@ CrlDistributionPointsObsCertExt = CRL Verteilungspunkte (veraltete Erweiterung)
 
 CrlNumberCertExt = CRL Nummer
 
+CrlReason.0.text = Unspezifiziert (0)
+CrlReason.0.tooltip = Es wird kein spezifischer Grund f\u00FCr die Sperrung des Zertifikats angegeben.
+CrlReason.1.text = Schl\u00FCssel Kompromittierung (1)
+CrlReason.1.tooltip = Dieser Grund zeigt an, dass bekannt ist oder vermutet wird, dass der private Schl\u00FCssel des Zertifikatsinhabers kompromittiert wurde.
+CrlReason.2.text = CA Kompromittierung (2)
+CrlReason.2.tooltip = Dieser Grund zeigt an, dass bekannt ist oder vermutet wird, dass der private Schl\u00FCssel der CA kompromittiert wurde.
+CrlReason.3.text = Zugeh\u00F6rigkeit ge\u00E4ndert (3)
+CrlReason.3.tooltip = Dieser Grund zeigt an, dass sich der Name oder andere Informationen im Zertifikat ge\u00E4ndert haben.
+CrlReason.4.text = Ersetzt (4)
+CrlReason.4.tooltip = Dieser Grund gibt an, dass das Zertifikat durch ein neues ersetzt wurde (z.B. wegen einer defekten Smartcard).
+CrlReason.5.text = Betrieb eingestellt (5)
+CrlReason.5.tooltip = Dieser Grund zeigt an, dass das Zertifikat au\u00DFer Betrieb genommen wurde und nicht l\u00E4nger ben\u00F6tigt wird.
+CrlReason.6.text = Zertifikat On Hold (6)
+CrlReason.6.tooltip = Dieser Grund zeigt an, dass das Zertifikat vor\u00FCbergehend gesperrt wurde und zu einem sp\u00E4teren Zeitpunkt entweder wieder entsperrt oder dauerhaft gesperrt werden k\u00F6nnte.
+#CrlReason 7 is unknown - not used
+CrlReason.8.text = Entfernen von der Sperrliste (8)
+CrlReason.8.tooltip = Dieser Grund gibt an, dass das Zertifikat vorher tempor\u00E4r gesperrt war und zuk\u00FCnftig aus der CRL entfernt werden soll.
+CrlReason.9.text = Berechtigung zur\u00FCckgezogen (9)
+CrlReason.9.tooltip = Dieser Grund gibt an, dass dem Zertifikatsinhaber die mit dem Zertifikat verbundenen Berechtigungen entzogen worden sind.
+CrlReason.10.text = AA Kompromittierung (10)
+CrlReason.10.tooltip = Dieser Grund zeigt an, dass bekannt ist oder vermutet wird, dass der private Schl\u00FCssel der AA (Attribute Authority) kompromittiert wurde.
+
 CrlScopeCertExt = CRL Bereich
 
 CrlSignKeyUsage = CRL Signierung
@@ -245,8 +257,6 @@ KeyAgreementKeyUsage = Schl\u00FCsseleinigung
 
 KeyCertSignKeyUsage = Zertifikatssignierung
 
-KeyCompromiseCrlReason = Schl\u00FCssel Kompromittierung (1)
-
 KeyCompromiseReasonFlag = Schl\u00FCssel Kompromittierung
 
 KeyEnciphermentKeyUsage = Verschl\u00FCsselung von Schl\u00FCsseln
@@ -418,8 +428,6 @@ PrimaryKeyUsageRestrictionObsCertExt = Nutzungsbeschr\u00E4nkung des Prim\u00E4r
 
 PrivateKeyUsagePeriodCertExt = Nutzungszeitraum des Prim\u00E4rschl\u00FCssels
 
-PrivilegeWithdrawnCrlReason = Berechtigung zur\u00FCckgezogen (9)
-
 PrivilegeWithdrawnReasonFlag = Berechtigung zur\u00FCckgezogen
 
 Procuration = Vermittlung
@@ -462,8 +470,6 @@ QCType.Web  = Web
 
 ReasonCodeCertExt = Code der Ursache
 
-RemoveFromCrlCrlReason = Entfernen von der Sperrliste (8)
-
 RequireExplicitPolicy = Ben\u00F6tigte Skip Zertifikate f\u00FCr explizite Richtlinie: {0}
 
 ReservedNetscapeCertificateType = Reserviert
@@ -543,8 +549,6 @@ SubjectKeyIdentifierCertExt = Schl\u00FCsselkennung des Antragsstellers
 
 SubtreesConstraintObsCertExt = Beschr\u00E4nkung des Unterbaums (veraltete Erweiterung)
 
-SupersededCrlReason = Ersetzt (4)
-
 SupersededReasonFlag = Ersetzt
 
 TSLSignExtKeyUsage = Trusted-Service-Statusliste (TSL) signieren (0.4.0.2231.3.0)
@@ -559,8 +563,6 @@ TimeStampingExtKeyUsage = Zeitstempel (1.3.6.1.5.5.7.3.8)
 
 TitleAttributeType = Titel
 
-UnspecifiedCrlReason = Unspezifiziert (0)
-
 UnstructuredAddressAttributeType = Unstrukturierte Adresse
 
 UnstructuredNameAttributeType = Unstrukturierter Name
@@ -600,3 +602,4 @@ VeriSignUnknown = VeriSign Unbekannt
 custom = > Custom Erweiterung <
 
 unknown = (Unbekannte OID)
+
diff --git a/kse/src/main/resources/org/kse/crypto/x509/resources_es.properties b/kse/src/main/resources/org/kse/crypto/x509/resources_es.properties
index 243ec7f28..e3de16134 100644
--- a/kse/src/main/resources/org/kse/crypto/x509/resources_es.properties
+++ b/kse/src/main/resources/org/kse/crypto/x509/resources_es.properties
@@ -1,6 +1,4 @@
 
-AaCompromiseCrlReason = Compromiso de AA (10)
-
 AaCompromiseReasonFlag = Compromiso de AA
 
 AcceptableCertificatePoliciesCertExt = Pol\u00EDticas de Certificado Aceptables
@@ -28,8 +26,6 @@ Admission.RegistrationNumber  = N\u00FAmero de Registro: {0}
 
 AdobePDFSigningExtKeyUsage = Firma de Adobe PDF (1.2.840.113583.1.1.5)
 
-AffiliationChangedCrlReason = Afiliaci\u00F3n Cambiada (3)
-
 AffiliationChangedReasonFlag = Afiliaci\u00F3n Cambiada
 
 AnyExtendedKeyUsageExtKeyUsage = Cualquier Uso de Clave Extendido (2.5.29.37.0)
@@ -72,8 +68,6 @@ BiometricInfo.HashAlgorithm       = Algoritmo Hash: {0}
 BiometricInfo.SourceDataUri       = URI de Datos Fuente: {0}
 BiometricInfo.TypeOfBiometricData = Tipo: {0}
 
-CaCompromiseCrlReason = Compromiso de CA (2)
-
 CaCompromiseReasonFlag = Compromiso de CA
 
 CaIssuersAccessMethod = Emisores de CA (1.3.6.1.5.5.7.48.2)
@@ -82,8 +76,6 @@ CaRepositoryAccessMethod = Repositorio de CA (1.3.6.1.5.5.7.48.5)
 
 CertificateGenFailed.exception.message = Falla en la generaci\u00F3n del certificado.
 
-CertificateHoldCrlReason = Certificado en Espera (6)
-
 CertificateHoldReasonFlag = Certificado en Espera
 
 CertificateIssuer = Emisor del Certificado:
@@ -98,8 +90,6 @@ CertificatePolicy = Pol\u00EDtica de Certificado [{0}]:
 
 CertificateSerialNumber = N\u00FAmero de Serie del Certificado: {0}
 
-CessationOfOperationCrlReason = Cesaci\u00F3n de Operaciones (5)
-
 CessationOfOperationReasonFlag = Causa de cese de operaciones
 
 ChainModel = Modelo de cadena
@@ -126,6 +116,28 @@ CrlDistributionPointsObsCertExt = Puntos de distribuci\u00F3n de CRL (extensi\u0
 
 CrlNumberCertExt = N\u00FAmero de CRL
 
+CrlReason.0.text = No especificado (0)
+CrlReason.0.tooltip = Esta raz\u00F3n indica que no se especifica por qu\u00E9 se ha revocado el certificado.
+CrlReason.1.text = Compromiso de Clave (1)
+CrlReason.1.tooltip = Esta raz\u00F3n indica que se sabe o se sospecha que la clave privada del sujeto del certificado se ha visto comprometida.
+CrlReason.2.text = Compromiso de CA (2)
+CrlReason.2.tooltip = Esta raz\u00F3n indica que se sabe o se sospecha que la clave privada de la CA se ha visto comprometida.
+CrlReason.3.text = Afiliaci\u00F3n Cambiada (3)
+CrlReason.3.tooltip = Esta raz\u00F3n indica que el nombre del sujeto u otra informaci\u00F3n del certificado ha cambiado.
+CrlReason.4.text = Sustituido (4)
+CrlReason.4.tooltip = Esta raz\u00F3n indica que el certificado ha sido sustituido.
+CrlReason.5.text = Cesaci\u00F3n de Operaci\u00F3n (5)
+CrlReason.5.tooltip = Esta raz\u00F3n indica que el certificado ya no es necesario.
+CrlReason.6.text = Certificado en Espera (6)
+CrlReason.6.tooltip = Esta raz\u00F3n indica que el certificado se ha puesto en espera.
+#CrlReason 7 is unknown - not used
+CrlReason.8.text = Eliminar de CRL (8)
+CrlReason.8.tooltip = Esta raz\u00F3n indica que el certificado estaba previamente en espera y debe eliminarse de la CRL.
+CrlReason.9.text = Privilegio Retirado (9)
+CrlReason.9.tooltip = Esta raz\u00F3n indica que los privilegios otorgados al sujeto del certificado se han retirado.
+CrlReason.10.text = Compromiso de AA (10)
+CrlReason.10.tooltip = Esta raz\u00F3n indica que se sabe o se sospecha que la clave privada de la AA (Autoridad de Atributos) se ha visto comprometida.
+
 CrlScopeCertExt = Alcance de CRL
 
 CrlSignKeyUsage = Firma de CRL
@@ -250,8 +262,6 @@ KeyAgreementKeyUsage = Acuerdo de Clave
 
 KeyCertSignKeyUsage = Firma de Certificado
 
-KeyCompromiseCrlReason = Compromiso de Clave (1)
-
 KeyCompromiseReasonFlag = Compromiso de Clave
 
 KeyEnciphermentKeyUsage = Cifrado de Clave
@@ -423,8 +433,6 @@ PrimaryKeyUsageRestrictionObsCertExt = Restricci\u00F3n de Uso de Clave Principa
 
 PrivateKeyUsagePeriodCertExt = Per\u00EDodo de Uso de Clave Privada
 
-PrivilegeWithdrawnCrlReason = Privilegio Retirado (9)
-
 PrivilegeWithdrawnReasonFlag = Privilegio Retirado
 
 Procuration = Procuraci\u00F3n
@@ -471,8 +479,6 @@ QCType.Web  = Web
 
 ReasonCodeCertExt = C\u00F3digo de Raz\u00F3n
 
-RemoveFromCrlCrlReason = Eliminar de CRL (8)
-
 RequireExplicitPolicy = Requerir Pol\u00EDtica Expl\u00EDcita: Omitir Certificados: {0}
 
 ReservedNetscapeCertificateType = Reservado
@@ -552,8 +558,6 @@ SubjectKeyIdentifierCertExt = Identificador de clave del sujeto (SKI)
 
 SubtreesConstraintObsCertExt = Restricci\u00F3n de sub\u00E1rboles (extensi\u00F3n obsoleta)
 
-SupersededCrlReason = Sustituida (4)
-
 SupersededReasonFlag = Sustituida
 
 TSLSignExtKeyUsage = Firma de lista de estado de servicio confiable (TSL) (0.4.0.2231.3.0)
@@ -568,8 +572,6 @@ TimeStampingExtKeyUsage = Marca de tiempo (1.3.6.1.5.5.7.3.8)
 
 TitleAttributeType = T\u00EDTULO
 
-UnspecifiedCrlReason = No especificado (0)
-
 UnstructuredAddressAttributeType = DIRECCI\u00F3N NO ESTRUCTURADA
 
 UnstructuredNameAttributeType = NOMBRE NO ESTRUCTURADO
diff --git a/kse/src/main/resources/org/kse/crypto/x509/resources_fr.properties b/kse/src/main/resources/org/kse/crypto/x509/resources_fr.properties
index 0fdc05c44..b0533960b 100644
--- a/kse/src/main/resources/org/kse/crypto/x509/resources_fr.properties
+++ b/kse/src/main/resources/org/kse/crypto/x509/resources_fr.properties
@@ -1,5 +1,4 @@
 
-AaCompromiseCrlReason = Autorité d\u2019attributs compromise (AA compromise) (10)
 AaCompromiseReasonFlag = Autorité d\u2019attributs compromise
 AcceptableCertificatePoliciesCertExt = Politique de certification acceptable
 AcceptablePrivilegePoliciesCertExt = Politique de privilèges acceptables
@@ -18,7 +17,6 @@ Admission.ProfessionItem = Élément sur la profession : {0}
 Admission.ProfessionOID = OID de la profession : {0}
 Admission.RegistrationNumber = Numéro d\u2019enregistrement : {0}
 AdobePDFSigningExtKeyUsage = Signature de documents PDF (1.2.840.113583.1.1.5)
-AffiliationChangedCrlReason = Changement d\u2019affiliation (3)
 AffiliationChangedReasonFlag = Changement d\u2019affiliation
 AnyExtendedKeyUsageExtKeyUsage = Tout usage étendu de clef  (2.5.29.37.0)
 AttributeDescriptorCertExt = Descripteur d\u2019attribut (AD)
@@ -39,12 +37,10 @@ BiometricInfo.BiometricDataHash = Empreinte biométrique : {0}
 BiometricInfo.HashAlgorithm = Algorithme de l\u2019empreinte : {0}
 BiometricInfo.SourceDataUri = Adresse URI de la source de données : {0}
 BiometricInfo.TypeOfBiometricData = Type : {0}
-CaCompromiseCrlReason = Autorité compromise (2)
 CaCompromiseReasonFlag = Autorité de certification compromise
 CaIssuersAccessMethod = Émetteur d\u2019autorité (1.3.6.1.5.5.7.48.2)
 CaRepositoryAccessMethod = Dépôt d\u2019autorité (1.3.6.1.5.5.7.48.5)
 CertificateGenFailed.exception.message = La génération du certificat a échoué.
-CertificateHoldCrlReason = Suspension du certificat (6)
 CertificateHoldReasonFlag = Certificat suspendu
 CertificateIssuer = Émetteur du certificat :
 CertificateIssuerCertExt = Émetteur du certificat
@@ -52,7 +48,6 @@ CertificatePoliciesCertExt = Politique de certification (CP)
 CertificatePoliciesObsCertExt = Politique de certification (extension obsolète)
 CertificatePolicy = Politique de certification [{0}] :
 CertificateSerialNumber = Numéro de série du certificat : {0}
-CessationOfOperationCrlReason = Cessation d\u2019activité (5)
 CessationOfOperationReasonFlag = Cessation d\u2019activité
 ChainModel = Modèle suivant la chaîne
 ClientAuthExtKeyUsage = Authentication de client Web TLS (1.3.6.1.5.5.7.3.2)
@@ -66,6 +61,29 @@ CrlDistributionPoint = Point de distribution de liste de révocation [{0}] :
 CrlDistributionPointsCertExt = Points de distribution de la liste de révocation (CRL DP)
 CrlDistributionPointsObsCertExt = Point de distribution de la liste de révocation (extension obsolète)
 CrlNumberCertExt = Numéro de la liste de révocation
+
+CrlReason.0.text = Non spécifié (0)
+CrlReason.0.tooltip = Cette raison indique qu\u2019il n\u2019est pas précisé pourquoi le certificat a été révoqué.\n[Unspecified (0)]
+CrlReason.1.text = Clef compromise (1)
+CrlReason.1.tooltip = Cette raison indique qu\u2019il est connu ou suspecté que la clef privée du certificat a été compromise.\n[Key compromise (1)]
+CrlReason.2.text = Autorité compromise (2)
+CrlReason.2.tooltip = Cette raison indique qu\u2019il est connu ou suspecté que la clef privée de l\u2019autorité de certification a été compromise.\n[CA compromise (2)]
+CrlReason.3.text = Changement d\u2019affiliation (3)
+CrlReason.3.tooltip = Cette raison indique que le nom du sujet ou d\u2019autres informations dans le certificat ont changé.\n[Affiliation changed (3)]
+CrlReason.4.text = Remplacement du certificat (4)
+CrlReason.4.tooltip = Cette raison indique que le certificat a été remplacé.\n[Superseded (4)]
+CrlReason.5.text = Cessation d\u2019activité (5)
+CrlReason.5.tooltip = Cette raison indique que le certificat n\u2019est plus nécessaire.\n[Cessation of operation (5)]
+CrlReason.6.text = Suspension du certificat (6)
+CrlReason.6.tooltip = Cette raison indique que le certificat a été mis en attente.\n[Certificate on hold (6)]
+#CrlReason 7 is unknown - not used
+CrlReason.8.text = Retrait de la liste de révocation (8)
+CrlReason.8.tooltip = Cette raison indique que le certificat était auparavant en attente et doit être supprimé de la liste de révocation de certificats.\n[Remove from CRL (8)]
+CrlReason.9.text = Suppression de privilège (9)
+CrlReason.9.tooltip = Cette raison indique que les privilèges accordés au sujet du certificat ont été retirés.\n[Privilege withdrawn (9)]
+CrlReason.10.text = Autorité d\u2019attributs compromise (10)
+CrlReason.10.tooltip = Cette raison indique qu\u2019il est connu ou suspecté que la clef privée de l\u2019AA [Attribute Authority] a été compromise.\n[AA compromise (10)]
+
 CrlScopeCertExt = Portée de la liste de révocation
 CrlSignKeyUsage = (6) Signature de liste de révocation (CRL)
 CrlStreamIdentifierCertExt = Identificateur de flux de la liste de révocation
@@ -133,7 +151,6 @@ IssuingDistributionPointCertExt = Point de distribution de l\u2019émetteur (IDP
 IssuingDistributionPointObsCertExt = Point de distribution d\u2019émission (extension obsolète)
 KeyAgreementKeyUsage = (4) Échange de clefs
 KeyCertSignKeyUsage = (5) Signature de certificats
-KeyCompromiseCrlReason = Clef compromise (1)
 KeyCompromiseReasonFlag = Clef compromise
 KeyEnciphermentKeyUsage = (2) Chiffrement de clefs
 KeyUsageCertExt = Usage de la clef (KU)
@@ -226,7 +243,6 @@ PolicyQualifierInformation = Information de qualificateur de politique [{0}.{1}]
 PrimaryKeyAttributesObsCertExt = Attributs de la clef primaire (extension obsolète)
 PrimaryKeyUsageRestrictionObsCertExt = Restrictions d\u2019utilisation de la clef primaire (extension obsolète)
 PrivateKeyUsagePeriodCertExt = Période de validité de la clef privée
-PrivilegeWithdrawnCrlReason = Suppression de privilège (9)
 PrivilegeWithdrawnReasonFlag = Privilège retiré
 Procuration = Procuration
 Procuration.CertRef = Référence du certificat :
@@ -253,7 +269,6 @@ QCType.Seal = eSeal
 QCType.Sign = eSign
 QCType.Web  = Web
 ReasonCodeCertExt = Code de la raison
-RemoveFromCrlCrlReason = Retrait de la liste de révocation (8)
 RequireExplicitPolicy = Requiert la politique d\u2019écartement explicite des certificats : {0}
 ReservedNetscapeCertificateType = Reservé
 Restriction = Restriction
@@ -294,7 +309,6 @@ SubjectIsNotCa = Le sujet n\u2019est pas une autorité
 SubjectKeyIdentifier = Identificateur de la clef (SKI) :\n{0}
 SubjectKeyIdentifierCertExt = Identificateur de la clef du sujet (SKI)
 SubtreesConstraintObsCertExt = Contrainte des sous\u2010éléments (extension obsolète)
-SupersededCrlReason = Remplacement du certificat (4)
 SupersededReasonFlag = Remplacement du certificat
 TSLSignExtKeyUsage = Signature de la liste d\u2019état de service sécurisé (TSL) (0.4.0.2231.3.0)
 TargetInformationCertExt = Information de cible
@@ -302,7 +316,6 @@ TimeSpecificationCertExt = Spécification de temps
 TimeStampingAccessMethod = Horodatage (1.3.6.1.5.5.7.48.3)
 TimeStampingExtKeyUsage = Horodatage (1.3.6.1.5.5.7.3.8)
 TitleAttributeType = Titre
-UnspecifiedCrlReason = Non spécifiée (0)
 UnstructuredAddressAttributeType = Adresse non structurée
 UnstructuredNameAttributeType = Nom non structurée
 UnusedReasonFlag = Inutilisé
diff --git a/kse/src/main/resources/org/kse/crypto/x509/resources_ru.properties b/kse/src/main/resources/org/kse/crypto/x509/resources_ru.properties
index d4fa188ba..18376df4a 100644
--- a/kse/src/main/resources/org/kse/crypto/x509/resources_ru.properties
+++ b/kse/src/main/resources/org/kse/crypto/x509/resources_ru.properties
@@ -8,6 +8,29 @@ CaRepositoryAccessMethod=\u0420\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\
 CodeSigningExtKeyUsage=\u041F\u043E\u0434\u043F\u0438\u0441\u044B\u0432\u0430\u043D\u0438\u0435 \u043A\u043E\u0434\u0430 (1.3.6.1.5.5.7.3.3)
 CommonNameAttributeType=CN
 CountryNameAttributeType=C
+
+#CrlReason.0.text = Unspecified (0)
+CrlReason.0.tooltip = \u042D\u0442\u0430 \u043F\u0440\u0438\u0447\u0438\u043D\u0430 \u0443\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442 \u043D\u0430 \u0442\u043E, \u0447\u0442\u043E \u043D\u0435 \u0443\u043A\u0430\u0437\u0430\u043D\u043E, \u043F\u043E\u0447\u0435\u043C\u0443 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442 \u0431\u044B\u043B \u043E\u0442\u043E\u0437\u0432\u0430\u043D.
+#CrlReason.1.text = Key Compromise (1)
+#CrlReason.1.tooltip = This reason indicates that it is known or suspected that the certificate subject's private key has been compromised.
+#CrlReason.2.text = CA Compromise (2)
+#CrlReason.2.tooltip = This reason indicates that it is known or suspected that the CA's private key has been compromised.
+#CrlReason.3.text = Affiliation Changed (3)
+#CrlReason.3.tooltip = This reason indicates that the subject's name or other information in the certificate has changed.
+CrlReason.4.text = \u0417\u0430\u043C\u0435\u043D\u0435\u043D\u043E (4)
+#CrlReason.4.tooltip = This reason indicates that the certificate has been superseded.
+#CrlReason.5.text = Cessation of Operation (5)
+#CrlReason.5.tooltip = This reason indicates that the certificate is no longer needed.
+#CrlReason.6.text = Certificate Hold (6)
+#CrlReason.6.tooltip = This reason indicates that the certificate has been put on hold.
+#CrlReason 7 is unknown - not used
+CrlReason.8.text = \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0438\u0437 CRL (8)
+#CrlReason.8.tooltip = This reason indicates that the certificate was previously on hold and should be removed from the CRL.
+CrlReason.9.text = \u041F\u0440\u0438\u0432\u0438\u043B\u0435\u0433\u0438\u044F \u043E\u0442\u043E\u0437\u0432\u0430\u043D\u0430 (9)
+#CrlReason.9.tooltip = This reason indicates that the privileges granted to the subject of the certificate have been withdrawn.
+#CrlReason.10.text = AA Compromise (10)
+#CrlReason.10.tooltip = This reason indicates that it is known or suspected that the AA's (Attribute Authority) private key has been compromised.
+
 DataEnciphermentKeyUsage=\u0428\u0438\u0444\u0440\u043E\u0432\u0430\u043D\u0438\u0435 \u0434\u0430\u043D\u043D\u044B\u0445
 DateOfBirth=\u0414\u0430\u0442\u0430 \u0440\u043E\u0436\u0434\u0435\u043D\u0438\u044F
 DecipherOnlyKeyUsage=\u0422\u043E\u043B\u044C\u043A\u043E \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043E\u0432\u043A\u0430
@@ -56,7 +79,6 @@ PolicyInformationUtil.CpsPointer=CPS: {0}
 PolicyInformationUtil.Organization=\u041E\u0440\u0433\u0430\u043D\u0438\u0437\u0430\u0446\u0438\u044F: {0}
 PolicyInformationUtil.UserNotice=User Notice: [{0}]
 PrivateKeyUsagePeriodCertExt=\u041F\u0435\u0440\u0438\u043E\u0434 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F \u043F\u0440\u0438\u0432\u0430\u0442\u043D\u043E\u0433\u043E \u043A\u043B\u044E\u0447\u0430
-PrivilegeWithdrawnCrlReason=\u041F\u0440\u0438\u0432\u0438\u043B\u0435\u0433\u0438\u044F \u043E\u0442\u043E\u0437\u0432\u0430\u043D\u0430 (9)
 PrivilegeWithdrawnReasonFlag=\u041F\u0440\u0438\u0432\u0438\u043B\u0435\u0433\u0438\u044F \u043E\u0442\u043E\u0437\u0432\u0430\u043D\u0430
 Procuration.CertRef.Issuer=\u042D\u043C\u0438\u0442\u0435\u043D\u0442:
 Procuration.CertRef.SN=\u0421\u0435\u0440\u0438\u0439\u043D\u044B\u0439 \u043D\u043E\u043C\u0435\u0440: {0}
@@ -72,7 +94,6 @@ QCPDS.locations={0}: <a href="{1}">{1}</a>
 QCPDS=QC PKI Disclosure Statements
 QCType.Web=\u0412\u0435\u0431
 ReasonCodeCertExt=\u041A\u043E\u0434 \u043F\u0440\u0438\u0447\u0438\u043D\u044B
-RemoveFromCrlCrlReason=\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0438\u0437 CRL (8)
 Restriction=\u041E\u0433\u0440\u0430\u043D\u0438\u0447\u0435\u043D\u0438\u0435
 SETCardCertRequired=SET Card Cert Required
 SETCertificateType=SET Certificate Type
@@ -94,7 +115,6 @@ SslServerNetscapeCertificateType=SSL-\u0441\u0435\u0440\u0432\u0435\u0440
 SubjectIsCa=\u0421\u0443\u0431\u044A\u0435\u043A\u0442 \u044F\u0432\u043B\u044F\u0435\u0442\u0441\u044F \u0423\u0426
 SubjectIsNotCa=\u0421\u0443\u0431\u044A\u0435\u043A\u0442 \u043D\u0435 \u044F\u0432\u043B\u044F\u0435\u0442\u0441\u044F \u0423\u0426
 SubtreesConstraintObsCertExt=\u041E\u0433\u0440\u0430\u043D\u0438\u0447\u0435\u043D\u0438\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0435\u0432\u044C\u0435\u0432 (\u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0435\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435)
-SupersededCrlReason=\u0417\u0430\u043C\u0435\u043D\u0435\u043D\u043E (4)
 SupersededReasonFlag=\u0417\u0430\u043C\u0435\u043D\u0435\u043D\u043E
 TSLSignExtKeyUsage=\u041F\u043E\u0434\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0441\u043F\u0438\u0441\u043A\u0430 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0439 \u0434\u043E\u0432\u0435\u0440\u0435\u043D\u043D\u044B\u0445 \u0441\u043B\u0443\u0436\u0431 (TSL) (0.4.0.2231.3.0)
 UserNotice=\u0423\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F:
diff --git a/kse/src/main/resources/org/kse/crypto/x509/resources_zh.properties b/kse/src/main/resources/org/kse/crypto/x509/resources_zh.properties
new file mode 100644
index 000000000..e16625a29
--- /dev/null
+++ b/kse/src/main/resources/org/kse/crypto/x509/resources_zh.properties
@@ -0,0 +1,21 @@
+CrlReason.0.text     = 未明确 (0)
+CrlReason.0.tooltip  = 此原因表明，该证书被吊销的原因尚不明确。
+CrlReason.1.text     = 密钥泄露 (1)
+CrlReason.1.tooltip  = 此原因表明，已知或怀疑证书持有者的私钥已被泄露。
+CrlReason.2.text     = CA 泄露 (2)
+CrlReason.2.tooltip  = 此原因表明，已知或怀疑 CA 的私钥已被泄露。
+CrlReason.3.text     = 所属关系已变更 (3)
+CrlReason.3.tooltip  = 此原因表明，证书中的持有者名称或其他信息已发生改变。
+CrlReason.4.text     = 被取代 (4)
+CrlReason.4.tooltip  = 此原因表明，该证书已被取代。
+CrlReason.5.text     = 停止运营 (5)
+CrlReason.5.tooltip  = 此原因表明，该证书不再需要。
+CrlReason.6.text     = 证书挂起 (6)
+CrlReason.6.tooltip  = 此原因表明，该证书已被挂起。
+#CrlReason 7 is unknown - not used
+CrlReason.8.text     = 从 CRL 中删除 (8)
+CrlReason.8.tooltip  = 此原因表明，该证书先前处于挂起状态，应将其从 CRL 中删除。
+CrlReason.9.text     = 特权被撤销 (9)
+CrlReason.9.tooltip  = 此原因表明，授予持有者证书的特权已被撤销。
+CrlReason.10.text    = AA（属性管理机构） 泄露 (10)
+CrlReason.10.tooltip = 此原因表明，已知或怀疑属性管理机构（AA）的私钥已遭泄露。 
diff --git a/kse/src/main/resources/org/kse/gui/dialogs/resources.properties b/kse/src/main/resources/org/kse/gui/dialogs/resources.properties
index e608516e5..aeb652068 100644
--- a/kse/src/main/resources/org/kse/gui/dialogs/resources.properties
+++ b/kse/src/main/resources/org/kse/gui/dialogs/resources.properties
@@ -621,9 +621,11 @@ DViewSignature.jtfVersion.tooltip                 = Signer's version number
 
 PasswordCallbackHandler.Title = PIN Login
 
+RevokedCertsTableHeadRend.ReasonColumn.tooltip         = Reason for certificate revocation
 RevokedCertsTableHeadRend.RevocationDateColumn.tooltip = Revocation date/time of revoked certificate
 RevokedCertsTableHeadRend.SerialNumberColumn.tooltip   = Serial number of revoked certificate
 
+RevokedCertsTableModel.ReasonColumn = Reason
 RevokedCertsTableModel.RevocationDateColumn = Revocation Date
 RevokedCertsTableModel.SerialNumberColumn   = Serial Number
 
diff --git a/kse/src/main/resources/org/kse/gui/dialogs/resources_de.properties b/kse/src/main/resources/org/kse/gui/dialogs/resources_de.properties
index 614296e33..1e5cd8236 100644
--- a/kse/src/main/resources/org/kse/gui/dialogs/resources_de.properties
+++ b/kse/src/main/resources/org/kse/gui/dialogs/resources_de.properties
@@ -564,11 +564,14 @@ DViewSecretKey.jtfKeySize.tooltip         = Gr\u00F6\u00DFe des Schl\u00FCssels
 
 PasswordCallbackHandler.Title = PIN-Anmeldung
 
+#RevokedCertsTableHeadRend.ReasonColumn.tooltip         = TBD
 RevokedCertsTableHeadRend.RevocationDateColumn.tooltip = Datum und Uhrzeit der Zertifikatssperrung
 RevokedCertsTableHeadRend.SerialNumberColumn.tooltip   = Seriennummer des gesperrten Zertifikates
 
+RevokedCertsTableModel.ReasonColumn = Grund
 RevokedCertsTableModel.RevocationDateColumn = Datum der Sperrung
 RevokedCertsTableModel.SerialNumberColumn   = Seriennummer
+
 DViewCsr.NoVerify.message=Signatur ist ung\u00FCltig
 DViewCsr.Verify.title=Ergebnis der Signaturpr\u00FCfung
 DViewCsr.VerifyOK.message=Signatur ist g\u00FCltig
diff --git a/kse/src/main/resources/org/kse/gui/dialogs/resources_es.properties b/kse/src/main/resources/org/kse/gui/dialogs/resources_es.properties
index 497618fbd..f5a6da55e 100644
--- a/kse/src/main/resources/org/kse/gui/dialogs/resources_es.properties
+++ b/kse/src/main/resources/org/kse/gui/dialogs/resources_es.properties
@@ -619,9 +619,11 @@ DViewSignature.jtfVersion.tooltip                 = N\u00FAmero de versi\u00F3n
 
 PasswordCallbackHandler.Title = Inicio de sesi\u00F3n con PIN
 
+#RevokedCertsTableHeadRend.ReasonColumn.tooltip         = TBD
 RevokedCertsTableHeadRend.RevocationDateColumn.tooltip = Fecha y hora de revocaci\u00F3n del certificado revocado
 RevokedCertsTableHeadRend.SerialNumberColumn.tooltip   = N\u00FAmero de serie del certificado revocado
 
+RevokedCertsTableModel.ReasonColumn = Raz\u00F3n
 RevokedCertsTableModel.RevocationDateColumn = Fecha de revocaci\u00F3n
 RevokedCertsTableModel.SerialNumberColumn   = N\u00FAmero de serie
 
diff --git a/kse/src/main/resources/org/kse/gui/dialogs/resources_fr.properties b/kse/src/main/resources/org/kse/gui/dialogs/resources_fr.properties
index f0c0cf1d6..f92e7a5fa 100644
--- a/kse/src/main/resources/org/kse/gui/dialogs/resources_fr.properties
+++ b/kse/src/main/resources/org/kse/gui/dialogs/resources_fr.properties
@@ -612,9 +612,11 @@ DViewSignature.jtfVersion.tooltip                 = Num\u00E9ro de version de la
 
 PasswordCallbackHandler.Title = Code PIN
 
+RevokedCertsTableHeadRend.ReasonColumn.tooltip         = Raison de la r\u00E9vocation
 RevokedCertsTableHeadRend.RevocationDateColumn.tooltip = Date et heure de r\u00E9vocation du certificat
 RevokedCertsTableHeadRend.SerialNumberColumn.tooltip   = Num\u00E9ro de s\u00E9rie du certificat r\u00E9voqu\u00E9
 
+RevokedCertsTableModel.ReasonColumn = Raison
 RevokedCertsTableModel.RevocationDateColumn = Date de r\u00E9vocation
 RevokedCertsTableModel.SerialNumberColumn   = Num\u00E9ro de s\u00E9rie
 
diff --git a/kse/src/main/resources/org/kse/gui/dialogs/resources_ru.properties b/kse/src/main/resources/org/kse/gui/dialogs/resources_ru.properties
index 53617a88d..9b5a0f48c 100644
--- a/kse/src/main/resources/org/kse/gui/dialogs/resources_ru.properties
+++ b/kse/src/main/resources/org/kse/gui/dialogs/resources_ru.properties
@@ -551,7 +551,9 @@ DViewSecretKey.jtfFormat.tooltip=\u041A\u043E\u0434\u0438\u0440\u043E\u0432\u043
 DViewSecretKey.jtfKeySize.text={0} \u0431\u0438\u0442
 DViewSecretKey.jtfKeySize.tooltip=\u0420\u0430\u0437\u043C\u0435\u0440 \u0441\u0435\u043A\u0440\u0435\u0442\u043D\u043E\u0433\u043E \u043A\u043B\u044E\u0447\u0430
 PasswordCallbackHandler.Title=PIN \u043B\u043E\u0433\u0438\u043D
+#RevokedCertsTableHeadRend.ReasonColumn.tooltip=TBD
 RevokedCertsTableHeadRend.RevocationDateColumn.tooltip=\u0414\u0430\u0442\u0430/\u0432\u0440\u0435\u043C\u044F \u043E\u0442\u0437\u044B\u0432\u0430 \u043E\u0442\u043E\u0437\u0432\u0430\u043D\u043D\u043E\u0433\u043E \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u0430
 RevokedCertsTableHeadRend.SerialNumberColumn.tooltip=\u0421\u0435\u0440\u0438\u0439\u043D\u044B\u0439 \u043D\u043E\u043C\u0435\u0440 \u043E\u0442\u043E\u0437\u0432\u0430\u043D\u043D\u043E\u0433\u043E \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u0430
+#RevokedCertsTableModel.ReasonColumn=TBD
 RevokedCertsTableModel.RevocationDateColumn=\u0414\u0430\u0442\u0430 \u043E\u0442\u0437\u044B\u0432\u0430
 RevokedCertsTableModel.SerialNumberColumn=\u0421\u0435\u0440\u0438\u0439\u043D\u044B\u0439 \u043D\u043E\u043C\u0435\u0440
diff --git a/kse/src/main/resources/org/kse/gui/dialogs/resources_zh.properties b/kse/src/main/resources/org/kse/gui/dialogs/resources_zh.properties
index c65a2ab68..83e5bd000 100644
--- a/kse/src/main/resources/org/kse/gui/dialogs/resources_zh.properties
+++ b/kse/src/main/resources/org/kse/gui/dialogs/resources_zh.properties
@@ -621,9 +621,11 @@ DViewSignature.jtfVersion.tooltip                 = 签名者的版本号
 
 PasswordCallbackHandler.Title = PIN 登录
 
+RevokedCertsTableHeadRend.ReasonColumn.tooltip         = 证书吊销的原因
 RevokedCertsTableHeadRend.RevocationDateColumn.tooltip = 吊销证书的吊销日期/时间
 RevokedCertsTableHeadRend.SerialNumberColumn.tooltip   = 吊销证书的序列号
 
+RevokedCertsTableModel.ReasonColumn         = 原因
 RevokedCertsTableModel.RevocationDateColumn = 吊销日期
 RevokedCertsTableModel.SerialNumberColumn   = 序列号
 
diff --git a/kse/src/main/resources/org/kse/gui/dialogs/sign/resources.properties b/kse/src/main/resources/org/kse/gui/dialogs/sign/resources.properties
index d3801b7e8..775c2223b 100644
--- a/kse/src/main/resources/org/kse/gui/dialogs/sign/resources.properties
+++ b/kse/src/main/resources/org/kse/gui/dialogs/sign/resources.properties
@@ -8,26 +8,6 @@ DCrlReason.jdtRevocationDate.tooltip       = Revocation date
 DCrlReason.jlReason.text                   = Reason:
 DCrlReason.jlRevocationDate.text           = Revocation date:
 DCrlReason.jlSubject.text                  = Subject:
-DCrlReason.jrbAACompromise.text            = AA compromise
-DCrlReason.jrbAACompromise.tooltip         = This reason indicates that it is known or suspected that the AA's (Attribute Authority) private key has been compromised. 
-DCrlReason.jrbAffiliationChanged.text      = Affiliation changed
-DCrlReason.jrbAffiliationChanged.tooltip   = This reason indicates that the subject's name or other information in the certificate has changed. 
-DCrlReason.jrbCACompromise.text            = CA compromise
-DCrlReason.jrbCACompromise.tooltip         = This reason indicates that it is known or suspected that the CA's private key has been compromised.
-DCrlReason.jrbCertificateHold.text         = Certificate on hold
-DCrlReason.jrbCertificateHold.tooltip      = This reason indicates that the certificate has been put on hold.
-DCrlReason.jrbCessationOfOperation.text    = Cessation of operation
-DCrlReason.jrbCessationOfOperation.tooltip = This reason indicates that the certificate is no longer needed. 
-DCrlReason.jrbKeyCompromise.text           = Key compromise
-DCrlReason.jrbKeyCompromise.tooltip        = This reason indicates that it is known or suspected that the certificate subject's private key has been compromised. 
-DCrlReason.jrbPrivilegeWithdrawn.text      = Privilege withdrawn
-DCrlReason.jrbPrivilegeWithdrawn.tooltip   = This reason indicates that the privileges granted to the subject of the certificate have been withdrawn.
-DCrlReason.jrbRemoveFromCR.text            = Remove from CRL
-DCrlReason.jrbRemoveFromCR.tooltip         = This reason indicates that the certificate was previously on hold and should be removed from the CRL. 
-DCrlReason.jrbSuperseded.text              = Superseded
-DCrlReason.jrbSuperseded.tooltip           = This reason indicates that the certificate has been superseded. 
-DCrlReason.jrbUnspecified.text             = Unspecified
-DCrlReason.jrbUnspecified.tooltip          = This reason indicates that it is unspecified as to why the certificate has been revoked.
 
 DListCertificatesKS.SelectCertificate.message = You must select a certificate
 DListCertificatesKS.Title                     = List Certificates
@@ -239,7 +219,6 @@ DSignFile.ChooseOutputFile.Title            = Choose Output File
 DSignFile.EmptyTimestampUrl.message         = Time stamping is selected, but TSA URL is empty.
 DSignFile.InputFileChooser.button           = Choose
 DSignFile.InputFileRequired.message         = Path to Input File required.
-#DSignFile.NoOpenFile.Problem                = Could not open Input File ''{0}''.
 DSignFile.OutputFileChooser.button          = Choose
 DSignFile.OverWriteOutput.message           = The file ''{0}'' already exists. Overwrite it with a new signature?
 DSignFile.Sign.Title                        = Sign File
diff --git a/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_de.properties b/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_de.properties
index 1fa72ee96..cedc5cd28 100644
--- a/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_de.properties
+++ b/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_de.properties
@@ -6,26 +6,6 @@ DCrlReason.jdtRevocationDate.text          = Sperrdatum
 DCrlReason.jdtRevocationDate.tooltip       = Sperrdatum
 DCrlReason.jlReason.text                   = Grund:
 DCrlReason.jlRevocationDate.text           = Sperrdatum:
-DCrlReason.jrbAACompromise.text            = AA Kompromittierung
-DCrlReason.jrbAACompromise.tooltip         = Dieser Grund zeigt an, dass bekannt ist oder vermutet wird, dass der private Schl\u00FCssel der AA (Attribute Authority) kompromittiert wurde.
-DCrlReason.jrbAffiliationChanged.text      = Zugeh\\u00F6rigkeit ge\\u00E4ndert
-DCrlReason.jrbAffiliationChanged.tooltip   = Dieser Grund zeigt an, dass sich der Name oder andere Informationen im Zertifikat ge\u00E4ndert haben.
-DCrlReason.jrbCACompromise.text            = CA Kompromittierung
-DCrlReason.jrbCACompromise.tooltip         = Dieser Grund zeigt an, dass bekannt ist oder vermutet wird, dass der private Schl\u00FCssel der CA kompromittiert wurde.
-DCrlReason.jrbCertificateHold.text         = Zertifikat On Hold
-DCrlReason.jrbCertificateHold.tooltip      = Dieser Grund zeigt an, dass das Zertifikat vor\u00FCbergehend gesperrt wurde und zu einem sp\u00E4teren Zeitpunkt entweder wieder entsperrt oder dauerhaft gesperrt werden k\u00F6nnte.
-DCrlReason.jrbCessationOfOperation.text    = Einstellung des Betriebs
-DCrlReason.jrbCessationOfOperation.tooltip = Dieser Grund zeigt an, dass das Zertifikat au\u00DFer Betrieb genommen wurde und nicht l\u00E4nger ben\u00F6tigt wird.
-DCrlReason.jrbKeyCompromise.text           = Schl\u00FCssel-Kompromittierung
-DCrlReason.jrbKeyCompromise.tooltip        = Dieser Grund zeigt an, dass bekannt ist oder vermutet wird, dass der private Schl\u00FCssel des Zertifikatsinhabers kompromittiert wurde.
-DCrlReason.jrbPrivilegeWithdrawn.text      = Entzug der Berechtigung
-DCrlReason.jrbPrivilegeWithdrawn.tooltip   = Dieser Grund gibt an, dass dem Zertifikatsinhaber die mit dem Zertifikat verbundenen Berechtigungen entzogen worden sind.
-DCrlReason.jrbRemoveFromCR.text            = Entfernen aus CRL
-DCrlReason.jrbRemoveFromCR.tooltip         = Dieser Grund gibt an, dass das Zertifikat vorher tempor\u00E4r gesperrt war und zuk\u00FCnftig aus der CRL entfernt werden soll.
-DCrlReason.jrbSuperseded.text              = Ersetzt
-DCrlReason.jrbSuperseded.tooltip           = Dieser Grund gibt an, dass das Zertifikat durch ein neues ersetzt wurde (z.B. wegen einer defekten Smartcard).
-DCrlReason.jrbUnspecified.text             = Unspezifiziert
-DCrlReason.jrbUnspecified.tooltip          = Es wird kein spezifischer Grund f\u00FCr die Sperrung des Zertifikats angegeben.
 
 DListCertificatesKS.SelectCertificate.message = Bitte ein Zertifikat ausw\u00E4hlen
 DListCertificatesKS.Title                     = Liste der Zertifikate
diff --git a/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_es.properties b/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_es.properties
index 19c4e09c3..29200a5bc 100644
--- a/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_es.properties
+++ b/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_es.properties
@@ -8,26 +8,6 @@ DCrlReason.jdtRevocationDate.tooltip       = Fecha de revocaci\u00F3n
 DCrlReason.jlReason.text                   = Raz\u00F3n:
 DCrlReason.jlRevocationDate.text           = Fecha de revocaci\u00F3n:
 DCrlReason.jlSubject.text                  = Asunto:
-DCrlReason.jrbAACompromise.text            = Compromiso de AA
-DCrlReason.jrbAACompromise.tooltip         = Esta raz\u00F3n indica que se sabe o se sospecha que la clave privada de la AA (Autoridad de Atributos) se ha visto comprometida.
-DCrlReason.jrbAffiliationChanged.text      = Afiliaci\u00F3n cambiada
-DCrlReason.jrbAffiliationChanged.tooltip   = Esta raz\u00F3n indica que el nombre del sujeto u otra informaci\u00F3n del certificado ha cambiado.
-DCrlReason.jrbCACompromise.text            = Compromiso de CA
-DCrlReason.jrbCACompromise.tooltip         = Esta raz\u00F3n indica que se sabe o se sospecha que la clave privada de la CA se ha visto comprometida.
-DCrlReason.jrbCertificateHold.text         = Certificado en espera
-DCrlReason.jrbCertificateHold.tooltip      = Esta raz\u00F3n indica que el certificado se ha puesto en espera.
-DCrlReason.jrbCessationOfOperation.text    = Cesaci\u00F3n de la operaci\u00F3n
-DCrlReason.jrbCessationOfOperation.tooltip = Esta raz\u00F3n indica que el certificado ya no es necesario.
-DCrlReason.jrbKeyCompromise.text           = Compromiso de clave
-DCrlReason.jrbKeyCompromise.tooltip        = Esta raz\u00F3n indica que se sabe o se sospecha que la clave privada del sujeto del certificado se ha visto comprometida.
-DCrlReason.jrbPrivilegeWithdrawn.text      = Privilegio retirado
-DCrlReason.jrbPrivilegeWithdrawn.tooltip   = Esta raz\u00F3n indica que los privilegios otorgados al sujeto del certificado se han retirado.
-DCrlReason.jrbRemoveFromCR.text            = Eliminar de CRL
-DCrlReason.jrbRemoveFromCR.tooltip         = Esta raz\u00F3n indica que el certificado estaba previamente en espera y debe eliminarse de la CRL.
-DCrlReason.jrbSuperseded.text              = Sustituido
-DCrlReason.jrbSuperseded.tooltip           = Esta raz\u00F3n indica que el certificado ha sido sustituido.
-DCrlReason.jrbUnspecified.text             = No especificado
-DCrlReason.jrbUnspecified.tooltip          = Esta raz\u00F3n indica que no se especifica por qu\u00E9 se ha revocado el certificado.
 
 DListCertificatesKS.SelectCertificate.message = Debe seleccionar un certificado
 DListCertificatesKS.Title                     = Lista de Certificados
diff --git a/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_fr.properties b/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_fr.properties
index 609592e4f..580a773ca 100644
--- a/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_fr.properties
+++ b/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_fr.properties
@@ -7,26 +7,6 @@ DCrlReason.jdtRevocationDate.tooltip       = Date de révocation
 DCrlReason.jlReason.text                   = Raison\u00A0:
 DCrlReason.jlRevocationDate.text           = Date de révocation\u00A0:
 DCrlReason.jlSubject.text                  = Sujet\u00A0:
-DCrlReason.jrbAACompromise.text            = AA compromise (10)
-DCrlReason.jrbAACompromise.tooltip         = Cette raison indique qu\u2019il est connu ou suspecté que la clef privée de l\u2019AA [Attribute Authority] a été compromise.\n[AA compromise (10)]
-DCrlReason.jrbAffiliationChanged.text      = Affiliation modifiée (3)
-DCrlReason.jrbAffiliationChanged.tooltip   = Cette raison indique que le nom du sujet ou d\u2019autres informations dans le certificat ont changé.\n[Affiliation changed (3)]
-DCrlReason.jrbCACompromise.text            = AC compromise (2)
-DCrlReason.jrbCACompromise.tooltip         = Cette raison indique qu\u2019il est connu ou suspecté que la clef privée de l\u2019autorité de certification a été compromise.\n[CA compromise (2)]
-DCrlReason.jrbCertificateHold.text         = Certificat en attente (6)
-DCrlReason.jrbCertificateHold.tooltip      = Cette raison indique que le certificat a été mis en attente.\n[Certificate on hold (6)]
-DCrlReason.jrbCessationOfOperation.text    = Cessation d\u2019exploitation (5)
-DCrlReason.jrbCessationOfOperation.tooltip = Cette raison indique que le certificat n\u2019est plus nécessaire.\n[Cessation of operation (5)]
-DCrlReason.jrbKeyCompromise.text           = Clef compromise (1)
-DCrlReason.jrbKeyCompromise.tooltip        = Cette raison indique qu\u2019il est connu ou suspecté que la clef privée du certificat a été compromise.\n[Key compromise (1)]
-DCrlReason.jrbPrivilegeWithdrawn.text      = Privilège retiré (9)
-DCrlReason.jrbPrivilegeWithdrawn.tooltip   = Cette raison indique que les privilèges accordés au sujet du certificat ont été retirés.\n[Privilege withdrawn (9)]
-DCrlReason.jrbRemoveFromCR.text            = Supprimé de la CRL (8)
-DCrlReason.jrbRemoveFromCR.tooltip         = Cette raison indique que le certificat était auparavant en attente et doit être supprimé de la liste de révocation de certificats.\n[Remove from CRL (8)]
-DCrlReason.jrbSuperseded.text              = Remplacé (4)
-DCrlReason.jrbSuperseded.tooltip           = Cette raison indique que le certificat a été remplacé.\n[Superseded (4)]
-DCrlReason.jrbUnspecified.text             = Non spécifié (0)
-DCrlReason.jrbUnspecified.tooltip          = Cette raison indique qu\u2019il n\u2019est pas précisé pourquoi le certificat a été révoqué.\n[Unspecified (0)]
 
 DListCertificatesKS.SelectCertificate.message = Vous devez sélectionner un certificat
 DListCertificatesKS.Title                     = Liste des certificats
diff --git a/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_ru.properties b/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_ru.properties
index fd70ecc8f..9f6aacc7a 100644
--- a/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_ru.properties
+++ b/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_ru.properties
@@ -2,7 +2,6 @@ DCrlReason.Subject.Title=\u0421\u0443\u0431\u044A\u0435\u043A\u0442:
 DCrlReason.jbCancel.text=\u041E\u0442\u043C\u0435\u043D\u0430
 DCrlReason.jbOK.text=OK
 DCrlReason.jlSubject.text=\u0421\u0443\u0431\u044A\u0435\u043A\u0442:
-DCrlReason.jrbUnspecified.tooltip=\u042D\u0442\u0430 \u043F\u0440\u0438\u0447\u0438\u043D\u0430 \u0443\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442 \u043D\u0430 \u0442\u043E, \u0447\u0442\u043E \u043D\u0435 \u0443\u043A\u0430\u0437\u0430\u043D\u043E, \u043F\u043E\u0447\u0435\u043C\u0443 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442 \u0431\u044B\u043B \u043E\u0442\u043E\u0437\u0432\u0430\u043D.
 DCustomClaim.jbCancel.text=\u041E\u0442\u043C\u0435\u043D\u0430
 DCustomClaim.jbOK.text=Ok
 DCustomClaim.jlValue.text=\u0417\u043D\u0430\u0447\u0435\u043D\u0438\u0435:
diff --git a/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_zh.properties b/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_zh.properties
index dc7829b58..6f7119e38 100644
--- a/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_zh.properties
+++ b/kse/src/main/resources/org/kse/gui/dialogs/sign/resources_zh.properties
@@ -8,26 +8,6 @@ DCrlReason.jdtRevocationDate.tooltip       = 吊销日期
 DCrlReason.jlReason.text                   = 原因：
 DCrlReason.jlRevocationDate.text           = 吊销日期：
 DCrlReason.jlSubject.text                  = 持有者：
-DCrlReason.jrbAACompromise.text            = AA（属性管理机构） 泄露
-DCrlReason.jrbAACompromise.tooltip         = 此原因表明，已知或怀疑属性管理机构（AA）的私钥已遭泄露。 
-DCrlReason.jrbAffiliationChanged.text      = 所属关系已变更
-DCrlReason.jrbAffiliationChanged.tooltip   = 此原因表明，证书中的持有者名称或其他信息已发生改变。
-DCrlReason.jrbCACompromise.text            = CA 泄露
-DCrlReason.jrbCACompromise.tooltip         = 此原因表明，已知或怀疑 CA 的私钥已被泄露。
-DCrlReason.jrbCertificateHold.text         = 证书挂起
-DCrlReason.jrbCertificateHold.tooltip      = 此原因表明，该证书已被挂起。
-DCrlReason.jrbCessationOfOperation.text    = 停止运营
-DCrlReason.jrbCessationOfOperation.tooltip = 此原因表明，该证书不再需要。
-DCrlReason.jrbKeyCompromise.text           = 密钥泄露
-DCrlReason.jrbKeyCompromise.tooltip        = 此原因表明，已知或怀疑证书持有者的私钥已被泄露。
-DCrlReason.jrbPrivilegeWithdrawn.text      = 特权被撤销
-DCrlReason.jrbPrivilegeWithdrawn.tooltip   = 此原因表明，授予持有者证书的特权已被撤销。
-DCrlReason.jrbRemoveFromCR.text            = 从 CRL 中删除
-DCrlReason.jrbRemoveFromCR.tooltip         = 此原因表明，该证书先前处于挂起状态，应将其从 CRL 中删除。
-DCrlReason.jrbSuperseded.text              = 被取代
-DCrlReason.jrbSuperseded.tooltip           = 此原因表明，该证书已被取代。
-DCrlReason.jrbUnspecified.text             = 未明确
-DCrlReason.jrbUnspecified.tooltip          = 此原因表明，该证书被吊销的原因尚不明确。
 
 DListCertificatesKS.SelectCertificate.message = 您必须选择一个证书
 DListCertificatesKS.Title                     = 列出证书


Reviews:
user: login: jonwltn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-15T04:09:57Z
user: login: The-Lum
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-15T09:28:41Z
user: login: The-Lum
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-15T11:42:41Z
user: login: kaikramer
body: I have found a little bug but the PR looks good otherwise
state: CHANGES_REQUESTED
author_association: OWNER
submitted_at: 2025-03-15T22:13:48Z
user: login: kaikramer
state: COMMENTED
author_association: OWNER
submitted_at: 2025-03-15T22:17:44Z
user: login: jonwltn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-16T05:06:07Z
user: login: jonwltn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-16T05:12:48Z
user: login: The-Lum
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-16T07:16:02Z
user: login: kaikramer
state: COMMENTED
author_association: OWNER
submitted_at: 2025-03-16T16:02:00Z
user: login: jonwltn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T16:12:00Z
user: login: jonwltn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T16:15:28Z
user: login: jonwltn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T16:16:48Z
user: login: jonwltn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T16:17:55Z
user: login: jonwltn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T16:19:46Z
user: login: jonwltn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T16:20:33Z
user: login: The-Lum
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T17:33:44Z
user: login: kaikramer
state: COMMENTED
author_association: OWNER
submitted_at: 2025-03-19T22:46:08Z
user: login: jonwltn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T00:12:10Z
user: login: kaikramer
state: COMMENTED
author_association: OWNER
submitted_at: 2025-03-21T22:25:01Z
user: login: secnotes
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-21T23:18:46Z
user: login: jonwltn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-22T04:43:55Z
user: login: jonwltn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-22T04:46:01Z
user: login: The-Lum
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-22T16:59:47Z
user: login: jonwltn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-23T04:10:03Z
user: login: kaikramer
state: APPROVED
author_association: OWNER
submitted_at: 2025-03-29T16:54:57Z

Review comments:
diff_hunk: @@ -575,9 +575,22 @@ DViewSecretKey.jtfKeySize.tooltip         = Taille de la clef secr\u00E8te
 
 PasswordCallbackHandler.Title = Code PIN
 
+RevokedCertsTableCellRend.AA_COMPROMISE.text          = AA compromise (10)
+RevokedCertsTableCellRend.AFFILIATION_CHANGED.text    = Affiliation modifiée (3)
+RevokedCertsTableCellRend.CA_COMPROMISE.text          = AC compromise (2)
+RevokedCertsTableCellRend.CERTIFICATE_HOLD.text       = Certificat en attente (6)
+RevokedCertsTableCellRend.CESSATION_OF_OPERATION.text = Cessation d\u2019exploitation (5)
+RevokedCertsTableCellRend.KEY_COMPROMISE.text         = Clef compromise (1)
+RevokedCertsTableCellRend.PRIVILEGE_WITHDRAWN.text    = Privilège retiré (9)
+RevokedCertsTableCellRend.REMOVE_FROM_CRL.text        = Supprimé de la CRL (8)
+RevokedCertsTableCellRend.SUPERSEDED.text             = Remplacé (4)
+RevokedCertsTableCellRend.UNSPECIFIED.text            = Non spécifié (0)
+
+#RevokedCertsTableHeadRend.ReasonColumn.tooltip         = TBD
path: kse/src/main/resources/org/kse/gui/dialogs/resources_fr.properties
user: login: jonwltn
body: @The-Lum If you'll provide a translation, I'll update the PR.
created_at: 2025-03-15T04:09:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -575,9 +575,22 @@ DViewSecretKey.jtfKeySize.tooltip         = Taille de la clef secr\u00E8te
 
 PasswordCallbackHandler.Title = Code PIN
 
+RevokedCertsTableCellRend.AA_COMPROMISE.text          = AA compromise (10)
+RevokedCertsTableCellRend.AFFILIATION_CHANGED.text    = Affiliation modifiée (3)
+RevokedCertsTableCellRend.CA_COMPROMISE.text          = AC compromise (2)
+RevokedCertsTableCellRend.CERTIFICATE_HOLD.text       = Certificat en attente (6)
+RevokedCertsTableCellRend.CESSATION_OF_OPERATION.text = Cessation d\u2019exploitation (5)
+RevokedCertsTableCellRend.KEY_COMPROMISE.text         = Clef compromise (1)
+RevokedCertsTableCellRend.PRIVILEGE_WITHDRAWN.text    = Privilège retiré (9)
+RevokedCertsTableCellRend.REMOVE_FROM_CRL.text        = Supprimé de la CRL (8)
+RevokedCertsTableCellRend.SUPERSEDED.text             = Remplacé (4)
+RevokedCertsTableCellRend.UNSPECIFIED.text            = Non spécifié (0)
+
+#RevokedCertsTableHeadRend.ReasonColumn.tooltip         = TBD
path: kse/src/main/resources/org/kse/gui/dialogs/resources_fr.properties
user: login: The-Lum
body: Hi @jonwltn 

Thanks for this PR.

Why not simply:
- `Raison de la r\u00E9vocation`

Then an open question:
- Do you know if the columns are sortable or not ?
_(For example to sort by reason code?)_

 
Regards,
Th.


created_at: 2025-03-15T09:28:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -575,9 +575,22 @@ DViewSecretKey.jtfKeySize.tooltip         = Taille de la clef secr\u00E8te
 
 PasswordCallbackHandler.Title = Code PIN
 
+RevokedCertsTableCellRend.AA_COMPROMISE.text          = AA compromise (10)
+RevokedCertsTableCellRend.AFFILIATION_CHANGED.text    = Affiliation modifiée (3)
+RevokedCertsTableCellRend.CA_COMPROMISE.text          = AC compromise (2)
+RevokedCertsTableCellRend.CERTIFICATE_HOLD.text       = Certificat en attente (6)
+RevokedCertsTableCellRend.CESSATION_OF_OPERATION.text = Cessation d\u2019exploitation (5)
+RevokedCertsTableCellRend.KEY_COMPROMISE.text         = Clef compromise (1)
+RevokedCertsTableCellRend.PRIVILEGE_WITHDRAWN.text    = Privilège retiré (9)
+RevokedCertsTableCellRend.REMOVE_FROM_CRL.text        = Supprimé de la CRL (8)
+RevokedCertsTableCellRend.SUPERSEDED.text             = Remplacé (4)
+RevokedCertsTableCellRend.UNSPECIFIED.text            = Non spécifié (0)
+
+#RevokedCertsTableHeadRend.ReasonColumn.tooltip         = TBD
path: kse/src/main/resources/org/kse/gui/dialogs/resources_fr.properties
user: login: The-Lum
body: Hi @jonwltn, @kaikramer and all

Another open question:
- Is it good or not to add integer reason code  in bracket after the text _(as I had done on French resources, and on other screens where reason code appears)_?

Regards,
Th.
created_at: 2025-03-15T11:42:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -55,10 +60,16 @@ public Component getTableCellRendererComponent(JTable jtRevokedCerts, Object val
         JLabel cell = (JLabel) super.getTableCellRendererComponent(jtRevokedCerts, value, isSelected, hasFocus, row,
                                                                    col);
 
-        if (col == 0) {
-            cell.setText(HexUtil.getHexString((BigInteger) value, "0x", 4, 0));
-        } else {
-            cell.setText(StringUtils.formatDate((Date) value));
+        switch (col) {
+            case RevokedCertsTableModel.COL_SERIAL_NUMBER:
+                cell.setText(HexUtil.getHexString((BigInteger) value, "0x", 4, 0));
+                break;
+            case RevokedCertsTableModel.COL_REVOCATION_DATE:
+                cell.setText(StringUtils.formatDate((Date) value));
+                break;
+            case RevokedCertsTableModel.COL_REASON:
+                cell.setText(res.getString("RevokedCertsTableCellRend." + ((CRLReason) value).name() + ".text"));
path: kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableCellRend.java
user: login: kaikramer
body: That will throw a NPE if the entry does not have a reason code extension.
created_at: 2025-03-15T22:06:15Z
author_association: OWNER
diff_hunk: @@ -575,9 +575,22 @@ DViewSecretKey.jtfKeySize.tooltip         = Taille de la clef secr\u00E8te
 
 PasswordCallbackHandler.Title = Code PIN
 
+RevokedCertsTableCellRend.AA_COMPROMISE.text          = AA compromise (10)
+RevokedCertsTableCellRend.AFFILIATION_CHANGED.text    = Affiliation modifiée (3)
+RevokedCertsTableCellRend.CA_COMPROMISE.text          = AC compromise (2)
+RevokedCertsTableCellRend.CERTIFICATE_HOLD.text       = Certificat en attente (6)
+RevokedCertsTableCellRend.CESSATION_OF_OPERATION.text = Cessation d\u2019exploitation (5)
+RevokedCertsTableCellRend.KEY_COMPROMISE.text         = Clef compromise (1)
+RevokedCertsTableCellRend.PRIVILEGE_WITHDRAWN.text    = Privilège retiré (9)
+RevokedCertsTableCellRend.REMOVE_FROM_CRL.text        = Supprimé de la CRL (8)
+RevokedCertsTableCellRend.SUPERSEDED.text             = Remplacé (4)
+RevokedCertsTableCellRend.UNSPECIFIED.text            = Non spécifié (0)
+
+#RevokedCertsTableHeadRend.ReasonColumn.tooltip         = TBD
path: kse/src/main/resources/org/kse/gui/dialogs/resources_fr.properties
user: login: kaikramer
body: > Hi @jonwltn, @kaikramer and all
> 
> Another open question:
> 
>     * Is it good or not to add integer reason code  in bracket after the text _(as I had done on French resources, and on other screens where reason code appears)_?
> 
> 
> Regards, Th.

Yeah, that's probably a good idea. 
created_at: 2025-03-15T22:17:44Z
author_association: OWNER
diff_hunk: @@ -575,9 +575,22 @@ DViewSecretKey.jtfKeySize.tooltip         = Taille de la clef secr\u00E8te
 
 PasswordCallbackHandler.Title = Code PIN
 
+RevokedCertsTableCellRend.AA_COMPROMISE.text          = AA compromise (10)
+RevokedCertsTableCellRend.AFFILIATION_CHANGED.text    = Affiliation modifiée (3)
+RevokedCertsTableCellRend.CA_COMPROMISE.text          = AC compromise (2)
+RevokedCertsTableCellRend.CERTIFICATE_HOLD.text       = Certificat en attente (6)
+RevokedCertsTableCellRend.CESSATION_OF_OPERATION.text = Cessation d\u2019exploitation (5)
+RevokedCertsTableCellRend.KEY_COMPROMISE.text         = Clef compromise (1)
+RevokedCertsTableCellRend.PRIVILEGE_WITHDRAWN.text    = Privilège retiré (9)
+RevokedCertsTableCellRend.REMOVE_FROM_CRL.text        = Supprimé de la CRL (8)
+RevokedCertsTableCellRend.SUPERSEDED.text             = Remplacé (4)
+RevokedCertsTableCellRend.UNSPECIFIED.text            = Non spécifié (0)
+
+#RevokedCertsTableHeadRend.ReasonColumn.tooltip         = TBD
path: kse/src/main/resources/org/kse/gui/dialogs/resources_fr.properties
user: login: jonwltn
body: I'll add the integer codes to all the reason text strings.

Sorting the table columns is a great idea. I'll add that, too. It'll be an alphabetical sort, rather than integer reason code sort, over the translated strings.

created_at: 2025-03-16T05:06:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -55,10 +60,16 @@ public Component getTableCellRendererComponent(JTable jtRevokedCerts, Object val
         JLabel cell = (JLabel) super.getTableCellRendererComponent(jtRevokedCerts, value, isSelected, hasFocus, row,
                                                                    col);
 
-        if (col == 0) {
-            cell.setText(HexUtil.getHexString((BigInteger) value, "0x", 4, 0));
-        } else {
-            cell.setText(StringUtils.formatDate((Date) value));
+        switch (col) {
+            case RevokedCertsTableModel.COL_SERIAL_NUMBER:
+                cell.setText(HexUtil.getHexString((BigInteger) value, "0x", 4, 0));
+                break;
+            case RevokedCertsTableModel.COL_REVOCATION_DATE:
+                cell.setText(StringUtils.formatDate((Date) value));
+                break;
+            case RevokedCertsTableModel.COL_REASON:
+                cell.setText(res.getString("RevokedCertsTableCellRend." + ((CRLReason) value).name() + ".text"));
path: kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableCellRend.java
user: login: jonwltn
body: Oh, yeah! I'll fix it.
created_at: 2025-03-16T05:12:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -575,9 +575,22 @@ DViewSecretKey.jtfKeySize.tooltip         = Taille de la clef secr\u00E8te
 
 PasswordCallbackHandler.Title = Code PIN
 
+RevokedCertsTableCellRend.AA_COMPROMISE.text          = AA compromise (10)
+RevokedCertsTableCellRend.AFFILIATION_CHANGED.text    = Affiliation modifiée (3)
+RevokedCertsTableCellRend.CA_COMPROMISE.text          = AC compromise (2)
+RevokedCertsTableCellRend.CERTIFICATE_HOLD.text       = Certificat en attente (6)
+RevokedCertsTableCellRend.CESSATION_OF_OPERATION.text = Cessation d\u2019exploitation (5)
+RevokedCertsTableCellRend.KEY_COMPROMISE.text         = Clef compromise (1)
+RevokedCertsTableCellRend.PRIVILEGE_WITHDRAWN.text    = Privilège retiré (9)
+RevokedCertsTableCellRend.REMOVE_FROM_CRL.text        = Supprimé de la CRL (8)
+RevokedCertsTableCellRend.SUPERSEDED.text             = Remplacé (4)
+RevokedCertsTableCellRend.UNSPECIFIED.text            = Non spécifié (0)
+
+#RevokedCertsTableHeadRend.ReasonColumn.tooltip         = TBD
path: kse/src/main/resources/org/kse/gui/dialogs/resources_fr.properties
user: login: The-Lum
body: > I'll add the integer codes to all the reason text strings.

Perhaps you could directly include the resource where it is already done?
_(In order to avoid to copy, and have redundant values on the resource files)_

Similar to:
- https://github.com/kaikramer/keystore-explorer/blob/main/kse%2Fsrc%2Fmain%2Fjava%2Forg%2Fkse%2Fgui%2Fdialogs%2Fextensions%2FDExtendedKeyUsage.java#L77-L78

> Sorting the table columns is a great idea. I'll add that, too. It'll be an alphabetical sort, rather than integer reason code sort, over the translated strings.

I think first on a simple clik on the header...(like on other GUI) especily to sort date, or serial also.

Regards,
Th. 

created_at: 2025-03-16T07:16:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -575,9 +575,22 @@ DViewSecretKey.jtfKeySize.tooltip         = Taille de la clef secr\u00E8te
 
 PasswordCallbackHandler.Title = Code PIN
 
+RevokedCertsTableCellRend.AA_COMPROMISE.text          = AA compromise (10)
+RevokedCertsTableCellRend.AFFILIATION_CHANGED.text    = Affiliation modifiée (3)
+RevokedCertsTableCellRend.CA_COMPROMISE.text          = AC compromise (2)
+RevokedCertsTableCellRend.CERTIFICATE_HOLD.text       = Certificat en attente (6)
+RevokedCertsTableCellRend.CESSATION_OF_OPERATION.text = Cessation d\u2019exploitation (5)
+RevokedCertsTableCellRend.KEY_COMPROMISE.text         = Clef compromise (1)
+RevokedCertsTableCellRend.PRIVILEGE_WITHDRAWN.text    = Privilège retiré (9)
+RevokedCertsTableCellRend.REMOVE_FROM_CRL.text        = Supprimé de la CRL (8)
+RevokedCertsTableCellRend.SUPERSEDED.text             = Remplacé (4)
+RevokedCertsTableCellRend.UNSPECIFIED.text            = Non spécifié (0)
+
+#RevokedCertsTableHeadRend.ReasonColumn.tooltip         = TBD
path: kse/src/main/resources/org/kse/gui/dialogs/resources_fr.properties
user: login: kaikramer
body: Sorting by clicking on the table header works out of the box, there's nothing to do for it:

![image](https://github.com/user-attachments/assets/c9408589-1cc1-4109-a5c7-91542981e174)

created_at: 2025-03-16T16:02:00Z
author_association: OWNER
diff_hunk: @@ -854,29 +854,7 @@ private static String getReasonCodeStringValue(byte[] value) throws IOException
 
         long crlReasonLong = crlReason.getValue().longValue();
 
-        if (crlReasonLong == CRLReason.unspecified) {
-            sb.append(res.getString("UnspecifiedCrlReason"));
-        } else if (crlReasonLong == CRLReason.keyCompromise) {
-            sb.append(res.getString("KeyCompromiseCrlReason"));
-        } else if (crlReasonLong == CRLReason.cACompromise) {
-            sb.append(res.getString("CaCompromiseCrlReason"));
-        } else if (crlReasonLong == CRLReason.affiliationChanged) {
-            sb.append(res.getString("AffiliationChangedCrlReason"));
-        } else if (crlReasonLong == CRLReason.superseded) {
-            sb.append(res.getString("SupersededCrlReason"));
-        } else if (crlReasonLong == CRLReason.cessationOfOperation) {
-            sb.append(res.getString("CessationOfOperationCrlReason"));
-        } else if (crlReasonLong == CRLReason.certificateHold) {
-            sb.append(res.getString("CertificateHoldCrlReason"));
-        } else if (crlReasonLong == CRLReason.removeFromCRL) {
-            sb.append(res.getString("RemoveFromCrlCrlReason"));
-        } else if (crlReasonLong == CRLReason.privilegeWithdrawn) {
-            sb.append(res.getString("PrivilegeWithdrawnCrlReason"));
-        } else
-        // CRLReason.aACompromise
-        {
-            sb.append(res.getString("AaCompromiseCrlReason"));
-        }
+        sb.append(res.getString("CrlReason." + crlReasonLong + ".text"));
path: kse/src/main/java/org/kse/crypto/x509/X509Ext.java
user: login: jonwltn
body: This will throw resource not found if the number is < 0 or > 10. I can add a check if you want to use a blank string for these cases where the CRL Reason extension is malformed. The previous code just defaulted to AA Compromised.
created_at: 2025-03-18T16:12:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -64,19 +75,47 @@ public void load(X509CRLEntry[] revokedCerts) {
             sortedRevokedCerts.put(revokedCert.getSerialNumber(), revokedCert);
         }
 
-        data = new Object[sortedRevokedCerts.size()][2];
+        data = new Object[sortedRevokedCerts.size()][COLUMN_COUNT];
 
         int i = 0;
         for (Iterator<?> itr = sortedRevokedCerts.entrySet().iterator(); itr.hasNext(); i++) {
             X509CRLEntry x509CrlEntry = (X509CRLEntry) ((Map.Entry<?, ?>) itr.next()).getValue();
 
-            data[i][0] = x509CrlEntry.getSerialNumber();
-            data[i][1] = x509CrlEntry.getRevocationDate();
+            data[i][COL_SERIAL_NUMBER] = x509CrlEntry.getSerialNumber();
+            data[i][COL_REVOCATION_DATE] = x509CrlEntry.getRevocationDate();
+            data[i][COL_REASON] = getReasonString(x509CrlEntry.getRevocationReason());
         }
 
         fireTableDataChanged();
     }
 
+    /**
+     * Load the RevokedCertsTableModel with a map of RevokedEntry.
+     *
+     * @param mapRevokedEntry The X.509 CRL entries
+     */
+    public void load(Map<BigInteger, RevokedEntry> mapRevokedEntry) {
+        data = new Object[mapRevokedEntry.size()][COLUMN_COUNT];
+
+        int i = 0;
+        for (Map.Entry<BigInteger, RevokedEntry> pair : mapRevokedEntry.entrySet()) {
+            RevokedEntry entry = pair.getValue();
+            data[i][COL_SERIAL_NUMBER] = entry.getUserCertificateSerial();
+            data[i][COL_REVOCATION_DATE] = entry.getRevocationDate();
+            data[i][COL_REASON] = getReasonString(entry.getReason());
+            i++;
+        }
+        fireTableDataChanged();
+    }
+
+    private String getReasonString(CRLReason reason) {
+        String reasonString = "";
path: kse/src/main/java/org/kse/gui/dialogs/RevokedCertsTableModel.java
user: login: jonwltn
body: Use a blank string if the CRL does not have a reason extension.
created_at: 2025-03-18T16:15:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -126,6 +116,28 @@ CrlDistributionPointsObsCertExt = CRL Distribution Points (obsolete extension)
 
 CrlNumberCertExt = CRL Number
 
+CrlReason.0.text = Unspecified (0)
path: kse/src/main/resources/org/kse/crypto/x509/resources.properties
user: login: jonwltn
body: Moved all the CRL reason text and tooltips to the x509 resources.
created_at: 2025-03-18T16:16:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -121,6 +111,28 @@ CrlDistributionPointsObsCertExt = CRL Verteilungspunkte (veraltete Erweiterung)
 
 CrlNumberCertExt = CRL Nummer
 
+CrlReason.0.text = Unspezifiziert (0)
path: kse/src/main/resources/org/kse/crypto/x509/resources_de.properties
user: login: jonwltn
body: I think the German translations are ok, but I did notice differences between the x509 resources and the CRL signing resources.
created_at: 2025-03-18T16:17:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -66,6 +61,29 @@ CrlDistributionPoint = Point de distribution de liste de révocation [{0}] :
 CrlDistributionPointsCertExt = Points de distribution de la liste de révocation (CRL DP)
 CrlDistributionPointsObsCertExt = Point de distribution de la liste de révocation (extension obsolète)
 CrlNumberCertExt = Numéro de la liste de révocation
+
path: kse/src/main/resources/org/kse/crypto/x509/resources_fr.properties
user: login: jonwltn
body: I'm going to need to have a review of the French translations. I picked one and used it, but many times there were different strings for each item. Or we can just leave it as it is for now, and have a new PR for fixing the French translation for the CRL reasons.
created_at: 2025-03-18T16:19:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -8,6 +8,29 @@ CaRepositoryAccessMethod=\u0420\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\
 CodeSigningExtKeyUsage=\u041F\u043E\u0434\u043F\u0438\u0441\u044B\u0432\u0430\u043D\u0438\u0435 \u043A\u043E\u0434\u0430 (1.3.6.1.5.5.7.3.3)
 CommonNameAttributeType=CN
 CountryNameAttributeType=C
+
+#CrlReason.0.text = Unspecified (0)
path: kse/src/main/resources/org/kse/crypto/x509/resources_ru.properties
user: login: jonwltn
body: The Russian translation was very hit or miss. Only one tooltip and a few translated reasons. I left the rest here as comments.
created_at: 2025-03-18T16:20:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -66,6 +61,29 @@ CrlDistributionPoint = Point de distribution de liste de révocation [{0}] :
 CrlDistributionPointsCertExt = Points de distribution de la liste de révocation (CRL DP)
 CrlDistributionPointsObsCertExt = Point de distribution de la liste de révocation (extension obsolète)
 CrlNumberCertExt = Numéro de la liste de révocation
+
path: kse/src/main/resources/org/kse/crypto/x509/resources_fr.properties
user: login: The-Lum
body: OK, I will can help on that later...
created_at: 2025-03-18T17:33:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -121,6 +111,28 @@ CrlDistributionPointsObsCertExt = CRL Verteilungspunkte (veraltete Erweiterung)
 
 CrlNumberCertExt = CRL Nummer
 
+CrlReason.0.text = Unspezifiziert (0)
path: kse/src/main/resources/org/kse/crypto/x509/resources_de.properties
user: login: kaikramer
body: Ok, I will check this
created_at: 2025-03-19T22:46:08Z
author_association: OWNER
diff_hunk: @@ -621,9 +621,11 @@ DViewSignature.jtfVersion.tooltip                 = 签名者的版本号
 
 PasswordCallbackHandler.Title = PIN 登录
 
+#RevokedCertsTableHeadRend.ReasonColumn.tooltip         = TBD
path: kse/src/main/resources/org/kse/gui/dialogs/resources_zh.properties
user: login: jonwltn
body: @liyansong2018 I added new string when implementing #414. I'll update my PR if you have a translation for the Reason column tooltip. The English that I used is: Reason for certificate revocation.
created_at: 2025-03-21T00:12:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -121,6 +111,28 @@ CrlDistributionPointsObsCertExt = CRL Verteilungspunkte (veraltete Erweiterung)
 
 CrlNumberCertExt = CRL Nummer
 
+CrlReason.0.text = Unspezifiziert (0)
path: kse/src/main/resources/org/kse/crypto/x509/resources_de.properties
user: login: kaikramer
body: That was a valuable hint. There is a mistake in the translation of "AA compromise" in resources/org/kse/crypto/x509/resources_de.properties (should be "AA Kompromittierung")

The translations of the other reason codes are equivalent, the translations in the sign resource are a bit more consistent.
created_at: 2025-03-21T22:25:01Z
author_association: OWNER
diff_hunk: @@ -621,9 +621,11 @@ DViewSignature.jtfVersion.tooltip                 = 签名者的版本号
 
 PasswordCallbackHandler.Title = PIN 登录
 
+#RevokedCertsTableHeadRend.ReasonColumn.tooltip         = TBD
path: kse/src/main/resources/org/kse/gui/dialogs/resources_zh.properties
user: login: secnotes
body: > Reason for certificate revocation.

Chinese:  证书吊销的原因
created_at: 2025-03-21T23:18:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -121,6 +111,28 @@ CrlDistributionPointsObsCertExt = CRL Verteilungspunkte (veraltete Erweiterung)
 
 CrlNumberCertExt = CRL Nummer
 
+CrlReason.0.text = Unspezifiziert (0)
path: kse/src/main/resources/org/kse/crypto/x509/resources_de.properties
user: login: jonwltn
body: Updated
created_at: 2025-03-22T04:43:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -619,9 +619,11 @@ DViewSignature.jtfVersion.tooltip                 = N\u00FAmero de versi\u00F3n
 
 PasswordCallbackHandler.Title = Inicio de sesi\u00F3n con PIN
 
+#RevokedCertsTableHeadRend.ReasonColumn.tooltip         = TBD
path: kse/src/main/resources/org/kse/gui/dialogs/resources_es.properties
user: login: jonwltn
body: @jgrateron If you provide a Spanish translation for this new tooltip (Reason column added to CRL table), I'll update the PR. The English that I used is: "Reason for certificate revocation"
created_at: 2025-03-22T04:46:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -66,6 +61,29 @@ CrlDistributionPoint = Point de distribution de liste de révocation [{0}] :
 CrlDistributionPointsCertExt = Points de distribution de la liste de révocation (CRL DP)
 CrlDistributionPointsObsCertExt = Point de distribution de la liste de révocation (extension obsolète)
 CrlNumberCertExt = Numéro de la liste de révocation
+
path: kse/src/main/resources/org/kse/crypto/x509/resources_fr.properties
user: login: The-Lum
body: @jonwltn 

- You can just suppress `UnspecifiedCrlReason` (on `resources_fr`) if it is now never used?

Regards,
Th.
created_at: 2025-03-22T16:59:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -66,6 +61,29 @@ CrlDistributionPoint = Point de distribution de liste de révocation [{0}] :
 CrlDistributionPointsCertExt = Points de distribution de la liste de révocation (CRL DP)
 CrlDistributionPointsObsCertExt = Point de distribution de la liste de révocation (extension obsolète)
 CrlNumberCertExt = Numéro de la liste de révocation
+
path: kse/src/main/resources/org/kse/crypto/x509/resources_fr.properties
user: login: jonwltn
body: I missed that one. Thanks for pointing it out. The sign CRL dialog now looks like this:
![image](https://github.com/user-attachments/assets/b6d57d0d-5346-4f65-a0b4-b6a6bb2cc0bb)

created_at: 2025-03-23T04:10:02Z
author_association: CONTRIBUTOR

PR comments:
user: login: jonwltn
created_at: 2025-03-26T14:26:43Z
body: I've been waiting for a Spanish translation for the tooltip on the new column added to the table, but otherwise, this is PR is ready to go.
author_association: CONTRIBUTOR
user: login: kaikramer
created_at: 2025-03-29T16:56:58Z
body: Thanks for the PR!
author_association: OWNER