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,429 @@
using GostCryptography.Base;
using GostCryptography.Config;
using GostCryptography.Gost_28147_89;
using GostCryptography.Properties;
using GostCryptography.Reflection;
using System;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Security.Policy;
using System.Xml;
namespace GostCryptography.Xml
{
sealed class GostEncryptedXmlImpl : EncryptedXml
{
public GostEncryptedXmlImpl(ProviderType providerType)
{
ProviderType = providerType;
}
public GostEncryptedXmlImpl(ProviderType providerType, XmlDocument document) : base(document)
{
ProviderType = providerType;
}
public GostEncryptedXmlImpl(ProviderType providerType, XmlDocument document, Evidence evidence) : base(document, evidence)
{
ProviderType = providerType;
}
public ProviderType ProviderType { get; }
public new void AddKeyNameMapping(string keyName, object keyObject)
{
if (string.IsNullOrEmpty(keyName))
{
throw ExceptionUtility.ArgumentNull(nameof(keyName));
}
if (keyObject == null)
{
throw ExceptionUtility.ArgumentNull(nameof(keyObject));
}
if (keyObject is GostAsymmetricAlgorithm)
{
this.GetKeyNameMapping().Add(keyName, keyObject);
}
else
{
base.AddKeyNameMapping(keyName, keyObject);
}
}
[SecuritySafeCritical]
public new EncryptedData Encrypt(XmlElement element, X509Certificate2 certificate)
{
if (element == null || certificate == null || !certificate.IsGost())
{
return base.Encrypt(element, certificate);
}
var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
var encryptionKey = new Gost_28147_89_SymmetricAlgorithm(publicKey.ProviderType);
var encryptedKey = new EncryptedKey();
encryptedKey.KeyInfo.AddClause(new KeyInfoX509Data(certificate));
encryptedKey.EncryptionMethod = new EncryptionMethod(publicKey.KeyExchangeAlgorithm);
encryptedKey.CipherData.CipherValue = EncryptKey(encryptionKey, publicKey);
var encryptedData = new EncryptedData
{
Type = XmlEncElementUrl,
EncryptionMethod = new EncryptionMethod(encryptionKey.AlgorithmName)
};
encryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedKey));
encryptedData.CipherData.CipherValue = EncryptData(element, encryptionKey, false);
return encryptedData;
}
public static byte[] EncryptKey(Gost_28147_89_SymmetricAlgorithmBase sessionKey, GostAsymmetricAlgorithm publicKey)
{
if (sessionKey == null)
{
throw ExceptionUtility.ArgumentNull(nameof(sessionKey));
}
if (publicKey == null)
{
throw ExceptionUtility.ArgumentNull(nameof(publicKey));
}
var formatter = publicKey.CreateKeyExchangeFormatter();
return formatter.CreateKeyExchangeData(sessionKey);
}
public static byte[] EncryptKey(Gost_28147_89_SymmetricAlgorithmBase sessionKey, Gost_28147_89_SymmetricAlgorithmBase sharedKey, GostKeyExchangeExportMethod exportMethod)
{
if (sessionKey == null)
{
throw ExceptionUtility.ArgumentNull(nameof(sessionKey));
}
if (sharedKey == null)
{
throw ExceptionUtility.ArgumentNull(nameof(sharedKey));
}
return sharedKey.EncodePrivateKey(sessionKey, exportMethod);
}
public override byte[] GetDecryptionIV(EncryptedData encryptedData, string symmetricAlgorithmUri)
{
if (encryptedData == null)
{
throw ExceptionUtility.ArgumentNull(nameof(encryptedData));
}
if (symmetricAlgorithmUri == null)
{
if (encryptedData.EncryptionMethod == null)
{
return base.GetDecryptionIV(encryptedData, null);
}
symmetricAlgorithmUri = encryptedData.EncryptionMethod.KeyAlgorithm;
}
if (Gost_28147_89_SymmetricAlgorithm.AlgorithmNameValue.Equals(symmetricAlgorithmUri, StringComparison.OrdinalIgnoreCase))
{
var iv = new byte[8];
Buffer.BlockCopy(this.GetCipherValue(encryptedData.CipherData), 0, iv, 0, iv.Length);
return iv;
}
return base.GetDecryptionIV(encryptedData, symmetricAlgorithmUri);
}
public override SymmetricAlgorithm GetDecryptionKey(EncryptedData encryptedData, string symmetricAlgorithmUri)
{
if (encryptedData == null)
{
throw ExceptionUtility.ArgumentNull(nameof(encryptedData));
}
SymmetricAlgorithm decryptionKey = null;
if (encryptedData.KeyInfo != null)
{
EncryptedKey encryptedKey = null;
foreach (var keyInfo in encryptedData.KeyInfo)
{
// Извлечение ключа по имени
if (keyInfo is KeyInfoName)
{
var keyName = ((KeyInfoName)keyInfo).Value;
var keyAlgorithm = this.GetKeyNameMapping()[keyName];
if (keyAlgorithm == null)
{
var nsManager = new XmlNamespaceManager(this.GetDocument().NameTable);
nsManager.AddNamespace("enc", XmlEncNamespaceUrl);
var encryptedKeyNodes = this.GetDocument().SelectNodes("//enc:EncryptedKey", nsManager);
if (encryptedKeyNodes != null)
{
foreach (XmlElement encryptedKeyNode in encryptedKeyNodes)
{
var currentEncryptedKey = new EncryptedKey();
currentEncryptedKey.LoadXml(encryptedKeyNode);
if ((currentEncryptedKey.CarriedKeyName == keyName) && (currentEncryptedKey.Recipient == Recipient))
{
encryptedKey = currentEncryptedKey;
break;
}
}
}
}
else
{
decryptionKey = (SymmetricAlgorithm)keyAlgorithm;
}
break;
}
// Извлечение ключа по ссылке
if (keyInfo is KeyInfoRetrievalMethod)
{
var idValue = CryptographyXmlUtils.ExtractIdFromLocalUri(((KeyInfoRetrievalMethod)keyInfo).Uri);
var idElement = GetIdElement(this.GetDocument(), idValue);
if (idElement != null)
{
encryptedKey = new EncryptedKey();
encryptedKey.LoadXml(idElement);
}
break;
}
// Ключ в готовом виде
if (keyInfo is KeyInfoEncryptedKey)
{
encryptedKey = ((KeyInfoEncryptedKey)keyInfo).EncryptedKey;
break;
}
}
if (decryptionKey == null && encryptedKey != null)
{
if (symmetricAlgorithmUri == null)
{
if (encryptedData.EncryptionMethod == null)
{
throw ExceptionUtility.CryptographicException(Resources.XmlMissingAlgorithm);
}
symmetricAlgorithmUri = encryptedData.EncryptionMethod.KeyAlgorithm;
}
decryptionKey = DecryptEncryptedKeyClass(encryptedKey, symmetricAlgorithmUri);
}
}
return decryptionKey;
}
[SecuritySafeCritical]
private SymmetricAlgorithm DecryptEncryptedKeyClass(EncryptedKey encryptedKey, string symmetricAlgorithmUri)
{
if (encryptedKey == null)
{
throw ExceptionUtility.ArgumentNull(nameof(encryptedKey));
}
SymmetricAlgorithm decryptionKey = null;
if (encryptedKey.KeyInfo != null)
{
foreach (var keyInfo in encryptedKey.KeyInfo)
{
// Извлечение ключа по имени
if (keyInfo is KeyInfoName)
{
var keyName = ((KeyInfoName)keyInfo).Value;
var keyAlgorithm = this.GetKeyNameMapping()[keyName];
if (keyAlgorithm != null)
{
if (keyAlgorithm is SymmetricAlgorithm)
{
decryptionKey = DecryptKeyClass(encryptedKey.CipherData.CipherValue, (SymmetricAlgorithm)keyAlgorithm, symmetricAlgorithmUri, encryptedKey.EncryptionMethod.KeyAlgorithm);
}
else if (keyAlgorithm is RSA)
{
var useOaep = (encryptedKey.EncryptionMethod != null) && (encryptedKey.EncryptionMethod.KeyAlgorithm == XmlEncRSAOAEPUrl);
decryptionKey = DecryptKeyClass(encryptedKey.CipherData.CipherValue, (RSA)keyAlgorithm, useOaep, symmetricAlgorithmUri);
}
else if (keyAlgorithm is GostAsymmetricAlgorithm)
{
decryptionKey = DecryptKeyClass(encryptedKey.CipherData.CipherValue, (GostAsymmetricAlgorithm)keyAlgorithm);
}
}
break;
}
// Извлечение ключа из сертификата
if (keyInfo is KeyInfoX509Data)
{
var certificates = CryptographyXmlUtils.BuildBagOfCertsDecryption((KeyInfoX509Data)keyInfo);
foreach (var certificate in certificates)
{
var privateKey = certificate.GetPrivateKeyAlgorithm();
if (privateKey is RSA)
{
var useOaep = (encryptedKey.EncryptionMethod != null) && (encryptedKey.EncryptionMethod.KeyAlgorithm == XmlEncRSAOAEPUrl);
decryptionKey = DecryptKeyClass(encryptedKey.CipherData.CipherValue, (RSA)privateKey, useOaep, symmetricAlgorithmUri);
}
else if (privateKey is GostAsymmetricAlgorithm)
{
decryptionKey = DecryptKeyClass(encryptedKey.CipherData.CipherValue, (GostAsymmetricAlgorithm)privateKey);
}
}
break;
}
// Извлечение ключа по ссылке
if (keyInfo is KeyInfoRetrievalMethod)
{
var idValue = CryptographyXmlUtils.ExtractIdFromLocalUri(((KeyInfoRetrievalMethod)keyInfo).Uri);
var idElement = GetIdElement(this.GetDocument(), idValue);
if (idElement != null)
{
var secondEncryptedKey = new EncryptedKey();
secondEncryptedKey.LoadXml(idElement);
decryptionKey = DecryptEncryptedKeyClass(secondEncryptedKey, symmetricAlgorithmUri);
}
break;
}
// Ключ в готовом виде
if (keyInfo is KeyInfoEncryptedKey)
{
var secondEncryptedKey = ((KeyInfoEncryptedKey)keyInfo).EncryptedKey;
var symmetricAlgorithm = DecryptEncryptedKeyClass(secondEncryptedKey, symmetricAlgorithmUri);
if (symmetricAlgorithm != null)
{
decryptionKey = DecryptKeyClass(encryptedKey.CipherData.CipherValue, symmetricAlgorithm, symmetricAlgorithmUri, encryptedKey.EncryptionMethod.KeyAlgorithm);
}
break;
}
}
}
return decryptionKey;
}
private static SymmetricAlgorithm DecryptKeyClass(byte[] keyData, SymmetricAlgorithm algorithm, string symmetricAlgorithmUri, string encryptionKeyAlgorithm)
{
if (keyData == null)
{
throw ExceptionUtility.ArgumentNull(nameof(keyData));
}
if (algorithm == null)
{
throw ExceptionUtility.ArgumentNull(nameof(algorithm));
}
SymmetricAlgorithm decryptionKey = null;
if (algorithm is Gost_28147_89_SymmetricAlgorithmBase gost28147)
{
if (string.Equals(encryptionKeyAlgorithm, GostEncryptedXml.XmlEncGostKeyExportUrl, StringComparison.OrdinalIgnoreCase))
{
decryptionKey = gost28147.DecodePrivateKey(keyData, GostKeyExchangeExportMethod.GostKeyExport);
}
if (string.Equals(encryptionKeyAlgorithm, GostEncryptedXml.XmlEncGostCryptoProKeyExportUrl, StringComparison.OrdinalIgnoreCase))
{
decryptionKey = gost28147.DecodePrivateKey(keyData, GostKeyExchangeExportMethod.CryptoProKeyExport);
}
}
else
{
var decryptionKeyBytes = DecryptKey(keyData, algorithm);
if (decryptionKeyBytes != null)
{
decryptionKey = (SymmetricAlgorithm)GostCryptoConfig.CreateFromName(symmetricAlgorithmUri);
decryptionKey.Key = decryptionKeyBytes;
}
}
if (decryptionKey == null)
{
throw ExceptionUtility.CryptographicException(Resources.XmlMissingAlgorithm);
}
return decryptionKey;
}
private static SymmetricAlgorithm DecryptKeyClass(byte[] keyData, RSA algorithm, bool useOaep, string symmetricAlgorithmUri)
{
if (keyData == null)
{
throw ExceptionUtility.ArgumentNull(nameof(keyData));
}
if (algorithm == null)
{
throw ExceptionUtility.ArgumentNull(nameof(algorithm));
}
SymmetricAlgorithm decryptionKey = null;
var decryptionKeyBytes = DecryptKey(keyData, algorithm, useOaep);
if (decryptionKeyBytes != null)
{
decryptionKey = (SymmetricAlgorithm)GostCryptoConfig.CreateFromName(symmetricAlgorithmUri);
decryptionKey.Key = decryptionKeyBytes;
}
if (decryptionKey == null)
{
throw ExceptionUtility.CryptographicException(Resources.XmlMissingAlgorithm);
}
return decryptionKey;
}
public static SymmetricAlgorithm DecryptKeyClass(byte[] keyData, GostAsymmetricAlgorithm privateKey)
{
if (keyData == null)
{
throw ExceptionUtility.ArgumentNull(nameof(keyData));
}
if (privateKey == null)
{
throw ExceptionUtility.ArgumentNull(nameof(privateKey));
}
var deformatter = privateKey.CreateKeyExchangeDeformatter();
var decryptionKey = deformatter.DecryptKeyExchangeAlgorithm(keyData);
return decryptionKey;
}
}
}