summaryrefslogtreecommitdiffstats
path: root/pki/base/common/src/com/netscape/cmscore/dbs
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/common/src/com/netscape/cmscore/dbs')
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/BigIntegerMapper.java118
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/ByteArrayMapper.java93
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CRLDBSchema.java57
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CRLIssuingPointRecord.java325
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CRLRepository.java365
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CertDBSchema.java64
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CertRecord.java278
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CertRecordList.java118
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CertRecordMapper.java98
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java1985
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DBRegistry.java553
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DBSSession.java447
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DBSUtil.java56
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DBSearchResults.java92
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java951
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DBVirtualList.java769
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DateArrayMapper.java105
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/DateMapper.java108
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/IntegerMapper.java86
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java58
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/KeyRecord.java348
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordList.java93
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordMapper.java111
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java553
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/KeyStateMapper.java80
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/LdapFilterConverter.java61
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/LongMapper.java117
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/MetaInfoMapper.java119
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/ObjectStreamMapper.java135
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/PublicKeyMapper.java150
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.java82
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/Repository.java504
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/RepositoryRecord.java112
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/RepositorySchema.java44
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfo.java81
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfoMapper.java167
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/StringMapper.java91
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/StringVectorMapper.java106
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/X500NameMapper.java107
-rw-r--r--pki/base/common/src/com/netscape/cmscore/dbs/X509CertImplMapper.java363
40 files changed, 10150 insertions, 0 deletions
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/BigIntegerMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/BigIntegerMapper.java
new file mode 100644
index 000000000..c0afbe742
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/BigIntegerMapper.java
@@ -0,0 +1,118 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.math.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java BigInteger object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class BigIntegerMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs BigInteger mapper.
+ */
+ public BigIntegerMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Returns a list of supported ldap attribute names.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object into ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName,
+ BigIntegerToDB((BigInteger) obj)));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ parent.set(name, BigIntegerFromDB(
+ (String) attr.getStringValues().nextElement()));
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ String v = null;
+
+ try {
+ if (value.startsWith("0x") || value.startsWith("0X")) {
+ v = BigIntegerToDB(new
+ BigInteger(value.substring(2), 16));
+ } else {
+ v = BigIntegerToDB(new BigInteger(value));
+ }
+ } catch (NumberFormatException e) {
+ v = value;
+ }
+ return mLdapName + op + v;
+ }
+
+ public static String BigIntegerToDB(BigInteger i) {
+ int len = i.toString().length();
+ String ret = null;
+
+ if (len < 10) {
+ ret = "0" + Integer.toString(len) + i.toString();
+ } else {
+ ret = Integer.toString(len) + i.toString();
+ }
+ return ret;
+ }
+
+ public static BigInteger BigIntegerFromDB(String i) {
+ String s = i.substring(2);
+
+ // possibly check length
+ return new BigInteger(s);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/ByteArrayMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/ByteArrayMapper.java
new file mode 100644
index 000000000..fcb806bb5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/ByteArrayMapper.java
@@ -0,0 +1,93 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java byte array object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class ByteArrayMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs a byte array mapper.
+ */
+ public ByteArrayMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Lists a list of supported ldap attribute names.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object to ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ byte data[] = (byte[]) obj;
+ if (data == null) {
+ CMS.debug("ByteArrayMapper:mapObjectToLDAPAttributeSet " + name +
+ " size=0");
+ } else {
+ CMS.debug("ByteArrayMapper:mapObjectToLDAPAttributeSet " + name +
+ " size=" + data.length);
+ }
+ attrs.add(new LDAPAttribute(mLdapName, data));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ parent.set(name, (byte[]) attr.getByteValues().nextElement());
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CRLDBSchema.java b/pki/base/common/src/com/netscape/cmscore/dbs/CRLDBSchema.java
new file mode 100644
index 000000000..ad065f924
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CRLDBSchema.java
@@ -0,0 +1,57 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents a collection of schema information
+ * for CRL.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CRLDBSchema {
+
+ public static final String LDAP_OC_TOP = "top";
+ public static final String LDAP_OC_CRL_RECORD = "crlIssuingPointRecord";
+ public static final String LDAP_ATTR_CRL_ID = "cn";
+ public static final String LDAP_ATTR_CRL_NUMBER = "crlNumber";
+ public static final String LDAP_ATTR_DELTA_NUMBER = "deltaNumber";
+ public static final String LDAP_ATTR_CRL_SIZE = "crlSize";
+ public static final String LDAP_ATTR_DELTA_SIZE = "deltaSize";
+ public static final String LDAP_ATTR_THIS_UPDATE = "thisUpdate";
+ public static final String LDAP_ATTR_NEXT_UPDATE = "nextUpdate";
+ public static final String LDAP_ATTR_FIRST_UNSAVED = "firstUnsaved";
+ public static final String LDAP_ATTR_CRL = "certificateRevocationList";
+ public static final String LDAP_ATTR_CA_CERT = "cACertificate";
+ public static final String LDAP_ATTR_CRL_CACHE = "crlCache";
+ public static final String LDAP_ATTR_REVOKED_CERTS = "revokedCerts";
+ public static final String LDAP_ATTR_UNREVOKED_CERTS = "unrevokedCerts";
+ public static final String LDAP_ATTR_EXPIRED_CERTS = "expiredCerts";
+ public static final String LDAP_ATTR_DELTA_CRL = "deltaRevocationList";
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CRLIssuingPointRecord.java b/pki/base/common/src/com/netscape/cmscore/dbs/CRLIssuingPointRecord.java
new file mode 100644
index 000000000..8d7f19ca6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CRLIssuingPointRecord.java
@@ -0,0 +1,325 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.math.*;
+import java.io.*;
+import java.security.cert.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.crldb.*;
+
+
+/**
+ * A class represents a CRL issuing point record.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CRLIssuingPointRecord implements ICRLIssuingPointRecord, IDBObj {
+
+ protected String mId = null; // internal unique id
+ protected BigInteger mCRLNumber = null; // CRL number
+ protected Long mCRLSize = null;
+ protected Date mThisUpdate = null;
+ protected Date mNextUpdate = null;
+ protected BigInteger mDeltaCRLNumber = null; // delta CRL number
+ protected Long mDeltaCRLSize = null;
+ protected String mFirstUnsaved = null;
+ protected byte mCRL[] = null;
+ protected byte mCACert[] = null;
+ protected Hashtable mCRLCache = null;
+ protected Hashtable mRevokedCerts = null;
+ protected Hashtable mUnrevokedCerts = null;
+ protected Hashtable mExpiredCerts = null;
+ protected byte mDeltaCRL[] = null;
+ protected static Vector mNames = new Vector();
+ static {
+ mNames.addElement(ATTR_ID);
+ mNames.addElement(ATTR_CRL_NUMBER);
+ mNames.addElement(ATTR_DELTA_NUMBER);
+ mNames.addElement(ATTR_CRL_SIZE);
+ mNames.addElement(ATTR_DELTA_SIZE);
+ mNames.addElement(ATTR_THIS_UPDATE);
+ mNames.addElement(ATTR_NEXT_UPDATE);
+ mNames.addElement(ATTR_FIRST_UNSAVED);
+ mNames.addElement(ATTR_CRL);
+ mNames.addElement(ATTR_CA_CERT);
+ mNames.addElement(ATTR_CRL_CACHE);
+ mNames.addElement(ATTR_REVOKED_CERTS);
+ mNames.addElement(ATTR_UNREVOKED_CERTS);
+ mNames.addElement(ATTR_EXPIRED_CERTS);
+ mNames.addElement(ATTR_DELTA_CRL);
+ }
+
+ /**
+ * Constructs empty CRLIssuingPointRecord. This is
+ * required in database framework.
+ */
+ public CRLIssuingPointRecord() {
+ }
+
+ /**
+ * Constructs a CRLIssuingPointRecord
+ */
+ public CRLIssuingPointRecord(String id, BigInteger crlNumber, Long crlSize,
+ Date thisUpdate, Date nextUpdate) {
+ mId = id;
+ mCRLNumber = crlNumber;
+ mCRLSize = crlSize;
+ mThisUpdate = thisUpdate;
+ mNextUpdate = nextUpdate;
+ mDeltaCRLNumber = BigInteger.ZERO;
+ mFirstUnsaved = NEW_CACHE;
+ mDeltaCRLSize = Long.valueOf(-1L);
+ mCRLCache = null;
+ mRevokedCerts = null;
+ mUnrevokedCerts = null;
+ mExpiredCerts = null;
+ }
+
+ /**
+ * Constructs a CRLIssuingPointRecord
+ */
+ public CRLIssuingPointRecord(String id, BigInteger crlNumber, Long crlSize,
+ Date thisUpdate, Date nextUpdate, BigInteger deltaCRLNumber, Long deltaCRLSize,
+ Hashtable revokedCerts, Hashtable unrevokedCerts, Hashtable expiredCerts) {
+ mId = id;
+ mCRLNumber = crlNumber;
+ mCRLSize = crlSize;
+ mThisUpdate = thisUpdate;
+ mNextUpdate = nextUpdate;
+ mDeltaCRLNumber = deltaCRLNumber;
+ mDeltaCRLSize = deltaCRLSize;
+ mFirstUnsaved = NEW_CACHE;
+ mCRLCache = null;
+ mRevokedCerts = revokedCerts;
+ mUnrevokedCerts = unrevokedCerts;
+ mExpiredCerts = expiredCerts;
+ }
+
+ public void set(String name, Object obj) throws EBaseException {
+ if (name.equalsIgnoreCase(ATTR_ID)) {
+ mId = (String) obj;
+ } else if (name.equalsIgnoreCase(ATTR_CRL_NUMBER)) {
+ mCRLNumber = (BigInteger) obj;
+ } else if (name.equalsIgnoreCase(ATTR_CRL_SIZE)) {
+ mCRLSize = (Long) obj;
+ } else if (name.equalsIgnoreCase(ATTR_THIS_UPDATE)) {
+ mThisUpdate = (Date) obj;
+ } else if (name.equalsIgnoreCase(ATTR_NEXT_UPDATE)) {
+ mNextUpdate = (Date) obj;
+ } else if (name.equalsIgnoreCase(ATTR_DELTA_NUMBER)) {
+ mDeltaCRLNumber = (BigInteger) obj;
+ } else if (name.equalsIgnoreCase(ATTR_DELTA_SIZE)) {
+ mDeltaCRLSize = (Long) obj;
+ } else if (name.equalsIgnoreCase(ATTR_FIRST_UNSAVED)) {
+ mFirstUnsaved = (String) obj;
+ } else if (name.equalsIgnoreCase(ATTR_CRL)) {
+ mCRL = (byte[]) obj;
+ } else if (name.equalsIgnoreCase(ATTR_CA_CERT)) {
+ mCACert = (byte[]) obj;
+ } else if (name.equalsIgnoreCase(ATTR_CRL_CACHE)) {
+ mCRLCache = (Hashtable) obj;
+ } else if (name.equalsIgnoreCase(ATTR_REVOKED_CERTS)) {
+ mRevokedCerts = (Hashtable) obj;
+ } else if (name.equalsIgnoreCase(ATTR_UNREVOKED_CERTS)) {
+ mUnrevokedCerts = (Hashtable) obj;
+ } else if (name.equalsIgnoreCase(ATTR_EXPIRED_CERTS)) {
+ mExpiredCerts = (Hashtable) obj;
+ } else if (name.equalsIgnoreCase(ATTR_DELTA_CRL)) {
+ mDeltaCRL = (byte[]) obj;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ public Object get(String name) throws EBaseException {
+ if (name.equalsIgnoreCase(ATTR_ID)) {
+ return mId;
+ } else if (name.equalsIgnoreCase(ATTR_CRL_NUMBER)) {
+ return mCRLNumber;
+ } else if (name.equalsIgnoreCase(ATTR_CRL_SIZE)) {
+ return mCRLSize;
+ } else if (name.equalsIgnoreCase(ATTR_THIS_UPDATE)) {
+ return mThisUpdate;
+ } else if (name.equalsIgnoreCase(ATTR_NEXT_UPDATE)) {
+ return mNextUpdate;
+ } else if (name.equalsIgnoreCase(ATTR_DELTA_NUMBER)) {
+ return mDeltaCRLNumber;
+ } else if (name.equalsIgnoreCase(ATTR_DELTA_SIZE)) {
+ return mDeltaCRLSize;
+ } else if (name.equalsIgnoreCase(ATTR_FIRST_UNSAVED)) {
+ return mFirstUnsaved;
+ } else if (name.equalsIgnoreCase(ATTR_CRL)) {
+ return mCRL;
+ } else if (name.equalsIgnoreCase(ATTR_CA_CERT)) {
+ return mCACert;
+ } else if (name.equalsIgnoreCase(ATTR_CRL_CACHE)) {
+ return mCRLCache;
+ } else if (name.equalsIgnoreCase(ATTR_REVOKED_CERTS)) {
+ return mRevokedCerts;
+ } else if (name.equalsIgnoreCase(ATTR_UNREVOKED_CERTS)) {
+ return mUnrevokedCerts;
+ } else if (name.equalsIgnoreCase(ATTR_EXPIRED_CERTS)) {
+ return mExpiredCerts;
+ } else if (name.equalsIgnoreCase(ATTR_DELTA_CRL)) {
+ return mDeltaCRL;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ public void delete(String name) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+
+ public Enumeration getElements() {
+ return mNames.elements();
+ }
+
+ public Enumeration getSerializableAttrNames() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieve unique CRL identifier.
+ */
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Retrieves CRL number.
+ */
+ public BigInteger getCRLNumber() {
+ return mCRLNumber;
+ }
+
+ /**
+ * Retrieves CRL size.
+ */
+ public Long getCRLSize() {
+ return mCRLSize;
+ }
+
+ /**
+ * Retrieves this update time.
+ */
+ public Date getThisUpdate() {
+ return mThisUpdate;
+ }
+
+ /**
+ * Retrieves next update time.
+ */
+ public Date getNextUpdate() {
+ return mNextUpdate;
+ }
+
+ /**
+ * Retrieves delta CRL number.
+ */
+ public BigInteger getDeltaCRLNumber() {
+ return mDeltaCRLNumber;
+ }
+
+ /**
+ * Retrieves CRL size.
+ */
+ public Long getDeltaCRLSize() {
+ return mDeltaCRLSize;
+ }
+
+ /**
+ * Retrieve unique CRL identifier.
+ */
+ public String getFirstUnsaved() {
+ return mFirstUnsaved;
+ }
+
+ /**
+ * Retrieves CRL encodings.
+ */
+ public byte[] getCRL() {
+ return mCRL;
+ }
+
+ /**
+ * Retrieves CRL encodings.
+ */
+ public byte[] getDeltaCRL() {
+ return mDeltaCRL;
+ }
+
+ public byte[] getCACert() {
+ return mCACert;
+ }
+
+ public Hashtable getCRLCacheNoClone() {
+ if (mCRLCache == null)
+ return null;
+ else
+ return (Hashtable) mCRLCache;
+ }
+
+ public Hashtable getCRLCache() {
+ if (mCRLCache == null)
+ return null;
+ else
+ return (Hashtable) mCRLCache.clone();
+ }
+
+ /**
+ * Retrieves cache info of revoked certificates.
+ */
+ public Hashtable getRevokedCerts() {
+ if (mRevokedCerts == null)
+ return null;
+ else
+ return (Hashtable) mRevokedCerts.clone();
+ }
+
+ /**
+ * Retrieves cache info of unrevoked certificates.
+ */
+ public Hashtable getUnrevokedCerts() {
+ if (mUnrevokedCerts == null)
+ return null;
+ else
+ return (Hashtable) mUnrevokedCerts.clone();
+ }
+
+ /**
+ * Retrieves cache info of expired certificates.
+ */
+ public Hashtable getExpiredCerts() {
+ if (mExpiredCerts == null)
+ return null;
+ else
+ return (Hashtable) mExpiredCerts.clone();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CRLRepository.java b/pki/base/common/src/com/netscape/cmscore/dbs/CRLRepository.java
new file mode 100644
index 000000000..c2eba5acb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CRLRepository.java
@@ -0,0 +1,365 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.*;
+import java.util.*;
+import java.io.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.repository.*;
+
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.util.*;
+
+import com.netscape.certsrv.apps.*;
+
+/**
+ * A class represents a CRL repository. It stores all the
+ * CRL issuing points.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CRLRepository extends Repository implements ICRLRepository {
+
+ private final String mLdapCRLIssuingPointName = "cn";
+ private IDBSubsystem mDBService;
+ private String mBaseDN;
+
+ /**
+ * Constructs a CRL repository.
+ */
+ public CRLRepository(IDBSubsystem dbService, int increment, String baseDN)
+ throws EDBException {
+ super(dbService, increment, baseDN);
+ mBaseDN = baseDN;
+ mDBService = dbService;
+
+ IDBRegistry reg = dbService.getRegistry();
+
+ /**
+ String crlRecordOC[] = new String[1];
+ crlRecordOC[0] = Schema.LDAP_OC_CRL_RECORD;
+ reg.registerObjectClass(CRLIssuingPointRecord.class.getName(),
+ crlRecordOC);
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_ID, new
+ StringMapper(Schema.LDAP_ATTR_CRL_ID));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CRL_NUMBER, new
+ BigIntegerMapper(Schema.LDAP_ATTR_CRL_NUMBER));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CRL_SIZE, new
+ LongMapper(Schema.LDAP_ATTR_CRL_SIZE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_THIS_UPDATE, new
+ DateMapper(Schema.LDAP_ATTR_THIS_UPDATE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_NEXT_UPDATE, new
+ DateMapper(Schema.LDAP_ATTR_NEXT_UPDATE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CRL, new
+ ByteArrayMapper(Schema.LDAP_ATTR_CRL));
+ **/
+ }
+
+ /**
+ * Retrieves backend database handle.
+ */
+ public IDBSubsystem getDBSubsystem() {
+ return mDBService;
+ }
+
+ /**
+ * Retrieves DN of this repository.
+ */
+ public String getDN() {
+ return mBaseDN;
+ }
+
+ /**
+ * Removes all objects with this repository.
+ */
+ public void removeAllObjects() throws EBaseException
+ {
+ }
+
+ /**
+ * Adds CRL issuing points.
+ */
+ public void addCRLIssuingPointRecord(ICRLIssuingPointRecord rec)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = mLdapCRLIssuingPointName + "=" +
+ ((CRLIssuingPointRecord) rec).getId().toString() + "," + getDN();
+
+ s.add(name, rec);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * Retrieves all issuing points' names
+ */
+ public Vector getIssuingPointsNames() throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ try {
+ String[] attrs = {ICRLIssuingPointRecord.ATTR_ID, "objectclass"};
+ String filter = "objectclass=" + CMS.getCRLIssuingPointRecordName();
+ IDBSearchResults res = s.search(getDN(), filter, attrs);
+ Vector v = new Vector();
+ while (res.hasMoreElements()) {
+ ICRLIssuingPointRecord nextelement =
+ (ICRLIssuingPointRecord)res.nextElement();
+ CMS.debug("CRLRepository getIssuingPointsNames(): name = "
+ +nextelement.getId());
+ v.addElement(nextelement.getId());
+ }
+
+ return v;
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * Reads issuing point record.
+ */
+ public ICRLIssuingPointRecord readCRLIssuingPointRecord(String id)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ CRLIssuingPointRecord rec = null;
+
+ try {
+ String name = mLdapCRLIssuingPointName + "=" + id +
+ "," + getDN();
+
+ if (s != null) {
+ rec = (CRLIssuingPointRecord) s.read(name);
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return rec;
+ }
+
+ /**
+ * deletes issuing point record.
+ */
+ public void deleteCRLIssuingPointRecord(String id)
+ throws EBaseException {
+ IDBSSession s = null;
+
+ try {
+ s = mDBService.createSession();
+ String name = mLdapCRLIssuingPointName + "=" + id +
+ "," + getDN();
+
+ if (s != null) s.delete(name);
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ public void modifyCRLIssuingPointRecord(String id,
+ ModificationSet mods) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = mLdapCRLIssuingPointName + "=" + id +
+ "," + getDN();
+
+ if (s != null) s.modify(name, mods);
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ /**
+ * Updates CRL issuing point record.
+ */
+ public void updateCRLIssuingPointRecord(String id, byte[] newCRL,
+ Date thisUpdate, Date nextUpdate, BigInteger crlNumber, Long crlSize)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ if (newCRL != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL,
+ Modification.MOD_REPLACE, newCRL);
+ }
+ if (nextUpdate != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_NEXT_UPDATE,
+ Modification.MOD_REPLACE, nextUpdate);
+ }
+ mods.add(ICRLIssuingPointRecord.ATTR_THIS_UPDATE,
+ Modification.MOD_REPLACE, thisUpdate);
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_NUMBER,
+ Modification.MOD_REPLACE, crlNumber);
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_SIZE,
+ Modification.MOD_REPLACE, crlSize);
+ modifyCRLIssuingPointRecord(id, mods);
+ }
+
+ /**
+ * Updates CRL issuing point record.
+ */
+ public void updateCRLIssuingPointRecord(String id, byte[] newCRL,
+ Date thisUpdate, Date nextUpdate, BigInteger crlNumber, Long crlSize,
+ Hashtable revokedCerts, Hashtable unrevokedCerts, Hashtable expiredCerts)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ if (newCRL != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL,
+ Modification.MOD_REPLACE, newCRL);
+ }
+ if (nextUpdate != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_NEXT_UPDATE,
+ Modification.MOD_REPLACE, nextUpdate);
+ }
+ mods.add(ICRLIssuingPointRecord.ATTR_THIS_UPDATE,
+ Modification.MOD_REPLACE, thisUpdate);
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_NUMBER,
+ Modification.MOD_REPLACE, crlNumber);
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_SIZE,
+ Modification.MOD_REPLACE, crlSize);
+ if (revokedCerts != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_REVOKED_CERTS,
+ Modification.MOD_REPLACE, revokedCerts);
+ }
+ if (unrevokedCerts != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_UNREVOKED_CERTS,
+ Modification.MOD_REPLACE, unrevokedCerts);
+ }
+ if (expiredCerts != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_EXPIRED_CERTS,
+ Modification.MOD_REPLACE, expiredCerts);
+ }
+ if (revokedCerts != null || unrevokedCerts != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_FIRST_UNSAVED,
+ Modification.MOD_REPLACE, ICRLIssuingPointRecord.CLEAN_CACHE);
+ }
+ modifyCRLIssuingPointRecord(id, mods);
+ }
+
+ /**
+ * Updates CRL issuing point record with recently revoked certificates info.
+ */
+ public void updateRevokedCerts(String id, Hashtable revokedCerts,
+ Hashtable unrevokedCerts)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ mods.add(ICRLIssuingPointRecord.ATTR_REVOKED_CERTS,
+ Modification.MOD_REPLACE, revokedCerts);
+ mods.add(ICRLIssuingPointRecord.ATTR_UNREVOKED_CERTS,
+ Modification.MOD_REPLACE, unrevokedCerts);
+ mods.add(ICRLIssuingPointRecord.ATTR_FIRST_UNSAVED,
+ Modification.MOD_REPLACE, ICRLIssuingPointRecord.CLEAN_CACHE);
+ modifyCRLIssuingPointRecord(id, mods);
+ }
+
+ /**
+ * Updates CRL issuing point record with recently expired certificates info.
+ */
+ public void updateExpiredCerts(String id, Hashtable expiredCerts)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ mods.add(ICRLIssuingPointRecord.ATTR_EXPIRED_CERTS,
+ Modification.MOD_REPLACE, expiredCerts);
+ modifyCRLIssuingPointRecord(id, mods);
+ }
+
+ /**
+ * Updates CRL issuing point record with CRL cache info.
+ */
+ public void updateCRLCache(String id, Long crlSize,
+ Hashtable revokedCerts,
+ Hashtable unrevokedCerts,
+ Hashtable expiredCerts)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ if (crlSize != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_CRL_SIZE,
+ Modification.MOD_REPLACE, crlSize);
+ }
+ mods.add(ICRLIssuingPointRecord.ATTR_REVOKED_CERTS,
+ Modification.MOD_REPLACE, revokedCerts);
+ mods.add(ICRLIssuingPointRecord.ATTR_UNREVOKED_CERTS,
+ Modification.MOD_REPLACE, unrevokedCerts);
+ mods.add(ICRLIssuingPointRecord.ATTR_EXPIRED_CERTS,
+ Modification.MOD_REPLACE, expiredCerts);
+ mods.add(ICRLIssuingPointRecord.ATTR_FIRST_UNSAVED,
+ Modification.MOD_REPLACE, ICRLIssuingPointRecord.CLEAN_CACHE);
+ modifyCRLIssuingPointRecord(id, mods);
+ }
+
+ /**
+ * Updates CRL issuing point record with delta-CRL.
+ */
+ public void updateDeltaCRL(String id, BigInteger deltaCRLNumber,
+ Long deltaCRLSize, Date nextUpdate,
+ byte[] deltaCRL)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ if (deltaCRLNumber != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_DELTA_NUMBER,
+ Modification.MOD_REPLACE, deltaCRLNumber);
+ }
+ if (deltaCRLSize != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_DELTA_SIZE,
+ Modification.MOD_REPLACE, deltaCRLSize);
+ }
+ if (nextUpdate != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_NEXT_UPDATE,
+ Modification.MOD_REPLACE, nextUpdate);
+ }
+ if (deltaCRL != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_DELTA_CRL,
+ Modification.MOD_REPLACE, deltaCRL);
+ }
+ modifyCRLIssuingPointRecord(id, mods);
+ }
+
+ public void updateFirstUnsaved(String id, String firstUnsaved)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ if (firstUnsaved != null) {
+ mods.add(ICRLIssuingPointRecord.ATTR_FIRST_UNSAVED,
+ Modification.MOD_REPLACE, firstUnsaved);
+ }
+ modifyCRLIssuingPointRecord(id, mods);
+ }
+
+ public BigInteger getLastSerialNumberInRange(BigInteger serial_low_bound, BigInteger serial_upper_bound)
+ throws EBaseException {
+
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CertDBSchema.java b/pki/base/common/src/com/netscape/cmscore/dbs/CertDBSchema.java
new file mode 100644
index 000000000..c444a45ac
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CertDBSchema.java
@@ -0,0 +1,64 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents a collection of certificate record
+ * specific schema information.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CertDBSchema {
+
+ public static final String LDAP_OC_TOP = "top";
+ public static final String LDAP_ATTR_META_INFO = "metaInfo";
+ public static final String LDAP_ATTR_SERIALNO = "serialno";
+ public static final String LDAP_ATTR_CREATE_TIME = "dateOfCreate";
+ public static final String LDAP_ATTR_MODIFY_TIME = "dateOfModify";
+ public static final String LDAP_ATTR_PUBLIC_KEY_DATA = "publicKeyData";
+
+ public static final String LDAP_OC_CERT_RECORD = "certificateRecord";
+ public static final String LDAP_ATTR_CERT_RECORD_ID = "certRecordId";
+ public static final String LDAP_ATTR_NOT_BEFORE = "notBefore";
+ public static final String LDAP_ATTR_NOT_AFTER = "notAfter";
+ public static final String LDAP_ATTR_SIGNED_CERT = "userCertificate";
+ public static final String LDAP_ATTR_VERSION = "version";
+ public static final String LDAP_ATTR_DURATION = "duration";
+ public static final String LDAP_ATTR_SUBJECT = "subjectName";
+ public static final String LDAP_ATTR_ALGORITHM = "algorithmId";
+ public static final String LDAP_ATTR_SIGNING_ALGORITHM = "signingAlgorithmId";
+ public static final String LDAP_ATTR_REVO_INFO = "revInfo";
+ public static final String LDAP_ATTR_CERT_STATUS = "certStatus";
+ public static final String LDAP_ATTR_AUTO_RENEW = "autoRenew";
+ public static final String LDAP_ATTR_ISSUED_BY = "issuedBy";
+ public static final String LDAP_ATTR_REVOKED_BY = "revokedBy";
+ public static final String LDAP_ATTR_REVOKED_ON = "revokedOn";
+ public static final String LDAP_ATTR_EXTENSION = "extension";
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CertRecord.java b/pki/base/common/src/com/netscape/cmscore/dbs/CertRecord.java
new file mode 100644
index 000000000..308d801e3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CertRecord.java
@@ -0,0 +1,278 @@
+// --- 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.cmscore.dbs;
+
+
+import java.io.*;
+import java.math.*;
+import java.util.*;
+import java.security.cert.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents a serializable certificate record.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CertRecord implements IDBObj, ICertRecord {
+
+ private BigInteger mId = null;
+ private X509CertImpl mX509Certificate = null;
+ private String mStatus = null;
+ private String mAutoRenew = null;
+ private MetaInfo mMetaInfo = null;
+ // XXX revocationInfo not serializable
+ private transient RevocationInfo mRevocationInfo = null;
+ private Date mCreateTime = null;
+ private Date mModifyTime = null;
+ private String mIssuedBy = null;
+ private String mRevokedBy = null;
+ private Date mRevokedOn = null;
+
+ protected static Vector mNames = new Vector();
+ static {
+ mNames.addElement(ATTR_ID);
+ mNames.addElement(ATTR_META_INFO);
+ mNames.addElement(ATTR_REVO_INFO);
+ mNames.addElement(ATTR_X509CERT);
+ mNames.addElement(ATTR_CREATE_TIME);
+ mNames.addElement(ATTR_MODIFY_TIME);
+ mNames.addElement(ATTR_CERT_STATUS);
+ mNames.addElement(ATTR_AUTO_RENEW);
+ mNames.addElement(ATTR_ISSUED_BY);
+ mNames.addElement(ATTR_REVOKED_BY);
+ mNames.addElement(ATTR_REVOKED_ON);
+ }
+
+ /**
+ * Constructs empty certificate record.
+ */
+ public CertRecord() {
+ }
+
+ /**
+ * Constructs certiificate record with certificate
+ * and meta info.
+ */
+ public CertRecord(BigInteger id, Certificate cert, MetaInfo meta) {
+ mId = id;
+ if (cert instanceof X509CertImpl)
+ mX509Certificate = (X509CertImpl) cert;
+ mMetaInfo = meta;
+ mStatus = STATUS_VALID;
+ mAutoRenew = AUTO_RENEWAL_ENABLED;
+ mCreateTime = CMS.getCurrentDate();
+ mModifyTime = CMS.getCurrentDate();
+ }
+
+ /**
+ * Sets attribute to this record.
+ */
+ public void set(String name, Object obj) throws EBaseException {
+ if (name.equalsIgnoreCase(ATTR_REVO_INFO)) {
+ mRevocationInfo = (RevocationInfo) obj;
+ } else if (name.equalsIgnoreCase(ATTR_ID)) {
+ mId = (BigInteger) obj;
+ } else if (name.equalsIgnoreCase(ATTR_META_INFO)) {
+ mMetaInfo = (MetaInfo) obj;
+ } else if (name.equalsIgnoreCase(ATTR_X509CERT)) {
+ mX509Certificate = (X509CertImpl) obj;
+ } else if (name.equalsIgnoreCase(ATTR_CERT_STATUS)) {
+ mStatus = (String) obj;
+ } else if (name.equalsIgnoreCase(ATTR_AUTO_RENEW)) {
+ mAutoRenew = (String) obj;
+ } else if (name.equalsIgnoreCase(ATTR_CREATE_TIME)) {
+ mCreateTime = (Date) obj;
+ } else if (name.equalsIgnoreCase(ATTR_MODIFY_TIME)) {
+ mModifyTime = (Date) obj;
+ } else if (name.equalsIgnoreCase(ATTR_ISSUED_BY)) {
+ mIssuedBy = (String) obj;
+ } else if (name.equalsIgnoreCase(ATTR_REVOKED_BY)) {
+ mRevokedBy = (String) obj;
+ } else if (name.equalsIgnoreCase(ATTR_REVOKED_ON)) {
+ mRevokedOn = (Date) obj;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ /**
+ * Retrieves attributes from this record.
+ */
+ public Object get(String name) throws EBaseException {
+ if (name.equalsIgnoreCase(ATTR_REVO_INFO)) {
+ return mRevocationInfo;
+ } else if (name.equalsIgnoreCase(ATTR_ID)) {
+ return mId;
+ } else if (name.equalsIgnoreCase(ATTR_META_INFO)) {
+ return mMetaInfo;
+ } else if (name.equalsIgnoreCase(ATTR_X509CERT)) {
+ return mX509Certificate;
+ } else if (name.equalsIgnoreCase(ATTR_CERT_STATUS)) {
+ return mStatus;
+ } else if (name.equalsIgnoreCase(ATTR_AUTO_RENEW)) {
+ return mAutoRenew;
+ } else if (name.equalsIgnoreCase(ATTR_CREATE_TIME)) {
+ return mCreateTime;
+ } else if (name.equalsIgnoreCase(ATTR_MODIFY_TIME)) {
+ return mModifyTime;
+ } else if (name.equalsIgnoreCase(ATTR_ISSUED_BY)) {
+ return mIssuedBy;
+ } else if (name.equalsIgnoreCase(ATTR_REVOKED_BY)) {
+ return mRevokedBy;
+ } else if (name.equalsIgnoreCase(ATTR_REVOKED_ON)) {
+ return mRevokedOn;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ /**
+ * Deletes attribute from this record.
+ */
+ public void delete(String name) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+
+ public Enumeration getElements() {
+ return mNames.elements();
+ }
+
+ public Enumeration getSerializableAttrNames() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieves X509 certificate.
+ */
+ public X509CertImpl getCertificate() {
+ return mX509Certificate;
+ }
+
+ /**
+ * Retrieves meta information.
+ */
+ public MetaInfo getMetaInfo() {
+ return mMetaInfo;
+ }
+
+ /**
+ * Retrieves certificate status.
+ */
+ public String getStatus() {
+ return mStatus;
+ }
+
+ /**
+ * Retrieves the auto renew mode.
+ */
+ public String getAutoRenew() {
+ return mAutoRenew;
+ }
+
+ /**
+ * Retrieves revocation information.
+ */
+ public IRevocationInfo getRevocationInfo() {
+ return mRevocationInfo;
+ }
+
+ /**
+ * Retrieves serial number of this record. Usually,
+ * it is the same of the serial number of the
+ * associated certificate.
+ */
+ public BigInteger getSerialNumber() {
+ return mId;
+ }
+
+ /**
+ * Retrieves the person who issues this certificate.
+ */
+ public String getIssuedBy() {
+ return mIssuedBy;
+ }
+
+ /**
+ * Retrieves the person who revokes this certificate.
+ */
+ public String getRevokedBy() {
+ return mRevokedBy;
+ }
+
+ /**
+ * Retrieves the date which this record is revoked.
+ */
+ public Date getRevokedOn() {
+ return mRevokedOn;
+ }
+
+ /**
+ * Retrieves certificate serial number.
+ */
+ public BigInteger getCertificateSerialNumber() {
+ return mX509Certificate.getSerialNumber();
+ }
+
+ /**
+ * Retrieves not after.
+ */
+ public Date getNotAfter() {
+ return mX509Certificate.getNotAfter();
+ }
+
+ public Date getNotBefore() {
+ return mX509Certificate.getNotBefore();
+ }
+
+ /**
+ * Return revocation date.
+ */
+ public Date getRevocationDate() throws EDBException {
+ return mRevocationInfo.getRevocationDate();
+ }
+
+ public Date getCreateTime() {
+ return mCreateTime;
+ }
+
+ public Date getModifyTime() {
+ return mModifyTime;
+ }
+
+ /**
+ * String representation
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ buf.append("CertRecord: ");
+ if (getSerialNumber() != null)
+ buf.append(" " + getSerialNumber().toString());
+ return buf.toString();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CertRecordList.java b/pki/base/common/src/com/netscape/cmscore/dbs/CertRecordList.java
new file mode 100644
index 000000000..18b8c1bf5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CertRecordList.java
@@ -0,0 +1,118 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+
+import com.netscape.cmscore.dbs.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents a list of certificate records.
+ * <P>
+ *
+ * @author thomask mzhao
+ * @version $Revision$, $Date$
+ */
+public class CertRecordList implements ICertRecordList {
+
+ private IDBVirtualList mVlist = null;
+
+ /**
+ * Constructs a request list.
+ */
+ public CertRecordList(IDBVirtualList vlist) {
+ mVlist = vlist;
+ }
+
+ public int getCurrentIndex() {
+ return mVlist.getCurrentIndex();
+ }
+
+ /**
+ * Retrieves the size of request list.
+ */
+ public int getSize() {
+ // get the size of the virtual list
+ return mVlist.getSize();
+ }
+
+ public int getSizeBeforeJumpTo() {
+ return mVlist.getSizeBeforeJumpTo();
+
+ }
+
+ public int getSizeAfterJumpTo() {
+ return mVlist.getSizeAfterJumpTo();
+
+ }
+
+ /**
+ * Process certificate record as soon as it is returned.
+ * kmccarth: changed to ignore startidx and endidx because VLVs don't
+ * provide a stable list.
+ */
+ public void processCertRecords(int startidx, int endidx,
+ IElementProcessor ep) throws EBaseException {
+ int i = 0;
+ while ( i<mVlist.getSize() ) {
+ Object element = mVlist.getElementAt(i);
+ if (element != null && (! (element instanceof String)) ) {
+ ep.process(element);
+ }
+ i++;
+ }
+ }
+
+ /**
+ * Retrieves requests.
+ * It's no good to call this if you didnt check
+ * if the startidx, endidx are valid.
+ */
+ public Enumeration getCertRecords(int startidx, int endidx)
+ throws EBaseException {
+ Vector entries = new Vector();
+
+ for (int i = startidx; i <= endidx; i++) {
+ Object element = mVlist.getElementAt(i);
+
+ // CMS.debug("gerCertRecords[" + i + "] element: " + element);
+ if (element != null) {
+ entries.addElement(element);
+ }
+ }
+ return entries.elements();
+ }
+
+ public Object getCertRecord(int index)
+ throws EBaseException {
+
+ Object element = mVlist.getElementAt(index);
+
+ return element;
+
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CertRecordMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/CertRecordMapper.java
new file mode 100644
index 000000000..6b910ebbb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CertRecordMapper.java
@@ -0,0 +1,98 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import java.security.cert.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.util.Debug;
+import com.netscape.certsrv.apps.CMS;
+
+
+/**
+ * A class represents a mapper to serialize
+ * certificate record into database.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class CertRecordMapper implements IDBAttrMapper {
+
+ private ICertificateRepository mDB = null;
+
+ public CertRecordMapper(ICertificateRepository db) {
+ mDB = db;
+ }
+
+ public Enumeration getSupportedLDAPAttributeNames() {
+ Vector v = new Vector();
+
+ v.addElement(CertDBSchema.LDAP_ATTR_CERT_RECORD_ID);
+ return v.elements();
+ }
+
+ public void mapObjectToLDAPAttributeSet(IDBObj parent, String name,
+ Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ try {
+ CertRecord rec = (CertRecord) obj;
+
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_CERT_RECORD_ID,
+ rec.getSerialNumber().toString()));
+ } catch (Exception e) {
+ Debug.trace(e.toString());
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_SERIALIZE_FAILED", name));
+ }
+ }
+
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ try {
+ LDAPAttribute attr = attrs.getAttribute(
+ CertDBSchema.LDAP_ATTR_CERT_RECORD_ID);
+
+ if (attr == null)
+ return;
+ String serialno = (String) attr.getStringValues().nextElement();
+ ICertRecord rec = mDB.readCertificateRecord(
+ new BigInteger(serialno));
+
+ parent.set(name, rec);
+ } catch (Exception e) {
+ Debug.trace(e.toString());
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_DESERIALIZE_FAILED", name));
+ }
+ }
+
+ public String mapSearchFilter(String name, String op, String value)
+ throws EBaseException {
+ return name + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java b/pki/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java
new file mode 100644
index 000000000..526e855e6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java
@@ -0,0 +1,1985 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.BigInteger;
+import java.util.*;
+import java.io.*;
+import java.security.*;
+import java.security.cert.*;
+import java.security.cert.Certificate;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.cmscore.cert.*;
+
+
+/**
+ * A class represents a certificate repository. It
+ * stores all the issued certificate.
+ * <P>
+ *
+ * @author thomask
+ * @author kanda
+ * @version $Revision$, $Date$
+ */
+public class CertificateRepository extends Repository
+ implements ICertificateRepository {
+
+ public final String CERT_X509ATTRIBUTE = "x509signedcert";
+
+ private IDBSubsystem mDBService;
+ private String mBaseDN;
+ private String mRequestBaseDN;
+ private boolean mConsistencyCheck = false;
+ private boolean mSkipIfInconsistent = false;
+
+ private int mCertStatusUpdateInterval = 0;
+ private Hashtable mCRLIssuingPoints = new Hashtable();
+
+ private int mTransitMaxRecords = 1000000;
+ private int mTransitRecordPageSize = 200;
+
+ /**
+ * Constructs a certificate repository.
+ */
+ public CertificateRepository(IDBSubsystem dbService, String certRepoBaseDN, int increment, String baseDN)
+ throws EDBException {
+ super(dbService, increment, baseDN);
+ mBaseDN = certRepoBaseDN;
+
+ mDBService = dbService;
+
+ // registers CMS database attributes
+ IDBRegistry reg = dbService.getRegistry();
+
+ IConfigStore cfg = mDBService.getConfigStore();
+ }
+
+ public ICertRecord createCertRecord(BigInteger id, Certificate cert, MetaInfo meta) {
+ return new CertRecord(id, cert, meta);
+ }
+
+ public BigInteger getLastSerialNumberInRange(BigInteger serial_low_bound, BigInteger serial_upper_bound)
+ throws EBaseException {
+
+ CMS.debug("CertificateRepository: in getLastSerialNumberInRange: low " + serial_low_bound + " high " + serial_upper_bound);
+
+ if(serial_low_bound == null || serial_upper_bound == null || serial_low_bound.compareTo(serial_upper_bound) >= 0 )
+ {
+ return null;
+
+ }
+
+ String ldapfilter = "(" + "certstatus" + "=*" + ")";
+
+ String[] attrs = null;
+
+ ICertRecordList recList = findCertRecordsInList(ldapfilter,attrs,serial_upper_bound.toString(10),"serialno", 5 * -1);
+
+ int size = recList.getSize();
+
+ CMS.debug("CertificateRepository:getLastSerialNumberInRange: recList size " + size);
+
+ if (size <= 0) {
+ CMS.debug("CertificateRepository:getLastSerialNumberInRange: index may be empty");
+
+ BigInteger ret = new BigInteger(serial_low_bound.toString(10));
+
+ ret = ret.add(new BigInteger("-1"));
+ CMS.debug("CertificateRepository:getLastCertRecordSerialNo: returning " + ret);
+ return ret;
+ }
+ int ltSize = recList.getSizeBeforeJumpTo();
+
+ Vector cList = new Vector(ltSize);
+
+ CMS.debug("CertificateRepository:getLastSerialNumberInRange: ltSize " + ltSize);
+
+ CertRecord curRec = null;
+
+ int i;
+ Object obj = null;
+
+ for (i = 0; i < 5; i++) {
+ obj = recList.getCertRecord(i);
+
+ if (obj != null) {
+ curRec = (CertRecord) obj;
+
+ BigInteger serial = curRec.getSerialNumber();
+
+ CMS.debug("CertificateRepository:getLastCertRecordSerialNo: serialno " + serial);
+
+ if( ((serial.compareTo(serial_low_bound) == 0) || (serial.compareTo(serial_low_bound) == 1) ) &&
+ ((serial.compareTo(serial_upper_bound) == 0) || (serial.compareTo(serial_upper_bound) == -1) ))
+ {
+ CMS.debug("getLastSerialNumberInRange returning: " + serial);
+ return serial;
+ }
+ } else {
+ CMS.debug("getLastSerialNumberInRange:found null from getCertRecord");
+ }
+ }
+
+
+ BigInteger ret = new BigInteger(serial_low_bound.toString(10));
+
+ ret = ret.add(new BigInteger("-1"));
+
+ CMS.debug("CertificateRepository:getLastCertRecordSerialNo: returning " + ret);
+ return ret;
+
+ }
+
+ /**
+ * Removes all objects with this repository.
+ */
+ public void removeCertRecords(BigInteger beginS, BigInteger endS) throws EBaseException
+ {
+ String filter = "(" + CertRecord.ATTR_CERT_STATUS + "=*" + ")";
+ ICertRecordList list =findCertRecordsInList(filter,
+ null, "serialno", 10);
+ int size = list.getSize();
+ Enumeration e = list.getCertRecords(0, size - 1);
+ while (e.hasMoreElements()) {
+ CertRecord rec = (CertRecord) e.nextElement();
+ BigInteger cur = rec.getSerialNumber();
+ BigInteger max = cur.max(beginS);
+ BigInteger min = cur;
+ if (endS != null)
+ min = cur.min(endS);
+ if (cur.equals(beginS) || cur.equals(endS) ||
+ (cur.equals(max) && cur.equals(min)))
+ deleteCertificateRecord(cur);
+ }
+ }
+
+ public void setConsistencyCheck(boolean ConsistencyCheck) {
+ mConsistencyCheck = ConsistencyCheck;
+ }
+
+ public void setSkipIfInConsistent(boolean SkipIfInconsistent) {
+ mSkipIfInconsistent = SkipIfInconsistent;
+ }
+
+ public void setTransitMaxRecords(int max) {
+ mTransitMaxRecords = max;
+ }
+
+ public void setTransitRecordPageSize(int size) {
+ mTransitRecordPageSize = size;
+
+ }
+
+ /**
+ * register CRL Issuing Point
+ */
+ public void addCRLIssuingPoint(String id, ICRLIssuingPoint crlIssuingPoint) {
+ mCRLIssuingPoints.put(id, crlIssuingPoint);
+ }
+
+ /**
+ * interval value: (in seconds)
+ * 0 - disable
+ * >0 - enable
+ */
+ public CertStatusUpdateThread mCertStatusUpdateThread = null;
+ public RetrieveModificationsThread mRetrieveModificationsThread = null;
+
+ public void setCertStatusUpdateInterval(IRepository requestRepo, int interval, boolean listenToCloneModifications) {
+ CMS.debug("In setCertStatusUpdateInterval " + interval);
+ if (interval == 0) {
+ CMS.debug("In setCertStatusUpdateInterval interval = 0" + interval);
+ if (mCertStatusUpdateThread != null) {
+ mCertStatusUpdateThread.stop();
+ }
+ if (mRetrieveModificationsThread != null) {
+ mRetrieveModificationsThread.stop();
+ }
+ return;
+ }
+
+ CMS.debug("In setCertStatusUpdateInterval listenToCloneModifications="+listenToCloneModifications+
+ " mRetrieveModificationsThread="+mRetrieveModificationsThread);
+ if (listenToCloneModifications && mRetrieveModificationsThread == null) {
+ CMS.debug("In setCertStatusUpdateInterval about to create RetrieveModificationsThread");
+ mRetrieveModificationsThread = new RetrieveModificationsThread(this, "RetrieveModificationsThread");
+ LDAPSearchResults mResults = null;
+ try {
+ mResults = startSearchForModifiedCertificateRecords();
+ } catch (Exception e) {
+ mResults = null;
+ }
+ if (mResults != null) {
+ mRetrieveModificationsThread.setResults(mResults);
+ mRetrieveModificationsThread.start();
+ }
+ }
+
+ CMS.debug("In setCertStatusUpdateInterval mCertStatusUpdateThread " + mCertStatusUpdateThread);
+ if (mCertStatusUpdateThread == null) {
+ CMS.debug("In setCertStatusUpdateInterval about to create CertStatusUpdateThread ");
+ mCertStatusUpdateThread = new CertStatusUpdateThread(this, requestRepo, "CertStatusUpdateThread");
+ mCertStatusUpdateThread.setInterval(interval);
+ mCertStatusUpdateThread.start();
+ } else {
+ CMS.debug("In setCertStatusUpdateInterval it thinks the thread is up already ");
+ mCertStatusUpdateThread.setInterval(interval);
+ // dont do anything if we have a thread running already
+ }
+ }
+
+
+ /**
+ * Blocking method.
+ */
+ public void updateCertStatus() throws EBaseException {
+
+ CMS.debug("In updateCertStatus()");
+
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ CMS.getLogMessage("CMSCORE_DBS_START_VALID_SEARCH"));
+ transitInvalidCertificates();
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ CMS.getLogMessage("CMSCORE_DBS_FINISH_VALID_SEARCH"));
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ CMS.getLogMessage("CMSCORE_DBS_START_EXPIRED_SEARCH"));
+ transitValidCertificates();
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ CMS.getLogMessage("CMSCORE_DBS_FINISH_EXPIRED_SEARCH"));
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ CMS.getLogMessage("CMSCORE_DBS_START_REVOKED_EXPIRED_SEARCH"));
+ transitRevokedExpiredCertificates();
+ CMS.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ CMS.getLogMessage("CMSCORE_DBS_FINISH_REVOKED_EXPIRED_SEARCH"));
+ }
+
+ /**
+ * Retrieves DN of this repository.
+ */
+ public String getDN() {
+ return mBaseDN;
+ }
+
+ public void setRequestDN( String requestDN ) {
+ mRequestBaseDN = requestDN;
+ }
+
+ public String getRequestDN() {
+ return mRequestBaseDN;
+ }
+ /**
+ * Retrieves backend database handle.
+ */
+ public IDBSubsystem getDBSubsystem() {
+ return mDBService;
+ }
+
+ /**
+ * Adds a certificate record to the repository. Each certificate
+ * record contains four parts: certificate, meta-attributes,
+ * issue information and reovcation information.
+ * <P>
+ *
+ * @param cert X.509 certificate
+ * @exception EBaseException failed to add new certificate to
+ * the repository
+ */
+ public void addCertificateRecord(ICertRecord record)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" +
+ ((CertRecord) record).getSerialNumber().toString() + "," + getDN();
+ SessionContext ctx = SessionContext.getContext();
+ String uid = (String) ctx.get(SessionContext.USER_ID);
+
+ if (uid == null) {
+ // XXX is this right?
+ record.set(CertRecord.ATTR_ISSUED_BY, "system");
+
+ /**
+ System.out.println("XXX servlet should set USER_ID");
+ throw new EBaseException(BaseResources.UNKNOWN_PRINCIPAL_1,
+ "null");
+ **/
+ } else {
+ record.set(CertRecord.ATTR_ISSUED_BY, uid);
+ }
+
+ // Check validity of this certificate. If it is not invalid,
+ // mark it so. We will have a thread to transit the status
+ // from INVALID to VALID.
+ X509CertImpl x509cert = (X509CertImpl) record.get(
+ CertRecord.ATTR_X509CERT);
+
+ if (x509cert != null) {
+ Date now = CMS.getCurrentDate();
+
+ if (x509cert.getNotBefore().after(now)) {
+ // not yet valid
+ record.set(ICertRecord.ATTR_CERT_STATUS,
+ ICertRecord.STATUS_INVALID);
+ }
+ }
+
+ s.add(name, record);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * Used by the Clone Master (CLA) to add a revoked certificate
+ * record to the repository.
+ * <p>
+ *
+ * @param record a CertRecord
+ * @exception EBaseException failed to add new certificate to
+ * the repository
+ */
+ public void addRevokedCertRecord(CertRecord record)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" +
+ record.getSerialNumber().toString() + "," + getDN();
+
+ s.add(name, record);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * This transits a certificate status from VALID to EXPIRED
+ * if a certificate becomes expired.
+ */
+ public void transitValidCertificates() throws EBaseException {
+
+ Date now = CMS.getCurrentDate();
+ ICertRecordList recList = getValidCertsByNotAfterDate(now, -1 * mTransitRecordPageSize);
+
+ int size = recList.getSize();
+
+ if (size <= 0) {
+ CMS.debug("index may be empty");
+ return;
+ }
+ int ltSize = recList.getSizeBeforeJumpTo();
+
+ ltSize = Math.min(ltSize, mTransitMaxRecords);
+
+ Vector cList = new Vector(ltSize);
+
+ CMS.debug("transidValidCertificates: list size: " + size);
+ CMS.debug("transitValidCertificates: ltSize " + ltSize);
+
+ CertRecord curRec = null;
+
+ int i;
+ Object obj = null;
+
+ for (i = 0; i < ltSize; i++) {
+ obj = recList.getCertRecord(i);
+
+ if (obj != null) {
+ curRec = (CertRecord) obj;
+
+ Date notAfter = curRec.getNotAfter();
+
+ //CMS.debug("notAfter " + notAfter.toString() + " now " + now.toString());
+ if (notAfter.after(now)) {
+ CMS.debug("Record does not qualify,notAfter " + notAfter.toString() + " date " + now.toString());
+ continue;
+ }
+
+ CMS.debug("transitValid: curRec: " + i + " " + curRec.toString());
+
+ if (mConsistencyCheck) {
+ cList.add(curRec);
+ } else {
+ cList.add(curRec.getSerialNumber());
+ }
+ } else {
+ CMS.debug("found null from getCertRecord");
+ }
+ }
+
+ CertRecord cRec = null;
+ BigInteger serial = null;
+
+ transitCertList(cList, CertRecord.STATUS_EXPIRED);
+ }
+
+ /**
+ * This transits a certificate status from REVOKED to REVOKED_EXPIRED
+ * if an revoked certificate becomes expired.
+ */
+ public void transitRevokedExpiredCertificates() throws EBaseException {
+ Date now = CMS.getCurrentDate();
+ ICertRecordList recList = getRevokedCertsByNotAfterDate(now, -1 * mTransitRecordPageSize);
+
+ int size = recList.getSize();
+
+ if (size <= 0) {
+ CMS.debug("index may be empty");
+ return;
+ }
+
+ int ltSize = recList.getSizeBeforeJumpTo();
+ Vector cList = new Vector(ltSize);
+
+ ltSize = Math.min(ltSize, mTransitMaxRecords);
+
+ CMS.debug("transitRevokedExpiredCertificates: list size: " + size);
+ CMS.debug("transitRevokedExpiredCertificates: ltSize " + ltSize);
+
+ CertRecord curRec = null;
+ int i;
+ Object obj = null;
+
+ for (i = 0; i < ltSize; i++) {
+ obj = recList.getCertRecord(i);
+ if (obj != null) {
+ curRec = (CertRecord) obj;
+ CMS.debug("transitRevokedExpired: curRec: " + i + " " + curRec.toString());
+
+ Date notAfter = curRec.getNotAfter();
+
+ // CMS.debug("notAfter " + notAfter.toString() + " now " + now.toString());
+ if (notAfter.after(now)) {
+ CMS.debug("Record does not qualify,notAfter " + notAfter.toString() + " date " + now.toString());
+ continue;
+ }
+
+ if (mConsistencyCheck) {
+ cList.add(curRec);
+ } else {
+ cList.add(curRec.getSerialNumber());
+ }
+ } else {
+ CMS.debug("found null record in getCertRecord");
+ }
+ }
+
+ transitCertList(cList, CertRecord.STATUS_REVOKED_EXPIRED);
+
+ }
+
+ /**
+ * This transits a certificate status from INVALID to VALID
+ * if a certificate becomes valid.
+ */
+ public void transitInvalidCertificates() throws EBaseException {
+
+ Date now = CMS.getCurrentDate();
+
+ ICertRecordList recList = getInvalidCertsByNotBeforeDate(now, -1 * mTransitRecordPageSize);
+
+ int size = recList.getSize();
+
+ if (size <= 0) {
+ CMS.debug("index may be empty");
+ return;
+ }
+ int ltSize = recList.getSizeBeforeJumpTo();
+
+ ltSize = Math.min(ltSize, mTransitMaxRecords);
+
+ Vector cList = new Vector(ltSize);
+
+ CMS.debug("transidInValidCertificates: list size: " + size);
+ CMS.debug("transitInValidCertificates: ltSize " + ltSize);
+
+ CertRecord curRec = null;
+
+ int i;
+
+ Object obj = null;
+
+ for (i = 0; i < ltSize; i++) {
+ obj = recList.getCertRecord(i);
+
+ if (obj != null) {
+ curRec = (CertRecord) obj;
+
+ Date notBefore = curRec.getNotBefore();
+
+ //CMS.debug("notBefore " + notBefore.toString() + " now " + now.toString());
+ if (notBefore.after(now)) {
+ CMS.debug("Record does not qualify,notBefore " + notBefore.toString() + " date " + now.toString());
+ continue;
+
+ }
+ CMS.debug("transitInValid: curRec: " + i + " " + curRec.toString());
+
+ if (mConsistencyCheck) {
+ cList.add(curRec);
+ } else {
+ cList.add(curRec.getSerialNumber());
+ }
+
+ } else {
+ CMS.debug("found null from getCertRecord");
+ }
+ }
+
+ transitCertList(cList, CertRecord.STATUS_VALID);
+
+ }
+
+ private void transitCertList(Vector cList, String newCertStatus) throws EBaseException {
+ CertRecord cRec = null;
+ BigInteger serial = null;
+
+ int i;
+
+ CMS.debug("transitCertList " + newCertStatus);
+
+ for (i = 0; i < cList.size(); i++) {
+ if (mConsistencyCheck) {
+ cRec = (CertRecord) cList.elementAt(i);
+
+ if (cRec == null)
+ continue;
+
+ serial = cRec.getSerialNumber();
+ } else {
+ serial = (BigInteger) cList.elementAt(i);
+ }
+
+ updateStatus(serial, newCertStatus);
+
+ if (newCertStatus.equals(CertRecord.STATUS_REVOKED_EXPIRED)) {
+
+ // inform all CRLIssuingPoints about revoked and expired certificate
+
+ Enumeration eIPs = mCRLIssuingPoints.elements();
+
+ while (eIPs.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) eIPs.nextElement();
+
+ if (ip != null) {
+ ip.addExpiredCert(serial);
+ }
+ }
+
+ }
+
+ CMS.debug("transitCertList number at: " + i + " = " + serial);
+ }
+
+ cList.removeAllElements();
+ }
+
+ /**
+ * Reads the certificate identified by the given serial no.
+ */
+ public X509CertImpl getX509Certificate(BigInteger serialNo)
+ throws EBaseException {
+ X509CertImpl cert = null;
+ ICertRecord cr = readCertificateRecord(serialNo);
+
+ return (cr.getCertificate());
+ }
+
+ /**
+ * Deletes certificate record.
+ */
+ public void deleteCertificateRecord(BigInteger serialNo)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" +
+ serialNo.toString() + "," + getDN();
+
+ s.delete(name);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * Reads certificate from repository.
+ */
+ public ICertRecord readCertificateRecord(BigInteger serialNo)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ CertRecord rec = null;
+
+ try {
+ String name = "cn" + "=" +
+ serialNo.toString() + "," + getDN();
+
+ rec = (CertRecord) s.read(name);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return rec;
+ }
+
+ public synchronized void modifyCertificateRecord(BigInteger serialNo,
+ ModificationSet mods) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" +
+ serialNo.toString() + "," + getDN();
+
+ mods.add(CertRecord.ATTR_MODIFY_TIME, Modification.MOD_REPLACE,
+ CMS.getCurrentDate());
+ s.modify(name, mods);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * Checks if the specified certificate is in the repository.
+ */
+ public boolean containsCertificate(BigInteger serialNo)
+ throws EBaseException {
+ try {
+ ICertRecord cr = readCertificateRecord(serialNo);
+
+ if (cr != null)
+ return true;
+ } catch (EBaseException e) {
+ }
+ return false;
+ }
+
+ /**
+ * Marks certificate as revoked.
+ */
+ public void markAsRevoked(BigInteger id, IRevocationInfo info)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ mods.add(CertRecord.ATTR_REVO_INFO, Modification.MOD_ADD, info);
+ SessionContext ctx = SessionContext.getContext();
+ String uid = (String) ctx.get(SessionContext.USER_ID);
+
+ if (uid == null) {
+ mods.add(CertRecord.ATTR_REVOKED_BY, Modification.MOD_ADD,
+ "system");
+ } else {
+ mods.add(CertRecord.ATTR_REVOKED_BY, Modification.MOD_ADD,
+ uid);
+ }
+ mods.add(CertRecord.ATTR_REVOKED_ON, Modification.MOD_ADD,
+ CMS.getCurrentDate());
+ mods.add(CertRecord.ATTR_CERT_STATUS, Modification.MOD_REPLACE,
+ CertRecord.STATUS_REVOKED);
+ modifyCertificateRecord(id, mods);
+ }
+
+ /**
+ * Unmarks revoked certificate.
+ */
+ public void unmarkRevoked(BigInteger id, IRevocationInfo info,
+ Date revokedOn, String revokedBy)
+ throws EBaseException {
+ ModificationSet mods = new ModificationSet();
+
+ mods.add(CertRecord.ATTR_REVO_INFO, Modification.MOD_DELETE, info);
+ mods.add(CertRecord.ATTR_REVOKED_BY, Modification.MOD_DELETE, revokedBy);
+ mods.add(CertRecord.ATTR_REVOKED_ON, Modification.MOD_DELETE, revokedOn);
+ mods.add(CertRecord.ATTR_CERT_STATUS, Modification.MOD_REPLACE,
+ CertRecord.STATUS_VALID);
+ modifyCertificateRecord(id, mods);
+ }
+
+ /**
+ * Updates the certificiate record status to the specified.
+ */
+ public void updateStatus(BigInteger id, String status)
+ throws EBaseException {
+ CMS.debug("updateStatus: " + id + " status " + status);
+ ModificationSet mods = new ModificationSet();
+
+ mods.add(CertRecord.ATTR_CERT_STATUS, Modification.MOD_REPLACE,
+ status);
+ modifyCertificateRecord(id, mods);
+ }
+
+ public Enumeration searchCertificates(String filter, int maxSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ CMS.debug("searchCertificates filter " + filter + " maxSize " + maxSize);
+ try {
+ e = s.search(getDN(), filter, maxSize);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ public Enumeration searchCertificates(String filter, int maxSize, int timeLimit)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ CMS.debug("searchCertificateswith time limit filter " + filter);
+ try {
+ e = s.search(getDN(), filter, maxSize, timeLimit);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Returns a list of X509CertImp that satisfies the filter.
+ * @deprecated replaced by <code>findCertificatesInList</code>
+ */
+ public Enumeration findCertRecs(String filter)
+ throws EBaseException {
+ CMS.debug("findCertRecs " + filter);
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+ try {
+ e = s.search(getDN(), filter);
+ } finally {
+ if (s != null) s.close();
+ }
+ return e;
+ }
+
+ public Enumeration findCertRecs(String filter, String[] attrs)
+ throws EBaseException {
+
+ CMS.debug( "findCertRecs " + filter
+ + "attrs " + Arrays.toString( attrs ) );
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+ try {
+ e = s.search(getDN(), filter, attrs);
+ } finally {
+ if (s != null) s.close();
+ }
+ return e;
+
+ }
+
+ public Enumeration findCertificates(String filter)
+ throws EBaseException {
+ Enumeration e = findCertRecords(filter);
+ Vector v = new Vector();
+
+ while (e.hasMoreElements()) {
+ CertRecord rec = (CertRecord) e.nextElement();
+
+ v.addElement(rec.getCertificate());
+ }
+ return v.elements();
+ }
+
+ /**
+ * Finds a list of certificate records that satisifies
+ * the filter.
+ * If you are going to process everything in the list,
+ * use this.
+ */
+ public Enumeration findCertRecords(String filter)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ //e = s.search(getDN(), filter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(filter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Finds certificate records. Here is a list of filter
+ * attribute can be used:
+ * <pre>
+ * certRecordId
+ * certMetaInfo
+ * certStatus
+ * certCreateTime
+ * certModifyTime
+ * x509Cert.notBefore
+ * x509Cert.notAfter
+ * x509Cert.subject
+ * </pre>
+ * The filter should follow RFC1558 LDAP filter syntax.
+ * For example,
+ * <pre>
+ * (&(certRecordId=5)(x509Cert.notBefore=934398398))
+ * </pre>
+ */
+ public ICertRecordList findCertRecordsInList(String filter,
+ String attrs[], int pageSize) throws EBaseException {
+ return findCertRecordsInList(filter, attrs, CertRecord.ATTR_ID,
+ pageSize);
+ }
+
+ public ICertRecordList findCertRecordsInList(String filter,
+ String attrs[], String sortKey, int pageSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ CMS.debug("In findCertRecordsInList");
+ CertRecordList list = null;
+
+ try {
+ DBVirtualList vlist = (DBVirtualList) s.createVirtualList(getDN(), filter, attrs,
+ sortKey, pageSize);
+
+ list = new CertRecordList(vlist);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return list;
+ }
+
+ public ICertRecordList findCertRecordsInList(String filter,
+ String attrs[], String jumpTo, String sortKey, int pageSize)
+ throws EBaseException {
+ return findCertRecordsInList(filter, attrs, jumpTo, false, sortKey, pageSize);
+
+ }
+
+ public ICertRecordList findCertRecordsInList(String filter,
+ String attrs[], String jumpTo, boolean hardJumpTo,
+ String sortKey, int pageSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ CertRecordList list = null;
+
+ CMS.debug("In findCertRecordsInList with Jumpto " + jumpTo);
+ try {
+ String jumpToVal = null;
+
+ if (hardJumpTo) {
+ CMS.debug("In findCertRecordsInList with hardJumpto ");
+ jumpToVal = "99";
+ } else {
+ int len = jumpTo.length();
+
+ if (len > 9) {
+ jumpToVal = Integer.toString(len) + jumpTo;
+ } else {
+ jumpToVal = "0" + Integer.toString(len) + jumpTo;
+ }
+ }
+
+ DBVirtualList vlist = (DBVirtualList) s.createVirtualList(getDN(), filter,
+ attrs, jumpToVal, sortKey, pageSize);
+
+ list = new CertRecordList(vlist);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return list;
+ }
+
+ public ICertRecordList findCertRecordsInListRawJumpto(String filter,
+ String attrs[], String jumpTo, String sortKey, int pageSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ CertRecordList list = null;
+
+ CMS.debug("In findCertRecordsInListRawJumpto with Jumpto " + jumpTo);
+
+ try {
+
+ DBVirtualList vlist = (DBVirtualList) s.createVirtualList(getDN(), filter,
+ attrs, jumpTo, sortKey, pageSize);
+
+ list = new CertRecordList(vlist);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return list;
+ }
+
+ /**
+ * Marks certificate as renewable.
+ */
+ public void markCertificateAsRenewable(ICertRecord record)
+ throws EBaseException {
+ changeRenewalAttribute(((CertRecord) record).getSerialNumber().toString(),
+ CertRecord.AUTO_RENEWAL_ENABLED);
+ }
+
+ /**
+ * Marks certificate as renewable.
+ */
+ public void markCertificateAsNotRenewable(ICertRecord record)
+ throws EBaseException {
+ changeRenewalAttribute(((CertRecord) record).getSerialNumber().toString(),
+ CertRecord.AUTO_RENEWAL_DISABLED);
+ }
+
+ public void markCertificateAsRenewed(String serialNo)
+ throws EBaseException {
+ changeRenewalAttribute(serialNo, CertRecord.AUTO_RENEWAL_DONE);
+ }
+
+ public void markCertificateAsRenewalNotified(String serialNo)
+ throws EBaseException {
+ changeRenewalAttribute(serialNo, CertRecord.AUTO_RENEWAL_NOTIFIED);
+ }
+
+ private void changeRenewalAttribute(String serialno, String value)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" + serialno +
+ "," + getDN();
+ ModificationSet mods = new ModificationSet();
+
+ mods.add(CertRecord.ATTR_AUTO_RENEW, Modification.MOD_REPLACE,
+ value);
+ s.modify(name, mods);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * temp solution...
+ */
+ public class RenewableCertificateCollection {
+ Vector mToRenew = null;
+ Vector mToNotify = null;
+ public RenewableCertificateCollection() {
+ }
+
+ public Vector getRenewable() {
+ return mToRenew;
+ }
+
+ public Vector getNotifiable() {
+ return mToNotify;
+ }
+
+ public void addCertificate(String renewalFlag, Object o) {
+ if (renewalFlag.equals(CertRecord.AUTO_RENEWAL_ENABLED)) {
+ if (mToRenew == null)
+ mToRenew = new Vector();
+ mToRenew.addElement(o);
+ }
+ if (renewalFlag.equals(CertRecord.AUTO_RENEWAL_DISABLED)) {
+ if (mToNotify == null)
+ mToNotify = new Vector();
+ mToNotify.addElement(o);
+ }
+ }
+ }
+
+ public Hashtable getRenewableCertificates(String renewalTime)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ Hashtable tab = null;
+
+ try {
+ String filter = "(&(" + CertRecord.ATTR_CERT_STATUS + "=" +
+ CertRecord.STATUS_VALID + ")("
+ + CertRecord.ATTR_X509CERT +
+ "." + CertificateValidity.NOT_AFTER + "<=" + renewalTime +
+ ")(!(" + CertRecord.ATTR_AUTO_RENEW + "=" +
+ CertRecord.AUTO_RENEWAL_DONE +
+ "))(!(" + CertRecord.ATTR_AUTO_RENEW + "=" +
+ CertRecord.AUTO_RENEWAL_NOTIFIED + ")))";
+ //Enumeration e = s.search(getDN(), filter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(filter, null, "serialno", 10);
+ int size = list.getSize();
+ Enumeration e = list.getCertRecords(0, size - 1);
+
+ tab = new Hashtable();
+ while (e.hasMoreElements()) {
+ CertRecord rec = (CertRecord) e.nextElement();
+ X509CertImpl cert = rec.getCertificate();
+ String subjectDN = cert.getSubjectDN().toString();
+ String renewalFlag = rec.getAutoRenew();
+
+ // See if the subjectDN is in the table
+ Object val = null;
+
+ if ((val = tab.get(subjectDN)) == null) {
+ RenewableCertificateCollection collection =
+ new RenewableCertificateCollection();
+
+ collection.addCertificate(renewalFlag, cert);
+ tab.put(subjectDN, collection);
+ } else {
+ ((RenewableCertificateCollection) val).addCertificate(renewalFlag, cert);
+ }
+ }
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return tab;
+ }
+
+ /**
+ * Gets all valid and unexpired certificates pertaining
+ * to a subject DN.
+ *
+ * @param subjectDN The distinguished name of the subject.
+ * @param validityType The type of certificates to get.
+ * @return An array of certificates.
+ */
+
+ public X509CertImpl[] getX509Certificates(String subjectDN,
+ int validityType) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ X509CertImpl certs[] = null;
+
+ try {
+ // XXX - not checking validityType...
+ String filter = "(&(" + CertRecord.ATTR_X509CERT +
+ "." + X509CertInfo.SUBJECT + "=" + subjectDN;
+
+ if (validityType == ALL_VALID_CERTS) {
+ filter += ")(" +
+ CertRecord.ATTR_CERT_STATUS + "=" +
+ CertRecord.STATUS_VALID;
+ }
+ if (validityType == ALL_UNREVOKED_CERTS) {
+ filter += ")(|(" +
+ CertRecord.ATTR_CERT_STATUS + "=" +
+ CertRecord.STATUS_VALID + ")(" +
+ CertRecord.ATTR_CERT_STATUS + "=" +
+ CertRecord.STATUS_EXPIRED + ")";
+ }
+ filter += "))";
+
+ //Enumeration e = s.search(getDN(), filter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(filter, null, "serialno", 10);
+ int size = list.getSize();
+ Enumeration e = list.getCertRecords(0, size - 1);
+
+ Vector v = new Vector();
+
+ while (e.hasMoreElements()) {
+ CertRecord rec = (CertRecord) e.nextElement();
+
+ v.addElement(rec.getCertificate());
+ }
+ if (v.size() == 0)
+ return null;
+ certs = new X509CertImpl[v.size()];
+ v.copyInto(certs);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return certs;
+ }
+
+ public X509CertImpl[] getX509Certificates(String filter)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ X509CertImpl certs[] = null;
+
+ try {
+ Enumeration e = null;
+
+ if (filter != null && filter.length() > 0) {
+ //e = s.search(getDN(), filter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(filter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ }
+
+ Vector v = new Vector();
+
+ while (e != null && e.hasMoreElements()) {
+ CertRecord rec = (CertRecord) e.nextElement();
+
+ v.addElement(rec.getCertificate());
+ }
+ if (v.size() > 0) {
+ certs = new X509CertImpl[v.size()];
+ v.copyInto(certs);
+ }
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return certs;
+ }
+
+ /**
+ * Retrives all valid certificates excluding ones already revoked.
+ * @param from The starting point of the serial number range.
+ * @param to The ending point of the serial number range.
+ */
+ public Enumeration getValidCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Vector v = new Vector();
+
+ try {
+
+ // 'from' determines 'jumpto' value
+ // 'to' determines where to stop looking
+
+ String ldapfilter = "(certstatus=VALID)";
+
+ String fromVal = "0";
+ try {
+ if (from != null) {
+ int fv = Integer.parseInt(from);
+ fromVal = from;
+ }
+ } catch (Exception e1) {
+ // from is not integer
+ }
+
+ ICertRecordList list =
+ findCertRecordsInList(ldapfilter, null, fromVal, "serialno", 40);
+
+ BigInteger toInt = null;
+ if (to != null && !to.trim().equals("")) {
+ toInt = new BigInteger(to);
+ }
+
+ for (int i=0;; i++) {
+ CertRecord rec = (CertRecord) list.getCertRecord(i);
+ CMS.debug("processing record: "+i);
+ if (rec == null) {
+ break; // no element returned
+ } else {
+
+ CMS.debug("processing record: "+i+" "+rec.getSerialNumber());
+ // Check if we are past the 'to' marker
+ if (toInt != null) {
+ if (rec.getSerialNumber().compareTo(toInt) > 0) {
+ break;
+ }
+ }
+ v.addElement(rec);
+ }
+ }
+
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ CMS.debug("returning "+v.size()+" elements");
+ return v.elements();
+ }
+
+ /**
+ * Retrives all valid certificates excluding ones already revoked.
+ */
+ public Enumeration getAllValidCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ Date now = CMS.getCurrentDate();
+ String ldapfilter = "(&(!(" + CertRecord.ATTR_REVO_INFO + "=*))(" +
+ CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_BEFORE + "<=" +
+ DateMapper.dateToDB(now) + ")(" +
+ CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_AFTER + ">=" +
+ DateMapper.dateToDB(now) + "))";
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all valid not published certificates
+ * excluding ones already revoked.
+ * @param from The starting point of the serial number range.
+ * @param to The ending point of the serial number range.
+ */
+ public Enumeration getValidNotPublishedCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ Date now = CMS.getCurrentDate();
+ String ldapfilter = "(&(";
+
+ if (from != null && from.length() > 0)
+ ldapfilter += CertRecord.ATTR_ID + ">=" + from + ")(";
+ if (to != null && to.length() > 0)
+ ldapfilter += CertRecord.ATTR_ID + "<=" + to + ")(";
+ ldapfilter += "!(" + CertRecord.ATTR_REVO_INFO + "=*))(" +
+ CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_BEFORE + "<=" +
+ DateMapper.dateToDB(now) + ")(" +
+ CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_AFTER + ">=" +
+ DateMapper.dateToDB(now) + ")(!(" +
+ "certMetainfo=" +
+ CertRecord.META_LDAPPUBLISH +
+ ":true)))";
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all valid not published certificates
+ * excluding ones already revoked.
+ */
+ public Enumeration getAllValidNotPublishedCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ Date now = CMS.getCurrentDate();
+ String ldapfilter = "(&(!(" + CertRecord.ATTR_REVO_INFO + "=*))(" +
+ CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_BEFORE + "<=" +
+ DateMapper.dateToDB(now) + ")(" +
+ CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_AFTER + ">=" +
+ DateMapper.dateToDB(now) + ")(!(" +
+ "certMetainfo=" +
+ CertRecord.META_LDAPPUBLISH +
+ ":true)))";
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all expired certificates.
+ * @param from The starting point of the serial number range.
+ * @param to The ending point of the serial number range.
+ */
+ public Enumeration getExpiredCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ Date now = CMS.getCurrentDate();
+ String ldapfilter = "(&(";
+
+ if (from != null && from.length() > 0)
+ ldapfilter += CertRecord.ATTR_ID + ">=" + from + ")(";
+ if (to != null && to.length() > 0)
+ ldapfilter += CertRecord.ATTR_ID + "<=" + to + ")(";
+ ldapfilter += "!(" + CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_AFTER + ">=" +
+ DateMapper.dateToDB(now) + ")))";
+ //e = s.search(getDN(), ldapfilter);
+
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all expired certificates.
+ */
+ public Enumeration getAllExpiredCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ Date now = CMS.getCurrentDate();
+ String ldapfilter = "(!(" + CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_AFTER + ">=" +
+ DateMapper.dateToDB(now) + "))";
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all expired published certificates.
+ * @param from The starting point of the serial number range.
+ * @param to The ending point of the serial number range.
+ */
+ public Enumeration getExpiredPublishedCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ Date now = CMS.getCurrentDate();
+ String ldapfilter = "(&(";
+
+ if (from != null && from.length() > 0)
+ ldapfilter += CertRecord.ATTR_ID + ">=" + from + ")(";
+ if (to != null && to.length() > 0)
+ ldapfilter += CertRecord.ATTR_ID + "<=" + to + ")(";
+ ldapfilter += "!(" + CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_AFTER + ">=" +
+ //DateMapper.dateToDB(now) + ")))";
+ DateMapper.dateToDB(now) + "))(" +
+ "certMetainfo=" +
+ CertRecord.META_LDAPPUBLISH +
+ ":true))";
+ //e = s.search(getDN(), ldapfilter);
+
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all expired publishedcertificates.
+ */
+ public Enumeration getAllExpiredPublishedCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ Date now = CMS.getCurrentDate();
+ String ldapfilter = "(&";
+
+ ldapfilter += "(!(" + CertRecord.ATTR_X509CERT + "." +
+ CertificateValidity.NOT_AFTER + ">=" +
+ DateMapper.dateToDB(now) + "))";
+ ldapfilter += "(certMetainfo=" +
+ CertRecord.META_LDAPPUBLISH +
+ ":true))";
+
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ public ICertRecordList getInvalidCertsByNotBeforeDate(Date date, int pageSize)
+ throws EBaseException {
+
+ String now = null;
+
+ Date rightNow = CMS.getCurrentDate();
+
+ ICertRecordList list = null;
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String ldapfilter = "(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_INVALID + ")";
+
+ String[] attrs = null;
+
+ if (mConsistencyCheck == false) {
+ attrs = new String[] { "objectclass", CertRecord.ATTR_ID, CertRecord.ATTR_X509CERT};
+ }
+
+ CMS.debug("getInvalidCertificatesByNotBeforeDate filter " + ldapfilter);
+ //e = s.search(getDN(), ldapfilter);
+ CMS.debug("getInvalidCertificatesByNotBeforeDate: about to call findCertRecordsInList");
+
+ list = findCertRecordsInListRawJumpto(ldapfilter, attrs,
+ DateMapper.dateToDB(date), "notBefore", pageSize);
+
+ //e = list.getCertRecords(0, size - 1);
+
+ } finally {
+ // XXX - transaction is not done at this moment
+
+
+ CMS.debug("In getInvalidCertsByNotBeforeDate finally.");
+
+ if (s != null)
+ s.close();
+ }
+ return list;
+
+ }
+
+ public ICertRecordList getValidCertsByNotAfterDate(Date date, int pageSize)
+ throws EBaseException {
+
+ String now = null;
+
+ ICertRecordList list = null;
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String ldapfilter = "(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_VALID + ")";
+
+ String[] attrs = null;
+
+ if (mConsistencyCheck == false) {
+ attrs = new String[] { "objectclass", CertRecord.ATTR_ID, CertRecord.ATTR_X509CERT};
+ }
+
+ CMS.debug("getValidCertsByNotAfterDate filter " + ldapfilter);
+ //e = s.search(getDN(), ldapfilter);
+ list = findCertRecordsInListRawJumpto(ldapfilter, attrs, DateMapper.dateToDB(date), "notAfter", pageSize);
+
+ } finally {
+ // XXX - transaction is not done at this moment
+
+ if (s != null)
+ s.close();
+ }
+ return list;
+ }
+
+ public ICertRecordList getRevokedCertsByNotAfterDate(Date date, int pageSize)
+ throws EBaseException {
+
+ ICertRecordList list = null;
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String ldapfilter = "(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED + ")";
+
+ String[] attrs = null;
+
+ if (mConsistencyCheck == false) {
+ attrs = new String[] { "objectclass", CertRecord.ATTR_REVOKED_ON, CertRecord.ATTR_ID,
+ CertRecord.ATTR_REVO_INFO, CertificateValidity.NOT_AFTER, CertRecord.ATTR_X509CERT};
+ }
+
+ CMS.debug("getRevokedCertificatesByNotAfterDate filter " + ldapfilter);
+ //e = s.search(getDN(), ldapfilter);
+ CMS.debug("getRevokedCertificatesByNotAfterDate: about to call findCertRecordsInList");
+
+ list = findCertRecordsInListRawJumpto(ldapfilter, attrs,
+ DateMapper.dateToDB(date), "notafter", pageSize);
+
+ } finally {
+ // XXX - transaction is not done at this moment
+
+
+ if (s != null)
+ s.close();
+ }
+ return list;
+
+ }
+
+ /**
+ * Retrieves all revoked certificates in the serial number range.
+ * @param from The starting point of the serial number range.
+ * @param to The ending point of the serial number range.
+ */
+ public Enumeration getRevokedCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ String ldapfilter = "(&(" + CertRecord.ATTR_REVO_INFO + "=*)";
+
+ if (from != null && from.length() > 0)
+ ldapfilter += "(" + CertRecord.ATTR_ID + ">=" + from + ")";
+ if (to != null && to.length() > 0)
+ ldapfilter += "(" + CertRecord.ATTR_ID + "<=" + to + ")";
+ ldapfilter += ")";
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all revoked certificates including ones already expired or
+ * not yet valid.
+ */
+ public Enumeration getAllRevokedCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+ String ldapfilter = "(|(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED + ")(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED_EXPIRED + "))"; // index is setup for this filter
+
+ try {
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrieves all revoked publishedcertificates in the serial number range.
+ * @param from The starting point of the serial number range.
+ * @param to The ending point of the serial number range.
+ */
+ public Enumeration getRevokedPublishedCertificates(String from, String to)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ String ldapfilter = "(&(" + CertRecord.ATTR_REVO_INFO + "=*)";
+
+ if (from != null && from.length() > 0)
+ ldapfilter += "(" + CertRecord.ATTR_ID + ">=" + from + ")";
+ if (to != null && to.length() > 0)
+ ldapfilter += "(" + CertRecord.ATTR_ID + "<=" + to + ")";
+ //ldapfilter += ")";
+ ldapfilter += "(certMetainfo=" +
+ CertRecord.META_LDAPPUBLISH +
+ ":true))";
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all revoked published certificates including ones
+ * already expired or not yet valid.
+ */
+ public Enumeration getAllRevokedPublishedCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+ String ldapfilter = "(&(|(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED + ")(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED_EXPIRED + "))"; // index is setup for this filter
+
+ ldapfilter += "(certMetainfo=" +
+ CertRecord.META_LDAPPUBLISH +
+ ":true))";
+ try {
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrieves all revoked certificates that have not expired.
+ */
+ public Enumeration getRevokedCertificates(Date asOfDate)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+
+ /*e = s.search(getDN(), "(&(" +
+ CertRecord.ATTR_REVO_INFO + "=*)(" + CertRecord.ATTR_X509CERT +
+ "." + CertificateValidity.NOT_AFTER + " >= " +
+ DateMapper.dateToDB(asOfDate) + "))");*/
+ String ldapfilter = "(&(" +
+ CertRecord.ATTR_REVO_INFO + "=*)(" + CertRecord.ATTR_X509CERT +
+ "." + CertificateValidity.NOT_AFTER + " >= " +
+ DateMapper.dateToDB(asOfDate) + "))";
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ // XXX - transaction is not done at this moment
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrives all revoked certificates excluing ones already expired.
+ */
+ public Enumeration getAllRevokedNonExpiredCertificates()
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+ String ldapfilter = "(" + CertRecord.ATTR_CERT_STATUS + "=" + CertRecord.STATUS_REVOKED + ")"; // index is setup for this filter
+
+ try {
+ //e = s.search(getDN(), ldapfilter);
+ ICertRecordList list = null;
+
+ list = findCertRecordsInList(ldapfilter, null, "serialno", 10);
+ int size = list.getSize();
+
+ e = list.getCertRecords(0, size - 1);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ private LDAPSearchResults startSearchForModifiedCertificateRecords()
+ throws EBaseException {
+ CMS.debug("startSearchForModifiedCertificateRecords");
+ LDAPSearchResults r = null;
+ IDBSSession s = mDBService.createSession();
+
+ String filter = "(" + CertRecord.ATTR_CERT_STATUS + "=*)";
+ try {
+ r = s.persistentSearch(getDN(), filter, null);
+ CMS.debug("startSearchForModifiedCertificateRecords persistentSearch started");
+ } catch (Exception e) {
+ CMS.debug("startSearchForModifiedCertificateRecords persistentSearch Exception="+e);
+ r = null;
+ if (s != null)
+ s.close();
+ }
+ return r;
+ }
+
+ public void getModifications(LDAPEntry entry) {
+ if (entry != null) {
+ CMS.debug("getModifications entry DN="+entry.getDN());
+
+ LDAPAttributeSet entryAttrs = entry.getAttributeSet();
+ ICertRecord certRec = null;
+ try {
+ certRec = (ICertRecord)mDBService.getRegistry().createObject(entryAttrs);
+ } catch (Exception e) {
+ }
+ if (certRec != null) {
+ String status = certRec.getStatus();
+ CMS.debug("getModifications serialNumber="+certRec.getSerialNumber()+
+ " status="+status);
+ if (status != null && (status.equals(ICertRecord.STATUS_VALID) ||
+ status.equals(ICertRecord.STATUS_REVOKED))) {
+
+ Enumeration eIPs = mCRLIssuingPoints.elements();
+
+ while (eIPs.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) eIPs.nextElement();
+
+ if (ip != null) {
+ if (status.equals(ICertRecord.STATUS_REVOKED)) {
+ IRevocationInfo rInfo = certRec.getRevocationInfo();
+ if (rInfo != null) {
+ ip.addRevokedCert(certRec.getSerialNumber(),
+ new RevokedCertImpl(certRec.getSerialNumber(),
+ rInfo.getRevocationDate(),
+ rInfo.getCRLEntryExtensions()));
+ }
+ } else {
+ ip.addUnrevokedCert(certRec.getSerialNumber());
+ }
+ }
+ }
+
+ }
+ }
+ } else {
+ CMS.debug("getModifications entry == null");
+ }
+ }
+
+
+ /**
+ * Checks if the presented certificate belongs to the repository
+ * and is revoked.
+ *
+ * @param cert certificate to verify.
+ * @return RevocationInfo if the presented certificate is revoked otherwise null.
+ */
+ public RevocationInfo isCertificateRevoked(X509CertImpl cert)
+ throws EBaseException {
+ RevocationInfo info = null;
+
+ // 615932
+ if (cert == null)
+ return null;
+
+ ICertRecord rec = readCertificateRecord(cert.getSerialNumber());
+
+ if (rec != null) {
+ if (rec.getStatus().equals(ICertRecord.STATUS_REVOKED)) {
+ X500Name name = (X500Name) cert.getSubjectDN();
+ X500Name repCertName = (X500Name) rec.getCertificate().getSubjectDN();
+
+ if (name.equals(repCertName)) {
+ byte[] certEncoded = null;
+ byte[] repCertEncoded = null;
+
+ try {
+ certEncoded = cert.getEncoded();
+ repCertEncoded = rec.getCertificate().getEncoded();
+ } catch (Exception e) {
+ }
+
+ if (certEncoded != null &&
+ repCertEncoded != null &&
+ certEncoded.length == repCertEncoded.length) {
+ int i;
+
+ for (i = 0; i < certEncoded.length; i++) {
+ if (certEncoded[i] != repCertEncoded[i])
+ break;
+ }
+ if (i >= certEncoded.length) {
+ info = (RevocationInfo) ((CertRecord) rec).getRevocationInfo();
+ }
+ }
+ }
+ }
+ }
+
+ return info;
+ }
+
+ public void shutdown() {
+ if (mCertStatusUpdateThread != null)
+ mCertStatusUpdateThread.destroy();
+
+ if (mRetrieveModificationsThread != null)
+ mRetrieveModificationsThread.destroy();
+ }
+}
+
+
+class CertStatusUpdateThread extends Thread {
+ CertificateRepository _cr = null;
+ IRepository _rr = null;
+ int _interval;
+
+ CertStatusUpdateThread(CertificateRepository cr, IRepository rr, String name) {
+ super(name);
+ CMS.debug("new CertStatusUpdateThread");
+ //setName(name);
+
+ _cr = cr;
+ _rr = rr;
+ }
+
+ public void setInterval(int interval) {
+ _interval = interval;
+ }
+
+ public void run() {
+ CMS.debug("Inside run method of CertStatusUpdateThread");
+
+ while (true) {
+ try {
+ // block the update while another thread
+ // (such as the CRL Update) is running
+ CMS.debug("About to start updateCertStatus");
+ synchronized (_cr.mCertStatusUpdateThread) {
+ CMS.debug("Starting updateCertStatus (entered lock)");
+ _cr.updateCertStatus();
+ CMS.debug("updateCertStatus done");
+
+ CMS.debug("Starting cert checkRanges");
+ _cr.checkRanges();
+ CMS.debug("cert checkRanges done");
+
+ CMS.debug("Starting request checkRanges");
+ _rr.checkRanges();
+ CMS.debug("request checkRanges done");
+ }
+
+ } catch (Exception e) {
+ CMS.debug("updateCertStatus done: " + e.toString());
+ }
+ try {
+ sleep(_interval * 1000);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+}
+
+
+class RetrieveModificationsThread extends Thread {
+ CertificateRepository _cr = null;
+ LDAPSearchResults _results = null;
+
+ RetrieveModificationsThread(CertificateRepository cr, String name) {
+ super(name);
+ CMS.debug("new RetrieveModificationsThread");
+ //setName(name);
+
+ _cr = cr;
+ }
+
+ public void setResults(LDAPSearchResults results) {
+ _results = results;
+ }
+
+ public void run() {
+ CMS.debug("Inside run method of RetrieveModificationsThread");
+
+ if (_results != null) {
+ try {
+ while (_results.hasMoreElements()) {
+ LDAPEntry entry = _results.next();
+ _cr.getModifications(entry);
+ }
+ } catch (LDAPException e) {
+ CMS.debug("LDAPException: "+e.toString());
+ }
+ } else {
+ CMS.debug("_results are null");
+ }
+ CMS.debug("Done with run method of RetrieveModificationsThread");
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DBRegistry.java b/pki/base/common/src/com/netscape/cmscore/dbs/DBRegistry.java
new file mode 100644
index 000000000..660e385fe
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DBRegistry.java
@@ -0,0 +1,553 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents a registry where all the
+ * schema (object classes and attribute) information
+ * is stored.
+ *
+ * Attribute mappers can be registered with this
+ * registry.
+ *
+ * Given the schema information stored, this registry
+ * has knowledge to convert a Java object into a
+ * LDAPAttributeSet or vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class DBRegistry implements IDBRegistry, ISubsystem {
+
+ private IConfigStore mConfig = null;
+ private Hashtable mOCclassNames = new Hashtable();
+ private Hashtable mOCldapNames = new Hashtable();
+ private Hashtable mAttrufNames = new Hashtable();
+ private IFilterConverter mConverter = null;
+ private Vector mDynAttrMappers = new Vector();
+
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs registry.
+ */
+ public DBRegistry() {
+ }
+
+ /**
+ * Retrieves subsystem identifier.
+ */
+ public String getId() {
+ return "dbsregistry";
+ }
+
+ /**
+ * Sets subsystem identifier. This is an internal
+ * subsystem, and is not loadable.
+ */
+ public void setId(String id) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_OPERATION"));
+ }
+
+ /**
+ * Initializes the internal registery. Connects to the
+ * data source, and create a pool of connection of which
+ * applications can use. Optionally, check the integrity
+ * of the database.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ mConverter = new LdapFilterConverter(mAttrufNames);
+ }
+
+ /**
+ * Retrieves configuration store.
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Starts up this subsystem.
+ */
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * Shutdowns this subsystem gracefully.
+ */
+ public void shutdown() {
+ mOCclassNames.clear();
+ mOCclassNames = null;
+ mOCldapNames.clear();
+ mOCldapNames = null;
+ mAttrufNames.clear();
+ mAttrufNames = null;
+ mConverter = null;
+ }
+
+ /**
+ * Registers object class.
+ */
+ public void registerObjectClass(String className, String ldapNames[])
+ throws EDBException {
+ try {
+ Class c = Class.forName(className);
+
+ mOCclassNames.put(className, ldapNames);
+ mOCldapNames.put(sortAndConcate(
+ ldapNames).toLowerCase(),
+ new NameAndObject(className, c));
+ } catch (ClassNotFoundException e) {
+
+ /*LogDoc
+ *
+ * @phase db startup
+ * @reason failed to register object class
+ * @message DBRegistry: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB,
+ ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_INVALID_CLASS_NAME", className));
+ }
+ }
+
+ /**
+ * See if an object class is registered.
+ */
+ public boolean isObjectClassRegistered(String className) {
+ return mOCclassNames.containsKey(className);
+ }
+
+ /**
+ * Registers attribute mapper.
+ */
+ public void registerAttribute(String ufName, IDBAttrMapper mapper)
+ throws EDBException {
+ // should not allows 'objectclass' as attribute; it has
+ // special meaning
+ mAttrufNames.put(ufName.toLowerCase(), mapper);
+ }
+
+ /**
+ * See if an attribute is registered.
+ */
+ public boolean isAttributeRegistered(String ufName) {
+ return mAttrufNames.containsKey(ufName.toLowerCase());
+ }
+
+ public void registerDynamicMapper(IDBDynAttrMapper mapper) {
+ mDynAttrMappers.add(mapper);
+ }
+
+ /**
+ * Creates LDAP-based search filters with help of
+ * registered mappers.
+ * Parses filter from filter string specified in RFC1558.
+ * <pre>
+ * <filter> ::= '(' <filtercomp> ')'
+ * <filtercomp> ::= <and> | <or> | <not> | <item>
+ * <and> ::= '&' <filterlist>
+ * <or> ::= '|' <filterlist>
+ * <not> ::= '!' <filter>
+ * <filterlist> ::= <filter> | <filter> <filterlist>
+ * <item> ::= <simple> | <present> | <substring>
+ * <simple> ::= <attr> <filtertype> <value>
+ * <filtertype> ::= <equal> | <approx> | <greater> | <less>
+ * <equal> ::= '='
+ * <approx> ::= '~='
+ * <greater> ::= '>='
+ * <less> ::= '<='
+ * <present> ::= <attr> '=*'
+ * <substring> ::= <attr> '=' <initial> <any> <final>
+ * <initial> ::= NULL | <value>
+ * <any> ::= '*' <starval>
+ * <starval> ::= NULL | <value> '*' <starval>
+ * <final> ::= NULL | <value>
+ * </pre>
+ */
+ public String getFilter(String filter) throws EBaseException {
+ return getFilter(filter, mConverter);
+ }
+
+ public String getFilter(String filter, IFilterConverter c)
+ throws EBaseException {
+ String f = filter;
+
+ f = f.trim();
+ if (f.startsWith("(") && f.endsWith(")")) {
+ return "(" + getFilterComp(f.substring(1,
+ f.length() - 1), c) + ")";
+ } else {
+ return getFilterComp(filter, c);
+ }
+ }
+
+ private String getFilterComp(String f, IFilterConverter c)
+ throws EBaseException {
+ f = f.trim();
+ if (f.startsWith("&")) { // AND operation
+ return "&" + getFilterList(f.substring(1,
+ f.length()), c);
+ } else if (f.startsWith("|")) { // OR operation
+ return "|" + getFilterList(f.substring(1,
+ f.length()), c);
+ } else if (f.startsWith("!")) { // NOT operation
+ return "!" + getFilter(f.substring(1, f.length()), c);
+ } else { // item
+ return getFilterItem(f, c);
+ }
+ }
+
+ private String getFilterList(String f, IFilterConverter c)
+ throws EBaseException {
+ f = f.trim();
+ int level = 0;
+ int start = 0;
+ int end = 0;
+ Vector v = new Vector();
+
+ for (int i = 0; i < f.length(); i++) {
+ if (f.charAt(i) == '(') {
+ if (level == 0) {
+ start = i;
+ }
+ level++;
+ }
+ if (f.charAt(i) == ')') {
+ level--;
+ if (level == 0) {
+ end = i;
+ String filter = getFilter(f.substring(start, end + 1), c);
+
+ v.addElement(filter);
+ }
+ }
+ }
+ String result = "";
+
+ for (int i = 0; i < v.size(); i++) {
+ result += (String) v.elementAt(i);
+ }
+ return result;
+ }
+
+ /**
+ * So, here we need to separate item into name, op, value.
+ */
+ private String getFilterItem(String f, IFilterConverter c)
+ throws EBaseException {
+ f = f.trim();
+ int idx = f.indexOf('=');
+
+ if (idx == -1) {
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_INVALID_FILTER_ITEM", "="));
+ }
+
+ String type = f.substring(0, idx).trim();
+ String value = f.substring(idx + 1).trim(); // skip '='
+
+ // make decision by looking at the type
+ type = type.trim();
+ if (type.endsWith("~")) {
+ // approximate match
+ String name = type.substring(0, type.length() - 1).trim();
+
+ return c.convert(name, "~=", value);
+ } else if (type.endsWith("!")) {
+ String name = type.substring(0, type.length() - 1).trim();
+
+ return c.convert(name, "!=", value);
+ } else if (type.endsWith(">")) {
+ // greater than
+ String name = type.substring(0, type.length() - 1).trim();
+
+ return c.convert(name, ">=", value);
+ } else if (type.endsWith("<")) {
+ String name = type.substring(0, type.length() - 1).trim();
+
+ return c.convert(name, "<=", value);
+ }
+
+ // for those that are not simple
+ if (value.startsWith("*") && value.length() == 1) {
+ return c.convert(type, "=", "*");
+ }
+
+ // if value contains no '*', then it is equality
+ if (value.indexOf('*') == -1) {
+ if (type.equals("objectclass")) {
+ String ldapNames[] = (String[])
+ mOCclassNames.get(value);
+
+ if (ldapNames == null)
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_INVALID_FILTER_ITEM", f));
+ String filter = "";
+
+ for (int g = 0; g < ldapNames.length; g++) {
+ filter += "(objectclass=" +
+ ldapNames[g] + ")";
+ }
+ return "&" + filter;
+ } else {
+ return c.convert(type, "=", value);
+ }
+ }
+ // XXX - does not support substring!!
+ return c.convert(type, "=", value);
+ }
+
+ /**
+ * Maps object into LDAP attribute set.
+ */
+ public void mapObject(IDBObj parent, String name, Object obj,
+ LDAPAttributeSet attrs) throws EBaseException {
+ IDBAttrMapper mapper = (IDBAttrMapper) mAttrufNames.get(
+ name.toLowerCase());
+
+ if (mapper == null) {
+ return; // no mapper found, just skip this attribute
+ }
+ mapper.mapObjectToLDAPAttributeSet(parent, name, obj, attrs);
+ }
+
+ /**
+ * Retrieves a list of LDAP attributes that are associated
+ * with the given attributes.
+ * This method is used for searches, to map the database attributes
+ * to LDAP attributes.
+ */
+ public String[] getLDAPAttributes(String attrs[])
+ throws EBaseException {
+ IDBAttrMapper mapper;
+
+ if (attrs == null)
+ return null;
+ Vector v = new Vector();
+
+ for (int i = 0; i < attrs.length; i++) {
+
+ if (attrs[i].equals("objectclass")) {
+ v.addElement("objectclass");
+ continue;
+ }
+
+ if (isAttributeRegistered(attrs[i])) {
+ mapper = (IDBAttrMapper)
+ mAttrufNames.get(attrs[i].toLowerCase());
+ if (mapper == null) {
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_INVALID_ATTRS"));
+ }
+ Enumeration e = mapper.getSupportedLDAPAttributeNames();
+
+ while (e.hasMoreElements()) {
+ String s = (String) e.nextElement();
+
+ if (!v.contains(s)) {
+ v.addElement(s);
+ }
+ }
+ } else {
+ IDBDynAttrMapper matchingDynAttrMapper = null;
+ // check if a dynamic mapper can handle the attribute
+ for (Iterator dynMapperIter = mDynAttrMappers.iterator();
+ dynMapperIter.hasNext();) {
+ IDBDynAttrMapper dynAttrMapper =
+ (IDBDynAttrMapper)dynMapperIter.next();
+ if (dynAttrMapper.supportsLDAPAttributeName(attrs[i])) {
+ matchingDynAttrMapper = dynAttrMapper;
+ break;
+ }
+ }
+ if (matchingDynAttrMapper != null) {
+ v.addElement(attrs[i]);
+ } else {
+ /*LogDoc
+ *
+ * @phase retrieve ldap attr
+ * @reason failed to get registered object class
+ * @message DBRegistry: <attr> is not registered
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB,
+ ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_DBS_ATTR_NOT_REGISTER", attrs[i]));
+ throw new EDBException(CMS.getLogMessage("CMSCORE_DBS_ATTR_NOT_REGISTER", attrs[i]));
+ }
+ }
+
+ }
+ if (v.size() == 0)
+ return null;
+ String ldapAttrs[] = new String[v.size()];
+
+ v.copyInto(ldapAttrs);
+ return ldapAttrs;
+ }
+
+ /**
+ * Creates attribute set from object.
+ */
+ public LDAPAttributeSet createLDAPAttributeSet(IDBObj obj)
+ throws EBaseException {
+ Enumeration e = obj.getSerializableAttrNames();
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+
+ // add object class to attribute set
+ String className = ((Object) obj).getClass().getName();
+ String vals[] = (String[]) mOCclassNames.get(className);
+
+ attrs.add(new LDAPAttribute("objectclass", vals));
+
+ // give every attribute a chance to put stuff in attr set
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+
+ if (obj.get(name) != null) {
+ mapObject(obj, name, obj.get(name), attrs);
+ }
+ }
+ return attrs;
+ }
+
+ /**
+ * Creates object from attribute set.
+ */
+ public IDBObj createObject(LDAPAttributeSet attrs)
+ throws EBaseException {
+ // map object class attribute to object
+ LDAPAttribute attr = attrs.getAttribute("objectclass");
+
+ //CMS.debug("createObject: attrs " + attrs.toString());
+
+ attrs.remove("objectclass");
+
+ // sort the object class values
+ Enumeration vals = attr.getStringValues();
+ Vector v = new Vector();
+
+ while (vals.hasMoreElements()) {
+ v.addElement(vals.nextElement());
+ }
+ String s[] = new String[v.size()];
+
+ v.copyInto(s);
+ String sorted = sortAndConcate(s).toLowerCase();
+ NameAndObject no = (NameAndObject) mOCldapNames.get(sorted);
+
+ if (no == null) {
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_INVALID_CLASS_NAME", sorted));
+ }
+ Class c = (Class) no.getObject();
+
+ try {
+ IDBObj obj = (IDBObj) c.newInstance();
+ Enumeration ee = obj.getSerializableAttrNames();
+
+ while (ee.hasMoreElements()) {
+ String oname = (String) ee.nextElement();
+ IDBAttrMapper mapper = (IDBAttrMapper)
+ mAttrufNames.get(
+ oname.toLowerCase());
+
+ if (mapper == null) {
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_NO_MAPPER_FOUND", oname));
+ }
+ mapper.mapLDAPAttributeSetToObject(attrs,
+ oname, obj);
+ }
+ return obj;
+ } catch (Exception e) {
+
+ /*LogDoc
+ *
+ * @phase create ldap attr
+ * @reason failed to create object class
+ * @message DBRegistry: <attr> is not registered
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB,
+ ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_INVALID_ATTRS"));
+ }
+ }
+
+ /**
+ * Sorts and concate given strings.
+ */
+ private String sortAndConcate(String s[]) {
+ Vector v = new Vector();
+
+ // sort it first
+ for (int i = 0; i < s.length; i++) {
+ for (int j = 0; j < v.size(); j++) {
+ String t = (String) v.elementAt(j);
+
+ if (s[i].compareTo(t) < 0) {
+ v.insertElementAt(s[i], j);
+ break;
+ }
+ }
+ if (i != (v.size() - 1))
+ v.addElement(s[i]);
+ }
+
+ // concate them
+ String result = "";
+
+ for (int i = 0; i < v.size(); i++) {
+ result += ((String) v.elementAt(i) + "+");
+ }
+ return result;
+ }
+}
+
+
+/**
+ * Just a convenient container class.
+ */
+class NameAndObject {
+
+ private String mN = null;
+ private Object mO = null;
+
+ public NameAndObject(String name, Object o) {
+ mN = name;
+ mO = o;
+ }
+
+ public String getName() {
+ return mN;
+ }
+
+ public Object getObject() {
+ return mO;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DBSSession.java b/pki/base/common/src/com/netscape/cmscore/dbs/DBSSession.java
new file mode 100644
index 000000000..03c86a219
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DBSSession.java
@@ -0,0 +1,447 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import netscape.ldap.controls.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents the database session. Operations
+ * can be performed with a session.
+ *
+ * Transaction and Caching support can be integrated
+ * into session.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class DBSSession implements IDBSSession {
+
+ private IDBSubsystem mDBSystem = null;
+ private LDAPConnection mConn = null;
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs a database session.
+ *
+ * @param system the database subsytem
+ * @param c the ldap connection
+ */
+ public DBSSession(IDBSubsystem system, LDAPConnection c) {
+ mDBSystem = system;
+ mConn = c;
+ try {
+ // no limit
+ mConn.setOption(LDAPv2.SIZELIMIT, Integer.valueOf(0));
+ } catch (LDAPException e) {
+ }
+ }
+
+ /**
+ * Returns database subsystem.
+ */
+ public ISubsystem getDBSubsystem() {
+ return mDBSystem;
+ }
+
+ /**
+ * Closes this session.
+ */
+ public void close() throws EDBException {
+ // return ldap connection.
+ mDBSystem.returnConn(mConn);
+ }
+
+ /**
+ * Adds object to backend database. For example,
+ * <PRE>
+ * session.add("cn=123459,o=certificate repository,o=airius.com",
+ * certRec);
+ * </PRE>
+ *
+ * @param name the name of the ldap entry
+ * @param obj the DBobj that can be mapped to ldap attrubute set
+ */
+ public void add(String name, IDBObj obj) throws EBaseException {
+ try {
+ LDAPAttributeSet attrs = mDBSystem.getRegistry(
+ ).createLDAPAttributeSet(obj);
+ LDAPEntry e = new LDAPEntry(name, attrs);
+
+ /*LogDoc
+ *
+ * @phase local ldap add
+ * @message DBSSession: begin LDAP add <entry>
+ */
+ mConn.add(e);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ name + " " + e.toString()));
+ }
+ }
+
+ /**
+ * Reads an object from the database.
+ * all attributes will be returned
+ *
+ * @param name the name of the ldap entry
+ */
+ public IDBObj read(String name) throws EBaseException {
+ return read(name, null);
+ }
+
+ /**
+ * Reads an object from the database, and only populates
+ * the selected attributes.
+ *
+ * @param name the name of the ldap entry
+ * @param attrs the attributes to be selected
+ */
+ public IDBObj read(String name, String attrs[])
+ throws EBaseException {
+ try {
+ String ldapattrs[] = null;
+
+ if (attrs != null) {
+ ldapattrs = mDBSystem.getRegistry(
+ ).getLDAPAttributes(attrs);
+ }
+
+ /*LogDoc
+ *
+ * @phase local ldap read
+ * @message DBSSession: begin LDAP read <entry>
+ */
+ LDAPSearchResults res = mConn.search(name,
+ LDAPv2.SCOPE_BASE, "(objectclass=*)",
+ ldapattrs, false);
+ LDAPEntry entry = (LDAPEntry) res.nextElement();
+
+ return mDBSystem.getRegistry().createObject(
+ entry.getAttributeSet());
+ } catch (LDAPException e) {
+
+ /*LogDoc
+ *
+ * @phase local ldap read
+ * @message DBSSession: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_INFO, "DBSSession: " + e.toString());
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ if (e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT)
+ throw new EDBRecordNotFoundException(
+ CMS.getUserMessage("CMS_DBS_RECORD_NOT_FOUND"));
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ name + " " + e.toString()));
+ }
+ }
+
+ /**
+ * Deletes object from database.
+ */
+ public void delete(String name) throws EBaseException {
+ try {
+ mConn.delete(name);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ name + " " + e.toString()));
+ }
+ }
+
+ /**
+ * Modify an object in the database.
+ */
+ public void modify(String name, ModificationSet mods)
+ throws EBaseException {
+ try {
+ LDAPModificationSet ldapMods = new
+ LDAPModificationSet();
+ Enumeration e = mods.getModifications();
+
+ while (e.hasMoreElements()) {
+ Modification mod = (Modification)
+ e.nextElement();
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+
+ mDBSystem.getRegistry().mapObject(null,
+ mod.getName(), mod.getValue(), attrs);
+ Enumeration e0 = attrs.getAttributes();
+
+ while (e0.hasMoreElements()) {
+ ldapMods.add(toLdapModOp(mod.getOp()),
+ (LDAPAttribute)
+ e0.nextElement());
+ }
+ }
+
+ /*LogDoc
+ *
+ * @phase local ldap add
+ * @message DBSSession: begin LDAP modify <entry>
+ */
+ mConn.modify(name, ldapMods);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ name + " " + e.toString()));
+ }
+ }
+
+ private int toLdapModOp(int modOp) throws EBaseException {
+ switch (modOp) {
+ case Modification.MOD_ADD:
+ return LDAPModification.ADD;
+
+ case Modification.MOD_DELETE:
+ return LDAPModification.DELETE;
+
+ case Modification.MOD_REPLACE:
+ return LDAPModification.REPLACE;
+ }
+ throw new EBaseException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ Integer.toString(modOp)));
+ }
+
+ /**
+ * Searchs for a list of objects that match the
+ * filter.
+ */
+ public IDBSearchResults search(String base, String filter)
+ throws EBaseException {
+ return search(base, filter, null);
+ }
+
+ public IDBSearchResults search(String base, String filter, int maxSize)
+ throws EBaseException {
+ try {
+ String ldapattrs[] = null;
+ String ldapfilter =
+ mDBSystem.getRegistry().getFilter(filter);
+
+ LDAPSearchConstraints cons = new LDAPSearchConstraints();
+
+ cons.setMaxResults(maxSize);
+
+ LDAPSearchResults res = mConn.search(base,
+ LDAPv2.SCOPE_ONE, ldapfilter, ldapattrs, false, cons);
+
+ return new DBSearchResults(mDBSystem.getRegistry(),
+ res);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ // XXX error handling, should not raise exception if
+ // entry not found
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ e.toString()));
+ }
+ }
+
+ public IDBSearchResults search(String base, String filter, int maxSize, int timeLimit)
+ throws EBaseException {
+ try {
+ String ldapattrs[] = null;
+ String ldapfilter =
+ mDBSystem.getRegistry().getFilter(filter);
+
+ LDAPSearchConstraints cons = new LDAPSearchConstraints();
+
+ cons.setMaxResults(maxSize);
+ cons.setServerTimeLimit(timeLimit);
+
+ LDAPSearchResults res = mConn.search(base,
+ LDAPv2.SCOPE_ONE, ldapfilter, ldapattrs, false, cons);
+
+ return new DBSearchResults(mDBSystem.getRegistry(),
+ res);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ // XXX error handling, should not raise exception if
+ // entry not found
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ e.toString()));
+ }
+ }
+
+ /**
+ * Retrieves a list of object that satifies the given
+ * filter.
+ */
+ public IDBSearchResults search(String base, String filter,
+ String attrs[]) throws EBaseException {
+ try {
+ String ldapattrs[] = null;
+
+ if (attrs != null) {
+ ldapattrs = mDBSystem.getRegistry(
+ ).getLDAPAttributes(attrs);
+ }
+ String ldapfilter =
+ mDBSystem.getRegistry().getFilter(filter);
+
+ /*LogDoc
+ *
+ * @phase local ldap add
+ * @message DBSSession: begin LDAP search <filter>
+ */
+ LDAPSearchConstraints cons = new LDAPSearchConstraints();
+
+ cons.setMaxResults(0);
+
+ LDAPSearchResults res = mConn.search(base,
+ LDAPv2.SCOPE_ONE, ldapfilter, ldapattrs, false, cons);
+
+ return new DBSearchResults(mDBSystem.getRegistry(),
+ res);
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ // XXX error handling, should not raise exception if
+ // entry not found
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ e.toString()));
+ }
+ }
+
+ public LDAPSearchResults persistentSearch(String base, String filter, String attrs[])
+ throws EBaseException {
+ try {
+ String ldapattrs[] = null;
+ if (attrs != null) {
+ ldapattrs = mDBSystem.getRegistry(
+ ).getLDAPAttributes(attrs);
+ }
+ String ldapfilter =
+ mDBSystem.getRegistry().getFilter(filter);
+
+ Integer version = (Integer)(mConn.getOption(LDAPv2.PROTOCOL_VERSION));
+
+ // Only version 3 protocol supports persistent search.
+ if (version.intValue() == 2) {
+ mConn.setOption(LDAPv2.PROTOCOL_VERSION, Integer.valueOf(3));
+ }
+
+ int op = LDAPPersistSearchControl.MODIFY;
+
+ boolean changesOnly = true;
+ boolean returnControls = true;
+ boolean isCritical = true;
+ LDAPPersistSearchControl persistCtrl = new
+ LDAPPersistSearchControl( op, changesOnly,
+ returnControls, isCritical );
+
+ LDAPSearchConstraints cons = new LDAPSearchConstraints();
+ cons.setBatchSize(0);
+ cons.setServerControls( persistCtrl );
+
+ LDAPSearchResults res = mConn.search(base,
+ LDAPv2.SCOPE_ONE, ldapfilter, ldapattrs, false, cons);
+ return res;
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE)
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ // XXX error handling, should not raise exception if
+ // entry not found
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LDAP_OP_FAILURE",
+ e.toString()));
+ }
+ }
+
+ /**
+ * Retrieves a list of objects.
+ */
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[]) throws EBaseException {
+ return new DBVirtualList(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs);
+ }
+
+ /**
+ * Retrieves a list of objects.
+ */
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[], String sortKey[]) throws EBaseException {
+ return new DBVirtualList(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs, sortKey);
+ }
+
+ /**
+ * Retrieves a list of objects.
+ */
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[], String sortKey) throws EBaseException {
+ return new DBVirtualList(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs, sortKey);
+ }
+
+ /**
+ * Retrieves a list of objects.
+ */
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[], String sortKey[], int pageSize) throws EBaseException {
+ return new DBVirtualList(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs, sortKey, pageSize);
+ }
+
+ /**
+ * Retrieves a list of objects.
+ */
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[], String sortKey, int pageSize) throws EBaseException {
+ return new DBVirtualList(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs, sortKey, pageSize);
+ }
+
+ public IDBVirtualList createVirtualList(String base, String filter,
+ String attrs[], String startFrom, String sortKey, int pageSize) throws EBaseException {
+ return new DBVirtualList(mDBSystem.getRegistry(), mConn, base,
+ filter, attrs, startFrom, sortKey, pageSize);
+
+ }
+
+ /**
+ * Releases object to this interface. This allows us to
+ * use memory more efficiently.
+ */
+ public void release(Object obj) {
+ // not implemented
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DBSUtil.java b/pki/base/common/src/com/netscape/cmscore/dbs/DBSUtil.java
new file mode 100644
index 000000000..475a77dcb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DBSUtil.java
@@ -0,0 +1,56 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.math.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java BigInteger object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class DBSUtil {
+
+ public static String longToDB(long val) {
+ String s = Long.toString(val);
+ // prefix with 2 digits that represents
+ // the length of the value
+ int l = s.length();
+ String dbVal = "";
+
+ if (s.length() < 10) {
+ dbVal = "0";
+ }
+ return dbVal + Integer.toString(l) + s;
+ }
+
+ public static long longFromDB(String dbLong) {
+ // remove the first 2 digits
+ String s = dbLong.substring(2);
+
+ return Long.parseLong(s);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DBSearchResults.java b/pki/base/common/src/com/netscape/cmscore/dbs/DBSearchResults.java
new file mode 100644
index 000000000..b7f6cd616
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DBSearchResults.java
@@ -0,0 +1,92 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents the search results. A search
+ * results object contain a enumeration of
+ * Java objects that are just read from the database.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class DBSearchResults implements IDBSearchResults {
+
+ private IDBRegistry mRegistry = null;
+ private Enumeration mRes = null;
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs search results.
+ */
+ public DBSearchResults(IDBRegistry registry, Enumeration res) {
+ mRegistry = registry;
+ mRes = res;
+ }
+
+ /**
+ * Checks if any element is available.
+ */
+ public boolean hasMoreElements() {
+ return mRes.hasMoreElements();
+ }
+
+ /**
+ * Retrieves next element.
+ */
+ public Object nextElement() {
+ LDAPEntry entry = null;
+
+ try {
+ Object o = mRes.nextElement();
+
+ if (o instanceof LDAPEntry) {
+ entry = (LDAPEntry) o;
+ return mRegistry.createObject(entry.getAttributeSet());
+ } else {
+ if (o instanceof LDAPException)
+ ;
+ // doing nothing because the last object in the search
+ // results is always LDAPException
+ else
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB,
+ ILogger.LL_FAILURE, "DBSearchResults: result format error class=" + o.getClass().getName());
+ }
+ } catch (Exception e) {
+
+ /*LogDoc
+ *
+ * @phase local ldap search
+ * @reason failed to get next element
+ * @message DBSearchResults: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB,
+ ILogger.LL_FAILURE, "DBSearchResults: " + e.toString());
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java b/pki/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java
new file mode 100644
index 000000000..797dd8324
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java
@@ -0,0 +1,951 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import netscape.ldap.*;
+import netscape.ldap.util.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmscore.base.*;
+import com.netscape.cmscore.ldapconn.*;
+import com.netscape.cmscore.cert.*;
+
+
+/**
+ * A class represents the database subsystem that manages
+ * the backend data storage.
+ *
+ * This subsystem maintains multiple sessions that allows
+ * operations to be performed, and provide a registry
+ * where all the schema information is stored.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class DBSubsystem implements IDBSubsystem {
+
+ public static String ID = IDBSubsystem.SUB_ID;
+
+ private IConfigStore mConfig = null;
+ private IConfigStore mDBConfig = null;
+ private LdapBoundConnFactory mLdapConnFactory = null;
+ private DBRegistry mRegistry = null;
+ private String mBaseDN = null;
+ private ISubsystem mOwner = null;
+
+ private Hashtable[] mRepos = null;
+
+ private BigInteger mNextSerialConfig = null;
+ private boolean mEnableSerialMgmt = false;
+
+ private static final String PEOPLE_DN = "ou=people";
+ private static final String GROUPS_DN = "ou=groups";
+ private static final String REQUESTS_DN = "ou=requests";
+ private static final String XCERTS_DN = "cn=crossCerts";
+ private static final String BASEDN = "o=netscapeCertificateServer";
+ private static final String DEFAULT_DATABASE = "userRoot";
+ private static final String AT_OC = "objectclass";
+ private static final String AT_O = "o";
+ private static final String AT_OU = "ou";
+ private static final String CA_DN = "ou=ca";
+ private static final String CR_DN = "ou=certificateRepository, ou=ca";
+ private static final String CRL_DN = "ou=crlIssuingPoints, ou=ca";
+ private static final String CA_REQUESTS_DN = "ou=ca, ou=requests";
+ private static final String KRA_DN = "ou=kra";
+ private static final String KR_DN = "ou=keyRepository, ou=kra";
+ private static final String KRA_REQUESTS_DN = "ou=kra, ou=requests";
+ private static final String REPLICA_DN = "ou=replica";
+ private static final String PROP_ENABLE_SERIAL_NUMBER_RECOVERY =
+ "enableSerialNumberRecovery";
+ // This value is only equal to the next Serial number that the CA's
+ // going to issue when cms just start up or it's just set from console.
+ // It doesn't record the next serial number at other time when cms's
+ // runing not to increase overhead when issuing certs.
+ private static final String PROP_NEXT_SERIAL_NUMBER =
+ "nextSerialNumber";
+ private static final String PROP_MIN_SERIAL_NUMBER="beginSerialNumber";
+ private static final String PROP_MAX_SERIAL_NUMBER = "endSerialNumber";
+ private static final String PROP_NEXT_MIN_SERIAL_NUMBER="nextBeginSerialNumber";
+ private static final String PROP_NEXT_MAX_SERIAL_NUMBER ="nextEndSerialNumber";
+ private static final String PROP_SERIAL_LOW_WATER_MARK="serialLowWaterMark";
+ private static final String PROP_SERIAL_INCREMENT="serialIncrement";
+ private static final String PROP_SERIAL_BASEDN="serialDN";
+ private static final String PROP_SERIAL_RANGE_DN="serialRangeDN";
+
+ private static final String PROP_MIN_REQUEST_NUMBER="beginRequestNumber";
+ private static final String PROP_MAX_REQUEST_NUMBER="endRequestNumber";
+ private static final String PROP_NEXT_MIN_REQUEST_NUMBER="nextBeginRequestNumber";
+ private static final String PROP_NEXT_MAX_REQUEST_NUMBER="nextEndRequestNumber";
+ private static final String PROP_REQUEST_LOW_WATER_MARK="requestLowWaterMark";
+ private static final String PROP_REQUEST_INCREMENT="requestIncrement";
+ private static final String PROP_REQUEST_BASEDN="requestDN";
+ private static final String PROP_REQUEST_RANGE_DN="requestRangeDN";
+
+ private static final String PROP_MIN_REPLICA_NUMBER="beginReplicaNumber";
+ private static final String PROP_MAX_REPLICA_NUMBER = "endReplicaNumber";
+ private static final String PROP_NEXT_MIN_REPLICA_NUMBER="nextBeginReplicaNumber";
+ private static final String PROP_NEXT_MAX_REPLICA_NUMBER ="nextEndReplicaNumber";
+ private static final String PROP_REPLICA_LOW_WATER_MARK="replicaLowWaterMark";
+ private static final String PROP_REPLICA_INCREMENT="replicaIncrement";
+ private static final String PROP_REPLICA_BASEDN="replicaDN";
+ private static final String PROP_REPLICA_RANGE_DN="replicaRangeDN";
+
+ private static final String PROP_INFINITE_SERIAL_NUMBER = "1000000000";
+ private static final String PROP_INFINITE_REQUEST_NUMBER = "1000000000";
+ private static final String PROP_INFINITE_REPLICA_NUMBER = "1000";
+ private static final String PROP_BASEDN = "basedn";
+ private static final String PROP_LDAP = "ldap";
+ private static final String PROP_NEXT_RANGE = "nextRange";
+ private static final String PROP_ENABLE_SERIAL_MGMT = "enableSerialManagement";
+
+ // hash keys
+ private static final String NAME="name";
+ private static final String PROP_MIN="min";
+ private static final String PROP_MIN_NAME="min_name";
+ private static final String PROP_MAX = "max";
+ private static final String PROP_MAX_NAME = "max_name";
+ private static final String PROP_NEXT_MIN="next_min";
+ private static final String PROP_NEXT_MIN_NAME="next_min_name";
+ private static final String PROP_NEXT_MAX = "next_max";
+ private static final String PROP_NEXT_MAX_NAME = "next_max_name";
+ private static final String PROP_LOW_WATER_MARK="lowWaterMark";
+ private static final String PROP_LOW_WATER_MARK_NAME="lowWaterMark_name";
+ private static final String PROP_INCREMENT = "increment";
+ private static final String PROP_INCREMENT_NAME = "increment_name";
+ private static final String PROP_RANGE_DN="rangeDN";
+
+ private static final BigInteger BI_ONE = new BigInteger("1");
+
+ private ILogger mLogger = null;
+
+ // singleton enforcement
+
+ private static IDBSubsystem mInstance = new DBSubsystem();
+
+ public static IDBSubsystem getInstance() {
+ return mInstance;
+ }
+
+ /**
+ * This method is used for unit tests. It allows the underlying instance
+ * to be stubbed out.
+ * @param dbSubsystem The stubbed out subsystem to override with.
+ */
+ public static void setInstance(IDBSubsystem dbSubsystem) {
+ mInstance = dbSubsystem;
+ }
+
+ // end singleton enforcement.
+
+ /**
+ * Constructs database subsystem.
+ */
+ private DBSubsystem() {
+ }
+
+ /**
+ * Retrieves subsystem identifier.
+ */
+ public String getId() {
+ return IDBSubsystem.SUB_ID;
+ }
+
+ /**
+ * Sets subsystem identifier.
+ */
+ public void setId(String id) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_OPERATION"));
+ }
+
+ public boolean enableSerialNumberRecovery() {
+ try {
+ return mDBConfig.getBoolean(
+ PROP_ENABLE_SERIAL_NUMBER_RECOVERY, true);
+ } catch (EBaseException e) {
+ // by default
+ return true;
+ }
+ }
+
+ public boolean getEnableSerialMgmt() {
+ return mEnableSerialMgmt;
+ }
+
+ public void setEnableSerialMgmt(boolean v)
+ throws EBaseException {
+ if (v) {
+ CMS.debug("DBSubsystem: Enabling Serial Number Management");
+ } else {
+ CMS.debug("DBSubsystem: Disabling Serial Number Management");
+ }
+
+ mDBConfig.putBoolean(PROP_ENABLE_SERIAL_MGMT, v);
+ IConfigStore rootStore = getOwner().getConfigStore();
+ rootStore.commit(false);
+ mEnableSerialMgmt = v;
+ }
+
+ public BigInteger getNextSerialConfig() {
+ return mNextSerialConfig;
+ }
+
+ public void setNextSerialConfig(BigInteger serial)
+ throws EBaseException {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB,
+ ILogger.LL_INFO, "DBSubsystem: " +
+ "Setting next serial number: 0x" + serial.toString(16));
+ mDBConfig.putString(PROP_NEXT_SERIAL_NUMBER,
+ serial.toString(16));
+ }
+
+ /**
+ * Gets minimum serial number limit in config file
+ *
+ * @param repo repo identifier
+ * @return min serial number
+ */
+ public String getMinSerialConfig(int repo)
+ {
+ return (String) (mRepos[repo]).get(PROP_MIN);
+ }
+
+ /**
+ * Gets maximum serial number limit in config file
+ *
+ * @param repo repo identifier
+ * @return max serial number
+ */
+ public String getMaxSerialConfig(int repo) {
+ return (String) (mRepos[repo]).get(PROP_MAX);
+ }
+
+ /**
+ * Gets minimum serial number limit in next range in config file
+ *
+ * @param repo repo identifier
+ * @return min serial number in next range
+ */
+ public String getNextMinSerialConfig(int repo)
+ {
+ String ret = (String) (mRepos[repo]).get(PROP_NEXT_MIN);
+ if (ret.equals("-1")) {
+ return null;
+ }
+ else {
+ return ret;
+ }
+ }
+
+ /**
+ * Gets maximum serial number limit in next range in config file
+ *
+ * @param repo repo identifier
+ * @return max serial number in next range
+ */
+ public String getNextMaxSerialConfig(int repo) {
+ String ret = (String) (mRepos[repo]).get(PROP_NEXT_MAX);
+ if (ret.equals("-1")) {
+ return null;
+ }
+ else {
+ return ret;
+ }
+ }
+
+ /**
+ * Gets low water mark limit in config file
+ *
+ * @param repo repo identifier
+ * @return low water mark
+ */
+ public String getLowWaterMarkConfig(int repo) {
+ return (String) (mRepos[repo]).get(PROP_LOW_WATER_MARK);
+ }
+
+ /**
+ * Gets range increment for next range in config file
+ *
+ * @param repo repo identifier
+ * @return range increment
+ */
+ public String getIncrementConfig(int repo)
+ {
+ return (String) (mRepos[repo]).get(PROP_INCREMENT);
+ }
+
+ /**
+ * Sets maximum serial number limit in config file
+ *
+ * @param repo repo identifier
+ * @param serial max serial number
+ * @exception EBaseException failed to set
+ */
+ public void setMaxSerialConfig(int repo, String serial)
+ throws EBaseException {
+ Hashtable h = mRepos[repo];
+ CMS.debug("DBSubsystem: Setting max serial number for " + h.get(NAME) + ": " + serial);
+
+ //persist to file
+ mDBConfig.putString((String) h.get(PROP_MAX_NAME), serial);
+ IConfigStore rootStore = getOwner().getConfigStore();
+ rootStore.commit(false);
+
+ h.put(PROP_MAX, serial);
+ mRepos[repo] = h;
+ }
+
+ /**
+ * Sets minimum serial number limit in config file
+ *
+ * @param repo repo identifier
+ * @param serial min serial number
+ * @exception EBaseException failed to set
+ */
+ public void setMinSerialConfig(int repo, String serial)
+ throws EBaseException {
+ Hashtable h = mRepos[repo];
+ CMS.debug("DBSubsystem: Setting min serial number for " + h.get(NAME) + ": " + serial);
+
+ //persist to file
+ mDBConfig.putString((String) h.get(PROP_MIN_NAME), serial);
+ IConfigStore rootStore = getOwner().getConfigStore();
+ rootStore.commit(false);
+
+ h.put(PROP_MIN, serial);
+ mRepos[repo] = h;
+ }
+
+ /**
+ * Sets maximum serial number limit for next range in config file
+ *
+ * @param repo repo identifier
+ * @param serial max serial number for next range
+ * @exception EBaseException failed to set
+ */
+ public void setNextMaxSerialConfig(int repo, String serial)
+ throws EBaseException {
+ Hashtable h = mRepos[repo];
+ if (serial == null) {
+ CMS.debug("DBSubsystem: Removing next max " + h.get(NAME) + " number");
+ mDBConfig.remove((String) h.get(PROP_NEXT_MAX_NAME));
+ } else {
+ CMS.debug("DBSubsystem: Setting next max " + h.get(NAME) + " number: " + serial);
+ mDBConfig.putString((String) h.get(PROP_NEXT_MAX_NAME), serial);
+ }
+ IConfigStore rootStore = getOwner().getConfigStore();
+ rootStore.commit(false);
+ if (serial == null) {
+ Object o2 = h.remove(PROP_NEXT_MAX);
+ } else {
+ h.put(PROP_NEXT_MAX, serial);
+ }
+ mRepos[repo] = h;
+ }
+
+ /**
+ * Sets minimum serial number limit for next range in config file
+ *
+ * @param repo repo identifier
+ * @param serial min serial number for next range
+ * @exception EBaseException failed to set
+ */
+ public void setNextMinSerialConfig(int repo, String serial)
+ throws EBaseException {
+ Hashtable h = mRepos[repo];
+ if (serial == null) {
+ CMS.debug("DBSubsystem: Removing next min " + h.get(NAME) + " number");
+ mDBConfig.remove((String) h.get(PROP_NEXT_MIN_NAME));
+ } else {
+ CMS.debug("DBSubsystem: Setting next min " + h.get(NAME) + " number: " + serial);
+ mDBConfig.putString((String) h.get(PROP_NEXT_MIN_NAME), serial);
+ }
+ IConfigStore rootStore = getOwner().getConfigStore();
+ rootStore.commit(false);
+ if (serial == null) {
+ Object o2 = h.remove(PROP_NEXT_MIN);
+ } else {
+ h.put(PROP_NEXT_MIN, serial);
+ }
+ mRepos[repo] = h;
+ }
+
+ /**
+ * Gets start of next range from database.
+ * Increments the nextRange attribute and allocates
+ * this range to the current instance by creating a pkiRange object.
+ *
+ * @param repo repo identifier
+ * @return start of next range
+ */
+ public String getNextRange(int repo) {
+ LDAPConnection conn = null;
+ String nextRange = null;
+ try {
+ Hashtable h = mRepos[repo];
+ conn = mLdapConnFactory.getConn();
+ String dn = (String) h.get(PROP_BASEDN) + "," + mBaseDN;
+ String rangeDN = (String) h.get(PROP_RANGE_DN) + "," + mBaseDN;
+
+ LDAPEntry entry = conn.read(dn);
+ LDAPAttribute attr = entry.getAttribute(PROP_NEXT_RANGE);
+ nextRange = (String) attr.getStringValues().nextElement();
+
+ BigInteger nextRangeNo = new BigInteger(nextRange);
+ if (nextRangeNo == null) {
+ throw new EBaseException("nextRangeNo is null!");
+ }
+
+ BigInteger incrementNo = new BigInteger((String) h.get(PROP_INCREMENT));
+ if (incrementNo == null) {
+ throw new EBaseException("incrementNo is null!");
+ }
+
+ // To make sure attrNextRange always increments, first delete the current value and then
+ // increment. Two operations in the same transaction
+
+ LDAPAttribute attrNextRange = new LDAPAttribute(PROP_NEXT_RANGE, nextRangeNo.add(incrementNo).toString());
+ LDAPModification [] mods = {
+ new LDAPModification( LDAPModification.DELETE, attr),
+ new LDAPModification( LDAPModification.ADD, attrNextRange ) };
+ conn.modify( dn, mods );
+
+ // Add new range object
+ String endRange = nextRangeNo.add(incrementNo).subtract(BI_ONE).toString();
+ LDAPAttributeSet attrs = new LDAPAttributeSet();
+ attrs.add(new LDAPAttribute("objectClass", "top"));
+ attrs.add(new LDAPAttribute("objectClass", "pkiRange"));
+ attrs.add(new LDAPAttribute("beginRange" , nextRange));
+ attrs.add(new LDAPAttribute("endRange" , endRange));
+ attrs.add(new LDAPAttribute("cn", nextRange));
+ attrs.add(new LDAPAttribute("host", CMS.getEESSLHost()));
+ attrs.add(new LDAPAttribute("securePort", CMS.getEESSLPort()));
+ String dn2 = "cn=" + nextRange + "," + rangeDN;
+ LDAPEntry rangeEntry = new LDAPEntry(dn2, attrs);
+ conn.add(rangeEntry);
+ } catch (Exception e) {
+ CMS.debug("DBSubsystem: getNextRange. Unable to provide next range :" + e);
+ e.printStackTrace();
+ nextRange = null;
+ } finally {
+ try {
+ if ((conn != null) && (mLdapConnFactory!= null)) {
+ CMS.debug("Releasing ldap connection");
+ mLdapConnFactory.returnConn(conn);
+ }
+ }
+ catch (Exception e) {
+ CMS.debug("Error releasing the ldap connection" + e.toString());
+ }
+ }
+ return nextRange;
+ }
+
+ /**
+ * Determines if a range conflict has been observed in database.
+ * If so, delete the conflict entry and remove the next range.
+ * When the next number is requested, if the number of certs is still
+ * below the low water mark, then a new range will be requested.
+ *
+ * @param repo repo identifier
+ * @return true if range conflict, false otherwise
+ */
+ public boolean hasRangeConflict(int repo)
+ {
+ LDAPConnection conn = null;
+ boolean conflict = false;
+ try {
+ String nextRangeStart = getNextMinSerialConfig(repo);
+ if (nextRangeStart == null) {
+ return false;
+ }
+ Hashtable h = mRepos[repo];
+ conn = mLdapConnFactory.getConn();
+ String rangedn = (String) h.get(PROP_RANGE_DN) + "," + mBaseDN;
+ String filter = "(&(nsds5ReplConflict=*)(objectClass=pkiRange)(host= " +
+ CMS.getEESSLHost() + ")(SecurePort=" + CMS.getEESSLPort() +
+ ")(beginRange=" + nextRangeStart + "))";
+ LDAPSearchResults results = conn.search(rangedn, LDAPv3.SCOPE_SUB,
+ filter, null, false);
+
+ while (results.hasMoreElements()) {
+ conflict = true;
+ LDAPEntry entry = results.next();
+ String dn = entry.getDN();
+ CMS.debug("Deleting conflict entry:" + dn);
+ conn.delete(dn);
+ }
+ } catch (Exception e) {
+ CMS.debug("DBSubsystem: hasRangeConflict. Error while checking next range." + e);
+ e.printStackTrace();
+ } finally {
+ try {
+ if ((conn != null) && (mLdapConnFactory!= null)) {
+ CMS.debug("Releasing ldap connection");
+ mLdapConnFactory.returnConn(conn);
+ }
+ }
+ catch (Exception e) {
+ CMS.debug("Error releasing the ldap connection" + e.toString());
+ }
+ }
+ return conflict;
+ }
+
+ public ISubsystem getOwner() {
+ return mOwner;
+ }
+
+ /**
+ * Initializes the internal registery. Connects to the
+ * data source, and create a pool of connection of which
+ * applications can use. Optionally, check the integrity
+ * of the database.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+
+
+ mLogger = CMS.getLogger();
+ mDBConfig = config;
+ mRepos = new Hashtable[IDBSubsystem.NUM_REPOS];
+
+ mConfig = config.getSubStore(PROP_LDAP);
+ IConfigStore tmpConfig = null;
+ try {
+ mBaseDN = mConfig.getString(PROP_BASEDN, "o=NetscapeCertificateServer");
+
+ mOwner = owner;
+
+ mNextSerialConfig = new BigInteger(mDBConfig.getString(
+ PROP_NEXT_SERIAL_NUMBER, "0"), 16);
+
+ mEnableSerialMgmt = mDBConfig.getBoolean(PROP_ENABLE_SERIAL_MGMT, false);
+
+ // populate the certs hash entry
+ Hashtable certs = new Hashtable();
+ certs.put(NAME, "certs");
+ certs.put(PROP_BASEDN, mDBConfig.getString(PROP_SERIAL_BASEDN,""));
+ certs.put(PROP_RANGE_DN, mDBConfig.getString(PROP_SERIAL_RANGE_DN, ""));
+
+ certs.put(PROP_MIN_NAME, PROP_MIN_SERIAL_NUMBER);
+ certs.put(PROP_MIN, mDBConfig.getString(
+ PROP_MIN_SERIAL_NUMBER, "0"));
+
+ certs.put(PROP_MAX_NAME, PROP_MAX_SERIAL_NUMBER);
+ certs.put(PROP_MAX, mDBConfig.getString(
+ PROP_MAX_SERIAL_NUMBER, PROP_INFINITE_SERIAL_NUMBER));
+
+ certs.put(PROP_NEXT_MIN_NAME, PROP_NEXT_MIN_SERIAL_NUMBER);
+ certs.put(PROP_NEXT_MIN, mDBConfig.getString(
+ PROP_NEXT_MIN_SERIAL_NUMBER, "-1"));
+
+ certs.put(PROP_NEXT_MAX_NAME, PROP_NEXT_MAX_SERIAL_NUMBER);
+ certs.put(PROP_NEXT_MAX, mDBConfig.getString(
+ PROP_NEXT_MAX_SERIAL_NUMBER, "-1"));
+
+ certs.put(PROP_LOW_WATER_MARK_NAME, PROP_SERIAL_LOW_WATER_MARK);
+ certs.put(PROP_LOW_WATER_MARK, mDBConfig.getString(
+ PROP_SERIAL_LOW_WATER_MARK, "5000"));
+
+ certs.put(PROP_INCREMENT_NAME, PROP_SERIAL_INCREMENT);
+ certs.put(PROP_INCREMENT, mDBConfig.getString(
+ PROP_SERIAL_INCREMENT, PROP_INFINITE_SERIAL_NUMBER));
+
+ mRepos[CERTS]=certs;
+
+ // populate the requests hash entry
+ Hashtable requests = new Hashtable();
+ requests.put(NAME, "requests");
+ requests.put(PROP_BASEDN, mDBConfig.getString(PROP_REQUEST_BASEDN,""));
+ requests.put(PROP_RANGE_DN, mDBConfig.getString(PROP_REQUEST_RANGE_DN, ""));
+
+ requests.put(PROP_MIN_NAME, PROP_MIN_REQUEST_NUMBER);
+ requests.put(PROP_MIN, mDBConfig.getString(
+ PROP_MIN_REQUEST_NUMBER, "0"));
+
+ requests.put(PROP_MAX_NAME, PROP_MAX_REQUEST_NUMBER);
+ requests.put(PROP_MAX, mDBConfig.getString(
+ PROP_MAX_REQUEST_NUMBER, PROP_INFINITE_REQUEST_NUMBER));
+
+ requests.put(PROP_NEXT_MIN_NAME, PROP_NEXT_MIN_REQUEST_NUMBER);
+ requests.put(PROP_NEXT_MIN, mDBConfig.getString(
+ PROP_NEXT_MIN_REQUEST_NUMBER, "-1"));
+
+ requests.put(PROP_NEXT_MAX_NAME, PROP_NEXT_MAX_REQUEST_NUMBER);
+ requests.put(PROP_NEXT_MAX, mDBConfig.getString(
+ PROP_NEXT_MAX_REQUEST_NUMBER, "-1"));
+
+ requests.put(PROP_LOW_WATER_MARK_NAME, PROP_REQUEST_LOW_WATER_MARK);
+ requests.put(PROP_LOW_WATER_MARK, mDBConfig.getString(
+ PROP_REQUEST_LOW_WATER_MARK, "5000"));
+
+ requests.put(PROP_INCREMENT_NAME, PROP_REQUEST_INCREMENT);
+ requests.put(PROP_INCREMENT, mDBConfig.getString(
+ PROP_REQUEST_INCREMENT, PROP_INFINITE_REQUEST_NUMBER));
+
+ mRepos[REQUESTS] = requests;
+
+ // populate replica ID hash entry
+ Hashtable replicaID = new Hashtable();
+ replicaID.put(NAME, "requests");
+ replicaID.put(PROP_BASEDN, mDBConfig.getString(PROP_REPLICA_BASEDN,""));
+ replicaID.put(PROP_RANGE_DN, mDBConfig.getString(PROP_REPLICA_RANGE_DN, ""));
+
+ replicaID.put(PROP_MIN_NAME, PROP_MIN_REPLICA_NUMBER);
+ replicaID.put(PROP_MIN, mDBConfig.getString(
+ PROP_MIN_REPLICA_NUMBER, "1"));
+
+ replicaID.put(PROP_MAX_NAME, PROP_MAX_REPLICA_NUMBER);
+ replicaID.put(PROP_MAX, mDBConfig.getString(
+ PROP_MAX_REPLICA_NUMBER, PROP_INFINITE_REPLICA_NUMBER));
+
+ replicaID.put(PROP_NEXT_MIN_NAME, PROP_NEXT_MIN_REPLICA_NUMBER);
+ replicaID.put(PROP_NEXT_MIN, mDBConfig.getString(
+ PROP_NEXT_MIN_REPLICA_NUMBER, "-1"));
+
+ replicaID.put(PROP_NEXT_MAX_NAME, PROP_NEXT_MAX_REPLICA_NUMBER);
+ replicaID.put(PROP_NEXT_MAX, mDBConfig.getString(
+ PROP_NEXT_MAX_REPLICA_NUMBER, "-1"));
+
+ replicaID.put(PROP_LOW_WATER_MARK_NAME, PROP_REPLICA_LOW_WATER_MARK);
+ replicaID.put(PROP_LOW_WATER_MARK, mDBConfig.getString(
+ PROP_REPLICA_LOW_WATER_MARK, "10"));
+
+ replicaID.put(PROP_INCREMENT_NAME, PROP_REPLICA_INCREMENT);
+ replicaID.put(PROP_INCREMENT, mDBConfig.getString(
+ PROP_REPLICA_INCREMENT, PROP_INFINITE_REPLICA_NUMBER));
+
+ mRepos[REPLICA_ID] = replicaID;
+
+
+ // initialize registry
+ mRegistry = new DBRegistry();
+ mRegistry.init(this, null);
+
+ // initialize LDAP connection factory
+ // by default return error if server is down at startup time.
+ mLdapConnFactory = new LdapBoundConnFactory(true);
+ tmpConfig = (IConfigStore) (((PropConfigStore) mConfig).clone());
+
+ tmpConfig.putString(PROP_BASEDN, mBaseDN);
+ } catch (EBaseException e) {
+ if (CMS.isPreOpMode())
+ return;
+ throw e;
+ }
+
+ try {
+ mLdapConnFactory.init(tmpConfig);
+ } catch (ELdapServerDownException e) {
+ if (CMS.isPreOpMode())
+ return;
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ } catch (ELdapException ex) {
+ if (CMS.isPreOpMode())
+ return;
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_ERROR", ex.toString()));
+ } catch (EBaseException e) {
+ if (CMS.isPreOpMode())
+ return;
+ throw e;
+ }
+
+ try {
+ // registers CMS database attributes
+ IDBRegistry reg = getRegistry();
+
+ String certRecordOC[] = new String[2];
+
+ certRecordOC[0] = CertDBSchema.LDAP_OC_TOP;
+ certRecordOC[1] = CertDBSchema.LDAP_OC_CERT_RECORD;
+
+ if (!reg.isObjectClassRegistered(CertRecord.class.getName())) {
+ reg.registerObjectClass(CertRecord.class.getName(),
+ certRecordOC);
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_ID)) {
+ reg.registerAttribute(CertRecord.ATTR_ID, new
+ BigIntegerMapper(CertDBSchema.LDAP_ATTR_SERIALNO));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_META_INFO)) {
+ reg.registerAttribute(CertRecord.ATTR_META_INFO, new
+ MetaInfoMapper(CertDBSchema.LDAP_ATTR_META_INFO));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_REVO_INFO)) {
+ reg.registerAttribute(CertRecord.ATTR_REVO_INFO, new
+ RevocationInfoMapper());
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_X509CERT)) {
+ reg.registerAttribute(CertRecord.ATTR_X509CERT, new
+ X509CertImplMapper());
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_CERT_STATUS)) {
+ reg.registerAttribute(CertRecord.ATTR_CERT_STATUS, new
+ StringMapper(CertDBSchema.LDAP_ATTR_CERT_STATUS));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_AUTO_RENEW)) {
+ reg.registerAttribute(CertRecord.ATTR_AUTO_RENEW, new
+ StringMapper(CertDBSchema.LDAP_ATTR_AUTO_RENEW));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_CREATE_TIME)) {
+ reg.registerAttribute(CertRecord.ATTR_CREATE_TIME, new
+ DateMapper(CertDBSchema.LDAP_ATTR_CREATE_TIME));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_MODIFY_TIME)) {
+ reg.registerAttribute(CertRecord.ATTR_MODIFY_TIME, new
+ DateMapper(CertDBSchema.LDAP_ATTR_MODIFY_TIME));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_ISSUED_BY)) {
+ reg.registerAttribute(CertRecord.ATTR_ISSUED_BY, new
+ StringMapper(CertDBSchema.LDAP_ATTR_ISSUED_BY));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_REVOKED_BY)) {
+ reg.registerAttribute(CertRecord.ATTR_REVOKED_BY, new
+ StringMapper(CertDBSchema.LDAP_ATTR_REVOKED_BY));
+ }
+ if (!reg.isAttributeRegistered(CertRecord.ATTR_REVOKED_ON)) {
+ reg.registerAttribute(CertRecord.ATTR_REVOKED_ON, new
+ DateMapper(CertDBSchema.LDAP_ATTR_REVOKED_ON));
+ }
+
+ if (!reg.isAttributeRegistered(CertificateValidity.NOT_AFTER)) {
+ reg.registerAttribute(CertificateValidity.NOT_AFTER, new
+ DateMapper(CertDBSchema.LDAP_ATTR_NOT_AFTER));
+ }
+
+ if (!reg.isAttributeRegistered(CertificateValidity.NOT_BEFORE)) {
+ reg.registerAttribute(CertificateValidity.NOT_BEFORE, new
+ DateMapper(CertDBSchema.LDAP_ATTR_NOT_BEFORE));
+ }
+
+ String crlRecordOC[] = new String[2];
+
+ crlRecordOC[0] = CRLDBSchema.LDAP_OC_TOP;
+ crlRecordOC[1] = CRLDBSchema.LDAP_OC_CRL_RECORD;
+ reg.registerObjectClass(CRLIssuingPointRecord.class.getName(),
+ crlRecordOC);
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_ID, new
+ StringMapper(CRLDBSchema.LDAP_ATTR_CRL_ID));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CRL_NUMBER, new
+ BigIntegerMapper(CRLDBSchema.LDAP_ATTR_CRL_NUMBER));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_DELTA_NUMBER, new
+ BigIntegerMapper(CRLDBSchema.LDAP_ATTR_DELTA_NUMBER));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CRL_SIZE, new
+ LongMapper(CRLDBSchema.LDAP_ATTR_CRL_SIZE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_DELTA_SIZE, new
+ LongMapper(CRLDBSchema.LDAP_ATTR_DELTA_SIZE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_THIS_UPDATE, new
+ DateMapper(CRLDBSchema.LDAP_ATTR_THIS_UPDATE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_NEXT_UPDATE, new
+ DateMapper(CRLDBSchema.LDAP_ATTR_NEXT_UPDATE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_FIRST_UNSAVED, new
+ StringMapper(CRLDBSchema.LDAP_ATTR_FIRST_UNSAVED));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CRL, new
+ ByteArrayMapper(CRLDBSchema.LDAP_ATTR_CRL));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_DELTA_CRL, new
+ ByteArrayMapper(CRLDBSchema.LDAP_ATTR_DELTA_CRL));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CA_CERT, new
+ ByteArrayMapper(CRLDBSchema.LDAP_ATTR_CA_CERT));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_CRL_CACHE, new
+ ObjectStreamMapper(CRLDBSchema.LDAP_ATTR_CRL_CACHE));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_REVOKED_CERTS, new
+ ObjectStreamMapper(CRLDBSchema.LDAP_ATTR_REVOKED_CERTS));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_UNREVOKED_CERTS, new
+ ObjectStreamMapper(CRLDBSchema.LDAP_ATTR_UNREVOKED_CERTS));
+ reg.registerAttribute(ICRLIssuingPointRecord.ATTR_EXPIRED_CERTS, new
+ ObjectStreamMapper(CRLDBSchema.LDAP_ATTR_EXPIRED_CERTS));
+
+ if (!reg.isObjectClassRegistered(
+ RepositoryRecord.class.getName())) {
+ String repRecordOC[] = new String[2];
+
+ repRecordOC[0] = RepositorySchema.LDAP_OC_TOP;
+ repRecordOC[1] = RepositorySchema.LDAP_OC_REPOSITORY;
+ reg.registerObjectClass(
+ RepositoryRecord.class.getName(), repRecordOC);
+ }
+ if (!reg.isAttributeRegistered(IRepositoryRecord.ATTR_SERIALNO)) {
+ reg.registerAttribute(IRepositoryRecord.ATTR_SERIALNO,
+ new BigIntegerMapper(RepositorySchema.LDAP_ATTR_SERIALNO));
+ }
+ if (!reg.isAttributeRegistered(IRepositoryRecord.ATTR_PUB_STATUS)) {
+ reg.registerAttribute(IRepositoryRecord.ATTR_PUB_STATUS,
+ new StringMapper(RepositorySchema.LDAP_ATTR_PUB_STATUS));
+ }
+
+ } catch (EBaseException e) {
+ if (CMS.isPreOpMode())
+ return;
+ throw e;
+ }
+ }
+
+ /**
+ * Starts up this service.
+ */
+ public void startup() throws EBaseException {
+ }
+
+ /**
+ * Retrieves configuration store.
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Retrieves base DN of backend database.
+ */
+ public String getBaseDN() {
+ return mBaseDN;
+ }
+
+ /**
+ * Retrieves LDAP connection info (host, port, secure)
+ */
+ public LdapConnInfo getLdapConnInfo() {
+ if (mLdapConnFactory != null)
+ return mLdapConnFactory.getConnInfo();
+ return null;
+ }
+
+ public LdapAuthInfo getLdapAuthInfo() {
+ if (mLdapConnFactory != null)
+ return mLdapConnFactory.getAuthInfo();
+ return null;
+ }
+
+ /**
+ * Shutdowns this subsystem gracefully.
+ */
+ public void shutdown() {
+ try {
+ if (mLdapConnFactory != null) {
+ mLdapConnFactory.reset();
+ mLdapConnFactory = null;
+ }
+ } catch (ELdapException e) {
+
+ /*LogDoc
+ *
+ * @phase shutdown server
+ * @reason shutdown db subsystem
+ * @message DBSubsystem: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB,
+ ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+ if (mRegistry != null)
+ mRegistry.shutdown();
+ }
+
+ /**
+ * Retrieves the registry.
+ */
+ public IDBRegistry getRegistry() {
+ return mRegistry;
+ }
+
+ /**
+ * Creates a database session.
+ */
+ public IDBSSession createSession() throws EDBException {
+ LDAPConnection conn = null;
+
+ try {
+ conn = mLdapConnFactory.getConn();
+
+ String schemaAdded = mDBConfig.getString("newSchemaEntryAdded", "");
+
+ if (schemaAdded.equals("")) {
+ LDAPSchema dirSchema = new LDAPSchema();
+
+ // create new attribute: userType
+ dirSchema.fetchSchema(conn);
+ LDAPAttributeSchema userType = dirSchema.getAttribute("usertype");
+
+ if (userType == null) {
+ userType = new LDAPAttributeSchema("usertype", "usertype-oid",
+ "Distinguish whether the user is administrator, agent or subsystem.",
+ LDAPAttributeSchema.cis, false);
+ userType.add(conn);
+ }
+
+ // create new objectclass: cmsuser
+ dirSchema.fetchSchema(conn);
+ LDAPObjectClassSchema newObjClass = dirSchema.getObjectClass("cmsuser");
+ String[] requiredAttrs = {"usertype"};
+ String[] optionalAttrs = new String[0];
+
+ if (newObjClass == null) {
+ newObjClass = new LDAPObjectClassSchema("cmsuser", "cmsuser-oid",
+ "top", "CMS User", requiredAttrs, optionalAttrs);
+ newObjClass.add(conn);
+ }
+ mDBConfig.putString("newSchemaEntryAdded", "true");
+ IConfigStore rootStore = getOwner().getConfigStore();
+
+ rootStore.commit(false);
+ }
+ } catch (ELdapException e) {
+ if (e instanceof ELdapServerDownException) {
+ throw new EDBNotAvailException(
+ CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE"));
+ }
+
+ /*LogDoc
+ *
+ * @phase create db session
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_CONN_ERROR", e.toString()));
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_CONNECT_LDAP_FAILED", e.toString()));
+ } catch (LDAPException e) {
+ if (e.getLDAPResultCode() != 20) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_SCHEMA_ERROR", e.toString()));
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_ADD_ENTRY_FAILED", e.toString()));
+ }
+ } catch (EBaseException e) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_CONF_ERROR",
+ e.toString()));
+ }
+ return new DBSSession(this, conn);
+ }
+
+ public void returnConn(LDAPConnection conn) {
+ mLdapConnFactory.returnConn(conn);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DBVirtualList.java b/pki/base/common/src/com/netscape/cmscore/dbs/DBVirtualList.java
new file mode 100644
index 000000000..8a3b3cba7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DBVirtualList.java
@@ -0,0 +1,769 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import netscape.ldap.controls.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents a virtual list of search results.
+ * Note that this class must be used with DS4.0.
+ *
+ * @author thomask
+ * @author mzhao
+ * @version $Revision$, $Date$
+ */
+public class DBVirtualList implements IDBVirtualList {
+
+ private IDBRegistry mRegistry = null;
+ private LDAPConnection mConn = null;
+ private String mBase = null;
+ private String mFilter = null;
+ private String mAttrs[] = null;
+ // virtual list size
+ private int mSize = -1;
+
+ private Vector mEntries = new Vector();
+ // mSize is get or not?
+ private boolean mInitialized = false;
+ private LDAPSortKey[] mKeys;
+ private LDAPControl[] mPageControls = null;
+ // page buffer size
+ private int mPageSize = 10;
+ // the top of the buffer
+ private int mTop = 0;
+ private int mBeforeCount;
+ private int mAfterCount;
+ // the index of the first entry returned
+ private int mSelectedIndex = 0;
+ private int mJumpToIndex = 0;
+ private int mJumpToInitialIndex = 0; // Initial index hit in jumpto operation
+ private int mJumpToDirection = 1; // Do we proceed forward or backwards
+ private String mJumpTo = null; // Determines if this is the jumpto case
+
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs a virtual list.
+ * Be sure to setPageSize() later if your pageSize is not the default 10
+ * Be sure to setSortKey() before fetchs
+ *
+ * param registry the registry of attribute mappers
+ * param c the ldap connection. It has to be version 3 and upper
+ * param base the base distinguished name to search from
+ * param filter search filter specifying the search criteria
+ * param attrs list of attributes that you want returned in the search results
+ */
+ public DBVirtualList(IDBRegistry registry, LDAPConnection c,
+ String base, String filter, String attrs[]) throws EBaseException {
+ mRegistry = registry;
+ mFilter = filter;
+ mBase = base;
+ mAttrs = attrs;
+ CMS.debug( "In DBVirtualList filter attrs filter: " + filter
+ + " attrs: " + Arrays.toString( attrs ) );
+ mPageControls = new LDAPControl[2];
+ try {
+ mConn = (LDAPConnection) c.clone();
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED",
+ e.toString()));
+ }
+ }
+
+ /**
+ * Constructs a virtual list.
+ * Be sure to setPageSize() later if your pageSize is not the default 10
+ *
+ * param registry the registry of attribute mappers
+ * param c the ldap connection. It has to be version 3 and upper
+ * param base the base distinguished name to search from
+ * param filter search filter specifying the search criteria
+ * param attrs list of attributes that you want returned in the search results
+ * param sortKey the attributes to sort by
+ */
+ public DBVirtualList(IDBRegistry registry, LDAPConnection c,
+ String base, String filter, String attrs[], String sortKey[])
+ throws EBaseException {
+
+ CMS.debug( "In DBVirtualList filter attrs sotrKey[] filter: " + filter
+ + " attrs: " + Arrays.toString( attrs ) );
+ mRegistry = registry;
+ mFilter = filter;
+ try {
+ mConn = (LDAPConnection) c.clone();
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED",
+ e.toString()));
+ }
+ mBase = base;
+ mAttrs = attrs;
+ mPageControls = new LDAPControl[2];
+ setSortKey(sortKey);
+ }
+
+ /**
+ * Constructs a virtual list.
+ * Be sure to setPageSize() later if your pageSize is not the default 10
+ *
+ * param registry the registry of attribute mappers
+ * param c the ldap connection. It has to be version 3 and upper
+ * param base the base distinguished name to search from
+ * param filter search filter specifying the search criteria
+ * param attrs list of attributes that you want returned in the search results
+ * param sortKey the attribute to sort by
+ */
+ public DBVirtualList(IDBRegistry registry, LDAPConnection c,
+ String base, String filter, String attrs[], String sortKey)
+ throws EBaseException {
+
+ CMS.debug( "In DBVirtualList filter attrs sortKey filter: " + filter + " attrs: " + Arrays.toString( attrs ) );
+ mRegistry = registry;
+ mFilter = filter;
+ try {
+ mConn = (LDAPConnection) c.clone();
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED",
+ e.toString()));
+ }
+ mBase = base;
+ mAttrs = attrs;
+ mPageControls = new LDAPControl[2];
+ setSortKey(sortKey);
+ }
+
+ /**
+ * Constructs a virtual list.
+ *
+ * param registry the registry of attribute mappers
+ * param c the ldap connection. It has to be version 3 and upper
+ * param base the base distinguished name to search from
+ * param filter search filter specifying the search criteria
+ * param attrs list of attributes that you want returned in the search results
+ * param sortKey the attributes to sort by
+ * param pageSize the size of a page. There is a 3*pageSize buffer maintained so
+ * pageUp and pageDown won't invoke fetch from ldap server
+ */
+ public DBVirtualList(IDBRegistry registry, LDAPConnection c,
+ String base, String filter, String attrs[], String sortKey[],
+ int pageSize) throws EBaseException {
+
+ CMS.debug( "In DBVirtualList filter attrs sortKey[] pageSize filter: "
+ + filter + " attrs: " + Arrays.toString( attrs )
+ + " pageSize " + pageSize );
+ mRegistry = registry;
+ mFilter = filter;
+ try {
+ mConn = (LDAPConnection) c.clone();
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED",
+ e.toString()));
+ }
+ mBase = base;
+ mAttrs = attrs;
+ mPageControls = new LDAPControl[2];
+ setSortKey(sortKey);
+ setPageSize(pageSize);
+ }
+
+ /**
+ * Constructs a virtual list.
+ *
+ * param registry the registry of attribute mappers
+ * param c the ldap connection. It has to be version 3 and upper
+ * param base the base distinguished name to search from
+ * param filter search filter specifying the search criteria
+ * param attrs list of attributes that you want returned in the search results
+ * param sortKey the attribute to sort by
+ * param pageSize the size of a page. There is a 3*pageSize buffer maintained so
+ * pageUp and pageDown won't invoke fetch from ldap server
+ */
+ public DBVirtualList(IDBRegistry registry, LDAPConnection c,
+ String base, String filter, String attrs[], String sortKey,
+ int pageSize) throws EBaseException {
+
+ CMS.debug( "In DBVirtualList filter attrs sortKey pageSize filter: "
+ + filter + " attrs: " + Arrays.toString( attrs )
+ + " pageSize " + pageSize );
+ mRegistry = registry;
+ mFilter = filter;
+ try {
+ mConn = (LDAPConnection) c.clone();
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED",
+ e.toString()));
+ }
+ mBase = base;
+ mAttrs = attrs;
+ mPageControls = new LDAPControl[2];
+ setSortKey(sortKey);
+ setPageSize(pageSize);
+ }
+
+ public DBVirtualList(IDBRegistry registry, LDAPConnection c,
+ String base, String filter, String attrs[],
+ String startFrom, String sortKey,
+ int pageSize) throws EBaseException {
+
+ CMS.debug( "In DBVirtualList filter attrs startFrom sortKey pageSize "
+ + "filter: " + filter
+ + " attrs: " + Arrays.toString( attrs )
+ + " pageSize " + pageSize + " startFrom " + startFrom );
+ mRegistry = registry;
+ mFilter = filter;
+ try {
+ mConn = (LDAPConnection) c.clone();
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED",
+ e.toString()));
+ }
+ mBase = base;
+ mAttrs = attrs;
+ mPageControls = new LDAPControl[2];
+ mJumpTo = startFrom;
+ setSortKey(sortKey);
+ // setPageSize(pageSize);
+
+ if (pageSize < 0) {
+ mJumpToDirection = -1;
+ }
+ mPageSize = pageSize;
+
+ mBeforeCount = 0;
+ mAfterCount = mPageSize;
+ }
+
+ /**
+ * Set the paging size of this virtual list.
+ * The page size here is just a buffer size. A buffer is kept around
+ * that is three times as large as the number of visible entries.
+ * That way, you can scroll up/down several items(up to a page-full)
+ * without refetching entries from the directory.
+ *
+ * @param size the page size
+ */
+ public void setPageSize(int size) {
+
+ if (mJumpTo != null) {
+ return;
+ }
+
+ mPageSize = size;
+ mBeforeCount = 0; //mPageSize;
+ mAfterCount = mPageSize; // mPageSize + mPageSize;
+
+ //CMS.debug("In setPageSize " + size + " mBeforeCount " + mBeforeCount + " mAfterCount " + mAfterCount);
+ }
+
+ /**
+ * set the sort key
+ *
+ * @param sortKey the attribute to sort by
+ */
+ public void setSortKey(String sortKey) throws EBaseException {
+ String keys[] = new String[1];
+
+ keys[0] = sortKey;
+ setSortKey(keys);
+ }
+
+ /**
+ * set the sort key
+ *
+ * @param sortKey the attributes to sort by
+ */
+ public void setSortKey(String[] sortKeys) throws EBaseException {
+ if (sortKeys == null)
+ throw new EBaseException("sort keys cannot be null");
+ try {
+
+ mKeys = new LDAPSortKey[sortKeys.length];
+ String la[] = mRegistry.getLDAPAttributes(sortKeys);
+
+ for (int j = 0; j < sortKeys.length; j++) {
+ mKeys[j] = new LDAPSortKey(la[j]);
+ }
+ } catch (Exception e) {
+
+ /*LogDoc
+ *
+ * @phase local ldap search
+ * @reason Failed at setSortKey.
+ * @message DBVirtualList: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+ // Paged results also require a sort control
+ if (mKeys != null) {
+ mPageControls[0] =
+ new LDAPSortControl(mKeys, true);
+ }else {
+ throw new EBaseException("sort keys cannot be null");
+ }
+ }
+
+ /**
+ * Retrieves the size of this virtual list.
+ * Recommend to call getSize() before getElementAt() or getElements()
+ * since you'd better check if the index is out of bound first.
+ */
+ public int getSize() {
+ if (!mInitialized) {
+ mInitialized = true;
+ // Do an initial search to get the virtual list size
+ // Keep one page before and one page after the start
+ if (mJumpTo == null) {
+ mBeforeCount = 0; //mPageSize;
+ mAfterCount = mPageSize; // mPageSize + mPageSize;
+ }
+ // Create the initial paged results control
+ /* Since this one is only used to get the size of the virtual list;
+ we don't care about the starting index. If there is no partial
+ match, the first one before (or after, if none before) is returned
+ as the index entry. Instead of "A", you could use the other
+ constructor and specify 0 both for startIndex and for
+ contentCount. */
+ LDAPVirtualListControl cont = null;
+
+ if (mJumpTo == null) {
+ cont = new LDAPVirtualListControl("A",
+ mBeforeCount,
+ mAfterCount);
+ } else {
+
+ if (mPageSize < 0) {
+ mBeforeCount = mPageSize * -1;
+ mAfterCount = 0;
+ }
+ cont = new LDAPVirtualListControl(mJumpTo,
+ mBeforeCount,
+ mAfterCount);
+ }
+ mPageControls[1] = cont;
+ getJumpToPage();
+ }
+
+ CMS.debug("Getting Virtual List size: " + mSize);
+ return mSize;
+ }
+
+ public int getSizeBeforeJumpTo() {
+
+ if (!mInitialized || mJumpTo == null)
+ return 0;
+
+ int size = 0;
+
+ if (mJumpToDirection < 0) {
+ size = mTop + mEntries.size();
+ } else {
+ size = mTop;
+
+ }
+
+ return size;
+
+ }
+
+ public int getSizeAfterJumpTo() {
+
+ if (!mInitialized || mJumpTo == null)
+ return 0;
+
+ int size = mSize - mTop;
+
+ return size;
+
+ }
+
+ private synchronized boolean getEntries() {
+ // Specify necessary controls for vlist
+ // LDAPSearchConstraints cons = mConn.getSearchConstraints();
+ LDAPSearchConstraints cons = new LDAPSearchConstraints();
+
+ cons.setMaxResults(0);
+ if (mPageControls != null) {
+ cons.setServerControls(mPageControls);
+ //System.out.println( "setting vlist control" );
+ }
+ // Empty the buffer
+ mEntries.removeAllElements();
+ // Do a search
+ try {
+ //what happen if there is no matching?
+ String ldapFilter = mRegistry.getFilter(mFilter);
+ String ldapAttrs[] = null;
+ LDAPSearchResults result;
+
+ if (mAttrs != null) {
+ ldapAttrs = mRegistry.getLDAPAttributes(mAttrs);
+
+ /*
+ LDAPv2.SCOPE_BASE:
+ (search only the base DN)
+ LDAPv2.SCOPE_ONE:
+ (search only entries under the base DN)
+ LDAPv2.SCOPE_SUB:
+ (search the base DN and all entries within its subtree)
+ */
+ result = mConn.search(mBase,
+ LDAPConnection.SCOPE_ONE, ldapFilter, ldapAttrs,
+ false, cons);
+
+ } else {
+ result = mConn.search(mBase,
+ LDAPConnection.SCOPE_ONE, ldapFilter, null,
+ false, cons);
+ }
+ if (result == null) {
+ return false;
+ }
+ int damageCounter = 0;
+
+ while (result.hasMoreElements()) {
+ LDAPEntry entry = (LDAPEntry) result.nextElement();
+
+ try {
+ //maintain mEntries as vector of LDAPEntry
+ Object o = mRegistry.createObject(entry.getAttributeSet());
+
+ mEntries.addElement(o);
+ } catch (Exception e) {
+
+ CMS.debug("Exception " + e);
+
+ /*LogDoc
+ *
+ * @phase local ldap search
+ * @reason Failed to get enties.
+ * @message DBVirtualList: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_VL_ADD", e.toString()));
+ // #539044
+ damageCounter++;
+ if (damageCounter > 100) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_VL_CORRUPTED_ENTRIES", Integer.toString(damageCounter)));
+ return false;
+ }
+ }
+ }
+ } catch (Exception e) {
+
+ /*LogDoc
+ *
+ * @phase local ldap search
+ * @reason Failed to get enties.
+ * @message DBVirtualList: <exception thrown>
+ */
+ CMS.debug("getEntries: exception " + e);
+
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("OPERATION_ERROR", e.toString()));
+ }
+ //System.out.println( "Returning " + mEntries.size() +
+ // " entries" );
+
+ CMS.debug("getEntries returning " + mEntries.size());
+ return true;
+ }
+
+ public int getCurrentIndex() {
+ return mTop;
+ }
+
+ private synchronized boolean getJumpToPage() {
+ try {
+ // Get the actual entries
+ if (!getEntries())
+ return false;
+
+ // Check if we have a control returned
+ LDAPControl[] c = mConn.getResponseControls();
+ LDAPVirtualListResponse nextCont =
+ LDAPVirtualListResponse.parseResponse(c);
+
+ if (nextCont != null) {
+ mSelectedIndex = nextCont.getFirstPosition() - 1;
+ mTop = Math.max(0, mSelectedIndex - mBeforeCount);
+
+ CMS.debug("mTop " + mTop);
+ if (mJumpTo != null) {
+ mJumpToInitialIndex = mTop;
+ }
+
+ // Now we know the total size of the virtual list box
+ mSize = nextCont.getContentCount();
+ ((LDAPVirtualListControl) mPageControls[1]).setListSize(mSize);
+ mInitialized = true;
+ //System.out.println( "Virtual window: " + mTop +
+ // ".." + (mTop+mEntries.size()-1) +
+ // " of " + mSize );
+ } else {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_DBS_VL_NULL_RESPONSE"));
+ }
+ return true;
+ } catch (Exception e) {
+ // happens when connection is not available
+ return false;
+ }
+ }
+
+ /** Get a page starting at "first" (although we may also fetch
+ * some preceding entries)
+ * Recommend to call getSize() before getElementAt() or getElements()
+ * since you'd better check if the index is out of bound first.
+ *
+ * @param first the index of the first entry of the page you want to fetch
+ */
+ public boolean getPage(int first) {
+ CMS.debug("getPage " + first);
+ if (!mInitialized) {
+ LDAPVirtualListControl cont = new LDAPVirtualListControl(0,
+ mBeforeCount,
+ mAfterCount, 0);
+
+ mPageControls[1] = cont;
+ }
+
+ //CMS.debug("about to set range first " + first + " mBeforeCount " + mBeforeCount + " mAfterCount " + mAfterCount);
+ ((LDAPVirtualListControl) mPageControls[1]).setRange(first, mBeforeCount, mAfterCount);
+ return getPage();
+ }
+
+ /** Fetch a buffer
+ */
+ private boolean getPage() {
+ // Get the actual entries
+ if (!getEntries())
+ return false;
+
+ // Check if we have a control returned
+ LDAPControl[] c = mConn.getResponseControls();
+ LDAPVirtualListResponse nextCont =
+ LDAPVirtualListResponse.parseResponse(c);
+
+ if (nextCont != null) {
+ mSelectedIndex = nextCont.getFirstPosition() - 1;
+ mTop = Math.max(0, mSelectedIndex - mBeforeCount);
+ //CMS.debug("New mTop: " + mTop + " mSelectedIndex " + mSelectedIndex);
+ // Now we know the total size of the virtual list box
+ mSize = nextCont.getContentCount();
+ ((LDAPVirtualListControl) mPageControls[1]).setListSize(mSize);
+ mInitialized = true;
+ //System.out.println( "Virtual window: " + mTop +
+ // ".." + (mTop+mEntries.size()-1) +
+ // " of " + mSize );
+ } else {
+
+ /*LogDoc
+ *
+ * @phase local ldap search
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_VL_NULL_RESPONSE"));
+ }
+ return true;
+ }
+
+ /** Called by application to scroll the list with initial letters.
+ * Consider text to be an initial substring of the attribute of the
+ * primary sorting key(the first one specified in the sort key array)
+ * of an entry.
+ * If no entries match, the one just before(or after, if none before)
+ * will be returned as mSelectedIndex
+ *
+ * @param text the prefix of the first entry of the page you want to fetch
+ */
+ public boolean getPage(String text) {
+ mPageControls[1] =
+ new LDAPVirtualListControl(text,
+ mBeforeCount,
+ mAfterCount);
+ //System.out.println( "Setting requested start to " +
+ // text + ", -" + mBeforeCount + ", +" +
+ // mAfterCount );
+ return getPage();
+ }
+
+ /**
+ * fetch data of a single list item
+ * Recommend to call getSize() before getElementAt() or getElements()
+ * since you'd better check if the index is out of bound first.
+ * If the index is out of range of the virtual list, an exception will be thrown
+ * and return null
+ *
+ * @param index the index of the element to fetch
+ */
+ public Object getElementAt(int index) {
+
+ /* mSize may not be init at this time! Bad !
+ * the caller should really check the index is within bound before this
+ * but I'll take care of this just in case they are too irresponsible
+ */
+ int baseJumpTo = 0;
+
+ if (!mInitialized)
+ mSize = getSize();
+
+ CMS.debug("getElementAt: " + index + " mTop " + mTop);
+
+ //System.out.println( "need entry " + index );
+ if ((index < 0) || (index >= mSize)) {
+ CMS.debug("returning null");
+ return null;
+ }
+
+ if (mJumpTo != null) { //Handle the explicit jumpto case
+
+ if (index == 0)
+ mJumpToIndex = 0; // Keep a running jumpto index for this page of data
+ else
+ mJumpToIndex++;
+
+ //CMS.debug("getElementAtJT: " + index + " mTop " + mTop + " mEntries.size() " + mEntries.size());
+
+ if ((mJumpToDirection > 0) && (mJumpToInitialIndex + index >= mSize)) // out of data in forward paging jumpto case
+ {
+ CMS.debug("mJumpTo virtual list exhausted mTop " + mTop + " mSize " + mSize);
+ return null;
+ }
+
+ if (mJumpToIndex >= mEntries.size()) // In jumpto case, page of data has been exhausted
+ {
+ mJumpToIndex = 0; // new page will be needed reset running count
+
+ if (mJumpToDirection > 0) { //proceed in positive direction past hit point
+ getPage(index + mJumpToInitialIndex + 1);
+ } else { //proceed backwards from hit point
+ if (mTop == 0) {
+ getPage(0);
+ CMS.debug("asking for a page less than zero in reverse case, return null");
+ return null;
+ }
+
+ CMS.debug("getting page reverse mJumptoIndex " + mJumpToIndex + " mTop " + mTop);
+ getPage(mTop);
+
+ }
+
+ }
+
+ if (mJumpToDirection > 0) // handle getting entry in forward direction
+ {
+ return mEntries.elementAt(mJumpToIndex);
+ } else { // handle getting entry in reverse direction
+ int reverse_index = mEntries.size() - mJumpToIndex - 1;
+
+ CMS.debug("reverse direction getting index " + reverse_index);
+
+ if (reverse_index < 0 || reverse_index >= mEntries.size()) {
+ CMS.debug("reverse_index out of range " + reverse_index);
+ return null;
+ }
+ return mEntries.elementAt(reverse_index);
+ }
+ }
+
+ //CMS.debug("getElementAt noJumpto: " + index);
+
+ if ((index < mTop) || (index >= mTop + mEntries.size())) { // handle the non jumpto case
+ //fetch a new page
+ //System.out.println( "fetching a page starting at " +
+ // index );
+ // CMS.debug("getElementAt noJumpto: getting page index: " + index + " mEntries.size() " + mEntries.size() + " mTop: " + mTop);
+ getPage(index);
+ }
+
+ int offset = index - mTop;
+
+ if ((offset < 0) || (offset >= mEntries.size()))
+ //XXX
+ return ("No entry at " + index);
+ else
+ return mEntries.elementAt(offset);
+ }
+
+ public Object getJumpToElementAt(int i) {
+ return mEntries.elementAt(i);
+ }
+
+ /**
+ * This function processes elements as soon as it arrives. It is
+ * more memory-efficient.
+ */
+ public void processElements(int startidx, int endidx, IElementProcessor ep)
+ throws EBaseException {
+
+ /* mSize may not be init at this time! Bad !
+ * the caller should really check the index is within bound before this
+ * but I'll take care of this just in case they are too irresponsible
+ */
+ if (!mInitialized)
+ mSize = getSize();
+
+ // short-cut the existing code ... :(
+ if (mJumpTo != null) {
+ for (int i = startidx; i <= endidx; i++) {
+ Object element = getJumpToElementAt(i);
+
+ if (element != null)
+ ep.process(element);
+ }
+ return;
+ }
+
+ //guess this is what you really mean to try to improve performance
+ if (startidx >= endidx) {
+ throw new EBaseException("startidx must be less than endidx");
+ }else {
+ setPageSize(endidx - startidx);
+ getPage(startidx);
+ }
+
+ for (int i = startidx; i <= endidx; i++) {
+ Object element = getElementAt(i);
+
+ if (element != null)
+ ep.process(element);
+ }
+ }
+
+ /**
+ * get the virutal selected index
+ */
+ public int getSelectedIndex() {
+ return mSelectedIndex;
+ }
+
+ /**
+ * get the top of the buffer
+ */
+ public int getFirstIndex() {
+ return mTop;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DateArrayMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/DateArrayMapper.java
new file mode 100644
index 000000000..e073fe633
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DateArrayMapper.java
@@ -0,0 +1,105 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java Date array object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class DateArrayMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs a date array mapper.
+ */
+ public DateArrayMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of support ldap attributes.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object to a set of attributes.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ Date dates[] = (Date[]) obj;
+
+ if (dates == null)
+ return;
+ LDAPAttribute attr = new LDAPAttribute(mLdapName);
+
+ for (int i = 0; i < dates.length; i++) {
+ attr.addValue(DateMapper.dateToDB(dates[i]));
+ }
+ attrs.add(attr);
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ Enumeration e = attr.getStringValues();
+ Vector v = new Vector();
+
+ while (e.hasMoreElements()) {
+ v.addElement(DateMapper.dateFromDB((String)
+ e.nextElement()));
+ }
+ if (v.size() == 0)
+ return;
+ Date dates[] = new Date[v.size()];
+
+ v.copyInto(dates);
+ parent.set(name, dates);
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DateMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/DateMapper.java
new file mode 100644
index 000000000..8b0009479
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/DateMapper.java
@@ -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) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmscore.dbs;
+
+
+import java.util.*;
+import java.text.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java Date object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class DateMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+ private static SimpleDateFormat formatter = new
+ SimpleDateFormat("yyyyMMddHHmmss'Z'");
+
+ /**
+ * Constructs date mapper.
+ */
+ public DateMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of ldap attribute names.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object to ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName,
+ dateToDB((Date) obj)));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ parent.set(name, dateFromDB((String)
+ attr.getStringValues().nextElement()));
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ String val = null;
+
+ try {
+ val = dateToDB(new Date(Long.parseLong(value)));
+ } catch (NumberFormatException e) {
+ val = value;
+ }
+ return mLdapName + op + val;
+ }
+
+ public synchronized static String dateToDB(Date date) {
+ return formatter.format(date);
+ }
+
+ public synchronized static Date dateFromDB(String dbDate) {
+ try {
+ return formatter.parse(dbDate);
+ } catch (ParseException e) {
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/IntegerMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/IntegerMapper.java
new file mode 100644
index 000000000..2293bea26
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/IntegerMapper.java
@@ -0,0 +1,86 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java Integer object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class IntegerMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs mapper to deal with Integer.
+ */
+ public IntegerMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of supported ldap attributes.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object to ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName,
+ ((Integer) obj).toString()));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ parent.set(name, new Integer((String)
+ attr.getStringValues().nextElement()));
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java
new file mode 100644
index 000000000..7a5e02a04
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java
@@ -0,0 +1,58 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents a collection of key record
+ * specific schema information.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KeyDBSchema {
+
+ public static final String LDAP_OC_TOP = "top";
+ public static final String LDAP_ATTR_SERIALNO = "serialno";
+ public static final String LDAP_ATTR_CREATE_TIME = "dateOfCreate";
+ public static final String LDAP_ATTR_MODIFY_TIME = "dateOfModify";
+ public static final String LDAP_ATTR_META_INFO = "metaInfo";
+ public static final String LDAP_OC_KEYRECORD = "keyRecord";
+ public static final String LDAP_ATTR_OWNER_NAME = "ownerName";
+ public static final String LDAP_ATTR_PRIVATE_KEY_DATA = "privateKeyData";
+ public static final String LDAP_ATTR_KEY_RECORD_ID = "keyRecordId";
+ public static final String LDAP_ATTR_PUBLIC_KEY_DATA = "publicKeyData";
+ public static final String LDAP_ATTR_KEY_SIZE = "keySize";
+ public static final String LDAP_ATTR_ALGORITHM = "algorithm";
+ public static final String LDAP_ATTR_STATE = "keyState";
+ public static final String LDAP_ATTR_DATE_OF_RECOVERY =
+ "dateOfRecovery";
+ public static final String LDAP_ATTR_PUBLIC_KEY_FORMAT =
+ "publicKeyFormat";
+ public static final String LDAP_ATTR_ARCHIVED_BY = "archivedBy";
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecord.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecord.java
new file mode 100644
index 000000000..7b6fcdb8d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecord.java
@@ -0,0 +1,348 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+//import netscape.security.provider.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import netscape.ldap.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.keydb.*;
+
+
+/**
+ * A class represents a Key record. It maintains the key
+ * life cycle as well as other information about an
+ * archived key. Namely, whether a key is inactive because
+ * of compromise.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KeyRecord implements IDBObj, IKeyRecord {
+
+ private BigInteger mSerialNo = null;
+ private KeyState mState = null;
+ private MetaInfo mMetaInfo = null;
+ private String mAlgorithm = null;
+ private byte mPrivateKey[] = null;
+ private byte mPublicKey[] = null;
+ private Integer mSize = null;
+ private String mOwnerName = null;
+ private Date mDatesOfRecovery[] = null;
+ private Date mCreateTime = null;
+ private Date mModifyTime = null;
+ private String mArchivedBy = null;
+
+ protected static Vector mNames = new Vector();
+ static {
+ mNames.addElement(ATTR_STATE);
+ mNames.addElement(ATTR_ID);
+ mNames.addElement(ATTR_OWNER_NAME);
+ mNames.addElement(ATTR_KEY_SIZE);
+ mNames.addElement(ATTR_ALGORITHM);
+ mNames.addElement(ATTR_PRIVATE_KEY_DATA);
+ mNames.addElement(ATTR_PUBLIC_KEY_DATA);
+ mNames.addElement(ATTR_DATE_OF_RECOVERY);
+ mNames.addElement(ATTR_META_INFO);
+ mNames.addElement(ATTR_CREATE_TIME);
+ mNames.addElement(ATTR_MODIFY_TIME);
+ mNames.addElement(ATTR_ARCHIVED_BY);
+ }
+
+ /**
+ * Constructs empty key record.
+ */
+ public KeyRecord() {
+ }
+
+ /*
+ * Constructs key record.
+ *
+ * @param key key to be archived
+ */
+ public KeyRecord(BigInteger serialNo, byte publicData[],
+ byte privateData[], String owner,
+ String algorithm, String agentId)
+ throws EBaseException {
+ mSerialNo = serialNo;
+ mPublicKey = publicData;
+ mPrivateKey = privateData;
+ mOwnerName = owner;
+ mAlgorithm = algorithm;
+ mState = KeyState.VALID;
+ mCreateTime = com.netscape.certsrv.apps.CMS.getCurrentDate();
+ mModifyTime = com.netscape.certsrv.apps.CMS.getCurrentDate();
+ mArchivedBy = agentId;
+ }
+
+ /**
+ * Sets an attribute.
+ * <P>
+ */
+ public void set(String name, Object object) throws EBaseException {
+ if (name.equalsIgnoreCase(ATTR_STATE)) {
+ mState = (KeyState) object;
+ } else if (name.equalsIgnoreCase(ATTR_ID)) {
+ mSerialNo = (BigInteger) object;
+ } else if (name.equalsIgnoreCase(ATTR_KEY_SIZE)) {
+ mSize = (Integer) object;
+ } else if (name.equalsIgnoreCase(ATTR_OWNER_NAME)) {
+ mOwnerName = (String) object;
+ } else if (name.equalsIgnoreCase(ATTR_ALGORITHM)) {
+ mAlgorithm = (String) object;
+ } else if (name.equalsIgnoreCase(ATTR_PRIVATE_KEY_DATA)) {
+ mPrivateKey = (byte[]) object;
+ } else if (name.equalsIgnoreCase(ATTR_PUBLIC_KEY_DATA)) {
+ mPublicKey = (byte[]) object;
+ } else if (name.equalsIgnoreCase(ATTR_DATE_OF_RECOVERY)) {
+ mDatesOfRecovery = (Date[]) object;
+ } else if (name.equalsIgnoreCase(ATTR_META_INFO)) {
+ mMetaInfo = (MetaInfo) object;
+ } else if (name.equalsIgnoreCase(ATTR_CREATE_TIME)) {
+ mCreateTime = (Date) object;
+ } else if (name.equalsIgnoreCase(ATTR_MODIFY_TIME)) {
+ mModifyTime = (Date) object;
+ } else if (name.equalsIgnoreCase(ATTR_ARCHIVED_BY)) {
+ mArchivedBy = (String) object;
+ } else {
+ throw new EBaseException(com.netscape.certsrv.apps.CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ /**
+ * Retrieves an attribute.
+ * <P>
+ */
+ public Object get(String name) throws EBaseException {
+ if (name.equalsIgnoreCase(ATTR_STATE)) {
+ return mState;
+ } else if (name.equalsIgnoreCase(ATTR_ID)) {
+ return mSerialNo;
+ } else if (name.equalsIgnoreCase(ATTR_KEY_SIZE)) {
+ return mSize;
+ } else if (name.equalsIgnoreCase(ATTR_OWNER_NAME)) {
+ return mOwnerName;
+ } else if (name.equalsIgnoreCase(ATTR_ALGORITHM)) {
+ return mAlgorithm;
+ } else if (name.equalsIgnoreCase(ATTR_PRIVATE_KEY_DATA)) {
+ return mPrivateKey;
+ } else if (name.equalsIgnoreCase(ATTR_PUBLIC_KEY_DATA)) {
+ return mPublicKey;
+ } else if (name.equalsIgnoreCase(ATTR_DATE_OF_RECOVERY)) {
+ return mDatesOfRecovery;
+ } else if (name.equalsIgnoreCase(ATTR_CREATE_TIME)) {
+ return mCreateTime;
+ } else if (name.equalsIgnoreCase(ATTR_MODIFY_TIME)) {
+ return mModifyTime;
+ } else if (name.equalsIgnoreCase(ATTR_META_INFO)) {
+ return mMetaInfo;
+ } else if (name.equalsIgnoreCase(ATTR_ARCHIVED_BY)) {
+ return mArchivedBy;
+ } else {
+ throw new EBaseException(com.netscape.certsrv.apps.CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ /**
+ * Deletes an attribute.
+ * <P>
+ */
+ public void delete(String name) throws EBaseException {
+ throw new EBaseException(com.netscape.certsrv.apps.CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+
+ /**
+ * Retrieves an enumeration of attributes.
+ * <P>
+ */
+ public Enumeration getElements() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieves serializable attribute names.
+ */
+ public Enumeration getSerializableAttrNames() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieves serial number of the key record. Each key record
+ * is uniquely identified by serial number.
+ * <P>
+ *
+ * @return serial number of this key record
+ */
+ public BigInteger getSerialNumber() throws EBaseException {
+ return mSerialNo;
+ }
+
+ /**
+ * Sets serial number.
+ */
+ public void setSerialNumber(BigInteger serialno) throws EBaseException {
+ mSerialNo = serialno;
+ }
+
+ /**
+ * Retrieves the key state. This gives key life cycle
+ * information.
+ * <P>
+ *
+ * @return key state
+ */
+ public KeyState getState() throws EBaseException {
+ return mState;
+ }
+
+ /**
+ * Sets key state.
+ * <P>
+ */
+ public void setState(KeyState state) throws EBaseException {
+ mState = state;
+ }
+
+ /**
+ * Retrieves the uid of person who archived this record.
+ */
+ public String getArchivedBy() {
+ return mArchivedBy;
+ }
+
+ /**
+ * Retrieves key.
+ * <P>
+ *
+ * @return archived key
+ */
+ public byte[] getPrivateKeyData() throws EBaseException {
+ return mPrivateKey;
+ }
+
+ /**
+ * Sets key data.
+ */
+ public void setPrivateKeyData(byte keydata[]) throws EBaseException {
+ mPrivateKey = keydata;
+ }
+
+ /**
+ * Retrieves the key size.
+ * <P>
+ *
+ * @return key size
+ */
+ public Integer getKeySize() throws EBaseException {
+ return mSize;
+ }
+
+ /**
+ * Sets key size.
+ * <P>
+ */
+ public void setKeySize(Integer keySize) throws EBaseException {
+ mSize = keySize;
+ }
+
+ /**
+ * Retrieves owner name.
+ * <P>
+ */
+ public String getOwnerName() throws EBaseException {
+ return mOwnerName;
+ }
+
+ /**
+ * Sets owner name.
+ * <P>
+ */
+ public void setOwnerName(String name) throws EBaseException {
+ mOwnerName = name;
+ }
+
+ /**
+ * Retrieves the public key.
+ * <P>
+ */
+ public byte[] getPublicKeyData() throws EBaseException {
+ return mPublicKey;
+ }
+
+ /**
+ * Sets the public key.
+ * <P>
+ */
+ public void setPublicKeyData(byte key[]) throws EBaseException {
+ mPublicKey = key;
+ }
+
+ /**
+ * Retrieves the date(s) of revocation.
+ * <P>
+ */
+ public Date[] getDateOfRevocation() throws EBaseException {
+ return mDatesOfRecovery;
+ }
+
+ /**
+ * Sets the dateso of revocation.
+ * <P>
+ */
+ public void setDateOfRevocation(Date dates[]) throws EBaseException {
+ mDatesOfRecovery = dates;
+ }
+
+ /**
+ * Retrieves algorithm of the key pair.
+ */
+ public String getAlgorithm() {
+ return mAlgorithm;
+ }
+
+ public MetaInfo getMetaInfo() {
+ return mMetaInfo;
+ }
+
+ /**
+ * Retrieves the creation time of this record.
+ */
+ public Date getCreateTime() {
+ return mCreateTime;
+ }
+
+ /**
+ * Retrieves the last modification time of
+ * this record.
+ */
+ public Date getModifyTime() {
+ return mModifyTime;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordList.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordList.java
new file mode 100644
index 000000000..250e66e6c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordList.java
@@ -0,0 +1,93 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.cmscore.dbs.*;
+
+
+/**
+ * A class represents a list of key records.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KeyRecordList implements IKeyRecordList {
+
+ private IDBVirtualList mVlist = null;
+
+ /**
+ * Constructs a key list.
+ */
+ public KeyRecordList(IDBVirtualList vlist) {
+ mVlist = vlist;
+ }
+
+ /**
+ * Retrieves the size of key list.
+ */
+ public int getSize() {
+ return mVlist.getSize();
+ }
+
+ public int getSizeBeforeJumpTo() {
+
+ return mVlist.getSizeBeforeJumpTo();
+
+ }
+
+ public int getSizeAfterJumpTo() {
+
+ return mVlist.getSizeAfterJumpTo();
+ }
+
+ public IKeyRecord getKeyRecord(int i) {
+ KeyRecord record = (KeyRecord) mVlist.getElementAt(i);
+
+ if (record == null) return null;
+
+ return record;
+ }
+ /**
+ * Retrieves requests.
+ */
+ public Enumeration getKeyRecords(int startidx, int endidx)
+ throws EBaseException {
+ Vector entries = new Vector();
+
+ for (int i = startidx; i <= endidx; i++) {
+ Object element = mVlist.getElementAt(i);
+
+ if (element != null) {
+ entries.addElement(element);
+ }
+ }
+ if (entries != null) {
+ return entries.elements();
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordMapper.java
new file mode 100644
index 000000000..eaaf3779f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecordMapper.java
@@ -0,0 +1,111 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import java.security.cert.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents a mapper to serialize
+ * key record into database.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KeyRecordMapper implements IDBAttrMapper {
+
+ private IKeyRepository mDB = null;
+ private ILogger mLogger = CMS.getLogger();
+
+ public KeyRecordMapper(IKeyRepository db) {
+ mDB = db;
+ }
+
+ public Enumeration getSupportedLDAPAttributeNames() {
+ Vector v = new Vector();
+
+ v.addElement(KeyDBSchema.LDAP_ATTR_KEY_RECORD_ID);
+ return v.elements();
+ }
+
+ public void mapObjectToLDAPAttributeSet(IDBObj parent, String name,
+ Object obj, LDAPAttributeSet attrs) throws EBaseException {
+ try {
+ KeyRecord rec = (KeyRecord) obj;
+
+ attrs.add(new LDAPAttribute(KeyDBSchema.LDAP_ATTR_KEY_RECORD_ID,
+ rec.getSerialNumber().toString()));
+ } catch (Exception e) {
+
+ /*LogDoc
+ *
+ * @phase Maps object to ldap attribute set
+ * @message KeyRecordMapper: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_KEYRECORD_MAPPER_ERROR", e.toString()));
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_SERIALIZE_FAILED", name));
+ }
+ }
+
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ try {
+ LDAPAttribute attr = attrs.getAttribute(
+ KeyDBSchema.LDAP_ATTR_KEY_RECORD_ID);
+
+ if (attr == null)
+ return;
+ String serialno = (String) attr.getStringValues().nextElement();
+ IKeyRecord rec = mDB.readKeyRecord(new
+ BigInteger(serialno));
+
+ parent.set(name, rec);
+ } catch (Exception e) {
+
+ /*LogDoc
+ *
+ * @phase Maps ldap attribute set to object
+ * @message KeyRecordMapper: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_KEYRECORD_MAPPER_ERROR", e.toString()));
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_DESERIALIZE_FAILED", name));
+ }
+ }
+
+ public String mapSearchFilter(String name, String op, String value)
+ throws EBaseException {
+ return name + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java
new file mode 100644
index 000000000..06b5f2614
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java
@@ -0,0 +1,553 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmscore.util.*;
+import com.netscape.cmscore.dbs.*;
+
+
+/**
+ * A class represents a Key repository. This is the container of
+ * archived keys.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KeyRepository extends Repository implements IKeyRepository {
+
+ public KeyStatusUpdateThread mKeyStatusUpdateThread = null;
+ protected IDBSubsystem mDBService = null;
+
+ /**
+ * Internal constants
+ */
+ private String mBaseDN = null;
+
+ /**
+ * Constructs a key repository. It checks if the key repository
+ * does exist. If not, it creates the repository.
+ * <P>
+ *
+ * @param service db service
+ * @exception EBaseException failed to setup key repository
+ */
+ public KeyRepository(IDBSubsystem service, int increment, String baseDN)
+ throws EDBException {
+ super(service, increment, baseDN);
+ mBaseDN = baseDN;
+ mDBService = service;
+
+ // register key record schema
+ IDBRegistry reg = service.getRegistry();
+ String keyRecordOC[] = new String[2];
+
+ keyRecordOC[0] = KeyDBSchema.LDAP_OC_TOP;
+ keyRecordOC[1] = KeyDBSchema.LDAP_OC_KEYRECORD;
+
+ if (!reg.isObjectClassRegistered(KeyRecord.class.getName())) {
+ reg.registerObjectClass(KeyRecord.class.getName(),
+ keyRecordOC);
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_ID)) {
+ reg.registerAttribute(KeyRecord.ATTR_ID, new
+ BigIntegerMapper(KeyDBSchema.LDAP_ATTR_SERIALNO));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_ALGORITHM)) {
+ reg.registerAttribute(KeyRecord.ATTR_ALGORITHM, new
+ StringMapper(KeyDBSchema.LDAP_ATTR_ALGORITHM));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_STATE)) {
+ reg.registerAttribute(KeyRecord.ATTR_STATE, new
+ KeyStateMapper(KeyDBSchema.LDAP_ATTR_STATE));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_KEY_SIZE)) {
+ reg.registerAttribute(KeyRecord.ATTR_KEY_SIZE, new
+ IntegerMapper(KeyDBSchema.LDAP_ATTR_KEY_SIZE));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_OWNER_NAME)) {
+ reg.registerAttribute(KeyRecord.ATTR_OWNER_NAME, new
+ StringMapper(KeyDBSchema.LDAP_ATTR_OWNER_NAME));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_PRIVATE_KEY_DATA)) {
+ reg.registerAttribute(KeyRecord.ATTR_PRIVATE_KEY_DATA, new
+ ByteArrayMapper(KeyDBSchema.LDAP_ATTR_PRIVATE_KEY_DATA));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_PUBLIC_KEY_DATA)) {
+ reg.registerAttribute(KeyRecord.ATTR_PUBLIC_KEY_DATA, new
+ PublicKeyMapper(KeyDBSchema.LDAP_ATTR_PUBLIC_KEY_DATA));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_DATE_OF_RECOVERY)) {
+ reg.registerAttribute(KeyRecord.ATTR_DATE_OF_RECOVERY, new
+ DateArrayMapper(KeyDBSchema.LDAP_ATTR_DATE_OF_RECOVERY));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_CREATE_TIME)) {
+ reg.registerAttribute(KeyRecord.ATTR_CREATE_TIME, new
+ DateMapper(KeyDBSchema.LDAP_ATTR_CREATE_TIME));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_MODIFY_TIME)) {
+ reg.registerAttribute(KeyRecord.ATTR_MODIFY_TIME, new
+ DateMapper(KeyDBSchema.LDAP_ATTR_MODIFY_TIME));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_META_INFO)) {
+ reg.registerAttribute(KeyRecord.ATTR_META_INFO, new
+ MetaInfoMapper(KeyDBSchema.LDAP_ATTR_META_INFO));
+ }
+ if (!reg.isAttributeRegistered(KeyRecord.ATTR_ARCHIVED_BY)) {
+ reg.registerAttribute(KeyRecord.ATTR_ARCHIVED_BY, new
+ StringMapper(KeyDBSchema.LDAP_ATTR_ARCHIVED_BY));
+ }
+ }
+
+ public void setKeyStatusUpdateInterval(IRepository requestRepo, int interval) {
+ CMS.debug("In setKeyStatusUpdateInterval " + interval);
+ // don't run the thread if serial management is disabled.
+ if ((interval == 0) || (!mDBService.getEnableSerialMgmt())) {
+ CMS.debug("In setKeyStatusUpdateInterval interval = 0" + interval);
+ if (mKeyStatusUpdateThread != null) {
+ mKeyStatusUpdateThread.stop();
+ }
+ return;
+ }
+
+ CMS.debug("In setKeyStatusUpdateInterval mKeyStatusUpdateThread " + mKeyStatusUpdateThread);
+ if (mKeyStatusUpdateThread == null) {
+ CMS.debug("In setKeyStatusUpdateInterval about to create KeyStatusUpdateThread ");
+ mKeyStatusUpdateThread = new KeyStatusUpdateThread(this, requestRepo, "KeyStatusUpdateThread");
+ mKeyStatusUpdateThread.setInterval(interval);
+ mKeyStatusUpdateThread.start();
+ } else {
+ CMS.debug("In setKeyStatusUpdateInterval it thinks the thread is up already ");
+ mKeyStatusUpdateThread.setInterval(interval);
+ // dont do anything if we have a thread running already
+ }
+ }
+
+ public IDBSubsystem getDBSubsystem() {
+ return mDBService;
+ }
+
+ /**
+ * Retrieves the DN of this repository.
+ */
+ public String getDN() {
+ return mBaseDN;
+ }
+
+ /**
+ * Removes all objects with this repository.
+ */
+ public void removeAllObjects() throws EBaseException
+ {
+ String filter = "(" + KeyRecord.ATTR_OWNER_NAME + "=*" + ")";
+ IKeyRecordList list = findKeyRecordsInList(filter,
+ null, "serialno", 10);
+ int size = list.getSize();
+ Enumeration e = list.getKeyRecords(0, size - 1);
+ while (e.hasMoreElements()) {
+ KeyRecord rec = (KeyRecord) e.nextElement();
+ deleteKeyRecord(rec.getSerialNumber());
+ }
+ }
+
+ /**
+ * Archives a key to the repository.
+ * <P>
+ *
+ * @param record key record
+ * @exception EBaseException failed to archive key
+ */
+ public void addKeyRecord(IKeyRecord record) throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" +
+ ((KeyRecord) record).getSerialNumber().toString() + "," + getDN();
+
+ if (s != null) s.add(name, (KeyRecord) record);
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ /**
+ * Recovers an archived key by serial number.
+ * <P>
+ *
+ * @param serialNo serial number
+ * @return key record
+ * @exception EBaseException failed to recover key
+ */
+ public IKeyRecord readKeyRecord(BigInteger serialNo)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ KeyRecord rec = null;
+
+ try {
+ String name = "cn" + "=" +
+ serialNo.toString() + "," + getDN();
+
+ if (s != null) rec = (KeyRecord) s.read(name);
+ } finally {
+ if (s != null) s.close();
+ }
+ return rec;
+ }
+
+ /**
+ * Recovers an archived key by owner name.
+ * <P>
+ *
+ * @param ownerName owner name
+ * @return key record
+ * @exception EBaseException failed to recover key
+ */
+ public IKeyRecord readKeyRecord(X500Name ownerName)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ KeyRecord keyRec = null;
+
+ try {
+ if (ownerName != null) {
+ String filter = "(" + KeyRecord.ATTR_OWNER_NAME + "=" +
+ ownerName.toString() + ")";
+ IDBSearchResults res = s.search(getDN(), filter);
+
+ keyRec = (KeyRecord) res.nextElement();
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return keyRec;
+ }
+
+ /**
+ * Recovers archived key using public key.
+ */
+ public IKeyRecord readKeyRecord(PublicKey publicKey)
+ throws EBaseException {
+ // XXX - setup binary search attributes
+ byte data[] = publicKey.getEncoded();
+
+ if (data == null)
+ throw new EBaseException("null data");
+ IDBSSession s = mDBService.createSession();
+ KeyRecord rec = null;
+
+ try {
+ String filter = "(" + KeyRecord.ATTR_PUBLIC_KEY_DATA + "=" +
+ escapeBinaryData(data) + ")";
+ if( s != null ) {
+ IDBSearchResults res = s.search(getDN(), filter);
+
+ rec = (KeyRecord) res.nextElement();
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return rec;
+ }
+
+
+ /**
+ * Recovers archived key using b64 encoded cert
+ */
+ public IKeyRecord readKeyRecord(String cert)
+ throws EBaseException {
+
+ IDBSSession s = mDBService.createSession();
+ KeyRecord rec = null;
+
+ try {
+ String filter = "(publicKey=x509cert#\"" +cert+"\")";
+CMS.debug("filter= " + filter);
+
+ if( s != null ) {
+ IDBSearchResults res = s.search(getDN(), filter);
+
+ rec = (KeyRecord) res.nextElement();
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return rec;
+ }
+
+ /**
+ * Modifies key record.
+ */
+ public void modifyKeyRecord(BigInteger serialNo, ModificationSet mods)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" +
+ serialNo.toString() + "," + getDN();
+
+ mods.add(KeyRecord.ATTR_MODIFY_TIME, Modification.MOD_REPLACE,
+ new Date());
+ if (s != null) s.modify(name, mods);
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ public void deleteKeyRecord(BigInteger serialNo)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+
+ try {
+ String name = "cn" + "=" +
+ serialNo.toString() + "," + getDN();
+
+ if (s != null) s.delete(name);
+ } finally {
+ if (s != null) s.close();
+ }
+ }
+
+ /**
+ * Read RFC-2254
+ */
+ public static String escapeBinaryData(byte data[]) {
+ String result = "";
+
+ for (int i = 0; i < data.length; i++) {
+ result = result + "\\" + Integer.toHexString((int) data[i]);
+ }
+ return result;
+ }
+
+ public Enumeration searchKeys(String filter, int maxSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ e = s.search(getDN(), filter, maxSize);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ public Enumeration searchKeys(String filter, int maxSize, int timeLimit)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ Enumeration e = null;
+
+ try {
+ e = s.search(getDN(), filter, maxSize, timeLimit);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ return e;
+ }
+
+ /**
+ * Retrieves key record list.
+ */
+ public IKeyRecordList findKeyRecordsInList(String filter,
+ String attrs[], int pageSize) throws EBaseException {
+ return findKeyRecordsInList(filter, attrs, IKeyRecord.ATTR_ID,
+ pageSize);
+ }
+
+ public IKeyRecordList findKeyRecordsInList(String filter,
+ String attrs[], String sortKey, int pageSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ IKeyRecordList list = null;
+
+ try {
+ if (s != null) {
+ list = new KeyRecordList(
+ s.createVirtualList(getDN(), "(&(objectclass=" +
+ KeyRecord.class.getName() + ")" + filter + ")",
+ attrs, sortKey, pageSize));
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return list;
+ }
+
+ public IKeyRecordList findKeyRecordsInList(String filter,
+ String attrs[],String jumpTo, String sortKey, int pageSize)
+ throws EBaseException {
+ IDBSSession s = mDBService.createSession();
+ IKeyRecordList list = null;
+
+ int len = jumpTo.length();
+
+ String jumpToVal = null;
+
+ if (len > 9) {
+ jumpToVal = Integer.toString(len) + jumpTo;
+ } else {
+ jumpToVal = "0" + Integer.toString(len) + jumpTo;
+ }
+
+ try {
+ if (s != null) {
+ list = new KeyRecordList(
+ s.createVirtualList(getDN(), "(&(objectclass=" +
+ KeyRecord.class.getName() + ")" + filter + ")",
+ attrs,jumpToVal, sortKey, pageSize));
+ }
+ } finally {
+ if (s != null) s.close();
+ }
+ return list;
+ }
+
+ public BigInteger getLastSerialNumberInRange(BigInteger serial_low_bound, BigInteger serial_upper_bound) throws
+ EBaseException {
+
+ CMS.debug("KeyRepository: in getLastSerialNumberInRange: low " + serial_low_bound + " high " + serial_upper_bound);
+
+ if(serial_low_bound == null || serial_upper_bound == null || serial_low_bound.compareTo(serial_upper_bound) >= 0)
+ {
+ return null;
+ }
+
+ String ldapfilter = "(" + "serialno" + "=*" + ")";
+ String[] attrs = null;
+
+ KeyRecordList recList = (KeyRecordList) findKeyRecordsInList(ldapfilter,attrs,serial_upper_bound.toString(10),"serialno", 5 * -1);
+
+ int size = recList.getSize();
+
+ CMS.debug("KeyRepository: getLastSerialNumberInRange: recList size " + size);
+
+ if (size <= 0) {
+ CMS.debug("KeyRepository: getLastSerialNumberInRange: index may be empty");
+
+ BigInteger ret = new BigInteger(serial_low_bound.toString(10));
+
+ ret = ret.add(new BigInteger("-1"));
+
+ CMS.debug("KeyRepository: getLastSerialNumberInRange returning: " + ret );
+ return ret;
+ }
+ int ltSize = recList.getSizeBeforeJumpTo();
+
+ Vector cList = new Vector(ltSize);
+
+ CMS.debug("KeyRepository:getLastSerialNumberInRange: ltSize " + ltSize);
+
+ int i;
+ KeyRecord curRec = null;
+
+ for (i = 0; i < 5; i++) {
+ curRec = (KeyRecord) recList.getKeyRecord(i);
+
+ if (curRec != null) {
+
+ BigInteger serial = curRec.getSerialNumber();
+
+ CMS.debug("KeyRepository: getLastCertRecordSerialNo: serialno " + serial);
+
+ if( ((serial.compareTo(serial_low_bound) == 0) || (serial.compareTo(serial_low_bound) == 1) ) &&
+ ((serial.compareTo(serial_upper_bound) == 0) || (serial.compareTo(serial_upper_bound) == -1) ))
+ {
+ CMS.debug("KeyRepository: getLastSerialNumberInRange returning: " + serial);
+ return serial;
+ }
+ } else {
+ CMS.debug("KeyRepository: getLastSerialNumberInRange:found null from getCertRecord");
+ }
+ }
+
+ BigInteger ret = new BigInteger(serial_low_bound.toString(10));
+
+ ret = ret.add(new BigInteger("-1"));
+
+ CMS.debug("KeyRepository: getLastSerialNumberInRange returning: " + ret );
+ return ret ;
+
+ }
+
+ public void shutdown() {
+ if (mKeyStatusUpdateThread != null)
+ mKeyStatusUpdateThread.destroy();
+ }
+
+}
+
+class KeyStatusUpdateThread extends Thread {
+ KeyRepository _kr = null;
+ IRepository _rr = null;
+ int _interval;
+
+ KeyStatusUpdateThread(KeyRepository kr, IRepository rr, String name) {
+ super(name);
+ CMS.debug("new KeyStatusUpdateThread");
+
+ _kr = kr;
+ _rr = rr;
+ }
+
+ public void setInterval(int interval) {
+ _interval = interval;
+ }
+
+ public void run() {
+ CMS.debug("Inside run method of KeyStatusUpdateThread");
+
+ while (true) {
+ try {
+ // block the update while another thread
+ // (such as the CRL Update) is running
+ CMS.debug("About to start checkRanges");
+ synchronized (_kr.mKeyStatusUpdateThread) {
+ CMS.debug("Starting key checkRanges");
+ _kr.checkRanges();
+ CMS.debug("key checkRanges done");
+
+ CMS.debug("Starting request checkRanges");
+ _rr.checkRanges();
+ CMS.debug("request checkRanges done");
+ }
+ } catch (Exception e) {
+ CMS.debug("key checkRanges done");
+ }
+ try {
+ sleep(_interval * 1000);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+}
+
+
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyStateMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyStateMapper.java
new file mode 100644
index 000000000..0630efa7c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyStateMapper.java
@@ -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.cmscore.dbs;
+
+
+import java.util.*;
+import java.math.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.keydb.*;
+
+
+/**
+ * A class represents a key state mapper.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class KeyStateMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+
+ public KeyStateMapper(String ldapName) {
+ mLdapName = ldapName;
+ }
+
+ public Enumeration getSupportedLDAPAttributeNames() {
+ Vector v = new Vector();
+
+ v.addElement(mLdapName);
+ return v.elements();
+ }
+
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName,
+ ((KeyState) obj).toString()));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null) {
+ return;
+ }
+ parent.set(name, KeyState.toKeyState(
+ ((String) attr.getStringValues().nextElement())));
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/LdapFilterConverter.java b/pki/base/common/src/com/netscape/cmscore/dbs/LdapFilterConverter.java
new file mode 100644
index 000000000..db5db02c9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/LdapFilterConverter.java
@@ -0,0 +1,61 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents a filter converter
+ * that understands how to convert a attribute
+ * type from one defintion to another.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class LdapFilterConverter implements IFilterConverter {
+
+ private Hashtable mReg = null;
+
+ /**
+ * Constructs filter convertor.
+ */
+ public LdapFilterConverter(Hashtable reg) {
+ mReg = reg;
+ }
+
+ /**
+ * Converts database filter to ldap filter.
+ */
+ public String convert(String name, String op, String value) {
+ AttributeNameHelper h = new AttributeNameHelper(name);
+ IDBAttrMapper mapper = (IDBAttrMapper) mReg.get(
+ h.getPrefix().toLowerCase());
+
+ if (mapper == null)
+ return null;
+ try {
+ return mapper.mapSearchFilter(name, op, value);
+ } catch (EBaseException e) {
+ }
+ return null;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/LongMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/LongMapper.java
new file mode 100644
index 000000000..9006081f5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/LongMapper.java
@@ -0,0 +1,117 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.math.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java Long object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class LongMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs Long mapper.
+ */
+ public LongMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Returns a list of supported ldap attribute names.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object into ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName,
+ LongToDB((Long) obj)));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ parent.set(name, LongFromDB(
+ (String) attr.getStringValues().nextElement()));
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ String v = null;
+
+ try {
+ if (value.startsWith("0x") || value.startsWith("0X")) {
+ v = LongToDB(Long.valueOf(value.substring(2), 16));
+ } else {
+ v = LongToDB(Long.valueOf(value));
+ }
+ } catch (NumberFormatException e) {
+ v = value;
+ }
+ return mLdapName + op + v;
+ }
+
+ public static String LongToDB(Long i) {
+ int len = i.toString().length();
+ String ret = null;
+
+ if (len < 10) {
+ ret = "0" + Integer.toString(len) + i.toString();
+ } else {
+ ret = Integer.toString(len) + i.toString();
+ }
+ return ret;
+ }
+
+ public static Long LongFromDB(String i) {
+ String s = i.substring(2);
+
+ // possibly check length
+ return new Long(s);
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/MetaInfoMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/MetaInfoMapper.java
new file mode 100644
index 000000000..c3248ec12
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/MetaInfoMapper.java
@@ -0,0 +1,119 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.math.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represent mapper for metainfo attribute. Metainfo
+ * is in format of the following:
+ *
+ * <PRE>
+ * metaInfoType:metaInfoValue
+ * metaInfoType:metaInfoValue
+ * metaInfoType:metaInfoValue
+ * metaInfoType:metaInfoValue
+ * </PRE>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class MetaInfoMapper implements IDBAttrMapper {
+
+ public static final String SEP = ":";
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs a metainfo object.
+ */
+ public MetaInfoMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Returns a list of supported ldap attribute names.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object into ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ MetaInfo info = (MetaInfo) obj;
+ Enumeration e = info.getElements();
+
+ if (!e.hasMoreElements())
+ return; // dont add anything
+ LDAPAttribute attr = new LDAPAttribute(mLdapName);
+
+ while (e.hasMoreElements()) {
+ String s = null;
+ String attrName = (String) e.nextElement();
+ String value = (String) info.get(attrName);
+
+ s = attrName + SEP + value;
+ attr.addValue(s);
+ }
+ attrs.add(attr);
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object into
+ * 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ Enumeration values = attr.getStringValues();
+ MetaInfo info = new MetaInfo();
+
+ while (values.hasMoreElements()) {
+ String s = (String) values.nextElement();
+ StringTokenizer st = new StringTokenizer(s, SEP);
+
+ info.set(st.nextToken(), st.nextToken());
+ }
+ parent.set(name, info);
+ }
+
+ /**
+ * Map search filters into LDAP search filter.
+ * Possible search filter:
+ * (&(metaInfo=reserver0:value0)(metaInfo=reserved1:value1))
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/ObjectStreamMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/ObjectStreamMapper.java
new file mode 100644
index 000000000..5c02b4014
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/ObjectStreamMapper.java
@@ -0,0 +1,135 @@
+// --- 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.cmscore.dbs;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Enumeration;
+import java.util.Vector;
+import netscape.ldap.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.EDBException;
+import com.netscape.certsrv.dbs.IDBAttrMapper;
+import com.netscape.certsrv.dbs.IDBObj;
+import com.netscape.certsrv.logging.ILogger;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class ObjectStreamMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs object stream mapper.
+ */
+ public ObjectStreamMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of supported ldap attributes.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object to ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent, String name,
+ Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(bos);
+
+ os.writeObject(obj);
+ byte data[] = bos.toByteArray();
+ if (data == null) {
+ CMS.debug("ObjectStreamMapper:mapObjectToLDAPAttributeSet " +
+ name + " size=0");
+ } else {
+ CMS.debug("ObjectStreamMapper:mapObjectToLDAPAttributeSet " +
+ name + " size=" + data.length);
+ }
+ attrs.add(new LDAPAttribute(mLdapName,
+ data));
+ } catch (IOException e) {
+
+ /*LogDoc
+ *
+ * @phase Maps object to ldap attribute set
+ * @message ObjectStreamMapper: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_OBJECTSTREAM_MAPPER_ERROR",
+ e.toString()));
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_SERIALIZE_FAILED", name));
+ }
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ try {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null) {
+ return;
+ }
+ ByteArrayInputStream bis = new ByteArrayInputStream(
+ (byte[]) attr.getByteValues().nextElement());
+ ObjectInputStream is = new ObjectInputStream(bis);
+
+ parent.set(name, is.readObject());
+ } catch (IOException e) {
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_DESERIALIZE_FAILED", name));
+ } catch (ClassNotFoundException e) {
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_DESERIALIZE_FAILED", name));
+ }
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/PublicKeyMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/PublicKeyMapper.java
new file mode 100644
index 000000000..4d93f843a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/PublicKeyMapper.java
@@ -0,0 +1,150 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import java.security.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cmscore.cert.*;
+
+
+/**
+ * A class represents an attribute mapper that maps
+ * a public key data into LDAP attribute and
+ * vice versa.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class PublicKeyMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs a byte array mapper.
+ */
+ public PublicKeyMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Lists a list of supported ldap attribute names.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps object to ldap attribute set.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName, (byte[]) obj));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null) {
+ return;
+ }
+ parent.set(name, (byte[]) attr.getByteValues().nextElement());
+ }
+
+ /**
+ * Maps search filters into LDAP search filter. It knows
+ * how to extract public key from the certificate.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ int i = value.indexOf("#");
+
+ if (i != -1) {
+ String tag = value.substring(0, i);
+ String val = value.substring(i + 1);
+
+ try {
+ if (val.startsWith("\"")) {
+ val = val.substring(1, val.length() - 1);
+ }
+ X509Certificate cert = CertUtils.mapCert(val);
+ PublicKey key = cert.getPublicKey();
+ byte pub[] = key.getEncoded();
+
+ return mLdapName + op + escapeBinaryData(pub);
+ } catch (Exception e) {
+
+ /*LogDoc
+ *
+ * @phase Maps search filters into LDAP search filter
+ * @message PublicKeyMapper: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_PUBLICKEY_MAPPER_ERROR",
+ e.toString()));
+ }
+ }
+ return mLdapName + op + value;
+ }
+
+ private String normalize(String s) {
+ String val = "";
+
+ for (int i = 0; i < s.length(); i++) {
+ if (s.charAt(i) == '\n') {
+ continue;
+ } else if (s.charAt(i) == '\r') {
+ continue;
+ } else if (s.charAt(i) == '"') {
+ continue;
+ }
+ val += s.charAt(i);
+ }
+ return val;
+ }
+
+ public static String escapeBinaryData(byte data[]) {
+ String result = "";
+
+ for (int i = 0; i < data.length; i++) {
+ int v = 0xff & data[i];
+
+ result = result + "\\" + (v < 16 ? "0" : "") +
+ Integer.toHexString(v);
+ }
+ return result;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.java b/pki/base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.java
new file mode 100644
index 000000000..ddf292b12
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.java
@@ -0,0 +1,82 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.BigInteger;
+
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.replicadb.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.CMS;
+
+/**
+ * A class represents a replica repository. It
+ * creates unique managed replica IDs.
+ * <P>
+ *
+ * @author alee
+ * @version $Revision$, $Date$
+ */
+public class ReplicaIDRepository extends Repository
+ implements IReplicaIDRepository {
+
+ private IDBSubsystem mDBService;
+ private String mBaseDN;
+
+ /**
+ * Constructs a certificate repository.
+ */
+ public ReplicaIDRepository(IDBSubsystem dbService, int increment, String baseDN)
+ throws EDBException {
+ super(dbService, increment, baseDN);
+ mBaseDN = baseDN;
+ mDBService = dbService;
+ }
+
+
+ /**
+ * Returns last serial number in given range
+ */
+ public BigInteger getLastSerialNumberInRange(BigInteger serial_low_bound, BigInteger serial_upper_bound)
+ throws EBaseException {
+ CMS.debug("ReplicaIDReposoitory: in getLastSerialNumberInRange: low " + serial_low_bound + " high " + serial_upper_bound);
+ if(serial_low_bound == null || serial_upper_bound == null || serial_low_bound.compareTo(serial_upper_bound) >= 0 ) {
+ return null;
+ }
+ BigInteger ret = new BigInteger(getMinSerial());
+ if ((ret==null) || (ret.compareTo(serial_upper_bound) >0) || (ret.compareTo(serial_low_bound) <0)) {
+ return null;
+ }
+ return ret;
+ }
+
+ /**
+ * Retrieves DN of this repository.
+ */
+ public String getDN() {
+ return mBaseDN;
+ }
+
+ /**
+ * Retrieves backend database handle.
+ */
+ public IDBSubsystem getDBSubsystem() {
+ return mDBService;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/Repository.java b/pki/base/common/src/com/netscape/cmscore/dbs/Repository.java
new file mode 100644
index 000000000..df84b1156
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/Repository.java
@@ -0,0 +1,504 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.repository.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.dbs.replicadb.*;
+
+/**
+ * A class represents a generic repository. It maintains unique
+ * serial number within repository.
+ * <P>
+ * To build domain specific repository, subclass should be
+ * created.
+ * <P>
+ *
+ * @author galperin
+ * @author thomask
+ * @version $Revision: 1.4
+ *
+ $, $Date$
+ */
+
+public abstract class Repository implements IRepository {
+
+ private static final BigInteger BI_ONE = new BigInteger("1");
+ private BigInteger BI_INCREMENT = null;
+ private static final BigInteger BI_ZERO = new BigInteger("0");
+ // (the next serialNo to be issued) - 1
+ private BigInteger mSerialNo = null;
+ // the serialNo attribute stored in db
+ private BigInteger mNext = null;
+
+ private String mMaxSerial = null;
+ private String mMinSerial = null;
+ private String mNextMaxSerial = null;
+ private String mNextMinSerial = null;
+
+ private BigInteger mMinSerialNo = null;
+ private BigInteger mMaxSerialNo = null;
+ private BigInteger mNextMinSerialNo = null;
+ private BigInteger mNextMaxSerialNo = null;
+
+ private BigInteger mIncrementNo = null;
+ private BigInteger mLowWaterMarkNo = null;
+
+ private IDBSubsystem mDB = null;
+ private String mBaseDN = null;
+ private boolean mInit = false;
+ private int mRadix = 10;
+ private int mRepo = -1;
+
+
+ private BigInteger mLastSerialNo = null;
+ /**
+ * Constructs a repository.
+ * <P>
+ */
+ public Repository(IDBSubsystem db, int increment, String baseDN)
+ throws EDBException {
+ mDB = db;
+ mBaseDN = baseDN;
+
+
+ BI_INCREMENT = new BigInteger(Integer.toString(increment));
+
+ // register schema
+ IDBRegistry reg = db.getRegistry();
+
+ /**
+ if (!reg.isObjectClassRegistered(
+ RepositoryRecord.class.getName())) {
+ String repRecordOC[] = new String[2];
+ repRecordOC[0] = RepositorySchema.LDAP_OC_TOP;
+ repRecordOC[1] = RepositorySchema.LDAP_OC_REPOSITORY;
+ reg.registerObjectClass(
+ RepositoryRecord.class.getName(), repRecordOC);
+ }
+ if (!reg.isAttributeRegistered(RepositoryRecord.ATTR_SERIALNO)) {
+ reg.registerAttribute(RepositoryRecord.ATTR_SERIALNO,
+ new BigIntegerMapper(RepositorySchema.LDAP_ATTR_SERIALNO));
+ }
+ **/
+ }
+
+ /**
+ * Resets serial number.
+ */
+ public void resetSerialNumber(BigInteger serial) throws EBaseException
+ {
+ IDBSSession s = mDB.createSession();
+
+ try {
+ String name = mBaseDN;
+ ModificationSet mods = new ModificationSet();
+ mods.add(IRepositoryRecord.ATTR_SERIALNO,
+ Modification.MOD_REPLACE, serial);
+ s.modify(name, mods);
+ } finally {
+ if (s != null)
+ s.close();
+ }
+ }
+
+ /**
+ * Retrieves the next serial number attr in db.
+ * <P>
+ *
+ * @return next serial number
+ */
+ protected BigInteger getSerialNumber() throws EBaseException {
+ IDBSSession s = mDB.createSession();
+
+ CMS.debug("Repository: getSerialNumber.");
+ RepositoryRecord rec = null;
+
+ try {
+ if (s != null) rec = (RepositoryRecord) s.read(mBaseDN);
+ } finally {
+ if (s != null) s.close();
+ }
+
+ if( rec == null ) {
+ CMS.debug( "Repository::getSerialNumber() - "
+ + "- rec is null!" );
+ throw new EBaseException( "rec is null" );
+ }
+
+ BigInteger serial = rec.getSerialNumber();
+
+ if (!mInit) {
+ // cms may crash after issue a cert but before update
+ // the serial number record
+ try {
+ IDBObj obj = s.read("cn=" +
+ serial + "," + mBaseDN);
+
+ if (obj != null) {
+ serial = serial.add(BI_ONE);
+ setSerialNumber(serial);
+ }
+ }catch (EBaseException e) {
+ // do nothing
+ }
+ mInit = true;
+ }
+ return serial;
+ }
+
+ /**
+ * Updates the serial number to the specified in db.
+ * <P>
+ *
+ * @param num serial number
+ */
+ protected void setSerialNumber(BigInteger num) throws EBaseException {
+
+ CMS.debug("Repository:setSerialNumber " + num.toString());
+
+ return;
+
+ }
+
+ /**
+ * Get the maximum serial number.
+ *
+ * @return maximum serial number
+ */
+ public String getMaxSerial() {
+ return mMaxSerial;
+ }
+
+ /**
+ * Set the maximum serial number.
+ *
+ * @param serial maximum number
+ * @exception EBaseException failed to set maximum serial number
+ */
+ public void setMaxSerial(String serial) throws EBaseException {
+ BigInteger maxSerial = null;
+ CMS.debug("Repository:setMaxSerial " + serial);
+
+ maxSerial = new BigInteger(serial, mRadix);
+ if (maxSerial != null) {
+ mMaxSerial = serial;
+ mMaxSerialNo = maxSerial;
+ }
+ }
+
+ /**
+ * Get the maximum serial number in next range.
+ *
+ * @return maximum serial number in next range
+ */
+ public String getNextMaxSerial() {
+ return mNextMaxSerial;
+ }
+
+ /**
+ * Set the maximum serial number in next range
+ *
+ * @param serial maximum number in next range
+ * @exception EBaseException failed to set maximum serial number in next range
+ */
+ public void setNextMaxSerial(String serial) throws EBaseException {
+ BigInteger maxSerial = null;
+ CMS.debug("Repository:setNextMaxSerial " + serial);
+
+ maxSerial = new BigInteger(serial, mRadix);
+ if (maxSerial != null) {
+ mNextMaxSerial = serial;
+ mNextMaxSerialNo = maxSerial;
+ }
+
+ return;
+ }
+
+ /**
+ * Get the minimum serial number.
+ *
+ * @return minimum serial number
+ */
+ public String getMinSerial() {
+ return mMinSerial;
+ }
+
+
+ /**
+ * init serial number cache
+ */
+ private void initCache() throws EBaseException {
+ mNext = getSerialNumber();
+ BigInteger serialConfig = new BigInteger("0");
+ mRadix = 10;
+
+ CMS.debug("Repository: in InitCache");
+
+ if (this instanceof ICertificateRepository) {
+ CMS.debug("Repository: Instance of Certificate Repository.");
+ mRadix = 16;
+ mRepo = IDBSubsystem.CERTS;
+ } else if (this instanceof IKeyRepository) {
+ // Key Repository uses the same configuration parameters as Certificate
+ // Repository. This is ok because they are on separate subsystems.
+ CMS.debug("Repository: Instance of Key Repository");
+ mRadix = 16;
+ mRepo = IDBSubsystem.CERTS;
+ } else if (this instanceof IReplicaIDRepository) {
+ CMS.debug("Repository: Instance of Replica ID repository");
+ mRepo = IDBSubsystem.REPLICA_ID;
+ } else {
+ // CRLRepository subclasses this too, but does not use serial number stuff
+ CMS.debug("Repository: Instance of Request Repository or CRLRepository.");
+ mRepo = IDBSubsystem.REQUESTS;
+ }
+
+ mMinSerial = mDB.getMinSerialConfig(mRepo);
+ mMaxSerial = mDB.getMaxSerialConfig(mRepo);
+ mNextMinSerial = mDB.getNextMinSerialConfig(mRepo);
+ mNextMaxSerial = mDB.getNextMaxSerialConfig(mRepo);
+ String increment = mDB.getIncrementConfig(mRepo);
+ String lowWaterMark = mDB.getLowWaterMarkConfig(mRepo);
+
+ CMS.debug("Repository: minSerial " + mMinSerial + " maxSerial: " + mMaxSerial);
+
+ if(mMinSerial != null)
+ mMinSerialNo = new BigInteger(mMinSerial,mRadix);
+
+ if(mMaxSerial != null)
+ mMaxSerialNo = new BigInteger(mMaxSerial,mRadix);
+
+ if(mNextMinSerial != null)
+ mNextMinSerialNo = new BigInteger(mNextMinSerial,mRadix);
+
+ if(mNextMaxSerial != null)
+ mNextMaxSerialNo = new BigInteger(mNextMaxSerial,mRadix);
+
+ if(lowWaterMark != null)
+ mLowWaterMarkNo = new BigInteger(lowWaterMark,mRadix);
+
+ if(increment != null)
+ mIncrementNo = new BigInteger(increment,mRadix);
+
+ BigInteger theSerialNo = null;
+ theSerialNo = getLastSerialNumberInRange(mMinSerialNo,mMaxSerialNo);
+
+ if(theSerialNo != null) {
+
+ mLastSerialNo = new BigInteger(theSerialNo.toString());
+ CMS.debug("Repository: mLastSerialNo: " + mLastSerialNo.toString());
+
+ }
+ else {
+
+ throw new EBaseException("Error in obtaining the last serial number in the repository!");
+
+ }
+
+ }
+
+ /**
+ * get the next serial number in cache
+ */
+ public BigInteger getTheSerialNumber() throws EBaseException {
+
+ CMS.debug("Repository:In getTheSerialNumber " );
+ if (mLastSerialNo == null)
+ initCache();
+ BigInteger serial = new BigInteger((mLastSerialNo.add(BI_ONE)).toString());
+
+ if (mMaxSerialNo != null && serial.compareTo(mMaxSerialNo) > 0)
+ return null;
+ else
+ return serial;
+ }
+
+ /**
+ * Updates the serial number to the specified in db and cache.
+ * <P>
+ *
+ * @param num serial number
+ */
+ public void setTheSerialNumber(BigInteger num) throws EBaseException {
+ // mSerialNo is already set. But just in case
+
+ CMS.debug("Repository:In setTheSerialNumber " + num.toString());
+ if (mLastSerialNo == null)
+ initCache();
+
+ if (num.compareTo(mSerialNo) <= 0) {
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_SETBACK_SERIAL",
+ mSerialNo.toString(16)));
+ }
+ // write the config parameter. It's needed in case the serialNum gap
+ // < BI_INCREMENT and server restart right afterwards.
+ mDB.setNextSerialConfig(num);
+
+ mSerialNo = num.subtract(BI_ONE);
+ mNext = num.add(BI_INCREMENT);
+ setSerialNumber(mNext);
+ }
+
+ /**
+ * Retrieves the next serial number, and also increase the
+ * serial number by one.
+ * <P>
+ *
+ * @return serial number
+ */
+ public synchronized BigInteger getNextSerialNumber() throws
+ EBaseException {
+
+ CMS.debug("Repository: in getNextSerialNumber. ");
+
+ if (mLastSerialNo == null) {
+ initCache();
+
+ mLastSerialNo = mLastSerialNo.add(BI_ONE);
+
+
+ } else {
+ mLastSerialNo = mLastSerialNo.add(BI_ONE);
+ }
+
+ if( mLastSerialNo == null ) {
+ CMS.debug( "Repository::getNextSerialNumber() " +
+ "- mLastSerialNo is null!" );
+ throw new EBaseException( "mLastSerialNo is null" );
+ }
+
+ // check if we have reached the end of the range
+ // if so, move to next range
+ if (mLastSerialNo.compareTo( mMaxSerialNo ) > 0 ) {
+ if (mDB.getEnableSerialMgmt()) {
+ CMS.debug("Reached the end of the range. Attempting to move to next range");
+ mMinSerialNo = mNextMinSerialNo;
+ mMaxSerialNo = mNextMaxSerialNo;
+ mLastSerialNo = mMinSerialNo;
+ mNextMinSerialNo = null;
+ mNextMaxSerialNo = null;
+ if ((mMaxSerialNo == null) || (mMinSerialNo == null)) {
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LIMIT_REACHED",
+ mLastSerialNo.toString()));
+ }
+
+ // persist the changes
+ mDB.setMinSerialConfig(mRepo, mMinSerialNo.toString());
+ mDB.setMaxSerialConfig(mRepo, mMaxSerialNo.toString());
+ mDB.setNextMinSerialConfig(mRepo, null);
+ mDB.setNextMaxSerialConfig(mRepo, null);
+ } else {
+ throw new EDBException(CMS.getUserMessage("CMS_DBS_LIMIT_REACHED",
+ mLastSerialNo.toString()));
+ }
+ }
+
+ BigInteger retSerial = new BigInteger(mLastSerialNo.toString());
+
+ CMS.debug("Repository: getNextSerialNumber: returning retSerial " + retSerial);
+ return retSerial;
+ }
+
+ /**
+ * Checks to see if a new range is needed, or if we have reached the end of the
+ * current range, or if a range conflict has occurred.
+ *
+ * @exception EBaseException failed to check next range for conflicts
+ */
+ public void checkRanges() throws EBaseException
+ {
+ if (!mDB.getEnableSerialMgmt()) {
+ CMS.debug("Serial Management not enabled. Returning .. ");
+ return;
+ }
+ if (CMS.getEESSLPort() == null) {
+ CMS.debug("Server not completely started. Returning ..");
+ return;
+ }
+
+ if (mLastSerialNo == null)
+ initCache();
+
+ BigInteger numsInRange = mMaxSerialNo.subtract(mLastSerialNo);
+ BigInteger numsInNextRange = null;
+ BigInteger numsAvail = null;
+ CMS.debug("Serial numbers left in range: " + numsInRange.toString());
+ CMS.debug("Last Serial Number: " + mLastSerialNo.toString());
+ if ((mNextMaxSerialNo != null) && (mNextMinSerialNo != null)) {
+ numsInNextRange = mNextMaxSerialNo.subtract(mNextMinSerialNo);
+ numsAvail = numsInRange.add(numsInNextRange);
+ CMS.debug("Serial Numbers in next range: " + numsInNextRange.toString());
+ CMS.debug("Serial Numbers available: " + numsAvail.toString());
+ } else {
+ numsAvail = numsInRange;
+ CMS.debug("Serial Numbers available: " + numsAvail.toString());
+ }
+
+ if ((numsAvail.compareTo(mLowWaterMarkNo) < 0) && (!CMS.isPreOpMode()) ) {
+ CMS.debug("Low water mark reached. Requesting next range");
+ mNextMinSerialNo = new BigInteger(mDB.getNextRange(mRepo), mRadix);
+ if (mNextMinSerialNo == null) {
+ CMS.debug("Next Range not available");
+ } else {
+ CMS.debug("nNextMinSerialNo has been set to " + mNextMinSerialNo.toString(mRadix));
+ mNextMaxSerialNo = mNextMinSerialNo.add(mIncrementNo);
+ numsAvail = numsAvail.add(mIncrementNo);
+ mDB.setNextMinSerialConfig(mRepo, mNextMinSerialNo.toString(mRadix));
+ mDB.setNextMaxSerialConfig(mRepo, mNextMaxSerialNo.toString(mRadix));
+ }
+ }
+
+ if (numsInRange.compareTo (mLowWaterMarkNo) < 0 ) {
+ // check for a replication error
+ CMS.debug("Checking for a range conflict");
+ if (mDB.hasRangeConflict(mRepo)) {
+ CMS.debug("Range Conflict found! Removing next range.");
+ mNextMaxSerialNo = null;
+ mNextMinSerialNo= null;
+ mDB.setNextMinSerialConfig(mRepo, null);
+ mDB.setNextMaxSerialConfig(mRepo, null);
+ }
+ }
+ }
+
+ /**
+ * Sets whether serial number management is enabled for certs
+ * and requests.
+ *
+ * @param value true/false
+ * @exception EBaseException failed to set
+ */
+ public void setEnableSerialMgmt(boolean value) throws EBaseException
+ {
+ mDB.setEnableSerialMgmt(value);
+ }
+
+ public abstract BigInteger getLastSerialNumberInRange(BigInteger serial_low_bound, BigInteger serial_upper_bound) throws
+ EBaseException;
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/RepositoryRecord.java b/pki/base/common/src/com/netscape/cmscore/dbs/RepositoryRecord.java
new file mode 100644
index 000000000..7aa63fa1d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/RepositoryRecord.java
@@ -0,0 +1,112 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.repository.*;
+
+
+/**
+ * A class represents a repository record.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class RepositoryRecord implements IRepositoryRecord {
+
+ private BigInteger mSerialNo = null;
+ private String mPublishingStatus = null;
+
+ protected static Vector mNames = new Vector();
+ static {
+ mNames.addElement(IRepositoryRecord.ATTR_SERIALNO);
+ mNames.addElement(IRepositoryRecord.ATTR_PUB_STATUS);
+ }
+
+ /**
+ * Constructs a repository record.
+ * <P>
+ */
+ public RepositoryRecord() {
+ }
+
+ /**
+ * Sets attribute.
+ */
+ public void set(String name, Object obj) throws EBaseException {
+ if (name.equalsIgnoreCase(IRepositoryRecord.ATTR_SERIALNO)) {
+ mSerialNo = (BigInteger) obj;
+ } else if (name.equalsIgnoreCase(IRepositoryRecord.ATTR_PUB_STATUS)) {
+ mPublishingStatus = (String) obj;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ /**
+ * Retrieves attribute from this record.
+ */
+ public Object get(String name) throws EBaseException {
+ if (name.equalsIgnoreCase(IRepositoryRecord.ATTR_SERIALNO)) {
+ return mSerialNo;
+ } else if (name.equalsIgnoreCase(IRepositoryRecord.ATTR_PUB_STATUS)) {
+ return mPublishingStatus;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+ }
+
+ /**
+ * Deletes an attribute.
+ */
+ public void delete(String name) throws EBaseException {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name));
+ }
+
+ /**
+ * Retrieves a list of attribute names.
+ */
+ public Enumeration getElements() {
+ return mNames.elements();
+ }
+
+ public Enumeration getSerializableAttrNames() {
+ return mNames.elements();
+ }
+
+ /**
+ * Retrieves serial number.
+ */
+ public BigInteger getSerialNumber() {
+ return mSerialNo;
+ }
+
+ public String getPublishingStatus() {
+ return mPublishingStatus;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/RepositorySchema.java b/pki/base/common/src/com/netscape/cmscore/dbs/RepositorySchema.java
new file mode 100644
index 000000000..436c8633e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/RepositorySchema.java
@@ -0,0 +1,44 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents a collection of repository-specific
+ * schema information.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class RepositorySchema {
+
+ public static final String LDAP_OC_TOP = "top";
+ public static final String LDAP_OC_REPOSITORY = "repository";
+ public static final String LDAP_ATTR_SERIALNO = "serialno";
+ public static final String LDAP_ATTR_PUB_STATUS = "publishingStatus";
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfo.java b/pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfo.java
new file mode 100644
index 000000000..81ae72053
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfo.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.cmscore.dbs;
+
+
+import java.util.*;
+import java.io.*;
+import java.math.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.certdb.*;
+
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.util.*;
+
+
+/**
+ * A class represents a certificate revocation info. This
+ * object is written as an attribute of certificate record
+ * which essentially signifies a revocation act.
+ * <P>
+ *
+ * @author galperin
+ * @version $Revision$, $Date$
+ */
+public class RevocationInfo implements IRevocationInfo, Serializable {
+
+ private Date mRevocationDate = null;
+ private CRLExtensions mCRLEntryExtensions = null;
+
+ /**
+ * Constructs revocation info.
+ */
+ public RevocationInfo() {
+ }
+
+ /**
+ * Constructs revocation info used by revocation
+ * request implementation.
+ *
+ * @param reason if not null contains CRL entry extension
+ * that specifies revocation reason
+ * @see CRLReasonExtension
+ */
+ public RevocationInfo(Date revocationDate, CRLExtensions exts) {
+ mRevocationDate = revocationDate;
+ mCRLEntryExtensions = exts;
+ }
+
+ /**
+ * Retrieves revocation date.
+ */
+ public Date getRevocationDate() {
+ return mRevocationDate;
+ }
+
+ /**
+ * Retrieves CRL extensions.
+ */
+ public CRLExtensions getCRLEntryExtensions() {
+ return mCRLEntryExtensions;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfoMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfoMapper.java
new file mode 100644
index 000000000..6ee2c7bb2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/RevocationInfoMapper.java
@@ -0,0 +1,167 @@
+// --- 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.cmscore.dbs;
+
+
+import java.math.*;
+import java.io.*;
+import java.util.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.util.Debug;
+
+
+/**
+ * A class represents a mapper to serialize
+ * revocation information into database.
+ * <P>
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class RevocationInfoMapper implements IDBAttrMapper {
+
+ protected static Vector mNames = new Vector();
+ static {
+ mNames.addElement(CertDBSchema.LDAP_ATTR_REVO_INFO);
+ }
+
+ /**
+ * Constructs revocation information mapper.
+ */
+ public RevocationInfoMapper() {
+ }
+
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return mNames.elements();
+ }
+
+ public void mapObjectToLDAPAttributeSet(IDBObj parent, String name,
+ Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ try {
+ // in format of <date>;<extensions>
+ String value = "";
+ RevocationInfo info = (RevocationInfo) obj;
+ Date d = info.getRevocationDate();
+
+ value = DateMapper.dateToDB(d);
+ CRLExtensions exts = info.getCRLEntryExtensions();
+ // CRLExtension's DER encoding and decoding does not work!
+ // That is why we need to do our own serialization.
+ Enumeration e = exts.getElements();
+
+ while (e.hasMoreElements()) {
+ Extension ext = (Extension) e.nextElement();
+
+ if (ext instanceof CRLReasonExtension) {
+ RevocationReason reason =
+ ((CRLReasonExtension) ext).getReason();
+
+ value = value + ";CRLReasonExtension=" +
+ Integer.toString(reason.toInt());
+ } else if (ext instanceof InvalidityDateExtension) {
+ Date invalidityDate =
+ ((InvalidityDateExtension) ext).getInvalidityDate();
+
+ value = value + ";InvalidityDateExtension=" +
+ DateMapper.dateToDB(invalidityDate);
+ } else {
+ Debug.trace("XXX skipped extension");
+ }
+ }
+ attrs.add(new LDAPAttribute(CertDBSchema.LDAP_ATTR_REVO_INFO,
+ value));
+ } catch (Exception e) {
+ Debug.trace(e.toString());
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_SERIALIZE_FAILED", name));
+ }
+ }
+
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ try {
+ LDAPAttribute attr = attrs.getAttribute(
+ CertDBSchema.LDAP_ATTR_REVO_INFO);
+
+ if (attr == null)
+ return;
+ String value = (String) attr.getStringValues().nextElement();
+ int i = value.indexOf(';'); // look for 1st ";"
+ String str = null;
+ CRLExtensions exts = new CRLExtensions();
+ Date d = null;
+
+ if (i == -1) {
+ // only date found; no extensions
+ d = DateMapper.dateFromDB(value);
+ } else {
+ String s = value;
+
+ str = s.substring(0, i);
+ d = DateMapper.dateFromDB(str);
+ s = s.substring(i + 1);
+ do {
+ i = s.indexOf(';');
+ if (i == -1) {
+ str = s;
+ } else {
+ str = s.substring(0, i);
+ s = s.substring(i + 1);
+ }
+ if (str.startsWith("CRLReasonExtension=")) {
+ String reasonStr = str.substring(19);
+ RevocationReason reason = RevocationReason.fromInt(
+ Integer.parseInt(reasonStr));
+ CRLReasonExtension ext = new CRLReasonExtension(reason);
+
+ exts.set(CRLReasonExtension.NAME, ext);
+ } else if (str.startsWith("InvalidityDateExtension=")) {
+ String invalidityDateStr = str.substring(24);
+ Date invalidityDate = DateMapper.dateFromDB(invalidityDateStr);
+ InvalidityDateExtension ext =
+ new InvalidityDateExtension(invalidityDate);
+
+ exts.set(InvalidityDateExtension.NAME, ext);
+ } else {
+ Debug.trace("XXX skipped extension");
+ }
+ }
+ while (i != -1);
+ }
+ RevocationInfo info = new RevocationInfo(d, exts);
+
+ parent.set(name, info);
+ } catch (Exception e) {
+ Debug.trace(e.toString());
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_DESERIALIZE_FAILED", name));
+ }
+ }
+
+ public String mapSearchFilter(String name, String op, String value)
+ throws EBaseException {
+ return CertDBSchema.LDAP_ATTR_REVO_INFO + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/StringMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/StringMapper.java
new file mode 100644
index 000000000..e9fbd64e7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/StringMapper.java
@@ -0,0 +1,91 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java String object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class StringMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs string mapper.
+ */
+ public StringMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of supported ldap attributes.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps attribute value to ldap attributes.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName, (String) obj));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent)
+ throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null) {
+ return;
+ }
+ try {
+ parent.set(name, (String)
+ attr.getStringValues().nextElement());
+ } catch (NoSuchElementException e) {
+ // attribute present, but without value
+ }
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/StringVectorMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/StringVectorMapper.java
new file mode 100644
index 000000000..2ec203eb6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/StringVectorMapper.java
@@ -0,0 +1,106 @@
+// --- 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.cmscore.dbs;
+
+
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java String object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class StringVectorMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ /**
+ * Constructs string vector mapper.
+ */
+ public StringVectorMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of supported ldap attributes.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps attribute value to ldap attributes.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ Vector v = (Vector) obj;
+ int s = v.size();
+
+ if (s == 0) {
+ return;
+ }
+ String m[] = new String[s];
+
+ for (int i = 0; i < s; i++) {
+ m[i] = (String) v.elementAt(i);
+ }
+ attrs.add(new LDAPAttribute(mLdapName, m));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null)
+ return;
+ Enumeration e = attr.getStringValues();
+ Vector v = new Vector();
+
+ while (e.hasMoreElements()) {
+ v.addElement((String) e.nextElement());
+ }
+ if (v.size() == 0)
+ return;
+ String m[] = new String[v.size()];
+
+ v.copyInto(m);
+ parent.set(name, m);
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/X500NameMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/X500NameMapper.java
new file mode 100644
index 000000000..b7e386f77
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/X500NameMapper.java
@@ -0,0 +1,107 @@
+// --- 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.cmscore.dbs;
+
+
+import java.io.*;
+import java.util.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * A class represents ann attribute mapper that maps
+ * a Java X500Name object into LDAP attribute,
+ * and vice versa.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class X500NameMapper implements IDBAttrMapper {
+
+ private String mLdapName = null;
+ private Vector v = new Vector();
+
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Constructs X500Name mapper.
+ */
+ public X500NameMapper(String ldapName) {
+ mLdapName = ldapName;
+ v.addElement(mLdapName);
+ }
+
+ /**
+ * Retrieves a list of ldap attributes.
+ */
+ public Enumeration getSupportedLDAPAttributeNames() {
+ return v.elements();
+ }
+
+ /**
+ * Maps attribute value to ldap attributes.
+ */
+ public void mapObjectToLDAPAttributeSet(IDBObj parent,
+ String name, Object obj, LDAPAttributeSet attrs)
+ throws EBaseException {
+ attrs.add(new LDAPAttribute(mLdapName,
+ ((X500Name) obj).toString()));
+ }
+
+ /**
+ * Maps LDAP attributes into object, and put the object
+ * into 'parent'.
+ */
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ LDAPAttribute attr = attrs.getAttribute(mLdapName);
+
+ if (attr == null) {
+ return;
+ }
+ try {
+ parent.set(name, new X500Name((String)
+ attr.getStringValues().nextElement()));
+ } catch (IOException e) {
+
+ /*LogDoc
+ *
+ * @phase Maps LDAP attributes into object
+ * @message X500NameMapper: <exception thrown>
+ */
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_DBS_X500NAME_MAPPER_ERROR",
+ e.toString()));
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_DESERIALIZE_FAILED", name));
+ }
+ }
+
+ /**
+ * Maps search filters into LDAP search filter.
+ */
+ public String mapSearchFilter(String name, String op,
+ String value) throws EBaseException {
+ return mLdapName + op + value;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/X509CertImplMapper.java b/pki/base/common/src/com/netscape/cmscore/dbs/X509CertImplMapper.java
new file mode 100644
index 000000000..29e1db849
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cmscore/dbs/X509CertImplMapper.java
@@ -0,0 +1,363 @@
+// --- 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.cmscore.dbs;
+
+
+import java.io.*;
+import java.util.*;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cmscore.dbs.*;
+import com.netscape.cmscore.cert.*;
+import com.netscape.cmscore.util.Debug;
+
+
+/**
+ * A class represents a mapper to serialize
+ * x509 certificate into database.
+ *
+ * @author thomask
+ * @version $Revision$, $Date$
+ */
+public class X509CertImplMapper implements IDBAttrMapper {
+
+ public X509CertImplMapper() {
+ }
+
+ public Enumeration getSupportedLDAPAttributeNames() {
+ Vector v = new Vector();
+
+ v.addElement(CertDBSchema.LDAP_ATTR_NOT_BEFORE);
+ v.addElement(CertDBSchema.LDAP_ATTR_NOT_AFTER);
+ v.addElement(CertDBSchema.LDAP_ATTR_DURATION);
+ v.addElement(CertDBSchema.LDAP_ATTR_EXTENSION);
+ v.addElement(CertDBSchema.LDAP_ATTR_SUBJECT);
+ v.addElement(CertDBSchema.LDAP_ATTR_SIGNED_CERT);
+ v.addElement(CertDBSchema.LDAP_ATTR_VERSION);
+ v.addElement(CertDBSchema.LDAP_ATTR_ALGORITHM);
+ v.addElement(CertDBSchema.LDAP_ATTR_SIGNING_ALGORITHM);
+ v.addElement(CertDBSchema.LDAP_ATTR_PUBLIC_KEY_DATA);
+ return v.elements();
+ }
+
+ public void mapObjectToLDAPAttributeSet(IDBObj parent, String name,
+ Object obj, LDAPAttributeSet attrs) throws EBaseException {
+ try {
+ X509CertImpl cert = (X509CertImpl) obj;
+ // make information searchable
+ Date notBefore = cert.getNotBefore();
+
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_NOT_BEFORE,
+ DateMapper.dateToDB(notBefore)));
+ Date notAfter = cert.getNotAfter();
+
+ attrs.add(new LDAPAttribute(CertDBSchema.LDAP_ATTR_NOT_AFTER,
+ DateMapper.dateToDB(notAfter)));
+ attrs.add(new LDAPAttribute(CertDBSchema.LDAP_ATTR_DURATION,
+ DBSUtil.longToDB(notAfter.getTime() - notBefore.getTime())));
+ attrs.add(new LDAPAttribute(CertDBSchema.LDAP_ATTR_SUBJECT,
+ cert.getSubjectDN().getName()));
+ attrs.add(new LDAPAttribute(CertDBSchema.LDAP_ATTR_PUBLIC_KEY_DATA, cert.getPublicKey().getEncoded()));
+ // make extension searchable
+ Set nonCritSet = cert.getNonCriticalExtensionOIDs();
+
+ if (nonCritSet != null) {
+ for (Iterator i = nonCritSet.iterator(); i.hasNext();) {
+ String oid = (String) i.next();
+
+ if (oid.equals("2.16.840.1.113730.1.1")) {
+ String extVal = getCertTypeExtensionInfo(cert);
+
+ if (extVal != null) {
+ oid = oid + ";" + extVal;
+ }
+ } else if (oid.equals("2.5.29.19")) {
+ String extVal = getBasicConstraintsExtensionInfo(cert);
+
+ if (extVal != null) {
+ oid = oid + ";" + extVal;
+ }
+ }
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_EXTENSION, oid));
+ }
+ }
+ Set critSet = cert.getCriticalExtensionOIDs();
+
+ if (critSet != null) {
+ for (Iterator i = critSet.iterator(); i.hasNext();) {
+ String oid = (String) i.next();
+
+ if (oid.equals("2.16.840.1.113730.1.1")) {
+ String extVal = getCertTypeExtensionInfo(cert);
+
+ if (extVal != null) {
+ oid = oid + ";" + extVal;
+ }
+ } else if (oid.equals("2.5.29.19")) {
+ String extVal = getBasicConstraintsExtensionInfo(cert);
+
+ if (extVal != null) {
+ oid = oid + ";" + extVal;
+ }
+ }
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_EXTENSION, oid));
+ }
+ }
+
+ // something extra; so that we can rebuild the
+ // object quickly
+ // if we dont add ";binary", communicator does
+ // not know how to display the certificate in
+ // pretty print format.
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_SIGNED_CERT + ";binary",
+ cert.getEncoded()));
+
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_VERSION,
+ Integer.toString(cert.getVersion())));
+ X509Key pubKey = (X509Key) cert.getPublicKey();
+
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_ALGORITHM,
+ pubKey.getAlgorithmId().getOID().toString()));
+ attrs.add(new LDAPAttribute(
+ CertDBSchema.LDAP_ATTR_SIGNING_ALGORITHM,
+ cert.getSigAlgOID()));
+ } catch (CertificateEncodingException e) {
+ throw new EDBException(
+ CMS.getUserMessage("CMS_DBS_SERIALIZE_FAILED", name));
+ }
+ }
+
+ private String getCertTypeExtensionInfo(X509CertImpl cert) {
+ try {
+ Extension ext = cert.getExtension("2.16.840.1.113730.1.1");
+
+ if (ext == null) {
+ // sometime time (during installation) it
+ // is named differently
+ ext = cert.getExtension(NSCertTypeExtension.NAME);
+ if (ext == null)
+ return null;
+ }
+ NSCertTypeExtension nsExt = (NSCertTypeExtension) ext;
+
+ String result = "";
+
+ Boolean sslServer = (Boolean) nsExt.get(
+ NSCertTypeExtension.SSL_SERVER);
+
+ result += "SSLServer=" + sslServer.toString() + ",";
+ Boolean sslClient = (Boolean) nsExt.get(
+ NSCertTypeExtension.SSL_CLIENT);
+
+ result += "SSLClient=" + sslClient.toString() + ",";
+ Boolean email = (Boolean) nsExt.get(
+ NSCertTypeExtension.EMAIL);
+
+ result += "Email=" + email.toString() + ",";
+ Boolean sslCA = (Boolean) nsExt.get(
+ NSCertTypeExtension.SSL_CA);
+
+ result += "SSLCA=" + sslCA.toString() + ",";
+ Boolean mailCA = (Boolean) nsExt.get(
+ NSCertTypeExtension.EMAIL_CA);
+
+ result += "EmailCA=" + mailCA.toString() + ",";
+ Boolean objectSigning = (Boolean) nsExt.get(
+ NSCertTypeExtension.OBJECT_SIGNING);
+
+ result += "objectSigning=" +
+ objectSigning.toString();
+ return result;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ private String getBasicConstraintsExtensionInfo(X509CertImpl cert) {
+ try {
+ Extension ext = cert.getExtension("2.5.29.19");
+
+ if (ext == null) {
+ // sometime time (during installation) it
+ // is named differently
+ ext = cert.getExtension(BasicConstraintsExtension.NAME);
+ if (ext == null)
+ return null;
+ }
+ BasicConstraintsExtension bcExt = (BasicConstraintsExtension) ext;
+
+ String result = "";
+
+ Boolean isCA = (Boolean) bcExt.get(
+ BasicConstraintsExtension.IS_CA);
+
+ result += "isCA=" + isCA.toString() + ",";
+ Integer pathLen = (Integer) bcExt.get(
+ BasicConstraintsExtension.PATH_LEN);
+
+ result += "pathLen=" + pathLen.toString();
+ return result;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public void mapLDAPAttributeSetToObject(LDAPAttributeSet attrs,
+ String name, IDBObj parent) throws EBaseException {
+ try {
+ // rebuild object quickly using binary image
+ // XXX bad! when we add this attribute,
+ // we add it as userCertificate, but when
+ // we retrieve it, DS returns it as
+ // userCertificate;binary. So I cannot do the
+ // following:
+ // LDAPAttribute attr = attrs.getAttribute(
+ // Schema.LDAP_ATTR_SIGNED_CERT);
+
+ X509CertInfo certinfo = new X509CertInfo();
+ LDAPAttribute attr = attrs.getAttribute(
+ CertDBSchema.LDAP_ATTR_SIGNED_CERT);
+
+ if (attr == null) {
+ // YUK!
+ attr = attrs.getAttribute(
+ CertDBSchema.LDAP_ATTR_SIGNED_CERT + ";binary");
+ }
+ if (attr != null) {
+ byte der[] = (byte[])
+ attr.getByteValues().nextElement();
+ X509CertImpl impl = new X509CertImpl(der);
+
+ parent.set(name, impl);
+ }
+ } catch (CertificateException e) {
+ //throw new EDBException(
+ // DBResources.FAILED_TO_DESERIALIZE_1, name);
+ parent.set(name, null);
+ } catch (Exception e) {
+ //throw new EDBException(
+ // DBResources.FAILED_TO_DESERIALIZE_1, name);
+ parent.set(name, null);
+
+ }
+ }
+
+ public String mapSearchFilter(String name, String op, String value)
+ throws EBaseException {
+ AttributeNameHelper h = new AttributeNameHelper(name);
+ String suffix = h.getSuffix();
+
+ if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_NOT_BEFORE)) {
+ name = CertDBSchema.LDAP_ATTR_NOT_BEFORE;
+ try {
+ value = DateMapper.dateToDB(new
+ Date(Long.parseLong(value)));
+ } catch (NumberFormatException e) {
+ }
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_NOT_AFTER)) {
+ name = CertDBSchema.LDAP_ATTR_NOT_AFTER;
+ try {
+ value = DateMapper.dateToDB(new
+ Date(Long.parseLong(value)));
+ } catch (NumberFormatException e) {
+ }
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_SUBJECT)) {
+ name = CertDBSchema.LDAP_ATTR_SUBJECT;
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_PUBLIC_KEY_DATA)) {
+ name = CertDBSchema.LDAP_ATTR_PUBLIC_KEY_DATA;
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_DURATION)) {
+ name = CertDBSchema.LDAP_ATTR_DURATION;
+ value = DBSUtil.longToDB(Long.parseLong(value));
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_VERSION)) {
+ name = CertDBSchema.LDAP_ATTR_VERSION;
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_ALGORITHM)) {
+ name = CertDBSchema.LDAP_ATTR_ALGORITHM;
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_SIGNING_ALGORITHM)) {
+ name = CertDBSchema.LDAP_ATTR_SIGNING_ALGORITHM;
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_SERIAL_NUMBER)) {
+ name = CertDBSchema.LDAP_ATTR_CERT_RECORD_ID;
+ } else if (suffix.equalsIgnoreCase(ICertRecord.X509CERT_EXTENSION)) {
+ name = CertDBSchema.LDAP_ATTR_EXTENSION;
+ } else if (suffix.equalsIgnoreCase(ICertRecord.ATTR_REVO_INFO)) {
+ name = CertDBSchema.LDAP_ATTR_REVO_INFO;
+ value = "*;CRLReasonExtension=" + value + "*";
+ } else if (suffix.equalsIgnoreCase("nsExtension.SSLClient")) {
+ // special case for NS cert type extension
+ name = CertDBSchema.LDAP_ATTR_EXTENSION;
+ if (value.equals("on")) {
+ value = "2.16.840.1.113730.1.1;*SSLClient=true*";
+ } else {
+ value = "2.16.840.1.113730.1.1;*SSLClient=false*";
+ }
+ } else if (suffix.equalsIgnoreCase("nsExtension.SSLServer")) {
+ // special case for NS cert type extension
+ name = CertDBSchema.LDAP_ATTR_EXTENSION;
+ if (value.equals("on")) {
+ value = "2.16.840.1.113730.1.1;*SSLServer=true*";
+ } else {
+ value = "2.16.840.1.113730.1.1;*SSLServer=false*";
+ }
+ } else if (suffix.equalsIgnoreCase("nsExtension.SecureEmail")) {
+ // special case for NS cert type extension
+ name = CertDBSchema.LDAP_ATTR_EXTENSION;
+ if (value.equals("on")) {
+ value = "2.16.840.1.113730.1.1;*Email=true*";
+ } else {
+ value = "2.16.840.1.113730.1.1;*Email=false*";
+ }
+ } else if (suffix.equalsIgnoreCase("nsExtension.SubordinateSSLCA")) {
+ // special case for NS cert type extension
+ name = CertDBSchema.LDAP_ATTR_EXTENSION;
+ if (value.equals("on")) {
+ value = "2.16.840.1.113730.1.1;*SSLCA=true*";
+ } else {
+ value = "2.16.840.1.113730.1.1;*SSLCA=false*";
+ }
+ } else if (suffix.equalsIgnoreCase("nsExtension.SubordinateEmailCA")) {
+ // special case for NS cert type extension
+ name = CertDBSchema.LDAP_ATTR_EXTENSION;
+ if (value.equals("on")) {
+ value = "2.16.840.1.113730.1.1;*EmailCA=true*";
+ } else {
+ value = "2.16.840.1.113730.1.1;*EmailCA=false*";
+ }
+ } else if (suffix.equalsIgnoreCase("BasicConstraints.isCA")) {
+ // special case for Basic Constraints extension
+ name = CertDBSchema.LDAP_ATTR_EXTENSION;
+ if (value.equals("on")) {
+ value = "2.5.29.19;*isCA=true*";
+ } else {
+ value = "2.5.29.19;*isCA=false*";
+ }
+ }
+ return name + op + value;
+ }
+}