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

164 lines
6.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using GostCryptography.Asn1.Gost.Gost_28147_89;
using GostCryptography.Asn1.Gost.Gost_R3410;
using GostCryptography.Base;
using GostCryptography.Gost_28147_89;
using GostCryptography.Native;
using GostCryptography.Properties;
using System.Security;
using System.Security.Cryptography;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Базовый класс всех реализаций общего секретного ключа ГОСТ Р 34.10
/// </summary>
public abstract class Gost_R3410_KeyExchangeAlgorithm : GostKeyExchangeAlgorithm
{
/// <inheritdoc />
[SecurityCritical]
protected Gost_R3410_KeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, Gost_R3410_KeyExchangeParams keyExchangeParameters, int keySize, int signatureAlgId) : base(providerType)
{
if (provHandle == null)
{
throw ExceptionUtility.ArgumentNull(nameof(provHandle));
}
if (keyHandle == null)
{
throw ExceptionUtility.ArgumentNull(nameof(keyHandle));
}
if (keyExchangeParameters == null)
{
throw ExceptionUtility.ArgumentNull(nameof(keyExchangeParameters));
}
_provHandle = provHandle.DangerousAddRef();
_keyHandle = keyHandle.DangerousAddRef();
_keyExchangeParameters = keyExchangeParameters;
_keySize = keySize;
_signatureAlgId = signatureAlgId;
}
[SecurityCritical]
private readonly SafeProvHandleImpl _provHandle;
[SecurityCritical]
private readonly SafeKeyHandleImpl _keyHandle;
[SecurityCritical]
private readonly Gost_R3410_KeyExchangeParams _keyExchangeParameters;
private readonly int _keySize;
private readonly int _signatureAlgId;
/// <inheritdoc />
[SecuritySafeCritical]
public override byte[] EncodeKeyExchange(SymmetricAlgorithm keyExchangeAlgorithm, GostKeyExchangeExportMethod keyExchangeExportMethod)
{
if (keyExchangeAlgorithm is Gost_28147_89_SymmetricAlgorithm symAlg)
{
return EncodeKeyExchangeInternal(symAlg, keyExchangeExportMethod);
}
if (keyExchangeAlgorithm is Gost_28147_89_SymmetricAlgorithmBase symAlgBase)
{
using (var gostKeyExchangeAlgorithm = new Gost_28147_89_SymmetricAlgorithm(symAlgBase.ProviderType))
{
return gostKeyExchangeAlgorithm.EncodePrivateKey(symAlgBase, keyExchangeExportMethod);
}
}
throw ExceptionUtility.Argument(nameof(keyExchangeAlgorithm), Resources.RequiredGost28147);
}
[SecurityCritical]
private byte[] EncodeKeyExchangeInternal(Gost_28147_89_SymmetricAlgorithm keyExchangeAlgorithm, GostKeyExchangeExportMethod keyExchangeExportMethod)
{
switch (keyExchangeExportMethod)
{
case GostKeyExchangeExportMethod.GostKeyExport:
return EncodeKeyExchangeInternal(keyExchangeAlgorithm, Constants.CALG_SIMPLE_EXPORT);
case GostKeyExchangeExportMethod.CryptoProKeyExport:
return EncodeKeyExchangeInternal(keyExchangeAlgorithm, Constants.CALG_PRO_EXPORT);
}
throw ExceptionUtility.ArgumentOutOfRange(nameof(keyExchangeExportMethod));
}
[SecurityCritical]
private byte[] EncodeKeyExchangeInternal(Gost_28147_89_SymmetricAlgorithm keyExchangeAlgorithm, int keyExchangeExportAlgId)
{
Gost_28147_89_KeyExchangeInfo keyExchangeInfo;
SafeKeyHandleImpl keyExchangeHandle = null;
try
{
var importedKeyBytes = CryptoApiHelper.EncodePublicBlob(_keyExchangeParameters, _keySize, _signatureAlgId);
CryptoApiHelper.ImportCspBlob(importedKeyBytes, _provHandle, _keyHandle, out keyExchangeHandle);
CryptoApiHelper.SetKeyExchangeExportAlgId(ProviderType, keyExchangeHandle, keyExchangeExportAlgId);
var symKeyHandle = keyExchangeAlgorithm.GetSafeHandle();
keyExchangeInfo = CryptoApiHelper.ExportKeyExchange(symKeyHandle, keyExchangeHandle);
}
finally
{
keyExchangeHandle.TryDispose();
}
return keyExchangeInfo.Encode();
}
/// <inheritdoc />
[SecuritySafeCritical]
public override SymmetricAlgorithm DecodeKeyExchange(byte[] encodedKeyExchangeData, GostKeyExchangeExportMethod keyExchangeExportMethod)
{
switch (keyExchangeExportMethod)
{
case GostKeyExchangeExportMethod.GostKeyExport:
return DecodeKeyExchangeInternal(encodedKeyExchangeData, Constants.CALG_SIMPLE_EXPORT);
case GostKeyExchangeExportMethod.CryptoProKeyExport:
return DecodeKeyExchangeInternal(encodedKeyExchangeData, Constants.CALG_PRO_EXPORT);
}
throw ExceptionUtility.ArgumentOutOfRange(nameof(keyExchangeExportMethod));
}
[SecurityCritical]
private SymmetricAlgorithm DecodeKeyExchangeInternal(byte[] encodedKeyExchangeData, int keyExchangeExportAlgId)
{
var keyExchangeInfo = new Gost_28147_89_KeyExchangeInfo();
keyExchangeInfo.Decode(encodedKeyExchangeData);
SafeKeyHandleImpl symKeyHandle;
SafeKeyHandleImpl keyExchangeHandle = null;
try
{
var importedKeyBytes = CryptoApiHelper.EncodePublicBlob(_keyExchangeParameters, _keySize, _signatureAlgId);
CryptoApiHelper.ImportCspBlob(importedKeyBytes, _provHandle, _keyHandle, out keyExchangeHandle);
CryptoApiHelper.SetKeyExchangeExportAlgId(ProviderType, keyExchangeHandle, keyExchangeExportAlgId);
symKeyHandle = CryptoApiHelper.ImportKeyExchange(_provHandle, keyExchangeInfo, keyExchangeHandle);
}
finally
{
keyExchangeHandle.TryDispose();
}
return new Gost_28147_89_SymmetricAlgorithm(ProviderType, _provHandle, symKeyHandle);
}
/// <inheritdoc />
[SecuritySafeCritical]
protected override void Dispose(bool disposing)
{
_keyHandle.TryDispose();
_provHandle.TryDispose();
base.Dispose(disposing);
}
}
}