Basic formatting applied. Unnecessary comments have been removed. Suspicious code is covered by TODO.
163 lines
6.3 KiB
C#
163 lines
6.3 KiB
C#
using GostCryptography.Asn1.Gost.Gost_28147_89;
|
||
using GostCryptography.Asn1.Gost.Gost_R3410;
|
||
using GostCryptography.Base;
|
||
using GostCryptography.Gost_28147_89;
|
||
using GostCryptography.Properties;
|
||
using System;
|
||
using System.Security.Cryptography;
|
||
|
||
namespace GostCryptography.Gost_R3410
|
||
{
|
||
/// <summary>
|
||
/// Базовый класс для реализации шифрования общего секретного ключа по ГОСТ Р 34.10
|
||
/// </summary>
|
||
/// <typeparam name="TKey">Информация о ключе цифровой подписи ГОСТ Р 34.10</typeparam>
|
||
/// <typeparam name="TKeyParams">Параметры ключа цифровой подписи ГОСТ Р 34.10</typeparam>
|
||
/// <typeparam name="TKeyAlgorithm">Алгоритм общего секретного ключа ГОСТ Р 34.10</typeparam>
|
||
public abstract class Gost_R3410_KeyExchangeFormatter<TKey, TKeyParams, TKeyAlgorithm> : GostKeyExchangeFormatter
|
||
where TKey : Gost_R3410_KeyExchange, new()
|
||
where TKeyParams : Gost_R3410_KeyExchangeParams
|
||
where TKeyAlgorithm : Gost_R3410_KeyExchangeAlgorithm
|
||
{
|
||
/// <summary>
|
||
/// Конструктор
|
||
/// </summary>
|
||
protected Gost_R3410_KeyExchangeFormatter()
|
||
{
|
||
}
|
||
|
||
/// <summary>
|
||
/// Конструктор
|
||
/// </summary>
|
||
/// <param name="publicKey">Открытый ключ для шифрации общего секретного ключа</param>
|
||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||
/// <exception cref="ArgumentNullException"></exception>
|
||
protected Gost_R3410_KeyExchangeFormatter(AsymmetricAlgorithm publicKey)
|
||
{
|
||
SetKey(publicKey);
|
||
}
|
||
|
||
private Gost_R3410_AsymmetricAlgorithmBase<TKeyParams, TKeyAlgorithm> _publicKey;
|
||
|
||
/// <inheritdoc />
|
||
public override string Parameters => null;
|
||
|
||
/// <inheritdoc />
|
||
public override void SetKey(AsymmetricAlgorithm publicKey)
|
||
{
|
||
if (publicKey == null)
|
||
{
|
||
throw ExceptionUtility.ArgumentNull(nameof(publicKey));
|
||
}
|
||
|
||
if (!(publicKey is Gost_R3410_AsymmetricAlgorithmBase<TKeyParams, TKeyAlgorithm> gostPublicKey))
|
||
{
|
||
throw ExceptionUtility.ArgumentOutOfRange(nameof(publicKey), Resources.ShouldSupportGost3410);
|
||
}
|
||
|
||
_publicKey = gostPublicKey;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public override byte[] CreateKeyExchange(byte[] keyExchangeData)
|
||
{
|
||
if (keyExchangeData == null)
|
||
{
|
||
throw ExceptionUtility.ArgumentNull(nameof(keyExchangeData));
|
||
}
|
||
|
||
using (var keyExchangeAlgorithm = new Gost_28147_89_SymmetricAlgorithm(_publicKey.ProviderType))
|
||
{
|
||
keyExchangeAlgorithm.Key = keyExchangeData;
|
||
|
||
return CreateKeyExchangeData(keyExchangeAlgorithm);
|
||
}
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public override byte[] CreateKeyExchange(byte[] keyExchangeData, Type keyExchangeAlgorithmType)
|
||
{
|
||
if (keyExchangeData == null)
|
||
{
|
||
throw ExceptionUtility.ArgumentNull(nameof(keyExchangeData));
|
||
}
|
||
|
||
if (keyExchangeAlgorithmType == null)
|
||
{
|
||
throw ExceptionUtility.ArgumentNull(nameof(keyExchangeAlgorithmType));
|
||
}
|
||
|
||
if (!typeof(GostSymmetricAlgorithm).IsAssignableFrom(keyExchangeAlgorithmType))
|
||
{
|
||
throw ExceptionUtility.ArgumentOutOfRange(nameof(keyExchangeAlgorithmType));
|
||
}
|
||
|
||
GostSymmetricAlgorithm keyExchangeAlgorithm;
|
||
|
||
if (_publicKey != null)
|
||
{
|
||
var constructorInfo = keyExchangeAlgorithmType.GetConstructor(new[] { typeof(ProviderType) });
|
||
keyExchangeAlgorithm = (GostSymmetricAlgorithm)constructorInfo.Invoke(new object[] { _publicKey.ProviderType });
|
||
}
|
||
else
|
||
{
|
||
keyExchangeAlgorithm = (GostSymmetricAlgorithm)Activator.CreateInstance(keyExchangeAlgorithmType);
|
||
}
|
||
|
||
using (keyExchangeAlgorithm)
|
||
{
|
||
keyExchangeAlgorithm.Key = keyExchangeData;
|
||
|
||
return CreateKeyExchangeData(keyExchangeAlgorithm);
|
||
}
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public override byte[] CreateKeyExchangeData(SymmetricAlgorithm keyExchangeAlgorithm)
|
||
{
|
||
if (keyExchangeAlgorithm == null)
|
||
{
|
||
throw ExceptionUtility.ArgumentNull(nameof(keyExchangeAlgorithm));
|
||
}
|
||
|
||
var keyExchangeInfo = CreateKeyExchangeInfo(keyExchangeAlgorithm);
|
||
|
||
return keyExchangeInfo.Encode();
|
||
}
|
||
|
||
private TKey CreateKeyExchangeInfo(SymmetricAlgorithm keyExchangeAlgorithm)
|
||
{
|
||
if (keyExchangeAlgorithm == null)
|
||
{
|
||
throw ExceptionUtility.ArgumentNull(nameof(keyExchangeAlgorithm));
|
||
}
|
||
|
||
var keyExchange = new TKey();
|
||
var keyExchangeParameters = _publicKey.ExportParameters(false);
|
||
|
||
using (var keyExchangeAsym = CreateEphemeralAlgorithm(_publicKey.ProviderType, keyExchangeParameters))
|
||
{
|
||
byte[] encodedKeyExchangeInfo;
|
||
|
||
using (var keyExchangeAlg = keyExchangeAsym.CreateKeyExchange(keyExchangeParameters))
|
||
{
|
||
encodedKeyExchangeInfo = keyExchangeAlg.EncodeKeyExchange(keyExchangeAlgorithm, GostKeyExchangeExportMethod.CryptoProKeyExport);
|
||
}
|
||
|
||
var keyExchangeInfo = new Gost_28147_89_KeyExchangeInfo();
|
||
keyExchangeInfo.Decode(encodedKeyExchangeInfo);
|
||
|
||
keyExchange.SessionEncryptedKey = keyExchangeInfo;
|
||
keyExchange.TransportParameters = keyExchangeAsym.ExportParameters(false);
|
||
}
|
||
|
||
return keyExchange;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Создает экземпляр алгоритма шифрования общего секретного ключа
|
||
/// </summary>
|
||
protected abstract Gost_R3410_EphemeralAsymmetricAlgorithm<TKeyParams, TKeyAlgorithm> CreateEphemeralAlgorithm(ProviderType providerType, TKeyParams keyExchangeParameters);
|
||
}
|
||
}
|