Esempio n. 1
0
        private static IEnumerable <KeyValuePair <string, string> > ReadReverseRdns(X500DistinguishedName name)
        {
            AsnReader x500NameReader = new AsnReader(name.RawData, AsnEncodingRules.DER);
            AsnReader sequenceReader = x500NameReader.ReadSequence();
            var       rdnReaders     = new Stack <AsnReader>();

            x500NameReader.ThrowIfNotEmpty();

            while (sequenceReader.HasData)
            {
                rdnReaders.Push(sequenceReader.ReadSetOf());
            }

            while (rdnReaders.Count > 0)
            {
                AsnReader rdnReader = rdnReaders.Pop();
                while (rdnReader.HasData)
                {
                    AsnReader tavReader = rdnReader.ReadSequence();
                    string    oid       = tavReader.ReadObjectIdentifierAsString();
                    string    value     = tavReader.ReadDirectoryOrIA5String();
                    tavReader.ThrowIfNotEmpty();
                    yield return(new KeyValuePair <string, string>(oid, value));
                }
            }
        }
Esempio n. 2
0
        public void FindByTemplateName(string templateName)
        {
            FindCore(
                cert =>
            {
                X509Extension ext = FindExtension(cert, Oids.EnrollCertTypeExtension);

                if (ext != null)
                {
                    // Try a V1 template structure, just a string:
                    AsnReader reader   = new AsnReader(ext.RawData, AsnEncodingRules.DER);
                    string decodedName = reader.ReadDirectoryOrIA5String();
                    reader.ThrowIfNotEmpty();

                    // If this doesn't match, maybe a V2 template will
                    if (StringComparer.OrdinalIgnoreCase.Equals(templateName, decodedName))
                    {
                        return(true);
                    }
                }

                ext = FindExtension(cert, Oids.CertificateTemplate);

                if (ext != null)
                {
                    CertificateTemplateAsn template = CertificateTemplateAsn.Decode(ext.RawData, AsnEncodingRules.DER);
                    if (StringComparer.Ordinal.Equals(templateName, template.TemplateID))
                    {
                        return(true);
                    }
                }

                return(false);
            });
        }
        private static string X500DistinguishedNameDecode(
            byte[] encodedName,
            bool printOid,
            bool reverse,
            bool quoteIfNeeded,
            string dnSeparator,
            string multiValueSeparator,
            bool addTrailingDelimiter)
        {
            AsnReader x500NameReader         = new AsnReader(encodedName, AsnEncodingRules.DER);
            AsnReader x500NameSequenceReader = x500NameReader.ReadSequence();
            var       rdnReaders             = new List <AsnReader>();

            x500NameReader.ThrowIfNotEmpty();

            while (x500NameSequenceReader.HasData)
            {
                rdnReaders.Add(x500NameSequenceReader.ReadSetOf());
            }

            // We need to allocate a StringBuilder to hold the data as we're building it, and there's the usual
            // arbitrary process of choosing a number that's "big enough" to minimize reallocations without wasting
            // too much space in the average case.
            //
            // So, let's look at an example of what our output might be.
            //
            // GitHub.com's SSL cert has a "pretty long" subject (partially due to the unknown OIDs):
            //   businessCategory=Private Organization
            //   1.3.6.1.4.1.311.60.2.1.3=US
            //   1.3.6.1.4.1.311.60.2.1.2=Delaware
            //   serialNumber=5157550
            //   street=548 4th Street
            //   postalCode=94107
            //   C=US
            //   ST=California
            //   L=San Francisco
            //   O=GitHub, Inc.
            //   CN=github.com
            //
            // Which comes out to 228 characters using OpenSSL's default pretty-print
            // (openssl x509 -in github.cer -text -noout)
            // Throw in some "maybe-I-need-to-quote-this" quotes, and a couple of extra/extra-long O/OU values
            // and round that up to the next programmer number, and you get that 512 should avoid reallocations
            // in all but the most dire of cases.
            StringBuilder decodedName  = new StringBuilder(512);
            int           entryCount   = rdnReaders.Count;
            bool          printSpacing = false;

            for (int i = 0; i < entryCount; i++)
            {
                int loc = reverse ? entryCount - i - 1 : i;

                // RelativeDistinguishedName ::=
                //   SET SIZE (1..MAX) OF AttributeTypeAndValue
                //
                // AttributeTypeAndValue::= SEQUENCE {
                //   type AttributeType,
                //   value    AttributeValue }
                //
                // AttributeType::= OBJECT IDENTIFIER
                //
                // AttributeValue ::= ANY-- DEFINED BY AttributeType

                if (printSpacing)
                {
                    decodedName.Append(dnSeparator);
                }
                else
                {
                    printSpacing = true;
                }

                AsnReader rdnReader = rdnReaders[loc];
                bool      hadValue  = false;

                while (rdnReader.HasData)
                {
                    AsnReader tavReader      = rdnReader.ReadSequence();
                    string    oid            = tavReader.ReadObjectIdentifierAsString();
                    string    attributeValue = tavReader.ReadDirectoryOrIA5String();

                    tavReader.ThrowIfNotEmpty();

                    if (hadValue)
                    {
                        decodedName.Append(multiValueSeparator);
                    }
                    else
                    {
                        hadValue = true;
                    }

                    if (printOid)
                    {
                        AppendOid(decodedName, oid);
                    }


                    bool quote = quoteIfNeeded && NeedsQuoting(attributeValue);

                    if (quote)
                    {
                        decodedName.Append('"');

                        // If the RDN itself had a quote within it, that quote needs to be escaped
                        // with another quote.
                        attributeValue = attributeValue.Replace("\"", "\"\"");
                    }

                    decodedName.Append(attributeValue);

                    if (quote)
                    {
                        decodedName.Append('"');
                    }
                }
            }

            if (addTrailingDelimiter && decodedName.Length > 0)
            {
                decodedName.Append(dnSeparator);
            }

            return(decodedName.ToString());
        }