Add project
Basic formatting applied. Unnecessary comments have been removed. Suspicious code is covered by TODO.
This commit is contained in:
72
Hcs.Client/GostCryptography/Asn1/Gost/GostAsn1Choice.cs
Normal file
72
Hcs.Client/GostCryptography/Asn1/Gost/GostAsn1Choice.cs
Normal file
@ -0,0 +1,72 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
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");
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,151 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
using GostCryptography.Properties;
|
||||
using System;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,161 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
using GostCryptography.Asn1.Gost.Gost_28147_89;
|
||||
using GostCryptography.Asn1.Gost.PublicKey;
|
||||
using GostCryptography.Properties;
|
||||
using System;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,157 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
using GostCryptography.Properties;
|
||||
using System;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512
|
||||
{
|
||||
public static class Gost_R3410_2012_512_Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Алгоритм ГОСТ Р 34.10-2012 для ключей длины 512 бит, используемый при экспорте/импорте ключей
|
||||
/// </summary>
|
||||
public static readonly OidValue KeyAlgorithm = OidValue.FromString("1.2.643.7.1.1.1.2");
|
||||
|
||||
/// <summary>
|
||||
/// Алгоритм Диффи-Хеллмана на базе эллиптической кривой для ключей длины 512 бит
|
||||
/// </summary>
|
||||
public static readonly OidValue DhAlgorithm = OidValue.FromString("1.2.643.7.1.1.6.2");
|
||||
|
||||
/// <summary>
|
||||
/// Алгоритм цифровой подписи ГОСТ Р 34.10-2012 для ключей длины 512 бит
|
||||
/// </summary>
|
||||
public static readonly OidValue SignatureAlgorithm = OidValue.FromString("1.2.643.7.1.1.3.3");
|
||||
|
||||
/// <summary>
|
||||
/// Функция хэширования ГОСТ Р 34.11-2012, длина выхода 512 бит
|
||||
/// </summary>
|
||||
public static readonly OidValue HashAlgorithm = OidValue.FromString("1.2.643.7.1.1.2.3");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512
|
||||
{
|
||||
public sealed class Gost_R3410_2012_512_DhPublicKeyType : Gost_R3410_PublicKeyType
|
||||
{
|
||||
protected override Asn1Type CreateParams()
|
||||
{
|
||||
return new Gost_R3410_2012_512_PublicKeyParams();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public sealed class Gost_R3410_2012_512_KeyExchange : Gost_R3410_KeyExchange
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override OidValue KeyAlgorithm => Gost_R3410_2012_512_Constants.KeyAlgorithm;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_2012_512_PublicKeyParams();
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Gost_R3410_KeyExchangeParams CreateKeyExchangeParams() => new Gost_R3410_2012_512_KeyExchangeParams();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public sealed class Gost_R3410_2012_512_KeyExchangeParams : Gost_R3410_KeyExchangeParams
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Gost_R3410_2012_512_KeyExchangeParams()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Gost_R3410_2012_512_KeyExchangeParams(Gost_R3410_2012_512_KeyExchangeParams other) : base(other)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Gost_R3410_KeyExchangeParams Clone() => new Gost_R3410_2012_512_KeyExchangeParams(this);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Gost_R3410_PublicKey CreatePublicKey() => new Gost_R3410_2012_512_PublicKey();
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_2012_512_PublicKeyParams();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public sealed class Gost_R3410_2012_512_PublicKey : Gost_R3410_PublicKey
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Gost_R3410_2012_512_PublicKey() : base(128)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512
|
||||
{
|
||||
public sealed class Gost_R3410_2012_512_PublicKeyParams : Gost_R3410_PublicKeyParams
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512
|
||||
{
|
||||
public sealed class Gost_R3410_2012_512_PublicKeyType : Gost_R3410_PublicKeyType
|
||||
{
|
||||
protected override Asn1Type CreateParams()
|
||||
{
|
||||
return new Gost_R3410_2012_512_PublicKeyParams();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
using GostCryptography.Asn1.Gost.Gost_R3411;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512
|
||||
{
|
||||
public sealed class Gost_R3411_2012_512_DigestParams : Gost_R3411_DigestParams
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
using GostCryptography.Asn1.Gost.Gost_R3411;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512
|
||||
{
|
||||
public sealed class Gost_R3411_2012_512_DigestParamsType : Gost_R3411_DigestParamsType
|
||||
{
|
||||
protected override Asn1Type CreateParams()
|
||||
{
|
||||
return new Gost_R3411_2012_512_DigestParams();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_94
|
||||
{
|
||||
public static class Gost_R3410_94_Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Алгоритм ГОСТ Р 34.10-94, используемый при экспорте/импорте ключей
|
||||
/// </summary>
|
||||
public static readonly OidValue KeyAlgorithm = OidValue.FromString("1.2.643.2.2.20");
|
||||
|
||||
/// <summary>
|
||||
/// Алгоритм Диффи-Хеллмана на базе потенциальной функции
|
||||
/// </summary>
|
||||
public static readonly OidValue DhAlgorithm = OidValue.FromString("1.2.643.2.2.99");
|
||||
|
||||
/// <summary>
|
||||
/// Алгоритм цифровой подписи ГОСТ Р 34.10-94
|
||||
/// </summary>
|
||||
public static readonly OidValue SignatureAlgorithm = OidValue.FromString("1.2.643.2.2.4");
|
||||
|
||||
/// <summary>
|
||||
/// Функция хэширования ГОСТ Р 34.11-94
|
||||
/// </summary>
|
||||
public static readonly OidValue HashAlgorithm = OidValue.FromString("1.2.643.2.2.9");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_94
|
||||
{
|
||||
public sealed class Gost_R3410_94_DhPublicKeyType : Gost_R3410_PublicKeyType
|
||||
{
|
||||
protected override Asn1Type CreateParams()
|
||||
{
|
||||
return new Gost_R3410_94_PublicKeyParams();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_94
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public sealed class Gost_R3410_94_KeyExchange : Gost_R3410_KeyExchange
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override OidValue KeyAlgorithm => Gost_R3410_94_Constants.KeyAlgorithm;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_94_PublicKeyParams();
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Gost_R3410_KeyExchangeParams CreateKeyExchangeParams() => new Gost_R3410_94_KeyExchangeParams();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_94
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public sealed class Gost_R3410_94_KeyExchangeParams : Gost_R3410_KeyExchangeParams
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Gost_R3410_94_KeyExchangeParams()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Gost_R3410_94_KeyExchangeParams(Gost_R3410_94_KeyExchangeParams other) : base(other)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Gost_R3410_KeyExchangeParams Clone() => new Gost_R3410_94_KeyExchangeParams(this);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Gost_R3410_PublicKey CreatePublicKey() => new Gost_R3410_94_PublicKey();
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_94_PublicKeyParams();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_94
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public sealed class Gost_R3410_94_PublicKey : Gost_R3410_PublicKey
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Gost_R3410_94_PublicKey() : base(64)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_94
|
||||
{
|
||||
public sealed class Gost_R3410_94_PublicKeyParams : Gost_R3410_PublicKeyParams
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_94
|
||||
{
|
||||
public sealed class Gost_R3410_94_PublicKeyType : Gost_R3410_PublicKeyType
|
||||
{
|
||||
protected override Asn1Type CreateParams()
|
||||
{
|
||||
return new Gost_R3410_94_PublicKeyParams();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
using GostCryptography.Asn1.Gost.Gost_R3411;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_94
|
||||
{
|
||||
public sealed class Gost_R3411_94_DigestParams : Gost_R3411_DigestParams
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
using GostCryptography.Asn1.Gost.Gost_R3411;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3410_94
|
||||
{
|
||||
public sealed class Gost_R3411_94_DigestParamsType : Gost_R3411_DigestParamsType
|
||||
{
|
||||
protected override Asn1Type CreateParams()
|
||||
{
|
||||
return new Gost_R3411_94_DigestParams();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3411
|
||||
{
|
||||
public abstract class Gost_R3411_DigestParams : Asn1ObjectIdentifier
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
namespace GostCryptography.Asn1.Gost.Gost_R3411
|
||||
{
|
||||
public abstract class Gost_R3411_DigestParamsType : GostAsn1Choice
|
||||
{
|
||||
protected override short TagForm => 0x00;
|
||||
|
||||
protected override int TagIdCode => ObjectIdentifierTypeCode;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.PublicKey
|
||||
{
|
||||
public sealed class AlgorithmId
|
||||
{
|
||||
public AlgorithmId(Asn1ObjectIdentifier id, Asn1Type type)
|
||||
{
|
||||
Id = id;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
public Asn1ObjectIdentifier Id { get; }
|
||||
|
||||
public Asn1Type Type { get; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
using GostCryptography.Properties;
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.PublicKey
|
||||
{
|
||||
public sealed class AlgorithmIdentifier : Asn1Type
|
||||
{
|
||||
public AlgorithmIdentifier()
|
||||
{
|
||||
}
|
||||
|
||||
public AlgorithmIdentifier(Asn1ObjectIdentifier algorithm, Asn1OpenType parameters)
|
||||
{
|
||||
Algorithm = algorithm;
|
||||
Parameters = parameters;
|
||||
}
|
||||
|
||||
public Asn1ObjectIdentifier Algorithm { get; private set; }
|
||||
|
||||
public Asn1Type Parameters { get; private set; }
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;
|
||||
|
||||
Algorithm = null;
|
||||
Parameters = 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);
|
||||
}
|
||||
|
||||
Algorithm = new Asn1ObjectIdentifier();
|
||||
Algorithm.Decode(buffer, true, parsedLen.Value);
|
||||
|
||||
if (!context.Expired())
|
||||
{
|
||||
Parameters = new Asn1OpenType();
|
||||
Parameters.Decode(buffer, true, 0);
|
||||
}
|
||||
|
||||
CheckAlg(true);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = 0;
|
||||
CheckAlg(false);
|
||||
|
||||
if (Parameters != null)
|
||||
{
|
||||
len += Parameters.Encode(buffer, true);
|
||||
}
|
||||
|
||||
len += Algorithm.Encode(buffer, true);
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
private void CheckAlg(bool decode)
|
||||
{
|
||||
AlgorithmId algorithmId = null;
|
||||
|
||||
foreach (var alg in PkiConstants.SupportedAlgorithms)
|
||||
{
|
||||
if (alg.Id.Equals(Algorithm))
|
||||
{
|
||||
algorithmId = alg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((algorithmId != null) && ((decode && (Parameters != null)) && (algorithmId.Type != null)))
|
||||
{
|
||||
try
|
||||
{
|
||||
var buffer = new Asn1BerDecodeBuffer(((Asn1OpenType)Parameters).Value);
|
||||
Parameters = (Asn1Type)Activator.CreateInstance(algorithmId.Type.GetType());
|
||||
Parameters.Decode(buffer, true, 0);
|
||||
buffer.InvokeEndElement("parameters", -1);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Asn1Util.WriteStackTrace(exception, Console.Error);
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1TableConstraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
116
Hcs.Client/GostCryptography/Asn1/Gost/PublicKey/PkiConstants.cs
Normal file
116
Hcs.Client/GostCryptography/Asn1/Gost/PublicKey/PkiConstants.cs
Normal file
@ -0,0 +1,116 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
using GostCryptography.Asn1.Gost.Gost_28147_89;
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410_2001;
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410_2012_256;
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410_2012_512;
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410_94;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.PublicKey
|
||||
{
|
||||
static class PkiConstants
|
||||
{
|
||||
// ГОСТ 28147-89
|
||||
|
||||
private static readonly AlgorithmId Gost_28147_89_EncryptAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_28147_89_Constants.EncryptAlgorithm),
|
||||
new Gost_28147_89_Params());
|
||||
|
||||
// ГОСТ Р 34.10-94
|
||||
|
||||
private static readonly AlgorithmId Gost_R3410_94_KeyAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_94_Constants.KeyAlgorithm),
|
||||
new Gost_R3410_94_PublicKeyType());
|
||||
|
||||
private static readonly AlgorithmId Gost_R3410_94_DhAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_94_Constants.DhAlgorithm),
|
||||
new Gost_R3410_94_DhPublicKeyType());
|
||||
|
||||
private static readonly AlgorithmId Gost_R3410_94_SignatureAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_94_Constants.SignatureAlgorithm),
|
||||
new NullParams());
|
||||
|
||||
private static readonly AlgorithmId Gost_R3411_94_HashAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_94_Constants.HashAlgorithm),
|
||||
new Gost_R3411_94_DigestParamsType());
|
||||
|
||||
// ГОСТ Р 34.10-2001
|
||||
|
||||
private static readonly AlgorithmId Gost_R3410_2001_KeyAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_2001_Constants.KeyAlgorithm),
|
||||
new Gost_R3410_2001_PublicKeyType());
|
||||
|
||||
private static readonly AlgorithmId Gost_R3410_2001_DhAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_2001_Constants.DhAlgorithm),
|
||||
new Gost_R3410_2001_DhPublicKeyType());
|
||||
|
||||
private static readonly AlgorithmId Gost_R3410_2001_SignatureAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_2001_Constants.SignatureAlgorithm),
|
||||
new NullParams());
|
||||
|
||||
private static readonly AlgorithmId Gost_R3411_2001_HashAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_2001_Constants.HashAlgorithm),
|
||||
new Gost_R3411_2001_DigestParamsType());
|
||||
|
||||
// ГОСТ Р 34.10-2012/256
|
||||
|
||||
private static readonly AlgorithmId Gost_R3410_2012_256_KeyAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_2012_256_Constants.KeyAlgorithm),
|
||||
new Gost_R3410_2012_256_PublicKeyType());
|
||||
|
||||
private static readonly AlgorithmId Gost_R3410_2012_256_DhAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_2012_256_Constants.DhAlgorithm),
|
||||
new Gost_R3410_2012_256_DhPublicKeyType());
|
||||
|
||||
private static readonly AlgorithmId Gost_R3410_2012_256_SignatureAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_2012_256_Constants.SignatureAlgorithm),
|
||||
new NullParams());
|
||||
|
||||
private static readonly AlgorithmId Gost_R3411_2012_256_HashAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_2012_256_Constants.HashAlgorithm),
|
||||
new Gost_R3411_2012_256_DigestParamsType());
|
||||
|
||||
// ГОСТ Р 34.10-2012/512
|
||||
|
||||
private static readonly AlgorithmId Gost_R3410_2012_512_KeyAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_2012_512_Constants.KeyAlgorithm),
|
||||
new Gost_R3410_2012_512_PublicKeyType());
|
||||
|
||||
private static readonly AlgorithmId Gost_R3410_2012_512_DhAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_2012_512_Constants.DhAlgorithm),
|
||||
new Gost_R3410_2012_512_DhPublicKeyType());
|
||||
|
||||
private static readonly AlgorithmId Gost_R3410_2012_512_SignatureAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_2012_512_Constants.SignatureAlgorithm),
|
||||
new NullParams());
|
||||
|
||||
private static readonly AlgorithmId Gost_R3411_2012_512_HashAlgorithm = new AlgorithmId(
|
||||
new Asn1ObjectIdentifier(Gost_R3410_2012_512_Constants.HashAlgorithm),
|
||||
new Gost_R3411_2012_512_DigestParamsType());
|
||||
|
||||
|
||||
public static readonly AlgorithmId[] SupportedAlgorithms =
|
||||
{
|
||||
Gost_28147_89_EncryptAlgorithm,
|
||||
|
||||
Gost_R3410_94_KeyAlgorithm,
|
||||
Gost_R3410_94_DhAlgorithm,
|
||||
Gost_R3410_94_SignatureAlgorithm,
|
||||
Gost_R3411_94_HashAlgorithm,
|
||||
|
||||
Gost_R3410_2001_KeyAlgorithm,
|
||||
Gost_R3410_2001_DhAlgorithm,
|
||||
Gost_R3410_2001_SignatureAlgorithm,
|
||||
Gost_R3411_2001_HashAlgorithm,
|
||||
|
||||
Gost_R3410_2012_256_KeyAlgorithm,
|
||||
Gost_R3410_2012_256_DhAlgorithm,
|
||||
Gost_R3410_2012_256_SignatureAlgorithm,
|
||||
Gost_R3411_2012_256_HashAlgorithm,
|
||||
|
||||
Gost_R3410_2012_512_KeyAlgorithm,
|
||||
Gost_R3410_2012_512_DhAlgorithm,
|
||||
Gost_R3410_2012_512_SignatureAlgorithm,
|
||||
Gost_R3411_2012_512_HashAlgorithm
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
using GostCryptography.Asn1.Ber;
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Gost.PublicKey
|
||||
{
|
||||
public sealed class SubjectPublicKeyInfo : Asn1Type
|
||||
{
|
||||
public AlgorithmIdentifier Algorithm { get; set; }
|
||||
|
||||
public Asn1BitString SubjectPublicKey { get; set; }
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;
|
||||
|
||||
Algorithm = null;
|
||||
SubjectPublicKey = null;
|
||||
|
||||
var context = new Asn1BerDecodeContext(buffer, elemLength);
|
||||
var parsedLen = new IntHolder();
|
||||
|
||||
if (!context.MatchElemTag(0, 0x20, 0x10, parsedLen, false))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
Algorithm = new AlgorithmIdentifier();
|
||||
Algorithm.Decode(buffer, true, parsedLen.Value);
|
||||
|
||||
if (!context.MatchElemTag(0, 0, 3, parsedLen, false))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
SubjectPublicKey = new Asn1BitString();
|
||||
SubjectPublicKey.Decode(buffer, true, parsedLen.Value);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = 0;
|
||||
len += SubjectPublicKey.Encode(buffer, true);
|
||||
len += Algorithm.Encode(buffer, true);
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user