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

package org.bouncycastle.cert.crmf;

import org.bouncycastle.asn1.crmf.CertTemplate;
import java.util.Iterator;
import org.bouncycastle.asn1.crmf.CertReqMsg;
import org.bouncycastle.asn1.crmf.ProofOfPossession;
import org.bouncycastle.asn1.crmf.CertRequest;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.crmf.SubsequentMessage;
import org.bouncycastle.cert.CertIOException;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x509.Time;
import org.bouncycastle.asn1.crmf.OptionalValidity;
import java.util.Date;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import java.util.ArrayList;
import org.bouncycastle.asn1.crmf.AttributeTypeAndValue;
import org.bouncycastle.asn1.crmf.PKMACValue;
import org.bouncycastle.asn1.ASN1Null;
import org.bouncycastle.asn1.crmf.POPOPrivKey;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.operator.ContentSigner;
import java.util.List;
import org.bouncycastle.asn1.crmf.CertTemplateBuilder;
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
import java.math.BigInteger;

public class CertificateRequestMessageBuilder
{
    private final BigInteger certReqId;
    private ExtensionsGenerator extGenerator;
    private CertTemplateBuilder templateBuilder;
    private List controls;
    private ContentSigner popSigner;
    private PKMACBuilder pkmacBuilder;
    private char[] password;
    private GeneralName sender;
    private int popoType;
    private POPOPrivKey popoPrivKey;
    private ASN1Null popRaVerified;
    private PKMACValue agreeMAC;
    private AttributeTypeAndValue[] regInfo;
    
    public CertificateRequestMessageBuilder(final BigInteger certReqId) {
        this.popoType = 2;
        this.certReqId = certReqId;
        this.extGenerator = new ExtensionsGenerator();
        this.templateBuilder = new CertTemplateBuilder();
        this.controls = new ArrayList();
        this.regInfo = null;
    }
    
    public CertificateRequestMessageBuilder setRegInfo(final AttributeTypeAndValue[] regInfo) {
        this.regInfo = regInfo;
        return this;
    }
    
    public CertificateRequestMessageBuilder setPublicKey(final SubjectPublicKeyInfo publicKey) {
        if (publicKey != null) {
            this.templateBuilder.setPublicKey(publicKey);
        }
        return this;
    }
    
    public CertificateRequestMessageBuilder setIssuer(final X500Name issuer) {
        if (issuer != null) {
            this.templateBuilder.setIssuer(issuer);
        }
        return this;
    }
    
    public CertificateRequestMessageBuilder setSubject(final X500Name subject) {
        if (subject != null) {
            this.templateBuilder.setSubject(subject);
        }
        return this;
    }
    
    public CertificateRequestMessageBuilder setSerialNumber(final BigInteger bigInteger) {
        if (bigInteger != null) {
            this.templateBuilder.setSerialNumber(new ASN1Integer(bigInteger));
        }
        return this;
    }
    
    public CertificateRequestMessageBuilder setSerialNumber(final ASN1Integer serialNumber) {
        if (serialNumber != null) {
            this.templateBuilder.setSerialNumber(serialNumber);
        }
        return this;
    }
    
    public CertificateRequestMessageBuilder setValidity(final Date date, final Date date2) {
        this.templateBuilder.setValidity(new OptionalValidity(this.createTime(date), this.createTime(date2)));
        return this;
    }
    
    private Time createTime(final Date date) {
        if (date != null) {
            return new Time(date);
        }
        return null;
    }
    
    public CertificateRequestMessageBuilder addExtension(final ASN1ObjectIdentifier asn1ObjectIdentifier, final boolean b, final ASN1Encodable asn1Encodable) throws CertIOException {
        CRMFUtil.addExtension(this.extGenerator, asn1ObjectIdentifier, b, asn1Encodable);
        return this;
    }
    
    public CertificateRequestMessageBuilder addExtension(final ASN1ObjectIdentifier asn1ObjectIdentifier, final boolean b, final byte[] array) {
        this.extGenerator.addExtension(asn1ObjectIdentifier, b, array);
        return this;
    }
    
    public CertificateRequestMessageBuilder addControl(final Control control) {
        this.controls.add(control);
        return this;
    }
    
    public CertificateRequestMessageBuilder setProofOfPossessionSigningKeySigner(final ContentSigner popSigner) {
        if (this.popoPrivKey != null || this.popRaVerified != null || this.agreeMAC != null) {
            throw new IllegalStateException("only one proof of possession allowed");
        }
        this.popSigner = popSigner;
        return this;
    }
    
    public CertificateRequestMessageBuilder setProofOfPossessionSubsequentMessage(final SubsequentMessage subsequentMessage) {
        if (this.popSigner != null || this.popRaVerified != null || this.agreeMAC != null) {
            throw new IllegalStateException("only one proof of possession allowed");
        }
        this.popoType = 2;
        this.popoPrivKey = new POPOPrivKey(subsequentMessage);
        return this;
    }
    
    public CertificateRequestMessageBuilder setProofOfPossessionSubsequentMessage(final int popoType, final SubsequentMessage subsequentMessage) {
        if (this.popSigner != null || this.popRaVerified != null || this.agreeMAC != null) {
            throw new IllegalStateException("only one proof of possession allowed");
        }
        if (popoType != 2 && popoType != 3) {
            throw new IllegalArgumentException("type must be ProofOfPossession.TYPE_KEY_ENCIPHERMENT or ProofOfPossession.TYPE_KEY_AGREEMENT");
        }
        this.popoType = popoType;
        this.popoPrivKey = new POPOPrivKey(subsequentMessage);
        return this;
    }
    
    public CertificateRequestMessageBuilder setProofOfPossessionAgreeMAC(final PKMACValue agreeMAC) {
        if (this.popSigner != null || this.popRaVerified != null || this.popoPrivKey != null) {
            throw new IllegalStateException("only one proof of possession allowed");
        }
        this.agreeMAC = agreeMAC;
        return this;
    }
    
    public CertificateRequestMessageBuilder setProofOfPossessionRaVerified() {
        if (this.popSigner != null || this.popoPrivKey != null) {
            throw new IllegalStateException("only one proof of possession allowed");
        }
        this.popRaVerified = DERNull.INSTANCE;
        return this;
    }
    
    public CertificateRequestMessageBuilder setAuthInfoPKMAC(final PKMACBuilder pkmacBuilder, final char[] password) {
        this.pkmacBuilder = pkmacBuilder;
        this.password = password;
        return this;
    }
    
    public CertificateRequestMessageBuilder setAuthInfoSender(final X500Name x500Name) {
        return this.setAuthInfoSender(new GeneralName(x500Name));
    }
    
    public CertificateRequestMessageBuilder setAuthInfoSender(final GeneralName sender) {
        this.sender = sender;
        return this;
    }
    
    public CertificateRequestMessage build() throws CRMFException {
        final ASN1EncodableVector asn1EncodableVector = new ASN1EncodableVector(3);
        asn1EncodableVector.add(new ASN1Integer(this.certReqId));
        if (!this.extGenerator.isEmpty()) {
            this.templateBuilder.setExtensions(this.extGenerator.generate());
        }
        asn1EncodableVector.add(this.templateBuilder.build());
        if (!this.controls.isEmpty()) {
            final ASN1EncodableVector asn1EncodableVector2 = new ASN1EncodableVector();
            for (final Control control : this.controls) {
                asn1EncodableVector2.add(new AttributeTypeAndValue(control.getType(), control.getValue()));
            }
            asn1EncodableVector.add(new DERSequence(asn1EncodableVector2));
        }
        final CertRequest instance = CertRequest.getInstance(new DERSequence(asn1EncodableVector));
        ProofOfPossession proofOfPossession;
        if (this.popSigner != null) {
            final CertTemplate certTemplate = instance.getCertTemplate();
            ProofOfPossessionSigningKeyBuilder proofOfPossessionSigningKeyBuilder;
            if (certTemplate.getSubject() == null || certTemplate.getPublicKey() == null) {
                proofOfPossessionSigningKeyBuilder = new ProofOfPossessionSigningKeyBuilder(instance.getCertTemplate().getPublicKey());
                if (this.sender != null) {
                    proofOfPossessionSigningKeyBuilder.setSender(this.sender);
                }
                else {
                    proofOfPossessionSigningKeyBuilder.setPublicKeyMac(this.pkmacBuilder, this.password);
                }
            }
            else {
                proofOfPossessionSigningKeyBuilder = new ProofOfPossessionSigningKeyBuilder(instance);
            }
            proofOfPossession = new ProofOfPossession(proofOfPossessionSigningKeyBuilder.build(this.popSigner));
        }
        else if (this.popoPrivKey != null) {
            proofOfPossession = new ProofOfPossession(this.popoType, this.popoPrivKey);
        }
        else if (this.agreeMAC != null) {
            proofOfPossession = new ProofOfPossession(3, new POPOPrivKey(this.agreeMAC));
        }
        else if (this.popRaVerified != null) {
            proofOfPossession = new ProofOfPossession();
        }
        else {
            proofOfPossession = new ProofOfPossession();
        }
        return new CertificateRequestMessage(new CertReqMsg(instance, proofOfPossession, this.regInfo));
    }
}
