internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded) where T : KrbSubjectPublicKeyInfo, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); KrbAlgorithmIdentifier.Decode <KrbAlgorithmIdentifier>(sequenceReader, out decoded.Algorithm); if (sequenceReader.TryReadPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpSubjectPublicKey)) { decoded.SubjectPublicKey = tmpSubjectPublicKey; } else { decoded.SubjectPublicKey = sequenceReader.ReadBitString(out _); } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out CertificateAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); System.Security.Cryptography.X509Certificates.Asn1.TbsCertificateAsn.Decode(sequenceReader, out decoded.TbsCertificate); System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.SignatureAlgorithm); if (sequenceReader.TryReadPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpSignatureValue)) { decoded.SignatureValue = tmpSignatureValue; } else { decoded.SignatureValue = sequenceReader.ReadBitString(out _); } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded) where T : KrbDiffieHellmanValidationParameters, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); if (sequenceReader.TryReadPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpSeed)) { decoded.Seed = tmpSeed; } else { decoded.Seed = sequenceReader.ReadBitString(out _); } decoded.PGenOutput = sequenceReader.ReadInteger(); sequenceReader.ThrowIfNotEmpty(); }
public static void TryCopyBitStringBytes_ExtremelyNested() { byte[] dataBytes = new byte[4 * 16384]; // This will build 2^14 nested indefinite length values. // In the end, none of them contain any content. // // For what it's worth, the initial algorithm succeeded at 1017, and StackOverflowed with 1018. int end = dataBytes.Length / 2; // UNIVERSAL BIT STRING [Constructed] const byte Tag = 0x20 | (byte)UniversalTagNumber.BitString; for (int i = 0; i < end; i += 2) { dataBytes[i] = Tag; // Indefinite length dataBytes[i + 1] = 0x80; } AsnReader reader = new AsnReader(dataBytes, AsnEncodingRules.BER); int bytesWritten; int unusedBitCount; Assert.True( reader.TryReadBitString(Span <byte> .Empty, out unusedBitCount, out bytesWritten)); Assert.Equal(0, bytesWritten); Assert.Equal(0, unusedBitCount); reader = new AsnReader(dataBytes, AsnEncodingRules.BER); byte[] output = reader.ReadBitString(out unusedBitCount); Assert.Equal(0, unusedBitCount); // It's Same (ReferenceEqual) on .NET Core, but just Equal on .NET Framework Assert.Equal(Array.Empty <byte>(), output); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out OriginatorPublicKeyAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.Algorithm); if (sequenceReader.TryReadPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpPublicKey)) { decoded.PublicKey = tmpPublicKey; } else { decoded.PublicKey = sequenceReader.ReadBitString(out _); } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out TbsCertificateAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader defaultReader; AsnReader collectionReader; if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); if (!explicitReader.TryReadInt32(out decoded.Version)) { explicitReader.ThrowIfNotEmpty(); } explicitReader.ThrowIfNotEmpty(); } else { defaultReader = new AsnReader(s_defaultVersion, AsnEncodingRules.DER); if (!defaultReader.TryReadInt32(out decoded.Version)) { defaultReader.ThrowIfNotEmpty(); } } decoded.SerialNumber = sequenceReader.ReadIntegerBytes(); System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.SignatureAlgorithm); if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) { throw new CryptographicException(); } decoded.Issuer = sequenceReader.ReadEncodedValue(); System.Security.Cryptography.X509Certificates.Asn1.ValidityAsn.Decode(sequenceReader, out decoded.Validity); if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) { throw new CryptographicException(); } decoded.Subject = sequenceReader.ReadEncodedValue(); System.Security.Cryptography.Asn1.SubjectPublicKeyInfoAsn.Decode(sequenceReader, out decoded.SubjectPublicKeyInfo); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { if (sequenceReader.TryReadPrimitiveBitStringValue(new Asn1Tag(TagClass.ContextSpecific, 1), out _, out ReadOnlyMemory <byte> tmpIssuerUniqueId)) { decoded.IssuerUniqueId = tmpIssuerUniqueId; } else { decoded.IssuerUniqueId = sequenceReader.ReadBitString(new Asn1Tag(TagClass.ContextSpecific, 1), out _); } } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { if (sequenceReader.TryReadPrimitiveBitStringValue(new Asn1Tag(TagClass.ContextSpecific, 2), out _, out ReadOnlyMemory <byte> tmpSubjectUniqueId)) { decoded.SubjectUniqueId = tmpSubjectUniqueId; } else { decoded.SubjectUniqueId = sequenceReader.ReadBitString(new Asn1Tag(TagClass.ContextSpecific, 2), out _); } } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); // Decode SEQUENCE OF for Extensions { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <System.Security.Cryptography.Asn1.X509ExtensionAsn>(); System.Security.Cryptography.Asn1.X509ExtensionAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Asn1.X509ExtensionAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.Extensions = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); } sequenceReader.ThrowIfNotEmpty(); }
public static void ExpectedTag_IgnoresConstructed( AsnEncodingRules ruleSet, string inputHex, TagClass tagClass, int tagValue) { byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, ruleSet); Asn1Tag correctConstructed = new Asn1Tag(tagClass, tagValue, true); Asn1Tag correctPrimitive = new Asn1Tag(tagClass, tagValue, false); Assert.True( reader.TryReadPrimitiveBitString( out int ubc1, out ReadOnlyMemory <byte> val1, correctConstructed)); Assert.False(reader.HasData); reader = new AsnReader(inputData, ruleSet); Assert.True( reader.TryReadPrimitiveBitString( out int ubc2, out ReadOnlyMemory <byte> val2, correctPrimitive)); Assert.False(reader.HasData); string val1Hex = val1.ByteArrayToHex(); Assert.Equal(val1Hex, val2.ByteArrayToHex()); Assert.Equal(ubc1, ubc2); reader = new AsnReader(inputData, ruleSet); byte[] output1 = new byte[inputData.Length]; Assert.True(reader.TryReadBitString(output1.AsSpan(1), out ubc1, out int written, correctConstructed)); Assert.Equal(ubc2, ubc1); Assert.Equal(val1Hex, output1.AsSpan(1, written).ByteArrayToHex()); Assert.False(reader.HasData); reader = new AsnReader(inputData, ruleSet); Assert.True(reader.TryReadBitString(output1.AsSpan(2), out ubc1, out written, correctPrimitive)); Assert.Equal(ubc2, ubc1); Assert.Equal(val1Hex, output1.AsSpan(2, written).ByteArrayToHex()); Assert.False(reader.HasData); reader = new AsnReader(inputData, ruleSet); byte[] output2 = reader.ReadBitString(out ubc1, correctConstructed); Assert.Equal(ubc2, ubc1); Assert.Equal(val1Hex, output2.ByteArrayToHex()); Assert.False(reader.HasData); reader = new AsnReader(inputData, ruleSet); byte[] output3 = reader.ReadBitString(out ubc1, correctPrimitive); Assert.Equal(ubc2, ubc1); Assert.Equal(val1Hex, output3.ByteArrayToHex()); Assert.False(reader.HasData); }
public static void TagMustBeCorrect_Custom(AsnEncodingRules ruleSet) { byte[] inputData = { 0x87, 2, 0, 0x80 }; byte[] output = new byte[inputData.Length]; AsnReader reader = new AsnReader(inputData, ruleSet); Asn1Tag wrongTag1 = new Asn1Tag(TagClass.Application, 0); Asn1Tag wrongTag2 = new Asn1Tag(TagClass.ContextSpecific, 1); Asn1Tag correctTag = new Asn1Tag(TagClass.ContextSpecific, 7); AssertExtensions.Throws <ArgumentException>( "expectedTag", () => reader.TryReadPrimitiveBitString(out _, out _, Asn1Tag.Null)); AssertExtensions.Throws <ArgumentException>( "expectedTag", () => reader.TryReadBitString(output, out _, out _, Asn1Tag.Null)); AssertExtensions.Throws <ArgumentException>( "expectedTag", () => reader.ReadBitString(out _, Asn1Tag.Null)); Assert.True(reader.HasData, "HasData after bad universal tag"); Assert.Throws <AsnContentException>(() => reader.TryReadPrimitiveBitString(out _, out _)); Assert.Throws <AsnContentException>(() => reader.TryReadBitString(output, out _, out _)); Assert.Throws <AsnContentException>(() => reader.ReadBitString(out _)); Assert.True(reader.HasData, "HasData after default tag"); Assert.Throws <AsnContentException>(() => reader.TryReadPrimitiveBitString(out _, out _, wrongTag1)); Assert.Throws <AsnContentException>(() => reader.TryReadBitString(output, out _, out _, wrongTag1)); Assert.Throws <AsnContentException>(() => reader.ReadBitString(out _, wrongTag1)); Assert.True(reader.HasData, "HasData after wrong custom class"); Assert.Throws <AsnContentException>(() => reader.TryReadPrimitiveBitString(out _, out _, wrongTag2)); Assert.Throws <AsnContentException>(() => reader.TryReadBitString(output, out _, out _, wrongTag2)); Assert.Throws <AsnContentException>(() => reader.ReadBitString(out _, wrongTag2)); Assert.True(reader.HasData, "HasData after wrong custom tag value"); Assert.True( reader.TryReadPrimitiveBitString( out int unusedBitCount, out ReadOnlyMemory <byte> contents, correctTag)); Assert.Equal("80", contents.ByteArrayToHex()); Assert.Equal(0, unusedBitCount); Assert.False(reader.HasData, "HasData after reading value"); reader = new AsnReader(inputData, ruleSet); Assert.True( reader.TryReadBitString( output.AsSpan(1), out unusedBitCount, out int written, correctTag)); Assert.Equal("80", output.AsSpan(1, written).ByteArrayToHex()); Assert.Equal(0, unusedBitCount); Assert.False(reader.HasData, "HasData after reading value"); reader = new AsnReader(inputData, ruleSet); byte[] output2 = reader.ReadBitString(out unusedBitCount, correctTag); Assert.Equal("80", output2.ByteArrayToHex()); Assert.Equal(0, unusedBitCount); Assert.False(reader.HasData, "HasData after reading value"); }
internal CertificateDataAsn(byte[] rawData) { AsnReader reader = new AsnReader(rawData, AsnEncodingRules.DER).ReadSequence(); AsnReader tbsCertificate = reader.ReadSequence(); if (tbsCertificate.PeekTag() == explicit0) { AsnReader version = tbsCertificate.ReadSequence(explicit0); version.TryReadInt32(out Version); } else if (tbsCertificate.PeekTag() != Asn1Tag.Integer) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } else { Version = 0; } if (Version < 0 || Version > 2) { throw new CryptographicException(); } SerialNumber = tbsCertificate.GetIntegerBytes().ToArray(); AsnReader tbsSignature = tbsCertificate.ReadSequence(); TbsSignature.AlgorithmId = tbsSignature.ReadObjectIdentifierAsString(); TbsSignature.Parameters = tbsSignature.HasData ? tbsSignature.GetEncodedValue().ToArray() : Array.Empty <byte>(); if (tbsSignature.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } Issuer = new X500DistinguishedName(tbsCertificate.GetEncodedValue().ToArray()); AsnReader validity = tbsCertificate.ReadSequence(); NotBefore = validity.GetUtcTime().UtcDateTime; // FIXME NotAfter = validity.GetUtcTime().UtcDateTime; if (validity.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } Subject = new X500DistinguishedName(tbsCertificate.GetEncodedValue().ToArray()); SubjectPublicKeyInfo = tbsCertificate.GetEncodedValue().ToArray(); AsnReader subjectPublicKeyInfo = new AsnReader(SubjectPublicKeyInfo, AsnEncodingRules.DER).ReadSequence(); AsnReader subjectKeyAlgorithm = subjectPublicKeyInfo.ReadSequence(); PublicKeyAlgorithm.AlgorithmId = subjectKeyAlgorithm.ReadObjectIdentifierAsString(); PublicKeyAlgorithm.Parameters = subjectKeyAlgorithm.HasData ? subjectKeyAlgorithm.GetEncodedValue().ToArray() : Array.Empty <byte>(); if (subjectKeyAlgorithm.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } PublicKey = subjectPublicKeyInfo.ReadBitString(); if (subjectPublicKeyInfo.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } if (Version > 0 && tbsCertificate.HasData && tbsCertificate.PeekTag() == explicit1) { IssuerUniqueId = tbsCertificate.ReadBitString(); } else { IssuerUniqueId = null; } if (Version > 0 && tbsCertificate.HasData && tbsCertificate.PeekTag() == explicit2) { SubjectUniqueId = tbsCertificate.ReadBitString(); } else { SubjectUniqueId = null; } Extensions = new List <X509Extension>(); if (Version > 1 && tbsCertificate.HasData && tbsCertificate.PeekTag() == explicit3) { AsnReader extensions = tbsCertificate.ReadSequence(explicit3); extensions = extensions.ReadSequence(); while (extensions.HasData) { AsnReader extensionReader = extensions.ReadSequence(); string oid = extensionReader.ReadObjectIdentifierAsString(); bool critical = false; if (extensionReader.PeekTag() == Asn1Tag.Boolean) { critical = extensionReader.ReadBoolean(); } byte[] extensionData = extensionReader.ReadOctetString(); Extensions.Add(new X509Extension(oid, extensionData, critical)); if (extensionReader.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } } } if (tbsCertificate.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } AsnReader signatureAlgorithm = reader.ReadSequence(); SignatureAlgorithm.AlgorithmId = signatureAlgorithm.ReadObjectIdentifierAsString(); SignatureAlgorithm.Parameters = signatureAlgorithm.HasData ? signatureAlgorithm.GetEncodedValue().ToArray() : Array.Empty <byte>(); if (signatureAlgorithm.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } SignatureValue = reader.ReadBitString(); if (reader.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } RawData = rawData; }