internal static X509Certificate2Collection CreateBagOfCertificates(CmsSigner signer) { X509Certificate2Collection certificates = new X509Certificate2Collection(); certificates.AddRange(signer.Certificates); if (signer.IncludeOption != X509IncludeOption.None) { if (signer.IncludeOption == X509IncludeOption.EndCertOnly) { certificates.Add(signer.Certificate); return certificates; } int count = 1; X509Chain chain = new X509Chain(); chain.Build(signer.Certificate); if ((chain.ChainStatus.Length > 0) && ((chain.ChainStatus[0].Status & X509ChainStatusFlags.PartialChain) == X509ChainStatusFlags.PartialChain)) { throw new CryptographicException(-2146762486); } if (signer.IncludeOption == X509IncludeOption.WholeChain) { count = chain.ChainElements.Count; } else if (chain.ChainElements.Count > 1) { count = chain.ChainElements.Count - 1; } for (int i = 0; i < count; i++) { certificates.Add(chain.ChainElements[i].Certificate); } } return certificates; }
/// <summary> /// Firma el mensaje PKCS #7 con el certificado del firmante /// </summary> /// <param name="pMensaje">Mensaje (como cadena de bytes)</param> /// <param name="pCertificadoFirmante">Certificado usado para firmar</param> /// <returns>Mensaje Firmado (como cadena de bytes)</returns> /// <remarks></remarks> public static byte[] FirmarMensaje(byte[] pMensaje, X509Certificate2 pCertificadoFirmante) { byte[] msjFirmado; try { // Se pone el Mensaje recibido en un objeto ContentInfo ContentInfo infoContenidoMsj = new ContentInfo(pMensaje); // Se instancia el CMS Firmado con el ContentInfo SignedCms cmsFirmado = new SignedCms(infoContenidoMsj); // Se instancia el objeto CmsSigner con las caracteristicas del firmante CmsSigner cmsFirmante = new CmsSigner(pCertificadoFirmante); cmsFirmante.IncludeOption = X509IncludeOption.EndCertOnly; // Se firma el mensaje PKCS #7 con el certificado cmsFirmado.ComputeSignature(cmsFirmante); msjFirmado = cmsFirmado.Encode(); // Retorno el mensaje PKCS #7 firmado . return msjFirmado; } catch (Exception excepcionAlFirmar) { throw new Exception("ERROR: Procedimiento: FirmarMensaje. Al intentar firmar el mensaje con el certificado del firmante: " + excepcionAlFirmar.Message); } }
/// <summary> /// Firma mensaje /// </summary> /// <param name="argBytesMsg">Bytes del mensaje</param> /// <param name="argCertFirmante">Certificado usado para firmar</param> /// <returns>Bytes del mensaje firmado</returns> /// <remarks></remarks> public static byte[] FirmaBytesMensaje(byte[] argBytesMsg, X509Certificate2 argCertFirmante) { try { // Pongo el mensaje en un objeto ContentInfo (requerido para construir el obj SignedCms) ContentInfo infoContenido = new ContentInfo(argBytesMsg); SignedCms cmsFirmado = new SignedCms(infoContenido); // Creo objeto CmsSigner que tiene las caracteristicas del firmante CmsSigner cmsFirmante = new CmsSigner(argCertFirmante); cmsFirmante.IncludeOption = X509IncludeOption.EndCertOnly; if (VerboseMode) { Console.WriteLine("***Firmando bytes del mensaje..."); } // Firmo el mensaje PKCS #7 cmsFirmado.ComputeSignature(cmsFirmante); if (VerboseMode) { Console.WriteLine("***OK mensaje firmado"); } // Encodeo el mensaje PKCS #7. return cmsFirmado.Encode(); } catch (Exception excepcionAlFirmar) { throw new Exception("***Error al firmar: " + excepcionAlFirmar.Message); } }
public byte[] GetSignature(byte[] content) { if (content == null) { throw new ArgumentNullException(nameof(content)); } var certificate = _Provider.GetCertificate(); if (certificate == null) { throw new InvalidOperationException("Certificate not found."); } var chain = GetChainWithoutRoot(); var contentInfo = new ContentInfo(content); var signedCms = new SignedCms(contentInfo, true); var signer = new System.Security.Cryptography.Pkcs.CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, certificate); signedCms.Certificates.AddRange(chain); signedCms.ComputeSignature(signer); return(signedCms.Encode()); }
RealCmsSigner GetRealCmsSigner (MailboxAddress mailbox, DigestAlgorithm digestAlgo) { var signer = new RealCmsSigner (GetCmsSignerCertificate (mailbox)); signer.DigestAlgorithm = new Oid (GetDigestOid (digestAlgo)); signer.SignedAttributes.Add (new Pkcs9SigningTime ()); signer.IncludeOption = X509IncludeOption.ExcludeRoot; return signer; }
RealCmsSigner GetRealCmsSigner(MailboxAddress mailbox, DigestAlgorithm digestAlgo) { var signer = new RealCmsSigner(GetCmsSignerCertificate(mailbox)); signer.DigestAlgorithm = new Oid(GetDigestOid(digestAlgo)); signer.IncludeOption = X509IncludeOption.ExcludeRoot; return(signer); }
private byte[] Sign(byte[] messageBytes) { Pkcs.ContentInfo content = new Pkcs.ContentInfo(messageBytes); Pkcs.SignedCms signed = new Pkcs.SignedCms(content); Pkcs.CmsSigner signer = new Pkcs.CmsSigner(_signerCert); signed.ComputeSignature(signer); byte[] signedBytes = signed.Encode(); return(signedBytes); }
public byte[] Sign(byte[] data) { ContentInfo contentInfo = new ContentInfo(_md5.ComputeHash(data)); SignedCms signedCms = new SignedCms(contentInfo); CmsSigner cmsSigner = new CmsSigner(_cert); cmsSigner.IncludeOption = X509IncludeOption.WholeChain; signedCms.ComputeSignature(cmsSigner); return signedCms.Encode(); }
public void ConstructorSubjectKeyIdentifier () { CmsSigner ps = new CmsSigner (SubjectIdentifierType.SubjectKeyIdentifier); // default properties AssertEquals ("SignedAttributes", 0, ps.SignedAttributes.Count); AssertNull ("Certificate", ps.Certificate); AssertEquals ("DigestAlgorithm.FriendlyName", sha1Name, ps.DigestAlgorithm.FriendlyName); AssertEquals ("DigestAlgorithm.Value", sha1Oid, ps.DigestAlgorithm.Value); AssertEquals ("IncludeOption", X509IncludeOption.ExcludeRoot, ps.IncludeOption); AssertEquals ("SignerIdentifierType", SubjectIdentifierType.SubjectKeyIdentifier, ps.SignerIdentifierType); AssertEquals ("UnsignedAttributes", 0, ps.UnsignedAttributes.Count); }
public void ConstructorSubjectKeyIdentifier () { CmsSigner ps = new CmsSigner (SubjectIdentifierType.SubjectKeyIdentifier); // default properties Assert.AreEqual (0, ps.SignedAttributes.Count, "SignedAttributes"); Assert.IsNull (ps.Certificate, "Certificate"); Assert.AreEqual (sha1Name, ps.DigestAlgorithm.FriendlyName, "DigestAlgorithm.FriendlyName"); Assert.AreEqual (sha1Oid, ps.DigestAlgorithm.Value, "DigestAlgorithm.Value"); Assert.AreEqual (X509IncludeOption.ExcludeRoot, ps.IncludeOption, "IncludeOption"); Assert.AreEqual (SubjectIdentifierType.SubjectKeyIdentifier, ps.SignerIdentifierType, "SignerIdentifierType"); Assert.AreEqual (0, ps.UnsignedAttributes.Count, "UnsignedAttributes"); }
private void _bSendMessage_Click(object sender, EventArgs e) { this.AddLogEntry("Creating message."); // We create the message object ActiveUp.Net.Mail.Message message = new ActiveUp.Net.Mail.Message(); // We assign the sender email message.From.Email = this._tbFromEmail.Text; // We assign the recipient email message.To.Add(this._tbToEmail.Text); // We assign the subject message.Subject = this._tbSubject.Text; // We assign the body text message.BodyText.Text = this._tbBodyText.Text; // It is required to build the mime part tree before signing message.BuildMimePartTree(); if (_tbCertificate.Text != string.Empty) { CmsSigner signer = new CmsSigner(new X509Certificate2(_tbCertificate.Text)); // Here we only want the signer's certificate to be sent along. Not the whole chain. signer.IncludeOption = X509IncludeOption.EndCertOnly; message.SmimeAttachSignatureBy(signer); } // We send the email using the specified SMTP server this.AddLogEntry("Sending message."); try { message.Send(this._tbSmtpServer.Text); this.AddLogEntry("Message sent successfully."); } catch (SmtpException ex) { this.AddLogEntry(string.Format("Smtp Error: {0}", ex.Message)); } catch (Exception ex) { this.AddLogEntry(string.Format("Failed: {0}", ex.Message)); } }
Stream Sign(RealCmsSigner signer, Stream content, bool detach) { var contentInfo = new ContentInfo(ReadAllBytes(content)); var signed = new SignedCms(contentInfo, detach); try { signed.ComputeSignature(signer); } catch (CryptographicException) { signer.IncludeOption = X509IncludeOption.EndCertOnly; signed.ComputeSignature(signer); } var signedData = signed.Encode(); return(new MemoryStream(signedData, false)); }
RealCmsSigner GetRealCmsSigner(MailboxAddress mailbox, DigestAlgorithm digestAlgo) { X509Certificate2 certificate; if ((certificate = GetCmsSignerCertificate(mailbox)) == null) { throw new CertificateNotFoundException(mailbox, "A valid signing certificate could not be found."); } var signer = new RealCmsSigner(certificate); signer.DigestAlgorithm = new Oid(GetDigestOid(digestAlgo)); signer.SignedAttributes.Add(GetSecureMimeCapabilities()); signer.SignedAttributes.Add(new Pkcs9SigningTime()); signer.IncludeOption = X509IncludeOption.ExcludeRoot; return(signer); }
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 byte[] FirmaBytesMensaje( byte[] argBytesMsg, X509Certificate2 argCertFirmante ) { ContentInfo infoContenido = new ContentInfo( argBytesMsg ); SignedCms cmsFirmado = new SignedCms( infoContenido ); CmsSigner cmsFirmante = new CmsSigner( argCertFirmante ); try { cmsFirmante.IncludeOption = X509IncludeOption.EndCertOnly; cmsFirmado.ComputeSignature( cmsFirmante ); } catch ( Exception error ) { this.manejadorErrores.ManejarError( error, "FirmaBytesMensaje", error.Message ); } return cmsFirmado.Encode(); }
private MailMessage GenerateHtmlMessage(string from, string to, string subject, string content, string[] attachmentFilepaths) { MailMessage mail = new MailMessage(); mail.From = new MailAddress(from); mail.To.Add(to); mail.Subject = subject; string body = null; if (attachmentFilepaths != null && attachmentFilepaths.Length > 0) { StringBuilder sb = new StringBuilder(); sb.Append("MIME-Version: 1.0\r\n"); sb.Append("Content-Type: multipart/mixed; boundary=unique-boundary-1\r\n"); sb.Append("\r\n"); sb.Append("This is a multi-part message in MIME format.\r\n"); sb.Append("--unique-boundary-1\r\n"); sb.Append("Content-Type: text/html\r\n"); //could use text/plain as well here if you want a plaintext message sb.Append("Content-Transfer-Encoding: 7Bit\r\n\r\n"); sb.Append(content); if (!content.EndsWith("\r\n")) sb.Append("\r\n"); sb.Append("\r\n\r\n"); foreach (string filepath in attachmentFilepaths) { sb.Append(GenerateRawAttachement(filepath)); } body = sb.ToString(); } else { body = "Content-Type: text/html\r\nContent-Transfer-Encoding: 7Bit\r\n\r\n" + content; } //input your certification and private key. X509Certificate2 cert = new X509Certificate2("emailcertification.pfx", "6522626", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); ContentInfo contentInfo = new ContentInfo(Encoding.UTF8.GetBytes(body)); SignedCms signedCms = new SignedCms(contentInfo, false); CmsSigner Signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, cert); signedCms.ComputeSignature(Signer); byte[] signedBytes = signedCms.Encode(); MemoryStream stream = new MemoryStream(signedBytes); AlternateView view = new AlternateView(stream, "application/pkcs7-mime; smime-type=signed-data;name=smime.p7m"); mail.AlternateViews.Add(view); return mail; }
public static bool IsSignedBy(this X509Certificate thisCertificate, X509Certificate signerCertificate) { X509Certificate2 c = new X509Certificate2(thisCertificate.GetTbsCertificate()); X509Certificate2 i = new X509Certificate2(signerCertificate.GetTbsCertificate()); X509Certificate2 c2 = new X509Certificate2(@"c:\temp\der.cer"); X509Certificate2 i2 = new X509Certificate2(@"c:\temp\cader.cer"); /*byte[] pvSubject = thisCertificate.GetTbsCertificate(); byte[] pvIssuer = signerCertificate.GetTbsCertificate(); */ System.Text.Encoding.ASCII.GetString(c.RawData); IntPtr pvSubject = c.Handle; IntPtr pvIssuer = i.Handle; int res = SspiProvider.CryptVerifyCertificateSignatureEx(IntPtr.Zero, X509_ASN_ENCODING, CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT, pvSubject, CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, pvIssuer, 0, IntPtr.Zero); Marshal.GetLastWin32Error(); CmsSigner signer = new CmsSigner(i); SignedCms signedMessage = new SignedCms(); // deserialize PKCS #7 byte array signedMessage.Decode(thisCertificate.GetTbsCertificate()); Log.Write("Veryfy old"); Log.Write("EndVeryfy old"); Log.Write("Get signer's public key"); var publicKey = signerCertificate.GetPublicKey(); Log.Write("Got signer's public key"); try { Log.Write("Veryfy signature"); //TODO: log errors thisCertificate.Verify(publicKey); Log.Write("Verified"); } catch (CertificateException) { return false; } catch (InvalidKeyException) { return false; } return true; }
public static SignatureResponse Sign(byte[] data) { // TODO: // padding configuration // algorithm configuration // encoding configuration /* SHA1Managed sha1 = new SHA1Managed(); byte[] hash = sha1.ComputeHash(data); var sig = csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1")); //sig = csp.SignData(Encoding.UTF8.GetBytes(text), CryptoConfig.MapNameToOID("SHA1")); MessageBox.Show("SignData"); */ var content = new ContentInfo(data); var cms = new SignedCms(content, true); // TODO detached config var signer = new CmsSigner(); signer.IncludeOption = X509IncludeOption.EndCertOnly; cms.ComputeSignature(signer, false); var sig = cms.Encode(); //ensure my signature is correct before continuing. cms.CheckSignature(true); var newCMS = new SignedCms(content, false); newCMS.Decode(sig); newCMS.CheckSignature(true); var cert = cms.Certificates[0]; CheckSig(sig, data); return new SignatureResponse { publicKey = Convert.ToBase64String(cert.PublicKey.EncodedKeyValue.RawData), signature = Convert.ToBase64String(sig), fullSig = null // TODO }; }
public static byte[] SignFile(X509Certificate2 cert, byte[] data) { try { ContentInfo content = new ContentInfo(data); SignedCms signedCms = new SignedCms(content, false); if (VerifySign(data)) { signedCms.Decode(data); } CmsSigner signer = new CmsSigner(cert); signer.IncludeOption = X509IncludeOption.WholeChain; signedCms.ComputeSignature(signer); return signedCms.Encode(); } catch (Exception ex) { throw new Exception("Erro ao assinar arquivo. A mensagem retornada foi: " + ex.Message); } }
public void ComputeCounterSignature(CmsSigner signer) { if (_parentSignerInfo != null) { throw new CryptographicException(SR.Cryptography_Cms_NoCounterCounterSigner); } if (signer == null) { throw new ArgumentNullException(nameof(signer)); } signer.CheckCertificateValue(); int myIdx = _document.SignerInfos.FindIndexForSigner(this); if (myIdx < 0) { throw new CryptographicException(SR.Cryptography_Cms_SignerNotFound); } // Make sure that we're using the most up-to-date version of this that we can. SignerInfo effectiveThis = _document.SignerInfos[myIdx]; X509Certificate2Collection chain; SignerInfoAsn newSignerInfo = signer.Sign(effectiveThis._signature, null, false, out chain); AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); writer.PushSetOf(); AsnSerializer.Serialize(newSignerInfo, writer); writer.PopSetOf(); AttributeAsn newUnsignedAttr = new AttributeAsn { AttrType = new Oid(Oids.CounterSigner, Oids.CounterSigner), AttrValues = writer.Encode(), }; ref SignedDataAsn signedData = ref _document.GetRawData();
private void CoSign(CmsSigner signer, bool silent) { SafeCryptProvHandle safeCryptProvHandle; CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer, silent, out safeCryptProvHandle); try { SafeLocalAllocHandle pSignerEncodeInfo = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO)))); try { // Marshal to unmanaged memory. Marshal.StructureToPtr(signerEncodeInfo, pSignerEncodeInfo.DangerousGetHandle(), false); // Add the signature. if (!CAPI.CryptMsgControl(m_safeCryptMsgHandle, 0, CAPI.CMSG_CTRL_ADD_SIGNER, pSignerEncodeInfo.DangerousGetHandle())) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } finally { Marshal.DestroyStructure(pSignerEncodeInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO)); pSignerEncodeInfo.Dispose(); } } finally { // and don't forget to dispose of resources allocated for the structure. signerEncodeInfo.Dispose(); safeCryptProvHandle.Dispose(); } // Finally, add certs to bag of certs. PkcsUtils.AddCertsToMessage(m_safeCryptMsgHandle, Certificates, PkcsUtils.CreateBagOfCertificates(signer)); }
private AsnWriter WritePkcs8() { PrivateKeyInfoAsn info = new PrivateKeyInfoAsn { PrivateKeyAlgorithm = { Algorithm = AlgorithmId, }, PrivateKey = PrivateKeyBytes, }; if (AlgorithmParameters?.Length > 0) { info.PrivateKeyAlgorithm.Parameters = AlgorithmParameters; } if (Attributes.Count > 0) { info.Attributes = PkcsHelpers.NormalizeSet(CmsSigner.BuildAttributes(Attributes).ToArray()); } // Write in BER in case any of the provided fields was BER. return(AsnSerializer.Serialize(info, AsnEncodingRules.BER)); }
public void ComputeCounterSignature(CmsSigner signer) { // We only support one level of counter signing. if (m_parentSignerInfo != null) { throw new CryptographicException(CAPI.E_NOTIMPL); } if (signer == null) { throw new ArgumentNullException("signer"); } if (signer.Certificate == null) { signer.Certificate = PkcsUtils.SelectSignerCertificate(); } if (!signer.Certificate.HasPrivateKey) { throw new CryptographicException(CAPI.NTE_NO_KEY); } CounterSign(signer); }
internal byte[] SignProject(ExcelVbaProject proj) { if (!Certificate.HasPrivateKey) { //throw (new InvalidOperationException("The certificate doesn't have a private key")); Certificate = null; return null; } var hash = GetContentHash(proj); BinaryWriter bw = new BinaryWriter(new MemoryStream()); bw.Write((byte)0x30); //Constructed Type bw.Write((byte)0x32); //Total length bw.Write((byte)0x30); //Constructed Type bw.Write((byte)0x0E); //Length SpcIndirectDataContent bw.Write((byte)0x06); //Oid Tag Indentifier bw.Write((byte)0x0A); //Lenght OId bw.Write(new byte[] { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x1D }); //Encoded Oid 1.3.6.1.4.1.311.2.1.29 bw.Write((byte)0x04); //Octet String Tag Identifier bw.Write((byte)0x00); //Zero length bw.Write((byte)0x30); //Constructed Type (DigestInfo) bw.Write((byte)0x20); //Length DigestInfo bw.Write((byte)0x30); //Constructed Type (Algorithm) bw.Write((byte)0x0C); //length AlgorithmIdentifier bw.Write((byte)0x06); //Oid Tag Indentifier bw.Write((byte)0x08); //Lenght OId bw.Write(new byte[] { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05 }); //Encoded Oid for 1.2.840.113549.2.5 (AlgorithmIdentifier MD5) bw.Write((byte)0x05); //Null type identifier bw.Write((byte)0x00); //Null length bw.Write((byte)0x04); //Octet String Identifier bw.Write((byte)hash.Length); //Hash length bw.Write(hash); //Content hash ContentInfo contentInfo = new ContentInfo(((MemoryStream)bw.BaseStream).ToArray()); contentInfo.ContentType.Value = "1.3.6.1.4.1.311.2.1.4"; Verifier = new SignedCms(contentInfo); var signer = new CmsSigner(Certificate); Verifier.ComputeSignature(signer, false); return Verifier.Encode(); }
public void ComputeSignature(CmsSigner signer, bool silent) { if (signer == null) { throw new ArgumentNullException(nameof(signer)); } // While it shouldn't be possible to change the length of ContentInfo.Content // after it's built, use the property at this stage, then use the saved value // (if applicable) after this point. if (ContentInfo.Content.Length == 0) { throw new CryptographicException(SR.Cryptography_Cms_Sign_Empty_Content); } // If we had content already, use that now. // (The second signer doesn't inherit edits to signedCms.ContentInfo.Content) ReadOnlyMemory <byte> content = _heldContent ?? ContentInfo.Content; string contentType = _contentType ?? ContentInfo.ContentType.Value ?? Oids.Pkcs7Data; X509Certificate2Collection chainCerts; SignerInfoAsn newSigner = signer.Sign(content, contentType, silent, out chainCerts); bool firstSigner = false; if (!_hasData) { firstSigner = true; _signedData = new SignedDataAsn { DigestAlgorithms = Array.Empty <AlgorithmIdentifierAsn>(), SignerInfos = Array.Empty <SignerInfoAsn>(), EncapContentInfo = new EncapsulatedContentInfoAsn { ContentType = contentType }, }; // Since we're going to call Decode before this method exits we don't need to save // the copy of _heldContent or _contentType here if we're attached. if (!Detached) { using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER)) { writer.WriteOctetString(content.Span); _signedData.EncapContentInfo.Content = writer.Encode(); } } _hasData = true; } int newIdx = _signedData.SignerInfos.Length; Array.Resize(ref _signedData.SignerInfos, newIdx + 1); _signedData.SignerInfos[newIdx] = newSigner; UpdateCertificatesFromAddition(chainCerts); ConsiderDigestAddition(newSigner.DigestAlgorithm); UpdateMetadata(); if (firstSigner) { Reencode(); Debug.Assert(_heldContent != null); Debug.Assert(_contentType == contentType); } }
public void ComputeSignature(CmsSigner signer) { this.ComputeSignature(signer, true); }
public void ComputeSignatureCmsSignerUnknown () { ContentInfo ci = new ContentInfo (asnNull); SignedCms sp = new SignedCms (ci); CmsSigner signer = new CmsSigner (SubjectIdentifierType.Unknown, GetCertificate (true)); signer.Certificates.Add (new X509Certificate2 (intca_cer)); signer.Certificates.Add (new X509Certificate2 (root_cer)); sp.ComputeSignature (signer); byte[] encoded = sp.Encode (); string s = BitConverter.ToString (encoded); #if DEBUG FileStream fs = File.OpenWrite ("ComputeSignaturePkcs7SignerUnknown.der"); fs.Write (encoded, 0, encoded.Length); fs.Close (); #endif RoundTrip (encoded); }
private byte[] Sign(byte[] messageBytes) { Pkcs.ContentInfo content = new Pkcs.ContentInfo(messageBytes); Pkcs.SignedCms signed = new Pkcs.SignedCms(content); Pkcs.CmsSigner signer = new Pkcs.CmsSigner(_signerCert); signed.ComputeSignature(signer); byte[] signedBytes = signed.Encode(); return signedBytes; }
public void ComputeCounterSignature(CmsSigner signer) { }
public void ComputeSignature(CmsSigner signer, bool silent) { ComputeSignature(); }
/// <summary> /// Подписание данных (файла) с помощью сертификата ЭП /// </summary> /// <param name="certificate">Сертификат Электронной Подписи, которым будет подписан файл</param> /// <returns>Файл с подписью (в случае прикрепленной подписи будет файл с данными и подписью) </returns> public byte[] Sign(ICertificate certificate) { //создаем контейнер с данными, которые будут подписываться var content = new ContentInfo(this.Original); //создаем пакет, в который помещаем контейнер с данными и параметры подписи //это основной объект, в рамках которого формируются проверки и преобразования подписи var cms = new SignedCms(content, this.Detached); //создаем подписанта (объект на основе сертификата, который будет подписывать) var signer = new CmsSigner(certificate.CertificateX509); //с помощью подписанта подписываем пакет так, //что теперь в пакете находятся не сами данные, //а именно подписанные данные, то есть: // - сама подпись в случае отсоединенной подписи // - подпись с оригинальными данными в случае присоединенной подписи cms.ComputeSignature(signer, false); // сохраняем подписанный пакет byte[] result = cms.Encode(); return result; }
/// <summary> /// Signs the message and envelopes it. /// </summary> /// <param name="signer">An object containing the signer's information.</param> /// <example> /// <code> /// [C#] /// /// CmsSigner signer = new CmsSigner(new X509Certificate2("C:\\mycertificate.pfx")); /// /// // Here we only want the signer's certificate to be sent along. Not the whole chain. /// signer.IncludeOption = X509IncludeOption.EndCertOnly; /// /// message.SmimeEnvelopeAndSignBy(signer); /// </code> /// </example> public void SmimeEnvelopeAndSignBy(CmsSigner signer) { string mimeString = this.ToMimeString(); byte[] tosign = Encoding.ASCII.GetBytes(mimeString); SignedCms cms = new SignedCms(new ContentInfo(tosign)); cms.ComputeSignature(signer); MimePart envelope = new MimePart(); envelope.ContentType.MimeType = "application/pkcs7-mime"; envelope.ContentType.Parameters.Add("smime-type", "signed-data"); envelope.ContentType.Parameters.Add("name", "smime.p7m"); envelope.ContentDisposition.Disposition = "attachment"; envelope.ContentDisposition.FileName = "smime.p7m"; envelope.ContentTransferEncoding = ContentTransferEncoding.Base64; envelope.BinaryContent = cms.Encode(); this.PartTreeRoot = envelope; this.ContentType = this.PartTreeRoot.ContentType; this.ContentDisposition = this.PartTreeRoot.ContentDisposition; this.ContentTransferEncoding = this.PartTreeRoot.ContentTransferEncoding; }
/// <summary> /// Сформировать ЭП /// </summary> /// <param name="certificate"></param> /// <param name="data"></param> /// <param name="detached"></param> /// <returns></returns> public static byte[] Sign(X509Certificate2 certificate, byte[] data, bool detached) { // то что подписываем var contentInfo = new ContentInfo(data); var signedCms = new SignedCms(contentInfo, detached); // сертификато для подписания var cmsSigner = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, certificate); signedCms.ComputeSignature(cmsSigner, true); // подпись return signedCms.Encode(); }
public void ComputeSignature(CmsSigner signer) => ComputeSignature(signer, true);
private void CounterSign(CmsSigner signer) { CspParameters parameters = new CspParameters(); if (!System.Security.Cryptography.X509Certificates.X509Utils.GetPrivateKeyInfo(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(signer.Certificate), ref parameters)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } KeyContainerPermission permission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags); KeyContainerPermissionAccessEntry accessEntry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Sign | KeyContainerPermissionFlags.Open); permission.AccessEntries.Add(accessEntry); permission.Demand(); uint dwIndex = (uint) PkcsUtils.GetSignerIndex(this.m_signedCms.GetCryptMsgHandle(), this, 0); System.Security.Cryptography.SafeLocalAllocHandle handle = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_SIGNER_ENCODE_INFO)))); System.Security.Cryptography.CAPI.CMSG_SIGNER_ENCODE_INFO structure = PkcsUtils.CreateSignerEncodeInfo(signer); try { Marshal.StructureToPtr(structure, handle.DangerousGetHandle(), false); if (!System.Security.Cryptography.CAPI.CryptMsgCountersign(this.m_signedCms.GetCryptMsgHandle(), dwIndex, 1, handle.DangerousGetHandle())) { throw new CryptographicException(Marshal.GetLastWin32Error()); } this.m_signedCms.ReopenToDecode(); } finally { Marshal.DestroyStructure(handle.DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CMSG_SIGNER_ENCODE_INFO)); handle.Dispose(); structure.Dispose(); } PkcsUtils.AddCertsToMessage(this.m_signedCms.GetCryptMsgHandle(), this.m_signedCms.Certificates, PkcsUtils.CreateBagOfCertificates(signer)); }
private unsafe void CounterSign(CmsSigner signer) { // Sanity check. Debug.Assert(signer != null); // CspParameters parameters = new CspParameters(); if (X509Utils.GetPrivateKeyInfo(X509Utils.GetCertContext(signer.Certificate), ref parameters) == false) { throw new CryptographicException(Marshal.GetLastWin32Error()); } KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags); KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Open | KeyContainerPermissionFlags.Sign); kp.AccessEntries.Add(entry); kp.Demand(); // Get the signer's index. uint index = (uint)PkcsUtils.GetSignerIndex(m_signedCms.GetCryptMsgHandle(), this, 0); // Create CMSG_SIGNER_ENCODE_INFO structure. SafeLocalAllocHandle pSignerEncodeInfo = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO)))); SafeCryptProvHandle safeCryptProvHandle; CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer, out safeCryptProvHandle); try { // Marshal to unmanaged memory. Marshal.StructureToPtr(signerEncodeInfo, pSignerEncodeInfo.DangerousGetHandle(), false); // Counter sign. if (!CAPI.CryptMsgCountersign(m_signedCms.GetCryptMsgHandle(), index, 1, pSignerEncodeInfo.DangerousGetHandle())) { throw new CryptographicException(Marshal.GetLastWin32Error()); } // CAPI requires that the messge be re-encoded if any unauthenticated // attribute has been added. So, let's re-open it to decode to work // around this limitation. m_signedCms.ReopenToDecode(); } finally { Marshal.DestroyStructure(pSignerEncodeInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO)); pSignerEncodeInfo.Dispose(); // and don't forget to dispose of resources allocated for the structure. signerEncodeInfo.Dispose(); safeCryptProvHandle.Dispose(); } // Finally, add certs to bag of certs. PkcsUtils.AddCertsToMessage(m_signedCms.GetCryptMsgHandle(), m_signedCms.Certificates, PkcsUtils.CreateBagOfCertificates(signer)); return; }
public void ComputeSignature(CmsSigner signer) { ComputeSignature(); }
public void ComputeSignature(CmsSigner signer) { this.m_signer = signer; SignInternal(signer.Certificate, this.m_contentInfo.Content); }
public static byte[] SignMsg(int hashAlg, byte[] msg, X509Certificate2 signerCert) { // Place message in a ContentInfo object. // This is required to build a SignedCms object. ContentInfo contentInfo = new ContentInfo(msg); // Instantiate SignedCms object with the ContentInfo above. // Has default SubjectIdentifierType IssuerAndSerialNumber. // Has default Detached property value false, so message is // included in the encoded SignedCms. SignedCms signedCms = new SignedCms(contentInfo, true); // Formulate a CmsSigner object, which has all the needed // characteristics of the signer. CmsSigner cmsSigner = new CmsSigner(signerCert); // Sign the PKCS #7 message. signedCms.ComputeSignature(cmsSigner, false); // Encode the PKCS #7 message. return signedCms.Encode(); }
// Sign the message with the private key of the signer. private static byte[] SignMsg(Byte[] msg, X509Certificate2 signerCert, bool detached) { // Place message in a ContentInfo object. // This is required to build a SignedCms object. var contentInfo = new ContentInfo(msg); // Instantiate SignedCms object with the ContentInfo above. // Has default SubjectIdentifierType IssuerAndSerialNumber. var signedCms = new SignedCms(contentInfo, detached); // Formulate a CmsSigner object for the signer. var cmsSigner = new CmsSigner(signerCert); // Include the following line if the top certificate in the // smartcard is not in the trusted list. cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly; // Sign the CMS/PKCS #7 message. The second argument is // needed to ask for the pin. signedCms.ComputeSignature(cmsSigner, false); // Encode the CMS/PKCS #7 message. return signedCms.Encode(); }
// Sign the message with the private key of the signer. public byte[] SignMsg(Byte[] msg, X509Certificate2 signerCert, bool detached) { // Place message in a ContentInfo object. // This is required to build a SignedCms object. ContentInfo contentInfo = new ContentInfo(msg); // Instantiate SignedCms object with the ContentInfo above. // Has default SubjectIdentifierType IssuerAndSerialNumber. SignedCms signedCms = new SignedCms(contentInfo, detached); // Formulate a CmsSigner object for the signer. CmsSigner cmsSigner = new CmsSigner(signerCert); // Include the following line if the top certificate in the // smartcard is not in the trusted list. cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly; // Sign the CMS/PKCS #7 message. The second argument is // needed to ask for the pin. signedCms.ComputeSignature(cmsSigner, false); // TODO: Here the user can fail the password or cancel...what to do? // Encode the CMS/PKCS #7 message. byte[] bb = signedCms.Encode(); //return bb here if no timestamp is to be applied if (!Config.Stamp) return bb; CmsSignedData sd = new CmsSignedData(bb); SignerInformationStore signers = sd.GetSignerInfos(); byte[] signature = null; SignerInformation signer = null; foreach (SignerInformation signer_ in signers.GetSigners()) { signer = signer_; break; } signature = signer.GetSignature(); Org.BouncyCastle.Asn1.Cms.AttributeTable at = new Org.BouncyCastle.Asn1.Cms.AttributeTable(GetTimestamp(signature)); signer = SignerInformation.ReplaceUnsignedAttributes(signer, at); IList signerInfos = new ArrayList(); signerInfos.Add(signer); sd = CmsSignedData.ReplaceSigners(sd, new SignerInformationStore(signerInfos)); bb = sd.GetEncoded(); return bb; }
/// <summary> /// Signs a data hash and returns the signature /// </summary> /// <param name="x">Certificate used to sign the data</param> /// <param name="hashedData">Data digest to be signed</param> /// <returns>Returns a string containing a PKCS#7 signature</returns> private String EncodeCMS(X509Certificate2 x, byte[] hashedData) { //we are creating a CMS/PKCS#7 message Oid digestOid = new Oid("1.2.840.113549.1.7.2"); ContentInfo contentInfo = new ContentInfo(digestOid, hashedData); //true: signature is detached and will be added to the file SignedCms signedCms = new SignedCms(contentInfo, true); CmsSigner cmsSigner = new CmsSigner(x); // false will prompt the user to enter the pin if a PIV is used signedCms.ComputeSignature(cmsSigner, false); byte[] encode = signedCms.Encode(); return Convert.ToBase64String(encode); }
/// <summary> /// Signs the signature request with the specified certificate, embeds all the specified additional certificates /// in the signature, and uses the provided additional certificates (along with the Operating /// System certificate store, if present) to build the full chain for the signing cert and /// embed that in the signature. /// </summary> /// <param name="signingCert">The certificate and private key to sign the document with</param> /// <param name="chainBuildingCertificates">Additional certificates to use when building the chain to embed</param> /// <param name="certificatesToEmbed">Additional certificates to add to the signature</param> public void Sign(X509Certificate2 signingCert, X509Certificate2Collection chainBuildingCertificates, X509Certificate2Collection certificatesToEmbed) { if (_signature != null) { throw new InvalidOperationException("A signature already exists"); } // Create the content info var content = new ContentInfo(Payload.Encode()); // Create the signer var signer = new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, signingCert); var signingTime = new Pkcs9SigningTime(DateTime.UtcNow); signer.SignedAttributes.Add( new CryptographicAttributeObject( signingTime.Oid, new AsnEncodedDataCollection(signingTime))); // We do want the whole chain in the file, but we can't control how // CmsSigner builds the chain and add our additional certificates. // So, we tell it not to worry and we manually build the chain and // add it to the signer. signer.IncludeOption = X509IncludeOption.EndCertOnly; // Embed all the certificates in the CMS var chain = new X509Chain(); if (chainBuildingCertificates != null) { chain.ChainPolicy.ExtraStore.AddRange(chainBuildingCertificates); } chain.Build(signingCert); foreach (var element in chain.ChainElements) { // Don't re-embed the signing certificate! if (!Equals(element.Certificate, signingCert)) { signer.Certificates.Add(element.Certificate); } } if (certificatesToEmbed != null) { signer.Certificates.AddRange(certificatesToEmbed); } // Create the message and sign it // Use a local variable so that if the signature fails to compute, this object // remains in a "good" state. var cms = new SignedCms(content); cms.ComputeSignature(signer); _signature = cms; }
public void ComputeEmptySignatureCmsSigner () { CmsSigner signer = new CmsSigner (); SignedCms sp = new SignedCms (); sp.ComputeSignature (signer); }
public void ComputeCounterSignature(CmsSigner signer) { if (this.m_parentSignerInfo != null) { throw new CryptographicException(-2147483647); } if (signer == null) { throw new ArgumentNullException("signer"); } if (signer.Certificate == null) { signer.Certificate = PkcsUtils.SelectSignerCertificate(); } if (!signer.Certificate.HasPrivateKey) { throw new CryptographicException(-2146893811); } this.CounterSign(signer); }
internal static System.Security.Cryptography.CAPI.CMSG_SIGNER_ENCODE_INFO CreateSignerEncodeInfo(CmsSigner signer) { return(CreateSignerEncodeInfo(signer, false)); }
public void ComputeSignature(CmsSigner signer, bool silent) { if (signer == null) { throw new ArgumentNullException(nameof(signer)); } // While it shouldn't be possible to change the length of ContentInfo.Content // after it's built, use the property at this stage, then use the saved value // (if applicable) after this point. if (ContentInfo.Content.Length == 0) { throw new CryptographicException(SR.Cryptography_Cms_Sign_Empty_Content); } if (_hasData && signer.SignerIdentifierType == SubjectIdentifierType.NoSignature) { // Even if all signers have been removed, throw if doing a NoSignature signature // on a loaded (from file, or from first signature) document. // // This matches the .NET Framework behavior. throw new CryptographicException(SR.Cryptography_Cms_Sign_No_Signature_First_Signer); } if (signer.Certificate == null && signer.SignerIdentifierType != SubjectIdentifierType.NoSignature) { if (silent) { // .NET Framework compatibility, silent disallows prompting, so throws InvalidOperationException // in this state. // // The message is different than on NetFX, because the resource string was for // enveloped CMS recipients (and the other site which would use that resource // is unreachable code due to CmsRecipient's ctor guarding against null certificates) throw new InvalidOperationException(SR.Cryptography_Cms_NoSignerCertSilent); } // Otherwise, PNSE. .NET Core doesn't support launching the cert picker UI. throw new PlatformNotSupportedException(SR.Cryptography_Cms_NoSignerCert); } // If we had content already, use that now. // (The second signer doesn't inherit edits to signedCms.ContentInfo.Content) ReadOnlyMemory <byte> content = _heldContent ?? ContentInfo.Content; string contentType = _contentType ?? ContentInfo.ContentType.Value ?? Oids.Pkcs7Data; X509Certificate2Collection chainCerts; SignerInfoAsn newSigner = signer.Sign(content, contentType, silent, out chainCerts); bool firstSigner = false; if (!_hasData) { firstSigner = true; _signedData = new SignedDataAsn { DigestAlgorithms = Array.Empty <AlgorithmIdentifierAsn>(), SignerInfos = Array.Empty <SignerInfoAsn>(), EncapContentInfo = new EncapsulatedContentInfoAsn { ContentType = contentType }, }; // Since we're going to call Decode before this method exits we don't need to save // the copy of _heldContent or _contentType here if we're attached. if (!Detached) { using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER)) { writer.WriteOctetString(content.Span); _signedData.EncapContentInfo.Content = writer.Encode(); } } _hasData = true; } int newIdx = _signedData.SignerInfos.Length; Array.Resize(ref _signedData.SignerInfos, newIdx + 1); _signedData.SignerInfos[newIdx] = newSigner; UpdateCertificatesFromAddition(chainCerts); ConsiderDigestAddition(newSigner.DigestAlgorithm); UpdateMetadata(); if (firstSigner) { Reencode(); Debug.Assert(_heldContent != null); Debug.Assert(_contentType == contentType); } }
internal static unsafe System.Security.Cryptography.CAPI.CMSG_SIGNER_ENCODE_INFO CreateSignerEncodeInfo(CmsSigner signer, bool silent) { System.Security.Cryptography.CAPI.CMSG_SIGNER_ENCODE_INFO cmsg_signer_encode_info = new System.Security.Cryptography.CAPI.CMSG_SIGNER_ENCODE_INFO(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_SIGNER_ENCODE_INFO))); System.Security.Cryptography.SafeCryptProvHandle invalidHandle = System.Security.Cryptography.SafeCryptProvHandle.InvalidHandle; uint pdwKeySpec = 0; bool pfCallerFreeProv = false; cmsg_signer_encode_info.HashAlgorithm.pszObjId = signer.DigestAlgorithm.Value; if (string.Compare(signer.Certificate.PublicKey.Oid.Value, "1.2.840.10040.4.1", StringComparison.Ordinal) == 0) { cmsg_signer_encode_info.HashEncryptionAlgorithm.pszObjId = "1.2.840.10040.4.3"; } cmsg_signer_encode_info.cAuthAttr = (uint)signer.SignedAttributes.Count; cmsg_signer_encode_info.rgAuthAttr = CreateCryptAttributes(signer.SignedAttributes); cmsg_signer_encode_info.cUnauthAttr = (uint)signer.UnsignedAttributes.Count; cmsg_signer_encode_info.rgUnauthAttr = CreateCryptAttributes(signer.UnsignedAttributes); if (signer.SignerIdentifierType == SubjectIdentifierType.NoSignature) { cmsg_signer_encode_info.HashEncryptionAlgorithm.pszObjId = "1.3.6.1.5.5.7.6.2"; cmsg_signer_encode_info.pCertInfo = IntPtr.Zero; cmsg_signer_encode_info.dwKeySpec = pdwKeySpec; if (!System.Security.Cryptography.CAPI.CryptAcquireContext(ref invalidHandle, (string)null, (string)null, 1, 0xf0000000)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } cmsg_signer_encode_info.hCryptProv = invalidHandle.DangerousGetHandle(); GC.SuppressFinalize(invalidHandle); cmsg_signer_encode_info.SignerId.dwIdChoice = 1; X500DistinguishedName name = new X500DistinguishedName("CN=Dummy Signer") { Oid = new Oid("1.3.6.1.4.1.311.21.9") }; cmsg_signer_encode_info.SignerId.Value.IssuerSerialNumber.Issuer.cbData = (uint)name.RawData.Length; System.Security.Cryptography.SafeLocalAllocHandle handle2 = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long)cmsg_signer_encode_info.SignerId.Value.IssuerSerialNumber.Issuer.cbData)); Marshal.Copy(name.RawData, 0, handle2.DangerousGetHandle(), name.RawData.Length); cmsg_signer_encode_info.SignerId.Value.IssuerSerialNumber.Issuer.pbData = handle2.DangerousGetHandle(); GC.SuppressFinalize(handle2); cmsg_signer_encode_info.SignerId.Value.IssuerSerialNumber.SerialNumber.cbData = 1; System.Security.Cryptography.SafeLocalAllocHandle handle3 = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long)cmsg_signer_encode_info.SignerId.Value.IssuerSerialNumber.SerialNumber.cbData)); byte *handle = (byte *)handle3.DangerousGetHandle(); handle[0] = 0; cmsg_signer_encode_info.SignerId.Value.IssuerSerialNumber.SerialNumber.pbData = handle3.DangerousGetHandle(); GC.SuppressFinalize(handle3); return(cmsg_signer_encode_info); } System.Security.Cryptography.SafeCertContextHandle certContext = System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(signer.Certificate); if (!System.Security.Cryptography.CAPI.CAPISafe.CryptAcquireCertificatePrivateKey(certContext, silent ? 70 : 6, IntPtr.Zero, ref invalidHandle, ref pdwKeySpec, ref pfCallerFreeProv)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } cmsg_signer_encode_info.dwKeySpec = pdwKeySpec; cmsg_signer_encode_info.hCryptProv = invalidHandle.DangerousGetHandle(); GC.SuppressFinalize(invalidHandle); System.Security.Cryptography.CAPI.CERT_CONTEXT cert_context = *((System.Security.Cryptography.CAPI.CERT_CONTEXT *)certContext.DangerousGetHandle()); cmsg_signer_encode_info.pCertInfo = cert_context.pCertInfo; if (signer.SignerIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier) { uint pcbData = 0; System.Security.Cryptography.SafeLocalAllocHandle pvData = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle; if (!System.Security.Cryptography.CAPI.CAPISafe.CertGetCertificateContextProperty(certContext, 20, pvData, ref pcbData)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } if (pcbData <= 0) { return(cmsg_signer_encode_info); } pvData = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long)pcbData)); if (!System.Security.Cryptography.CAPI.CAPISafe.CertGetCertificateContextProperty(certContext, 20, pvData, ref pcbData)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } cmsg_signer_encode_info.SignerId.dwIdChoice = 2; cmsg_signer_encode_info.SignerId.Value.KeyId.cbData = pcbData; cmsg_signer_encode_info.SignerId.Value.KeyId.pbData = pvData.DangerousGetHandle(); GC.SuppressFinalize(pvData); } return(cmsg_signer_encode_info); }
public static byte[] SignDetached(byte[] data, X509Certificate2 signingCert) { ContentInfo content = new ContentInfo(data); SignedCms signedMessage = new SignedCms(content, true); CmsSigner signer = new CmsSigner(signingCert); signedMessage.ComputeSignature(signer); byte[] signedBytes = signedMessage.Encode(); return signedBytes; }
public void ComputeSignature(CmsSigner signer, bool silent) { if (signer == null) { throw new ArgumentNullException("signer"); } if (ContentInfo.Content.Length == 0) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Sign_Empty_Content")); } if (SubjectIdentifierType.NoSignature == signer.SignerIdentifierType) { if (m_safeCryptMsgHandle != null && !m_safeCryptMsgHandle.IsInvalid) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Sign_No_Signature_First_Signer")); } // First signer. Sign(signer, silent); return; } if (signer.Certificate == null) { if (silent) { throw new InvalidOperationException(SecurityResources.GetResourceString("Cryptography_Cms_RecipientCertificateNotFound")); } else { signer.Certificate = PkcsUtils.SelectSignerCertificate(); } } if (!signer.Certificate.HasPrivateKey) { throw new CryptographicException(CAPI.NTE_NO_KEY); } // CspParameters parameters = new CspParameters(); if (X509Utils.GetPrivateKeyInfo(X509Utils.GetCertContext(signer.Certificate), ref parameters)) { KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags); KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Open | KeyContainerPermissionFlags.Sign); kp.AccessEntries.Add(entry); kp.Demand(); } if (m_safeCryptMsgHandle == null || m_safeCryptMsgHandle.IsInvalid) { // First signer. Sign(signer, silent); } else { // Co-signing. CoSign(signer, silent); } }
/// <summary> /// Attaches a clear signature to the message. It is advised to do so when the receiving party might not be S/MIME capable. /// The content of the message is still visible, i.e. the message isn't enveloped. /// </summary> /// <param name="signer">An object containing the signer's information.</param> /// <example> /// <code> /// [C#] /// /// CmsSigner signer = new CmsSigner(new X509Certificate2("C:\\mycertificate.pfx")); /// /// // Here we only want the signer's certificate to be sent along. Not the whole chain. /// signer.IncludeOption = X509IncludeOption.EndCertOnly; /// /// message.SmimeAttachSignatureBy(signer); /// </code> /// </example> public void SmimeAttachSignatureBy(CmsSigner signer) { string body = this.PartTreeRoot.ToMimeString(); byte[] tosign = Encoding.ASCII.GetBytes(body.TrimEnd('\r', '\n') + "\r\n"); SignedCms cms = new SignedCms(new ContentInfo(tosign), true); cms.ComputeSignature(signer); MimePart envelope = new MimePart(); this.Signatures.Smime = cms; envelope.ContentType.MimeType = "multipart/signed"; envelope.ContentType.Parameters.Add("protocol", "\"application/x-pkcs7-signature\""); envelope.ContentType.Parameters.Add("micalg", cms.SignerInfos[0].DigestAlgorithm.FriendlyName); string unique = Codec.GetUniqueString(); string boundary = "---AU_MimePart_" + unique; envelope.ContentType.Parameters.Add("boundary", boundary); envelope.SubParts.Add(this.PartTreeRoot); envelope.SubParts.Add(MimePart.GetSignaturePart(cms)); this.PartTreeRoot = envelope; this.ContentType = this.PartTreeRoot.ContentType; this.ContentDisposition = this.PartTreeRoot.ContentDisposition; this.ContentTransferEncoding = this.PartTreeRoot.ContentTransferEncoding; }
private unsafe void Sign(CmsSigner signer, bool silent) { SafeCryptMsgHandle safeCryptMsgHandle = null; CAPI.CMSG_SIGNED_ENCODE_INFO signedEncodeInfo = new CAPI.CMSG_SIGNED_ENCODE_INFO(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNED_ENCODE_INFO))); SafeCryptProvHandle safeCryptProvHandle; CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer, silent, out safeCryptProvHandle); byte[] encodedMessage = null; try { SafeLocalAllocHandle pSignerEncodeInfo = CAPI.LocalAlloc(CAPI.LMEM_FIXED, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO)))); try { Marshal.StructureToPtr(signerEncodeInfo, pSignerEncodeInfo.DangerousGetHandle(), false); X509Certificate2Collection bagOfCerts = PkcsUtils.CreateBagOfCertificates(signer); SafeLocalAllocHandle pEncodedBagOfCerts = PkcsUtils.CreateEncodedCertBlob(bagOfCerts); signedEncodeInfo.cSigners = 1; signedEncodeInfo.rgSigners = pSignerEncodeInfo.DangerousGetHandle(); signedEncodeInfo.cCertEncoded = (uint)bagOfCerts.Count; if (bagOfCerts.Count > 0) { signedEncodeInfo.rgCertEncoded = pEncodedBagOfCerts.DangerousGetHandle(); } // Because of the way CAPI treats inner content OID, we should pass NULL // for data type, otherwise detached will not work. if (String.Compare(this.ContentInfo.ContentType.Value, CAPI.szOID_RSA_data, StringComparison.OrdinalIgnoreCase) == 0) { safeCryptMsgHandle = CAPI.CryptMsgOpenToEncode(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, Detached ? CAPI.CMSG_DETACHED_FLAG : 0, CAPI.CMSG_SIGNED, new IntPtr(&signedEncodeInfo), IntPtr.Zero, IntPtr.Zero); } else { safeCryptMsgHandle = CAPI.CryptMsgOpenToEncode(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, Detached ? CAPI.CMSG_DETACHED_FLAG : 0, CAPI.CMSG_SIGNED, new IntPtr(&signedEncodeInfo), this.ContentInfo.ContentType.Value, IntPtr.Zero); } if (safeCryptMsgHandle == null || safeCryptMsgHandle.IsInvalid) { throw new CryptographicException(Marshal.GetLastWin32Error()); } if (this.ContentInfo.Content.Length > 0) { if (!CAPI.CAPISafe.CryptMsgUpdate(safeCryptMsgHandle, this.ContentInfo.pContent, (uint)this.ContentInfo.Content.Length, true)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } // Retrieve encoded message. encodedMessage = PkcsUtils.GetContent(safeCryptMsgHandle); safeCryptMsgHandle.Dispose(); pEncodedBagOfCerts.Dispose(); } finally { Marshal.DestroyStructure(pSignerEncodeInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO)); pSignerEncodeInfo.Dispose(); } } finally { // Don't forget to free all the resource still held inside signerEncodeInfo. signerEncodeInfo.Dispose(); safeCryptProvHandle.Dispose(); } // Re-open to decode. safeCryptMsgHandle = OpenToDecode(encodedMessage, this.ContentInfo, this.Detached); if (m_safeCryptMsgHandle != null && !m_safeCryptMsgHandle.IsInvalid) { m_safeCryptMsgHandle.Dispose(); } m_safeCryptMsgHandle = safeCryptMsgHandle; GC.KeepAlive(signer); }