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)); } } }
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)); } } }
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); } }