// --- 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.security.PublicKey; import java.util.Date; import java.util.Enumeration; import java.util.Vector; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import netscape.security.x509.X500Name; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.dbs.EDBException; import com.netscape.certsrv.dbs.IDBRegistry; import com.netscape.certsrv.dbs.IDBSSession; import com.netscape.certsrv.dbs.IDBSearchResults; import com.netscape.certsrv.dbs.IDBSubsystem; import com.netscape.certsrv.dbs.Modification; import com.netscape.certsrv.dbs.ModificationSet; import com.netscape.certsrv.dbs.keydb.IKeyRecord; import com.netscape.certsrv.dbs.keydb.IKeyRecordList; import com.netscape.certsrv.dbs.keydb.IKeyRepository; import com.netscape.certsrv.dbs.repository.IRepository; /** * A class represents a Key repository. This is the container of * archived keys. *
* * @author thomask * @version $Revision$, $Date$ */ public class KeyRepository extends Repository implements IKeyRepository { public KeyStatusUpdateTask mKeyStatusUpdateTask; protected IDBSubsystem mDBService; IRepository requestRepository; /** * Internal constants */ private String mBaseDN = null; /** * Constructs a key repository. It checks if the key repository * does exist. If not, it creates the repository. *
*
* @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));
}
if (!reg.isAttributeRegistered(KeyRecord.ATTR_CLIENT_ID)) {
reg.registerAttribute(KeyRecord.ATTR_CLIENT_ID, new
StringMapper(KeyDBSchema.LDAP_ATTR_CLIENT_ID));
}
if (!reg.isAttributeRegistered(KeyRecord.ATTR_STATUS)) {
reg.registerAttribute(KeyRecord.ATTR_STATUS, new
StringMapper(KeyDBSchema.LDAP_ATTR_STATUS));
}
if (!reg.isAttributeRegistered(KeyRecord.ATTR_DATA_TYPE)) {
reg.registerAttribute(KeyRecord.ATTR_DATA_TYPE, new
StringMapper(KeyDBSchema.LDAP_ATTR_DATA_TYPE));
}
}
public void setKeyStatusUpdateInterval(IRepository requestRepo, int interval) {
CMS.debug("In setKeyStatusUpdateInterval " + interval);
this.requestRepository = requestRepo;
// stop running task
if (mKeyStatusUpdateTask != null) {
mKeyStatusUpdateTask.stop();
}
// don't run the thread if serial management is disabled.
if (interval == 0 || !mDBService.getEnableSerialMgmt()) {
CMS.debug("In setKeyStatusUpdateInterval interval = 0");
return;
}
CMS.debug("In setKeyStatusUpdateInterval scheduling key status update every " + interval + " seconds.");
mKeyStatusUpdateTask = new KeyStatusUpdateTask(this, interval);
mKeyStatusUpdateTask.start();
}
/**
* This method blocks when another thread is running
*/
public synchronized void updateKeyStatus() {
try {
CMS.debug("About to start checkRanges");
CMS.debug("Starting key checkRanges");
checkRanges();
CMS.debug("key checkRanges done");
CMS.debug("Starting request checkRanges");
requestRepository.checkRanges();
CMS.debug("request checkRanges done");
} catch (Exception e) {
CMS.debug("key checkRanges done: " + e.toString());
}
}
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
*
* @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.
*
*
* @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.
*
*
* @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[]) {
StringBuffer result = new StringBuffer();
for (int i = 0; i < data.length; i++) {
result.append("\\" + Integer.toHexString(data[i]));
}
return result.toString();
}
public Enumeration