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

package org.bouncycastle.cms;

import org.bouncycastle.operator.DigestCalculator;
import org.bouncycastle.operator.ExtendedContentSigner;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.asn1.cms.SignerIdentifier;
import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.operator.DigestCalculatorProvider;
import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;

public class SignerInfoGeneratorBuilder
{
    private final DigestAlgorithmIdentifierFinder digAlgFinder;
    private DigestCalculatorProvider digestProvider;
    private boolean directSignature;
    private CMSAttributeTableGenerator signedGen;
    private CMSAttributeTableGenerator unsignedGen;
    private CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder;
    private AlgorithmIdentifier contentDigest;
    
    public SignerInfoGeneratorBuilder(final DigestCalculatorProvider digestCalculatorProvider) {
        this(digestCalculatorProvider, new DefaultCMSSignatureEncryptionAlgorithmFinder());
    }
    
    public SignerInfoGeneratorBuilder(final DigestCalculatorProvider digestProvider, final CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder) {
        this.digAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
        this.digestProvider = digestProvider;
        this.sigEncAlgFinder = sigEncAlgFinder;
    }
    
    public SignerInfoGeneratorBuilder setDirectSignature(final boolean directSignature) {
        this.directSignature = directSignature;
        return this;
    }
    
    public SignerInfoGeneratorBuilder setContentDigest(final AlgorithmIdentifier contentDigest) {
        this.contentDigest = contentDigest;
        return this;
    }
    
    public SignerInfoGeneratorBuilder setSignedAttributeGenerator(final CMSAttributeTableGenerator signedGen) {
        this.signedGen = signedGen;
        return this;
    }
    
    public SignerInfoGeneratorBuilder setUnsignedAttributeGenerator(final CMSAttributeTableGenerator unsignedGen) {
        this.unsignedGen = unsignedGen;
        return this;
    }
    
    public SignerInfoGenerator build(final ContentSigner contentSigner, final X509CertificateHolder associatedCertificate) throws OperatorCreationException {
        final SignerInfoGenerator generator = this.createGenerator(contentSigner, new SignerIdentifier(new IssuerAndSerialNumber(associatedCertificate.toASN1Structure())));
        generator.setAssociatedCertificate(associatedCertificate);
        return generator;
    }
    
    public SignerInfoGenerator build(final ContentSigner contentSigner, final byte[] array) throws OperatorCreationException {
        return this.createGenerator(contentSigner, new SignerIdentifier(new DEROctetString(array)));
    }
    
    private SignerInfoGenerator createGenerator(final ContentSigner contentSigner, final SignerIdentifier signerIdentifier) throws OperatorCreationException {
        DigestCalculator digestCalculator;
        if (this.contentDigest != null) {
            digestCalculator = this.digestProvider.get(this.contentDigest);
        }
        else {
            AlgorithmIdentifier algorithmIdentifier = null;
            if (contentSigner instanceof ExtendedContentSigner) {
                algorithmIdentifier = ((ExtendedContentSigner)contentSigner).getDigestAlgorithmIdentifier();
            }
            if (algorithmIdentifier == null) {
                algorithmIdentifier = this.digAlgFinder.find(contentSigner.getAlgorithmIdentifier());
            }
            if (algorithmIdentifier == null) {
                throw new OperatorCreationException("no digest algorithm specified for signature algorithm");
            }
            digestCalculator = this.digestProvider.get(algorithmIdentifier);
        }
        if (this.directSignature) {
            return new SignerInfoGenerator(signerIdentifier, contentSigner, digestCalculator.getAlgorithmIdentifier(), this.sigEncAlgFinder);
        }
        if (this.signedGen != null || this.unsignedGen != null) {
            if (this.signedGen == null) {
                this.signedGen = new DefaultSignedAttributeTableGenerator();
            }
            return new SignerInfoGenerator(signerIdentifier, contentSigner, digestCalculator, this.sigEncAlgFinder, this.signedGen, this.unsignedGen);
        }
        return new SignerInfoGenerator(signerIdentifier, contentSigner, digestCalculator, this.sigEncAlgFinder, new DefaultSignedAttributeTableGenerator(), null);
    }
}
