Beispiel #1
0
 /*
  * returns true if email can be encrypted
  */
 public static string CanEncrypt(Node emails)
 {
     if (emails.Count == 0)
     {
         return("there are no recipients");
     }
     try
     {
         List <MailboxAddress> list = new List <MailboxAddress>();
         foreach (Node idx in emails)
         {
             list.Add(new MailboxAddress("", idx.Get <string>()));
         }
         TextPart entity = new TextPart("text");
         using (WindowsSecureMimeContext ctx = new WindowsSecureMimeContext(sys.StoreLocation.CurrentUser))
         {
             ApplicationPkcs7Mime.Encrypt(ctx, list, entity);
         }
         return(null);
     }
     catch (Exception err)
     {
         return(err.Message);
     }
 }
Beispiel #2
0
        public virtual void TestSecureMimeEncryption()
        {
            var certificate = new X509Certificate2(Path.Combine("..", "..", "TestData", "smime", "smime.p12"), "no.secret");
            var body        = new TextPart("plain")
            {
                Text = "This is some cleartext that we'll end up encrypting..."
            };
            var recipients = new CmsRecipientCollection();

            recipients.Add(new CmsRecipient(certificate, SubjectIdentifierType.SubjectKeyIdentifier));

            using (var ctx = CreateContext()) {
                var encrypted = ApplicationPkcs7Mime.Encrypt(ctx, recipients, body);

                Assert.AreEqual(SecureMimeType.EnvelopedData, encrypted.SecureMimeType, "S/MIME type did not match.");

                using (var stream = new MemoryStream()) {
                    ctx.DecryptTo(encrypted.ContentObject.Open(), stream);
                    stream.Position = 0;

                    var decrypted = MimeEntity.Load(stream);

                    Assert.IsInstanceOf <TextPart> (decrypted, "Decrypted part is not the expected type.");
                    Assert.AreEqual(body.Text, ((TextPart)decrypted).Text, "Decrypted content is not the same as the original.");
                }
            }
        }
Beispiel #3
0
        public async Task Encrypt_VS_Decrypt(string fileName)
        {
            var stream = await GetAssetStreamAsync(fileName);

            var context = new TestSecureContext(
                await GetFromPemFileAsync <X509Certificate>("pem.pem", "password"),
                EncryptionAlgorithm.TripleDes,
                await GetFromPemFileAsync <RsaPrivateCrtKeyParameters>("pem.pem", "password"));

            var encrypted = ApplicationPkcs7Mime.Encrypt(
                context,
                new List <MailboxAddress>
            {
                new MailboxAddress(string.Empty)
            },
                new MimePart
            {
                Content = new MimeContent(stream)
            });

            var decrypted = encrypted.Decrypt(context);

            Assert.IsInstanceOf <MimePart>(decrypted);
            FileAssert.AreEqual(stream, ((MimePart)decrypted).Content.Stream);
        }
         static void Main (string[] args)
 		{
 			//  Select a binary file
 			var dialog = new OpenFileDialog {
 				Filter = "All files (*.*)|*.*",
 				InitialDirectory = "./",
 				Title = "Select a text file"
 			};
 			var filename = (dialog.ShowDialog () == DialogResult.OK) ? dialog.FileName : null;
             var certificate2 = new X509Certificate2 ("c:/temp1/cert.pfx", "password");
             MimeEntity body;
 
 			using (var content = new MemoryStream (File.ReadAllBytes (filename)))
 			    var part = new MimePart (MimeTypes.GetMimeType (filename)) {
 				    ContentDisposition = new ContentDisposition (ContentDisposition.Attachment),
 				    ContentTransferEncoding = ContentEncoding.Binary,
 				    FileName = Path.GetFileName (filename),
 				    Content = new MimeContent (content)
 			    };
 
 			    var recipient = new CmsRecipient (certificate2) {
                     EncryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.TripleDes }
                 };
                 var recipients = new CmsRecipientCollection ();
 			    recipients.Add (recipient);
 
                 var signer = new CmsSigner (certificate2) {
 				    DigestAlgorithm = DigestAlgorithm.Sha256
 			    };
 
 			    using (var ctx = new TemporarySecureMimeContext ())
 				    body = ApplicationPkcs7Mime.SignAndEncrypt (ctx, signer, recipients, part);
 			}
Beispiel #5
0
 /*
  * tries to encrypt a MimeEntity
  */
 public static MimeEntity EncryptEntity(MimeEntity entity, IEnumerable <MailboxAddress> list)
 {
     using (WindowsSecureMimeContext ctx = new WindowsSecureMimeContext(sys.StoreLocation.CurrentUser))
     {
         return(ApplicationPkcs7Mime.Encrypt(ctx, list, entity));
     }
 }
Beispiel #6
0
 /*
  * tries to sign and encrypt a MimeEntity
  */
 public static MimeEntity SignAndEncryptEntity(MimeEntity entity, MailboxAddress signer, IEnumerable <MailboxAddress> list)
 {
     using (WindowsSecureMimeContext ctx = new WindowsSecureMimeContext(sys.StoreLocation.CurrentUser))
     {
         return(ApplicationPkcs7Mime.SignAndEncrypt(ctx, signer, DigestAlgorithm.Sha1, list, entity));
     }
 }
Beispiel #7
0
        public void Pkcs7Sign(MimeMessage message)
        {
            // digitally sign our message body using our custom S/MIME cryptography context
            using (var ctx = new MySecureMimeContext()) {
                // Note: this assumes that the Sender address has an S/MIME signing certificate
                // and private key with an X.509 Subject Email identifier that matches the
                // sender's email address.
                var sender = message.From.Mailboxes.FirstOrDefault();

                message.Body = ApplicationPkcs7Mime.Sign(ctx, sender, DigestAlgorithm.Sha1, message.Body);
            }
        }
Beispiel #8
0
        public void TestSecureMimeSignAndEncrypt()
        {
            var self       = new MailboxAddress("MimeKit UnitTests", "*****@*****.**");
            var recipients = new List <MailboxAddress> ();

            // encrypt to ourselves...
            recipients.Add(self);

            var cleartext = new TextPart("plain");

            cleartext.Text = "This is some cleartext that we'll end up encrypting...";

            ApplicationPkcs7Mime encrypted;

            using (var ctx = CreateContext()) {
                encrypted = ApplicationPkcs7Mime.SignAndEncrypt(ctx, self, DigestAlgorithm.Sha1, recipients, cleartext);

                Assert.AreEqual(SecureMimeType.EnvelopedData, encrypted.SecureMimeType, "S/MIME type did not match.");
            }

            using (var ctx = CreateContext()) {
                IList <IDigitalSignature> signatures;

                var decrypted = encrypted.Decrypt(ctx, out signatures);

                Assert.IsNull(signatures, "Did not expect to find any signatures from an encrypted message.");

                // The decrypted part should be a multipart/signed
                Assert.IsInstanceOfType(typeof(MultipartSigned), decrypted, "Expected the decrypted part to be a multipart/signed.");
                var signed = (MultipartSigned)decrypted;

                Assert.IsInstanceOfType(typeof(TextPart), signed[0], "Expected the first part of the multipart/signed to be a multipart.");
                Assert.IsInstanceOfType(typeof(ApplicationPkcs7Signature), signed[1], "Expected second part of the multipart/signed to be a pkcs7-signature.");

                var extracted = (TextPart)signed[0];
                Assert.AreEqual(cleartext.Text, extracted.Text, "The decrypted text part's text does not match the original.");

                signatures = signed.Verify(ctx);

                Assert.AreEqual(1, signatures.Count, "Verify returned an unexpected number of signatures.");
                foreach (var signature in signatures)
                {
                    try {
                        bool valid = signature.Verify();

                        Assert.IsTrue(valid, "Bad signature from {0}", signature.SignerCertificate.Email);
                    } catch (DigitalSignatureVerifyException ex) {
                        Assert.Fail("Failed to verify signature: {0}", ex);
                    }
                }
            }
        }
Beispiel #9
0
 public void Encrypt(MimeMessage message)
 {
     // encrypt our message body using our custom S/MIME cryptography context
     using (var ctx = new MySecureMimeContext()) {
         // Note: this assumes that each of the recipients has an S/MIME certificate
         // with an X.509 Subject Email identifier that matches their email address.
         //
         // If this is not the case, you can use SecureMailboxAddresses instead of
         // normal MailboxAddresses which would allow you to specify the fingerprint
         // of their certificates. You could also choose to use one of the Encrypt()
         // overloads that take a list of CmsRecipients, instead.
         message.Body = ApplicationPkcs7Mime.Encrypt(ctx, message.To.Mailboxes, message.Body);
     }
 }
Beispiel #10
0
        public void TestSecureMimeEncapsulatedSigning()
        {
            var self = new MailboxAddress("MimeKit UnitTests", "*****@*****.**");

            var cleartext = new TextPart("plain");

            cleartext.Text = "This is some text that we'll end up signing...";

            using (var ctx = CreateContext()) {
                var        signed = ApplicationPkcs7Mime.Sign(ctx, self, DigestAlgorithm.Sha1, cleartext);
                MimeEntity extracted;

                Assert.AreEqual(SecureMimeType.SignedData, signed.SecureMimeType, "S/MIME type did not match.");

                var signatures = signed.Verify(ctx, out extracted);

                Assert.IsInstanceOfType(typeof(TextPart), extracted, "Extracted part is not the expected type.");
                Assert.AreEqual(cleartext.Text, ((TextPart)extracted).Text, "Extracted content is not the same as the original.");

                Assert.AreEqual(1, signatures.Count, "Verify returned an unexpected number of signatures.");
                foreach (var signature in signatures)
                {
                    try {
                        bool valid = signature.Verify();

                        Assert.IsTrue(valid, "Bad signature from {0}", signature.SignerCertificate.Email);
                    } catch (DigitalSignatureVerifyException ex) {
                        Assert.Fail("Failed to verify signature: {0}", ex);
                    }

                    var algorithms = ((SecureMimeDigitalSignature)signature).EncryptionAlgorithms;
                    Assert.AreEqual(EncryptionAlgorithm.Camellia256, algorithms[0], "Expected Camellia-256 capability");
                    Assert.AreEqual(EncryptionAlgorithm.Aes256, algorithms[1], "Expected AES-256 capability");
                    Assert.AreEqual(EncryptionAlgorithm.Camellia192, algorithms[2], "Expected Camellia-192 capability");
                    Assert.AreEqual(EncryptionAlgorithm.Aes192, algorithms[3], "Expected AES-192 capability");
                    Assert.AreEqual(EncryptionAlgorithm.Camellia128, algorithms[4], "Expected Camellia-128 capability");
                    Assert.AreEqual(EncryptionAlgorithm.Aes128, algorithms[5], "Expected AES-128 capability");
                    Assert.AreEqual(EncryptionAlgorithm.Idea, algorithms[6], "Expected IDEA capability");
                    Assert.AreEqual(EncryptionAlgorithm.Cast5, algorithms[7], "Expected Cast5 capability");
                    Assert.AreEqual(EncryptionAlgorithm.TripleDes, algorithms[8], "Expected Triple-DES capability");
                    //Assert.AreEqual (EncryptionAlgorithm.RC2128, algorithms[9], "Expected RC2-128 capability");
                    //Assert.AreEqual (EncryptionAlgorithm.RC264, algorithms[10], "Expected RC2-64 capability");
                    //Assert.AreEqual (EncryptionAlgorithm.Des, algorithms[11], "Expected DES capability");
                    //Assert.AreEqual (EncryptionAlgorithm.RC240, algorithms[12], "Expected RC2-40 capability");
                }
            }
        }
Beispiel #11
0
        public void TestSecureMimeCompression()
        {
            var original = new TextPart("plain");

            original.Text = "This is some text that we'll end up compressing...";

            using (var ctx = CreateContext()) {
                var compressed = ApplicationPkcs7Mime.Compress(ctx, original);

                Assert.AreEqual(SecureMimeType.CompressedData, compressed.SecureMimeType, "S/MIME type did not match.");

                var decompressed = compressed.Decompress(ctx);

                Assert.IsInstanceOfType(typeof(TextPart), decompressed, "Decompressed part is not the expected type.");
                Assert.AreEqual(original.Text, ((TextPart)decompressed).Text, "Decompressed content is not the same as the original.");
            }
        }
Beispiel #12
0
        public static bool SendEncryptMessage(MimeMessage message)
        {
            bool isSuccess = false;

            try
            {
                using (var ctx = new SecureMimeContext())
                {
                    message.Body = ApplicationPkcs7Mime.Encrypt(ctx, message.To.Mailboxes, message.Body);
                    SendEmailByMailServer(message);
                    isSuccess = true;
                }
                return(isSuccess);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.InnerException.ToString());
                return(isSuccess);
            }
        }
Beispiel #13
0
        public void TestSecureMimeEncryption()
        {
            var self       = new MailboxAddress("MimeKit UnitTests", "*****@*****.**");
            var recipients = new List <MailboxAddress> ();

            // encrypt to ourselves...
            recipients.Add(self);

            var cleartext = new TextPart("plain");

            cleartext.Text = "This is some cleartext that we'll end up encrypting...";

            using (var ctx = CreateContext()) {
                var encrypted = ApplicationPkcs7Mime.Encrypt(ctx, recipients, cleartext);

                Assert.AreEqual(SecureMimeType.EnvelopedData, encrypted.SecureMimeType, "S/MIME type did not match.");

                var decrypted = encrypted.Decrypt(ctx);

                Assert.IsInstanceOfType(typeof(TextPart), decrypted, "Decrypted part is not the expected type.");
                Assert.AreEqual(cleartext.Text, ((TextPart)decrypted).Text, "Decrypted content is not the same as the original.");
            }
        }
Beispiel #14
0
 /// <summary>
 /// Visit the application/pkcs7-mime MIME entity.
 /// </summary>
 /// <remarks>
 /// Visits the application/pkcs7-mime MIME entity.
 /// </remarks>
 /// <param name="entity">The application/pkcs7-mime MIME entity.</param>
 protected internal virtual void VisitApplicationPkcs7Mime(ApplicationPkcs7Mime entity)
 {
     VisitMimePart(entity);
 }
Beispiel #15
0
        public void TestArgumentExceptions()
        {
            var path   = Path.Combine("..", "..", "TestData", "smime", "smime.p12");
            var entity = new TextPart("plain")
            {
                Text = "This is some text..."
            };
            var mailbox    = new MailboxAddress("MimeKit UnitTests", "*****@*****.**");
            var recipients = new CmsRecipientCollection();
            var signer     = new CmsSigner(path, "no.secret");
            var mailboxes  = new [] { mailbox };

            recipients.Add(new CmsRecipient(signer.Certificate));

            using (var ctx = new TemporarySecureMimeContext()) {
                using (var file = File.OpenRead(path))
                    ctx.Import(file, "no.secret");

                // Compress
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Compress(null, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Compress(ctx, null));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Compress(null));

                // Encrypt
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(null, mailboxes, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(null, recipients, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(ctx, (IEnumerable <MailboxAddress>)null, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(ctx, (CmsRecipientCollection)null, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(ctx, recipients, null));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(ctx, mailboxes, null));

                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt((IEnumerable <MailboxAddress>)null, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt((CmsRecipientCollection)null, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(recipients, null));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Encrypt(mailboxes, null));

                // Sign
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(null, mailbox, DigestAlgorithm.Sha1, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(null, signer, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(ctx, (MailboxAddress)null, DigestAlgorithm.Sha1, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(ctx, (CmsSigner)null, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(ctx, mailbox, DigestAlgorithm.Sha1, null));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(ctx, signer, null));

                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign((MailboxAddress)null, DigestAlgorithm.Sha1, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign((CmsSigner)null, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(mailbox, DigestAlgorithm.Sha1, null));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.Sign(signer, null));

                // SignAndEncrypt
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(null, mailbox, DigestAlgorithm.Sha1, mailboxes, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(ctx, null, DigestAlgorithm.Sha1, mailboxes, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(ctx, mailbox, DigestAlgorithm.Sha1, null, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(ctx, mailbox, DigestAlgorithm.Sha1, mailboxes, null));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(null, DigestAlgorithm.Sha1, mailboxes, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(mailbox, DigestAlgorithm.Sha1, null, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(mailbox, DigestAlgorithm.Sha1, mailboxes, null));

                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(null, signer, recipients, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(ctx, null, recipients, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(ctx, signer, null, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(ctx, signer, recipients, null));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(null, recipients, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(signer, null, entity));
                Assert.Throws <ArgumentNullException> (() => ApplicationPkcs7Mime.SignAndEncrypt(signer, recipients, null));

                var compressed = ApplicationPkcs7Mime.Compress(ctx, entity);
                var encrypted  = ApplicationPkcs7Mime.Encrypt(recipients, entity);
                var signed     = ApplicationPkcs7Mime.Sign(signer, entity);

                // Decompress
                Assert.Throws <ArgumentNullException> (() => compressed.Decompress(null));
                Assert.Throws <InvalidOperationException> (() => encrypted.Decompress(ctx));
                Assert.Throws <InvalidOperationException> (() => signed.Decompress(ctx));

                // Decrypt
                Assert.Throws <ArgumentNullException> (() => encrypted.Decrypt(null));
                Assert.Throws <InvalidOperationException> (() => compressed.Decrypt(ctx));
                Assert.Throws <InvalidOperationException> (() => signed.Decrypt(ctx));

                // Verify
                Assert.Throws <ArgumentNullException> (() => {
                    MimeEntity mime;

                    signed.Verify(null, out mime);
                });
                Assert.Throws <InvalidOperationException> (() => {
                    MimeEntity mime;

                    compressed.Verify(ctx, out mime);
                });
                Assert.Throws <InvalidOperationException> (() => {
                    MimeEntity mime;

                    encrypted.Verify(ctx, out mime);
                });
            }
        }
Beispiel #16
0
 protected internal override void VisitApplicationPkcs7Mime(ApplicationPkcs7Mime entity)
 {
     ApplicationPkcs7Mime++;
     base.VisitApplicationPkcs7Mime(entity);
 }
Beispiel #17
0
 /*
  * extracts body parts from message and put into node
  */
 private static void ExtractBody(
     IEnumerable <MimeEntity> entities,
     Node node,
     bool skipSignature,
     MimeMessage msg,
     string basePath,
     string attachmentDirectory,
     string linkedAttachmentDirectory)
 {
     foreach (MimeEntity idxBody in entities)
     {
         if (idxBody is TextPart)
         {
             TextPart tp = idxBody as TextPart;
             if (idxBody.ContentType.MediaType == "text")
             {
                 if (idxBody.ContentType.MediaSubtype == "plain")
                 {
                     node["body"]["plain"].Value = tp.Text;
                 }
                 else if (idxBody.ContentType.MediaSubtype == "html")
                 {
                     node["body"]["html"].Value = CleanHtml(tp.Text);
                 }
             }
         }
         else if (idxBody is ApplicationPkcs7Mime)
         {
             ApplicationPkcs7Mime pkcs7 = idxBody as ApplicationPkcs7Mime;
             if (pkcs7.SecureMimeType == SecureMimeType.EnvelopedData)
             {
                 try
                 {
                     MimeEntity entity = pkcs7.Decrypt();
                     ExtractBody(new MimeEntity[] { entity }, node, false, msg, basePath, attachmentDirectory, linkedAttachmentDirectory);
                     node["encrypted"].Value = true;
                 }
                 catch (Exception err)
                 {
                     // couldn't decrypt
                     node["body"]["plain"].Value = "couldn't decrypt message, exceptions was; '" + err.Message + "'";
                     node["encrypted"].Value     = true;
                 }
             }
         }
         else if (!skipSignature && idxBody is MultipartSigned)
         {
             MultipartSigned signed = idxBody as MultipartSigned;
             bool            valid  = false;
             foreach (IDigitalSignature signature in signed.Verify())
             {
                 valid = signature.Verify();
                 if (!valid)
                 {
                     break;
                 }
             }
             node["signed"].Value = valid;
             ExtractBody(new MimeEntity[] { signed }, node, true, msg, basePath, attachmentDirectory, linkedAttachmentDirectory);
         }
         else if (idxBody is Multipart)
         {
             Multipart mp = idxBody as Multipart;
             ExtractBody(mp, node, false, msg, basePath, attachmentDirectory, linkedAttachmentDirectory);
         }
         else if (idxBody is MimePart)
         {
             // this is an attachment
             ExtractAttachments(idxBody as MimePart, msg, node, basePath, attachmentDirectory, linkedAttachmentDirectory);
         }
     }
 }
Beispiel #18
0
        public void TestSecureMimeSignAndEncrypt()
        {
            var self       = new MailboxAddress("MimeKit UnitTests", "*****@*****.**");
            var recipients = new List <MailboxAddress> ();

            // encrypt to ourselves...
            recipients.Add(self);

            var cleartext = new TextPart("plain");

            cleartext.Text = "This is some cleartext that we'll end up encrypting...";

            ApplicationPkcs7Mime encrypted;

            using (var ctx = CreateContext()) {
                encrypted = ApplicationPkcs7Mime.SignAndEncrypt(ctx, self, DigestAlgorithm.Sha1, recipients, cleartext);

                Assert.AreEqual(SecureMimeType.EnvelopedData, encrypted.SecureMimeType, "S/MIME type did not match.");
            }

            using (var ctx = CreateContext()) {
                var decrypted = encrypted.Decrypt(ctx);

                // The decrypted part should be a multipart/signed
                Assert.IsInstanceOfType(typeof(MultipartSigned), decrypted, "Expected the decrypted part to be a multipart/signed.");
                var signed = (MultipartSigned)decrypted;

                Assert.IsInstanceOfType(typeof(TextPart), signed[0], "Expected the first part of the multipart/signed to be a multipart.");
                Assert.IsInstanceOfType(typeof(ApplicationPkcs7Signature), signed[1], "Expected second part of the multipart/signed to be a pkcs7-signature.");

                var extracted = (TextPart)signed[0];
                Assert.AreEqual(cleartext.Text, extracted.Text, "The decrypted text part's text does not match the original.");

                var signatures = signed.Verify(ctx);

                Assert.AreEqual(1, signatures.Count, "Verify returned an unexpected number of signatures.");
                foreach (var signature in signatures)
                {
                    try {
                        bool valid = signature.Verify();

                        Assert.IsTrue(valid, "Bad signature from {0}", signature.SignerCertificate.Email);
                    } catch (DigitalSignatureVerifyException ex) {
                        Assert.Fail("Failed to verify signature: {0}", ex);
                    }

                    var algorithms = ((SecureMimeDigitalSignature)signature).EncryptionAlgorithms;
                    Assert.AreEqual(EncryptionAlgorithm.Camellia256, algorithms[0], "Expected Camellia-256 capability");
                    Assert.AreEqual(EncryptionAlgorithm.Aes256, algorithms[1], "Expected AES-256 capability");
                    Assert.AreEqual(EncryptionAlgorithm.Camellia192, algorithms[2], "Expected Camellia-192 capability");
                    Assert.AreEqual(EncryptionAlgorithm.Aes192, algorithms[3], "Expected AES-192 capability");
                    Assert.AreEqual(EncryptionAlgorithm.Camellia128, algorithms[4], "Expected Camellia-128 capability");
                    Assert.AreEqual(EncryptionAlgorithm.Aes128, algorithms[5], "Expected AES-128 capability");
                    Assert.AreEqual(EncryptionAlgorithm.Idea, algorithms[6], "Expected IDEA capability");
                    Assert.AreEqual(EncryptionAlgorithm.Cast5, algorithms[7], "Expected Cast5 capability");
                    Assert.AreEqual(EncryptionAlgorithm.TripleDes, algorithms[8], "Expected Triple-DES capability");
                    //Assert.AreEqual (EncryptionAlgorithm.RC2128, algorithms[9], "Expected RC2-128 capability");
                    //Assert.AreEqual (EncryptionAlgorithm.RC264, algorithms[10], "Expected RC2-64 capability");
                    //Assert.AreEqual (EncryptionAlgorithm.Des, algorithms[11], "Expected DES capability");
                    //Assert.AreEqual (EncryptionAlgorithm.RC240, algorithms[12], "Expected RC2-40 capability");
                }
            }
        }