Basic formatting applied. Unnecessary comments have been removed. Suspicious code is covered by TODO.
306 lines
7.3 KiB
C#
306 lines
7.3 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace GostCryptography.Asn1.Ber
|
|
{
|
|
public class Asn1BerEncodeBuffer : Asn1EncodeBuffer
|
|
{
|
|
public Asn1BerEncodeBuffer()
|
|
{
|
|
ByteIndex = SizeIncrement - 1;
|
|
}
|
|
|
|
public Asn1BerEncodeBuffer(int sizeIncrement)
|
|
: base(sizeIncrement)
|
|
{
|
|
ByteIndex = SizeIncrement - 1;
|
|
}
|
|
|
|
public virtual MemoryStream ByteArrayInputStream
|
|
{
|
|
get
|
|
{
|
|
var index = ByteIndex + 1;
|
|
return new MemoryStream(Data, index, Data.Length - index);
|
|
}
|
|
}
|
|
|
|
public override byte[] MsgCopy
|
|
{
|
|
get
|
|
{
|
|
var sourceIndex = ByteIndex + 1;
|
|
var length = Data.Length - sourceIndex;
|
|
var destinationArray = new byte[length];
|
|
|
|
Array.Copy(Data, sourceIndex, destinationArray, 0, length);
|
|
|
|
return destinationArray;
|
|
}
|
|
}
|
|
|
|
public override int MsgLength
|
|
{
|
|
get
|
|
{
|
|
var num = ByteIndex + 1;
|
|
return (Data.Length - num);
|
|
}
|
|
}
|
|
|
|
public virtual void BinDump()
|
|
{
|
|
BinDump(null);
|
|
}
|
|
|
|
public override void BinDump(StreamWriter outs, string varName)
|
|
{
|
|
var buffer = new Asn1BerDecodeBuffer(ByteArrayInputStream);
|
|
|
|
try
|
|
{
|
|
buffer.Parse(new Asn1BerMessageDumpHandler(outs));
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
Console.Out.WriteLine(exception.Message);
|
|
Console.Error.Write(exception.StackTrace);
|
|
Console.Error.Flush();
|
|
}
|
|
}
|
|
|
|
protected internal override void CheckSize(int bytesRequired)
|
|
{
|
|
if (bytesRequired > (ByteIndex + 1))
|
|
{
|
|
var num = ((bytesRequired - 1) / SizeIncrement) + 1;
|
|
var num2 = num * SizeIncrement;
|
|
var destinationArray = new byte[Data.Length + num2];
|
|
var destinationIndex = (ByteIndex + num2) + 1;
|
|
var length = Data.Length - (ByteIndex + 1);
|
|
|
|
Array.Copy(Data, ByteIndex + 1, destinationArray, destinationIndex, length);
|
|
|
|
Data = destinationArray;
|
|
ByteIndex = destinationIndex - 1;
|
|
}
|
|
}
|
|
|
|
public override void Copy(byte data)
|
|
{
|
|
if (ByteIndex < 0)
|
|
{
|
|
CheckSize(1);
|
|
}
|
|
|
|
Data[ByteIndex--] = data;
|
|
}
|
|
|
|
public override void Copy(byte[] data)
|
|
{
|
|
CheckSize(data.Length);
|
|
ByteIndex -= data.Length;
|
|
|
|
Array.Copy(data, 0, Data, ByteIndex + 1, data.Length);
|
|
}
|
|
|
|
public virtual void Copy(string data)
|
|
{
|
|
var length = data.Length;
|
|
CheckSize(length);
|
|
ByteIndex -= length;
|
|
|
|
for (var i = 0; i < length; ++i)
|
|
{
|
|
Data[(ByteIndex + i) + 1] = (byte)data[i];
|
|
}
|
|
}
|
|
|
|
public virtual void Copy(byte[] data, int startOffset, int length)
|
|
{
|
|
CheckSize(length);
|
|
ByteIndex -= length;
|
|
|
|
Array.Copy(data, startOffset, Data, ByteIndex + 1, length);
|
|
}
|
|
|
|
public virtual int EncodeIdentifier(int ident)
|
|
{
|
|
var flag = true;
|
|
var num = 0;
|
|
var num2 = ident;
|
|
|
|
do
|
|
{
|
|
if (ByteIndex < 0)
|
|
{
|
|
CheckSize(1);
|
|
}
|
|
|
|
Data[ByteIndex] = (byte)(num2 % 0x80);
|
|
|
|
if (!flag)
|
|
{
|
|
Data[ByteIndex] = (byte)(Data[ByteIndex] | 0x80);
|
|
}
|
|
else
|
|
{
|
|
flag = false;
|
|
}
|
|
|
|
ByteIndex--;
|
|
num2 /= 0x80;
|
|
num++;
|
|
|
|
}
|
|
while (num2 > 0);
|
|
|
|
return num;
|
|
}
|
|
|
|
public virtual int EncodeIntValue(long ivalue)
|
|
{
|
|
long num2;
|
|
long num = ivalue;
|
|
|
|
var num3 = 0;
|
|
|
|
do
|
|
{
|
|
num2 = num % 0x100L;
|
|
num /= 0x100L;
|
|
|
|
if ((num < 0L) && (num2 != 0L))
|
|
{
|
|
num -= 1L;
|
|
}
|
|
|
|
Copy((byte)num2);
|
|
|
|
num3++;
|
|
}
|
|
while ((num != 0L) && (num != -1L));
|
|
|
|
if ((ivalue > 0L) && ((num2 & 0x80L) == 0x80L))
|
|
{
|
|
Copy(0);
|
|
num3++;
|
|
return num3;
|
|
}
|
|
|
|
if ((ivalue < 0L) && ((num2 & 0x80L) == 0L))
|
|
{
|
|
Copy(0xff);
|
|
num3++;
|
|
}
|
|
|
|
return num3;
|
|
}
|
|
|
|
public virtual int EncodeLength(int len)
|
|
{
|
|
var num = 0;
|
|
|
|
bool flag;
|
|
|
|
if (len >= 0)
|
|
{
|
|
flag = len > 0x7f;
|
|
|
|
var num2 = len;
|
|
|
|
do
|
|
{
|
|
if (ByteIndex < 0)
|
|
{
|
|
CheckSize(1);
|
|
}
|
|
|
|
Data[ByteIndex--] = (byte)(num2 % 0x100);
|
|
num++;
|
|
num2 /= 0x100;
|
|
}
|
|
while (num2 > 0);
|
|
}
|
|
else
|
|
{
|
|
flag = len == Asn1Status.IndefiniteLength;
|
|
}
|
|
|
|
if (flag)
|
|
{
|
|
if (ByteIndex < 0)
|
|
{
|
|
CheckSize(1);
|
|
}
|
|
|
|
Data[ByteIndex--] = (byte)(num | 0x80);
|
|
num++;
|
|
}
|
|
|
|
return num;
|
|
}
|
|
|
|
public virtual int EncodeTag(Asn1Tag tag)
|
|
{
|
|
var num = (byte)(((byte)tag.Class) | ((byte)tag.Form));
|
|
var num2 = 0;
|
|
|
|
if (tag.IdCode < 0x1f)
|
|
{
|
|
Copy((byte)(num | tag.IdCode));
|
|
num2++;
|
|
return num2;
|
|
}
|
|
|
|
num2 += EncodeIdentifier(tag.IdCode);
|
|
Copy((byte)(num | 0x1f));
|
|
num2++;
|
|
|
|
return num2;
|
|
}
|
|
|
|
public virtual int EncodeTagAndLength(Asn1Tag tag, int len)
|
|
{
|
|
return (EncodeLength(len) + EncodeTag(tag));
|
|
}
|
|
|
|
public virtual int EncodeTagAndLength(short tagClass, short tagForm, int tagIdCode, int len)
|
|
{
|
|
var tag = new Asn1Tag(tagClass, tagForm, tagIdCode);
|
|
return EncodeTagAndLength(tag, len);
|
|
}
|
|
|
|
public override Stream GetInputStream()
|
|
{
|
|
return ByteArrayInputStream;
|
|
}
|
|
|
|
public override void Reset()
|
|
{
|
|
ByteIndex = Data.Length - 1;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
var num = ByteIndex + 1;
|
|
var num2 = Data.Length - num;
|
|
var str = new StringBuilder("").ToString();
|
|
|
|
for (var i = 0; i < num2; ++i)
|
|
{
|
|
str = str + Asn1Util.ToHexString(Data[i + num]);
|
|
}
|
|
|
|
return str;
|
|
}
|
|
|
|
public override void Write(Stream outs)
|
|
{
|
|
var offset = ByteIndex + 1;
|
|
outs.Write(Data, offset, Data.Length - offset);
|
|
}
|
|
}
|
|
}
|