Skip to content

Commit

Permalink
Implements GostSignedCms.RemoveCertificate()
Browse files Browse the repository at this point in the history
#49 v2.0.10
  • Loading branch information
AlexMAS committed Jan 31, 2024
1 parent 49cd681 commit 3fc2397
Show file tree
Hide file tree
Showing 9 changed files with 304 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
10 changes: 7 additions & 3 deletions Source/GostCryptography/GostCryptography.csproj
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<GostCryptographyVersion>2.0.10</GostCryptographyVersion>
</PropertyGroup>

<PropertyGroup>
<TargetFrameworks>net40;net452</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AssemblyTitle>GostCryptography</AssemblyTitle>
<Product>GostCryptography</Product>
<AssemblyVersion>2.0.9.0</AssemblyVersion>
<FileVersion>2.0.9.0</FileVersion>
<AssemblyVersion>$(GostCryptographyVersion).0</AssemblyVersion>
<FileVersion>$(GostCryptographyVersion).0</FileVersion>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<PropertyGroup>
<NoWarn>1701;1702;1591</NoWarn>
<PackageId>GostCryptography</PackageId>
<Title>GostCryptography</Title>
<Version>2.0.9</Version>
<Version>$(GostCryptographyVersion)</Version>
<Authors>Alexander Mezhov</Authors>
<Company />
<Description>.NET driver for ViPNet CSP and CryptoPro CSP. Implements crypto algorithms based on Russian national cryptographic standards GOST 28147-89, GOST R 34.10 and GOST R 34.11. Also provides abstractions to sign and verify CMS/PKCS #7 messages, sign, verify and encrypt XML documents.</Description>
Expand Down
17 changes: 16 additions & 1 deletion Source/GostCryptography/Native/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -419,9 +419,24 @@ public static class Constants
/// </summary>
public const int SCARD_W_CANCELLED_BY_USER = -2146434962;

#endregion


#region Типы операций над сообщениями PKCS #7

/// <summary>
/// Добавление сертификата в сообщение.
/// </summary>
public const uint CMSG_CTRL_ADD_CERT = 10;

/// <summary>
/// Удаление сертификата из сообщения (по индексу).
/// </summary>
public const uint CMSG_CTRL_DEL_CERT = 11;

#endregion


// ReSharper restore InconsistentNaming
}
}
}
11 changes: 11 additions & 0 deletions Source/GostCryptography/Native/CryptoApi.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Text;

Expand Down Expand Up @@ -153,6 +154,16 @@ public static class CryptoApi

#endregion


#region Для работы с сообщениями PKCS #7

[ResourceExposure(ResourceScope.None)]
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool CryptMsgControl([In] SafeHandle hCryptMsg, [In] uint dwFlags, [In] uint dwCtrlType, [In] IntPtr pvCtrlPara);

#endregion

// ReSharper restore InconsistentNaming
}
}
17 changes: 17 additions & 0 deletions Source/GostCryptography/Native/CryptoApiHelper.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
Expand Down Expand Up @@ -1300,6 +1301,22 @@ private static void SetHashValue(SafeHashHandleImpl hashHandle, byte[] hashValue
#endregion


#region Для работы с сообщениями PKCS #7

public static void RemoveCertificate(SafeHandle cmsMessageHandle, int certIndex)
{
unsafe
{
if (!CryptoApi.CryptMsgControl(cmsMessageHandle, 0, Constants.CMSG_CTRL_DEL_CERT, new IntPtr(&certIndex)))
{
throw CreateWin32Error();
}
}
}

#endregion


public static T DangerousAddRef<T>(this T handle) where T : SafeHandle
{
var success = false;
Expand Down
16 changes: 16 additions & 0 deletions Source/GostCryptography/Pkcs/GostSignedCms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Security.Cryptography.X509Certificates;

using GostCryptography.Config;
using GostCryptography.Reflection;

namespace GostCryptography.Pkcs
{
Expand Down Expand Up @@ -154,6 +155,21 @@ public void CheckHash()
_signedCms.CheckHash();
}

/// <summary>
/// Удаляет из сообщения указанный сертификат.
/// </summary>
public void RemoveCertificate(X509Certificate2 certificate)
{
_signedCms.RemoveCertificate(certificate);
}

/// <summary>
/// Удаляет из сообщения все сертификаты.
/// </summary>
public void RemoveCertificates()
{
_signedCms.RemoveCertificates();
}

private static SubjectIdentifierType InitSubjectIdentifierType(SubjectIdentifierType signerIdentifierType)
{
Expand Down
11 changes: 10 additions & 1 deletion Source/GostCryptography/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Source/GostCryptography/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -384,4 +384,7 @@
<data name="Provider_2012_512_IsNotInstalled" xml:space="preserve">
<value>GOST R 34.10-2012/512 Cryptographic Service Provider is not installed.</value>
</data>
<data name="SignedCmsCannotFindPrivateMember" xml:space="preserve">
<value>Cannot find private member '{0}'.</value>
</data>
</root>
Loading

0 comments on commit 3fc2397

Please sign in to comment.