Search in sources :

Example 1 with CertStatusInfo

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);
    }
}
Also used : IssuerEntry(org.xipki.ocsp.api.IssuerEntry) OcspStoreException(org.xipki.ocsp.api.OcspStoreException) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) CertStatusInfo(org.xipki.ocsp.api.CertStatusInfo) Date(java.util.Date) CertRevocationInfo(org.xipki.security.CertRevocationInfo) CrlInfo(org.xipki.ocsp.api.CrlInfo) CertStatus(org.xipki.ocsp.api.CertStatus) ResultSet(java.sql.ResultSet) DataAccessException(org.xipki.datasource.DataAccessException)

Example 2 with CertStatusInfo

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;
}
Also used : OcspStoreException(org.xipki.ocsp.api.OcspStoreException) HashAlgo(org.xipki.security.HashAlgo) CertStatusInfo(org.xipki.ocsp.api.CertStatusInfo) Extensions(org.xipki.ocsp.server.impl.type.Extensions) Date(java.util.Date) LinkedList(java.util.LinkedList) Extension(org.xipki.ocsp.server.impl.type.Extension) WritableOnlyExtension(org.xipki.ocsp.server.impl.type.WritableOnlyExtension) ExtendedExtension(org.xipki.ocsp.server.impl.type.ExtendedExtension) CertRevocationInfo(org.xipki.security.CertRevocationInfo) OcspStore(org.xipki.ocsp.api.OcspStore) BigInteger(java.math.BigInteger)

Aggregations

Date (java.util.Date)2 CertStatusInfo (org.xipki.ocsp.api.CertStatusInfo)2 OcspStoreException (org.xipki.ocsp.api.OcspStoreException)2 CertRevocationInfo (org.xipki.security.CertRevocationInfo)2 BigInteger (java.math.BigInteger)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 LinkedList (java.util.LinkedList)1 DataAccessException (org.xipki.datasource.DataAccessException)1 CertStatus (org.xipki.ocsp.api.CertStatus)1 CrlInfo (org.xipki.ocsp.api.CrlInfo)1 IssuerEntry (org.xipki.ocsp.api.IssuerEntry)1 OcspStore (org.xipki.ocsp.api.OcspStore)1 ExtendedExtension (org.xipki.ocsp.server.impl.type.ExtendedExtension)1 Extension (org.xipki.ocsp.server.impl.type.Extension)1 Extensions (org.xipki.ocsp.server.impl.type.Extensions)1 WritableOnlyExtension (org.xipki.ocsp.server.impl.type.WritableOnlyExtension)1 HashAlgo (org.xipki.security.HashAlgo)1