Search in sources :

Example 1 with IssuerEntry

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);
    }
}
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 IssuerEntry

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;
    }
}
Also used : RequestIssuer(org.xipki.ocsp.api.RequestIssuer) IssuerEntry(org.xipki.ocsp.api.IssuerEntry) HashMap(java.util.HashMap) PreparedStatement(java.sql.PreparedStatement) IssuerStore(org.xipki.ocsp.api.IssuerStore) LinkedList(java.util.LinkedList) X509Certificate(java.security.cert.X509Certificate) OcspStoreException(org.xipki.ocsp.api.OcspStoreException) SQLException(java.sql.SQLException) DataAccessException(org.xipki.datasource.DataAccessException) IOException(java.io.IOException) CertificateException(java.security.cert.CertificateException) Date(java.util.Date) BigInteger(java.math.BigInteger) CrlInfo(org.xipki.ocsp.api.CrlInfo) ResultSet(java.sql.ResultSet)

Example 3 with IssuerEntry

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;
    }
}
Also used : BigInteger(java.math.BigInteger) IssuerEntry(org.xipki.ocsp.api.IssuerEntry) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) DataAccessException(org.xipki.datasource.DataAccessException)

Example 4 with IssuerEntry

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;
}
Also used : BigInteger(java.math.BigInteger) IssuerEntry(org.xipki.ocsp.api.IssuerEntry) SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) CertificateException(java.security.cert.CertificateException) InvalidConfException(org.xipki.common.InvalidConfException) SQLException(java.sql.SQLException) DataAccessException(org.xipki.datasource.DataAccessException) CertificateException(java.security.cert.CertificateException) X509Certificate(java.security.cert.X509Certificate) DataAccessException(org.xipki.datasource.DataAccessException) HashSet(java.util.HashSet)

Example 5 with IssuerEntry

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;
}
Also used : RequestIssuer(org.xipki.ocsp.api.RequestIssuer) IssuerEntry(org.xipki.ocsp.api.IssuerEntry) SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) IssuerStore(org.xipki.ocsp.api.IssuerStore) LinkedList(java.util.LinkedList) X509Certificate(java.security.cert.X509Certificate)

Aggregations

PreparedStatement (java.sql.PreparedStatement)5 SQLException (java.sql.SQLException)5 IssuerEntry (org.xipki.ocsp.api.IssuerEntry)5 ResultSet (java.sql.ResultSet)4 DataAccessException (org.xipki.datasource.DataAccessException)4 BigInteger (java.math.BigInteger)3 X509Certificate (java.security.cert.X509Certificate)3 CertificateException (java.security.cert.CertificateException)2 Date (java.util.Date)2 LinkedList (java.util.LinkedList)2 CrlInfo (org.xipki.ocsp.api.CrlInfo)2 IssuerStore (org.xipki.ocsp.api.IssuerStore)2 OcspStoreException (org.xipki.ocsp.api.OcspStoreException)2 RequestIssuer (org.xipki.ocsp.api.RequestIssuer)2 IOException (java.io.IOException)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 InvalidConfException (org.xipki.common.InvalidConfException)1 CertStatus (org.xipki.ocsp.api.CertStatus)1 CertStatusInfo (org.xipki.ocsp.api.CertStatusInfo)1