Example usage for org.bouncycastle.asn1.x509 Extension freshestCRL

List of usage examples for org.bouncycastle.asn1.x509 Extension freshestCRL

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.x509 Extension freshestCRL.

Prototype

ASN1ObjectIdentifier freshestCRL

To view the source code for org.bouncycastle.asn1.x509 Extension freshestCRL.

Click Source Link

Document

Freshest CRL

Usage

From source file:org.xipki.pki.ca.server.impl.X509Ca.java

License:Open Source License

private X509CRL doGenerateCrl(final boolean deltaCrl, final Date thisUpdate, final Date nextUpdate,
        final AuditEvent event, final String msgId) throws OperationException {
    X509CrlSignerEntryWrapper crlSigner = getCrlSigner();
    if (crlSigner == null) {
        throw new OperationException(ErrorCode.NOT_PERMITTED, "CRL generation is not allowed");
    }//from   w  w w  .  j  a v a 2s. c o m

    String caName = caInfo.getName();
    LOG.info("     START generateCrl: ca={}, deltaCRL={}, nextUpdate={}", caName, 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;

        X509Cert caCert = caInfo.getCertificate();
        List<CertRevInfoWithSerial> revInfos;
        boolean isFirstCrlEntry = true;

        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;
        do {
            if (deltaCrl) {
                revInfos = certstore.getCertsForDeltaCrl(caCert, startId, numEntries,
                        control.isOnlyContainsCaCerts(), control.isOnlyContainsUserCerts());
            } else {
                revInfos = certstore.getRevokedCerts(caCert, notExpireAt, startId, numEntries,
                        control.isOnlyContainsCaCerts(), control.isOnlyContainsUserCerts());
            }

            long maxId = 1;

            for (CertRevInfoWithSerial revInfo : revInfos) {
                if (revInfo.getId() > maxId) {
                    maxId = revInfo.getId();
                }

                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", caName, 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;
            } // end for

            startId = maxId + 1;

        } while (revInfos.size() >= numEntries);
        // end do

        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((DistributionPointName) null, // distributionPoint,
                        onlyUserCerts, // onlyContainsUserCerts,
                        onlyCaCerts, // onlyContainsCACerts,
                        (ReasonFlags) null, // onlySomeReasons,
                        !directCrl, // indirectCRL,
                        false); // onlyContainsAttributeCerts

                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, caCert, notExpireAt, onlyCaCerts, onlyUserCerts);

        ConcurrentContentSigner concurrentSigner = (tmpCrlSigner == null) ? caInfo.getSigner(null)
                : tmpCrlSigner;

        X509CRLHolder crlHolder;
        try {
            crlHolder = concurrentSigner.build(crlBuilder);
        } catch (NoIdleSignerException ex) {
            throw new OperationException(ErrorCode.SYSTEM_FAILURE, "NoIdleSignerException: " + ex.getMessage());
        }

        try {
            X509CRL crl = X509Util.toX509Crl(crlHolder.toASN1Structure());
            caInfo.getCaEntry().setNextCrlNumber(crlNumber.longValue() + 1);
            caInfo.commitNextCrlNo();
            publishCrl(crl);

            successful = true;
            LOG.info("SUCCESSFUL generateCrl: ca={}, crlNumber={}, thisUpdate={}", caName, 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={}", caName);
        }
    }
}