summaryrefslogtreecommitdiffstats
path: root/pki/base/common/src/com/netscape/cms/ocsp/DefStore.java
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/common/src/com/netscape/cms/ocsp/DefStore.java')
-rw-r--r--pki/base/common/src/com/netscape/cms/ocsp/DefStore.java924
1 files changed, 924 insertions, 0 deletions
diff --git a/pki/base/common/src/com/netscape/cms/ocsp/DefStore.java b/pki/base/common/src/com/netscape/cms/ocsp/DefStore.java
new file mode 100644
index 000000000..7c9c2bb1f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/ocsp/DefStore.java
@@ -0,0 +1,924 @@
+// --- 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.math.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authority.*;
+
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.crldb.ICRLRepository;
+import com.netscape.cmsutil.ocsp.*;
+import com.netscape.certsrv.apps.*;
+
+import org.mozilla.jss.pkix.cert.Extension;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.primitive.*;
+
+
+/**
+ * This is the default OCSP store that stores revocation information
+ * as certificate record (CMS internal data structure).
+ *
+ * @version $Revision$, $Date$
+ */
+public class DefStore implements IDefStore, IExtendedPluginInfo {
+
+ // refreshInSec is useful in the master-clone situation.
+ // clone does not know that the CRL has been updated in
+ // the master (by default no refresh)
+ private static final String PROP_USE_CACHE = "useCache";
+
+ private static final String PROP_REFRESH_IN_SEC = "refreshInSec";
+ private static final int DEF_REFRESH_IN_SEC = 0;
+
+ public static final BigInteger BIG_ZERO = new BigInteger("0");
+ public static final Long MINUS_ONE = Long.valueOf(-1);
+
+ private final static String PROP_BY_NAME =
+ "byName";
+ private final static String PROP_WAIT_ON_CRL_UPDATE =
+ "waitOnCRLUpdate";
+ private final static String PROP_NOT_FOUND_GOOD = "notFoundAsGood";
+ private final static String PROP_INCLUDE_NEXT_UPDATE =
+ "includeNextUpdate";
+
+ protected Hashtable mReqCounts = new Hashtable();
+ protected boolean mNotFoundGood = true;
+ protected boolean mUseCache = true;
+ protected boolean mByName = true;
+ protected boolean mIncludeNextUpdate = false;
+ protected Hashtable mCacheCRLIssuingPoints = new Hashtable();
+ private IOCSPAuthority mOCSPAuthority = null;
+ private IConfigStore mConfig = null;
+ private String mId = null;
+ private IDBSubsystem mDBService = null;
+ private X509CRLImpl mCRLImpl = null;
+ private CRLNumberExtension mCRLNumberExt = null;
+ private int mStateCount = 0;
+
+ /**
+ * Constructs the default store.
+ */
+ public DefStore() {
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector v = new Vector();
+
+ v.addElement(PROP_NOT_FOUND_GOOD + ";boolean; " + CMS.getUserMessage(locale, "CMS_OCSP_DEFSTORE_PROP_NOT_FOUND_GOOD"));
+ v.addElement(PROP_BY_NAME + ";boolean; " + CMS.getUserMessage(locale, "CMS_OCSP_DEFSTORE_PROP_BY_NAME"));
+ v.addElement(PROP_INCLUDE_NEXT_UPDATE + ";boolean; " + CMS.getUserMessage(locale, "CMS_OCSP_DEFSTORE_PROP_INCLUDE_NEXT_UPDATE"));
+ v.addElement(IExtendedPluginInfo.HELP_TEXT + "; " + CMS.getUserMessage(locale, "CMS_OCSP_DEFSTORE_DESC"));
+ v.addElement(IExtendedPluginInfo.HELP_TOKEN + ";configuration-ocspstores-defstore");
+ return com.netscape.cmsutil.util.Utils.getStringArrayFromVector(v);
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mOCSPAuthority = (IOCSPAuthority) owner;
+ mConfig = config;
+
+ mDBService = (IDBSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_DBS);
+
+ // Standalone OCSP server only stores information about revoked
+ // certificates. So there is no way for the OCSP server to
+ // tell if a certificate is good (issued) or not.
+ // When an OCSP client asks the status of a certificate,
+ // the OCSP server by default returns GOOD. If the server
+ // returns UNKNOWN, the OCSP client (browser) will display
+ // a error dialog that confuses the end-user.
+ //
+ // OCSP response can return unknown or good when a certificate
+ // is not revoked.
+ mNotFoundGood = mConfig.getBoolean(PROP_NOT_FOUND_GOOD, true);
+
+ mUseCache = mConfig.getBoolean(PROP_USE_CACHE, true);
+
+ mByName = mConfig.getBoolean(PROP_BY_NAME, true);
+
+ // To include next update in the OCSP response. If included,
+ // PSM (client) will check to see if the revoked information
+ // is too old or not
+ mIncludeNextUpdate = mConfig.getBoolean(PROP_INCLUDE_NEXT_UPDATE,
+ false);
+
+ // should move this into DBSubsystem ....
+ IDBRegistry reg = mDBService.getRegistry();
+
+ // init web gateway.
+ initWebGateway();
+
+ /**
+ DeleteOldCRLsThread t = new DeleteOldCRLsThread(this);
+ t.start();
+ **/
+ // deleteOldCRLs();
+ }
+
+ /**
+ * init web gateway - just gets the ee gateway for this CA.
+ */
+ private void initWebGateway()
+ throws EBaseException {
+ }
+
+ public IRepositoryRecord createRepositoryRecord() {
+ return CMS.createRepositoryRecord();
+ }
+
+ /**
+ * Returns to the client once the CRL is received.
+ */
+ public boolean waitOnCRLUpdate() {
+ boolean defaultVal = true;
+
+ try {
+ return mConfig.getBoolean(PROP_WAIT_ON_CRL_UPDATE, defaultVal);
+ } catch (EBaseException e) {
+ return defaultVal;
+ }
+ }
+
+ public boolean includeNextUpdate() {
+ return mIncludeNextUpdate;
+ }
+
+ public boolean isNotFoundGood() {
+ return mNotFoundGood;
+ }
+
+ public long getReqCount(String id) {
+ Long c = (Long) mReqCounts.get(id);
+
+ if (c == null)
+ return 0;
+ else
+ return c.longValue();
+ }
+
+ public void incReqCount(String id) {
+ mReqCounts.put(id, Long.valueOf(getReqCount(id) + 1));
+ }
+
+ /**
+ * This store will not delete the old CRL until the
+ * new one is totally committed.
+ */
+ public void deleteOldCRLs() throws EBaseException {
+ Enumeration recs = searchCRLIssuingPointRecord(
+ "objectclass=" +
+ CMS.getCRLIssuingPointRecordName(),
+ 100);
+ X509CertImpl theCert = null;
+ ICRLIssuingPointRecord theRec = null;
+
+ while (recs.hasMoreElements()) {
+ ICRLIssuingPointRecord rec = (ICRLIssuingPointRecord)
+ recs.nextElement();
+
+ deleteOldCRLsInCA(rec.getId());
+ }
+ }
+
+ public void deleteOldCRLsInCA(String caName) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ ICRLIssuingPointRecord cp = (ICRLIssuingPointRecord)
+ readCRLIssuingPoint(caName);
+
+ if (cp == null)
+ return; // nothing to do
+ if (cp.getThisUpdate() == null)
+ return; // nothing to do
+ String thisUpdate = Long.toString(
+ cp.getThisUpdate().getTime());
+ Enumeration e = searchRepository(
+ caName,
+ "(!" + IRepositoryRecord.ATTR_SERIALNO + "=" +
+ thisUpdate + ")");
+
+ while (e != null && e.hasMoreElements()) {
+ IRepositoryRecord r = (IRepositoryRecord)
+ e.nextElement();
+ Enumeration recs =
+ searchCertRecord(caName,
+ r.getSerialNumber().toString(),
+ ICertRecord.ATTR_ID + "=*");
+
+ log(ILogger.LL_INFO, "remove CRL 0x" +
+ r.getSerialNumber().toString(16) +
+ " of " + caName);
+ String rep_dn = "ou=" +
+ r.getSerialNumber().toString() +
+ ",cn=" + transformDN(caName) + "," +
+ getBaseDN();
+
+ while (recs != null && recs.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) recs.nextElement();
+ String cert_dn = "cn=" +
+ rec.getSerialNumber().toString() + "," + rep_dn;
+
+ s.delete(cert_dn);
+ }
+ s.delete(rep_dn);
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ public void log(int event, int level, String msg) {
+ mOCSPAuthority.log(event, level, msg);
+ }
+
+ public void log(int level, String msg) {
+ mOCSPAuthority.log(level, msg);
+ }
+
+ public void startup() throws EBaseException {
+ int refresh = mConfig.getInteger(PROP_REFRESH_IN_SEC,
+ DEF_REFRESH_IN_SEC);
+ if (refresh > 0) {
+ DefStoreCRLUpdater updater =
+ new DefStoreCRLUpdater(mCacheCRLIssuingPoints, refresh);
+ updater.start();
+ }
+ }
+
+ public void shutdown() {
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void setId(String id) throws EBaseException {
+ mId = id;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Validate an OCSP request.
+ */
+ public OCSPResponse validate(OCSPRequest request)
+ throws EBaseException {
+
+ IStatsSubsystem statsSub = (IStatsSubsystem)CMS.getSubsystem("stats");
+
+ mOCSPAuthority.incNumOCSPRequest(1);
+ long startTime = CMS.getCurrentDate().getTime();
+ try {
+ mOCSPAuthority.log(ILogger.LL_INFO, "start OCSP request");
+ TBSRequest tbsReq = request.getTBSRequest();
+
+ // (3) look into database to check the
+ // certificate's status
+ Vector singleResponses = new Vector();
+ if (statsSub != null) {
+ statsSub.startTiming("lookup");
+ }
+
+ long lookupStartTime = CMS.getCurrentDate().getTime();
+ for (int i = 0; i < tbsReq.getRequestCount(); i++) {
+ com.netscape.cmsutil.ocsp.Request req =
+ tbsReq.getRequestAt(i);
+ CertID cid = req.getCertID();
+ SingleResponse sr = processRequest(cid);
+
+ singleResponses.addElement(sr);
+ }
+ long lookupEndTime = CMS.getCurrentDate().getTime();
+ if (statsSub != null) {
+ statsSub.endTiming("lookup");
+ }
+ mOCSPAuthority.incLookupTime(lookupEndTime - lookupStartTime);
+
+ if (singleResponses.size() <= 0) {
+ CMS.debug("DefStore: No Request Found");
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OCSP_REQUEST_FAILURE", "No Request Found"));
+ return null;
+ }
+ if (statsSub != null) {
+ statsSub.startTiming("build_response");
+ }
+ SingleResponse res[] = new SingleResponse[singleResponses.size()];
+
+ singleResponses.copyInto(res);
+
+ ResponderID rid = null;
+
+ if (mByName) {
+ rid = mOCSPAuthority.getResponderIDByName();
+ } else {
+ rid = mOCSPAuthority.getResponderIDByHash();
+ }
+
+ Extension nonce[] = null;
+
+ for (int j = 0; j < tbsReq.getExtensionsCount(); j++) {
+ Extension thisExt = tbsReq.getRequestExtensionAt(j);
+
+ if (thisExt.getExtnId().equals(IOCSPAuthority.OCSP_NONCE)) {
+ nonce = new Extension[1];
+ nonce[0] = thisExt;
+ }
+ }
+
+ ResponseData rd = new ResponseData(rid,
+ new GeneralizedTime(CMS.getCurrentDate()), res, nonce);
+ if (statsSub != null) {
+ statsSub.endTiming("build_response");
+ }
+
+ if (statsSub != null) {
+ statsSub.startTiming("signing");
+ }
+ long signStartTime = CMS.getCurrentDate().getTime();
+ BasicOCSPResponse basicRes = mOCSPAuthority.sign(rd);
+ long signEndTime = CMS.getCurrentDate().getTime();
+ if (statsSub != null) {
+ statsSub.endTiming("signing");
+ }
+ mOCSPAuthority.incSignTime(signEndTime - signStartTime);
+
+ OCSPResponse response = new OCSPResponse(
+ OCSPResponseStatus.SUCCESSFUL,
+ new ResponseBytes(ResponseBytes.OCSP_BASIC,
+ new OCTET_STRING(ASN1Util.encode(basicRes))));
+
+ log(ILogger.LL_INFO, "done OCSP request");
+ long endTime = CMS.getCurrentDate().getTime();
+ mOCSPAuthority.incTotalTime(endTime - startTime);
+ return response;
+ } catch (Exception e) {
+ CMS.debug("DefStore: validation failed " + e.toString());
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OCSP_REQUEST_FAILURE", e.toString()));
+ return null;
+ }
+ }
+
+ /**
+ * Check against the database for status.
+ */
+ private SingleResponse processRequest(CertID cid) {
+ // need to find the right CA
+
+ CMS.debug("DefStore: process request");
+ try {
+ // cache result to speed up the performance
+ X509CertImpl theCert = null;
+ X509CRLImpl theCRL = null;
+ ICRLIssuingPointRecord theRec = null;
+ byte keyhsh[] = cid.getIssuerKeyHash().toByteArray();
+ CRLIPContainer matched = (CRLIPContainer)
+ mCacheCRLIssuingPoints.get(new String(keyhsh));
+
+ if (matched == null) {
+ Enumeration recs = searchCRLIssuingPointRecord(
+ "objectclass=" +
+ CMS.getCRLIssuingPointRecordName(),
+ 100);
+
+ while (recs.hasMoreElements()) {
+ ICRLIssuingPointRecord rec = (ICRLIssuingPointRecord)
+ recs.nextElement();
+ byte certdata[] = rec.getCACert();
+ X509CertImpl cert = null;
+
+ try {
+ cert = new X509CertImpl(certdata);
+ } catch (Exception e) {
+ // error
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OCSP_DECODE_CERT", e.toString()));
+ return null;
+ }
+ MessageDigest md = MessageDigest.getInstance(
+ mOCSPAuthority.getDigestName(cid.getHashAlgorithm()));
+ X509Key key = (X509Key) cert.getPublicKey();
+ byte digest[] = md.digest(key.getKey());
+
+ if (mOCSPAuthority.arraysEqual(digest, keyhsh)) {
+ theCert = cert;
+ theRec = rec;
+ incReqCount(theRec.getId());
+ byte crldata[] = rec.getCRL();
+
+ if (rec.getCRLCache() == null) {
+ CMS.debug("DefStore: start building x509 crl impl");
+ try {
+ theCRL = new X509CRLImpl(crldata);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("OCSP_DECODE_CRL", e.toString()));
+ }
+ CMS.debug("DefStore: done building x509 crl impl");
+ } else {
+ CMS.debug("DefStore: using crl cache");
+ }
+ mCacheCRLIssuingPoints.put(new String(digest), new CRLIPContainer(theRec, theCert, theCRL));
+ break;
+ }
+ }
+ } else {
+ theCert = matched.getX509CertImpl();
+ theRec = matched.getCRLIssuingPointRecord();
+ theCRL = matched.getX509CRLImpl();
+ incReqCount(theRec.getId());
+ }
+
+ // check the serial number
+ if (theCert != null) {
+ INTEGER serialNo = cid.getSerialNumber();
+
+ log(ILogger.EV_AUDIT, AuditFormat.LEVEL, "Checked Status of certificate 0x" + serialNo.toString(16));
+ CMS.debug("DefStore: process request 0x" + serialNo.toString(16));
+ CertStatus certStatus = null;
+ GeneralizedTime thisUpdate = null;
+
+ if (theRec == null) {
+ thisUpdate = new GeneralizedTime(CMS.getCurrentDate());
+ } else {
+ thisUpdate = new GeneralizedTime(
+ theRec.getThisUpdate());
+ }
+ GeneralizedTime nextUpdate = null;
+
+ if (includeNextUpdate()) {
+ // this is an optional field
+ if (theRec == null) {
+ nextUpdate = new GeneralizedTime(CMS.getCurrentDate());
+ } else {
+ nextUpdate = new GeneralizedTime(
+ theRec.getNextUpdate());
+ }
+ }
+
+ if (theCRL == null) {
+ certStatus = new UnknownInfo();
+
+ // if crl is not available, we can try crl cache
+ if (theRec != null) {
+ CMS.debug("DefStore: evaluating crl cache");
+ Hashtable cache = theRec.getCRLCacheNoClone();
+ if (cache != null) {
+ RevokedCertificate rc = (RevokedCertificate)
+ cache.get(new BigInteger(serialNo.toString()));
+ if (rc == null) {
+ if (isNotFoundGood()) {
+ certStatus = new GoodInfo();
+ } else {
+ certStatus = new UnknownInfo();
+ }
+ } else {
+
+ certStatus = new RevokedInfo(
+ new GeneralizedTime(
+ rc.getRevocationDate()));
+ }
+ }
+ }
+
+ } else {
+ CMS.debug("DefStore: evaluating x509 crl impl");
+ X509CRLEntry crlentry = theCRL.getRevokedCertificate(new BigInteger(serialNo.toString()));
+
+ if (crlentry == null) {
+ // good or unknown
+ if (isNotFoundGood()) {
+ certStatus = new GoodInfo();
+ } else {
+ certStatus = new UnknownInfo();
+ }
+ } else {
+ certStatus = new RevokedInfo(new GeneralizedTime(
+ crlentry.getRevocationDate()));
+
+ }
+ }
+ return new SingleResponse(cid, certStatus, thisUpdate,
+ nextUpdate);
+ }
+ } catch (Exception e) {
+ // error log
+ CMS.debug("DefStore: failed processing request e=" + e);
+ }
+ return null;
+ }
+
+ private String transformDN(String dn) {
+ String newdn = dn;
+
+ newdn = newdn.replace(',', '_');
+ newdn = newdn.replace('=', '-');
+ return newdn;
+ }
+
+ public String getBaseDN() {
+ return mDBService.getBaseDN();
+ }
+
+ public Enumeration searchAllCRLIssuingPointRecord(int maxSize)
+ throws EBaseException {
+ return searchCRLIssuingPointRecord(
+ "objectclass=" +
+ CMS.getCRLIssuingPointRecordName(),
+ maxSize);
+ }
+
+ public Enumeration searchCRLIssuingPointRecord(String filter,
+ int maxSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ e = s.search(getBaseDN(), filter, maxSize);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ public synchronized void modifyCRLIssuingPointRecord(String name,
+ ModificationSet mods) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String dn = "cn=" +
+ transformDN(name) + "," + getBaseDN();
+
+ s.modify(dn, mods);
+ } catch (EBaseException e) {
+ CMS.debug("modifyCRLIssuingPointRecord: error=" + e);
+ CMS.debug(e);
+ throw e;
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ /**
+ * Returns an issuing point.
+ */
+ public ICRLIssuingPointRecord readCRLIssuingPoint(String name)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ ICRLIssuingPointRecord rec = null;
+
+ try {
+ String dn = "cn=" +
+ transformDN(name) + "," + getBaseDN();
+
+ if (s != null) {
+ rec = (ICRLIssuingPointRecord) s.read(dn);
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return rec;
+ }
+
+ public ICRLIssuingPointRecord createCRLIssuingPointRecord(
+ String name, BigInteger crlNumber,
+ Long crlSize, Date thisUpdate, Date nextUpdate) {
+ return CMS.createCRLIssuingPointRecord(
+ name, crlNumber, crlSize, thisUpdate, nextUpdate);
+ }
+
+ public void deleteCRLIssuingPointRecord(String id)
+ throws EBaseException {
+
+ IDBSSession s = null;
+
+ try {
+ s = mDBService.createSession();
+ String name = "cn=" + transformDN(id) + "," + getBaseDN();
+ CMS.debug("DefStore::deleteCRLIssuingPointRecord: Attempting to delete: " + name);
+ if (s != null) s.delete(name);
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ /**
+ * Creates a new issuing point in OCSP.
+ */
+ public void addCRLIssuingPoint(String name, ICRLIssuingPointRecord rec)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String dn = "cn=" +
+ transformDN(name) + "," + getBaseDN();
+
+ s.add(dn, (ICRLIssuingPointRecord) rec);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ public Enumeration searchRepository(String name, String filter)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ e = s.search("cn=" + transformDN(name) + "," + getBaseDN(),
+ filter);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Creates a new issuing point in OCSP.
+ */
+ public void addRepository(String name, String thisUpdate,
+ IRepositoryRecord rec)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String dn = "ou=" + thisUpdate + ",cn=" +
+ transformDN(name) + "," + getBaseDN();
+
+ s.add(dn, rec);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ public void modifyCertRecord(String name, String thisUpdate,
+ String sno,
+ ModificationSet mods) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String dn = "cn=" + sno + ",ou=" + thisUpdate +
+ ",cn=" + transformDN(name) + "," + getBaseDN();
+
+ if (s != null) s.modify(dn, mods);
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ public Enumeration searchCertRecord(String name, String thisUpdate,
+ String filter) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ e = s.search("ou=" + thisUpdate + ",cn=" +
+ transformDN(name) + "," + getBaseDN(),
+ filter);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ public ICertRecord readCertRecord(String name, String thisUpdate,
+ String sno)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ ICertRecord rec = null;
+
+ try {
+ String dn = "cn=" + sno + ",ou=" + thisUpdate +
+ ",cn=" + transformDN(name) + "," + getBaseDN();
+
+ if (s != null) {
+ rec = (ICertRecord) s.read(dn);
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return rec;
+ }
+
+ /**
+ * Creates a new issuing point in OCSP.
+ */
+ public void addCertRecord(String name, String thisUpdate,
+ String sno, ICertRecord rec)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String dn = "cn=" + sno + ",ou=" + thisUpdate +
+ ",cn=" + transformDN(name) + "," + getBaseDN();
+
+ s.add(dn, rec);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ public NameValuePairs getConfigParameters() {
+ try {
+ NameValuePairs params = new NameValuePairs();
+
+ params.add(Constants.PR_OCSPSTORE_IMPL_NAME,
+ mConfig.getString("class"));
+ params.add(PROP_NOT_FOUND_GOOD,
+ mConfig.getString(PROP_NOT_FOUND_GOOD, "true"));
+ params.add(PROP_BY_NAME,
+ mConfig.getString(PROP_BY_NAME, "true"));
+ params.add(PROP_INCLUDE_NEXT_UPDATE,
+ mConfig.getString(PROP_INCLUDE_NEXT_UPDATE, "false"));
+ return params;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public void setConfigParameters(NameValuePairs pairs)
+ throws EBaseException {
+ Enumeration k = pairs.getNames();
+
+ while (k.hasMoreElements()) {
+ String key = (String) k.nextElement();
+
+ mConfig.put(key, pairs.getValue(key));
+ }
+ }
+
+ public void updateCRL(X509CRL crl) throws EBaseException {
+ try {
+ mStateCount++;
+
+ CMS.debug("DefStore: Ready to update Issuer");
+
+ try {
+ if (!((X509CRLImpl)crl).areEntriesIncluded())
+ crl = new X509CRLImpl(((X509CRLImpl)crl).getEncoded());
+ } catch (Exception e) {
+ CMS.debug(e);
+ }
+
+ // commit update
+ ModificationSet mods = new ModificationSet();
+
+ if (crl.getThisUpdate() != null)
+ mods.add(ICRLIssuingPointRecord.ATTR_THIS_UPDATE,
+ Modification.MOD_REPLACE, crl.getThisUpdate());
+ if (crl.getNextUpdate() != null)
+ mods.add(ICRLIssuingPointRecord.ATTR_NEXT_UPDATE,
+ Modification.MOD_REPLACE, crl.getNextUpdate());
+ if (mUseCache) {
+ if (((X509CRLImpl)crl).getListOfRevokedCertificates() != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_CACHE,
+ Modification.MOD_REPLACE,
+ ((X509CRLImpl)crl).getListOfRevokedCertificates());
+ }
+ }
+ if (((X509CRLImpl) crl).getNumberOfRevokedCertificates() < 0) {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_SIZE,
+ Modification.MOD_REPLACE, Long.valueOf(0));
+ } else {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_SIZE,
+ Modification.MOD_REPLACE, Long.valueOf(((X509CRLImpl) crl).getNumberOfRevokedCertificates()));
+ }
+ BigInteger crlNumber = ((X509CRLImpl)crl).getCRLNumber();
+ if (crlNumber == null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_NUMBER,
+ Modification.MOD_REPLACE, new BigInteger("-1"));
+ } else {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_NUMBER,
+ Modification.MOD_REPLACE, crlNumber);
+ }
+ try {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL,
+ Modification.MOD_REPLACE, crl.getEncoded());
+ } catch (Exception e) {
+ // ignore
+ }
+ CMS.debug("DefStore: ready to CRL update " +
+ crl.getIssuerDN().getName());
+ modifyCRLIssuingPointRecord(
+ crl.getIssuerDN().getName(), mods);
+ CMS.debug("DefStore: done CRL update " +
+ crl.getIssuerDN().getName());
+
+ // update cache
+ mCacheCRLIssuingPoints.clear();
+
+ log(ILogger.LL_INFO, "AddCRLServlet: Finish Committing CRL." +
+ " thisUpdate=" + crl.getThisUpdate() +
+ " nextUpdate=" + crl.getNextUpdate());
+
+ } finally {
+ mStateCount--;
+ }
+ }
+
+ public int getStateCount() {
+ return mStateCount;
+ }
+
+}
+
+
+class DeleteOldCRLsThread extends Thread {
+ private DefStore mDefStore = null;
+
+ public DeleteOldCRLsThread(DefStore defStore) {
+ mDefStore = defStore;
+ }
+
+ public void run() {
+ try {
+ mDefStore.deleteOldCRLs();
+ } catch (EBaseException e) {
+ }
+ }
+}
+
+
+class CRLIPContainer {
+ private ICRLIssuingPointRecord mRec = null;
+ private X509CertImpl mCert = null;
+ private X509CRLImpl mCRL = null;
+
+ public CRLIPContainer(ICRLIssuingPointRecord rec, X509CertImpl cert, X509CRLImpl crl) {
+ mRec = rec;
+ mCert = cert;
+ mCRL = crl;
+ }
+
+ public ICRLIssuingPointRecord getCRLIssuingPointRecord() {
+ return mRec;
+ }
+
+ public X509CertImpl getX509CertImpl() {
+ return mCert;
+ }
+
+ public X509CRLImpl getX509CRLImpl() {
+ return mCRL;
+ }
+}
+
+class DefStoreCRLUpdater extends Thread {
+ private Hashtable mCache = null;
+ private int mSec = 0;
+
+ public DefStoreCRLUpdater(Hashtable cache, int sec) {
+ mCache = cache;
+ mSec = sec;
+ }
+
+ public void run() {
+ while (true) {
+ try {
+ CMS.debug("DefStore: CRLUpdater invoked");
+ mCache.clear();
+ sleep(mSec * 1000); // turn sec into millis-sec
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+}