Search in sources :

Example 6 with CertRevocationInfo

use of org.xipki.security.CertRevocationInfo in project xipki by xipki.

the class CertStoreQueryExecutor method revokeCert.

// method addCrl
X509CertWithRevocationInfo revokeCert(NameId ca, BigInteger serialNumber, CertRevocationInfo revInfo, boolean force, boolean publishToDeltaCrlCache, CaIdNameMap idNameMap) throws OperationException, DataAccessException {
    ParamUtil.requireNonNull("ca", ca);
    ParamUtil.requireNonNull("serialNumber", serialNumber);
    ParamUtil.requireNonNull("revInfo", revInfo);
    X509CertWithRevocationInfo certWithRevInfo = getCertWithRevocationInfo(ca, serialNumber, idNameMap);
    if (certWithRevInfo == null) {
        LOG.warn("certificate with CA={} and serialNumber={} does not exist", ca.getName(), LogUtil.formatCsn(serialNumber));
        return null;
    }
    CertRevocationInfo currentRevInfo = certWithRevInfo.getRevInfo();
    if (currentRevInfo != null) {
        CrlReason currentReason = currentRevInfo.getReason();
        if (currentReason == CrlReason.CERTIFICATE_HOLD) {
            if (revInfo.getReason() == CrlReason.CERTIFICATE_HOLD) {
                throw new OperationException(ErrorCode.CERT_REVOKED, "certificate already revoked with the requested reason " + currentReason.getDescription());
            } else {
                revInfo.setRevocationTime(currentRevInfo.getRevocationTime());
                revInfo.setInvalidityTime(currentRevInfo.getInvalidityTime());
            }
        } else if (!force) {
            throw new OperationException(ErrorCode.CERT_REVOKED, "certificate already revoked with reason " + currentReason.getDescription());
        }
    }
    long certId = certWithRevInfo.getCert().getCertId().longValue();
    long revTimeSeconds = revInfo.getRevocationTime().getTime() / 1000;
    Long invTimeSeconds = null;
    if (revInfo.getInvalidityTime() != null) {
        invTimeSeconds = revInfo.getInvalidityTime().getTime() / 1000;
    }
    PreparedStatement ps = borrowPreparedStatement(SQLs.SQL_REVOKE_CERT);
    try {
        int idx = 1;
        ps.setLong(idx++, System.currentTimeMillis() / 1000);
        setBoolean(ps, idx++, true);
        ps.setLong(idx++, revTimeSeconds);
        setLong(ps, idx++, invTimeSeconds);
        ps.setInt(idx++, revInfo.getReason().getCode());
        ps.setLong(idx++, certId);
        int count = ps.executeUpdate();
        if (count != 1) {
            String message = (count > 1) ? count + " rows modified, but exactly one is expected" : "no row is modified, but exactly one is expected";
            throw new OperationException(ErrorCode.SYSTEM_FAILURE, message);
        }
    } catch (SQLException ex) {
        throw datasource.translate(SQLs.SQL_REVOKE_CERT, ex);
    } finally {
        releaseDbResources(ps, null);
    }
    if (publishToDeltaCrlCache) {
        publishToDeltaCrlCache(ca, certWithRevInfo.getCert().getCert().getSerialNumber());
    }
    certWithRevInfo.setRevInfo(revInfo);
    return certWithRevInfo;
}
Also used : CertRevocationInfo(org.xipki.security.CertRevocationInfo) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) CrlReason(org.xipki.security.CrlReason) DERPrintableString(org.bouncycastle.asn1.DERPrintableString) DEROctetString(org.bouncycastle.asn1.DEROctetString) OperationException(org.xipki.ca.api.OperationException)

Example 7 with CertRevocationInfo

use of org.xipki.security.CertRevocationInfo in project xipki by xipki.

the class CertStoreQueryExecutor method getCertWithRevocationInfo.

// method getCertForId
X509CertWithRevocationInfo getCertWithRevocationInfo(NameId ca, BigInteger serial, CaIdNameMap idNameMap) throws DataAccessException, OperationException {
    ParamUtil.requireNonNull("ca", ca);
    ParamUtil.requireNonNull("serial", serial);
    ParamUtil.requireNonNull("idNameMap", idNameMap);
    final String sql = sqls.sqlCertWithRevInfo;
    long certId;
    String b64Cert;
    boolean revoked;
    int revReason = 0;
    long revTime = 0;
    long revInvTime = 0;
    int certprofileId = 0;
    ResultSet rs = null;
    PreparedStatement ps = borrowPreparedStatement(sql);
    try {
        int idx = 1;
        ps.setInt(idx++, ca.getId());
        ps.setString(idx++, serial.toString(16));
        rs = ps.executeQuery();
        if (!rs.next()) {
            return null;
        }
        certId = rs.getLong("ID");
        b64Cert = rs.getString("CERT");
        certprofileId = rs.getInt("PID");
        revoked = rs.getBoolean("REV");
        if (revoked) {
            revReason = rs.getInt("RR");
            revTime = rs.getLong("RT");
            revInvTime = rs.getLong("RIT");
        }
    } catch (SQLException ex) {
        throw datasource.translate(sql, ex);
    } finally {
        releaseDbResources(ps, null);
    }
    byte[] certBytes = Base64.decodeFast(b64Cert);
    X509Certificate cert;
    try {
        cert = X509Util.parseCert(certBytes);
    } catch (CertificateException ex) {
        throw new OperationException(ErrorCode.SYSTEM_FAILURE, ex);
    }
    CertRevocationInfo revInfo = null;
    if (revoked) {
        Date invalidityTime = (revInvTime == 0) ? null : new Date(1000 * revInvTime);
        revInfo = new CertRevocationInfo(revReason, new Date(1000 * revTime), invalidityTime);
    }
    X509CertWithDbId certWithMeta = new X509CertWithDbId(cert, certBytes);
    certWithMeta.setCertId(certId);
    String profileName = idNameMap.getCertprofileName(certprofileId);
    X509CertWithRevocationInfo ret = new X509CertWithRevocationInfo();
    ret.setCertprofile(profileName);
    ret.setCert(certWithMeta);
    ret.setRevInfo(revInfo);
    return ret;
}
Also used : SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) CertificateException(java.security.cert.CertificateException) X509CertWithDbId(org.xipki.ca.api.X509CertWithDbId) DERPrintableString(org.bouncycastle.asn1.DERPrintableString) DEROctetString(org.bouncycastle.asn1.DEROctetString) X509Certificate(java.security.cert.X509Certificate) Date(java.util.Date) CertRevocationInfo(org.xipki.security.CertRevocationInfo) ResultSet(java.sql.ResultSet) OperationException(org.xipki.ca.api.OperationException)

Example 8 with CertRevocationInfo

use of org.xipki.security.CertRevocationInfo in project xipki by xipki.

the class CaManagerQueryExecutor method createCaInfo.

// method createResponder
X509CaInfo createCaInfo(String name, boolean masterMode, CertificateStore certstore) throws CaMgmtException {
    final String sql = sqls.sqlSelectCa;
    PreparedStatement stmt = null;
    ResultSet rs = null;
    try {
        stmt = prepareStatement(sql);
        stmt.setString(1, name);
        rs = stmt.executeQuery();
        if (!rs.next()) {
            throw new CaMgmtException("uknown CA " + name);
        }
        int artCode = rs.getInt("ART");
        if (artCode != CertArt.X509PKC.getCode()) {
            throw new CaMgmtException("CA " + name + " is not X509CA, and is not supported");
        }
        String crlUris = rs.getString("CRL_URIS");
        String deltaCrlUris = rs.getString("DELTACRL_URIS");
        CertRevocationInfo revocationInfo = null;
        boolean revoked = rs.getBoolean("REV");
        if (revoked) {
            int revReason = rs.getInt("RR");
            long revTime = rs.getInt("RT");
            long revInvalidityTime = rs.getInt("RIT");
            Date revInvTime = (revInvalidityTime == 0) ? null : new Date(revInvalidityTime * 1000);
            revocationInfo = new CertRevocationInfo(revReason, new Date(revTime * 1000), revInvTime);
        }
        List<String> tmpCrlUris = null;
        if (StringUtil.isNotBlank(crlUris)) {
            tmpCrlUris = StringUtil.splitByComma(crlUris);
        }
        List<String> tmpDeltaCrlUris = null;
        if (StringUtil.isNotBlank(deltaCrlUris)) {
            tmpDeltaCrlUris = StringUtil.splitByComma(deltaCrlUris);
        }
        String ocspUris = rs.getString("OCSP_URIS");
        List<String> tmpOcspUris = null;
        if (StringUtil.isNotBlank(ocspUris)) {
            tmpOcspUris = StringUtil.splitByComma(ocspUris);
        }
        String caCertUris = rs.getString("CACERT_URIS");
        List<String> tmpCaCertUris = null;
        if (StringUtil.isNotBlank(caCertUris)) {
            tmpCaCertUris = StringUtil.splitByComma(caCertUris);
        }
        X509CaUris caUris = new X509CaUris(tmpCaCertUris, tmpOcspUris, tmpCrlUris, tmpDeltaCrlUris);
        int id = rs.getInt("ID");
        int serialNoSize = rs.getInt("SN_SIZE");
        long nextCrlNo = rs.getLong("NEXT_CRLNO");
        String signerType = rs.getString("SIGNER_TYPE");
        String signerConf = rs.getString("SIGNER_CONF");
        int numCrls = rs.getInt("NUM_CRLS");
        int expirationPeriod = rs.getInt("EXPIRATION_PERIOD");
        X509CaEntry entry = new X509CaEntry(new NameId(id, name), serialNoSize, nextCrlNo, signerType, signerConf, caUris, numCrls, expirationPeriod);
        String b64cert = rs.getString("CERT");
        X509Certificate cert = generateCert(b64cert);
        entry.setCert(cert);
        String status = rs.getString("STATUS");
        CaStatus caStatus = CaStatus.forName(status);
        entry.setStatus(caStatus);
        String maxValidityS = rs.getString("MAX_VALIDITY");
        CertValidity maxValidity = CertValidity.getInstance(maxValidityS);
        entry.setMaxValidity(maxValidity);
        int keepExpiredCertDays = rs.getInt("KEEP_EXPIRED_CERT_DAYS");
        entry.setKeepExpiredCertInDays(keepExpiredCertDays);
        String crlsignerName = rs.getString("CRLSIGNER_NAME");
        if (StringUtil.isNotBlank(crlsignerName)) {
            entry.setCrlSignerName(crlsignerName);
        }
        String responderName = rs.getString("RESPONDER_NAME");
        if (StringUtil.isNotBlank(responderName)) {
            entry.setResponderName(responderName);
        }
        String extraControl = rs.getString("EXTRA_CONTROL");
        if (StringUtil.isNotBlank(extraControl)) {
            entry.setExtraControl(new ConfPairs(extraControl).unmodifiable());
        }
        String cmpcontrolName = rs.getString("CMPCONTROL_NAME");
        if (StringUtil.isNotBlank(cmpcontrolName)) {
            entry.setCmpControlName(cmpcontrolName);
        }
        boolean duplicateKeyPermitted = (rs.getInt("DUPLICATE_KEY") != 0);
        entry.setDuplicateKeyPermitted(duplicateKeyPermitted);
        boolean duplicateSubjectPermitted = (rs.getInt("DUPLICATE_SUBJECT") != 0);
        entry.setDuplicateSubjectPermitted(duplicateSubjectPermitted);
        boolean saveReq = (rs.getInt("SAVE_REQ") != 0);
        entry.setSaveRequest(saveReq);
        int permission = rs.getInt("PERMISSION");
        entry.setPermission(permission);
        entry.setRevocationInfo(revocationInfo);
        String validityModeS = rs.getString("VALIDITY_MODE");
        ValidityMode validityMode = null;
        if (validityModeS != null) {
            validityMode = ValidityMode.forName(validityModeS);
        }
        if (validityMode == null) {
            validityMode = ValidityMode.STRICT;
        }
        entry.setValidityMode(validityMode);
        try {
            return new X509CaInfo(entry, certstore);
        } catch (OperationException ex) {
            throw new CaMgmtException(ex);
        }
    } catch (SQLException ex) {
        throw new CaMgmtException(datasource, sql, ex);
    } finally {
        datasource.releaseResources(stmt, rs);
    }
}
Also used : NameId(org.xipki.ca.api.NameId) CertValidity(org.xipki.ca.api.profile.CertValidity) SQLException(java.sql.SQLException) ConfPairs(org.xipki.common.ConfPairs) PreparedStatement(java.sql.PreparedStatement) CaStatus(org.xipki.ca.server.mgmt.api.CaStatus) Date(java.util.Date) X509Certificate(java.security.cert.X509Certificate) CertRevocationInfo(org.xipki.security.CertRevocationInfo) CaMgmtException(org.xipki.ca.server.mgmt.api.CaMgmtException) X509CaUris(org.xipki.ca.server.mgmt.api.x509.X509CaUris) ValidityMode(org.xipki.ca.server.mgmt.api.ValidityMode) ResultSet(java.sql.ResultSet) OperationException(org.xipki.ca.api.OperationException) X509CaEntry(org.xipki.ca.server.mgmt.api.x509.X509CaEntry)

Example 9 with CertRevocationInfo

use of org.xipki.security.CertRevocationInfo 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 10 with CertRevocationInfo

use of org.xipki.security.CertRevocationInfo in project xipki by xipki.

the class CrlDbCertStatusStore method initializeStore.

private synchronized void initializeStore(DataSourceWrapper datasource) {
    if (crlUpdateInProcess.get()) {
        return;
    }
    crlUpdateInProcess.set(true);
    Boolean updateCrlSuccessful = null;
    File updateMeFile = new File(crlFilename + ".UPDATEME");
    if (!updateMeFile.exists()) {
        LOG.info("The CRL will not be updated. Create new file {} to force the update", updateMeFile.getAbsolutePath());
        crlUpdated = true;
        crlUpdateFailed = false;
        return;
    }
    try {
        File fullCrlFile = new File(crlFilename);
        if (!fullCrlFile.exists()) {
            // file does not exist
            LOG.warn("CRL File {} does not exist", crlFilename);
            return;
        }
        LOG.info("UPDATE_CERTSTORE: a newer CRL is available");
        updateCrlSuccessful = false;
        X509CRL crl = X509Util.parseCrl(crlFilename);
        File revFile = new File(crlFilename + ".revocation");
        CertRevocationInfo caRevInfo = null;
        if (revFile.exists()) {
            Properties props = new Properties();
            FileInputStream is = new FileInputStream(revFile);
            try {
                props.load(is);
            } finally {
                is.close();
            }
            String str = props.getProperty(KEY_CA_REVOCATION_TIME);
            if (StringUtil.isNotBlank(str)) {
                Date revocationTime = DateUtil.parseUtcTimeyyyyMMddhhmmss(str);
                Date invalidityTime = null;
                str = props.getProperty(KEY_CA_INVALIDITY_TIME);
                if (StringUtil.isNotBlank(str)) {
                    invalidityTime = DateUtil.parseUtcTimeyyyyMMddhhmmss(str);
                }
                caRevInfo = new CertRevocationInfo(CrlReason.UNSPECIFIED, revocationTime, invalidityTime);
            }
        }
        ImportCrl importCrl = new ImportCrl(datasource, useUpdateDatesFromCrl, crl, crlUrl, caCert, issuerCert, caRevInfo, certsDirName);
        updateCrlSuccessful = importCrl.importCrlToOcspDb();
        crlUpdated = true;
        if (updateCrlSuccessful) {
            crlUpdateFailed = false;
            LOG.info("updated CertStore {} successfully", name);
        } else {
            crlUpdateFailed = true;
            LOG.error("updating CertStore {} failed", name);
        }
    } catch (Throwable th) {
        LogUtil.error(LOG, th, "could not execute initializeStore()");
        crlUpdateFailed = true;
        crlUpdated = true;
    } finally {
        updateMeFile.delete();
        crlUpdateInProcess.set(false);
        if (updateCrlSuccessful != null) {
            if (updateCrlSuccessful.booleanValue()) {
                LOG.info("UPDATE_CRL: successful");
            } else {
                LOG.warn("UPDATE_CRL: failed");
            }
        }
    }
}
Also used : CertRevocationInfo(org.xipki.security.CertRevocationInfo) X509CRL(java.security.cert.X509CRL) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Properties(java.util.Properties) File(java.io.File) FileInputStream(java.io.FileInputStream) Date(java.util.Date)

Aggregations

CertRevocationInfo (org.xipki.security.CertRevocationInfo)14 Date (java.util.Date)9 PreparedStatement (java.sql.PreparedStatement)8 SQLException (java.sql.SQLException)8 DERPrintableString (org.bouncycastle.asn1.DERPrintableString)7 OperationException (org.xipki.ca.api.OperationException)7 DEROctetString (org.bouncycastle.asn1.DEROctetString)6 ResultSet (java.sql.ResultSet)5 CrlReason (org.xipki.security.CrlReason)5 X509Certificate (java.security.cert.X509Certificate)4 X509CertWithDbId (org.xipki.ca.api.X509CertWithDbId)3 CaMgmtException (org.xipki.ca.server.mgmt.api.CaMgmtException)3 X509CertificateInfo (org.xipki.ca.api.publisher.x509.X509CertificateInfo)2 CertStatusInfo (org.xipki.ocsp.api.CertStatusInfo)2 OcspStoreException (org.xipki.ocsp.api.OcspStoreException)2 File (java.io.File)1 FileInputStream (java.io.FileInputStream)1 IOException (java.io.IOException)1 BigInteger (java.math.BigInteger)1 CertificateException (java.security.cert.CertificateException)1