use of org.xipki.ocsp.api.IssuerEntry in project xipki by xipki.
the class DbCertStatusStore method getCertStatus.
// method initIssuerStore
@Override
public CertStatusInfo getCertStatus(Date time, RequestIssuer reqIssuer, BigInteger serialNumber, boolean includeCertHash, boolean includeRit, boolean inheritCaRevocation) throws OcspStoreException {
if (serialNumber.signum() != 1) {
// non-positive serial number
return CertStatusInfo.getUnknownCertStatusInfo(new Date(), null);
}
if (!initialized) {
throw new OcspStoreException("initialization of CertStore is still in process");
}
if (initializationFailed) {
throw new OcspStoreException("initialization of CertStore failed");
}
String sql;
try {
IssuerEntry issuer = issuerStore.getIssuerForFp(reqIssuer);
if (issuer == null) {
return null;
}
if (includeCertHash) {
sql = includeRit ? sqlCsWithCertHash : sqlCsNoRitWithCertHash;
} else {
sql = includeRit ? sqlCs : sqlCsNoRit;
}
CrlInfo crlInfo = issuer.getCrlInfo();
Date thisUpdate;
Date nextUpdate = null;
if (crlInfo != null && crlInfo.isUseCrlUpdates()) {
thisUpdate = crlInfo.getThisUpdate();
// this.nextUpdate is still in the future (10 seconds buffer)
if (crlInfo.getNextUpdate().getTime() - System.currentTimeMillis() > 10 * 1000) {
nextUpdate = crlInfo.getNextUpdate();
}
} else {
thisUpdate = new Date();
}
ResultSet rs = null;
CertStatusInfo certStatusInfo = null;
boolean unknown = true;
boolean ignore = false;
String certprofile = null;
String b64CertHash = null;
boolean revoked = false;
int reason = 0;
long revTime = 0;
long invalTime = 0;
PreparedStatement ps = datasource.prepareStatement(datasource.getConnection(), sql);
try {
ps.setInt(1, issuer.getId());
ps.setString(2, serialNumber.toString(16));
rs = ps.executeQuery();
if (rs.next()) {
unknown = false;
long timeInSec = time.getTime() / 1000;
if (!ignore && ignoreNotYetValidCert) {
long notBeforeInSec = rs.getLong("NBEFORE");
if (notBeforeInSec != 0 && timeInSec < notBeforeInSec) {
ignore = true;
}
}
if (!ignore && ignoreExpiredCert) {
long notAfterInSec = rs.getLong("NAFTER");
if (notAfterInSec != 0 && timeInSec > notAfterInSec) {
ignore = true;
}
}
if (!ignore) {
if (includeCertHash) {
b64CertHash = rs.getString("HASH");
}
revoked = rs.getBoolean("REV");
if (revoked) {
reason = rs.getInt("RR");
revTime = rs.getLong("RT");
if (includeRit) {
invalTime = rs.getLong("RIT");
}
}
}
}
// end if (rs.next())
} catch (SQLException ex) {
throw datasource.translate(sql, ex);
} finally {
releaseDbResources(ps, rs);
}
if (unknown) {
if (unknownSerialAsGood) {
certStatusInfo = CertStatusInfo.getGoodCertStatusInfo(certHashAlgo, null, thisUpdate, nextUpdate, null);
} else {
certStatusInfo = CertStatusInfo.getUnknownCertStatusInfo(thisUpdate, nextUpdate);
}
} else {
if (ignore) {
certStatusInfo = CertStatusInfo.getIgnoreCertStatusInfo(thisUpdate, nextUpdate);
} else {
byte[] certHash = (b64CertHash == null) ? null : Base64.decodeFast(b64CertHash);
if (revoked) {
Date invTime = (invalTime == 0 || invalTime == revTime) ? null : new Date(invalTime * 1000);
CertRevocationInfo revInfo = new CertRevocationInfo(reason, new Date(revTime * 1000), invTime);
certStatusInfo = CertStatusInfo.getRevokedCertStatusInfo(revInfo, certHashAlgo, certHash, thisUpdate, nextUpdate, certprofile);
} else {
certStatusInfo = CertStatusInfo.getGoodCertStatusInfo(certHashAlgo, certHash, thisUpdate, nextUpdate, certprofile);
}
}
}
if (includeCrlId && crlInfo != null) {
certStatusInfo.setCrlId(crlInfo.getCrlId());
}
if (includeArchiveCutoff) {
if (retentionInterval != 0) {
Date date;
// expired certificate remains in status store for ever
if (retentionInterval < 0) {
date = issuer.getNotBefore();
} else {
long nowInMs = System.currentTimeMillis();
long dateInMs = Math.max(issuer.getNotBefore().getTime(), nowInMs - DAY * retentionInterval);
date = new Date(dateInMs);
}
certStatusInfo.setArchiveCutOff(date);
}
}
if ((!inheritCaRevocation) || issuer.getRevocationInfo() == null) {
return certStatusInfo;
}
CertRevocationInfo caRevInfo = issuer.getRevocationInfo();
CertStatus certStatus = certStatusInfo.getCertStatus();
boolean replaced = false;
if (certStatus == CertStatus.GOOD || certStatus == CertStatus.UNKNOWN) {
replaced = true;
} else if (certStatus == CertStatus.REVOKED) {
if (certStatusInfo.getRevocationInfo().getRevocationTime().after(caRevInfo.getRevocationTime())) {
replaced = true;
}
}
if (replaced) {
CertRevocationInfo newRevInfo;
if (caRevInfo.getReason() == CrlReason.CA_COMPROMISE) {
newRevInfo = caRevInfo;
} else {
newRevInfo = new CertRevocationInfo(CrlReason.CA_COMPROMISE, caRevInfo.getRevocationTime(), caRevInfo.getInvalidityTime());
}
certStatusInfo = CertStatusInfo.getRevokedCertStatusInfo(newRevInfo, certStatusInfo.getCertHashAlgo(), certStatusInfo.getCertHash(), certStatusInfo.getThisUpdate(), certStatusInfo.getNextUpdate(), certStatusInfo.getCertprofile());
}
return certStatusInfo;
} catch (DataAccessException ex) {
throw new OcspStoreException(ex.getMessage(), ex);
}
}
use of org.xipki.ocsp.api.IssuerEntry in project xipki by xipki.
the class DbCertStatusStore method initIssuerStore.
private synchronized void initIssuerStore() {
if (storeUpdateInProcess.get()) {
return;
}
storeUpdateInProcess.set(true);
try {
if (initialized) {
final String sql = "SELECT ID,REV,RT,S1C FROM ISSUER";
PreparedStatement ps = preparedStatement(sql);
ResultSet rs = null;
try {
Map<Integer, SimpleIssuerEntry> newIssuers = new HashMap<>();
rs = ps.executeQuery();
while (rs.next()) {
String sha1Fp = rs.getString("S1C");
if (!issuerFilter.includeIssuerWithSha1Fp(sha1Fp)) {
continue;
}
int id = rs.getInt("ID");
boolean revoked = rs.getBoolean("REV");
Long revTimeMs = revoked ? rs.getLong("RT") * 1000 : null;
SimpleIssuerEntry issuerEntry = new SimpleIssuerEntry(id, revTimeMs);
newIssuers.put(id, issuerEntry);
}
// no change in the issuerStore
Set<Integer> newIds = newIssuers.keySet();
Set<Integer> ids = (issuerStore != null) ? issuerStore.getIds() : Collections.emptySet();
boolean issuersUnchanged = (ids.size() == newIds.size()) && ids.containsAll(newIds) && newIds.containsAll(ids);
if (issuersUnchanged) {
for (Integer id : newIds) {
IssuerEntry entry = issuerStore.getIssuerForId(id);
SimpleIssuerEntry newEntry = newIssuers.get(id);
if (newEntry.match(entry)) {
issuersUnchanged = false;
break;
}
}
}
if (issuersUnchanged) {
return;
}
} finally {
releaseDbResources(ps, rs);
}
}
// end if(initialized)
final String sql = "SELECT ID,NBEFORE,REV,RT,S1C,CERT,CRL_INFO FROM ISSUER";
PreparedStatement ps = preparedStatement(sql);
ResultSet rs = null;
try {
rs = ps.executeQuery();
List<IssuerEntry> caInfos = new LinkedList<>();
while (rs.next()) {
String sha1Fp = rs.getString("S1C");
if (!issuerFilter.includeIssuerWithSha1Fp(sha1Fp)) {
continue;
}
int id = rs.getInt("ID");
String b64Cert = rs.getString("CERT");
X509Certificate cert = X509Util.parseBase64EncodedCert(b64Cert);
IssuerEntry caInfoEntry = new IssuerEntry(id, cert);
String crlInfoStr = rs.getString("CRL_INFO");
if (StringUtil.isNotBlank(crlInfoStr)) {
CrlInfo crlInfo = new CrlInfo(crlInfoStr);
caInfoEntry.setCrlInfo(crlInfo);
}
RequestIssuer reqIssuer = new RequestIssuer(HashAlgo.SHA1, caInfoEntry.getEncodedHash(HashAlgo.SHA1));
for (IssuerEntry existingIssuer : caInfos) {
if (existingIssuer.matchHash(reqIssuer)) {
throw new Exception("found at least two issuers with the same subject and key");
}
}
boolean revoked = rs.getBoolean("REV");
if (revoked) {
long lo = rs.getLong("RT");
caInfoEntry.setRevocationInfo(new Date(lo * 1000));
}
caInfos.add(caInfoEntry);
}
// end while (rs.next())
initialized = false;
this.issuerStore = new IssuerStore(caInfos);
LOG.info("Updated issuers: {}", name);
initializationFailed = false;
initialized = true;
} finally {
releaseDbResources(ps, rs);
}
} catch (Throwable th) {
storeUpdateInProcess.set(false);
LogUtil.error(LOG, th, "could not executing initIssuerStore()");
initializationFailed = true;
initialized = true;
}
}
use of org.xipki.ocsp.api.IssuerEntry in project xipki by xipki.
the class ResponseCacher method storeIssuer.
synchronized Integer storeIssuer(X509Certificate issuerCert) throws CertificateException, InvalidConfException, DataAccessException {
if (!master) {
throw new IllegalStateException("storeIssuer is not permitted in slave mode");
}
for (Integer id : issuerStore.getIds()) {
if (issuerStore.getIssuerForId(id).getCert().equals(issuerCert)) {
return id;
}
}
byte[] encodedCert = issuerCert.getEncoded();
String sha1FpCert = HashAlgo.SHA1.base64Hash(encodedCert);
int maxId = (int) datasource.getMax(null, "ISSUER", "ID");
int id = maxId + 1;
try {
final String sql = SQL_ADD_ISSUER;
PreparedStatement ps = null;
try {
ps = prepareStatement(sql);
int idx = 1;
ps.setInt(idx++, id);
ps.setString(idx++, sha1FpCert);
ps.setString(idx++, Base64.encodeToString(encodedCert));
ps.execute();
IssuerEntry newInfo = new IssuerEntry(id, issuerCert);
issuerStore.addIssuer(newInfo);
return id;
} catch (SQLException ex) {
throw datasource.translate(sql, ex);
} finally {
datasource.releaseResources(ps, null);
}
} catch (DataAccessException ex) {
if (ex.getReason().isDescendantOrSelfOf(Reason.DuplicateKey)) {
return id;
}
throw ex;
}
}
use of org.xipki.ocsp.api.IssuerEntry in project xipki by xipki.
the class ResponseCacher method updateCacheStore0.
/**
* update the cache store.
* @return whether the ResponseCacher is on service.
*/
private boolean updateCacheStore0() {
try {
if (this.issuerStore == null) {
return initIssuerStore();
}
// check for new issuers
PreparedStatement ps = null;
ResultSet rs = null;
Set<Integer> ids = new HashSet<>();
try {
ps = prepareStatement(SQL_SELECT_ISSUER_ID);
rs = ps.executeQuery();
if (master) {
// whether the database is accessible
return true;
}
while (rs.next()) {
ids.add(rs.getInt("ID"));
}
} catch (SQLException ex) {
LogUtil.error(LOG, datasource.translate(SQL_SELECT_ISSUER_ID, ex), "could not executing updateCacheStore()");
return false;
} catch (Exception ex) {
LogUtil.error(LOG, ex, "could not executing updateCacheStore()");
return false;
} finally {
datasource.releaseResources(ps, rs, false);
}
// add the new issuers
ps = null;
rs = null;
Set<Integer> currentIds = issuerStore.getIds();
for (Integer id : ids) {
if (currentIds.contains(id)) {
continue;
}
try {
if (ps == null) {
ps = prepareStatement(sqlSelectIssuerCert);
}
ps.setInt(1, id);
rs = ps.executeQuery();
rs.next();
String b64Cert = rs.getString("CERT");
X509Certificate cert = X509Util.parseBase64EncodedCert(b64Cert);
IssuerEntry caInfoEntry = new IssuerEntry(id, cert);
issuerStore.addIssuer(caInfoEntry);
LOG.info("added issuer {}", id);
} catch (SQLException ex) {
LogUtil.error(LOG, datasource.translate(sqlSelectIssuerCert, ex), "could not executing updateCacheStore()");
return false;
} catch (Exception ex) {
LogUtil.error(LOG, ex, "could not executing updateCacheStore()");
return false;
} finally {
datasource.releaseResources(null, rs, false);
}
}
if (ps != null) {
datasource.releaseResources(ps, null, false);
}
} catch (DataAccessException ex) {
LogUtil.error(LOG, ex, "could not executing updateCacheStore()");
return false;
} catch (CertificateException ex) {
// don't set the onService to false.
LogUtil.error(LOG, ex, "could not executing updateCacheStore()");
}
return true;
}
use of org.xipki.ocsp.api.IssuerEntry in project xipki by xipki.
the class ResponseCacher method initIssuerStore.
// method updateCacheStore0
private boolean initIssuerStore() throws DataAccessException, CertificateException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = prepareStatement(SQL_SELECT_ISSUER);
rs = ps.executeQuery();
List<IssuerEntry> caInfos = new LinkedList<>();
PreparedStatement deleteIssuerStmt = null;
while (rs.next()) {
int id = rs.getInt("ID");
String b64Cert = rs.getString("CERT");
X509Certificate cert = X509Util.parseBase64EncodedCert(b64Cert);
IssuerEntry caInfoEntry = new IssuerEntry(id, cert);
RequestIssuer reqIssuer = new RequestIssuer(HashAlgo.SHA1, caInfoEntry.getEncodedHash(HashAlgo.SHA1));
boolean duplicated = false;
for (IssuerEntry existingIssuer : caInfos) {
if (existingIssuer.matchHash(reqIssuer)) {
duplicated = true;
break;
}
}
String subject = cert.getSubjectX500Principal().getName();
if (duplicated) {
if (deleteIssuerStmt == null) {
deleteIssuerStmt = prepareStatement(SQL_DELETE_ISSUER);
}
deleteIssuerStmt.setInt(1, id);
deleteIssuerStmt.executeUpdate();
LOG.warn("Delete duplicated issuer {}: {}", id, subject);
} else {
LOG.info("added issuer {}: {}", id, subject);
caInfos.add(caInfoEntry);
}
}
// end while (rs.next())
this.issuerStore = new IssuerStore(caInfos);
LOG.info("Updated issuers");
} catch (SQLException ex) {
throw datasource.translate(SQL_SELECT_ISSUER, ex);
} finally {
datasource.releaseResources(ps, rs, false);
}
return true;
}
Aggregations