-
Notifications
You must be signed in to change notification settings - Fork 137
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 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 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. 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 Move callback reference from CMS to CMSEngine Socket callback moved to CMSEngine to avoid dependencies on global variables. 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. 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. 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. Add comment for the option ocsp.store.ldapStore.validateConnCertWithCRL Modify local variable names Update log message for revoked certificate 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 Improve OCSP exception handling Add stack trace for error logs when they are generated from internal error 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.
- Loading branch information
Showing
7 changed files
with
343 additions
and
18 deletions.
There are no files selected for viewing
108 changes: 108 additions & 0 deletions
108
base/ocsp/src/main/java/com/netscape/cms/ocsp/CRLLdapValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
// --- 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) 2023 Red Hat, Inc. | ||
// All rights reserved. | ||
// --- END COPYRIGHT BLOCK --- | ||
package com.netscape.cms.ocsp; | ||
|
||
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; | ||
|
||
import com.netscape.certsrv.base.EBaseException; | ||
import com.netscape.cmscore.dbs.CRLIssuingPointRecord; | ||
|
||
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()); | ||
CRLIssuingPointRecord pt = null; | ||
try { | ||
X509CertImpl peerCert = new X509CertImpl(certificate.getEncoded()); | ||
Enumeration<CRLIssuingPointRecord> 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) { | ||
CRLIssuingPointRecord tPt = eCRL.nextElement(); | ||
logger.debug("CRLLdapValidator: CRL check issuer " + tPt.getId()); | ||
X509CertImpl caCert = new X509CertImpl(tPt.getCACert()); | ||
try { | ||
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 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) { | ||
logger.error("CRLLdapValidator: problem extracting key from SKI/AKI: " + e.getMessage(), e); | ||
} | ||
} | ||
} catch (EBaseException | CertificateException e) { | ||
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()); | ||
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(), e); | ||
} | ||
logger.error("CRLLdapValidator: peer certificate not valid"); | ||
return false; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.