// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.cert;

import java.io.OutputStream;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.x509.CertificateList;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.util.Exceptions;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.operator.ContentSigner;
import java.io.IOException;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.x509.TBSCertList;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1GeneralizedTime;
import org.bouncycastle.asn1.ASN1Integer;
import java.math.BigInteger;
import java.util.Enumeration;
import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import java.util.Locale;
import org.bouncycastle.asn1.x509.Time;
import java.util.Date;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
import org.bouncycastle.asn1.x509.V2TBSCertListGenerator;

public class X509v2CRLBuilder
{
    private V2TBSCertListGenerator tbsGen;
    private ExtensionsGenerator extGenerator;
    
    public X509v2CRLBuilder(final X500Name issuer, final Date date) {
        this.tbsGen = new V2TBSCertListGenerator();
        this.extGenerator = new ExtensionsGenerator();
        this.tbsGen.setIssuer(issuer);
        this.tbsGen.setThisUpdate(new Time(date));
    }
    
    public X509v2CRLBuilder(final X500Name issuer, final Date date, final Locale locale) {
        this.tbsGen = new V2TBSCertListGenerator();
        this.extGenerator = new ExtensionsGenerator();
        this.tbsGen.setIssuer(issuer);
        this.tbsGen.setThisUpdate(new Time(date, locale));
    }
    
    public X509v2CRLBuilder(final X500Name issuer, final Time thisUpdate) {
        this.tbsGen = new V2TBSCertListGenerator();
        this.extGenerator = new ExtensionsGenerator();
        this.tbsGen.setIssuer(issuer);
        this.tbsGen.setThisUpdate(thisUpdate);
    }
    
    public X509v2CRLBuilder(final X509CRLHolder x509CRLHolder) {
        (this.tbsGen = new V2TBSCertListGenerator()).setIssuer(x509CRLHolder.getIssuer());
        this.tbsGen.setThisUpdate(new Time(x509CRLHolder.getThisUpdate()));
        final Date nextUpdate = x509CRLHolder.getNextUpdate();
        if (nextUpdate != null) {
            this.tbsGen.setNextUpdate(new Time(nextUpdate));
        }
        this.addCRL(x509CRLHolder);
        this.extGenerator = new ExtensionsGenerator();
        final Extensions extensions = x509CRLHolder.getExtensions();
        if (extensions != null) {
            final Enumeration oids = extensions.oids();
            while (oids.hasMoreElements()) {
                final ASN1ObjectIdentifier asn1ObjectIdentifier = oids.nextElement();
                if (!Extension.altSignatureAlgorithm.equals(asn1ObjectIdentifier)) {
                    if (Extension.altSignatureValue.equals(asn1ObjectIdentifier)) {
                        continue;
                    }
                    this.extGenerator.addExtension(extensions.getExtension(asn1ObjectIdentifier));
                }
            }
        }
    }
    
    public boolean hasExtension(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        return this.doGetExtension(asn1ObjectIdentifier) != null;
    }
    
    public Extension getExtension(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        return this.doGetExtension(asn1ObjectIdentifier);
    }
    
    private Extension doGetExtension(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        if (this.extGenerator.isEmpty()) {
            return null;
        }
        return this.extGenerator.generate().getExtension(asn1ObjectIdentifier);
    }
    
    public X509v2CRLBuilder setThisUpdate(final Date date) {
        return this.setThisUpdate(new Time(date));
    }
    
    public X509v2CRLBuilder setThisUpdate(final Date date, final Locale locale) {
        return this.setThisUpdate(new Time(date, locale));
    }
    
    public X509v2CRLBuilder setThisUpdate(final Time thisUpdate) {
        this.tbsGen.setThisUpdate(thisUpdate);
        return this;
    }
    
    public X509v2CRLBuilder setNextUpdate(final Date date) {
        return this.setNextUpdate(new Time(date));
    }
    
    public X509v2CRLBuilder setNextUpdate(final Date date, final Locale locale) {
        return this.setNextUpdate(new Time(date, locale));
    }
    
    public X509v2CRLBuilder setNextUpdate(final Time nextUpdate) {
        this.tbsGen.setNextUpdate(nextUpdate);
        return this;
    }
    
    public X509v2CRLBuilder addCRLEntry(final BigInteger bigInteger, final Date date, final int n) {
        this.tbsGen.addCRLEntry(new ASN1Integer(bigInteger), new Time(date), n);
        return this;
    }
    
    public X509v2CRLBuilder addCRLEntry(final BigInteger bigInteger, final Date date, final int n, final Date date2) {
        this.tbsGen.addCRLEntry(new ASN1Integer(bigInteger), new Time(date), n, new ASN1GeneralizedTime(date2));
        return this;
    }
    
    public X509v2CRLBuilder addCRLEntry(final BigInteger bigInteger, final Date date, final Extensions extensions) {
        this.tbsGen.addCRLEntry(new ASN1Integer(bigInteger), new Time(date), extensions);
        return this;
    }
    
    public X509v2CRLBuilder addCRL(final X509CRLHolder x509CRLHolder) {
        final TBSCertList tbsCertList = x509CRLHolder.toASN1Structure().getTBSCertList();
        if (tbsCertList != null) {
            final Enumeration revokedCertificateEnumeration = tbsCertList.getRevokedCertificateEnumeration();
            while (revokedCertificateEnumeration.hasMoreElements()) {
                this.tbsGen.addCRLEntry(ASN1Sequence.getInstance(((ASN1Encodable)revokedCertificateEnumeration.nextElement()).toASN1Primitive()));
            }
        }
        return this;
    }
    
    public X509v2CRLBuilder addExtension(final ASN1ObjectIdentifier asn1ObjectIdentifier, final boolean b, final ASN1Encodable asn1Encodable) throws CertIOException {
        CertUtils.addExtension(this.extGenerator, asn1ObjectIdentifier, b, asn1Encodable);
        return this;
    }
    
    public X509v2CRLBuilder addExtension(final ASN1ObjectIdentifier asn1ObjectIdentifier, final boolean b, final byte[] array) throws CertIOException {
        this.extGenerator.addExtension(asn1ObjectIdentifier, b, array);
        return this;
    }
    
    public X509v2CRLBuilder addExtension(final Extension extension) throws CertIOException {
        this.extGenerator.addExtension(extension);
        return this;
    }
    
    public X509v2CRLBuilder replaceExtension(final ASN1ObjectIdentifier asn1ObjectIdentifier, final boolean b, final ASN1Encodable asn1Encodable) throws CertIOException {
        try {
            this.extGenerator = CertUtils.doReplaceExtension(this.extGenerator, new Extension(asn1ObjectIdentifier, b, new DEROctetString(asn1Encodable)));
        }
        catch (final IOException ex) {
            throw new CertIOException("cannot encode extension: " + ex.getMessage(), ex);
        }
        return this;
    }
    
    public X509v2CRLBuilder replaceExtension(final Extension extension) throws CertIOException {
        this.extGenerator = CertUtils.doReplaceExtension(this.extGenerator, extension);
        return this;
    }
    
    public X509v2CRLBuilder replaceExtension(final ASN1ObjectIdentifier asn1ObjectIdentifier, final boolean b, final byte[] array) throws CertIOException {
        this.extGenerator = CertUtils.doReplaceExtension(this.extGenerator, new Extension(asn1ObjectIdentifier, b, array));
        return this;
    }
    
    public X509v2CRLBuilder removeExtension(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        this.extGenerator = CertUtils.doRemoveExtension(this.extGenerator, asn1ObjectIdentifier);
        return this;
    }
    
    public X509CRLHolder build(final ContentSigner contentSigner) {
        this.tbsGen.setSignature(contentSigner.getAlgorithmIdentifier());
        if (!this.extGenerator.isEmpty()) {
            this.tbsGen.setExtensions(this.extGenerator.generate());
        }
        return generateFullCRL(contentSigner, this.tbsGen.generateTBSCertList());
    }
    
    public X509CRLHolder build(final ContentSigner contentSigner, final boolean b, final ContentSigner contentSigner2) {
        this.tbsGen.setSignature(null);
        try {
            this.extGenerator.addExtension(Extension.altSignatureAlgorithm, b, contentSigner2.getAlgorithmIdentifier());
        }
        catch (final IOException ex) {
            throw Exceptions.illegalStateException("cannot add altSignatureAlgorithm extension", ex);
        }
        this.tbsGen.setExtensions(this.extGenerator.generate());
        try {
            this.extGenerator.addExtension(Extension.altSignatureValue, b, new DERBitString(generateSig(contentSigner2, this.tbsGen.generatePreTBSCertList())));
            this.tbsGen.setSignature(contentSigner.getAlgorithmIdentifier());
            this.tbsGen.setExtensions(this.extGenerator.generate());
            final TBSCertList generateTBSCertList = this.tbsGen.generateTBSCertList();
            return new X509CRLHolder(generateCRLStructure(generateTBSCertList, contentSigner.getAlgorithmIdentifier(), generateSig(contentSigner, generateTBSCertList)));
        }
        catch (final IOException ex2) {
            throw Exceptions.illegalArgumentException("cannot produce certificate signature", ex2);
        }
    }
    
    private static X509CRLHolder generateFullCRL(final ContentSigner contentSigner, final TBSCertList list) {
        try {
            return new X509CRLHolder(generateCRLStructure(list, contentSigner.getAlgorithmIdentifier(), generateSig(contentSigner, list)));
        }
        catch (final IOException ex) {
            throw Exceptions.illegalStateException("cannot produce certificate signature", ex);
        }
    }
    
    private static CertificateList generateCRLStructure(final TBSCertList list, final AlgorithmIdentifier algorithmIdentifier, final byte[] array) {
        final ASN1EncodableVector asn1EncodableVector = new ASN1EncodableVector();
        asn1EncodableVector.add(list);
        asn1EncodableVector.add(algorithmIdentifier);
        asn1EncodableVector.add(new DERBitString(array));
        return CertificateList.getInstance(new DERSequence(asn1EncodableVector));
    }
    
    private static byte[] generateSig(final ContentSigner contentSigner, final ASN1Object asn1Object) throws IOException {
        final OutputStream outputStream = contentSigner.getOutputStream();
        asn1Object.encodeTo(outputStream, "DER");
        outputStream.close();
        return contentSigner.getSignature();
    }
}
