Skip to content

Commit

Permalink
Add callback for CRL validation at application level
Browse files Browse the repository at this point in the history
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
  • Loading branch information
fmarco76 committed Jul 21, 2023
1 parent b9a9eb0 commit ecc6b01
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// --- 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<ICRLIssuingPointRecord> 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());
}
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -238,6 +237,7 @@ public void startup() throws EBaseException {

updater.start();
}
CMS.setApprovalCallbask(new CRLLdapValidator(this));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public void initSubsystem(ISubsystem subsystem, IConfigStore subsystemConfig) th
}
}


protected void startupSubsystems() throws Exception {

for (ISubsystem subsystem : subsystems.values()) {
Expand Down
11 changes: 11 additions & 0 deletions base/server/src/main/java/com/netscape/cmscore/apps/CMS.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -53,6 +54,8 @@ public final class CMS {

private static CMSEngine engine;

private static SSLCertificateApprovalCallback approvalCallbask;

public static CMSEngine getCMSEngine() {
return engine;
}
Expand All @@ -61,6 +64,14 @@ public static void setCMSEngine(CMSEngine engine) {
CMS.engine = engine;
}

public static SSLCertificateApprovalCallback getApprovalCallbask() {
return approvalCallbask;
}

public static void setApprovalCallbask(SSLCertificateApprovalCallback approvalCallbask) {
CMS.approvalCallbask = approvalCallbask;
}

/**
* Return the product name from /usr/share/pki/CS_SERVER_VERSION
* which is provided by the server theme package.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.getApprovalCallbask(), null);

} else {
// Let's create a selection callback in the case the client auth
Expand All @@ -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.getApprovalCallbask(),
new SSLClientCertificateSelectionCB(mClientAuthCertNickname));
}

Expand Down

0 comments on commit ecc6b01

Please sign in to comment.