summary refs log tree commit diff
path: root/crypto/test/src/asn1/test/InputStreamTest.cs
blob: 4cfb304d153d2a650ac594f71f36938af54adf94 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
using System;
using System.IO;

using NUnit.Framework;

using Org.BouncyCastle.Utilities.Encoders;
using Org.BouncyCastle.Utilities.Test;

namespace Org.BouncyCastle.Asn1.Tests
{
	[TestFixture]
	public class InputStreamTest
		: SimpleTest
	{
        private static readonly byte[] outOfBoundsLength = new byte[] { (byte)0x30, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff };
        private static readonly byte[] negativeLength = new byte[] { (byte)0x30, (byte)0x84, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff };
        private static readonly byte[] outsideLimitLength = new byte[] { (byte)0x30, (byte)0x83, (byte)0x0f, (byte)0xff, (byte)0xff };

        private static readonly byte[] classCast1 = Base64.Decode("p1AkHmYAvfOEIrL4ESfrNg==");
        private static readonly byte[] classCast2 = Base64.Decode("JICNbaBUTTq7uxj5mg==");
        private static readonly byte[] classCast3 = Base64.Decode("JAKzADNCxhrrBSVS");
        private static readonly byte[] memoryError1 = Base64.Decode("vm66gOiEe+FV/NvujMwSkUp5Lffw5caQlaRU5sdMPC70IGWmyK2/");
        private static readonly byte[] memoryError2 = Base64.Decode("vm4ogOSEfVGsS3w+KTzb2A0ALYR8VBOQqQeuRwnsPC4AAGWEDLjd");

		public override string Name
		{
			get { return "InputStream"; }
		}

		public override void PerformTest()
		{
			Asn1InputStream aIn = new Asn1InputStream(outOfBoundsLength);

			try
			{
				aIn.ReadObject();
				Fail("out of bounds length not detected.");
			}
			catch (IOException e)
			{
				if (!e.Message.StartsWith("DER length more than 4 bytes"))
				{
					Fail("wrong exception: " + e.Message);
				}
			}

			aIn = new Asn1InputStream(negativeLength);

			try
			{
				aIn.ReadObject();
				Fail("negative length not detected.");
			}
			catch (IOException e)
			{
				if (!e.Message.Equals("corrupted stream - negative length found"))
				{
					Fail("wrong exception: " + e.Message);
				}
			}

			aIn = new Asn1InputStream(outsideLimitLength);

			try
			{
				aIn.ReadObject();
				Fail("outside limit length not detected.");
			}
			catch (IOException e)
			{
                if (!e.Message.Equals("corrupted stream - out of bounds length found: 1048575 >= 5"))
                {
					Fail("wrong exception: " + e.Message);
				}
			}

            DoTestWithByteArray(classCast1, "unknown object encountered: Org.BouncyCastle.Asn1.DerApplicationSpecific");
            DoTestWithByteArray(classCast2, "unknown object encountered: Org.BouncyCastle.Asn1.BerTaggedObjectParser");
            DoTestWithByteArray(classCast3, "unknown object encountered in constructed OCTET STRING: Org.BouncyCastle.Asn1.DerTaggedObject");

            DoTestWithByteArray(memoryError1, "corrupted stream - out of bounds length found: 2078365180 >= 39");
            DoTestWithByteArray(memoryError2, "corrupted stream - out of bounds length found: 2102504523 >= 39");
        }

        private void DoTestWithByteArray(byte[] data, string message)
        {
            try
            {
                Asn1InputStream input = new Asn1InputStream(data);

                IAsn1Convertible p;
                while ((p = input.ReadObject()) != null)
                {
                    Asn1Sequence asn1 = Asn1Sequence.GetInstance(p);
                    for (int i = 0; i < asn1.Count; i++)
                    {
                        IAsn1Convertible c = asn1[i];
                    }
                }
            }
            catch (IOException e)
            {
                IsEquals(e.Message, message, e.Message);
            }
            // TODO Without InMemoryRepresentable, the IOException may be swapped/wrapped with an Asn1ParsingException
            catch (Asn1ParsingException e)
            {
                Exception messageException = e;

                IOException ioe = e.InnerException as IOException;
                if (ioe != null)
                {
                    messageException = ioe;
                }

                IsEquals(messageException.Message, message, messageException.Message);
            }
        }

		public static void Main(
			string[] args)
		{
			RunTest(new InputStreamTest());
		}

		[Test]
		public void TestFunction()
		{
			string resultText = Perform().ToString();

			Assert.AreEqual(Name + ": Okay", resultText);
		}
	}
}