package org.cagrid.gaards.dorian.federation;
import gov.nih.nci.cagrid.common.FaultHelper;
import gov.nih.nci.cagrid.common.Utils;
import gov.nih.nci.cagrid.dorian.common.CommonUtils;
import java.security.interfaces.RSAPublicKey;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import org.cagrid.gaards.dorian.X509Certificate;
import org.cagrid.gaards.dorian.ca.CertificateAuthority;
import org.cagrid.gaards.dorian.common.Lifetime;
import org.cagrid.gaards.dorian.common.LoggingObject;
import org.cagrid.gaards.dorian.service.util.PreparedStatementBuilder;
import org.cagrid.gaards.dorian.stubs.types.DorianInternalFault;
import org.cagrid.gaards.dorian.stubs.types.InvalidHostCertificateFault;
import org.cagrid.gaards.dorian.stubs.types.InvalidHostCertificateRequestFault;
import org.cagrid.gaards.pki.CertUtil;
import org.cagrid.gaards.pki.KeyUtil;
import org.cagrid.tools.database.Database;
public class HostCertificateManager extends LoggingObject {
public static final String TABLE = "host_certificates";
public static final String ID = "ID";
public static final String SERIAL = "SERIAL_NUMBER";
public static final String HOST = "HOST";
public static final String SUBJECT = "SUBJECT";
public static final String STATUS = "STATUS";
public static final String OWNER = "OWNER";
public static final String CERTIFICATE = "CERTIFICATE";
public static final String PUBLIC_KEY = "PUBLIC_KEY";
public static final String EXPIRATION = "EXPIRATION";
private boolean dbBuilt = false;
private Database db;
private CertificateAuthority ca;
private IdentityFederationProperties conf;
private Publisher publisher;
private CertificateBlacklistManager blackList;
public HostCertificateManager(Database db, IdentityFederationProperties conf, CertificateAuthority ca,
Publisher publisher, CertificateBlacklistManager blackList) {
this.db = db;
this.ca = ca;
this.conf = conf;
this.publisher = publisher;
this.blackList = blackList;
}
private void publishCRLIfNeeded(HostCertificateStatus s1, HostCertificateStatus s2) {
if ((s1.equals(HostCertificateStatus.Active)) && (s2.equals(HostCertificateStatus.Suspended))) {
publisher.publishCRL();
} else if ((s1.equals(HostCertificateStatus.Active)) && (s2.equals(HostCertificateStatus.Compromised))) {
publisher.publishCRL();
} else if ((s1.equals(HostCertificateStatus.Suspended)) && (s2.equals(HostCertificateStatus.Active))) {
publisher.publishCRL();
}
}
public synchronized HostCertificateRecord renewHostCertificate(long id) throws DorianInternalFault,
InvalidHostCertificateFault {
HostCertificateRecord record = this.getHostCertificateRecord(id);
if (!record.getStatus().equals(HostCertificateStatus.Active)) {
InvalidHostCertificateFault fault = new InvalidHostCertificateFault();
fault.setFaultString("Only active host certificates may be renewed.");
throw fault;
}
Connection c = null;
try {
java.security.cert.X509Certificate oldCert = CertUtil.loadCertificate(record.getCertificate()
.getCertificateAsString());
blackList.addCertificateToBlackList(oldCert, CertificateBlacklistManager.CERTIFICATE_RENEWED);
java.security.PublicKey key = KeyUtil.loadPublicKey(record.getPublicKey().getKeyAsString());
Date start = new Date();
Lifetime lifetime = this.conf.getIssuedCertificateLifetime();
Date end = org.cagrid.gaards.dorian.service.util.Utils.getExpiredDate(lifetime);
if (end.after(ca.getCACertificate().getNotAfter())) {
end = ca.getCACertificate().getNotAfter();
}
java.security.cert.X509Certificate cert = ca.signHostCertificate(record.getHost(), key, start, end);
record.setSerialNumber(cert.getSerialNumber().longValue());
record.setSubject(cert.getSubjectDN().getName());
X509Certificate x509 = new X509Certificate();
x509.setCertificateAsString(CertUtil.writeCertificate(cert));
record.setCertificate(x509);
c = db.getConnection();
PreparedStatement s = c.prepareStatement("update " + TABLE + " SET " + SERIAL + " = ? , " + SUBJECT
+ " = ? , " + EXPIRATION + " = ? , " + CERTIFICATE + " = ? WHERE " + ID + "= ?");
s.setLong(1, record.getSerialNumber());
s.setString(2, record.getSubject());
s.setLong(3, cert.getNotAfter().getTime());
s.setString(4, record.getCertificate().getCertificateAsString());
s.setLong(5, record.getId());
s.execute();
return record;
} catch (Exception e) {
logError(e.getMessage(), e);
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("An unexpected error occurred.");
FaultHelper helper = new FaultHelper(fault);
helper.addFaultCause(e);
fault = (DorianInternalFault) helper.getFault();
throw fault;
} finally {
db.releaseConnection(c);
}
}
public synchronized HostCertificateRecord approveHostCertifcate(long id) throws DorianInternalFault,
InvalidHostCertificateFault {
Connection c = null;
HostCertificateRecord record = this.getHostCertificateRecord(id);
// Check to see if the status is pending.
if (!record.getStatus().equals(HostCertificateStatus.Pending)) {
InvalidHostCertificateFault fault = new InvalidHostCertificateFault();
fault.setFaultString("Only pending host certificates may be approved.");
throw fault;
}
try {
java.security.PublicKey key = KeyUtil.loadPublicKey(record.getPublicKey().getKeyAsString());
String host = record.getHost();
Date start = new Date();
Lifetime lifetime = this.conf.getIssuedCertificateLifetime();
Date end = org.cagrid.gaards.dorian.service.util.Utils.getExpiredDate(lifetime);
if (end.after(ca.getCACertificate().getNotAfter())) {
end = ca.getCACertificate().getNotAfter();
}
java.security.cert.X509Certificate cert = ca.signHostCertificate(host, key, start, end);
record.setSerialNumber(cert.getSerialNumber().longValue());
record.setSubject(cert.getSubjectDN().getName());
record.setStatus(HostCertificateStatus.Active);
X509Certificate x509 = new X509Certificate();
x509.setCertificateAsString(CertUtil.writeCertificate(cert));
record.setCertificate(x509);
c = db.getConnection();
PreparedStatement s = c.prepareStatement("update " + TABLE + " SET " + SERIAL + " = ? , " + SUBJECT
+ " = ? , " + STATUS + " = ? , " + EXPIRATION + " = ?, " + CERTIFICATE + " = ? WHERE " + ID + "= ?");
s.setLong(1, record.getSerialNumber());
s.setString(2, record.getSubject());
s.setString(3, record.getStatus().getValue());
s.setLong(4, cert.getNotAfter().getTime());
s.setString(5, record.getCertificate().getCertificateAsString());
s.setLong(6, record.getId());
s.execute();
} catch (Exception e) {
logError(e.getMessage(), e);
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("An unexpected error occurred.");
FaultHelper helper = new FaultHelper(fault);
helper.addFaultCause(e);
fault = (DorianInternalFault) helper.getFault();
throw fault;
} finally {
db.releaseConnection(c);
}
return record;
}
public synchronized long requestHostCertifcate(String owner, HostCertificateRequest req)
throws DorianInternalFault, InvalidHostCertificateRequestFault {
if (Utils.clean(req.getHostname()) == null) {
InvalidHostCertificateRequestFault fault = new InvalidHostCertificateRequestFault();
fault.setFaultString("No host specified.");
throw fault;
}
if (req.getPublicKey() == null) {
InvalidHostCertificateRequestFault fault = new InvalidHostCertificateRequestFault();
fault.setFaultString("No public key specified.");
throw fault;
}
if (Utils.clean(req.getPublicKey().getKeyAsString()) == null) {
InvalidHostCertificateRequestFault fault = new InvalidHostCertificateRequestFault();
fault.setFaultString("No public key specified.");
throw fault;
}
// 1) We need to verify that a certificate for this host has never been
// requested, unless it was compromised or rejected.
if (certificateCannotBeRequested(req.getHostname())) {
InvalidHostCertificateRequestFault fault = new InvalidHostCertificateRequestFault();
fault.setFaultString("A host certificate cannot be request for " + req.getHostname()
+ " a certificate for that host already exists.");
throw fault;
}
java.security.PublicKey key = null;
try {
key = KeyUtil.loadPublicKey(req.getPublicKey().getKeyAsString());
} catch (Exception e) {
InvalidHostCertificateRequestFault fault = new InvalidHostCertificateRequestFault();
fault.setFaultString("Invalid Public Key provided.");
throw fault;
}
if (key == null) {
InvalidHostCertificateRequestFault fault = new InvalidHostCertificateRequestFault();
fault.setFaultString("Invalid Public Key provided.");
throw fault;
}
// 2) If it was compromised we want to verify that the public keys are
// different.
HostCertificateFilter f = new HostCertificateFilter();
f.setStatus(HostCertificateStatus.Compromised);
List<HostCertificateRecord> records = findHostCertificates(f);
for (int i = 0; i < records.size(); i++) {
java.security.PublicKey oldKey = null;
try {
oldKey = KeyUtil.loadPublicKey(records.get(i).getPublicKey().getKeyAsString());
} catch (Exception e) {
logError(e.getMessage(), e);
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("An unexpected error occurred validating the public key.");
throw fault;
}
if (oldKey.equals(key)) {
InvalidHostCertificateRequestFault fault = new InvalidHostCertificateRequestFault();
fault
.setFaultString("The public key provided is not acceptable it was determined that this key was compromised.");
throw fault;
}
}
// 3) We need to verify the size of the public key
int keySize = ca.getProperties().getIssuedCertificateKeySize();
int size = ((RSAPublicKey) key).getModulus().bitLength();
if (keySize != size) {
InvalidHostCertificateRequestFault fault = new InvalidHostCertificateRequestFault();
fault.setFaultString("The size of the public key specified is " + size + " bits and is required to be "
+ keySize + " bits.");
throw fault;
}
Connection c = null;
long id = -1;
try {
c = db.getConnection();
PreparedStatement s = c.prepareStatement("INSERT INTO " + TABLE + " SET " + SERIAL + "= ?," + HOST + "= ?,"
+ SUBJECT + "= ?," + OWNER + "= ?," + STATUS + "= ?," + PUBLIC_KEY + "= ?," + CERTIFICATE + "= ?");
s.setLong(1, -1);
s.setString(2, req.getHostname());
s.setString(3, "");
s.setString(4, owner);
s.setString(5, HostCertificateStatus.Pending.getValue());
s.setString(6, req.getPublicKey().getKeyAsString());
s.setString(7, "");
s.execute();
id = db.getLastAutoId(c);
} catch (Exception e) {
logError(e.getMessage(), e);
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("An unexpected error occurred.");
FaultHelper helper = new FaultHelper(fault);
helper.addFaultCause(e);
fault = (DorianInternalFault) helper.getFault();
throw fault;
} finally {
db.releaseConnection(c);
}
return id;
}
public List<HostCertificateRecord> findHostCertificates(HostCertificateFilter f) throws DorianInternalFault {
this.buildDatabase();
Connection c = null;
List<HostCertificateRecord> hosts = new ArrayList<HostCertificateRecord>();
try {
c = db.getConnection();
PreparedStatementBuilder select = new PreparedStatementBuilder(TABLE);
select.addSelectField(ID);
select.addSelectField(HOST);
select.addSelectField(OWNER);
select.addSelectField(SUBJECT);
select.addSelectField(SERIAL);
select.addSelectField(STATUS);
select.addSelectField(PUBLIC_KEY);
select.addSelectField(CERTIFICATE);
if (f != null) {
if (f.getId() != null) {
select.addWhereField(ID, "=", f.getId());
}
if (f.getSerialNumber() != null) {
select.addWhereField(SERIAL, "=", f.getSerialNumber());
}
if (f.getHost() != null) {
select.addWhereField(HOST, "LIKE", "%" + f.getHost() + "%");
}
if (f.getSubject() != null) {
select.addWhereField(SUBJECT, "LIKE", "%" + f.getSubject() + "%");
}
if (f.getOwner() != null) {
select.addWhereField(OWNER, "LIKE", "%" + f.getOwner() + "%");
}
if (f.getStatus() != null) {
select.addWhereField(STATUS, "=", f.getStatus().getValue());
}
if (f.getIsExpired() != null) {
Calendar cal = new GregorianCalendar();
long time = cal.getTimeInMillis();
if (f.getIsExpired().booleanValue()) {
select.addClause("(" + EXPIRATION + ">0 AND " + EXPIRATION + "<" + Long.valueOf(time) + ")");
} else {
select.addClause("(" + EXPIRATION + ">0 AND " + EXPIRATION + ">" + Long.valueOf(time) + ")");
}
}
}
PreparedStatement s = select.prepareStatement(c);
ResultSet rs = s.executeQuery();
while (rs.next()) {
HostCertificateRecord record = new HostCertificateRecord();
record.setId(rs.getInt(ID));
record.setHost(rs.getString(HOST));
record.setOwner(rs.getString(OWNER));
record.setSubject(rs.getString(SUBJECT));
record.setSerialNumber(rs.getLong(SERIAL));
record.setStatus(HostCertificateStatus.fromValue(rs.getString(STATUS)));
String keyStr = Utils.clean(rs.getString(PUBLIC_KEY));
if (keyStr != null) {
PublicKey pk = new PublicKey();
pk.setKeyAsString(keyStr);
record.setPublicKey(pk);
}
String certStr = Utils.clean(rs.getString(CERTIFICATE));
if (certStr != null) {
X509Certificate cert = new X509Certificate();
cert.setCertificateAsString(certStr);
record.setCertificate(cert);
}
hosts.add(record);
}
rs.close();
s.close();
} catch (Exception e) {
logError(e.getMessage(), e);
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("An unexpected error occurred.");
FaultHelper helper = new FaultHelper(fault);
helper.addFaultCause(e);
fault = (DorianInternalFault) helper.getFault();
throw fault;
} finally {
db.releaseConnection(c);
}
return hosts;
}
public List<HostRecord> getHostRecords(HostSearchCriteria f) throws DorianInternalFault {
this.buildDatabase();
Connection c = null;
List<HostRecord> hosts = new ArrayList<HostRecord>();
try {
c = db.getConnection();
PreparedStatementBuilder select = new PreparedStatementBuilder(TABLE);
select.addSelectField(HOST);
select.addSelectField(OWNER);
select.addSelectField(SUBJECT);
if (f != null) {
select.addWhereField(STATUS, "=", HostCertificateStatus.Active.getValue());
if (f.getHostname() != null) {
select.addWhereField(HOST, "LIKE", "%" + f.getHostname() + "%");
}
if (f.getIdentity() != null) {
String subject = CommonUtils.identityToSubject(f.getIdentity());
select.addWhereField(SUBJECT, "LIKE", "%" + subject + "%");
}
if (f.getHostCertificateSubject() != null) {
select.addWhereField(SUBJECT, "LIKE", "%" + f.getHostCertificateSubject() + "%");
}
if (f.getOwner() != null) {
select.addWhereField(OWNER, "LIKE", "%" + f.getOwner() + "%");
}
}
PreparedStatement s = select.prepareStatement(c);
ResultSet rs = s.executeQuery();
while (rs.next()) {
HostRecord record = new HostRecord();
record.setHostname(rs.getString(HOST));
record.setOwner(rs.getString(OWNER));
record.setIdentity(CommonUtils.subjectToIdentity(rs.getString(SUBJECT)));
record.setHostCertificateSubject(rs.getString(SUBJECT));
hosts.add(record);
}
rs.close();
s.close();
} catch (Exception e) {
logError(e.getMessage(), e);
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("An unexpected error occurred.");
FaultHelper helper = new FaultHelper(fault);
helper.addFaultCause(e);
fault = (DorianInternalFault) helper.getFault();
throw fault;
} finally {
db.releaseConnection(c);
}
return hosts;
}
public List<HostCertificateRecord> getHostCertificateRecords(String owner) throws DorianInternalFault {
this.buildDatabase();
List<HostCertificateRecord> records = new ArrayList<HostCertificateRecord>();
Connection c = null;
try {
c = db.getConnection();
PreparedStatement s = c.prepareStatement("select " + ID + " from " + TABLE + " WHERE " + OWNER + " = ?");
s.setString(1, owner);
ResultSet rs = s.executeQuery();
while (rs.next()) {
records.add(getHostCertificateRecord(rs.getInt(ID)));
}
rs.close();
s.close();
} catch (Exception e) {
logError(e.getMessage(), e);
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("An unexpected error occurred.");
FaultHelper helper = new FaultHelper(fault);
helper.addFaultCause(e);
fault = (DorianInternalFault) helper.getFault();
throw fault;
} finally {
db.releaseConnection(c);
}
return records;
}
public List<Long> getHostCertificateRecordsSerialNumbers(String owner) throws DorianInternalFault {
this.buildDatabase();
List<Long> sn = new ArrayList<Long>();
Connection c = null;
try {
c = db.getConnection();
PreparedStatement s = c.prepareStatement("select " + SERIAL + " from " + TABLE + " WHERE " + OWNER
+ " = ? AND " + STATUS + " <> ? AND " + STATUS + " <> ? ");
s.setString(1, owner);
s.setString(2, HostCertificateStatus.Pending.getValue());
s.setString(3, HostCertificateStatus.Rejected.getValue());
ResultSet rs = s.executeQuery();
while (rs.next()) {
sn.add(new Long(rs.getLong(SERIAL)));
}
rs.close();
s.close();
} catch (Exception e) {
logError(e.getMessage(), e);
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("An unexpected error occurred.");
FaultHelper helper = new FaultHelper(fault);
helper.addFaultCause(e);
fault = (DorianInternalFault) helper.getFault();
throw fault;
} finally {
db.releaseConnection(c);
}
return sn;
}
public List<Long> getDisabledHostCertificatesSerialNumbers() throws DorianInternalFault {
this.buildDatabase();
List<Long> entries = new ArrayList<Long>();
Connection c = null;
try {
c = db.getConnection();
PreparedStatement s = c.prepareStatement("select " + SERIAL + " from " + TABLE + " WHERE " + STATUS
+ " = ? OR " + STATUS + " = ? ");
s.setString(1, HostCertificateStatus.Suspended.getValue());
s.setString(2, HostCertificateStatus.Compromised.getValue());
ResultSet rs = s.executeQuery();
while (rs.next()) {
long sn = rs.getLong(SERIAL);
entries.add(new Long(sn));
}
rs.close();
s.close();
} catch (Exception e) {
logError(e.getMessage(), e);
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("An unexpected error occurred.");
FaultHelper helper = new FaultHelper(fault);
helper.addFaultCause(e);
fault = (DorianInternalFault) helper.getFault();
throw fault;
} finally {
db.releaseConnection(c);
}
return entries;
}
public HostCertificateRecord getHostCertificateRecord(long id) throws DorianInternalFault,
InvalidHostCertificateFault {
buildDatabase();
Connection c = null;
HostCertificateRecord record = null;
try {
c = db.getConnection();
PreparedStatement s = c.prepareStatement("select " + ID + "," + HOST + "," + SUBJECT + "," + OWNER + ","
+ SERIAL + "," + STATUS + "," + PUBLIC_KEY + "," + CERTIFICATE + " from " + TABLE + " WHERE " + ID
+ "= ?");
s.setLong(1, id);
ResultSet rs = s.executeQuery();
if (rs.next()) {
record = new HostCertificateRecord();
record.setId(rs.getInt(ID));
record.setHost(rs.getString(HOST));
record.setOwner(rs.getString(OWNER));
record.setSerialNumber(rs.getLong(SERIAL));
record.setStatus(HostCertificateStatus.fromValue(rs.getString(STATUS)));
record.setSubject(rs.getString(SUBJECT));
String keyStr = Utils.clean(rs.getString(PUBLIC_KEY));
if (keyStr != null) {
PublicKey pk = new PublicKey();
pk.setKeyAsString(keyStr);
record.setPublicKey(pk);
}
String certStr = Utils.clean(rs.getString(CERTIFICATE));
if (certStr != null) {
X509Certificate cert = new X509Certificate();
cert.setCertificateAsString(certStr);
record.setCertificate(cert);
}
}
rs.close();
s.close();
} catch (Exception e) {
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("An unexpected error occurred.");
FaultHelper helper = new FaultHelper(fault);
helper.addFaultCause(e);
fault = (DorianInternalFault) helper.getFault();
throw fault;
} finally {
db.releaseConnection(c);
}
if (record == null) {
InvalidHostCertificateFault fault = new InvalidHostCertificateFault();
fault.setFaultString("No such host certificate exists.");
throw fault;
}
return record;
}
public synchronized void updateHostCertificateRecord(HostCertificateUpdate update) throws DorianInternalFault,
InvalidHostCertificateFault {
if (!determineIfRecordExistById(update.getId())) {
InvalidHostCertificateFault fault = new InvalidHostCertificateFault();
fault.setFaultString("Could not update host certificate record, no such host certificate exists.");
throw fault;
}
HostCertificateRecord record = getHostCertificateRecord(update.getId());
// First see if the certificate has been compromised, if it has NO
// updates are allowed.
if (record.getStatus().equals(HostCertificateStatus.Compromised)) {
InvalidHostCertificateFault fault = new InvalidHostCertificateFault();
fault
.setFaultString("Could not update host certificate record, the host certificate has been compromised.");
throw fault;
}
if (record.getStatus().equals(HostCertificateStatus.Rejected)) {
InvalidHostCertificateFault fault = new InvalidHostCertificateFault();
fault
.setFaultString("Could not update host certificate record, the host certificate request was rejected.");
throw fault;
}
boolean updateStatus = false;
if ((update.getStatus() != null) && (!update.getStatus().equals(record.getStatus()))) {
if (update.getStatus().equals(HostCertificateStatus.Pending)) {
InvalidHostCertificateFault fault = new InvalidHostCertificateFault();
fault
.setFaultString("Could not update host certificate record, the status of a host certificate cannot be change to "
+ HostCertificateStatus.Pending + " once it has been approved.");
throw fault;
} else if (record.getStatus().equals(HostCertificateStatus.Pending)
&& (!update.getStatus().equals(HostCertificateStatus.Rejected))) {
InvalidHostCertificateFault fault = new InvalidHostCertificateFault();
fault
.setFaultString("Could not update the status of a host certificate record until it has been approved or rejected.");
throw fault;
}
updateStatus = true;
}
boolean updateOwner = false;
if ((update.getOwner() != null) && (!update.getOwner().equals(record.getOwner()))) {
updateOwner = true;
}
if (updateOwner || updateStatus) {
Connection c = null;
try {
c = db.getConnection();
StringBuffer sb = new StringBuffer();
sb.append("update " + TABLE + " SET ");
if (updateStatus) {
sb.append(STATUS + "= ?");
}
if (updateOwner) {
if (updateStatus) {
sb.append(",");
}
sb.append(OWNER + "= ? ");
}
sb.append(" WHERE " + ID + "= ?");
PreparedStatement s = c.prepareStatement(sb.toString());
int count = 1;
if (updateStatus) {
s.setString(count, update.getStatus().toString());
count++;
}
if (updateOwner) {
s.setString(count, update.getOwner());
count++;
}
s.setLong(count, update.getId());
s.execute();
if (updateStatus) {
publishCRLIfNeeded(record.getStatus(), update.getStatus());
}
} catch (Exception e) {
logError(e.getMessage(), e);
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("An unexpected error occurred.");
FaultHelper helper = new FaultHelper(fault);
helper.addFaultCause(e);
fault = (DorianInternalFault) helper.getFault();
throw fault;
} finally {
db.releaseConnection(c);
}
}
}
private boolean determineIfRecordExistById(long id) throws DorianInternalFault {
buildDatabase();
Connection c = null;
boolean exists = false;
try {
c = db.getConnection();
PreparedStatement s = c.prepareStatement("select count(*) from " + TABLE + " WHERE " + ID + "= ?");
s.setLong(1, id);
ResultSet rs = s.executeQuery();
if (rs.next()) {
if (rs.getInt(1) > 0) {
exists = true;
}
}
rs.close();
s.close();
} catch (Exception e) {
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("Unexpected Database Error");
FaultHelper helper = new FaultHelper(fault);
helper.addFaultCause(e);
fault = (DorianInternalFault) helper.getFault();
throw fault;
} finally {
db.releaseConnection(c);
}
return exists;
}
private boolean certificateCannotBeRequested(String host) throws DorianInternalFault {
buildDatabase();
Connection c = null;
boolean exists = false;
try {
c = db.getConnection();
PreparedStatement s = c.prepareStatement("select count(*) from " + TABLE + " WHERE " + HOST + "= ? AND "
+ STATUS + " <> ? AND " + STATUS + " <> ? ");
s.setString(1, host);
s.setString(2, HostCertificateStatus.Rejected.getValue());
s.setString(3, HostCertificateStatus.Compromised.getValue());
ResultSet rs = s.executeQuery();
if (rs.next()) {
if (rs.getInt(1) > 0) {
exists = true;
}
}
rs.close();
s.close();
} catch (Exception e) {
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("An unexpected error occurred.");
FaultHelper helper = new FaultHelper(fault);
helper.addFaultCause(e);
fault = (DorianInternalFault) helper.getFault();
throw fault;
} finally {
db.releaseConnection(c);
}
return exists;
}
public void buildDatabase() throws DorianInternalFault {
if (!dbBuilt) {
try {
if (!this.db.tableExists(TABLE)) {
String certificates = "CREATE TABLE " + TABLE + " (" + ID
+ " INT NOT NULL AUTO_INCREMENT PRIMARY KEY," + SERIAL + " BIGINT," + HOST
+ " VARCHAR(255) NOT NULL," + SUBJECT + " TEXT," + STATUS + " VARCHAR(15) NOT NULL," + OWNER
+ " TEXT NOT NULL," + EXPIRATION + " BIGINT," + CERTIFICATE + " TEXT," + PUBLIC_KEY
+ " TEXT NOT NULL, " + "INDEX document_index (ID));";
db.update(certificates);
}
} catch (Exception e) {
logError(e.getMessage(), e);
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("An unexpected database error occurred.");
FaultHelper helper = new FaultHelper(fault);
helper.addFaultCause(e);
fault = (DorianInternalFault) helper.getFault();
throw fault;
}
this.dbBuilt = true;
}
}
public void clearDatabase() throws DorianInternalFault {
buildDatabase();
try {
db.update("delete from " + TABLE);
} catch (Exception e) {
logError(e.getMessage(), e);
DorianInternalFault fault = new DorianInternalFault();
fault.setFaultString("An unexpected database error occurred.");
FaultHelper helper = new FaultHelper(fault);
helper.addFaultCause(e);
fault = (DorianInternalFault) helper.getFault();
throw fault;
}
}
}