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

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

import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.BasicConstraints;
import java.io.IOException;
import java.util.Enumeration;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.ASN1Primitive;
import java.security.cert.CertificateEncodingException;
import org.bouncycastle.util.Arrays;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.CertificateExpiredException;
import java.util.Date;
import java.security.cert.CertificateParsingException;
import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import java.security.PublicKey;
import javax.security.auth.x500.X500Principal;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;

class X509CertificateObject extends X509CertificateImpl implements PKCS12BagAttributeCarrier
{
    private final Object cacheLock;
    private X509CertificateInternal internalCertificateValue;
    private X500Principal issuerValue;
    private PublicKey publicKeyValue;
    private X500Principal subjectValue;
    private long[] validityValues;
    private volatile boolean hashValueSet;
    private volatile int hashValue;
    private PKCS12BagAttributeCarrier attrCarrier;
    
    X509CertificateObject(final JcaJceHelper jcaJceHelper, final org.bouncycastle.asn1.x509.Certificate certificate) throws CertificateParsingException {
        super(jcaJceHelper, certificate, createBasicConstraints(certificate), createKeyUsage(certificate), createSigAlgName(certificate), createSigAlgParams(certificate));
        this.cacheLock = new Object();
        this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
    }
    
    @Override
    public void checkValidity(final Date date) throws CertificateExpiredException, CertificateNotYetValidException {
        final long time = date.getTime();
        final long[] validityValues = this.getValidityValues();
        if (time > validityValues[1]) {
            throw new CertificateExpiredException("certificate expired on " + this.c.getEndDate().getTime());
        }
        if (time < validityValues[0]) {
            throw new CertificateNotYetValidException("certificate not valid till " + this.c.getStartDate().getTime());
        }
    }
    
    @Override
    public X500Principal getIssuerX500Principal() {
        synchronized (this.cacheLock) {
            if (null != this.issuerValue) {
                return this.issuerValue;
            }
        }
        final X500Principal issuerX500Principal = super.getIssuerX500Principal();
        synchronized (this.cacheLock) {
            if (null == this.issuerValue) {
                this.issuerValue = issuerX500Principal;
            }
            return this.issuerValue;
        }
    }
    
    @Override
    public PublicKey getPublicKey() {
        synchronized (this.cacheLock) {
            if (null != this.publicKeyValue) {
                return this.publicKeyValue;
            }
        }
        final PublicKey publicKey = super.getPublicKey();
        if (null == publicKey) {
            return null;
        }
        synchronized (this.cacheLock) {
            if (null == this.publicKeyValue) {
                this.publicKeyValue = publicKey;
            }
            return this.publicKeyValue;
        }
    }
    
    @Override
    public X500Principal getSubjectX500Principal() {
        synchronized (this.cacheLock) {
            if (null != this.subjectValue) {
                return this.subjectValue;
            }
        }
        final X500Principal subjectX500Principal = super.getSubjectX500Principal();
        synchronized (this.cacheLock) {
            if (null == this.subjectValue) {
                this.subjectValue = subjectX500Principal;
            }
            return this.subjectValue;
        }
    }
    
    public long[] getValidityValues() {
        synchronized (this.cacheLock) {
            if (null != this.validityValues) {
                return this.validityValues;
            }
        }
        final long[] validityValues = { super.getNotBefore().getTime(), super.getNotAfter().getTime() };
        synchronized (this.cacheLock) {
            if (null == this.validityValues) {
                this.validityValues = validityValues;
            }
            return this.validityValues;
        }
    }
    
    @Override
    public byte[] getEncoded() throws CertificateEncodingException {
        return Arrays.clone(this.getInternalCertificate().getEncoded());
    }
    
    @Override
    public boolean equals(final Object other) {
        if (other == this) {
            return true;
        }
        if (other instanceof X509CertificateObject) {
            final X509CertificateObject x509CertificateObject = (X509CertificateObject)other;
            if (this.hashValueSet && x509CertificateObject.hashValueSet) {
                if (this.hashValue != x509CertificateObject.hashValue) {
                    return false;
                }
            }
            else if (null == this.internalCertificateValue || null == x509CertificateObject.internalCertificateValue) {
                final ASN1BitString signature = this.c.getSignature();
                if (null != signature && !signature.equals(x509CertificateObject.c.getSignature())) {
                    return false;
                }
            }
            return this.getInternalCertificate().equals(x509CertificateObject.getInternalCertificate());
        }
        return this.getInternalCertificate().equals(other);
    }
    
    @Override
    public int hashCode() {
        if (!this.hashValueSet) {
            this.hashValue = this.getInternalCertificate().hashCode();
            this.hashValueSet = true;
        }
        return this.hashValue;
    }
    
    public int originalHashCode() {
        try {
            int n = 0;
            final byte[] encoded = this.getInternalCertificate().getEncoded();
            for (byte b = 1; b < encoded.length; ++b) {
                n += encoded[b] * b;
            }
            return n;
        }
        catch (final CertificateEncodingException ex) {
            return 0;
        }
    }
    
    @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 X509CertificateInternal getInternalCertificate() {
        synchronized (this.cacheLock) {
            if (null != this.internalCertificateValue) {
                return this.internalCertificateValue;
            }
        }
        byte[] encoded = null;
        CertificateEncodingException ex = null;
        try {
            encoded = this.c.getEncoded("DER");
        }
        catch (final IOException ex2) {
            ex = new X509CertificateEncodingException(ex2);
        }
        final X509CertificateInternal internalCertificateValue = new X509CertificateInternal(this.bcHelper, this.c, this.basicConstraints, this.keyUsage, this.sigAlgName, this.sigAlgParams, encoded, ex);
        synchronized (this.cacheLock) {
            if (null == this.internalCertificateValue) {
                this.internalCertificateValue = internalCertificateValue;
            }
            return this.internalCertificateValue;
        }
    }
    
    private static BasicConstraints createBasicConstraints(final org.bouncycastle.asn1.x509.Certificate certificate) throws CertificateParsingException {
        try {
            final byte[] extensionOctets = X509CertificateImpl.getExtensionOctets(certificate, Extension.basicConstraints);
            if (null == extensionOctets) {
                return null;
            }
            return BasicConstraints.getInstance(extensionOctets);
        }
        catch (final Exception obj) {
            throw new CertificateParsingException("cannot construct BasicConstraints: " + obj);
        }
    }
    
    private static boolean[] createKeyUsage(final org.bouncycastle.asn1.x509.Certificate certificate) throws CertificateParsingException {
        try {
            final byte[] extensionOctets = X509CertificateImpl.getExtensionOctets(certificate, Extension.keyUsage);
            if (null == extensionOctets) {
                return null;
            }
            final ASN1BitString instance = ASN1BitString.getInstance(extensionOctets);
            final byte[] bytes = instance.getBytes();
            final int n = bytes.length * 8 - instance.getPadBits();
            final boolean[] array = new boolean[(n < 9) ? 9 : n];
            for (int i = 0; i != n; ++i) {
                array[i] = ((bytes[i / 8] & 128 >>> i % 8) != 0x0);
            }
            return array;
        }
        catch (final Exception obj) {
            throw new CertificateParsingException("cannot construct KeyUsage: " + obj);
        }
    }
    
    private static String createSigAlgName(final org.bouncycastle.asn1.x509.Certificate certificate) throws CertificateParsingException {
        try {
            return X509SignatureUtil.getSignatureName(certificate.getSignatureAlgorithm());
        }
        catch (final Exception obj) {
            throw new CertificateParsingException("cannot construct SigAlgName: " + obj);
        }
    }
    
    private static byte[] createSigAlgParams(final org.bouncycastle.asn1.x509.Certificate certificate) throws CertificateParsingException {
        try {
            final ASN1Encodable parameters = certificate.getSignatureAlgorithm().getParameters();
            if (null == parameters) {
                return null;
            }
            return parameters.toASN1Primitive().getEncoded("DER");
        }
        catch (final Exception obj) {
            throw new CertificateParsingException("cannot construct SigAlgParams: " + obj);
        }
    }
    
    private static class X509CertificateEncodingException extends CertificateEncodingException
    {
        private final Throwable cause;
        
        X509CertificateEncodingException(final Throwable cause) {
            this.cause = cause;
        }
        
        @Override
        public Throwable getCause() {
            return this.cause;
        }
    }
}
