Exemplo 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.ReadAnyAsnString();
                    tavReader.ThrowIfNotEmpty();
                    yield return(new KeyValuePair <string, string>(oid, value));
                }
            }
        }
Exemplo 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.ReadAnyAsnString();
                    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 IEnumerable <KeyValuePair <string, string> > ReadReverseRdns(X500DistinguishedName name)
        {
            Stack <AsnReader> rdnReaders;

            try
            {
                AsnReader x500NameReader = new AsnReader(name.RawData, AsnEncodingRules.DER);
                AsnReader sequenceReader = x500NameReader.ReadSequence();
                x500NameReader.ThrowIfNotEmpty();
                rdnReaders = new Stack <AsnReader>();

                while (sequenceReader.HasData)
                {
                    rdnReaders.Push(sequenceReader.ReadSetOf());
                }
            }
            catch (AsnContentException e)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
            }

            while (rdnReaders.Count > 0)
            {
                AsnReader rdnReader = rdnReaders.Pop();
                while (rdnReader.HasData)
                {
                    string oid;
                    string value;

                    try
                    {
                        AsnReader tavReader = rdnReader.ReadSequence();
                        oid   = tavReader.ReadObjectIdentifier();
                        value = tavReader.ReadAnyAsnString();
                        tavReader.ThrowIfNotEmpty();
                    }
                    catch (AsnContentException e)
                    {
                        throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
                    }

                    yield return(new KeyValuePair <string, string>(oid, value));
                }
            }
        }
Exemplo n.º 4
0
        private static string X500DistinguishedNameDecode(
            byte[] encodedName,
            bool printOid,
            bool reverse,
            bool quoteIfNeeded,
            string dnSeparator,
            string multiValueSeparator,
            bool addTrailingDelimiter)
        {
            try
            {
                AsnReader x500NameReader         = new AsnReader(encodedName, AsnEncodingRules.DER);
                AsnReader x500NameSequenceReader = x500NameReader.ReadSequence();
                var       rdnReaders             = new List <AsnReader>();

                x500NameReader.ThrowIfNotEmpty();

                while (x500NameSequenceReader.HasData)
                {
                    // To match Windows' behavior, permit multi-value RDN SETs to not
                    // be DER sorted.
                    rdnReaders.Add(x500NameSequenceReader.ReadSetOf(skipSortOrderValidation: true));
                }

                // 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.ReadObjectIdentifier();
                        string    attributeValue = tavReader.ReadAnyAsnString();

                        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());
            }
            catch (AsnContentException e)
            {
                throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
            }
        }