From b9a9eb01baea7fec7cd1dcf39d7167c347f75ff6 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Wed, 19 Jul 2023 15:15:40 +0200 Subject: [PATCH 01/11] Modify init order for OCSP subsystem The init order for OCSP is modified to allow CRL retrieval before creating connection with DS or other services. Secure`connections will be verified against the CRL. Solve RHCS-4262 --- .../org/dogtagpki/server/ocsp/OCSPEngine.java | 49 +++++++++++++++++++ .../com/netscape/cmscore/apps/CMSEngine.java | 40 ++++++++------- 2 files changed, 71 insertions(+), 18 deletions(-) diff --git a/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java b/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java index bba325e51ae..0832864ab1d 100644 --- a/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java +++ b/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java @@ -63,5 +63,54 @@ public void initSubsystem(ISubsystem subsystem, IConfigStore subsystemConfig) th } super.initSubsystem(subsystem, subsystemConfig); + if (subsystem instanceof OCSPAuthority) { + subsystem.startup(); + } } + + protected void startupSubsystems() throws Exception { + + for (ISubsystem subsystem : subsystems.values()) { + logger.info("CMSEngine: Starting " + subsystem.getId() + " subsystem"); + if (!(subsystem instanceof OCSPAuthority)) + subsystem.startup(); + } + + // global admin servlet. (anywhere else more fit for this ?) + } + @Override + protected void initSequence() throws Exception { + + initDebug(); + init(); + initPasswordStore(); + initSubsystemListeners(); + initSecurityProvider(); + initPluginRegistry(); + initLogSubsystem(); + initDatabase(); + initJssSubsystem(); + initDBSubsystem(); + initUGSubsystem(); + initOIDLoaderSubsystem(); + initX500NameSubsystem(); + // skip TP subsystem; + // problem in needing dbsubsystem in constructor. and it's not used. + initRequestSubsystem(); + + + startupSubsystems(); + + initAuthSubsystem(); + initAuthzSubsystem(); + initJobsScheduler(); + + configureAutoShutdown(); + configureServerCertNickname(); + configureExcludedLdapAttrs(); + + initSecurityDomain(); + } + + } diff --git a/base/server/src/main/java/com/netscape/cmscore/apps/CMSEngine.java b/base/server/src/main/java/com/netscape/cmscore/apps/CMSEngine.java index 7671828fa70..07b00092925 100644 --- a/base/server/src/main/java/com/netscape/cmscore/apps/CMSEngine.java +++ b/base/server/src/main/java/com/netscape/cmscore/apps/CMSEngine.java @@ -1102,6 +1102,28 @@ public void start() throws Exception { CMS.setCMSEngine(this); + initSequence(); + + // Register realm for this subsystem + ProxyRealm.registerRealm(id, new PKIRealm()); + + ready = true; + isStarted = true; + + mStartupTime = System.currentTimeMillis(); + + logger.info(name + " engine started"); + // Register TomcatJSS socket listener + TomcatJSS tomcatJss = TomcatJSS.getInstance(); + if(serverSocketListener == null) { + serverSocketListener = new PKIServerSocketListener(); + } + tomcatJss.addSocketListener(serverSocketListener); + + notifySubsystemStarted(); + } + + protected void initSequence() throws Exception { initDebug(); initPasswordStore(); initSubsystemListeners(); @@ -1131,24 +1153,6 @@ public void start() throws Exception { configureExcludedLdapAttrs(); initSecurityDomain(); - - // Register realm for this subsystem - ProxyRealm.registerRealm(id, new PKIRealm()); - - ready = true; - isStarted = true; - - mStartupTime = System.currentTimeMillis(); - - logger.info(name + " engine started"); - // Register TomcatJSS socket listener - TomcatJSS tomcatJss = TomcatJSS.getInstance(); - if(serverSocketListener == null) { - serverSocketListener = new PKIServerSocketListener(); - } - tomcatJss.addSocketListener(serverSocketListener); - - notifySubsystemStarted(); } public boolean isInRunningState() { From 57df77e43400c42d2d15a01b3c8b7978e0df0b5f Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Fri, 21 Jul 2023 18:09:17 +0200 Subject: [PATCH 02/11] Add callback for CRL validation at application level Add new field in CMS for a callback validation of certificate instantiated by PKISocketFactory. This is useful for OCSP where the OCSP protocol cannot be enabled and the verification is done on CRLs. Solve RHCS-4262 --- .../netscape/cms/ocsp/CRLLdapValidator.java | 81 +++++++++++++++++++ .../java/com/netscape/cms/ocsp/LDAPStore.java | 2 +- .../org/dogtagpki/server/ocsp/OCSPEngine.java | 1 + .../java/com/netscape/cmscore/apps/CMS.java | 11 +++ .../cmscore/ldapconn/PKISocketFactory.java | 4 +- 5 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java diff --git a/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java b/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java new file mode 100644 index 00000000000..1b6b04bb109 --- /dev/null +++ b/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java @@ -0,0 +1,81 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program 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; version 2 of the License. +// +// This program 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 this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cms.ocsp; + +import java.security.cert.X509CRLEntry; +import java.util.Enumeration; + +import org.mozilla.jss.crypto.X509Certificate; +import org.mozilla.jss.netscape.security.x509.X509CRLImpl; +import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; + +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord; + +public class CRLLdapValidator implements SSLCertificateApprovalCallback { + + public static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CRLLdapValidator.class); + + private LDAPStore crlStore; + + + + public CRLLdapValidator(LDAPStore crlStore) { + super(); + this.crlStore = crlStore; + } + + + @Override + public boolean approve(X509Certificate certificate, ValidityStatus currentStatus) { + logger.info("CRLLdapValidator: validate of peer's certificate for the connection " + certificate.getSubjectDN().toString()); + ICRLIssuingPointRecord pt = null; + try { + Enumeration eCRL = crlStore.searchAllCRLIssuingPointRecord(-1); + while (eCRL.hasMoreElements() && pt == null) { + ICRLIssuingPointRecord tPt = eCRL.nextElement(); + logger.debug("CRLLdapValidator: CRL check issuer " + tPt.getId()); + if(tPt.getId().equals(certificate.getIssuerDN().toString())) { + pt = tPt; + } + } + } catch (EBaseException e) { + logger.error("CRLLdapValidator: problem find CRL issuing point for " + certificate.getIssuerDN().toString()); + return false; + } + if (pt == null) { + logger.error("CRLLdapValidator: CRL issuing point not found for " + certificate.getIssuerDN().toString()); + return false; + } + try { + X509CRLImpl crl = new X509CRLImpl(pt.getCRL()); + X509CRLEntry crlentry = crl.getRevokedCertificate(certificate.getSerialNumber()); + + if (crlentry == null) { + if (crlStore.isNotFoundGood()) { + return true; + } + } + } catch (Exception e) { + logger.error("CRLLdapValidator: crl check error. " + e.getMessage()); + } + logger.info("CRLLdapValidator: peer certificate not valid"); + return false; + } + +} diff --git a/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java b/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java index fb4e321877c..60d212ca6d2 100644 --- a/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java +++ b/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java @@ -17,7 +17,6 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cms.ocsp; -import java.lang.Integer; import java.math.BigInteger; import java.security.MessageDigest; import java.security.cert.X509CRL; @@ -238,6 +237,7 @@ public void startup() throws EBaseException { updater.start(); } + CMS.setApprovalCallbask(new CRLLdapValidator(this)); } @Override diff --git a/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java b/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java index 0832864ab1d..0ac6f421829 100644 --- a/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java +++ b/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java @@ -68,6 +68,7 @@ public void initSubsystem(ISubsystem subsystem, IConfigStore subsystemConfig) th } } + protected void startupSubsystems() throws Exception { for (ISubsystem subsystem : subsystems.values()) { diff --git a/base/server/src/main/java/com/netscape/cmscore/apps/CMS.java b/base/server/src/main/java/com/netscape/cmscore/apps/CMS.java index a5b8a1be6f3..3e1e41a9c19 100644 --- a/base/server/src/main/java/com/netscape/cmscore/apps/CMS.java +++ b/base/server/src/main/java/com/netscape/cmscore/apps/CMS.java @@ -23,6 +23,7 @@ import java.util.Locale; import java.util.ResourceBundle; +import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,6 +54,8 @@ public final class CMS { private static CMSEngine engine; + private static SSLCertificateApprovalCallback approvalCallback; + public static CMSEngine getCMSEngine() { return engine; } @@ -61,6 +64,14 @@ public static void setCMSEngine(CMSEngine engine) { CMS.engine = engine; } + public static SSLCertificateApprovalCallback getApprovalCallback() { + return approvalCallback; + } + + public static void setApprovalCallbask(SSLCertificateApprovalCallback approvalCallback) { + CMS.approvalCallback = approvalCallback; + } + /** * Return the product name from /usr/share/pki/CS_SERVER_VERSION * which is provided by the server theme package. diff --git a/base/server/src/main/java/com/netscape/cmscore/ldapconn/PKISocketFactory.java b/base/server/src/main/java/com/netscape/cmscore/ldapconn/PKISocketFactory.java index ccbebdc7c0c..25e35b569df 100644 --- a/base/server/src/main/java/com/netscape/cmscore/ldapconn/PKISocketFactory.java +++ b/base/server/src/main/java/com/netscape/cmscore/ldapconn/PKISocketFactory.java @@ -151,7 +151,7 @@ public SSLSocket makeSSLSocket(String host, int port) throws UnknownHostExceptio SSLSocket s; if (mClientAuthCertNickname == null) { - s = new SSLSocket(host, port); + s = new SSLSocket(host, port, null, 0, CMS.getApprovalCallback(), null); } else { // Let's create a selection callback in the case the client auth @@ -161,7 +161,7 @@ public SSLSocket makeSSLSocket(String host, int port) throws UnknownHostExceptio Socket js = new Socket(InetAddress.getByName(host), port); s = new SSLSocket(js, host, - null, + CMS.getApprovalCallback(), new SSLClientCertificateSelectionCB(mClientAuthCertNickname)); } From e6a1e0c23e7b8b78e739e1200c44ae151de7d6a1 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Fri, 28 Jul 2023 10:56:56 +0200 Subject: [PATCH 03/11] Make crl check for connection optional Add a new parameter to enable the crl check for OCSP connection when acting as client. The new parameter is `ocsp.store.ldapStore.checkSubsystemConnection` and its default value is `false`. When set to `true` connection certificate are verified using the crl stored in the LDAP. --- base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java b/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java index 60d212ca6d2..2100de84355 100644 --- a/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java +++ b/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java @@ -81,6 +81,7 @@ public class LDAPStore implements IDefStore, IExtendedPluginInfo { private static final String DEF_CA_CERT_ATTR = "cACertificate;binary"; private static final String PROP_HOST = "host"; private static final String PROP_PORT = "port"; + private static final String PROP_CHECK_SUBSYSTEM_CONNECTION = "checkSubsystemConnection"; private final static String PROP_NOT_FOUND_GOOD = "notFoundAsGood"; private final static String PROP_INCLUDE_NEXT_UPDATE = @@ -237,7 +238,9 @@ public void startup() throws EBaseException { updater.start(); } - CMS.setApprovalCallbask(new CRLLdapValidator(this)); + if(mConfig.getBoolean(PROP_CHECK_SUBSYSTEM_CONNECTION, false)) { + CMS.setApprovalCallbask(new CRLLdapValidator(this)); + } } @Override From 7ad255e9067c66ac6ec928af0742fe7c431eef36 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Fri, 28 Jul 2023 16:30:27 +0200 Subject: [PATCH 04/11] Add crl check for OCSP acting as server When OCSP is acting as server certificate can be verified using CRL internally stored. To verify the certificates the `LDAPStore` has to be enabled with the variable `ocsp.store.ldapStore.checkSubsystemConnection` and the variable `auths.revocationChecking.enabled` both set to true. Solve RHCS-4262 --- .../netscape/cms/ocsp/CRLLdapValidator.java | 2 +- .../java/com/netscape/cms/ocsp/LDAPStore.java | 10 ++- .../org/dogtagpki/server/ocsp/OCSPEngine.java | 71 +++++++++++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java b/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java index 1b6b04bb109..857eff7b7f9 100644 --- a/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java +++ b/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java @@ -12,7 +12,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // -// (C) 2007 Red Hat, Inc. +// (C) 2023 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package com.netscape.cms.ocsp; diff --git a/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java b/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java index 2100de84355..379a8bcdbeb 100644 --- a/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java +++ b/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java @@ -94,6 +94,8 @@ public class LDAPStore implements IDefStore, IExtendedPluginInfo { private String mCACertAttr = null; protected Hashtable mReqCounts = new Hashtable<>(); private Hashtable mCRLs = new Hashtable<>(); + private boolean mCheckConnection = false; + /** * Constructs the default store. @@ -137,6 +139,7 @@ public void init(IConfigStore config, DBSubsystem dbSubsystem) throws EBaseExcep DEF_CA_CERT_ATTR); mByName = mConfig.getBoolean(PROP_BY_NAME, true); + mCheckConnection = mConfig.getBoolean(PROP_CHECK_SUBSYSTEM_CONNECTION, false); } /** @@ -238,7 +241,7 @@ public void startup() throws EBaseException { updater.start(); } - if(mConfig.getBoolean(PROP_CHECK_SUBSYSTEM_CONNECTION, false)) { + if(mCheckConnection) { CMS.setApprovalCallbask(new CRLLdapValidator(this)); } } @@ -493,6 +496,11 @@ public void setConfigParameters(NameValuePairs pairs) mConfig.put(key, pairs.get(key)); } } + + public boolean isCRLCheckAvailable() { + return mCheckConnection; + } + } class CRLUpdater extends Thread { diff --git a/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java b/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java index 0ac6f421829..db1941f744b 100644 --- a/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java +++ b/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java @@ -18,10 +18,21 @@ package org.dogtagpki.server.ocsp; +import java.security.cert.X509CRLEntry; +import java.security.cert.X509Certificate; +import java.util.Enumeration; + +import javax.security.auth.x500.X500Principal; import javax.servlet.annotation.WebListener; +import org.mozilla.jss.netscape.security.x509.X509CRLImpl; +import org.mozilla.jss.ssl.SSLCertificateApprovalCallback.ValidityStatus; + +import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.IConfigStore; import com.netscape.certsrv.base.ISubsystem; +import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord; +import com.netscape.cms.ocsp.LDAPStore; import com.netscape.cmscore.apps.CMS; import com.netscape.cmscore.apps.CMSEngine; import com.netscape.cmscore.apps.EngineConfig; @@ -113,5 +124,65 @@ protected void initSequence() throws Exception { initSecurityDomain(); } + @Override + public boolean isRevoked(X509Certificate[] certificates) { + LDAPStore crlStore = null; + for (ISubsystem subsystem : subsystems.values()) { + if (subsystem instanceof OCSPAuthority) { + OCSPAuthority ocsp = (OCSPAuthority) subsystem; + if (ocsp.getDefaultStore() instanceof LDAPStore) { + crlStore = (LDAPStore) ocsp.getDefaultStore(); + } + break; + } + } + + if (crlStore == null || !crlStore.isCRLCheckAvailable()) { + return super.isRevoked(certificates); + } + + for (X509Certificate cert: certificates) { + if(crlCertValid(crlStore, cert, null)) { + return false; + } + } + return true; + + } + + + private boolean crlCertValid(LDAPStore crlStore, X509Certificate certificate, ValidityStatus currentStatus) { + logger.info("OCSPEngine: validate of peer's certificate for the connection " + certificate.getSubjectX500Principal().toString()); + ICRLIssuingPointRecord pt = null; + try { + Enumeration eCRL = crlStore.searchAllCRLIssuingPointRecord(-1); + while (eCRL.hasMoreElements() && pt == null) { + ICRLIssuingPointRecord tPt = eCRL.nextElement(); + logger.debug("OCSPEngine: CRL check issuer " + tPt.getId()); + if(certificate.getIssuerX500Principal().equals(new X500Principal(tPt.getId()))) { + pt = tPt; + } + } + } catch (EBaseException e) { + logger.error("OCSPEngine: problem find CRL issuing point for " + certificate.getIssuerX500Principal().toString()); + return false; + } + if (pt == null) { + logger.error("OCSPEngine: CRL issuing point not found for " + certificate.getIssuerX500Principal().toString()); + return false; + } + try { + X509CRLImpl crl = new X509CRLImpl(pt.getCRL()); + X509CRLEntry crlentry = crl.getRevokedCertificate(certificate.getSerialNumber()); + + if (crlentry == null && crlStore.isNotFoundGood()) { + return true; + } + } catch (Exception e) { + logger.error("OCSPEngine: crl check error. " + e.getMessage()); + } + logger.info("OCSPEngine: peer certificate not valid"); + return false; + } } From d54adc9d9f11ac1dd31632c9cbd92fe65ab89a3a Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Mon, 31 Jul 2023 18:34:42 +0200 Subject: [PATCH 05/11] Move callback reference from CMS to CMSEngine Socket callback moved to CMSEngine to avoid dependencies on global variables. --- .../java/com/netscape/cms/ocsp/CRLLdapValidator.java | 8 ++++---- .../main/java/com/netscape/cms/ocsp/LDAPStore.java | 2 +- .../java/org/dogtagpki/server/ocsp/OCSPEngine.java | 6 +++--- .../src/main/java/com/netscape/cmscore/apps/CMS.java | 11 ----------- .../java/com/netscape/cmscore/apps/CMSEngine.java | 11 +++++++++++ .../netscape/cmscore/ldapconn/PKISocketFactory.java | 10 ++++++++-- 6 files changed, 27 insertions(+), 21 deletions(-) diff --git a/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java b/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java index 857eff7b7f9..0b6ea60cf07 100644 --- a/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java +++ b/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java @@ -43,7 +43,7 @@ public CRLLdapValidator(LDAPStore crlStore) { @Override public boolean approve(X509Certificate certificate, ValidityStatus currentStatus) { - logger.info("CRLLdapValidator: validate of peer's certificate for the connection " + certificate.getSubjectDN().toString()); + logger.info("CRLLdapValidator: validate of peer's certificate for the connection " + certificate.getSubjectDN()); ICRLIssuingPointRecord pt = null; try { Enumeration eCRL = crlStore.searchAllCRLIssuingPointRecord(-1); @@ -55,11 +55,11 @@ public boolean approve(X509Certificate certificate, ValidityStatus currentStatus } } } catch (EBaseException e) { - logger.error("CRLLdapValidator: problem find CRL issuing point for " + certificate.getIssuerDN().toString()); + logger.error("CRLLdapValidator: problem find CRL issuing point. " + e.getMessage(), e); return false; } if (pt == null) { - logger.error("CRLLdapValidator: CRL issuing point not found for " + certificate.getIssuerDN().toString()); + logger.error("CRLLdapValidator: CRL issuing point not found for " + certificate.getIssuerDN()); return false; } try { @@ -72,7 +72,7 @@ public boolean approve(X509Certificate certificate, ValidityStatus currentStatus } } } catch (Exception e) { - logger.error("CRLLdapValidator: crl check error. " + e.getMessage()); + logger.error("CRLLdapValidator: crl check error. " + e.getMessage(), e); } logger.info("CRLLdapValidator: peer certificate not valid"); return false; diff --git a/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java b/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java index 379a8bcdbeb..40238ca89fc 100644 --- a/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java +++ b/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java @@ -242,7 +242,7 @@ public void startup() throws EBaseException { updater.start(); } if(mCheckConnection) { - CMS.setApprovalCallbask(new CRLLdapValidator(this)); + CMS.getCMSEngine().setApprovalCallback(new CRLLdapValidator(this)); } } diff --git a/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java b/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java index db1941f744b..a4644552064 100644 --- a/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java +++ b/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java @@ -142,11 +142,11 @@ public boolean isRevoked(X509Certificate[] certificates) { } for (X509Certificate cert: certificates) { - if(crlCertValid(crlStore, cert, null)) { - return false; + if(!crlCertValid(crlStore, cert, null)) { + return true; } } - return true; + return false; } diff --git a/base/server/src/main/java/com/netscape/cmscore/apps/CMS.java b/base/server/src/main/java/com/netscape/cmscore/apps/CMS.java index 3e1e41a9c19..a5b8a1be6f3 100644 --- a/base/server/src/main/java/com/netscape/cmscore/apps/CMS.java +++ b/base/server/src/main/java/com/netscape/cmscore/apps/CMS.java @@ -23,7 +23,6 @@ import java.util.Locale; import java.util.ResourceBundle; -import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,8 +53,6 @@ public final class CMS { private static CMSEngine engine; - private static SSLCertificateApprovalCallback approvalCallback; - public static CMSEngine getCMSEngine() { return engine; } @@ -64,14 +61,6 @@ public static void setCMSEngine(CMSEngine engine) { CMS.engine = engine; } - public static SSLCertificateApprovalCallback getApprovalCallback() { - return approvalCallback; - } - - public static void setApprovalCallbask(SSLCertificateApprovalCallback approvalCallback) { - CMS.approvalCallback = approvalCallback; - } - /** * Return the product name from /usr/share/pki/CS_SERVER_VERSION * which is provided by the server theme package. diff --git a/base/server/src/main/java/com/netscape/cmscore/apps/CMSEngine.java b/base/server/src/main/java/com/netscape/cmscore/apps/CMSEngine.java index 07b00092925..dcedec8db42 100644 --- a/base/server/src/main/java/com/netscape/cmscore/apps/CMSEngine.java +++ b/base/server/src/main/java/com/netscape/cmscore/apps/CMSEngine.java @@ -50,6 +50,7 @@ import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.netscape.security.util.Cert; import org.mozilla.jss.netscape.security.x509.X509CertImpl; +import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; import com.netscape.certsrv.authentication.ISharedToken; import com.netscape.certsrv.base.EBaseException; @@ -151,6 +152,8 @@ public class CMSEngine implements ServletContextListener { protected LogSubsystem logSubsystem = LogSubsystem.getInstance(); protected JssSubsystem jssSubsystem = JssSubsystem.getInstance(); protected DBSubsystem dbSubsystem = new DBSubsystem(); + protected SSLCertificateApprovalCallback approvalCallback; + protected RequestRepository requestRepository; @@ -301,6 +304,14 @@ public void registerPendingListener(String name, IRequestListener listener) { pendingNotifier.registerListener(name, listener); } + public SSLCertificateApprovalCallback getApprovalCallback() { + return approvalCallback; + } + + public void setApprovalCallback(SSLCertificateApprovalCallback approvalCallback) { + this.approvalCallback = approvalCallback; + } + public void loadConfig(String path) throws Exception { ConfigStorage storage = new FileConfigStore(path); config = createConfig(storage); diff --git a/base/server/src/main/java/com/netscape/cmscore/ldapconn/PKISocketFactory.java b/base/server/src/main/java/com/netscape/cmscore/ldapconn/PKISocketFactory.java index 25e35b569df..b1c5b2db2f7 100644 --- a/base/server/src/main/java/com/netscape/cmscore/ldapconn/PKISocketFactory.java +++ b/base/server/src/main/java/com/netscape/cmscore/ldapconn/PKISocketFactory.java @@ -27,6 +27,7 @@ import java.util.logging.Logger; import org.dogtagpki.server.PKIClientSocketListener; +import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; import org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback; import org.mozilla.jss.ssl.SSLHandshakeCompletedEvent; import org.mozilla.jss.ssl.SSLHandshakeCompletedListener; @@ -149,9 +150,14 @@ public SSLSocket makeSSLSocket(String host, int port) throws UnknownHostExceptio */ SSLSocket s; + SSLCertificateApprovalCallback callback = null; + + if (CMS.getCMSEngine() != null) { + callback = CMS.getCMSEngine().getApprovalCallback(); + } if (mClientAuthCertNickname == null) { - s = new SSLSocket(host, port, null, 0, CMS.getApprovalCallback(), null); + s = new SSLSocket(host, port, null, 0, callback, null); } else { // Let's create a selection callback in the case the client auth @@ -161,7 +167,7 @@ public SSLSocket makeSSLSocket(String host, int port) throws UnknownHostExceptio Socket js = new Socket(InetAddress.getByName(host), port); s = new SSLSocket(js, host, - CMS.getApprovalCallback(), + callback, new SSLClientCertificateSelectionCB(mClientAuthCertNickname)); } From 1615339cdd88fb507ddda7683e522adf9158036e Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Thu, 3 Aug 2023 20:50:28 +0200 Subject: [PATCH 06/11] OCSP default CRL check and CA cert validation The parameter `ocsp.store.ldapStore.checkSubsystemConnection` default value has been modified to `true` so when LDAPStore is used certificates are verified against the CRL. Additionally, during the certificate verification the certificate signer is verified with the CA certificate providing the CRL to be sure it is the real issuer. --- .../com/netscape/cms/ocsp/CRLLdapValidator.java | 16 +++++++++++++++- .../java/com/netscape/cms/ocsp/LDAPStore.java | 2 +- .../org/dogtagpki/server/ocsp/OCSPEngine.java | 17 +++++++++++++++-- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java b/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java index 0b6ea60cf07..d9c20d2b97d 100644 --- a/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java +++ b/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java @@ -17,11 +17,17 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cms.ocsp; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.Security; +import java.security.SignatureException; +import java.security.cert.CertificateException; import java.security.cert.X509CRLEntry; import java.util.Enumeration; import org.mozilla.jss.crypto.X509Certificate; import org.mozilla.jss.netscape.security.x509.X509CRLImpl; +import org.mozilla.jss.netscape.security.x509.X509CertImpl; import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; import com.netscape.certsrv.base.EBaseException; @@ -51,7 +57,15 @@ public boolean approve(X509Certificate certificate, ValidityStatus currentStatus ICRLIssuingPointRecord tPt = eCRL.nextElement(); logger.debug("CRLLdapValidator: CRL check issuer " + tPt.getId()); if(tPt.getId().equals(certificate.getIssuerDN().toString())) { - pt = tPt; + try { + X509CertImpl caCert = new X509CertImpl(tPt.getCACert()); + X509CertImpl certToVerify = new X509CertImpl(certificate.getEncoded()); + certToVerify.verify(caCert.getPublicKey(), Security.getProvider("Mozilla-JSS")); + pt = tPt; + } catch (CertificateException | InvalidKeyException | NoSuchAlgorithmException + | SignatureException e) { + logger.error("CRLLdapValidator: issuer certificate cannot verify the certificate signature." ); + } } } } catch (EBaseException e) { diff --git a/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java b/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java index 40238ca89fc..cbc1f923e3a 100644 --- a/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java +++ b/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java @@ -139,7 +139,7 @@ public void init(IConfigStore config, DBSubsystem dbSubsystem) throws EBaseExcep DEF_CA_CERT_ATTR); mByName = mConfig.getBoolean(PROP_BY_NAME, true); - mCheckConnection = mConfig.getBoolean(PROP_CHECK_SUBSYSTEM_CONNECTION, false); + mCheckConnection = mConfig.getBoolean(PROP_CHECK_SUBSYSTEM_CONNECTION, true); } /** diff --git a/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java b/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java index a4644552064..49417da3e02 100644 --- a/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java +++ b/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java @@ -18,6 +18,11 @@ package org.dogtagpki.server.ocsp; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.Security; +import java.security.SignatureException; +import java.security.cert.CertificateException; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; import java.util.Enumeration; @@ -26,6 +31,7 @@ import javax.servlet.annotation.WebListener; import org.mozilla.jss.netscape.security.x509.X509CRLImpl; +import org.mozilla.jss.netscape.security.x509.X509CertImpl; import org.mozilla.jss.ssl.SSLCertificateApprovalCallback.ValidityStatus; import com.netscape.certsrv.base.EBaseException; @@ -152,7 +158,7 @@ public boolean isRevoked(X509Certificate[] certificates) { private boolean crlCertValid(LDAPStore crlStore, X509Certificate certificate, ValidityStatus currentStatus) { - logger.info("OCSPEngine: validate of peer's certificate for the connection " + certificate.getSubjectX500Principal().toString()); + logger.info("OCSPEngine: validate of peer's certificate for the connection " + certificate.getSubjectX500Principal()); ICRLIssuingPointRecord pt = null; try { Enumeration eCRL = crlStore.searchAllCRLIssuingPointRecord(-1); @@ -160,7 +166,14 @@ private boolean crlCertValid(LDAPStore crlStore, X509Certificate certificate, Va ICRLIssuingPointRecord tPt = eCRL.nextElement(); logger.debug("OCSPEngine: CRL check issuer " + tPt.getId()); if(certificate.getIssuerX500Principal().equals(new X500Principal(tPt.getId()))) { - pt = tPt; + try { + X509CertImpl caCert = new X509CertImpl(tPt.getCACert()); + certificate.verify(caCert.getPublicKey(), Security.getProvider("Mozilla-JSS")); + pt = tPt; + } catch (CertificateException | InvalidKeyException | NoSuchAlgorithmException + | SignatureException e) { + logger.error("OCSPEngine: issuer certificate cannot verify the certificate signature." ); + } } } } catch (EBaseException e) { From 2b31525a51b113bc1a71669ec4a08b2903ffc7d9 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Fri, 4 Aug 2023 12:45:07 +0200 Subject: [PATCH 07/11] Rename checkSubsystemConnection to validateConnCertWithCRL The option `ocsp.store.ldapStore.validateConnCertWithCRL` enables the revocation verification of peer certificates using the CRL stored in the LDAP shared with the CA. When it is set to `true` (default value), the peer certificate of all the outcome connections from the OCSP subsystem are verified with the CRL. If the option `auths.revocationChecking.enabled` is also set to `true` the peer certificate ot all the income connections to the OCSP subsystem are verified with the CRL. --- .../src/main/java/com/netscape/cms/ocsp/LDAPStore.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java b/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java index cbc1f923e3a..c2650edcbcb 100644 --- a/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java +++ b/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java @@ -81,7 +81,7 @@ public class LDAPStore implements IDefStore, IExtendedPluginInfo { private static final String DEF_CA_CERT_ATTR = "cACertificate;binary"; private static final String PROP_HOST = "host"; private static final String PROP_PORT = "port"; - private static final String PROP_CHECK_SUBSYSTEM_CONNECTION = "checkSubsystemConnection"; + private static final String PROP_VALIDATE_CONNECTION_WITH_CRL = "validateConnCertWithCRL"; private final static String PROP_NOT_FOUND_GOOD = "notFoundAsGood"; private final static String PROP_INCLUDE_NEXT_UPDATE = @@ -94,7 +94,7 @@ public class LDAPStore implements IDefStore, IExtendedPluginInfo { private String mCACertAttr = null; protected Hashtable mReqCounts = new Hashtable<>(); private Hashtable mCRLs = new Hashtable<>(); - private boolean mCheckConnection = false; + private boolean mValidateConnection = true; /** @@ -139,7 +139,7 @@ public void init(IConfigStore config, DBSubsystem dbSubsystem) throws EBaseExcep DEF_CA_CERT_ATTR); mByName = mConfig.getBoolean(PROP_BY_NAME, true); - mCheckConnection = mConfig.getBoolean(PROP_CHECK_SUBSYSTEM_CONNECTION, true); + mValidateConnection = mConfig.getBoolean(PROP_VALIDATE_CONNECTION_WITH_CRL, true); } /** @@ -241,7 +241,7 @@ public void startup() throws EBaseException { updater.start(); } - if(mCheckConnection) { + if(mValidateConnection) { CMS.getCMSEngine().setApprovalCallback(new CRLLdapValidator(this)); } } @@ -498,7 +498,7 @@ public void setConfigParameters(NameValuePairs pairs) } public boolean isCRLCheckAvailable() { - return mCheckConnection; + return mValidateConnection; } } From 4366f72c343329e2831e8e9f346a51a429d565a9 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Fri, 4 Aug 2023 19:42:38 +0200 Subject: [PATCH 08/11] Use AKI/SKI to match peer certificate with CA CRL Identification of CRL issuing point done by matching Authority Key Identifier with Subject Key Identifier instead of DN matching. This should make more reliable the check because not affected of encoding or format changes in the DN. --- .../netscape/cms/ocsp/CRLLdapValidator.java | 41 ++++++++++++------- .../org/dogtagpki/server/ocsp/OCSPEngine.java | 40 ++++++++++++------ 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java b/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java index d9c20d2b97d..69e43ebc2f6 100644 --- a/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java +++ b/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java @@ -17,15 +17,17 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cms.ocsp; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.Security; -import java.security.SignatureException; +import java.io.IOException; import java.security.cert.CertificateException; import java.security.cert.X509CRLEntry; +import java.util.Arrays; import java.util.Enumeration; import org.mozilla.jss.crypto.X509Certificate; +import org.mozilla.jss.netscape.security.x509.AuthorityKeyIdentifierExtension; +import org.mozilla.jss.netscape.security.x509.KeyIdentifier; +import org.mozilla.jss.netscape.security.x509.PKIXExtensions; +import org.mozilla.jss.netscape.security.x509.SubjectKeyIdentifierExtension; import org.mozilla.jss.netscape.security.x509.X509CRLImpl; import org.mozilla.jss.netscape.security.x509.X509CertImpl; import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; @@ -52,23 +54,34 @@ public boolean approve(X509Certificate certificate, ValidityStatus currentStatus logger.info("CRLLdapValidator: validate of peer's certificate for the connection " + certificate.getSubjectDN()); ICRLIssuingPointRecord pt = null; try { + X509CertImpl peerCert = new X509CertImpl(certificate.getEncoded()); Enumeration eCRL = crlStore.searchAllCRLIssuingPointRecord(-1); + AuthorityKeyIdentifierExtension aPeeExt = (AuthorityKeyIdentifierExtension) peerCert.getExtension(PKIXExtensions.AuthorityKey_Id.toString()); + if(aPeeExt == null) { + logger.error("CRLLdapValidator: the certificate has not Authority Key Identifier Extension. CRL verification cannot be done."); + return false; + } while (eCRL.hasMoreElements() && pt == null) { ICRLIssuingPointRecord tPt = eCRL.nextElement(); logger.debug("CRLLdapValidator: CRL check issuer " + tPt.getId()); - if(tPt.getId().equals(certificate.getIssuerDN().toString())) { - try { - X509CertImpl caCert = new X509CertImpl(tPt.getCACert()); - X509CertImpl certToVerify = new X509CertImpl(certificate.getEncoded()); - certToVerify.verify(caCert.getPublicKey(), Security.getProvider("Mozilla-JSS")); + X509CertImpl caCert = new X509CertImpl(tPt.getCACert()); + try { + SubjectKeyIdentifierExtension sCaExt = (SubjectKeyIdentifierExtension) caCert.getExtension(PKIXExtensions.SubjectKey_Id.toString()); + if(sCaExt == null) { + logger.error("CRLLdapValidator: signing certificate missing Subject Key Identifier. Skip CA " + caCert.getName()); + continue; + } + + KeyIdentifier sCaKeyId = (KeyIdentifier) sCaExt.get(SubjectKeyIdentifierExtension.KEY_ID); + KeyIdentifier aPeerKeyId = (KeyIdentifier) aPeeExt.get(AuthorityKeyIdentifierExtension.KEY_ID); + if(Arrays.equals(sCaKeyId.getIdentifier(), aPeerKeyId.getIdentifier())) { pt = tPt; - } catch (CertificateException | InvalidKeyException | NoSuchAlgorithmException - | SignatureException e) { - logger.error("CRLLdapValidator: issuer certificate cannot verify the certificate signature." ); } + } catch (IOException e) { + logger.error("CRLLdapValidator: problem extracting key from SKI/AKI"); } } - } catch (EBaseException e) { + } catch (EBaseException | CertificateException e) { logger.error("CRLLdapValidator: problem find CRL issuing point. " + e.getMessage(), e); return false; } @@ -88,7 +101,7 @@ public boolean approve(X509Certificate certificate, ValidityStatus currentStatus } catch (Exception e) { logger.error("CRLLdapValidator: crl check error. " + e.getMessage(), e); } - logger.info("CRLLdapValidator: peer certificate not valid"); + logger.error("CRLLdapValidator: peer certificate not valid"); return false; } diff --git a/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java b/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java index 49417da3e02..cb3441a5353 100644 --- a/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java +++ b/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java @@ -18,18 +18,19 @@ package org.dogtagpki.server.ocsp; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.Security; -import java.security.SignatureException; +import java.io.IOException; import java.security.cert.CertificateException; import java.security.cert.X509CRLEntry; import java.security.cert.X509Certificate; +import java.util.Arrays; import java.util.Enumeration; -import javax.security.auth.x500.X500Principal; import javax.servlet.annotation.WebListener; +import org.mozilla.jss.netscape.security.x509.AuthorityKeyIdentifierExtension; +import org.mozilla.jss.netscape.security.x509.KeyIdentifier; +import org.mozilla.jss.netscape.security.x509.PKIXExtensions; +import org.mozilla.jss.netscape.security.x509.SubjectKeyIdentifierExtension; import org.mozilla.jss.netscape.security.x509.X509CRLImpl; import org.mozilla.jss.netscape.security.x509.X509CertImpl; import org.mozilla.jss.ssl.SSLCertificateApprovalCallback.ValidityStatus; @@ -161,22 +162,35 @@ private boolean crlCertValid(LDAPStore crlStore, X509Certificate certificate, Va logger.info("OCSPEngine: validate of peer's certificate for the connection " + certificate.getSubjectX500Principal()); ICRLIssuingPointRecord pt = null; try { + X509CertImpl peerCert = new X509CertImpl(certificate.getEncoded()); Enumeration eCRL = crlStore.searchAllCRLIssuingPointRecord(-1); + AuthorityKeyIdentifierExtension aPeeExt = (AuthorityKeyIdentifierExtension) peerCert.getExtension(PKIXExtensions.AuthorityKey_Id.toString()); + if(aPeeExt == null) { + logger.error("OCSPEngine: the certificate has not Authority Key Identifier Extension. CRL verification cannot be done."); + return false; + } while (eCRL.hasMoreElements() && pt == null) { ICRLIssuingPointRecord tPt = eCRL.nextElement(); logger.debug("OCSPEngine: CRL check issuer " + tPt.getId()); - if(certificate.getIssuerX500Principal().equals(new X500Principal(tPt.getId()))) { - try { - X509CertImpl caCert = new X509CertImpl(tPt.getCACert()); - certificate.verify(caCert.getPublicKey(), Security.getProvider("Mozilla-JSS")); + X509CertImpl caCert = new X509CertImpl(tPt.getCACert()); + + try { + SubjectKeyIdentifierExtension sCaExt = (SubjectKeyIdentifierExtension) caCert.getExtension(PKIXExtensions.SubjectKey_Id.toString()); + if(sCaExt == null) { + logger.error("OCSPEngine: signing certificate missing Subject Key Identifier. Skip CA " + caCert.getName()); + continue; + } + + KeyIdentifier sCaKeyId = (KeyIdentifier) sCaExt.get(SubjectKeyIdentifierExtension.KEY_ID); + KeyIdentifier aPeerKeyId = (KeyIdentifier) aPeeExt.get(AuthorityKeyIdentifierExtension.KEY_ID); + if(Arrays.equals(sCaKeyId.getIdentifier(), aPeerKeyId.getIdentifier())) { pt = tPt; - } catch (CertificateException | InvalidKeyException | NoSuchAlgorithmException - | SignatureException e) { - logger.error("OCSPEngine: issuer certificate cannot verify the certificate signature." ); } + } catch (IOException e) { + logger.error("OCSPEngine: problem extracting key from SKI/AKI"); } } - } catch (EBaseException e) { + } catch (EBaseException | CertificateException e) { logger.error("OCSPEngine: problem find CRL issuing point for " + certificate.getIssuerX500Principal().toString()); return false; } From 584cc11c292a55d7e36039e3ba9cd90f54aecc6f Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Fri, 4 Aug 2023 19:57:58 +0200 Subject: [PATCH 09/11] Add comment for the option ocsp.store.ldapStore.validateConnCertWithCRL --- base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java b/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java index c2650edcbcb..5485e888df5 100644 --- a/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java +++ b/base/ocsp/src/main/java/com/netscape/cms/ocsp/LDAPStore.java @@ -81,6 +81,10 @@ public class LDAPStore implements IDefStore, IExtendedPluginInfo { private static final String DEF_CA_CERT_ATTR = "cACertificate;binary"; private static final String PROP_HOST = "host"; private static final String PROP_PORT = "port"; + + // This option enables the revocation verification of peer certificates using the CRL stored in the LDAP. + // Peer certificate of all the outcome connections from the OCSP subsystem are verified with the CRL. + // If also auths.revocationChecking.is set to true the peer certificate og all the income connections to the OCSP subsystem are verified with the CRL. private static final String PROP_VALIDATE_CONNECTION_WITH_CRL = "validateConnCertWithCRL"; private final static String PROP_NOT_FOUND_GOOD = "notFoundAsGood"; From 35135124ebb737959876f55ca314850e915d3ce2 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Fri, 4 Aug 2023 20:09:30 +0200 Subject: [PATCH 10/11] Modify local variable names --- .../com/netscape/cms/ocsp/CRLLdapValidator.java | 14 +++++++------- .../java/org/dogtagpki/server/ocsp/OCSPEngine.java | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java b/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java index 69e43ebc2f6..c6112aaf984 100644 --- a/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java +++ b/base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java @@ -56,8 +56,8 @@ public boolean approve(X509Certificate certificate, ValidityStatus currentStatus try { X509CertImpl peerCert = new X509CertImpl(certificate.getEncoded()); Enumeration eCRL = crlStore.searchAllCRLIssuingPointRecord(-1); - AuthorityKeyIdentifierExtension aPeeExt = (AuthorityKeyIdentifierExtension) peerCert.getExtension(PKIXExtensions.AuthorityKey_Id.toString()); - if(aPeeExt == null) { + AuthorityKeyIdentifierExtension peerAKIExt = (AuthorityKeyIdentifierExtension) peerCert.getExtension(PKIXExtensions.AuthorityKey_Id.toString()); + if(peerAKIExt == null) { logger.error("CRLLdapValidator: the certificate has not Authority Key Identifier Extension. CRL verification cannot be done."); return false; } @@ -66,15 +66,15 @@ public boolean approve(X509Certificate certificate, ValidityStatus currentStatus logger.debug("CRLLdapValidator: CRL check issuer " + tPt.getId()); X509CertImpl caCert = new X509CertImpl(tPt.getCACert()); try { - SubjectKeyIdentifierExtension sCaExt = (SubjectKeyIdentifierExtension) caCert.getExtension(PKIXExtensions.SubjectKey_Id.toString()); - if(sCaExt == null) { + SubjectKeyIdentifierExtension caAKIExt = (SubjectKeyIdentifierExtension) caCert.getExtension(PKIXExtensions.SubjectKey_Id.toString()); + if(caAKIExt == null) { logger.error("CRLLdapValidator: signing certificate missing Subject Key Identifier. Skip CA " + caCert.getName()); continue; } - KeyIdentifier sCaKeyId = (KeyIdentifier) sCaExt.get(SubjectKeyIdentifierExtension.KEY_ID); - KeyIdentifier aPeerKeyId = (KeyIdentifier) aPeeExt.get(AuthorityKeyIdentifierExtension.KEY_ID); - if(Arrays.equals(sCaKeyId.getIdentifier(), aPeerKeyId.getIdentifier())) { + KeyIdentifier caSKIId = (KeyIdentifier) caAKIExt.get(SubjectKeyIdentifierExtension.KEY_ID); + KeyIdentifier peerAKIId = (KeyIdentifier) peerAKIExt.get(AuthorityKeyIdentifierExtension.KEY_ID); + if(Arrays.equals(caSKIId.getIdentifier(), peerAKIId.getIdentifier())) { pt = tPt; } } catch (IOException e) { diff --git a/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java b/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java index cb3441a5353..457e3bdd7e0 100644 --- a/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java +++ b/base/ocsp/src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java @@ -164,8 +164,8 @@ private boolean crlCertValid(LDAPStore crlStore, X509Certificate certificate, Va try { X509CertImpl peerCert = new X509CertImpl(certificate.getEncoded()); Enumeration eCRL = crlStore.searchAllCRLIssuingPointRecord(-1); - AuthorityKeyIdentifierExtension aPeeExt = (AuthorityKeyIdentifierExtension) peerCert.getExtension(PKIXExtensions.AuthorityKey_Id.toString()); - if(aPeeExt == null) { + AuthorityKeyIdentifierExtension peerAKIExt = (AuthorityKeyIdentifierExtension) peerCert.getExtension(PKIXExtensions.AuthorityKey_Id.toString()); + if(peerAKIExt == null) { logger.error("OCSPEngine: the certificate has not Authority Key Identifier Extension. CRL verification cannot be done."); return false; } @@ -175,15 +175,15 @@ private boolean crlCertValid(LDAPStore crlStore, X509Certificate certificate, Va X509CertImpl caCert = new X509CertImpl(tPt.getCACert()); try { - SubjectKeyIdentifierExtension sCaExt = (SubjectKeyIdentifierExtension) caCert.getExtension(PKIXExtensions.SubjectKey_Id.toString()); - if(sCaExt == null) { + SubjectKeyIdentifierExtension caSKIExt = (SubjectKeyIdentifierExtension) caCert.getExtension(PKIXExtensions.SubjectKey_Id.toString()); + if(caSKIExt == null) { logger.error("OCSPEngine: signing certificate missing Subject Key Identifier. Skip CA " + caCert.getName()); continue; } - KeyIdentifier sCaKeyId = (KeyIdentifier) sCaExt.get(SubjectKeyIdentifierExtension.KEY_ID); - KeyIdentifier aPeerKeyId = (KeyIdentifier) aPeeExt.get(AuthorityKeyIdentifierExtension.KEY_ID); - if(Arrays.equals(sCaKeyId.getIdentifier(), aPeerKeyId.getIdentifier())) { + KeyIdentifier caSKIId = (KeyIdentifier) caSKIExt.get(SubjectKeyIdentifierExtension.KEY_ID); + KeyIdentifier peerAKIId = (KeyIdentifier) peerAKIExt.get(AuthorityKeyIdentifierExtension.KEY_ID); + if(Arrays.equals(caSKIId.getIdentifier(), peerAKIId.getIdentifier())) { pt = tPt; } } catch (IOException e) { From 47f268c406f41c9b049390826aac5608db1b2c3f Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Tue, 8 Aug 2023 11:55:31 +0200 Subject: [PATCH 11/11] Update log message for revoked certificate --- base/server/cmsbundle/src/LogMessages.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/server/cmsbundle/src/LogMessages.properties b/base/server/cmsbundle/src/LogMessages.properties index 12815638856..fe8eac2ccb5 100644 --- a/base/server/cmsbundle/src/LogMessages.properties +++ b/base/server/cmsbundle/src/LogMessages.properties @@ -68,7 +68,7 @@ CMSCORE_AUTH_AUTH_FAILED=Failed to authenticate as admin UID={0}. Error: {1} CMSCORE_AUTH_UID_NOT_FOUND=UID {0} is not a user in the internal usr/grp database. Error {1} CMSCORE_AUTH_MISSING_CERT=Agent authentication missing certificate credential. CMSCORE_AUTH_NO_CERT=No Client Certificate Found -CMSCORE_AUTH_REVOKED_CERT=Cannot authenticate agent. Agent certificate has been revoked. +CMSCORE_AUTH_REVOKED_CERT=Cannot authenticate user. Role user certificate has been revoked. CMSCORE_AUTH_AGENT_AUTH_FAILED=Cannot authenticate agent with certificate Serial 0x{0} Subject DN {1}. Error: {2} CMSCORE_AUTH_CANNOT_AGENT_AUTH=Cannot authenticate agent. LDAP Error: {0} CMSCORE_AUTH_AGENT_USER_NOT_FOUND=Cannot authenticate agent. Could not find a user for the agent cert. Check errors from UGSubsystem.