/// <summary> /// Sign and Encrypt the specified entity. /// </summary> /// <param name="ctx">The S/MIME context to use for signing and encrypting.</param> /// <param name="signer">The signer.</param> /// <param name="digestAlgo">The digest algorithm to use for signing.</param> /// <param name="recipients">The recipients.</param> /// <param name="entity">The entity.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="ctx"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="signer"/> is<c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="recipients"/> is<c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="entity"/> is<c>null</c>.</para> /// </exception> /// <exception cref="CertificateNotFoundException"> /// <para>A signing certificate could not be found for <paramref name="signer"/>.</para> /// <para>-or-</para> /// <para>A certificate could not be found for one or more of the <paramref name="recipients"/>.</para> /// </exception> public static ApplicationPkcs7Mime SignAndEncrypt(SecureMimeContext ctx, MailboxAddress signer, DigestAlgorithm digestAlgo, IEnumerable <MailboxAddress> recipients, MimeEntity entity) { // FIXME: find out what exceptions BouncyCastle can throw... if (ctx == null) { throw new ArgumentNullException("ctx"); } if (signer == null) { throw new ArgumentNullException("signer"); } if (recipients == null) { throw new ArgumentNullException("recipients"); } if (entity == null) { throw new ArgumentNullException("entity"); } return(Encrypt(ctx, recipients, MultipartSigned.Create(ctx, signer, digestAlgo, entity))); }
/// <summary> /// Sign and Encrypt the specified entity. /// </summary> /// <param name="ctx">The S/MIME context to use for signing and encrypting.</param> /// <param name="signer">The signer.</param> /// <param name="recipients">The recipients.</param> /// <param name="entity">The entity.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="ctx"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="signer"/> is<c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="recipients"/> is<c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="entity"/> is<c>null</c>.</para> /// </exception> public static ApplicationPkcs7Mime SignAndEncrypt(SecureMimeContext ctx, CmsSigner signer, CmsRecipientCollection recipients, MimeEntity entity) { // FIXME: find out what exceptions BouncyCastle can throw... if (ctx == null) { throw new ArgumentNullException("ctx"); } if (signer == null) { throw new ArgumentNullException("signer"); } if (recipients == null) { throw new ArgumentNullException("recipients"); } if (entity == null) { throw new ArgumentNullException("entity"); } return(Encrypt(ctx, recipients, MultipartSigned.Create(ctx, signer, entity))); }
/// <summary> /// Creates a new <see cref="MultipartSigned"/>. /// </summary> /// <remarks> /// Cryptographically signs the entity using the supplied signer in order /// to generate a detached signature and then adds the entity along with /// the detached signature data to a new multipart/signed part. /// </remarks> /// <returns>A new <see cref="MultipartSigned"/> instance.</returns> /// <param name="ctx">The S/MIME context to use for signing.</param> /// <param name="signer">The signer.</param> /// <param name="entity">The entity to sign.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="ctx"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="signer"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static MultipartSigned Create(SecureMimeContext ctx, CmsSigner signer, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (signer == null) { throw new ArgumentNullException("signer"); } if (entity == null) { throw new ArgumentNullException("entity"); } entity.Prepare(EncodingConstraint.SevenBit, 78); using (var memory = new MemoryBlockStream()) { using (var filtered = new FilteredStream(memory)) { // Note: see rfc3156, section 3 - second note filtered.Add(new ArmoredFromFilter()); // Note: see rfc3156, section 5.4 (this is the main difference between rfc2015 and rfc3156) filtered.Add(new TrailingWhitespaceFilter()); // Note: see rfc2015 or rfc3156, section 5.1 filtered.Add(new Unix2DosFilter()); entity.WriteTo(filtered); filtered.Flush(); } memory.Position = 0; // Note: we need to parse the modified entity structure to preserve any modifications var parser = new MimeParser(memory, MimeFormat.Entity); var parsed = parser.ParseEntity(); memory.Position = 0; // sign the cleartext content var micalg = ctx.GetDigestAlgorithmName(signer.DigestAlgorithm); var signature = ctx.Sign(signer, memory); var signed = new MultipartSigned(); // set the protocol and micalg Content-Type parameters signed.ContentType.Parameters["protocol"] = ctx.SignatureProtocol; signed.ContentType.Parameters["micalg"] = micalg; // add the modified/parsed entity as our first part signed.Add(parsed); // add the detached signature as the second part signed.Add(signature); return(signed); } }
static MultipartSigned Create(CryptographyContext ctx, DigestAlgorithm digestAlgo, MimeEntity entity, MimeEntity signature) { var micalg = ctx.GetDigestAlgorithmName(digestAlgo); var signed = new MultipartSigned(); // set the protocol and micalg Content-Type parameters signed.ContentType.Parameters["protocol"] = ctx.SignatureProtocol; signed.ContentType.Parameters["micalg"] = micalg; // add the modified/parsed entity as our first part signed.Add(entity); // add the detached signature as the second part signed.Add(signature); return(signed); }
/// <summary> /// Cryptographically signs and encrypts the specified entity. /// </summary> /// <remarks> /// Cryptographically signs entity using the supplied signer and then /// encrypts the result to the specified recipients. /// </remarks> /// <returns>The signed and encrypted entity.</returns> /// <param name="ctx">The S/MIME context to use for signing and encrypting.</param> /// <param name="signer">The signer.</param> /// <param name="digestAlgo">The digest algorithm to use for signing.</param> /// <param name="recipients">The recipients.</param> /// <param name="entity">The entity.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="ctx"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="signer"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="recipients"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="CertificateNotFoundException"> /// <para>A signing certificate could not be found for <paramref name="signer"/>.</para> /// <para>-or-</para> /// <para>A certificate could not be found for one or more of the <paramref name="recipients"/>.</para> /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static ApplicationPkcs7Mime SignAndEncrypt(SecureMimeContext ctx, MailboxAddress signer, DigestAlgorithm digestAlgo, IEnumerable <MailboxAddress> recipients, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } if (signer == null) { throw new ArgumentNullException(nameof(signer)); } if (recipients == null) { throw new ArgumentNullException(nameof(recipients)); } if (entity == null) { throw new ArgumentNullException(nameof(entity)); } return(Encrypt(ctx, recipients, MultipartSigned.Create(ctx, signer, digestAlgo, entity))); }
/// <summary> /// Cryptographically signs and encrypts the specified entity. /// </summary> /// <remarks> /// Cryptographically signs entity using the supplied signer and then /// encrypts the result to the specified recipients. /// </remarks> /// <returns>The signed and encrypted entity.</returns> /// <param name="ctx">The S/MIME context to use for signing and encrypting.</param> /// <param name="signer">The signer.</param> /// <param name="recipients">The recipients.</param> /// <param name="entity">The entity.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="ctx"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="signer"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="recipients"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static ApplicationPkcs7Mime SignAndEncrypt(SecureMimeContext ctx, CmsSigner signer, CmsRecipientCollection recipients, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } if (signer == null) { throw new ArgumentNullException(nameof(signer)); } if (recipients == null) { throw new ArgumentNullException(nameof(recipients)); } if (entity == null) { throw new ArgumentNullException(nameof(entity)); } return(Encrypt(ctx, recipients, MultipartSigned.Create(ctx, signer, entity))); }
/// <summary> /// Visit the multipart/signed MIME entity. /// </summary> /// <remarks> /// Visits the multipart/signed MIME entity. /// </remarks> /// <param name="signed">The multipart/signed MIME entity.</param> protected internal virtual void VisitMultipartSigned (MultipartSigned signed) { VisitMultipart (signed); }
/// <summary> /// Creates a new <see cref="MultipartSigned"/>. /// </summary> /// <remarks> /// Cryptographically signs the entity using the supplied signer in order /// to generate a detached signature and then adds the entity along with /// the detached signature data to a new multipart/signed part. /// </remarks> /// <returns>A new <see cref="MultipartSigned"/> instance.</returns> /// <param name="ctx">The S/MIME context to use for signing.</param> /// <param name="signer">The signer.</param> /// <param name="entity">The entity to sign.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="ctx"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="signer"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static MultipartSigned Create (SecureMimeContext ctx, CmsSigner signer, MimeEntity entity) { if (ctx == null) throw new ArgumentNullException ("ctx"); if (signer == null) throw new ArgumentNullException ("signer"); if (entity == null) throw new ArgumentNullException ("entity"); PrepareEntityForSigning (entity); using (var memory = new MemoryBlockStream ()) { using (var filtered = new FilteredStream (memory)) { // Note: see rfc3156, section 3 - second note filtered.Add (new ArmoredFromFilter ()); // Note: see rfc3156, section 5.4 (this is the main difference between rfc2015 and rfc3156) filtered.Add (new TrailingWhitespaceFilter ()); // Note: see rfc2015 or rfc3156, section 5.1 filtered.Add (new Unix2DosFilter ()); entity.WriteTo (filtered); filtered.Flush (); } memory.Position = 0; // Note: we need to parse the modified entity structure to preserve any modifications var parser = new MimeParser (memory, MimeFormat.Entity); var parsed = parser.ParseEntity (); memory.Position = 0; // sign the cleartext content var micalg = ctx.GetDigestAlgorithmName (signer.DigestAlgorithm); var signature = ctx.Sign (signer, memory); var signed = new MultipartSigned (); // set the protocol and micalg Content-Type parameters signed.ContentType.Parameters["protocol"] = ctx.SignatureProtocol; signed.ContentType.Parameters["micalg"] = micalg; // add the modified/parsed entity as our first part signed.Add (parsed); // add the detached signature as the second part signed.Add (signature); return signed; } }