public void AddRange(X509ExtensionCollection collection)
        {
            if (collection == null)
            {
                throw new ArgumentNullException("collection");
            }
            if (readOnly)
            {
                throw new NotSupportedException("Extensions are read only");
            }

            for (int i = 0; i < collection.InnerList.Count; i++)
            {
                InnerList.Add(collection[i]);
            }
        }
        // that's were the real job is!
        private void Parse(byte[] data)
        {
            try
            {
                decoder = new ASN1(data);
                // Certificate
                if (decoder.Tag != 0x30)
                {
                    throw new CryptographicException(encoding_error);
                }
                // Certificate / TBSCertificate
                if (decoder[0].Tag != 0x30)
                {
                    throw new CryptographicException(encoding_error);
                }

                ASN1 tbsCertificate = decoder[0];

                int tbs = 0;
                // Certificate / TBSCertificate / Version
                ASN1 v = decoder[0][tbs];
                version = 1;                            // DEFAULT v1
                if ((v.Tag == 0xA0) && (v.Count > 0))
                {
                    // version (optional) is present only in v2+ certs
                    version += v[0].Value[0];                       // zero based
                    tbs++;
                }

                // Certificate / TBSCertificate / CertificateSerialNumber
                ASN1 sn = decoder[0][tbs++];
                if (sn.Tag != 0x02)
                {
                    throw new CryptographicException(encoding_error);
                }
                serialnumber = sn.Value;
                Array.Reverse(serialnumber, 0, serialnumber.Length);

                // Certificate / TBSCertificate / AlgorithmIdentifier
                tbs++;
                // ASN1 signatureAlgo = tbsCertificate.Element (tbs++, 0x30);

                issuer       = tbsCertificate.Element(tbs++, 0x30);
                m_issuername = X501.ToString(issuer);

                ASN1 validity  = tbsCertificate.Element(tbs++, 0x30);
                ASN1 notBefore = validity[0];
                m_from = ASN1Convert.ToDateTime(notBefore);
                ASN1 notAfter = validity[1];
                m_until = ASN1Convert.ToDateTime(notAfter);

                subject   = tbsCertificate.Element(tbs++, 0x30);
                m_subject = X501.ToString(subject);

                ASN1 subjectPublicKeyInfo = tbsCertificate.Element(tbs++, 0x30);

                ASN1 algorithm = subjectPublicKeyInfo.Element(0, 0x30);
                ASN1 algo      = algorithm.Element(0, 0x06);
                m_keyalgo = ASN1Convert.ToOid(algo);
                // parameters ANY DEFINED BY algorithm OPTIONAL
                // so we dont ask for a specific (Element) type and return DER
                ASN1 parameters = algorithm[1];
                m_keyalgoparams = ((algorithm.Count > 1) ? parameters.GetBytes() : null);

                ASN1 subjectPublicKey = subjectPublicKeyInfo.Element(1, 0x03);
                // we must drop th first byte (which is the number of unused bits
                // in the BITSTRING)
                int n = subjectPublicKey.Length - 1;
                m_rawpublickey = new byte[n];
                Buffer.BlockCopy(subjectPublicKey.Value, 1, m_rawpublickey, 0, n);

                // signature processing
                byte[] bitstring = decoder[2].Value;
                // first byte contains unused bits in first byte
                signature = new byte[bitstring.Length - 1];
                Buffer.BlockCopy(bitstring, 1, signature, 0, signature.Length);

                algorithm       = decoder[1];
                algo            = algorithm.Element(0, 0x06);
                m_signaturealgo = ASN1Convert.ToOid(algo);
                parameters      = algorithm[1];
                if (parameters != null)
                {
                    m_signaturealgoparams = parameters.GetBytes();
                }
                else
                {
                    m_signaturealgoparams = null;
                }

                // Certificate / TBSCertificate / issuerUniqueID
                ASN1 issuerUID = tbsCertificate.Element(tbs, 0x81);
                if (issuerUID != null)
                {
                    tbs++;
                    issuerUniqueID = issuerUID.Value;
                }

                // Certificate / TBSCertificate / subjectUniqueID
                ASN1 subjectUID = tbsCertificate.Element(tbs, 0x82);
                if (subjectUID != null)
                {
                    tbs++;
                    subjectUniqueID = subjectUID.Value;
                }

                // Certificate / TBSCertificate / Extensions
                ASN1 extns = tbsCertificate.Element(tbs, 0xA3);
                if ((extns != null) && (extns.Count == 1))
                {
                    extensions = new X509ExtensionCollection(extns[0]);
                }
                else
                {
                    extensions = new X509ExtensionCollection(null);
                }

                // keep a copy of the original data
                m_encodedcert = (byte[])data.Clone();
            }
            catch (Exception ex)
            {
                throw new CryptographicException(encoding_error, ex);
            }
        }