Add support for ГОСТ Р 34.10 digital signatures

- Implemented the GostKeyValue class for handling public key parameters in ГОСТ Р 34.10 digital signatures.
- Created the GostSignedXml class to manage XML signatures using ГОСТ 34.10, including methods for computing and checking signatures.
- Developed the GostSignedXmlImpl class to encapsulate the signature computation logic and public key retrieval.
- Added specific key value classes for ГОСТ Р 34.10-2001, ГОСТ Р 34.10-2012/256, and ГОСТ Р 34.10-2012/512 to support different signature algorithms.
- Ensured compatibility with existing XML signature standards while integrating ГОСТ cryptography.
This commit is contained in:
master
2025-11-09 21:59:57 +02:00
parent 75c2bcafce
commit cef4cb2c5a
486 changed files with 32952 additions and 801 deletions

View File

@@ -0,0 +1,21 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public abstract class Asn18BitCharString : Asn1CharString
{
public const int BitsPerCharA = 8;
public const int BitsPerCharU = 7;
protected internal Asn18BitCharString(short typeCode)
: base(typeCode)
{
}
protected internal Asn18BitCharString(string data, short typeCode)
: base(data, typeCode)
{
}
}
}

View File

@@ -0,0 +1,401 @@
using System;
using System.IO;
using GostCryptography.Properties;
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();
}
}
}

View File

@@ -0,0 +1,72 @@
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;
}
}
}

View File

@@ -0,0 +1,305 @@
using System;
using System.IO;
using System.Text;
namespace GostCryptography.Asn1.Ber
{
public class Asn1BerEncodeBuffer : Asn1EncodeBuffer
{
public Asn1BerEncodeBuffer()
{
ByteIndex = SizeIncrement - 1;
}
public Asn1BerEncodeBuffer(int sizeIncrement)
: base(sizeIncrement)
{
ByteIndex = SizeIncrement - 1;
}
public virtual MemoryStream ByteArrayInputStream
{
get
{
var index = ByteIndex + 1;
return new MemoryStream(Data, index, Data.Length - index);
}
}
public override byte[] MsgCopy
{
get
{
var sourceIndex = ByteIndex + 1;
var length = Data.Length - sourceIndex;
var destinationArray = new byte[length];
Array.Copy(Data, sourceIndex, destinationArray, 0, length);
return destinationArray;
}
}
public override int MsgLength
{
get
{
var num = ByteIndex + 1;
return (Data.Length - num);
}
}
public virtual void BinDump()
{
BinDump(null);
}
public override void BinDump(StreamWriter outs, string varName)
{
var buffer = new Asn1BerDecodeBuffer(ByteArrayInputStream);
try
{
buffer.Parse(new Asn1BerMessageDumpHandler(outs));
}
catch (Exception exception)
{
Console.Out.WriteLine(exception.Message);
Console.Error.Write(exception.StackTrace);
Console.Error.Flush();
}
}
protected internal override void CheckSize(int bytesRequired)
{
if (bytesRequired > (ByteIndex + 1))
{
var num = ((bytesRequired - 1) / SizeIncrement) + 1;
var num2 = num * SizeIncrement;
var destinationArray = new byte[Data.Length + num2];
var destinationIndex = (ByteIndex + num2) + 1;
var length = Data.Length - (ByteIndex + 1);
Array.Copy(Data, ByteIndex + 1, destinationArray, destinationIndex, length);
Data = destinationArray;
ByteIndex = destinationIndex - 1;
}
}
public override void Copy(byte data)
{
if (ByteIndex < 0)
{
CheckSize(1);
}
Data[ByteIndex--] = data;
}
public override void Copy(byte[] data)
{
CheckSize(data.Length);
ByteIndex -= data.Length;
Array.Copy(data, 0, Data, ByteIndex + 1, data.Length);
}
public virtual void Copy(string data)
{
var length = data.Length;
CheckSize(length);
ByteIndex -= length;
for (var i = 0; i < length; ++i)
{
Data[(ByteIndex + i) + 1] = (byte)data[i];
}
}
public virtual void Copy(byte[] data, int startOffset, int length)
{
CheckSize(length);
ByteIndex -= length;
Array.Copy(data, startOffset, Data, ByteIndex + 1, length);
}
public virtual int EncodeIdentifier(int ident)
{
var flag = true;
var num = 0;
var num2 = ident;
do
{
if (ByteIndex < 0)
{
CheckSize(1);
}
Data[ByteIndex] = (byte)(num2 % 0x80);
if (!flag)
{
Data[ByteIndex] = (byte)(Data[ByteIndex] | 0x80);
}
else
{
flag = false;
}
ByteIndex--;
num2 /= 0x80;
num++;
}
while (num2 > 0);
return num;
}
public virtual int EncodeIntValue(long ivalue)
{
long num2;
long num = ivalue;
var num3 = 0;
do
{
num2 = num % 0x100L;
num /= 0x100L;
if ((num < 0L) && (num2 != 0L))
{
num -= 1L;
}
Copy((byte)num2);
num3++;
}
while ((num != 0L) && (num != -1L));
if ((ivalue > 0L) && ((num2 & 0x80L) == 0x80L))
{
Copy(0);
num3++;
return num3;
}
if ((ivalue < 0L) && ((num2 & 0x80L) == 0L))
{
Copy(0xff);
num3++;
}
return num3;
}
public virtual int EncodeLength(int len)
{
var num = 0;
bool flag;
if (len >= 0)
{
flag = len > 0x7f;
var num2 = len;
do
{
if (ByteIndex < 0)
{
CheckSize(1);
}
Data[ByteIndex--] = (byte)(num2 % 0x100);
num++;
num2 /= 0x100;
}
while (num2 > 0);
}
else
{
flag = len == Asn1Status.IndefiniteLength;
}
if (flag)
{
if (ByteIndex < 0)
{
CheckSize(1);
}
Data[ByteIndex--] = (byte)(num | 0x80);
num++;
}
return num;
}
public virtual int EncodeTag(Asn1Tag tag)
{
var num = (byte)(((byte)tag.Class) | ((byte)tag.Form));
var num2 = 0;
if (tag.IdCode < 0x1f)
{
Copy((byte)(num | tag.IdCode));
num2++;
return num2;
}
num2 += EncodeIdentifier(tag.IdCode);
Copy((byte)(num | 0x1f));
num2++;
return num2;
}
public virtual int EncodeTagAndLength(Asn1Tag tag, int len)
{
return (EncodeLength(len) + EncodeTag(tag));
}
public virtual int EncodeTagAndLength(short tagClass, short tagForm, int tagIdCode, int len)
{
var tag = new Asn1Tag(tagClass, tagForm, tagIdCode);
return EncodeTagAndLength(tag, len);
}
public override Stream GetInputStream()
{
return ByteArrayInputStream;
}
public override void Reset()
{
ByteIndex = Data.Length - 1;
}
public override string ToString()
{
var num = ByteIndex + 1;
var num2 = Data.Length - num;
var str = new StringBuilder("").ToString();
for (var i = 0; i < num2; ++i)
{
str = str + Asn1Util.ToHexString(Data[i + num]);
}
return str;
}
public override void Write(Stream outs)
{
var offset = ByteIndex + 1;
outs.Write(Data, offset, Data.Length - offset);
}
}
}

View File

@@ -0,0 +1,41 @@
using System.IO;
namespace GostCryptography.Asn1.Ber
{
public class Asn1BerInputStream : Asn1BerDecodeBuffer, IAsn1InputStream
{
public Asn1BerInputStream(Stream inputStream)
: base(inputStream)
{
}
public virtual int Available()
{
var inputStream = GetInputStream();
if (inputStream != null)
{
var num = inputStream.Length - inputStream.Position;
return (int)num;
}
return 0;
}
public virtual void Close()
{
var inputStream = GetInputStream();
if (inputStream != null)
{
inputStream.Close();
}
}
public virtual bool MarkSupported()
{
var inputStream = GetInputStream();
return ((inputStream != null) && inputStream.CanSeek);
}
}
}

View File

@@ -0,0 +1,135 @@
using System;
using System.IO;
using System.Text;
namespace GostCryptography.Asn1.Ber
{
public class Asn1BerMessageDumpHandler : IAsn1TaggedEventHandler
{
private const int MaxBytesPerLine = 12;
private int _offset;
private readonly StreamWriter _printStream;
public Asn1BerMessageDumpHandler()
{
_printStream = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = true };
_offset = 0;
}
public Asn1BerMessageDumpHandler(StreamWriter outs)
{
_printStream = outs;
_offset = 0;
}
public virtual void Contents(byte[] data)
{
if (data.Length != 0)
{
PrintOffset();
var flag = true;
var builder = new StringBuilder(100);
var builder2 = new StringBuilder(100);
for (var i = 0; i < data.Length; ++i)
{
builder.Append(Asn1Util.ToHexString(data[i]));
builder.Append(' ');
int num2 = data[i];
if ((num2 >= 0x20) && (num2 <= 0x7f))
{
builder2.Append((char)num2);
}
else
{
builder2.Append('.');
}
if (((i + 1) % MaxBytesPerLine) == 0)
{
if (!flag)
{
_printStream.Write(" : ");
}
else
{
flag = false;
}
_printStream.WriteLine(builder + ": " + builder2);
builder.Length = 0;
builder2.Length = 0;
}
}
if (builder.Length > 0)
{
while (builder.Length < 0x24)
{
builder.Append(' ');
}
if (!flag)
{
_printStream.Write(" : ");
}
_printStream.WriteLine(builder + ": " + builder2);
}
_offset += data.Length;
}
}
public virtual void EndElement(Asn1Tag tag)
{
}
public virtual void StartElement(Asn1Tag tag, int len, byte[] tagLenBytes)
{
PrintOffset();
new StringBuilder(40); // WTF?
var index = 0;
while (index < tagLenBytes.Length)
{
_printStream.Write(Asn1Util.ToHexString(tagLenBytes[index]));
_printStream.Write(' ');
index++;
}
while (index < MaxBytesPerLine)
{
_printStream.Write(" ");
index++;
}
_printStream.Write(": ");
_printStream.Write(tag.Constructed ? "C " : "P ");
_printStream.Write(tag + " ");
_printStream.WriteLine(Convert.ToString(len));
_offset += tagLenBytes.Length;
}
private void PrintOffset()
{
var str = Convert.ToString(_offset);
var num = 4 - str.Length;
for (var i = 0; i < num; ++i)
{
_printStream.Write('0');
}
_printStream.Write(str);
_printStream.Write(" : ");
}
}
}

View File

@@ -0,0 +1,277 @@
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));
}
}
}
}
}

View File

@@ -0,0 +1,137 @@
using System;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1BigInteger : Asn1Type
{
private const int MaxBigIntLen = 0x186a0;
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BigIntegerTypeCode);
public static readonly BigInteger Zero = new BigInteger();
private BigInteger _value;
public Asn1BigInteger()
{
_value = new BigInteger();
}
public Asn1BigInteger(BigInteger value)
{
_value = value;
}
public Asn1BigInteger(string value)
{
_value = new BigInteger(value);
}
public Asn1BigInteger(string value, int radix)
{
_value = new BigInteger(value, radix);
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
_value = DecodeValue(buffer, length);
buffer.TypeCode = 2;
}
public BigInteger DecodeValue(Asn1DecodeBuffer buffer, int length)
{
var ivalue = new byte[length];
if (length > MaxBigIntLen)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1TooBigIntegerValue, length);
}
for (var i = 0; i < length; ++i)
{
ivalue[i] = (byte)buffer.ReadByte();
}
var integer = new BigInteger();
if (length > 0)
{
integer.SetData(ivalue);
}
return integer;
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = EncodeValue(buffer, _value, true);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Tag, len);
}
return len;
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
if (explicitTagging)
{
outs.EncodeTag(Tag);
}
var buffer = new Asn1BerEncodeBuffer();
var len = EncodeValue(buffer, _value, true);
outs.EncodeLength(len);
outs.Write(buffer.MsgCopy);
}
private static int EncodeValue(Asn1EncodeBuffer buffer, BigInteger ivalue, bool doCopy)
{
var data = ivalue.GetData();
var length = data.Length;
for (var i = length - 1; i >= 0; --i)
{
if (doCopy)
{
buffer.Copy(data[i]);
}
}
return length;
}
public virtual bool Equals(long value)
{
return _value.Equals(value);
}
public override bool Equals(object value)
{
var integer = value as Asn1BigInteger;
if (integer == null)
{
return false;
}
return _value.Equals(integer._value);
}
public override int GetHashCode()
{
return _value.GetHashCode();
}
public override string ToString()
{
return _value.ToString(10);
}
}
}

View File

@@ -0,0 +1,455 @@
using System;
using System.Collections;
using System.Text;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1BitString : Asn1Type
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BitStringTypeCode);
[NonSerialized]
public byte[] Value;
[NonSerialized]
public int NumBits;
public Asn1BitString()
{
NumBits = 0;
Value = null;
}
public Asn1BitString(bool[] bitValues)
{
AllocBitArray(bitValues.Length);
var index = 0;
var num4 = 0x80;
var num = 0;
var num2 = 0;
while (num < bitValues.Length)
{
if (bitValues[num])
{
num2 |= num4;
}
num4 = num4 >> 1;
if (num4 == 0)
{
Value[index++] = (byte)num2;
num4 = 0x80;
num2 = 0;
}
num++;
}
if (num4 != 0x80)
{
Value[index] = (byte)num2;
}
}
public Asn1BitString(BitArray bitArray)
{
AllocBitArray(bitArray.Length);
var index = 0;
var num4 = 0x80;
var num = 0;
var num2 = 0;
while (num < bitArray.Length)
{
if (bitArray.Get(num))
{
num2 |= num4;
}
num4 = num4 >> 1;
if (num4 == 0)
{
Value[index++] = (byte)num2;
num4 = 0x80;
num2 = 0;
}
num++;
}
if (num4 != 0x80)
{
Value[index] = (byte)num2;
}
}
public Asn1BitString(string value)
{
var numbits = new IntHolder();
Value = Asn1Value.ParseString(value, numbits);
NumBits = numbits.Value;
}
public Asn1BitString(int numBits, byte[] data)
{
NumBits = numBits;
Value = data;
}
private void AllocBitArray(int numbits)
{
NumBits = numbits;
var num = (NumBits + 7) / 8;
if ((Value == null) || (Value.Length < num))
{
Value = new byte[num];
}
}
public virtual void Clear(int bitIndex)
{
this[bitIndex] = false;
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var elemLength = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
var lastTag = buffer.LastTag;
if ((lastTag == null) || !lastTag.Constructed)
{
if (elemLength < 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
}
if (elemLength != 0)
{
var num8 = elemLength - 1;
var num7 = buffer.Read();
if (num7 < 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
}
if ((num7 < 0) || (num7 > 7))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfBitString, num7);
}
if ((num8 == 0) && (num7 != 0))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
}
NumBits = (num8 * 8) - num7;
Value = new byte[num8];
buffer.Read(Value);
}
else
{
NumBits = 0;
Value = null;
}
}
else
{
var num3 = 0;
var offset = 0;
var index = -1;
var num6 = 0;
var context = new Asn1BerDecodeContext(buffer, elemLength);
while (!context.Expired())
{
var nbytes = MatchTag(buffer, Tag);
if (nbytes <= 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
}
num3 += nbytes;
if (offset == 0)
{
AllocBitArray(num3 * 8);
}
else
{
ReallocBitArray(num3 * 8);
}
index = offset;
buffer.Read(Value, offset, nbytes);
offset = num3;
}
if (index >= 0)
{
num6 = Value[index];
if (((offset - index) - 1) > 0)
{
Array.Copy(Value, index + 1, Value, index, (offset - index) - 1);
}
num3--;
}
if ((num6 < 0) || (num6 > 7))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfBitString, num6);
}
ReallocBitArray((num3 * 8) - num6);
if (elemLength == Asn1Status.IndefiniteLength)
{
MatchTag(buffer, Asn1Tag.Eoc);
}
}
buffer.TypeCode = 3;
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var length = (NumBits + 7) / 8;
var num2 = NumBits % 8;
if (num2 != 0)
{
num2 = 8 - num2;
Value[length - 1] = (byte)(Value[length - 1] & ((byte)~((1 << num2) - 1)));
}
if (length != 0)
{
buffer.Copy(Value, 0, length);
}
buffer.Copy((byte)num2);
length++;
if (explicitTagging)
{
length += buffer.EncodeTagAndLength(Tag, length);
}
return length;
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
outs.EncodeBitString(Value, NumBits, explicitTagging, Tag);
}
public override bool Equals(object value)
{
var str = value as Asn1BitString;
if (str == null)
{
return false;
}
return Equals(str.NumBits, str.Value);
}
public virtual bool Equals(int nbits, byte[] value)
{
if (nbits != NumBits)
{
return false;
}
var num = ((nbits - 1) / 8) + 1;
for (var i = 0; i < num; ++i)
{
if (value[i] != Value[i])
{
return false;
}
}
return true;
}
public virtual bool Get(int bitno)
{
var index = bitno / 8;
var num2 = 1 << (7 - (bitno % 8));
if ((Value != null) && (Value.Length >= index))
{
int num3 = Value[index];
return ((num3 & num2) != 0);
}
return false;
}
public override int GetHashCode()
{
return (Value != null) ? Value.GetHashCode() : base.GetHashCode();
}
private void ReallocBitArray(int numbits)
{
NumBits = numbits;
var num = (NumBits + 7) / 8;
if (Value.Length != num)
{
var value = Value;
Value = new byte[num];
if (value != null)
{
Array.Copy(value, 0, Value, 0, Math.Min(value.Length, num));
}
}
}
public virtual void Set(int bitIndex)
{
Set(bitIndex, true);
}
public virtual void Set(int bitIndex, bool value)
{
var index = bitIndex / 8;
var num2 = 1 << (7 - (bitIndex % 8));
var num3 = index + 1;
if (Value == null)
{
Value = new byte[num3];
}
else if (Value.Length < num3)
{
var destinationArray = new byte[num3];
Array.Copy(Value, 0, destinationArray, 0, Value.Length);
Value = destinationArray;
}
int num4 = Value[index];
num4 = value ? (num4 | num2) : (num4 & ~num2);
Value[index] = (byte)num4;
if ((bitIndex + 1) > NumBits)
{
NumBits = bitIndex + 1;
}
}
public virtual bool[] ToBoolArray()
{
var flagArray = new bool[NumBits];
var num4 = 0;
var numbits = NumBits;
foreach (var num3 in Value)
{
var num5 = 0x80;
var num = (numbits < 8) ? numbits : 8;
for (var j = 0; j < num; ++j)
{
flagArray[num4++] = (num3 & num5) != 0;
num5 = num5 >> 1;
}
numbits -= 8;
}
return flagArray;
}
public virtual string ToHexString()
{
var str = new StringBuilder("").ToString();
foreach (var b in Value)
{
str = str + Asn1Util.ToHexString(b);
}
return str;
}
public override string ToString()
{
var str = new StringBuilder("").ToString();
if (NumBits <= 0x10)
{
if (NumBits != 0)
{
var flagArray = ToBoolArray();
foreach (bool b in flagArray)
{
str = str + (b ? "1" : "0");
}
}
return str;
}
var num2 = 4;
var capacity = (NumBits + 3) / 4;
var builder = new StringBuilder(capacity);
if (Value != null)
{
var num4 = 0;
var index = 0;
while (num4 < capacity)
{
var num6 = (Value[index] >> num2) & 15;
builder.Append((char)(num6 + ((num6 >= 10) ? 0x57 : 0x30)));
num2 -= 4;
if (num2 < 0)
{
num2 = 4;
index++;
}
num4++;
}
}
return builder.ToString();
}
public virtual bool this[int bitIndex]
{
get { return Get(bitIndex); }
set { Set(bitIndex, value); }
}
public override int Length
{
get { return NumBits; }
}
}
}

View File

@@ -0,0 +1,125 @@
using System;
using System.Text;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1BmpString : Asn1CharString
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BmpStringTypeCode);
public Asn1BmpString()
: base(BmpStringTypeCode)
{
}
public Asn1BmpString(string data)
: base(data, BmpStringTypeCode)
{
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var elemLength = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
var len = elemLength;
var sb = new StringBuilder();
var lastTag = buffer.LastTag;
if ((lastTag == null) || !lastTag.Constructed)
{
sb.EnsureCapacity(elemLength / 2);
ReadSegment(buffer, sb, len);
}
else
{
var capacity = 0;
var context = new Asn1BerDecodeContext(buffer, elemLength);
while (!context.Expired())
{
var num3 = MatchTag(buffer, Asn1OctetString.Tag);
if (num3 <= 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
}
capacity += num3;
sb.EnsureCapacity(capacity);
ReadSegment(buffer, sb, num3);
}
if (elemLength == Asn1Status.IndefiniteLength)
{
MatchTag(buffer, Asn1Tag.Eoc);
}
}
Value = sb.ToString();
buffer.TypeCode = BmpStringTypeCode;
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var length = Value.Length;
for (var i = length - 1; i >= 0; --i)
{
var num3 = Value[i];
var num = num3 % 0x100;
var num2 = num3 / 0x100;
buffer.Copy((byte)num);
buffer.Copy((byte)num2);
}
length *= 2;
if (explicitTagging)
{
length += buffer.EncodeTagAndLength(Tag, length);
}
return length;
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
outs.EncodeBmpString(Value, explicitTagging, Tag);
}
private static void ReadSegment(Asn1DecodeBuffer buffer, StringBuilder sb, int len)
{
if ((len % 2) != 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
}
while (len > 0)
{
var num = buffer.Read();
if (num == -1)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
}
var num2 = num * 0x100;
len--;
num = buffer.Read();
if (num == -1)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
}
num2 += num;
len--;
sb.Append((char)num2);
}
}
}
}

View File

@@ -0,0 +1,102 @@
using System;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1Boolean : Asn1Type
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BooleanTypeCode);
public static readonly Asn1Boolean FalseValue = new Asn1Boolean(false);
public static readonly Asn1Boolean TrueValue = new Asn1Boolean(true);
[NonSerialized]
public bool Value;
public Asn1Boolean()
{
Value = false;
}
public Asn1Boolean(bool value)
{
Value = value;
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
if (explicitTagging)
{
MatchTag(buffer, Tag);
}
var num = buffer.Read();
if (num < 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
}
buffer.TypeCode = BooleanTypeCode;
Value = num != 0;
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = 1;
buffer.Copy(Value ? byte.MaxValue : ((byte)0));
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Tag, len);
}
return len;
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
if (explicitTagging)
{
outs.EncodeTag(Tag);
}
outs.EncodeLength(1);
outs.WriteByte(Value ? -1 : 0);
}
public virtual bool Equals(bool value)
{
return (Value == value);
}
public override bool Equals(object value)
{
var flag = value as Asn1Boolean;
if (flag == null)
{
return false;
}
return (Value == flag.Value);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public override string ToString()
{
if (!Value)
{
return "FALSE";
}
return "TRUE";
}
}
}

View File

@@ -0,0 +1,12 @@
using System.IO;
namespace GostCryptography.Asn1.Ber
{
public class Asn1CerInputStream : Asn1BerInputStream
{
public Asn1CerInputStream(Stream inputStream)
: base(inputStream)
{
}
}
}

View File

@@ -0,0 +1,236 @@
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();
}
}
}
}

View File

@@ -0,0 +1,46 @@
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
public class Asn1CharRange : Asn1CharSet
{
private readonly int _lower;
private readonly int _upper;
public Asn1CharRange(int lower, int upper)
: base((upper - lower) + 1)
{
_lower = lower;
_upper = upper;
}
public override int MaxValue
{
get { return _upper; }
}
public override int GetCharAtIndex(int index)
{
index += _lower;
if (index > _upper)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", index);
}
return index;
}
public override int GetCharIndex(int charValue)
{
var num = charValue - _lower;
if (num < 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", charValue);
}
return num;
}
}
}

View File

@@ -0,0 +1,35 @@
namespace GostCryptography.Asn1.Ber
{
public abstract class Asn1CharSet
{
private readonly int _aBitsPerChar;
private readonly int _uBitsPerChar;
protected internal Asn1CharSet(int nchars)
{
_uBitsPerChar = Asn1Integer.GetBitCount(nchars - 1);
_aBitsPerChar = 1;
while (_uBitsPerChar > _aBitsPerChar)
{
_aBitsPerChar = _aBitsPerChar << 1;
}
}
public abstract int MaxValue { get; }
public abstract int GetCharAtIndex(int index);
public abstract int GetCharIndex(int charValue);
public virtual int GetNumBitsPerChar(bool aligned)
{
if (!aligned)
{
return _uBitsPerChar;
}
return _aBitsPerChar;
}
}
}

View File

@@ -0,0 +1,156 @@
using System;
using System.Text;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public abstract class Asn1CharString : Asn1Type
{
[NonSerialized]
protected StringBuilder StringBuffer;
[NonSerialized]
private readonly short _typeCode;
[NonSerialized]
public string Value;
protected internal Asn1CharString(short typeCode)
{
Value = new StringBuilder().ToString();
_typeCode = typeCode;
}
protected internal Asn1CharString(string data, short typeCode)
{
Value = data;
_typeCode = typeCode;
}
public override int Length
{
get { return Value.Length; }
}
protected virtual void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength, Asn1Tag tag)
{
int num2;
var elemLength = explicitTagging ? MatchTag(buffer, tag) : implicitLength;
var num3 = elemLength;
var num4 = 0;
if (StringBuffer == null)
{
StringBuffer = new StringBuilder();
}
var lastTag = buffer.LastTag;
if ((lastTag == null) || !lastTag.Constructed)
{
if (num3 < 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
}
StringBuffer.Length = num3;
while (num3 > 0)
{
num2 = buffer.Read();
if (num2 == -1)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
}
StringBuffer[num4++] = (char)num2;
num3--;
}
}
else
{
var capacity = 0;
var context = new Asn1BerDecodeContext(buffer, elemLength);
while (!context.Expired())
{
var num5 = MatchTag(buffer, Asn1OctetString.Tag);
if (num5 <= 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
}
capacity += num5;
StringBuffer.EnsureCapacity(capacity);
while (num5 > 0)
{
num2 = buffer.Read();
if (num2 == -1)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
}
StringBuffer.Append((char)num2);
num5--;
}
}
if (elemLength == Asn1Status.IndefiniteLength)
{
MatchTag(buffer, Asn1Tag.Eoc);
}
}
Value = StringBuffer.ToString();
buffer.TypeCode = (short)tag.IdCode;
}
protected virtual int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging, Asn1Tag tag)
{
var length = Value.Length;
buffer.Copy(Value);
if (explicitTagging)
{
length += buffer.EncodeTagAndLength(tag, length);
}
return length;
}
public override bool Equals(object value)
{
var str = value as Asn1CharString;
if (str == null)
{
return false;
}
return Equals(str.Value);
}
public bool Equals(string value)
{
return Value.Equals(value);
}
public override int GetHashCode()
{
return (Value != null) ? Value.GetHashCode() : base.GetHashCode();
}
public override string ToString()
{
return Value;
}
}
}

View File

@@ -0,0 +1,55 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public abstract class Asn1Choice : Asn1Type
{
[NonSerialized]
private int _choiceId;
[NonSerialized]
protected Asn1Type Element;
public virtual int ChoiceId => _choiceId;
public abstract string ElemName { get; }
public virtual Asn1Type GetElement()
{
return Element;
}
public virtual void SetElement(int choiceId, Asn1Type element)
{
_choiceId = choiceId;
Element = element;
}
public override bool Equals(object value)
{
var choice = value as Asn1Choice;
if (choice == null)
{
return false;
}
if (_choiceId != choice._choiceId)
{
return false;
}
return Element.Equals(choice.Element);
}
public override int GetHashCode()
{
return Element?.GetHashCode() ?? base.GetHashCode();
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1ChoiceExt : Asn1OpenType
{
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
base.Decode(buffer, false, 0);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
return base.Encode(buffer, false);
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
base.Encode(outs, false);
}
}
}

View File

@@ -0,0 +1,326 @@
using System;
using System.Collections;
using System.IO;
using GostCryptography.Properties;
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);
}
}
}

View File

@@ -0,0 +1,17 @@
using System.IO;
namespace GostCryptography.Asn1.Ber
{
public class Asn1DerDecodeBuffer : Asn1BerDecodeBuffer
{
public Asn1DerDecodeBuffer(byte[] msgdata)
: base(msgdata)
{
}
public Asn1DerDecodeBuffer(Stream inputStream)
: base(inputStream)
{
}
}
}

View File

@@ -0,0 +1,16 @@
namespace GostCryptography.Asn1.Ber
{
public class Asn1DerEncodeBuffer : Asn1BerEncodeBuffer
{
public Asn1DerEncodeBuffer()
{
ByteIndex = SizeIncrement - 1;
}
public Asn1DerEncodeBuffer(int sizeIncrement)
: base(sizeIncrement)
{
ByteIndex = SizeIncrement - 1;
}
}
}

View File

@@ -0,0 +1,42 @@
using System.IO;
namespace GostCryptography.Asn1.Ber
{
public class Asn1DerInputStream : Asn1DerDecodeBuffer, IAsn1InputStream
{
public Asn1DerInputStream(Stream inputStream)
: base(inputStream)
{
}
public virtual int Available()
{
var inputStream = GetInputStream();
if (inputStream != null)
{
var num = inputStream.Length - inputStream.Position;
return (int)num;
}
return 0;
}
public virtual void Close()
{
var inputStream = GetInputStream();
if (inputStream != null)
{
inputStream.Close();
}
}
public virtual bool MarkSupported()
{
var inputStream = GetInputStream();
return ((inputStream != null) && inputStream.CanSeek);
}
}
}

View File

@@ -0,0 +1,58 @@
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
public class Asn1DiscreteCharSet : Asn1CharSet
{
private readonly int[] _charSet;
public Asn1DiscreteCharSet(string charSet)
: base(charSet.Length)
{
_charSet = new int[charSet.Length];
for (var i = 0; i < _charSet.Length; i++)
{
_charSet[i] = charSet[i];
}
}
public Asn1DiscreteCharSet(int[] charSet)
: base(charSet.Length)
{
_charSet = charSet;
}
public override int MaxValue
{
get { return _charSet[_charSet.Length - 1]; }
}
public override int GetCharAtIndex(int index)
{
if (index >= _charSet.Length)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", index);
}
return _charSet[index];
}
public override int GetCharIndex(int charValue)
{
var index = 0;
while ((index < _charSet.Length) && (_charSet[index] != charValue))
{
index++;
}
if (index >= _charSet.Length)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", charValue);
}
return index;
}
}
}

View File

@@ -0,0 +1,84 @@
using System;
using System.IO;
namespace GostCryptography.Asn1.Ber
{
public abstract class Asn1EncodeBuffer : Asn1MessageBuffer
{
public const int DefaultSizeIncrement = 0x400;
protected byte[] Data;
protected int ByteIndex;
protected int SizeIncrement;
protected Asn1EncodeBuffer()
{
InitBuffer(DefaultSizeIncrement);
}
protected Asn1EncodeBuffer(int sizeIncrement)
{
if (sizeIncrement == 0)
{
sizeIncrement = DefaultSizeIncrement;
}
InitBuffer(sizeIncrement);
}
public abstract byte[] MsgCopy { get; }
public abstract int MsgLength { get; }
public virtual void BinDump(string varName)
{
var outs = new StreamWriter(Console.OpenStandardOutput(), Console.Out.Encoding)
{
AutoFlush = true
};
BinDump(outs, varName);
}
public abstract void BinDump(StreamWriter outs, string varName);
protected internal virtual void CheckSize(int bytesRequired)
{
if ((ByteIndex + bytesRequired) > Data.Length)
{
var num = ((bytesRequired - 1) / SizeIncrement) + 1;
var num2 = num * SizeIncrement;
var destinationArray = new byte[Data.Length + num2];
Array.Copy(Data, 0, destinationArray, 0, ByteIndex + 1);
Data = destinationArray;
}
}
public abstract void Copy(byte value);
public abstract void Copy(byte[] value);
public virtual void HexDump()
{
HexDump(GetInputStream());
}
public virtual void HexDump(StreamWriter outs)
{
HexDump(GetInputStream(), outs);
}
protected virtual void InitBuffer(int sizeIncrement)
{
SizeIncrement = sizeIncrement;
Data = new byte[SizeIncrement];
ByteIndex = 0;
}
public abstract void Reset();
public abstract void Write(Stream outs);
}
}

View File

@@ -0,0 +1,80 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public abstract class Asn1Enumerated : Asn1Type
{
public const int Undefined = -999;
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, EnumeratedTypeCode);
[NonSerialized]
public int Value;
public Asn1Enumerated()
{
Value = Undefined;
}
public Asn1Enumerated(int value)
{
Value = value;
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
Value = (int)Asn1RunTime.DecodeIntValue(buffer, length, true);
buffer.TypeCode = EnumeratedTypeCode;
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = buffer.EncodeIntValue(Value);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Tag, len);
}
return len;
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
if (explicitTagging)
{
outs.EncodeTag(Tag);
}
outs.EncodeIntValue(Value, true);
}
public virtual bool Equals(int value)
{
return (Value == value);
}
public override bool Equals(object value)
{
var enumerated = value as Asn1Enumerated;
return (enumerated != null && Value == enumerated.Value);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public virtual int ParseValue(string value)
{
return -1;
}
public override string ToString()
{
return null;
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1GeneralString : Asn1VarWidthCharString
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, GeneralStringTypeCode);
public Asn1GeneralString()
: base(GeneralStringTypeCode)
{
}
public Asn1GeneralString(string data)
: base(data, GeneralStringTypeCode)
{
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
Decode(buffer, explicitTagging, implicitLength, Tag);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
return Encode(buffer, explicitTagging, Tag);
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
outs.EncodeCharString(Value, explicitTagging, Tag);
}
}
}

View File

@@ -0,0 +1,344 @@
using System;
using System.Text;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1GeneralizedTime : Asn1Time
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, GeneralTimeTypeCode);
public Asn1GeneralizedTime()
: base(GeneralTimeTypeCode, false)
{
}
public Asn1GeneralizedTime(bool useDerRules)
: base(GeneralTimeTypeCode, useDerRules)
{
}
public Asn1GeneralizedTime(string data)
: base(data, GeneralTimeTypeCode, false)
{
}
public Asn1GeneralizedTime(string data, bool useDerRules)
: base(data, GeneralTimeTypeCode, useDerRules)
{
}
public virtual int Century
{
get
{
var yearValue = Year;
if (yearValue < 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, yearValue);
}
return (yearValue / 100);
}
set
{
if ((value < 0) || (value > 0x63))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidCenturyValue, value);
}
SafeParseString();
YearValue = (value * 100) + (YearValue % 100);
CompileString();
}
}
protected override bool CompileString()
{
int minuteValue;
if (((YearValue < 0) || (MonthValue <= 0)) || ((DayValue <= 0) || (HourValue < 0)))
{
return false;
}
Value = "";
if (StringBuffer == null)
{
StringBuffer = new StringBuilder();
}
else
{
StringBuffer.Length = 0;
}
if ((DerRules || UtcFlag) && ((DiffHourValue != 0) || (DiffMinValue != 0)))
{
var time = GetTime();
time.AddMinutes(-DiffMinValue);
time.AddHours(-DiffHourValue);
PutInteger(4, time.Year);
PutInteger(2, time.Month);
PutInteger(2, time.Day);
PutInteger(2, time.Hour);
minuteValue = time.Minute;
}
else
{
PutInteger(4, YearValue);
PutInteger(2, MonthValue);
PutInteger(2, DayValue);
PutInteger(2, HourValue);
minuteValue = MinuteValue;
}
if ((DerRules || (minuteValue > 0)) || ((SecondValue > 0) || (SecFraction.Length > 0)))
{
PutInteger(2, minuteValue);
if ((DerRules || (SecondValue > 0)) || (SecFraction.Length > 0))
{
PutInteger(2, SecondValue);
if (SecFraction.Length > 0)
{
StringBuffer.Append('.');
StringBuffer.Append(SecFraction);
}
}
}
if (DerRules || UtcFlag)
{
StringBuffer.Append('Z');
}
else if ((DiffHourValue != 0) || (DiffMinValue != 0))
{
StringBuffer.Append((DiffHourValue > 0) ? '+' : '-');
if (DiffMinValue != 0)
{
PutInteger(2, Math.Abs(DiffHourValue));
PutInteger(2, Math.Abs(DiffMinValue));
}
else
{
PutInteger(2, Math.Abs(DiffHourValue));
}
}
Value = StringBuffer.ToString();
return true;
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
Decode(buffer, explicitTagging, implicitLength, Tag);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
return Encode(buffer, explicitTagging, Tag);
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
Encode(outs, explicitTagging, Tag);
}
public override void ParseString(string data)
{
if (data == null)
{
throw ExceptionUtility.ArgumentNull("data");
}
Clear();
var off = new IntHolder(0);
try
{
YearValue = ParseInt(data, off, 4);
MonthValue = ParseInt(data, off, 2);
DayValue = ParseInt(data, off, 2);
if (YearValue < 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, YearValue);
}
if ((MonthValue < 1) || (MonthValue > 12))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMonthValue, MonthValue);
}
int num = DaysInMonth[MonthValue];
if (((MonthValue == 2) && ((YearValue % 4) == 0)) && (((YearValue % 100) != 0) || ((YearValue % 400) == 0)))
{
num++;
}
if ((DayValue < 1) || (DayValue > num))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDayValue, DayValue);
}
var num2 = 0;
if (!char.IsDigit(CharAt(data, off.Value)))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1HoursExpected);
}
HourValue = ParseInt(data, off, 2);
num2++;
if (char.IsDigit(CharAt(data, off.Value)))
{
MinuteValue = ParseInt(data, off, 2);
num2++;
if (char.IsDigit(CharAt(data, off.Value)))
{
SecondValue = ParseInt(data, off, 2);
num2++;
}
}
if ((num2 >= 1) && ((HourValue < 0) || (HourValue > 0x17)))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidHourValue, HourValue);
}
if ((num2 >= 2) && ((MinuteValue < 0) || (MinuteValue > 0x3b)))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMinuteValue, MinuteValue);
}
if ((num2 == 3) && ((SecondValue < 0) || (SecondValue > 0x3b)))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidSecondValue, SecondValue);
}
var ch = CharAt(data, off.Value);
if (DerRules && (ch == ','))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDecimalMark);
}
if ((ch == '.') || (ch == ','))
{
off.Value++;
if (num2 != 3)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedSymbol);
}
var length = 0;
while (char.IsDigit(CharAt(data, off.Value + length)))
{
length++;
}
if (length == 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedSymbol);
}
SecFraction = data.Substring(off.Value, length);
off.Value += length;
}
if (CharAt(data, off.Value) == 'Z')
{
off.Value++;
UtcFlag = true;
if (off.Value != data.Length)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedValuesAtEndOfString);
}
}
else
{
if (DerRules)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedZoneOffset);
}
UtcFlag = false;
var ch2 = CharAt(data, off.Value);
switch (ch2)
{
case '-':
case '+':
off.Value++;
if (!char.IsDigit(CharAt(data, off.Value)))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHour);
}
DiffHourValue = ParseInt(data, off, 2);
if (char.IsDigit(CharAt(data, off.Value)))
{
DiffMinValue = ParseInt(data, off, 2);
}
if ((DiffHourValue < 0) || (DiffHourValue > 12))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHourValue, DiffHourValue);
}
if ((DiffMinValue < 0) || (DiffMinValue > 0x3b))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffMinuteValue, DiffMinValue);
}
if (ch2 == '-')
{
DiffHourValue = -DiffHourValue;
DiffMinValue = -DiffMinValue;
}
break;
}
}
Parsed = true;
if (data != Value)
{
CompileString();
}
}
catch (IndexOutOfRangeException)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDateFormat);
}
catch (FormatException)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidNumberFormat);
}
catch (ArgumentException)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDateFormat);
}
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1GraphicString : Asn1VarWidthCharString
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, GraphicStringTypeCode);
public Asn1GraphicString()
: base(GraphicStringTypeCode)
{
}
public Asn1GraphicString(string data)
: base(data, GraphicStringTypeCode)
{
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
Decode(buffer, explicitTagging, implicitLength, Tag);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
return Encode(buffer, explicitTagging, Tag);
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
outs.EncodeCharString(base.Value, explicitTagging, Tag);
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1Ia5String : Asn18BitCharString
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, Ia5StringTypeCode);
public Asn1Ia5String()
: base(Ia5StringTypeCode)
{
}
public Asn1Ia5String(string data)
: base(data, Ia5StringTypeCode)
{
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
Decode(buffer, explicitTagging, implicitLength, Tag);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
return Encode(buffer, explicitTagging, Tag);
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
outs.EncodeCharString(Value, explicitTagging, Tag);
}
}
}

View File

@@ -0,0 +1,91 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1Integer : Asn1Type
{
public const int SizeOfInt = 4;
public const int SizeOfLong = 8;
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BigIntegerTypeCode);
[NonSerialized]
public long Value;
public Asn1Integer()
{
Value = 0L;
}
public Asn1Integer(long value)
{
Value = value;
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
Value = Asn1RunTime.DecodeIntValue(buffer, length, true);
buffer.TypeCode = BigIntegerTypeCode;
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = buffer.EncodeIntValue(Value);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Tag, len);
}
return len;
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
if (explicitTagging)
{
outs.EncodeTag(Tag);
}
outs.EncodeIntValue(Value, true);
}
public virtual bool Equals(long value)
{
return (Value == value);
}
public override bool Equals(object value)
{
var integer = value as Asn1Integer;
if (integer == null)
{
return false;
}
return (Value == integer.Value);
}
public virtual int GetBitCount()
{
return Asn1RunTime.GetLongBitCount(Value);
}
public static int GetBitCount(long ivalue)
{
return Asn1RunTime.GetLongBitCount(ivalue);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public override string ToString()
{
return Convert.ToString(Value);
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.IO;
namespace GostCryptography.Asn1.Ber
{
public abstract class Asn1MessageBuffer
{
public abstract Stream GetInputStream();
public static void HexDump(Stream ins)
{
var outs = new StreamWriter(Console.OpenStandardOutput(), Console.Out.Encoding)
{
AutoFlush = true
};
HexDump(ins, outs);
}
public static void HexDump(Stream ins, StreamWriter outs)
{
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1Null : Asn1Type
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, NullTypeCode);
public static readonly Asn1Null NullValue = new Asn1Null();
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
if (explicitTagging)
{
MatchTag(buffer, Tag);
}
buffer.TypeCode = NullTypeCode;
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = 0;
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Tag, len);
}
return len;
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
if (explicitTagging)
{
outs.EncodeTag(Tag);
}
outs.EncodeLength(0);
}
public override string ToString()
{
return "NULL";
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1NumericString : Asn18BitCharString
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, NumericStringTypeCode);
public Asn1NumericString()
: base(NumericStringTypeCode)
{
}
public Asn1NumericString(string data)
: base(data, NumericStringTypeCode)
{
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
Decode(buffer, explicitTagging, implicitLength, Tag);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
return Encode(buffer, explicitTagging, Tag);
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
outs.EncodeCharString(Value, explicitTagging, Tag);
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1ObjectDescriptor : Asn1VarWidthCharString
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, ObjectDescriptorTypeCode);
public Asn1ObjectDescriptor()
: base(ObjectDescriptorTypeCode)
{
}
public Asn1ObjectDescriptor(string data)
: base(data, ObjectDescriptorTypeCode)
{
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
Decode(buffer, explicitTagging, implicitLength, Tag);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
return Encode(buffer, explicitTagging, Tag);
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
outs.EncodeCharString(Value, explicitTagging, Tag);
}
}
}

View File

@@ -0,0 +1,137 @@
using System;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1ObjectIdentifier : Asn1Type
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, ObjectIdentifierTypeCode);
[NonSerialized]
protected OidValue OidValue;
public OidValue Oid => OidValue;
public Asn1ObjectIdentifier()
{
OidValue = null;
}
public Asn1ObjectIdentifier(OidValue oidValue)
{
OidValue = oidValue;
}
public static Asn1ObjectIdentifier FromString(string value)
{
return string.IsNullOrEmpty(value) ? null : new Asn1ObjectIdentifier(OidValue.FromString(value));
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var len = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
if (len <= 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
}
OidValue = OidValue.FromArray(buffer.DecodeOidContents(len));
buffer.TypeCode = ObjectIdentifierTypeCode;
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
if (((OidValue.Items.Length < 2) || (OidValue.Items[0] > 2)) || ((OidValue.Items[0] != 2) && (OidValue.Items[1] > 0x27)))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
}
var len = 0;
for (var i = OidValue.Items.Length - 1; i >= 1; i--)
{
len += buffer.EncodeIdentifier((i == 1) ? ((OidValue.Items[0] * 40) + OidValue.Items[1]) : OidValue.Items[i]);
}
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Tag, len);
}
return len;
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
if (((OidValue.Items.Length < 2) || (OidValue.Items[0] > 2)) || ((OidValue.Items[0] != 2) && (OidValue.Items[1] > 0x27)))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
}
var len = 1;
for (var i = 2; i < OidValue.Items.Length; i++)
{
len += Asn1RunTime.GetIdentBytesCount(OidValue.Items[i]);
}
if (explicitTagging)
{
outs.EncodeTag(Tag);
}
outs.EncodeLength(len);
var ident = (OidValue.Items[0] * 40) + OidValue.Items[1];
outs.EncodeIdentifier(ident);
for (var i = 2; i < OidValue.Items.Length; i++)
{
outs.EncodeIdentifier(OidValue.Items[i]);
}
}
public override bool Equals(object obj)
{
if (this == obj)
{
return true;
}
if (!(obj is Asn1ObjectIdentifier))
{
return false;
}
var other = (Asn1ObjectIdentifier)obj;
if (OidValue == other.OidValue)
{
return true;
}
if (OidValue == null || other.OidValue == null)
{
return false;
}
return OidValue.Equals(other.OidValue);
}
public override int GetHashCode()
{
return OidValue?.GetHashCode() ?? base.GetHashCode();
}
public override string ToString()
{
return OidValue?.ToString() ?? base.ToString();
}
}
}

View File

@@ -0,0 +1,235 @@
using System;
using System.IO;
using System.Text;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1OctetString : Asn1Type, IComparable
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, OctetStringTypeCode);
[NonSerialized]
public byte[] Value;
public Asn1OctetString()
{
Value = null;
}
public Asn1OctetString(byte[] data)
{
Value = data;
}
public Asn1OctetString(string value)
{
Value = string.IsNullOrEmpty(value) ? new byte[0] : Asn1Value.ParseString(value);
}
public Asn1OctetString(byte[] data, int offset, int nbytes)
{
Value = new byte[nbytes];
if (data != null)
{
Array.Copy(data, offset, Value, 0, nbytes);
}
}
public override int Length
{
get { return Value.Length; }
}
public virtual int CompareTo(object octstr)
{
var value = ((Asn1OctetString)octstr).Value;
var num = (Value.Length < value.Length) ? Value.Length : value.Length;
for (var i = 0; i < num; i++)
{
var num2 = Value[i] & 0xff;
var num3 = value[i] & 0xff;
if (num2 < num3)
{
return -1;
}
if (num2 > num3)
{
return 1;
}
}
if (Value.Length == value.Length)
{
return 0;
}
if (Value.Length < value.Length)
{
return -1;
}
return 1;
}
private void AllocByteArray(int nbytes)
{
if (Value == null)
{
Value = new byte[nbytes];
}
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var elemLength = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
var lastTag = buffer.LastTag;
if ((lastTag == null) || !lastTag.Constructed)
{
if (elemLength < 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
}
Value = new byte[elemLength];
if (elemLength != 0)
{
buffer.Read(Value);
}
}
else
{
var nbytes = 0;
var offset = 0;
var context = new Asn1BerDecodeContext(buffer, elemLength);
while (!context.Expired())
{
var num2 = MatchTag(buffer, Tag);
if (num2 <= 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
}
nbytes += num2;
if (offset == 0)
{
Value = new byte[nbytes];
}
else
{
ReAllocByteArray(nbytes);
}
buffer.Read(Value, offset, num2);
offset = nbytes;
}
if (elemLength == Asn1Status.IndefiniteLength)
{
MatchTag(buffer, Asn1Tag.Eoc);
}
}
buffer.TypeCode = OctetStringTypeCode;
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
if (Value == null)
{
Value = new byte[0];
}
var length = Value.Length;
if (length != 0)
{
buffer.Copy(Value);
}
if (explicitTagging)
{
length += buffer.EncodeTagAndLength(Tag, length);
}
return length;
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
outs.EncodeOctetString(Value, explicitTagging, Tag);
}
public bool Equals(byte[] value)
{
if (value.Length != Value.Length)
{
return false;
}
for (var i = 0; i < value.Length; i++)
{
if (value[i] != Value[i])
{
return false;
}
}
return true;
}
public override bool Equals(object value)
{
var str = value as Asn1OctetString;
return (str != null) && Equals(str.Value);
}
public override int GetHashCode()
{
return (Value != null) ? Value.GetHashCode() : base.GetHashCode();
}
private void ReAllocByteArray(int nbytes)
{
var value = Value;
Value = new byte[nbytes];
if (value != null)
{
Array.Copy(value, 0, Value, 0, value.Length);
}
}
public virtual Stream ToInputStream()
{
return new MemoryStream(Value, 0, Value.Length);
}
public override string ToString()
{
var str = new StringBuilder("").ToString();
if (Value != null)
{
foreach (var b in Value)
{
str = str + Asn1Util.ToHexString(b);
}
}
return str;
}
}
}

View File

@@ -0,0 +1,86 @@
using System;
using System.Collections;
using System.Text;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1OpenExt : Asn1Type
{
[NonSerialized]
public ArrayList Value = new ArrayList();
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
DecodeComponent(buffer);
}
public virtual void DecodeComponent(Asn1BerDecodeBuffer buffer)
{
var type = new Asn1OpenType();
type.Decode(buffer, false, 0);
Value.Add(type);
}
public virtual void DecodeEventComponent(Asn1BerDecodeBuffer buffer)
{
buffer.InvokeStartElement("...", -1);
var type = new Asn1OpenType();
type.Decode(buffer, false, 0);
Value.Add(type);
buffer.InvokeCharacters(type.ToString());
buffer.InvokeEndElement("...", -1);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var num = 0;
for (var i = Value.Count - 1; i >= 0; i--)
{
var type = (Asn1OpenType)Value[i];
num += type.Encode(buffer, false);
}
return num;
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
foreach (Asn1OpenType type in Value)
{
if (type != null)
{
type.Encode(outs, false);
}
}
}
public override string ToString()
{
if (Value == null)
{
return "<null>";
}
var builder = new StringBuilder();
for (var i = 0; i < Value.Count; i++)
{
var type = (Asn1OpenType)Value[i];
if (i != 0)
{
builder.Append(", ");
}
builder.Append(type);
}
return builder.ToString();
}
}
}

View File

@@ -0,0 +1,103 @@
using System;
using System.IO;
using System.Text;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1OpenType : Asn1OctetString
{
private const string EncodedDataMessage = "ENCODED DATA";
[NonSerialized]
private readonly Asn1EncodeBuffer _encodeBuffer;
[NonSerialized]
private readonly int _length;
[NonSerialized]
private readonly bool _textEncoding;
public Asn1OpenType()
{
_length = 0;
_textEncoding = false;
}
public Asn1OpenType(byte[] data)
: base(data)
{
_length = 0;
_textEncoding = false;
}
public Asn1OpenType(Asn1EncodeBuffer buffer)
{
if (buffer is Asn1BerEncodeBuffer)
{
_length = buffer.MsgLength;
_encodeBuffer = buffer;
}
else
{
Value = buffer.MsgCopy;
}
_textEncoding = false;
}
public Asn1OpenType(byte[] data, int offset, int nbytes)
: base(data, offset, nbytes)
{
_length = 0;
_textEncoding = false;
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
Value = buffer.DecodeOpenType();
buffer.TypeCode = OpenTypeTypeCode;
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
if (Value == null)
{
return _length;
}
return base.Encode(buffer, false);
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
if (Value != null)
{
outs.Write(Value);
}
}
public override string ToString()
{
if (Value != null)
{
try
{
return (_textEncoding ? Encoding.UTF8.GetString(Value, 0, Value.Length) : base.ToString());
}
catch (IOException)
{
return null;
}
}
if (_encodeBuffer != null)
{
return _encodeBuffer.ToString();
}
return EncodedDataMessage;
}
}
}

View File

@@ -0,0 +1,87 @@
using System.IO;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
public abstract class Asn1OutputStream : Stream
{
protected readonly Stream OutputStream;
public Asn1OutputStream(Stream outputStream)
{
OutputStream = outputStream;
}
public override bool CanRead
{
get { return false; }
}
public override bool CanSeek
{
get { return OutputStream.CanSeek; }
}
public override bool CanWrite
{
get { return OutputStream.CanWrite; }
}
public override long Length
{
get { return OutputStream.Length; }
}
public override long Position
{
get { return OutputStream.Position; }
set { OutputStream.Position = value; }
}
public override void Close()
{
OutputStream.Close();
}
public override void Flush()
{
OutputStream.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
throw ExceptionUtility.NotSupported(Resources.Asn1ReadOutputStreamNotSupported);
}
public override long Seek(long offset, SeekOrigin origin)
{
return OutputStream.Seek(offset, origin);
}
public override void SetLength(long value)
{
OutputStream.SetLength(value);
}
public virtual void Write(byte[] b)
{
OutputStream.Write(b, 0, b.Length);
}
public override void Write(byte[] b, int off, int len)
{
OutputStream.Write(b, off, len);
}
public override void WriteByte(byte b)
{
OutputStream.WriteByte(b);
}
public virtual void WriteByte(int b)
{
OutputStream.WriteByte((byte)b);
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1PrintableString : Asn18BitCharString
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, PrintableStringTypeCode);
public Asn1PrintableString()
: base(PrintableStringTypeCode)
{
}
public Asn1PrintableString(string data)
: base(data, PrintableStringTypeCode)
{
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
Decode(buffer, explicitTagging, implicitLength, Tag);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
return Encode(buffer, explicitTagging, Tag);
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
outs.EncodeCharString(Value, explicitTagging, Tag);
}
}
}

View File

@@ -0,0 +1,371 @@
using System;
using System.Text;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1Real : Asn1Type
{
private const int MinusInfinity = 0x41;
private const int PlusInfinity = 0x40;
private const int RealBase2 = 0;
private const int RealBase8 = 0x10;
private const int RealBase16 = 0x20;
private const int RealBaseMask = 0x30;
private const int RealBinary = 0x80;
private const int RealExplen1 = 0;
private const int RealExplen2 = 1;
private const int RealExplen3 = 2;
private const int RealExplenLong = 3;
private const int RealExplenMask = 3;
private const int RealFactorMask = 12;
private const int RealIso6093Mask = 0x3f;
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, RealTypeCode);
[NonSerialized]
public double Value;
public Asn1Real()
{
Value = 0.0;
}
public Asn1Real(double value)
{
Value = value;
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
if (length == 0)
{
Value = 0.0;
}
else
{
var num2 = buffer.ReadByte();
if (length == 1)
{
switch (num2)
{
case PlusInfinity:
Value = double.PositiveInfinity;
return;
case MinusInfinity:
Value = double.NegativeInfinity;
return;
}
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
}
length--;
if ((num2 & RealBinary) == 0)
{
var num8 = length;
var num9 = 0;
var builder = new StringBuilder { Length = num8 };
while (num8 > 0)
{
var num7 = buffer.Read();
if (num7 == -1)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
}
builder[num9++] = (char)num7;
num8--;
}
var num10 = num2 & RealIso6093Mask;
var num11 = 0;
for (var i = 0; i < builder.Length; i++)
{
var ch = builder[i];
if ((num10 >= 2) && (ch == ','))
{
builder[i] = '.';
num11++;
}
else if (((num10 >= 1) && (((ch >= '0') && (ch <= '9')) || ((ch == '+') || (ch == '-')))) || (((num10 >= 2) && (ch == '.')) || ((num10 == 3) && ((ch == 'E') || (ch == 'e')))))
{
num11++;
}
else if ((num11 != 0) || (ch != ' '))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
}
}
try
{
Value = double.Parse(builder.ToString());
}
catch (FormatException)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
}
}
else
{
int num6;
int num3;
switch ((num2 & RealExplenMask))
{
case RealExplen1:
num3 = 1;
break;
case RealExplen2:
num3 = 2;
break;
case RealExplen3:
num3 = 3;
break;
default:
num3 = buffer.ReadByte();
length--;
break;
}
var num4 = (int)Asn1RunTime.DecodeIntValue(buffer, num3, true);
length -= num3;
var num5 = Asn1RunTime.DecodeIntValue(buffer, length, false) * (1L << ((num2 & RealFactorMask) >> 2));
switch ((num2 & RealBaseMask))
{
case RealBase2:
num6 = 2;
break;
case RealBase8:
num6 = 8;
break;
case RealBase16:
num6 = 16;
break;
default:
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
}
Value = num5 * Math.Pow(num6, num4);
if ((num2 & PlusInfinity) != 0)
{
Value = -Value;
}
}
buffer.TypeCode = RealTypeCode;
}
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = 0;
if (double.IsNegativeInfinity(Value))
{
len = buffer.EncodeIntValue(MinusInfinity);
}
else if (double.IsPositiveInfinity(Value))
{
len = buffer.EncodeIntValue(PlusInfinity);
}
else if (Value != 0.0)
{
var num2 = BitConverter.DoubleToInt64Bits(Value);
var num3 = ((num2 >> RealIso6093Mask) == 0L) ? 1 : -1;
var num4 = ((int)((num2 >> 0x34) & 0x7ffL)) - 0x433;
var w = (num4 == 0) ? ((num2 & 0xfffffffffffffL) << 1) : ((num2 & 0xfffffffffffffL) | 0x10000000000000L);
if (w != 0L)
{
var bits = TrailingZerosCnt(w);
w = Asn1Util.UrShift(w, bits);
num4 += bits;
}
len += buffer.EncodeIntValue(w);
var num7 = buffer.EncodeIntValue(num4);
len += num7;
var num8 = RealBinary;
if (num3 == -1)
{
num8 |= PlusInfinity;
}
switch (num7)
{
case RealExplen2:
break;
case RealExplen3:
num8 |= 1;
break;
case RealExplenLong:
num8 |= 2;
break;
default:
num8 |= 3;
len += buffer.EncodeIntValue(num7);
break;
}
buffer.Copy((byte)num8);
len++;
}
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Tag, len);
}
return len;
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
if (explicitTagging)
{
outs.EncodeTag(Tag);
}
if (Value == 0.0)
{
outs.EncodeLength(0);
}
else if (Value == double.NegativeInfinity)
{
outs.EncodeIntValue(MinusInfinity, true);
}
else if (Value == double.PositiveInfinity)
{
outs.EncodeIntValue(PlusInfinity, true);
}
else
{
var len = 1;
var num2 = BitConverter.DoubleToInt64Bits(Value);
var num3 = ((num2 >> RealIso6093Mask) == 0L) ? 1 : -1;
var num4 = ((int)((num2 >> 0x34) & 0x7ffL)) - 0x433;
var w = (num4 == 0) ? ((num2 & 0xfffffffffffffL) << 1) : ((num2 & 0xfffffffffffffL) | 0x10000000000000L);
if (w != 0L)
{
var bits = TrailingZerosCnt(w);
w = Asn1Util.UrShift(w, bits);
num4 += bits;
len += Asn1Util.GetUlongBytesCount(w);
}
else
{
len++;
}
var num7 = RealBinary;
if (num3 == -1)
{
num7 |= PlusInfinity;
}
var bytesCount = Asn1Util.GetBytesCount(num4);
len += bytesCount;
switch (bytesCount)
{
case RealExplen2:
break;
case RealExplen3:
num7 |= 1;
break;
case RealExplenLong:
num7 |= 2;
break;
default:
num7 |= 3;
len++;
break;
}
outs.EncodeLength(len);
outs.WriteByte((byte)num7);
if ((num7 & 3) == 3)
{
outs.EncodeIntValue(bytesCount, false);
}
outs.EncodeIntValue(num4, false);
outs.EncodeIntValue(w, false);
}
}
public virtual bool Equals(double value)
{
return (Value == value);
}
public override bool Equals(object value)
{
var real = value as Asn1Real;
if (real == null)
{
return false;
}
return (Value == real.Value);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public override string ToString()
{
return Value.ToString();
}
private static int TrailingZerosCnt(long w)
{
var num = Asn1RunTime.IntTrailingZerosCnt((int)w);
if (num >= RealBase16)
{
return (Asn1RunTime.IntTrailingZerosCnt((int)Asn1Util.UrShift(w, RealBase16)) + RealBase16);
}
return num;
}
}
}

View File

@@ -0,0 +1,74 @@
using System;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1RelativeOid : Asn1ObjectIdentifier
{
public new static readonly Asn1Tag Tag = new Asn1Tag(0, 0, RelativeOidTypeCode);
public Asn1RelativeOid()
{
}
public Asn1RelativeOid(OidValue oidValue)
: base(oidValue)
{
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var len = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
OidValue = OidValue.FromArray(buffer.DecodeRelOidContents(len));
buffer.TypeCode = RelativeOidTypeCode;
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
if (OidValue.Items.Length < 1)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
}
var len = 0;
for (var i = OidValue.Items.Length - 1; i >= 0; i--)
{
len += buffer.EncodeIdentifier(OidValue.Items[i]);
}
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Tag, len);
}
return len;
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
var len = 0;
foreach (var i in OidValue.Items)
{
len += Asn1RunTime.GetIdentBytesCount(i);
}
if (explicitTagging)
{
outs.EncodeTag(Tag);
}
outs.EncodeLength(len);
foreach (var i in OidValue.Items)
{
outs.EncodeIdentifier(i);
}
}
}
}

View File

@@ -0,0 +1,151 @@
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
public static class Asn1RunTime
{
public const int LicBer = 1;
public const int LicPer = 2;
public const int LicXer = 4;
public const long Bit0Mask = -9223372036854775808L;
public static long DecodeIntValue(Asn1DecodeBuffer buffer, int length, bool signExtend)
{
var num = 0L;
if (length > 8)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1IntegerValueIsTooLarge);
}
for (var i = 0; i < length; i++)
{
var num2 = buffer.ReadByte();
if (num2 < 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
}
if ((i == 0) && signExtend)
{
num = (num2 > 0x7f) ? -1 : 0;
}
num = (num * 0x100L) + num2;
}
return num;
}
public static int GetIdentBytesCount(long ident)
{
if (ident < 0x80L)
{
return 1;
}
if (ident < 0x4000L)
{
return 2;
}
if (ident < 0x200000L)
{
return 3;
}
if (ident < 0x10000000L)
{
return 4;
}
if (ident < 0x800000000L)
{
return 5;
}
if (ident < 0x40000000000L)
{
return 6;
}
if (ident < 0x2000000000000L)
{
return 7;
}
if (ident < 0x100000000000000L)
{
return 8;
}
return 9;
}
public static int GetLongBitCount(long ivalue)
{
var num = ivalue & Bit0Mask;
var num2 = 0;
if (ivalue != 0L)
{
while ((ivalue & Bit0Mask) == num)
{
num2++;
ivalue = ivalue << 1;
}
if (num == Bit0Mask)
{
num2--;
}
return (0x40 - num2);
}
return 0;
}
public static int GetLongBytesCount(long value)
{
var num = 0x7f80000000000000L;
var num2 = 8;
if (value < 0L)
{
value ^= -1L;
}
while ((num2 > 1) && ((value & num) == 0L))
{
num = num >> 8;
num2--;
}
return num2;
}
public static int GetUlongBytesCount(long value)
{
var number = -72057594037927936L;
var num2 = 8;
while ((num2 > 1) && ((value & number) == 0L))
{
number = Asn1Util.UrShift(number, 8);
num2--;
}
return num2;
}
public static int IntTrailingZerosCnt(int w)
{
return (0x20 -
(((w & 0xffff) != 0)
? (((w & 0xff) != 0) ? ((((w & 15) != 0) ? (((w & 3) != 0) ? (((w & 1) != 0) ? 8 : 7) : (((w & 4) != 0) ? 6 : 5)) : (((w & 0x30) != 0) ? (((w & 0x10) != 0) ? 4 : 3) : (((w & 0x40) != 0) ? 2 : (((w & 0x80) != 0) ? 1 : 0)))) + 0x18) : (((((w = Asn1Util.UrShift(w, 8)) & 15) != 0) ? (((w & 3) != 0) ? (((w & 1) != 0) ? 8 : 7) : (((w & 4) != 0) ? 6 : 5)) : (((w & 0x30) != 0) ? (((w & 0x10) != 0) ? 4 : 3) : (((w & 0x40) != 0) ? 2 : (((w & 0x80) != 0) ? 1 : 0)))) + 0x10))
: ((((w = Asn1Util.UrShift(w, 0x10)) & 0xff) != 0) ? ((((w & 15) != 0) ? (((w & 3) != 0) ? (((w & 1) != 0) ? 8 : 7) : (((w & 4) != 0) ? 6 : 5)) : (((w & 0x30) != 0) ? (((w & 0x10) != 0) ? 4 : 3) : (((w & 0x40) != 0) ? 2 : (((w & 0x80) != 0) ? 1 : 0)))) + 8) : ((((w = Asn1Util.UrShift(w, 8)) & 15) != 0) ? (((w & 3) != 0) ? (((w & 1) != 0) ? 8 : 7) : (((w & 4) != 0) ? 6 : 5)) : (((w & 0x30) != 0) ? (((w & 0x10) != 0) ? 4 : 3) : (((w & 0x40) != 0) ? 2 : (((w & 0x80) != 0) ? 1 : 0)))))));
}
}
}

View File

@@ -0,0 +1,7 @@
namespace GostCryptography.Asn1.Ber
{
public static class Asn1Status
{
public const int IndefiniteLength = -9999;
}
}

View File

@@ -0,0 +1,35 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1T61String : Asn1VarWidthCharString
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, T61StringTypeCode);
public Asn1T61String()
: base(T61StringTypeCode)
{
}
public Asn1T61String(string data)
: base(data, T61StringTypeCode)
{
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
Decode(buffer, explicitTagging, implicitLength, Tag);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
return Encode(buffer, explicitTagging, Tag);
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
outs.EncodeCharString(Value, explicitTagging, Tag);
}
}
}

View File

@@ -0,0 +1,108 @@
using System;
using System.Text;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1Tag
{
public const short Universal = 0;
public const short Private = 0xc0;
public const short Application = 0x40;
public const short Bit8Mask = 0x80;
public const short ClassMask = 0xc0;
public const short CONS = 0x20;
public const short CTXT = 0x80;
public const bool EXPL = true;
public const short EXTIDCODE = 0x1f;
public const short FormMask = 0x20;
public const short IDMask = 0x1f;
public const bool IMPL = false;
public const short L7BitsMask = 0x7f;
public const short PRIM = 0;
public static readonly Asn1Tag Eoc = new Asn1Tag(0, 0, Asn1Type.EocTypeCode);
public static readonly Asn1Tag Set = new Asn1Tag(0, 0x20, Asn1Type.SetTypeCode);
public static readonly Asn1Tag Sequence = new Asn1Tag(0, 0x20, Asn1Type.SequenceTypeCode);
public static readonly Asn1Tag Enumerated = new Asn1Tag(0, 0, Asn1Type.EnumeratedTypeCode);
[NonSerialized]
public short Class;
[NonSerialized]
public short Form;
[NonSerialized]
public int IdCode;
public Asn1Tag()
{
Class = 0;
Form = 0;
IdCode = 0;
}
public Asn1Tag(short tagclass, short form, int idCode)
{
Class = tagclass;
Form = form;
IdCode = idCode;
}
public virtual bool Constructed
{
get { return (Form == 0x20); }
}
public bool Equals(Asn1Tag tag)
{
return Equals(tag.Class, tag.Form, tag.IdCode);
}
public virtual bool Equals(short tagclass, short form, int idCode)
{
return ((Class == tagclass) && (IdCode == idCode));
}
public virtual bool IsEoc()
{
return Equals(0, 0, 0);
}
public override string ToString()
{
var builder = new StringBuilder();
builder.Append("[");
switch (Class)
{
case 0x80:
break;
case Private:
builder.Append("PRIVATE ");
break;
case Universal:
builder.Append("UNIVERSAL ");
break;
case Application:
builder.Append("APPLICATION ");
break;
default:
builder.Append("??? ");
break;
}
builder.Append(Convert.ToString(IdCode));
builder.Append("]");
return builder.ToString();
}
}
}

View File

@@ -0,0 +1,569 @@
using System;
using System.Text;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public abstract class Asn1Time : Asn18BitCharString, IComparable
{
public const int January = 1;
public const int February = 2;
public const int March = 3;
public const int April = 4;
public const int May = 5;
public const int June = 6;
public const int July = 7;
public const int August = 8;
public const int September = 9;
public const int October = 10;
public const int November = 11;
public const int December = 12;
public static readonly short[] DaysInMonth = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
public Asn1Time(short typeCode, bool useDerRules)
: base(typeCode)
{
DerRules = useDerRules;
Init();
}
public Asn1Time(string data, short typeCode, bool useDerRules)
: base(data, typeCode)
{
DerRules = useDerRules;
Init();
}
[NonSerialized]
protected bool Parsed;
[NonSerialized]
protected bool DerRules;
[NonSerialized]
protected int DiffHourValue;
public virtual int DiffHour
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return DiffHourValue;
}
set
{
if ((value < -12) || (value > 12))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHourValue, value);
}
SafeParseString();
DiffHourValue = value;
CompileString();
}
}
[NonSerialized]
protected int DiffMinValue;
public virtual int DiffMinute
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return DiffMinValue;
}
}
[NonSerialized]
protected string SecFraction;
public virtual string Fraction
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return SecFraction;
}
set
{
SafeParseString();
SecFraction = value;
CompileString();
}
}
[NonSerialized]
protected int YearValue;
public virtual int Year
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return YearValue;
}
set
{
if (value < 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, value);
}
if (!CheckDate(DayValue, MonthValue, value))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValueForDayAndMonth, value, DayValue, MonthValue);
}
SafeParseString();
YearValue = value;
CompileString();
}
}
[NonSerialized]
protected int MonthValue;
public virtual int Month
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return MonthValue;
}
set
{
if ((value < 1) || (value > 12))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMonthValue, value);
}
if (!CheckDate(DayValue, value, YearValue))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMonthValueForDayAndYear, value, DayValue, YearValue);
}
SafeParseString();
MonthValue = value;
CompileString();
}
}
[NonSerialized]
protected int DayValue;
public virtual int Day
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return DayValue;
}
set
{
if (((value < 1) || (value > 31)) || !CheckDate(value, MonthValue, YearValue))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDayValueForMonthAndYear, value, MonthValue, YearValue);
}
SafeParseString();
DayValue = value;
CompileString();
}
}
[NonSerialized]
protected int HourValue;
public virtual int Hour
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return HourValue;
}
set
{
if ((value < 0) || (value > 23))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidHourValue, value);
}
SafeParseString();
HourValue = value;
CompileString();
}
}
[NonSerialized]
protected int MinuteValue;
public virtual int Minute
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return MinuteValue;
}
set
{
if ((value < 0) || (value > 59))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMinuteValue, value);
}
SafeParseString();
MinuteValue = value;
CompileString();
}
}
[NonSerialized]
protected int SecondValue;
public virtual int Second
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return SecondValue;
}
set
{
if ((value < 0) || (value > 59))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidSecondValue, value);
}
SafeParseString();
SecondValue = value;
CompileString();
}
}
[NonSerialized]
protected bool UtcFlag;
public virtual bool Utc
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return UtcFlag;
}
set
{
if (!DerRules)
{
SafeParseString();
UtcFlag = value;
CompileString();
}
}
}
public virtual int CompareTo(object other)
{
if (other is DateTime)
{
var time2 = (DateTime)other;
return (int)(GetTime().Ticks - time2.Ticks);
}
return (int)(GetTime().Ticks - ((Asn1Time)other).GetTime().Ticks);
}
protected static char CharAt(string s, int index)
{
if (index >= s.Length)
{
return '\0';
}
return s[index];
}
private static bool CheckDate(int day, int month, int year)
{
if ((day <= 0) || (month <= 0))
{
return true;
}
if ((year >= 0) && (month > 0))
{
int num = DaysInMonth[month];
if (((month == 2) && ((year % 4) == 0)) && (((year % 100) != 0) || ((year % 400) == 0)))
{
num++;
}
if ((day >= 1) && (day <= num))
{
return true;
}
}
else if (month > 0)
{
if (day <= DaysInMonth[month])
{
return true;
}
if ((month == 2) && (day <= (DaysInMonth[month] + 1)))
{
return true;
}
}
return false;
}
public virtual void Clear()
{
YearValue = MonthValue = DayValue = HourValue = -1;
MinuteValue = SecondValue = DiffHourValue = DiffMinValue = 0;
UtcFlag = DerRules;
Parsed = true;
SecFraction = "";
Value = "";
}
protected abstract bool CompileString();
protected override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength, Asn1Tag tag)
{
Parsed = false;
base.Decode(buffer, explicitTagging, implicitLength, tag);
DerRules = buffer is Asn1DerDecodeBuffer;
}
protected override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging, Asn1Tag tag)
{
SafeParseString();
var flag = buffer is Asn1DerEncodeBuffer;
if (DerRules != flag)
{
DerRules = flag;
if (!CompileString())
{
throw ExceptionUtility.CryptographicException(Resources.Asn1TimeStringCouldNotBeGenerated);
}
}
return base.Encode(buffer, explicitTagging, tag);
}
public virtual void Encode(Asn1BerOutputStream outs, bool explicitTagging, Asn1Tag tag)
{
SafeParseString();
outs.EncodeCharString(Value, explicitTagging, tag);
}
public override bool Equals(object value)
{
if (value is Asn1Time)
{
return GetTime().Equals(((Asn1Time)value).GetTime());
}
return ((value is DateTime) && GetTime().Equals((DateTime)value));
}
public virtual int GetDiff()
{
if (!Parsed)
{
ParseString(Value);
}
return ((DiffHourValue * 60) + DiffMinValue);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public virtual DateTime GetTime()
{
if (!string.IsNullOrEmpty(SecFraction))
{
return new DateTime(YearValue, MonthValue, DayValue, HourValue, MinuteValue, SecondValue, int.Parse(SecFraction));
}
return new DateTime(YearValue, MonthValue, DayValue, HourValue, MinuteValue, SecondValue);
}
protected virtual void Init()
{
YearValue = MonthValue = DayValue = HourValue = -1;
MinuteValue = SecondValue = 0;
DiffHourValue = DiffMinValue = 0;
UtcFlag = DerRules;
SecFraction = "";
}
protected static int ParseInt(string str, IntHolder off, int len)
{
if ((off.Value + len) > str.Length)
{
throw ExceptionUtility.ArgumentOutOfRange("off");
}
var mValue = off.Value;
off.Value += len;
return int.Parse(str.Substring(mValue, len));
}
public abstract void ParseString(string data);
protected virtual void PutInteger(int width, int value)
{
PutInteger(StringBuffer, width, value);
}
public static void PutInteger(StringBuilder data, int width, int value)
{
var str = Convert.ToString(value);
var length = str.Length;
if (length < width)
{
for (var i = length; i < width; i++)
{
data.Append('0');
}
}
else if (length > width)
{
str = str.Substring(length - width);
}
data.Append(str);
}
protected virtual void SafeParseString()
{
try
{
if (!Parsed)
{
ParseString(Value);
}
}
catch (Exception)
{
}
}
public virtual void SetDiff(int inMinutes)
{
if (Math.Abs(inMinutes) > 720)
{
throw ExceptionUtility.CryptographicException(Resources.InvalidDiffValue, inMinutes);
}
SafeParseString();
DiffHourValue = inMinutes / 60;
DiffMinValue = inMinutes % 60;
CompileString();
}
public virtual void SetDiff(int dhour, int dminute)
{
if ((dhour < -12) || (dhour > 12))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHourValue, dhour);
}
if (Math.Abs(dminute) > 59)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffMinuteValue, dminute);
}
SafeParseString();
DiffHourValue = dhour;
if (dhour < 0)
{
DiffMinValue = -Math.Abs(dminute);
}
else
{
DiffMinValue = Math.Abs(dminute);
}
CompileString();
}
public virtual void SetTime(DateTime time)
{
Clear();
YearValue = time.Year;
MonthValue = time.Month;
DayValue = time.Day;
HourValue = time.Hour;
MinuteValue = time.Minute;
SecondValue = time.Second;
SecFraction = Convert.ToString(time.Millisecond);
DiffHourValue = DiffMinValue = 0;
UtcFlag = DerRules;
CompileString();
}
}
}

View File

@@ -0,0 +1,46 @@
using System;
using System.IO;
namespace GostCryptography.Asn1.Ber
{
public class Asn1TraceHandler : IAsn1NamedEventHandler
{
internal StreamWriter mPrintStream;
public Asn1TraceHandler()
{
mPrintStream = new StreamWriter(Console.OpenStandardOutput(), Console.Out.Encoding);
mPrintStream.AutoFlush = true;
}
public Asn1TraceHandler(StreamWriter ps)
{
mPrintStream = ps;
}
public virtual void Characters(string svalue, short typeCode)
{
mPrintStream.WriteLine("data: " + svalue);
}
public virtual void EndElement(string name, int index)
{
mPrintStream.Write(name);
if (index >= 0)
{
mPrintStream.Write("[" + index + "]");
}
mPrintStream.WriteLine(": end");
}
public virtual void StartElement(string name, int index)
{
mPrintStream.Write(name);
if (index >= 0)
{
mPrintStream.Write("[" + index + "]");
}
mPrintStream.WriteLine(": start");
}
}
}

View File

@@ -0,0 +1,168 @@
using System;
using System.IO;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public abstract class Asn1Type : IAsn1Type
{
public const short EocTypeCode = 0;
public const short BooleanTypeCode = 1;
public const short BigIntegerTypeCode = 2;
public const short BitStringTypeCode = 3;
public const short OctetStringTypeCode = 4;
public const short NullTypeCode = 5;
public const short ObjectIdentifierTypeCode = 6;
public const short ObjectDescriptorTypeCode = 7;
public const short ExternalTypeCode = 8;
public const short RealTypeCode = 9;
public const short EnumeratedTypeCode = 10;
public const short Utf8StringTypeCode = 12;
public const short RelativeOidTypeCode = 13;
public const short SequenceTypeCode = 0x10;
public const short SetTypeCode = 0x11;
public const short NumericStringTypeCode = 0x12;
public const short PrintableStringTypeCode = 0x13;
public const short T61StringTypeCode = 20;
public const short VideoTexStringTypeCode = 0x15;
public const short Ia5StringTypeCode = 0x16;
public const short UtcTimeTypeCode = 0x17;
public const short GeneralTimeTypeCode = 0x18;
public const short GraphicStringTypeCode = 0x19;
public const short VisibleStringTypeCode = 0x1a;
public const short GeneralStringTypeCode = 0x1b;
public const short UniversalStringTypeCode = 0x1c;
public const short BmpStringTypeCode = 30;
public const short OpenTypeTypeCode = 0x63;
[NonSerialized]
private readonly IntHolder _parsedLen = new IntHolder();
[NonSerialized]
private readonly Asn1Tag _parsedTag = new Asn1Tag();
public virtual int Length
{
get { throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException); }
}
public virtual void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
}
public virtual int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
return 0;
}
public virtual void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
}
public virtual void Print(TextWriter outs, string varName, int level)
{
Indent(outs, level);
outs.WriteLine(varName + " = " + ToString());
}
public virtual void Decode(Asn1BerDecodeBuffer buffer)
{
Decode(buffer, true, 0);
}
public virtual int Encode(Asn1BerEncodeBuffer buffer)
{
return Encode(buffer, true);
}
public static string GetTypeName(short typeCode)
{
switch (typeCode)
{
case EocTypeCode:
return "EOC";
case BooleanTypeCode:
return "BOOLEAN";
case BigIntegerTypeCode:
return "INTEGER";
case BitStringTypeCode:
return "BIT STRING";
case OctetStringTypeCode:
return "OCTET STRING";
case NullTypeCode:
return "NULL";
case ObjectIdentifierTypeCode:
return "OBJECT IDENTIFIER";
case ObjectDescriptorTypeCode:
return "ObjectDescriptor";
case ExternalTypeCode:
return "EXTERNAL";
case RealTypeCode:
return "REAL";
case EnumeratedTypeCode:
return "ENUMERATED";
case Utf8StringTypeCode:
return "UTF8String";
case SequenceTypeCode:
return "SEQUENCE";
case SetTypeCode:
return "SET";
case NumericStringTypeCode:
return "NumericString";
case PrintableStringTypeCode:
return "PrintableString";
case T61StringTypeCode:
return "T61String";
case VideoTexStringTypeCode:
return "VideotexString";
case Ia5StringTypeCode:
return "IA5String";
case UtcTimeTypeCode:
return "UTCTime";
case GeneralTimeTypeCode:
return "GeneralTime";
case GraphicStringTypeCode:
return "GraphicString";
case VisibleStringTypeCode:
return "VisibleString";
case GeneralStringTypeCode:
return "GeneralString";
case UniversalStringTypeCode:
return "UniversalString";
case BmpStringTypeCode:
return "BMPString";
case OpenTypeTypeCode:
return "ANY";
}
return "?";
}
public virtual void Indent(TextWriter outs, int level)
{
var num2 = level * 3;
for (var i = 0; i < num2; i++)
{
outs.Write(" ");
}
}
protected virtual int MatchTag(Asn1BerDecodeBuffer buffer, Asn1Tag tag)
{
return MatchTag(buffer, tag.Class, tag.Form, tag.IdCode);
}
protected virtual int MatchTag(Asn1BerDecodeBuffer buffer, short tagClass, short tagForm, int tagIdCode)
{
if (!buffer.MatchTag(tagClass, tagForm, tagIdCode, _parsedTag, _parsedLen))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1TagMatchFailedException, new Asn1Tag(tagClass, tagForm, tagIdCode), _parsedTag, buffer.ByteCount);
}
return _parsedLen.Value;
}
}
}

View File

@@ -0,0 +1,227 @@
using System;
using System.Text;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1UniversalString : Asn1Type
{
public const int BitsPerChar = 0x20;
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, UniversalStringTypeCode);
[NonSerialized]
private StringBuilder _stringBuffer;
[NonSerialized]
private int[] _value;
public Asn1UniversalString()
{
_value = new int[0];
}
public Asn1UniversalString(int[] value)
{
_value = value;
}
public Asn1UniversalString(string value)
{
_value = new int[value.Length];
for (var i = 0; i < value.Length; i++)
{
_value[i] = value[i];
}
}
public override int Length
{
get { return _value.Length; }
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var llen = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
var idx = new IntHolder(0);
var lastTag = buffer.LastTag;
if ((lastTag == null) || !lastTag.Constructed)
{
ReadSegment(buffer, llen, idx);
}
else
{
var context = new Asn1BerDecodeContext(buffer, llen);
while (!context.Expired())
{
var num2 = MatchTag(buffer, Asn1OctetString.Tag);
if (num2 <= 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
}
ReadSegment(buffer, num2, idx);
}
if (llen == Asn1Status.IndefiniteLength)
{
MatchTag(buffer, Asn1Tag.Eoc);
}
}
buffer.TypeCode = UniversalStringTypeCode;
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var length = _value.Length;
for (var i = length - 1; i >= 0; i--)
{
var num3 = _value[i];
for (var j = 0; j < 4; j++)
{
var num = num3 % 0x100;
num3 /= 0x100;
buffer.Copy((byte)num);
}
}
length *= 4;
if (explicitTagging)
{
length += buffer.EncodeTagAndLength(Tag, length);
}
return length;
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
outs.EncodeUnivString(_value, explicitTagging, Tag);
}
public override bool Equals(object value)
{
var str = value as Asn1UniversalString;
if (str == null)
{
return false;
}
if (_value.Length != str._value.Length)
{
return false;
}
for (var i = 0; i < _value.Length; i++)
{
if (_value[i] != str._value[i])
{
return false;
}
}
return true;
}
public override int GetHashCode()
{
if (_value.Length == 0)
{
return base.GetHashCode();
}
var num = 0;
var num2 = (_value.Length > 20) ? 20 : _value.Length;
for (var i = 0; i < num2; i++)
{
num ^= _value[i];
}
return num;
}
private void ReadSegment(Asn1BerDecodeBuffer buffer, int llen, IntHolder idx)
{
if ((llen < 0) || ((llen % 4) != 0))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
}
var num4 = llen / 4;
if (_value.Length == 0)
{
_value = new int[num4];
}
else if ((idx.Value + num4) >= _value.Length)
{
ReallocIntArray(idx.Value + num4);
}
var value = idx.Value;
while (value < (idx.Value + num4))
{
_value[value] = 0;
for (var i = 0; i < 4; i++)
{
var num = buffer.Read();
if (num == -1)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
}
_value[value] = (_value[value] * 0x100) + num;
}
value++;
}
idx.Value = value;
}
private void ReallocIntArray(int nint)
{
var value = _value;
_value = new int[nint];
if (value != null)
{
Array.Copy(value, 0, _value, 0, value.Length);
}
}
public override string ToString()
{
if (_stringBuffer == null)
{
_stringBuffer = new StringBuilder();
}
_stringBuffer.Length = _value.Length;
for (var i = 0; i < _value.Length; i++)
{
_stringBuffer[i] = (char)_value[i];
}
return _stringBuffer.ToString();
}
}
}

View File

@@ -0,0 +1,361 @@
using System;
using System.Text;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1UtcTime : Asn1Time
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, UtcTimeTypeCode);
public Asn1UtcTime()
: base(UtcTimeTypeCode, false)
{
}
public Asn1UtcTime(bool useDerRules)
: base(UtcTimeTypeCode, useDerRules)
{
}
public Asn1UtcTime(string data)
: base(data, UtcTimeTypeCode, false)
{
}
public Asn1UtcTime(string data, bool useDerRules)
: base(data, UtcTimeTypeCode, useDerRules)
{
}
public override string Fraction
{
get
{
return "";
}
set
{
SecFraction = "";
throw ExceptionUtility.CryptographicException(Resources.Asn1FractionNotSupportedForUtcTime);
}
}
public override int Year
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return YearValue;
}
set
{
if (value < 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, YearValue);
}
if (value < 100)
{
if (value >= 50)
{
Year = value + 0x76c;
}
else
{
Year = value + 0x7d0;
}
}
Year = value;
}
}
public override void Clear()
{
Clear();
HourValue = MinuteValue = -1;
UtcFlag = true;
}
public override int CompareTo(object obj)
{
return base.CompareTo(obj);
}
protected override bool CompileString()
{
Value = "";
if (((YearValue < 0) || (DayValue <= 0)) || (((MonthValue <= 0) || (HourValue < 0)) || (MinuteValue < 0)))
{
return false;
}
if (StringBuffer == null)
{
StringBuffer = new StringBuilder();
}
else
{
StringBuffer.Length = 0;
}
if ((DerRules || UtcFlag) && ((DiffHourValue != 0) || (DiffMinValue != 0)))
{
var time = GetTime();
time.AddMinutes(-DiffMinValue);
time.AddHours(-DiffHourValue);
PutInteger(2, time.Year);
PutInteger(2, time.Month);
PutInteger(2, time.Day);
PutInteger(2, time.Hour);
PutInteger(2, time.Minute);
}
else
{
PutInteger(2, YearValue);
PutInteger(2, MonthValue);
PutInteger(2, DayValue);
PutInteger(2, HourValue);
PutInteger(2, MinuteValue);
}
PutInteger(2, SecondValue);
if (DerRules || UtcFlag)
{
StringBuffer.Append('Z');
}
else if ((DiffHourValue != 0) || (DiffMinValue != 0))
{
StringBuffer.Append((DiffHourValue > 0) ? '+' : '-');
PutInteger(2, Math.Abs(DiffHourValue));
PutInteger(2, Math.Abs(DiffMinValue));
}
Value = StringBuffer.ToString();
return true;
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
Decode(buffer, explicitTagging, implicitLength, Tag);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
return Encode(buffer, explicitTagging, Tag);
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
Encode(outs, explicitTagging, Tag);
}
protected override void Init()
{
Init();
HourValue = MinuteValue = -1;
UtcFlag = true;
}
public override void ParseString(string data)
{
if (data == null)
{
throw ExceptionUtility.ArgumentNull("data");
}
Clear();
var off = new IntHolder(0);
try
{
YearValue = ParseInt(data, off, 2);
MonthValue = ParseInt(data, off, 2);
DayValue = ParseInt(data, off, 2);
if (YearValue < 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, YearValue);
}
if (YearValue < 100)
{
if (YearValue > 70)
{
YearValue += 0x76c;
}
else
{
YearValue += 0x7d0;
}
}
if ((MonthValue < 1) || (MonthValue > 12))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMonthValue, MonthValue);
}
var num = DaysInMonth[MonthValue];
if (((MonthValue == 2) && ((YearValue % 4) == 0)) && (((YearValue % 100) != 0) || ((YearValue % 400) == 0)))
{
num++;
}
if ((DayValue < 1) || (DayValue > num))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDayValue, DayValue);
}
var num2 = 0;
if (!char.IsDigit(CharAt(data, off.Value)))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1HoursExpected);
}
HourValue = ParseInt(data, off, 2);
num2++;
if (!char.IsDigit(CharAt(data, off.Value)))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1MinutesExpected);
}
MinuteValue = ParseInt(data, off, 2);
num2++;
if (char.IsDigit(CharAt(data, off.Value)))
{
SecondValue = ParseInt(data, off, 2);
num2++;
}
if ((num2 >= 2) && ((HourValue < 0) || (HourValue > UtcTimeTypeCode)))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidHourValue, HourValue);
}
if ((num2 >= 2) && ((MinuteValue < 0) || (MinuteValue > 0x3b)))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMinuteValue, MinuteValue);
}
if ((num2 == 3) && ((SecondValue < 0) || (SecondValue > 0x3b)))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidSecondValue, SecondValue);
}
CharAt(data, off.Value);
if (CharAt(data, off.Value) == 'Z')
{
off.Value++;
UtcFlag = true;
if (off.Value != data.Length)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedValuesAtEndOfString);
}
}
else
{
if (DerRules)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedZoneOffset);
}
UtcFlag = false;
var ch = CharAt(data, off.Value);
switch (ch)
{
case '-':
case '+':
off.Value++;
if (!char.IsDigit(CharAt(data, off.Value)))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHour);
}
DiffHourValue = ParseInt(data, off, 2);
if (!char.IsDigit(CharAt(data, off.Value)))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffMinute);
}
DiffMinValue = ParseInt(data, off, 2);
if ((DiffHourValue < 0) || (DiffHourValue > 12))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHourValue, DiffHourValue);
}
if ((DiffMinValue < 0) || (DiffMinValue > 0x3b))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffMinuteValue, DiffMinValue);
}
if (ch == '-')
{
DiffHourValue = -DiffHourValue;
DiffMinValue = -DiffMinValue;
}
break;
}
}
Parsed = true;
if (data != Value)
{
CompileString();
}
}
catch (IndexOutOfRangeException)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDateFormat);
}
catch (FormatException)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidNumberFormat);
}
catch (ArgumentException)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDateFormat);
}
}
public override void SetTime(DateTime time)
{
Clear();
YearValue = time.Year;
MonthValue = time.Month;
DayValue = time.Day;
HourValue = time.Hour;
MinuteValue = time.Minute;
SecondValue = time.Second;
SecFraction = "";
DiffHourValue = DiffMinValue = 0;
UtcFlag = true;
CompileString();
}
}
}

View File

@@ -0,0 +1,98 @@
using System;
using System.IO;
using System.Text;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1Utf8String : Asn1CharString
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, Utf8StringTypeCode);
public Asn1Utf8String()
: base(Utf8StringTypeCode)
{
}
public Asn1Utf8String(string data)
: base(data, Utf8StringTypeCode)
{
}
private byte[] AllocByteArray(int nbytes)
{
return new byte[nbytes];
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var num = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
var str = new Asn1OctetString();
str.Decode(buffer, false, num);
Value = Encoding.UTF8.GetString(str.Value, 0, str.Value.Length);
if (explicitTagging && (num == Asn1Status.IndefiniteLength))
{
MatchTag(buffer, Asn1Tag.Eoc);
}
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = 0;
try
{
var bytes = Encoding.UTF8.GetBytes(Value);
len = bytes.Length;
buffer.Copy(bytes);
}
catch (IOException exception)
{
Console.Out.WriteLine("This JVM does not support UTF-8 encoding");
Asn1Util.WriteStackTrace(exception, Console.Error);
}
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Tag, len);
}
return len;
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
try
{
var bytes = Encoding.UTF8.GetBytes(Value);
if (explicitTagging)
{
outs.EncodeTag(Tag);
}
outs.EncodeLength(bytes.Length);
outs.Write(bytes);
}
catch (IOException exception)
{
Console.Out.WriteLine("This JVM does not support UTF-8 encoding");
Asn1Util.WriteStackTrace(exception, Console.Error);
}
}
private byte[] ReAllocByteArray(byte[] ba1, int nbytes)
{
var destinationArray = new byte[nbytes];
if (ba1 != null)
{
Array.Copy(ba1, 0, destinationArray, 0, ba1.Length);
}
return destinationArray;
}
}
}

View File

@@ -0,0 +1,336 @@
using System;
using System.Collections;
using System.IO;
using System.Text;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
public static class Asn1Util
{
private static readonly byte[] Base64DecodeTable =
{
0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
60, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 0x10, 0x11, 0x12, 0x13, 20, 0x15, 0x16,
0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 30, 0x1f, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 40, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
0x31, 50, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff
};
private static readonly byte[] Base64EncodeTable =
{
0x41, 0x42, 0x43, 0x44, 0x45, 70, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 80,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 90, 0x61, 0x62, 0x63, 100, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 110, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
0x77, 120, 0x79, 0x7a, 0x30, 0x31, 50, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x2f
};
public static string BcdToString(byte[] bcd)
{
var index = 0;
var builder = new StringBuilder(bcd.Length * 2);
for (var i = 0; i < (bcd.Length * 2); i++)
{
byte num3;
if ((i % 2) == 0)
{
num3 = (byte)(bcd[index] & 15);
}
else
{
num3 = (byte)UrShift(bcd[index++], 4);
}
if (num3 == 15)
{
break;
}
builder.Append((num3 < 10) ? ((char)(num3 + 0x30)) : ((char)((num3 + 0x41) - 10)));
}
return builder.ToString();
}
public static byte[] DecodeBase64Array(byte[] srcArray)
{
var num = srcArray.Length / 4;
if ((4 * num) != srcArray.Length)
{
throw ExceptionUtility.Argument("srcArray", Resources.Asn1InvalidEncodedDataLength);
}
var num2 = 0;
var num3 = num;
if (srcArray.Length != 0)
{
if (srcArray[srcArray.Length - 1] == 0x3d)
{
num2++;
num3--;
}
if (srcArray[srcArray.Length - 2] == 0x3d)
{
num2++;
}
}
var buffer = new byte[(3 * num) - num2];
var num4 = 0;
var num5 = 0;
for (var i = 0; i < num3; i++)
{
var num7 = DecodeBase64Char(srcArray[num4++]);
var num8 = DecodeBase64Char(srcArray[num4++]);
var num9 = DecodeBase64Char(srcArray[num4++]);
var num10 = DecodeBase64Char(srcArray[num4++]);
buffer[num5++] = (byte)((num7 << 2) | (num8 >> 4));
buffer[num5++] = (byte)((num8 << 4) | (num9 >> 2));
buffer[num5++] = (byte)((num9 << 6) | num10);
}
if (num2 != 0)
{
var num11 = DecodeBase64Char(srcArray[num4++]);
var num12 = DecodeBase64Char(srcArray[num4++]);
buffer[num5++] = (byte)((num11 << 2) | (num12 >> 4));
if (num2 == 1)
{
var num13 = DecodeBase64Char(srcArray[num4++]);
buffer[num5++] = (byte)((num12 << 4) | (num13 >> 2));
}
}
return buffer;
}
private static int DecodeBase64Char(byte c)
{
var num = (c < 0x80) ? Base64DecodeTable[c - 40] : -1;
if (num < 0)
{
throw ExceptionUtility.Argument("c", Resources.Asn1IllegalCharacter, c);
}
return num;
}
public static byte[] EncodeBase64Array(byte[] srcArray)
{
var num = srcArray.Length / 3;
var num2 = srcArray.Length - (3 * num);
var num3 = 4 * ((srcArray.Length + 2) / 3);
var buffer = new byte[num3];
var num4 = 0;
var num5 = 0;
for (var i = 0; i < num; i++)
{
var num7 = srcArray[num4++] & 0xff;
var num8 = srcArray[num4++] & 0xff;
var num9 = srcArray[num4++] & 0xff;
buffer[num5++] = Base64EncodeTable[num7 >> 2];
buffer[num5++] = Base64EncodeTable[((num7 << 4) & 0x3f) | (num8 >> 4)];
buffer[num5++] = Base64EncodeTable[((num8 << 2) & 0x3f) | (num9 >> 6)];
buffer[num5++] = Base64EncodeTable[num9 & 0x3f];
}
if (num2 != 0)
{
var num10 = srcArray[num4++] & 0xff;
buffer[num5++] = Base64EncodeTable[num10 >> 2];
if (num2 == 1)
{
buffer[num5++] = Base64EncodeTable[(num10 << 4) & 0x3f];
buffer[num5++] = 0x3d;
buffer[num5++] = 0x3d;
return buffer;
}
var num11 = srcArray[num4++] & 0xff;
buffer[num5++] = Base64EncodeTable[((num10 << 4) & 0x3f) | (num11 >> 4)];
buffer[num5++] = Base64EncodeTable[(num11 << 2) & 0x3f];
buffer[num5++] = 0x3d;
}
return buffer;
}
public static byte[] GetAddressBytes(string ipaddress)
{
var index = 0;
var buffer = new byte[4];
var tokenizer = new Tokenizer(ipaddress, ".");
try
{
while (tokenizer.HasMoreTokens())
{
buffer[index] = Convert.ToByte(tokenizer.NextToken());
index++;
}
}
catch (Exception)
{
}
return buffer;
}
public static int GetBytesCount(long val)
{
return Asn1RunTime.GetLongBytesCount(val);
}
public static int GetUlongBytesCount(long val)
{
return Asn1RunTime.GetUlongBytesCount(val);
}
public static byte[] StringToBcd(string str)
{
int num2;
var buffer = new byte[(str.Length + 1) / 2];
byte num = 0;
var num3 = num2 = 0;
while (num3 < str.Length)
{
var c = char.ToUpper(str[num3]);
var flag = char.IsDigit(c);
if (!flag && ((c < 'A') || (c >= 'F')))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ValueParseException, str, num3);
}
if ((num3 % 2) != 0)
{
num = (byte)(num | ((byte)(((byte)((flag != null) ? (c - 0x30) : ((c - 0x41) + 10))) << 4)));
buffer[num2++] = num;
}
else
{
num = flag ? ((byte)(c - '0')) : ((byte)((c - 'A') + 10));
}
num3++;
}
if ((num3 % 2) != 0)
{
buffer[num2++] = (byte)(num | 240);
}
return buffer;
}
public static void ToArray(ICollection c, object[] objects)
{
var num = 0;
var enumerator = c.GetEnumerator();
while (enumerator.MoveNext())
{
objects[num++] = enumerator.Current;
}
}
public static byte[] ToByteArray(string sourceString)
{
return Encoding.UTF8.GetBytes(sourceString);
}
public static char[] ToCharArray(byte[] byteArray)
{
return Encoding.UTF8.GetChars(byteArray);
}
public static string ToHexString(byte b)
{
var builder = new StringBuilder(4);
var str = Convert.ToString(b, 0x10);
var length = str.Length;
if (length < 2)
{
builder.Append('0');
builder.Append(str);
}
else if (length > 2)
{
builder.Append(str[length - 2]);
builder.Append(str[length - 1]);
}
else
{
builder.Append(str);
}
return builder.ToString();
}
public static string ToHexString(byte[] b, int offset, int nbytes)
{
var builder = new StringBuilder(nbytes * 4);
for (var i = 0; i < nbytes; i++)
{
builder.Append(ToHexString(b[offset + i]));
builder.Append(" ");
}
return builder.ToString();
}
public static int UrShift(int number, int bits)
{
if (number >= 0)
{
return (number >> bits);
}
return ((number >> bits) + (2 << ~bits));
}
public static int UrShift(int number, long bits)
{
return UrShift(number, (int)bits);
}
public static long UrShift(long number, int bits)
{
if (number >= 0L)
{
return (number >> bits);
}
return ((number >> bits) + (2L << ~bits));
}
public static long UrShift(long number, long bits)
{
return UrShift(number, (int)bits);
}
public static void WriteStackTrace(Exception throwable, TextWriter stream)
{
stream.Write(throwable.StackTrace);
stream.Flush();
}
}
}

View File

@@ -0,0 +1,170 @@
using System;
using System.Text;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
public static class Asn1Value
{
private static byte[] AllocBitArray(int numbits)
{
var num = numbits / 8;
if ((numbits % 8) != 0)
{
num++;
}
return new byte[num];
}
public static byte[] ParseString(string data)
{
return ParseString(data, null);
}
public static byte[] ParseString(string data, IntHolder numbits)
{
char ch;
int num;
int num2;
int num3;
int num4;
int num5;
char ch2 = data[0];
byte[] buffer;
switch (ch2)
{
case '\'':
case '"':
if (!data.EndsWith("B"))
{
if (data.EndsWith("H"))
{
var builder = new StringBuilder();
num3 = (data.Length - 3) * 4;
buffer = AllocBitArray(num3);
builder.Length = 2;
num = 1;
num2 = 0;
ch = '\0';
while ((num < data.Length) && (ch != ch2))
{
ch = data[num++];
if (ch != ch2)
{
builder[0] = ch;
ch = (num >= data.Length) ? '0' : data[num];
builder[1] = (ch == ch2) ? '0' : ch;
buffer[num2++] = (byte)Convert.ToInt32(builder.ToString(), 0x10);
}
num++;
}
}
else
{
if (data[data.Length - 1] != ch2)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ValueParseException, data, data.Length - 1);
}
num3 = (data.Length - 2) * 8;
buffer = AllocBitArray(num3);
num = 1;
ch = '\0';
while ((num < data.Length) && (ch != ch2))
{
ch = data[num];
if (ch != ch2)
{
buffer[num - 1] = (byte)ch;
}
num++;
}
}
return SetNumBits(numbits, num3, buffer);
}
num3 = data.Length - 3;
buffer = AllocBitArray(num3);
num5 = 0x80;
num = 1;
num4 = 0;
num2 = 0;
while (num < data.Length)
{
ch = data[num];
if (ch == '1')
{
num4 |= num5;
}
else
{
if (ch == ch2)
{
break;
}
if (ch != '0')
{
ExceptionUtility.CryptographicException(Resources.Asn1ValueParseException, data, num);
}
}
num5 = num5 >> 1;
if (num5 == 0)
{
buffer[num2++] = (byte)num4;
num5 = 0x80;
num4 = 0;
}
num++;
}
break;
default:
num3 = data.Length * 8;
buffer = AllocBitArray(num3);
num = 0;
while (num < data.Length)
{
ch = data[num];
buffer[num] = (byte)ch;
num++;
}
return SetNumBits(numbits, num3, buffer);
}
if (num5 != 0x80)
{
buffer[num2] = (byte)num4;
}
return SetNumBits(numbits, num3, buffer);
}
private static byte[] SetNumBits(IntHolder numbits, int num3, byte[] buffer)
{
if (numbits != null)
{
numbits.Value = num3;
}
return buffer;
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public abstract class Asn1VarWidthCharString : Asn1CharString
{
public const int BitsPerCharA = 8;
public const int BitsPerCharU = 8;
protected internal Asn1VarWidthCharString(short typeCode)
: base(typeCode)
{
}
protected internal Asn1VarWidthCharString(string data, short typeCode)
: base(data, typeCode)
{
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1VideotexString : Asn1VarWidthCharString
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, VideoTexStringTypeCode);
public Asn1VideotexString()
: base(VideoTexStringTypeCode)
{
}
public Asn1VideotexString(string data)
: base(data, VideoTexStringTypeCode)
{
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
Decode(buffer, explicitTagging, implicitLength, Tag);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
return Encode(buffer, explicitTagging, Tag);
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
outs.EncodeCharString(Value, explicitTagging, Tag);
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class Asn1VisibleString : Asn18BitCharString
{
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, VisibleStringTypeCode);
public Asn1VisibleString()
: base(VisibleStringTypeCode)
{
}
public Asn1VisibleString(string data)
: base(data, VisibleStringTypeCode)
{
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
Decode(buffer, explicitTagging, implicitLength, Tag);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
return Encode(buffer, explicitTagging, Tag);
}
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
{
outs.EncodeCharString(Value, explicitTagging, Tag);
}
}
}

View File

@@ -0,0 +1,809 @@
using System;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public class BigInteger
{
private const int AddressBits = 3;
private const int BitIndexMask = 7;
private const int BitsPerUnit = 8;
internal const int MaxBigIntLen = 100000;
private const int UnitMask = -1;
[NonSerialized]
private static readonly int[] BitsPerDigit =
{
0, 0, 0x400, 0x658, 0x800, 0x94a, 0xa58, 0xb3b, 0xc00, 0xcaf, 0xd4a, 0xdd7, 0xe58, 0xece, 0xf3b, 0xfa1,
0x1000, 0x105a, 0x10af, 0x10fe, 0x114a, 0x1192, 0x11d7, 0x1219, 0x1258, 0x1294, 0x12ce, 0x1306, 0x133b, 0x136f, 0x13a1, 0x13d2,
0x1400, 0x142e, 0x145a, 0x1485, 0x14af
};
[NonSerialized]
private static readonly int[] ByteRadix =
{
0, 0, 0x80, 0, 0, 0, 0, 0, 0x40, 0, 100, 0, 0, 0, 0, 0, 0x10
};
[NonSerialized]
private static readonly int[] DigitsPerByte =
{
0, 0, 7, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 1
};
private static readonly byte[] Zero = new byte[0];
[NonSerialized]
private int _sign;
[NonSerialized]
private byte[] _value;
public BigInteger()
{
_value = Zero;
_sign = 0;
}
public BigInteger(long value)
: this(value.ToString())
{
}
public BigInteger(string value)
{
Init(value, 10);
}
public BigInteger(byte[] value, int sign)
{
_value = value;
_sign = sign;
}
public BigInteger(string value, int radix)
{
Init(value, radix);
}
private static int BitsLeftOf(int x)
{
if (x != 0)
{
return (UnitMask << (BitsPerUnit - x));
}
return UnitMask;
}
private static void DestructiveMulAdd(byte[] x, int y, byte z)
{
var num = (byte)(y & 0xff);
var num2 = z;
var length = x.Length;
var num5 = 0;
for (var i = length - 1; i >= 0; i--)
{
var num4 = (num * x[i]) + num5;
x[i] = (byte)num4;
num5 = num4 >> BitsPerUnit;
}
var num7 = x[length - 1] + num2;
x[length - 1] = (byte)num7;
num5 = num7 >> BitsPerUnit;
for (var j = length - 2; j >= 0; j--)
{
num7 = x[j] + num5;
x[j] = (byte)num7;
num5 = num7 >> BitsPerUnit;
}
}
private static void DivideByInt(ref BigInteger divident, int divisor, ref BigInteger quotient, ref int reminder)
{
var index = 0;
var num3 = 4;
var num4 = 0;
var num5 = 0;
if (divisor == 0)
{
return;
}
reminder = 0;
if (divident._sign == 0)
{
quotient._sign = 0;
quotient._value = Zero;
return;
}
quotient._value = new byte[divident._value.Length];
var num2 = quotient._value.Length - 1;
quotient._sign = ((quotient._sign * divisor) > 0) ? 1 : -1;
var num6 = divident._value.Length * 2;
while (num4 < num6)
{
num5 = num5 << 4;
num4++;
num5 |= (divident._value[index] >> num3) & 15;
if (num3 == 0)
{
num3 = 4;
index++;
}
else
{
num3 = 0;
}
ShiftLeft(quotient, 4);
if (num5 >= divisor)
{
quotient._value[num2] = (byte)(quotient._value[num2] | ((byte)((num5 / divisor) & 15)));
num5 = num5 % divisor;
}
reminder = num5;
}
quotient._value = RemoveLeadingZeroBytes(quotient._value);
}
public bool Equals(long value)
{
return Equals(new BigInteger(value));
}
public override bool Equals(object value)
{
var integer = value as BigInteger;
if (integer == null)
{
return false;
}
if (_value.Length != integer._value.Length)
{
return false;
}
for (var i = 0; i < _value.Length; i++)
{
if (_value[i] != integer._value[i])
{
return false;
}
}
return true;
}
private static void FastCopy(ref BigInteger src, ref BigInteger dst)
{
dst._value = new byte[src._value.Length];
Array.Copy(src._value, 0, dst._value, 0, src._value.Length);
dst._sign = src._sign;
}
private BigInteger GetCopy()
{
var integer = new BigInteger();
if (_value.Length > 0)
{
integer._value = new byte[_value.Length];
Array.Copy(_value, 0, integer._value, 0, _value.Length);
}
else
{
integer._value = Zero;
}
integer._sign = _sign;
return integer;
}
private BigInteger GetCopyAndInverse()
{
var integer = new BigInteger();
if (_value.Length > 0)
{
integer._value = new byte[_value.Length];
if (_sign < 0)
{
integer._value = GetData();
integer._sign = 1;
return integer;
}
Array.Copy(_value, 0, integer._value, 0, _value.Length);
integer._sign = _sign;
return integer;
}
integer._value = Zero;
return integer;
}
public byte[] GetData()
{
int num2;
var dataLen = GetDataLen();
var index = _value.Length - 1;
var num4 = dataLen - 1;
if (_sign == 0)
{
return Zero;
}
var buffer = new byte[dataLen];
if (_sign >= 0)
{
num2 = _value.Length - 1;
while (((num2 >= 0) && (num4 >= 0)) && (index >= 0))
{
buffer[num4] = _value[index];
num2--;
num4--;
index--;
}
if ((dataLen - _value.Length) > 0)
{
buffer[num4] = 0;
}
return buffer;
}
num2 = _value.Length - 1;
while (((num2 >= 0) && (num4 >= 0)) && (index >= 0))
{
unchecked
{
buffer[num4] = (byte)-_value[index];
}
if (_value[index] != 0)
{
num2--;
num4--;
index--;
break;
}
num2--;
num4--;
index--;
}
while (((num2 >= 0) && (num4 >= 0)) && (index >= 0))
{
unchecked
{
buffer[num4] = (byte)~_value[index];
}
num2--;
num4--;
index--;
}
if ((dataLen - _value.Length) > 0)
{
buffer[num4] = 0xff;
}
return buffer;
}
private int GetDataLen()
{
if (_sign == 0)
{
return 1;
}
if ((_sign > 0) && ((_value[0] & 0x80) != 0))
{
return (_value.Length + 1);
}
if (_sign < 0)
{
var num = _value[0];
if ((_value.Length == 1) || ((_value.Length > 1) && (_value[1] == 0)))
{
num = (byte)~(num - 1);
}
else
{
unchecked
{
num = (byte)~num;
}
}
if ((num & 0x80) == 0)
{
return (_value.Length + 1);
}
}
return _value.Length;
}
public override int GetHashCode()
{
if (_value == null)
{
return base.GetHashCode();
}
if (_value.Length == 0)
{
return base.GetHashCode();
}
var num = 0;
var num2 = (_value.Length > 20) ? 20 : _value.Length;
for (var i = 0; i < num2; i++)
{
num ^= _value[i];
}
return num;
}
public void Init(string val, int radix)
{
var str = "";
if (val[0] == '-')
{
val = val.Substring(1);
str = "-";
}
if (val.StartsWith("0x"))
{
radix = 0x10;
val = val.Substring(2);
}
else if (val.StartsWith("0b"))
{
radix = 2;
val = val.Substring(2);
}
else if (val.StartsWith("0o"))
{
radix = 8;
val = val.Substring(2);
}
val = str + val;
var startIndex = 0;
var length = val.Length;
if (((radix != 2) && (radix != 0x10)) && ((radix != 10) && (radix != 8)))
{
throw new FormatException(Resources.Asn1InvalidFormatForBigIntegerValue);
}
if (val.Length == 0)
{
throw new FormatException(Resources.Asn1ZeroLengthBigInteger);
}
_sign = 1;
var index = val.IndexOf('-');
if (index != -1)
{
if (index != 0)
{
throw new FormatException(Resources.Asn1IllegalEmbeddedMinusSign);
}
if (val.Length == 1)
{
throw new FormatException(Resources.Asn1ZeroLengthBigInteger);
}
_sign = -1;
startIndex = 1;
}
while ((startIndex < length) && (val[startIndex] == '0'))
{
startIndex++;
}
if (startIndex == length)
{
_sign = 0;
_value = Zero;
}
else
{
var num2 = length - startIndex;
var num5 = Asn1Util.UrShift(num2 * BitsPerDigit[radix], 10) + 1;
var num1 = (num5 + 0x1f) / 0x20;
_value = new byte[num2];
var num6 = num2 % DigitsPerByte[radix];
if (num6 == 0)
{
num6 = DigitsPerByte[radix];
}
var str2 = val.Substring(startIndex, num6);
startIndex += num6;
_value[_value.Length - 1] = Convert.ToByte(str2, radix);
if (_value[_value.Length - 1] < 0)
{
throw new FormatException(Resources.Asn1IllegalDigit);
}
var y = ByteRadix[radix];
byte z;
while (startIndex < val.Length)
{
str2 = val.Substring(startIndex, DigitsPerByte[radix]);
startIndex += DigitsPerByte[radix];
z = Convert.ToByte(str2, radix);
if (z < 0)
{
throw new FormatException(Resources.Asn1IllegalDigit);
}
DestructiveMulAdd(_value, y, z);
}
_value = TrustedStripLeadingZeroInts(_value);
}
}
private static string IntToStr(long value, int radix)
{
var chArray = new char[0x22];
var num = 0;
var str = "";
if ((radix >= 2) && (radix <= 0x10))
{
while (num < 0x22)
{
chArray[num++] = (char)((ushort)(value % radix));
if ((value /= radix) == 0L)
{
break;
}
}
while (num != 0)
{
var ch = chArray[--num];
if (ch < '\n')
{
str = str + ((char)(ch + '0'));
}
else
{
str = str + ((char)((ch - '\n') + 0x41));
}
}
}
return str;
}
public bool IsNegative()
{
return (_sign < 0);
}
private char NibbleToHexChar(int b)
{
if ((b >= 0) && (b <= 9))
{
return (char)(b + 0x30);
}
if ((b >= 10) && (b <= 15))
{
return (char)((b - 10) + 0x61);
}
return '?';
}
public static implicit operator BigInteger(long value)
{
return new BigInteger(value);
}
private static byte[] RemoveLeadingZeroBytes(byte[] data)
{
if (data.Length == 0)
{
return data;
}
var index = 0;
while ((index < data.Length) && (data[index] == 0))
{
index++;
}
var destinationArray = new byte[data.Length - index];
Array.Copy(data, index, destinationArray, 0, data.Length - index);
return destinationArray;
}
public void SetData(byte[] ivalue)
{
if (ivalue.Length > MaxBigIntLen)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1TooBigIntegerValue, ivalue.Length);
}
if ((ivalue.Length > 0) && ((ivalue[0] & 0x80) != 0))
{
var index = 0;
var num = 0;
_sign = -1;
while ((num < ivalue.Length) && (ivalue[index] == 0xff))
{
num++;
index++;
}
var num2 = num;
while ((num2 < ivalue.Length) && (ivalue[index] == 0))
{
num2++;
index++;
}
var num3 = (num2 == ivalue.Length) ? 1 : 0;
_value = new byte[(ivalue.Length - num) + num3];
index = num;
var num4 = num;
while (num < ivalue.Length)
{
unchecked
{
_value[(num - num4) + num3] = (byte)~ivalue[index];
}
num++;
index++;
}
for (num = _value.Length - 1; (_value[num] = (byte)(_value[num] + 1)) == 0; num--)
{
}
_value = RemoveLeadingZeroBytes(_value);
}
else
{
_value = RemoveLeadingZeroBytes(ivalue);
_sign = (ivalue.Length == 0) ? 0 : 1;
}
}
private static int ShiftLeft(BigInteger data, uint shift)
{
var value = data._value;
var length = value.Length;
var index = (int)(shift >> AddressBits);
var num3 = ((int)shift) & BitIndexMask;
var num4 = 8 - num3;
var num5 = 0;
var num7 = length;
if (length != 0)
{
length = length << AddressBits;
var num6 = (int)((((length - shift) + 8L) - 1L) >> AddressBits);
while (num5 < (num6 - 1))
{
value[num5++] = (byte)((value[index] << num3) | ((num4 == 8) ? 0 : (value[index + 1] >> num4)));
index++;
}
length &= BitIndexMask;
value[num5] = (num7 == num6) ? ((byte)((value[index] & BitsLeftOf(length)) << num3)) : ((byte)((value[index] << num3) | ((num4 == 8) ? 0 : ((value[index + 1] & BitsLeftOf(length)) >> num4))));
if (num6 < num7)
{
for (var i = num6; i < (num7 - num6); i++)
{
value[i] = 0;
}
}
}
return 0;
}
public override string ToString()
{
return ToString(10);
}
public string ToString(int radix)
{
if ((radix == 2) || (radix == 0x10))
{
int num;
int num2;
if (radix == 2)
{
num2 = 8;
num = 1;
}
else
{
num2 = 2;
num = 4;
}
var num3 = num2 * GetDataLen();
var chArray = new char[num3];
var index = num3 - 1;
for (var i = _value.Length - 1; i >= 0; i--)
{
byte num6;
int num8;
if (_sign < 0)
{
unchecked
{
num6 = (byte)~_value[i];
}
if ((_sign < 0) && ((num6 = (byte)(num6 + 1)) != 0))
{
_sign = 0;
}
}
else
{
num6 = _value[i];
}
var num7 = num8 = 0;
while (num7 < num2)
{
var b = (num6 >> num8) & ((1 << num) - 1);
chArray[index] = NibbleToHexChar(b);
num7++;
index--;
num8 += num;
}
}
while (index >= 0)
{
chArray[index--] = '0';
}
return new string(chArray);
}
var reminder = 0;
var str = "";
var quotient = new BigInteger();
var copy = (radix == 10) ? GetCopy() : GetCopyAndInverse();
do
{
DivideByInt(ref copy, ByteRadix[radix], ref quotient, ref reminder);
var str2 = IntToStr(reminder, radix);
var length = str2.Length;
str = str2 + str;
if ((quotient._value.Length != 0) || (radix != 10))
{
int num12;
for (num12 = length; num12 < DigitsPerByte[radix]; num12++)
{
str = '0' + str;
}
FastCopy(ref quotient, ref copy);
if (((quotient._value.Length == 0) && (_sign > 0)) && ((radix != 10) && ((reminder & 0x80) != 0)))
{
str = '0' + str;
}
}
else if ((_sign < 0) && (radix == 10))
{
str = '-' + str;
}
}
while ((quotient._value != null) && (quotient._value.Length != 0));
return str;
}
private static byte[] TrustedStripLeadingZeroInts(byte[] val)
{
var index = 0;
while ((index < val.Length) && (val[index] == 0))
{
index++;
}
if (index <= 0)
{
return val;
}
var buffer = new byte[val.Length - index];
for (var i = 0; i < (val.Length - index); i++)
{
buffer[i] = val[index + i];
}
return buffer;
}
}
}

View File

@@ -0,0 +1,12 @@
namespace GostCryptography.Asn1.Ber
{
public interface IAsn1InputStream
{
int Available();
void Close();
void Mark();
bool MarkSupported();
void Reset();
long Skip(long nbytes);
}
}

View File

@@ -0,0 +1,9 @@
namespace GostCryptography.Asn1.Ber
{
public interface IAsn1NamedEventHandler
{
void Characters(string svalue, short typeCode);
void EndElement(string name, int index);
void StartElement(string name, int index);
}
}

View File

@@ -0,0 +1,9 @@
namespace GostCryptography.Asn1.Ber
{
public interface IAsn1TaggedEventHandler
{
void Contents(byte[] data);
void EndElement(Asn1Tag tag);
void StartElement(Asn1Tag tag, int len, byte[] tagLenBytes);
}
}

View File

@@ -0,0 +1,12 @@
using System.IO;
namespace GostCryptography.Asn1.Ber
{
public interface IAsn1Type
{
void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength);
int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging);
void Encode(Asn1BerOutputStream outs, bool explicitTagging);
void Print(TextWriter outs, string varName, int level);
}
}

View File

@@ -0,0 +1,16 @@
namespace GostCryptography.Asn1.Ber
{
public class IntHolder
{
public int Value;
public IntHolder()
{
}
public IntHolder(int value)
{
Value = value;
}
}
}

View File

@@ -0,0 +1,156 @@
using System;
using System.Collections;
namespace GostCryptography.Asn1.Ber
{
class Tokenizer : IEnumerator
{
private readonly char[] _chars;
private readonly bool _includeDelims;
private long _currentPos;
private string _delimiters;
public Tokenizer(string source)
{
_delimiters = " \t\n\r\f";
_chars = source.ToCharArray();
}
public Tokenizer(string source, string delimiters)
: this(source)
{
_delimiters = delimiters;
}
public Tokenizer(string source, string delimiters, bool includeDelims)
: this(source, delimiters)
{
_includeDelims = includeDelims;
}
public int Count
{
get
{
int num3;
var currentPos = _currentPos;
var num2 = 0;
try
{
while (true)
{
NextToken();
num2++;
}
}
catch (ArgumentOutOfRangeException)
{
_currentPos = currentPos;
num3 = num2;
}
return num3;
}
}
public bool MoveNext()
{
return HasMoreTokens();
}
public void Reset()
{
}
public object Current
{
get { return NextToken(); }
}
public bool HasMoreTokens()
{
var currentPos = _currentPos;
try
{
NextToken();
}
catch (ArgumentOutOfRangeException)
{
return false;
}
finally
{
_currentPos = currentPos;
}
return true;
}
public string NextToken()
{
return NextToken(_delimiters);
}
public string NextToken(string delimiters)
{
_delimiters = delimiters;
var array = delimiters.ToCharArray();
if (_currentPos == _chars.Length)
{
throw ExceptionUtility.ArgumentOutOfRange("delimiters");
}
if ((Array.IndexOf(array, _chars[(int)((IntPtr)_currentPos)], 0, array.Length) != -1) && _includeDelims)
{
long num;
_currentPos = (num = _currentPos) + 1L;
return ("" + _chars[(int)((IntPtr)num)]);
}
return NextToken(delimiters.ToCharArray());
}
private string NextToken(char[] delimiters)
{
var str = "";
var currentPos = _currentPos;
while (Array.IndexOf(delimiters, _chars[(int)((IntPtr)_currentPos)], 0, delimiters.Length) != -1)
{
if ((_currentPos += 1L) == _chars.Length)
{
_currentPos = currentPos;
throw ExceptionUtility.ArgumentOutOfRange("delimiters");
}
}
while (Array.IndexOf(delimiters, _chars[(int)((IntPtr)_currentPos)], 0, delimiters.Length) == -1)
{
str = str + _chars[(int)((IntPtr)_currentPos)];
if ((_currentPos += 1L) == _chars.Length)
{
return str;
}
}
return str;
}
public string RemainingString()
{
if ((_chars != null) && (_currentPos < _chars.Length))
{
return new string(_chars, (int)_currentPos, _chars.Length);
}
return null;
}
}
}

View File

@@ -0,0 +1,75 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost
{
public abstract class GostAsn1Choice : Asn1Choice
{
private const byte Null = 1;
private const byte Params = 2;
protected abstract short TagForm { get; }
protected abstract int TagIdCode { get; }
protected abstract Asn1Type CreateParams();
public override string ElemName
{
get
{
switch (ChoiceId)
{
case Null:
return "null_";
case Params:
return "params_";
}
return "UNDEFINED";
}
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var tag = new Asn1Tag();
buffer.Mark();
var num = buffer.DecodeTagAndLength(tag);
if (tag.Equals(0, 0, NullTypeCode))
{
buffer.Reset();
SetElement(Null, new NullParams());
Element.Decode(buffer, true, num);
}
else
{
if (!tag.Equals(0, TagForm, TagIdCode))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidChoiceOptionTagException, tag, buffer.ByteCount);
}
buffer.Reset();
SetElement(Params, CreateParams());
Element.Decode(buffer, true, num);
}
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
switch (ChoiceId)
{
case Null:
return GetElement().Encode(buffer, true);
case Params:
return GetElement().Encode(buffer, true);
}
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidChoiceOptionException);
}
}
}

View File

@@ -0,0 +1,70 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_28147_89
{
public sealed class Gost_28147_89_BlobParams : Asn1Type
{
public Asn1ObjectIdentifier EncryptionParamSet { get; set; }
public Asn1OpenExt ExtElement { get; set; }
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;
EncryptionParamSet = null;
ExtElement = null;
var context = new Asn1BerDecodeContext(buffer, elemLength);
var parsedLen = new IntHolder();
if (!context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
}
EncryptionParamSet = new Asn1ObjectIdentifier();
EncryptionParamSet.Decode(buffer, true, parsedLen.Value);
if (!context.Expired())
{
if (buffer.PeekTag().Equals(0, 0, ObjectIdentifierTypeCode))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1SeqOrderException);
}
ExtElement = new Asn1OpenExt();
while (!context.Expired())
{
ExtElement.DecodeComponent(buffer);
}
}
else
{
ExtElement = null;
}
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = 0;
if (ExtElement != null)
{
len += ExtElement.Encode(buffer, false);
}
len += EncryptionParamSet.Encode(buffer, true);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len);
}
return len;
}
}
}

View File

@@ -0,0 +1,20 @@
namespace GostCryptography.Asn1.Gost.Gost_28147_89
{
public static class Gost_28147_89_Constants
{
/// <summary>
/// Алгоритм шифрования ГОСТ 28147-89.
/// </summary>
public static readonly OidValue EncryptAlgorithm = OidValue.FromString("1.2.643.2.2.21");
/// <summary>
/// Алгоритм шифрования по ГОСТ Р 34.12-2015 Магма.
/// </summary>
public static readonly OidValue EncryptAlgorithmMagma = OidValue.FromString("1.2.643.7.1.1.5.1");
/// <summary>
/// Алгоритм шифрования по ГОСТ Р 34.12-2015 Кузнечик.
/// </summary>
public static readonly OidValue EncryptAlgorithmKuznyechik = OidValue.FromString("1.2.643.7.1.1.5.2");
}
}

View File

@@ -0,0 +1,82 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_28147_89
{
public sealed class Gost_28147_89_EncryptedKey : Asn1Type
{
public Gost_28147_89_Key EncryptedKey { get; set; }
public Gost_28147_89_Mac MacKey { get; set; }
public Gost_28147_89_Key MaskKey { get; set; }
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;
EncryptedKey = null;
MacKey = null;
MaskKey = null;
var context = new Asn1BerDecodeContext(buffer, elemLength);
var parsedLen = new IntHolder();
if (!context.MatchElemTag(0, 0, OctetStringTypeCode, parsedLen, false))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
}
EncryptedKey = new Gost_28147_89_Key();
EncryptedKey.Decode(buffer, true, parsedLen.Value);
if (context.MatchElemTag(0x80, 0, EocTypeCode, parsedLen, true))
{
MaskKey = new Gost_28147_89_Key();
MaskKey.Decode(buffer, false, parsedLen.Value);
}
if (!context.MatchElemTag(0, 0, OctetStringTypeCode, parsedLen, false))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
}
MacKey = new Gost_28147_89_Mac();
MacKey.Decode(buffer, true, parsedLen.Value);
if (MacKey.Length != 4)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(MacKey.Length), MacKey.Length);
}
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = 0;
if (MacKey.Length != 4)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(MacKey.Length), MacKey.Length);
}
len += MacKey.Encode(buffer, true);
if (MaskKey != null)
{
var maskKeyLen = MaskKey.Encode(buffer, false);
len += maskKeyLen;
len += buffer.EncodeTagAndLength(0x80, 0, EocTypeCode, maskKeyLen);
}
len += EncryptedKey.Encode(buffer, true);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len);
}
return len;
}
}
}

View File

@@ -0,0 +1,35 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_28147_89
{
public sealed class Gost_28147_89_Iv : Asn1OctetString
{
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
base.Decode(buffer, explicitTagging, implicitLength);
if (Length != 8)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length);
}
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
if (Length != 8)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length);
}
var len = base.Encode(buffer, false);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Tag, len);
}
return len;
}
}
}

View File

@@ -0,0 +1,44 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_28147_89
{
public sealed class Gost_28147_89_Key : Asn1OctetString
{
public Gost_28147_89_Key()
{
}
public Gost_28147_89_Key(byte[] data)
: base(data)
{
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
base.Decode(buffer, explicitTagging, implicitLength);
if (Length != 32)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length);
}
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
if (Length != 32)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length);
}
var len = base.Encode(buffer, false);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Tag, len);
}
return len;
}
}
}

View File

@@ -0,0 +1,153 @@
using System;
using GostCryptography.Asn1.Ber;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_28147_89
{
/// <summary>
/// Информация о зашифрованном ключе ГОСТ 28147-89.
/// </summary>
public sealed class Gost_28147_89_KeyExchangeInfo
{
/// <summary>
/// Идентификатор OID параметров шифрования.
/// </summary>
public string EncryptionParamSet { get; set; }
/// <summary>
/// Зашифрованный ключ.
/// </summary>
public byte[] EncryptedKey { get; set; }
/// <summary>
/// Контрольная сумма зашифрованного ключа (Message Authentication Code, MAC).
/// </summary>
public byte[] Mac { get; set; }
/// <summary>
/// Материал ключа пользователя (User Keying Material, UKM).
/// </summary>
public byte[] Ukm { get; set; }
/// <summary>
/// Зашифровать информацию о ключе.
/// </summary>
public void Decode(byte[] data)
{
if (data == null)
{
throw ExceptionUtility.ArgumentNull(nameof(data));
}
try
{
var asnDecoder = new Asn1BerDecodeBuffer(data);
var keyWrap = new Gost_28147_89_KeyWrap();
keyWrap.Decode(asnDecoder);
EncryptionParamSet = keyWrap.EncryptedParams.EncryptionParamSet.Oid.Value;
EncryptedKey = keyWrap.EncryptedKey.EncryptedKey.Value;
Mac = keyWrap.EncryptedKey.MacKey.Value;
Ukm = keyWrap.EncryptedParams.Ukm.Value;
}
catch (Exception exception)
{
throw ExceptionUtility.CryptographicException(exception, Resources.Asn1DecodeError, nameof(Gost_28147_89_KeyWrap));
}
}
/// <summary>
/// Расшифровать информацию о ключе.
/// </summary>
public byte[] Encode()
{
byte[] data;
var keyWrap = new Gost_28147_89_KeyWrap();
try
{
keyWrap.EncryptedKey = new Gost_28147_89_EncryptedKey
{
EncryptedKey = new Gost_28147_89_Key(EncryptedKey),
MacKey = new Gost_28147_89_Mac(Mac)
};
keyWrap.EncryptedParams = new Gost_28147_89_KeyWrapParams
{
EncryptionParamSet = Asn1ObjectIdentifier.FromString(EncryptionParamSet),
Ukm = new Asn1OctetString(Ukm)
};
var asnEncoder = new Asn1BerEncodeBuffer();
keyWrap.Encode(asnEncoder);
data = asnEncoder.MsgCopy;
}
catch (Exception exception)
{
throw ExceptionUtility.CryptographicException(exception, Resources.Asn1DecodeError, nameof(Gost_28147_89_KeyWrap));
}
return data;
}
/// <summary>
/// Расшифровать идентификатор OID параметров шифрования.
/// </summary>
public static string DecodeEncryptionParamSet(byte[] data)
{
if (data == null)
{
throw ExceptionUtility.ArgumentNull(nameof(data));
}
string encryptionParamSet;
try
{
var asnDecoder = new Asn1BerDecodeBuffer(data);
var parameters = new Gost_28147_89_BlobParams();
parameters.Decode(asnDecoder);
encryptionParamSet = parameters.EncryptionParamSet.Oid.Value;
}
catch (Exception exception)
{
throw ExceptionUtility.CryptographicException(exception, Resources.Asn1DecodeError, typeof(Gost_28147_89_BlobParams).FullName);
}
return encryptionParamSet;
}
/// <summary>
/// Зашифровать идентификатор OID параметров шифрования.
/// </summary>
public static byte[] EncodeEncryptionParamSet(string encryptionParamSet)
{
if (encryptionParamSet == null)
{
throw ExceptionUtility.ArgumentNull(nameof(encryptionParamSet));
}
byte[] data;
try
{
var parameters = new Gost_28147_89_BlobParams { EncryptionParamSet = Asn1ObjectIdentifier.FromString(encryptionParamSet) };
var asnEncoder = new Asn1BerEncodeBuffer();
parameters.Encode(asnEncoder);
data = asnEncoder.MsgCopy;
}
catch (Exception exception)
{
throw ExceptionUtility.CryptographicException(exception, Resources.Asn1EncodeError, nameof(Gost_28147_89_BlobParams));
}
return data;
}
}
}

View File

@@ -0,0 +1,54 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_28147_89
{
public sealed class Gost_28147_89_KeyWrap : Asn1Type
{
public Gost_28147_89_EncryptedKey EncryptedKey { get; set; }
public Gost_28147_89_KeyWrapParams EncryptedParams { get; set; }
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;
EncryptedKey = null;
EncryptedParams = null;
var context = new Asn1BerDecodeContext(buffer, elemLength);
var parsedLen = new IntHolder();
if (!context.MatchElemTag(0, 0x20, SequenceTypeCode, parsedLen, false))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
}
EncryptedKey = new Gost_28147_89_EncryptedKey();
EncryptedKey.Decode(buffer, true, parsedLen.Value);
if (!context.MatchElemTag(0, 0x20, SequenceTypeCode, parsedLen, false))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
}
EncryptedParams = new Gost_28147_89_KeyWrapParams();
EncryptedParams.Decode(buffer, true, parsedLen.Value);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = 0;
len += EncryptedParams.Encode(buffer, true);
len += EncryptedKey.Encode(buffer, true);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len);
}
return len;
}
}
}

View File

@@ -0,0 +1,67 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_28147_89
{
public sealed class Gost_28147_89_KeyWrapParams : Asn1Type
{
public Asn1ObjectIdentifier EncryptionParamSet { get; set; }
public Asn1OctetString Ukm { get; set; }
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;
EncryptionParamSet = null;
Ukm = null;
var context = new Asn1BerDecodeContext(buffer, elemLength);
var parsedLen = new IntHolder();
if (!context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
}
EncryptionParamSet = new Asn1ObjectIdentifier();
EncryptionParamSet.Decode(buffer, true, parsedLen.Value);
if (context.MatchElemTag(0, 0, OctetStringTypeCode, parsedLen, false))
{
Ukm = new Asn1OctetString();
Ukm.Decode(buffer, true, parsedLen.Value);
if (Ukm.Length != 8)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Ukm.Length), Ukm.Length);
}
}
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = 0;
if (Ukm != null)
{
if (Ukm.Length != 8)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Ukm.Length), Ukm.Length);
}
len += Ukm.Encode(buffer, true);
}
len += EncryptionParamSet.Encode(buffer, true);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len);
}
return len;
}
}
}

View File

@@ -0,0 +1,45 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_28147_89
{
public sealed class Gost_28147_89_Mac : Asn1OctetString
{
public Gost_28147_89_Mac()
{
}
public Gost_28147_89_Mac(byte[] data)
: base(data)
{
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
base.Decode(buffer, explicitTagging, implicitLength);
if ((Length < 1) || (Length > 4))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length);
}
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
if ((Length < 1) || (Length > 4))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length);
}
var len = base.Encode(buffer, false);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Tag, len);
}
return len;
}
}
}

View File

@@ -0,0 +1,55 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_28147_89
{
public sealed class Gost_28147_89_Params : Asn1Type
{
public Asn1ObjectIdentifier EncryptionParamSet { get; private set; }
public Gost_28147_89_Iv Iv { get; private set; }
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;
EncryptionParamSet = null;
Iv = null;
var context = new Asn1BerDecodeContext(buffer, elemLength);
var parsedLen = new IntHolder();
if (!context.MatchElemTag(0, 0, OctetStringTypeCode, parsedLen, false))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
}
Iv = new Gost_28147_89_Iv();
Iv.Decode(buffer, true, parsedLen.Value);
if (!context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
}
EncryptionParamSet = new Asn1ObjectIdentifier();
EncryptionParamSet.Decode(buffer, true, parsedLen.Value);
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = 0;
len += EncryptionParamSet.Encode(buffer, true);
len += Iv.Encode(buffer, true);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len);
}
return len;
}
}
}

View File

@@ -0,0 +1,165 @@
using System;
using GostCryptography.Asn1.Ber;
using GostCryptography.Asn1.Gost.Gost_28147_89;
using GostCryptography.Asn1.Gost.PublicKey;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_R3410
{
/// <summary>
/// Информация о ключе цифровой подписи ГОСТ Р 34.10.
/// </summary>
public abstract class Gost_R3410_KeyExchange
{
/// <summary>
/// Информация о зашифрованном ключе ГОСТ 28147-89.
/// </summary>
public Gost_28147_89_KeyExchangeInfo SessionEncryptedKey { get; set; }
/// <summary>
/// Параметры ключа цифровой подписи ГОСТ Р 34.10.
/// </summary>
public Gost_R3410_KeyExchangeParams TransportParameters { get; set; }
protected abstract OidValue KeyAlgorithm { get; }
protected abstract Gost_R3410_PublicKeyParams CreatePublicKeyParams();
protected abstract Gost_R3410_KeyExchangeParams CreateKeyExchangeParams();
/// <summary>
/// Расшифровать информацию о ключе.
/// </summary>
public void Decode(byte[] data)
{
if (data == null)
{
throw ExceptionUtility.ArgumentNull(nameof(data));
}
try
{
var asnDecoder = new Asn1BerDecodeBuffer(data);
var keyTransport = new Gost_R3410_KeyTransport();
keyTransport.Decode(asnDecoder);
DecodeSessionKey(keyTransport);
DecodePublicKey(keyTransport);
}
catch (Exception exception)
{
throw ExceptionUtility.CryptographicException(exception, Resources.Asn1DecodeError, nameof(Gost_R3410_KeyTransport));
}
}
private void DecodeSessionKey(Gost_R3410_KeyTransport keyTransport)
{
SessionEncryptedKey = new Gost_28147_89_KeyExchangeInfo
{
EncryptionParamSet = keyTransport.TransportParams.EncryptionParamSet.Oid.Value,
EncryptedKey = keyTransport.SessionEncryptedKey.EncryptedKey.Value,
Mac = keyTransport.SessionEncryptedKey.MacKey.Value,
Ukm = keyTransport.TransportParams.Ukm.Value
};
}
private void DecodePublicKey(Gost_R3410_KeyTransport keyTransport)
{
var publicKeyInfo = keyTransport.TransportParams.EphemeralPublicKey;
var publicKeyAlgOid = publicKeyInfo.Algorithm.Algorithm.Oid.Value;
if (!publicKeyAlgOid.Equals(KeyAlgorithm.Value))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1DecodeAlg, publicKeyAlgOid);
}
var choice = publicKeyInfo.Algorithm.Parameters as Asn1Choice;
if (choice == null)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1DecodeAlgorithmParameters);
}
var publicKeyParams = choice.GetElement() as Gost_R3410_PublicKeyParams;
if (publicKeyParams == null)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1DecodeAlgorithmParameters);
}
var asnDecoder = new Asn1BerDecodeBuffer(publicKeyInfo.SubjectPublicKey.Value);
var publicKey = new Asn1OctetString();
publicKey.Decode(asnDecoder);
TransportParameters = CreateKeyExchangeParams();
TransportParameters.PublicKeyParamSet = publicKeyParams.PublicKeyParamSet.Oid.Value;
TransportParameters.DigestParamSet = publicKeyParams.DigestParamSet?.Oid.Value;
TransportParameters.EncryptionParamSet = publicKeyParams.EncryptionParamSet?.Oid.Value;
TransportParameters.PublicKey = publicKey.Value;
TransportParameters.PrivateKey = null;
}
/// <summary>
/// Зашифровать информацию о ключе.
/// </summary>
public byte[] Encode()
{
var asnEncoder = new Asn1BerEncodeBuffer();
var keyTransport = new Gost_R3410_KeyTransport();
try
{
keyTransport.SessionEncryptedKey = new Gost_28147_89_EncryptedKey
{
EncryptedKey = new Gost_28147_89_Key(SessionEncryptedKey.EncryptedKey),
MacKey = new Gost_28147_89_Mac(SessionEncryptedKey.Mac)
};
keyTransport.TransportParams = new Gost_R3410_TransportParams
{
EncryptionParamSet = Asn1ObjectIdentifier.FromString(SessionEncryptedKey.EncryptionParamSet),
EphemeralPublicKey = EncodePublicKey(TransportParameters),
Ukm = new Asn1OctetString(SessionEncryptedKey.Ukm)
};
keyTransport.Encode(asnEncoder);
}
catch (Exception exception)
{
throw ExceptionUtility.CryptographicException(exception, Resources.Asn1EncodeError, nameof(Gost_R3410_KeyTransport));
}
return asnEncoder.MsgCopy;
}
private SubjectPublicKeyInfo EncodePublicKey(Gost_R3410_KeyExchangeParams transportParameters)
{
var asnEncoder = new Asn1BerEncodeBuffer();
var publicKey = new Asn1OctetString(transportParameters.PublicKey);
publicKey.Encode(asnEncoder);
var publicKeyValue = asnEncoder.MsgCopy;
var publicKeyInfo = new SubjectPublicKeyInfo
{
SubjectPublicKey = new Asn1BitString(publicKeyValue.Length * 8, publicKeyValue)
};
var publicKeyParams = CreatePublicKeyParams();
publicKeyParams.PublicKeyParamSet = Asn1ObjectIdentifier.FromString(transportParameters.PublicKeyParamSet);
publicKeyParams.DigestParamSet = Asn1ObjectIdentifier.FromString(transportParameters.DigestParamSet);
publicKeyParams.EncryptionParamSet = Asn1ObjectIdentifier.FromString(transportParameters.EncryptionParamSet);
asnEncoder.Reset();
publicKeyParams.Encode(asnEncoder);
var publicKeyAlgOid = new Asn1ObjectIdentifier(KeyAlgorithm);
publicKeyInfo.Algorithm = new AlgorithmIdentifier(publicKeyAlgOid, new Asn1OpenType(asnEncoder.MsgCopy));
return publicKeyInfo;
}
}
}

View File

@@ -0,0 +1,161 @@
using System;
using GostCryptography.Asn1.Ber;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_R3410
{
/// <summary>
/// Параметры ключа цифровой подписи ГОСТ Р 34.10.
/// </summary>
public abstract class Gost_R3410_KeyExchangeParams
{
protected Gost_R3410_KeyExchangeParams()
{
}
protected Gost_R3410_KeyExchangeParams(Gost_R3410_KeyExchangeParams other)
{
DigestParamSet = other.DigestParamSet;
PublicKeyParamSet = other.PublicKeyParamSet;
EncryptionParamSet = other.EncryptionParamSet;
PublicKey = other.PublicKey;
PrivateKey = other.PrivateKey;
}
/// <summary>
/// Идентификатор OID параметров хэширования.
/// </summary>
public string DigestParamSet { get; set; }
/// <summary>
/// Идентификатор OID параметров открытого ключа.
/// </summary>
public string PublicKeyParamSet { get; set; }
/// <summary>
/// Идентификатор OID параметров шифрования.
/// </summary>
public string EncryptionParamSet { get; set; }
/// <summary>
/// Открытый ключ.
/// </summary>
public byte[] PublicKey { get; set; }
/// <summary>
/// Закрытый ключ.
/// </summary>
public byte[] PrivateKey { get; set; }
public abstract Gost_R3410_KeyExchangeParams Clone();
protected abstract Gost_R3410_PublicKey CreatePublicKey();
protected abstract Gost_R3410_PublicKeyParams CreatePublicKeyParams();
/// <summary>
/// Расшифровать параметры.
/// </summary>
public void DecodeParameters(byte[] data)
{
if (data == null)
{
throw ExceptionUtility.ArgumentNull(nameof(data));
}
try
{
var asnDecoder = new Asn1BerDecodeBuffer(data);
var publicKeyParams = CreatePublicKeyParams();
publicKeyParams.Decode(asnDecoder);
PublicKeyParamSet = publicKeyParams.PublicKeyParamSet.Oid.Value;
DigestParamSet = publicKeyParams.DigestParamSet?.Oid.Value;
EncryptionParamSet = publicKeyParams.EncryptionParamSet?.Oid.Value;
}
catch (Exception exception)
{
throw ExceptionUtility.CryptographicException(exception, Resources.Asn1DecodeError, nameof(Gost_R3410_PublicKeyParams));
}
}
/// <summary>
/// Зашифровать параметры.
/// </summary>
public byte[] EncodeParameters()
{
byte[] data;
try
{
var publicKeyParams = CreatePublicKeyParams();
publicKeyParams.PublicKeyParamSet = Asn1ObjectIdentifier.FromString(PublicKeyParamSet);
publicKeyParams.DigestParamSet = Asn1ObjectIdentifier.FromString(DigestParamSet);
publicKeyParams.EncryptionParamSet = Asn1ObjectIdentifier.FromString(EncryptionParamSet);
var asnEncoder = new Asn1BerEncodeBuffer();
publicKeyParams.Encode(asnEncoder);
data = asnEncoder.MsgCopy;
}
catch (Exception exception)
{
throw ExceptionUtility.CryptographicException(exception, Resources.Asn1EncodeError, nameof(Gost_R3410_PublicKeyParams));
}
return data;
}
/// <summary>
/// Расшифровать публичный ключ.
/// </summary>
public void DecodePublicKey(byte[] data)
{
if (data == null)
{
throw ExceptionUtility.ArgumentNull(nameof(data));
}
try
{
var asnDecoder = new Asn1BerDecodeBuffer(data);
var publicKey = CreatePublicKey();
publicKey.Decode(asnDecoder);
PublicKey = publicKey.Value;
}
catch (Exception exception)
{
throw ExceptionUtility.CryptographicException(exception, Resources.Asn1DecodeError, nameof(Gost_R3410_PublicKey));
}
}
/// <summary>
/// Зашифровать публичный ключ.
/// </summary>
public byte[] EncodePublicKey()
{
byte[] data;
try
{
var publicKey = CreatePublicKey();
publicKey.Value = PublicKey;
var asnEncoder = new Asn1BerEncodeBuffer();
publicKey.Encode(asnEncoder);
data = asnEncoder.MsgCopy;
}
catch (Exception exception)
{
throw ExceptionUtility.CryptographicException(exception, Resources.Asn1EncodeError, nameof(Gost_R3410_PublicKeyParams));
}
return data;
}
}
}

View File

@@ -0,0 +1,61 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Asn1.Gost.Gost_28147_89;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_R3410
{
public sealed class Gost_R3410_KeyTransport : Asn1Type
{
public Gost_28147_89_EncryptedKey SessionEncryptedKey { get; set; }
public Gost_R3410_TransportParams TransportParams { get; set; }
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;
SessionEncryptedKey = null;
TransportParams = null;
var context = new Asn1BerDecodeContext(buffer, elemLength);
var parsedLen = new IntHolder();
if (!context.MatchElemTag(0, 0x20, SequenceTypeCode, parsedLen, false))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
}
SessionEncryptedKey = new Gost_28147_89_EncryptedKey();
SessionEncryptedKey.Decode(buffer, true, parsedLen.Value);
if (context.MatchElemTag(0x80, 0x20, EocTypeCode, parsedLen, true))
{
TransportParams = new Gost_R3410_TransportParams();
TransportParams.Decode(buffer, false, parsedLen.Value);
}
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = 0;
if (TransportParams != null)
{
var tpLength = TransportParams.Encode(buffer, false);
len += tpLength;
len += buffer.EncodeTagAndLength(0x80, 0x20, EocTypeCode, tpLength);
}
len += SessionEncryptedKey.Encode(buffer, true);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len);
}
return len;
}
}
}

View File

@@ -0,0 +1,42 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_R3410
{
public abstract class Gost_R3410_PublicKey : Asn1OctetString
{
private readonly int _keySize;
protected Gost_R3410_PublicKey(int keySize)
{
_keySize = keySize;
}
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
base.Decode(buffer, explicitTagging, implicitLength);
if (Length != _keySize)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length);
}
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
if (Length != _keySize)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length);
}
var len = base.Encode(buffer, false);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Tag, len);
}
return len;
}
}
}

View File

@@ -0,0 +1,83 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_R3410
{
public abstract class Gost_R3410_PublicKeyParams : Asn1Type
{
public Asn1ObjectIdentifier PublicKeyParamSet { get; set; }
public Asn1ObjectIdentifier DigestParamSet { get; set; }
public Asn1ObjectIdentifier EncryptionParamSet { get; set; }
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;
PublicKeyParamSet = null;
DigestParamSet = null;
EncryptionParamSet = null;
var context = new Asn1BerDecodeContext(buffer, elemLength);
var parsedLen = new IntHolder();
if (context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false))
{
PublicKeyParamSet = new Asn1ObjectIdentifier();
PublicKeyParamSet.Decode(buffer, true, parsedLen.Value);
}
else
{
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
}
if (context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false))
{
DigestParamSet = new Asn1ObjectIdentifier();
DigestParamSet.Decode(buffer, true, parsedLen.Value);
}
if (context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false))
{
EncryptionParamSet = new Asn1ObjectIdentifier();
EncryptionParamSet.Decode(buffer, true, parsedLen.Value);
}
if (!context.Expired())
{
var lastTag = buffer.PeekTag();
if (lastTag.Equals(0, 0, ObjectIdentifierTypeCode))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1SeqOrderException);
}
}
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = 0;
if (EncryptionParamSet != null)
{
len += EncryptionParamSet.Encode(buffer, true);
}
if (DigestParamSet != null)
{
len += DigestParamSet.Encode(buffer, true);
}
len += PublicKeyParamSet.Encode(buffer, true);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len);
}
return len;
}
}
}

View File

@@ -0,0 +1,9 @@
namespace GostCryptography.Asn1.Gost.Gost_R3410
{
public abstract class Gost_R3410_PublicKeyType : GostAsn1Choice
{
protected override short TagForm => 0x20;
protected override int TagIdCode => SequenceTypeCode;
}
}

View File

@@ -0,0 +1,85 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Asn1.Gost.Gost_28147_89;
using GostCryptography.Asn1.Gost.PublicKey;
using GostCryptography.Properties;
namespace GostCryptography.Asn1.Gost.Gost_R3410
{
public sealed class Gost_R3410_TransportParams : Asn1Type
{
public Asn1ObjectIdentifier EncryptionParamSet { get; set; }
public SubjectPublicKeyInfo EphemeralPublicKey { get; set; }
public Asn1OctetString Ukm { get; set; }
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
{
var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;
EncryptionParamSet = null;
EphemeralPublicKey = null;
Ukm = null;
var context = new Asn1BerDecodeContext(buffer, elemLength);
var parsedLen = new IntHolder();
if (!context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
}
EncryptionParamSet = new Asn1ObjectIdentifier();
EncryptionParamSet.Decode(buffer, true, parsedLen.Value);
if (context.MatchElemTag(0x80, 0x20, EocTypeCode, parsedLen, true))
{
EphemeralPublicKey = new SubjectPublicKeyInfo();
EphemeralPublicKey.Decode(buffer, false, parsedLen.Value);
}
if (!context.MatchElemTag(0, 0, OctetStringTypeCode, parsedLen, false))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
}
Ukm = new Asn1OctetString();
Ukm.Decode(buffer, true, parsedLen.Value);
if (Ukm.Length != 8)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Ukm.Length), Ukm.Length);
}
}
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
{
var len = 0;
if (Ukm.Length != 8)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Ukm.Length), Ukm.Length);
}
len += Ukm.Encode(buffer, true);
if (EphemeralPublicKey != null)
{
var epkLength = EphemeralPublicKey.Encode(buffer, false);
len += epkLength;
len += buffer.EncodeTagAndLength(0x80, 0x20, EocTypeCode, epkLength);
}
len += EncryptionParamSet.Encode(buffer, true);
if (explicitTagging)
{
len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len);
}
return len;
}
}
}

View File

@@ -0,0 +1,25 @@
namespace GostCryptography.Asn1.Gost.Gost_R3410_2001
{
public static class Gost_R3410_2001_Constants
{
/// <summary>
/// Алгоритм ГОСТ Р 34.10-2001, используемый при экспорте/импорте ключей.
/// </summary>
public static readonly OidValue KeyAlgorithm = OidValue.FromString("1.2.643.2.2.19");
/// <summary>
/// Алгоритм Диффи-Хеллмана на базе эллиптической кривой.
/// </summary>
public static readonly OidValue DhAlgorithm = OidValue.FromString("1.2.643.2.2.98");
/// <summary>
/// Алгоритм цифровой подписи ГОСТ Р 34.10-2001.
/// </summary>
public static readonly OidValue SignatureAlgorithm = OidValue.FromString("1.2.643.2.2.3");
/// <summary>
/// Функция хэширования ГОСТ Р 34.11-94.
/// </summary>
public static readonly OidValue HashAlgorithm = OidValue.FromString("1.2.643.2.2.9");
}
}

View File

@@ -0,0 +1,13 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Asn1.Gost.Gost_R3410;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2001
{
public sealed class Gost_R3410_2001_DhPublicKeyType : Gost_R3410_PublicKeyType
{
protected override Asn1Type CreateParams()
{
return new Gost_R3410_2001_PublicKeyParams();
}
}
}

View File

@@ -0,0 +1,17 @@
using GostCryptography.Asn1.Gost.Gost_R3410;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2001
{
/// <inheritdoc />
public sealed class Gost_R3410_2001_KeyExchange : Gost_R3410_KeyExchange
{
/// <inheritdoc />
protected override OidValue KeyAlgorithm => Gost_R3410_2001_Constants.KeyAlgorithm;
/// <inheritdoc />
protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_2001_PublicKeyParams();
/// <inheritdoc />
protected override Gost_R3410_KeyExchangeParams CreateKeyExchangeParams() => new Gost_R3410_2001_KeyExchangeParams();
}
}

View File

@@ -0,0 +1,28 @@
using GostCryptography.Asn1.Gost.Gost_R3410;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2001
{
/// <inheritdoc />
public sealed class Gost_R3410_2001_KeyExchangeParams : Gost_R3410_KeyExchangeParams
{
/// <inheritdoc />
public Gost_R3410_2001_KeyExchangeParams()
{
}
/// <inheritdoc />
public Gost_R3410_2001_KeyExchangeParams(Gost_R3410_2001_KeyExchangeParams other) : base(other)
{
}
/// <inheritdoc />
public override Gost_R3410_KeyExchangeParams Clone() => new Gost_R3410_2001_KeyExchangeParams(this);
/// <inheritdoc />
protected override Gost_R3410_PublicKey CreatePublicKey() => new Gost_R3410_2001_PublicKey();
/// <inheritdoc />
protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_2001_PublicKeyParams();
}
}

View File

@@ -0,0 +1,13 @@
using GostCryptography.Asn1.Gost.Gost_R3410;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2001
{
/// <inheritdoc />
public sealed class Gost_R3410_2001_PublicKey : Gost_R3410_PublicKey
{
/// <inheritdoc />
public Gost_R3410_2001_PublicKey() : base(64)
{
}
}
}

View File

@@ -0,0 +1,8 @@
using GostCryptography.Asn1.Gost.Gost_R3410;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2001
{
public sealed class Gost_R3410_2001_PublicKeyParams : Gost_R3410_PublicKeyParams
{
}
}

View File

@@ -0,0 +1,13 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Asn1.Gost.Gost_R3410;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2001
{
public sealed class Gost_R3410_2001_PublicKeyType : Gost_R3410_PublicKeyType
{
protected override Asn1Type CreateParams()
{
return new Gost_R3410_2001_PublicKeyParams();
}
}
}

View File

@@ -0,0 +1,8 @@
using GostCryptography.Asn1.Gost.Gost_R3411;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2001
{
public sealed class Gost_R3411_2001_DigestParams : Gost_R3411_DigestParams
{
}
}

View File

@@ -0,0 +1,13 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Asn1.Gost.Gost_R3411;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2001
{
public sealed class Gost_R3411_2001_DigestParamsType : Gost_R3411_DigestParamsType
{
protected override Asn1Type CreateParams()
{
return new Gost_R3411_2001_DigestParams();
}
}
}

View File

@@ -0,0 +1,25 @@
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256
{
public static class Gost_R3410_2012_256_Constants
{
/// <summary>
/// Алгоритм ГОСТ Р 34.10-2012 для ключей длины 256 бит, используемый при экспорте/импорте ключей.
/// </summary>
public static readonly OidValue KeyAlgorithm = OidValue.FromString("1.2.643.7.1.1.1.1");
/// <summary>
/// Алгоритм Диффи-Хеллмана на базе эллиптической кривой для ключей длины 256 бит.
/// </summary>
public static readonly OidValue DhAlgorithm = OidValue.FromString("1.2.643.7.1.1.6.1");
/// <summary>
/// Алгоритм цифровой подписи ГОСТ Р 34.10-2012 для ключей длины 256 бит.
/// </summary>
public static readonly OidValue SignatureAlgorithm = OidValue.FromString("1.2.643.7.1.1.3.2");
/// <summary>
/// Функция хэширования ГОСТ Р 34.11-2012, длина выхода 256 бит.
/// </summary>
public static readonly OidValue HashAlgorithm = OidValue.FromString("1.2.643.7.1.1.2.2");
}
}

View File

@@ -0,0 +1,13 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Asn1.Gost.Gost_R3410;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256
{
public sealed class Gost_R3410_2012_256_DhPublicKeyType : Gost_R3410_PublicKeyType
{
protected override Asn1Type CreateParams()
{
return new Gost_R3410_2012_256_PublicKeyParams();
}
}
}

View File

@@ -0,0 +1,17 @@
using GostCryptography.Asn1.Gost.Gost_R3410;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256
{
/// <inheritdoc />
public sealed class Gost_R3410_2012_256_KeyExchange : Gost_R3410_KeyExchange
{
/// <inheritdoc />
protected override OidValue KeyAlgorithm => Gost_R3410_2012_256_Constants.KeyAlgorithm;
/// <inheritdoc />
protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_2012_256_PublicKeyParams();
/// <inheritdoc />
protected override Gost_R3410_KeyExchangeParams CreateKeyExchangeParams() => new Gost_R3410_2012_256_KeyExchangeParams();
}
}

View File

@@ -0,0 +1,28 @@
using GostCryptography.Asn1.Gost.Gost_R3410;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256
{
/// <inheritdoc />
public sealed class Gost_R3410_2012_256_KeyExchangeParams : Gost_R3410_KeyExchangeParams
{
/// <inheritdoc />
public Gost_R3410_2012_256_KeyExchangeParams()
{
}
/// <inheritdoc />
public Gost_R3410_2012_256_KeyExchangeParams(Gost_R3410_2012_256_KeyExchangeParams other) : base(other)
{
}
/// <inheritdoc />
public override Gost_R3410_KeyExchangeParams Clone() => new Gost_R3410_2012_256_KeyExchangeParams(this);
/// <inheritdoc />
protected override Gost_R3410_PublicKey CreatePublicKey() => new Gost_R3410_2012_256_PublicKey();
/// <inheritdoc />
protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_2012_256_PublicKeyParams();
}
}

View File

@@ -0,0 +1,13 @@
using GostCryptography.Asn1.Gost.Gost_R3410;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256
{
/// <inheritdoc />
public sealed class Gost_R3410_2012_256_PublicKey : Gost_R3410_PublicKey
{
/// <inheritdoc />
public Gost_R3410_2012_256_PublicKey() : base(64)
{
}
}
}

View File

@@ -0,0 +1,8 @@
using GostCryptography.Asn1.Gost.Gost_R3410;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256
{
public sealed class Gost_R3410_2012_256_PublicKeyParams : Gost_R3410_PublicKeyParams
{
}
}

View File

@@ -0,0 +1,13 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Asn1.Gost.Gost_R3410;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256
{
public sealed class Gost_R3410_2012_256_PublicKeyType : Gost_R3410_PublicKeyType
{
protected override Asn1Type CreateParams()
{
return new Gost_R3410_2012_256_PublicKeyParams();
}
}
}

View File

@@ -0,0 +1,8 @@
using GostCryptography.Asn1.Gost.Gost_R3411;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256
{
public sealed class Gost_R3411_2012_256_DigestParams : Gost_R3411_DigestParams
{
}
}

View File

@@ -0,0 +1,13 @@
using GostCryptography.Asn1.Ber;
using GostCryptography.Asn1.Gost.Gost_R3411;
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256
{
public sealed class Gost_R3411_2012_256_DigestParamsType : Gost_R3411_DigestParamsType
{
protected override Asn1Type CreateParams()
{
return new Gost_R3411_2012_256_DigestParams();
}
}
}

Some files were not shown because too many files have changed in this diff Show More