Esempio n. 1
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.");
                }
            }
        }
        public static void CopyExceptions()
        {
            CmsRecipient a0 = s_cr0;
            CmsRecipient a1 = s_cr1;
            CmsRecipient a2 = s_cr2;

            CmsRecipientCollection c = new CmsRecipientCollection();

            c.Add(a0);
            c.Add(a1);
            c.Add(a2);

            CmsRecipient[] a = new CmsRecipient[3];
            Assert.Throws <ArgumentNullException>(() => c.CopyTo(null, 0));
            Assert.Throws <ArgumentOutOfRangeException>(() => c.CopyTo(a, -1));
            Assert.Throws <ArgumentOutOfRangeException>(() => c.CopyTo(a, 3));
            AssertExtensions.Throws <ArgumentException>(null, () => c.CopyTo(a, 1));

            ICollection ic = c;

            Assert.Throws <ArgumentNullException>(() => ic.CopyTo(null, 0));
            Assert.Throws <ArgumentOutOfRangeException>(() => ic.CopyTo(a, -1));
            Assert.Throws <ArgumentOutOfRangeException>(() => ic.CopyTo(a, 3));
            AssertExtensions.Throws <ArgumentException>(null, () => ic.CopyTo(a, 1));
            AssertExtensions.Throws <ArgumentException>(null, () => ic.CopyTo(new CmsRecipient[2, 2], 1));
            Assert.Throws <InvalidCastException>(() => ic.CopyTo(new int[10], 1));

            if (PlatformDetection.IsNonZeroLowerBoundArraySupported)
            {
                // Array has non-zero lower bound
                Array array = Array.CreateInstance(typeof(object), new int[] { 10 }, new int[] { 10 });
                Assert.Throws <IndexOutOfRangeException>(() => ic.CopyTo(array, 0));
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Encrypt data for the specified set of certificates.
        /// Adapted from http://msdn.microsoft.com/en-us/library/bb924547.aspx
        /// </summary>
        /// <param name="msg">Data to encrypt</param>
        /// <param name="recipientCerts">Certificates to encrypt for</param>
        /// <returns>Encrypted blob</returns>
        static public byte[] EncryptMsg(
            Byte[] msg,
            X509Certificate2Collection recipientCerts)
        {
            //  Place the message in a ContentInfo object.
            //  This is required to build an EnvelopedCms object.
            ContentInfo contentInfo = new ContentInfo(msg);

            //  Instantiate an EnvelopedCms object with the ContentInfo
            //  above.
            //  Has default SubjectIdentifierType IssuerAndSerialNumber.
            //  Has default ContentEncryptionAlgorithm property value
            //  RSA_DES_EDE3_CBC.
            EnvelopedCms envelopedCms = new EnvelopedCms(contentInfo);

            //  Formulate a CmsRecipient object collection that
            //  represent information about the recipients
            //  to encrypt the message for.
            CmsRecipientCollection recips = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, recipientCerts);

            //  Encrypt the message for the recipient.
            envelopedCms.Encrypt(recips);

            //  The encoded EnvelopedCms message contains the message
            //  ciphertext and the information about each recipient
            //  that the message was enveloped for.
            return(envelopedCms.Encode());
        }
        public static void Oneary()
        {
            CmsRecipient           a0 = s_cr0;
            CmsRecipientCollection c  = new CmsRecipientCollection(a0);

            AssertEquals(c, new CmsRecipient[] { a0 });
        }
        public static void RemoveNonExistent()
        {
            CmsRecipientCollection c  = new CmsRecipientCollection();
            CmsRecipient           a0 = s_cr0;

            c.Remove(a0);  // You can "remove" items that aren't in the collection - this is defined as a NOP.
        }
Esempio n. 6
0
        public static void MultipleRecipientIdentifiers_RoundTrip()
        {
            ContentInfo            contentInfo = new ContentInfo(new byte[] { 1, 2, 3 });
            EnvelopedCms           ecms        = new EnvelopedCms(contentInfo);
            CmsRecipientCollection recipients  = new CmsRecipientCollection();

            using (X509Certificate2 issuerSerialCert = Certificates.RSAKeyTransfer1.GetCertificate())
                using (X509Certificate2 explicitSkiCert = Certificates.RSAKeyTransfer_ExplicitSki.GetCertificate())
                {
                    // CmsRecipients have different identifiers to test multiple identifier encryption.
                    recipients.Add(new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerialCert));
                    recipients.Add(new CmsRecipient(SubjectIdentifierType.SubjectKeyIdentifier, explicitSkiCert));
                    ecms.Encrypt(recipients);
                }

            byte[] encodedMessage = ecms.Encode();

            ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);

            // Try decoding it, doesn't really matter with which cert you want to do it as it's not what this
            // test aims for.

            using (X509Certificate2 privateCert = Certificates.RSAKeyTransfer_ExplicitSki.TryGetCertificateWithPrivateKey())
            {
                if (privateCert == null)
                {
                    return; // CertLoader can't load the private certificate.
                }
                ecms.Decrypt(new X509Certificate2Collection(privateCert));
            }
            Assert.Equal(contentInfo.ContentType.Value, ecms.ContentInfo.ContentType.Value);
            Assert.Equal <byte>(contentInfo.Content, ecms.ContentInfo.Content);
        }
Esempio n. 7
0
        public sealed override byte[] Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes)
        {
            using (SafeCryptMsgHandle hCryptMsg = EncodeHelpers.CreateCryptMsgHandleToEncode(recipients, contentInfo.ContentType, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes))
            {
                byte[] encodedContent;
                if (contentInfo.ContentType.Value.Equals(Oids.Pkcs7Data, StringComparison.OrdinalIgnoreCase))
                {
                    unsafe
                    {
                        byte[] content = contentInfo.Content;
                        fixed(byte *pContent = content)
                        {
                            DATA_BLOB blob = new DATA_BLOB((IntPtr)pContent, (uint)(content.Length));

                            encodedContent = Interop.Crypt32.CryptEncodeObjectToByteArray(CryptDecodeObjectStructType.X509_OCTET_STRING, &blob);
                        }
                    }
                }
                else
                {
                    encodedContent = contentInfo.Content;
                }

                if (encodedContent.Length > 0)
                {
                    if (!Interop.Crypt32.CryptMsgUpdate(hCryptMsg, encodedContent, encodedContent.Length, fFinal: true))
                    {
                        throw Marshal.GetLastWin32Error().ToCryptographicException();
                    }
                }

                byte[] encodedMessage = hCryptMsg.GetMsgParamAsByteArray(CryptMsgParamType.CMSG_CONTENT_PARAM);
                return(encodedMessage);
            }
        }
        public static void CopyExceptions()
        {
            CmsRecipient a0 = s_cr0;
            CmsRecipient a1 = s_cr1;
            CmsRecipient a2 = s_cr2;

            CmsRecipientCollection c = new CmsRecipientCollection();

            c.Add(a0);
            c.Add(a1);
            c.Add(a2);

            CmsRecipient[] a = new CmsRecipient[3];
            Assert.Throws <ArgumentNullException>(() => c.CopyTo(null, 0));
            Assert.Throws <ArgumentOutOfRangeException>(() => c.CopyTo(a, -1));
            Assert.Throws <ArgumentOutOfRangeException>(() => c.CopyTo(a, 3));
            Assert.Throws <ArgumentException>(() => c.CopyTo(a, 1));

            ICollection ic = c;

            Assert.Throws <ArgumentNullException>(() => ic.CopyTo(null, 0));
            Assert.Throws <ArgumentOutOfRangeException>(() => ic.CopyTo(a, -1));
            Assert.Throws <ArgumentOutOfRangeException>(() => ic.CopyTo(a, 3));
            Assert.Throws <ArgumentException>(() => ic.CopyTo(a, 1));
            Assert.Throws <ArgumentException>(() => ic.CopyTo(new CmsRecipient[2, 2], 1));
            Assert.Throws <InvalidCastException>(() => ic.CopyTo(new int[10], 1));
        }
        public void EnvelopedCmsRecipientCollectionNull()
        {
            EnvelopedCms           ep   = new EnvelopedCms();
            CmsRecipientCollection p7rc = null;             // do not confuse compiler

            ep.Encrypt(p7rc);
        }
         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);
 			}
Esempio n. 11
0
        public override unsafe byte[] Encrypt(
            CmsRecipientCollection recipients,
            ContentInfo contentInfo,
            AlgorithmIdentifier contentEncryptionAlgorithm,
            X509Certificate2Collection originatorCerts,
            CryptographicAttributeObjectCollection unprotectedAttributes)
        {
            byte[] encryptedContent = EncryptContent(
                contentInfo,
                contentEncryptionAlgorithm,
                out byte[] cek,
                out byte[] parameterBytes);

            // Pin the CEK to prevent it from getting copied during heap compaction.
            fixed(byte *pinnedCek = cek)
            {
                try
                {
                    return(Encrypt(
                               recipients,
                               contentInfo,
                               contentEncryptionAlgorithm,
                               originatorCerts,
                               unprotectedAttributes,
                               encryptedContent,
                               cek,
                               parameterBytes));
                }
                finally
                {
                    Array.Clear(cek, 0, cek.Length);
                }
            }
        }
Esempio n. 12
0
 public override byte[] Encrypt(
     CmsRecipientCollection recipients,
     ContentInfo contentInfo,
     AlgorithmIdentifier contentEncryptionAlgorithm,
     X509Certificate2Collection originatorCerts,
     CryptographicAttributeObjectCollection unprotectedAttributes)
 {
     throw new PlatformNotSupportedException(SR.PlatformNotSupported_CryptographyPkcs);
 }
Esempio n. 13
0
 public sealed unsafe override byte[] Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes)
 {
     using (SafeCryptMsgHandle hCryptMsg = EncodeHelpers.CreateCryptMsgHandleToEncode(recipients, contentInfo.ContentType, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes))
     {
         byte[] encodedContent;
         if (contentInfo.ContentType.Value !.Equals(Oids.Pkcs7Data, StringComparison.OrdinalIgnoreCase))
         {
             encodedContent = PkcsHelpers.EncodeOctetString(contentInfo.Content);
         }
Esempio n. 14
0
        /// <summary>
        /// Шифрует сообщение
        /// </summary>
        /// <param name="msg">Сообщение</param>
        /// <param name="recipientCerts">Сертификат</param>
        /// <returns>Результат шифровки</returns>
        public static byte[] EncryptMsg(Byte[] msg, X509Certificate2Collection recipientCerts)
        {
            ContentInfo            contentInfo  = new ContentInfo(msg);
            EnvelopedCms           envelopedCms = new EnvelopedCms(contentInfo);
            CmsRecipientCollection recips       = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, recipientCerts);

            envelopedCms.Encrypt(recips);
            return(envelopedCms.Encode());
        }
        public sealed unsafe override byte[] Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes)
        {
            using (SafeCryptMsgHandle hCryptMsg = EncodeHelpers.CreateCryptMsgHandleToEncode(recipients, contentInfo.ContentType, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes))
            {
                byte[] encodedContent;
                if (contentInfo.ContentType.Value.Equals(Oids.Pkcs7Data, StringComparison.OrdinalIgnoreCase))
                {
                    unsafe
                    {
                        byte[] content = contentInfo.Content;
                        fixed(byte *pContent = content)
                        {
                            DATA_BLOB blob = new DATA_BLOB((IntPtr)pContent, (uint)(content.Length));

                            encodedContent = Interop.Crypt32.CryptEncodeObjectToByteArray(CryptDecodeObjectStructType.X509_OCTET_STRING, &blob);
                        }
                    }
                }
                else
                {
                    encodedContent = contentInfo.Content;

                    if (encodedContent.Length > 0)
                    {
                        // Windows will throw if it encounters indefinite length encoding.
                        // Let's reencode if that is the case
                        ReencodeIfUsingIndefiniteLengthEncodingOnOuterStructure(ref encodedContent);
                    }
                }

                if (encodedContent.Length > 0)
                {
                    // Pin to avoid copy during heap compaction
                    fixed(byte *pinnedContent = encodedContent)
                    {
                        try
                        {
                            if (!Interop.Crypt32.CryptMsgUpdate(hCryptMsg, encodedContent, encodedContent.Length, fFinal: true))
                            {
                                throw Marshal.GetLastWin32Error().ToCryptographicException();
                            }
                        }
                        finally
                        {
                            if (!object.ReferenceEquals(encodedContent, contentInfo.Content))
                            {
                                Array.Clear(encodedContent, 0, encodedContent.Length);
                            }
                        }
                    }
                }

                byte[] encodedMessage = hCryptMsg.GetMsgParamAsByteArray(CryptMsgParamType.CMSG_CONTENT_PARAM);
                return(encodedMessage);
            }
        }
        public static void DecryptMultipleRecipients()
        {
            // Force Decrypt() to try multiple recipients. Ensure that a failure to find a matching cert in one doesn't cause it to quit early.

            CertLoader[] certLoaders = new CertLoader[]
            {
                Certificates.RSAKeyTransfer1,
                Certificates.RSAKeyTransfer2,
                Certificates.RSAKeyTransfer3,
            };

            byte[]                 content    = { 6, 3, 128, 33, 44 };
            EnvelopedCms           ecms       = new EnvelopedCms(new ContentInfo(content), new AlgorithmIdentifier(new Oid(Oids.Aes256)));
            CmsRecipientCollection recipients = new CmsRecipientCollection();

            foreach (CertLoader certLoader in certLoaders)
            {
                recipients.Add(new CmsRecipient(certLoader.GetCertificate()));
            }
            ecms.Encrypt(recipients);
            byte[] encodedMessage = ecms.Encode();

            ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);

            // How do we know that Decrypt() tries receipients in the order they appear in ecms.RecipientInfos? Because we wrote the implementation.
            // Not that some future implementation can't ever change it but it's the best guess we have.
            RecipientInfo me = ecms.RecipientInfos[2];

            CertLoader matchingCertLoader = null;

            for (int index = 0; index < recipients.Count; index++)
            {
                if (recipients[index].Certificate.Issuer == ((X509IssuerSerial)(me.RecipientIdentifier.Value)).IssuerName)
                {
                    matchingCertLoader = certLoaders[index];
                    break;
                }
            }
            Assert.NotNull(matchingCertLoader);

            using (X509Certificate2 cert = matchingCertLoader.TryGetCertificateWithPrivateKey())
            {
                if (cert == null)
                {
                    return; // Sorry - CertLoader is not configured to load certs with private keys - we've tested as much as we can.
                }
                X509Certificate2Collection extraStore = new X509Certificate2Collection();
                extraStore.Add(cert);
                ecms.Decrypt(extraStore);
            }

            ContentInfo contentInfo = ecms.ContentInfo;

            Assert.Equal <byte>(content, contentInfo.Content);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="message"></param>
        /// <param name="encryptionCertificates"></param>
        /// <returns></returns>
        internal static byte[] EncryptMessage(Byte[] message, X509Certificate2Collection encryptionCertificates)
        {
            EnvelopedCms envelopedCms = new EnvelopedCms(new ContentInfo(message));

            CmsRecipientCollection recipients = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, encryptionCertificates);

            envelopedCms.Encrypt(recipients);

            return(envelopedCms.Encode());
        }
Esempio n. 18
0
        /// <summary>
        ///     CMS encryption of a data
        /// </summary>
        /// <param name="data">Data to encrypt</param>
        /// <param name="encryptionCertificates">A list of certificates to encrypt the data with</param>
        /// <returns>The encrypted data</returns>
        internal static byte[] Encrypt(string data, X509Certificate2Collection encryptionCertificates)
        {
            byte[] messageBytes = Encoding.ASCII.GetBytes(data);
            var    envelopedCms = new EnvelopedCms(new ContentInfo(messageBytes));
            var    recipients   = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber,
                                                             encryptionCertificates);

            envelopedCms.Encrypt(recipients);
            return(envelopedCms.Encode());
        }
        public static void Twoary()
        {
            CmsRecipient           a0 = s_cr0;
            CmsRecipientCollection c  = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, new X509Certificate2Collection(a0.Certificate));

            Assert.Equal(1, c.Count);
            CmsRecipient actual = c[0];

            Assert.Equal(a0.RecipientIdentifierType, actual.RecipientIdentifierType);
            Assert.Equal(a0.Certificate, actual.Certificate);
        }
        public static void Twoary_Ski()
        {
            CmsRecipient           a0 = s_cr0;
            CmsRecipientCollection c  = new CmsRecipientCollection(SubjectIdentifierType.SubjectKeyIdentifier, new X509Certificate2Collection(a0.Certificate));

            Assert.Equal(1, c.Count);
            CmsRecipient actual = c[0];

            Assert.Equal(SubjectIdentifierType.SubjectKeyIdentifier, actual.RecipientIdentifierType);
            Assert.Equal(a0.Certificate, actual.Certificate);
        }
Esempio n. 21
0
        public void TestArgumentExceptions()
        {
            var stream = new MemoryStream();

            Assert.Throws <ArgumentNullException> (() => new ApplicationPkcs7Signature((MimeEntityConstructorArgs)null));
            Assert.Throws <ArgumentNullException> (() => new ApplicationPkcs7Mime((MimeEntityConstructorArgs)null));
            Assert.Throws <ArgumentNullException> (() => new ApplicationPkcs7Signature((Stream)null));

            // Accept
            Assert.Throws <ArgumentNullException> (() => new ApplicationPkcs7Mime(SecureMimeType.SignedData, stream).Accept(null));
            Assert.Throws <ArgumentNullException> (() => new ApplicationPkcs7Signature(stream).Accept(null));

            using (var ctx = CreateContext()) {
                var signer     = new CmsSigner(Path.Combine("..", "..", "TestData", "smime", "smime.p12"), "no.secret");
                var mailbox    = new MailboxAddress("Unit Tests", "*****@*****.**");
                var recipients = new CmsRecipientCollection();
                DigitalSignatureCollection signatures;
                MimeEntity entity;

                Assert.Throws <ArgumentNullException> (() => ctx.CanSign(null));
                Assert.Throws <ArgumentNullException> (() => ctx.CanEncrypt(null));
                Assert.Throws <ArgumentNullException> (() => ctx.Compress(null));
                Assert.Throws <ArgumentNullException> (() => ctx.Decompress(null));
                Assert.Throws <ArgumentNullException> (() => ctx.DecompressTo(null, stream));
                Assert.Throws <ArgumentNullException> (() => ctx.DecompressTo(stream, null));
                Assert.Throws <ArgumentNullException> (() => ctx.Decrypt(null));
                Assert.Throws <ArgumentNullException> (() => ctx.DecryptTo(null, stream));
                Assert.Throws <ArgumentNullException> (() => ctx.DecryptTo(stream, null));
                Assert.Throws <ArgumentNullException> (() => ctx.EncapsulatedSign(null, stream));
                Assert.Throws <ArgumentNullException> (() => ctx.EncapsulatedSign(signer, null));
                Assert.Throws <ArgumentNullException> (() => ctx.EncapsulatedSign(null, DigestAlgorithm.Sha256, stream));
                Assert.Throws <ArgumentNullException> (() => ctx.EncapsulatedSign(mailbox, DigestAlgorithm.Sha256, null));
                Assert.Throws <ArgumentNullException> (() => ctx.Encrypt((CmsRecipientCollection)null, stream));
                Assert.Throws <ArgumentNullException> (() => ctx.Encrypt(recipients, null));
                Assert.Throws <ArgumentNullException> (() => ctx.Encrypt((IEnumerable <MailboxAddress>)null, stream));
                Assert.Throws <ArgumentNullException> (() => ctx.Encrypt(new MailboxAddress[0], null));
                Assert.Throws <ArgumentNullException> (() => ctx.Export(null));
                Assert.Throws <ArgumentNullException> (() => ctx.GetDigestAlgorithm(null));
                Assert.Throws <ArgumentNullException> (() => ctx.Import((Stream)null));
                Assert.Throws <ArgumentNullException> (() => ctx.Import(stream, null));
                Assert.Throws <ArgumentNullException> (() => ctx.Import((X509Crl)null));
                Assert.Throws <ArgumentNullException> (() => ctx.Import((X509Certificate)null));
                Assert.Throws <ArgumentNullException> (() => ctx.Sign(null, stream));
                Assert.Throws <ArgumentNullException> (() => ctx.Sign(signer, null));
                Assert.Throws <ArgumentNullException> (() => ctx.Sign(null, DigestAlgorithm.Sha256, stream));
                Assert.Throws <ArgumentNullException> (() => ctx.Sign(mailbox, DigestAlgorithm.Sha256, null));
                Assert.Throws <ArgumentNullException> (() => ctx.Verify(null, stream));
                Assert.Throws <ArgumentNullException> (() => ctx.Verify(stream, null));
                Assert.Throws <ArgumentNullException> (() => ctx.Verify(null, out signatures));
                Assert.Throws <ArgumentNullException> (() => ctx.Verify(null, out entity));
            }
        }
Esempio n. 22
0
        public static CmsRecipientCollection DeepCopy(this CmsRecipientCollection recipients)
        {
            CmsRecipientCollection recipientsCopy = new CmsRecipientCollection();

            foreach (CmsRecipient recipient in recipients)
            {
                X509Certificate2 originalCert  = recipient.Certificate;
                X509Certificate2 certCopy      = new X509Certificate2(originalCert.Handle);
                CmsRecipient     recipientCopy = new CmsRecipient(recipient.RecipientIdentifierType, certCopy);
                recipientsCopy.Add(recipientCopy);
                GC.KeepAlive(originalCert);
            }
            return(recipientsCopy);
        }
Esempio n. 23
0
        public static void DecodeRecipients3_RoundTrip()
        {
            ContentInfo            contentInfo = new ContentInfo(new byte[] { 1, 2, 3 });
            EnvelopedCms           ecms        = new EnvelopedCms(contentInfo, KeyAgreeRecipientInfoTests.TripleDesAlgId);
            CmsRecipientCollection recipients  = new CmsRecipientCollection();

            foreach (X509Certificate2 cert in s_certs)
            {
                recipients.Add(new CmsRecipient(cert));
            }
            ecms.Encrypt(recipients);
            byte[] encodedMessage = ecms.Encode();

            VerifyRecipients3(encodedMessage);
        }
        public static void IndexOutOfBounds()
        {
            CmsRecipient a0 = s_cr0;
            CmsRecipient a1 = s_cr1;
            CmsRecipient a2 = s_cr2;

            CmsRecipientCollection c = new CmsRecipientCollection();

            c.Add(a0);
            c.Add(a1);
            c.Add(a2);

            object ignore = null;

            Assert.Throws <ArgumentOutOfRangeException>(() => ignore = c[-1]);
            Assert.Throws <ArgumentOutOfRangeException>(() => ignore = c[3]);
        }
        public static void Add()
        {
            CmsRecipient a0 = s_cr0;
            CmsRecipient a1 = s_cr1;
            CmsRecipient a2 = s_cr2;

            CmsRecipientCollection c = new CmsRecipientCollection();
            int index;

            index = c.Add(a0);
            Assert.Equal(0, index);
            index = c.Add(a1);
            Assert.Equal(1, index);
            index = c.Add(a2);
            Assert.Equal(2, index);

            AssertEquals(c, new CmsRecipient[] { a0, a1, a2 });
        }
Esempio n. 26
0
        /// <summary>
        /// Encrypts raw data and returns a <see cref="EnvelopedCms"/> instance with the encrypted data.
        /// </summary>
        /// <param name="content">The content to encrypt</param>
        /// <param name="encryptingCertificates">The collection of certificate used for encrytion</param>
        /// <returns>The encrypted <see cref="EnvelopedCms"/> instance.</returns>
        public EnvelopedCms CreateEncryptedEnvelope(byte[] content, X509Certificate2Collection encryptingCertificates)
        {
            if (content == null)
            {
                throw new EncryptionException(EncryptionError.NullContent);
            }
            if (encryptingCertificates == null || encryptingCertificates.Count == 0)
            {
                throw new EncryptionException(EncryptionError.NoCertificates);
            }

            CmsRecipientCollection recipients   = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, encryptingCertificates);
            EnvelopedCms           dataEnvelope = new EnvelopedCms(CreateDataContainer(content), ToAlgorithmID(m_encryptionAlgorithm));

            dataEnvelope.Encrypt(recipients);

            return(dataEnvelope);
        }
Esempio n. 27
0
        public void TestArgumentExceptions()
        {
            Assert.Throws <ArgumentNullException> (() => new CmsRecipient((X509Certificate2)null));
            Assert.Throws <ArgumentNullException> (() => new CmsRecipient((X509Certificate)null));
            Assert.Throws <ArgumentNullException> (() => new CmsRecipient((Stream)null));
            Assert.Throws <ArgumentNullException> (() => new CmsRecipient((string)null));

            var recipients = new CmsRecipientCollection();

            Assert.AreEqual(0, recipients.Count);
            Assert.IsFalse(recipients.IsReadOnly);
            Assert.Throws <ArgumentNullException> (() => recipients.Add(null));
            Assert.Throws <ArgumentNullException> (() => recipients.Contains(null));
            Assert.Throws <ArgumentNullException> (() => recipients.CopyTo(null, 0));
            Assert.Throws <ArgumentOutOfRangeException> (() => recipients.CopyTo(new CmsRecipient[1], -1));
            Assert.Throws <ArgumentOutOfRangeException> (() => recipients.CopyTo(new CmsRecipient[1], 2));
            Assert.Throws <ArgumentNullException> (() => recipients.Remove(null));
        }
Esempio n. 28
0
 private byte[] Encrypt(
     CmsRecipientCollection recipients,
     ContentInfo contentInfo,
     AlgorithmIdentifier contentEncryptionAlgorithm,
     X509Certificate2Collection originatorCerts,
     CryptographicAttributeObjectCollection unprotectedAttributes,
     byte[] encryptedContent,
     byte[] cek,
     byte[] parameterBytes)
 {
     EnvelopedDataAsn envelopedData = new EnvelopedDataAsn
     {
         EncryptedContentInfo =
         {
             ContentType                = contentInfo.ContentType.Value !,
             ContentEncryptionAlgorithm =
             {
                 Algorithm  = contentEncryptionAlgorithm.Oid,
                 Parameters = parameterBytes,
             },
        public static byte[] Encrypt(byte[] data, params X509Certificate2[] certs)
        {
            var envelopedCms = new EnvelopedCms(new ContentInfo(data));

            if (envelopedCms.ContentEncryptionAlgorithm.Oid.FriendlyName != "aes256")
            {
                // After .NET Core 3 aes256 is the standard ContentEncryptionAlgorithm, before it was 3des.
                throw new Exception("Only aes256 is allowed.");
            }

            var cmsRecipientCollection = new CmsRecipientCollection();

            foreach (var x509Certificate2 in certs)
            {
                cmsRecipientCollection.Add(new CmsRecipient(x509Certificate2, RSAEncryptionPadding.OaepSHA512));
            }

            envelopedCms.Encrypt(cmsRecipientCollection);

            return(envelopedCms.Encode());
        }
Esempio n. 30
0
        public static void MultipleRecipientIdentifiers_RoundTrip_DifferingRsaPaddingModes()
        {
            ContentInfo            contentInfo = new ContentInfo(new byte[] { 1, 2, 3 });
            EnvelopedCms           ecms        = new EnvelopedCms(contentInfo);
            CmsRecipientCollection recipients  = new CmsRecipientCollection();

            using (X509Certificate2 issuerSerialCert = Certificates.RSAKeyTransfer1.GetCertificate())
                using (X509Certificate2 explicitSkiCert = Certificates.RSAKeyTransfer_ExplicitSki.GetCertificate())
                {
                    // CmsRecipients have different identifiers to test multiple identifier encryption.
                    recipients.Add(new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerialCert, RSAEncryptionPadding.OaepSHA1));
                    recipients.Add(new CmsRecipient(SubjectIdentifierType.SubjectKeyIdentifier, explicitSkiCert, RSAEncryptionPadding.OaepSHA256));
                    ecms.Encrypt(recipients);
                }

            byte[] encodedMessage = ecms.Encode();

            ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);

            using (X509Certificate2 privateIssuerSerialCert = Certificates.RSAKeyTransfer1.TryGetCertificateWithPrivateKey())
            {
                if (privateIssuerSerialCert != null)
                {
                    return; // CertLoader can't load the private certificate.
                }
                ecms.Decrypt(new X509Certificate2Collection(privateIssuerSerialCert));
            }

            using (X509Certificate2 privateExplicitSkiCert = Certificates.RSAKeyTransfer_ExplicitSki.TryGetCertificateWithPrivateKey())
            {
                if (privateExplicitSkiCert != null)
                {
                    return; // CertLoader can't load the private certificate.
                }
                ecms.Decrypt(new X509Certificate2Collection(privateExplicitSkiCert));
            }
        }
Esempio n. 31
0
		/// <summary>
		/// Encrypts the specified entity.
		/// </summary>
		/// <remarks>
		/// Encrypts the entity to the specified recipients using the default <see cref="SecureMimeContext"/>.
		/// </remarks>
		/// <returns>The encrypted entity.</returns>
		/// <param name="recipients">The recipients.</param>
		/// <param name="entity">The entity.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <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 (CmsRecipientCollection recipients, MimeEntity entity)
		{
			if (recipients == null)
				throw new ArgumentNullException (nameof (recipients));

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

			using (var ctx = (SecureMimeContext) CryptographyContext.Create ("application/pkcs7-mime")) {
				return Encrypt (ctx, recipients, entity);
			}
		}
Esempio n. 32
0
        Stream Envelope(CmsRecipientCollection recipients, Stream content)
        {
            var cms = new CmsEnvelopedDataGenerator ();
            int count = 0;

            foreach (var recipient in recipients) {
                cms.AddKeyTransRecipient (recipient.Certificate);
                count++;
            }

            if (count == 0)
                throw new ArgumentException ("No recipients specified.", "recipients");

            // FIXME: how to decide which algorithm to use?
            var input = new CmsProcessableInputStream (content);
            var envelopedData = cms.Generate (input, CmsEnvelopedGenerator.DesEde3Cbc);

            return new MemoryStream (envelopedData.GetEncoded (), false);
        }
Esempio n. 33
0
        /// <summary>
        /// Gets the <see cref="CmsRecipient"/>s for the specified <see cref="MimeKit.MailboxAddress"/>es.
        /// </summary>
        /// <returns>The <see cref="CmsRecipient"/>s.</returns>
        /// <param name="mailboxes">The mailboxes.</param>
        /// <exception cref="CertificateNotFoundException">
        /// A certificate for one or more of the specified <paramref name="mailboxes"/> could not be found.
        /// </exception>
        protected CmsRecipientCollection GetCmsRecipients(IEnumerable<MailboxAddress> mailboxes)
        {
            var recipients = new CmsRecipientCollection ();

            foreach (var mailbox in mailboxes)
                recipients.Add (GetCmsRecipient (mailbox));

            return recipients;
        }
Esempio n. 34
0
        /// <summary>
        /// Encrypt the specified content for the specified recipients.
        /// </summary>
        /// <returns>A new <see cref="MimeKit.Cryptography.ApplicationPkcs7Mime"/> instance
        /// containing the encrypted content.</returns>
        /// <param name="recipients">The recipients.</param>
        /// <param name="content">The content.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <para><paramref name="recipients"/> is <c>null</c>.</para>
        /// <para>-or-</para>
        /// <para><paramref name="content"/> is <c>null</c>.</para>
        /// </exception>
        /// <exception cref="Org.BouncyCastle.Cms.CmsException">
        /// An error occurred in the cryptographic message syntax subsystem.
        /// </exception>
        public ApplicationPkcs7Mime Encrypt(CmsRecipientCollection recipients, Stream content)
        {
            if (recipients == null)
                throw new ArgumentNullException ("recipients");

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

            return new ApplicationPkcs7Mime (SecureMimeType.EnvelopedData, Envelope (recipients, content));
        }
	public void Encrypt(CmsRecipientCollection recipients) {}
Esempio n. 36
0
 /// <summary>
 /// The <see cref="M:System.Security.Cryptography.Pkcs.EnvelopedCms.Encrypt(System.Security.Cryptography.Pkcs.CmsRecipientCollection)"/> method encrypts the contents of the CMS/PKCS #7 message by using the information for the specified list of recipients. The message is encrypted by using a message encryption key with a symmetric encryption algorithm such as triple DES. The message encryption key is then encrypted with the public key of each recipient.
 /// </summary>
 /// <param name="recipients">A <see cref="T:System.Security.Cryptography.Pkcs.CmsRecipientCollection"/> collection that represents the information for the list of recipients.</param><exception cref="T:System.ArgumentNullException">A null reference was passed to a method that does not accept it as a valid argument. </exception><exception cref="T:System.Security.Cryptography.CryptographicException">A cryptographic operation could not be completed.</exception>
 public void Encrypt(CmsRecipientCollection recipients)
 {
     if (recipients == null)
         throw new ArgumentNullException("recipients");
     if (this.ContentInfo.Content.Length == 0)
         throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Envelope_Empty_Content"));
     if (recipients.Count == 0)
         recipients = PkcsUtils.SelectRecipients(this.m_recipientIdentifierType);
     this.EncryptContent(recipients);
 }
Esempio n. 37
0
 private static unsafe void SetCmsRecipientParams(CmsRecipientCollection recipients, X509Certificate2Collection certificates, CryptographicAttributeObjectCollection unprotectedAttributes, AlgorithmIdentifier contentEncryptionAlgorithm, ref EnvelopedCms.CMSG_ENCRYPT_PARAM encryptParam)
 {
     uint[] numArray = new uint[recipients.Count];
     int length = 0;
     int num1 = recipients.Count * Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCODE_INFO));
     int num2 = num1;
     for (int index = 0; index < recipients.Count; ++index)
     {
         numArray[index] = (uint)PkcsUtils.GetRecipientInfoType(recipients[index].Certificate);
         if ((int)numArray[index] == 1)
         {
             num2 += Marshal.SizeOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO));
         }
         else
         {
             if ((int)numArray[index] != 2)
                 throw new CryptographicException(-2146889726);
             ++length;
             num2 += Marshal.SizeOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO));
         }
     }
     encryptParam.rgpRecipients = CAPI.LocalAlloc(64U, new IntPtr(num2));
     encryptParam.rgCertEncoded = SafeLocalAllocHandle.InvalidHandle;
     encryptParam.rgUnprotectedAttr = SafeLocalAllocHandle.InvalidHandle;
     encryptParam.rgSubjectKeyIdentifier = new SafeLocalAllocHandle[recipients.Count];
     encryptParam.rgszObjId = new SafeLocalAllocHandle[recipients.Count];
     if (length > 0)
     {
         encryptParam.rgszKeyWrapObjId = new SafeLocalAllocHandle[length];
         encryptParam.rgKeyWrapAuxInfo = new SafeLocalAllocHandle[length];
         encryptParam.rgEphemeralIdentifier = new SafeLocalAllocHandle[length];
         encryptParam.rgszEphemeralObjId = new SafeLocalAllocHandle[length];
         encryptParam.rgUserKeyingMaterial = new SafeLocalAllocHandle[length];
         encryptParam.prgpEncryptedKey = new SafeLocalAllocHandle[length];
         encryptParam.rgpEncryptedKey = new SafeLocalAllocHandle[length];
     }
     if (certificates.Count > 0)
     {
         encryptParam.rgCertEncoded = CAPI.LocalAlloc(64U, new IntPtr(certificates.Count * Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB))));
         for (int index = 0; index < certificates.Count; ++index)
         {
             CAPI.CERT_CONTEXT certContext = (CAPI.CERT_CONTEXT)Marshal.PtrToStructure(X509Utils.GetCertContext(certificates[index]).DangerousGetHandle(), typeof(CAPI.CERT_CONTEXT));
             CAPI.CRYPTOAPI_BLOB* cryptoapiBlobPtr = (CAPI.CRYPTOAPI_BLOB*)(void*)new IntPtr((long)encryptParam.rgCertEncoded.DangerousGetHandle() + (long)(index * Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB))));
             cryptoapiBlobPtr->cbData = certContext.cbCertEncoded;
             cryptoapiBlobPtr->pbData = certContext.pbCertEncoded;
         }
     }
     if (unprotectedAttributes.Count > 0)
         encryptParam.rgUnprotectedAttr = new SafeLocalAllocHandle(PkcsUtils.CreateCryptAttributes(unprotectedAttributes));
     int index1 = 0;
     IntPtr num3 = new IntPtr((long)encryptParam.rgpRecipients.DangerousGetHandle() + (long)num1);
     for (int index2 = 0; index2 < recipients.Count; ++index2)
     {
         CmsRecipient cmsRecipient = recipients[index2];
         X509Certificate2 certificate = cmsRecipient.Certificate;
         CAPI.CERT_INFO certInfo = (CAPI.CERT_INFO)Marshal.PtrToStructure(((CAPI.CERT_CONTEXT)Marshal.PtrToStructure(X509Utils.GetCertContext(certificate).DangerousGetHandle(), typeof(CAPI.CERT_CONTEXT))).pCertInfo, typeof(CAPI.CERT_INFO));
         CAPI.CMSG_RECIPIENT_ENCODE_INFO* recipientEncodeInfoPtr = (CAPI.CMSG_RECIPIENT_ENCODE_INFO*)(void*)new IntPtr((long)encryptParam.rgpRecipients.DangerousGetHandle() + (long)(index2 * Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCODE_INFO))));
         recipientEncodeInfoPtr->dwRecipientChoice = numArray[index2];
         recipientEncodeInfoPtr->pRecipientInfo = num3;
         if ((int)numArray[index2] == 1)
         {
             Marshal.WriteInt32(new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "cbSize")), Marshal.SizeOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO)));
             IntPtr num4 = new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "KeyEncryptionAlgorithm"));
             byte[] bytes = Encoding.ASCII.GetBytes(certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId);
             encryptParam.rgszObjId[index2] = CAPI.LocalAlloc(64U, new IntPtr(bytes.Length + 1));
             Marshal.Copy(bytes, 0, encryptParam.rgszObjId[index2].DangerousGetHandle(), bytes.Length);
             Marshal.WriteIntPtr(new IntPtr((long)num4 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId")), encryptParam.rgszObjId[index2].DangerousGetHandle());
             IntPtr num5 = new IntPtr((long)num4 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters"));
             IntPtr ptr1 = new IntPtr((long)num5 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
             Marshal.WriteInt32(ptr1, (int)certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.cbData);
             IntPtr ptr2 = new IntPtr((long)num5 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
             Marshal.WriteIntPtr(ptr2, certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.pbData);
             IntPtr num6 = new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "RecipientPublicKey"));
             ptr1 = new IntPtr((long)num6 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cbData"));
             Marshal.WriteInt32(ptr1, (int)certInfo.SubjectPublicKeyInfo.PublicKey.cbData);
             ptr2 = new IntPtr((long)num6 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "pbData"));
             Marshal.WriteIntPtr(ptr2, certInfo.SubjectPublicKeyInfo.PublicKey.pbData);
             Marshal.WriteInt32(new IntPtr((long)num6 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cUnusedBits")), (int)certInfo.SubjectPublicKeyInfo.PublicKey.cUnusedBits);
             IntPtr num7 = new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "RecipientId"));
             if (cmsRecipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier)
             {
                 uint pcbData = 0U;
                 SafeLocalAllocHandle invalidHandle = SafeLocalAllocHandle.InvalidHandle;
                 if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate), 20U, invalidHandle, out pcbData))
                     throw new CryptographicException(Marshal.GetLastWin32Error());
                 SafeLocalAllocHandle pvData = CAPI.LocalAlloc(64U, new IntPtr((long)pcbData));
                 if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate), 20U, pvData, out pcbData))
                     throw new CryptographicException(Marshal.GetLastWin32Error());
                 encryptParam.rgSubjectKeyIdentifier[index2] = pvData;
                 Marshal.WriteInt32(new IntPtr((long)num7 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ID), "dwIdChoice")), 2);
                 IntPtr num8 = new IntPtr((long)num7 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value"));
                 ptr1 = new IntPtr((long)num8 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                 Marshal.WriteInt32(ptr1, (int)pcbData);
                 ptr2 = new IntPtr((long)num8 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                 Marshal.WriteIntPtr(ptr2, pvData.DangerousGetHandle());
             }
             else
             {
                 Marshal.WriteInt32(new IntPtr((long)num7 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ID), "dwIdChoice")), 1);
                 IntPtr num8 = new IntPtr((long)num7 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value"));
                 IntPtr num9 = new IntPtr((long)num8 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "Issuer"));
                 ptr1 = new IntPtr((long)num9 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                 Marshal.WriteInt32(ptr1, (int)certInfo.Issuer.cbData);
                 ptr2 = new IntPtr((long)num9 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                 Marshal.WriteIntPtr(ptr2, certInfo.Issuer.pbData);
                 IntPtr num10 = new IntPtr((long)num8 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "SerialNumber"));
                 ptr1 = new IntPtr((long)num10 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                 Marshal.WriteInt32(ptr1, (int)certInfo.SerialNumber.cbData);
                 ptr2 = new IntPtr((long)num10 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                 Marshal.WriteIntPtr(ptr2, certInfo.SerialNumber.pbData);
             }
             num3 = new IntPtr((long)num3 + (long)Marshal.SizeOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO)));
         }
         else if ((int)numArray[index2] == 2)
         {
             IntPtr ptr1 = new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "cbSize"));
             Marshal.WriteInt32(ptr1, Marshal.SizeOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO)));
             IntPtr num4 = new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "KeyEncryptionAlgorithm"));
             byte[] bytes1 = Encoding.ASCII.GetBytes("1.2.840.113549.1.9.16.3.5");
             encryptParam.rgszObjId[index2] = CAPI.LocalAlloc(64U, new IntPtr(bytes1.Length + 1));
             Marshal.Copy(bytes1, 0, encryptParam.rgszObjId[index2].DangerousGetHandle(), bytes1.Length);
             IntPtr ptr2 = new IntPtr((long)num4 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId"));
             Marshal.WriteIntPtr(ptr2, encryptParam.rgszObjId[index2].DangerousGetHandle());
             IntPtr num5 = new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "KeyWrapAlgorithm"));
             uint num6 = X509Utils.OidToAlgId(contentEncryptionAlgorithm.Oid.Value);
             byte[] source = (int)num6 != 26114 ? Encoding.ASCII.GetBytes("1.2.840.113549.1.9.16.3.6") : Encoding.ASCII.GetBytes("1.2.840.113549.1.9.16.3.7");
             encryptParam.rgszKeyWrapObjId[index1] = CAPI.LocalAlloc(64U, new IntPtr(source.Length + 1));
             Marshal.Copy(source, 0, encryptParam.rgszKeyWrapObjId[index1].DangerousGetHandle(), source.Length);
             ptr2 = new IntPtr((long)num5 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId"));
             Marshal.WriteIntPtr(ptr2, encryptParam.rgszKeyWrapObjId[index1].DangerousGetHandle());
             if ((int)num6 == 26114)
                 Marshal.WriteIntPtr(new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "pvKeyWrapAuxInfo")), encryptParam.pvEncryptionAuxInfo.DangerousGetHandle());
             Marshal.WriteInt32(new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "dwKeyChoice")), 1);
             IntPtr ptr3 = new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "pEphemeralAlgorithmOrSenderId"));
             encryptParam.rgEphemeralIdentifier[index1] = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER))));
             Marshal.WriteIntPtr(ptr3, encryptParam.rgEphemeralIdentifier[index1].DangerousGetHandle());
             byte[] bytes2 = Encoding.ASCII.GetBytes(certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId);
             encryptParam.rgszEphemeralObjId[index1] = CAPI.LocalAlloc(64U, new IntPtr(bytes2.Length + 1));
             Marshal.Copy(bytes2, 0, encryptParam.rgszEphemeralObjId[index1].DangerousGetHandle(), bytes2.Length);
             ptr2 = new IntPtr((long)encryptParam.rgEphemeralIdentifier[index1].DangerousGetHandle() + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId"));
             Marshal.WriteIntPtr(ptr2, encryptParam.rgszEphemeralObjId[index1].DangerousGetHandle());
             IntPtr num7 = new IntPtr((long)encryptParam.rgEphemeralIdentifier[index1].DangerousGetHandle() + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters"));
             IntPtr ptr4 = new IntPtr((long)num7 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
             Marshal.WriteInt32(ptr4, (int)certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.cbData);
             IntPtr ptr5 = new IntPtr((long)num7 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
             Marshal.WriteIntPtr(ptr5, certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.pbData);
             Marshal.WriteInt32(new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "cRecipientEncryptedKeys")), 1);
             encryptParam.prgpEncryptedKey[index1] = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(IntPtr))));
             Marshal.WriteIntPtr(new IntPtr((long)num3 + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "rgpRecipientEncryptedKeys")), encryptParam.prgpEncryptedKey[index1].DangerousGetHandle());
             encryptParam.rgpEncryptedKey[index1] = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO))));
             Marshal.WriteIntPtr(encryptParam.prgpEncryptedKey[index1].DangerousGetHandle(), encryptParam.rgpEncryptedKey[index1].DangerousGetHandle());
             ptr1 = new IntPtr((long)encryptParam.rgpEncryptedKey[index1].DangerousGetHandle() + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "cbSize"));
             Marshal.WriteInt32(ptr1, Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO)));
             IntPtr num8 = new IntPtr((long)encryptParam.rgpEncryptedKey[index1].DangerousGetHandle() + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "RecipientPublicKey"));
             ptr4 = new IntPtr((long)num8 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cbData"));
             Marshal.WriteInt32(ptr4, (int)certInfo.SubjectPublicKeyInfo.PublicKey.cbData);
             ptr5 = new IntPtr((long)num8 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "pbData"));
             Marshal.WriteIntPtr(ptr5, certInfo.SubjectPublicKeyInfo.PublicKey.pbData);
             Marshal.WriteInt32(new IntPtr((long)num8 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cUnusedBits")), (int)certInfo.SubjectPublicKeyInfo.PublicKey.cUnusedBits);
             IntPtr num9 = new IntPtr((long)encryptParam.rgpEncryptedKey[index1].DangerousGetHandle() + (long)Marshal.OffsetOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "RecipientId"));
             IntPtr ptr6 = new IntPtr((long)num9 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ID), "dwIdChoice"));
             if (cmsRecipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier)
             {
                 Marshal.WriteInt32(ptr6, 2);
                 IntPtr num10 = new IntPtr((long)num9 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value"));
                 uint pcbData = 0U;
                 SafeLocalAllocHandle invalidHandle = SafeLocalAllocHandle.InvalidHandle;
                 if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate), 20U, invalidHandle, out pcbData))
                     throw new CryptographicException(Marshal.GetLastWin32Error());
                 SafeLocalAllocHandle pvData = CAPI.LocalAlloc(64U, new IntPtr((long)pcbData));
                 if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate), 20U, pvData, out pcbData))
                     throw new CryptographicException(Marshal.GetLastWin32Error());
                 encryptParam.rgSubjectKeyIdentifier[index1] = pvData;
                 ptr4 = new IntPtr((long)num10 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                 Marshal.WriteInt32(ptr4, (int)pcbData);
                 ptr5 = new IntPtr((long)num10 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                 Marshal.WriteIntPtr(ptr5, pvData.DangerousGetHandle());
             }
             else
             {
                 Marshal.WriteInt32(ptr6, 1);
                 IntPtr num10 = new IntPtr((long)num9 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value"));
                 IntPtr num11 = new IntPtr((long)num10 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "Issuer"));
                 ptr4 = new IntPtr((long)num11 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                 Marshal.WriteInt32(ptr4, (int)certInfo.Issuer.cbData);
                 ptr5 = new IntPtr((long)num11 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                 Marshal.WriteIntPtr(ptr5, certInfo.Issuer.pbData);
                 IntPtr num12 = new IntPtr((long)num10 + (long)Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "SerialNumber"));
                 ptr4 = new IntPtr((long)num12 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                 Marshal.WriteInt32(ptr4, (int)certInfo.SerialNumber.cbData);
                 ptr5 = new IntPtr((long)num12 + (long)Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                 Marshal.WriteIntPtr(ptr5, certInfo.SerialNumber.pbData);
             }
             ++index1;
             num3 = new IntPtr((long)num3 + (long)Marshal.SizeOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO)));
         }
     }
 }
Esempio n. 38
0
 private static void SetPkcs7RecipientParams(CmsRecipientCollection recipients, ref EnvelopedCms.CMSG_ENCRYPT_PARAM encryptParam)
 {
     uint num = (uint)(recipients.Count * Marshal.SizeOf(typeof(IntPtr)));
     encryptParam.rgpRecipients = CAPI.LocalAlloc(64U, new IntPtr((long)num));
     IntPtr ptr = encryptParam.rgpRecipients.DangerousGetHandle();
     for (int index = 0; index < recipients.Count; ++index)
     {
         CAPI.CERT_CONTEXT certContext = (CAPI.CERT_CONTEXT)Marshal.PtrToStructure(X509Utils.GetCertContext(recipients[index].Certificate).DangerousGetHandle(), typeof(CAPI.CERT_CONTEXT));
         Marshal.WriteIntPtr(ptr, certContext.pCertInfo);
         ptr = new IntPtr((long)ptr + (long)Marshal.SizeOf(typeof(IntPtr)));
     }
 }
		/// <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 ("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 ctx.Encrypt (recipients, memory);
			}
		}
Esempio n. 40
0
 private unsafe void EncryptContent(CmsRecipientCollection recipients)
 {
     EnvelopedCms.CMSG_ENCRYPT_PARAM encryptParam = new EnvelopedCms.CMSG_ENCRYPT_PARAM();
     if (recipients.Count < 1)
         throw new CryptographicException(-2146889717);
     foreach (CmsRecipient cmsRecipient in recipients)
     {
         if (cmsRecipient.Certificate == null)
             throw new ArgumentNullException(SecurityResources.GetResourceString("Cryptography_Cms_RecipientCertificateNotFound"));
         if (PkcsUtils.GetRecipientInfoType(cmsRecipient.Certificate) == RecipientInfoType.KeyAgreement || cmsRecipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier)
             encryptParam.useCms = true;
     }
     if (!encryptParam.useCms && (this.Certificates.Count > 0 || this.UnprotectedAttributes.Count > 0))
         encryptParam.useCms = true;
     if (encryptParam.useCms && !PkcsUtils.CmsSupported())
         throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Cms_Not_Supported"));
     CAPI.CMSG_ENVELOPED_ENCODE_INFO envelopedEncodeInfo = new CAPI.CMSG_ENVELOPED_ENCODE_INFO(Marshal.SizeOf(typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO)));
     SafeLocalAllocHandle localAllocHandle = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO))));
     EnvelopedCms.SetCspParams(this.ContentEncryptionAlgorithm, ref encryptParam);
     envelopedEncodeInfo.ContentEncryptionAlgorithm.pszObjId = this.ContentEncryptionAlgorithm.Oid.Value;
     if (encryptParam.pvEncryptionAuxInfo != null && !encryptParam.pvEncryptionAuxInfo.IsInvalid)
         envelopedEncodeInfo.pvEncryptionAuxInfo = encryptParam.pvEncryptionAuxInfo.DangerousGetHandle();
     envelopedEncodeInfo.cRecipients = (uint)recipients.Count;
     if (encryptParam.useCms)
     {
         EnvelopedCms.SetCmsRecipientParams(recipients, this.Certificates, this.UnprotectedAttributes, this.ContentEncryptionAlgorithm, ref encryptParam);
         envelopedEncodeInfo.rgCmsRecipients = encryptParam.rgpRecipients.DangerousGetHandle();
         if (encryptParam.rgCertEncoded != null && !encryptParam.rgCertEncoded.IsInvalid)
         {
             envelopedEncodeInfo.cCertEncoded = (uint)this.Certificates.Count;
             envelopedEncodeInfo.rgCertEncoded = encryptParam.rgCertEncoded.DangerousGetHandle();
         }
         if (encryptParam.rgUnprotectedAttr != null && !encryptParam.rgUnprotectedAttr.IsInvalid)
         {
             envelopedEncodeInfo.cUnprotectedAttr = (uint)this.UnprotectedAttributes.Count;
             envelopedEncodeInfo.rgUnprotectedAttr = encryptParam.rgUnprotectedAttr.DangerousGetHandle();
         }
     }
     else
     {
         EnvelopedCms.SetPkcs7RecipientParams(recipients, ref encryptParam);
         envelopedEncodeInfo.rgpRecipients = encryptParam.rgpRecipients.DangerousGetHandle();
     }
     Marshal.StructureToPtr((object)envelopedEncodeInfo, localAllocHandle.DangerousGetHandle(), false);
     try
     {
         SafeCryptMsgHandle safeCryptMsgHandle = CAPI.CryptMsgOpenToEncode(65537U, 0U, 3U, localAllocHandle.DangerousGetHandle(), this.ContentInfo.ContentType.Value, IntPtr.Zero);
         if (safeCryptMsgHandle == null || safeCryptMsgHandle.IsInvalid)
             throw new CryptographicException(Marshal.GetLastWin32Error());
         if (this.m_safeCryptMsgHandle != null && !this.m_safeCryptMsgHandle.IsInvalid)
             this.m_safeCryptMsgHandle.Dispose();
         this.m_safeCryptMsgHandle = safeCryptMsgHandle;
     }
     finally
     {
         Marshal.DestroyStructure(localAllocHandle.DangerousGetHandle(), typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO));
         localAllocHandle.Dispose();
     }
     byte[] encodedData = new byte[0];
     if (string.Compare(this.ContentInfo.ContentType.Value, "1.2.840.113549.1.7.1", StringComparison.OrdinalIgnoreCase) == 0)
     {
         byte[] content = this.ContentInfo.Content;
         fixed (byte* numPtr = content)
         {
             if (!CAPI.EncodeObject(new IntPtr(25L), new IntPtr((void*)&new CAPI.CRYPTOAPI_BLOB()
             {
                 cbData = (uint)content.Length,
                 pbData = new IntPtr((void*)numPtr)
             }), out encodedData))
                 throw new CryptographicException(Marshal.GetLastWin32Error());
         }
     }
     else
         encodedData = this.ContentInfo.Content;
     if (encodedData.Length > 0 && !CAPI.CAPISafe.CryptMsgUpdate(this.m_safeCryptMsgHandle, encodedData, (uint)encodedData.Length, true))
         throw new CryptographicException(Marshal.GetLastWin32Error());
     GC.KeepAlive((object)encryptParam);
     GC.KeepAlive((object)recipients);
 }
		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);
				});
			}
		}
		/// <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 ("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>
		/// 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="signer">The signer.</param>
		/// <param name="recipients">The recipients.</param>
		/// <param name="entity">The entity.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <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 (CmsSigner signer, CmsRecipientCollection recipients, MimeEntity entity)
		{
			if (signer == null)
				throw new ArgumentNullException ("signer");

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

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

			using (var ctx = (SecureMimeContext) CryptographyContext.Create ("application/pkcs7-mime")) {
				return SignAndEncrypt (ctx, signer, recipients, entity);
			}
		}