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

package org.bouncycastle.jcajce.provider.asymmetric.util;

import org.bouncycastle.util.Exceptions;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.params.ParametersWithContext;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import java.security.InvalidAlgorithmParameterException;
import org.bouncycastle.jcajce.util.SpecUtil;
import java.security.ProviderException;
import java.security.SignatureException;
import java.security.SecureRandom;
import java.security.PrivateKey;
import java.security.InvalidKeyException;
import java.security.PublicKey;
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.jcajce.spec.ContextParameterSpec;
import java.security.AlgorithmParameters;
import java.security.spec.AlgorithmParameterSpec;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import java.security.SignatureSpi;

public abstract class BaseDeterministicOrRandomSignature extends SignatureSpi
{
    private final JcaJceHelper helper;
    private final AlgorithmParameterSpec originalSpec;
    protected AlgorithmParameters engineParams;
    protected ContextParameterSpec paramSpec;
    protected AsymmetricKeyParameter keyParams;
    protected boolean isInitState;
    
    protected BaseDeterministicOrRandomSignature(final String s) {
        this.helper = new BCJcaJceHelper();
        this.isInitState = true;
        this.originalSpec = ContextParameterSpec.EMPTY_CONTEXT_SPEC;
    }
    
    @Override
    protected final void engineInitVerify(final PublicKey publicKey) throws InvalidKeyException {
        this.verifyInit(publicKey);
        this.paramSpec = ContextParameterSpec.EMPTY_CONTEXT_SPEC;
        this.isInitState = true;
        this.reInit();
    }
    
    protected abstract void verifyInit(final PublicKey p0) throws InvalidKeyException;
    
    @Override
    protected final void engineInitSign(final PrivateKey privateKey) throws InvalidKeyException {
        this.signInit(privateKey, null);
        this.paramSpec = ContextParameterSpec.EMPTY_CONTEXT_SPEC;
        this.isInitState = true;
        this.reInit();
    }
    
    @Override
    protected final void engineInitSign(final PrivateKey privateKey, final SecureRandom secureRandom) throws InvalidKeyException {
        this.signInit(privateKey, secureRandom);
        this.paramSpec = ContextParameterSpec.EMPTY_CONTEXT_SPEC;
        this.isInitState = true;
        this.reInit();
    }
    
    protected abstract void signInit(final PrivateKey p0, final SecureRandom p1) throws InvalidKeyException;
    
    @Override
    protected final void engineUpdate(final byte b) throws SignatureException {
        this.isInitState = false;
        this.updateEngine(b);
    }
    
    protected abstract void updateEngine(final byte p0) throws SignatureException;
    
    @Override
    protected final void engineUpdate(final byte[] array, final int n, final int n2) throws SignatureException {
        this.isInitState = false;
        this.updateEngine(array, n, n2);
    }
    
    protected abstract void updateEngine(final byte[] p0, final int p1, final int p2) throws SignatureException;
    
    @Override
    protected void engineSetParameter(AlgorithmParameterSpec originalSpec) throws InvalidAlgorithmParameterException {
        if (originalSpec == null) {
            if (this.originalSpec == null) {
                return;
            }
            originalSpec = this.originalSpec;
        }
        if (!this.isInitState) {
            throw new ProviderException("cannot call setParameter in the middle of update");
        }
        if (originalSpec instanceof ContextParameterSpec) {
            this.paramSpec = (ContextParameterSpec)originalSpec;
            this.reInit();
        }
        else {
            final byte[] context = SpecUtil.getContextFrom(originalSpec);
            if (context == null) {
                throw new InvalidAlgorithmParameterException("unknown AlgorithmParameterSpec in signature");
            }
            this.paramSpec = new ContextParameterSpec(context);
            this.reInit();
        }
    }
    
    private void reInit() {
        CipherParameters keyParams = this.keyParams;
        if (this.keyParams.isPrivate()) {
            if (this.appRandom != null) {
                keyParams = new ParametersWithRandom(keyParams, this.appRandom);
            }
            if (this.paramSpec != null) {
                keyParams = new ParametersWithContext(keyParams, this.paramSpec.getContext());
            }
            this.reInitialize(true, keyParams);
        }
        else {
            if (this.paramSpec != null) {
                keyParams = new ParametersWithContext(keyParams, this.paramSpec.getContext());
            }
            this.reInitialize(false, keyParams);
        }
    }
    
    protected abstract void reInitialize(final boolean p0, final CipherParameters p1);
    
    @Override
    protected final AlgorithmParameters engineGetParameters() {
        if (this.engineParams == null && this.paramSpec != null && this.paramSpec != ContextParameterSpec.EMPTY_CONTEXT_SPEC) {
            try {
                (this.engineParams = this.helper.createAlgorithmParameters("CONTEXT")).init(this.paramSpec);
            }
            catch (final Exception ex) {
                throw Exceptions.illegalStateException(ex.toString(), ex);
            }
        }
        return this.engineParams;
    }
    
    @Override
    @Deprecated
    protected final void engineSetParameter(final String s, final Object o) {
        throw new UnsupportedOperationException("SetParameter unsupported");
    }
    
    @Override
    @Deprecated
    protected final Object engineGetParameter(final String s) {
        throw new UnsupportedOperationException("GetParameter unsupported");
    }
}
