237 lines
6.9 KiB
C#
237 lines
6.9 KiB
C#
using System.IO;
|
|
|
|
namespace GostCryptography.Asn1.Ber
|
|
{
|
|
public class Asn1CerOutputStream : Asn1BerOutputStream
|
|
{
|
|
public Asn1CerOutputStream(Stream outputStream)
|
|
: base(outputStream)
|
|
{
|
|
}
|
|
|
|
public Asn1CerOutputStream(Stream outputStream, int bufSize)
|
|
: base(outputStream, bufSize)
|
|
{
|
|
}
|
|
|
|
public override void Encode(Asn1Type type, bool explicitTagging)
|
|
{
|
|
type.Encode(this, explicitTagging);
|
|
}
|
|
|
|
public override void EncodeBitString(byte[] value, int numbits, bool explicitTagging, Asn1Tag tag)
|
|
{
|
|
if ((((numbits + 7) / 8) + 1) <= 0x3e8)
|
|
{
|
|
base.EncodeBitString(value, numbits, explicitTagging, tag);
|
|
}
|
|
else
|
|
{
|
|
if (explicitTagging)
|
|
{
|
|
EncodeTagAndIndefLen(Asn1BitString.Tag.Class, 0x20, Asn1BitString.Tag.IdCode);
|
|
}
|
|
else
|
|
{
|
|
OutputStream.WriteByte(0x80);
|
|
}
|
|
|
|
var num = (numbits + 7) / 8;
|
|
var num2 = numbits % 8;
|
|
|
|
if (num2 != 0)
|
|
{
|
|
num2 = 8 - num2;
|
|
value[num - 1] = (byte)(value[num - 1] & ((byte)~((1 << num2) - 1)));
|
|
}
|
|
|
|
for (var i = 0; i < num; i += 0x3e8)
|
|
{
|
|
var len = num - i;
|
|
|
|
if (len > 0x3e8)
|
|
{
|
|
len = 0x3e8;
|
|
EncodeTagAndLength(Asn1BitString.Tag, len);
|
|
}
|
|
else
|
|
{
|
|
EncodeTagAndLength(Asn1BitString.Tag, len + 1);
|
|
OutputStream.WriteByte((byte)num2);
|
|
}
|
|
|
|
if (len > 0)
|
|
{
|
|
OutputStream.Write(value, i, len);
|
|
}
|
|
}
|
|
|
|
EncodeEoc();
|
|
}
|
|
}
|
|
|
|
public override void EncodeBmpString(string value, bool explicitTagging, Asn1Tag tag)
|
|
{
|
|
if ((value == null) || (value.Length <= 500))
|
|
{
|
|
base.EncodeBmpString(value, explicitTagging, tag);
|
|
}
|
|
else
|
|
{
|
|
if (explicitTagging)
|
|
{
|
|
EncodeTagAndIndefLen(Asn1BmpString.Tag.Class, 0x20, Asn1BmpString.Tag.IdCode);
|
|
}
|
|
else
|
|
{
|
|
OutputStream.WriteByte(0x80);
|
|
}
|
|
|
|
for (var i = 0; i < value.Length; i += 500)
|
|
{
|
|
var num2 = value.Length - i;
|
|
|
|
if (num2 > 500)
|
|
{
|
|
num2 = 500;
|
|
}
|
|
|
|
EncodeTagAndLength(Asn1OctetString.Tag, num2 * 2);
|
|
|
|
for (var j = 0; j < num2; j++)
|
|
{
|
|
var num5 = value[j + i];
|
|
var num4 = num5 / 0x100;
|
|
|
|
var num3 = num5 % 0x100;
|
|
OutputStream.WriteByte((byte)num4);
|
|
OutputStream.WriteByte((byte)num3);
|
|
}
|
|
}
|
|
|
|
EncodeEoc();
|
|
}
|
|
}
|
|
|
|
public override void EncodeCharString(string value, bool explicitTagging, Asn1Tag tag)
|
|
{
|
|
if ((value == null) || (value.Length <= 0x3e8))
|
|
{
|
|
base.EncodeCharString(value, explicitTagging, tag);
|
|
}
|
|
else
|
|
{
|
|
var data = Asn1Util.ToByteArray(value);
|
|
|
|
if (explicitTagging)
|
|
{
|
|
EncodeTag(tag.Class, 0x20, tag.IdCode);
|
|
}
|
|
|
|
EncodeOctetString(data, false, tag);
|
|
}
|
|
}
|
|
|
|
public override void EncodeOctetString(byte[] value, bool explicitTagging, Asn1Tag tag)
|
|
{
|
|
if ((value == null) || (value.Length <= 0x3e8))
|
|
{
|
|
base.EncodeOctetString(value, explicitTagging, tag);
|
|
}
|
|
else
|
|
{
|
|
if (explicitTagging)
|
|
{
|
|
EncodeTagAndIndefLen(Asn1OctetString.Tag.Class, 0x20, Asn1OctetString.Tag.IdCode);
|
|
}
|
|
else
|
|
{
|
|
OutputStream.WriteByte(0x80);
|
|
}
|
|
|
|
for (var i = 0; i < value.Length; i += 0x3e8)
|
|
{
|
|
var len = value.Length - i;
|
|
|
|
if (len > 0x3e8)
|
|
{
|
|
len = 0x3e8;
|
|
}
|
|
|
|
EncodeTagAndLength(Asn1OctetString.Tag, len);
|
|
Write(value, i, len);
|
|
}
|
|
|
|
EncodeEoc();
|
|
}
|
|
}
|
|
|
|
public virtual void EncodeStringTag(int nbytes, Asn1Tag tag)
|
|
{
|
|
if (nbytes <= 0x3e8)
|
|
{
|
|
EncodeTag(tag);
|
|
}
|
|
else
|
|
{
|
|
EncodeTag(tag.Class, 0x20, tag.IdCode);
|
|
}
|
|
}
|
|
|
|
public virtual void EncodeStringTag(int nbytes, short tagClass, short tagForm, int tagIdCode)
|
|
{
|
|
if (nbytes <= 0x3e8)
|
|
{
|
|
EncodeTag(new Asn1Tag(tagClass, tagForm, tagIdCode));
|
|
}
|
|
else
|
|
{
|
|
EncodeTag(tagClass, 0x20, tagIdCode);
|
|
}
|
|
}
|
|
|
|
public override void EncodeUnivString(int[] value, bool explicitTagging, Asn1Tag tag)
|
|
{
|
|
if ((value == null) || (value.Length <= 250))
|
|
{
|
|
base.EncodeUnivString(value, explicitTagging, tag);
|
|
}
|
|
else
|
|
{
|
|
if (explicitTagging)
|
|
{
|
|
EncodeTagAndIndefLen(Asn1UniversalString.Tag.Class, 0x20, Asn1UniversalString.Tag.IdCode);
|
|
}
|
|
else
|
|
{
|
|
OutputStream.WriteByte(0x80);
|
|
}
|
|
|
|
for (var i = 0; i < value.Length; i += 250)
|
|
{
|
|
var num2 = value.Length - i;
|
|
|
|
if (num2 > 250)
|
|
{
|
|
num2 = 250;
|
|
}
|
|
|
|
EncodeTagAndLength(Asn1OctetString.Tag, num2 * 4);
|
|
|
|
for (int j = 0; j < num2; j++)
|
|
{
|
|
var number = value[j + 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));
|
|
}
|
|
}
|
|
|
|
EncodeEoc();
|
|
}
|
|
}
|
|
}
|
|
}
|