326 lines
8.6 KiB
C#
326 lines
8.6 KiB
C#
using GostCryptography.Properties;
|
|
using System;
|
|
using System.Collections;
|
|
using System.IO;
|
|
|
|
namespace GostCryptography.Asn1.Ber
|
|
{
|
|
public abstract class Asn1DecodeBuffer : Asn1MessageBuffer
|
|
{
|
|
private readonly ArrayList _captureBufferList;
|
|
private int _byteCount;
|
|
private Stream _inputStream;
|
|
private long _markedPosition;
|
|
private ArrayList _namedEventHandlerList;
|
|
private int _savedByteCount;
|
|
private short _typeCode;
|
|
private int[] _oidBuffer;
|
|
|
|
protected Asn1DecodeBuffer(byte[] msgdata)
|
|
{
|
|
_namedEventHandlerList = new ArrayList();
|
|
_captureBufferList = new ArrayList(5);
|
|
|
|
SetInputStream(msgdata, 0, msgdata.Length);
|
|
}
|
|
|
|
protected Asn1DecodeBuffer(Stream inputStream)
|
|
{
|
|
_namedEventHandlerList = new ArrayList();
|
|
_captureBufferList = new ArrayList(5);
|
|
|
|
_inputStream = inputStream.CanSeek ? inputStream : new BufferedStream(inputStream);
|
|
|
|
Init();
|
|
}
|
|
|
|
public virtual int ByteCount
|
|
{
|
|
get { return _byteCount; }
|
|
}
|
|
|
|
public virtual Asn1DecodeBuffer EventHandlerList
|
|
{
|
|
set { _namedEventHandlerList = value._namedEventHandlerList; }
|
|
}
|
|
|
|
public virtual short TypeCode
|
|
{
|
|
set { _typeCode = value; }
|
|
}
|
|
|
|
public virtual void AddCaptureBuffer(MemoryStream buffer)
|
|
{
|
|
_captureBufferList.Add(buffer);
|
|
}
|
|
|
|
public virtual void AddNamedEventHandler(IAsn1NamedEventHandler handler)
|
|
{
|
|
_namedEventHandlerList.Add(handler);
|
|
}
|
|
|
|
public virtual void Capture(int nbytes)
|
|
{
|
|
for (var i = 0; i < nbytes; i++)
|
|
{
|
|
var num = _inputStream.ReadByte();
|
|
|
|
if (num == -1)
|
|
{
|
|
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
|
}
|
|
|
|
foreach (MemoryStream s in _captureBufferList)
|
|
{
|
|
s.WriteByte((byte)num);
|
|
}
|
|
|
|
_byteCount++;
|
|
}
|
|
}
|
|
|
|
public virtual long DecodeIntValue(int length, bool signExtend)
|
|
{
|
|
return Asn1RunTime.DecodeIntValue(this, length, signExtend);
|
|
}
|
|
|
|
public virtual int[] DecodeOidContents(int llen)
|
|
{
|
|
var index = 0;
|
|
|
|
if (_oidBuffer == null)
|
|
{
|
|
_oidBuffer = new int[0x80];
|
|
}
|
|
|
|
while (llen > 0)
|
|
{
|
|
int num;
|
|
|
|
if (index >= 0x80)
|
|
{
|
|
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
|
|
}
|
|
|
|
_oidBuffer[index] = 0;
|
|
|
|
do
|
|
{
|
|
num = ReadByte();
|
|
_oidBuffer[index] = (_oidBuffer[index] * 0x80) + (num & 0x7f);
|
|
llen--;
|
|
}
|
|
while ((num & 0x80) != 0);
|
|
|
|
if (index == 0)
|
|
{
|
|
var num3 = _oidBuffer[0];
|
|
|
|
_oidBuffer[0] = ((num3 / 40) >= 2) ? 2 : (num3 / 40);
|
|
_oidBuffer[1] = (_oidBuffer[0] == 2) ? (num3 - 80) : (num3 % 40);
|
|
|
|
index = 2;
|
|
}
|
|
else
|
|
{
|
|
index++;
|
|
}
|
|
}
|
|
|
|
if (llen != 0)
|
|
{
|
|
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
|
}
|
|
|
|
var destinationArray = new int[index];
|
|
Array.Copy(_oidBuffer, 0, destinationArray, 0, index);
|
|
return destinationArray;
|
|
}
|
|
|
|
public virtual int[] DecodeRelOidContents(int llen)
|
|
{
|
|
var index = 0;
|
|
|
|
if (_oidBuffer == null)
|
|
{
|
|
_oidBuffer = new int[0x80];
|
|
}
|
|
|
|
while (llen > 0)
|
|
{
|
|
int num;
|
|
|
|
if (index >= 0x80)
|
|
{
|
|
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
|
|
}
|
|
|
|
_oidBuffer[index] = 0;
|
|
|
|
do
|
|
{
|
|
num = ReadByte();
|
|
_oidBuffer[index] = (_oidBuffer[index] * 0x80) + (num & 0x7f);
|
|
llen--;
|
|
}
|
|
while ((num & 0x80) != 0);
|
|
|
|
index++;
|
|
}
|
|
|
|
if (llen != 0)
|
|
{
|
|
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
|
}
|
|
|
|
var destinationArray = new int[index];
|
|
Array.Copy(_oidBuffer, 0, destinationArray, 0, index);
|
|
return destinationArray;
|
|
}
|
|
|
|
public override Stream GetInputStream()
|
|
{
|
|
return _inputStream;
|
|
}
|
|
|
|
public virtual void HexDump()
|
|
{
|
|
HexDump(_inputStream);
|
|
}
|
|
|
|
protected virtual void Init()
|
|
{
|
|
_byteCount = 0;
|
|
_markedPosition = 0L;
|
|
_savedByteCount = 0;
|
|
}
|
|
|
|
public virtual void InvokeCharacters(string svalue)
|
|
{
|
|
var enumerator = _namedEventHandlerList.GetEnumerator();
|
|
|
|
while (enumerator.MoveNext())
|
|
{
|
|
((IAsn1NamedEventHandler)enumerator.Current).Characters(svalue, _typeCode);
|
|
}
|
|
}
|
|
|
|
public virtual void InvokeEndElement(string name, int index)
|
|
{
|
|
var enumerator = _namedEventHandlerList.GetEnumerator();
|
|
|
|
while (enumerator.MoveNext())
|
|
{
|
|
((IAsn1NamedEventHandler)enumerator.Current).EndElement(name, index);
|
|
}
|
|
}
|
|
|
|
public virtual void InvokeStartElement(string name, int index)
|
|
{
|
|
var enumerator = _namedEventHandlerList.GetEnumerator();
|
|
|
|
while (enumerator.MoveNext())
|
|
{
|
|
((IAsn1NamedEventHandler)enumerator.Current).StartElement(name, index);
|
|
}
|
|
}
|
|
|
|
public virtual void Mark()
|
|
{
|
|
_savedByteCount = _byteCount;
|
|
_markedPosition = _inputStream.Position;
|
|
}
|
|
|
|
public virtual int Read()
|
|
{
|
|
var num = _inputStream.ReadByte();
|
|
|
|
if (num == -1)
|
|
{
|
|
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
|
}
|
|
|
|
foreach (MemoryStream s in _captureBufferList)
|
|
{
|
|
s.WriteByte((byte)num);
|
|
}
|
|
|
|
_byteCount++;
|
|
|
|
return num;
|
|
}
|
|
|
|
public virtual void Read(byte[] buffer)
|
|
{
|
|
Read(buffer, 0, buffer.Length);
|
|
}
|
|
|
|
public virtual void Read(byte[] buffer, int offset, int nbytes)
|
|
{
|
|
var count = nbytes;
|
|
var num3 = offset;
|
|
|
|
while (count > 0)
|
|
{
|
|
var num = _inputStream.Read(buffer, num3, count);
|
|
|
|
if (num <= 0)
|
|
{
|
|
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
|
}
|
|
|
|
num3 += num;
|
|
count -= num;
|
|
}
|
|
|
|
foreach (MemoryStream s in _captureBufferList)
|
|
{
|
|
s.Write(buffer, offset, nbytes);
|
|
}
|
|
|
|
_byteCount += nbytes;
|
|
}
|
|
|
|
public abstract int ReadByte();
|
|
|
|
public virtual void RemoveCaptureBuffer(MemoryStream buffer)
|
|
{
|
|
for (var i = 0; i < _captureBufferList.Count; i++)
|
|
{
|
|
if (buffer == _captureBufferList[i])
|
|
{
|
|
_captureBufferList.RemoveAt(i);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
public virtual void Reset()
|
|
{
|
|
try
|
|
{
|
|
_inputStream.Position = _markedPosition;
|
|
_byteCount = _savedByteCount;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
}
|
|
|
|
public virtual void SetInputStream(byte[] msgdata, int offset, int length)
|
|
{
|
|
_inputStream = new MemoryStream(msgdata, offset, length);
|
|
|
|
Init();
|
|
}
|
|
|
|
public virtual long Skip(long nbytes)
|
|
{
|
|
var inputStream = _inputStream;
|
|
var position = inputStream.Position;
|
|
|
|
return (inputStream.Seek(nbytes, SeekOrigin.Current) - position);
|
|
}
|
|
}
|
|
}
|