/// <summary> /// Cryptographically signs the specified entity. /// </summary> /// <remarks> /// <para>Signs the entity using the supplied signer, digest algorithm and <see cref="SecureMimeContext"/>.</para> /// <para>For better interoperability with other mail clients, you should use /// <see cref="MultipartSigned.Create(SecureMimeContext, CmsSigner, MimeEntity)"/> /// instead as the multipart/signed format is supported among a much larger /// subset of mail client software.</para> /// </remarks> /// <returns>The signed entity.</returns> /// <param name="ctx">The S/MIME context to use for signing.</param> /// <param name="signer">The signer.</param> /// <param name="digestAlgo">The digest algorithm to use for signing.</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="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="CertificateNotFoundException"> /// A signing certificate could not be found for <paramref name="signer"/>. /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static ApplicationPkcs7Mime Sign(SecureMimeContext ctx, MailboxAddress signer, DigestAlgorithm digestAlgo, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (signer == null) { throw new ArgumentNullException("signer"); } if (entity == null) { throw new ArgumentNullException("entity"); } using (var memory = new MemoryBlockStream()) { var options = FormatOptions.CloneDefault(); options.NewLineFormat = NewLineFormat.Dos; entity.WriteTo(options, memory); memory.Position = 0; return(ctx.EncapsulatedSign(signer, digestAlgo, memory)); } }
/// <summary> /// Encrypts the specified entity. /// </summary> /// <remarks> /// Encrypts the entity to the specified recipients using the supplied <see cref="SecureMimeContext"/>. /// </remarks> /// <returns>The encrypted entity.</returns> /// <param name="ctx">The S/MIME context to use for encrypting.</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="recipients"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentException"> /// Valid certificates could not be found for one or more of the <paramref name="recipients"/>. /// </exception> /// <exception cref="CertificateNotFoundException"> /// A certificate could not be found for one or more of the <paramref name="recipients"/>. /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static ApplicationPkcs7Mime Encrypt(SecureMimeContext ctx, IEnumerable <MailboxAddress> recipients, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (recipients == null) { throw new ArgumentNullException("recipients"); } if (entity == null) { throw new ArgumentNullException("entity"); } using (var memory = new MemoryBlockStream()) { var options = FormatOptions.CloneDefault(); options.NewLineFormat = NewLineFormat.Dos; entity.WriteTo(options, memory); memory.Position = 0; return((ApplicationPkcs7Mime)ctx.Encrypt(recipients, memory)); } }
/// <summary> /// Cryptographically signs the specified entity. /// </summary> /// <remarks> /// <para>Signs the entity using the supplied signer and <see cref="SecureMimeContext"/>.</para> /// <para>For better interoperability with other mail clients, you should use /// <see cref="MultipartSigned.Create(SecureMimeContext, CmsSigner, MimeEntity)"/> /// instead as the multipart/signed format is supported among a much larger /// subset of mail client software.</para> /// </remarks> /// <returns>The signed entity.</returns> /// <param name="ctx">The S/MIME context to use for signing.</param> /// <param name="signer">The signer.</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="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 Sign(SecureMimeContext ctx, CmsSigner signer, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } if (signer == null) { throw new ArgumentNullException(nameof(signer)); } if (entity == null) { throw new ArgumentNullException(nameof(entity)); } using (var memory = new MemoryBlockStream()) { var options = FormatOptions.CloneDefault(); options.NewLineFormat = NewLineFormat.Dos; entity.WriteTo(options, memory); memory.Position = 0; return(ctx.EncapsulatedSign(signer, memory)); } }
/// <summary> /// Encrypts the specified entity. /// </summary> /// <remarks> /// Encrypts the entity to the specified recipients using the supplied <see cref="SecureMimeContext"/>. /// </remarks> /// <returns>The encrypted entity.</returns> /// <param name="ctx">The S/MIME context to use for encrypting.</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="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 Encrypt(SecureMimeContext ctx, CmsRecipientCollection recipients, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } if (recipients == null) { throw new ArgumentNullException(nameof(recipients)); } if (entity == null) { throw new ArgumentNullException(nameof(entity)); } using (var memory = new MemoryBlockStream()) { var options = FormatOptions.CloneDefault(); options.NewLineFormat = NewLineFormat.Dos; entity.WriteTo(options, memory); memory.Position = 0; return(ctx.Encrypt(recipients, memory)); } }
/// <summary> /// Verify the multipart/signed part. /// </summary> /// <remarks> /// Verifies the multipart/signed part using the supplied cryptography context. /// </remarks> /// <returns>A signer info collection.</returns> /// <param name="ctx">The cryptography context to use for verifying the signature.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="ctx"/> is <c>null</c>. /// </exception> /// <exception cref="System.FormatException"> /// The multipart is malformed in some way. /// </exception> /// <exception cref="System.NotSupportedException"> /// <paramref name="ctx"/> does not support verifying the signature part. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was cancelled via the cancellation token. /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public async Task <DigitalSignatureCollection> VerifyAsync(CryptographyContext ctx, CancellationToken cancellationToken = default(CancellationToken)) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } var protocol = ContentType.Parameters["protocol"]?.Trim(); if (string.IsNullOrEmpty(protocol)) { throw new FormatException("The multipart/signed part did not specify a protocol."); } if (!ctx.Supports(protocol)) { throw new NotSupportedException("The specified cryptography context does not support the signature protocol."); } if (Count < 2) { throw new FormatException("The multipart/signed part did not contain the expected children."); } var signature = this[1] as MimePart; if (signature == null || signature.Content == null) { throw new FormatException("The signature part could not be found."); } var ctype = signature.ContentType; var value = string.Format("{0}/{1}", ctype.MediaType, ctype.MediaSubtype); if (!ctx.Supports(value)) { throw new NotSupportedException(string.Format("The specified cryptography context does not support '{0}'.", value)); } using (var signatureData = new MemoryBlockStream()) { await signature.Content.DecodeToAsync(signatureData, cancellationToken).ConfigureAwait(false); signatureData.Position = 0; using (var cleartext = new MemoryBlockStream()) { // Note: see rfc2015 or rfc3156, section 5.1 var options = FormatOptions.CloneDefault(); options.NewLineFormat = NewLineFormat.Dos; options.VerifyingSignature = true; await this[0].WriteToAsync(options, cleartext, cancellationToken); cleartext.Position = 0; return(await ctx.VerifyAsync(cleartext, signatureData, cancellationToken).ConfigureAwait(false)); } } }
/// <summary> /// Verifies the multipart/signed part. /// </summary> /// <remarks> /// Verifies the multipart/signed part using the supplied cryptography context. /// </remarks> /// <returns>A signer info collection.</returns> /// <param name="ctx">The cryptography context to use for verifying the signature.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="ctx"/> is <c>null</c>. /// </exception> /// <exception cref="System.FormatException"> /// The multipart is malformed in some way. /// </exception> /// <exception cref="System.NotSupportedException"> /// <paramref name="ctx"/> does not support verifying the signature part. /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public DigitalSignatureCollection Verify(CryptographyContext ctx) { if (ctx == null) { throw new ArgumentNullException("ctx"); } var protocol = ContentType.Parameters["protocol"]; if (string.IsNullOrEmpty(protocol)) { throw new FormatException("The multipart/signed part did not specify a protocol."); } if (!ctx.Supports(protocol.Trim())) { throw new NotSupportedException("The specified cryptography context does not support the signature protocol."); } if (Count < 2) { throw new FormatException("The multipart/signed part did not contain the expected children."); } var signature = this[1] as MimePart; if (signature == null || signature.ContentObject == null) { throw new FormatException("The signature part could not be found."); } var ctype = signature.ContentType; var value = string.Format("{0}/{1}", ctype.MediaType, ctype.MediaSubtype); if (!ctx.Supports(value)) { throw new NotSupportedException(string.Format("The specified cryptography context does not support '{0}'.", value)); } using (var signatureData = new MemoryBlockStream()) { signature.ContentObject.DecodeTo(signatureData); signatureData.Position = 0; using (var cleartext = new MemoryBlockStream()) { // Note: see rfc2015 or rfc3156, section 5.1 var options = FormatOptions.CloneDefault(); options.NewLineFormat = NewLineFormat.Dos; this[0].WriteTo(options, cleartext); cleartext.Position = 0; return(ctx.Verify(cleartext, signatureData)); } } }
/// <summary> /// Compresses the specified entity. /// </summary> /// <remarks> /// <para>Compresses the specified entity using the specified <see cref="SecureMimeContext"/>.</para> /// <para>It should be noted that this feature is not supported by most mail clients, /// even among those that support S/MIME.</para> /// </remarks> /// <returns>The compressed entity.</returns> /// <param name="ctx">The S/MIME context to use for compressing.</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="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 Compress(SecureMimeContext ctx, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (entity == null) { throw new ArgumentNullException("entity"); } using (var memory = new MemoryBlockStream()) { var options = FormatOptions.CloneDefault(); options.NewLineFormat = NewLineFormat.Dos; entity.WriteTo(options, memory); memory.Position = 0; return(ctx.Compress(memory)); } }