Add support for ГОСТ Р 34.10 digital signatures
- Implemented the GostKeyValue class for handling public key parameters in ГОСТ Р 34.10 digital signatures. - Created the GostSignedXml class to manage XML signatures using ГОСТ 34.10, including methods for computing and checking signatures. - Developed the GostSignedXmlImpl class to encapsulate the signature computation logic and public key retrieval. - Added specific key value classes for ГОСТ Р 34.10-2001, ГОСТ Р 34.10-2012/256, and ГОСТ Р 34.10-2012/512 to support different signature algorithms. - Ensured compatibility with existing XML signature standards while integrating ГОСТ cryptography.
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<MyXml>
|
||||
<SomeElement Encrypt="false">
|
||||
Here is public data.
|
||||
</SomeElement>
|
||||
<SomeElement Encrypt="true">
|
||||
Here is private data.
|
||||
</SomeElement>
|
||||
<SomeElement Encrypt="true">
|
||||
Here is private data.
|
||||
</SomeElement>
|
||||
<SomeElement Encrypt="true">
|
||||
Here is private data.
|
||||
</SomeElement>
|
||||
</MyXml>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<MyXml>
|
||||
<SomeElement Id="Id1">
|
||||
Here is some data to sign.
|
||||
</SomeElement>
|
||||
</MyXml>
|
||||
53
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/Data/SmevExample.xml
vendored
Normal file
53
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/Data/SmevExample.xml
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
|
||||
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
|
||||
>
|
||||
<S:Header>
|
||||
<wsse:Security S:actor="http://smev.gosuslugi.ru/actors/smev">
|
||||
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
<ds:KeyInfo>
|
||||
<wsse:SecurityTokenReference>
|
||||
<wsse:Reference URI="#SenderCertificate"/>
|
||||
</wsse:SecurityTokenReference>
|
||||
</ds:KeyInfo>
|
||||
</ds:Signature>
|
||||
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
|
||||
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
|
||||
wsu:Id="SenderCertificate"
|
||||
>
|
||||
</wsse:BinarySecurityToken>
|
||||
</wsse:Security>
|
||||
</S:Header>
|
||||
<S:Body wsu:Id="body">
|
||||
<ws:queryINNFL xmlns:ws="http://ws.unisoft/">
|
||||
<smev:Message xmlns:smev="http://smev.gosuslugi.ru/rev110801">
|
||||
<smev:Sender>
|
||||
<smev:Code>MINECONOMSK_SYS_1</smev:Code>
|
||||
<smev:Name>Минэкономразвития СК</smev:Name>
|
||||
</smev:Sender>
|
||||
<smev:Recipient>
|
||||
<smev:Code>13312</smev:Code>
|
||||
<smev:Name>ФНС</smev:Name>
|
||||
</smev:Recipient>
|
||||
<smev:Originator>
|
||||
<smev:Code>MINECONOMSK_SYS_1</smev:Code>
|
||||
<smev:Name>Минэкономразвития СК</smev:Name>
|
||||
</smev:Originator>
|
||||
<smev:TypeCode>2</smev:TypeCode>
|
||||
<smev:Date>2012-03-13T11:10:54.54Z</smev:Date>
|
||||
</smev:Message>
|
||||
<smev:MessageData xmlns:smev="http://smev.gosuslugi.ru/rev110801">
|
||||
<smev:AppData wsu:Id="fns-AppData">
|
||||
<Документ xmlns="http://ws.unisoft/FNSINN/queryINNFL" ВерсФорм="4.01" ИдЗапрос="AB324006-978B-44D4-933D-C5E6DFA8A576">
|
||||
<СвЮЛ ИННЮЛ="7825497650" НаимОрг="Нагрузочное тестирование" ОГРН="1037843048880"/>
|
||||
<СвФЛ ДатаРожд="12.07.1954" МестоРожд="РОССИЯ,,ГОРЬКОВСКАЯ ОБЛ.,АРЗАМАССКИЙ Р-Н,,НИКОЛЬСКОЕ С., ,,,">
|
||||
<ФИО Имя="ПЕТР" Отчество="АЛЕКСЕЕВИЧ" Фамилия="ЧАХЛОВ"/>
|
||||
<УдЛичнФЛ ВыдДок="АРОВД" ДатаДок="16.11.2002" КодВидДок="21" СерНомДок="22 02 919928"/>
|
||||
</СвФЛ>
|
||||
</Документ>
|
||||
</smev:AppData>
|
||||
</smev:MessageData>
|
||||
</ws:queryINNFL>
|
||||
</S:Body>
|
||||
</S:Envelope>
|
||||
@@ -0,0 +1,37 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net40;net452</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Security" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="nunit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0-preview.2" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GostCryptography\GostCryptography.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,103 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрование и дешифрование данных с использованием случайного сессионного ключа.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест имитирует обмен данными между условным отправителем, который шифрует заданный поток байт, и условным получателем, который дешифрует
|
||||
/// зашифрованный поток байт. Шифрация осуществляется с использованием случайного симметричного ключа, который в свою очередь шифруется
|
||||
/// с использованием открытого ключа получателя. Соответственно для дешифрации данных сначала расшифровывается случайный симметричный ключ
|
||||
/// с использованием закрытого ключа получателя.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрование и дешифрование данных с использованием случайного сессионного ключа")]
|
||||
public class EncryptDecryptSessionKeyTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptAndDecrypt(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var privateKey = (GostAsymmetricAlgorithm)certificate.GetPrivateKeyAlgorithm();
|
||||
var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
var encryptedDataStream = SendEncryptedDataStream(publicKey, dataStream, out var iv, out var sessionKey);
|
||||
var decryptedDataStream = ReceiveEncryptedDataStream(privateKey, encryptedDataStream, iv, sessionKey);
|
||||
|
||||
// Then
|
||||
Assert.That(dataStream, Is.EqualTo(decryptedDataStream));
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to encrypt..."));
|
||||
}
|
||||
|
||||
private static Stream SendEncryptedDataStream(GostAsymmetricAlgorithm publicKey, Stream dataStream, out byte[] iv, out byte[] sessionKey)
|
||||
{
|
||||
var encryptedDataStream = new MemoryStream();
|
||||
|
||||
// Отправитель создает случайный сессионный ключ для шифрации данных
|
||||
using (var senderSessionKey = new Gost_28147_89_SymmetricAlgorithm(publicKey.ProviderType))
|
||||
{
|
||||
// Отправитель передает получателю вектор инициализации
|
||||
iv = senderSessionKey.IV;
|
||||
|
||||
// Отправитель шифрует сессионный ключ и передает его получателю
|
||||
var formatter = publicKey.CreateKeyExchangeFormatter();
|
||||
sessionKey = formatter.CreateKeyExchangeData(senderSessionKey);
|
||||
|
||||
// Отправитель шифрует данные с использованием сессионного ключа
|
||||
using (var encryptor = senderSessionKey.CreateEncryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, encryptor, CryptoStreamMode.Write);
|
||||
dataStream.CopyTo(cryptoStream);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
}
|
||||
}
|
||||
|
||||
encryptedDataStream.Position = 0;
|
||||
|
||||
return encryptedDataStream;
|
||||
}
|
||||
|
||||
private static Stream ReceiveEncryptedDataStream(GostAsymmetricAlgorithm privateKey, Stream encryptedDataStream, byte[] iv, byte[] sessionKey)
|
||||
{
|
||||
var decryptedDataStream = new MemoryStream();
|
||||
|
||||
var deformatter = privateKey.CreateKeyExchangeDeformatter();
|
||||
|
||||
// Получатель принимает от отправителя зашифрованный сессионный ключ и дешифрует его
|
||||
using (var receiverSessionKey = deformatter.DecryptKeyExchangeAlgorithm(sessionKey))
|
||||
{
|
||||
// Получатель принимает от отправителя вектор инициализации
|
||||
receiverSessionKey.IV = iv;
|
||||
|
||||
// Получатель дешифрует данные с использованием сессионного ключа
|
||||
using (var decryptor = receiverSessionKey.CreateDecryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read);
|
||||
cryptoStream.CopyTo(decryptedDataStream);
|
||||
}
|
||||
}
|
||||
|
||||
decryptedDataStream.Position = 0;
|
||||
|
||||
return decryptedDataStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление имитовставки на базе общего симметричного ключа ГОСТ 28147-89.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест выполняет подпись и проверку подписи потока байт с использованием имитовставки.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление имитовставки на базе общего симметричного ключа ГОСТ 28147-89")]
|
||||
public class Gost_28147_89_ImitHashAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeImitHash(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
var imitDataStream = CreateImitDataStream(sharedKey, dataStream);
|
||||
var isValidImitDataStream = VerifyImitDataStream(sharedKey, imitDataStream);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidImitDataStream);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data for imit..."));
|
||||
}
|
||||
|
||||
private static Stream CreateImitDataStream(Gost_28147_89_SymmetricAlgorithmBase sharedKey, Stream dataStream)
|
||||
{
|
||||
// Создание объекта для вычисления имитовставки
|
||||
using (var imitHash = new Gost_28147_89_ImitHashAlgorithm(sharedKey))
|
||||
{
|
||||
// Вычисление имитовставки для потока данных
|
||||
var imitHashValue = imitHash.ComputeHash(dataStream);
|
||||
|
||||
// Запись имитовставки в начало выходного потока данных
|
||||
var imitDataStream = new MemoryStream();
|
||||
imitDataStream.Write(imitHashValue, 0, imitHashValue.Length);
|
||||
|
||||
// Копирование исходного потока данных в выходной поток
|
||||
dataStream.Position = 0;
|
||||
dataStream.CopyTo(imitDataStream);
|
||||
|
||||
imitDataStream.Position = 0;
|
||||
|
||||
return imitDataStream;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool VerifyImitDataStream(Gost_28147_89_SymmetricAlgorithmBase sharedKey, Stream imitDataStream)
|
||||
{
|
||||
// Создание объекта для вычисления имитовставки
|
||||
using (var imitHash = new Gost_28147_89_ImitHashAlgorithm(sharedKey))
|
||||
{
|
||||
// Считывание имитовставки из потока данных
|
||||
var imitHashValue = new byte[imitHash.HashSize / 8];
|
||||
imitDataStream.Read(imitHashValue, 0, imitHashValue.Length);
|
||||
|
||||
// Вычисление реального значения имитовставки для потока данных
|
||||
var expectedImitHashValue = imitHash.ComputeHash(imitDataStream);
|
||||
|
||||
// Сравнение исходной имитовставки с ожидаемой
|
||||
return imitHashValue.SequenceEqual(expectedImitHashValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрование и дешифрование данных с использованием общего симметричного ключа ГОСТ 28147-89.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, шифрует его с использованием общего симметричного ключа,
|
||||
/// а затем дешифрует зашифрованные данные и проверяет корректность дешифрации.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрование и дешифрование данных с использованием общего симметричного ключа ГОСТ 28147-89")]
|
||||
public class Gost_28147_89_SymmetricAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldEncryptAndDecrypt(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
var encryptedDataStream = EncryptDataStream(sharedKey, dataStream);
|
||||
var decryptedDataStream = DecryptDataStream(sharedKey, encryptedDataStream);
|
||||
|
||||
// Then
|
||||
Assert.That(dataStream, Is.EqualTo(decryptedDataStream));
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to encrypt..."));
|
||||
}
|
||||
|
||||
private static Stream EncryptDataStream(SymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
var encryptedDataStream = new MemoryStream();
|
||||
|
||||
using (var encryptor = sharedKey.CreateEncryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, encryptor, CryptoStreamMode.Write);
|
||||
dataStream.CopyTo(cryptoStream);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
}
|
||||
|
||||
encryptedDataStream.Position = 0;
|
||||
|
||||
return encryptedDataStream;
|
||||
}
|
||||
|
||||
private static Stream DecryptDataStream(SymmetricAlgorithm sharedKey, Stream encryptedDataStream)
|
||||
{
|
||||
var decryptedDataStream = new MemoryStream();
|
||||
|
||||
using (var decryptor = sharedKey.CreateDecryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read);
|
||||
cryptoStream.CopyTo(decryptedDataStream);
|
||||
decryptedDataStream.Flush();
|
||||
}
|
||||
|
||||
decryptedDataStream.Position = 0;
|
||||
|
||||
return decryptedDataStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрование и дешифрование данных с использованием случайного сессионного ключа ГОСТ Р 34.12-2015 Кузнечик.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест имитирует обмен данными между условным отправителем, который шифрует заданный поток байт, и условным получателем, который дешифрует
|
||||
/// зашифрованный поток байт. Шифрация осуществляется с использованием случайного симметричного ключа, который в свою очередь шифруется
|
||||
/// с использованием открытого ключа получателя. Соответственно для дешифрации данных сначала расшифровывается случайный симметричный ключ
|
||||
/// с использованием закрытого ключа получателя.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрование и дешифрование данных с использованием случайного сессионного ключа ГОСТ Р 34.12-2015 Кузнечик")]
|
||||
public class KuznyechikEncryptDecryptSessionKeyTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptAndDecrypt(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var privateKey = (GostAsymmetricAlgorithm)certificate.GetPrivateKeyAlgorithm();
|
||||
var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
var encryptedDataStream = SendEncryptedDataStream(publicKey, dataStream, out var iv, out var sessionKey);
|
||||
var decryptedDataStream = ReceiveEncryptedDataStream(privateKey, encryptedDataStream, iv, sessionKey);
|
||||
|
||||
// Then
|
||||
Assert.That(dataStream, Is.EqualTo(decryptedDataStream));
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to encrypt..."));
|
||||
}
|
||||
|
||||
private static Stream SendEncryptedDataStream(GostAsymmetricAlgorithm publicKey, Stream dataStream, out byte[] iv, out byte[] sessionKey)
|
||||
{
|
||||
var encryptedDataStream = new MemoryStream();
|
||||
|
||||
// Отправитель создает случайный сессионный ключ для шифрации данных
|
||||
using (var senderSessionKey = new Gost_3412_K_SymmetricAlgorithm(publicKey.ProviderType))
|
||||
{
|
||||
// Отправитель передает получателю вектор инициализации
|
||||
iv = senderSessionKey.IV;
|
||||
|
||||
// Отправитель шифрует сессионный ключ и передает его получателю
|
||||
var formatter = publicKey.CreateKeyExchangeFormatter();
|
||||
sessionKey = formatter.CreateKeyExchangeData(senderSessionKey);
|
||||
|
||||
// Отправитель шифрует данные с использованием сессионного ключа
|
||||
using (var encryptor = senderSessionKey.CreateEncryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, encryptor, CryptoStreamMode.Write);
|
||||
dataStream.CopyTo(cryptoStream);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
}
|
||||
}
|
||||
|
||||
encryptedDataStream.Position = 0;
|
||||
|
||||
return encryptedDataStream;
|
||||
}
|
||||
|
||||
private static Stream ReceiveEncryptedDataStream(GostAsymmetricAlgorithm privateKey, Stream encryptedDataStream, byte[] iv, byte[] sessionKey)
|
||||
{
|
||||
var decryptedDataStream = new MemoryStream();
|
||||
|
||||
var deformatter = privateKey.CreateKeyExchangeDeformatter();
|
||||
|
||||
// Получатель принимает от отправителя зашифрованный сессионный ключ и дешифрует его
|
||||
using (var receiverSessionKey = deformatter.DecryptKeyExchangeAlgorithm(sessionKey))
|
||||
{
|
||||
// Получатель принимает от отправителя вектор инициализации
|
||||
receiverSessionKey.IV = iv;
|
||||
|
||||
// Получатель дешифрует данные с использованием сессионного ключа
|
||||
using (var decryptor = receiverSessionKey.CreateDecryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read);
|
||||
cryptoStream.CopyTo(decryptedDataStream);
|
||||
}
|
||||
}
|
||||
|
||||
decryptedDataStream.Position = 0;
|
||||
|
||||
return decryptedDataStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление имитовставки на базе общего симметричного ключа ГОСТ Р 34.12-2015 Кузнечик.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест выполняет подпись и проверку подписи потока байт с использованием имитовставки.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление имитовставки на базе общего симметричного ключа ГОСТ Р 34.12-2015 Кузнечик")]
|
||||
public class KuznyechikImitHashAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeImitHash(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
var sharedKey = new Gost_3412_K_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
var imitDataStream = CreateImitDataStream(sharedKey, dataStream);
|
||||
var isValidImitDataStream = VerifyImitDataStream(sharedKey, imitDataStream);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidImitDataStream);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data for imit..."));
|
||||
}
|
||||
|
||||
private static Stream CreateImitDataStream(Gost_3412_K_SymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
// Создание объекта для вычисления имитовставки
|
||||
using (var imitHash = new Gost_3412_K_ImitHashAlgorithm(sharedKey))
|
||||
{
|
||||
// Вычисление имитовставки для потока данных
|
||||
var imitHashValue = imitHash.ComputeHash(dataStream);
|
||||
|
||||
// Запись имитовставки в начало выходного потока данных
|
||||
var imitDataStream = new MemoryStream();
|
||||
imitDataStream.Write(imitHashValue, 0, imitHashValue.Length);
|
||||
|
||||
// Копирование исходного потока данных в выходной поток
|
||||
dataStream.Position = 0;
|
||||
dataStream.CopyTo(imitDataStream);
|
||||
|
||||
imitDataStream.Position = 0;
|
||||
|
||||
return imitDataStream;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool VerifyImitDataStream(Gost_3412_K_SymmetricAlgorithm sharedKey, Stream imitDataStream)
|
||||
{
|
||||
// Создание объекта для вычисления имитовставки
|
||||
using (var imitHash = new Gost_3412_K_ImitHashAlgorithm(sharedKey))
|
||||
{
|
||||
// Считывание имитовставки из потока данных
|
||||
var imitHashValue = new byte[imitHash.HashSize / 8];
|
||||
imitDataStream.Read(imitHashValue, 0, imitHashValue.Length);
|
||||
|
||||
// Вычисление реального значения имитовставки для потока данных
|
||||
var expectedImitHashValue = imitHash.ComputeHash(imitDataStream);
|
||||
|
||||
// Сравнение исходной имитовставки с ожидаемой
|
||||
return imitHashValue.SequenceEqual(expectedImitHashValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрование и дешифрование данных с использованием общего симметричного ключа ГОСТ Р 34.12-2015 Кузнечик.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, шифрует его с использованием общего симметричного ключа,
|
||||
/// а затем дешифрует зашифрованные данные и проверяет корректность дешифрации.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрование и дешифрование данных с использованием общего симметричного ключа ГОСТ Р 34.12-2015 Кузнечик")]
|
||||
public class KuznyechikSymmetricAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldEncryptAndDecrypt(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var sharedKey = new Gost_3412_K_SymmetricAlgorithm(providerType);
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
var encryptedDataStream = EncryptDataStream(sharedKey, dataStream);
|
||||
var decryptedDataStream = DecryptDataStream(sharedKey, encryptedDataStream);
|
||||
|
||||
// Then
|
||||
Assert.That(dataStream, Is.EqualTo(decryptedDataStream));
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to encrypt..."));
|
||||
}
|
||||
|
||||
private static Stream EncryptDataStream(SymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
var encryptedDataStream = new MemoryStream();
|
||||
|
||||
using (var encryptor = sharedKey.CreateEncryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, encryptor, CryptoStreamMode.Write);
|
||||
dataStream.CopyTo(cryptoStream);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
}
|
||||
|
||||
encryptedDataStream.Position = 0;
|
||||
|
||||
return encryptedDataStream;
|
||||
}
|
||||
|
||||
private static Stream DecryptDataStream(SymmetricAlgorithm sharedKey, Stream encryptedDataStream)
|
||||
{
|
||||
var decryptedDataStream = new MemoryStream();
|
||||
|
||||
using (var decryptor = sharedKey.CreateDecryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read);
|
||||
cryptoStream.CopyTo(decryptedDataStream);
|
||||
decryptedDataStream.Flush();
|
||||
}
|
||||
|
||||
decryptedDataStream.Position = 0;
|
||||
|
||||
return decryptedDataStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрование и дешифрование данных с использованием случайного сессионного ключа ГОСТ Р 34.12-2015 Магма.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест имитирует обмен данными между условным отправителем, который шифрует заданный поток байт, и условным получателем, который дешифрует
|
||||
/// зашифрованный поток байт. Шифрация осуществляется с использованием случайного симметричного ключа, который в свою очередь шифруется
|
||||
/// с использованием открытого ключа получателя. Соответственно для дешифрации данных сначала расшифровывается случайный симметричный ключ
|
||||
/// с использованием закрытого ключа получателя.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрование и дешифрование данных с использованием случайного сессионного ключа ГОСТ Р 34.12-2015 Магма")]
|
||||
public class MagmaEncryptDecryptSessionKeyTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptAndDecrypt(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var privateKey = (GostAsymmetricAlgorithm)certificate.GetPrivateKeyAlgorithm();
|
||||
var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
var encryptedDataStream = SendEncryptedDataStream(publicKey, dataStream, out var iv, out var sessionKey);
|
||||
var decryptedDataStream = ReceiveEncryptedDataStream(privateKey, encryptedDataStream, iv, sessionKey);
|
||||
|
||||
// Then
|
||||
Assert.That(dataStream, Is.EqualTo(decryptedDataStream));
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to encrypt..."));
|
||||
}
|
||||
|
||||
private static Stream SendEncryptedDataStream(GostAsymmetricAlgorithm publicKey, Stream dataStream, out byte[] iv, out byte[] sessionKey)
|
||||
{
|
||||
var encryptedDataStream = new MemoryStream();
|
||||
|
||||
// Отправитель создает случайный сессионный ключ для шифрации данных
|
||||
using (var senderSessionKey = new Gost_3412_M_SymmetricAlgorithm(publicKey.ProviderType))
|
||||
{
|
||||
// Отправитель передает получателю вектор инициализации
|
||||
iv = senderSessionKey.IV;
|
||||
|
||||
// Отправитель шифрует сессионный ключ и передает его получателю
|
||||
var formatter = publicKey.CreateKeyExchangeFormatter();
|
||||
sessionKey = formatter.CreateKeyExchangeData(senderSessionKey);
|
||||
|
||||
// Отправитель шифрует данные с использованием сессионного ключа
|
||||
using (var encryptor = senderSessionKey.CreateEncryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, encryptor, CryptoStreamMode.Write);
|
||||
dataStream.CopyTo(cryptoStream);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
}
|
||||
}
|
||||
|
||||
encryptedDataStream.Position = 0;
|
||||
|
||||
return encryptedDataStream;
|
||||
}
|
||||
|
||||
private static Stream ReceiveEncryptedDataStream(GostAsymmetricAlgorithm privateKey, Stream encryptedDataStream, byte[] iv, byte[] sessionKey)
|
||||
{
|
||||
var decryptedDataStream = new MemoryStream();
|
||||
|
||||
var deformatter = privateKey.CreateKeyExchangeDeformatter();
|
||||
|
||||
// Получатель принимает от отправителя зашифрованный сессионный ключ и дешифрует его
|
||||
using (var receiverSessionKey = deformatter.DecryptKeyExchangeAlgorithm(sessionKey))
|
||||
{
|
||||
// Получатель принимает от отправителя вектор инициализации
|
||||
receiverSessionKey.IV = iv;
|
||||
|
||||
// Получатель дешифрует данные с использованием сессионного ключа
|
||||
using (var decryptor = receiverSessionKey.CreateDecryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read);
|
||||
cryptoStream.CopyTo(decryptedDataStream);
|
||||
}
|
||||
}
|
||||
|
||||
decryptedDataStream.Position = 0;
|
||||
|
||||
return decryptedDataStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление имитовставки на базе общего симметричного ключа ГОСТ Р 34.12-2015 Магма.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест выполняет подпись и проверку подписи потока байт с использованием имитовставки.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление имитовставки на базе общего симметричного ключа ГОСТ Р 34.12-2015 Магма")]
|
||||
public class MagmaImitHashAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeImitHash(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
var sharedKey = new Gost_3412_M_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
var imitDataStream = CreateImitDataStream(sharedKey, dataStream);
|
||||
var isValidImitDataStream = VerifyImitDataStream(sharedKey, imitDataStream);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidImitDataStream);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data for imit..."));
|
||||
}
|
||||
|
||||
private static Stream CreateImitDataStream(Gost_3412_M_SymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
// Создание объекта для вычисления имитовставки
|
||||
using (var imitHash = new Gost_3412_M_ImitHashAlgorithm(sharedKey))
|
||||
{
|
||||
// Вычисление имитовставки для потока данных
|
||||
var imitHashValue = imitHash.ComputeHash(dataStream);
|
||||
|
||||
// Запись имитовставки в начало выходного потока данных
|
||||
var imitDataStream = new MemoryStream();
|
||||
imitDataStream.Write(imitHashValue, 0, imitHashValue.Length);
|
||||
|
||||
// Копирование исходного потока данных в выходной поток
|
||||
dataStream.Position = 0;
|
||||
dataStream.CopyTo(imitDataStream);
|
||||
|
||||
imitDataStream.Position = 0;
|
||||
|
||||
return imitDataStream;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool VerifyImitDataStream(Gost_3412_M_SymmetricAlgorithm sharedKey, Stream imitDataStream)
|
||||
{
|
||||
// Создание объекта для вычисления имитовставки
|
||||
using (var imitHash = new Gost_3412_M_ImitHashAlgorithm(sharedKey))
|
||||
{
|
||||
// Считывание имитовставки из потока данных
|
||||
var imitHashValue = new byte[imitHash.HashSize / 8];
|
||||
imitDataStream.Read(imitHashValue, 0, imitHashValue.Length);
|
||||
|
||||
// Вычисление реального значения имитовставки для потока данных
|
||||
var expectedImitHashValue = imitHash.ComputeHash(imitDataStream);
|
||||
|
||||
// Сравнение исходной имитовставки с ожидаемой
|
||||
return imitHashValue.SequenceEqual(expectedImitHashValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_28147_89
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрование и дешифрование данных с использованием общего симметричного ключа ГОСТ Р 34.12-2015 Магма.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, шифрует его с использованием общего симметричного ключа,
|
||||
/// а затем дешифрует зашифрованные данные и проверяет корректность дешифрации.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрование и дешифрование данных с использованием общего симметричного ключа ГОСТ Р 34.12-2015 Магма")]
|
||||
public class MagmaSymmetricAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldEncryptAndDecrypt(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var sharedKey = new Gost_3412_M_SymmetricAlgorithm(providerType);
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
var encryptedDataStream = EncryptDataStream(sharedKey, dataStream);
|
||||
var decryptedDataStream = DecryptDataStream(sharedKey, encryptedDataStream);
|
||||
|
||||
// Then
|
||||
Assert.That(dataStream, Is.EqualTo(decryptedDataStream));
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to encrypt..."));
|
||||
}
|
||||
|
||||
private static Stream EncryptDataStream(SymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
var encryptedDataStream = new MemoryStream();
|
||||
|
||||
using (var encryptor = sharedKey.CreateEncryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, encryptor, CryptoStreamMode.Write);
|
||||
dataStream.CopyTo(cryptoStream);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
}
|
||||
|
||||
encryptedDataStream.Position = 0;
|
||||
|
||||
return encryptedDataStream;
|
||||
}
|
||||
|
||||
private static Stream DecryptDataStream(SymmetricAlgorithm sharedKey, Stream encryptedDataStream)
|
||||
{
|
||||
var decryptedDataStream = new MemoryStream();
|
||||
|
||||
using (var decryptor = sharedKey.CreateDecryptor())
|
||||
{
|
||||
var cryptoStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read);
|
||||
cryptoStream.CopyTo(decryptedDataStream);
|
||||
decryptedDataStream.Flush();
|
||||
}
|
||||
|
||||
decryptedDataStream.Position = 0;
|
||||
|
||||
return decryptedDataStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using System.Security;
|
||||
|
||||
using GostCryptography.Gost_R3410;
|
||||
|
||||
using NUnit.Framework;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
using GostCryptography.Base;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3410
|
||||
{
|
||||
[TestFixture(Description = "Проверка возможности установки пароля для контейнера ключей")]
|
||||
public class SetContainerPasswordTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2001_Certificates))]
|
||||
public void ShouldSetContainerPassword_R3410_2001(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var data = GetSomeData();
|
||||
var certificate = testCase.Certificate;
|
||||
var securePassword = CreateSecureString(TestConfig.ContainerPassword);
|
||||
|
||||
// When
|
||||
|
||||
var privateKeyInfo = certificate.GetPrivateKeyInfo();
|
||||
var privateKey = new Gost_R3410_2001_AsymmetricAlgorithm(privateKeyInfo);
|
||||
privateKey.SetContainerPassword(securePassword);
|
||||
|
||||
var signature = CreateSignature(privateKey, data);
|
||||
var isValidSignature = VerifySignature(privateKey, data, signature);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignature);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2012_256_Certificates))]
|
||||
public void ShouldSetContainerPassword_R3410_2012_256(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var data = GetSomeData();
|
||||
var certificate = testCase.Certificate;
|
||||
var securePassword = CreateSecureString(TestConfig.ContainerPassword);
|
||||
|
||||
// When
|
||||
|
||||
var privateKeyInfo = certificate.GetPrivateKeyInfo();
|
||||
var privateKey = new Gost_R3410_2012_256_AsymmetricAlgorithm(privateKeyInfo);
|
||||
privateKey.SetContainerPassword(securePassword);
|
||||
|
||||
var signature = CreateSignature(privateKey, data);
|
||||
var isValidSignature = VerifySignature(privateKey, data, signature);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignature);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2012_512_Certificates))]
|
||||
public void ShouldSetContainerPassword_R3410_2012_512(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var data = GetSomeData();
|
||||
var certificate = testCase.Certificate;
|
||||
var securePassword = CreateSecureString(TestConfig.ContainerPassword);
|
||||
|
||||
// When
|
||||
|
||||
var privateKeyInfo = certificate.GetPrivateKeyInfo();
|
||||
var privateKey = new Gost_R3410_2012_512_AsymmetricAlgorithm(privateKeyInfo);
|
||||
privateKey.SetContainerPassword(securePassword);
|
||||
|
||||
var signature = CreateSignature(privateKey, data);
|
||||
var isValidSignature = VerifySignature(privateKey, data, signature);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignature);
|
||||
}
|
||||
|
||||
|
||||
private static byte[] CreateSignature(GostAsymmetricAlgorithm privateKey, byte[] data)
|
||||
{
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = privateKey.CreateHashAlgorithm())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(data);
|
||||
}
|
||||
|
||||
return privateKey.CreateSignature(hash);
|
||||
}
|
||||
|
||||
private static bool VerifySignature(GostAsymmetricAlgorithm publicKey, byte[] data, byte[] signature)
|
||||
{
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = publicKey.CreateHashAlgorithm())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(data);
|
||||
}
|
||||
|
||||
return publicKey.VerifySignature(hash, signature);
|
||||
}
|
||||
|
||||
private static SecureString CreateSecureString(string value)
|
||||
{
|
||||
var result = new SecureString();
|
||||
|
||||
foreach (var c in value)
|
||||
{
|
||||
result.AppendChar(c);
|
||||
}
|
||||
|
||||
result.MakeReadOnly();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] GetSomeData()
|
||||
{
|
||||
var random = new Random();
|
||||
var data = new byte[1024];
|
||||
random.NextBytes(data);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление HMAC на базе алгоритма хэширования ГОСТ Р 34.11-2012/256 и общего симметричного ключа ГОСТ 28147-89.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест выполняет подпись и проверку подписи потока байт с использованием HMAC.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление HMAC на базе алгоритма хэширования ГОСТ Р 34.11-2012/256 и общего симметричного ключа ГОСТ 28147-89")]
|
||||
public class Gost_R3411_2012_256_HMACTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeHMAC(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
var hmacDataStream = CreateHmacDataStream(sharedKey, dataStream);
|
||||
var isValidHmacDataStream = VerifyHmacDataStream(sharedKey, hmacDataStream);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidHmacDataStream);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to HMAC..."));
|
||||
}
|
||||
|
||||
private static Stream CreateHmacDataStream(GostSymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
// Создание объекта для вычисления HMAC
|
||||
using (var hmac = new Gost_R3411_2012_256_HMAC(sharedKey))
|
||||
{
|
||||
// Вычисление HMAC для потока данных
|
||||
var hmacValue = hmac.ComputeHash(dataStream);
|
||||
|
||||
// Запись HMAC в начало выходного потока данных
|
||||
var hmacDataStream = new MemoryStream();
|
||||
hmacDataStream.Write(hmacValue, 0, hmacValue.Length);
|
||||
|
||||
// Копирование исходного потока данных в выходной поток
|
||||
dataStream.Position = 0;
|
||||
dataStream.CopyTo(hmacDataStream);
|
||||
|
||||
hmacDataStream.Position = 0;
|
||||
|
||||
return hmacDataStream;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool VerifyHmacDataStream(GostSymmetricAlgorithm sharedKey, Stream hmacDataStream)
|
||||
{
|
||||
// Создание объекта для вычисления HMAC
|
||||
using (var hmac = new Gost_R3411_2012_256_HMAC(sharedKey))
|
||||
{
|
||||
// Считывание HMAC из потока данных
|
||||
var hmacValue = new byte[hmac.HashSize / 8];
|
||||
hmacDataStream.Read(hmacValue, 0, hmacValue.Length);
|
||||
|
||||
// Вычисление реального значения HMAC для потока данных
|
||||
var expectedHmacValue = hmac.ComputeHash(hmacDataStream);
|
||||
|
||||
// Сравнение исходного HMAC с ожидаемым
|
||||
return hmacValue.SequenceEqual(expectedHmacValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление хэша в соответствии с ГОСТ Р 34.11-2012/256.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, вычисляет хэш в соответствии с ГОСТ Р 34.11-2012/256 и проверяет его корректность.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление хэша в соответствии с ГОСТ Р 34.11-2012/256")]
|
||||
public class Gost_R3411_2012_256_HashAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeHash(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
|
||||
byte[] hashValue;
|
||||
|
||||
using (var hash = new Gost_R3411_2012_256_HashAlgorithm(providerType))
|
||||
{
|
||||
hashValue = hash.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(hashValue);
|
||||
Assert.AreEqual(256, 8 * hashValue.Length);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to hash..."));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Использование PRF на базе алгоритма хэширования ГОСТ Р 34.11-2012/256.
|
||||
/// </summary>
|
||||
[TestFixture(Description = "Использование PRF на базе алгоритма хэширования ГОСТ Р 34.11-2012/256")]
|
||||
public class Gost_R3411_2012_256_PRFTest
|
||||
{
|
||||
private static readonly byte[] Label = { 1, 2, 3, 4, 5 };
|
||||
private static readonly byte[] Seed = { 6, 7, 8, 9, 0 };
|
||||
private static readonly byte[] TestData = Encoding.UTF8.GetBytes("Some data to encrypt...");
|
||||
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldDeriveBytes(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
|
||||
byte[] randomBytes1;
|
||||
byte[] randomBytes2;
|
||||
byte[] randomBytes3;
|
||||
|
||||
using (var prf = new Gost_R3411_2012_256_PRF(initKey, Label, Seed))
|
||||
{
|
||||
randomBytes1 = prf.DeriveBytes();
|
||||
randomBytes2 = prf.DeriveBytes();
|
||||
randomBytes3 = prf.DeriveBytes();
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(randomBytes1);
|
||||
Assert.IsNotNull(randomBytes2);
|
||||
Assert.IsNotNull(randomBytes3);
|
||||
Assert.AreEqual(256, 8 * randomBytes1.Length);
|
||||
Assert.AreEqual(256, 8 * randomBytes2.Length);
|
||||
Assert.AreEqual(256, 8 * randomBytes3.Length);
|
||||
CollectionAssert.AreNotEqual(randomBytes1, randomBytes2);
|
||||
CollectionAssert.AreNotEqual(randomBytes1, randomBytes3);
|
||||
CollectionAssert.AreNotEqual(randomBytes2, randomBytes3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldDeriveKey(ProviderType providerType)
|
||||
{
|
||||
// TODO: VipNet does not support this feature - https://infotecs.ru/forum/topic/10142-oshibka-pri-sozdanii-klyucha-shifrovaniya-na-osnove-dannyih-polzovatelya-cryptderivekey/
|
||||
if (providerType.IsVipNet())
|
||||
{
|
||||
Assert.Ignore("VipNet does not support this feature");
|
||||
}
|
||||
|
||||
// Given
|
||||
var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
|
||||
GostSymmetricAlgorithm randomKey1;
|
||||
GostSymmetricAlgorithm randomKey2;
|
||||
GostSymmetricAlgorithm randomKey3;
|
||||
|
||||
using (var prf = new Gost_R3411_2012_256_PRF(initKey, Label, Seed))
|
||||
{
|
||||
randomKey1 = prf.DeriveKey();
|
||||
randomKey2 = prf.DeriveKey();
|
||||
randomKey3 = prf.DeriveKey();
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(randomKey1);
|
||||
Assert.IsNotNull(randomKey2);
|
||||
Assert.IsNotNull(randomKey3);
|
||||
AssertKeyIsValid(randomKey1);
|
||||
AssertKeyIsValid(randomKey2);
|
||||
AssertKeyIsValid(randomKey3);
|
||||
AssertKeysAreNotEqual(randomKey1, randomKey2);
|
||||
AssertKeysAreNotEqual(randomKey1, randomKey3);
|
||||
AssertKeysAreNotEqual(randomKey2, randomKey3);
|
||||
}
|
||||
|
||||
|
||||
public static void AssertKeyIsValid(GostSymmetricAlgorithm key)
|
||||
{
|
||||
var encryptedData = EncryptData(key, TestData);
|
||||
var decryptedData = DecryptData(key, encryptedData);
|
||||
CollectionAssert.AreEqual(TestData, decryptedData);
|
||||
}
|
||||
|
||||
public static void AssertKeysAreNotEqual(GostSymmetricAlgorithm key1, GostSymmetricAlgorithm key2)
|
||||
{
|
||||
var encryptedData1 = EncryptData(key1, TestData);
|
||||
var encryptedData2 = EncryptData(key2, TestData);
|
||||
CollectionAssert.AreNotEqual(encryptedData1, encryptedData2);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] EncryptData(GostSymmetricAlgorithm key, byte[] data)
|
||||
{
|
||||
var transform = key.CreateEncryptor();
|
||||
return transform.TransformFinalBlock(data, 0, data.Length);
|
||||
}
|
||||
|
||||
public static byte[] DecryptData(GostSymmetricAlgorithm key, byte[] data)
|
||||
{
|
||||
var transform = key.CreateDecryptor();
|
||||
return transform.TransformFinalBlock(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление HMAC на базе алгоритма хэширования ГОСТ Р 34.11-2012/512 и общего симметричного ключа ГОСТ 28147-89.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест выполняет подпись и проверку подписи потока байт с использованием HMAC.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление HMAC на базе алгоритма хэширования ГОСТ Р 34.11-2012/512 и общего симметричного ключа ГОСТ 28147-89")]
|
||||
public class Gost_R3411_2012_512_HMACTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeHMAC(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
var hmacDataStream = CreateHmacDataStream(sharedKey, dataStream);
|
||||
var isValidHmacDataStream = VerifyHmacDataStream(sharedKey, hmacDataStream);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidHmacDataStream);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to HMAC..."));
|
||||
}
|
||||
|
||||
private static Stream CreateHmacDataStream(GostSymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
// Создание объекта для вычисления HMAC
|
||||
using (var hmac = new Gost_R3411_2012_512_HMAC(sharedKey))
|
||||
{
|
||||
// Вычисление HMAC для потока данных
|
||||
var hmacValue = hmac.ComputeHash(dataStream);
|
||||
|
||||
// Запись HMAC в начало выходного потока данных
|
||||
var hmacDataStream = new MemoryStream();
|
||||
hmacDataStream.Write(hmacValue, 0, hmacValue.Length);
|
||||
|
||||
// Копирование исходного потока данных в выходной поток
|
||||
dataStream.Position = 0;
|
||||
dataStream.CopyTo(hmacDataStream);
|
||||
|
||||
hmacDataStream.Position = 0;
|
||||
|
||||
return hmacDataStream;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool VerifyHmacDataStream(GostSymmetricAlgorithm sharedKey, Stream hmacDataStream)
|
||||
{
|
||||
// Создание объекта для вычисления HMAC
|
||||
using (var hmac = new Gost_R3411_2012_512_HMAC(sharedKey))
|
||||
{
|
||||
// Считывание HMAC из потока данных
|
||||
var hmacValue = new byte[hmac.HashSize / 8];
|
||||
hmacDataStream.Read(hmacValue, 0, hmacValue.Length);
|
||||
|
||||
// Вычисление реального значения HMAC для потока данных
|
||||
var expectedHmacValue = hmac.ComputeHash(hmacDataStream);
|
||||
|
||||
// Сравнение исходного HMAC с ожидаемым
|
||||
return hmacValue.SequenceEqual(expectedHmacValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление хэша в соответствии с ГОСТ Р 34.11-2012/512.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, вычисляет хэш в соответствии с ГОСТ Р 34.11-2012/512 и проверяет его корректность.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление хэша в соответствии с ГОСТ Р 34.11-2012/512")]
|
||||
public class Gost_R3411_2012_512_HashAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeHash(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
|
||||
byte[] hashValue;
|
||||
|
||||
using (var hash = new Gost_R3411_2012_512_HashAlgorithm(providerType))
|
||||
{
|
||||
hashValue = hash.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(hashValue);
|
||||
Assert.AreEqual(512, 8 * hashValue.Length);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to hash..."));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Использование PRF на базе алгоритма хэширования ГОСТ Р 34.11-2012/512.
|
||||
/// </summary>
|
||||
[TestFixture(Description = "Использование PRF на базе алгоритма хэширования ГОСТ Р 34.11-2012/512")]
|
||||
public class Gost_R3411_2012_512_PRFTest
|
||||
{
|
||||
private static readonly byte[] Label = { 1, 2, 3, 4, 5 };
|
||||
private static readonly byte[] Seed = { 6, 7, 8, 9, 0 };
|
||||
private static readonly byte[] TestData = Encoding.UTF8.GetBytes("Some data to encrypt...");
|
||||
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldDeriveBytes(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
|
||||
byte[] randomBytes1;
|
||||
byte[] randomBytes2;
|
||||
byte[] randomBytes3;
|
||||
|
||||
using (var prf = new Gost_R3411_2012_512_PRF(initKey, Label, Seed))
|
||||
{
|
||||
randomBytes1 = prf.DeriveBytes();
|
||||
randomBytes2 = prf.DeriveBytes();
|
||||
randomBytes3 = prf.DeriveBytes();
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(randomBytes1);
|
||||
Assert.IsNotNull(randomBytes2);
|
||||
Assert.IsNotNull(randomBytes3);
|
||||
Assert.AreEqual(512, 8 * randomBytes1.Length);
|
||||
Assert.AreEqual(512, 8 * randomBytes2.Length);
|
||||
Assert.AreEqual(512, 8 * randomBytes3.Length);
|
||||
CollectionAssert.AreNotEqual(randomBytes1, randomBytes2);
|
||||
CollectionAssert.AreNotEqual(randomBytes1, randomBytes3);
|
||||
CollectionAssert.AreNotEqual(randomBytes2, randomBytes3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldDeriveKey(ProviderType providerType)
|
||||
{
|
||||
// TODO: VipNet does not support this feature - https://infotecs.ru/forum/topic/10142-oshibka-pri-sozdanii-klyucha-shifrovaniya-na-osnove-dannyih-polzovatelya-cryptderivekey/
|
||||
if (providerType.IsVipNet())
|
||||
{
|
||||
Assert.Ignore("VipNet does not support this feature");
|
||||
}
|
||||
|
||||
// Given
|
||||
var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
|
||||
GostSymmetricAlgorithm randomKey1;
|
||||
GostSymmetricAlgorithm randomKey2;
|
||||
GostSymmetricAlgorithm randomKey3;
|
||||
|
||||
using (var prf = new Gost_R3411_2012_512_PRF(initKey, Label, Seed))
|
||||
{
|
||||
randomKey1 = prf.DeriveKey();
|
||||
randomKey2 = prf.DeriveKey();
|
||||
randomKey3 = prf.DeriveKey();
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(randomKey1);
|
||||
Assert.IsNotNull(randomKey2);
|
||||
Assert.IsNotNull(randomKey3);
|
||||
AssertKeyIsValid(randomKey1);
|
||||
AssertKeyIsValid(randomKey2);
|
||||
AssertKeyIsValid(randomKey3);
|
||||
AssertKeysAreNotEqual(randomKey1, randomKey2);
|
||||
AssertKeysAreNotEqual(randomKey1, randomKey3);
|
||||
AssertKeysAreNotEqual(randomKey2, randomKey3);
|
||||
}
|
||||
|
||||
|
||||
public static void AssertKeyIsValid(GostSymmetricAlgorithm key)
|
||||
{
|
||||
var encryptedData = EncryptData(key, TestData);
|
||||
var decryptedData = DecryptData(key, encryptedData);
|
||||
CollectionAssert.AreEqual(TestData, decryptedData);
|
||||
}
|
||||
|
||||
public static void AssertKeysAreNotEqual(GostSymmetricAlgorithm key1, GostSymmetricAlgorithm key2)
|
||||
{
|
||||
var encryptedData1 = EncryptData(key1, TestData);
|
||||
var encryptedData2 = EncryptData(key2, TestData);
|
||||
CollectionAssert.AreNotEqual(encryptedData1, encryptedData2);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] EncryptData(GostSymmetricAlgorithm key, byte[] data)
|
||||
{
|
||||
var transform = key.CreateEncryptor();
|
||||
return transform.TransformFinalBlock(data, 0, data.Length);
|
||||
}
|
||||
|
||||
public static byte[] DecryptData(GostSymmetricAlgorithm key, byte[] data)
|
||||
{
|
||||
var transform = key.CreateDecryptor();
|
||||
return transform.TransformFinalBlock(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление HMAC на базе алгоритма хэширования ГОСТ Р 34.11-94 и общего симметричного ключа ГОСТ 28147-89.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест выполняет подпись и проверку подписи потока байт с использованием HMAC.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление HMAC на базе алгоритма хэширования ГОСТ Р 34.11-94 и общего симметричного ключа ГОСТ 28147-89")]
|
||||
public class Gost_R3411_94_HMACTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeHMAC(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
var hmacDataStream = CreateHmacDataStream(sharedKey, dataStream);
|
||||
var isValidHmacDataStream = VerifyHmacDataStream(sharedKey, hmacDataStream);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidHmacDataStream);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to HMAC..."));
|
||||
}
|
||||
|
||||
private static Stream CreateHmacDataStream(GostSymmetricAlgorithm sharedKey, Stream dataStream)
|
||||
{
|
||||
// Создание объекта для вычисления HMAC
|
||||
using (var hmac = new Gost_R3411_94_HMAC(sharedKey))
|
||||
{
|
||||
// Вычисление HMAC для потока данных
|
||||
var hmacValue = hmac.ComputeHash(dataStream);
|
||||
|
||||
// Запись HMAC в начало выходного потока данных
|
||||
var hmacDataStream = new MemoryStream();
|
||||
hmacDataStream.Write(hmacValue, 0, hmacValue.Length);
|
||||
|
||||
// Копирование исходного потока данных в выходной поток
|
||||
dataStream.Position = 0;
|
||||
dataStream.CopyTo(hmacDataStream);
|
||||
|
||||
hmacDataStream.Position = 0;
|
||||
|
||||
return hmacDataStream;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool VerifyHmacDataStream(GostSymmetricAlgorithm sharedKey, Stream hmacDataStream)
|
||||
{
|
||||
// Создание объекта для вычисления HMAC
|
||||
using (var hmac = new Gost_R3411_94_HMAC(sharedKey))
|
||||
{
|
||||
// Считывание HMAC из потока данных
|
||||
var hmacValue = new byte[hmac.HashSize / 8];
|
||||
hmacDataStream.Read(hmacValue, 0, hmacValue.Length);
|
||||
|
||||
// Вычисление реального значения HMAC для потока данных
|
||||
var expectedHmacValue = hmac.ComputeHash(hmacDataStream);
|
||||
|
||||
// Сравнение исходного HMAC с ожидаемым
|
||||
return hmacValue.SequenceEqual(expectedHmacValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Вычисление хэша в соответствии с ГОСТ Р 34.11-94.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, вычисляет хэш в соответствии с ГОСТ Р 34.11-94 и проверяет его корректность.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Вычисление хэша в соответствии с ГОСТ Р 34.11-94")]
|
||||
public class Gost_R3411_94_HashAlgorithmTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldComputeHash(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
|
||||
byte[] hashValue;
|
||||
|
||||
using (var hash = new Gost_R3411_94_HashAlgorithm(providerType))
|
||||
{
|
||||
hashValue = hash.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(hashValue);
|
||||
Assert.AreEqual(256, 8 * hashValue.Length);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to hash..."));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Gost_R3411;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Gost_R3411
|
||||
{
|
||||
/// <summary>
|
||||
/// Использование PRF на базе алгоритма хэширования ГОСТ Р 34.11-94.
|
||||
/// </summary>
|
||||
[TestFixture(Description = "Использование PRF на базе алгоритма хэширования ГОСТ Р 34.11-94")]
|
||||
public class Gost_R3411_94_PRFTest
|
||||
{
|
||||
private static readonly byte[] Label = { 1, 2, 3, 4, 5 };
|
||||
private static readonly byte[] Seed = { 6, 7, 8, 9, 0 };
|
||||
private static readonly byte[] TestData = Encoding.UTF8.GetBytes("Some data to encrypt...");
|
||||
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldDeriveBytes(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
|
||||
byte[] randomBytes1;
|
||||
byte[] randomBytes2;
|
||||
byte[] randomBytes3;
|
||||
|
||||
using (var prf = new Gost_R3411_94_PRF(initKey, Label, Seed))
|
||||
{
|
||||
randomBytes1 = prf.DeriveBytes();
|
||||
randomBytes2 = prf.DeriveBytes();
|
||||
randomBytes3 = prf.DeriveBytes();
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(randomBytes1);
|
||||
Assert.IsNotNull(randomBytes2);
|
||||
Assert.IsNotNull(randomBytes3);
|
||||
Assert.AreEqual(256, 8 * randomBytes1.Length);
|
||||
Assert.AreEqual(256, 8 * randomBytes2.Length);
|
||||
Assert.AreEqual(256, 8 * randomBytes3.Length);
|
||||
CollectionAssert.AreNotEqual(randomBytes1, randomBytes2);
|
||||
CollectionAssert.AreNotEqual(randomBytes1, randomBytes3);
|
||||
CollectionAssert.AreNotEqual(randomBytes2, randomBytes3);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldDeriveKey(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var initKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
|
||||
// When
|
||||
|
||||
GostSymmetricAlgorithm randomKey1;
|
||||
GostSymmetricAlgorithm randomKey2;
|
||||
GostSymmetricAlgorithm randomKey3;
|
||||
|
||||
using (var prf = new Gost_R3411_94_PRF(initKey, Label, Seed))
|
||||
{
|
||||
randomKey1 = prf.DeriveKey();
|
||||
randomKey2 = prf.DeriveKey();
|
||||
randomKey3 = prf.DeriveKey();
|
||||
}
|
||||
|
||||
// Then
|
||||
Assert.IsNotNull(randomKey1);
|
||||
Assert.IsNotNull(randomKey2);
|
||||
Assert.IsNotNull(randomKey3);
|
||||
AssertKeyIsValid(randomKey1);
|
||||
AssertKeyIsValid(randomKey2);
|
||||
AssertKeyIsValid(randomKey3);
|
||||
AssertKeysAreNotEqual(randomKey1, randomKey2);
|
||||
AssertKeysAreNotEqual(randomKey1, randomKey3);
|
||||
AssertKeysAreNotEqual(randomKey2, randomKey3);
|
||||
}
|
||||
|
||||
|
||||
public static void AssertKeyIsValid(GostSymmetricAlgorithm key)
|
||||
{
|
||||
var encryptedData = EncryptData(key, TestData);
|
||||
var decryptedData = DecryptData(key, encryptedData);
|
||||
CollectionAssert.AreEqual(TestData, decryptedData);
|
||||
}
|
||||
|
||||
public static void AssertKeysAreNotEqual(GostSymmetricAlgorithm key1, GostSymmetricAlgorithm key2)
|
||||
{
|
||||
var encryptedData1 = EncryptData(key1, TestData);
|
||||
var encryptedData2 = EncryptData(key2, TestData);
|
||||
CollectionAssert.AreNotEqual(encryptedData1, encryptedData2);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] EncryptData(GostSymmetricAlgorithm key, byte[] data)
|
||||
{
|
||||
var transform = key.CreateEncryptor();
|
||||
return transform.TransformFinalBlock(data, 0, data.Length);
|
||||
}
|
||||
|
||||
public static byte[] DecryptData(GostSymmetricAlgorithm key, byte[] data)
|
||||
{
|
||||
var transform = key.CreateDecryptor();
|
||||
return transform.TransformFinalBlock(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography.Pkcs;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Pkcs
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация сообщения CMS/PKCS#7.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает сообщение, шифрует его в формате CMS/PKCS#7, а затем дешифрует зашифрованное сообщение.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация сообщения CMS/PKCS#7")]
|
||||
public class EnvelopedCmsEncryptTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptAndDecrypt(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var message = CreateMessage();
|
||||
|
||||
// When
|
||||
var encryptedMessage = EncryptMessage(certificate, message);
|
||||
var decryptedMessage = DecryptMessage(encryptedMessage);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(message.SequenceEqual(decryptedMessage));
|
||||
}
|
||||
|
||||
private static byte[] CreateMessage()
|
||||
{
|
||||
// Некоторое сообщение для подписи
|
||||
|
||||
return Encoding.UTF8.GetBytes("Some message to sign...");
|
||||
}
|
||||
|
||||
private static byte[] EncryptMessage(X509Certificate2 certificate, byte[] message)
|
||||
{
|
||||
// Создание объекта для шифрования сообщения
|
||||
var envelopedCms = new EnvelopedCms(new ContentInfo(message));
|
||||
|
||||
// Создание объект с информацией о получателе
|
||||
var recipient = new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, certificate);
|
||||
|
||||
// Шифрование сообщения CMS/PKCS#7
|
||||
envelopedCms.Encrypt(recipient);
|
||||
|
||||
// Создание сообщения CMS/PKCS#7
|
||||
return envelopedCms.Encode();
|
||||
}
|
||||
|
||||
private static byte[] DecryptMessage(byte[] encryptedMessage)
|
||||
{
|
||||
// Создание объекта для расшифровки сообщения
|
||||
var envelopedCms = new EnvelopedCms();
|
||||
|
||||
// Чтение сообщения CMS/PKCS#7
|
||||
envelopedCms.Decode(encryptedMessage);
|
||||
|
||||
// Расшифровка сообщения CMS/PKCS#7
|
||||
envelopedCms.Decrypt(envelopedCms.RecipientInfos[0]);
|
||||
|
||||
return envelopedCms.ContentInfo.Content;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Security.Cryptography.Pkcs;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Pkcs;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Pkcs
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка отсоединенной подписи сообщения CMS/PKCS#7.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает сообщение, формирует отсоединенную подпись сообщения в формате CMS/PKCS#7,
|
||||
/// а затем проверяет подпись полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка отсоединенной подписи сообщения CMS/PKCS#7")]
|
||||
public class SignedCmsDetachedSignTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSign(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var message = CreateMessage();
|
||||
|
||||
// When
|
||||
var detachedSignature = SignMessage(certificate, message);
|
||||
var isValidDetachedSignature = VerifyMessage(message, detachedSignature);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidDetachedSignature);
|
||||
}
|
||||
|
||||
private static byte[] CreateMessage()
|
||||
{
|
||||
// Некоторое сообщение для подписи
|
||||
|
||||
return Encoding.UTF8.GetBytes("Some message to sign...");
|
||||
}
|
||||
|
||||
private static byte[] SignMessage(X509Certificate2 certificate, byte[] message)
|
||||
{
|
||||
// Создание объекта для подписи сообщения
|
||||
var signedCms = new GostSignedCms(new ContentInfo(message), true);
|
||||
|
||||
// Создание объект с информацией о подписчике
|
||||
var signer = new CmsSigner(certificate);
|
||||
|
||||
// Включение информации только о конечном сертификате (только для теста)
|
||||
signer.IncludeOption = X509IncludeOption.EndCertOnly;
|
||||
|
||||
// Создание подписи для сообщения CMS/PKCS#7
|
||||
signedCms.ComputeSignature(signer);
|
||||
|
||||
// Создание подписи CMS/PKCS#7
|
||||
return signedCms.Encode();
|
||||
}
|
||||
|
||||
private static bool VerifyMessage(byte[] message, byte[] detachedSignature)
|
||||
{
|
||||
// Создание объекта для проверки подписи сообщения
|
||||
var signedCms = new GostSignedCms(new ContentInfo(message), true);
|
||||
|
||||
// Чтение подписи CMS/PKCS#7
|
||||
signedCms.Decode(detachedSignature);
|
||||
|
||||
try
|
||||
{
|
||||
// Проверка подписи CMS/PKCS#7
|
||||
signedCms.CheckSignature(true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System.Security.Cryptography.Pkcs;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Pkcs;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Pkcs
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи сообщения CMS/PKCS#7.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает сообщение, формирует подписанное сообщение в формате CMS/PKCS#7,
|
||||
/// исключая информацию о сертификате подписчика с целью минимизации размера сообщения,
|
||||
/// а затем проверяет подпись полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи сообщения CMS/PKCS#7")]
|
||||
public class SignedCmsSignAndExcludeCertificates
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSign(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var message = CreateMessage();
|
||||
|
||||
// When
|
||||
var signedMessage = SignMessage(certificate, message);
|
||||
var isValidSignedMessage = VerifyMessage(certificate, signedMessage);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignedMessage);
|
||||
}
|
||||
|
||||
private static byte[] CreateMessage()
|
||||
{
|
||||
// Некоторое сообщение для подписи
|
||||
|
||||
return Encoding.UTF8.GetBytes("Some message to sign...");
|
||||
}
|
||||
|
||||
private static byte[] SignMessage(X509Certificate2 certificate, byte[] message)
|
||||
{
|
||||
// Создание объекта для подписи сообщения
|
||||
var signedCms = new GostSignedCms(new ContentInfo(message));
|
||||
|
||||
// Создание объект с информацией о подписчике
|
||||
var signer = new CmsSigner(certificate);
|
||||
|
||||
// Включение информации только о конечном сертификате (только для теста)
|
||||
signer.IncludeOption = X509IncludeOption.EndCertOnly;
|
||||
|
||||
// Создание подписи для сообщения CMS/PKCS#7
|
||||
signedCms.ComputeSignature(signer);
|
||||
|
||||
// Исключение сертификатов для уменьшения размера сообщения
|
||||
signedCms.RemoveCertificates();
|
||||
|
||||
// Создание сообщения CMS/PKCS#7
|
||||
return signedCms.Encode();
|
||||
}
|
||||
|
||||
private static bool VerifyMessage(X509Certificate2 certificate, byte[] signedMessage)
|
||||
{
|
||||
// Создание объекта для проверки подписи сообщения
|
||||
var signedCms = new GostSignedCms();
|
||||
|
||||
// Чтение сообщения CMS/PKCS#7
|
||||
signedCms.Decode(signedMessage);
|
||||
|
||||
// Список сертификатов подписчика
|
||||
var signerCerts = new X509Certificate2Collection(certificate);
|
||||
|
||||
try
|
||||
{
|
||||
// Проверка подписи сообщения CMS/PKCS#7
|
||||
signedCms.CheckSignature(signerCerts, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Security.Cryptography.Pkcs;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Pkcs;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Pkcs
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи сообщения CMS/PKCS#7.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает сообщение, формирует подписанное сообщение в формате CMS/PKCS#7,
|
||||
/// а затем проверяет подпись полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи сообщения CMS/PKCS#7")]
|
||||
public class SignedCmsSignTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSign(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var message = CreateMessage();
|
||||
|
||||
// When
|
||||
var signedMessage = SignMessage(certificate, message);
|
||||
var isValidSignedMessage = VerifyMessage(signedMessage);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignedMessage);
|
||||
}
|
||||
|
||||
private static byte[] CreateMessage()
|
||||
{
|
||||
// Некоторое сообщение для подписи
|
||||
|
||||
return Encoding.UTF8.GetBytes("Some message to sign...");
|
||||
}
|
||||
|
||||
private static byte[] SignMessage(X509Certificate2 certificate, byte[] message)
|
||||
{
|
||||
// Создание объекта для подписи сообщения
|
||||
var signedCms = new GostSignedCms(new ContentInfo(message));
|
||||
|
||||
// Создание объект с информацией о подписчике
|
||||
var signer = new CmsSigner(certificate);
|
||||
|
||||
// Включение информации только о конечном сертификате (только для теста)
|
||||
signer.IncludeOption = X509IncludeOption.EndCertOnly;
|
||||
|
||||
// Создание подписи для сообщения CMS/PKCS#7
|
||||
signedCms.ComputeSignature(signer);
|
||||
|
||||
// Создание сообщения CMS/PKCS#7
|
||||
return signedCms.Encode();
|
||||
}
|
||||
|
||||
private static bool VerifyMessage(byte[] signedMessage)
|
||||
{
|
||||
// Создание объекта для проверки подписи сообщения
|
||||
var signedCms = new GostSignedCms();
|
||||
|
||||
// Чтение сообщения CMS/PKCS#7
|
||||
signedCms.Decode(signedMessage);
|
||||
|
||||
try
|
||||
{
|
||||
// Проверка подписи сообщения CMS/PKCS#7
|
||||
signedCms.CheckSignature(true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
118
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/Properties/Resources.Designer.cs
generated
vendored
Normal file
118
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/Properties/Resources.Designer.cs
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace GostCryptography.Tests.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GostCryptography.Tests.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?>
|
||||
///<MyXml>
|
||||
/// <SomeElement Encrypt="false">
|
||||
/// Here is public data.
|
||||
/// </SomeElement>
|
||||
/// <SomeElement Encrypt="true">
|
||||
/// Here is private data.
|
||||
/// </SomeElement>
|
||||
/// <SomeElement Encrypt="true">
|
||||
/// Here is private data.
|
||||
/// </SomeElement>
|
||||
/// <SomeElement Encrypt="true">
|
||||
/// Here is private data.
|
||||
/// </SomeElement>
|
||||
///</MyXml>.
|
||||
/// </summary>
|
||||
internal static string EncryptedXmlExample {
|
||||
get {
|
||||
return ResourceManager.GetString("EncryptedXmlExample", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?>
|
||||
///<MyXml>
|
||||
/// <SomeElement Id="Id1">
|
||||
/// Here is some data to sign.
|
||||
/// </SomeElement>
|
||||
///</MyXml>.
|
||||
/// </summary>
|
||||
internal static string SignedXmlExample {
|
||||
get {
|
||||
return ResourceManager.GetString("SignedXmlExample", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to <?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
///<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
/// xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
|
||||
/// xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
|
||||
/// >
|
||||
/// <S:Header>
|
||||
/// <wsse:Security S:actor="http://smev.gosuslugi.ru/actors/smev">
|
||||
/// <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
/// <ds:KeyInfo>
|
||||
/// <wsse:SecurityTokenR [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string SmevExample {
|
||||
get {
|
||||
return ResourceManager.GetString("SmevExample", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
130
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/Properties/Resources.resx
vendored
Normal file
130
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/Properties/Resources.resx
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="EncryptedXmlExample" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\data\encryptedxmlexample.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
<data name="SignedXmlExample" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\data\signedxmlexample.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
<data name="SmevExample" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\data\smevexample.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,74 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи потока байт с помощью сертификата.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, вычисляет цифровую подпись потока байт с использованием закрытого ключа сертификата,
|
||||
/// а затем с помощью открытого ключа сертификата проверяет полученную подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи потока байт с помощью сертификата")]
|
||||
public class SignDataStreamCertificateTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSignDataStream(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var privateKey = (GostAsymmetricAlgorithm)certificate.GetPrivateKeyAlgorithm();
|
||||
var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
|
||||
dataStream.Seek(0, SeekOrigin.Begin);
|
||||
var signature = CreateSignature(privateKey, dataStream);
|
||||
|
||||
dataStream.Seek(0, SeekOrigin.Begin);
|
||||
var isValidSignature = VerifySignature(publicKey, dataStream, signature);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignature);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт для подписи
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to sign..."));
|
||||
}
|
||||
|
||||
private static byte[] CreateSignature(GostAsymmetricAlgorithm privateKey, Stream dataStream)
|
||||
{
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = privateKey.CreateHashAlgorithm())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
return privateKey.CreateSignature(hash);
|
||||
}
|
||||
|
||||
private static bool VerifySignature(GostAsymmetricAlgorithm publicKey, Stream dataStream, byte[] signature)
|
||||
{
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = publicKey.CreateHashAlgorithm())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
return publicKey.VerifySignature(hash, signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Config;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи потока байт с помощью сертификата и информации об алгоритме цифровой подписи
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, вычисляет цифровую подпись потока байт с использованием закрытого ключа сертификата,
|
||||
/// а затем с помощью открытого ключа сертификата проверяет полученную подпись. Для вычисления цифровой подписи
|
||||
/// и ее проверки используется информация об алгоритме цифровой подписи <see cref="SignatureDescription"/>,
|
||||
/// получаемая с помощью метода <see cref="GostCryptoConfig.CreateFromName"/>.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи потока байт с помощью сертификата и информации об алгоритме цифровой подписи")]
|
||||
public class SignDataStreamSignatureDescriptionTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSignDataStream(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var privateKey = (GostAsymmetricAlgorithm)certificate.GetPrivateKeyAlgorithm();
|
||||
var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
|
||||
dataStream.Seek(0, SeekOrigin.Begin);
|
||||
var signature = CreateSignature(privateKey, dataStream);
|
||||
|
||||
dataStream.Seek(0, SeekOrigin.Begin);
|
||||
var isValidSignature = VerifySignature(publicKey, dataStream, signature);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignature);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт для подписи
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to sign..."));
|
||||
}
|
||||
|
||||
private static byte[] CreateSignature(AsymmetricAlgorithm privateKey, Stream dataStream)
|
||||
{
|
||||
var signatureDescription = (SignatureDescription)GostCryptoConfig.CreateFromName(privateKey.SignatureAlgorithm);
|
||||
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = signatureDescription.CreateDigest())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
var formatter = signatureDescription.CreateFormatter(privateKey);
|
||||
formatter.SetHashAlgorithm(signatureDescription.DigestAlgorithm);
|
||||
|
||||
return formatter.CreateSignature(hash);
|
||||
}
|
||||
|
||||
private static bool VerifySignature(AsymmetricAlgorithm publicKey, Stream dataStream, byte[] signature)
|
||||
{
|
||||
var signatureDescription = (SignatureDescription)GostCryptoConfig.CreateFromName(publicKey.SignatureAlgorithm);
|
||||
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = signatureDescription.CreateDigest())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
var deformatter = signatureDescription.CreateDeformatter(publicKey);
|
||||
deformatter.SetHashAlgorithm(signatureDescription.DigestAlgorithm);
|
||||
|
||||
return deformatter.VerifySignature(hash, signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Base;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи потока байт с помощью сертификата и классов форматирования.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает поток байт, вычисляет цифровую подпись потока байт с использованием закрытого ключа сертификата,
|
||||
/// а затем с помощью открытого ключа сертификата проверяет полученную подпись. Для вычисления цифровой подписи
|
||||
/// используется класс <see cref="GostSignatureFormatter"/>, для проверки цифровой подписи используется класс
|
||||
/// <see cref="GostSignatureDeformatter"/>.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи потока байт с помощью сертификата и классов форматирования")]
|
||||
public class SignDataStreamSignatureFormatterTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSignDataStream(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var privateKey = (GostAsymmetricAlgorithm)certificate.GetPrivateKeyAlgorithm();
|
||||
var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
var dataStream = CreateDataStream();
|
||||
|
||||
// When
|
||||
|
||||
dataStream.Seek(0, SeekOrigin.Begin);
|
||||
var signature = CreateSignature(privateKey, dataStream);
|
||||
|
||||
dataStream.Seek(0, SeekOrigin.Begin);
|
||||
var isValidSignature = VerifySignature(publicKey, dataStream, signature);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(isValidSignature);
|
||||
}
|
||||
|
||||
private static Stream CreateDataStream()
|
||||
{
|
||||
// Некоторый поток байт для подписи
|
||||
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes("Some data to sign..."));
|
||||
}
|
||||
|
||||
private static byte[] CreateSignature(GostAsymmetricAlgorithm privateKey, Stream dataStream)
|
||||
{
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = privateKey.CreateHashAlgorithm())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
var formatter = new GostSignatureFormatter(privateKey);
|
||||
|
||||
return formatter.CreateSignature(hash);
|
||||
}
|
||||
|
||||
private static bool VerifySignature(GostAsymmetricAlgorithm publicKey, Stream dataStream, byte[] signature)
|
||||
{
|
||||
byte[] hash;
|
||||
|
||||
using (var hashAlg = publicKey.CreateHashAlgorithm())
|
||||
{
|
||||
hash = hashAlg.ComputeHash(dataStream);
|
||||
}
|
||||
|
||||
var deformatter = new GostSignatureDeformatter(publicKey);
|
||||
|
||||
return deformatter.VerifySignature(hash, signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
21
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/TestCertificateInfo.cs
vendored
Normal file
21
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/TestCertificateInfo.cs
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace GostCryptography.Tests
|
||||
{
|
||||
public class TestCertificateInfo
|
||||
{
|
||||
public TestCertificateInfo(string name, X509Certificate2 certificate)
|
||||
{
|
||||
Name = name;
|
||||
Certificate = certificate;
|
||||
}
|
||||
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public X509Certificate2 Certificate { get; }
|
||||
|
||||
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
}
|
||||
79
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/TestConfig.cs
vendored
Normal file
79
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography.Tests/TestConfig.cs
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Config;
|
||||
|
||||
namespace GostCryptography.Tests
|
||||
{
|
||||
public static class TestConfig
|
||||
{
|
||||
static TestConfig()
|
||||
{
|
||||
Providers = new[] { GostCryptoConfig.ProviderType, GostCryptoConfig.ProviderType_2012_512, GostCryptoConfig.ProviderType_2012_1024 };
|
||||
|
||||
var gost_R3410_2001 = new TestCertificateInfo("ГОСТ Р 34.10-2001", FindGostCertificate(filter: c => c.IsGost_R3410_2001()));
|
||||
var gost_R3410_2012_256 = new TestCertificateInfo("ГОСТ Р 34.10-2012/256", FindGostCertificate(filter: c => c.IsGost_R3410_2012_256()));
|
||||
var gost_R3410_2012_512 = new TestCertificateInfo("ГОСТ Р 34.10-2012/512", FindGostCertificate(filter: c => c.IsGost_R3410_2012_512()));
|
||||
|
||||
var gost_R3410_Certificates = new List<TestCertificateInfo> { gost_R3410_2001, gost_R3410_2012_256, gost_R3410_2012_512 };
|
||||
var gost_R3410_2001_Certificates = new List<TestCertificateInfo> { gost_R3410_2001 };
|
||||
var gost_R3410_2012_256_Certificates = new List<TestCertificateInfo> { gost_R3410_2012_256 };
|
||||
var gost_R3410_2012_512_Certificates = new List<TestCertificateInfo> { gost_R3410_2012_512 };
|
||||
|
||||
gost_R3410_Certificates.RemoveAll(c => c.Certificate == null);
|
||||
gost_R3410_2001_Certificates.RemoveAll(c => c.Certificate == null);
|
||||
gost_R3410_2012_256_Certificates.RemoveAll(c => c.Certificate == null);
|
||||
gost_R3410_2012_512_Certificates.RemoveAll(c => c.Certificate == null);
|
||||
|
||||
Gost_R3410_Certificates = gost_R3410_Certificates;
|
||||
Gost_R3410_2001_Certificates = gost_R3410_2001_Certificates;
|
||||
Gost_R3410_2012_256_Certificates = gost_R3410_2012_256_Certificates;
|
||||
Gost_R3410_2012_512_Certificates = gost_R3410_2012_512_Certificates;
|
||||
}
|
||||
|
||||
|
||||
public const StoreName DefaultStoreName = StoreName.My;
|
||||
|
||||
public const StoreLocation DefaultStoreLocation = StoreLocation.LocalMachine;
|
||||
|
||||
public static IEnumerable<ProviderType> Providers { get; }
|
||||
|
||||
public static IEnumerable<TestCertificateInfo> Gost_R3410_Certificates { get; }
|
||||
|
||||
public static IEnumerable<TestCertificateInfo> Gost_R3410_2001_Certificates { get; }
|
||||
|
||||
public static IEnumerable<TestCertificateInfo> Gost_R3410_2012_256_Certificates { get; }
|
||||
|
||||
public static IEnumerable<TestCertificateInfo> Gost_R3410_2012_512_Certificates { get; }
|
||||
|
||||
public const string ContainerPassword = "GostCryptography";
|
||||
|
||||
|
||||
[SecuritySafeCritical]
|
||||
public static X509Certificate2 FindGostCertificate(StoreName storeName = DefaultStoreName, StoreLocation storeLocation = DefaultStoreLocation, Predicate<X509Certificate2> filter = null)
|
||||
{
|
||||
var store = new X509Store(storeName, storeLocation);
|
||||
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var certificate in store.Certificates)
|
||||
{
|
||||
if (certificate.HasPrivateKey && certificate.IsGost() && (filter == null || filter(certificate)))
|
||||
{
|
||||
return certificate;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
store.Close();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация XML для широковещательной рассылки.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, выборочно шифрует элементы данного документа, а затем дешифрует полученный зашифрованный документ.
|
||||
/// Элементы шифруются с использованием случайного сессионного ключа, который в свою очередь кодируется (экспортируется)
|
||||
/// с использованием публичного ключа сертификата получателя. Расшифровка документа происходит с использованием первого
|
||||
/// найденного секретного ключа сертификата получателя.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация XML для широковещательной рассылки")]
|
||||
public sealed class EncryptedXmlBroadcastTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var certificates = new[] { certificate };
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml;
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, certificates);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument);
|
||||
var actualXml = decryptedXmlDocument.OuterXml;
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.EncryptedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, IEnumerable<X509Certificate2> certificates)
|
||||
{
|
||||
// Создание объекта для шифрации XML
|
||||
var encryptedXml = new GostEncryptedXml();
|
||||
|
||||
// Поиск элементов для шифрации
|
||||
var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']");
|
||||
|
||||
if (elements != null)
|
||||
{
|
||||
var elementIndex = 0;
|
||||
|
||||
foreach (XmlElement element in elements)
|
||||
{
|
||||
// Формирование элемента EncryptedData
|
||||
var elementEncryptedData = new EncryptedData();
|
||||
elementEncryptedData.Id = "EncryptedElement" + elementIndex++;
|
||||
elementEncryptedData.Type = EncryptedXml.XmlEncElementUrl;
|
||||
elementEncryptedData.KeyInfo = new KeyInfo();
|
||||
|
||||
using (var sessionKey = new Gost_28147_89_SymmetricAlgorithm())
|
||||
{
|
||||
elementEncryptedData.EncryptionMethod = new EncryptionMethod(sessionKey.AlgorithmName);
|
||||
|
||||
// Шифрация элемента с использованием симметричного ключа
|
||||
var encryptedElement = encryptedXml.EncryptData(element, sessionKey, false);
|
||||
|
||||
foreach (var certificate in certificates)
|
||||
{
|
||||
// Шифрация сессионного ключа с использованием открытого ключа сертификата
|
||||
var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm());
|
||||
|
||||
// Формирование информации о зашифрованном сессионном ключе
|
||||
var encryptedSessionKey = new EncryptedKey();
|
||||
encryptedSessionKey.CipherData = new CipherData(encryptedSessionKeyData);
|
||||
encryptedSessionKey.EncryptionMethod = new EncryptionMethod(GostEncryptedXml.XmlEncGostCryptoProKeyExportUrl);
|
||||
encryptedSessionKey.AddReference(new DataReference { Uri = "#" + elementEncryptedData.Id });
|
||||
encryptedSessionKey.KeyInfo.AddClause(new KeyInfoX509Data(certificate));
|
||||
|
||||
// Добавление ссылки на зашифрованный ключ, используемый при шифровании данных
|
||||
elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey));
|
||||
}
|
||||
|
||||
// Установка зашифрованных данных у объекта EncryptedData
|
||||
elementEncryptedData.CipherData.CipherValue = encryptedElement;
|
||||
}
|
||||
|
||||
// Замена элемента его зашифрованным представлением
|
||||
GostEncryptedXml.ReplaceElement(element, elementEncryptedData, false);
|
||||
}
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument)
|
||||
{
|
||||
// Создание объекта для дешифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(encryptedXmlDocument);
|
||||
|
||||
var nsManager = new XmlNamespaceManager(encryptedXmlDocument.NameTable);
|
||||
nsManager.AddNamespace("enc", EncryptedXml.XmlEncNamespaceUrl);
|
||||
|
||||
// Поиск всех зашифрованных XML-элементов
|
||||
var encryptedDataList = encryptedXmlDocument.SelectNodes("//enc:EncryptedData", nsManager);
|
||||
|
||||
if (encryptedDataList != null)
|
||||
{
|
||||
foreach (XmlElement encryptedData in encryptedDataList)
|
||||
{
|
||||
// Загрузка элемента EncryptedData
|
||||
var elementEncryptedData = new EncryptedData();
|
||||
elementEncryptedData.LoadXml(encryptedData);
|
||||
|
||||
// Извлечение симметричный ключ для расшифровки элемента EncryptedData
|
||||
var sessionKey = GetDecryptionKey(elementEncryptedData);
|
||||
|
||||
if (sessionKey != null)
|
||||
{
|
||||
// Расшифровка элемента EncryptedData
|
||||
var decryptedData = encryptedXml.DecryptData(elementEncryptedData, sessionKey);
|
||||
|
||||
// Замена элемента EncryptedData его расшифрованным представлением
|
||||
encryptedXml.ReplaceData(encryptedData, decryptedData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return encryptedXmlDocument;
|
||||
}
|
||||
|
||||
private static SymmetricAlgorithm GetDecryptionKey(EncryptedData encryptedData)
|
||||
{
|
||||
SymmetricAlgorithm sessionKey = null;
|
||||
|
||||
foreach (var keyInfo in encryptedData.KeyInfo)
|
||||
{
|
||||
if (keyInfo is KeyInfoEncryptedKey)
|
||||
{
|
||||
var encryptedKey = ((KeyInfoEncryptedKey)keyInfo).EncryptedKey;
|
||||
|
||||
if (encryptedKey != null)
|
||||
{
|
||||
foreach (var ekKeyInfo in encryptedKey.KeyInfo)
|
||||
{
|
||||
if (ekKeyInfo is KeyInfoX509Data)
|
||||
{
|
||||
var certificates = ((KeyInfoX509Data)ekKeyInfo).Certificates;
|
||||
|
||||
// Поиск закрытого ключа для дешифрации сессионного ключа
|
||||
var privateKey = FindPrivateKey(certificates);
|
||||
|
||||
if (privateKey != null)
|
||||
{
|
||||
// Дешифрация сессионного ключа с использованием закрытого ключа сертификата
|
||||
sessionKey = GostEncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, privateKey);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sessionKey;
|
||||
}
|
||||
|
||||
private static GostAsymmetricAlgorithm FindPrivateKey(IEnumerable certificates)
|
||||
{
|
||||
// Какая-то логика поиска закрытого ключа
|
||||
|
||||
GostAsymmetricAlgorithm privateKey = null;
|
||||
|
||||
var store = new X509Store(TestConfig.DefaultStoreName, TestConfig.DefaultStoreLocation);
|
||||
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
|
||||
var storeCertificates = store.Certificates;
|
||||
store.Close();
|
||||
|
||||
foreach (X509Certificate2 certificate in certificates)
|
||||
{
|
||||
var index = storeCertificates.IndexOf(certificate);
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
privateKey = storeCertificates[index].GetPrivateKeyAlgorithm() as GostAsymmetricAlgorithm;
|
||||
|
||||
if (privateKey != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return privateKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация XML документа с использованием сертификата.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, выборочно шифрует элементы данного документа с использованием сертификата,
|
||||
/// а затем дешифрует полученный зашифрованный документ.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация XML документа с использованием сертификата")]
|
||||
public sealed class EncryptedXmlCertificateTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml;
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, certificate);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument);
|
||||
var actualXml = decryptedXmlDocument.OuterXml;
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.EncryptedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, X509Certificate2 certificate)
|
||||
{
|
||||
// Создание объекта для шифрации XML
|
||||
var encryptedXml = new GostEncryptedXml();
|
||||
|
||||
// Поиск элементов для шифрации
|
||||
var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']");
|
||||
|
||||
if (elements != null)
|
||||
{
|
||||
foreach (XmlElement element in elements)
|
||||
{
|
||||
// Шифрация элемента
|
||||
var elementEncryptedData = encryptedXml.Encrypt(element, certificate);
|
||||
|
||||
// Замена элемента его зашифрованным представлением
|
||||
GostEncryptedXml.ReplaceElement(element, elementEncryptedData, false);
|
||||
}
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument)
|
||||
{
|
||||
// Создание объекта для дешифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(encryptedXmlDocument);
|
||||
|
||||
// Расшифровка зашифрованных элементов документа
|
||||
encryptedXml.DecryptDocument();
|
||||
|
||||
return encryptedXmlDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Gost_R3410;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация XML с использованием контейнера ключей.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест имитирует обмен данными между условным отправителем, который шифрует заданный XML-документ, и условным получателем, который дешифрует
|
||||
/// зашифрованный XML-документ. Шифрация и дешифрация осуществляется без использования сертификатов. Шифрация осуществляется с использованием
|
||||
/// случайного симметричного ключа, который в свою очередь шифруется с использованием открытого ключа получателя. Соответственно для дешифрации
|
||||
/// данных сначала расшифровывается случайный симметричный ключ с использованием закрытого ключа получателя.
|
||||
///
|
||||
/// Перед началом теста имитируется передача получателем своего открытого ключа отправителю. Для этого получатель извлекает информацию о закрытом
|
||||
/// ключе из контейнера ключей, формирует закрытый ключ для дешифрации XML и условно передает (экспортирует) отправителю информацию о своем открытом
|
||||
/// ключе. Отправитель в свою очередь принимает (импортирует) от получателя информацию о его открытом ключе и формирует открытый ключ для шифрации XML.
|
||||
///
|
||||
/// Тест создает XML-документ, выборочно шифрует элементы данного документа с использованием случайного симметричного ключа, а затем дешифрует
|
||||
/// полученный зашифрованный документ. Случайный симметричного ключ в свою очередь шифруется открытым асимметричным ключом получателя и в зашифрованном
|
||||
/// виде добавляется в зашифрованный документ.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация XML с использованием контейнера ключей")]
|
||||
public class EncryptedXmlKeyContainerTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2001_Certificates))]
|
||||
public void ShouldEncryptXmlWithGost_R3410_2001(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
|
||||
var certificate = testCase.Certificate;
|
||||
|
||||
// Получатель экспортирует отправителю информацию о своем открытом ключе
|
||||
var keyContainer = certificate.GetPrivateKeyInfo();
|
||||
var privateKey = new Gost_R3410_2001_AsymmetricAlgorithm(keyContainer);
|
||||
var publicKeyInfo = privateKey.ExportParameters(false);
|
||||
|
||||
// Отправитель импортирует от получателя информацию о его открытом ключе
|
||||
var publicKey = new Gost_R3410_2001_AsymmetricAlgorithm();
|
||||
publicKey.ImportParameters(publicKeyInfo);
|
||||
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml;
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, publicKey);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument, privateKey);
|
||||
var actualXml = decryptedXmlDocument.OuterXml;
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2012_256_Certificates))]
|
||||
public void ShouldEncryptXmlWithGost_R3410_2012_256(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
|
||||
var certificate = testCase.Certificate;
|
||||
|
||||
// Получатель экспортирует отправителю информацию о своем открытом ключе
|
||||
var keyContainer = certificate.GetPrivateKeyInfo();
|
||||
var privateKey = new Gost_R3410_2012_256_AsymmetricAlgorithm(keyContainer);
|
||||
var publicKeyInfo = privateKey.ExportParameters(false);
|
||||
|
||||
// Отправитель импортирует от получателя информацию о его открытом ключе
|
||||
var publicKey = new Gost_R3410_2012_256_AsymmetricAlgorithm();
|
||||
publicKey.ImportParameters(publicKeyInfo);
|
||||
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml;
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, publicKey);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument, privateKey);
|
||||
var actualXml = decryptedXmlDocument.OuterXml;
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2012_512_Certificates))]
|
||||
public void ShouldEncryptXmlWithGost_R3410_2012_512(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
|
||||
var certificate = testCase.Certificate;
|
||||
|
||||
// Получатель экспортирует отправителю информацию о своем открытом ключе
|
||||
var keyContainer = certificate.GetPrivateKeyInfo();
|
||||
var privateKey = new Gost_R3410_2012_512_AsymmetricAlgorithm(keyContainer);
|
||||
var publicKeyInfo = privateKey.ExportParameters(false);
|
||||
|
||||
// Отправитель импортирует от получателя информацию о его открытом ключе
|
||||
var publicKey = new Gost_R3410_2012_512_AsymmetricAlgorithm();
|
||||
publicKey.ImportParameters(publicKeyInfo);
|
||||
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml;
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, publicKey);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument, privateKey);
|
||||
var actualXml = decryptedXmlDocument.OuterXml;
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.EncryptedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, GostAsymmetricAlgorithm publicKey)
|
||||
{
|
||||
// Создание объекта для шифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(publicKey.ProviderType);
|
||||
|
||||
// Поиск элементов для шифрации
|
||||
var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']");
|
||||
|
||||
if (elements != null)
|
||||
{
|
||||
var elementIndex = 0;
|
||||
|
||||
foreach (XmlElement element in elements)
|
||||
{
|
||||
// Создание случайного сессионного ключа
|
||||
using (var sessionKey = new Gost_28147_89_SymmetricAlgorithm(publicKey.ProviderType))
|
||||
{
|
||||
// Шифрация элемента
|
||||
var encryptedData = encryptedXml.EncryptData(element, sessionKey, false);
|
||||
|
||||
// Шифрация сессионного ключа с использованием публичного асимметричного ключа
|
||||
var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, publicKey);
|
||||
|
||||
// Формирование элемента EncryptedData
|
||||
var elementEncryptedData = new EncryptedData();
|
||||
elementEncryptedData.Id = "EncryptedElement" + elementIndex++;
|
||||
elementEncryptedData.Type = EncryptedXml.XmlEncElementUrl;
|
||||
elementEncryptedData.EncryptionMethod = new EncryptionMethod(sessionKey.AlgorithmName);
|
||||
elementEncryptedData.CipherData.CipherValue = encryptedData;
|
||||
elementEncryptedData.KeyInfo = new KeyInfo();
|
||||
|
||||
// Формирование информации о зашифрованном сессионном ключе
|
||||
var encryptedSessionKey = new EncryptedKey();
|
||||
encryptedSessionKey.CipherData = new CipherData(encryptedSessionKeyData);
|
||||
encryptedSessionKey.EncryptionMethod = new EncryptionMethod(publicKey.KeyExchangeAlgorithm);
|
||||
encryptedSessionKey.AddReference(new DataReference { Uri = "#" + elementEncryptedData.Id });
|
||||
encryptedSessionKey.KeyInfo.AddClause(new KeyInfoName { Value = "KeyName1" });
|
||||
|
||||
// Добавление ссылки на зашифрованный ключ, используемый при шифровании данных
|
||||
elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey));
|
||||
|
||||
// Замена элемента его зашифрованным представлением
|
||||
GostEncryptedXml.ReplaceElement(element, elementEncryptedData, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument, GostAsymmetricAlgorithm privateKey)
|
||||
{
|
||||
// Создание объекта для дешифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(privateKey.ProviderType, encryptedXmlDocument);
|
||||
|
||||
// Добавление ссылки на приватный асимметричный ключ
|
||||
encryptedXml.AddKeyNameMapping("KeyName1", privateKey);
|
||||
|
||||
// Расшифровка зашифрованных элементов документа
|
||||
encryptedXml.DecryptDocument();
|
||||
|
||||
return encryptedXmlDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация XML с использованием случайного сессионного ключа.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, выборочно шифрует элементы данного документа с использованием случайного симметричного ключа,
|
||||
/// а затем дешифрует полученный зашифрованный документ. Случайный симметричного ключ в свою очередь шифруется общим симметричным
|
||||
/// ключом и в зашифрованном виде добавляется в зашифрованный документ.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация XML с использованием случайного сессионного ключа")]
|
||||
public class EncryptedXmlSessionKey
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldEncryptXml(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml;
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, sharedKey);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument, sharedKey);
|
||||
var actualXml = decryptedXmlDocument.OuterXml;
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.EncryptedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, GostSymmetricAlgorithm sharedKey)
|
||||
{
|
||||
// Создание объекта для шифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(sharedKey.ProviderType);
|
||||
|
||||
// Поиск элементов для шифрации
|
||||
var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']");
|
||||
|
||||
if (elements != null)
|
||||
{
|
||||
var elementIndex = 0;
|
||||
|
||||
foreach (XmlElement element in elements)
|
||||
{
|
||||
// Создание случайного сессионного ключа
|
||||
using (var sessionKey = new Gost_28147_89_SymmetricAlgorithm(sharedKey.ProviderType))
|
||||
{
|
||||
// Шифрация элемента
|
||||
var encryptedData = encryptedXml.EncryptData(element, sessionKey, false);
|
||||
|
||||
// Шифрация сессионного ключа с использованием общего симметричного ключа
|
||||
var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, sharedKey, GostKeyExchangeExportMethod.CryptoProKeyExport);
|
||||
|
||||
// Формирование элемента EncryptedData
|
||||
var elementEncryptedData = new EncryptedData();
|
||||
elementEncryptedData.Id = "EncryptedElement" + elementIndex++;
|
||||
elementEncryptedData.Type = EncryptedXml.XmlEncElementUrl;
|
||||
elementEncryptedData.EncryptionMethod = new EncryptionMethod(sessionKey.AlgorithmName);
|
||||
elementEncryptedData.CipherData.CipherValue = encryptedData;
|
||||
elementEncryptedData.KeyInfo = new KeyInfo();
|
||||
|
||||
// Формирование информации о зашифрованном сессионном ключе
|
||||
var encryptedSessionKey = new EncryptedKey();
|
||||
encryptedSessionKey.CipherData = new CipherData(encryptedSessionKeyData);
|
||||
encryptedSessionKey.EncryptionMethod = new EncryptionMethod(GostEncryptedXml.XmlEncGostCryptoProKeyExportUrl);
|
||||
encryptedSessionKey.AddReference(new DataReference { Uri = "#" + elementEncryptedData.Id });
|
||||
encryptedSessionKey.KeyInfo.AddClause(new KeyInfoName { Value = "SharedKey1" });
|
||||
|
||||
// Добавление ссылки на зашифрованный ключ, используемый при шифровании данных
|
||||
elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey));
|
||||
|
||||
// Замена элемента его зашифрованным представлением
|
||||
GostEncryptedXml.ReplaceElement(element, elementEncryptedData, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument, GostSymmetricAlgorithm sharedKey)
|
||||
{
|
||||
// Создание объекта для дешифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(sharedKey.ProviderType, encryptedXmlDocument);
|
||||
|
||||
// Добавление ссылки на общий симметричный ключ
|
||||
encryptedXml.AddKeyNameMapping("SharedKey1", sharedKey);
|
||||
|
||||
// Расшифровка зашифрованных элементов документа
|
||||
encryptedXml.DecryptDocument();
|
||||
|
||||
return encryptedXmlDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация XML с использованием общего симметричного ключа.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, выборочно шифрует элементы данного документа с использованием общего симметричного ключа,
|
||||
/// а затем дешифрует полученный зашифрованный документ.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация XML с использованием общего симметричного ключа")]
|
||||
public sealed class EncryptedXmlSharedKeyTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))]
|
||||
public void ShouldEncryptXml(ProviderType providerType)
|
||||
{
|
||||
// Given
|
||||
var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType);
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml;
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, sharedKey);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument, sharedKey);
|
||||
var actualXml = decryptedXmlDocument.OuterXml;
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.EncryptedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, Gost_28147_89_SymmetricAlgorithm sharedKey)
|
||||
{
|
||||
// Создание объекта для шифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(sharedKey.ProviderType);
|
||||
|
||||
// Поиск элементов для шифрации
|
||||
var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']");
|
||||
|
||||
if (elements != null)
|
||||
{
|
||||
foreach (XmlElement element in elements)
|
||||
{
|
||||
// Шифрация элемента
|
||||
var encryptedData = encryptedXml.EncryptData(element, sharedKey, false);
|
||||
|
||||
// Формирование элемента EncryptedData
|
||||
var elementEncryptedData = new EncryptedData();
|
||||
elementEncryptedData.Type = EncryptedXml.XmlEncElementUrl;
|
||||
elementEncryptedData.EncryptionMethod = new EncryptionMethod(sharedKey.AlgorithmName);
|
||||
elementEncryptedData.CipherData.CipherValue = encryptedData;
|
||||
|
||||
// Замена элемента его зашифрованным представлением
|
||||
GostEncryptedXml.ReplaceElement(element, elementEncryptedData, false);
|
||||
}
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument, Gost_28147_89_SymmetricAlgorithm sharedKey)
|
||||
{
|
||||
// Создание объекта для дешифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(sharedKey.ProviderType, encryptedXmlDocument);
|
||||
|
||||
var nsManager = new XmlNamespaceManager(encryptedXmlDocument.NameTable);
|
||||
nsManager.AddNamespace("enc", EncryptedXml.XmlEncNamespaceUrl);
|
||||
|
||||
// Поиск всех зашифрованных XML-элементов
|
||||
var encryptedDataList = encryptedXmlDocument.SelectNodes("//enc:EncryptedData", nsManager);
|
||||
|
||||
if (encryptedDataList != null)
|
||||
{
|
||||
foreach (XmlElement encryptedData in encryptedDataList)
|
||||
{
|
||||
// Загрузка элемента EncryptedData
|
||||
var elementEncryptedData = new EncryptedData();
|
||||
elementEncryptedData.LoadXml(encryptedData);
|
||||
|
||||
// Расшифровка элемента EncryptedData
|
||||
var decryptedData = encryptedXml.DecryptData(elementEncryptedData, sharedKey);
|
||||
|
||||
// Замена элемента EncryptedData его расшифрованным представлением
|
||||
encryptedXml.ReplaceData(encryptedData, decryptedData);
|
||||
}
|
||||
}
|
||||
|
||||
return encryptedXmlDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация XML документа с использованием сертификата и алгоритма ГОСТ Р 34.12-2015 Кузнечик.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, шифрует его целиком с использованием сертификата, а затем дешифрует зашифрованный документ.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация XML документа с использованием сертификата и алгоритма ГОСТ Р 34.12-2015 Кузнечик")]
|
||||
public sealed class KuznyechikEncryptedXmlCertificateTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml.Replace("\r\n", "\n");
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, certificate);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument);
|
||||
var actualXml = decryptedXmlDocument.OuterXml.Replace("\r\n", "\n");
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.EncryptedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, X509Certificate2 certificate)
|
||||
{
|
||||
var publicKeyAlgorithm = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
|
||||
using (var sessionKey = new Gost_3412_K_SymmetricAlgorithm(publicKeyAlgorithm.ProviderType))
|
||||
{
|
||||
var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, publicKeyAlgorithm);
|
||||
|
||||
var encryptedSessionKey = new EncryptedKey
|
||||
{
|
||||
CipherData = new CipherData(encryptedSessionKeyData),
|
||||
EncryptionMethod = new EncryptionMethod(publicKeyAlgorithm.KeyExchangeAlgorithm),
|
||||
};
|
||||
|
||||
encryptedSessionKey.KeyInfo.AddClause(new KeyInfoX509Data(certificate));
|
||||
|
||||
var elementEncryptedData = new EncryptedData
|
||||
{
|
||||
EncryptionMethod = new EncryptionMethod(sessionKey.AlgorithmName),
|
||||
};
|
||||
|
||||
var encryptedXml = new GostEncryptedXml();
|
||||
var xmlBytes = Encoding.UTF8.GetBytes(xmlDocument.OuterXml);
|
||||
var encryptedData = encryptedXml.EncryptData(xmlBytes, sessionKey);
|
||||
|
||||
elementEncryptedData.CipherData.CipherValue = encryptedData;
|
||||
elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey));
|
||||
|
||||
GostEncryptedXml.ReplaceElement(xmlDocument.DocumentElement, elementEncryptedData, false);
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument)
|
||||
{
|
||||
// Создание объекта для дешифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(encryptedXmlDocument);
|
||||
|
||||
// Расшифровка зашифрованных элементов документа
|
||||
encryptedXml.DecryptDocument();
|
||||
|
||||
return encryptedXmlDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_28147_89;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Шифрация и дешифрация XML документа с использованием сертификата и алгоритма ГОСТ Р 34.12-2015 Магма.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, шифрует его целиком с использованием сертификата, а затем дешифрует зашифрованный документ.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Шифрация и дешифрация XML документа с использованием сертификата и алгоритма ГОСТ Р 34.12-2015 Магма")]
|
||||
public sealed class MagmaEncryptedXmlCertificateTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldEncryptXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
var expectedXml = xmlDocument.OuterXml.Replace("\r\n", "\n");
|
||||
|
||||
// When
|
||||
var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, certificate);
|
||||
var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument);
|
||||
var actualXml = decryptedXmlDocument.OuterXml.Replace("\r\n", "\n");
|
||||
|
||||
// Then
|
||||
Assert.AreEqual(expectedXml, actualXml);
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.EncryptedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, X509Certificate2 certificate)
|
||||
{
|
||||
var publicKeyAlgorithm = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm();
|
||||
|
||||
using (var sessionKey = new Gost_3412_M_SymmetricAlgorithm(publicKeyAlgorithm.ProviderType))
|
||||
{
|
||||
var encryptedSessionKeyData = GostEncryptedXml.EncryptKey(sessionKey, publicKeyAlgorithm);
|
||||
|
||||
var encryptedSessionKey = new EncryptedKey
|
||||
{
|
||||
CipherData = new CipherData(encryptedSessionKeyData),
|
||||
EncryptionMethod = new EncryptionMethod(publicKeyAlgorithm.KeyExchangeAlgorithm),
|
||||
};
|
||||
|
||||
encryptedSessionKey.KeyInfo.AddClause(new KeyInfoX509Data(certificate));
|
||||
|
||||
var elementEncryptedData = new EncryptedData
|
||||
{
|
||||
EncryptionMethod = new EncryptionMethod(sessionKey.AlgorithmName),
|
||||
};
|
||||
|
||||
var encryptedXml = new GostEncryptedXml();
|
||||
var xmlBytes = Encoding.UTF8.GetBytes(xmlDocument.OuterXml);
|
||||
var encryptedData = encryptedXml.EncryptData(xmlBytes, sessionKey);
|
||||
|
||||
elementEncryptedData.CipherData.CipherValue = encryptedData;
|
||||
elementEncryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedSessionKey));
|
||||
|
||||
GostEncryptedXml.ReplaceElement(xmlDocument.DocumentElement, elementEncryptedData, false);
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument)
|
||||
{
|
||||
// Создание объекта для дешифрации XML
|
||||
var encryptedXml = new GostEncryptedXml(encryptedXmlDocument);
|
||||
|
||||
// Расшифровка зашифрованных элементов документа
|
||||
encryptedXml.DecryptDocument();
|
||||
|
||||
return encryptedXmlDocument;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи XML-документа с использованием сертификата.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, подписывает определенную часть данного документа с использованием сертификата,
|
||||
/// а затем проверяет полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи XML-документа с использованием сертификата")]
|
||||
public class SignedXmlCertificateTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSignXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
|
||||
// When
|
||||
var signedXmlDocument = SignXmlDocument(xmlDocument, certificate);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.SignedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument SignXmlDocument(XmlDocument xmlDocument, X509Certificate2 certificate)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(xmlDocument);
|
||||
|
||||
// Установка ключа для создания подписи
|
||||
signedXml.SetSigningCertificate(certificate);
|
||||
|
||||
// Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования
|
||||
var dataReference = new Reference { Uri = "#Id1", DigestMethod = GetDigestMethod(certificate) };
|
||||
|
||||
// Установка ссылки на узел
|
||||
signedXml.AddReference(dataReference);
|
||||
|
||||
// Установка информации о сертификате, который использовался для создания подписи
|
||||
var keyInfo = new KeyInfo();
|
||||
keyInfo.AddClause(new KeyInfoX509Data(certificate));
|
||||
signedXml.KeyInfo = keyInfo;
|
||||
|
||||
// Вычисление подписи
|
||||
signedXml.ComputeSignature();
|
||||
|
||||
// Получение XML-представления подписи
|
||||
var signatureXml = signedXml.GetXml();
|
||||
|
||||
// Добавление подписи в исходный документ
|
||||
xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(signatureXml, true));
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static bool VerifyXmlDocumentSignature(XmlDocument signedXmlDocument)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(signedXmlDocument);
|
||||
|
||||
// Поиск узла с подписью
|
||||
var nodeList = signedXmlDocument.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl);
|
||||
|
||||
// Загрузка найденной подписи
|
||||
signedXml.LoadXml((XmlElement)nodeList[0]);
|
||||
|
||||
// Проверка подписи
|
||||
return signedXml.CheckSignature();
|
||||
}
|
||||
|
||||
private static string GetDigestMethod(X509Certificate2 certificate)
|
||||
{
|
||||
// Имя алгоритма вычисляем динамически, чтобы сделать код теста универсальным
|
||||
|
||||
using (var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm())
|
||||
using (var hashAlgorithm = publicKey.CreateHashAlgorithm())
|
||||
{
|
||||
return hashAlgorithm.AlgorithmName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи всего XML документа с использованием сертификата
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, подписывает весь документ с использованием сертификата,
|
||||
/// а затем проверяет полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи всего XML документа с использованием сертификата")]
|
||||
public class SignedXmlDocumentTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSignXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
|
||||
// When
|
||||
var signedXmlDocument = SignXmlDocument(xmlDocument, certificate);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.SignedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument SignXmlDocument(XmlDocument xmlDocument, X509Certificate2 certificate)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(xmlDocument);
|
||||
|
||||
// Установка ключа для создания подписи
|
||||
signedXml.SetSigningCertificate(certificate);
|
||||
|
||||
// Ссылка на весь документ и указание алгоритма хэширования
|
||||
var dataReference = new Reference { Uri = "", DigestMethod = GetDigestMethod(certificate) };
|
||||
|
||||
// Метод преобразования для подписи всего документа
|
||||
dataReference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
|
||||
|
||||
// Установка ссылки на узел
|
||||
signedXml.AddReference(dataReference);
|
||||
|
||||
// Установка информации о сертификате, который использовался для создания подписи
|
||||
var keyInfo = new KeyInfo();
|
||||
keyInfo.AddClause(new KeyInfoX509Data(certificate));
|
||||
signedXml.KeyInfo = keyInfo;
|
||||
|
||||
// Вычисление подписи
|
||||
signedXml.ComputeSignature();
|
||||
|
||||
// Получение XML-представления подписи
|
||||
var signatureXml = signedXml.GetXml();
|
||||
|
||||
// Добавление подписи в исходный документ
|
||||
xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(signatureXml, true));
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static bool VerifyXmlDocumentSignature(XmlDocument signedXmlDocument)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(signedXmlDocument);
|
||||
|
||||
// Поиск узла с подписью
|
||||
var nodeList = signedXmlDocument.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl);
|
||||
|
||||
// Загрузка найденной подписи
|
||||
signedXml.LoadXml((XmlElement)nodeList[0]);
|
||||
|
||||
// Проверка подписи
|
||||
return signedXml.CheckSignature();
|
||||
}
|
||||
|
||||
private static string GetDigestMethod(X509Certificate2 certificate)
|
||||
{
|
||||
// Имя алгоритма вычисляем динамически, чтобы сделать код теста универсальным
|
||||
|
||||
using (var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm())
|
||||
using (var hashAlgorithm = publicKey.CreateHashAlgorithm())
|
||||
{
|
||||
return hashAlgorithm.AlgorithmName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Gost_R3410;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи XML-документа с использованием контейнера ключей.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, подписывает определенную часть данного документа с использованием контейнера ключей,
|
||||
/// а затем проверяет полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи XML-документа с использованием контейнера ключей")]
|
||||
public class SignedXmlKeyContainerTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2001_Certificates))]
|
||||
public void ShouldSignXmlWithGost_R3410_2001(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var keyContainer = certificate.GetPrivateKeyInfo();
|
||||
var signingKey = new Gost_R3410_2001_AsymmetricAlgorithm(keyContainer);
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
|
||||
// When
|
||||
var signedXmlDocument = SignXmlDocument(xmlDocument, new Gost_R3410_2001_KeyValue(signingKey));
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2012_256_Certificates))]
|
||||
public void ShouldSignXmlWithGost_R3410_2012_256(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var keyContainer = certificate.GetPrivateKeyInfo();
|
||||
var signingKey = new Gost_R3410_2012_256_AsymmetricAlgorithm(keyContainer);
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
|
||||
// When
|
||||
var signedXmlDocument = SignXmlDocument(xmlDocument, new Gost_R3410_2012_256_KeyValue(signingKey));
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_2012_512_Certificates))]
|
||||
public void ShouldSignXmlWithGost_R3410_2012_512(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var keyContainer = certificate.GetPrivateKeyInfo();
|
||||
var signingKey = new Gost_R3410_2012_512_AsymmetricAlgorithm(keyContainer);
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
|
||||
// When
|
||||
var signedXmlDocument = SignXmlDocument(xmlDocument, new Gost_R3410_2012_512_KeyValue(signingKey));
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.SignedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument SignXmlDocument(XmlDocument xmlDocument, GostKeyValue keyValue)
|
||||
{
|
||||
var signingKey = keyValue.PublicKey;
|
||||
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(xmlDocument);
|
||||
|
||||
// Установка ключа для создания подписи
|
||||
signedXml.SigningKey = signingKey;
|
||||
|
||||
// Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования
|
||||
var dataReference = new Reference { Uri = "#Id1", DigestMethod = GetDigestMethod(signingKey) };
|
||||
|
||||
// Установка ссылки на узел
|
||||
signedXml.AddReference(dataReference);
|
||||
|
||||
// Установка информации о ключе, который использовался для создания подписи
|
||||
var keyInfo = new KeyInfo();
|
||||
keyInfo.AddClause(keyValue);
|
||||
signedXml.KeyInfo = keyInfo;
|
||||
|
||||
// Вычисление подписи
|
||||
signedXml.ComputeSignature();
|
||||
|
||||
// Получение XML-представления подписи
|
||||
var signatureXml = signedXml.GetXml();
|
||||
|
||||
// Добавление подписи в исходный документ
|
||||
xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(signatureXml, true));
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static bool VerifyXmlDocumentSignature(XmlDocument signedXmlDocument)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(signedXmlDocument);
|
||||
|
||||
// Поиск узла с подписью
|
||||
var nodeList = signedXmlDocument.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl);
|
||||
|
||||
// Загрузка найденной подписи
|
||||
signedXml.LoadXml((XmlElement)nodeList[0]);
|
||||
|
||||
// Проверка подписи
|
||||
return signedXml.CheckSignature();
|
||||
}
|
||||
|
||||
private static string GetDigestMethod(GostAsymmetricAlgorithm signingKey)
|
||||
{
|
||||
// Имя алгоритма вычисляем динамически, чтобы сделать код теста универсальным
|
||||
|
||||
using (var hashAlgorithm = signingKey.CreateHashAlgorithm())
|
||||
{
|
||||
return hashAlgorithm.AlgorithmName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
using System;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи запроса к сервису СМЭВ (Система межведомственного электронного взаимодействия).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает запрос к сервису СМЭВ, подписывает определенную часть данного запроса с использованием сертификата,
|
||||
/// а затем проверяет полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[TestFixture(Description = "Подпись и проверка подписи запроса к сервису СМЭВ (Система межведомственного электронного взаимодействия)")]
|
||||
public sealed class SignedXmlSmevTest
|
||||
{
|
||||
private const string WsSecurityExtNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
|
||||
private const string WsSecurityUtilityNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
|
||||
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSignXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var smevRequest = CreateSmevRequest();
|
||||
|
||||
// When
|
||||
var signedXmlDocument = SignSmevRequest(smevRequest, certificate);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(VerifySmevRequestSignature(signedXmlDocument));
|
||||
}
|
||||
|
||||
private static XmlDocument CreateSmevRequest()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.SmevExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument SignSmevRequest(XmlDocument smevRequest, X509Certificate2 certificate)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(smevRequest) { GetIdElementHandler = GetSmevIdElement };
|
||||
|
||||
// Установка ключа для создания подписи
|
||||
signedXml.SetSigningCertificate(certificate);
|
||||
|
||||
// Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования
|
||||
var dataReference = new Reference { Uri = "#body", DigestMethod = GetDigestMethod(certificate) };
|
||||
|
||||
// Метод преобразования, применяемый к данным перед их подписью (в соответствии с методическими рекомендациями СМЭВ)
|
||||
var dataTransform = new XmlDsigExcC14NTransform();
|
||||
dataReference.AddTransform(dataTransform);
|
||||
|
||||
// Установка ссылки на узел
|
||||
signedXml.AddReference(dataReference);
|
||||
|
||||
// Установка алгоритма нормализации узла SignedInfo (в соответствии с методическими рекомендациями СМЭВ)
|
||||
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
|
||||
|
||||
// Установка алгоритма хэширования (в соответствии с методическими рекомендациями СМЭВ)
|
||||
signedXml.SignedInfo.SignatureMethod = GetSignatureMethod(certificate);
|
||||
|
||||
// Вычисление подписи
|
||||
signedXml.ComputeSignature();
|
||||
|
||||
// Получение XML-представления подписи
|
||||
var signatureXml = signedXml.GetXml();
|
||||
|
||||
// Добавление подписи в исходный документ
|
||||
smevRequest.GetElementsByTagName("ds:Signature")[0].PrependChild(smevRequest.ImportNode(signatureXml.GetElementsByTagName("SignatureValue")[0], true));
|
||||
smevRequest.GetElementsByTagName("ds:Signature")[0].PrependChild(smevRequest.ImportNode(signatureXml.GetElementsByTagName("SignedInfo")[0], true));
|
||||
smevRequest.GetElementsByTagName("wsse:BinarySecurityToken")[0].InnerText = Convert.ToBase64String(certificate.RawData);
|
||||
|
||||
return smevRequest;
|
||||
}
|
||||
|
||||
private static bool VerifySmevRequestSignature(XmlDocument signedSmevRequest)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(signedSmevRequest) { GetIdElementHandler = GetSmevIdElement };
|
||||
|
||||
// Поиск узла с подписью
|
||||
var nodeList = signedSmevRequest.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl);
|
||||
|
||||
// Загрузка найденной подписи
|
||||
signedXml.LoadXml((XmlElement)nodeList[0]);
|
||||
|
||||
// Поиск ссылки на BinarySecurityToken
|
||||
var references = signedXml.KeyInfo.GetXml().GetElementsByTagName("Reference", WsSecurityExtNamespace);
|
||||
|
||||
if (references.Count > 0)
|
||||
{
|
||||
// Определение ссылки на сертификат (ссылка на узел документа)
|
||||
var binaryTokenReference = ((XmlElement)references[0]).GetAttribute("URI");
|
||||
|
||||
if (!string.IsNullOrEmpty(binaryTokenReference) && binaryTokenReference[0] == '#')
|
||||
{
|
||||
// Поиск элемента с закодированным в Base64 сертификатом
|
||||
var binaryTokenElement = signedXml.GetIdElement(signedSmevRequest, binaryTokenReference.Substring(1));
|
||||
|
||||
if (binaryTokenElement != null)
|
||||
{
|
||||
// Загрузка сертификата, который был использован для подписи
|
||||
var certificate = new X509Certificate2(Convert.FromBase64String(binaryTokenElement.InnerText));
|
||||
|
||||
// Проверка подписи
|
||||
return signedXml.CheckSignature(certificate.GetPublicKeyAlgorithm());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static XmlElement GetSmevIdElement(XmlDocument document, string idValue)
|
||||
{
|
||||
var namespaceManager = new XmlNamespaceManager(document.NameTable);
|
||||
namespaceManager.AddNamespace("wsu", WsSecurityUtilityNamespace);
|
||||
|
||||
return document.SelectSingleNode("//*[@wsu:Id='" + idValue + "']", namespaceManager) as XmlElement;
|
||||
}
|
||||
|
||||
private static string GetSignatureMethod(X509Certificate2 certificate)
|
||||
{
|
||||
// Имя алгоритма вычисляем динамически, чтобы сделать код теста универсальным
|
||||
|
||||
using (var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm())
|
||||
{
|
||||
return publicKey.SignatureAlgorithm;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetDigestMethod(X509Certificate2 certificate)
|
||||
{
|
||||
// Имя алгоритма вычисляем динамически, чтобы сделать код теста универсальным
|
||||
|
||||
using (var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm())
|
||||
using (var hashAlgorithm = publicKey.CreateHashAlgorithm())
|
||||
{
|
||||
return hashAlgorithm.AlgorithmName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
|
||||
using GostCryptography.Base;
|
||||
using GostCryptography.Tests.Properties;
|
||||
using GostCryptography.Xml;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace GostCryptography.Tests.Xml.Sign
|
||||
{
|
||||
/// <summary>
|
||||
/// Подпись и проверка подписи XML-документа с предварительным XSLT-преобразованием подписываемых данных.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Тест создает XML-документ, подписывает определенную часть данного документа с использованием сертификата,
|
||||
/// предварительно осуществляя XSLT-преобразование подписываемых данных, а затем проверяет полученную цифровую подпись.
|
||||
/// </remarks>
|
||||
[Ignore("TODO: Нужно произвести диагностику с подключением логирования")]
|
||||
[TestFixture(Description = "Подпись и проверка подписи XML-документа с предварительным XSLT-преобразованием подписываемых данных")]
|
||||
public sealed class SignedXmlTransformTest
|
||||
{
|
||||
[Test]
|
||||
[TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))]
|
||||
public void ShouldSignXml(TestCertificateInfo testCase)
|
||||
{
|
||||
// Given
|
||||
var certificate = testCase.Certificate;
|
||||
var xmlDocument = CreateXmlDocument();
|
||||
|
||||
// When
|
||||
var signedXmlDocument = SignXmlDocument(xmlDocument, certificate);
|
||||
|
||||
// Then
|
||||
Assert.IsTrue(VerifyXmlDocumentSignature(signedXmlDocument));
|
||||
}
|
||||
|
||||
private static XmlDocument CreateXmlDocument()
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
document.LoadXml(Resources.SignedXmlExample);
|
||||
return document;
|
||||
}
|
||||
|
||||
private static XmlDocument SignXmlDocument(XmlDocument xmlDocument, X509Certificate2 certificate)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(xmlDocument);
|
||||
|
||||
// Установка ключа для создания подписи
|
||||
signedXml.SetSigningCertificate(certificate);
|
||||
|
||||
// Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования
|
||||
var dataReference = new Reference { Uri = "#Id1", DigestMethod = GetDigestMethod(certificate) };
|
||||
|
||||
// Метод преобразования, применяемый к данным перед их подписью
|
||||
var dataTransform = CreateDataTransform();
|
||||
dataReference.AddTransform(dataTransform);
|
||||
|
||||
// Установка ссылки на узел
|
||||
signedXml.AddReference(dataReference);
|
||||
|
||||
// Установка информации о сертификате, который использовался для создания подписи
|
||||
var keyInfo = new KeyInfo();
|
||||
keyInfo.AddClause(new KeyInfoX509Data(certificate));
|
||||
signedXml.KeyInfo = keyInfo;
|
||||
|
||||
// Вычисление подписи
|
||||
signedXml.ComputeSignature();
|
||||
|
||||
// Получение XML-представления подписи
|
||||
var signatureXml = signedXml.GetXml();
|
||||
|
||||
// Добавление подписи в исходный документ
|
||||
xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(signatureXml, true));
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
private static XmlDsigXsltTransform CreateDataTransform()
|
||||
{
|
||||
var dataTransformDocument = new XmlDocument();
|
||||
|
||||
dataTransformDocument.LoadXml(@"
|
||||
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:ds='http://www.w3.org/2000/09/xmldsig#'>
|
||||
<xsl:template match='/'>
|
||||
<xsl:apply-templates />
|
||||
</xsl:template>
|
||||
<xsl:template match='*'>
|
||||
<xsl:copy>
|
||||
<xsl:copy-of select='@*' />
|
||||
<xsl:apply-templates />
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
<xsl:template match='ds:Signature' />
|
||||
</xsl:stylesheet>");
|
||||
|
||||
var dataTransform = new XmlDsigXsltTransform();
|
||||
dataTransform.LoadInnerXml(dataTransformDocument.ChildNodes);
|
||||
|
||||
return dataTransform;
|
||||
}
|
||||
|
||||
private static bool VerifyXmlDocumentSignature(XmlDocument signedXmlDocument)
|
||||
{
|
||||
// Создание подписчика XML-документа
|
||||
var signedXml = new GostSignedXml(signedXmlDocument);
|
||||
|
||||
// Поиск узла с подписью
|
||||
var nodeList = signedXmlDocument.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl);
|
||||
|
||||
// Загрузка найденной подписи
|
||||
signedXml.LoadXml((XmlElement)nodeList[0]);
|
||||
|
||||
// Проверка подписи
|
||||
return signedXml.CheckSignature();
|
||||
}
|
||||
|
||||
private static string GetDigestMethod(X509Certificate2 certificate)
|
||||
{
|
||||
// Имя алгоритма вычисляем динамически, чтобы сделать код теста универсальным
|
||||
|
||||
using (var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm())
|
||||
using (var hashAlgorithm = publicKey.CreateHashAlgorithm())
|
||||
{
|
||||
return hashAlgorithm.AlgorithmName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class Asn18BitCharString : Asn1CharString
|
||||
{
|
||||
public const int BitsPerCharA = 8;
|
||||
public const int BitsPerCharU = 7;
|
||||
|
||||
protected internal Asn18BitCharString(short typeCode)
|
||||
: base(typeCode)
|
||||
{
|
||||
}
|
||||
|
||||
protected internal Asn18BitCharString(string data, short typeCode)
|
||||
: base(data, typeCode)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
401
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BerDecodeBuffer.cs
vendored
Normal file
401
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BerDecodeBuffer.cs
vendored
Normal file
@@ -0,0 +1,401 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1BerDecodeBuffer : Asn1DecodeBuffer
|
||||
{
|
||||
private readonly IntHolder _lenHolder;
|
||||
private readonly Asn1Tag _tagHolder;
|
||||
|
||||
private Asn1Tag _lastParsedTag;
|
||||
private MemoryStream _openTypeCaptureBuffer;
|
||||
private MemoryStream _parserCaptureBuffer;
|
||||
|
||||
public Asn1BerDecodeBuffer(byte[] msgdata)
|
||||
: base(msgdata)
|
||||
{
|
||||
_tagHolder = new Asn1Tag();
|
||||
_lenHolder = new IntHolder();
|
||||
}
|
||||
|
||||
public Asn1BerDecodeBuffer(Stream inputStream)
|
||||
: base(inputStream)
|
||||
{
|
||||
_tagHolder = new Asn1Tag();
|
||||
_lenHolder = new IntHolder();
|
||||
}
|
||||
|
||||
public virtual Asn1Tag LastTag
|
||||
{
|
||||
get { return _lastParsedTag; }
|
||||
}
|
||||
|
||||
public static int CalcIndefLen(byte[] data, int offset, int len)
|
||||
{
|
||||
Asn1BerDecodeBuffer buffer;
|
||||
|
||||
if ((offset == 0) && (len == data.Length))
|
||||
{
|
||||
buffer = new Asn1BerDecodeBuffer(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
var destinationArray = new byte[len];
|
||||
Array.Copy(data, offset, destinationArray, 0, len);
|
||||
buffer = new Asn1BerDecodeBuffer(destinationArray);
|
||||
}
|
||||
|
||||
var tag = new Asn1Tag();
|
||||
var num = buffer.DecodeTagAndLength(tag);
|
||||
|
||||
if (num == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
var num2 = 1;
|
||||
num = 0;
|
||||
|
||||
while (num2 > 0)
|
||||
{
|
||||
var byteCount = buffer.ByteCount;
|
||||
var num4 = buffer.DecodeTagAndLength(tag);
|
||||
num += buffer.ByteCount - byteCount;
|
||||
|
||||
if (num4 > 0)
|
||||
{
|
||||
buffer.Skip(num4);
|
||||
num += num4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (num4 == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
num2++;
|
||||
continue;
|
||||
}
|
||||
if (tag.IsEoc() && (num4 == 0))
|
||||
{
|
||||
num2--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public virtual int DecodeLength()
|
||||
{
|
||||
var num3 = 0;
|
||||
var num2 = Read();
|
||||
|
||||
if (num2 < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
if (num2 <= 0x80)
|
||||
{
|
||||
if (num2 == 0x80)
|
||||
{
|
||||
return Asn1Status.IndefiniteLength;
|
||||
}
|
||||
|
||||
return num2;
|
||||
}
|
||||
|
||||
var num = num2 & 0x7f;
|
||||
|
||||
if (num > 4)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
while (num > 0)
|
||||
{
|
||||
num2 = Read();
|
||||
|
||||
if (num2 < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
num3 = (num3 * 0x100) + num2;
|
||||
num--;
|
||||
}
|
||||
|
||||
return num3;
|
||||
}
|
||||
|
||||
public virtual byte[] DecodeOpenType()
|
||||
{
|
||||
return DecodeOpenType(true);
|
||||
}
|
||||
|
||||
public virtual byte[] DecodeOpenType(bool saveData)
|
||||
{
|
||||
if (saveData)
|
||||
{
|
||||
if (_openTypeCaptureBuffer == null)
|
||||
{
|
||||
_openTypeCaptureBuffer = new MemoryStream(0x100);
|
||||
}
|
||||
else
|
||||
{
|
||||
_openTypeCaptureBuffer.Seek(0L, SeekOrigin.Begin);
|
||||
_openTypeCaptureBuffer.SetLength(0L);
|
||||
}
|
||||
|
||||
AddCaptureBuffer(_openTypeCaptureBuffer);
|
||||
}
|
||||
|
||||
DecodeOpenTypeElement(_tagHolder, _lenHolder, saveData);
|
||||
|
||||
if (saveData)
|
||||
{
|
||||
var buffer = _openTypeCaptureBuffer.ToArray();
|
||||
RemoveCaptureBuffer(_openTypeCaptureBuffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void DecodeOpenTypeElement(Asn1Tag tag, IntHolder len, bool saveData)
|
||||
{
|
||||
var nbytes = DecodeTagAndLength(tag);
|
||||
var byteCount = base.ByteCount;
|
||||
|
||||
if (nbytes > 0)
|
||||
{
|
||||
if (saveData)
|
||||
{
|
||||
Capture(nbytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
Skip(nbytes);
|
||||
}
|
||||
}
|
||||
else if (nbytes == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
MovePastEoc(saveData);
|
||||
}
|
||||
|
||||
len.Value = base.ByteCount - byteCount;
|
||||
}
|
||||
|
||||
public virtual void DecodeTag(Asn1Tag tag)
|
||||
{
|
||||
var num = Read();
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
tag.Class = (short)(num & 0xc0);
|
||||
tag.Form = (short)(num & 0x20);
|
||||
tag.IdCode = num & 0x1f;
|
||||
|
||||
if (tag.IdCode == 0x1f)
|
||||
{
|
||||
var num2 = 0L;
|
||||
var num3 = 0;
|
||||
|
||||
do
|
||||
{
|
||||
num = Read();
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
num2 = (num2 * 0x80L) + (num & 0x7f);
|
||||
|
||||
if ((num2 > 0x7fffffffL) || (num3++ > 8))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidTagValue);
|
||||
}
|
||||
|
||||
}
|
||||
while ((num & 0x80) != 0);
|
||||
|
||||
tag.IdCode = (int)num2;
|
||||
}
|
||||
|
||||
_lastParsedTag = tag;
|
||||
}
|
||||
|
||||
public virtual int DecodeTagAndLength(Asn1Tag tag)
|
||||
{
|
||||
DecodeTag(tag);
|
||||
return DecodeLength();
|
||||
}
|
||||
|
||||
public virtual bool MatchTag(Asn1Tag tag)
|
||||
{
|
||||
return MatchTag(tag.Class, tag.Form, tag.IdCode, null, null);
|
||||
}
|
||||
|
||||
public virtual bool MatchTag(Asn1Tag tag, Asn1Tag parsedTag, IntHolder parsedLen)
|
||||
{
|
||||
return MatchTag(tag.Class, tag.Form, tag.IdCode, parsedTag, parsedLen);
|
||||
}
|
||||
|
||||
public virtual bool MatchTag(short tagClass, short tagForm, int tagIdCode, Asn1Tag parsedTag, IntHolder parsedLen)
|
||||
{
|
||||
Mark();
|
||||
|
||||
var tag = parsedTag ?? _tagHolder;
|
||||
var holder = parsedLen ?? _lenHolder;
|
||||
|
||||
holder.Value = DecodeTagAndLength(tag);
|
||||
|
||||
if (!tag.Equals(tagClass, tagForm, tagIdCode))
|
||||
{
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void MovePastEoc(bool saveData)
|
||||
{
|
||||
var tag = new Asn1Tag();
|
||||
var num = 1;
|
||||
|
||||
while (num > 0)
|
||||
{
|
||||
var nbytes = DecodeTagAndLength(tag);
|
||||
|
||||
if (nbytes > 0)
|
||||
{
|
||||
if (saveData)
|
||||
{
|
||||
Capture(nbytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
Skip(nbytes);
|
||||
}
|
||||
}
|
||||
else if (nbytes == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
num++;
|
||||
}
|
||||
else if (tag.IsEoc() && (nbytes == 0))
|
||||
{
|
||||
num--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Parse(IAsn1TaggedEventHandler handler)
|
||||
{
|
||||
if (_parserCaptureBuffer == null)
|
||||
{
|
||||
RemoveCaptureBuffer(_parserCaptureBuffer);
|
||||
}
|
||||
|
||||
if (_parserCaptureBuffer == null)
|
||||
{
|
||||
_parserCaptureBuffer = new MemoryStream(0x100);
|
||||
AddCaptureBuffer(_parserCaptureBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
_parserCaptureBuffer.Seek(0L, SeekOrigin.Begin);
|
||||
_parserCaptureBuffer.SetLength(0L);
|
||||
}
|
||||
|
||||
ParseElement(handler, _tagHolder, _lenHolder);
|
||||
}
|
||||
|
||||
private void ParseCons(IAsn1TaggedEventHandler handler, int len)
|
||||
{
|
||||
var tag2 = new Asn1Tag();
|
||||
var holder = new IntHolder();
|
||||
var byteCount = base.ByteCount;
|
||||
|
||||
while (true)
|
||||
{
|
||||
ParseElement(handler, tag2, holder);
|
||||
|
||||
if (len == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
if (tag2.IsEoc() && (holder.Value == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((base.ByteCount - byteCount) >= len)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseElement(IAsn1TaggedEventHandler handler, Asn1Tag tag, IntHolder len)
|
||||
{
|
||||
_parserCaptureBuffer.Seek(0L, SeekOrigin.Begin);
|
||||
_parserCaptureBuffer.SetLength(0L);
|
||||
|
||||
len.Value = DecodeTagAndLength(tag);
|
||||
|
||||
if (!tag.IsEoc() || (len.Value != 0))
|
||||
{
|
||||
handler.StartElement(tag, len.Value, _parserCaptureBuffer.ToArray());
|
||||
|
||||
_parserCaptureBuffer.Seek(0L, SeekOrigin.Begin);
|
||||
_parserCaptureBuffer.SetLength(0L);
|
||||
|
||||
if ((len.Value > 0) || (len.Value == Asn1Status.IndefiniteLength))
|
||||
{
|
||||
if (tag.Constructed)
|
||||
{
|
||||
ParseCons(handler, len.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ParsePrim(handler, len.Value);
|
||||
}
|
||||
}
|
||||
|
||||
handler.EndElement(tag);
|
||||
}
|
||||
}
|
||||
|
||||
private void ParsePrim(IAsn1TaggedEventHandler handler, int len)
|
||||
{
|
||||
var buffer = new byte[len];
|
||||
Read(buffer);
|
||||
handler.Contents(buffer);
|
||||
}
|
||||
|
||||
public virtual Asn1Tag PeekTag()
|
||||
{
|
||||
var parsedTag = new Asn1Tag();
|
||||
PeekTag(parsedTag);
|
||||
return parsedTag;
|
||||
}
|
||||
|
||||
public virtual void PeekTag(Asn1Tag parsedTag)
|
||||
{
|
||||
Mark();
|
||||
DecodeTag(parsedTag);
|
||||
Reset();
|
||||
}
|
||||
|
||||
public override int ReadByte()
|
||||
{
|
||||
return Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1BerDecodeContext
|
||||
{
|
||||
private readonly int _decBufByteCount;
|
||||
private readonly Asn1BerDecodeBuffer _decodeBuffer;
|
||||
private readonly int _elemLength;
|
||||
private readonly Asn1Tag _tagHolder;
|
||||
|
||||
public Asn1BerDecodeContext(Asn1BerDecodeBuffer decodeBuffer, int elemLength)
|
||||
{
|
||||
_decodeBuffer = decodeBuffer;
|
||||
_decBufByteCount = decodeBuffer.ByteCount;
|
||||
_elemLength = elemLength;
|
||||
_tagHolder = new Asn1Tag();
|
||||
}
|
||||
|
||||
public virtual bool Expired()
|
||||
{
|
||||
if (_elemLength == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
var parsedLen = new IntHolder();
|
||||
var flag = _decodeBuffer.MatchTag(0, 0, 0, null, parsedLen);
|
||||
|
||||
if (flag)
|
||||
{
|
||||
_decodeBuffer.Reset();
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
var num = _decodeBuffer.ByteCount - _decBufByteCount;
|
||||
|
||||
return (num >= _elemLength);
|
||||
}
|
||||
|
||||
public virtual bool MatchElemTag(Asn1Tag tag, IntHolder parsedLen, bool advance)
|
||||
{
|
||||
return MatchElemTag(tag.Class, tag.Form, tag.IdCode, parsedLen, advance);
|
||||
}
|
||||
|
||||
public virtual bool MatchElemTag(short tagClass, short tagForm, int tagIdCode, IntHolder parsedLen, bool advance)
|
||||
{
|
||||
if (Expired())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var flag = _decodeBuffer.MatchTag(tagClass, tagForm, tagIdCode, _tagHolder, parsedLen);
|
||||
|
||||
if ((_elemLength != Asn1Status.IndefiniteLength) && (parsedLen.Value != Asn1Status.IndefiniteLength))
|
||||
{
|
||||
var num = _decodeBuffer.ByteCount - _decBufByteCount;
|
||||
|
||||
if ((parsedLen.Value < 0) || (parsedLen.Value > (_elemLength - num)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
}
|
||||
|
||||
if (flag && !advance)
|
||||
{
|
||||
_decodeBuffer.Reset();
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
305
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BerEncodeBuffer.cs
vendored
Normal file
305
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BerEncodeBuffer.cs
vendored
Normal file
@@ -0,0 +1,305 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1BerEncodeBuffer : Asn1EncodeBuffer
|
||||
{
|
||||
public Asn1BerEncodeBuffer()
|
||||
{
|
||||
ByteIndex = SizeIncrement - 1;
|
||||
}
|
||||
|
||||
public Asn1BerEncodeBuffer(int sizeIncrement)
|
||||
: base(sizeIncrement)
|
||||
{
|
||||
ByteIndex = SizeIncrement - 1;
|
||||
}
|
||||
|
||||
public virtual MemoryStream ByteArrayInputStream
|
||||
{
|
||||
get
|
||||
{
|
||||
var index = ByteIndex + 1;
|
||||
return new MemoryStream(Data, index, Data.Length - index);
|
||||
}
|
||||
}
|
||||
|
||||
public override byte[] MsgCopy
|
||||
{
|
||||
get
|
||||
{
|
||||
var sourceIndex = ByteIndex + 1;
|
||||
var length = Data.Length - sourceIndex;
|
||||
var destinationArray = new byte[length];
|
||||
|
||||
Array.Copy(Data, sourceIndex, destinationArray, 0, length);
|
||||
|
||||
return destinationArray;
|
||||
}
|
||||
}
|
||||
|
||||
public override int MsgLength
|
||||
{
|
||||
get
|
||||
{
|
||||
var num = ByteIndex + 1;
|
||||
return (Data.Length - num);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void BinDump()
|
||||
{
|
||||
BinDump(null);
|
||||
}
|
||||
|
||||
public override void BinDump(StreamWriter outs, string varName)
|
||||
{
|
||||
var buffer = new Asn1BerDecodeBuffer(ByteArrayInputStream);
|
||||
|
||||
try
|
||||
{
|
||||
buffer.Parse(new Asn1BerMessageDumpHandler(outs));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Console.Out.WriteLine(exception.Message);
|
||||
Console.Error.Write(exception.StackTrace);
|
||||
Console.Error.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
protected internal override void CheckSize(int bytesRequired)
|
||||
{
|
||||
if (bytesRequired > (ByteIndex + 1))
|
||||
{
|
||||
var num = ((bytesRequired - 1) / SizeIncrement) + 1;
|
||||
var num2 = num * SizeIncrement;
|
||||
var destinationArray = new byte[Data.Length + num2];
|
||||
var destinationIndex = (ByteIndex + num2) + 1;
|
||||
var length = Data.Length - (ByteIndex + 1);
|
||||
|
||||
Array.Copy(Data, ByteIndex + 1, destinationArray, destinationIndex, length);
|
||||
|
||||
Data = destinationArray;
|
||||
ByteIndex = destinationIndex - 1;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Copy(byte data)
|
||||
{
|
||||
if (ByteIndex < 0)
|
||||
{
|
||||
CheckSize(1);
|
||||
}
|
||||
|
||||
Data[ByteIndex--] = data;
|
||||
}
|
||||
|
||||
public override void Copy(byte[] data)
|
||||
{
|
||||
CheckSize(data.Length);
|
||||
ByteIndex -= data.Length;
|
||||
|
||||
Array.Copy(data, 0, Data, ByteIndex + 1, data.Length);
|
||||
}
|
||||
|
||||
public virtual void Copy(string data)
|
||||
{
|
||||
var length = data.Length;
|
||||
CheckSize(length);
|
||||
ByteIndex -= length;
|
||||
|
||||
for (var i = 0; i < length; ++i)
|
||||
{
|
||||
Data[(ByteIndex + i) + 1] = (byte)data[i];
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Copy(byte[] data, int startOffset, int length)
|
||||
{
|
||||
CheckSize(length);
|
||||
ByteIndex -= length;
|
||||
|
||||
Array.Copy(data, startOffset, Data, ByteIndex + 1, length);
|
||||
}
|
||||
|
||||
public virtual int EncodeIdentifier(int ident)
|
||||
{
|
||||
var flag = true;
|
||||
var num = 0;
|
||||
var num2 = ident;
|
||||
|
||||
do
|
||||
{
|
||||
if (ByteIndex < 0)
|
||||
{
|
||||
CheckSize(1);
|
||||
}
|
||||
|
||||
Data[ByteIndex] = (byte)(num2 % 0x80);
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
Data[ByteIndex] = (byte)(Data[ByteIndex] | 0x80);
|
||||
}
|
||||
else
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
|
||||
ByteIndex--;
|
||||
num2 /= 0x80;
|
||||
num++;
|
||||
|
||||
}
|
||||
while (num2 > 0);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public virtual int EncodeIntValue(long ivalue)
|
||||
{
|
||||
long num2;
|
||||
long num = ivalue;
|
||||
|
||||
var num3 = 0;
|
||||
|
||||
do
|
||||
{
|
||||
num2 = num % 0x100L;
|
||||
num /= 0x100L;
|
||||
|
||||
if ((num < 0L) && (num2 != 0L))
|
||||
{
|
||||
num -= 1L;
|
||||
}
|
||||
|
||||
Copy((byte)num2);
|
||||
|
||||
num3++;
|
||||
}
|
||||
while ((num != 0L) && (num != -1L));
|
||||
|
||||
if ((ivalue > 0L) && ((num2 & 0x80L) == 0x80L))
|
||||
{
|
||||
Copy(0);
|
||||
num3++;
|
||||
return num3;
|
||||
}
|
||||
|
||||
if ((ivalue < 0L) && ((num2 & 0x80L) == 0L))
|
||||
{
|
||||
Copy(0xff);
|
||||
num3++;
|
||||
}
|
||||
|
||||
return num3;
|
||||
}
|
||||
|
||||
public virtual int EncodeLength(int len)
|
||||
{
|
||||
var num = 0;
|
||||
|
||||
bool flag;
|
||||
|
||||
if (len >= 0)
|
||||
{
|
||||
flag = len > 0x7f;
|
||||
|
||||
var num2 = len;
|
||||
|
||||
do
|
||||
{
|
||||
if (ByteIndex < 0)
|
||||
{
|
||||
CheckSize(1);
|
||||
}
|
||||
|
||||
Data[ByteIndex--] = (byte)(num2 % 0x100);
|
||||
num++;
|
||||
num2 /= 0x100;
|
||||
}
|
||||
while (num2 > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
flag = len == Asn1Status.IndefiniteLength;
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
if (ByteIndex < 0)
|
||||
{
|
||||
CheckSize(1);
|
||||
}
|
||||
|
||||
Data[ByteIndex--] = (byte)(num | 0x80);
|
||||
num++;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public virtual int EncodeTag(Asn1Tag tag)
|
||||
{
|
||||
var num = (byte)(((byte)tag.Class) | ((byte)tag.Form));
|
||||
var num2 = 0;
|
||||
|
||||
if (tag.IdCode < 0x1f)
|
||||
{
|
||||
Copy((byte)(num | tag.IdCode));
|
||||
num2++;
|
||||
return num2;
|
||||
}
|
||||
|
||||
num2 += EncodeIdentifier(tag.IdCode);
|
||||
Copy((byte)(num | 0x1f));
|
||||
num2++;
|
||||
|
||||
return num2;
|
||||
}
|
||||
|
||||
public virtual int EncodeTagAndLength(Asn1Tag tag, int len)
|
||||
{
|
||||
return (EncodeLength(len) + EncodeTag(tag));
|
||||
}
|
||||
|
||||
public virtual int EncodeTagAndLength(short tagClass, short tagForm, int tagIdCode, int len)
|
||||
{
|
||||
var tag = new Asn1Tag(tagClass, tagForm, tagIdCode);
|
||||
return EncodeTagAndLength(tag, len);
|
||||
}
|
||||
|
||||
public override Stream GetInputStream()
|
||||
{
|
||||
return ByteArrayInputStream;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
ByteIndex = Data.Length - 1;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var num = ByteIndex + 1;
|
||||
var num2 = Data.Length - num;
|
||||
var str = new StringBuilder("").ToString();
|
||||
|
||||
for (var i = 0; i < num2; ++i)
|
||||
{
|
||||
str = str + Asn1Util.ToHexString(Data[i + num]);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
public override void Write(Stream outs)
|
||||
{
|
||||
var offset = ByteIndex + 1;
|
||||
outs.Write(Data, offset, Data.Length - offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1BerInputStream : Asn1BerDecodeBuffer, IAsn1InputStream
|
||||
{
|
||||
public Asn1BerInputStream(Stream inputStream)
|
||||
: base(inputStream)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int Available()
|
||||
{
|
||||
var inputStream = GetInputStream();
|
||||
|
||||
if (inputStream != null)
|
||||
{
|
||||
var num = inputStream.Length - inputStream.Position;
|
||||
return (int)num;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
var inputStream = GetInputStream();
|
||||
|
||||
if (inputStream != null)
|
||||
{
|
||||
inputStream.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool MarkSupported()
|
||||
{
|
||||
var inputStream = GetInputStream();
|
||||
return ((inputStream != null) && inputStream.CanSeek);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1BerMessageDumpHandler : IAsn1TaggedEventHandler
|
||||
{
|
||||
private const int MaxBytesPerLine = 12;
|
||||
|
||||
private int _offset;
|
||||
private readonly StreamWriter _printStream;
|
||||
|
||||
public Asn1BerMessageDumpHandler()
|
||||
{
|
||||
_printStream = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = true };
|
||||
_offset = 0;
|
||||
}
|
||||
|
||||
public Asn1BerMessageDumpHandler(StreamWriter outs)
|
||||
{
|
||||
_printStream = outs;
|
||||
_offset = 0;
|
||||
}
|
||||
|
||||
public virtual void Contents(byte[] data)
|
||||
{
|
||||
if (data.Length != 0)
|
||||
{
|
||||
PrintOffset();
|
||||
|
||||
var flag = true;
|
||||
var builder = new StringBuilder(100);
|
||||
var builder2 = new StringBuilder(100);
|
||||
|
||||
for (var i = 0; i < data.Length; ++i)
|
||||
{
|
||||
builder.Append(Asn1Util.ToHexString(data[i]));
|
||||
builder.Append(' ');
|
||||
|
||||
int num2 = data[i];
|
||||
|
||||
if ((num2 >= 0x20) && (num2 <= 0x7f))
|
||||
{
|
||||
builder2.Append((char)num2);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder2.Append('.');
|
||||
}
|
||||
|
||||
if (((i + 1) % MaxBytesPerLine) == 0)
|
||||
{
|
||||
if (!flag)
|
||||
{
|
||||
_printStream.Write(" : ");
|
||||
}
|
||||
else
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
|
||||
_printStream.WriteLine(builder + ": " + builder2);
|
||||
|
||||
builder.Length = 0;
|
||||
builder2.Length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (builder.Length > 0)
|
||||
{
|
||||
while (builder.Length < 0x24)
|
||||
{
|
||||
builder.Append(' ');
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
_printStream.Write(" : ");
|
||||
}
|
||||
|
||||
_printStream.WriteLine(builder + ": " + builder2);
|
||||
}
|
||||
|
||||
_offset += data.Length;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EndElement(Asn1Tag tag)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void StartElement(Asn1Tag tag, int len, byte[] tagLenBytes)
|
||||
{
|
||||
PrintOffset();
|
||||
|
||||
new StringBuilder(40); // WTF?
|
||||
|
||||
var index = 0;
|
||||
|
||||
while (index < tagLenBytes.Length)
|
||||
{
|
||||
_printStream.Write(Asn1Util.ToHexString(tagLenBytes[index]));
|
||||
_printStream.Write(' ');
|
||||
index++;
|
||||
}
|
||||
|
||||
while (index < MaxBytesPerLine)
|
||||
{
|
||||
_printStream.Write(" ");
|
||||
index++;
|
||||
}
|
||||
|
||||
_printStream.Write(": ");
|
||||
_printStream.Write(tag.Constructed ? "C " : "P ");
|
||||
_printStream.Write(tag + " ");
|
||||
_printStream.WriteLine(Convert.ToString(len));
|
||||
_offset += tagLenBytes.Length;
|
||||
}
|
||||
|
||||
private void PrintOffset()
|
||||
{
|
||||
var str = Convert.ToString(_offset);
|
||||
var num = 4 - str.Length;
|
||||
|
||||
for (var i = 0; i < num; ++i)
|
||||
{
|
||||
_printStream.Write('0');
|
||||
}
|
||||
|
||||
_printStream.Write(str);
|
||||
_printStream.Write(" : ");
|
||||
}
|
||||
}
|
||||
}
|
||||
277
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BerOutputStream.cs
vendored
Normal file
277
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BerOutputStream.cs
vendored
Normal file
@@ -0,0 +1,277 @@
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1BerOutputStream : Asn1OutputStream
|
||||
{
|
||||
private static readonly byte[] Eoc = new byte[2];
|
||||
|
||||
public Asn1BerOutputStream(Stream outputStream)
|
||||
: base(new BufferedStream(outputStream))
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1BerOutputStream(Stream outputStream, int bufSize)
|
||||
: base((bufSize == 0) ? outputStream : new BufferedStream(outputStream, bufSize))
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Encode(Asn1Type type, bool explicitTagging)
|
||||
{
|
||||
type.Encode(this, explicitTagging);
|
||||
}
|
||||
|
||||
public virtual void EncodeBitString(byte[] data, int numbits, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
}
|
||||
|
||||
var count = (numbits + 7) / 8;
|
||||
EncodeLength(count + 1);
|
||||
|
||||
var num2 = numbits % 8;
|
||||
|
||||
if (num2 != 0)
|
||||
{
|
||||
num2 = 8 - num2;
|
||||
data[count - 1] = (byte)(data[count - 1] & ((byte)~((1 << num2) - 1)));
|
||||
}
|
||||
|
||||
OutputStream.WriteByte((byte)num2);
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
OutputStream.Write(data, 0, count);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeBmpString(string data, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
}
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
EncodeLength(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeLength(data.Length * 2);
|
||||
|
||||
var length = data.Length;
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var num3 = data[i];
|
||||
var num2 = num3 / 0x100;
|
||||
var num = num3 % 0x100;
|
||||
|
||||
OutputStream.WriteByte((byte)num2);
|
||||
OutputStream.WriteByte((byte)num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeCharString(string data, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
}
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
EncodeLength(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeLength(data.Length);
|
||||
var buffer = Asn1Util.ToByteArray(data);
|
||||
OutputStream.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeEoc()
|
||||
{
|
||||
OutputStream.Write(Eoc, 0, Eoc.Length);
|
||||
}
|
||||
|
||||
public virtual void EncodeIdentifier(long ident)
|
||||
{
|
||||
var number = 0x7fL;
|
||||
var identBytesCount = Asn1RunTime.GetIdentBytesCount(ident);
|
||||
|
||||
number = number << (7 * identBytesCount);
|
||||
|
||||
if (identBytesCount > 0)
|
||||
{
|
||||
while (identBytesCount > 0)
|
||||
{
|
||||
number = Asn1Util.UrShift(number, 7);
|
||||
identBytesCount--;
|
||||
|
||||
var num3 = Asn1Util.UrShift(ident & number, identBytesCount * 7);
|
||||
|
||||
if (identBytesCount != 0)
|
||||
{
|
||||
num3 |= 0x80L;
|
||||
}
|
||||
|
||||
OutputStream.WriteByte((byte)num3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputStream.WriteByte(0);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeIntValue(long data, bool encodeLen)
|
||||
{
|
||||
long num2;
|
||||
var num = data;
|
||||
var buffer = new byte[9];
|
||||
var len = 0;
|
||||
var length = buffer.Length;
|
||||
|
||||
do
|
||||
{
|
||||
num2 = num % 0x100L;
|
||||
num /= 0x100L;
|
||||
|
||||
if ((num < 0L) && (num2 != 0L))
|
||||
{
|
||||
num -= 1L;
|
||||
}
|
||||
|
||||
buffer[--length] = (byte)num2;
|
||||
len++;
|
||||
}
|
||||
while ((num != 0L) && (num != -1L));
|
||||
|
||||
if ((data > 0L) && ((num2 & 0x80L) == 0x80L))
|
||||
{
|
||||
buffer[--length] = 0;
|
||||
len++;
|
||||
}
|
||||
else if ((data < 0L) && ((num2 & 0x80L) == 0L))
|
||||
{
|
||||
buffer[--length] = 0xff;
|
||||
len++;
|
||||
}
|
||||
|
||||
if (encodeLen)
|
||||
{
|
||||
EncodeLength(len);
|
||||
}
|
||||
|
||||
OutputStream.Write(buffer, length, len);
|
||||
}
|
||||
|
||||
public virtual void EncodeLength(int len)
|
||||
{
|
||||
if (len >= 0)
|
||||
{
|
||||
var bytesCount = Asn1Util.GetBytesCount(len);
|
||||
|
||||
if (len > 0x7f)
|
||||
{
|
||||
OutputStream.WriteByte((byte)(bytesCount | 0x80));
|
||||
}
|
||||
for (var i = (8 * bytesCount) - 8; i >= 0; i -= 8)
|
||||
{
|
||||
var num3 = (byte)((len >> i) & 0xff);
|
||||
OutputStream.WriteByte(num3);
|
||||
}
|
||||
}
|
||||
else if (len == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
OutputStream.WriteByte(0x80);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeOctetString(byte[] data, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
}
|
||||
if (data == null)
|
||||
{
|
||||
EncodeLength(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeLength(data.Length);
|
||||
OutputStream.Write(data, 0, data.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeTag(Asn1Tag tag)
|
||||
{
|
||||
var num = (byte)(((byte)tag.Class) | ((byte)tag.Form));
|
||||
if (tag.IdCode < 0x1f)
|
||||
{
|
||||
OutputStream.WriteByte((byte)(num | tag.IdCode));
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputStream.WriteByte((byte)(num | 0x1f));
|
||||
EncodeIdentifier(tag.IdCode);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeTag(short tagClass, short tagForm, int tagIdCode)
|
||||
{
|
||||
EncodeTag(new Asn1Tag(tagClass, tagForm, tagIdCode));
|
||||
}
|
||||
|
||||
public virtual void EncodeTagAndIndefLen(Asn1Tag tag)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
OutputStream.WriteByte(0x80);
|
||||
}
|
||||
|
||||
public virtual void EncodeTagAndIndefLen(short tagClass, short tagForm, int tagIdCode)
|
||||
{
|
||||
EncodeTag(new Asn1Tag(tagClass, tagForm, tagIdCode));
|
||||
OutputStream.WriteByte(0x80);
|
||||
}
|
||||
|
||||
public virtual void EncodeTagAndLength(Asn1Tag tag, int len)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
EncodeLength(len);
|
||||
}
|
||||
|
||||
public virtual void EncodeUnivString(int[] data, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
}
|
||||
if (data == null)
|
||||
{
|
||||
EncodeLength(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeLength(data.Length * 4);
|
||||
var length = data.Length;
|
||||
|
||||
for (var i = 0; i < length; ++i)
|
||||
{
|
||||
var number = data[i];
|
||||
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 0x18) & 0xff));
|
||||
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 0x10) & 0xff));
|
||||
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 8) & 0xff));
|
||||
OutputStream.WriteByte((byte)(number & 0xff));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
137
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BigInteger.cs
vendored
Normal file
137
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BigInteger.cs
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
using System;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1BigInteger : Asn1Type
|
||||
{
|
||||
private const int MaxBigIntLen = 0x186a0;
|
||||
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BigIntegerTypeCode);
|
||||
public static readonly BigInteger Zero = new BigInteger();
|
||||
|
||||
private BigInteger _value;
|
||||
|
||||
public Asn1BigInteger()
|
||||
{
|
||||
_value = new BigInteger();
|
||||
}
|
||||
|
||||
public Asn1BigInteger(BigInteger value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public Asn1BigInteger(string value)
|
||||
{
|
||||
_value = new BigInteger(value);
|
||||
}
|
||||
|
||||
public Asn1BigInteger(string value, int radix)
|
||||
{
|
||||
_value = new BigInteger(value, radix);
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
_value = DecodeValue(buffer, length);
|
||||
buffer.TypeCode = 2;
|
||||
}
|
||||
|
||||
public BigInteger DecodeValue(Asn1DecodeBuffer buffer, int length)
|
||||
{
|
||||
var ivalue = new byte[length];
|
||||
|
||||
if (length > MaxBigIntLen)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1TooBigIntegerValue, length);
|
||||
}
|
||||
|
||||
for (var i = 0; i < length; ++i)
|
||||
{
|
||||
ivalue[i] = (byte)buffer.ReadByte();
|
||||
}
|
||||
|
||||
var integer = new BigInteger();
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
integer.SetData(ivalue);
|
||||
}
|
||||
|
||||
return integer;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = EncodeValue(buffer, _value, true);
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
var buffer = new Asn1BerEncodeBuffer();
|
||||
var len = EncodeValue(buffer, _value, true);
|
||||
|
||||
outs.EncodeLength(len);
|
||||
outs.Write(buffer.MsgCopy);
|
||||
}
|
||||
|
||||
private static int EncodeValue(Asn1EncodeBuffer buffer, BigInteger ivalue, bool doCopy)
|
||||
{
|
||||
var data = ivalue.GetData();
|
||||
var length = data.Length;
|
||||
|
||||
for (var i = length - 1; i >= 0; --i)
|
||||
{
|
||||
if (doCopy)
|
||||
{
|
||||
buffer.Copy(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
public virtual bool Equals(long value)
|
||||
{
|
||||
return _value.Equals(value);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var integer = value as Asn1BigInteger;
|
||||
|
||||
if (integer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _value.Equals(integer._value);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _value.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return _value.ToString(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
455
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BitString.cs
vendored
Normal file
455
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BitString.cs
vendored
Normal file
@@ -0,0 +1,455 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1BitString : Asn1Type
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BitStringTypeCode);
|
||||
|
||||
[NonSerialized]
|
||||
public byte[] Value;
|
||||
|
||||
[NonSerialized]
|
||||
public int NumBits;
|
||||
|
||||
public Asn1BitString()
|
||||
{
|
||||
NumBits = 0;
|
||||
Value = null;
|
||||
}
|
||||
|
||||
public Asn1BitString(bool[] bitValues)
|
||||
{
|
||||
AllocBitArray(bitValues.Length);
|
||||
|
||||
var index = 0;
|
||||
var num4 = 0x80;
|
||||
var num = 0;
|
||||
var num2 = 0;
|
||||
|
||||
while (num < bitValues.Length)
|
||||
{
|
||||
if (bitValues[num])
|
||||
{
|
||||
num2 |= num4;
|
||||
}
|
||||
|
||||
num4 = num4 >> 1;
|
||||
|
||||
if (num4 == 0)
|
||||
{
|
||||
Value[index++] = (byte)num2;
|
||||
num4 = 0x80;
|
||||
num2 = 0;
|
||||
}
|
||||
|
||||
num++;
|
||||
}
|
||||
|
||||
if (num4 != 0x80)
|
||||
{
|
||||
Value[index] = (byte)num2;
|
||||
}
|
||||
}
|
||||
|
||||
public Asn1BitString(BitArray bitArray)
|
||||
{
|
||||
AllocBitArray(bitArray.Length);
|
||||
|
||||
var index = 0;
|
||||
var num4 = 0x80;
|
||||
var num = 0;
|
||||
var num2 = 0;
|
||||
|
||||
while (num < bitArray.Length)
|
||||
{
|
||||
if (bitArray.Get(num))
|
||||
{
|
||||
num2 |= num4;
|
||||
}
|
||||
|
||||
num4 = num4 >> 1;
|
||||
|
||||
if (num4 == 0)
|
||||
{
|
||||
Value[index++] = (byte)num2;
|
||||
num4 = 0x80;
|
||||
num2 = 0;
|
||||
}
|
||||
|
||||
num++;
|
||||
}
|
||||
|
||||
if (num4 != 0x80)
|
||||
{
|
||||
Value[index] = (byte)num2;
|
||||
}
|
||||
}
|
||||
|
||||
public Asn1BitString(string value)
|
||||
{
|
||||
var numbits = new IntHolder();
|
||||
Value = Asn1Value.ParseString(value, numbits);
|
||||
|
||||
NumBits = numbits.Value;
|
||||
}
|
||||
|
||||
public Asn1BitString(int numBits, byte[] data)
|
||||
{
|
||||
NumBits = numBits;
|
||||
Value = data;
|
||||
}
|
||||
|
||||
private void AllocBitArray(int numbits)
|
||||
{
|
||||
NumBits = numbits;
|
||||
|
||||
var num = (NumBits + 7) / 8;
|
||||
|
||||
if ((Value == null) || (Value.Length < num))
|
||||
{
|
||||
Value = new byte[num];
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Clear(int bitIndex)
|
||||
{
|
||||
this[bitIndex] = false;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var elemLength = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
var lastTag = buffer.LastTag;
|
||||
|
||||
if ((lastTag == null) || !lastTag.Constructed)
|
||||
{
|
||||
if (elemLength < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
if (elemLength != 0)
|
||||
{
|
||||
var num8 = elemLength - 1;
|
||||
var num7 = buffer.Read();
|
||||
|
||||
if (num7 < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
if ((num7 < 0) || (num7 > 7))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfBitString, num7);
|
||||
}
|
||||
|
||||
if ((num8 == 0) && (num7 != 0))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
NumBits = (num8 * 8) - num7;
|
||||
Value = new byte[num8];
|
||||
buffer.Read(Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
NumBits = 0;
|
||||
Value = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var num3 = 0;
|
||||
var offset = 0;
|
||||
var index = -1;
|
||||
var num6 = 0;
|
||||
|
||||
var context = new Asn1BerDecodeContext(buffer, elemLength);
|
||||
|
||||
while (!context.Expired())
|
||||
{
|
||||
var nbytes = MatchTag(buffer, Tag);
|
||||
|
||||
if (nbytes <= 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
|
||||
num3 += nbytes;
|
||||
|
||||
if (offset == 0)
|
||||
{
|
||||
AllocBitArray(num3 * 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReallocBitArray(num3 * 8);
|
||||
}
|
||||
|
||||
index = offset;
|
||||
buffer.Read(Value, offset, nbytes);
|
||||
offset = num3;
|
||||
}
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
num6 = Value[index];
|
||||
|
||||
if (((offset - index) - 1) > 0)
|
||||
{
|
||||
Array.Copy(Value, index + 1, Value, index, (offset - index) - 1);
|
||||
}
|
||||
|
||||
num3--;
|
||||
}
|
||||
|
||||
if ((num6 < 0) || (num6 > 7))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfBitString, num6);
|
||||
}
|
||||
|
||||
ReallocBitArray((num3 * 8) - num6);
|
||||
|
||||
if (elemLength == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
MatchTag(buffer, Asn1Tag.Eoc);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.TypeCode = 3;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var length = (NumBits + 7) / 8;
|
||||
var num2 = NumBits % 8;
|
||||
|
||||
if (num2 != 0)
|
||||
{
|
||||
num2 = 8 - num2;
|
||||
Value[length - 1] = (byte)(Value[length - 1] & ((byte)~((1 << num2) - 1)));
|
||||
}
|
||||
|
||||
if (length != 0)
|
||||
{
|
||||
buffer.Copy(Value, 0, length);
|
||||
}
|
||||
|
||||
buffer.Copy((byte)num2);
|
||||
length++;
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
length += buffer.EncodeTagAndLength(Tag, length);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeBitString(Value, NumBits, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var str = value as Asn1BitString;
|
||||
|
||||
if (str == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals(str.NumBits, str.Value);
|
||||
}
|
||||
|
||||
public virtual bool Equals(int nbits, byte[] value)
|
||||
{
|
||||
if (nbits != NumBits)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var num = ((nbits - 1) / 8) + 1;
|
||||
|
||||
for (var i = 0; i < num; ++i)
|
||||
{
|
||||
if (value[i] != Value[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool Get(int bitno)
|
||||
{
|
||||
var index = bitno / 8;
|
||||
var num2 = 1 << (7 - (bitno % 8));
|
||||
|
||||
if ((Value != null) && (Value.Length >= index))
|
||||
{
|
||||
int num3 = Value[index];
|
||||
return ((num3 & num2) != 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (Value != null) ? Value.GetHashCode() : base.GetHashCode();
|
||||
}
|
||||
|
||||
private void ReallocBitArray(int numbits)
|
||||
{
|
||||
NumBits = numbits;
|
||||
var num = (NumBits + 7) / 8;
|
||||
|
||||
if (Value.Length != num)
|
||||
{
|
||||
var value = Value;
|
||||
Value = new byte[num];
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
Array.Copy(value, 0, Value, 0, Math.Min(value.Length, num));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Set(int bitIndex)
|
||||
{
|
||||
Set(bitIndex, true);
|
||||
}
|
||||
|
||||
public virtual void Set(int bitIndex, bool value)
|
||||
{
|
||||
var index = bitIndex / 8;
|
||||
var num2 = 1 << (7 - (bitIndex % 8));
|
||||
var num3 = index + 1;
|
||||
|
||||
if (Value == null)
|
||||
{
|
||||
Value = new byte[num3];
|
||||
}
|
||||
else if (Value.Length < num3)
|
||||
{
|
||||
var destinationArray = new byte[num3];
|
||||
Array.Copy(Value, 0, destinationArray, 0, Value.Length);
|
||||
Value = destinationArray;
|
||||
}
|
||||
|
||||
int num4 = Value[index];
|
||||
num4 = value ? (num4 | num2) : (num4 & ~num2);
|
||||
Value[index] = (byte)num4;
|
||||
|
||||
if ((bitIndex + 1) > NumBits)
|
||||
{
|
||||
NumBits = bitIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool[] ToBoolArray()
|
||||
{
|
||||
var flagArray = new bool[NumBits];
|
||||
|
||||
var num4 = 0;
|
||||
var numbits = NumBits;
|
||||
|
||||
foreach (var num3 in Value)
|
||||
{
|
||||
var num5 = 0x80;
|
||||
var num = (numbits < 8) ? numbits : 8;
|
||||
|
||||
for (var j = 0; j < num; ++j)
|
||||
{
|
||||
flagArray[num4++] = (num3 & num5) != 0;
|
||||
num5 = num5 >> 1;
|
||||
}
|
||||
|
||||
numbits -= 8;
|
||||
}
|
||||
|
||||
return flagArray;
|
||||
}
|
||||
|
||||
public virtual string ToHexString()
|
||||
{
|
||||
var str = new StringBuilder("").ToString();
|
||||
|
||||
foreach (var b in Value)
|
||||
{
|
||||
str = str + Asn1Util.ToHexString(b);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var str = new StringBuilder("").ToString();
|
||||
|
||||
if (NumBits <= 0x10)
|
||||
{
|
||||
if (NumBits != 0)
|
||||
{
|
||||
var flagArray = ToBoolArray();
|
||||
|
||||
foreach (bool b in flagArray)
|
||||
{
|
||||
str = str + (b ? "1" : "0");
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
var num2 = 4;
|
||||
var capacity = (NumBits + 3) / 4;
|
||||
var builder = new StringBuilder(capacity);
|
||||
|
||||
if (Value != null)
|
||||
{
|
||||
var num4 = 0;
|
||||
var index = 0;
|
||||
|
||||
while (num4 < capacity)
|
||||
{
|
||||
var num6 = (Value[index] >> num2) & 15;
|
||||
builder.Append((char)(num6 + ((num6 >= 10) ? 0x57 : 0x30)));
|
||||
num2 -= 4;
|
||||
|
||||
if (num2 < 0)
|
||||
{
|
||||
num2 = 4;
|
||||
index++;
|
||||
}
|
||||
|
||||
num4++;
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public virtual bool this[int bitIndex]
|
||||
{
|
||||
get { return Get(bitIndex); }
|
||||
set { Set(bitIndex, value); }
|
||||
}
|
||||
|
||||
public override int Length
|
||||
{
|
||||
get { return NumBits; }
|
||||
}
|
||||
}
|
||||
}
|
||||
125
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BmpString.cs
vendored
Normal file
125
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1BmpString.cs
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1BmpString : Asn1CharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BmpStringTypeCode);
|
||||
|
||||
public Asn1BmpString()
|
||||
: base(BmpStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1BmpString(string data)
|
||||
: base(data, BmpStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var elemLength = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
var len = elemLength;
|
||||
var sb = new StringBuilder();
|
||||
|
||||
var lastTag = buffer.LastTag;
|
||||
|
||||
if ((lastTag == null) || !lastTag.Constructed)
|
||||
{
|
||||
sb.EnsureCapacity(elemLength / 2);
|
||||
ReadSegment(buffer, sb, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
var capacity = 0;
|
||||
var context = new Asn1BerDecodeContext(buffer, elemLength);
|
||||
|
||||
while (!context.Expired())
|
||||
{
|
||||
var num3 = MatchTag(buffer, Asn1OctetString.Tag);
|
||||
|
||||
if (num3 <= 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
|
||||
capacity += num3;
|
||||
sb.EnsureCapacity(capacity);
|
||||
ReadSegment(buffer, sb, num3);
|
||||
}
|
||||
|
||||
if (elemLength == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
MatchTag(buffer, Asn1Tag.Eoc);
|
||||
}
|
||||
}
|
||||
|
||||
Value = sb.ToString();
|
||||
buffer.TypeCode = BmpStringTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var length = Value.Length;
|
||||
|
||||
for (var i = length - 1; i >= 0; --i)
|
||||
{
|
||||
var num3 = Value[i];
|
||||
var num = num3 % 0x100;
|
||||
var num2 = num3 / 0x100;
|
||||
|
||||
buffer.Copy((byte)num);
|
||||
buffer.Copy((byte)num2);
|
||||
}
|
||||
|
||||
length *= 2;
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
length += buffer.EncodeTagAndLength(Tag, length);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeBmpString(Value, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
private static void ReadSegment(Asn1DecodeBuffer buffer, StringBuilder sb, int len)
|
||||
{
|
||||
if ((len % 2) != 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
var num = buffer.Read();
|
||||
|
||||
if (num == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
var num2 = num * 0x100;
|
||||
len--;
|
||||
num = buffer.Read();
|
||||
|
||||
if (num == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
num2 += num;
|
||||
len--;
|
||||
sb.Append((char)num2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
102
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Boolean.cs
vendored
Normal file
102
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Boolean.cs
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1Boolean : Asn1Type
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BooleanTypeCode);
|
||||
public static readonly Asn1Boolean FalseValue = new Asn1Boolean(false);
|
||||
public static readonly Asn1Boolean TrueValue = new Asn1Boolean(true);
|
||||
|
||||
[NonSerialized]
|
||||
public bool Value;
|
||||
|
||||
public Asn1Boolean()
|
||||
{
|
||||
Value = false;
|
||||
}
|
||||
|
||||
public Asn1Boolean(bool value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
MatchTag(buffer, Tag);
|
||||
}
|
||||
|
||||
var num = buffer.Read();
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
buffer.TypeCode = BooleanTypeCode;
|
||||
Value = num != 0;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = 1;
|
||||
|
||||
buffer.Copy(Value ? byte.MaxValue : ((byte)0));
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
outs.EncodeLength(1);
|
||||
outs.WriteByte(Value ? -1 : 0);
|
||||
}
|
||||
|
||||
public virtual bool Equals(bool value)
|
||||
{
|
||||
return (Value == value);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var flag = value as Asn1Boolean;
|
||||
|
||||
if (flag == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Value == flag.Value);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (!Value)
|
||||
{
|
||||
return "FALSE";
|
||||
}
|
||||
|
||||
return "TRUE";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1CerInputStream : Asn1BerInputStream
|
||||
{
|
||||
public Asn1CerInputStream(Stream inputStream)
|
||||
: base(inputStream)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
236
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CerOutputStream.cs
vendored
Normal file
236
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CerOutputStream.cs
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1CerOutputStream : Asn1BerOutputStream
|
||||
{
|
||||
public Asn1CerOutputStream(Stream outputStream)
|
||||
: base(outputStream)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1CerOutputStream(Stream outputStream, int bufSize)
|
||||
: base(outputStream, bufSize)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Encode(Asn1Type type, bool explicitTagging)
|
||||
{
|
||||
type.Encode(this, explicitTagging);
|
||||
}
|
||||
|
||||
public override void EncodeBitString(byte[] value, int numbits, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if ((((numbits + 7) / 8) + 1) <= 0x3e8)
|
||||
{
|
||||
base.EncodeBitString(value, numbits, explicitTagging, tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTagAndIndefLen(Asn1BitString.Tag.Class, 0x20, Asn1BitString.Tag.IdCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputStream.WriteByte(0x80);
|
||||
}
|
||||
|
||||
var num = (numbits + 7) / 8;
|
||||
var num2 = numbits % 8;
|
||||
|
||||
if (num2 != 0)
|
||||
{
|
||||
num2 = 8 - num2;
|
||||
value[num - 1] = (byte)(value[num - 1] & ((byte)~((1 << num2) - 1)));
|
||||
}
|
||||
|
||||
for (var i = 0; i < num; i += 0x3e8)
|
||||
{
|
||||
var len = num - i;
|
||||
|
||||
if (len > 0x3e8)
|
||||
{
|
||||
len = 0x3e8;
|
||||
EncodeTagAndLength(Asn1BitString.Tag, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeTagAndLength(Asn1BitString.Tag, len + 1);
|
||||
OutputStream.WriteByte((byte)num2);
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
OutputStream.Write(value, i, len);
|
||||
}
|
||||
}
|
||||
|
||||
EncodeEoc();
|
||||
}
|
||||
}
|
||||
|
||||
public override void EncodeBmpString(string value, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if ((value == null) || (value.Length <= 500))
|
||||
{
|
||||
base.EncodeBmpString(value, explicitTagging, tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTagAndIndefLen(Asn1BmpString.Tag.Class, 0x20, Asn1BmpString.Tag.IdCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputStream.WriteByte(0x80);
|
||||
}
|
||||
|
||||
for (var i = 0; i < value.Length; i += 500)
|
||||
{
|
||||
var num2 = value.Length - i;
|
||||
|
||||
if (num2 > 500)
|
||||
{
|
||||
num2 = 500;
|
||||
}
|
||||
|
||||
EncodeTagAndLength(Asn1OctetString.Tag, num2 * 2);
|
||||
|
||||
for (var j = 0; j < num2; j++)
|
||||
{
|
||||
var num5 = value[j + i];
|
||||
var num4 = num5 / 0x100;
|
||||
|
||||
var num3 = num5 % 0x100;
|
||||
OutputStream.WriteByte((byte)num4);
|
||||
OutputStream.WriteByte((byte)num3);
|
||||
}
|
||||
}
|
||||
|
||||
EncodeEoc();
|
||||
}
|
||||
}
|
||||
|
||||
public override void EncodeCharString(string value, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if ((value == null) || (value.Length <= 0x3e8))
|
||||
{
|
||||
base.EncodeCharString(value, explicitTagging, tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = Asn1Util.ToByteArray(value);
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTag(tag.Class, 0x20, tag.IdCode);
|
||||
}
|
||||
|
||||
EncodeOctetString(data, false, tag);
|
||||
}
|
||||
}
|
||||
|
||||
public override void EncodeOctetString(byte[] value, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if ((value == null) || (value.Length <= 0x3e8))
|
||||
{
|
||||
base.EncodeOctetString(value, explicitTagging, tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTagAndIndefLen(Asn1OctetString.Tag.Class, 0x20, Asn1OctetString.Tag.IdCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputStream.WriteByte(0x80);
|
||||
}
|
||||
|
||||
for (var i = 0; i < value.Length; i += 0x3e8)
|
||||
{
|
||||
var len = value.Length - i;
|
||||
|
||||
if (len > 0x3e8)
|
||||
{
|
||||
len = 0x3e8;
|
||||
}
|
||||
|
||||
EncodeTagAndLength(Asn1OctetString.Tag, len);
|
||||
Write(value, i, len);
|
||||
}
|
||||
|
||||
EncodeEoc();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeStringTag(int nbytes, Asn1Tag tag)
|
||||
{
|
||||
if (nbytes <= 0x3e8)
|
||||
{
|
||||
EncodeTag(tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeTag(tag.Class, 0x20, tag.IdCode);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EncodeStringTag(int nbytes, short tagClass, short tagForm, int tagIdCode)
|
||||
{
|
||||
if (nbytes <= 0x3e8)
|
||||
{
|
||||
EncodeTag(new Asn1Tag(tagClass, tagForm, tagIdCode));
|
||||
}
|
||||
else
|
||||
{
|
||||
EncodeTag(tagClass, 0x20, tagIdCode);
|
||||
}
|
||||
}
|
||||
|
||||
public override void EncodeUnivString(int[] value, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
if ((value == null) || (value.Length <= 250))
|
||||
{
|
||||
base.EncodeUnivString(value, explicitTagging, tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
EncodeTagAndIndefLen(Asn1UniversalString.Tag.Class, 0x20, Asn1UniversalString.Tag.IdCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputStream.WriteByte(0x80);
|
||||
}
|
||||
|
||||
for (var i = 0; i < value.Length; i += 250)
|
||||
{
|
||||
var num2 = value.Length - i;
|
||||
|
||||
if (num2 > 250)
|
||||
{
|
||||
num2 = 250;
|
||||
}
|
||||
|
||||
EncodeTagAndLength(Asn1OctetString.Tag, num2 * 4);
|
||||
|
||||
for (int j = 0; j < num2; j++)
|
||||
{
|
||||
var number = value[j + i];
|
||||
|
||||
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 0x18) & 0xff));
|
||||
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 0x10) & 0xff));
|
||||
OutputStream.WriteByte((byte)(Asn1Util.UrShift(number, 8) & 0xff));
|
||||
OutputStream.WriteByte((byte)(number & 0xff));
|
||||
}
|
||||
}
|
||||
|
||||
EncodeEoc();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CharRange.cs
vendored
Normal file
46
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CharRange.cs
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1CharRange : Asn1CharSet
|
||||
{
|
||||
private readonly int _lower;
|
||||
private readonly int _upper;
|
||||
|
||||
public Asn1CharRange(int lower, int upper)
|
||||
: base((upper - lower) + 1)
|
||||
{
|
||||
_lower = lower;
|
||||
_upper = upper;
|
||||
}
|
||||
|
||||
public override int MaxValue
|
||||
{
|
||||
get { return _upper; }
|
||||
}
|
||||
|
||||
public override int GetCharAtIndex(int index)
|
||||
{
|
||||
index += _lower;
|
||||
|
||||
if (index > _upper)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", index);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
public override int GetCharIndex(int charValue)
|
||||
{
|
||||
var num = charValue - _lower;
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", charValue);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CharSet.cs
vendored
Normal file
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CharSet.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public abstract class Asn1CharSet
|
||||
{
|
||||
private readonly int _aBitsPerChar;
|
||||
private readonly int _uBitsPerChar;
|
||||
|
||||
protected internal Asn1CharSet(int nchars)
|
||||
{
|
||||
_uBitsPerChar = Asn1Integer.GetBitCount(nchars - 1);
|
||||
_aBitsPerChar = 1;
|
||||
|
||||
while (_uBitsPerChar > _aBitsPerChar)
|
||||
{
|
||||
_aBitsPerChar = _aBitsPerChar << 1;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract int MaxValue { get; }
|
||||
|
||||
public abstract int GetCharAtIndex(int index);
|
||||
|
||||
public abstract int GetCharIndex(int charValue);
|
||||
|
||||
public virtual int GetNumBitsPerChar(bool aligned)
|
||||
{
|
||||
if (!aligned)
|
||||
{
|
||||
return _uBitsPerChar;
|
||||
}
|
||||
|
||||
return _aBitsPerChar;
|
||||
}
|
||||
}
|
||||
}
|
||||
156
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CharString.cs
vendored
Normal file
156
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1CharString.cs
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class Asn1CharString : Asn1Type
|
||||
{
|
||||
[NonSerialized]
|
||||
protected StringBuilder StringBuffer;
|
||||
|
||||
[NonSerialized]
|
||||
private readonly short _typeCode;
|
||||
|
||||
[NonSerialized]
|
||||
public string Value;
|
||||
|
||||
|
||||
protected internal Asn1CharString(short typeCode)
|
||||
{
|
||||
Value = new StringBuilder().ToString();
|
||||
_typeCode = typeCode;
|
||||
}
|
||||
|
||||
protected internal Asn1CharString(string data, short typeCode)
|
||||
{
|
||||
Value = data;
|
||||
_typeCode = typeCode;
|
||||
}
|
||||
|
||||
|
||||
public override int Length
|
||||
{
|
||||
get { return Value.Length; }
|
||||
}
|
||||
|
||||
protected virtual void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength, Asn1Tag tag)
|
||||
{
|
||||
int num2;
|
||||
var elemLength = explicitTagging ? MatchTag(buffer, tag) : implicitLength;
|
||||
var num3 = elemLength;
|
||||
var num4 = 0;
|
||||
|
||||
if (StringBuffer == null)
|
||||
{
|
||||
StringBuffer = new StringBuilder();
|
||||
}
|
||||
|
||||
var lastTag = buffer.LastTag;
|
||||
|
||||
if ((lastTag == null) || !lastTag.Constructed)
|
||||
{
|
||||
if (num3 < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
StringBuffer.Length = num3;
|
||||
|
||||
while (num3 > 0)
|
||||
{
|
||||
num2 = buffer.Read();
|
||||
|
||||
if (num2 == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
StringBuffer[num4++] = (char)num2;
|
||||
num3--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var capacity = 0;
|
||||
var context = new Asn1BerDecodeContext(buffer, elemLength);
|
||||
|
||||
while (!context.Expired())
|
||||
{
|
||||
var num5 = MatchTag(buffer, Asn1OctetString.Tag);
|
||||
|
||||
if (num5 <= 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
|
||||
capacity += num5;
|
||||
StringBuffer.EnsureCapacity(capacity);
|
||||
|
||||
while (num5 > 0)
|
||||
{
|
||||
num2 = buffer.Read();
|
||||
|
||||
if (num2 == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
StringBuffer.Append((char)num2);
|
||||
num5--;
|
||||
}
|
||||
}
|
||||
|
||||
if (elemLength == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
MatchTag(buffer, Asn1Tag.Eoc);
|
||||
}
|
||||
}
|
||||
|
||||
Value = StringBuffer.ToString();
|
||||
buffer.TypeCode = (short)tag.IdCode;
|
||||
}
|
||||
|
||||
protected virtual int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
var length = Value.Length;
|
||||
buffer.Copy(Value);
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
length += buffer.EncodeTagAndLength(tag, length);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var str = value as Asn1CharString;
|
||||
|
||||
if (str == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals(str.Value);
|
||||
}
|
||||
|
||||
public bool Equals(string value)
|
||||
{
|
||||
return Value.Equals(value);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (Value != null) ? Value.GetHashCode() : base.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
55
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Choice.cs
vendored
Normal file
55
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Choice.cs
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class Asn1Choice : Asn1Type
|
||||
{
|
||||
[NonSerialized]
|
||||
private int _choiceId;
|
||||
|
||||
[NonSerialized]
|
||||
protected Asn1Type Element;
|
||||
|
||||
|
||||
public virtual int ChoiceId => _choiceId;
|
||||
|
||||
public abstract string ElemName { get; }
|
||||
|
||||
|
||||
public virtual Asn1Type GetElement()
|
||||
{
|
||||
return Element;
|
||||
}
|
||||
|
||||
public virtual void SetElement(int choiceId, Asn1Type element)
|
||||
{
|
||||
_choiceId = choiceId;
|
||||
|
||||
Element = element;
|
||||
}
|
||||
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var choice = value as Asn1Choice;
|
||||
|
||||
if (choice == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_choiceId != choice._choiceId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Element.Equals(choice.Element);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Element?.GetHashCode() ?? base.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
23
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1ChoiceExt.cs
vendored
Normal file
23
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1ChoiceExt.cs
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1ChoiceExt : Asn1OpenType
|
||||
{
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
base.Decode(buffer, false, 0);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return base.Encode(buffer, false);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
base.Encode(outs, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
326
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1DecodeBuffer.cs
vendored
Normal file
326
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1DecodeBuffer.cs
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public abstract class Asn1DecodeBuffer : Asn1MessageBuffer
|
||||
{
|
||||
private readonly ArrayList _captureBufferList;
|
||||
private int _byteCount;
|
||||
private Stream _inputStream;
|
||||
private long _markedPosition;
|
||||
private ArrayList _namedEventHandlerList;
|
||||
private int _savedByteCount;
|
||||
private short _typeCode;
|
||||
private int[] _oidBuffer;
|
||||
|
||||
protected Asn1DecodeBuffer(byte[] msgdata)
|
||||
{
|
||||
_namedEventHandlerList = new ArrayList();
|
||||
_captureBufferList = new ArrayList(5);
|
||||
|
||||
SetInputStream(msgdata, 0, msgdata.Length);
|
||||
}
|
||||
|
||||
protected Asn1DecodeBuffer(Stream inputStream)
|
||||
{
|
||||
_namedEventHandlerList = new ArrayList();
|
||||
_captureBufferList = new ArrayList(5);
|
||||
|
||||
_inputStream = inputStream.CanSeek ? inputStream : new BufferedStream(inputStream);
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
public virtual int ByteCount
|
||||
{
|
||||
get { return _byteCount; }
|
||||
}
|
||||
|
||||
public virtual Asn1DecodeBuffer EventHandlerList
|
||||
{
|
||||
set { _namedEventHandlerList = value._namedEventHandlerList; }
|
||||
}
|
||||
|
||||
public virtual short TypeCode
|
||||
{
|
||||
set { _typeCode = value; }
|
||||
}
|
||||
|
||||
public virtual void AddCaptureBuffer(MemoryStream buffer)
|
||||
{
|
||||
_captureBufferList.Add(buffer);
|
||||
}
|
||||
|
||||
public virtual void AddNamedEventHandler(IAsn1NamedEventHandler handler)
|
||||
{
|
||||
_namedEventHandlerList.Add(handler);
|
||||
}
|
||||
|
||||
public virtual void Capture(int nbytes)
|
||||
{
|
||||
for (var i = 0; i < nbytes; i++)
|
||||
{
|
||||
var num = _inputStream.ReadByte();
|
||||
|
||||
if (num == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
foreach (MemoryStream s in _captureBufferList)
|
||||
{
|
||||
s.WriteByte((byte)num);
|
||||
}
|
||||
|
||||
_byteCount++;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual long DecodeIntValue(int length, bool signExtend)
|
||||
{
|
||||
return Asn1RunTime.DecodeIntValue(this, length, signExtend);
|
||||
}
|
||||
|
||||
public virtual int[] DecodeOidContents(int llen)
|
||||
{
|
||||
var index = 0;
|
||||
|
||||
if (_oidBuffer == null)
|
||||
{
|
||||
_oidBuffer = new int[0x80];
|
||||
}
|
||||
|
||||
while (llen > 0)
|
||||
{
|
||||
int num;
|
||||
|
||||
if (index >= 0x80)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
|
||||
}
|
||||
|
||||
_oidBuffer[index] = 0;
|
||||
|
||||
do
|
||||
{
|
||||
num = ReadByte();
|
||||
_oidBuffer[index] = (_oidBuffer[index] * 0x80) + (num & 0x7f);
|
||||
llen--;
|
||||
}
|
||||
while ((num & 0x80) != 0);
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
var num3 = _oidBuffer[0];
|
||||
|
||||
_oidBuffer[0] = ((num3 / 40) >= 2) ? 2 : (num3 / 40);
|
||||
_oidBuffer[1] = (_oidBuffer[0] == 2) ? (num3 - 80) : (num3 % 40);
|
||||
|
||||
index = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
if (llen != 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
var destinationArray = new int[index];
|
||||
Array.Copy(_oidBuffer, 0, destinationArray, 0, index);
|
||||
return destinationArray;
|
||||
}
|
||||
|
||||
public virtual int[] DecodeRelOidContents(int llen)
|
||||
{
|
||||
var index = 0;
|
||||
|
||||
if (_oidBuffer == null)
|
||||
{
|
||||
_oidBuffer = new int[0x80];
|
||||
}
|
||||
|
||||
while (llen > 0)
|
||||
{
|
||||
int num;
|
||||
|
||||
if (index >= 0x80)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
|
||||
}
|
||||
|
||||
_oidBuffer[index] = 0;
|
||||
|
||||
do
|
||||
{
|
||||
num = ReadByte();
|
||||
_oidBuffer[index] = (_oidBuffer[index] * 0x80) + (num & 0x7f);
|
||||
llen--;
|
||||
}
|
||||
while ((num & 0x80) != 0);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
if (llen != 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
var destinationArray = new int[index];
|
||||
Array.Copy(_oidBuffer, 0, destinationArray, 0, index);
|
||||
return destinationArray;
|
||||
}
|
||||
|
||||
public override Stream GetInputStream()
|
||||
{
|
||||
return _inputStream;
|
||||
}
|
||||
|
||||
public virtual void HexDump()
|
||||
{
|
||||
HexDump(_inputStream);
|
||||
}
|
||||
|
||||
protected virtual void Init()
|
||||
{
|
||||
_byteCount = 0;
|
||||
_markedPosition = 0L;
|
||||
_savedByteCount = 0;
|
||||
}
|
||||
|
||||
public virtual void InvokeCharacters(string svalue)
|
||||
{
|
||||
var enumerator = _namedEventHandlerList.GetEnumerator();
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
((IAsn1NamedEventHandler)enumerator.Current).Characters(svalue, _typeCode);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void InvokeEndElement(string name, int index)
|
||||
{
|
||||
var enumerator = _namedEventHandlerList.GetEnumerator();
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
((IAsn1NamedEventHandler)enumerator.Current).EndElement(name, index);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void InvokeStartElement(string name, int index)
|
||||
{
|
||||
var enumerator = _namedEventHandlerList.GetEnumerator();
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
((IAsn1NamedEventHandler)enumerator.Current).StartElement(name, index);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Mark()
|
||||
{
|
||||
_savedByteCount = _byteCount;
|
||||
_markedPosition = _inputStream.Position;
|
||||
}
|
||||
|
||||
public virtual int Read()
|
||||
{
|
||||
var num = _inputStream.ReadByte();
|
||||
|
||||
if (num == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
foreach (MemoryStream s in _captureBufferList)
|
||||
{
|
||||
s.WriteByte((byte)num);
|
||||
}
|
||||
|
||||
_byteCount++;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public virtual void Read(byte[] buffer)
|
||||
{
|
||||
Read(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
public virtual void Read(byte[] buffer, int offset, int nbytes)
|
||||
{
|
||||
var count = nbytes;
|
||||
var num3 = offset;
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
var num = _inputStream.Read(buffer, num3, count);
|
||||
|
||||
if (num <= 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, ByteCount);
|
||||
}
|
||||
|
||||
num3 += num;
|
||||
count -= num;
|
||||
}
|
||||
|
||||
foreach (MemoryStream s in _captureBufferList)
|
||||
{
|
||||
s.Write(buffer, offset, nbytes);
|
||||
}
|
||||
|
||||
_byteCount += nbytes;
|
||||
}
|
||||
|
||||
public abstract int ReadByte();
|
||||
|
||||
public virtual void RemoveCaptureBuffer(MemoryStream buffer)
|
||||
{
|
||||
for (var i = 0; i < _captureBufferList.Count; i++)
|
||||
{
|
||||
if (buffer == _captureBufferList[i])
|
||||
{
|
||||
_captureBufferList.RemoveAt(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
try
|
||||
{
|
||||
_inputStream.Position = _markedPosition;
|
||||
_byteCount = _savedByteCount;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetInputStream(byte[] msgdata, int offset, int length)
|
||||
{
|
||||
_inputStream = new MemoryStream(msgdata, offset, length);
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
public virtual long Skip(long nbytes)
|
||||
{
|
||||
var inputStream = _inputStream;
|
||||
var position = inputStream.Position;
|
||||
|
||||
return (inputStream.Seek(nbytes, SeekOrigin.Current) - position);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1DerDecodeBuffer : Asn1BerDecodeBuffer
|
||||
{
|
||||
public Asn1DerDecodeBuffer(byte[] msgdata)
|
||||
: base(msgdata)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1DerDecodeBuffer(Stream inputStream)
|
||||
: base(inputStream)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1DerEncodeBuffer : Asn1BerEncodeBuffer
|
||||
{
|
||||
public Asn1DerEncodeBuffer()
|
||||
{
|
||||
ByteIndex = SizeIncrement - 1;
|
||||
}
|
||||
|
||||
public Asn1DerEncodeBuffer(int sizeIncrement)
|
||||
: base(sizeIncrement)
|
||||
{
|
||||
ByteIndex = SizeIncrement - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1DerInputStream : Asn1DerDecodeBuffer, IAsn1InputStream
|
||||
{
|
||||
public Asn1DerInputStream(Stream inputStream)
|
||||
: base(inputStream)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int Available()
|
||||
{
|
||||
var inputStream = GetInputStream();
|
||||
|
||||
if (inputStream != null)
|
||||
{
|
||||
var num = inputStream.Length - inputStream.Position;
|
||||
return (int)num;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
var inputStream = GetInputStream();
|
||||
|
||||
if (inputStream != null)
|
||||
{
|
||||
inputStream.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool MarkSupported()
|
||||
{
|
||||
var inputStream = GetInputStream();
|
||||
|
||||
return ((inputStream != null) && inputStream.CanSeek);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1DiscreteCharSet : Asn1CharSet
|
||||
{
|
||||
private readonly int[] _charSet;
|
||||
|
||||
public Asn1DiscreteCharSet(string charSet)
|
||||
: base(charSet.Length)
|
||||
{
|
||||
_charSet = new int[charSet.Length];
|
||||
|
||||
for (var i = 0; i < _charSet.Length; i++)
|
||||
{
|
||||
_charSet[i] = charSet[i];
|
||||
}
|
||||
}
|
||||
|
||||
public Asn1DiscreteCharSet(int[] charSet)
|
||||
: base(charSet.Length)
|
||||
{
|
||||
_charSet = charSet;
|
||||
}
|
||||
|
||||
public override int MaxValue
|
||||
{
|
||||
get { return _charSet[_charSet.Length - 1]; }
|
||||
}
|
||||
|
||||
public override int GetCharAtIndex(int index)
|
||||
{
|
||||
if (index >= _charSet.Length)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", index);
|
||||
}
|
||||
|
||||
return _charSet[index];
|
||||
}
|
||||
|
||||
public override int GetCharIndex(int charValue)
|
||||
{
|
||||
var index = 0;
|
||||
|
||||
while ((index < _charSet.Length) && (_charSet[index] != charValue))
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
if (index >= _charSet.Length)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", charValue);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
84
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1EncodeBuffer.cs
vendored
Normal file
84
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1EncodeBuffer.cs
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public abstract class Asn1EncodeBuffer : Asn1MessageBuffer
|
||||
{
|
||||
public const int DefaultSizeIncrement = 0x400;
|
||||
|
||||
protected byte[] Data;
|
||||
protected int ByteIndex;
|
||||
protected int SizeIncrement;
|
||||
|
||||
protected Asn1EncodeBuffer()
|
||||
{
|
||||
InitBuffer(DefaultSizeIncrement);
|
||||
}
|
||||
|
||||
protected Asn1EncodeBuffer(int sizeIncrement)
|
||||
{
|
||||
if (sizeIncrement == 0)
|
||||
{
|
||||
sizeIncrement = DefaultSizeIncrement;
|
||||
}
|
||||
|
||||
InitBuffer(sizeIncrement);
|
||||
}
|
||||
|
||||
public abstract byte[] MsgCopy { get; }
|
||||
|
||||
public abstract int MsgLength { get; }
|
||||
|
||||
public virtual void BinDump(string varName)
|
||||
{
|
||||
var outs = new StreamWriter(Console.OpenStandardOutput(), Console.Out.Encoding)
|
||||
{
|
||||
AutoFlush = true
|
||||
};
|
||||
|
||||
BinDump(outs, varName);
|
||||
}
|
||||
|
||||
public abstract void BinDump(StreamWriter outs, string varName);
|
||||
|
||||
protected internal virtual void CheckSize(int bytesRequired)
|
||||
{
|
||||
if ((ByteIndex + bytesRequired) > Data.Length)
|
||||
{
|
||||
var num = ((bytesRequired - 1) / SizeIncrement) + 1;
|
||||
var num2 = num * SizeIncrement;
|
||||
var destinationArray = new byte[Data.Length + num2];
|
||||
|
||||
Array.Copy(Data, 0, destinationArray, 0, ByteIndex + 1);
|
||||
|
||||
Data = destinationArray;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void Copy(byte value);
|
||||
|
||||
public abstract void Copy(byte[] value);
|
||||
|
||||
public virtual void HexDump()
|
||||
{
|
||||
HexDump(GetInputStream());
|
||||
}
|
||||
|
||||
public virtual void HexDump(StreamWriter outs)
|
||||
{
|
||||
HexDump(GetInputStream(), outs);
|
||||
}
|
||||
|
||||
protected virtual void InitBuffer(int sizeIncrement)
|
||||
{
|
||||
SizeIncrement = sizeIncrement;
|
||||
Data = new byte[SizeIncrement];
|
||||
ByteIndex = 0;
|
||||
}
|
||||
|
||||
public abstract void Reset();
|
||||
|
||||
public abstract void Write(Stream outs);
|
||||
}
|
||||
}
|
||||
80
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Enumerated.cs
vendored
Normal file
80
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Enumerated.cs
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class Asn1Enumerated : Asn1Type
|
||||
{
|
||||
public const int Undefined = -999;
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, EnumeratedTypeCode);
|
||||
|
||||
[NonSerialized]
|
||||
public int Value;
|
||||
|
||||
public Asn1Enumerated()
|
||||
{
|
||||
Value = Undefined;
|
||||
}
|
||||
|
||||
public Asn1Enumerated(int value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
Value = (int)Asn1RunTime.DecodeIntValue(buffer, length, true);
|
||||
buffer.TypeCode = EnumeratedTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = buffer.EncodeIntValue(Value);
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
outs.EncodeIntValue(Value, true);
|
||||
}
|
||||
|
||||
public virtual bool Equals(int value)
|
||||
{
|
||||
return (Value == value);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var enumerated = value as Asn1Enumerated;
|
||||
|
||||
return (enumerated != null && Value == enumerated.Value);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode();
|
||||
}
|
||||
|
||||
public virtual int ParseValue(string value)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1GeneralString.cs
vendored
Normal file
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1GeneralString.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1GeneralString : Asn1VarWidthCharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, GeneralStringTypeCode);
|
||||
|
||||
public Asn1GeneralString()
|
||||
: base(GeneralStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1GeneralString(string data)
|
||||
: base(data, GeneralStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeCharString(Value, explicitTagging, Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
344
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1GeneralizedTime.cs
vendored
Normal file
344
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1GeneralizedTime.cs
vendored
Normal file
@@ -0,0 +1,344 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1GeneralizedTime : Asn1Time
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, GeneralTimeTypeCode);
|
||||
|
||||
public Asn1GeneralizedTime()
|
||||
: base(GeneralTimeTypeCode, false)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1GeneralizedTime(bool useDerRules)
|
||||
: base(GeneralTimeTypeCode, useDerRules)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1GeneralizedTime(string data)
|
||||
: base(data, GeneralTimeTypeCode, false)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1GeneralizedTime(string data, bool useDerRules)
|
||||
: base(data, GeneralTimeTypeCode, useDerRules)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int Century
|
||||
{
|
||||
get
|
||||
{
|
||||
var yearValue = Year;
|
||||
|
||||
if (yearValue < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, yearValue);
|
||||
}
|
||||
|
||||
return (yearValue / 100);
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value < 0) || (value > 0x63))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidCenturyValue, value);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
YearValue = (value * 100) + (YearValue % 100);
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool CompileString()
|
||||
{
|
||||
int minuteValue;
|
||||
|
||||
if (((YearValue < 0) || (MonthValue <= 0)) || ((DayValue <= 0) || (HourValue < 0)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Value = "";
|
||||
|
||||
if (StringBuffer == null)
|
||||
{
|
||||
StringBuffer = new StringBuilder();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuffer.Length = 0;
|
||||
}
|
||||
|
||||
if ((DerRules || UtcFlag) && ((DiffHourValue != 0) || (DiffMinValue != 0)))
|
||||
{
|
||||
var time = GetTime();
|
||||
time.AddMinutes(-DiffMinValue);
|
||||
time.AddHours(-DiffHourValue);
|
||||
|
||||
PutInteger(4, time.Year);
|
||||
PutInteger(2, time.Month);
|
||||
PutInteger(2, time.Day);
|
||||
PutInteger(2, time.Hour);
|
||||
|
||||
minuteValue = time.Minute;
|
||||
}
|
||||
else
|
||||
{
|
||||
PutInteger(4, YearValue);
|
||||
PutInteger(2, MonthValue);
|
||||
PutInteger(2, DayValue);
|
||||
PutInteger(2, HourValue);
|
||||
|
||||
minuteValue = MinuteValue;
|
||||
}
|
||||
|
||||
if ((DerRules || (minuteValue > 0)) || ((SecondValue > 0) || (SecFraction.Length > 0)))
|
||||
{
|
||||
PutInteger(2, minuteValue);
|
||||
|
||||
if ((DerRules || (SecondValue > 0)) || (SecFraction.Length > 0))
|
||||
{
|
||||
PutInteger(2, SecondValue);
|
||||
|
||||
if (SecFraction.Length > 0)
|
||||
{
|
||||
StringBuffer.Append('.');
|
||||
StringBuffer.Append(SecFraction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DerRules || UtcFlag)
|
||||
{
|
||||
StringBuffer.Append('Z');
|
||||
}
|
||||
else if ((DiffHourValue != 0) || (DiffMinValue != 0))
|
||||
{
|
||||
StringBuffer.Append((DiffHourValue > 0) ? '+' : '-');
|
||||
|
||||
if (DiffMinValue != 0)
|
||||
{
|
||||
PutInteger(2, Math.Abs(DiffHourValue));
|
||||
PutInteger(2, Math.Abs(DiffMinValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
PutInteger(2, Math.Abs(DiffHourValue));
|
||||
}
|
||||
}
|
||||
|
||||
Value = StringBuffer.ToString();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
Encode(outs, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void ParseString(string data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
throw ExceptionUtility.ArgumentNull("data");
|
||||
}
|
||||
|
||||
Clear();
|
||||
|
||||
var off = new IntHolder(0);
|
||||
|
||||
try
|
||||
{
|
||||
YearValue = ParseInt(data, off, 4);
|
||||
MonthValue = ParseInt(data, off, 2);
|
||||
DayValue = ParseInt(data, off, 2);
|
||||
|
||||
if (YearValue < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, YearValue);
|
||||
}
|
||||
|
||||
if ((MonthValue < 1) || (MonthValue > 12))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMonthValue, MonthValue);
|
||||
}
|
||||
|
||||
int num = DaysInMonth[MonthValue];
|
||||
|
||||
if (((MonthValue == 2) && ((YearValue % 4) == 0)) && (((YearValue % 100) != 0) || ((YearValue % 400) == 0)))
|
||||
{
|
||||
num++;
|
||||
}
|
||||
|
||||
if ((DayValue < 1) || (DayValue > num))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDayValue, DayValue);
|
||||
}
|
||||
|
||||
var num2 = 0;
|
||||
|
||||
if (!char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1HoursExpected);
|
||||
}
|
||||
|
||||
HourValue = ParseInt(data, off, 2);
|
||||
num2++;
|
||||
|
||||
if (char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
MinuteValue = ParseInt(data, off, 2);
|
||||
num2++;
|
||||
|
||||
if (char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
SecondValue = ParseInt(data, off, 2);
|
||||
num2++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((num2 >= 1) && ((HourValue < 0) || (HourValue > 0x17)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidHourValue, HourValue);
|
||||
}
|
||||
|
||||
if ((num2 >= 2) && ((MinuteValue < 0) || (MinuteValue > 0x3b)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMinuteValue, MinuteValue);
|
||||
}
|
||||
|
||||
if ((num2 == 3) && ((SecondValue < 0) || (SecondValue > 0x3b)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidSecondValue, SecondValue);
|
||||
}
|
||||
|
||||
var ch = CharAt(data, off.Value);
|
||||
|
||||
if (DerRules && (ch == ','))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDecimalMark);
|
||||
}
|
||||
|
||||
if ((ch == '.') || (ch == ','))
|
||||
{
|
||||
off.Value++;
|
||||
|
||||
if (num2 != 3)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedSymbol);
|
||||
}
|
||||
|
||||
var length = 0;
|
||||
|
||||
while (char.IsDigit(CharAt(data, off.Value + length)))
|
||||
{
|
||||
length++;
|
||||
}
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedSymbol);
|
||||
}
|
||||
|
||||
SecFraction = data.Substring(off.Value, length);
|
||||
off.Value += length;
|
||||
}
|
||||
|
||||
if (CharAt(data, off.Value) == 'Z')
|
||||
{
|
||||
off.Value++;
|
||||
UtcFlag = true;
|
||||
|
||||
if (off.Value != data.Length)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedValuesAtEndOfString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DerRules)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedZoneOffset);
|
||||
}
|
||||
|
||||
UtcFlag = false;
|
||||
|
||||
var ch2 = CharAt(data, off.Value);
|
||||
|
||||
switch (ch2)
|
||||
{
|
||||
case '-':
|
||||
case '+':
|
||||
off.Value++;
|
||||
|
||||
if (!char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHour);
|
||||
}
|
||||
|
||||
DiffHourValue = ParseInt(data, off, 2);
|
||||
|
||||
if (char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
DiffMinValue = ParseInt(data, off, 2);
|
||||
}
|
||||
|
||||
if ((DiffHourValue < 0) || (DiffHourValue > 12))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHourValue, DiffHourValue);
|
||||
}
|
||||
|
||||
if ((DiffMinValue < 0) || (DiffMinValue > 0x3b))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffMinuteValue, DiffMinValue);
|
||||
}
|
||||
|
||||
if (ch2 == '-')
|
||||
{
|
||||
DiffHourValue = -DiffHourValue;
|
||||
DiffMinValue = -DiffMinValue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Parsed = true;
|
||||
|
||||
if (data != Value)
|
||||
{
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfRangeException)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDateFormat);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidNumberFormat);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDateFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1GraphicString.cs
vendored
Normal file
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1GraphicString.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1GraphicString : Asn1VarWidthCharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, GraphicStringTypeCode);
|
||||
|
||||
public Asn1GraphicString()
|
||||
: base(GraphicStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1GraphicString(string data)
|
||||
: base(data, GraphicStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeCharString(base.Value, explicitTagging, Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Ia5String.cs
vendored
Normal file
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Ia5String.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1Ia5String : Asn18BitCharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, Ia5StringTypeCode);
|
||||
|
||||
public Asn1Ia5String()
|
||||
: base(Ia5StringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1Ia5String(string data)
|
||||
: base(data, Ia5StringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeCharString(Value, explicitTagging, Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
91
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Integer.cs
vendored
Normal file
91
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Integer.cs
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1Integer : Asn1Type
|
||||
{
|
||||
public const int SizeOfInt = 4;
|
||||
public const int SizeOfLong = 8;
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BigIntegerTypeCode);
|
||||
|
||||
[NonSerialized]
|
||||
public long Value;
|
||||
|
||||
public Asn1Integer()
|
||||
{
|
||||
Value = 0L;
|
||||
}
|
||||
|
||||
public Asn1Integer(long value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
Value = Asn1RunTime.DecodeIntValue(buffer, length, true);
|
||||
buffer.TypeCode = BigIntegerTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = buffer.EncodeIntValue(Value);
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
outs.EncodeIntValue(Value, true);
|
||||
}
|
||||
|
||||
public virtual bool Equals(long value)
|
||||
{
|
||||
return (Value == value);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var integer = value as Asn1Integer;
|
||||
|
||||
if (integer == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Value == integer.Value);
|
||||
}
|
||||
|
||||
public virtual int GetBitCount()
|
||||
{
|
||||
return Asn1RunTime.GetLongBitCount(Value);
|
||||
}
|
||||
|
||||
public static int GetBitCount(long ivalue)
|
||||
{
|
||||
return Asn1RunTime.GetLongBitCount(ivalue);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Convert.ToString(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
24
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1MessageBuffer.cs
vendored
Normal file
24
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1MessageBuffer.cs
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public abstract class Asn1MessageBuffer
|
||||
{
|
||||
public abstract Stream GetInputStream();
|
||||
|
||||
public static void HexDump(Stream ins)
|
||||
{
|
||||
var outs = new StreamWriter(Console.OpenStandardOutput(), Console.Out.Encoding)
|
||||
{
|
||||
AutoFlush = true
|
||||
};
|
||||
|
||||
HexDump(ins, outs);
|
||||
}
|
||||
|
||||
public static void HexDump(Stream ins, StreamWriter outs)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
48
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Null.cs
vendored
Normal file
48
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Null.cs
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1Null : Asn1Type
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, NullTypeCode);
|
||||
public static readonly Asn1Null NullValue = new Asn1Null();
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
MatchTag(buffer, Tag);
|
||||
}
|
||||
|
||||
buffer.TypeCode = NullTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = 0;
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
outs.EncodeLength(0);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "NULL";
|
||||
}
|
||||
}
|
||||
}
|
||||
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1NumericString.cs
vendored
Normal file
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1NumericString.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1NumericString : Asn18BitCharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, NumericStringTypeCode);
|
||||
|
||||
public Asn1NumericString()
|
||||
: base(NumericStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1NumericString(string data)
|
||||
: base(data, NumericStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeCharString(Value, explicitTagging, Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1ObjectDescriptor : Asn1VarWidthCharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, ObjectDescriptorTypeCode);
|
||||
|
||||
public Asn1ObjectDescriptor()
|
||||
: base(ObjectDescriptorTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1ObjectDescriptor(string data)
|
||||
: base(data, ObjectDescriptorTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeCharString(Value, explicitTagging, Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
137
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1ObjectIdentifier.cs
vendored
Normal file
137
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1ObjectIdentifier.cs
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
using System;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1ObjectIdentifier : Asn1Type
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, ObjectIdentifierTypeCode);
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected OidValue OidValue;
|
||||
|
||||
public OidValue Oid => OidValue;
|
||||
|
||||
|
||||
public Asn1ObjectIdentifier()
|
||||
{
|
||||
OidValue = null;
|
||||
}
|
||||
|
||||
public Asn1ObjectIdentifier(OidValue oidValue)
|
||||
{
|
||||
OidValue = oidValue;
|
||||
}
|
||||
|
||||
|
||||
public static Asn1ObjectIdentifier FromString(string value)
|
||||
{
|
||||
return string.IsNullOrEmpty(value) ? null : new Asn1ObjectIdentifier(OidValue.FromString(value));
|
||||
}
|
||||
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var len = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
|
||||
if (len <= 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
OidValue = OidValue.FromArray(buffer.DecodeOidContents(len));
|
||||
buffer.TypeCode = ObjectIdentifierTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
if (((OidValue.Items.Length < 2) || (OidValue.Items[0] > 2)) || ((OidValue.Items[0] != 2) && (OidValue.Items[1] > 0x27)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
|
||||
}
|
||||
|
||||
var len = 0;
|
||||
|
||||
for (var i = OidValue.Items.Length - 1; i >= 1; i--)
|
||||
{
|
||||
len += buffer.EncodeIdentifier((i == 1) ? ((OidValue.Items[0] * 40) + OidValue.Items[1]) : OidValue.Items[i]);
|
||||
}
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (((OidValue.Items.Length < 2) || (OidValue.Items[0] > 2)) || ((OidValue.Items[0] != 2) && (OidValue.Items[1] > 0x27)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
|
||||
}
|
||||
|
||||
var len = 1;
|
||||
|
||||
for (var i = 2; i < OidValue.Items.Length; i++)
|
||||
{
|
||||
len += Asn1RunTime.GetIdentBytesCount(OidValue.Items[i]);
|
||||
}
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
outs.EncodeLength(len);
|
||||
var ident = (OidValue.Items[0] * 40) + OidValue.Items[1];
|
||||
outs.EncodeIdentifier(ident);
|
||||
|
||||
for (var i = 2; i < OidValue.Items.Length; i++)
|
||||
{
|
||||
outs.EncodeIdentifier(OidValue.Items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj is Asn1ObjectIdentifier))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var other = (Asn1ObjectIdentifier)obj;
|
||||
|
||||
if (OidValue == other.OidValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (OidValue == null || other.OidValue == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return OidValue.Equals(other.OidValue);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return OidValue?.GetHashCode() ?? base.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return OidValue?.ToString() ?? base.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
235
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OctetString.cs
vendored
Normal file
235
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OctetString.cs
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1OctetString : Asn1Type, IComparable
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, OctetStringTypeCode);
|
||||
|
||||
[NonSerialized]
|
||||
public byte[] Value;
|
||||
|
||||
public Asn1OctetString()
|
||||
{
|
||||
Value = null;
|
||||
}
|
||||
|
||||
public Asn1OctetString(byte[] data)
|
||||
{
|
||||
Value = data;
|
||||
}
|
||||
|
||||
public Asn1OctetString(string value)
|
||||
{
|
||||
Value = string.IsNullOrEmpty(value) ? new byte[0] : Asn1Value.ParseString(value);
|
||||
}
|
||||
|
||||
public Asn1OctetString(byte[] data, int offset, int nbytes)
|
||||
{
|
||||
Value = new byte[nbytes];
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
Array.Copy(data, offset, Value, 0, nbytes);
|
||||
}
|
||||
}
|
||||
|
||||
public override int Length
|
||||
{
|
||||
get { return Value.Length; }
|
||||
}
|
||||
|
||||
public virtual int CompareTo(object octstr)
|
||||
{
|
||||
var value = ((Asn1OctetString)octstr).Value;
|
||||
var num = (Value.Length < value.Length) ? Value.Length : value.Length;
|
||||
|
||||
for (var i = 0; i < num; i++)
|
||||
{
|
||||
var num2 = Value[i] & 0xff;
|
||||
var num3 = value[i] & 0xff;
|
||||
|
||||
if (num2 < num3)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (num2 > num3)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (Value.Length == value.Length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Value.Length < value.Length)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void AllocByteArray(int nbytes)
|
||||
{
|
||||
if (Value == null)
|
||||
{
|
||||
Value = new byte[nbytes];
|
||||
}
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var elemLength = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
var lastTag = buffer.LastTag;
|
||||
|
||||
if ((lastTag == null) || !lastTag.Constructed)
|
||||
{
|
||||
if (elemLength < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
Value = new byte[elemLength];
|
||||
|
||||
if (elemLength != 0)
|
||||
{
|
||||
buffer.Read(Value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var nbytes = 0;
|
||||
var offset = 0;
|
||||
var context = new Asn1BerDecodeContext(buffer, elemLength);
|
||||
|
||||
while (!context.Expired())
|
||||
{
|
||||
var num2 = MatchTag(buffer, Tag);
|
||||
|
||||
if (num2 <= 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
|
||||
nbytes += num2;
|
||||
|
||||
if (offset == 0)
|
||||
{
|
||||
Value = new byte[nbytes];
|
||||
}
|
||||
else
|
||||
{
|
||||
ReAllocByteArray(nbytes);
|
||||
}
|
||||
|
||||
buffer.Read(Value, offset, num2);
|
||||
offset = nbytes;
|
||||
}
|
||||
|
||||
if (elemLength == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
MatchTag(buffer, Asn1Tag.Eoc);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.TypeCode = OctetStringTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
if (Value == null)
|
||||
{
|
||||
Value = new byte[0];
|
||||
}
|
||||
|
||||
var length = Value.Length;
|
||||
|
||||
if (length != 0)
|
||||
{
|
||||
buffer.Copy(Value);
|
||||
}
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
length += buffer.EncodeTagAndLength(Tag, length);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeOctetString(Value, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public bool Equals(byte[] value)
|
||||
{
|
||||
if (value.Length != Value.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < value.Length; i++)
|
||||
{
|
||||
if (value[i] != Value[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var str = value as Asn1OctetString;
|
||||
|
||||
return (str != null) && Equals(str.Value);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (Value != null) ? Value.GetHashCode() : base.GetHashCode();
|
||||
}
|
||||
|
||||
private void ReAllocByteArray(int nbytes)
|
||||
{
|
||||
var value = Value;
|
||||
Value = new byte[nbytes];
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
Array.Copy(value, 0, Value, 0, value.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Stream ToInputStream()
|
||||
{
|
||||
return new MemoryStream(Value, 0, Value.Length);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var str = new StringBuilder("").ToString();
|
||||
|
||||
if (Value != null)
|
||||
{
|
||||
foreach (var b in Value)
|
||||
{
|
||||
str = str + Asn1Util.ToHexString(b);
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
86
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OpenExt.cs
vendored
Normal file
86
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OpenExt.cs
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1OpenExt : Asn1Type
|
||||
{
|
||||
[NonSerialized]
|
||||
public ArrayList Value = new ArrayList();
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
DecodeComponent(buffer);
|
||||
}
|
||||
|
||||
public virtual void DecodeComponent(Asn1BerDecodeBuffer buffer)
|
||||
{
|
||||
var type = new Asn1OpenType();
|
||||
type.Decode(buffer, false, 0);
|
||||
Value.Add(type);
|
||||
}
|
||||
|
||||
public virtual void DecodeEventComponent(Asn1BerDecodeBuffer buffer)
|
||||
{
|
||||
buffer.InvokeStartElement("...", -1);
|
||||
|
||||
var type = new Asn1OpenType();
|
||||
type.Decode(buffer, false, 0);
|
||||
|
||||
Value.Add(type);
|
||||
|
||||
buffer.InvokeCharacters(type.ToString());
|
||||
buffer.InvokeEndElement("...", -1);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var num = 0;
|
||||
|
||||
for (var i = Value.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var type = (Asn1OpenType)Value[i];
|
||||
num += type.Encode(buffer, false);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
foreach (Asn1OpenType type in Value)
|
||||
{
|
||||
if (type != null)
|
||||
{
|
||||
type.Encode(outs, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (Value == null)
|
||||
{
|
||||
return "<null>";
|
||||
}
|
||||
|
||||
var builder = new StringBuilder();
|
||||
|
||||
for (var i = 0; i < Value.Count; i++)
|
||||
{
|
||||
var type = (Asn1OpenType)Value[i];
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
builder.Append(", ");
|
||||
}
|
||||
|
||||
builder.Append(type);
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
103
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OpenType.cs
vendored
Normal file
103
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OpenType.cs
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1OpenType : Asn1OctetString
|
||||
{
|
||||
private const string EncodedDataMessage = "ENCODED DATA";
|
||||
|
||||
[NonSerialized]
|
||||
private readonly Asn1EncodeBuffer _encodeBuffer;
|
||||
|
||||
[NonSerialized]
|
||||
private readonly int _length;
|
||||
|
||||
[NonSerialized]
|
||||
private readonly bool _textEncoding;
|
||||
|
||||
|
||||
public Asn1OpenType()
|
||||
{
|
||||
_length = 0;
|
||||
_textEncoding = false;
|
||||
}
|
||||
|
||||
public Asn1OpenType(byte[] data)
|
||||
: base(data)
|
||||
{
|
||||
_length = 0;
|
||||
_textEncoding = false;
|
||||
}
|
||||
|
||||
public Asn1OpenType(Asn1EncodeBuffer buffer)
|
||||
{
|
||||
if (buffer is Asn1BerEncodeBuffer)
|
||||
{
|
||||
_length = buffer.MsgLength;
|
||||
_encodeBuffer = buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = buffer.MsgCopy;
|
||||
}
|
||||
|
||||
_textEncoding = false;
|
||||
}
|
||||
|
||||
public Asn1OpenType(byte[] data, int offset, int nbytes)
|
||||
: base(data, offset, nbytes)
|
||||
{
|
||||
_length = 0;
|
||||
_textEncoding = false;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Value = buffer.DecodeOpenType();
|
||||
buffer.TypeCode = OpenTypeTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
if (Value == null)
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
|
||||
return base.Encode(buffer, false);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (Value != null)
|
||||
{
|
||||
outs.Write(Value);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (Value != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (_textEncoding ? Encoding.UTF8.GetString(Value, 0, Value.Length) : base.ToString());
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (_encodeBuffer != null)
|
||||
{
|
||||
return _encodeBuffer.ToString();
|
||||
}
|
||||
|
||||
return EncodedDataMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
87
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OutputStream.cs
vendored
Normal file
87
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1OutputStream.cs
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
using System.IO;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public abstract class Asn1OutputStream : Stream
|
||||
{
|
||||
protected readonly Stream OutputStream;
|
||||
|
||||
public Asn1OutputStream(Stream outputStream)
|
||||
{
|
||||
OutputStream = outputStream;
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool CanSeek
|
||||
{
|
||||
get { return OutputStream.CanSeek; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return OutputStream.CanWrite; }
|
||||
}
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get { return OutputStream.Length; }
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get { return OutputStream.Position; }
|
||||
set { OutputStream.Position = value; }
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
OutputStream.Close();
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
OutputStream.Flush();
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw ExceptionUtility.NotSupported(Resources.Asn1ReadOutputStreamNotSupported);
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
return OutputStream.Seek(offset, origin);
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
OutputStream.SetLength(value);
|
||||
}
|
||||
|
||||
public virtual void Write(byte[] b)
|
||||
{
|
||||
OutputStream.Write(b, 0, b.Length);
|
||||
}
|
||||
|
||||
public override void Write(byte[] b, int off, int len)
|
||||
{
|
||||
OutputStream.Write(b, off, len);
|
||||
}
|
||||
|
||||
public override void WriteByte(byte b)
|
||||
{
|
||||
OutputStream.WriteByte(b);
|
||||
}
|
||||
|
||||
public virtual void WriteByte(int b)
|
||||
{
|
||||
OutputStream.WriteByte((byte)b);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1PrintableString : Asn18BitCharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, PrintableStringTypeCode);
|
||||
|
||||
public Asn1PrintableString()
|
||||
: base(PrintableStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1PrintableString(string data)
|
||||
: base(data, PrintableStringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeCharString(Value, explicitTagging, Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
371
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Real.cs
vendored
Normal file
371
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Real.cs
vendored
Normal file
@@ -0,0 +1,371 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1Real : Asn1Type
|
||||
{
|
||||
private const int MinusInfinity = 0x41;
|
||||
private const int PlusInfinity = 0x40;
|
||||
private const int RealBase2 = 0;
|
||||
private const int RealBase8 = 0x10;
|
||||
private const int RealBase16 = 0x20;
|
||||
private const int RealBaseMask = 0x30;
|
||||
private const int RealBinary = 0x80;
|
||||
private const int RealExplen1 = 0;
|
||||
private const int RealExplen2 = 1;
|
||||
private const int RealExplen3 = 2;
|
||||
private const int RealExplenLong = 3;
|
||||
private const int RealExplenMask = 3;
|
||||
private const int RealFactorMask = 12;
|
||||
private const int RealIso6093Mask = 0x3f;
|
||||
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, RealTypeCode);
|
||||
|
||||
[NonSerialized]
|
||||
public double Value;
|
||||
|
||||
public Asn1Real()
|
||||
{
|
||||
Value = 0.0;
|
||||
}
|
||||
|
||||
public Asn1Real(double value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
Value = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var num2 = buffer.ReadByte();
|
||||
|
||||
if (length == 1)
|
||||
{
|
||||
switch (num2)
|
||||
{
|
||||
case PlusInfinity:
|
||||
Value = double.PositiveInfinity;
|
||||
return;
|
||||
|
||||
case MinusInfinity:
|
||||
Value = double.NegativeInfinity;
|
||||
return;
|
||||
}
|
||||
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
|
||||
length--;
|
||||
|
||||
if ((num2 & RealBinary) == 0)
|
||||
{
|
||||
var num8 = length;
|
||||
var num9 = 0;
|
||||
|
||||
var builder = new StringBuilder { Length = num8 };
|
||||
|
||||
while (num8 > 0)
|
||||
{
|
||||
var num7 = buffer.Read();
|
||||
|
||||
if (num7 == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
builder[num9++] = (char)num7;
|
||||
num8--;
|
||||
}
|
||||
|
||||
var num10 = num2 & RealIso6093Mask;
|
||||
var num11 = 0;
|
||||
|
||||
for (var i = 0; i < builder.Length; i++)
|
||||
{
|
||||
var ch = builder[i];
|
||||
|
||||
if ((num10 >= 2) && (ch == ','))
|
||||
{
|
||||
builder[i] = '.';
|
||||
num11++;
|
||||
}
|
||||
else if (((num10 >= 1) && (((ch >= '0') && (ch <= '9')) || ((ch == '+') || (ch == '-')))) || (((num10 >= 2) && (ch == '.')) || ((num10 == 3) && ((ch == 'E') || (ch == 'e')))))
|
||||
{
|
||||
num11++;
|
||||
}
|
||||
else if ((num11 != 0) || (ch != ' '))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
Value = double.Parse(builder.ToString());
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int num6;
|
||||
int num3;
|
||||
|
||||
switch ((num2 & RealExplenMask))
|
||||
{
|
||||
case RealExplen1:
|
||||
num3 = 1;
|
||||
break;
|
||||
|
||||
case RealExplen2:
|
||||
num3 = 2;
|
||||
break;
|
||||
|
||||
case RealExplen3:
|
||||
num3 = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
num3 = buffer.ReadByte();
|
||||
length--;
|
||||
break;
|
||||
}
|
||||
|
||||
var num4 = (int)Asn1RunTime.DecodeIntValue(buffer, num3, true);
|
||||
length -= num3;
|
||||
|
||||
var num5 = Asn1RunTime.DecodeIntValue(buffer, length, false) * (1L << ((num2 & RealFactorMask) >> 2));
|
||||
|
||||
switch ((num2 & RealBaseMask))
|
||||
{
|
||||
case RealBase2:
|
||||
num6 = 2;
|
||||
break;
|
||||
|
||||
case RealBase8:
|
||||
num6 = 8;
|
||||
break;
|
||||
|
||||
case RealBase16:
|
||||
num6 = 16;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
|
||||
Value = num5 * Math.Pow(num6, num4);
|
||||
|
||||
if ((num2 & PlusInfinity) != 0)
|
||||
{
|
||||
Value = -Value;
|
||||
}
|
||||
}
|
||||
|
||||
buffer.TypeCode = RealTypeCode;
|
||||
}
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = 0;
|
||||
|
||||
if (double.IsNegativeInfinity(Value))
|
||||
{
|
||||
len = buffer.EncodeIntValue(MinusInfinity);
|
||||
}
|
||||
else if (double.IsPositiveInfinity(Value))
|
||||
{
|
||||
len = buffer.EncodeIntValue(PlusInfinity);
|
||||
}
|
||||
|
||||
else if (Value != 0.0)
|
||||
{
|
||||
var num2 = BitConverter.DoubleToInt64Bits(Value);
|
||||
var num3 = ((num2 >> RealIso6093Mask) == 0L) ? 1 : -1;
|
||||
var num4 = ((int)((num2 >> 0x34) & 0x7ffL)) - 0x433;
|
||||
var w = (num4 == 0) ? ((num2 & 0xfffffffffffffL) << 1) : ((num2 & 0xfffffffffffffL) | 0x10000000000000L);
|
||||
|
||||
if (w != 0L)
|
||||
{
|
||||
var bits = TrailingZerosCnt(w);
|
||||
w = Asn1Util.UrShift(w, bits);
|
||||
num4 += bits;
|
||||
}
|
||||
|
||||
len += buffer.EncodeIntValue(w);
|
||||
|
||||
var num7 = buffer.EncodeIntValue(num4);
|
||||
len += num7;
|
||||
|
||||
var num8 = RealBinary;
|
||||
|
||||
if (num3 == -1)
|
||||
{
|
||||
num8 |= PlusInfinity;
|
||||
}
|
||||
|
||||
switch (num7)
|
||||
{
|
||||
case RealExplen2:
|
||||
break;
|
||||
|
||||
case RealExplen3:
|
||||
num8 |= 1;
|
||||
break;
|
||||
|
||||
case RealExplenLong:
|
||||
num8 |= 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
num8 |= 3;
|
||||
len += buffer.EncodeIntValue(num7);
|
||||
break;
|
||||
}
|
||||
|
||||
buffer.Copy((byte)num8);
|
||||
len++;
|
||||
}
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
if (Value == 0.0)
|
||||
{
|
||||
outs.EncodeLength(0);
|
||||
}
|
||||
else if (Value == double.NegativeInfinity)
|
||||
{
|
||||
outs.EncodeIntValue(MinusInfinity, true);
|
||||
}
|
||||
else if (Value == double.PositiveInfinity)
|
||||
{
|
||||
outs.EncodeIntValue(PlusInfinity, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
var len = 1;
|
||||
var num2 = BitConverter.DoubleToInt64Bits(Value);
|
||||
var num3 = ((num2 >> RealIso6093Mask) == 0L) ? 1 : -1;
|
||||
var num4 = ((int)((num2 >> 0x34) & 0x7ffL)) - 0x433;
|
||||
var w = (num4 == 0) ? ((num2 & 0xfffffffffffffL) << 1) : ((num2 & 0xfffffffffffffL) | 0x10000000000000L);
|
||||
|
||||
if (w != 0L)
|
||||
{
|
||||
var bits = TrailingZerosCnt(w);
|
||||
w = Asn1Util.UrShift(w, bits);
|
||||
num4 += bits;
|
||||
len += Asn1Util.GetUlongBytesCount(w);
|
||||
}
|
||||
else
|
||||
{
|
||||
len++;
|
||||
}
|
||||
|
||||
var num7 = RealBinary;
|
||||
|
||||
if (num3 == -1)
|
||||
{
|
||||
num7 |= PlusInfinity;
|
||||
}
|
||||
|
||||
var bytesCount = Asn1Util.GetBytesCount(num4);
|
||||
len += bytesCount;
|
||||
|
||||
switch (bytesCount)
|
||||
{
|
||||
case RealExplen2:
|
||||
break;
|
||||
|
||||
case RealExplen3:
|
||||
num7 |= 1;
|
||||
break;
|
||||
|
||||
case RealExplenLong:
|
||||
num7 |= 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
num7 |= 3;
|
||||
len++;
|
||||
break;
|
||||
}
|
||||
|
||||
outs.EncodeLength(len);
|
||||
outs.WriteByte((byte)num7);
|
||||
|
||||
if ((num7 & 3) == 3)
|
||||
{
|
||||
outs.EncodeIntValue(bytesCount, false);
|
||||
}
|
||||
|
||||
outs.EncodeIntValue(num4, false);
|
||||
outs.EncodeIntValue(w, false);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Equals(double value)
|
||||
{
|
||||
return (Value == value);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var real = value as Asn1Real;
|
||||
|
||||
if (real == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Value == real.Value);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value.ToString();
|
||||
}
|
||||
|
||||
private static int TrailingZerosCnt(long w)
|
||||
{
|
||||
var num = Asn1RunTime.IntTrailingZerosCnt((int)w);
|
||||
|
||||
if (num >= RealBase16)
|
||||
{
|
||||
return (Asn1RunTime.IntTrailingZerosCnt((int)Asn1Util.UrShift(w, RealBase16)) + RealBase16);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
}
|
||||
}
|
||||
74
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1RelativeOid.cs
vendored
Normal file
74
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1RelativeOid.cs
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1RelativeOid : Asn1ObjectIdentifier
|
||||
{
|
||||
public new static readonly Asn1Tag Tag = new Asn1Tag(0, 0, RelativeOidTypeCode);
|
||||
|
||||
|
||||
public Asn1RelativeOid()
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1RelativeOid(OidValue oidValue)
|
||||
: base(oidValue)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var len = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
OidValue = OidValue.FromArray(buffer.DecodeRelOidContents(len));
|
||||
buffer.TypeCode = RelativeOidTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
if (OidValue.Items.Length < 1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException);
|
||||
}
|
||||
|
||||
var len = 0;
|
||||
|
||||
for (var i = OidValue.Items.Length - 1; i >= 0; i--)
|
||||
{
|
||||
len += buffer.EncodeIdentifier(OidValue.Items[i]);
|
||||
}
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
var len = 0;
|
||||
|
||||
foreach (var i in OidValue.Items)
|
||||
{
|
||||
len += Asn1RunTime.GetIdentBytesCount(i);
|
||||
}
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
outs.EncodeLength(len);
|
||||
|
||||
foreach (var i in OidValue.Items)
|
||||
{
|
||||
outs.EncodeIdentifier(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
151
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1RunTime.cs
vendored
Normal file
151
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1RunTime.cs
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public static class Asn1RunTime
|
||||
{
|
||||
public const int LicBer = 1;
|
||||
public const int LicPer = 2;
|
||||
public const int LicXer = 4;
|
||||
public const long Bit0Mask = -9223372036854775808L;
|
||||
|
||||
public static long DecodeIntValue(Asn1DecodeBuffer buffer, int length, bool signExtend)
|
||||
{
|
||||
var num = 0L;
|
||||
|
||||
if (length > 8)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1IntegerValueIsTooLarge);
|
||||
}
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var num2 = buffer.ReadByte();
|
||||
|
||||
if (num2 < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
if ((i == 0) && signExtend)
|
||||
{
|
||||
num = (num2 > 0x7f) ? -1 : 0;
|
||||
}
|
||||
|
||||
num = (num * 0x100L) + num2;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public static int GetIdentBytesCount(long ident)
|
||||
{
|
||||
if (ident < 0x80L)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ident < 0x4000L)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (ident < 0x200000L)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (ident < 0x10000000L)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (ident < 0x800000000L)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
if (ident < 0x40000000000L)
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
if (ident < 0x2000000000000L)
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
|
||||
if (ident < 0x100000000000000L)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
return 9;
|
||||
}
|
||||
|
||||
public static int GetLongBitCount(long ivalue)
|
||||
{
|
||||
var num = ivalue & Bit0Mask;
|
||||
var num2 = 0;
|
||||
|
||||
if (ivalue != 0L)
|
||||
{
|
||||
while ((ivalue & Bit0Mask) == num)
|
||||
{
|
||||
num2++;
|
||||
ivalue = ivalue << 1;
|
||||
}
|
||||
|
||||
if (num == Bit0Mask)
|
||||
{
|
||||
num2--;
|
||||
}
|
||||
|
||||
return (0x40 - num2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int GetLongBytesCount(long value)
|
||||
{
|
||||
var num = 0x7f80000000000000L;
|
||||
var num2 = 8;
|
||||
|
||||
if (value < 0L)
|
||||
{
|
||||
value ^= -1L;
|
||||
}
|
||||
|
||||
while ((num2 > 1) && ((value & num) == 0L))
|
||||
{
|
||||
num = num >> 8;
|
||||
num2--;
|
||||
}
|
||||
|
||||
return num2;
|
||||
}
|
||||
|
||||
public static int GetUlongBytesCount(long value)
|
||||
{
|
||||
var number = -72057594037927936L;
|
||||
var num2 = 8;
|
||||
|
||||
while ((num2 > 1) && ((value & number) == 0L))
|
||||
{
|
||||
number = Asn1Util.UrShift(number, 8);
|
||||
num2--;
|
||||
}
|
||||
|
||||
return num2;
|
||||
}
|
||||
|
||||
public static int IntTrailingZerosCnt(int w)
|
||||
{
|
||||
return (0x20 -
|
||||
(((w & 0xffff) != 0)
|
||||
? (((w & 0xff) != 0) ? ((((w & 15) != 0) ? (((w & 3) != 0) ? (((w & 1) != 0) ? 8 : 7) : (((w & 4) != 0) ? 6 : 5)) : (((w & 0x30) != 0) ? (((w & 0x10) != 0) ? 4 : 3) : (((w & 0x40) != 0) ? 2 : (((w & 0x80) != 0) ? 1 : 0)))) + 0x18) : (((((w = Asn1Util.UrShift(w, 8)) & 15) != 0) ? (((w & 3) != 0) ? (((w & 1) != 0) ? 8 : 7) : (((w & 4) != 0) ? 6 : 5)) : (((w & 0x30) != 0) ? (((w & 0x10) != 0) ? 4 : 3) : (((w & 0x40) != 0) ? 2 : (((w & 0x80) != 0) ? 1 : 0)))) + 0x10))
|
||||
: ((((w = Asn1Util.UrShift(w, 0x10)) & 0xff) != 0) ? ((((w & 15) != 0) ? (((w & 3) != 0) ? (((w & 1) != 0) ? 8 : 7) : (((w & 4) != 0) ? 6 : 5)) : (((w & 0x30) != 0) ? (((w & 0x10) != 0) ? 4 : 3) : (((w & 0x40) != 0) ? 2 : (((w & 0x80) != 0) ? 1 : 0)))) + 8) : ((((w = Asn1Util.UrShift(w, 8)) & 15) != 0) ? (((w & 3) != 0) ? (((w & 1) != 0) ? 8 : 7) : (((w & 4) != 0) ? 6 : 5)) : (((w & 0x30) != 0) ? (((w & 0x10) != 0) ? 4 : 3) : (((w & 0x40) != 0) ? 2 : (((w & 0x80) != 0) ? 1 : 0)))))));
|
||||
}
|
||||
}
|
||||
}
|
||||
7
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Status.cs
vendored
Normal file
7
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Status.cs
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public static class Asn1Status
|
||||
{
|
||||
public const int IndefiniteLength = -9999;
|
||||
}
|
||||
}
|
||||
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1T61String.cs
vendored
Normal file
35
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1T61String.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1T61String : Asn1VarWidthCharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, T61StringTypeCode);
|
||||
|
||||
public Asn1T61String()
|
||||
: base(T61StringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1T61String(string data)
|
||||
: base(data, T61StringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeCharString(Value, explicitTagging, Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
108
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Tag.cs
vendored
Normal file
108
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Tag.cs
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1Tag
|
||||
{
|
||||
public const short Universal = 0;
|
||||
public const short Private = 0xc0;
|
||||
public const short Application = 0x40;
|
||||
|
||||
public const short Bit8Mask = 0x80;
|
||||
public const short ClassMask = 0xc0;
|
||||
public const short CONS = 0x20;
|
||||
public const short CTXT = 0x80;
|
||||
public const bool EXPL = true;
|
||||
public const short EXTIDCODE = 0x1f;
|
||||
public const short FormMask = 0x20;
|
||||
public const short IDMask = 0x1f;
|
||||
public const bool IMPL = false;
|
||||
public const short L7BitsMask = 0x7f;
|
||||
public const short PRIM = 0;
|
||||
|
||||
public static readonly Asn1Tag Eoc = new Asn1Tag(0, 0, Asn1Type.EocTypeCode);
|
||||
public static readonly Asn1Tag Set = new Asn1Tag(0, 0x20, Asn1Type.SetTypeCode);
|
||||
public static readonly Asn1Tag Sequence = new Asn1Tag(0, 0x20, Asn1Type.SequenceTypeCode);
|
||||
public static readonly Asn1Tag Enumerated = new Asn1Tag(0, 0, Asn1Type.EnumeratedTypeCode);
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
public short Class;
|
||||
|
||||
[NonSerialized]
|
||||
public short Form;
|
||||
|
||||
[NonSerialized]
|
||||
public int IdCode;
|
||||
|
||||
|
||||
public Asn1Tag()
|
||||
{
|
||||
Class = 0;
|
||||
Form = 0;
|
||||
IdCode = 0;
|
||||
}
|
||||
|
||||
public Asn1Tag(short tagclass, short form, int idCode)
|
||||
{
|
||||
Class = tagclass;
|
||||
Form = form;
|
||||
IdCode = idCode;
|
||||
}
|
||||
|
||||
public virtual bool Constructed
|
||||
{
|
||||
get { return (Form == 0x20); }
|
||||
}
|
||||
|
||||
public bool Equals(Asn1Tag tag)
|
||||
{
|
||||
return Equals(tag.Class, tag.Form, tag.IdCode);
|
||||
}
|
||||
|
||||
public virtual bool Equals(short tagclass, short form, int idCode)
|
||||
{
|
||||
return ((Class == tagclass) && (IdCode == idCode));
|
||||
}
|
||||
|
||||
public virtual bool IsEoc()
|
||||
{
|
||||
return Equals(0, 0, 0);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
builder.Append("[");
|
||||
|
||||
switch (Class)
|
||||
{
|
||||
case 0x80:
|
||||
break;
|
||||
|
||||
case Private:
|
||||
builder.Append("PRIVATE ");
|
||||
break;
|
||||
|
||||
case Universal:
|
||||
builder.Append("UNIVERSAL ");
|
||||
break;
|
||||
|
||||
case Application:
|
||||
builder.Append("APPLICATION ");
|
||||
break;
|
||||
|
||||
default:
|
||||
builder.Append("??? ");
|
||||
break;
|
||||
}
|
||||
|
||||
builder.Append(Convert.ToString(IdCode));
|
||||
builder.Append("]");
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
569
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Time.cs
vendored
Normal file
569
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Time.cs
vendored
Normal file
@@ -0,0 +1,569 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class Asn1Time : Asn18BitCharString, IComparable
|
||||
{
|
||||
public const int January = 1;
|
||||
public const int February = 2;
|
||||
public const int March = 3;
|
||||
public const int April = 4;
|
||||
public const int May = 5;
|
||||
public const int June = 6;
|
||||
public const int July = 7;
|
||||
public const int August = 8;
|
||||
public const int September = 9;
|
||||
public const int October = 10;
|
||||
public const int November = 11;
|
||||
public const int December = 12;
|
||||
|
||||
public static readonly short[] DaysInMonth = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
|
||||
public Asn1Time(short typeCode, bool useDerRules)
|
||||
: base(typeCode)
|
||||
{
|
||||
DerRules = useDerRules;
|
||||
Init();
|
||||
}
|
||||
|
||||
public Asn1Time(string data, short typeCode, bool useDerRules)
|
||||
: base(data, typeCode)
|
||||
{
|
||||
DerRules = useDerRules;
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected bool Parsed;
|
||||
|
||||
[NonSerialized]
|
||||
protected bool DerRules;
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int DiffHourValue;
|
||||
|
||||
public virtual int DiffHour
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
return DiffHourValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value < -12) || (value > 12))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHourValue, value);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
DiffHourValue = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int DiffMinValue;
|
||||
|
||||
public virtual int DiffMinute
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
|
||||
return DiffMinValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected string SecFraction;
|
||||
|
||||
public virtual string Fraction
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
return SecFraction;
|
||||
}
|
||||
set
|
||||
{
|
||||
SafeParseString();
|
||||
SecFraction = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int YearValue;
|
||||
|
||||
public virtual int Year
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
return YearValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, value);
|
||||
}
|
||||
|
||||
if (!CheckDate(DayValue, MonthValue, value))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValueForDayAndMonth, value, DayValue, MonthValue);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
YearValue = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int MonthValue;
|
||||
|
||||
public virtual int Month
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
|
||||
return MonthValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value < 1) || (value > 12))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMonthValue, value);
|
||||
}
|
||||
|
||||
if (!CheckDate(DayValue, value, YearValue))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMonthValueForDayAndYear, value, DayValue, YearValue);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
MonthValue = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int DayValue;
|
||||
|
||||
public virtual int Day
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
return DayValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (((value < 1) || (value > 31)) || !CheckDate(value, MonthValue, YearValue))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDayValueForMonthAndYear, value, MonthValue, YearValue);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
DayValue = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int HourValue;
|
||||
|
||||
public virtual int Hour
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
return HourValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value < 0) || (value > 23))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidHourValue, value);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
HourValue = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int MinuteValue;
|
||||
|
||||
public virtual int Minute
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
return MinuteValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value < 0) || (value > 59))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMinuteValue, value);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
MinuteValue = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected int SecondValue;
|
||||
|
||||
public virtual int Second
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
return SecondValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if ((value < 0) || (value > 59))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidSecondValue, value);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
SecondValue = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[NonSerialized]
|
||||
protected bool UtcFlag;
|
||||
|
||||
public virtual bool Utc
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
|
||||
return UtcFlag;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (!DerRules)
|
||||
{
|
||||
SafeParseString();
|
||||
UtcFlag = value;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual int CompareTo(object other)
|
||||
{
|
||||
if (other is DateTime)
|
||||
{
|
||||
var time2 = (DateTime)other;
|
||||
return (int)(GetTime().Ticks - time2.Ticks);
|
||||
}
|
||||
return (int)(GetTime().Ticks - ((Asn1Time)other).GetTime().Ticks);
|
||||
}
|
||||
|
||||
|
||||
protected static char CharAt(string s, int index)
|
||||
{
|
||||
if (index >= s.Length)
|
||||
{
|
||||
return '\0';
|
||||
}
|
||||
|
||||
return s[index];
|
||||
}
|
||||
|
||||
private static bool CheckDate(int day, int month, int year)
|
||||
{
|
||||
if ((day <= 0) || (month <= 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((year >= 0) && (month > 0))
|
||||
{
|
||||
int num = DaysInMonth[month];
|
||||
|
||||
if (((month == 2) && ((year % 4) == 0)) && (((year % 100) != 0) || ((year % 400) == 0)))
|
||||
{
|
||||
num++;
|
||||
}
|
||||
|
||||
if ((day >= 1) && (day <= num))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (month > 0)
|
||||
{
|
||||
if (day <= DaysInMonth[month])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((month == 2) && (day <= (DaysInMonth[month] + 1)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
YearValue = MonthValue = DayValue = HourValue = -1;
|
||||
MinuteValue = SecondValue = DiffHourValue = DiffMinValue = 0;
|
||||
UtcFlag = DerRules;
|
||||
Parsed = true;
|
||||
SecFraction = "";
|
||||
Value = "";
|
||||
}
|
||||
|
||||
protected abstract bool CompileString();
|
||||
|
||||
protected override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength, Asn1Tag tag)
|
||||
{
|
||||
Parsed = false;
|
||||
base.Decode(buffer, explicitTagging, implicitLength, tag);
|
||||
DerRules = buffer is Asn1DerDecodeBuffer;
|
||||
}
|
||||
|
||||
protected override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
SafeParseString();
|
||||
|
||||
var flag = buffer is Asn1DerEncodeBuffer;
|
||||
|
||||
if (DerRules != flag)
|
||||
{
|
||||
DerRules = flag;
|
||||
|
||||
if (!CompileString())
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1TimeStringCouldNotBeGenerated);
|
||||
}
|
||||
}
|
||||
|
||||
return base.Encode(buffer, explicitTagging, tag);
|
||||
}
|
||||
|
||||
public virtual void Encode(Asn1BerOutputStream outs, bool explicitTagging, Asn1Tag tag)
|
||||
{
|
||||
SafeParseString();
|
||||
outs.EncodeCharString(Value, explicitTagging, tag);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (value is Asn1Time)
|
||||
{
|
||||
return GetTime().Equals(((Asn1Time)value).GetTime());
|
||||
}
|
||||
|
||||
return ((value is DateTime) && GetTime().Equals((DateTime)value));
|
||||
}
|
||||
|
||||
public virtual int GetDiff()
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
|
||||
return ((DiffHourValue * 60) + DiffMinValue);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Value.GetHashCode();
|
||||
}
|
||||
|
||||
public virtual DateTime GetTime()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(SecFraction))
|
||||
{
|
||||
return new DateTime(YearValue, MonthValue, DayValue, HourValue, MinuteValue, SecondValue, int.Parse(SecFraction));
|
||||
}
|
||||
|
||||
return new DateTime(YearValue, MonthValue, DayValue, HourValue, MinuteValue, SecondValue);
|
||||
}
|
||||
|
||||
protected virtual void Init()
|
||||
{
|
||||
YearValue = MonthValue = DayValue = HourValue = -1;
|
||||
MinuteValue = SecondValue = 0;
|
||||
DiffHourValue = DiffMinValue = 0;
|
||||
UtcFlag = DerRules;
|
||||
SecFraction = "";
|
||||
}
|
||||
|
||||
protected static int ParseInt(string str, IntHolder off, int len)
|
||||
{
|
||||
if ((off.Value + len) > str.Length)
|
||||
{
|
||||
throw ExceptionUtility.ArgumentOutOfRange("off");
|
||||
}
|
||||
|
||||
var mValue = off.Value;
|
||||
off.Value += len;
|
||||
|
||||
return int.Parse(str.Substring(mValue, len));
|
||||
}
|
||||
|
||||
public abstract void ParseString(string data);
|
||||
|
||||
protected virtual void PutInteger(int width, int value)
|
||||
{
|
||||
PutInteger(StringBuffer, width, value);
|
||||
}
|
||||
|
||||
public static void PutInteger(StringBuilder data, int width, int value)
|
||||
{
|
||||
var str = Convert.ToString(value);
|
||||
var length = str.Length;
|
||||
|
||||
if (length < width)
|
||||
{
|
||||
for (var i = length; i < width; i++)
|
||||
{
|
||||
data.Append('0');
|
||||
}
|
||||
}
|
||||
else if (length > width)
|
||||
{
|
||||
str = str.Substring(length - width);
|
||||
}
|
||||
|
||||
data.Append(str);
|
||||
}
|
||||
|
||||
protected virtual void SafeParseString()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetDiff(int inMinutes)
|
||||
{
|
||||
if (Math.Abs(inMinutes) > 720)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.InvalidDiffValue, inMinutes);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
DiffHourValue = inMinutes / 60;
|
||||
DiffMinValue = inMinutes % 60;
|
||||
CompileString();
|
||||
}
|
||||
|
||||
public virtual void SetDiff(int dhour, int dminute)
|
||||
{
|
||||
if ((dhour < -12) || (dhour > 12))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHourValue, dhour);
|
||||
}
|
||||
|
||||
if (Math.Abs(dminute) > 59)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffMinuteValue, dminute);
|
||||
}
|
||||
|
||||
SafeParseString();
|
||||
DiffHourValue = dhour;
|
||||
|
||||
if (dhour < 0)
|
||||
{
|
||||
DiffMinValue = -Math.Abs(dminute);
|
||||
}
|
||||
else
|
||||
{
|
||||
DiffMinValue = Math.Abs(dminute);
|
||||
}
|
||||
|
||||
CompileString();
|
||||
}
|
||||
|
||||
public virtual void SetTime(DateTime time)
|
||||
{
|
||||
Clear();
|
||||
YearValue = time.Year;
|
||||
MonthValue = time.Month;
|
||||
DayValue = time.Day;
|
||||
HourValue = time.Hour;
|
||||
MinuteValue = time.Minute;
|
||||
SecondValue = time.Second;
|
||||
SecFraction = Convert.ToString(time.Millisecond);
|
||||
DiffHourValue = DiffMinValue = 0;
|
||||
UtcFlag = DerRules;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
}
|
||||
46
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1TraceHandler.cs
vendored
Normal file
46
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1TraceHandler.cs
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public class Asn1TraceHandler : IAsn1NamedEventHandler
|
||||
{
|
||||
internal StreamWriter mPrintStream;
|
||||
|
||||
public Asn1TraceHandler()
|
||||
{
|
||||
mPrintStream = new StreamWriter(Console.OpenStandardOutput(), Console.Out.Encoding);
|
||||
mPrintStream.AutoFlush = true;
|
||||
}
|
||||
|
||||
public Asn1TraceHandler(StreamWriter ps)
|
||||
{
|
||||
mPrintStream = ps;
|
||||
}
|
||||
|
||||
public virtual void Characters(string svalue, short typeCode)
|
||||
{
|
||||
mPrintStream.WriteLine("data: " + svalue);
|
||||
}
|
||||
|
||||
public virtual void EndElement(string name, int index)
|
||||
{
|
||||
mPrintStream.Write(name);
|
||||
if (index >= 0)
|
||||
{
|
||||
mPrintStream.Write("[" + index + "]");
|
||||
}
|
||||
mPrintStream.WriteLine(": end");
|
||||
}
|
||||
|
||||
public virtual void StartElement(string name, int index)
|
||||
{
|
||||
mPrintStream.Write(name);
|
||||
if (index >= 0)
|
||||
{
|
||||
mPrintStream.Write("[" + index + "]");
|
||||
}
|
||||
mPrintStream.WriteLine(": start");
|
||||
}
|
||||
}
|
||||
}
|
||||
168
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Type.cs
vendored
Normal file
168
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Type.cs
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class Asn1Type : IAsn1Type
|
||||
{
|
||||
public const short EocTypeCode = 0;
|
||||
public const short BooleanTypeCode = 1;
|
||||
public const short BigIntegerTypeCode = 2;
|
||||
public const short BitStringTypeCode = 3;
|
||||
public const short OctetStringTypeCode = 4;
|
||||
public const short NullTypeCode = 5;
|
||||
public const short ObjectIdentifierTypeCode = 6;
|
||||
public const short ObjectDescriptorTypeCode = 7;
|
||||
public const short ExternalTypeCode = 8;
|
||||
public const short RealTypeCode = 9;
|
||||
public const short EnumeratedTypeCode = 10;
|
||||
public const short Utf8StringTypeCode = 12;
|
||||
public const short RelativeOidTypeCode = 13;
|
||||
public const short SequenceTypeCode = 0x10;
|
||||
public const short SetTypeCode = 0x11;
|
||||
public const short NumericStringTypeCode = 0x12;
|
||||
public const short PrintableStringTypeCode = 0x13;
|
||||
public const short T61StringTypeCode = 20;
|
||||
public const short VideoTexStringTypeCode = 0x15;
|
||||
public const short Ia5StringTypeCode = 0x16;
|
||||
public const short UtcTimeTypeCode = 0x17;
|
||||
public const short GeneralTimeTypeCode = 0x18;
|
||||
public const short GraphicStringTypeCode = 0x19;
|
||||
public const short VisibleStringTypeCode = 0x1a;
|
||||
public const short GeneralStringTypeCode = 0x1b;
|
||||
public const short UniversalStringTypeCode = 0x1c;
|
||||
public const short BmpStringTypeCode = 30;
|
||||
public const short OpenTypeTypeCode = 0x63;
|
||||
|
||||
[NonSerialized]
|
||||
private readonly IntHolder _parsedLen = new IntHolder();
|
||||
|
||||
[NonSerialized]
|
||||
private readonly Asn1Tag _parsedTag = new Asn1Tag();
|
||||
|
||||
public virtual int Length
|
||||
{
|
||||
get { throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException); }
|
||||
}
|
||||
|
||||
public virtual void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public virtual void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Print(TextWriter outs, string varName, int level)
|
||||
{
|
||||
Indent(outs, level);
|
||||
outs.WriteLine(varName + " = " + ToString());
|
||||
}
|
||||
|
||||
public virtual void Decode(Asn1BerDecodeBuffer buffer)
|
||||
{
|
||||
Decode(buffer, true, 0);
|
||||
}
|
||||
|
||||
public virtual int Encode(Asn1BerEncodeBuffer buffer)
|
||||
{
|
||||
return Encode(buffer, true);
|
||||
}
|
||||
|
||||
public static string GetTypeName(short typeCode)
|
||||
{
|
||||
switch (typeCode)
|
||||
{
|
||||
case EocTypeCode:
|
||||
return "EOC";
|
||||
case BooleanTypeCode:
|
||||
return "BOOLEAN";
|
||||
case BigIntegerTypeCode:
|
||||
return "INTEGER";
|
||||
case BitStringTypeCode:
|
||||
return "BIT STRING";
|
||||
case OctetStringTypeCode:
|
||||
return "OCTET STRING";
|
||||
case NullTypeCode:
|
||||
return "NULL";
|
||||
case ObjectIdentifierTypeCode:
|
||||
return "OBJECT IDENTIFIER";
|
||||
case ObjectDescriptorTypeCode:
|
||||
return "ObjectDescriptor";
|
||||
case ExternalTypeCode:
|
||||
return "EXTERNAL";
|
||||
case RealTypeCode:
|
||||
return "REAL";
|
||||
case EnumeratedTypeCode:
|
||||
return "ENUMERATED";
|
||||
case Utf8StringTypeCode:
|
||||
return "UTF8String";
|
||||
case SequenceTypeCode:
|
||||
return "SEQUENCE";
|
||||
case SetTypeCode:
|
||||
return "SET";
|
||||
case NumericStringTypeCode:
|
||||
return "NumericString";
|
||||
case PrintableStringTypeCode:
|
||||
return "PrintableString";
|
||||
case T61StringTypeCode:
|
||||
return "T61String";
|
||||
case VideoTexStringTypeCode:
|
||||
return "VideotexString";
|
||||
case Ia5StringTypeCode:
|
||||
return "IA5String";
|
||||
case UtcTimeTypeCode:
|
||||
return "UTCTime";
|
||||
case GeneralTimeTypeCode:
|
||||
return "GeneralTime";
|
||||
case GraphicStringTypeCode:
|
||||
return "GraphicString";
|
||||
case VisibleStringTypeCode:
|
||||
return "VisibleString";
|
||||
case GeneralStringTypeCode:
|
||||
return "GeneralString";
|
||||
case UniversalStringTypeCode:
|
||||
return "UniversalString";
|
||||
case BmpStringTypeCode:
|
||||
return "BMPString";
|
||||
case OpenTypeTypeCode:
|
||||
return "ANY";
|
||||
}
|
||||
|
||||
return "?";
|
||||
}
|
||||
|
||||
public virtual void Indent(TextWriter outs, int level)
|
||||
{
|
||||
var num2 = level * 3;
|
||||
|
||||
for (var i = 0; i < num2; i++)
|
||||
{
|
||||
outs.Write(" ");
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual int MatchTag(Asn1BerDecodeBuffer buffer, Asn1Tag tag)
|
||||
{
|
||||
return MatchTag(buffer, tag.Class, tag.Form, tag.IdCode);
|
||||
}
|
||||
|
||||
protected virtual int MatchTag(Asn1BerDecodeBuffer buffer, short tagClass, short tagForm, int tagIdCode)
|
||||
{
|
||||
if (!buffer.MatchTag(tagClass, tagForm, tagIdCode, _parsedTag, _parsedLen))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1TagMatchFailedException, new Asn1Tag(tagClass, tagForm, tagIdCode), _parsedTag, buffer.ByteCount);
|
||||
}
|
||||
|
||||
return _parsedLen.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
227
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1UniversalString.cs
vendored
Normal file
227
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1UniversalString.cs
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1UniversalString : Asn1Type
|
||||
{
|
||||
public const int BitsPerChar = 0x20;
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, UniversalStringTypeCode);
|
||||
|
||||
[NonSerialized]
|
||||
private StringBuilder _stringBuffer;
|
||||
|
||||
[NonSerialized]
|
||||
private int[] _value;
|
||||
|
||||
|
||||
public Asn1UniversalString()
|
||||
{
|
||||
_value = new int[0];
|
||||
}
|
||||
|
||||
public Asn1UniversalString(int[] value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public Asn1UniversalString(string value)
|
||||
{
|
||||
_value = new int[value.Length];
|
||||
|
||||
for (var i = 0; i < value.Length; i++)
|
||||
{
|
||||
_value[i] = value[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override int Length
|
||||
{
|
||||
get { return _value.Length; }
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var llen = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
var idx = new IntHolder(0);
|
||||
var lastTag = buffer.LastTag;
|
||||
|
||||
if ((lastTag == null) || !lastTag.Constructed)
|
||||
{
|
||||
ReadSegment(buffer, llen, idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
var context = new Asn1BerDecodeContext(buffer, llen);
|
||||
|
||||
while (!context.Expired())
|
||||
{
|
||||
var num2 = MatchTag(buffer, Asn1OctetString.Tag);
|
||||
|
||||
if (num2 <= 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidFormatOfConstructedValue, buffer.ByteCount);
|
||||
}
|
||||
|
||||
ReadSegment(buffer, num2, idx);
|
||||
}
|
||||
|
||||
if (llen == Asn1Status.IndefiniteLength)
|
||||
{
|
||||
MatchTag(buffer, Asn1Tag.Eoc);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.TypeCode = UniversalStringTypeCode;
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var length = _value.Length;
|
||||
|
||||
for (var i = length - 1; i >= 0; i--)
|
||||
{
|
||||
var num3 = _value[i];
|
||||
|
||||
for (var j = 0; j < 4; j++)
|
||||
{
|
||||
var num = num3 % 0x100;
|
||||
num3 /= 0x100;
|
||||
buffer.Copy((byte)num);
|
||||
}
|
||||
}
|
||||
|
||||
length *= 4;
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
length += buffer.EncodeTagAndLength(Tag, length);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
outs.EncodeUnivString(_value, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var str = value as Asn1UniversalString;
|
||||
|
||||
if (str == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_value.Length != str._value.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < _value.Length; i++)
|
||||
{
|
||||
if (_value[i] != str._value[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
if (_value.Length == 0)
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
var num = 0;
|
||||
var num2 = (_value.Length > 20) ? 20 : _value.Length;
|
||||
|
||||
for (var i = 0; i < num2; i++)
|
||||
{
|
||||
num ^= _value[i];
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
private void ReadSegment(Asn1BerDecodeBuffer buffer, int llen, IntHolder idx)
|
||||
{
|
||||
if ((llen < 0) || ((llen % 4) != 0))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException);
|
||||
}
|
||||
|
||||
var num4 = llen / 4;
|
||||
|
||||
if (_value.Length == 0)
|
||||
{
|
||||
_value = new int[num4];
|
||||
}
|
||||
else if ((idx.Value + num4) >= _value.Length)
|
||||
{
|
||||
ReallocIntArray(idx.Value + num4);
|
||||
}
|
||||
|
||||
var value = idx.Value;
|
||||
|
||||
while (value < (idx.Value + num4))
|
||||
{
|
||||
_value[value] = 0;
|
||||
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
var num = buffer.Read();
|
||||
|
||||
if (num == -1)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount);
|
||||
}
|
||||
|
||||
_value[value] = (_value[value] * 0x100) + num;
|
||||
}
|
||||
|
||||
value++;
|
||||
}
|
||||
|
||||
idx.Value = value;
|
||||
}
|
||||
|
||||
private void ReallocIntArray(int nint)
|
||||
{
|
||||
var value = _value;
|
||||
|
||||
_value = new int[nint];
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
Array.Copy(value, 0, _value, 0, value.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (_stringBuffer == null)
|
||||
{
|
||||
_stringBuffer = new StringBuilder();
|
||||
}
|
||||
|
||||
_stringBuffer.Length = _value.Length;
|
||||
|
||||
for (var i = 0; i < _value.Length; i++)
|
||||
{
|
||||
_stringBuffer[i] = (char)_value[i];
|
||||
}
|
||||
|
||||
return _stringBuffer.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
361
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1UtcTime.cs
vendored
Normal file
361
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1UtcTime.cs
vendored
Normal file
@@ -0,0 +1,361 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1UtcTime : Asn1Time
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, UtcTimeTypeCode);
|
||||
|
||||
|
||||
public Asn1UtcTime()
|
||||
: base(UtcTimeTypeCode, false)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1UtcTime(bool useDerRules)
|
||||
: base(UtcTimeTypeCode, useDerRules)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1UtcTime(string data)
|
||||
: base(data, UtcTimeTypeCode, false)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1UtcTime(string data, bool useDerRules)
|
||||
: base(data, UtcTimeTypeCode, useDerRules)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override string Fraction
|
||||
{
|
||||
get
|
||||
{
|
||||
return "";
|
||||
}
|
||||
set
|
||||
{
|
||||
SecFraction = "";
|
||||
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1FractionNotSupportedForUtcTime);
|
||||
}
|
||||
}
|
||||
|
||||
public override int Year
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Parsed)
|
||||
{
|
||||
ParseString(Value);
|
||||
}
|
||||
|
||||
return YearValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, YearValue);
|
||||
}
|
||||
|
||||
if (value < 100)
|
||||
{
|
||||
if (value >= 50)
|
||||
{
|
||||
Year = value + 0x76c;
|
||||
}
|
||||
else
|
||||
{
|
||||
Year = value + 0x7d0;
|
||||
}
|
||||
}
|
||||
|
||||
Year = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
Clear();
|
||||
HourValue = MinuteValue = -1;
|
||||
UtcFlag = true;
|
||||
}
|
||||
|
||||
public override int CompareTo(object obj)
|
||||
{
|
||||
return base.CompareTo(obj);
|
||||
}
|
||||
|
||||
protected override bool CompileString()
|
||||
{
|
||||
Value = "";
|
||||
|
||||
if (((YearValue < 0) || (DayValue <= 0)) || (((MonthValue <= 0) || (HourValue < 0)) || (MinuteValue < 0)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (StringBuffer == null)
|
||||
{
|
||||
StringBuffer = new StringBuilder();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuffer.Length = 0;
|
||||
}
|
||||
|
||||
if ((DerRules || UtcFlag) && ((DiffHourValue != 0) || (DiffMinValue != 0)))
|
||||
{
|
||||
var time = GetTime();
|
||||
time.AddMinutes(-DiffMinValue);
|
||||
time.AddHours(-DiffHourValue);
|
||||
|
||||
PutInteger(2, time.Year);
|
||||
PutInteger(2, time.Month);
|
||||
PutInteger(2, time.Day);
|
||||
PutInteger(2, time.Hour);
|
||||
PutInteger(2, time.Minute);
|
||||
}
|
||||
else
|
||||
{
|
||||
PutInteger(2, YearValue);
|
||||
PutInteger(2, MonthValue);
|
||||
PutInteger(2, DayValue);
|
||||
PutInteger(2, HourValue);
|
||||
PutInteger(2, MinuteValue);
|
||||
}
|
||||
|
||||
PutInteger(2, SecondValue);
|
||||
|
||||
if (DerRules || UtcFlag)
|
||||
{
|
||||
StringBuffer.Append('Z');
|
||||
}
|
||||
else if ((DiffHourValue != 0) || (DiffMinValue != 0))
|
||||
{
|
||||
StringBuffer.Append((DiffHourValue > 0) ? '+' : '-');
|
||||
PutInteger(2, Math.Abs(DiffHourValue));
|
||||
PutInteger(2, Math.Abs(DiffMinValue));
|
||||
}
|
||||
|
||||
Value = StringBuffer.ToString();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
Decode(buffer, explicitTagging, implicitLength, Tag);
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
return Encode(buffer, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
Encode(outs, explicitTagging, Tag);
|
||||
}
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
Init();
|
||||
HourValue = MinuteValue = -1;
|
||||
UtcFlag = true;
|
||||
}
|
||||
|
||||
public override void ParseString(string data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
throw ExceptionUtility.ArgumentNull("data");
|
||||
}
|
||||
|
||||
Clear();
|
||||
|
||||
var off = new IntHolder(0);
|
||||
|
||||
try
|
||||
{
|
||||
YearValue = ParseInt(data, off, 2);
|
||||
MonthValue = ParseInt(data, off, 2);
|
||||
DayValue = ParseInt(data, off, 2);
|
||||
|
||||
if (YearValue < 0)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, YearValue);
|
||||
}
|
||||
|
||||
if (YearValue < 100)
|
||||
{
|
||||
if (YearValue > 70)
|
||||
{
|
||||
YearValue += 0x76c;
|
||||
}
|
||||
else
|
||||
{
|
||||
YearValue += 0x7d0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((MonthValue < 1) || (MonthValue > 12))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMonthValue, MonthValue);
|
||||
}
|
||||
|
||||
var num = DaysInMonth[MonthValue];
|
||||
|
||||
if (((MonthValue == 2) && ((YearValue % 4) == 0)) && (((YearValue % 100) != 0) || ((YearValue % 400) == 0)))
|
||||
{
|
||||
num++;
|
||||
}
|
||||
|
||||
if ((DayValue < 1) || (DayValue > num))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDayValue, DayValue);
|
||||
}
|
||||
|
||||
var num2 = 0;
|
||||
|
||||
if (!char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1HoursExpected);
|
||||
}
|
||||
|
||||
HourValue = ParseInt(data, off, 2);
|
||||
num2++;
|
||||
|
||||
if (!char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1MinutesExpected);
|
||||
}
|
||||
|
||||
MinuteValue = ParseInt(data, off, 2);
|
||||
num2++;
|
||||
|
||||
if (char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
SecondValue = ParseInt(data, off, 2);
|
||||
num2++;
|
||||
}
|
||||
|
||||
if ((num2 >= 2) && ((HourValue < 0) || (HourValue > UtcTimeTypeCode)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidHourValue, HourValue);
|
||||
}
|
||||
|
||||
if ((num2 >= 2) && ((MinuteValue < 0) || (MinuteValue > 0x3b)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMinuteValue, MinuteValue);
|
||||
}
|
||||
|
||||
if ((num2 == 3) && ((SecondValue < 0) || (SecondValue > 0x3b)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidSecondValue, SecondValue);
|
||||
}
|
||||
|
||||
CharAt(data, off.Value);
|
||||
|
||||
if (CharAt(data, off.Value) == 'Z')
|
||||
{
|
||||
off.Value++;
|
||||
UtcFlag = true;
|
||||
|
||||
if (off.Value != data.Length)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedValuesAtEndOfString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DerRules)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1UnexpectedZoneOffset);
|
||||
}
|
||||
|
||||
UtcFlag = false;
|
||||
var ch = CharAt(data, off.Value);
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case '-':
|
||||
case '+':
|
||||
off.Value++;
|
||||
|
||||
if (!char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHour);
|
||||
}
|
||||
|
||||
DiffHourValue = ParseInt(data, off, 2);
|
||||
|
||||
if (!char.IsDigit(CharAt(data, off.Value)))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffMinute);
|
||||
}
|
||||
|
||||
DiffMinValue = ParseInt(data, off, 2);
|
||||
|
||||
if ((DiffHourValue < 0) || (DiffHourValue > 12))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHourValue, DiffHourValue);
|
||||
}
|
||||
|
||||
if ((DiffMinValue < 0) || (DiffMinValue > 0x3b))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffMinuteValue, DiffMinValue);
|
||||
}
|
||||
|
||||
if (ch == '-')
|
||||
{
|
||||
DiffHourValue = -DiffHourValue;
|
||||
DiffMinValue = -DiffMinValue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Parsed = true;
|
||||
|
||||
if (data != Value)
|
||||
{
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfRangeException)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDateFormat);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidNumberFormat);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDateFormat);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetTime(DateTime time)
|
||||
{
|
||||
Clear();
|
||||
YearValue = time.Year;
|
||||
MonthValue = time.Month;
|
||||
DayValue = time.Day;
|
||||
HourValue = time.Hour;
|
||||
MinuteValue = time.Minute;
|
||||
SecondValue = time.Second;
|
||||
SecFraction = "";
|
||||
DiffHourValue = DiffMinValue = 0;
|
||||
UtcFlag = true;
|
||||
CompileString();
|
||||
}
|
||||
}
|
||||
}
|
||||
98
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Utf8String.cs
vendored
Normal file
98
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Utf8String.cs
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
[Serializable]
|
||||
public class Asn1Utf8String : Asn1CharString
|
||||
{
|
||||
public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, Utf8StringTypeCode);
|
||||
|
||||
public Asn1Utf8String()
|
||||
: base(Utf8StringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
public Asn1Utf8String(string data)
|
||||
: base(data, Utf8StringTypeCode)
|
||||
{
|
||||
}
|
||||
|
||||
private byte[] AllocByteArray(int nbytes)
|
||||
{
|
||||
return new byte[nbytes];
|
||||
}
|
||||
|
||||
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
||||
{
|
||||
var num = explicitTagging ? MatchTag(buffer, Tag) : implicitLength;
|
||||
var str = new Asn1OctetString();
|
||||
str.Decode(buffer, false, num);
|
||||
|
||||
Value = Encoding.UTF8.GetString(str.Value, 0, str.Value.Length);
|
||||
|
||||
if (explicitTagging && (num == Asn1Status.IndefiniteLength))
|
||||
{
|
||||
MatchTag(buffer, Asn1Tag.Eoc);
|
||||
}
|
||||
}
|
||||
|
||||
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
||||
{
|
||||
var len = 0;
|
||||
|
||||
try
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(Value);
|
||||
len = bytes.Length;
|
||||
buffer.Copy(bytes);
|
||||
}
|
||||
catch (IOException exception)
|
||||
{
|
||||
Console.Out.WriteLine("This JVM does not support UTF-8 encoding");
|
||||
Asn1Util.WriteStackTrace(exception, Console.Error);
|
||||
}
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
len += buffer.EncodeTagAndLength(Tag, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
public override void Encode(Asn1BerOutputStream outs, bool explicitTagging)
|
||||
{
|
||||
try
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(Value);
|
||||
|
||||
if (explicitTagging)
|
||||
{
|
||||
outs.EncodeTag(Tag);
|
||||
}
|
||||
|
||||
outs.EncodeLength(bytes.Length);
|
||||
outs.Write(bytes);
|
||||
}
|
||||
catch (IOException exception)
|
||||
{
|
||||
Console.Out.WriteLine("This JVM does not support UTF-8 encoding");
|
||||
Asn1Util.WriteStackTrace(exception, Console.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] ReAllocByteArray(byte[] ba1, int nbytes)
|
||||
{
|
||||
var destinationArray = new byte[nbytes];
|
||||
|
||||
if (ba1 != null)
|
||||
{
|
||||
Array.Copy(ba1, 0, destinationArray, 0, ba1.Length);
|
||||
}
|
||||
|
||||
return destinationArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
336
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Util.cs
vendored
Normal file
336
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Util.cs
vendored
Normal file
@@ -0,0 +1,336 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public static class Asn1Util
|
||||
{
|
||||
private static readonly byte[] Base64DecodeTable =
|
||||
{
|
||||
0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
|
||||
60, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 0x10, 0x11, 0x12, 0x13, 20, 0x15, 0x16,
|
||||
0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 30, 0x1f, 0x20,
|
||||
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 40, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
|
||||
0x31, 50, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
|
||||
private static readonly byte[] Base64EncodeTable =
|
||||
{
|
||||
0x41, 0x42, 0x43, 0x44, 0x45, 70, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 80,
|
||||
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 90, 0x61, 0x62, 0x63, 100, 0x65, 0x66,
|
||||
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 110, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
|
||||
0x77, 120, 0x79, 0x7a, 0x30, 0x31, 50, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x2f
|
||||
};
|
||||
|
||||
public static string BcdToString(byte[] bcd)
|
||||
{
|
||||
var index = 0;
|
||||
var builder = new StringBuilder(bcd.Length * 2);
|
||||
|
||||
for (var i = 0; i < (bcd.Length * 2); i++)
|
||||
{
|
||||
byte num3;
|
||||
|
||||
if ((i % 2) == 0)
|
||||
{
|
||||
num3 = (byte)(bcd[index] & 15);
|
||||
}
|
||||
else
|
||||
{
|
||||
num3 = (byte)UrShift(bcd[index++], 4);
|
||||
}
|
||||
|
||||
if (num3 == 15)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
builder.Append((num3 < 10) ? ((char)(num3 + 0x30)) : ((char)((num3 + 0x41) - 10)));
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public static byte[] DecodeBase64Array(byte[] srcArray)
|
||||
{
|
||||
var num = srcArray.Length / 4;
|
||||
|
||||
if ((4 * num) != srcArray.Length)
|
||||
{
|
||||
throw ExceptionUtility.Argument("srcArray", Resources.Asn1InvalidEncodedDataLength);
|
||||
}
|
||||
|
||||
var num2 = 0;
|
||||
var num3 = num;
|
||||
|
||||
if (srcArray.Length != 0)
|
||||
{
|
||||
if (srcArray[srcArray.Length - 1] == 0x3d)
|
||||
{
|
||||
num2++;
|
||||
num3--;
|
||||
}
|
||||
if (srcArray[srcArray.Length - 2] == 0x3d)
|
||||
{
|
||||
num2++;
|
||||
}
|
||||
}
|
||||
|
||||
var buffer = new byte[(3 * num) - num2];
|
||||
var num4 = 0;
|
||||
var num5 = 0;
|
||||
|
||||
for (var i = 0; i < num3; i++)
|
||||
{
|
||||
var num7 = DecodeBase64Char(srcArray[num4++]);
|
||||
var num8 = DecodeBase64Char(srcArray[num4++]);
|
||||
var num9 = DecodeBase64Char(srcArray[num4++]);
|
||||
var num10 = DecodeBase64Char(srcArray[num4++]);
|
||||
|
||||
buffer[num5++] = (byte)((num7 << 2) | (num8 >> 4));
|
||||
buffer[num5++] = (byte)((num8 << 4) | (num9 >> 2));
|
||||
buffer[num5++] = (byte)((num9 << 6) | num10);
|
||||
}
|
||||
|
||||
if (num2 != 0)
|
||||
{
|
||||
var num11 = DecodeBase64Char(srcArray[num4++]);
|
||||
var num12 = DecodeBase64Char(srcArray[num4++]);
|
||||
|
||||
buffer[num5++] = (byte)((num11 << 2) | (num12 >> 4));
|
||||
|
||||
if (num2 == 1)
|
||||
{
|
||||
var num13 = DecodeBase64Char(srcArray[num4++]);
|
||||
buffer[num5++] = (byte)((num12 << 4) | (num13 >> 2));
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private static int DecodeBase64Char(byte c)
|
||||
{
|
||||
var num = (c < 0x80) ? Base64DecodeTable[c - 40] : -1;
|
||||
|
||||
if (num < 0)
|
||||
{
|
||||
throw ExceptionUtility.Argument("c", Resources.Asn1IllegalCharacter, c);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public static byte[] EncodeBase64Array(byte[] srcArray)
|
||||
{
|
||||
var num = srcArray.Length / 3;
|
||||
var num2 = srcArray.Length - (3 * num);
|
||||
var num3 = 4 * ((srcArray.Length + 2) / 3);
|
||||
var buffer = new byte[num3];
|
||||
var num4 = 0;
|
||||
var num5 = 0;
|
||||
|
||||
for (var i = 0; i < num; i++)
|
||||
{
|
||||
var num7 = srcArray[num4++] & 0xff;
|
||||
var num8 = srcArray[num4++] & 0xff;
|
||||
var num9 = srcArray[num4++] & 0xff;
|
||||
|
||||
buffer[num5++] = Base64EncodeTable[num7 >> 2];
|
||||
buffer[num5++] = Base64EncodeTable[((num7 << 4) & 0x3f) | (num8 >> 4)];
|
||||
buffer[num5++] = Base64EncodeTable[((num8 << 2) & 0x3f) | (num9 >> 6)];
|
||||
buffer[num5++] = Base64EncodeTable[num9 & 0x3f];
|
||||
}
|
||||
|
||||
if (num2 != 0)
|
||||
{
|
||||
var num10 = srcArray[num4++] & 0xff;
|
||||
buffer[num5++] = Base64EncodeTable[num10 >> 2];
|
||||
|
||||
if (num2 == 1)
|
||||
{
|
||||
buffer[num5++] = Base64EncodeTable[(num10 << 4) & 0x3f];
|
||||
buffer[num5++] = 0x3d;
|
||||
buffer[num5++] = 0x3d;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
var num11 = srcArray[num4++] & 0xff;
|
||||
buffer[num5++] = Base64EncodeTable[((num10 << 4) & 0x3f) | (num11 >> 4)];
|
||||
buffer[num5++] = Base64EncodeTable[(num11 << 2) & 0x3f];
|
||||
buffer[num5++] = 0x3d;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static byte[] GetAddressBytes(string ipaddress)
|
||||
{
|
||||
var index = 0;
|
||||
var buffer = new byte[4];
|
||||
var tokenizer = new Tokenizer(ipaddress, ".");
|
||||
|
||||
try
|
||||
{
|
||||
while (tokenizer.HasMoreTokens())
|
||||
{
|
||||
buffer[index] = Convert.ToByte(tokenizer.NextToken());
|
||||
index++;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static int GetBytesCount(long val)
|
||||
{
|
||||
return Asn1RunTime.GetLongBytesCount(val);
|
||||
}
|
||||
|
||||
public static int GetUlongBytesCount(long val)
|
||||
{
|
||||
return Asn1RunTime.GetUlongBytesCount(val);
|
||||
}
|
||||
|
||||
public static byte[] StringToBcd(string str)
|
||||
{
|
||||
int num2;
|
||||
var buffer = new byte[(str.Length + 1) / 2];
|
||||
byte num = 0;
|
||||
var num3 = num2 = 0;
|
||||
|
||||
while (num3 < str.Length)
|
||||
{
|
||||
var c = char.ToUpper(str[num3]);
|
||||
var flag = char.IsDigit(c);
|
||||
|
||||
if (!flag && ((c < 'A') || (c >= 'F')))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1ValueParseException, str, num3);
|
||||
}
|
||||
|
||||
if ((num3 % 2) != 0)
|
||||
{
|
||||
num = (byte)(num | ((byte)(((byte)((flag != null) ? (c - 0x30) : ((c - 0x41) + 10))) << 4)));
|
||||
buffer[num2++] = num;
|
||||
}
|
||||
else
|
||||
{
|
||||
num = flag ? ((byte)(c - '0')) : ((byte)((c - 'A') + 10));
|
||||
}
|
||||
|
||||
num3++;
|
||||
}
|
||||
|
||||
if ((num3 % 2) != 0)
|
||||
{
|
||||
buffer[num2++] = (byte)(num | 240);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static void ToArray(ICollection c, object[] objects)
|
||||
{
|
||||
var num = 0;
|
||||
var enumerator = c.GetEnumerator();
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
objects[num++] = enumerator.Current;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] ToByteArray(string sourceString)
|
||||
{
|
||||
return Encoding.UTF8.GetBytes(sourceString);
|
||||
}
|
||||
|
||||
public static char[] ToCharArray(byte[] byteArray)
|
||||
{
|
||||
return Encoding.UTF8.GetChars(byteArray);
|
||||
}
|
||||
|
||||
public static string ToHexString(byte b)
|
||||
{
|
||||
var builder = new StringBuilder(4);
|
||||
var str = Convert.ToString(b, 0x10);
|
||||
var length = str.Length;
|
||||
|
||||
if (length < 2)
|
||||
{
|
||||
builder.Append('0');
|
||||
builder.Append(str);
|
||||
}
|
||||
else if (length > 2)
|
||||
{
|
||||
builder.Append(str[length - 2]);
|
||||
builder.Append(str[length - 1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Append(str);
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public static string ToHexString(byte[] b, int offset, int nbytes)
|
||||
{
|
||||
var builder = new StringBuilder(nbytes * 4);
|
||||
|
||||
for (var i = 0; i < nbytes; i++)
|
||||
{
|
||||
builder.Append(ToHexString(b[offset + i]));
|
||||
builder.Append(" ");
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public static int UrShift(int number, int bits)
|
||||
{
|
||||
if (number >= 0)
|
||||
{
|
||||
return (number >> bits);
|
||||
}
|
||||
|
||||
return ((number >> bits) + (2 << ~bits));
|
||||
}
|
||||
|
||||
public static int UrShift(int number, long bits)
|
||||
{
|
||||
return UrShift(number, (int)bits);
|
||||
}
|
||||
|
||||
public static long UrShift(long number, int bits)
|
||||
{
|
||||
if (number >= 0L)
|
||||
{
|
||||
return (number >> bits);
|
||||
}
|
||||
|
||||
return ((number >> bits) + (2L << ~bits));
|
||||
}
|
||||
|
||||
public static long UrShift(long number, long bits)
|
||||
{
|
||||
return UrShift(number, (int)bits);
|
||||
}
|
||||
|
||||
public static void WriteStackTrace(Exception throwable, TextWriter stream)
|
||||
{
|
||||
stream.Write(throwable.StackTrace);
|
||||
stream.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
170
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Value.cs
vendored
Normal file
170
third_party/forks/AlexMAS.GostCryptography/Source/GostCryptography/Asn1/Ber/Asn1Value.cs
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using GostCryptography.Properties;
|
||||
|
||||
namespace GostCryptography.Asn1.Ber
|
||||
{
|
||||
public static class Asn1Value
|
||||
{
|
||||
private static byte[] AllocBitArray(int numbits)
|
||||
{
|
||||
var num = numbits / 8;
|
||||
|
||||
if ((numbits % 8) != 0)
|
||||
{
|
||||
num++;
|
||||
}
|
||||
|
||||
return new byte[num];
|
||||
}
|
||||
|
||||
public static byte[] ParseString(string data)
|
||||
{
|
||||
return ParseString(data, null);
|
||||
}
|
||||
|
||||
public static byte[] ParseString(string data, IntHolder numbits)
|
||||
{
|
||||
char ch;
|
||||
int num;
|
||||
int num2;
|
||||
int num3;
|
||||
int num4;
|
||||
int num5;
|
||||
|
||||
char ch2 = data[0];
|
||||
byte[] buffer;
|
||||
|
||||
switch (ch2)
|
||||
{
|
||||
case '\'':
|
||||
case '"':
|
||||
if (!data.EndsWith("B"))
|
||||
{
|
||||
if (data.EndsWith("H"))
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
num3 = (data.Length - 3) * 4;
|
||||
buffer = AllocBitArray(num3);
|
||||
builder.Length = 2;
|
||||
num = 1;
|
||||
num2 = 0;
|
||||
ch = '\0';
|
||||
|
||||
while ((num < data.Length) && (ch != ch2))
|
||||
{
|
||||
ch = data[num++];
|
||||
|
||||
if (ch != ch2)
|
||||
{
|
||||
builder[0] = ch;
|
||||
ch = (num >= data.Length) ? '0' : data[num];
|
||||
builder[1] = (ch == ch2) ? '0' : ch;
|
||||
buffer[num2++] = (byte)Convert.ToInt32(builder.ToString(), 0x10);
|
||||
}
|
||||
|
||||
num++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data[data.Length - 1] != ch2)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.Asn1ValueParseException, data, data.Length - 1);
|
||||
}
|
||||
|
||||
num3 = (data.Length - 2) * 8;
|
||||
buffer = AllocBitArray(num3);
|
||||
num = 1;
|
||||
ch = '\0';
|
||||
|
||||
while ((num < data.Length) && (ch != ch2))
|
||||
{
|
||||
ch = data[num];
|
||||
|
||||
if (ch != ch2)
|
||||
{
|
||||
buffer[num - 1] = (byte)ch;
|
||||
}
|
||||
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
return SetNumBits(numbits, num3, buffer);
|
||||
}
|
||||
|
||||
num3 = data.Length - 3;
|
||||
buffer = AllocBitArray(num3);
|
||||
num5 = 0x80;
|
||||
num = 1;
|
||||
num4 = 0;
|
||||
num2 = 0;
|
||||
|
||||
while (num < data.Length)
|
||||
{
|
||||
ch = data[num];
|
||||
|
||||
if (ch == '1')
|
||||
{
|
||||
num4 |= num5;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ch == ch2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (ch != '0')
|
||||
{
|
||||
ExceptionUtility.CryptographicException(Resources.Asn1ValueParseException, data, num);
|
||||
}
|
||||
}
|
||||
|
||||
num5 = num5 >> 1;
|
||||
|
||||
if (num5 == 0)
|
||||
{
|
||||
buffer[num2++] = (byte)num4;
|
||||
num5 = 0x80;
|
||||
num4 = 0;
|
||||
}
|
||||
|
||||
num++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
num3 = data.Length * 8;
|
||||
buffer = AllocBitArray(num3);
|
||||
num = 0;
|
||||
|
||||
while (num < data.Length)
|
||||
{
|
||||
ch = data[num];
|
||||
buffer[num] = (byte)ch;
|
||||
num++;
|
||||
}
|
||||
|
||||
return SetNumBits(numbits, num3, buffer);
|
||||
}
|
||||
|
||||
if (num5 != 0x80)
|
||||
{
|
||||
buffer[num2] = (byte)num4;
|
||||
}
|
||||
|
||||
return SetNumBits(numbits, num3, buffer);
|
||||
}
|
||||
|
||||
private static byte[] SetNumBits(IntHolder numbits, int num3, byte[] buffer)
|
||||
{
|
||||
if (numbits != null)
|
||||
{
|
||||
numbits.Value = num3;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user