using GostCryptography.Config; using System.Security; using System.Security.Cryptography.Pkcs; using System.Security.Cryptography.X509Certificates; namespace GostCryptography.Pkcs { /// /// Реализует методы для работы с сообщениями CMS (Cryptographic Message Syntax) / PKCS #7 (Public-Key Cryptography Standard #7) /// /// /// CMS (Cryptographic Message Syntax) или PKCS #7 (Public-Key Cryptography Standard #7) - это стандарт, поддерживаемый RSA Laboratories, /// который описываемый синтаксис криптографических сообщений. Синтаксис CMS описывает способы формирования криптографических сообщений, /// в результате чего сообщение становится полностью самодостаточным для его открытия и выполнения всех необходимых операций. С этой целью /// в CMS-сообщении размещается информация об исходном сообщении, алгоритмах хэширования и подписи, параметрах криптоалгоритмов, времени /// подписи, сертификат ключа электронной подписи, цепочка сертификации и т.д. Большинство из перечисленных атрибутов CMS-сообщения являются /// опциональными, но их обязательность может определяться прикладной системой. Отдельно следует отметить, что CMS/PKCS#7 позволяет ставить /// несколько подписей под одним документом, сохраняя всю необходимую информацию в сообщении. /// public sealed class GostSignedCms { static GostSignedCms() { GostCryptoConfig.Initialize(); } /// public GostSignedCms() { _signedCms = new SignedCms(); _signerIdentifierType = InitSubjectIdentifierType(SubjectIdentifierType.IssuerAndSerialNumber); } /// public GostSignedCms(SubjectIdentifierType signerIdentifierType) { _signedCms = new SignedCms(signerIdentifierType); _signerIdentifierType = InitSubjectIdentifierType(signerIdentifierType); } /// public GostSignedCms(ContentInfo contentInfo) { _signedCms = new SignedCms(contentInfo); _signerIdentifierType = InitSubjectIdentifierType(SubjectIdentifierType.IssuerAndSerialNumber); } /// public GostSignedCms(SubjectIdentifierType signerIdentifierType, ContentInfo contentInfo) { _signedCms = new SignedCms(signerIdentifierType, contentInfo); _signerIdentifierType = InitSubjectIdentifierType(signerIdentifierType); } /// public GostSignedCms(ContentInfo contentInfo, bool detached) { _signedCms = new SignedCms(contentInfo, detached); _signerIdentifierType = InitSubjectIdentifierType(SubjectIdentifierType.IssuerAndSerialNumber); } /// 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; /// public int Version => _signedCms.Version; /// public ContentInfo ContentInfo => _signedCms.ContentInfo; /// public bool Detached => _signedCms.Detached; /// public X509Certificate2Collection Certificates => _signedCms.Certificates; /// public SignerInfoCollection SignerInfos => _signedCms.SignerInfos; /// public byte[] Encode() { return _signedCms.Encode(); } /// public void Decode(byte[] encodedMessage) { _signedCms.Decode(encodedMessage); } /// public void ComputeSignature() { ComputeSignature(new CmsSigner(_signerIdentifierType), true); } /// public void ComputeSignature(CmsSigner signer) { ComputeSignature(signer, true); } /// public void ComputeSignature(CmsSigner signer, bool silent) { signer = InitCmsSigner(signer); _signedCms.ComputeSignature(signer, silent); } /// public void RemoveSignature(int index) { _signedCms.RemoveSignature(index); } /// public void RemoveSignature(SignerInfo signerInfo) { _signedCms.RemoveSignature(signerInfo); } /// public void CheckSignature(bool verifySignatureOnly) { _signedCms.CheckSignature(verifySignatureOnly); } /// public void CheckSignature(X509Certificate2Collection extraStore, bool verifySignatureOnly) { _signedCms.CheckSignature(extraStore, verifySignatureOnly); } /// 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; } } }