public static void TagMustBeCorrect_Universal(PublicEncodingRules ruleSet) { byte[] inputData = { 3, 2, 1, 0x7E }; AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); AssertExtensions.Throws <ArgumentException>( "expectedTag", () => reader.TryReadPrimitiveBitStringValue(Asn1Tag.Null, out _, out _)); Assert.True(reader.HasData, "HasData after bad universal tag"); Assert.Throws <CryptographicException>( () => reader.TryReadPrimitiveBitStringValue(new Asn1Tag(TagClass.ContextSpecific, 0), out _, out _)); Assert.True(reader.HasData, "HasData after wrong tag"); Assert.True(reader.TryReadPrimitiveBitStringValue(out int unusedBitCount, out ReadOnlyMemory <byte> contents)); Assert.Equal("7E", contents.ByteArrayToHex()); Assert.Equal(1, unusedBitCount); Assert.False(reader.HasData, "HasData after read"); }
public static void EmptyData_Allows0UnusedBits( PublicEncodingRules ruleSet, PublicTagClass tagClass, int tagValue, string expectedHex) { using (AsnWriter writer = new AsnWriter((AsnEncodingRules)ruleSet)) { if (tagClass == PublicTagClass.Universal) { Debug.Assert(tagValue == (int)UniversalTagNumber.BitString); writer.WriteBitString(ReadOnlySpan <byte> .Empty, 0); } else { writer.WriteBitString(new Asn1Tag((TagClass)tagClass, tagValue), ReadOnlySpan <byte> .Empty, 0); } Verify(writer, expectedHex); } }
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.ReadEncodedValue().ByteArrayToHex(), val2.ReadEncodedValue().ByteArrayToHex()); }
public static void ExpectedTag_IgnoresConstructed( PublicEncodingRules ruleSet, string inputHex, PublicTagClass tagClass, int tagValue) { byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); DateTimeOffset val1 = reader.ReadGeneralizedTime(new Asn1Tag((TagClass)tagClass, tagValue, true)); Assert.False(reader.HasData); reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); DateTimeOffset val2 = reader.ReadGeneralizedTime(new Asn1Tag((TagClass)tagClass, tagValue, false)); Assert.False(reader.HasData); Assert.Equal(val1, val2); }
public void VerifyWriteOctetString_PrimitiveOrConstructed( PublicEncodingRules ruleSet, int payloadLength, bool expectConstructed) { byte[] data = new byte[payloadLength]; Asn1Tag[] tagsToTry = { new Asn1Tag(UniversalTagNumber.OctetString), new Asn1Tag(UniversalTagNumber.OctetString, isConstructed: true), new Asn1Tag(TagClass.Private, 87), new Asn1Tag(TagClass.ContextSpecific, 13,isConstructed: true), }; byte[] answerBuf = new byte[payloadLength + 100]; foreach (Asn1Tag toTry in tagsToTry) { using (AsnWriter writer = new AsnWriter((AsnEncodingRules)ruleSet)) { writer.WriteOctetString(toTry, data); Assert.True(writer.TryEncode(answerBuf, out _)); } Assert.True(Asn1Tag.TryDecode(answerBuf, out Asn1Tag writtenTag, out _)); if (expectConstructed) { Assert.True(writtenTag.IsConstructed, $"writtenTag.IsConstructed ({toTry})"); } else { Assert.False(writtenTag.IsConstructed, $"writtenTag.IsConstructed ({toTry})"); } Assert.Equal(toTry.TagClass, writtenTag.TagClass); Assert.Equal(toTry.TagValue, writtenTag.TagValue); } }
public static void TagMustBeCorrect_Universal(PublicEncodingRules ruleSet) { byte[] inputData = "170D3530303130323132333435365A".HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); Assert.Throws <ArgumentException>( "expectedTag", () => reader.ReadUtcTime(Asn1Tag.Null)); Assert.True(reader.HasData, "HasData after bad universal tag"); Assert.Throws <CryptographicException>( () => reader.ReadUtcTime(new Asn1Tag(TagClass.ContextSpecific, 0))); Assert.True(reader.HasData, "HasData after wrong tag"); Assert.Equal( new DateTimeOffset(1950, 1, 2, 12, 34, 56, TimeSpan.Zero), reader.ReadUtcTime()); Assert.False(reader.HasData, "HasData after read"); }
public static void ReadBoolean_Success( PublicEncodingRules ruleSet, bool expectedValue, int expectedBytesRead, string inputHex) { byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); Asn1Tag tag = reader.PeekTag(); bool value; if (tag.TagClass == TagClass.Universal) { value = reader.ReadBoolean(); } else { value = reader.ReadBoolean(tag); } if (inputData.Length == expectedBytesRead) { Assert.False(reader.HasData, "reader.HasData"); } else { Assert.True(reader.HasData, "reader.HasData"); } if (expectedValue) { Assert.True(value, "value"); } else { Assert.False(value, "value"); } }
public static void EmptyData_Requires0UnusedBits(PublicEncodingRules ruleSet) { using (AsnWriter writer = new AsnWriter((AsnEncodingRules)ruleSet)) { Assert.Throws <CryptographicException>( () => writer.WriteBitString(ReadOnlySpan <byte> .Empty, 1)); Assert.Throws <CryptographicException>( () => writer.WriteBitString(ReadOnlySpan <byte> .Empty, 7)); Asn1Tag contextTag = new Asn1Tag(TagClass.ContextSpecific, 19); Assert.Throws <CryptographicException>( () => writer.WriteBitString(contextTag, ReadOnlySpan <byte> .Empty, 1)); Assert.Throws <CryptographicException>( () => writer.WriteBitString(contextTag, ReadOnlySpan <byte> .Empty, 7)); writer.WriteBitString(ReadOnlySpan <byte> .Empty, 0); writer.WriteBitString(contextTag, ReadOnlySpan <byte> .Empty, 0); } }
public static void TryCopyBMPStringBytes_Throws( string description, PublicEncodingRules ruleSet, string inputHex) { byte[] inputData = inputHex.HexToByteArray(); byte[] outputData = new byte[inputData.Length + 1]; outputData[0] = 252; int bytesWritten = -1; AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); Assert.Throws <CryptographicException>( () => { reader.TryCopyBMPStringBytes(outputData, out bytesWritten); }); Assert.Equal(-1, bytesWritten); Assert.Equal(252, outputData[0]); }
public static void TagMustBeCorrect_Universal(PublicEncodingRules ruleSet) { byte[] inputData = "180F32303136313130363031323334355A".HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); AssertExtensions.Throws <ArgumentException>( "expectedTag", () => reader.GetGeneralizedTime(Asn1Tag.Null)); Assert.True(reader.HasData, "HasData after bad universal tag"); Assert.Throws <CryptographicException>( () => reader.GetGeneralizedTime(new Asn1Tag(TagClass.ContextSpecific, 0))); Assert.True(reader.HasData, "HasData after wrong tag"); Assert.Equal( new DateTimeOffset(2016, 11, 6, 1, 23, 45, TimeSpan.Zero), reader.GetGeneralizedTime()); Assert.False(reader.HasData, "HasData after read"); }
public static void VerifyWriteNamedBitList_WithTag( PublicEncodingRules ruleSet, string expectedHex, object value) { int ruleSetVal = (int)ruleSet; TagClass tagClass = (TagClass)(byte)(ruleSetVal << 6); if (tagClass == TagClass.Universal) { tagClass = TagClass.Private; } Asn1Tag tag = new Asn1Tag(tagClass, ruleSetVal); using (AsnWriter writer = new AsnWriter((AsnEncodingRules)ruleSet)) { writer.WriteNamedBitList(tag, value); Verify(writer, expectedHex); } }
public static void VerifyWriteEnumeratedValue_Object_WithTag(PublicEncodingRules ruleSet) { AsnWriter objWriter = new AsnWriter((AsnEncodingRules)ruleSet); AsnWriter genWriter = new AsnWriter((AsnEncodingRules)ruleSet); Asn1Tag tag = new Asn1Tag(TagClass.ContextSpecific, 52); genWriter.WriteEnumeratedValue(tag, ReadEnumerated.UIntBacked.Fluff); objWriter.WriteEnumeratedValue(tag, (object)ReadEnumerated.UIntBacked.Fluff); tag = new Asn1Tag(TagClass.Private, 4); genWriter.WriteEnumeratedValue(tag, ReadEnumerated.SByteBacked.Fluff); objWriter.WriteEnumeratedValue(tag, (object)ReadEnumerated.SByteBacked.Fluff); tag = new Asn1Tag(TagClass.Application, 75); genWriter.WriteEnumeratedValue(tag, ReadEnumerated.ULongBacked.Fluff); objWriter.WriteEnumeratedValue(tag, (object)ReadEnumerated.ULongBacked.Fluff); Verify(objWriter, genWriter.Encode().ByteArrayToHex()); }
public void VerifyNonEnum(PublicEncodingRules ruleSet) { AsnWriter writer = new AsnWriter((AsnEncodingRules)ruleSet); Assert.Throws <ArgumentException>( () => writer.WriteEnumeratedValue(5)); Assert.Throws <ArgumentException>( () => writer.WriteEnumeratedValue((object)"hi")); Assert.Throws <ArgumentException>( () => writer.WriteEnumeratedValue((object)5)); Assert.Throws <ArgumentException>( () => writer.WriteEnumeratedValue(new Asn1Tag(TagClass.ContextSpecific, 3), 5)); Assert.Throws <ArgumentException>( () => writer.WriteEnumeratedValue(new Asn1Tag(TagClass.ContextSpecific, 3), (object)"hi")); Assert.Throws <ArgumentException>( () => writer.WriteEnumeratedValue(new Asn1Tag(TagClass.ContextSpecific, 3), (object)5)); }
public static void TagMustBeCorrect_Universal_Indefinite(PublicEncodingRules ruleSet) { byte[] inputData = "308005000000".HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); AssertExtensions.Throws <ArgumentException>( "expectedTag", () => reader.ReadSequence(Asn1Tag.Null)); Assert.True(reader.HasData, "HasData after bad universal tag"); Assert.Throws <CryptographicException>( () => reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0))); Assert.True(reader.HasData, "HasData after wrong tag"); AsnReader seq = reader.ReadSequence(); Assert.Equal("0500", seq.ReadEncodedValue().ByteArrayToHex()); Assert.False(reader.HasData, "HasData after read"); }
public static void CannotEncodeWhileUnbalanced(PublicEncodingRules ruleSet, bool customTag) { AsnWriter writer = new AsnWriter((AsnEncodingRules)ruleSet); if (customTag) { writer.PushSetOf(new Asn1Tag(TagClass.ContextSpecific, (int)ruleSet, true)); } else { writer.PushSetOf(); } int written = -5; Assert.Throws <InvalidOperationException>(() => writer.Encode()); Assert.Throws <InvalidOperationException>(() => writer.TryEncode(Span <byte> .Empty, out written)); Assert.Equal(-5, written); byte[] buf = new byte[10]; Assert.Throws <InvalidOperationException>(() => writer.TryEncode(buf, out written)); Assert.Equal(-5, written); }
public static void TryCopyIA5StringBytes( PublicEncodingRules ruleSet, string inputHex, string expectedString) { byte[] inputData = inputHex.HexToByteArray(); string expectedHex = Text.Encoding.ASCII.GetBytes(expectedString).ByteArrayToHex(); byte[] output = new byte[expectedHex.Length / 2]; AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); bool copied; int bytesWritten; if (output.Length > 0) { output[0] = 32; copied = reader.TryCopyIA5StringBytes(output.AsSpan(0, output.Length - 1), out bytesWritten); Assert.False(copied, "reader.TryCopyIA5StringBytes - too short"); Assert.Equal(0, bytesWritten); Assert.Equal(32, output[0]); } copied = reader.TryCopyIA5StringBytes(output, out bytesWritten); Assert.True(copied, "reader.TryCopyIA5StringBytes"); Assert.Equal( expectedHex, new ReadOnlySpan <byte>(output, 0, bytesWritten).ByteArrayToHex()); Assert.Equal(output.Length, bytesWritten); }
public static void ExpectedTag_IgnoresConstructed( PublicEncodingRules ruleSet, string inputHex, PublicTagClass tagClass, int tagValue) { byte[] inputData = inputHex.HexToByteArray(); Asn1Tag constructedTag = new Asn1Tag((TagClass)tagClass, tagValue, true); Asn1Tag primitiveTag = new Asn1Tag((TagClass)tagClass, tagValue, false); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); string val1 = reader.ReadObjectIdentifierAsString(constructedTag); Assert.False(reader.HasData); reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); Oid oid1 = reader.ReadObjectIdentifier(constructedTag); Assert.False(reader.HasData); reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); string val2 = reader.ReadObjectIdentifierAsString(primitiveTag); Assert.False(reader.HasData); reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); Oid oid2 = reader.ReadObjectIdentifier(primitiveTag); Assert.False(reader.HasData); Assert.Equal(val1, val2); Assert.Equal(oid1.Value, oid2.Value); Assert.Equal(oid1.Value, val1); }
public static void TagMustBeCorrect_Custom(PublicEncodingRules ruleSet) { byte[] inputData = { 0x87, 2, (byte)'h', (byte)'i' }; AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); const UniversalTagNumber EncodingType = UniversalTagNumber.UTF8String; AssertExtensions.Throws <ArgumentException>( "expectedTag", () => reader.TryGetPrimitiveCharacterStringBytes(Asn1Tag.Null, EncodingType, out _)); Assert.True(reader.HasData, "HasData after bad universal tag"); Assert.Throws <CryptographicException>( () => reader.TryGetPrimitiveCharacterStringBytes(EncodingType, out _)); Assert.True(reader.HasData, "HasData after default tag"); Assert.Throws <CryptographicException>( () => reader.TryGetPrimitiveCharacterStringBytes(new Asn1Tag(TagClass.Application, 0), EncodingType, out _)); Assert.True(reader.HasData, "HasData after wrong custom class"); Assert.Throws <CryptographicException>( () => reader.TryGetPrimitiveCharacterStringBytes(new Asn1Tag(TagClass.ContextSpecific, 1), EncodingType, out _)); Assert.True(reader.HasData, "HasData after wrong custom tag value"); Assert.True( reader.TryGetPrimitiveCharacterStringBytes( new Asn1Tag(TagClass.ContextSpecific, 7), EncodingType, out ReadOnlyMemory <byte> value)); Assert.Equal("6869", value.ByteArrayToHex()); Assert.False(reader.HasData, "HasData after reading value"); }
public static void WriteBitString_UnusedBitCount_MustBeValid( PublicEncodingRules ruleSet, int unusedBitCount, string inputHex, bool expectThrow) { byte[] inputBytes = inputHex.HexToByteArray(); using (AsnWriter writer = new AsnWriter((AsnEncodingRules)ruleSet)) { if (expectThrow) { Assert.Throws <CryptographicException>( () => writer.WriteBitString(inputBytes, unusedBitCount)); Assert.Throws <CryptographicException>( () => writer.WriteBitString( new Asn1Tag(TagClass.ContextSpecific, 3), inputBytes, unusedBitCount)); return; } byte[] output = new byte[512]; writer.WriteBitString(inputBytes, unusedBitCount); Assert.True(writer.TryEncode(output, out int bytesWritten)); // This assumes that inputBytes is never more than 999 (and avoids CER constructed forms) Assert.Equal(unusedBitCount, output[bytesWritten - inputBytes.Length - 1]); writer.WriteBitString(new Asn1Tag(TagClass.ContextSpecific, 9), inputBytes, unusedBitCount); Assert.True(writer.TryEncode(output, out bytesWritten)); Assert.Equal(unusedBitCount, output[bytesWritten - inputBytes.Length - 1]); } }
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); }
public static void TryCopyT61String( PublicEncodingRules ruleSet, string inputHex, string expectedValue) { byte[] inputData = inputHex.HexToByteArray(); char[] output = new char[expectedValue.Length]; AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); bool copied; int charsWritten; if (output.Length > 0) { output[0] = 'a'; copied = reader.TryCopyCharacterString( UniversalTagNumber.T61String, output.AsSpan(0, expectedValue.Length - 1), out charsWritten); Assert.False(copied, "reader.TryCopyT61String - too short"); Assert.Equal(0, charsWritten); Assert.Equal('a', output[0]); } copied = reader.TryCopyCharacterString( UniversalTagNumber.T61String, output, out charsWritten); Assert.True(copied, "reader.TryCopyT61String"); string actualValue = new string(output, 0, charsWritten); Assert.Equal(expectedValue, actualValue); }
public void VerifyFlagsBased(PublicEncodingRules ruleSet) { AsnWriter writer = new AsnWriter((AsnEncodingRules)ruleSet); AssertExtensions.Throws <ArgumentException>( "tEnum", () => writer.WriteEnumeratedValue(OpenFlags.IncludeArchived)); AssertExtensions.Throws <ArgumentException>( "tEnum", () => writer.WriteEnumeratedValue( new Asn1Tag(TagClass.ContextSpecific, 13), OpenFlags.IncludeArchived)); AssertExtensions.Throws <ArgumentException>( "tEnum", () => writer.WriteEnumeratedValue((object)OpenFlags.IncludeArchived)); AssertExtensions.Throws <ArgumentException>( "tEnum", () => writer.WriteEnumeratedValue( new Asn1Tag(TagClass.ContextSpecific, 13), (object)OpenFlags.IncludeArchived)); }
public static void VerifyWriteNamedBitList_FlagsEnumRequired(PublicEncodingRules ruleSet) { AsnWriter writer = new AsnWriter((AsnEncodingRules)ruleSet); AssertExtensions.Throws <ArgumentException>( "tEnum", () => writer.WriteNamedBitList(AsnEncodingRules.BER)); AssertExtensions.Throws <ArgumentException>( "tEnum", () => writer.WriteNamedBitList( new Asn1Tag(TagClass.ContextSpecific, 1), AsnEncodingRules.BER)); AssertExtensions.Throws <ArgumentException>( "tEnum", () => writer.WriteNamedBitList((object)AsnEncodingRules.BER)); AssertExtensions.Throws <ArgumentException>( "tEnum", () => writer.WriteNamedBitList( new Asn1Tag(TagClass.ContextSpecific, 1), (object)AsnEncodingRules.BER)); }
public static void ReadBoolean_Failure( string description, PublicEncodingRules ruleSet, string inputHex) { _ = description; byte[] inputData = inputHex.HexToByteArray(); AsnReader reader = new AsnReader(inputData, (AsnEncodingRules)ruleSet); Asn1Tag tag = default(Asn1Tag); if (inputData.Length > 0) { tag = reader.PeekTag(); } if (tag.TagClass == TagClass.Universal) { Assert.Throws <CryptographicException>(() => reader.ReadBoolean()); } else { Assert.Throws <CryptographicException>(() => reader.ReadBoolean(tag)); } if (inputData.Length == 0) { // If we started with nothing, where did the data come from? Assert.False(reader.HasData, "reader.HasData"); } else { // Nothing should have moved Assert.True(reader.HasData, "reader.HasData"); } }
public void VerifyWrite_String_Null(PublicEncodingRules ruleSet) => base.VerifyWrite_String_Null_Helper(ruleSet);
public new void VerifyWrite_EndOfContents_Span(PublicEncodingRules ruleSet) => base.VerifyWrite_EndOfContents_Span(ruleSet);
public void VerifyWrite_EndOfContents_String(PublicEncodingRules ruleSet) => base.VerifyWrite_EndOfContents_String_Helper(ruleSet);
public new void VerifyWrite_String_Null_CustomTag(PublicEncodingRules ruleSet) => base.VerifyWrite_String_Null_CustomTag(ruleSet);