using GostCryptography.Properties; namespace GostCryptography.Asn1.Ber { public class Asn1BerDecodeContext { private readonly int _decBufByteCount; private readonly Asn1BerDecodeBuffer _decodeBuffer; private readonly int _elemLength; private readonly Asn1Tag _tagHolder; public Asn1BerDecodeContext(Asn1BerDecodeBuffer decodeBuffer, int elemLength) { _decodeBuffer = decodeBuffer; _decBufByteCount = decodeBuffer.ByteCount; _elemLength = elemLength; _tagHolder = new Asn1Tag(); } public virtual bool Expired() { if (_elemLength == Asn1Status.IndefiniteLength) { var parsedLen = new IntHolder(); var flag = _decodeBuffer.MatchTag(0, 0, 0, null, parsedLen); if (flag) { _decodeBuffer.Reset(); } return flag; } var num = _decodeBuffer.ByteCount - _decBufByteCount; return (num >= _elemLength); } public virtual bool MatchElemTag(Asn1Tag tag, IntHolder parsedLen, bool advance) { return MatchElemTag(tag.Class, tag.Form, tag.IdCode, parsedLen, advance); } public virtual bool MatchElemTag(short tagClass, short tagForm, int tagIdCode, IntHolder parsedLen, bool advance) { if (Expired()) { return false; } var flag = _decodeBuffer.MatchTag(tagClass, tagForm, tagIdCode, _tagHolder, parsedLen); if ((_elemLength != Asn1Status.IndefiniteLength) && (parsedLen.Value != Asn1Status.IndefiniteLength)) { var num = _decodeBuffer.ByteCount - _decBufByteCount; if ((parsedLen.Value < 0) || (parsedLen.Value > (_elemLength - num))) { throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException); } } if (flag && !advance) { _decodeBuffer.Reset(); } return flag; } } }