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

package org.bouncycastle.asn1.x509;

import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.util.Properties;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Object;

public class TBSCertificate extends ASN1Object
{
    ASN1Sequence seq;
    ASN1Integer version;
    ASN1Integer serialNumber;
    AlgorithmIdentifier signature;
    X500Name issuer;
    Validity validity;
    X500Name subject;
    SubjectPublicKeyInfo subjectPublicKeyInfo;
    ASN1BitString issuerUniqueId;
    ASN1BitString subjectUniqueId;
    Extensions extensions;
    
    public static TBSCertificate getInstance(final ASN1TaggedObject asn1TaggedObject, final boolean b) {
        return getInstance(ASN1Sequence.getInstance(asn1TaggedObject, b));
    }
    
    public static TBSCertificate getInstance(final Object o) {
        if (o instanceof TBSCertificate) {
            return (TBSCertificate)o;
        }
        if (o != null) {
            return new TBSCertificate(ASN1Sequence.getInstance(o));
        }
        return null;
    }
    
    private TBSCertificate(final ASN1Sequence seq) {
        int n = 0;
        this.seq = seq;
        if (seq.getObjectAt(0) instanceof ASN1TaggedObject) {
            this.version = ASN1Integer.getInstance((ASN1TaggedObject)seq.getObjectAt(0), true);
        }
        else {
            n = -1;
            this.version = new ASN1Integer(0L);
        }
        boolean b = false;
        boolean b2 = false;
        if (this.version.hasValue(0)) {
            b = true;
        }
        else if (this.version.hasValue(1)) {
            b2 = true;
        }
        else if (!this.version.hasValue(2)) {
            throw new IllegalArgumentException("version number not recognised");
        }
        this.serialNumber = ASN1Integer.getInstance(seq.getObjectAt(n + 1));
        this.signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(n + 2));
        this.issuer = X500Name.getInstance(seq.getObjectAt(n + 3));
        this.validity = Validity.getInstance(seq.getObjectAt(n + 4));
        this.subject = X500Name.getInstance(seq.getObjectAt(n + 5));
        this.subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(seq.getObjectAt(n + 6));
        int i = seq.size() - (n + 6) - 1;
        if (i != 0 && b) {
            throw new IllegalArgumentException("version 1 certificate contains extra data");
        }
        while (i > 0) {
            final ASN1TaggedObject asn1TaggedObject = (ASN1TaggedObject)seq.getObjectAt(n + 6 + i);
            switch (asn1TaggedObject.getTagNo()) {
                case 1: {
                    this.issuerUniqueId = ASN1BitString.getInstance(asn1TaggedObject, false);
                    break;
                }
                case 2: {
                    this.subjectUniqueId = ASN1BitString.getInstance(asn1TaggedObject, false);
                    break;
                }
                case 3: {
                    if (b2) {
                        throw new IllegalArgumentException("version 2 certificate cannot contain extensions");
                    }
                    this.extensions = Extensions.getInstance(ASN1Sequence.getInstance(asn1TaggedObject, true));
                    break;
                }
                default: {
                    throw new IllegalArgumentException("Unknown tag encountered in structure: " + asn1TaggedObject.getTagNo());
                }
            }
            --i;
        }
    }
    
    public TBSCertificate(final ASN1Integer asn1Integer, final ASN1Integer serialNumber, final AlgorithmIdentifier signature, final X500Name issuer, final Validity validity, final X500Name subject, final SubjectPublicKeyInfo subjectPublicKeyInfo, final ASN1BitString issuerUniqueId, final ASN1BitString subjectUniqueId, final Extensions extensions) {
        if (serialNumber == null) {
            throw new NullPointerException("'serialNumber' cannot be null");
        }
        if (signature == null) {
            throw new NullPointerException("'signature' cannot be null");
        }
        if (issuer == null) {
            throw new NullPointerException("'issuer' cannot be null");
        }
        if (validity == null) {
            throw new NullPointerException("'validity' cannot be null");
        }
        if (subject == null) {
            throw new NullPointerException("'subject' cannot be null");
        }
        if (subjectPublicKeyInfo == null) {
            throw new NullPointerException("'subjectPublicKeyInfo' cannot be null");
        }
        this.version = ((asn1Integer != null) ? asn1Integer : new ASN1Integer(0L));
        this.serialNumber = serialNumber;
        this.signature = signature;
        this.issuer = issuer;
        this.validity = validity;
        this.subject = subject;
        this.subjectPublicKeyInfo = subjectPublicKeyInfo;
        this.issuerUniqueId = issuerUniqueId;
        this.subjectUniqueId = subjectUniqueId;
        this.extensions = extensions;
        this.seq = null;
    }
    
    public int getVersionNumber() {
        return this.version.intValueExact() + 1;
    }
    
    public ASN1Integer getVersion() {
        return this.version;
    }
    
    public ASN1Integer getSerialNumber() {
        return this.serialNumber;
    }
    
    public AlgorithmIdentifier getSignature() {
        return this.signature;
    }
    
    public X500Name getIssuer() {
        return this.issuer;
    }
    
    public Validity getValidity() {
        return this.validity;
    }
    
    public Time getStartDate() {
        return this.validity.getNotBefore();
    }
    
    public Time getEndDate() {
        return this.validity.getNotAfter();
    }
    
    public X500Name getSubject() {
        return this.subject;
    }
    
    public SubjectPublicKeyInfo getSubjectPublicKeyInfo() {
        return this.subjectPublicKeyInfo;
    }
    
    public ASN1BitString getIssuerUniqueId() {
        return this.issuerUniqueId;
    }
    
    public ASN1BitString getSubjectUniqueId() {
        return this.subjectUniqueId;
    }
    
    public Extensions getExtensions() {
        return this.extensions;
    }
    
    @Override
    public ASN1Primitive toASN1Primitive() {
        if (this.seq != null) {
            if (Properties.getPropertyValue("org.bouncycastle.x509.allow_non-der_tbscert") == null) {
                return this.seq;
            }
            if (Properties.isOverrideSet("org.bouncycastle.x509.allow_non-der_tbscert")) {
                return this.seq;
            }
        }
        final ASN1EncodableVector asn1EncodableVector = new ASN1EncodableVector(10);
        if (!this.version.hasValue(0)) {
            asn1EncodableVector.add(new DERTaggedObject(true, 0, this.version));
        }
        asn1EncodableVector.add(this.serialNumber);
        asn1EncodableVector.add(this.signature);
        asn1EncodableVector.add(this.issuer);
        asn1EncodableVector.add(this.validity);
        asn1EncodableVector.add(this.subject);
        asn1EncodableVector.add(this.subjectPublicKeyInfo);
        if (this.issuerUniqueId != null) {
            asn1EncodableVector.add(new DERTaggedObject(false, 1, this.issuerUniqueId));
        }
        if (this.subjectUniqueId != null) {
            asn1EncodableVector.add(new DERTaggedObject(false, 2, this.subjectUniqueId));
        }
        if (this.extensions != null) {
            asn1EncodableVector.add(new DERTaggedObject(true, 3, this.extensions));
        }
        return new DERSequence(asn1EncodableVector);
    }
}
