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

package org.bouncycastle.asn1.eac;

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

public class CVCertificateRequest extends ASN1Object
{
    private final ASN1TaggedObject original;
    private CertificateBody certificateBody;
    private byte[] innerSignature;
    private byte[] outerSignature;
    private static final int bodyValid = 1;
    private static final int signValid = 2;
    
    private CVCertificateRequest(final ASN1TaggedObject original) throws IOException {
        this.innerSignature = null;
        this.outerSignature = null;
        this.original = original;
        if (original.hasTag(64, 7)) {
            final ASN1Sequence instance = ASN1Sequence.getInstance(original.getBaseUniversal(false, 16));
            this.initCertBody(ASN1TaggedObject.getInstance(instance.getObjectAt(0), 64));
            this.outerSignature = ASN1OctetString.getInstance(ASN1TaggedObject.getInstance(instance.getObjectAt(instance.size() - 1)).getBaseUniversal(false, 4)).getOctets();
        }
        else {
            this.initCertBody(original);
        }
    }
    
    private void initCertBody(final ASN1TaggedObject asn1TaggedObject) throws IOException {
        if (!asn1TaggedObject.hasTag(64, 33)) {
            throw new IOException("not a CARDHOLDER_CERTIFICATE in request:" + asn1TaggedObject.getTagNo());
        }
        int n = 0;
        final Enumeration objects = ASN1Sequence.getInstance(asn1TaggedObject.getBaseUniversal(false, 16)).getObjects();
        while (objects.hasMoreElements()) {
            final ASN1TaggedObject instance = ASN1TaggedObject.getInstance(objects.nextElement(), 64);
            switch (instance.getTagNo()) {
                case 78: {
                    this.certificateBody = CertificateBody.getInstance(instance);
                    n |= 0x1;
                    continue;
                }
                case 55: {
                    this.innerSignature = ASN1OctetString.getInstance(instance.getBaseUniversal(false, 4)).getOctets();
                    n |= 0x2;
                    continue;
                }
                default: {
                    throw new IOException("Invalid tag, not an CV Certificate Request element:" + instance.getTagNo());
                }
            }
        }
        if ((n & 0x3) == 0x0) {
            throw new IOException("Invalid CARDHOLDER_CERTIFICATE in request:" + asn1TaggedObject.getTagNo());
        }
    }
    
    public static CVCertificateRequest getInstance(final Object o) {
        if (o instanceof CVCertificateRequest) {
            return (CVCertificateRequest)o;
        }
        if (o != null) {
            try {
                return new CVCertificateRequest(ASN1TaggedObject.getInstance(o, 64));
            }
            catch (final IOException ex) {
                throw new ASN1ParsingException("unable to parse data: " + ex.getMessage(), ex);
            }
        }
        return null;
    }
    
    public CertificateBody getCertificateBody() {
        return this.certificateBody;
    }
    
    public PublicKeyDataObject getPublicKey() {
        return this.certificateBody.getPublicKey();
    }
    
    public byte[] getInnerSignature() {
        return Arrays.clone(this.innerSignature);
    }
    
    public byte[] getOuterSignature() {
        return Arrays.clone(this.outerSignature);
    }
    
    public boolean hasOuterSignature() {
        return this.outerSignature != null;
    }
    
    @Override
    public ASN1Primitive toASN1Primitive() {
        if (this.original != null) {
            return this.original;
        }
        return EACTagged.create(33, new DERSequence(this.certificateBody, EACTagged.create(55, this.innerSignature)));
    }
}
