Add migrated to .NET 8.0 variant of Hcs.Client
This commit is contained in:
400
Hcs.ClientNet/GostCryptography/Asn1/Ber/Asn1BerDecodeBuffer.cs
Normal file
400
Hcs.ClientNet/GostCryptography/Asn1/Ber/Asn1BerDecodeBuffer.cs
Normal file
@ -0,0 +1,400 @@
|
||||
using GostCryptography.Properties;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1BerDecodeBuffer : Asn1DecodeBuffer
|
||||
{
|
||||
private readonly IntHolder _lenHolder;
|
||||
private readonly Asn1Tag _tagHolder;
|
||||
|
||||
private Asn1Tag _lastParsedTag;
|
||||
private MemoryStream _openTypeCaptureBuffer;
|
||||
private MemoryStream _parserCaptureBuffer;
|
||||
|
||||
public Asn1BerDecodeBuffer(byte[] msgdata)
|
||||
: base(msgdata)
|
||||
{
|
||||
_tagHolder = new Asn1Tag();
|
||||
_lenHolder = new IntHolder();
|
||||
}
|
||||
|
||||
public Asn1BerDecodeBuffer(Stream inputStream)
|
||||
: base(inputStream)
|
||||
{
|
||||
_tagHolder = new Asn1Tag();
|
||||
_lenHolder = new IntHolder();
|
||||
}
|
||||
|
||||
public virtual Asn1Tag LastTag
|
||||
{
|
||||
get { return _lastParsedTag; }
|
||||
}
|
||||
|
||||
public static int CalcIndefLen(byte[] data, int offset, int len)
|
||||
{
|
||||
Asn1BerDecodeBuffer buffer;
|
||||
|
||||
if ((offset == 0) && (len == data.Length))
|
||||
{
|
||||
buffer = new Asn1BerDecodeBuffer(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
var destinationArray = new byte[len];
|
||||
Array.Copy(data, offset, destinationArray, 0, len);
|
||||
buffer = new Asn1BerDecodeBuffer(destinationArray);
|
||||
}
|
||||
|
||||
var tag = new Asn1Tag();
|
||||
var num = buffer.DecodeTagAndLength(tag);
|
||||
|
||||
if (num == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
var num2 = 1;
|
||||
num = 0;
|
||||
|
||||
while (num2 > 0)
|
||||
{
|
||||
var byteCount = buffer.ByteCount;
|
||||
var num4 = buffer.DecodeTagAndLength(tag);
|
||||
num += buffer.ByteCount - byteCount;
|
||||
|
||||
if (num4 > 0)
|
||||
{
|
||||
buffer.Skip(num4);
|
||||
num += num4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (num4 == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
num2++;
|
||||
continue;
|
||||
}
|
||||
if (tag.IsEoc() && (num4 == 0))
|
||||
{
|
||||
num2--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public virtual int DecodeLength()
|
||||
{
|
||||
var num3 = 0;
|
||||
var num2 = Read();
|
||||
|
||||
if (num2 < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
if (num2 <= 0x80)
|
||||
{
|
||||
if (num2 == 0x80)
|
||||
{
|
||||
return Asn1Status.IndefiniteLength;
|
||||
}
|
||||
|
||||
return num2;
|
||||
}
|
||||
|
||||
var num = num2 & 0x7f;
|
||||
|
||||
if (num > 4)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
while (num > 0)
|
||||
{
|
||||
num2 = Read();
|
||||
|
||||
if (num2 < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
num3 = (num3 * 0x100) + num2;
|
||||
num--;
|
||||
}
|
||||
|
||||
return num3;
|
||||
}
|
||||
|
||||
public virtual byte[] DecodeOpenType()
|
||||
{
|
||||
return DecodeOpenType(true);
|
||||
}
|
||||
|
||||
public virtual byte[] DecodeOpenType(bool saveData)
|
||||
{
|
||||
if (saveData)
|
||||
{
|
||||
if (_openTypeCaptureBuffer == null)
|
||||
{
|
||||
_openTypeCaptureBuffer = new MemoryStream(0x100);
|
||||
}
|
||||
else
|
||||
{
|
||||
_openTypeCaptureBuffer.Seek(0L, SeekOrigin.Begin);
|
||||
_openTypeCaptureBuffer.SetLength(0L);
|
||||
}
|
||||
|
||||
AddCaptureBuffer(_openTypeCaptureBuffer);
|
||||
}
|
||||
|
||||
DecodeOpenTypeElement(_tagHolder, _lenHolder, saveData);
|
||||
|
||||
if (saveData)
|
||||
{
|
||||
var buffer = _openTypeCaptureBuffer.ToArray();
|
||||
RemoveCaptureBuffer(_openTypeCaptureBuffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void DecodeOpenTypeElement(Asn1Tag tag, IntHolder len, bool saveData)
|
||||
{
|
||||
var nbytes = DecodeTagAndLength(tag);
|
||||
var byteCount = base.ByteCount;
|
||||
|
||||
if (nbytes > 0)
|
||||
{
|
||||
if (saveData)
|
||||
{
|
||||
Capture(nbytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
Skip(nbytes);
|
||||
}
|
||||
}
|
||||
else if (nbytes == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
MovePastEoc(saveData);
|
||||
}
|
||||
|
||||
len.Value = base.ByteCount - byteCount;
|
||||
}
|
||||
|
||||
public virtual void DecodeTag(Asn1Tag tag)
|
||||
{
|
||||
var num = Read();
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
tag.Class = (short)(num & 0xc0);
|
||||
tag.Form = (short)(num & 0x20);
|
||||
tag.IdCode = num & 0x1f;
|
||||
|
||||
if (tag.IdCode == 0x1f)
|
||||
{
|
||||
var num2 = 0L;
|
||||
var num3 = 0;
|
||||
|
||||
do
|
||||
{
|
||||
num = Read();
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
num2 = (num2 * 0x80L) + (num & 0x7f);
|
||||
|
||||
if ((num2 > 0x7fffffffL) || (num3++ > 8))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidTagValue);
|
||||
}
|
||||
|
||||
}
|
||||
while ((num & 0x80) != 0);
|
||||
|
||||
tag.IdCode = (int)num2;
|
||||
}
|
||||
|
||||
_lastParsedTag = tag;
|
||||
}
|
||||
|
||||
public virtual int DecodeTagAndLength(Asn1Tag tag)
|
||||
{
|
||||
DecodeTag(tag);
|
||||
return DecodeLength();
|
||||
}
|
||||
|
||||
public virtual bool MatchTag(Asn1Tag tag)
|
||||
{
|
||||
return MatchTag(tag.Class, tag.Form, tag.IdCode, null, null);
|
||||
}
|
||||
|
||||
public virtual bool MatchTag(Asn1Tag tag, Asn1Tag parsedTag, IntHolder parsedLen)
|
||||
{
|
||||
return MatchTag(tag.Class, tag.Form, tag.IdCode, parsedTag, parsedLen);
|
||||
}
|
||||
|
||||
public virtual bool MatchTag(short tagClass, short tagForm, int tagIdCode, Asn1Tag parsedTag, IntHolder parsedLen)
|
||||
{
|
||||
Mark();
|
||||
|
||||
var tag = parsedTag ?? _tagHolder;
|
||||
var holder = parsedLen ?? _lenHolder;
|
||||
|
||||
holder.Value = DecodeTagAndLength(tag);
|
||||
|
||||
if (!tag.Equals(tagClass, tagForm, tagIdCode))
|
||||
{
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void MovePastEoc(bool saveData)
|
||||
{
|
||||
var tag = new Asn1Tag();
|
||||
var num = 1;
|
||||
|
||||
while (num > 0)
|
||||
{
|
||||
var nbytes = DecodeTagAndLength(tag);
|
||||
|
||||
if (nbytes > 0)
|
||||
{
|
||||
if (saveData)
|
||||
{
|
||||
Capture(nbytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
Skip(nbytes);
|
||||
}
|
||||
}
|
||||
else if (nbytes == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
num++;
|
||||
}
|
||||
else if (tag.IsEoc() && (nbytes == 0))
|
||||
{
|
||||
num--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Parse(IAsn1TaggedEventHandler handler)
|
||||
{
|
||||
if (_parserCaptureBuffer == null)
|
||||
{
|
||||
RemoveCaptureBuffer(_parserCaptureBuffer);
|
||||
}
|
||||
|
||||
if (_parserCaptureBuffer == null)
|
||||
{
|
||||
_parserCaptureBuffer = new MemoryStream(0x100);
|
||||
AddCaptureBuffer(_parserCaptureBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
_parserCaptureBuffer.Seek(0L, SeekOrigin.Begin);
|
||||
_parserCaptureBuffer.SetLength(0L);
|
||||
}
|
||||
|
||||
ParseElement(handler, _tagHolder, _lenHolder);
|
||||
}
|
||||
|
||||
private void ParseCons(IAsn1TaggedEventHandler handler, int len)
|
||||
{
|
||||
var tag2 = new Asn1Tag();
|
||||
var holder = new IntHolder();
|
||||
var byteCount = base.ByteCount;
|
||||
|
||||
while (true)
|
||||
{
|
||||
ParseElement(handler, tag2, holder);
|
||||
|
||||
if (len == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
if (tag2.IsEoc() && (holder.Value == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((base.ByteCount - byteCount) >= len)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseElement(IAsn1TaggedEventHandler handler, Asn1Tag tag, IntHolder len)
|
||||
{
|
||||
_parserCaptureBuffer.Seek(0L, SeekOrigin.Begin);
|
||||
_parserCaptureBuffer.SetLength(0L);
|
||||
|
||||
len.Value = DecodeTagAndLength(tag);
|
||||
|
||||
if (!tag.IsEoc() || (len.Value != 0))
|
||||
{
|
||||
handler.StartElement(tag, len.Value, _parserCaptureBuffer.ToArray());
|
||||
|
||||
_parserCaptureBuffer.Seek(0L, SeekOrigin.Begin);
|
||||
_parserCaptureBuffer.SetLength(0L);
|
||||
|
||||
if ((len.Value > 0) || (len.Value == Asn1Status.IndefiniteLength))
|
||||
{
|
||||
if (tag.Constructed)
|
||||
{
|
||||
ParseCons(handler, len.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ParsePrim(handler, len.Value);
|
||||
}
|
||||
}
|
||||
|
||||
handler.EndElement(tag);
|
||||
}
|
||||
}
|
||||
|
||||
private void ParsePrim(IAsn1TaggedEventHandler handler, int len)
|
||||
{
|
||||
var buffer = new byte[len];
|
||||
Read(buffer);
|
||||
handler.Contents(buffer);
|
||||
}
|
||||
|
||||
public virtual Asn1Tag PeekTag()
|
||||
{
|
||||
var parsedTag = new Asn1Tag();
|
||||
PeekTag(parsedTag);
|
||||
return parsedTag;
|
||||
}
|
||||
|
||||
public virtual void PeekTag(Asn1Tag parsedTag)
|
||||
{
|
||||
Mark();
|
||||
DecodeTag(parsedTag);
|
||||
Reset();
|
||||
}
|
||||
|
||||
public override int ReadByte()
|
||||
{
|
||||
return Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user