Files
hcs/Hcs.Client/GostCryptography/Asn1/Ber/Asn1BerOutputStream.cs
HOME-LAPTOP\kshkulev 33ab055b43 Add project
Basic formatting applied. Unnecessary comments have been removed. Suspicious code is covered by TODO.
2025-08-12 11:21:10 +09:00

278 lines
7.5 KiB
C#

using System.IO;
namespace GostCryptography.Asn1.Ber
{
public class Asn1BerOutputStream : Asn1OutputStream
{
private static readonly byte[] Eoc = new byte[2];
public Asn1BerOutputStream(Stream outputStream)
: base(new BufferedStream(outputStream))
{
}
public Asn1BerOutputStream(Stream outputStream, int bufSize)
: base((bufSize == 0) ? outputStream : new BufferedStream(outputStream, bufSize))
{
}
public virtual void Encode(Asn1Type type, bool explicitTagging)
{
type.Encode(this, explicitTagging);
}
public virtual void EncodeBitString(byte[] data, int numbits, bool explicitTagging, Asn1Tag tag)
{
if (explicitTagging)
{
EncodeTag(tag);
}
var count = (numbits + 7) / 8;
EncodeLength(count + 1);
var num2 = numbits % 8;
if (num2 != 0)
{
num2 = 8 - num2;
data[count - 1] = (byte)(data[count - 1] & ((byte)~((1 << num2) - 1)));
}
OutputStream.WriteByte((byte)num2);
if (count > 0)
{
OutputStream.Write(data, 0, count);
}
}
public virtual void EncodeBmpString(string data, bool explicitTagging, Asn1Tag tag)
{
if (explicitTagging)
{
EncodeTag(tag);
}
if (data == null)
{
EncodeLength(0);
}
else
{
EncodeLength(data.Length * 2);
var length = data.Length;
for (var i = 0; i < length; i++)
{
var num3 = data[i];
var num2 = num3 / 0x100;
var num = num3 % 0x100;
OutputStream.WriteByte((byte)num2);
OutputStream.WriteByte((byte)num);
}
}
}
public virtual void EncodeCharString(string data, bool explicitTagging, Asn1Tag tag)
{
if (explicitTagging)
{
EncodeTag(tag);
}
if (data == null)
{
EncodeLength(0);
}
else
{
EncodeLength(data.Length);
var buffer = Asn1Util.ToByteArray(data);
OutputStream.Write(buffer, 0, buffer.Length);
}
}
public virtual void EncodeEoc()
{
OutputStream.Write(Eoc, 0, Eoc.Length);
}
public virtual void EncodeIdentifier(long ident)
{
var number = 0x7fL;
var identBytesCount = Asn1RunTime.GetIdentBytesCount(ident);
number = number << (7 * identBytesCount);
if (identBytesCount > 0)
{
while (identBytesCount > 0)
{
number = Asn1Util.UrShift(number, 7);
identBytesCount--;
var num3 = Asn1Util.UrShift(ident & number, identBytesCount * 7);
if (identBytesCount != 0)
{
num3 |= 0x80L;
}
OutputStream.WriteByte((byte)num3);
}
}
else
{
OutputStream.WriteByte(0);
}
}
public virtual void EncodeIntValue(long data, bool encodeLen)
{
long num2;
var num = data;
var buffer = new byte[9];
var len = 0;
var length = buffer.Length;
do
{
num2 = num % 0x100L;
num /= 0x100L;
if ((num < 0L) && (num2 != 0L))
{
num -= 1L;
}
buffer[--length] = (byte)num2;
len++;
}
while ((num != 0L) && (num != -1L));
if ((data > 0L) && ((num2 & 0x80L) == 0x80L))
{
buffer[--length] = 0;
len++;
}
else if ((data < 0L) && ((num2 & 0x80L) == 0L))
{
buffer[--length] = 0xff;
len++;
}
if (encodeLen)
{
EncodeLength(len);
}
OutputStream.Write(buffer, length, len);
}
public virtual void EncodeLength(int len)
{
if (len >= 0)
{
var bytesCount = Asn1Util.GetBytesCount(len);
if (len > 0x7f)
{
OutputStream.WriteByte((byte)(bytesCount | 0x80));
}
for (var i = (8 * bytesCount) - 8; i >= 0; i -= 8)
{
var num3 = (byte)((len >> i) & 0xff);
OutputStream.WriteByte(num3);
}
}
else if (len == Asn1Status.IndefiniteLength)
{
OutputStream.WriteByte(0x80);
}
}
public virtual void EncodeOctetString(byte[] data, bool explicitTagging, Asn1Tag tag)
{
if (explicitTagging)
{
EncodeTag(tag);
}
if (data == null)
{
EncodeLength(0);
}
else
{
EncodeLength(data.Length);
OutputStream.Write(data, 0, data.Length);
}
}
public virtual void EncodeTag(Asn1Tag tag)
{
var num = (byte)(((byte)tag.Class) | ((byte)tag.Form));
if (tag.IdCode < 0x1f)
{
OutputStream.WriteByte((byte)(num | tag.IdCode));
}
else
{
OutputStream.WriteByte((byte)(num | 0x1f));
EncodeIdentifier(tag.IdCode);
}
}
public virtual void EncodeTag(short tagClass, short tagForm, int tagIdCode)
{
EncodeTag(new Asn1Tag(tagClass, tagForm, tagIdCode));
}
public virtual void EncodeTagAndIndefLen(Asn1Tag tag)
{
EncodeTag(tag);
OutputStream.WriteByte(0x80);
}
public virtual void EncodeTagAndIndefLen(short tagClass, short tagForm, int tagIdCode)
{
EncodeTag(new Asn1Tag(tagClass, tagForm, tagIdCode));
OutputStream.WriteByte(0x80);
}
public virtual void EncodeTagAndLength(Asn1Tag tag, int len)
{
EncodeTag(tag);
EncodeLength(len);
}
public virtual void EncodeUnivString(int[] data, bool explicitTagging, Asn1Tag tag)
{
if (explicitTagging)
{
EncodeTag(tag);
}
if (data == null)
{
EncodeLength(0);
}
else
{
EncodeLength(data.Length * 4);
var length = data.Length;
for (var i = 0; i < length; ++i)
{
var number = data[i];
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 0x18) & 0xff));
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 0x10) & 0xff));
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 8) & 0xff));
OutputStream.WriteByte((byte)(number & 0xff));
}
}
}
}
}