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

package org.bouncycastle.its.bc;

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DSA;
import org.bouncycastle.crypto.signers.DSADigestSigner;
import org.bouncycastle.crypto.signers.ECDSASigner;
import org.bouncycastle.crypto.io.DigestOutputStream;
import java.io.OutputStream;
import org.bouncycastle.util.Arrays;
import java.io.IOException;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.bc.BcDefaultDigestProvider;
import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
import org.bouncycastle.crypto.params.ECNamedDomainParameters;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.its.ITSCertificate;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.its.operator.ITSContentSigner;

public class BcITSContentSigner implements ITSContentSigner
{
    private final ECPrivateKeyParameters privKey;
    private final ITSCertificate signerCert;
    private final AlgorithmIdentifier digestAlgo;
    private final Digest digest;
    private final byte[] parentData;
    private final ASN1ObjectIdentifier curveID;
    private final byte[] parentDigest;
    
    public BcITSContentSigner(final ECPrivateKeyParameters ecPrivateKeyParameters) {
        this(ecPrivateKeyParameters, null);
    }
    
    public BcITSContentSigner(final ECPrivateKeyParameters privKey, final ITSCertificate signerCert) {
        this.privKey = privKey;
        this.curveID = ((ECNamedDomainParameters)privKey.getParameters()).getName();
        this.signerCert = signerCert;
        if (this.curveID.equals(SECObjectIdentifiers.secp256r1)) {
            this.digestAlgo = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256);
        }
        else if (this.curveID.equals(TeleTrusTObjectIdentifiers.brainpoolP256r1)) {
            this.digestAlgo = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256);
        }
        else {
            if (!this.curveID.equals(TeleTrusTObjectIdentifiers.brainpoolP384r1)) {
                throw new IllegalArgumentException("unknown key type");
            }
            this.digestAlgo = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384);
        }
        try {
            this.digest = BcDefaultDigestProvider.INSTANCE.get(this.digestAlgo);
        }
        catch (final OperatorCreationException ex) {
            throw new IllegalStateException("cannot recognise digest type: " + this.digestAlgo.getAlgorithm());
        }
        if (signerCert != null) {
            try {
                this.parentData = signerCert.getEncoded();
                this.parentDigest = new byte[this.digest.getDigestSize()];
                this.digest.update(this.parentData, 0, this.parentData.length);
                this.digest.doFinal(this.parentDigest, 0);
                return;
            }
            catch (final IOException ex2) {
                throw new IllegalStateException("signer certificate encoding failed: " + ex2.getMessage());
            }
        }
        this.parentData = null;
        this.parentDigest = new byte[this.digest.getDigestSize()];
        this.digest.doFinal(this.parentDigest, 0);
    }
    
    @Override
    public ITSCertificate getAssociatedCertificate() {
        return this.signerCert;
    }
    
    @Override
    public byte[] getAssociatedCertificateDigest() {
        return Arrays.clone(this.parentDigest);
    }
    
    @Override
    public AlgorithmIdentifier getDigestAlgorithm() {
        return this.digestAlgo;
    }
    
    @Override
    public OutputStream getOutputStream() {
        return new DigestOutputStream(this.digest);
    }
    
    @Override
    public boolean isForSelfSigning() {
        return this.parentData == null;
    }
    
    @Override
    public ASN1ObjectIdentifier getCurveID() {
        return this.curveID;
    }
    
    @Override
    public byte[] getSignature() {
        final byte[] array = new byte[this.digest.getDigestSize()];
        this.digest.doFinal(array, 0);
        final DSADigestSigner dsaDigestSigner = new DSADigestSigner(new ECDSASigner(), this.digest);
        dsaDigestSigner.init(true, this.privKey);
        dsaDigestSigner.update(array, 0, array.length);
        dsaDigestSigner.update(this.parentDigest, 0, this.parentDigest.length);
        return dsaDigestSigner.generateSignature();
    }
}
