From fb6aa8460c5d214788057b19bb104909361e1074 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Wed, 19 Jul 2023 15:15:40 +0200 Subject: [PATCH 01/14] 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 | 57 +++++++++++++++++++ .../com/netscape/cmscore/apps/CMSEngine.java | 32 ++++++----- 2 files changed, 76 insertions(+), 13 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 5f4d907d352..5d6c8872bf7 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 @@ -60,5 +60,62 @@ public void initSubsystem(Subsystem subsystem, ConfigStore subsystemConfig) thro } super.initSubsystem(subsystem, subsystemConfig); + if (subsystem instanceof OCSPAuthority) { + subsystem.startup(); + } } + + protected void startupSubsystems() throws Exception { + + for (Subsystem 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(); + initAuditor(); + initLogSubsystem(); + + initClientSocketListener(); + initServerSocketListener(); + + testLDAPConnections(); + initDatabase(); + + initJssSubsystem(); + initDBSubsystem(); + initUGSubsystem(); + initOIDLoaderSubsystem(); + initX500NameSubsystem(); + // skip TP subsystem; + // problem in needing dbsubsystem in constructor. and it's not used. + initRequestSubsystem(); + + + startupSubsystems(); + + initAuthSubsystem(); + initAuthzSubsystem(); + initCMSGateway(); + initJobsScheduler(); + + configureAutoShutdown(); + configureServerCertNickname(); + + 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 b7051ce31d1..2827f3206dc 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 @@ -1195,6 +1195,25 @@ public void start() throws Exception { String path = subsystemConfDir + File.separator + "CS.cfg"; loadConfig(path); + initSequence(); + + 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(); @@ -1231,19 +1250,6 @@ public void start() throws Exception { configureServerCertNickname(); initSecurityDomain(); - - ready = true; - isStarted = true; - - mStartupTime = System.currentTimeMillis(); - - logger.info(name + " engine started"); - - // Register TomcatJSS socket listener - TomcatJSS tomcatJss = TomcatJSS.getInstance(); - tomcatJss.addSocketListener(serverSocketListener); - - notifySubsystemStarted(); } public boolean isInRunningState() { From c4cd69a9e14caa676e055428294f85217f007be1 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Fri, 21 Jul 2023 18:09:17 +0200 Subject: [PATCH 02/14] 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 | 1 + .../org/dogtagpki/server/ocsp/OCSPEngine.java | 1 + .../java/com/netscape/cmscore/apps/CMS.java | 21 +++++ .../cmscore/ldapconn/PKISocketFactory.java | 4 +- 5 files changed, 106 insertions(+), 2 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 f1b64392d98..d574e632682 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 @@ -277,6 +277,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 5d6c8872bf7..29b55affbd4 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 @@ -65,6 +65,7 @@ public void initSubsystem(Subsystem subsystem, ConfigStore subsystemConfig) thro } } + protected void startupSubsystems() throws Exception { for (Subsystem 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 08247adb015..db8268f80ae 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; @@ -49,6 +50,26 @@ public final class CMS { public static final int PRE_OP_MODE = 0; public static final int RUNNING_MODE = 1; + private static CMSEngine engine; + + private static SSLCertificateApprovalCallback approvalCallback; + + public static CMSEngine getCMSEngine() { + return engine; + } + + 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 3835d41a7ac..8150123e1a8 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 @@ -175,7 +175,7 @@ public SSLSocket makeSSLSocket(String host, int port) throws UnknownHostExceptio SSLSocket s; if (clientCertNickname == 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 @@ -185,7 +185,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(clientCertNickname)); } From 66e95749425f8136632000613b886ff927c81ef1 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Fri, 28 Jul 2023 10:56:56 +0200 Subject: [PATCH 03/14] 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 d574e632682..edc438cf706 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 = @@ -277,7 +278,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 1a291d6a5500c441cb88a6d0f3b3afa8b9aa2f74 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Fri, 28 Jul 2023 16:30:27 +0200 Subject: [PATCH 04/14] 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 edc438cf706..7e7579773fd 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. @@ -141,6 +143,7 @@ public void init(ConfigStore config, DBSubsystem dbSubsystem) throws EBaseExcept DEF_CA_CERT_ATTR); mByName = mConfig.getBoolean(PROP_BY_NAME, true); + mCheckConnection = mConfig.getBoolean(PROP_CHECK_SUBSYSTEM_CONNECTION, false); } /** @@ -278,7 +281,7 @@ public void startup() throws EBaseException { updater.start(); } - if(mConfig.getBoolean(PROP_CHECK_SUBSYSTEM_CONNECTION, false)) { + if(mCheckConnection) { CMS.setApprovalCallbask(new CRLLdapValidator(this)); } } @@ -535,6 +538,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 29b55affbd4..eaa5dd55c56 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 @@ -17,11 +17,22 @@ // --- END COPYRIGHT BLOCK --- 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 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.Subsystem; +import com.netscape.cms.ocsp.LDAPStore; import com.netscape.cmscore.apps.CMSEngine; import com.netscape.cmscore.base.ConfigStorage; import com.netscape.cmscore.base.ConfigStore; +import com.netscape.cmscore.dbs.CRLIssuingPointRecord; import com.netscape.ocsp.OCSPAuthority; public class OCSPEngine extends CMSEngine { @@ -118,5 +129,65 @@ protected void initSequence() throws Exception { initSecurityDomain(); } + @Override + public boolean isRevoked(X509Certificate[] certificates) { + LDAPStore crlStore = null; + for (Subsystem 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()); + CRLIssuingPointRecord pt = null; + try { + Enumeration eCRL = crlStore.searchAllCRLIssuingPointRecord(-1); + while (eCRL.hasMoreElements() && pt == null) { + CRLIssuingPointRecord 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 3034d23d71681abe103ec675e99fb7fde44f4528 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Mon, 31 Jul 2023 18:34:42 +0200 Subject: [PATCH 05/14] Move callback reference from CMS to CMSEngine Socket callback moved to CMSEngine to avoid dependencies on global variables. --- .../netscape/cms/ocsp/CRLLdapValidator.java | 8 +++---- .../java/com/netscape/cms/ocsp/LDAPStore.java | 3 ++- .../org/dogtagpki/server/ocsp/OCSPEngine.java | 15 ++++++++++--- .../java/com/netscape/cmscore/apps/CMS.java | 21 ------------------- .../cmscore/ldapconn/PKISocketFactory.java | 12 ++++++++--- 5 files changed, 27 insertions(+), 32 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 7e7579773fd..882d4abd073 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 @@ -28,6 +28,7 @@ import java.util.Locale; import java.util.Vector; +import org.dogtagpki.server.ocsp.OCSPEngine; import org.mozilla.jss.asn1.GeneralizedTime; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.netscape.security.x509.RevokedCertificate; @@ -282,7 +283,7 @@ public void startup() throws EBaseException { updater.start(); } if(mCheckConnection) { - CMS.setApprovalCallbask(new CRLLdapValidator(this)); + OCSPEngine.getInstance().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 eaa5dd55c56..d9907d34679 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 @@ -24,6 +24,7 @@ import javax.security.auth.x500.X500Principal; import org.mozilla.jss.netscape.security.x509.X509CRLImpl; +import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; import org.mozilla.jss.ssl.SSLCertificateApprovalCallback.ValidityStatus; import com.netscape.certsrv.base.EBaseException; @@ -38,6 +39,7 @@ public class OCSPEngine extends CMSEngine { static OCSPEngine instance; + protected SSLCertificateApprovalCallback approvalCallback; public OCSPEngine() { super("OCSP"); @@ -147,11 +149,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; } @@ -190,4 +192,11 @@ private boolean crlCertValid(LDAPStore crlStore, X509Certificate certificate, Va return false; } + public SSLCertificateApprovalCallback getApprovalCallback() { + return approvalCallback; + } + + public void setApprovalCallback(SSLCertificateApprovalCallback approvalCallback) { + this.approvalCallback = approvalCallback; + } } 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 db8268f80ae..08247adb015 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; @@ -50,26 +49,6 @@ public final class CMS { public static final int PRE_OP_MODE = 0; public static final int RUNNING_MODE = 1; - private static CMSEngine engine; - - private static SSLCertificateApprovalCallback approvalCallback; - - public static CMSEngine getCMSEngine() { - return engine; - } - - 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 8150123e1a8..cfdfeb84c66 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 @@ -26,6 +26,8 @@ import java.util.List; import java.util.Vector; +import org.dogtagpki.server.ocsp.OCSPEngine; +import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; import org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback; import org.mozilla.jss.ssl.SSLHandshakeCompletedEvent; import org.mozilla.jss.ssl.SSLHandshakeCompletedListener; @@ -173,10 +175,14 @@ public SSLSocket makeSSLSocket(String host, int port) throws UnknownHostExceptio // let it inherit TLS range and cipher settings SSLSocket s; + SSLCertificateApprovalCallback callback = null; - if (clientCertNickname == null) { - s = new SSLSocket(host, port, null, 0, CMS.getApprovalCallback(), null); + if (OCSPEngine.getInstance() != null) { + callback = OCSPEngine.getInstance().getApprovalCallback(); + } + if (clientCertNickname == null) { + s = new SSLSocket(host, port, null, 0, callback, null); } else { // Let's create a selection callback in the case the client auth // No longer manually set the cert name. @@ -185,7 +191,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(clientCertNickname)); } From 79e1bbdda31739bb60acb5bc564e73973c6d1f41 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Thu, 3 Aug 2023 20:50:28 +0200 Subject: [PATCH 06/14] 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. --- .../netscape/cms/ocsp/CRLLdapValidator.java | 16 +++++++++++++++- .../java/com/netscape/cms/ocsp/LDAPStore.java | 2 +- .../org/dogtagpki/server/ocsp/OCSPEngine.java | 18 ++++++++++++++++-- 3 files changed, 32 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 882d4abd073..b568c31a384 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 @@ -144,7 +144,7 @@ public void init(ConfigStore config, DBSubsystem dbSubsystem) throws EBaseExcept 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 d9907d34679..6d472f1d0df 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 @@ -17,6 +17,12 @@ // --- END COPYRIGHT BLOCK --- 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; @@ -24,6 +30,7 @@ import javax.security.auth.x500.X500Principal; import org.mozilla.jss.netscape.security.x509.X509CRLImpl; +import org.mozilla.jss.netscape.security.x509.X509CertImpl; import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; import org.mozilla.jss.ssl.SSLCertificateApprovalCallback.ValidityStatus; @@ -159,7 +166,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()); CRLIssuingPointRecord pt = null; try { Enumeration eCRL = crlStore.searchAllCRLIssuingPointRecord(-1); @@ -167,7 +174,14 @@ private boolean crlCertValid(LDAPStore crlStore, X509Certificate certificate, Va CRLIssuingPointRecord 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 09f3287edfe15960cb35e66a00e958bba0cfecdb Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Fri, 4 Aug 2023 12:45:07 +0200 Subject: [PATCH 07/14] 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 b568c31a384..3fa67942f8a 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 @@ -82,7 +82,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 = @@ -95,7 +95,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; /** @@ -144,7 +144,7 @@ public void init(ConfigStore config, DBSubsystem dbSubsystem) throws EBaseExcept 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); } /** @@ -282,7 +282,7 @@ public void startup() throws EBaseException { updater.start(); } - if(mCheckConnection) { + if(mValidateConnection) { OCSPEngine.getInstance().setApprovalCallback(new CRLLdapValidator(this)); } } @@ -541,7 +541,7 @@ public void setConfigParameters(NameValuePairs pairs) } public boolean isCRLCheckAvailable() { - return mCheckConnection; + return mValidateConnection; } } From b1188aa42160da1b4f5cd736114345b420f9db61 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Fri, 4 Aug 2023 19:42:38 +0200 Subject: [PATCH 08/14] 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 | 41 ++++++++++++------- 2 files changed, 54 insertions(+), 28 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 6d472f1d0df..ba4b280d131 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,17 +18,17 @@ 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 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; @@ -169,22 +169,35 @@ private boolean crlCertValid(LDAPStore crlStore, X509Certificate certificate, Va logger.info("OCSPEngine: validate of peer's certificate for the connection " + certificate.getSubjectX500Principal()); CRLIssuingPointRecord 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) { CRLIssuingPointRecord 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 9b6cf5de26e4135011998bb983795c07e5e3a88b Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Fri, 4 Aug 2023 19:57:58 +0200 Subject: [PATCH 09/14] 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 3fa67942f8a..2c1fa248d3b 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 @@ -82,6 +82,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 ea7a7f57c2531d97f29b7980c86b1a76c14bd880 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Fri, 4 Aug 2023 20:09:30 +0200 Subject: [PATCH 10/14] 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 ba4b280d131..c85ee96ea61 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 @@ -171,8 +171,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; } @@ -182,15 +182,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 e9637297d52a0ff740ec0f22b79f4957c943a9c0 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Tue, 8 Aug 2023 11:55:31 +0200 Subject: [PATCH 11/14] Update log message for revoked certificate --- base/server/src/main/resources/LogMessages.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/server/src/main/resources/LogMessages.properties b/base/server/src/main/resources/LogMessages.properties index 5e3c2131151..c724ebb2923 100644 --- a/base/server/src/main/resources/LogMessages.properties +++ b/base/server/src/main/resources/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. From 5c146fa6f2ebda92a2327c49cc9fa923d1c6db87 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Wed, 16 Aug 2023 17:16:32 +0200 Subject: [PATCH 12/14] Modify the callback location Due to refactoring the engine object is not accessible using static reference from outside the declaring package. Therefore the callback reference have been stored globally in the `CMSEngine` class --- .../java/com/netscape/cms/ocsp/CRLLdapValidator.java | 8 ++++---- .../main/java/com/netscape/cms/ocsp/LDAPStore.java | 4 ++-- .../java/org/dogtagpki/server/ocsp/OCSPEngine.java | 12 +----------- .../java/com/netscape/cmscore/apps/CMSEngine.java | 11 +++++++++++ .../netscape/cmscore/ldapconn/PKISocketFactory.java | 12 +++--------- 5 files changed, 21 insertions(+), 26 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 c6112aaf984..8232e3880d1 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 @@ -33,7 +33,7 @@ import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; import com.netscape.certsrv.base.EBaseException; -import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord; +import com.netscape.cmscore.dbs.CRLIssuingPointRecord; public class CRLLdapValidator implements SSLCertificateApprovalCallback { @@ -52,17 +52,17 @@ 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()); - ICRLIssuingPointRecord pt = null; + CRLIssuingPointRecord pt = null; try { X509CertImpl peerCert = new X509CertImpl(certificate.getEncoded()); - Enumeration eCRL = crlStore.searchAllCRLIssuingPointRecord(-1); + Enumeration eCRL = crlStore.searchAllCRLIssuingPointRecord(-1); 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; } while (eCRL.hasMoreElements() && pt == null) { - ICRLIssuingPointRecord tPt = eCRL.nextElement(); + CRLIssuingPointRecord tPt = eCRL.nextElement(); logger.debug("CRLLdapValidator: CRL check issuer " + tPt.getId()); X509CertImpl caCert = new X509CertImpl(tPt.getCACert()); try { 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 2c1fa248d3b..0c41a3dec4c 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 @@ -28,7 +28,6 @@ import java.util.Locale; import java.util.Vector; -import org.dogtagpki.server.ocsp.OCSPEngine; import org.mozilla.jss.asn1.GeneralizedTime; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.netscape.security.x509.RevokedCertificate; @@ -42,6 +41,7 @@ import com.netscape.certsrv.common.NameValuePairs; import com.netscape.certsrv.ocsp.IDefStore; import com.netscape.cmscore.apps.CMS; +import com.netscape.cmscore.apps.CMSEngine; import com.netscape.cmscore.base.ConfigStore; import com.netscape.cmscore.dbs.CRLIssuingPointRecord; import com.netscape.cmscore.dbs.DBSubsystem; @@ -287,7 +287,7 @@ public void startup() throws EBaseException { updater.start(); } if(mValidateConnection) { - OCSPEngine.getInstance().setApprovalCallback(new CRLLdapValidator(this)); + CMSEngine.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 c85ee96ea61..bdce272b73b 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 @@ -31,7 +31,6 @@ 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; import org.mozilla.jss.ssl.SSLCertificateApprovalCallback.ValidityStatus; import com.netscape.certsrv.base.EBaseException; @@ -46,7 +45,6 @@ public class OCSPEngine extends CMSEngine { static OCSPEngine instance; - protected SSLCertificateApprovalCallback approvalCallback; public OCSPEngine() { super("OCSP"); @@ -101,12 +99,12 @@ protected void initSequence() throws Exception { initDebug(); + initAuditor(); init(); initPasswordStore(); initSubsystemListeners(); initSecurityProvider(); initPluginRegistry(); - initAuditor(); initLogSubsystem(); initClientSocketListener(); @@ -218,12 +216,4 @@ private boolean crlCertValid(LDAPStore crlStore, X509Certificate certificate, Va logger.info("OCSPEngine: peer certificate not valid"); return false; } - - public SSLCertificateApprovalCallback getApprovalCallback() { - return approvalCallback; - } - - public void setApprovalCallback(SSLCertificateApprovalCallback approvalCallback) { - this.approvalCallback = approvalCallback; - } } 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 2827f3206dc..4fad7d4dde4 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.base.EBaseException; import com.netscape.certsrv.base.SecurityDomainSessionTable; @@ -184,6 +185,8 @@ public class CMSEngine { private static final int PW_CANNOT_CONNECT = 3; private static final int PW_MAX_ATTEMPTS = 3; + protected static SSLCertificateApprovalCallback approvalCallback; + public CMSEngine(String name) { this.id = name.toLowerCase(); this.name = name; @@ -191,6 +194,14 @@ public CMSEngine(String name) { logger.info("Creating " + name + " engine"); } + public static SSLCertificateApprovalCallback getApprovalCallback() { + return approvalCallback; + } + + public static void setApprovalCallback(SSLCertificateApprovalCallback approvalCallback) { + CMSEngine.approvalCallback = approvalCallback; + } + public String getID() { return id; } 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 cfdfeb84c66..ff733740715 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 @@ -26,8 +26,6 @@ import java.util.List; import java.util.Vector; -import org.dogtagpki.server.ocsp.OCSPEngine; -import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; import org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback; import org.mozilla.jss.ssl.SSLHandshakeCompletedEvent; import org.mozilla.jss.ssl.SSLHandshakeCompletedListener; @@ -36,6 +34,7 @@ import com.netscape.certsrv.logging.SignedAuditEvent; import com.netscape.certsrv.logging.event.ClientAccessSessionEstablishEvent; +import com.netscape.cmscore.apps.CMSEngine; import com.netscape.cmscore.logging.Auditor; import com.netscape.cmsutil.crypto.CryptoUtil; @@ -175,14 +174,9 @@ public SSLSocket makeSSLSocket(String host, int port) throws UnknownHostExceptio // let it inherit TLS range and cipher settings SSLSocket s; - SSLCertificateApprovalCallback callback = null; - - if (OCSPEngine.getInstance() != null) { - callback = OCSPEngine.getInstance().getApprovalCallback(); - } if (clientCertNickname == null) { - s = new SSLSocket(host, port, null, 0, callback, null); + s = new SSLSocket(host, port, null, 0, CMSEngine.getApprovalCallback(), null); } else { // Let's create a selection callback in the case the client auth // No longer manually set the cert name. @@ -191,7 +185,7 @@ public SSLSocket makeSSLSocket(String host, int port) throws UnknownHostExceptio Socket js = new Socket(InetAddress.getByName(host), port); s = new SSLSocket(js, host, - callback, + CMSEngine.getApprovalCallback(), new SSLClientCertificateSelectionCB(clientCertNickname)); } From 760b625825b88eaeba8a4b36db4d4ea72f4ac771 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Thu, 17 Aug 2023 11:50:28 +0200 Subject: [PATCH 13/14] Improve OCSP exception handling Add stack trace for error logs when they are generated from internal error --- .../main/java/com/netscape/cms/ocsp/CRLLdapValidator.java | 2 +- .../src/main/java/org/dogtagpki/server/ocsp/OCSPEngine.java | 6 +++--- 2 files changed, 4 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 8232e3880d1..4aee75a230f 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 @@ -78,7 +78,7 @@ public boolean approve(X509Certificate certificate, ValidityStatus currentStatus pt = tPt; } } catch (IOException e) { - logger.error("CRLLdapValidator: problem extracting key from SKI/AKI"); + logger.error("CRLLdapValidator: problem extracting key from SKI/AKI: " + e.getMessage(), e); } } } catch (EBaseException | CertificateException 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 bdce272b73b..fea6351c083 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 @@ -100,6 +100,7 @@ protected void initSequence() throws Exception { initDebug(); initAuditor(); + initDBSubsystem(); init(); initPasswordStore(); initSubsystemListeners(); @@ -114,7 +115,6 @@ protected void initSequence() throws Exception { initDatabase(); initJssSubsystem(); - initDBSubsystem(); initUGSubsystem(); initOIDLoaderSubsystem(); initX500NameSubsystem(); @@ -192,7 +192,7 @@ private boolean crlCertValid(LDAPStore crlStore, X509Certificate certificate, Va pt = tPt; } } catch (IOException e) { - logger.error("OCSPEngine: problem extracting key from SKI/AKI"); + logger.error("OCSPEngine: problem extracting key from SKI/AKI: " + e.getMessage(), e); } } } catch (EBaseException | CertificateException e) { @@ -211,7 +211,7 @@ private boolean crlCertValid(LDAPStore crlStore, X509Certificate certificate, Va return true; } } catch (Exception e) { - logger.error("OCSPEngine: crl check error. " + e.getMessage()); + logger.error("OCSPEngine: crl check error. " + e.getMessage(), e); } logger.info("OCSPEngine: peer certificate not valid"); return false; From 8362f1e158ac87d8863160df8cd84e51ac607eb7 Mon Sep 17 00:00:00 2001 From: Marco Fargetta Date: Thu, 17 Aug 2023 17:13:19 +0200 Subject: [PATCH 14/14] Move the callback to PKISocketFactory and fix startup Moving the callback to `PKISocketFactory` there is no need to have store it in a static variable. However, only OCSPEngine instances have a valid value so no other instances are used. The startup order has been fixed. --- .../java/com/netscape/cms/ocsp/LDAPStore.java | 6 +++--- .../org/dogtagpki/server/ocsp/OCSPEngine.java | 20 ++++++++++++++++++- .../com/netscape/cmscore/apps/CMSEngine.java | 8 ++++---- .../ldapconn/LdapBoundConnFactory.java | 1 + .../cmscore/ldapconn/PKISocketFactory.java | 17 ++++++++++++---- 5 files changed, 40 insertions(+), 12 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 0c41a3dec4c..6714ccb4a4b 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 @@ -28,6 +28,7 @@ import java.util.Locale; import java.util.Vector; +import org.dogtagpki.server.ocsp.OCSPEngine; import org.mozilla.jss.asn1.GeneralizedTime; import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.netscape.security.x509.RevokedCertificate; @@ -41,7 +42,6 @@ import com.netscape.certsrv.common.NameValuePairs; import com.netscape.certsrv.ocsp.IDefStore; import com.netscape.cmscore.apps.CMS; -import com.netscape.cmscore.apps.CMSEngine; import com.netscape.cmscore.base.ConfigStore; import com.netscape.cmscore.dbs.CRLIssuingPointRecord; import com.netscape.cmscore.dbs.DBSubsystem; @@ -286,8 +286,8 @@ public void startup() throws EBaseException { updater.start(); } - if(mValidateConnection) { - CMSEngine.setApprovalCallback(new CRLLdapValidator(this)); + if(mValidateConnection && OCSPEngine.getInstance() != null) { + OCSPEngine.getInstance().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 fea6351c083..b416c4e6a6c 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 @@ -37,9 +37,14 @@ import com.netscape.certsrv.base.Subsystem; import com.netscape.cms.ocsp.LDAPStore; import com.netscape.cmscore.apps.CMSEngine; +import com.netscape.cmscore.apps.DatabaseConfig; import com.netscape.cmscore.base.ConfigStorage; import com.netscape.cmscore.base.ConfigStore; import com.netscape.cmscore.dbs.CRLIssuingPointRecord; +import com.netscape.cmscore.dbs.DBSubsystem; +import com.netscape.cmscore.ldapconn.LDAPConfig; +import com.netscape.cmscore.ldapconn.PKISocketConfig; +import com.netscape.cmsutil.password.PasswordStore; import com.netscape.ocsp.OCSPAuthority; public class OCSPEngine extends CMSEngine { @@ -69,6 +74,13 @@ public OCSPAuthority getOCSP() { return (OCSPAuthority) getSubsystem(OCSPAuthority.ID); } + @Override + public void initDBSubsystem() throws Exception { + + dbSubsystem = new DBSubsystem(); + dbSubsystem.setCMSEngine(this); + dbSubsystem.setEngineConfig(config); + } @Override public void initSubsystem(Subsystem subsystem, ConfigStore subsystemConfig) throws Exception { @@ -88,8 +100,14 @@ protected void startupSubsystems() throws Exception { for (Subsystem subsystem : subsystems.values()) { logger.info("CMSEngine: Starting " + subsystem.getId() + " subsystem"); - if (!(subsystem instanceof OCSPAuthority)) + if (!(subsystem instanceof OCSPAuthority)) { + DatabaseConfig dbConfig = config.getDatabaseConfig(); + LDAPConfig ldapConfig = dbConfig.getLDAPConfig(); + PKISocketConfig socketConfig = config.getSocketConfig(); + PasswordStore passwordStore = getPasswordStore(); + dbSubsystem.init(dbConfig, ldapConfig, socketConfig, passwordStore); subsystem.startup(); + } } // global admin servlet. (anywhere else more fit for this ?) 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 4fad7d4dde4..0baf101103e 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 @@ -185,7 +185,7 @@ public class CMSEngine { private static final int PW_CANNOT_CONNECT = 3; private static final int PW_MAX_ATTEMPTS = 3; - protected static SSLCertificateApprovalCallback approvalCallback; + protected SSLCertificateApprovalCallback approvalCallback; public CMSEngine(String name) { this.id = name.toLowerCase(); @@ -194,12 +194,12 @@ public CMSEngine(String name) { logger.info("Creating " + name + " engine"); } - public static SSLCertificateApprovalCallback getApprovalCallback() { + public SSLCertificateApprovalCallback getApprovalCallback() { return approvalCallback; } - public static void setApprovalCallback(SSLCertificateApprovalCallback approvalCallback) { - CMSEngine.approvalCallback = approvalCallback; + public void setApprovalCallback(SSLCertificateApprovalCallback approvalCallback) { + this.approvalCallback = approvalCallback; } public String getID() { diff --git a/base/server/src/main/java/com/netscape/cmscore/ldapconn/LdapBoundConnFactory.java b/base/server/src/main/java/com/netscape/cmscore/ldapconn/LdapBoundConnFactory.java index 870a15b3767..8bd3c9fef79 100644 --- a/base/server/src/main/java/com/netscape/cmscore/ldapconn/LdapBoundConnFactory.java +++ b/base/server/src/main/java/com/netscape/cmscore/ldapconn/LdapBoundConnFactory.java @@ -296,6 +296,7 @@ private LdapBoundConnection makeNewConnection(boolean errorIfDown) throws ELdapE if (engine != null) { socketFactory.setAuditor(engine.getAuditor()); socketFactory.addSocketListener(engine.getClientSocketListener()); + socketFactory.setApprovalCallback(engine.getApprovalCallback()); } socketFactory.setSecure(mConnInfo.getSecure()); if (mAuthInfo.getAuthType() == LdapAuthInfo.LDAP_AUTHTYPE_SSLCLIENTAUTH) { 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 ff733740715..f9261d34591 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 @@ -26,6 +26,7 @@ import java.util.List; import java.util.Vector; +import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; import org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback; import org.mozilla.jss.ssl.SSLHandshakeCompletedEvent; import org.mozilla.jss.ssl.SSLHandshakeCompletedListener; @@ -34,7 +35,6 @@ import com.netscape.certsrv.logging.SignedAuditEvent; import com.netscape.certsrv.logging.event.ClientAccessSessionEstablishEvent; -import com.netscape.cmscore.apps.CMSEngine; import com.netscape.cmscore.logging.Auditor; import com.netscape.cmsutil.crypto.CryptoUtil; @@ -56,7 +56,7 @@ public class PKISocketFactory implements LDAPSSLSocketFactoryExt { private boolean mClientAuth = false; private boolean keepAlive = true; private String mClientCiphers = null; - + private SSLCertificateApprovalCallback approvalCallback; protected List socketListeners = new ArrayList<>(); /* @@ -119,6 +119,14 @@ public void removeSocketListener(SSLSocketListener socketListener) { socketListeners.remove(socketListener); } + public SSLCertificateApprovalCallback getApprovalCallback() { + return approvalCallback; + } + + public void setApprovalCallback(SSLCertificateApprovalCallback approvalCallback) { + this.approvalCallback = approvalCallback; + } + public void init() { init(null); } @@ -176,7 +184,7 @@ public SSLSocket makeSSLSocket(String host, int port) throws UnknownHostExceptio SSLSocket s; if (clientCertNickname == null) { - s = new SSLSocket(host, port, null, 0, CMSEngine.getApprovalCallback(), null); + s = new SSLSocket(host, port, null, 0, approvalCallback, null); } else { // Let's create a selection callback in the case the client auth // No longer manually set the cert name. @@ -185,7 +193,7 @@ public SSLSocket makeSSLSocket(String host, int port) throws UnknownHostExceptio Socket js = new Socket(InetAddress.getByName(host), port); s = new SSLSocket(js, host, - CMSEngine.getApprovalCallback(), + approvalCallback, new SSLClientCertificateSelectionCB(clientCertNickname)); } @@ -193,6 +201,7 @@ public SSLSocket makeSSLSocket(String host, int port) throws UnknownHostExceptio s.enableV2CompatibleHello(false); for (SSLSocketListener socketListener : socketListeners) { + logger.error("Add listener!!! " + socketListener.toString()); s.addSocketListener(socketListener); }