Example usage for org.bouncycastle.asn1.ocsp CrlID getInstance

List of usage examples for org.bouncycastle.asn1.ocsp CrlID getInstance

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.ocsp CrlID getInstance.

Prototype

public static CrlID getInstance(Object obj) 

Source Link

Usage

From source file:org.xipki.ocsp.server.impl.certstore.CrlCertStatusStore.java

License:Open Source License

private synchronized void initializeStore(final boolean force) {
    Boolean updateCRLSuccessfull = null;

    try {/*  w w w . j  ava 2 s.  c  o m*/
        File fullCrlFile = new File(crlFilename);
        if (fullCrlFile.exists() == false) {
            // file does not exist
            LOG.warn("CRL File {} does not exist", crlFilename);
            return;
        }

        long newLastModifed = fullCrlFile.lastModified();

        boolean deltaCrlExists;
        File deltaCrlFile = null;
        if (deltaCrlFilename != null) {
            deltaCrlFile = new File(deltaCrlFilename);
            deltaCrlExists = deltaCrlFile.exists();
        } else {
            deltaCrlExists = false;
        }

        long newLastModifedOfDeltaCrl = deltaCrlExists ? deltaCrlFile.lastModified() : 0;

        if (force == false) {
            long now = System.currentTimeMillis();
            if (newLastModifed != lastmodifiedOfCrlFile) {
                if (now - newLastModifed < 5000) {
                    return; // still in copy process
                }
            }

            if (deltaCrlExists) {
                if (newLastModifedOfDeltaCrl != lastModifiedOfDeltaCrlFile) {
                    if (now - newLastModifed < 5000) {
                        return; // still in copy process
                    }
                }
            }
        } // end if(force)

        byte[] newFp = sha1Fp(fullCrlFile);
        boolean crlFileChanged = Arrays.equals(newFp, fpOfCrlFile) == false;

        if (crlFileChanged == false) {
            auditLogPCIEvent(AuditLevel.INFO, "UPDATE_CERTSTORE", "current CRL is still up-to-date");
            return;
        }

        byte[] newFpOfDeltaCrl = deltaCrlExists ? sha1Fp(deltaCrlFile) : null;
        boolean deltaCrlFileChanged = Arrays.equals(newFpOfDeltaCrl, fpOfDeltaCrlFile) == false;

        if (crlFileChanged == false && deltaCrlFileChanged == false) {
            return;
        }

        if (crlFileChanged) {
            LOG.info("CRL file {} has changed, updating of the CertStore required", crlFilename);
        }
        if (deltaCrlFileChanged) {
            LOG.info("DeltaCRL file {} has changed, updating of the CertStore required", deltaCrlFilename);
        }

        auditLogPCIEvent(AuditLevel.INFO, "UPDATE_CERTSTORE", "a newer version of CRL is available");
        updateCRLSuccessfull = false;

        X509CRL crl = X509Util.parseCRL(crlFilename);
        BigInteger crlNumber;
        {
            byte[] octetString = crl.getExtensionValue(Extension.cRLNumber.getId());
            if (octetString != null) {
                byte[] extnValue = DEROctetString.getInstance(octetString).getOctets();
                crlNumber = ASN1Integer.getInstance(extnValue).getPositiveValue();
            } else {
                crlNumber = null;
            }
        }

        X500Principal issuer = crl.getIssuerX500Principal();

        boolean caAsCrlIssuer = true;
        if (caCert.getSubjectX500Principal().equals(issuer) == false) {
            caAsCrlIssuer = false;
            if (issuerCert == null) {
                throw new IllegalArgumentException("issuerCert could not be null");
            }

            if (issuerCert.getSubjectX500Principal().equals(issuer) == false) {
                throw new IllegalArgumentException("The issuerCert and CRL do not match");
            }
        }

        X509Certificate crlSignerCert = caAsCrlIssuer ? caCert : issuerCert;
        try {
            crl.verify(crlSignerCert.getPublicKey());
        } catch (Exception e) {
            throw new CertStatusStoreException(e.getMessage(), e);
        }

        X509CRL deltaCrl = null;
        BigInteger deltaCrlNumber = null;
        BigInteger baseCrlNumber = null;

        if (deltaCrlExists) {
            if (crlNumber == null) {
                throw new CertStatusStoreException("baseCRL does not contains CRLNumber");
            }

            deltaCrl = X509Util.parseCRL(deltaCrlFilename);
            byte[] octetString = deltaCrl.getExtensionValue(Extension.deltaCRLIndicator.getId());
            if (octetString == null) {
                deltaCrl = null;
                LOG.warn("{} is a full CRL instead of delta CRL, ignore it", deltaCrlFilename);
            } else {
                byte[] extnValue = DEROctetString.getInstance(octetString).getOctets();
                baseCrlNumber = ASN1Integer.getInstance(extnValue).getPositiveValue();
                if (baseCrlNumber.equals(crlNumber) == false) {
                    deltaCrl = null;
                    LOG.info("{} is not a deltaCRL for the CRL {}, ignore it", deltaCrlFilename, crlFilename);
                } else {
                    octetString = deltaCrl.getExtensionValue(Extension.cRLNumber.getId());
                    extnValue = DEROctetString.getInstance(octetString).getOctets();
                    deltaCrlNumber = ASN1Integer.getInstance(extnValue).getPositiveValue();
                }
            }
        }

        if (crlFileChanged == false && deltaCrl == null) {
            return;
        }

        Date newThisUpdate;
        Date newNextUpdate;

        if (deltaCrl != null) {
            LOG.info("try to update CRL with CRLNumber={} and DeltaCRL with CRLNumber={}", crlNumber,
                    deltaCrlNumber);
            newThisUpdate = deltaCrl.getThisUpdate();
            newNextUpdate = deltaCrl.getNextUpdate();
        } else {
            newThisUpdate = crl.getThisUpdate();
            newNextUpdate = crl.getNextUpdate();
        }

        // Construct CrlID
        ASN1EncodableVector v = new ASN1EncodableVector();
        if (StringUtil.isNotBlank(crlUrl)) {
            v.add(new DERTaggedObject(true, 0, new DERIA5String(crlUrl, true)));
        }
        byte[] extValue = (deltaCrlExists ? deltaCrl : crl).getExtensionValue(Extension.cRLNumber.getId());
        if (extValue != null) {
            ASN1Integer asn1CrlNumber = ASN1Integer.getInstance(removeTagAndLenFromExtensionValue(extValue));
            v.add(new DERTaggedObject(true, 1, asn1CrlNumber));
        }
        v.add(new DERTaggedObject(true, 2, new DERGeneralizedTime(newThisUpdate)));
        this.crlID = CrlID.getInstance(new DERSequence(v));

        byte[] encodedCaCert;
        try {
            encodedCaCert = caCert.getEncoded();
        } catch (CertificateEncodingException e) {
            throw new CertStatusStoreException(e.getMessage(), e);
        }

        Certificate bcCaCert = Certificate.getInstance(encodedCaCert);
        byte[] encodedName;
        try {
            encodedName = bcCaCert.getSubject().getEncoded("DER");
        } catch (IOException e) {
            throw new CertStatusStoreException(e.getMessage(), e);
        }

        byte[] encodedKey = bcCaCert.getSubjectPublicKeyInfo().getPublicKeyData().getBytes();

        Map<HashAlgoType, IssuerHashNameAndKey> newIssuerHashMap = new ConcurrentHashMap<>();

        for (HashAlgoType hashAlgo : HashAlgoType.values()) {
            byte[] issuerNameHash = HashCalculator.hash(hashAlgo, encodedName);
            byte[] issuerKeyHash = HashCalculator.hash(hashAlgo, encodedKey);
            IssuerHashNameAndKey issuerHash = new IssuerHashNameAndKey(hashAlgo, issuerNameHash, issuerKeyHash);
            newIssuerHashMap.put(hashAlgo, issuerHash);
        }

        X500Name caName = X500Name.getInstance(caCert.getSubjectX500Principal().getEncoded());

        // extract the certificate, only in full CRL, not in delta CRL
        boolean certsIncluded = false;
        Set<CertWithInfo> certs = new HashSet<>();
        String oidExtnCerts = ObjectIdentifiers.id_xipki_ext_crlCertset.getId();
        byte[] extnValue = crl.getExtensionValue(oidExtnCerts);
        if (extnValue == null) {
            // try the legacy OID
            extnValue = crl.getExtensionValue("1.3.6.1.4.1.12655.100");
        }

        if (extnValue != null) {
            extnValue = removeTagAndLenFromExtensionValue(extnValue);
            certsIncluded = true;
            ASN1Set asn1Set = DERSet.getInstance(extnValue);
            int n = asn1Set.size();
            for (int i = 0; i < n; i++) {
                ASN1Encodable asn1 = asn1Set.getObjectAt(i);
                Certificate bcCert;
                String profileName = null;

                try {
                    ASN1Sequence seq = ASN1Sequence.getInstance(asn1);
                    bcCert = Certificate.getInstance(seq.getObjectAt(0));
                    if (seq.size() > 1) {
                        profileName = DERUTF8String.getInstance(seq.getObjectAt(1)).getString();
                    }
                } catch (IllegalArgumentException e) {
                    // backwards compatibility
                    bcCert = Certificate.getInstance(asn1);
                }

                if (caName.equals(bcCert.getIssuer()) == false) {
                    throw new CertStatusStoreException("invalid entry in CRL Extension certs");
                }

                if (profileName == null) {
                    profileName = "UNKNOWN";
                }

                certs.add(new CertWithInfo(bcCert, profileName));
            }
        }

        if (certsDirname != null) {
            if (extnValue != null) {
                LOG.warn("ignore certsDir '{}', since certificates are included in CRL Extension certs",
                        certsDirname);
            } else {
                certsIncluded = true;
                Set<CertWithInfo> tmpCerts = readCertWithInfosFromDir(caCert, certsDirname);
                certs.addAll(tmpCerts);
            }
        }

        Map<BigInteger, CrlCertStatusInfo> newCertStatusInfoMap = new ConcurrentHashMap<>();

        // First consider only full CRL
        Set<? extends X509CRLEntry> revokedCertListInFullCRL = crl.getRevokedCertificates();
        if (revokedCertListInFullCRL != null) {
            for (X509CRLEntry revokedCert : revokedCertListInFullCRL) {
                X500Principal thisIssuer = revokedCert.getCertificateIssuer();
                if (thisIssuer != null && caCert.getSubjectX500Principal().equals(thisIssuer) == false) {
                    throw new CertStatusStoreException("invalid CRLEntry");
                }
            }
        }

        Set<? extends X509CRLEntry> revokedCertListInDeltaCRL = null;
        if (deltaCrl != null) {
            revokedCertListInDeltaCRL = deltaCrl.getRevokedCertificates();
            if (revokedCertListInDeltaCRL != null) {
                for (X509CRLEntry revokedCert : revokedCertListInDeltaCRL) {
                    X500Principal thisIssuer = revokedCert.getCertificateIssuer();
                    if (thisIssuer != null && caCert.getSubjectX500Principal().equals(thisIssuer) == false) {
                        throw new CertStatusStoreException("invalid CRLEntry");
                    }
                }
            }
        }

        Map<BigInteger, X509CRLEntry> revokedCertMap = null;

        // merge the revoked list
        if (CollectionUtil.isNotEmpty(revokedCertListInDeltaCRL)) {
            revokedCertMap = new HashMap<BigInteger, X509CRLEntry>();
            for (X509CRLEntry entry : revokedCertListInFullCRL) {
                revokedCertMap.put(entry.getSerialNumber(), entry);
            }

            for (X509CRLEntry entry : revokedCertListInDeltaCRL) {
                BigInteger serialNumber = entry.getSerialNumber();
                java.security.cert.CRLReason reason = entry.getRevocationReason();
                if (reason == java.security.cert.CRLReason.REMOVE_FROM_CRL) {
                    revokedCertMap.remove(serialNumber);
                } else {
                    revokedCertMap.put(serialNumber, entry);
                }
            }
        }

        Iterator<? extends X509CRLEntry> it = null;
        if (revokedCertMap != null) {
            it = revokedCertMap.values().iterator();
        } else if (revokedCertListInFullCRL != null) {
            it = revokedCertListInFullCRL.iterator();
        }

        if (it != null) {
            while (it.hasNext()) {
                X509CRLEntry revokedCert = it.next();
                BigInteger serialNumber = revokedCert.getSerialNumber();
                byte[] encodedExtnValue = revokedCert.getExtensionValue(Extension.reasonCode.getId());

                int reasonCode;
                if (encodedExtnValue != null) {
                    ASN1Enumerated enumerated = ASN1Enumerated
                            .getInstance(removeTagAndLenFromExtensionValue(encodedExtnValue));
                    reasonCode = enumerated.getValue().intValue();
                } else {
                    reasonCode = CRLReason.UNSPECIFIED.getCode();
                }

                Date revTime = revokedCert.getRevocationDate();

                Date invalidityTime = null;
                extnValue = revokedCert.getExtensionValue(Extension.invalidityDate.getId());

                if (extnValue != null) {
                    extnValue = removeTagAndLenFromExtensionValue(extnValue);
                    ASN1GeneralizedTime gTime = DERGeneralizedTime.getInstance(extnValue);
                    try {
                        invalidityTime = gTime.getDate();
                    } catch (ParseException e) {
                        throw new CertStatusStoreException(e.getMessage(), e);
                    }

                    if (revTime.equals(invalidityTime)) {
                        invalidityTime = null;
                    }
                }

                CertWithInfo cert = null;
                if (certsIncluded) {
                    for (CertWithInfo bcCert : certs) {
                        if (bcCert.cert.getIssuer().equals(caName)
                                && bcCert.cert.getSerialNumber().getPositiveValue().equals(serialNumber)) {
                            cert = bcCert;
                            break;
                        }
                    }

                    if (cert == null) {
                        LOG.info("could not find certificate (issuer = '{}', serialNumber = '{}'",
                                X509Util.getRFC4519Name(caName), serialNumber);
                    } else {
                        certs.remove(cert);
                    }
                }

                Map<HashAlgoType, byte[]> certHashes = (cert == null) ? null : getCertHashes(cert.cert);

                CertRevocationInfo revocationInfo = new CertRevocationInfo(reasonCode, revTime, invalidityTime);
                CrlCertStatusInfo crlCertStatusInfo = CrlCertStatusInfo.getRevokedCertStatusInfo(revocationInfo,
                        (cert == null) ? null : cert.profileName, certHashes);
                newCertStatusInfoMap.put(serialNumber, crlCertStatusInfo);
            } // end while(it.hasNext())
        } // end if(it)

        for (CertWithInfo cert : certs) {
            Map<HashAlgoType, byte[]> certHashes = getCertHashes(cert.cert);
            CrlCertStatusInfo crlCertStatusInfo = CrlCertStatusInfo.getGoodCertStatusInfo(cert.profileName,
                    certHashes);
            newCertStatusInfoMap.put(cert.cert.getSerialNumber().getPositiveValue(), crlCertStatusInfo);
        }

        this.initialized = false;
        this.lastmodifiedOfCrlFile = newLastModifed;
        this.fpOfCrlFile = newFp;

        this.lastModifiedOfDeltaCrlFile = newLastModifedOfDeltaCrl;
        this.fpOfDeltaCrlFile = newFpOfDeltaCrl;

        this.issuerHashMap.clear();
        this.issuerHashMap.putAll(newIssuerHashMap);
        this.certStatusInfoMap.clear();
        this.certStatusInfoMap.putAll(newCertStatusInfoMap);
        this.thisUpdate = newThisUpdate;
        this.nextUpdate = newNextUpdate;

        this.initializationFailed = false;
        this.initialized = true;
        updateCRLSuccessfull = true;
        LOG.info("updated CertStore {}", getName());
    } catch (Exception e) {
        final String message = "could not execute initializeStore()";
        if (LOG.isErrorEnabled()) {
            LOG.error(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage());
        }
        LOG.debug(message, e);
        initializationFailed = true;
        initialized = true;
    } finally {
        if (updateCRLSuccessfull != null) {
            AuditLevel auditLevel;
            AuditStatus auditStatus;
            String eventType = "UPDATE_CRL";
            if (updateCRLSuccessfull) {
                auditLevel = AuditLevel.INFO;
                auditStatus = AuditStatus.FAILED;
            } else {
                auditLevel = AuditLevel.ERROR;
                auditStatus = AuditStatus.SUCCESSFUL;
            }

            auditLogPCIEvent(auditLevel, eventType, auditStatus.name());
        }
    }
}

From source file:org.xipki.pki.ocsp.server.impl.store.crl.CrlCertStatusStore.java

License:Open Source License

private synchronized void initializeStore(final boolean force) {
    Boolean updateCrlSuccessful = null;

    try {//from w  ww  . j  ava2 s  .  c o  m
        File fullCrlFile = new File(crlFilename);
        if (!fullCrlFile.exists()) {
            // file does not exist
            LOG.warn("CRL File {} does not exist", crlFilename);
            return;
        }

        long newLastModifed = fullCrlFile.lastModified();

        long newLastModifedOfDeltaCrl;
        boolean deltaCrlExists;
        File deltaCrlFile = null;
        if (deltaCrlFilename != null) {
            deltaCrlFile = new File(deltaCrlFilename);
            deltaCrlExists = deltaCrlFile.exists();
            newLastModifedOfDeltaCrl = deltaCrlExists ? deltaCrlFile.lastModified() : 0;
        } else {
            deltaCrlExists = false;
            newLastModifedOfDeltaCrl = 0;
        }

        if (!force) {
            long now = System.currentTimeMillis();
            if (newLastModifed != lastmodifiedOfCrlFile && now - newLastModifed < 5000) {
                return; // still in copy process
            }

            if (deltaCrlExists) {
                if (newLastModifedOfDeltaCrl != lastModifiedOfDeltaCrlFile && now - newLastModifed < 5000) {
                    return; // still in copy process
                }
            }
        } // end if (force)

        byte[] newFp = sha1Fp(fullCrlFile);
        boolean crlFileChanged = !Arrays.equals(newFp, fpOfCrlFile);

        byte[] newFpOfDeltaCrl = deltaCrlExists ? sha1Fp(deltaCrlFile) : null;
        boolean deltaCrlFileChanged = !Arrays.equals(newFpOfDeltaCrl, fpOfDeltaCrlFile);

        if (!crlFileChanged && !deltaCrlFileChanged) {
            return;
        }

        if (crlFileChanged) {
            LOG.info("CRL file {} has changed, update of the CertStore required", crlFilename);
        }
        if (deltaCrlFileChanged) {
            LOG.info("DeltaCRL file {} has changed, update of the CertStore required", deltaCrlFilename);
        }

        auditPciEvent(AuditLevel.INFO, "UPDATE_CERTSTORE", "a newer CRL is available");
        updateCrlSuccessful = false;

        X509CRL crl = X509Util.parseCrl(crlFilename);

        byte[] octetString = crl.getExtensionValue(Extension.cRLNumber.getId());
        if (octetString == null) {
            throw new OcspStoreException("CRL without CRLNumber is not supported");
        }
        BigInteger newCrlNumber = ASN1Integer.getInstance(DEROctetString.getInstance(octetString).getOctets())
                .getPositiveValue();

        if (crlNumber != null && newCrlNumber.compareTo(crlNumber) <= 0) {
            throw new OcspStoreException(
                    String.format("CRLNumber of new CRL (%s) <= current CRL (%s)", newCrlNumber, crlNumber));
        }

        X500Principal issuer = crl.getIssuerX500Principal();

        boolean caAsCrlIssuer = true;
        if (!caCert.getSubjectX500Principal().equals(issuer)) {
            caAsCrlIssuer = false;
            if (issuerCert == null) {
                throw new IllegalArgumentException("issuerCert must not be null");
            }

            if (!issuerCert.getSubjectX500Principal().equals(issuer)) {
                throw new IllegalArgumentException("issuerCert and CRL do not match");
            }
        }

        X509Certificate crlSignerCert = caAsCrlIssuer ? caCert : issuerCert;
        try {
            crl.verify(crlSignerCert.getPublicKey());
        } catch (Exception ex) {
            throw new OcspStoreException(ex.getMessage(), ex);
        }

        X509CRL deltaCrl = null;
        BigInteger deltaCrlNumber = null;
        BigInteger baseCrlNumber = null;

        if (deltaCrlExists) {
            if (newCrlNumber == null) {
                throw new OcspStoreException("baseCRL does not contains CRLNumber");
            }

            deltaCrl = X509Util.parseCrl(deltaCrlFilename);
            octetString = deltaCrl.getExtensionValue(Extension.deltaCRLIndicator.getId());
            if (octetString == null) {
                deltaCrl = null;
                LOG.warn("{} is a full CRL instead of delta CRL, ignore it", deltaCrlFilename);
            } else {
                byte[] extnValue = DEROctetString.getInstance(octetString).getOctets();
                baseCrlNumber = ASN1Integer.getInstance(extnValue).getPositiveValue();
                if (!baseCrlNumber.equals(newCrlNumber)) {
                    deltaCrl = null;
                    LOG.info("{} is not a deltaCRL for the CRL {}, ignore it", deltaCrlFilename, crlFilename);
                } else {
                    octetString = deltaCrl.getExtensionValue(Extension.cRLNumber.getId());
                    extnValue = DEROctetString.getInstance(octetString).getOctets();
                    deltaCrlNumber = ASN1Integer.getInstance(extnValue).getPositiveValue();
                }
            } // end if(octetString == null)
        } // end if(deltaCrlExists)

        Date newThisUpdate;
        Date newNextUpdate;

        if (deltaCrl != null) {
            LOG.info("try to update CRL with CRLNumber={} and DeltaCRL with CRLNumber={}", newCrlNumber,
                    deltaCrlNumber);
            newThisUpdate = deltaCrl.getThisUpdate();
            newNextUpdate = deltaCrl.getNextUpdate();
        } else {
            newThisUpdate = crl.getThisUpdate();
            newNextUpdate = crl.getNextUpdate();
        }

        // Construct CrlID
        ASN1EncodableVector vec = new ASN1EncodableVector();
        if (StringUtil.isNotBlank(crlUrl)) {
            vec.add(new DERTaggedObject(true, 0, new DERIA5String(crlUrl, true)));
        }

        byte[] extValue = ((deltaCrl != null) ? deltaCrl : crl).getExtensionValue(Extension.cRLNumber.getId());
        if (extValue != null) {
            ASN1Integer asn1CrlNumber = ASN1Integer.getInstance(extractCoreValue(extValue));
            vec.add(new DERTaggedObject(true, 1, asn1CrlNumber));
        }
        vec.add(new DERTaggedObject(true, 2, new DERGeneralizedTime(newThisUpdate)));
        this.crlId = CrlID.getInstance(new DERSequence(vec));

        byte[] encodedCaCert;
        try {
            encodedCaCert = caCert.getEncoded();
        } catch (CertificateEncodingException ex) {
            throw new OcspStoreException(ex.getMessage(), ex);
        }

        Certificate bcCaCert = Certificate.getInstance(encodedCaCert);
        byte[] encodedName;
        try {
            encodedName = bcCaCert.getSubject().getEncoded("DER");
        } catch (IOException ex) {
            throw new OcspStoreException(ex.getMessage(), ex);
        }

        byte[] encodedKey = bcCaCert.getSubjectPublicKeyInfo().getPublicKeyData().getBytes();
        Map<HashAlgoType, IssuerHashNameAndKey> newIssuerHashMap = new ConcurrentHashMap<>();

        for (HashAlgoType hashAlgo : HashAlgoType.values()) {
            byte[] issuerNameHash = hashAlgo.hash(encodedName);
            byte[] issuerKeyHash = hashAlgo.hash(encodedKey);
            IssuerHashNameAndKey issuerHash = new IssuerHashNameAndKey(hashAlgo, issuerNameHash, issuerKeyHash);
            newIssuerHashMap.put(hashAlgo, issuerHash);
        }

        X500Name caName = X500Name.getInstance(caCert.getSubjectX500Principal().getEncoded());

        // extract the certificate, only in full CRL, not in delta CRL
        String oidExtnCerts = ObjectIdentifiers.id_xipki_ext_crlCertset.getId();
        byte[] extnValue = crl.getExtensionValue(oidExtnCerts);

        boolean certsConsidered = false;
        Map<BigInteger, CertWithInfo> certsMap;
        if (extnValue != null) {
            extnValue = extractCoreValue(extnValue);
            certsConsidered = true;
            certsMap = extractCertsFromExtCrlCertSet(extnValue, caName);
        } else {
            certsMap = new HashMap<>();
        }

        if (certsDirname != null) {
            if (extnValue != null) {
                LOG.warn("ignore certsDir '{}', since certificates are included in {}", certsDirname,
                        " CRL Extension certs");
            } else {
                certsConsidered = true;
                readCertWithInfosFromDir(caCert, certsDirname, certsMap);
            }
        }

        Map<BigInteger, CrlCertStatusInfo> newCertStatusInfoMap = new ConcurrentHashMap<>();

        // First consider only full CRL
        Set<? extends X509CRLEntry> revokedCertListInFullCrl = crl.getRevokedCertificates();
        if (revokedCertListInFullCrl != null) {
            for (X509CRLEntry revokedCert : revokedCertListInFullCrl) {
                X500Principal rcIssuer = revokedCert.getCertificateIssuer();
                if (rcIssuer != null && !caCert.getSubjectX500Principal().equals(rcIssuer)) {
                    throw new OcspStoreException("invalid CRLEntry");
                }
            }
        }

        Set<? extends X509CRLEntry> revokedCertListInDeltaCrl = (deltaCrl == null) ? null
                : deltaCrl.getRevokedCertificates();
        if (revokedCertListInDeltaCrl != null) {
            for (X509CRLEntry revokedCert : revokedCertListInDeltaCrl) {
                X500Principal rcIssuer = revokedCert.getCertificateIssuer();
                if (rcIssuer != null && !caCert.getSubjectX500Principal().equals(rcIssuer)) {
                    throw new OcspStoreException("invalid CRLEntry");
                }
            }
        }

        Map<BigInteger, X509CRLEntry> revokedCertMap = null;

        // merge the revoked list
        if (revokedCertListInDeltaCrl != null && !revokedCertListInDeltaCrl.isEmpty()) {
            revokedCertMap = new HashMap<BigInteger, X509CRLEntry>();
            if (revokedCertListInFullCrl != null) {
                for (X509CRLEntry entry : revokedCertListInFullCrl) {
                    revokedCertMap.put(entry.getSerialNumber(), entry);
                }
            }

            for (X509CRLEntry entry : revokedCertListInDeltaCrl) {
                BigInteger serialNumber = entry.getSerialNumber();
                CRLReason reason = entry.getRevocationReason();
                if (reason == CRLReason.REMOVE_FROM_CRL) {
                    revokedCertMap.remove(serialNumber);
                } else {
                    revokedCertMap.put(serialNumber, entry);
                }
            }
        }

        Iterator<? extends X509CRLEntry> it = null;
        if (revokedCertMap != null) {
            it = revokedCertMap.values().iterator();
        } else if (revokedCertListInFullCrl != null) {
            it = revokedCertListInFullCrl.iterator();
        }

        while (it != null && it.hasNext()) {
            X509CRLEntry revokedCert = it.next();
            BigInteger serialNumber = revokedCert.getSerialNumber();
            byte[] encodedExtnValue = revokedCert.getExtensionValue(Extension.reasonCode.getId());

            int reasonCode;
            if (encodedExtnValue != null) {
                ASN1Enumerated enumerated = ASN1Enumerated.getInstance(extractCoreValue(encodedExtnValue));
                reasonCode = enumerated.getValue().intValue();
            } else {
                reasonCode = CrlReason.UNSPECIFIED.getCode();
            }

            Date revTime = revokedCert.getRevocationDate();

            Date invalidityTime = null;
            extnValue = revokedCert.getExtensionValue(Extension.invalidityDate.getId());

            if (extnValue != null) {
                extnValue = extractCoreValue(extnValue);
                ASN1GeneralizedTime genTime = DERGeneralizedTime.getInstance(extnValue);
                try {
                    invalidityTime = genTime.getDate();
                } catch (ParseException ex) {
                    throw new OcspStoreException(ex.getMessage(), ex);
                }

                if (revTime.equals(invalidityTime)) {
                    invalidityTime = null;
                }
            }

            CertWithInfo cert = null;
            if (certsConsidered) {
                cert = certsMap.remove(serialNumber);
                if (cert == null && LOG.isInfoEnabled()) {
                    LOG.info("could not find certificate (serialNumber='{}')", LogUtil.formatCsn(serialNumber));
                }
            }

            Certificate bcCert = (cert == null) ? null : cert.getCert();
            Map<HashAlgoType, byte[]> certHashes = (bcCert == null) ? null : getCertHashes(bcCert);
            Date notBefore = (bcCert == null) ? null : bcCert.getTBSCertificate().getStartDate().getDate();
            Date notAfter = (bcCert == null) ? null : bcCert.getTBSCertificate().getEndDate().getDate();

            CertRevocationInfo revocationInfo = new CertRevocationInfo(reasonCode, revTime, invalidityTime);
            String profileName = (cert == null) ? null : cert.getProfileName();
            CrlCertStatusInfo crlCertStatusInfo = CrlCertStatusInfo.getRevokedCertStatusInfo(revocationInfo,
                    profileName, certHashes, notBefore, notAfter);
            newCertStatusInfoMap.put(serialNumber, crlCertStatusInfo);
        } // end while

        for (BigInteger serialNumber : certsMap.keySet()) {
            CertWithInfo cert = certsMap.get(serialNumber);

            Certificate bcCert = cert.getCert();
            Map<HashAlgoType, byte[]> certHashes = (bcCert == null) ? null : getCertHashes(bcCert);
            Date notBefore = (bcCert == null) ? null : bcCert.getTBSCertificate().getStartDate().getDate();
            Date notAfter = (bcCert == null) ? null : bcCert.getTBSCertificate().getEndDate().getDate();
            CrlCertStatusInfo crlCertStatusInfo = CrlCertStatusInfo.getGoodCertStatusInfo(cert.getProfileName(),
                    certHashes, notBefore, notAfter);
            newCertStatusInfoMap.put(cert.getSerialNumber(), crlCertStatusInfo);
        }

        this.initialized = false;
        this.lastmodifiedOfCrlFile = newLastModifed;
        this.fpOfCrlFile = newFp;

        this.lastModifiedOfDeltaCrlFile = newLastModifedOfDeltaCrl;
        this.fpOfDeltaCrlFile = newFpOfDeltaCrl;

        this.issuerHashMap.clear();
        this.issuerHashMap.putAll(newIssuerHashMap);
        this.certStatusInfoMap.clear();
        this.certStatusInfoMap.putAll(newCertStatusInfoMap);
        this.thisUpdate = newThisUpdate;
        this.nextUpdate = newNextUpdate;
        this.crlNumber = newCrlNumber;

        this.initializationFailed = false;
        this.initialized = true;
        updateCrlSuccessful = true;
        LOG.info("updated CertStore {}", name);
    } catch (Exception ex) {
        LogUtil.error(LOG, ex, "could not execute initializeStore()");
        initializationFailed = true;
        initialized = true;
    } finally {
        if (updateCrlSuccessful != null) {
            AuditLevel auditLevel = updateCrlSuccessful ? AuditLevel.INFO : AuditLevel.ERROR;
            AuditStatus auditStatus = updateCrlSuccessful ? AuditStatus.SUCCESSFUL : AuditStatus.FAILED;
            auditPciEvent(auditLevel, "UPDATE_CRL", auditStatus.name());
        }
    }
}