Add project

Basic formatting applied. Unnecessary comments have been removed. Suspicious code is covered by TODO.
This commit is contained in:
2025-08-12 11:21:10 +09:00
parent bbcbe841a7
commit 33ab055b43
546 changed files with 176950 additions and 0 deletions

View File

@ -0,0 +1,57 @@
using System;
using System.Reflection;
using System.Security.Cryptography;
namespace GostCryptography.Reflection
{
static class CryptographyUtils
{
private static readonly object ObjToHashAlgorithmMethodSync = new object();
private static volatile MethodInfo _objToHashAlgorithmMethod;
public static HashAlgorithm ObjToHashAlgorithm(object hashAlg)
{
if (hashAlg == null)
{
throw ExceptionUtility.ArgumentNull(nameof(hashAlg));
}
HashAlgorithm hashAlgorithm = null;
if (_objToHashAlgorithmMethod == null)
{
lock (ObjToHashAlgorithmMethodSync)
{
if (_objToHashAlgorithmMethod == null)
{
var utilsType = Type.GetType("System.Security.Cryptography.Utils");
if (utilsType != null)
{
_objToHashAlgorithmMethod = utilsType.GetMethod("ObjToHashAlgorithm", BindingFlags.Static | BindingFlags.NonPublic, null, new[] { typeof(object) }, null);
}
}
}
}
if (_objToHashAlgorithmMethod != null)
{
try
{
hashAlgorithm = _objToHashAlgorithmMethod.Invoke(null, new[] { hashAlg }) as HashAlgorithm;
}
catch (TargetInvocationException exception)
{
if (exception.InnerException != null)
{
throw exception.InnerException;
}
throw;
}
}
return hashAlgorithm;
}
}
}

View File

@ -0,0 +1,136 @@
using GostCryptography.Properties;
using System;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
namespace GostCryptography.Reflection
{
static class CryptographyXmlUtils
{
public static X509Certificate2Collection BuildBagOfCertsVerification(KeyInfoX509Data keyInfoX509Data)
{
return BuildBagOfCerts(keyInfoX509Data, 0);
}
public static X509Certificate2Collection BuildBagOfCertsDecryption(KeyInfoX509Data keyInfoX509Data)
{
return BuildBagOfCerts(keyInfoX509Data, 1);
}
private static X509Certificate2Collection BuildBagOfCerts(KeyInfoX509Data keyInfoX509Data, int certUsageType)
{
try
{
return (X509Certificate2Collection)BuildBagOfCertsMethod.Invoke(null, new object[] { keyInfoX509Data, certUsageType });
}
catch (TargetInvocationException exception)
{
if (exception.InnerException != null)
{
throw exception.InnerException;
}
throw;
}
}
private static volatile MethodInfo _buildBagOfCertsMethod;
private static readonly object BuildBagOfCertsMethodSync = new object();
private static MethodInfo BuildBagOfCertsMethod
{
get
{
if (_buildBagOfCertsMethod == null)
{
lock (BuildBagOfCertsMethodSync)
{
if (_buildBagOfCertsMethod == null)
{
_buildBagOfCertsMethod = CryptographyXmlUtilsType.GetMethod("BuildBagOfCerts", BindingFlags.Static | BindingFlags.NonPublic);
}
}
}
if (_buildBagOfCertsMethod == null)
{
throw ExceptionUtility.CryptographicException(Resources.XmlCannotFindPrivateMember, $"{CryptographyXmlUtilsType.FullName}.BuildBagOfCerts()");
}
return _buildBagOfCertsMethod;
}
}
public static string ExtractIdFromLocalUri(string uri)
{
try
{
return (string)ExtractIdFromLocalUriMethod.Invoke(null, new object[] { uri });
}
catch (TargetInvocationException exception)
{
if (exception.InnerException != null)
{
throw exception.InnerException;
}
throw;
}
}
private static volatile MethodInfo _extractIdFromLocalUriMethod;
private static readonly object ExtractIdFromLocalUriMethodSync = new object();
private static MethodInfo ExtractIdFromLocalUriMethod
{
get
{
if (_extractIdFromLocalUriMethod == null)
{
lock (ExtractIdFromLocalUriMethodSync)
{
if (_extractIdFromLocalUriMethod == null)
{
_extractIdFromLocalUriMethod = CryptographyXmlUtilsType.GetMethod("ExtractIdFromLocalUri", BindingFlags.Static | BindingFlags.NonPublic);
}
}
}
if (_extractIdFromLocalUriMethod == null)
{
throw ExceptionUtility.CryptographicException(Resources.XmlCannotFindPrivateMember, $"{CryptographyXmlUtilsType.FullName}.ExtractIdFromLocalUri()");
}
return _extractIdFromLocalUriMethod;
}
}
private static volatile Type _cryptographyXmlUtilsType;
private static readonly object CryptographyXmlUtilsTypeSync = new object();
private static Type CryptographyXmlUtilsType
{
get
{
if (_cryptographyXmlUtilsType == null)
{
lock (CryptographyXmlUtilsTypeSync)
{
if (_cryptographyXmlUtilsType == null)
{
_cryptographyXmlUtilsType = typeof(SignedXml).Assembly.GetType("System.Security.Cryptography.Xml.Utils");
}
}
}
if (_cryptographyXmlUtilsType == null)
{
throw ExceptionUtility.CryptographicException(Resources.XmlCannotFindPrivateMember, "System.Security.Cryptography.Xml.Utils");
}
return _cryptographyXmlUtilsType;
}
}
}
}

View File

@ -0,0 +1,78 @@
using System.Reflection;
using System.Security.Cryptography;
namespace GostCryptography.Reflection
{
static class CspKeyContainerInfoHelper
{
private static readonly object CspKeyContainerInfoConstructorSync = new object();
private static volatile ConstructorInfo _cspKeyContainerInfoConstructor;
public static CspKeyContainerInfo CreateCspKeyContainerInfo(CspParameters parameters, bool randomKeyContainer)
{
CspKeyContainerInfo result = null;
if (_cspKeyContainerInfoConstructor == null)
{
lock (CspKeyContainerInfoConstructorSync)
{
if (_cspKeyContainerInfoConstructor == null)
{
_cspKeyContainerInfoConstructor = typeof(CspKeyContainerInfo).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(CspParameters), typeof(bool) }, null);
}
}
}
if (_cspKeyContainerInfoConstructor != null)
{
try
{
result = (CspKeyContainerInfo)_cspKeyContainerInfoConstructor.Invoke(new object[] { parameters, randomKeyContainer });
}
catch (TargetInvocationException exception)
{
if (exception.InnerException != null)
{
throw exception.InnerException;
}
throw;
}
if (result.KeyNumber == ((KeyNumber)(-1)))
{
var containerPatameters = GetCspKeyContainerInfoPatameters(result);
containerPatameters.KeyNumber = (int)KeyNumber.Exchange;
}
}
return result;
}
private static readonly object CspKeyContainerInfoPatametersFieldSync = new object();
private static volatile FieldInfo _cspKeyContainerInfoPatametersField;
private static CspParameters GetCspKeyContainerInfoPatameters(CspKeyContainerInfo cspKeyContainerInfo)
{
CspParameters result = null;
if (_cspKeyContainerInfoPatametersField == null)
{
lock (CspKeyContainerInfoPatametersFieldSync)
{
if (_cspKeyContainerInfoPatametersField == null)
{
_cspKeyContainerInfoPatametersField = typeof(CspKeyContainerInfo).GetField("m_parameters", BindingFlags.Instance | BindingFlags.NonPublic);
}
}
}
if (_cspKeyContainerInfoPatametersField != null)
{
result = _cspKeyContainerInfoPatametersField.GetValue(cspKeyContainerInfo) as CspParameters;
}
return result;
}
}
}

View File

@ -0,0 +1,83 @@
using GostCryptography.Properties;
using System.Collections;
using System.Reflection;
using System.Security.Cryptography.Xml;
using System.Xml;
namespace GostCryptography.Reflection
{
static class EncryptedXmlHelper
{
private static readonly object DocumentFieldSync = new object();
private static volatile FieldInfo _documentField;
public static XmlDocument GetDocument(this EncryptedXml encryptedXml)
{
if (_documentField == null)
{
lock (DocumentFieldSync)
{
if (_documentField == null)
{
_documentField = typeof(EncryptedXml).GetField("m_document", BindingFlags.Instance | BindingFlags.NonPublic);
}
}
}
if (_documentField == null)
{
throw ExceptionUtility.CryptographicException(Resources.XmlCannotFindPrivateMember, "m_document");
}
return (XmlDocument)_documentField.GetValue(encryptedXml);
}
private static readonly object KeyNameMappingFieldSync = new object();
private static volatile FieldInfo _keyNameMappingField;
public static Hashtable GetKeyNameMapping(this EncryptedXml encryptedXml)
{
if (_keyNameMappingField == null)
{
lock (KeyNameMappingFieldSync)
{
if (_keyNameMappingField == null)
{
_keyNameMappingField = typeof(EncryptedXml).GetField("m_keyNameMapping", BindingFlags.Instance | BindingFlags.NonPublic);
}
}
}
if (_keyNameMappingField == null)
{
throw ExceptionUtility.CryptographicException(Resources.XmlCannotFindPrivateMember, "m_keyNameMapping");
}
return (Hashtable)_keyNameMappingField.GetValue(encryptedXml);
}
private static readonly object GetCipherValueMethodSync = new object();
private static volatile MethodInfo _getCipherValueMethod;
public static byte[] GetCipherValue(this EncryptedXml encryptedXml, CipherData cipherData)
{
if (_getCipherValueMethod == null)
{
lock (GetCipherValueMethodSync)
{
if (_getCipherValueMethod == null)
{
_getCipherValueMethod = typeof(EncryptedXml).GetMethod("GetCipherValue", BindingFlags.Instance | BindingFlags.NonPublic);
}
}
}
if (_getCipherValueMethod == null)
{
throw ExceptionUtility.CryptographicException(Resources.XmlCannotFindPrivateMember, "GetCipherValue()");
}
return (byte[])_getCipherValueMethod.Invoke(encryptedXml, new object[] { cipherData });
}
}
}

View File

@ -0,0 +1,122 @@
using GostCryptography.Properties;
using System.Collections;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
namespace GostCryptography.Reflection
{
static class SignedXmlHelper
{
public static IEnumerator GetKeyInfoEnumerable(this SignedXml signedXml)
{
return (IEnumerator)KeyInfoEnumerableField.GetValue(signedXml);
}
public static void SetKeyInfoEnumerable(this SignedXml signedXml, IEnumerator keyInfoEnumerable)
{
KeyInfoEnumerableField.SetValue(signedXml, keyInfoEnumerable);
}
private static volatile FieldInfo _keyInfoEnumerableField;
private static readonly object KeyInfoEnumerableFieldSync = new object();
private static FieldInfo KeyInfoEnumerableField
{
get
{
if (_keyInfoEnumerableField == null)
{
lock (KeyInfoEnumerableFieldSync)
{
if (_keyInfoEnumerableField == null)
{
_keyInfoEnumerableField = typeof(SignedXml).GetField("m_keyInfoEnum", BindingFlags.Instance | BindingFlags.NonPublic);
}
}
}
if (_keyInfoEnumerableField == null)
{
throw ExceptionUtility.CryptographicException(Resources.XmlCannotFindPrivateMember, "m_keyInfoEnum");
}
return _keyInfoEnumerableField;
}
}
public static IEnumerator GetX509Enumerable(this SignedXml signedXml)
{
return (IEnumerator)X509EnumerableField.GetValue(signedXml);
}
public static void SetX509Enumerable(this SignedXml signedXml, IEnumerator x509Enumerable)
{
X509EnumerableField.SetValue(signedXml, x509Enumerable);
}
private static volatile FieldInfo _x509EnumerableField;
private static readonly object X509EnumerableSync = new object();
private static FieldInfo X509EnumerableField
{
get
{
if (_x509EnumerableField == null)
{
lock (X509EnumerableSync)
{
if (_x509EnumerableField == null)
{
_x509EnumerableField = typeof(SignedXml).GetField("m_x509Enum", BindingFlags.Instance | BindingFlags.NonPublic);
}
}
}
if (_x509EnumerableField == null)
{
throw ExceptionUtility.CryptographicException(Resources.XmlCannotFindPrivateMember, "m_x509Enum");
}
return _x509EnumerableField;
}
}
public static X509Certificate2Collection GetX509Collection(this SignedXml signedXml)
{
return (X509Certificate2Collection)X509CollectionField.GetValue(signedXml);
}
public static void SetX509Collection(this SignedXml signedXml, X509Certificate2Collection x509Collection)
{
X509CollectionField.SetValue(signedXml, x509Collection);
}
private static volatile FieldInfo _x509CollectionField;
private static readonly object X509CollectionFieldSync = new object();
private static FieldInfo X509CollectionField
{
get
{
if (_x509CollectionField == null)
{
lock (X509CollectionFieldSync)
{
if (_x509CollectionField == null)
{
_x509CollectionField = typeof(SignedXml).GetField("m_x509Collection", BindingFlags.Instance | BindingFlags.NonPublic);
}
}
}
if (_keyInfoEnumerableField == null)
{
throw ExceptionUtility.CryptographicException(Resources.XmlCannotFindPrivateMember, "m_x509Collection");
}
return _x509CollectionField;
}
}
}
}

View File

@ -0,0 +1,293 @@
using GostCryptography;
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;
using GostCryptography.Gost_R3410;
using GostCryptography.Native;
using System.Reflection;
// ReSharper disable once CheckNamespace
namespace System.Security.Cryptography.X509Certificates
{
/// <summary>
/// Методы расширения <see cref="X509Certificate2"/>
/// </summary>
[SecurityCritical]
public static class X509CertificateHelper
{
/// <summary>
/// Возвращает <see langword="true"/> для сертификатов ГОСТ
/// </summary>
public static bool IsGost(this X509Certificate2 certificate)
{
return certificate.IsGost_R3410_2012_512()
|| certificate.IsGost_R3410_2012_256()
|| certificate.IsGost_R3410_2001()
|| certificate.IsGost_R3410_94();
}
/// <summary>
/// Возвращает <see langword="true"/> для сертификатов ГОСТ Р 34.10-94
/// </summary>
public static bool IsGost_R3410_94(this X509Certificate2 certificate)
{
return Gost_R3410_94_Constants.KeyAlgorithm.Value.Equals(certificate.GetKeyAlgorithm());
}
/// <summary>
/// Возвращает <see langword="true"/> для сертификатов ГОСТ Р 34.10-2001
/// </summary>
public static bool IsGost_R3410_2001(this X509Certificate2 certificate)
{
return Gost_R3410_2001_Constants.KeyAlgorithm.Value.Equals(certificate.GetKeyAlgorithm());
}
/// <summary>
/// Возвращает <see langword="true"/> для сертификатов ГОСТ Р 34.10-2012/256
/// </summary>
public static bool IsGost_R3410_2012_256(this X509Certificate2 certificate)
{
return Gost_R3410_2012_256_Constants.KeyAlgorithm.Value.Equals(certificate.GetKeyAlgorithm());
}
/// <summary>
/// Возвращает <see langword="true"/> для сертификатов ГОСТ Р 34.10-2012/512
/// </summary>
public static bool IsGost_R3410_2012_512(this X509Certificate2 certificate)
{
return Gost_R3410_2012_512_Constants.KeyAlgorithm.Value.Equals(certificate.GetKeyAlgorithm());
}
/// <summary>
/// Возвращает <see cref="Oid"/> функции хэширования сертификата
/// </summary>
/// <param name="certificate"></param>
/// <returns></returns>
public static Oid GetHashAlgorithm(this X509Certificate2 certificate)
{
if (certificate.IsGost_R3410_2012_512())
{
return Gost_R3410_2012_512_Constants.HashAlgorithm.ToOid();
}
if (certificate.IsGost_R3410_2012_256())
{
return Gost_R3410_2012_256_Constants.HashAlgorithm.ToOid();
}
if (certificate.IsGost_R3410_2001())
{
return Gost_R3410_2001_Constants.HashAlgorithm.ToOid();
}
if (certificate.IsGost_R3410_94())
{
return Gost_R3410_94_Constants.HashAlgorithm.ToOid();
}
return null;
}
private static volatile MethodInfo _getPrivateKeyInfoMethod;
private static readonly object GetPrivateKeyInfoMethodSync = new object();
/// <summary>
/// Возвращает параметры <see cref="CspParameters"/> закрытого ключа сертификата
/// </summary>
/// <param name="certificate"></param>
/// <returns></returns>
public static CspParameters GetPrivateKeyInfo(this X509Certificate2 certificate)
{
if (certificate == null)
{
throw ExceptionUtility.ArgumentNull(nameof(certificate));
}
if (certificate.HasPrivateKey)
{
if (_getPrivateKeyInfoMethod == null)
{
lock (GetPrivateKeyInfoMethodSync)
{
if (_getPrivateKeyInfoMethod == null)
{
_getPrivateKeyInfoMethod = typeof(X509Certificate2).GetMethod("GetPrivateKeyInfo", BindingFlags.Static | BindingFlags.NonPublic);
}
}
}
if (_getPrivateKeyInfoMethod != null)
{
var certContext = GetCertContext(certificate);
if (certContext != null)
{
try
{
var parameters = new CspParameters();
var success = _getPrivateKeyInfoMethod.Invoke(null, new[] { certContext, parameters });
if (Equals(success, true))
{
return parameters;
}
}
catch
{
}
}
}
}
return null;
}
private static volatile MethodInfo _setPrivateKeyPropertyMethod;
private static readonly object SetPrivateKeyPropertyMethodSync = new object();
private static void SetPrivateKeyProperty(X509Certificate2 certificate, ICspAsymmetricAlgorithm privateKey)
{
if (_setPrivateKeyPropertyMethod == null)
{
lock (SetPrivateKeyPropertyMethodSync)
{
if (_setPrivateKeyPropertyMethod == null)
{
_setPrivateKeyPropertyMethod = typeof(X509Certificate2).GetMethod("SetPrivateKeyProperty", BindingFlags.Static | BindingFlags.NonPublic);
}
}
}
if (_setPrivateKeyPropertyMethod != null)
{
var certContext = GetCertContext(certificate);
if (certContext != null)
{
try
{
_setPrivateKeyPropertyMethod.Invoke(null, new[] { certContext, privateKey });
}
catch
{
}
}
}
}
private static volatile FieldInfo _certContextField;
private static readonly object CertContextFieldSync = new object();
private static object GetCertContext(X509Certificate2 certificate)
{
if (_certContextField == null)
{
lock (CertContextFieldSync)
{
if (_certContextField == null)
{
_certContextField = typeof(X509Certificate2).GetField("m_safeCertContext", BindingFlags.Instance | BindingFlags.NonPublic);
}
}
}
if (_certContextField != null)
{
try
{
return _certContextField.GetValue(certificate);
}
catch
{
}
}
return null;
}
/// <summary>
/// Возвращает закрытый ключ сертификата
/// </summary>
public static AsymmetricAlgorithm GetPrivateKeyAlgorithm(this X509Certificate2 certificate)
{
if (certificate.IsGost_R3410_2012_512())
{
var cspParameters = GetPrivateKeyInfo(certificate);
return new Gost_R3410_2012_512_AsymmetricAlgorithm(cspParameters);
}
if (certificate.IsGost_R3410_2012_256())
{
var cspParameters = GetPrivateKeyInfo(certificate);
return new Gost_R3410_2012_256_AsymmetricAlgorithm(cspParameters);
}
if (certificate.IsGost_R3410_2001())
{
var cspParameters = GetPrivateKeyInfo(certificate);
return new Gost_R3410_2001_AsymmetricAlgorithm(cspParameters);
}
return certificate.PrivateKey;
}
/// <summary>
/// Возвращает открытый ключ сертификата
/// </summary>
public static AsymmetricAlgorithm GetPublicKeyAlgorithm(this X509Certificate2 certificate)
{
if (certificate.IsGost_R3410_2012_512())
{
var publicKey = new Gost_R3410_2012_512_AsymmetricAlgorithm();
var encodedParameters = certificate.PublicKey.EncodedParameters.RawData;
var encodedKeyValue = certificate.PublicKey.EncodedKeyValue.RawData;
publicKey.ImportCspBlob(encodedParameters, encodedKeyValue);
return publicKey;
}
if (certificate.IsGost_R3410_2012_256())
{
var publicKey = new Gost_R3410_2012_256_AsymmetricAlgorithm();
var encodedParameters = certificate.PublicKey.EncodedParameters.RawData;
var encodedKeyValue = certificate.PublicKey.EncodedKeyValue.RawData;
publicKey.ImportCspBlob(encodedParameters, encodedKeyValue);
return publicKey;
}
if (certificate.IsGost_R3410_2001())
{
var publicKey = new Gost_R3410_2001_AsymmetricAlgorithm();
var encodedParameters = certificate.PublicKey.EncodedParameters.RawData;
var encodedKeyValue = certificate.PublicKey.EncodedKeyValue.RawData;
publicKey.ImportCspBlob(encodedParameters, encodedKeyValue);
return publicKey;
}
return certificate.PublicKey.Key;
}
/// <summary>
/// Возвращает сертификат для указанного ключа
/// </summary>
/// <param name="key">Ключ сертификата</param>
/// <param name="useAsPrivateKey">Использовать ключ, как приватный</param>
public static X509Certificate2 GetCertificate(this AsymmetricAlgorithm key, bool useAsPrivateKey = false)
{
X509Certificate2 certificate = null;
if (key is ISafeHandleProvider<SafeKeyHandleImpl> keyHandleProvider)
{
certificate = CryptoApiHelper.GetKeyCertificate(keyHandleProvider.SafeHandle);
}
if (useAsPrivateKey && (certificate != null) && (key is ICspAsymmetricAlgorithm privateKey))
{
SetPrivateKeyProperty(certificate, privateKey);
}
return certificate;
}
}
}