Search in sources :

Example 1 with OcspStoreException

use of org.xipki.ocsp.api.OcspStoreException 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 OcspStoreException

use of org.xipki.ocsp.api.OcspStoreException in project xipki by xipki.

the class DbCertStatusStore method init.

@Override
public void init(String conf, DataSourceWrapper datasource) throws OcspStoreException {
    ParamUtil.requireNonNull("conf", conf);
    this.datasource = ParamUtil.requireNonNull("datasource", datasource);
    sqlCs = datasource.buildSelectFirstSql(1, "NBEFORE,NAFTER,REV,RR,RT,RIT FROM CERT WHERE IID=? AND SN=?");
    sqlCsNoRit = datasource.buildSelectFirstSql(1, "NBEFORE,NAFTER,REV,RR,RT FROM CERT WHERE IID=? AND SN=?");
    sqlCsWithCertHash = datasource.buildSelectFirstSql(1, "NBEFORE,NAFTER,REV,RR,RT,RIT,HASH FROM CERT WHERE IID=? AND SN=?");
    sqlCsNoRitWithCertHash = datasource.buildSelectFirstSql(1, "NBEFORE,NAFTER,REV,RR,RT,HASH FROM CERT WHERE IID=? AND SN=?");
    try {
        this.certHashAlgo = getCertHashAlgo(datasource);
    } catch (DataAccessException ex) {
        throw new OcspStoreException("Could not retrieve the certhash's algorithm from the database", ex);
    }
    StoreConf storeConf = new StoreConf(conf);
    try {
        Set<X509Certificate> includeIssuers = null;
        Set<X509Certificate> excludeIssuers = null;
        if (CollectionUtil.isNonEmpty(storeConf.getCaCertsIncludes())) {
            includeIssuers = parseCerts(storeConf.getCaCertsIncludes());
        }
        if (CollectionUtil.isNonEmpty(storeConf.getCaCertsExcludes())) {
            excludeIssuers = parseCerts(storeConf.getCaCertsExcludes());
        }
        this.issuerFilter = new IssuerFilter(includeIssuers, excludeIssuers);
    } catch (CertificateException ex) {
        throw new OcspStoreException(ex.getMessage(), ex);
    }
    // end try
    initIssuerStore();
    if (this.scheduledThreadPoolExecutor != null) {
        this.scheduledThreadPoolExecutor.shutdownNow();
    }
    StoreUpdateService storeUpdateService = new StoreUpdateService();
    List<Runnable> scheduledServices = getScheduledServices();
    int size = 1;
    if (scheduledServices != null) {
        size += scheduledServices.size();
    }
    this.scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(size);
    Random random = new Random();
    this.scheduledThreadPoolExecutor.scheduleAtFixedRate(storeUpdateService, 60 + random.nextInt(60), 60, TimeUnit.SECONDS);
    if (scheduledServices != null) {
        for (Runnable service : scheduledServices) {
            this.scheduledThreadPoolExecutor.scheduleAtFixedRate(service, 60 + random.nextInt(60), 60, TimeUnit.SECONDS);
        }
    }
}
Also used : IssuerFilter(org.xipki.ocsp.api.IssuerFilter) OcspStoreException(org.xipki.ocsp.api.OcspStoreException) ScheduledThreadPoolExecutor(java.util.concurrent.ScheduledThreadPoolExecutor) CertificateException(java.security.cert.CertificateException) X509Certificate(java.security.cert.X509Certificate) Random(java.util.Random) DataAccessException(org.xipki.datasource.DataAccessException)

Example 3 with OcspStoreException

use of org.xipki.ocsp.api.OcspStoreException 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)

Example 4 with OcspStoreException

use of org.xipki.ocsp.api.OcspStoreException in project xipki by xipki.

the class OcspServerImpl method newStore.

// method initSigner
private OcspStore newStore(StoreType conf, Map<String, DataSourceWrapper> datasources) throws InvalidConfException {
    OcspStore store;
    String type = conf.getSource().getType();
    if ("CRL".equalsIgnoreCase(type)) {
        store = new CrlDbCertStatusStore();
    } else if ("XIPKI-DB".equals(type)) {
        store = new DbCertStatusStore();
    } else {
        try {
            store = ocspStoreFactoryRegister.newOcspStore(conf.getSource().getType());
        } catch (ObjectCreationException ex) {
            throw new InvalidConfException("ObjectCreationException of store " + conf.getName() + ":" + ex.getMessage(), ex);
        }
    }
    store.setName(conf.getName());
    Integer interval = conf.getRetentionInterval();
    int retentionInterva = (interval == null) ? -1 : interval.intValue();
    store.setRetentionInterval(retentionInterva);
    store.setUnknownSerialAsGood(getBoolean(conf.isUnknownSerialAsGood(), false));
    store.setIncludeArchiveCutoff(getBoolean(conf.isIncludeArchiveCutoff(), true));
    store.setIncludeCrlId(getBoolean(conf.isIncludeCrlID(), true));
    store.setIgnoreExpiredCert(getBoolean(conf.isIgnoreExpiredCert(), true));
    store.setIgnoreNotYetValidCert(getBoolean(conf.isIgnoreNotYetValidCert(), true));
    String datasourceName = conf.getSource().getDatasource();
    DataSourceWrapper datasource = null;
    if (datasourceName != null) {
        datasource = datasources.get(datasourceName);
        if (datasource == null) {
            throw new InvalidConfException("datasource named '" + datasourceName + "' not defined");
        }
    }
    try {
        store.init(conf.getSource().getConf(), datasource);
    } catch (OcspStoreException ex) {
        throw new InvalidConfException("CertStatusStoreException of store " + conf.getName() + ":" + ex.getMessage(), ex);
    }
    return store;
}
Also used : CrlDbCertStatusStore(org.xipki.ocsp.server.impl.store.crl.CrlDbCertStatusStore) DbCertStatusStore(org.xipki.ocsp.server.impl.store.db.DbCertStatusStore) BigInteger(java.math.BigInteger) CrlDbCertStatusStore(org.xipki.ocsp.server.impl.store.crl.CrlDbCertStatusStore) OcspStoreException(org.xipki.ocsp.api.OcspStoreException) OcspStore(org.xipki.ocsp.api.OcspStore) ObjectCreationException(org.xipki.common.ObjectCreationException) InvalidConfException(org.xipki.common.InvalidConfException) DataSourceWrapper(org.xipki.datasource.DataSourceWrapper)

Aggregations

OcspStoreException (org.xipki.ocsp.api.OcspStoreException)4 BigInteger (java.math.BigInteger)2 Date (java.util.Date)2 DataAccessException (org.xipki.datasource.DataAccessException)2 CertStatusInfo (org.xipki.ocsp.api.CertStatusInfo)2 OcspStore (org.xipki.ocsp.api.OcspStore)2 CertRevocationInfo (org.xipki.security.CertRevocationInfo)2 CertificateException (java.security.cert.CertificateException)1 X509Certificate (java.security.cert.X509Certificate)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 LinkedList (java.util.LinkedList)1 Random (java.util.Random)1 ScheduledThreadPoolExecutor (java.util.concurrent.ScheduledThreadPoolExecutor)1 InvalidConfException (org.xipki.common.InvalidConfException)1 ObjectCreationException (org.xipki.common.ObjectCreationException)1 DataSourceWrapper (org.xipki.datasource.DataSourceWrapper)1 CertStatus (org.xipki.ocsp.api.CertStatus)1 CrlInfo (org.xipki.ocsp.api.CrlInfo)1