Add migrated to .NET 8.0 variant of Hcs.Client

This commit is contained in:
2025-09-26 19:48:32 +09:00
parent da127df8f6
commit 6cd2fb82e9
503 changed files with 223796 additions and 0 deletions

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

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,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;
}
}
}

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,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;
}
}
}