CertificationRequestInfo
using Org.BouncyCastle.Asn1.X509;
using System;
namespace Org.BouncyCastle.Asn1.Pkcs
{
    public class CertificationRequestInfo : Asn1Encodable
    {
        private readonly DerInteger m_version;
        private readonly X509Name m_subject;
        private readonly SubjectPublicKeyInfo m_subjectPKInfo;
        private readonly Asn1Set m_attributes;
        public DerInteger Version => m_version;
        public X509Name Subject => m_subject;
        public SubjectPublicKeyInfo SubjectPublicKeyInfo => m_subjectPKInfo;
        public Asn1Set Attributes => m_attributes;
        public static CertificationRequestInfo GetInstance(object obj)
        {
            if (obj == null)
                return null;
            CertificationRequestInfo certificationRequestInfo = obj as CertificationRequestInfo;
            if (certificationRequestInfo != null)
                return certificationRequestInfo;
            return new CertificationRequestInfo(Asn1Sequence.GetInstance(obj));
        }
        public static CertificationRequestInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
        {
            return new CertificationRequestInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
        }
        public static CertificationRequestInfo GetTagged(Asn1TaggedObject taggedObject, bool declaredExplicit)
        {
            return new CertificationRequestInfo(Asn1Sequence.GetTagged(taggedObject, declaredExplicit));
        }
        public CertificationRequestInfo(X509Name subject, SubjectPublicKeyInfo pkInfo, Asn1Set attributes)
        {
            m_version = DerInteger.Zero;
            if (subject == null)
                throw new ArgumentNullException("subject");
            m_subject = subject;
            if (pkInfo == null)
                throw new ArgumentNullException("pkInfo");
            m_subjectPKInfo = pkInfo;
            m_attributes = ValidateAttributes(attributes);
        }
        private CertificationRequestInfo(Asn1Sequence seq)
        {
            int count = seq.Count;
            int sequencePosition = 0;
            if (count < 3 || count > 4)
                throw new ArgumentException("Bad sequence size: " + count.ToString(), "seq");
            m_version = DerInteger.GetInstance(seq[sequencePosition++]);
            m_subject = X509Name.GetInstance(seq[sequencePosition++]);
            m_subjectPKInfo = SubjectPublicKeyInfo.GetInstance(seq[sequencePosition++]);
            m_attributes = Asn1Utilities.ReadOptionalContextTagged(seq, ref sequencePosition, 0, false, Asn1Set.GetTagged);
            if (sequencePosition != count)
                throw new ArgumentException("Unexpected elements in sequence", "seq");
            ValidateAttributes(m_attributes);
        }
        public override Asn1Object ToAsn1Object()
        {
            Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector(4);
            asn1EncodableVector.Add(m_version, m_subject, m_subjectPKInfo);
            asn1EncodableVector.AddOptionalTagged(false, 0, m_attributes);
            return new DerSequence(asn1EncodableVector);
        }
        private static Asn1Set ValidateAttributes(Asn1Set attributes)
        {
            if (attributes != null) {
                foreach (Asn1Encodable attribute in attributes) {
                    AttributePkcs instance = AttributePkcs.GetInstance(attribute);
                    if (PkcsObjectIdentifiers.Pkcs9AtChallengePassword.Equals(instance.AttrType) && instance.AttrValues.Count != 1)
                        throw new ArgumentException("challengePassword attribute must have one value");
                }
                return attributes;
            }
            return attributes;
        }
    }
}