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

package org.bouncycastle.asn1.eac;

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.ASN1ParsingException;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1InputStream;
import java.util.Enumeration;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Sequence;
import java.io.IOException;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.ASN1Object;

public class CVCertificate extends ASN1Object
{
    private CertificateBody certificateBody;
    private byte[] signature;
    private int valid;
    private static int bodyValid;
    private static int signValid;
    
    private void setPrivateData(final ASN1TaggedObject asn1TaggedObject) throws IOException {
        this.valid = 0;
        if (!asn1TaggedObject.hasTag(64, 33)) {
            throw new IOException("not a CARDHOLDER_CERTIFICATE :" + asn1TaggedObject.getTagNo());
        }
        final Enumeration objects = ASN1Sequence.getInstance(asn1TaggedObject.getBaseUniversal(false, 16)).getObjects();
        while (objects.hasMoreElements()) {
            final Object nextElement = objects.nextElement();
            if (!(nextElement instanceof ASN1TaggedObject)) {
                throw new IOException("Invalid Object, not an Iso7816CertificateStructure");
            }
            final ASN1TaggedObject instance = ASN1TaggedObject.getInstance(nextElement, 64);
            switch (instance.getTagNo()) {
                case 78: {
                    this.certificateBody = CertificateBody.getInstance(instance);
                    this.valid |= CVCertificate.bodyValid;
                    continue;
                }
                case 55: {
                    this.signature = ASN1OctetString.getInstance(instance.getBaseUniversal(false, 4)).getOctets();
                    this.valid |= CVCertificate.signValid;
                    continue;
                }
                default: {
                    throw new IOException("Invalid tag, not an Iso7816CertificateStructure :" + instance.getTagNo());
                }
            }
        }
        if (this.valid != (CVCertificate.signValid | CVCertificate.bodyValid)) {
            throw new IOException("invalid CARDHOLDER_CERTIFICATE :" + asn1TaggedObject.getTagNo());
        }
    }
    
    public CVCertificate(final ASN1InputStream asn1InputStream) throws IOException {
        this.initFrom(asn1InputStream);
    }
    
    private void initFrom(final ASN1InputStream asn1InputStream) throws IOException {
        ASN1Primitive object;
        while ((object = asn1InputStream.readObject()) != null) {
            if (!(object instanceof ASN1TaggedObject)) {
                throw new IOException("Invalid Input Stream for creating an Iso7816CertificateStructure");
            }
            this.setPrivateData((ASN1TaggedObject)object);
        }
    }
    
    private CVCertificate(final ASN1TaggedObject privateData) throws IOException {
        this.setPrivateData(privateData);
    }
    
    public CVCertificate(final CertificateBody certificateBody, final byte[] array) throws IOException {
        this.certificateBody = certificateBody;
        this.signature = Arrays.clone(array);
        this.valid |= CVCertificate.bodyValid;
        this.valid |= CVCertificate.signValid;
    }
    
    public static CVCertificate getInstance(final Object o) {
        if (o instanceof CVCertificate) {
            return (CVCertificate)o;
        }
        if (o != null) {
            try {
                return new CVCertificate(ASN1TaggedObject.getInstance(o, 64));
            }
            catch (final IOException ex) {
                throw new ASN1ParsingException("unable to parse data: " + ex.getMessage(), ex);
            }
        }
        return null;
    }
    
    public byte[] getSignature() {
        return Arrays.clone(this.signature);
    }
    
    public CertificateBody getBody() {
        return this.certificateBody;
    }
    
    @Override
    public ASN1Primitive toASN1Primitive() {
        return EACTagged.create(33, new DERSequence(this.certificateBody, EACTagged.create(55, this.signature)));
    }
    
    public ASN1ObjectIdentifier getHolderAuthorization() throws IOException {
        return this.certificateBody.getCertificateHolderAuthorization().getOid();
    }
    
    public PackedDate getEffectiveDate() throws IOException {
        return this.certificateBody.getCertificateEffectiveDate();
    }
    
    public int getCertificateType() {
        return this.certificateBody.getCertificateType();
    }
    
    public PackedDate getExpirationDate() throws IOException {
        return this.certificateBody.getCertificateExpirationDate();
    }
    
    public int getRole() throws IOException {
        return this.certificateBody.getCertificateHolderAuthorization().getAccessRights();
    }
    
    public CertificationAuthorityReference getAuthorityReference() throws IOException {
        return this.certificateBody.getCertificationAuthorityReference();
    }
    
    public CertificateHolderReference getHolderReference() throws IOException {
        return this.certificateBody.getCertificateHolderReference();
    }
    
    public int getHolderAuthorizationRole() throws IOException {
        return this.certificateBody.getCertificateHolderAuthorization().getAccessRights() & 0xC0;
    }
    
    public Flags getHolderAuthorizationRights() throws IOException {
        return new Flags(this.certificateBody.getCertificateHolderAuthorization().getAccessRights() & 0x1F);
    }
    
    static {
        CVCertificate.bodyValid = 1;
        CVCertificate.signValid = 2;
    }
}
