public void VerifyLongDerStringRoundTrip() { string TestString = new string('A', 64000); Assert.AreEqual(TestString, DerUtils.DecodeString(DerUtils.EncodePrintableString(TestString)), "PrintableString should make encoding round trip unchanged"); Assert.AreEqual(TestString, DerUtils.DecodeString(DerUtils.EncodeBMPString(TestString)), "BMPString should make encoding round trip unchanged"); }
public void VerifyDerSequenceOfRoundTrip() { var testCases = new[] { new { entryData = new List <string>() { "data1" }, description = "single entry" }, new { entryData = new List <string>() { "data1", "data2", "data3" }, description = "multiple entries" }, new { entryData = new List <string>() { }, description = "no entries" }, }; foreach (var testCase in testCases) { // convert the input data from strings to der encoding, since that's the expected input format List <byte[]> derEntries = new List <byte[]>(); foreach (string entry in testCase.entryData) { derEntries.Add(DerUtils.EncodePrintableString(entry)); } List <byte[]> outputEntries = DerUtils.DecodeSequenceOf(DerUtils.EncodeSequenceOf(derEntries)); // verify the output matches the input Assert.AreEqual(testCase.entryData.Count, outputEntries.Count, "number of output entries should match the number of input entries for test case: " + testCase.description); for (int i = 0; i < outputEntries.Count; i++) { Assert.AreEqual(testCase.entryData[i], DerUtils.DecodeString(outputEntries[i]), "Output data should match input data for test case: " + testCase.description); } } }
public void VerifyDecodeDerStringInvalid() { string SomeShortText = "short text"; string SomeLongText = new string('A', 2000); // text more than 127 bytes long is encoded using DER long form length encoding byte[] DerLongFormLength2000 = new byte[] { 2 | 0x80, 7, 208 }; // long form DER length encoding for length=2000 byte[] IncorrectDerLongFormLength2000 = new byte[] { 3 | 0x80, 7, 208 }; // incorrect long form (claims 3 bytes are used for length but only 2 are actually provided). Used to test the case when the length of length here would extend past array bounds. var errorCases = new[] { new { test = (byte[])null, description = "null bytes" }, new { test = new byte[] { }, description = "empty bytes" }, new { test = new byte[] { DerUtils.TagIA5String }, description = "only tag" }, new { test = (new byte[] { 0xE, (byte)(SomeShortText.Length) }).Concat(Encoding.ASCII.GetBytes(SomeShortText)).ToArray(), description = "string encoding type not yet implemented" }, // technically tag 0xE is reserved so should never be implemented, meaning this test will be valid long-term even if other encodings are added new { test = (new byte[] { DerUtils.TagIA5String, (byte)(SomeShortText.Length + 1) }).Concat(Encoding.ASCII.GetBytes(SomeShortText)).ToArray(), description = "incorrect short form length (+1)" }, new { test = (new byte[] { DerUtils.TagIA5String, (byte)(SomeShortText.Length - 1) }).Concat(Encoding.ASCII.GetBytes(SomeShortText)).ToArray(), description = "incorrect short form length (-1)" }, new { test = (new byte[] { DerUtils.TagIA5String }).Concat(DerLongFormLength2000).Concat(Encoding.ASCII.GetBytes("Shorter text than header claims")).ToArray(), description = "incorrect long form length (actual data too short)" }, new { test = (new byte[] { DerUtils.TagIA5String }).Concat(DerLongFormLength2000).Concat(Encoding.ASCII.GetBytes(SomeLongText + "longer text than header claims")).ToArray(), description = "incorrect long form length (actual data too long)" }, new { test = (new byte[] { DerUtils.TagIA5String }).Concat(IncorrectDerLongFormLength2000).ToArray(), description = "long form length of length extends beyond array bounds" }, }; foreach (var errorCase in errorCases) { bool caughtError = false; try { DerUtils.DecodeString(errorCase.test); } catch (Exception) { caughtError = true; } Assert.IsTrue(caughtError, "DecodeDerString did not throw exception on test case: " + errorCase.description); } }
public void VerifyDecodeDerStringValid() { string SomeShortText = "short text"; string SomeLongText = new string('A', 2000); // text more than 127 bytes long is encoded using DER long form length encoding byte[] DerLongFormLength2000 = new byte[] { 2 | 0x80, 0x7, 0xD0 }; // long form DER length encoding for length=2000 byte[] DerLongFormLength4000 = new byte[] { 2 | 0x80, 0xF, 0xA0 }; // long form DER length encoding for length=4000 (used for multibyte Unicode test cases) var testCases = new[] { new { test = new byte[] { DerUtils.TagIA5String, 0 }, expected = string.Empty, description = "IA5String empty string" }, new { test = new byte[] { DerUtils.TagPrintableString, 0 }, expected = string.Empty, description = "PrintableString empty string" }, new { test = new byte[] { DerUtils.TagBMPString, 0 }, expected = string.Empty, description = "BMPString empty string" }, new { test = (new byte[] { DerUtils.TagIA5String, (byte)(SomeShortText.Length) }).Concat(Encoding.ASCII.GetBytes(SomeShortText)).ToArray(), expected = SomeShortText, description = "IA5String that falls into short form length encoding" }, new { test = (new byte[] { DerUtils.TagIA5String }).Concat(DerLongFormLength2000).Concat(Encoding.ASCII.GetBytes(SomeLongText)).ToArray(), expected = SomeLongText, description = "IA5String that falls into long form length encoding" }, new { test = (new byte[] { DerUtils.TagPrintableString, (byte)(SomeShortText.Length) }).Concat(Encoding.ASCII.GetBytes(SomeShortText)).ToArray(), expected = SomeShortText, description = "PrintableString that falls into short form length encoding" }, new { test = (new byte[] { DerUtils.TagPrintableString }).Concat(DerLongFormLength2000).Concat(Encoding.ASCII.GetBytes(SomeLongText)).ToArray(), expected = SomeLongText, description = "PrintableString that falls into long form length encoding" }, new { test = (new byte[] { DerUtils.TagBMPString, (byte)(Encoding.BigEndianUnicode.GetBytes(SomeShortText).Length) }).Concat(Encoding.BigEndianUnicode.GetBytes(SomeShortText)).ToArray(), expected = SomeShortText, description = "BMPString that falls into short form length encoding" }, new { test = (new byte[] { DerUtils.TagBMPString }).Concat(DerLongFormLength4000).Concat(Encoding.BigEndianUnicode.GetBytes(SomeLongText)).ToArray(), expected = SomeLongText, description = "BMPString that falls into long form length encoding" }, }; foreach (var testCase in testCases) { string output = null; try { output = DerUtils.DecodeString(testCase.test); } catch (Exception ex) { throw new AggregateException("Error on test case: " + testCase.description, ex); } Assert.AreEqual(testCase.expected, output, testCase.description); } }