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

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

import org.bouncycastle.util.Strings;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Enumeration;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import java.security.spec.RSAPrivateKeySpec;
import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import java.math.BigInteger;
import org.bouncycastle.jcajce.interfaces.BCKey;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import java.security.interfaces.RSAPrivateKey;

public class BCRSAPrivateKey implements RSAPrivateKey, PKCS12BagAttributeCarrier, BCKey
{
    static final long serialVersionUID = 5110188922551353628L;
    private static BigInteger ZERO;
    protected BigInteger modulus;
    protected BigInteger privateExponent;
    private byte[] algorithmIdentifierEnc;
    protected transient AlgorithmIdentifier algorithmIdentifier;
    protected transient RSAKeyParameters rsaPrivateKey;
    protected transient PKCS12BagAttributeCarrierImpl attrCarrier;
    
    BCRSAPrivateKey(final RSAKeyParameters rsaPrivateKey) {
        this.algorithmIdentifierEnc = getEncoding(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER);
        this.algorithmIdentifier = BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER;
        this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
        this.modulus = rsaPrivateKey.getModulus();
        this.privateExponent = rsaPrivateKey.getExponent();
        this.rsaPrivateKey = rsaPrivateKey;
    }
    
    BCRSAPrivateKey(final AlgorithmIdentifier algorithmIdentifier, final RSAKeyParameters rsaPrivateKey) {
        this.algorithmIdentifierEnc = getEncoding(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER);
        this.algorithmIdentifier = BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER;
        this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
        this.algorithmIdentifier = algorithmIdentifier;
        this.algorithmIdentifierEnc = getEncoding(algorithmIdentifier);
        this.modulus = rsaPrivateKey.getModulus();
        this.privateExponent = rsaPrivateKey.getExponent();
        this.rsaPrivateKey = rsaPrivateKey;
    }
    
    BCRSAPrivateKey(final RSAPrivateKeySpec rsaPrivateKeySpec) {
        this.algorithmIdentifierEnc = getEncoding(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER);
        this.algorithmIdentifier = BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER;
        this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
        this.modulus = rsaPrivateKeySpec.getModulus();
        this.privateExponent = rsaPrivateKeySpec.getPrivateExponent();
        this.rsaPrivateKey = new RSAKeyParameters(true, this.modulus, this.privateExponent);
    }
    
    BCRSAPrivateKey(final RSAPrivateKey rsaPrivateKey) {
        this.algorithmIdentifierEnc = getEncoding(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER);
        this.algorithmIdentifier = BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER;
        this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
        this.modulus = rsaPrivateKey.getModulus();
        this.privateExponent = rsaPrivateKey.getPrivateExponent();
        this.rsaPrivateKey = new RSAKeyParameters(true, this.modulus, this.privateExponent);
    }
    
    BCRSAPrivateKey(final AlgorithmIdentifier algorithmIdentifier, final org.bouncycastle.asn1.pkcs.RSAPrivateKey rsaPrivateKey) {
        this.algorithmIdentifierEnc = getEncoding(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER);
        this.algorithmIdentifier = BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER;
        this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
        this.algorithmIdentifier = algorithmIdentifier;
        this.algorithmIdentifierEnc = getEncoding(algorithmIdentifier);
        this.modulus = rsaPrivateKey.getModulus();
        this.privateExponent = rsaPrivateKey.getPrivateExponent();
        this.rsaPrivateKey = new RSAKeyParameters(true, this.modulus, this.privateExponent);
    }
    
    @Override
    public BigInteger getModulus() {
        return this.modulus;
    }
    
    @Override
    public BigInteger getPrivateExponent() {
        return this.privateExponent;
    }
    
    @Override
    public String getAlgorithm() {
        if (this.algorithmIdentifier.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS)) {
            return "RSASSA-PSS";
        }
        return "RSA";
    }
    
    @Override
    public String getFormat() {
        return "PKCS#8";
    }
    
    RSAKeyParameters engineGetKeyParameters() {
        return this.rsaPrivateKey;
    }
    
    @Override
    public byte[] getEncoded() {
        return KeyUtil.getEncodedPrivateKeyInfo(this.algorithmIdentifier, new org.bouncycastle.asn1.pkcs.RSAPrivateKey(this.getModulus(), BCRSAPrivateKey.ZERO, this.getPrivateExponent(), BCRSAPrivateKey.ZERO, BCRSAPrivateKey.ZERO, BCRSAPrivateKey.ZERO, BCRSAPrivateKey.ZERO, BCRSAPrivateKey.ZERO));
    }
    
    @Override
    public boolean equals(final Object o) {
        if (!(o instanceof RSAPrivateKey)) {
            return false;
        }
        if (o == this) {
            return true;
        }
        final RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)o;
        return this.getModulus().equals(rsaPrivateKey.getModulus()) && this.getPrivateExponent().equals(rsaPrivateKey.getPrivateExponent());
    }
    
    @Override
    public int hashCode() {
        return this.getModulus().hashCode() ^ this.getPrivateExponent().hashCode();
    }
    
    @Override
    public void setBagAttribute(final ASN1ObjectIdentifier asn1ObjectIdentifier, final ASN1Encodable asn1Encodable) {
        this.attrCarrier.setBagAttribute(asn1ObjectIdentifier, asn1Encodable);
    }
    
    @Override
    public ASN1Encodable getBagAttribute(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        return this.attrCarrier.getBagAttribute(asn1ObjectIdentifier);
    }
    
    @Override
    public Enumeration getBagAttributeKeys() {
        return this.attrCarrier.getBagAttributeKeys();
    }
    
    @Override
    public boolean hasFriendlyName() {
        return this.attrCarrier.hasFriendlyName();
    }
    
    @Override
    public void setFriendlyName(final String friendlyName) {
        this.attrCarrier.setFriendlyName(friendlyName);
    }
    
    private void readObject(final ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
        objectInputStream.defaultReadObject();
        if (this.algorithmIdentifierEnc == null) {
            this.algorithmIdentifierEnc = getEncoding(BCRSAPublicKey.DEFAULT_ALGORITHM_IDENTIFIER);
        }
        this.algorithmIdentifier = AlgorithmIdentifier.getInstance(this.algorithmIdentifierEnc);
        this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
        this.rsaPrivateKey = new RSAKeyParameters(true, this.modulus, this.privateExponent);
    }
    
    private void writeObject(final ObjectOutputStream objectOutputStream) throws IOException {
        objectOutputStream.defaultWriteObject();
    }
    
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        final String lineSeparator = Strings.lineSeparator();
        sb.append("RSA Private Key [").append(RSAUtil.generateKeyFingerprint(this.getModulus())).append("],[]").append(lineSeparator);
        sb.append("            modulus: ").append(this.getModulus().toString(16)).append(lineSeparator);
        return sb.toString();
    }
    
    private static byte[] getEncoding(final AlgorithmIdentifier algorithmIdentifier) {
        try {
            return algorithmIdentifier.getEncoded();
        }
        catch (final IOException ex) {
            return null;
        }
    }
    
    static {
        BCRSAPrivateKey.ZERO = BigInteger.valueOf(0L);
    }
}
