use of org.xipki.ocsp.api.CertStatusInfo 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.CertStatusInfo in project xipki by xipki.
the class OcspServerImpl method processCertReq.
// method ask
private OcspRespWithCacheInfo processCertReq(CertID certId, OCSPRespBuilder builder, ResponderImpl responder, RequestOption reqOpt, ResponseOption repOpt, OcspRespControl repControl) throws IOException {
HashAlgo reqHashAlgo = certId.getIssuer().hashAlgorithm();
if (!reqOpt.allows(reqHashAlgo)) {
LOG.warn("CertID.hashAlgorithm {} not allowed", reqHashAlgo);
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.malformedRequest);
}
CertStatusInfo certStatusInfo = null;
boolean exceptionOccurs = false;
BigInteger serial = certId.getSerialNumber();
Date now = new Date();
for (OcspStore store : responder.getStores()) {
try {
certStatusInfo = store.getCertStatus(now, certId.getIssuer(), serial, repOpt.isIncludeCerthash(), repOpt.isIncludeInvalidityDate(), responder.getResponderOption().isInheritCaRevocation());
if (certStatusInfo != null) {
break;
}
} catch (OcspStoreException ex) {
exceptionOccurs = true;
LogUtil.error(LOG, ex, "getCertStatus() of CertStatusStore " + store.getName());
}
}
if (certStatusInfo == null) {
if (exceptionOccurs) {
return unsuccesfulOCSPRespMap.get(OcspResponseStatus.tryLater);
} else {
certStatusInfo = CertStatusInfo.getIssuerUnknownCertStatusInfo(new Date(), null);
}
}
// end if
// certStatusInfo must not be null in any case, since at least one store is configured
Date thisUpdate = certStatusInfo.getThisUpdate();
if (thisUpdate == null) {
thisUpdate = new Date();
}
Date nextUpdate = certStatusInfo.getNextUpdate();
List<Extension> extensions = new LinkedList<>();
boolean unknownAsRevoked = false;
byte[] certStatus;
switch(certStatusInfo.getCertStatus()) {
case GOOD:
certStatus = bytes_certstatus_good;
break;
case ISSUER_UNKNOWN:
repControl.canCacheInfo = false;
certStatus = bytes_certstatus_unknown;
break;
case UNKNOWN:
case IGNORE:
repControl.canCacheInfo = false;
if (responder.getResponderOption().getMode() == OcspMode.RFC2560) {
certStatus = bytes_certstatus_unknown;
} else {
// (ocspMode == OCSPMode.RFC6960)
unknownAsRevoked = true;
certStatus = bytes_certstatus_rfc6960_unknown;
}
break;
case REVOKED:
CertRevocationInfo revInfo = certStatusInfo.getRevocationInfo();
certStatus = Template.getEncodeRevokedInfo(repOpt.isIncludeRevReason() ? revInfo.getReason() : null, revInfo.getRevocationTime());
Date invalidityDate = revInfo.getInvalidityTime();
if (repOpt.isIncludeInvalidityDate() && invalidityDate != null && !invalidityDate.equals(revInfo.getRevocationTime())) {
extensions.add(Template.getInvalidityDateExtension(invalidityDate));
}
break;
default:
throw new RuntimeException("unknown CertificateStatus:" + certStatusInfo.getCertStatus());
}
if (responder.getResponderOption().getMode() != OcspMode.RFC2560) {
repControl.includeExtendedRevokeExtension = true;
}
byte[] certHash = certStatusInfo.getCertHash();
if (certHash != null) {
extensions.add(Template.getCertHashExtension(certStatusInfo.getCertHashAlgo(), certHash));
}
if (certStatusInfo.getArchiveCutOff() != null) {
extensions.add(Template.getArchiveOffExtension(certStatusInfo.getArchiveCutOff()));
}
if (LOG.isDebugEnabled()) {
String certStatusText = null;
if (Arrays.equals(certStatus, bytes_certstatus_good)) {
certStatusText = "good";
} else if (Arrays.equals(certStatus, bytes_certstatus_unknown)) {
certStatusText = "unknown";
} else if (Arrays.equals(certStatus, bytes_certstatus_rfc6960_unknown)) {
certStatusText = "RFC6969_unknown";
} else {
certStatusText = unknownAsRevoked ? "unknown_as_revoked" : "revoked";
}
String msg = StringUtil.concatObjectsCap(250, "issuer: ", certId.getIssuer(), ", serialNumber: ", LogUtil.formatCsn(certId.getSerialNumber()), ", certStatus: ", certStatusText, ", thisUpdate: ", thisUpdate, ", nextUpdate: ", nextUpdate);
StringBuilder sb = new StringBuilder(msg.length() + 80);
sb.append(msg);
if (certHash != null) {
sb.append(", certHash: ").append(Hex.encode(certHash));
}
LOG.debug(sb.toString());
}
if (CollectionUtil.isEmpty(extensions)) {
builder.addResponse(certId, certStatus, thisUpdate, nextUpdate, null);
} else {
builder.addResponse(certId, certStatus, thisUpdate, nextUpdate, new Extensions(extensions));
}
repControl.cacheThisUpdate = Math.max(repControl.cacheThisUpdate, thisUpdate.getTime());
if (nextUpdate != null) {
repControl.cacheNextUpdate = Math.min(repControl.cacheNextUpdate, nextUpdate.getTime());
}
return null;
}
Aggregations