Basic formatting applied. Unnecessary comments have been removed. Suspicious code is covered by TODO.
177 lines
7.7 KiB
C#
177 lines
7.7 KiB
C#
using GostCryptography.Config;
|
||
using System.Security;
|
||
using System.Security.Cryptography.Pkcs;
|
||
using System.Security.Cryptography.X509Certificates;
|
||
|
||
namespace GostCryptography.Pkcs
|
||
{
|
||
/// <summary>
|
||
/// Реализует методы для работы с сообщениями CMS (Cryptographic Message Syntax) / PKCS #7 (Public-Key Cryptography Standard #7)
|
||
/// </summary>
|
||
/// <remarks>
|
||
/// CMS (Cryptographic Message Syntax) или PKCS #7 (Public-Key Cryptography Standard #7) - это стандарт, поддерживаемый RSA Laboratories,
|
||
/// который описываемый синтаксис криптографических сообщений. Синтаксис CMS описывает способы формирования криптографических сообщений,
|
||
/// в результате чего сообщение становится полностью самодостаточным для его открытия и выполнения всех необходимых операций. С этой целью
|
||
/// в CMS-сообщении размещается информация об исходном сообщении, алгоритмах хэширования и подписи, параметрах криптоалгоритмов, времени
|
||
/// подписи, сертификат ключа электронной подписи, цепочка сертификации и т.д. Большинство из перечисленных атрибутов CMS-сообщения являются
|
||
/// опциональными, но их обязательность может определяться прикладной системой. Отдельно следует отметить, что CMS/PKCS#7 позволяет ставить
|
||
/// несколько подписей под одним документом, сохраняя всю необходимую информацию в сообщении.
|
||
/// </remarks>
|
||
public sealed class GostSignedCms
|
||
{
|
||
static GostSignedCms()
|
||
{
|
||
GostCryptoConfig.Initialize();
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms()"/>
|
||
public GostSignedCms()
|
||
{
|
||
_signedCms = new SignedCms();
|
||
_signerIdentifierType = InitSubjectIdentifierType(SubjectIdentifierType.IssuerAndSerialNumber);
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms(SubjectIdentifierType)"/>
|
||
public GostSignedCms(SubjectIdentifierType signerIdentifierType)
|
||
{
|
||
_signedCms = new SignedCms(signerIdentifierType);
|
||
_signerIdentifierType = InitSubjectIdentifierType(signerIdentifierType);
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms(System.Security.Cryptography.Pkcs.ContentInfo)"/>
|
||
public GostSignedCms(ContentInfo contentInfo)
|
||
{
|
||
_signedCms = new SignedCms(contentInfo);
|
||
_signerIdentifierType = InitSubjectIdentifierType(SubjectIdentifierType.IssuerAndSerialNumber);
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms(SubjectIdentifierType,System.Security.Cryptography.Pkcs.ContentInfo)"/>
|
||
public GostSignedCms(SubjectIdentifierType signerIdentifierType, ContentInfo contentInfo)
|
||
{
|
||
_signedCms = new SignedCms(signerIdentifierType, contentInfo);
|
||
_signerIdentifierType = InitSubjectIdentifierType(signerIdentifierType);
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms(System.Security.Cryptography.Pkcs.ContentInfo,bool)"/>
|
||
public GostSignedCms(ContentInfo contentInfo, bool detached)
|
||
{
|
||
_signedCms = new SignedCms(contentInfo, detached);
|
||
_signerIdentifierType = InitSubjectIdentifierType(SubjectIdentifierType.IssuerAndSerialNumber);
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms(SubjectIdentifierType,System.Security.Cryptography.Pkcs.ContentInfo,bool)"/>
|
||
public GostSignedCms(SubjectIdentifierType signerIdentifierType, ContentInfo contentInfo, bool detached)
|
||
{
|
||
_signedCms = new SignedCms(signerIdentifierType, contentInfo, detached);
|
||
_signerIdentifierType = InitSubjectIdentifierType(signerIdentifierType);
|
||
}
|
||
|
||
private readonly SignedCms _signedCms;
|
||
private readonly SubjectIdentifierType _signerIdentifierType;
|
||
|
||
/// <inheritdoc cref="SignedCms.Version"/>
|
||
public int Version => _signedCms.Version;
|
||
|
||
/// <inheritdoc cref="SignedCms.ContentInfo"/>
|
||
public ContentInfo ContentInfo => _signedCms.ContentInfo;
|
||
|
||
/// <inheritdoc cref="SignedCms.Detached"/>
|
||
public bool Detached => _signedCms.Detached;
|
||
|
||
/// <inheritdoc cref="SignedCms.Certificates"/>
|
||
public X509Certificate2Collection Certificates => _signedCms.Certificates;
|
||
|
||
/// <inheritdoc cref="SignedCms.SignerInfos"/>
|
||
public SignerInfoCollection SignerInfos => _signedCms.SignerInfos;
|
||
|
||
/// <inheritdoc cref="SignedCms.Encode"/>
|
||
public byte[] Encode()
|
||
{
|
||
return _signedCms.Encode();
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms.Decode"/>
|
||
public void Decode(byte[] encodedMessage)
|
||
{
|
||
_signedCms.Decode(encodedMessage);
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms.ComputeSignature()"/>
|
||
public void ComputeSignature()
|
||
{
|
||
ComputeSignature(new CmsSigner(_signerIdentifierType), true);
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms.ComputeSignature(CmsSigner)"/>
|
||
public void ComputeSignature(CmsSigner signer)
|
||
{
|
||
ComputeSignature(signer, true);
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms.ComputeSignature(CmsSigner,bool)"/>
|
||
public void ComputeSignature(CmsSigner signer, bool silent)
|
||
{
|
||
signer = InitCmsSigner(signer);
|
||
|
||
_signedCms.ComputeSignature(signer, silent);
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms.RemoveSignature(int)"/>
|
||
public void RemoveSignature(int index)
|
||
{
|
||
_signedCms.RemoveSignature(index);
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms.RemoveSignature(SignerInfo)"/>
|
||
public void RemoveSignature(SignerInfo signerInfo)
|
||
{
|
||
_signedCms.RemoveSignature(signerInfo);
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms.CheckSignature(bool)"/>
|
||
public void CheckSignature(bool verifySignatureOnly)
|
||
{
|
||
_signedCms.CheckSignature(verifySignatureOnly);
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms.CheckSignature(X509Certificate2Collection,bool)"/>
|
||
public void CheckSignature(X509Certificate2Collection extraStore, bool verifySignatureOnly)
|
||
{
|
||
_signedCms.CheckSignature(extraStore, verifySignatureOnly);
|
||
}
|
||
|
||
/// <inheritdoc cref="SignedCms.CheckHash()"/>
|
||
public void CheckHash()
|
||
{
|
||
_signedCms.CheckHash();
|
||
}
|
||
|
||
private static SubjectIdentifierType InitSubjectIdentifierType(SubjectIdentifierType signerIdentifierType)
|
||
{
|
||
if (signerIdentifierType != SubjectIdentifierType.SubjectKeyIdentifier
|
||
&& signerIdentifierType != SubjectIdentifierType.IssuerAndSerialNumber
|
||
&& signerIdentifierType != SubjectIdentifierType.NoSignature)
|
||
{
|
||
return SubjectIdentifierType.IssuerAndSerialNumber;
|
||
}
|
||
|
||
return signerIdentifierType;
|
||
}
|
||
|
||
[SecuritySafeCritical]
|
||
private static CmsSigner InitCmsSigner(CmsSigner cmsSigner)
|
||
{
|
||
var certificate = cmsSigner.Certificate;
|
||
|
||
var hashAlgorithm = certificate?.GetHashAlgorithm();
|
||
|
||
if (hashAlgorithm != null)
|
||
{
|
||
cmsSigner.DigestAlgorithm = hashAlgorithm;
|
||
}
|
||
|
||
return cmsSigner;
|
||
}
|
||
}
|
||
}
|