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

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

import org.bouncycastle.util.Arrays;
import org.bouncycastle.crypto.PBEParametersGenerator;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import javax.crypto.spec.PBEKeySpec;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.security.auth.Destroyable;
import javax.crypto.interfaces.PBEKey;

public class BCPBEKey implements PBEKey, Destroyable
{
    private final AtomicBoolean hasBeenDestroyed;
    String algorithm;
    ASN1ObjectIdentifier oid;
    int type;
    int digest;
    int keySize;
    int ivSize;
    private final char[] password;
    private final byte[] salt;
    private final int iterationCount;
    private final CipherParameters param;
    boolean tryWrong;
    
    public BCPBEKey(final String algorithm, final ASN1ObjectIdentifier oid, final int type, final int digest, final int keySize, final int ivSize, final PBEKeySpec pbeKeySpec, final CipherParameters param) {
        this.hasBeenDestroyed = new AtomicBoolean(false);
        this.tryWrong = false;
        this.algorithm = algorithm;
        this.oid = oid;
        this.type = type;
        this.digest = digest;
        this.keySize = keySize;
        this.ivSize = ivSize;
        this.password = pbeKeySpec.getPassword();
        this.iterationCount = pbeKeySpec.getIterationCount();
        this.salt = pbeKeySpec.getSalt();
        this.param = param;
    }
    
    public BCPBEKey(final String algorithm, final CipherParameters param) {
        this.hasBeenDestroyed = new AtomicBoolean(false);
        this.tryWrong = false;
        this.algorithm = algorithm;
        this.param = param;
        this.password = null;
        this.iterationCount = -1;
        this.salt = null;
    }
    
    @Override
    public String getAlgorithm() {
        final String algorithm = this.algorithm;
        checkDestroyed(this);
        return algorithm;
    }
    
    @Override
    public String getFormat() {
        checkDestroyed(this);
        return "RAW";
    }
    
    @Override
    public byte[] getEncoded() {
        byte[] array;
        if (this.param != null) {
            KeyParameter keyParameter;
            if (this.param instanceof ParametersWithIV) {
                keyParameter = (KeyParameter)((ParametersWithIV)this.param).getParameters();
            }
            else {
                keyParameter = (KeyParameter)this.param;
            }
            array = keyParameter.getKey();
        }
        else if (this.type == 2) {
            array = PBEParametersGenerator.PKCS12PasswordToBytes(this.password);
        }
        else if (this.type == 5) {
            array = PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(this.password);
        }
        else {
            array = PBEParametersGenerator.PKCS5PasswordToBytes(this.password);
        }
        checkDestroyed(this);
        return array;
    }
    
    int getType() {
        final int type = this.type;
        checkDestroyed(this);
        return type;
    }
    
    int getDigest() {
        final int digest = this.digest;
        checkDestroyed(this);
        return digest;
    }
    
    int getKeySize() {
        final int keySize = this.keySize;
        checkDestroyed(this);
        return keySize;
    }
    
    public int getIvSize() {
        final int ivSize = this.ivSize;
        checkDestroyed(this);
        return ivSize;
    }
    
    public CipherParameters getParam() {
        final CipherParameters param = this.param;
        checkDestroyed(this);
        return param;
    }
    
    @Override
    public char[] getPassword() {
        final char[] clone = Arrays.clone(this.password);
        checkDestroyed(this);
        if (clone == null) {
            throw new IllegalStateException("no password available");
        }
        return clone;
    }
    
    @Override
    public byte[] getSalt() {
        final byte[] clone = Arrays.clone(this.salt);
        checkDestroyed(this);
        return clone;
    }
    
    @Override
    public int getIterationCount() {
        final int iterationCount = this.iterationCount;
        checkDestroyed(this);
        return iterationCount;
    }
    
    public ASN1ObjectIdentifier getOID() {
        final ASN1ObjectIdentifier oid = this.oid;
        checkDestroyed(this);
        return oid;
    }
    
    public void setTryWrongPKCS12Zero(final boolean tryWrong) {
        this.tryWrong = tryWrong;
    }
    
    boolean shouldTryWrongPKCS12() {
        return this.tryWrong;
    }
    
    @Override
    public void destroy() {
        if (!this.hasBeenDestroyed.getAndSet(true)) {
            if (this.password != null) {
                Arrays.fill(this.password, '\0');
            }
            if (this.salt != null) {
                Arrays.fill(this.salt, (byte)0);
            }
        }
    }
    
    @Override
    public boolean isDestroyed() {
        return this.hasBeenDestroyed.get();
    }
    
    static void checkDestroyed(final Destroyable destroyable) {
        if (destroyable.isDestroyed()) {
            throw new IllegalStateException("key has been destroyed");
        }
    }
}
