A signed multipart, as used by both S/MIME and PGP/MIME protocols.
The first child of a multipart/signed is the content while the second child is the detached signature data. Any other children are not defined and could be anything.
Inheritance: Multipart
        /// <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);
            }
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        /// <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)));
        }
Exemple #6
0
        /// <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)));
        }
Exemple #7
0
		/// <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);
		}
Exemple #8
0
		/// <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;
			}
		}