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

package org.bouncycastle.pkcs;

import org.bouncycastle.util.Exceptions;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Boolean;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.ASN1EncodableVector;
import java.io.OutputStream;
import org.bouncycastle.operator.ContentVerifier;
import org.bouncycastle.asn1.pkcs.CertificationRequestInfo;
import org.bouncycastle.operator.ContentVerifierProvider;
import java.util.ArrayList;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x500.X500Name;
import java.util.Enumeration;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.ASN1Encodable;
import java.io.IOException;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1BitString;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.pkcs.CertificationRequest;
import org.bouncycastle.asn1.pkcs.Attribute;

public class PKCS10CertificationRequest
{
    private static Attribute[] EMPTY_ARRAY;
    private final CertificationRequest certificationRequest;
    private final boolean isAltRequest;
    private final AlgorithmIdentifier altSignature;
    private final SubjectPublicKeyInfo altPublicKey;
    private final ASN1BitString altSignatureValue;
    
    private static CertificationRequest parseBytes(final byte[] array) throws IOException {
        try {
            final CertificationRequest instance = CertificationRequest.getInstance(ASN1Primitive.fromByteArray(array));
            if (instance == null) {
                throw new PKCSIOException("empty data passed to constructor");
            }
            return instance;
        }
        catch (final ClassCastException ex) {
            throw new PKCSIOException("malformed data: " + ex.getMessage(), ex);
        }
        catch (final IllegalArgumentException ex2) {
            throw new PKCSIOException("malformed data: " + ex2.getMessage(), ex2);
        }
    }
    
    private static ASN1Encodable getSingleValue(final Attribute attribute) {
        final ASN1Encodable[] attributeValues = attribute.getAttributeValues();
        if (attributeValues.length != 1) {
            throw new IllegalArgumentException("single value attribute value not size of 1");
        }
        return attributeValues[0];
    }
    
    public PKCS10CertificationRequest(final CertificationRequest certificationRequest) {
        if (certificationRequest == null) {
            throw new NullPointerException("certificationRequest cannot be null");
        }
        this.certificationRequest = certificationRequest;
        final ASN1Set attributes = certificationRequest.getCertificationRequestInfo().getAttributes();
        AlgorithmIdentifier instance = null;
        SubjectPublicKeyInfo instance2 = null;
        ASN1BitString instance3 = null;
        if (attributes != null) {
            final Enumeration objects = attributes.getObjects();
            while (objects.hasMoreElements()) {
                final Attribute instance4 = Attribute.getInstance(objects.nextElement());
                if (Extension.altSignatureAlgorithm.equals(instance4.getAttrType())) {
                    instance = AlgorithmIdentifier.getInstance(getSingleValue(instance4));
                }
                if (Extension.subjectAltPublicKeyInfo.equals(instance4.getAttrType())) {
                    instance2 = SubjectPublicKeyInfo.getInstance(getSingleValue(instance4));
                }
                if (Extension.altSignatureValue.equals(instance4.getAttrType())) {
                    instance3 = ASN1BitString.getInstance(getSingleValue(instance4));
                }
            }
        }
        this.isAltRequest = (instance != null | instance2 != null | instance3 != null);
        if (this.isAltRequest && !(instance != null & instance2 != null & instance3 != null)) {
            throw new IllegalArgumentException("invalid alternate public key details found");
        }
        this.altSignature = instance;
        this.altPublicKey = instance2;
        this.altSignatureValue = instance3;
    }
    
    public PKCS10CertificationRequest(final byte[] array) throws IOException {
        this(parseBytes(array));
    }
    
    public CertificationRequest toASN1Structure() {
        return this.certificationRequest;
    }
    
    public X500Name getSubject() {
        return X500Name.getInstance(this.certificationRequest.getCertificationRequestInfo().getSubject());
    }
    
    public AlgorithmIdentifier getSignatureAlgorithm() {
        return this.certificationRequest.getSignatureAlgorithm();
    }
    
    public byte[] getSignature() {
        return this.certificationRequest.getSignature().getOctets();
    }
    
    public SubjectPublicKeyInfo getSubjectPublicKeyInfo() {
        return this.certificationRequest.getCertificationRequestInfo().getSubjectPublicKeyInfo();
    }
    
    public Attribute[] getAttributes() {
        final ASN1Set attributes = this.certificationRequest.getCertificationRequestInfo().getAttributes();
        if (attributes == null) {
            return PKCS10CertificationRequest.EMPTY_ARRAY;
        }
        final Attribute[] array = new Attribute[attributes.size()];
        for (int i = 0; i != attributes.size(); ++i) {
            array[i] = Attribute.getInstance(attributes.getObjectAt(i));
        }
        return array;
    }
    
    public Attribute[] getAttributes(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        final ASN1Set attributes = this.certificationRequest.getCertificationRequestInfo().getAttributes();
        if (attributes == null) {
            return PKCS10CertificationRequest.EMPTY_ARRAY;
        }
        final ArrayList list = new ArrayList();
        for (int i = 0; i != attributes.size(); ++i) {
            final Attribute instance = Attribute.getInstance(attributes.getObjectAt(i));
            if (instance.getAttrType().equals(asn1ObjectIdentifier)) {
                list.add(instance);
            }
        }
        if (list.size() == 0) {
            return PKCS10CertificationRequest.EMPTY_ARRAY;
        }
        return (Attribute[])list.toArray(new Attribute[list.size()]);
    }
    
    public byte[] getEncoded() throws IOException {
        return this.certificationRequest.getEncoded();
    }
    
    public boolean isSignatureValid(final ContentVerifierProvider contentVerifierProvider) throws PKCSException {
        final CertificationRequestInfo certificationRequestInfo = this.certificationRequest.getCertificationRequestInfo();
        ContentVerifier value;
        try {
            value = contentVerifierProvider.get(this.certificationRequest.getSignatureAlgorithm());
            final OutputStream outputStream = value.getOutputStream();
            outputStream.write(certificationRequestInfo.getEncoded("DER"));
            outputStream.close();
        }
        catch (final Exception ex) {
            throw new PKCSException("unable to process signature: " + ex.getMessage(), ex);
        }
        return value.verify(this.getSignature());
    }
    
    public boolean hasAltPublicKey() {
        return this.isAltRequest;
    }
    
    public boolean isAltSignatureValid(final ContentVerifierProvider contentVerifierProvider) throws PKCSException {
        if (!this.isAltRequest) {
            throw new IllegalStateException("no alternate public key present");
        }
        final CertificationRequestInfo certificationRequestInfo = this.certificationRequest.getCertificationRequestInfo();
        final ASN1Set attributes = certificationRequestInfo.getAttributes();
        final ASN1EncodableVector asn1EncodableVector = new ASN1EncodableVector();
        final Enumeration objects = attributes.getObjects();
        while (objects.hasMoreElements()) {
            final Attribute instance = Attribute.getInstance(objects.nextElement());
            if (Extension.altSignatureValue.equals(instance.getAttrType())) {
                continue;
            }
            asn1EncodableVector.add(instance);
        }
        final CertificationRequestInfo certificationRequestInfo2 = new CertificationRequestInfo(certificationRequestInfo.getSubject(), certificationRequestInfo.getSubjectPublicKeyInfo(), new DERSet(asn1EncodableVector));
        ContentVerifier value;
        try {
            value = contentVerifierProvider.get(this.altSignature);
            final OutputStream outputStream = value.getOutputStream();
            outputStream.write(certificationRequestInfo2.getEncoded("DER"));
            outputStream.close();
        }
        catch (final Exception ex) {
            throw new PKCSException("unable to process signature: " + ex.getMessage(), ex);
        }
        return value.verify(this.altSignatureValue.getOctets());
    }
    
    public Extensions getRequestedExtensions() {
        final Attribute[] attributes = this.getAttributes();
        int i = 0;
        while (i != attributes.length) {
            final Attribute attribute = attributes[i];
            if (PKCSObjectIdentifiers.pkcs_9_at_extensionRequest.equals(attribute.getAttrType())) {
                final ExtensionsGenerator extensionsGenerator = new ExtensionsGenerator();
                final ASN1Set attrValues = attribute.getAttrValues();
                if (attrValues == null || attrValues.size() == 0) {
                    throw new IllegalStateException("pkcs_9_at_extensionRequest present but has no value");
                }
                final ASN1Sequence instance = ASN1Sequence.getInstance(attrValues.getObjectAt(0));
                try {
                    final Enumeration objects = instance.getObjects();
                    while (objects.hasMoreElements()) {
                        final ASN1Sequence instance2 = ASN1Sequence.getInstance(objects.nextElement());
                        final boolean b = instance2.size() == 3 && ASN1Boolean.getInstance(instance2.getObjectAt(1)).isTrue();
                        if (instance2.size() == 2) {
                            extensionsGenerator.addExtension(ASN1ObjectIdentifier.getInstance(instance2.getObjectAt(0)), false, ASN1OctetString.getInstance(instance2.getObjectAt(1)).getOctets());
                        }
                        else {
                            if (instance2.size() != 3) {
                                throw new IllegalStateException("incorrect sequence size of Extension get " + instance2.size() + " expected 2 or three");
                            }
                            extensionsGenerator.addExtension(ASN1ObjectIdentifier.getInstance(instance2.getObjectAt(0)), b, ASN1OctetString.getInstance(instance2.getObjectAt(2)).getOctets());
                        }
                    }
                }
                catch (final IllegalArgumentException ex) {
                    throw Exceptions.illegalStateException("asn1 processing issue: " + ex.getMessage(), ex);
                }
                return extensionsGenerator.generate();
            }
            else {
                ++i;
            }
        }
        return null;
    }
    
    @Override
    public boolean equals(final Object o) {
        return o == this || (o instanceof PKCS10CertificationRequest && this.toASN1Structure().equals(((PKCS10CertificationRequest)o).toASN1Structure()));
    }
    
    @Override
    public int hashCode() {
        return this.toASN1Structure().hashCode();
    }
    
    static {
        PKCS10CertificationRequest.EMPTY_ARRAY = new Attribute[0];
    }
}
