Beispiel #1
0
        /// <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));
            }
        }
Beispiel #2
0
        /// <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));
            }
        }
Beispiel #3
0
        /// <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));
            }
        }
Beispiel #4
0
        /// <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));
            }
        }
Beispiel #5
0
        /// <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));
                }
            }
        }
Beispiel #6
0
        /// <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));
                }
            }
        }
Beispiel #7
0
        /// <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));
            }
        }