Search in sources :

Example 6 with CrlControl

use of org.xipki.ca.server.mgmt.api.x509.CrlControl in project xipki by xipki.

the class X509Ca method generateCrl0.

private X509CRL generateCrl0(boolean deltaCrl, Date thisUpdate, Date nextUpdate, AuditEvent event, String msgId) throws OperationException {
    X509CrlSignerEntryWrapper crlSigner = getCrlSigner();
    if (crlSigner == null) {
        throw new OperationException(ErrorCode.NOT_PERMITTED, "CRL generation is not allowed");
    }
    LOG.info("     START generateCrl: ca={}, deltaCRL={}, nextUpdate={}", caIdent, deltaCrl, nextUpdate);
    event.addEventData(CaAuditConstants.NAME_crlType, deltaCrl ? "DELTA_CRL" : "FULL_CRL");
    if (nextUpdate == null) {
        event.addEventData(CaAuditConstants.NAME_nextUpdate, "null");
    } else {
        event.addEventData(CaAuditConstants.NAME_nextUpdate, DateUtil.toUtcTimeyyyyMMddhhmmss(nextUpdate));
        if (nextUpdate.getTime() - thisUpdate.getTime() < 10 * 60 * MS_PER_SECOND) {
            // less than 10 minutes
            throw new OperationException(ErrorCode.CRL_FAILURE, "nextUpdate and thisUpdate are too close");
        }
    }
    CrlControl crlControl = crlSigner.getCrlControl();
    boolean successful = false;
    try {
        ConcurrentContentSigner tmpCrlSigner = crlSigner.getSigner();
        CrlControl control = crlSigner.getCrlControl();
        boolean directCrl;
        X500Name crlIssuer;
        if (tmpCrlSigner == null) {
            directCrl = true;
            crlIssuer = caInfo.getPublicCaInfo().getX500Subject();
        } else {
            directCrl = false;
            crlIssuer = X500Name.getInstance(tmpCrlSigner.getCertificate().getSubjectX500Principal().getEncoded());
        }
        X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(crlIssuer, thisUpdate);
        if (nextUpdate != null) {
            crlBuilder.setNextUpdate(nextUpdate);
        }
        final int numEntries = 100;
        Date notExpireAt;
        if (control.isIncludeExpiredCerts()) {
            notExpireAt = new Date(0);
        } else {
            // 10 minutes buffer
            notExpireAt = new Date(thisUpdate.getTime() - 600L * MS_PER_SECOND);
        }
        long startId = 1;
        // we have to cache the serial entries to sort them
        List<CertRevInfoWithSerial> allRevInfos = new LinkedList<>();
        List<CertRevInfoWithSerial> revInfos;
        do {
            if (deltaCrl) {
                revInfos = certstore.getCertsForDeltaCrl(caIdent, startId, numEntries, control.isOnlyContainsCaCerts(), control.isOnlyContainsUserCerts());
            } else {
                revInfos = certstore.getRevokedCerts(caIdent, notExpireAt, startId, numEntries, control.isOnlyContainsCaCerts(), control.isOnlyContainsUserCerts());
            }
            allRevInfos.addAll(revInfos);
            long maxId = 1;
            for (CertRevInfoWithSerial revInfo : revInfos) {
                if (revInfo.getId() > maxId) {
                    maxId = revInfo.getId();
                }
            }
            // end for
            startId = maxId + 1;
        } while (// end do
        revInfos.size() >= numEntries);
        if (revInfos != null) {
            // free the memory
            revInfos.clear();
        }
        // sort the list by SerialNumber ASC
        Collections.sort(allRevInfos);
        boolean isFirstCrlEntry = true;
        for (CertRevInfoWithSerial revInfo : allRevInfos) {
            CrlReason reason = revInfo.getReason();
            if (crlControl.isExcludeReason() && reason != CrlReason.REMOVE_FROM_CRL) {
                reason = CrlReason.UNSPECIFIED;
            }
            Date revocationTime = revInfo.getRevocationTime();
            Date invalidityTime = revInfo.getInvalidityTime();
            switch(crlControl.getInvalidityDateMode()) {
                case FORBIDDEN:
                    invalidityTime = null;
                    break;
                case OPTIONAL:
                    break;
                case REQUIRED:
                    if (invalidityTime == null) {
                        invalidityTime = revocationTime;
                    }
                    break;
                default:
                    throw new RuntimeException("unknown TripleState: " + crlControl.getInvalidityDateMode());
            }
            BigInteger serial = revInfo.getSerial();
            LOG.debug("added cert ca={} serial={} to CRL", caIdent, serial);
            if (directCrl || !isFirstCrlEntry) {
                if (invalidityTime != null) {
                    crlBuilder.addCRLEntry(serial, revocationTime, reason.getCode(), invalidityTime);
                } else {
                    crlBuilder.addCRLEntry(serial, revocationTime, reason.getCode());
                }
                continue;
            }
            List<Extension> extensions = new ArrayList<>(3);
            if (reason != CrlReason.UNSPECIFIED) {
                Extension ext = createReasonExtension(reason.getCode());
                extensions.add(ext);
            }
            if (invalidityTime != null) {
                Extension ext = createInvalidityDateExtension(invalidityTime);
                extensions.add(ext);
            }
            Extension ext = createCertificateIssuerExtension(caInfo.getPublicCaInfo().getX500Subject());
            extensions.add(ext);
            crlBuilder.addCRLEntry(serial, revocationTime, new Extensions(extensions.toArray(new Extension[0])));
            isFirstCrlEntry = false;
        }
        // free the memory
        allRevInfos.clear();
        BigInteger crlNumber = caInfo.nextCrlNumber();
        event.addEventData(CaAuditConstants.NAME_crlNumber, crlNumber);
        boolean onlyUserCerts = crlControl.isOnlyContainsUserCerts();
        boolean onlyCaCerts = crlControl.isOnlyContainsCaCerts();
        if (onlyUserCerts && onlyCaCerts) {
            throw new RuntimeException("should not reach here, onlyUserCerts and onlyCACerts are both true");
        }
        try {
            // AuthorityKeyIdentifier
            byte[] akiValues = directCrl ? caInfo.getPublicCaInfo().getSubjectKeyIdentifer() : crlSigner.getSubjectKeyIdentifier();
            AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(akiValues);
            crlBuilder.addExtension(Extension.authorityKeyIdentifier, false, aki);
            // add extension CRL Number
            crlBuilder.addExtension(Extension.cRLNumber, false, new ASN1Integer(crlNumber));
            // IssuingDistributionPoint
            if (onlyUserCerts || onlyCaCerts || !directCrl) {
                IssuingDistributionPoint idp = new IssuingDistributionPoint(// distributionPoint,
                (DistributionPointName) null, // onlyContainsUserCerts,
                onlyUserCerts, // onlyContainsCACerts,
                onlyCaCerts, // onlySomeReasons,
                (ReasonFlags) null, // indirectCRL,
                !directCrl, // onlyContainsAttributeCerts
                false);
                crlBuilder.addExtension(Extension.issuingDistributionPoint, true, idp);
            }
            // freshestCRL
            List<String> deltaCrlUris = getCaInfo().getPublicCaInfo().getDeltaCrlUris();
            if (control.getDeltaCrlIntervals() > 0 && CollectionUtil.isNonEmpty(deltaCrlUris)) {
                CRLDistPoint cdp = CaUtil.createCrlDistributionPoints(deltaCrlUris, caInfo.getPublicCaInfo().getX500Subject(), crlIssuer);
                crlBuilder.addExtension(Extension.freshestCRL, false, cdp);
            }
        } catch (CertIOException ex) {
            LogUtil.error(LOG, ex, "crlBuilder.addExtension");
            throw new OperationException(ErrorCode.INVALID_EXTENSION, ex);
        }
        addXipkiCertset(crlBuilder, deltaCrl, control, notExpireAt, onlyCaCerts, onlyUserCerts);
        ConcurrentContentSigner concurrentSigner = (tmpCrlSigner == null) ? caInfo.getSigner(null) : tmpCrlSigner;
        ConcurrentBagEntrySigner signer0;
        try {
            signer0 = concurrentSigner.borrowSigner();
        } catch (NoIdleSignerException ex) {
            throw new OperationException(ErrorCode.SYSTEM_FAILURE, "NoIdleSignerException: " + ex.getMessage());
        }
        X509CRLHolder crlHolder;
        try {
            crlHolder = crlBuilder.build(signer0.value());
        } finally {
            concurrentSigner.requiteSigner(signer0);
        }
        try {
            X509CRL crl = X509Util.toX509Crl(crlHolder.toASN1Structure());
            caInfo.getCaEntry().setNextCrlNumber(crlNumber.longValue() + 1);
            caManager.commitNextCrlNo(caIdent, caInfo.getCaEntry().getNextCrlNumber());
            publishCrl(crl);
            successful = true;
            LOG.info("SUCCESSFUL generateCrl: ca={}, crlNumber={}, thisUpdate={}", caIdent, crlNumber, crl.getThisUpdate());
            if (!deltaCrl) {
                // clean up the CRL
                cleanupCrlsWithoutException(msgId);
            }
            return crl;
        } catch (CRLException | CertificateException ex) {
            throw new OperationException(ErrorCode.CRL_FAILURE, ex);
        }
    } finally {
        if (!successful) {
            LOG.info("    FAILED generateCrl: ca={}", caIdent);
        }
    }
}
Also used : CrlControl(org.xipki.ca.server.mgmt.api.x509.CrlControl) IssuingDistributionPoint(org.bouncycastle.asn1.x509.IssuingDistributionPoint) X509CRL(java.security.cert.X509CRL) ArrayList(java.util.ArrayList) AuthorityKeyIdentifier(org.bouncycastle.asn1.x509.AuthorityKeyIdentifier) CertificateException(java.security.cert.CertificateException) X500Name(org.bouncycastle.asn1.x500.X500Name) DERPrintableString(org.bouncycastle.asn1.DERPrintableString) DERUTF8String(org.bouncycastle.asn1.DERUTF8String) Extensions(org.bouncycastle.asn1.x509.Extensions) NoIdleSignerException(org.xipki.security.exception.NoIdleSignerException) X509v2CRLBuilder(org.bouncycastle.cert.X509v2CRLBuilder) CrlReason(org.xipki.security.CrlReason) CRLDistPoint(org.bouncycastle.asn1.x509.CRLDistPoint) CRLException(java.security.cert.CRLException) OperationException(org.xipki.ca.api.OperationException) ASN1Integer(org.bouncycastle.asn1.ASN1Integer) CertIOException(org.bouncycastle.cert.CertIOException) ConcurrentBagEntrySigner(org.xipki.security.ConcurrentBagEntrySigner) IssuingDistributionPoint(org.bouncycastle.asn1.x509.IssuingDistributionPoint) CRLDistPoint(org.bouncycastle.asn1.x509.CRLDistPoint) Date(java.util.Date) LinkedList(java.util.LinkedList) Extension(org.bouncycastle.asn1.x509.Extension) ConcurrentContentSigner(org.xipki.security.ConcurrentContentSigner) X509CRLHolder(org.bouncycastle.cert.X509CRLHolder) BigInteger(java.math.BigInteger)

Example 7 with CrlControl

use of org.xipki.ca.server.mgmt.api.x509.CrlControl in project xipki by xipki.

the class X509Ca method getCrlNextUpdate.

private Date getCrlNextUpdate(Date thisUpdate) {
    ParamUtil.requireNonNull("thisUpdate", thisUpdate);
    CrlControl control = getCrlSigner().getCrlControl();
    if (control.getUpdateMode() != UpdateMode.interval) {
        return null;
    }
    int intervalsTillNextCrl = 0;
    for (int i = 1; ; i++) {
        if (i % control.getFullCrlIntervals() == 0) {
            intervalsTillNextCrl = i;
            break;
        } else if (!control.isExtendedNextUpdate() && control.getDeltaCrlIntervals() > 0) {
            if (i % control.getDeltaCrlIntervals() == 0) {
                intervalsTillNextCrl = i;
                break;
            }
        }
    }
    Date nextUpdate;
    if (control.getIntervalMinutes() != null) {
        int minutesTillNextUpdate = intervalsTillNextCrl * control.getIntervalMinutes() + control.getOverlapMinutes();
        nextUpdate = new Date(MS_PER_SECOND * (thisUpdate.getTime() / MS_PER_SECOND / 60 + minutesTillNextUpdate) * 60);
    } else {
        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
        cal.setTime(thisUpdate);
        cal.add(Calendar.DAY_OF_YEAR, intervalsTillNextCrl);
        cal.set(Calendar.HOUR_OF_DAY, control.getIntervalDayTime().getHour());
        cal.set(Calendar.MINUTE, control.getIntervalDayTime().getMinute());
        cal.add(Calendar.MINUTE, control.getOverlapMinutes());
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        nextUpdate = cal.getTime();
    }
    return nextUpdate;
}
Also used : CrlControl(org.xipki.ca.server.mgmt.api.x509.CrlControl) Calendar(java.util.Calendar) IssuingDistributionPoint(org.bouncycastle.asn1.x509.IssuingDistributionPoint) CRLDistPoint(org.bouncycastle.asn1.x509.CRLDistPoint) Date(java.util.Date)

Example 8 with CrlControl

use of org.xipki.ca.server.mgmt.api.x509.CrlControl in project xipki by xipki.

the class X509Ca method shouldPublishToDeltaCrlCache.

// doUnrevokeCertificate
private boolean shouldPublishToDeltaCrlCache() {
    X509CrlSignerEntryWrapper crlSigner = getCrlSigner();
    if (crlSigner == null) {
        return false;
    }
    CrlControl control = crlSigner.getCrlControl();
    if (control.getUpdateMode() == UpdateMode.onDemand) {
        return false;
    }
    int deltaCrlInterval = control.getDeltaCrlIntervals();
    return deltaCrlInterval != 0 && deltaCrlInterval < control.getFullCrlIntervals();
}
Also used : CrlControl(org.xipki.ca.server.mgmt.api.x509.CrlControl) IssuingDistributionPoint(org.bouncycastle.asn1.x509.IssuingDistributionPoint) CRLDistPoint(org.bouncycastle.asn1.x509.CRLDistPoint)

Example 9 with CrlControl

use of org.xipki.ca.server.mgmt.api.x509.CrlControl in project xipki by xipki.

the class CrlSignerUpdateCmd method getCrlSignerChangeEntry.

protected X509ChangeCrlSignerEntry getCrlSignerChangeEntry() throws Exception {
    String signerCertConf = null;
    if (CaManager.NULL.equalsIgnoreCase(signerCert)) {
        signerCertConf = CaManager.NULL;
    } else if (signerCert != null) {
        byte[] certBytes = IoUtil.read(signerCert);
        X509Util.parseCert(new ByteArrayInputStream(certBytes));
        signerCertConf = Base64.encodeToString(certBytes);
    }
    if (signerConf != null) {
        String tmpSignerType = signerType;
        if (tmpSignerType == null) {
            X509CrlSignerEntry entry = caManager.getCrlSigner(name);
            if (entry == null) {
                throw new IllegalCmdParamException("please specify the signerType");
            }
            tmpSignerType = entry.getType();
        }
        signerConf = ShellUtil.canonicalizeSignerConf(tmpSignerType, signerConf, passwordResolver, securityFactory);
    }
    X509ChangeCrlSignerEntry dbEntry = new X509ChangeCrlSignerEntry(name);
    dbEntry.setSignerType(signerType);
    dbEntry.setSignerConf(signerConf);
    dbEntry.setCrlControl(crlControl);
    dbEntry.setBase64Cert(signerCertConf);
    return dbEntry;
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) IllegalCmdParamException(org.xipki.console.karaf.IllegalCmdParamException) X509CrlSignerEntry(org.xipki.ca.server.mgmt.api.x509.X509CrlSignerEntry) X509ChangeCrlSignerEntry(org.xipki.ca.server.mgmt.api.x509.X509ChangeCrlSignerEntry)

Aggregations

CrlControl (org.xipki.ca.server.mgmt.api.x509.CrlControl)7 X509CrlSignerEntry (org.xipki.ca.server.mgmt.api.x509.X509CrlSignerEntry)4 CRLDistPoint (org.bouncycastle.asn1.x509.CRLDistPoint)3 IssuingDistributionPoint (org.bouncycastle.asn1.x509.IssuingDistributionPoint)3 CaMgmtException (org.xipki.ca.server.mgmt.api.CaMgmtException)3 CertificateException (java.security.cert.CertificateException)2 PreparedStatement (java.sql.PreparedStatement)2 SQLException (java.sql.SQLException)2 Date (java.util.Date)2 X509ChangeCrlSignerEntry (org.xipki.ca.server.mgmt.api.x509.X509ChangeCrlSignerEntry)2 InvalidConfException (org.xipki.common.InvalidConfException)2 CmdFailure (org.xipki.console.karaf.CmdFailure)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 BigInteger (java.math.BigInteger)1 CRLException (java.security.cert.CRLException)1 CertificateEncodingException (java.security.cert.CertificateEncodingException)1 X509CRL (java.security.cert.X509CRL)1 ArrayList (java.util.ArrayList)1 Calendar (java.util.Calendar)1 LinkedList (java.util.LinkedList)1