예제 #1
0
        /// <summary>
        /// Creates a new <see cref="MimeKit.Cryptography.MultipartSigned"/> instance with the entity as the content.
        /// </summary>
        /// <returns>A new <see cref="MimeKit.Cryptography.MultipartSigned"/> instance.</returns>
        /// <param name="ctx">The cryptography 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 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="CertificateNotFoundException">
        /// A signing certificate could not be found for <paramref name="signer"/>.
        /// </exception>
        /// <exception cref="System.Security.Cryptography.CryptographicException">
        /// An error occurred while signing.
        /// </exception>
        public static MultipartSigned Create(CryptographyContext ctx, MailboxAddress signer, DigestAlgorithm digestAlgo, MimeEntity entity)
        {
            if (signer == null)
            {
                throw new ArgumentNullException("signer");
            }

            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }

            PrepareEntityForSigning(entity);

            using (var memory = new MemoryStream()) {
                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 signature = ctx.Sign(signer, digestAlgo, memory);
                var micalg    = ctx.GetMicAlgorithmName(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(parsed);

                // add the detached signature as the second part
                signed.Add(signature);

                return(signed);
            }
        }
예제 #2
0
        /// <summary>
        /// Creates a new <see cref="MimeKit.Cryptography.MultipartSigned"/> instance with the entity as the content.
        /// </summary>
        /// <returns>A new <see cref="MimeKit.Cryptography.MultipartSigned"/> instance.</returns>
        /// <param name="ctx">The cryptography 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 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="System.ArgumentOutOfRangeException">
        /// The <paramref name="digestAlgo"/> was out of range.
        /// </exception>
        /// <exception cref="System.NotSupportedException">
        /// The <paramref name="digestAlgo"/> is not supported.
        /// </exception>
        /// <exception cref="CertificateNotFoundException">
        /// A signing certificate could not be found for <paramref name="signer"/>.
        /// </exception>
        /// <exception cref="PrivateKeyNotFoundException">
        /// The private key 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 MultipartSigned Create(CryptographyContext ctx, MailboxAddress signer, DigestAlgorithm digestAlgo, MimeEntity entity)
        {
            if (signer == null)
                throw new ArgumentNullException ("signer");

            if (entity == null)
                throw new ArgumentNullException ("entity");

            PrepareEntityForSigning (entity);

            using (var memory = new MemoryStream ()) {
                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 signature = ctx.Sign (signer, digestAlgo, memory);
                var micalg = ctx.GetMicAlgorithmName (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 (parsed);

                // add the detached signature as the second part
                signed.Add (signature);

                return signed;
            }
        }