Skip to content

Commit 7a1f19b

Browse files
committed
added some unit tests for Asn1Builder class
1 parent f8a4c48 commit 7a1f19b

3 files changed

Lines changed: 225 additions & 0 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System;
2+
using Microsoft.VisualStudio.TestTools.UnitTesting;
3+
using SysadminsLV.Asn1Parser;
4+
using SysadminsLV.Asn1Parser.Universal;
5+
6+
namespace Asn1Parser.Tests.Builder;
7+
8+
[TestClass]
9+
public class Asn1BuilderContextSpecificTests {
10+
static Asn1Builder BuildTestContextSpecific() {
11+
return Asn1Builder.Create()
12+
.AddImplicit(0, [1, 2], true)
13+
.AddImplicit(1, new Asn1IA5String("a").GetRawDataAsMemory().Span, false)
14+
.AddExplicit(0, builder => builder.AddInteger(5))
15+
.AddExplicit(1, new Asn1Integer(5).GetRawDataAsMemory().Span, true)
16+
.AddExplicit(2, [48, 3, 2, 1, 5], false);
17+
}
18+
19+
[TestMethod]
20+
public void TestContextSpecific() {
21+
Asn1Builder builder = BuildTestContextSpecific();
22+
23+
ReadOnlyMemory<Byte> encoded = builder.GetEncodedAsMemory();
24+
var reader = new Asn1Reader(encoded);
25+
Assert.AreEqual(reader.Tag, 0x30);
26+
27+
Asn1BuilderTestBase.AssertContextSpecific(reader, 0x80, [0x80, 2, 1, 2]);
28+
Asn1BuilderTestBase.AssertContextSpecific(reader, 0x81, [0x81, 1, 0x61]);
29+
Asn1BuilderTestBase.AssertContextSpecific(reader, 0xa0, [0xa0, 3, 2, 1, 5]);
30+
Asn1BuilderTestBase.AssertContextSpecific(reader, 0xa1, [0xa1, 3, 2, 1, 5], useSibling: true);
31+
Asn1BuilderTestBase.AssertContextSpecific(reader, 0xa2, [0xa2, 3, 2, 1, 5], useSibling: true);
32+
}
33+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using System;
2+
using System.Numerics;
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
using SysadminsLV.Asn1Parser;
5+
using SysadminsLV.Asn1Parser.Universal;
6+
7+
namespace Asn1Parser.Tests.Builder;
8+
9+
public static class Asn1BuilderTestBase {
10+
static void moveNext(Asn1Reader reader, Asn1Type type, Boolean useSibling) {
11+
if (useSibling) {
12+
reader.MoveNextSiblingAndExpectTags(type);
13+
} else {
14+
reader.MoveNextAndExpectTags(type);
15+
}
16+
}
17+
18+
public static void AssertBoolean(Asn1Reader reader, Boolean expectedValue, Boolean useSibling = false) {
19+
moveNext(reader, Asn1Type.BOOLEAN, useSibling);
20+
var tag = (Asn1Boolean)reader.GetTagObject();
21+
Assert.AreEqual(expectedValue, tag.Value);
22+
}
23+
public static void AssertInteger(Asn1Reader reader, BigInteger expectedValue, Boolean useSibling = false) {
24+
moveNext(reader, Asn1Type.INTEGER, useSibling);
25+
var tag = (Asn1Integer)reader.GetTagObject();
26+
Assert.AreEqual(expectedValue, tag.Value);
27+
}
28+
public static void AssertBitStringSimple(Asn1Reader reader, ReadOnlySpan<Byte> expectedValue, Byte expectedUnusedBits, Boolean useSibling = false) {
29+
moveNext(reader, Asn1Type.BIT_STRING, useSibling);
30+
var tag = (Asn1BitString)reader.GetTagObject();
31+
Assert.AreEqual(expectedUnusedBits, tag.UnusedBits);
32+
Assert.IsTrue(expectedValue.SequenceEqual(tag.GetValue().Span));
33+
}
34+
public static void AssertBitString(Asn1Reader reader, Boolean useSibling = false) {
35+
moveNext(reader, Asn1Type.BIT_STRING, useSibling);
36+
var tag = (Asn1BitString)reader.GetTagObject();
37+
Assert.AreEqual(0, tag.UnusedBits);
38+
}
39+
public static void AssertOctetString(Asn1Reader reader, ReadOnlySpan<Byte> expectedValue, Boolean useSibling = false) {
40+
moveNext(reader, Asn1Type.OCTET_STRING, useSibling);
41+
var tag = (Asn1OctetString)reader.GetTagObject();
42+
Assert.IsTrue(expectedValue.SequenceEqual(tag.GetValue().Span));
43+
}
44+
public static void AssertOctetString(Asn1Reader reader, Boolean useSibling = false) {
45+
moveNext(reader, Asn1Type.OCTET_STRING, useSibling);
46+
}
47+
public static void AssertNull(Asn1Reader reader, Boolean useSibling = false) {
48+
moveNext(reader, Asn1Type.NULL, useSibling);
49+
var tag = (Asn1Null)reader.GetTagObject();
50+
Assert.AreEqual(2, tag.GetRawDataAsMemory().Length);
51+
}
52+
public static void AssertObjectIdentifier(Asn1Reader reader, String expectedValue, Boolean useSibling = false) {
53+
moveNext(reader, Asn1Type.OBJECT_IDENTIFIER, useSibling);
54+
var tag = (Asn1ObjectIdentifier)reader.GetTagObject();
55+
Assert.AreEqual(expectedValue, tag.Value.Value);
56+
}
57+
public static void AssertEnumerated(Asn1Reader reader, UInt64 expectedValue, Boolean useSibling = false) {
58+
moveNext(reader, Asn1Type.ENUMERATED, useSibling);
59+
var tag = (Asn1Enumerated)reader.GetTagObject();
60+
Assert.AreEqual(expectedValue, tag.Value);
61+
}
62+
public static void AssertString(Asn1Reader reader, Asn1Type type, String expectedValue, Boolean useSibling = false) {
63+
moveNext(reader, type, useSibling);
64+
var tag = (Asn1String)reader.GetTagObject();
65+
Assert.AreEqual(expectedValue, tag.Value);
66+
}
67+
public static void AssertRelativeOid(Asn1Reader reader, String expectedValue, Boolean useSibling = false) {
68+
moveNext(reader, Asn1Type.RELATIVE_OID, useSibling);
69+
var tag = (Asn1RelativeOid)reader.GetTagObject();
70+
Assert.AreEqual(expectedValue, tag.Value);
71+
}
72+
public static void AssertSequence(Asn1Reader reader, Boolean useSibling = false) {
73+
moveNext(reader, Asn1Type.SEQUENCE | (Asn1Type)Asn1Class.CONSTRUCTED, useSibling);
74+
}
75+
public static void AssertSet(Asn1Reader reader, Boolean useSibling = false) {
76+
moveNext(reader, Asn1Type.SET | (Asn1Type)Asn1Class.CONSTRUCTED, useSibling);
77+
}
78+
public static void AssertDateTime(Asn1Reader reader, DateTime expected, Boolean useUtc, Boolean useSibling = false) {
79+
moveNext(reader, useUtc
80+
? Asn1Type.UTCTime
81+
: Asn1Type.GeneralizedTime, useSibling);
82+
var tag = (Asn1DateTime)reader.GetTagObject();
83+
Assert.AreEqual(expected, tag.Value);
84+
}
85+
public static void AssertContextSpecific(Asn1Reader reader, Byte expectedTag, ReadOnlySpan<Byte> expectedBytes, Boolean useSibling = false) {
86+
moveNext(reader, (Asn1Type)expectedTag, useSibling);
87+
Asn1Universal tag = reader.GetTagObject();
88+
Assert.IsTrue(expectedBytes.SequenceEqual(tag.GetRawDataAsMemory().Span));
89+
}
90+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
using System;
2+
using System.Security.Cryptography;
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
using SysadminsLV.Asn1Parser;
5+
using SysadminsLV.Asn1Parser.Universal;
6+
7+
namespace Asn1Parser.Tests.Builder;
8+
9+
[TestClass]
10+
public class Asn1BuilderTests {
11+
const String EXPECTED_ENCODED = """
12+
MIIBGQEB/wEBAAIBBQMCBLADBAACAQEEAgECBAMCAQQFAAYIKwYBBQUHAwEKAQMM
13+
ClVURjhTdHJpbmcNAQUwBgIBAQIBAjADAgEFMQYCAQECAQIxAwIBBRIHNTU1IDU1
14+
NRMPUHJpbnRhYmxlU3RyaW5nFA1UZWxldGV4U3RyaW5nFQ5WaWRlb3RleFN0cmlu
15+
ZxYJSUE1U3RyaW5nFw0yNTAxMDExODAwMDBaGA8yMDI1MDEwMTE4MDAwMFoaDVZp
16+
c2libGVTdHJpbmccPAAAAFUAAABuAAAAaQAAAHYAAABlAAAAcgAAAHMAAABhAAAA
17+
bAAAAFMAAAB0AAAAcgAAAGkAAABuAAAAZx4SAEIATQBQAFMAdAByAGkAbgBn
18+
""";
19+
static Asn1Builder BuildTestSimple() {
20+
return Asn1Builder.Create()
21+
.AddBoolean(true)
22+
.AddBoolean(false)
23+
.AddInteger(5)
24+
.AddBitString([0xb0], true)
25+
.AddBitString(builder => builder.AddInteger(1))
26+
.AddOctetString(new Byte[] { 1, 2 })
27+
.AddOctetString(builder => builder.AddInteger(4))
28+
.AddNull()
29+
.AddObjectIdentifier(new Oid("1.3.6.1.5.5.7.3.1"))
30+
.AddEnumerated(3)
31+
.AddUTF8String("UTF8String")
32+
.AddRelativeOid(".5")
33+
.AddSequence(builder => builder.AddInteger(1).AddInteger(2))
34+
.AddSequence(new Asn1Integer(5).GetRawDataAsMemory().Span)
35+
.AddSet(builder => builder.AddInteger(1).AddInteger(2))
36+
.AddSet(new Asn1Integer(5).GetRawDataAsMemory().Span)
37+
.AddNumericString("555 555")
38+
.AddPrintableString("PrintableString")
39+
.AddTeletexString("TeletexString")
40+
.AddVideotexString("VideotexString")
41+
.AddIA5String("IA5String")
42+
.AddUtcTime(DateTime.Parse("2025-01-01 20:00:00"))
43+
.AddGeneralizedTime(DateTime.Parse("2025-01-01 20:00:00"))
44+
.AddVisibleString("VisibleString")
45+
.AddUniversalString("UniversalString")
46+
.AddBMPString("BMPString");
47+
}
48+
49+
[TestMethod]
50+
public void TestBuilderSimple() {
51+
Asn1Builder builder = BuildTestSimple();
52+
ReadOnlyMemory<Byte> encoded = builder.GetEncodedAsMemory();
53+
54+
String base64 = Convert.ToBase64String(encoded.Span);
55+
Assert.AreEqual(EXPECTED_ENCODED.Replace("\r\n", null), base64.Replace("\r\n", null));
56+
57+
// read envelope
58+
var reader = new Asn1Reader(encoded);
59+
Assert.AreEqual(reader.Tag, 0x30);
60+
61+
Asn1BuilderTestBase.AssertBoolean(reader, true);
62+
Asn1BuilderTestBase.AssertBoolean(reader, false);
63+
Asn1BuilderTestBase.AssertInteger(reader, 5);
64+
Asn1BuilderTestBase.AssertBitStringSimple(reader, [0xb0], 4);
65+
Asn1BuilderTestBase.AssertBitString(reader);
66+
Asn1Reader nestedReader = reader.GetReader();
67+
Asn1BuilderTestBase.AssertInteger(nestedReader, 1);
68+
Asn1BuilderTestBase.AssertOctetString(reader, [1, 2], useSibling: true);
69+
Asn1BuilderTestBase.AssertOctetString(reader);
70+
nestedReader = reader.GetReader();
71+
Asn1BuilderTestBase.AssertInteger(nestedReader, 4);
72+
Asn1BuilderTestBase.AssertNull(reader, useSibling: true);
73+
Asn1BuilderTestBase.AssertObjectIdentifier(reader, "1.3.6.1.5.5.7.3.1");
74+
Asn1BuilderTestBase.AssertEnumerated(reader, 3);
75+
Asn1BuilderTestBase.AssertString(reader, Asn1Type.UTF8String, Asn1Type.UTF8String.ToString());
76+
Asn1BuilderTestBase.AssertRelativeOid(reader, ".5");
77+
Asn1BuilderTestBase.AssertSequence(reader);
78+
nestedReader = reader.GetReader();
79+
Asn1BuilderTestBase.AssertInteger(nestedReader, 1);
80+
Asn1BuilderTestBase.AssertInteger(nestedReader, 2);
81+
Asn1BuilderTestBase.AssertSequence(reader, useSibling: true);
82+
nestedReader = reader.GetReader();
83+
Asn1BuilderTestBase.AssertInteger(nestedReader, 5);
84+
Asn1BuilderTestBase.AssertSet(reader, useSibling: true);
85+
nestedReader = reader.GetReader();
86+
Asn1BuilderTestBase.AssertInteger(nestedReader, 1);
87+
Asn1BuilderTestBase.AssertInteger(nestedReader, 2);
88+
Asn1BuilderTestBase.AssertSet(reader, useSibling: true);
89+
nestedReader = reader.GetReader();
90+
Asn1BuilderTestBase.AssertInteger(nestedReader, 5);
91+
Asn1BuilderTestBase.AssertString(reader, Asn1Type.NumericString, "555 555", useSibling: true);
92+
Asn1BuilderTestBase.AssertString(reader, Asn1Type.PrintableString, Asn1Type.PrintableString.ToString());
93+
Asn1BuilderTestBase.AssertString(reader, Asn1Type.TeletexString, Asn1Type.TeletexString.ToString());
94+
Asn1BuilderTestBase.AssertString(reader, Asn1Type.VideotexString, Asn1Type.VideotexString.ToString());
95+
Asn1BuilderTestBase.AssertString(reader, Asn1Type.IA5String, Asn1Type.IA5String.ToString());
96+
Asn1BuilderTestBase.AssertDateTime(reader, DateTime.Parse("2025-01-01 20:00:00"), true);
97+
Asn1BuilderTestBase.AssertDateTime(reader, DateTime.Parse("2025-01-01 20:00:00"), false);
98+
Asn1BuilderTestBase.AssertString(reader, Asn1Type.VisibleString, Asn1Type.VisibleString.ToString());
99+
Asn1BuilderTestBase.AssertString(reader, Asn1Type.UniversalString, Asn1Type.UniversalString.ToString());
100+
Asn1BuilderTestBase.AssertString(reader, Asn1Type.BMPString, Asn1Type.BMPString.ToString());
101+
}
102+
}

0 commit comments

Comments
 (0)