public static void TagMustBeCorrect_Custom_Indefinite(PublicEncodingRules ruleSet) { byte[] inputData = "A58005000000".HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); AssertExtensions.Throws <ArgumentException>( "expectedTag", () => reader.ReadSetOf(Asn1Tag.Null)); Assert.True(reader.HasData, "HasData after bad universal tag"); Assert.Throws <CryptographicException>(() => reader.ReadSetOf()); Assert.True(reader.HasData, "HasData after default tag"); Assert.Throws <CryptographicException>( () => reader.ReadSetOf(new Asn1Tag(TagClass.Application, 5))); Assert.True(reader.HasData, "HasData after wrong custom class"); Assert.Throws <CryptographicException>( () => reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 7))); Assert.True(reader.HasData, "HasData after wrong custom tag value"); AsnReader seq = reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 5)); Assert.Equal("0500", seq.GetEncodedValue().ByteArrayToHex()); Assert.False(reader.HasData, "HasData after reading value"); }
public static void ReadSetOf_DataSorting( AsnEncodingRules ruleSet, string inputHex, bool expectSuccess, int lastTagValue) { byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, ruleSet); AsnReader setOf; AsnReader laxReader = new AsnReader( inputData, ruleSet, new AsnReaderOptions { SkipSetSortOrderVerification = true }); if (expectSuccess) { setOf = reader.ReadSetOf(); } else { AsnReader alsoReader = new AsnReader(inputData, ruleSet); Assert.Throws <AsnContentException>(() => alsoReader.ReadSetOf()); Assert.Throws <AsnContentException>(() => laxReader.ReadSetOf(false)); setOf = reader.ReadSetOf(skipSortOrderValidation: true); } int lastTag = -1; while (setOf.HasData) { Asn1Tag tag = setOf.PeekTag(); lastTag = tag.TagValue; // Ignore the return, just drain it. setOf.ReadEncodedValue(); } Assert.Equal(lastTagValue, lastTag); setOf = laxReader.ReadSetOf(); lastTag = -1; while (setOf.HasData) { Asn1Tag tag = setOf.PeekTag(); lastTag = tag.TagValue; // Ignore the return, just drain it. setOf.ReadEncodedValue(); } Assert.Equal(lastTagValue, lastTag); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out OriginatorInfoAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader collectionReader; if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { // Decode SEQUENCE OF for CertificateSet { collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0)); var tmpList = new List <System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn>(); System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.CertificateSet = tmpList.ToArray(); } } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { // Decode SEQUENCE OF for RevocationInfoChoices { collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1)); var tmpList = new List <ReadOnlyMemory <byte> >(); ReadOnlyMemory <byte> tmpItem; while (collectionReader.HasData) { tmpItem = collectionReader.GetEncodedValue(); tmpList.Add(tmpItem); } decoded.RevocationInfoChoices = tmpList.ToArray(); } } sequenceReader.ThrowIfNotEmpty(); }
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)); } } }
private SignerInfoCollection GetCounterSigners(AttributeAsn[] unsignedAttrs) { // Since each "attribute" can have multiple "attribute values" there's no real // correlation to a predictive size here. List <SignerInfo> signerInfos = new List <SignerInfo>(); foreach (AttributeAsn attributeAsn in unsignedAttrs) { if (attributeAsn.AttrType.Value == Oids.CounterSigner) { AsnReader reader = new AsnReader(attributeAsn.AttrValues, AsnEncodingRules.BER); AsnReader collReader = reader.ReadSetOf(); if (reader.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } while (collReader.HasData) { SignerInfoAsn parsedData = AsnSerializer.Deserialize <SignerInfoAsn>(collReader.GetEncodedValue(), AsnEncodingRules.BER); SignerInfo signerInfo = new SignerInfo(ref parsedData, _document) { _parentSignerInfo = this }; signerInfos.Add(signerInfo); } } } return(new SignerInfoCollection(signerInfos.ToArray())); }
internal static void Decode(AsnReader reader, out SignedAttributesSet decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; Asn1Tag tag = reader.PeekTag(); AsnReader collectionReader; if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { // Decode SEQUENCE OF for SignedAttributes { collectionReader = reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0)); var tmpList = new List <System.Security.Cryptography.Asn1.AttributeAsn>(); System.Security.Cryptography.Asn1.AttributeAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Asn1.AttributeAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.SignedAttributes = tmpList.ToArray(); } } else { throw new CryptographicException(); } }
public static AttributeAsn[] NormalizeAttributeSet( AttributeAsn[] setItems, Action <byte[]> encodedValueProcessor = null) { byte[] normalizedValue; using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER)) { writer.PushSetOf(); foreach (AttributeAsn item in setItems) { item.Encode(writer); } writer.PopSetOf(); normalizedValue = writer.Encode(); if (encodedValueProcessor != null) { encodedValueProcessor(normalizedValue); } } AsnReader reader = new AsnReader(normalizedValue, AsnEncodingRules.DER); AsnReader setReader = reader.ReadSetOf(); AttributeAsn[] decodedSet = new AttributeAsn[setItems.Length]; int i = 0; while (setReader.HasData) { AttributeAsn.Decode(setReader, out AttributeAsn item); decodedSet[i] = item; i++; } return(decodedSet); }
public static void ReadSetOf_Success( PublicEncodingRules ruleSet, string inputHex, bool expectDataRemaining, int expectedSequenceTagNumber) { byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); AsnReader sequence = reader.ReadSetOf(); if (expectDataRemaining) { Assert.True(reader.HasData, "reader.HasData"); } else { Assert.False(reader.HasData, "reader.HasData"); } if (expectedSequenceTagNumber < 0) { Assert.False(sequence.HasData, "sequence.HasData"); } else { Assert.True(sequence.HasData, "sequence.HasData"); Asn1Tag firstTag = sequence.PeekTag(); Assert.Equal(expectedSequenceTagNumber, firstTag.TagValue); } }
public static IReadOnlyList <string> GetNameInfo(this X509Certificate2 certificate, string nameTypeOid, X509NameSource nameSource) { ThrowHelpers.CheckNullOrEempty(nameof(nameTypeOid), nameTypeOid); byte[] nameBytes = nameSource switch { X509NameSource.Issuer => certificate.IssuerName.RawData, X509NameSource.Subject => certificate.SubjectName.RawData, _ => ThrowHelpers.NotSupport <byte[], X509NameSource>(nameSource) }; List <string> result = new List <string>(); AsnReader nameReader = new AsnReader(nameBytes, AsnEncodingRules.DER); AsnReader mainSequence = nameReader.ReadSequence(); while (mainSequence.HasData) { AsnReader x509Name = mainSequence.ReadSetOf().ReadSequence(); string oid = x509Name.ReadObjectIdentifierAsString(); if (string.Equals(nameTypeOid, oid, StringComparison.Ordinal)) { result.Add(x509Name.GetCharacterString(UniversalTagNumber.PrintableString)); } } return(result); } }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out X501AttributeAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader collectionReader; decoded.AttrId = sequenceReader.ReadObjectIdentifier(); // Decode SEQUENCE OF for AttrValues { collectionReader = sequenceReader.ReadSetOf(); var tmpList = new List <ReadOnlyMemory <byte> >(); ReadOnlyMemory <byte> tmpItem; while (collectionReader.HasData) { tmpItem = collectionReader.GetEncodedValue(); tmpList.Add(tmpItem); } decoded.AttrValues = tmpList.ToArray(); } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out SignerInfoAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader collectionReader; if (!sequenceReader.TryReadInt32(out decoded.Version)) { sequenceReader.ThrowIfNotEmpty(); } System.Security.Cryptography.Pkcs.Asn1.SignerIdentifierAsn.Decode(sequenceReader, out decoded.Sid); System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.DigestAlgorithm); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { decoded.SignedAttributes = sequenceReader.ReadEncodedValue(); } System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.SignatureAlgorithm); if (sequenceReader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpSignatureValue)) { decoded.SignatureValue = tmpSignatureValue; } else { decoded.SignatureValue = sequenceReader.ReadOctetString(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { // Decode SEQUENCE OF for UnsignedAttributes { collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1)); var tmpList = new List <System.Security.Cryptography.Asn1.AttributeAsn>(); System.Security.Cryptography.Asn1.AttributeAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Asn1.AttributeAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.UnsignedAttributes = tmpList.ToArray(); } } sequenceReader.ThrowIfNotEmpty(); }
public static void ReadSetOf_Throws( string description, PublicEncodingRules ruleSet, string inputHex) { byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); Assert.Throws <CryptographicException>(() => reader.ReadSetOf()); }
public static void ReadSetOf_Throws( string description, AsnEncodingRules ruleSet, string inputHex) { _ = description; byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, ruleSet); Assert.Throws <AsnContentException>(() => reader.ReadSetOf()); }
private List <IFilterChoice> DecodeRecursiveFilterSets(AsnReader reader) { AsnReader subReader = reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, reader.PeekTag().TagValue)); List <IFilterChoice> filters = new List <IFilterChoice>(); while (subReader.HasData) { filters.Add(DecodeSearchFilter(subReader)); } return(filters); }
public static void TagMustBeCorrect_Universal_Indefinite(PublicEncodingRules ruleSet) { byte[] inputData = "318005000000".HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); Assert.Throws <ArgumentException>( "expectedTag", () => reader.ReadSetOf(Asn1Tag.Null)); Assert.True(reader.HasData, "HasData after bad universal tag"); Assert.Throws <CryptographicException>( () => reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0))); Assert.True(reader.HasData, "HasData after wrong tag"); AsnReader seq = reader.ReadSetOf(); Assert.Equal("0500", seq.ReadEncodedValue().ByteArrayToHex()); Assert.False(reader.HasData, "HasData after read"); }
public static void ReadSetOf_DataSorting( PublicEncodingRules ruleSet, string inputHex, bool expectSuccess, int lastTagValue) { byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); AsnReader setOf; if (expectSuccess) { setOf = reader.ReadSetOf(); } else { AsnReader alsoReader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); Assert.Throws <CryptographicException>(() => alsoReader.ReadSetOf()); setOf = reader.ReadSetOf(skipSortOrderValidation: true); } int lastTag = -1; while (setOf.HasData) { Asn1Tag tag = setOf.PeekTag(); lastTag = tag.TagValue; // Ignore the return, just drain it. setOf.GetEncodedValue(); } Assert.Equal(lastTagValue, lastTag); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out Asn1PartialAttribute decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new Asn1PartialAttribute(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader collectionReader; if (sequenceReader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpType)) { decoded.Type = tmpType; } else { decoded.Type = sequenceReader.ReadOctetString(); } // Decode SEQUENCE OF for Values { collectionReader = sequenceReader.ReadSetOf(); var tmpList = new List <ReadOnlyMemory <byte> >(); ReadOnlyMemory <byte> tmpItem; while (collectionReader.HasData) { if (collectionReader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmp)) { tmpItem = tmp; } else { tmpItem = collectionReader.ReadOctetString(); } tmpList.Add(tmpItem); } decoded.Values = tmpList.ToArray(); } sequenceReader.ThrowIfNotEmpty(); }
internal static T[] ReadSetOf <T>(this AsnReader reader, Func <AsnReader, T> readElement) { IEnumerable <T> ReadSetOfCore() { var set = reader.ReadSetOf(); while (set.HasData) { yield return(readElement(set)); } set.ThrowIfNotEmpty(); } // ToArray to ensure immediate materialization. If done lazily, it will break integrity validation, as the data wont be consumed. return(ReadSetOfCore().ToArray()); }
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)); } } }
public static void ExpectedTag_IgnoresConstructed( PublicEncodingRules ruleSet, string inputHex, PublicTagClass tagClass, int tagValue) { byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); AsnReader val1 = reader.ReadSetOf(new Asn1Tag((TagClass)tagClass, tagValue, true)); Assert.False(reader.HasData); reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); AsnReader val2 = reader.ReadSetOf(new Asn1Tag((TagClass)tagClass, tagValue, false)); Assert.False(reader.HasData); Assert.Equal(val1.GetEncodedValue().ByteArrayToHex(), val2.GetEncodedValue().ByteArrayToHex()); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out EncryptedDataAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader collectionReader; if (!sequenceReader.TryReadInt32(out decoded.Version)) { sequenceReader.ThrowIfNotEmpty(); } System.Security.Cryptography.Pkcs.Asn1.EncryptedContentInfoAsn.Decode(sequenceReader, out decoded.EncryptedContentInfo); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { // Decode SEQUENCE OF for UnprotectedAttributes { collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1)); var tmpList = new List <System.Security.Cryptography.Asn1.AttributeAsn>(); System.Security.Cryptography.Asn1.AttributeAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Asn1.AttributeAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.UnprotectedAttributes = tmpList.ToArray(); } } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out SafeBagAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader collectionReader; decoded.BagId = sequenceReader.ReadObjectIdentifierAsString(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); decoded.BagValue = explicitReader.GetEncodedValue(); explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.SetOf)) { // Decode SEQUENCE OF for BagAttributes { collectionReader = sequenceReader.ReadSetOf(); var tmpList = new List <System.Security.Cryptography.Asn1.AttributeAsn>(); System.Security.Cryptography.Asn1.AttributeAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Asn1.AttributeAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.BagAttributes = tmpList.ToArray(); } } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out CertificationRequestInfoAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader collectionReader; decoded.Version = sequenceReader.GetInteger(); if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) { throw new CryptographicException(); } decoded.Subject = sequenceReader.GetEncodedValue(); System.Security.Cryptography.Asn1.SubjectPublicKeyInfoAsn.Decode(sequenceReader, out decoded.SubjectPublicKeyInfo); // Decode SEQUENCE OF for Attributes { collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0)); var tmpList = new List <System.Security.Cryptography.Asn1.AttributeAsn>(); System.Security.Cryptography.Asn1.AttributeAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Asn1.AttributeAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.Attributes = tmpList.ToArray(); } sequenceReader.ThrowIfNotEmpty(); }
private static void AssertRdn( AsnReader reader, string atvOid, int offset, Asn1Tag valueTag, byte[] bytes, string label, string stringValue = null) { AsnReader rdn = reader.ReadSetOf(); AsnReader attributeTypeAndValue = rdn.ReadSequence(); Assert.Equal(atvOid, attributeTypeAndValue.ReadObjectIdentifier()); ReadOnlyMemory <byte> value = attributeTypeAndValue.ReadEncodedValue(); ReadOnlySpan <byte> valueSpan = value.Span; Assert.True(Asn1Tag.TryDecode(valueSpan, out Asn1Tag actualTag, out int bytesRead)); Assert.Equal(1, bytesRead); Assert.Equal(valueTag, actualTag); AssertRefSame( ref MemoryMarshal.GetReference(valueSpan), ref bytes[offset], $"{label} is at bytes[{offset}]"); if (stringValue != null) { AsnReader valueReader = new AsnReader(value, AsnEncodingRules.DER); Assert.Equal(stringValue, valueReader.ReadCharacterString((UniversalTagNumber)valueTag.TagValue)); Assert.False(valueReader.HasData, "valueReader.HasData"); } Assert.False(attributeTypeAndValue.HasData, $"attributeTypeAndValue.HasData ({label})"); Assert.False(rdn.HasData, $"rdn.HasData ({label})"); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out SignedDataAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader collectionReader; if (!sequenceReader.TryReadInt32(out decoded.Version)) { sequenceReader.ThrowIfNotEmpty(); } // Decode SEQUENCE OF for DigestAlgorithms { collectionReader = sequenceReader.ReadSetOf(); var tmpList = new List <System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn>(); System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.DigestAlgorithms = tmpList.ToArray(); } System.Security.Cryptography.Pkcs.Asn1.EncapsulatedContentInfoAsn.Decode(sequenceReader, out decoded.EncapContentInfo); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { // Decode SEQUENCE OF for CertificateSet { collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0)); var tmpList = new List <System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn>(); System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.CertificateSet = tmpList.ToArray(); } } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { // Decode SEQUENCE OF for Crls { collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1)); var tmpList = new List <ReadOnlyMemory <byte> >(); ReadOnlyMemory <byte> tmpItem; while (collectionReader.HasData) { tmpItem = collectionReader.ReadEncodedValue(); tmpList.Add(tmpItem); } decoded.Crls = tmpList.ToArray(); } } // Decode SEQUENCE OF for SignerInfos { collectionReader = sequenceReader.ReadSetOf(); var tmpList = new List <System.Security.Cryptography.Pkcs.Asn1.SignerInfoAsn>(); System.Security.Cryptography.Pkcs.Asn1.SignerInfoAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Pkcs.Asn1.SignerInfoAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.SignerInfos = tmpList.ToArray(); } sequenceReader.ThrowIfNotEmpty(); }
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); } }
internal static void Decode(AsnReader reader, out Asn1Filter decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new Asn1Filter(); Asn1Tag tag = reader.PeekTag(); AsnReader explicitReader; AsnReader collectionReader; if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { // Decode SEQUENCE OF for And { collectionReader = reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0)); var tmpList = new List <Asn1Filter>(); Asn1Filter tmpItem; while (collectionReader.HasData) { Asn1Filter.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.And = tmpList.ToArray(); } } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { // Decode SEQUENCE OF for Or { collectionReader = reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1)); var tmpList = new List <Asn1Filter>(); Asn1Filter tmpItem; while (collectionReader.HasData) { Asn1Filter.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.Or = tmpList.ToArray(); } } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { explicitReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); Asn1Filter tmpNot; Asn1Filter.Decode(explicitReader, out tmpNot); decoded.Not = tmpNot; explicitReader.ThrowIfNotEmpty(); } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) { Asn1AttributeValueAssertion tmpEqualityMatch; Asn1AttributeValueAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 3), out tmpEqualityMatch); decoded.EqualityMatch = tmpEqualityMatch; } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 4))) { Asn1SubstringFilter tmpSubstrings; Asn1SubstringFilter.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 4), out tmpSubstrings); decoded.Substrings = tmpSubstrings; } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 5))) { Asn1AttributeValueAssertion tmpGreaterOrEqual; Asn1AttributeValueAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 5), out tmpGreaterOrEqual); decoded.GreaterOrEqual = tmpGreaterOrEqual; } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 6))) { Asn1AttributeValueAssertion tmpLessOrEqual; Asn1AttributeValueAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 6), out tmpLessOrEqual); decoded.LessOrEqual = tmpLessOrEqual; } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 7))) { if (reader.TryGetPrimitiveOctetStringBytes(new Asn1Tag(TagClass.ContextSpecific, 7), out ReadOnlyMemory <byte> tmpPresent)) { decoded.Present = tmpPresent; } else { decoded.Present = reader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 7)); } } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 8))) { Asn1AttributeValueAssertion tmpApproxMatch; Asn1AttributeValueAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 8), out tmpApproxMatch); decoded.ApproxMatch = tmpApproxMatch; } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 9))) { Asn1MatchingRuleAssertion tmpExtensibleMatch; Asn1MatchingRuleAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 9), out tmpExtensibleMatch); decoded.ExtensibleMatch = tmpExtensibleMatch; } else { throw new CryptographicException(); } }
public static void ReadSequenceOf_PreservesOptions(AsnEncodingRules ruleSet) { // [5] (UtcTime) 500102123456Z // UtcTime 120102235959Z // // They're sorted backwards, though. const string PayloadHex = "850D3530303130323132333435365A" + "170D3132303130323233353935395A"; byte[] inputData; // Build the rule-specific form of SEQUENCE { [PRIVATE 9] SEQUENCE { SET-OF { dates }, NULL } } // The outer Set-Of is also invalid, because the NULL should be first. if (ruleSet == AsnEncodingRules.DER) { inputData = ("3024" + "E922" + "A21E" + PayloadHex + "0500").HexToByteArray(); } else { string inputHex = "3080" + "E980" + "A280" + PayloadHex + "0000" + "0500" + "0000" + "0000"; inputData = inputHex.HexToByteArray(); } AsnReaderOptions options = new AsnReaderOptions { SkipSetSortOrderVerification = true, UtcTimeTwoDigitYearMax = 2011, }; AsnReader initial = new AsnReader(inputData, ruleSet, options); AsnReader outer = initial.ReadSequence(); Assert.False(initial.HasData); AsnReader inner = outer.ReadSequence(new Asn1Tag(TagClass.Private, 9)); Assert.False(outer.HasData); Asn1Tag setTag = new Asn1Tag(TagClass.ContextSpecific, 2); if (ruleSet != AsnEncodingRules.BER) { Assert.Throws <AsnContentException>(() => inner.ReadSetOf(false, setTag)); } // This confirms that we've passed SkipSetOrderVerification this far. AsnReader setOf = inner.ReadSetOf(setTag); Assert.True(inner.HasData); Assert.Equal( new DateTimeOffset(1950, 1, 2, 12, 34, 56, TimeSpan.Zero), setOf.ReadUtcTime(new Asn1Tag(TagClass.ContextSpecific, 5))); // This confirms that we've passed UtcTimeTwoDigitYearMax, // the default would call this 2012. Assert.Equal( new DateTimeOffset(1912, 1, 2, 23, 59, 59, TimeSpan.Zero), setOf.ReadUtcTime()); Assert.False(setOf.HasData); inner.ReadNull(); Assert.False(inner.HasData); setOf.ThrowIfNotEmpty(); inner.ThrowIfNotEmpty(); outer.ThrowIfNotEmpty(); initial.ThrowIfNotEmpty(); }