상속: ICollection, IEnumerable
예제 #1
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;
            }
        }
예제 #2
0
        public static void Rc4AndCngWrappersDontMixTest()
        {
            //
            // Combination of RC4 over a CAPI certificate.
            //
            //  This works as long as the PKCS implementation opens the cert using CAPI. If he creates a CNG wrapper handle (by passing CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG),
            //  the test fails with a NOTSUPPORTED crypto exception inside Decrypt(). The same happens if the key is genuinely CNG.
            //

            byte[] content = { 6, 3, 128, 33, 44 };
            AlgorithmIdentifier rc4 = new AlgorithmIdentifier(new Oid(Oids.Rc4));

            EnvelopedCms ecms = new EnvelopedCms(new ContentInfo(content), rc4);
            CmsRecipientCollection recipients = new CmsRecipientCollection(new CmsRecipient(Certificates.RSAKeyTransferCapi1.GetCertificate()));
            ecms.Encrypt(recipients);
            byte[] encodedMessage = ecms.Encode();

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

            using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.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);
        }
예제 #3
0
 // Perform a deep copy of a certificate collection
 private CmsRecipientCollection(CmsRecipientCollection other)
 {
     m_recipients = new ArrayList(other.m_recipients.Count);
     foreach (CmsRecipient recipient in other.m_recipients)
     {
         m_recipients.Add(new CmsRecipient(recipient.RecipientIdentifierType, new X509Certificate2(recipient.Certificate)));
     }
 }
예제 #4
0
 public void Encrypt(CmsRecipientCollection recipients)
 {
     if (recipients == null)
     {
         throw new ArgumentNullException("recipients");
     }
     // ? foreach on Encrypt CmsRecipient ?
 }
 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);
 }
 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);
 }
예제 #7
0
		RealCmsRecipientCollection GetRealCmsRecipients (IEnumerable<MailboxAddress> mailboxes)
		{
			var recipients = new RealCmsRecipientCollection ();

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

			return recipients;
		}
예제 #8
0
        public static void DecodeRecipients3_RoundTrip()
        {
            ContentInfo contentInfo = new ContentInfo(new byte[] { 1, 2, 3 });
            EnvelopedCms ecms = new EnvelopedCms(contentInfo);
            CmsRecipientCollection recipients = new CmsRecipientCollection();
            foreach (X509Certificate2 cert in s_certs)
            {
                recipients.Add(new CmsRecipient(cert));
            }
            ecms.Encrypt(recipients);
            byte[] encodedMessage = ecms.Encode();

            VerifyRecipients3(encodedMessage);
        }
        /// <summary>
        /// Gets the preferred encryption algorithm to use for encrypting to the specified recipients.
        /// </summary>
        /// <remarks>
        /// <para>Gets the preferred encryption algorithm to use for encrypting to the specified recipients
        /// based on the encryption algorithms supported by each of the recipients, the
        /// <see cref="SecureMimeContext.EnabledEncryptionAlgorithms"/>, and the
        /// <see cref="SecureMimeContext.EncryptionAlgorithmRank"/>.</para>
        /// <para>If the supported encryption algorithms are unknown for any recipient, it is assumed that
        /// the recipient supports at least the Triple-DES encryption algorithm.</para>
        /// </remarks>
        /// <returns>The preferred encryption algorithm.</returns>
        /// <param name="recipients">The recipients.</param>
        protected virtual EncryptionAlgorithm GetPreferredEncryptionAlgorithm(RealCmsRecipientCollection recipients)
        {
            var votes = new int[EncryptionAlgorithmCount];

            foreach (var recipient in recipients)
            {
                var supported = CmsRecipient.GetEncryptionAlgorithms(recipient.Certificate);
                int cast      = EncryptionAlgorithmCount;

                foreach (var algorithm in supported)
                {
                    votes[(int)algorithm] += cast;
                    cast--;
                }
            }

            // Starting with S/MIME v3 (published in 1999), Triple-DES is a REQUIRED algorithm.
            // S/MIME v2.x and older only required RC2/40, but SUGGESTED Triple-DES.
            // Considering the fact that Bruce Schneier was able to write a
            // screensaver that could crack RC2/40 back in the late 90's, let's
            // not default to anything weaker than Triple-DES...
            EncryptionAlgorithm chosen = EncryptionAlgorithm.TripleDes;
            int nvotes = 0;

            // iterate through the algorithms, from strongest to weakest, keeping track
            // of the algorithm with the most amount of votes (between algorithms with
            // the same number of votes, choose the strongest of the 2 - i.e. the one
            // that we arrive at first).
            var algorithms = EncryptionAlgorithmRank;

            for (int i = 0; i < algorithms.Length; i++)
            {
                var algorithm = algorithms[i];

                if (!IsEnabled(algorithm))
                {
                    continue;
                }

                if (votes[(int)algorithm] > nvotes)
                {
                    nvotes = votes[(int)algorithm];
                    chosen = algorithm;
                }
            }

            return(chosen);
        }
        RealCmsRecipientCollection GetRealCmsRecipients(IEnumerable <MailboxAddress> recipients)
        {
            var collection = new RealCmsRecipientCollection();

            foreach (var recipient in recipients)
            {
                collection.Add(GetRealCmsRecipient(recipient));
            }

            if (collection.Count == 0)
            {
                throw new ArgumentException("No recipients specified.", nameof(recipients));
            }

            return(collection);
        }
        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 });
        }
        Stream Envelope(RealCmsRecipientCollection recipients, Stream content, EncryptionAlgorithm encryptionAlgorithm)
        {
            var contentInfo = new ContentInfo(ReadAllBytes(content));
            RealAlgorithmIdentifier algorithm;

            switch (encryptionAlgorithm)
            {
            case EncryptionAlgorithm.Aes256:
                algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.Aes256Cbc));
                break;

            case EncryptionAlgorithm.Aes192:
                algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.Aes192Cbc));
                break;

            case EncryptionAlgorithm.Aes128:
                algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.Aes128Cbc));
                break;

            case EncryptionAlgorithm.RC2128:
                algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.RC2Cbc), 128);
                break;

            case EncryptionAlgorithm.RC264:
                algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.RC2Cbc), 64);
                break;

            case EncryptionAlgorithm.RC240:
                algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.RC2Cbc), 40);
                break;

            default:
                algorithm = new RealAlgorithmIdentifier(new Oid(CmsEnvelopedGenerator.DesEde3Cbc));
                break;
            }

            var envelopedData = new EnvelopedCms(contentInfo, algorithm);

            envelopedData.Encrypt(recipients);

            return(new MemoryStream(envelopedData.Encode(), false));
        }
예제 #13
0
        public void Encrypt(CmsRecipientCollection recipients)
        {
            if (recipients == null)
            {
                throw new ArgumentNullException(nameof(recipients));
            }

            // .NET Framework compat note: Unlike the desktop, we don't provide a free UI to select the recipient. The app must give it to us programmatically.
            if (recipients.Count == 0)
            {
                throw new PlatformNotSupportedException(SR.Cryptography_Cms_NoRecipients);
            }

            if (_decryptorPal != null)
            {
                _decryptorPal.Dispose();
                _decryptorPal = null;
            }
            _encodedMessage = PkcsPal.Instance.Encrypt(recipients, ContentInfo, ContentEncryptionAlgorithm, Certificates, UnprotectedAttributes);
            _lastCall       = LastCall.Encrypt;
        }
예제 #14
0
            public static SafeCryptMsgHandle CreateCryptMsgHandleToEncode(CmsRecipientCollection recipients, Oid innerContentType, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes)
            {
                using (HeapBlockRetainer hb = new HeapBlockRetainer())
                {
                    // Deep copy the CmsRecipients (and especially their underlying X509Certificate2 objects). This will prevent malicious callers from altering them or disposing them while we're performing 
                    // unsafe memory crawling inside them.
                    recipients = recipients.DeepCopy();

                    // We must keep all the certificates inside recipients alive until the call to CryptMsgOpenToEncode() finishes. The CMSG_ENVELOPED_ENCODE_INFO* structure we passed to it
                    // contains direct pointers to memory owned by the CERT_INFO memory block whose lifetime is that of the certificate. 
                    hb.KeepAlive(recipients);
                    unsafe
                    {
                        CMSG_ENVELOPED_ENCODE_INFO* pEnvelopedEncodeInfo = CreateCmsEnvelopedEncodeInfo(recipients, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes, hb);
                        SafeCryptMsgHandle hCryptMsg = Interop.Crypt32.CryptMsgOpenToEncode(MsgEncodingType.All, 0, CryptMsgType.CMSG_ENVELOPED, pEnvelopedEncodeInfo, innerContentType.Value, IntPtr.Zero);
                        if (hCryptMsg == null || hCryptMsg.IsInvalid)
                            throw Marshal.GetLastWin32Error().ToCryptographicException();

                        return hCryptMsg;
                    }
                }
            }
        RealCmsRecipientCollection GetRealCmsRecipients(CmsRecipientCollection recipients)
        {
            var collection = new RealCmsRecipientCollection();

            foreach (var recipient in recipients)
            {
                var certificate = new X509Certificate2(recipient.Certificate.GetEncoded());
                RealSubjectIdentifierType type;

                if (recipient.RecipientIdentifierType == SubjectIdentifierType.IssuerAndSerialNumber)
                {
                    type = RealSubjectIdentifierType.IssuerAndSerialNumber;
                }
                else
                {
                    type = RealSubjectIdentifierType.SubjectKeyIdentifier;
                }

                collection.Add(new RealCmsRecipient(type, certificate));
            }

            return(collection);
        }
 public static void Nullary()
 {
     CmsRecipientCollection c = new CmsRecipientCollection();
     AssertEquals(c, Array.Empty<CmsRecipient>());
 }
예제 #17
0
 internal CmsRecipientEnumerator(CmsRecipientCollection recipients)
 {
     _recipients = recipients;
     _current = -1;
 }
예제 #18
0
        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);
        }
예제 #19
0
 /// <summary>
 /// Encrypt and encode a CMS. Return value is the RFC-compliant representation of the CMS that can be transmitted "on the wire."
 /// </summary>
 public abstract byte[] Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes);
예제 #20
0
        public void Encrypt(CmsRecipientCollection recipients)
        {
            if (recipients == null)
                throw new ArgumentNullException(nameof(recipients));

            // Desktop compat note: Unlike the desktop, we don't provide a free UI to select the recipient. The app must give it to us programmatically.
            if (recipients.Count == 0)
                throw new PlatformNotSupportedException(SR.Cryptography_Cms_NoRecipients);

            if (_decryptorPal != null)
            {
                _decryptorPal.Dispose();
                _decryptorPal = null;
            }
            _encodedMessage = PkcsPal.Instance.Encrypt(recipients, ContentInfo, ContentEncryptionAlgorithm, Certificates, UnprotectedAttributes);
            _lastCall = LastCall.Encrypt;
        }
 public static void Oneary()
 {
     CmsRecipient a0 = s_cr0;
     CmsRecipientCollection c = new CmsRecipientCollection(a0);
     AssertEquals(c, new CmsRecipient[] { a0 });
 }
 private static unsafe void SetCmsRecipientParams(CmsRecipientCollection recipients, X509Certificate2Collection certificates, CryptographicAttributeObjectCollection unprotectedAttributes, AlgorithmIdentifier contentEncryptionAlgorithm, ref CMSG_ENCRYPT_PARAM encryptParam)
 {
     int index = 0;
     uint[] numArray = new uint[recipients.Count];
     int num2 = 0;
     int num3 = recipients.Count * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCODE_INFO));
     int num4 = num3;
     for (index = 0; index < recipients.Count; index++)
     {
         numArray[index] = (uint) PkcsUtils.GetRecipientInfoType(recipients[index].Certificate);
         if (numArray[index] == 1)
         {
             num4 += Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO));
         }
         else
         {
             if (numArray[index] != 2)
             {
                 throw new CryptographicException(-2146889726);
             }
             num2++;
             num4 += Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO));
         }
     }
     encryptParam.rgpRecipients = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(num4));
     encryptParam.rgCertEncoded = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle;
     encryptParam.rgUnprotectedAttr = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle;
     encryptParam.rgSubjectKeyIdentifier = new System.Security.Cryptography.SafeLocalAllocHandle[recipients.Count];
     encryptParam.rgszObjId = new System.Security.Cryptography.SafeLocalAllocHandle[recipients.Count];
     if (num2 > 0)
     {
         encryptParam.rgszKeyWrapObjId = new System.Security.Cryptography.SafeLocalAllocHandle[num2];
         encryptParam.rgKeyWrapAuxInfo = new System.Security.Cryptography.SafeLocalAllocHandle[num2];
         encryptParam.rgEphemeralIdentifier = new System.Security.Cryptography.SafeLocalAllocHandle[num2];
         encryptParam.rgszEphemeralObjId = new System.Security.Cryptography.SafeLocalAllocHandle[num2];
         encryptParam.rgUserKeyingMaterial = new System.Security.Cryptography.SafeLocalAllocHandle[num2];
         encryptParam.prgpEncryptedKey = new System.Security.Cryptography.SafeLocalAllocHandle[num2];
         encryptParam.rgpEncryptedKey = new System.Security.Cryptography.SafeLocalAllocHandle[num2];
     }
     if (certificates.Count > 0)
     {
         encryptParam.rgCertEncoded = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(certificates.Count * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB))));
         for (index = 0; index < certificates.Count; index++)
         {
             System.Security.Cryptography.CAPI.CERT_CONTEXT cert_context = (System.Security.Cryptography.CAPI.CERT_CONTEXT) Marshal.PtrToStructure(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificates[index]).DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CERT_CONTEXT));
             System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB* cryptoapi_blobPtr = (System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB*) new IntPtr(((long) encryptParam.rgCertEncoded.DangerousGetHandle()) + (index * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB))));
             cryptoapi_blobPtr->cbData = cert_context.cbCertEncoded;
             cryptoapi_blobPtr->pbData = cert_context.pbCertEncoded;
         }
     }
     if (unprotectedAttributes.Count > 0)
     {
         encryptParam.rgUnprotectedAttr = new System.Security.Cryptography.SafeLocalAllocHandle(PkcsUtils.CreateCryptAttributes(unprotectedAttributes));
     }
     num2 = 0;
     IntPtr ptr = new IntPtr(((long) encryptParam.rgpRecipients.DangerousGetHandle()) + num3);
     for (index = 0; index < recipients.Count; index++)
     {
         CmsRecipient recipient = recipients[index];
         X509Certificate2 certificate = recipient.Certificate;
         System.Security.Cryptography.CAPI.CERT_CONTEXT cert_context2 = (System.Security.Cryptography.CAPI.CERT_CONTEXT) Marshal.PtrToStructure(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate).DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CERT_CONTEXT));
         System.Security.Cryptography.CAPI.CERT_INFO cert_info = (System.Security.Cryptography.CAPI.CERT_INFO) Marshal.PtrToStructure(cert_context2.pCertInfo, typeof(System.Security.Cryptography.CAPI.CERT_INFO));
         System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCODE_INFO* cmsg_recipient_encode_infoPtr = (System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCODE_INFO*) new IntPtr(((long) encryptParam.rgpRecipients.DangerousGetHandle()) + (index * Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCODE_INFO))));
         cmsg_recipient_encode_infoPtr->dwRecipientChoice = numArray[index];
         cmsg_recipient_encode_infoPtr->pRecipientInfo = ptr;
         if (numArray[index] == 1)
         {
             IntPtr ptr2 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "cbSize")));
             Marshal.WriteInt32(ptr2, Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO)));
             IntPtr ptr3 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "KeyEncryptionAlgorithm")));
             byte[] bytes = Encoding.ASCII.GetBytes(cert_info.SubjectPublicKeyInfo.Algorithm.pszObjId);
             encryptParam.rgszObjId[index] = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(bytes.Length + 1));
             Marshal.Copy(bytes, 0, encryptParam.rgszObjId[index].DangerousGetHandle(), bytes.Length);
             IntPtr ptr4 = new IntPtr(((long) ptr3) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId")));
             Marshal.WriteIntPtr(ptr4, encryptParam.rgszObjId[index].DangerousGetHandle());
             IntPtr ptr5 = new IntPtr(((long) ptr3) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters")));
             IntPtr ptr6 = new IntPtr(((long) ptr5) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData")));
             Marshal.WriteInt32(ptr6, (int) cert_info.SubjectPublicKeyInfo.Algorithm.Parameters.cbData);
             IntPtr ptr7 = new IntPtr(((long) ptr5) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData")));
             Marshal.WriteIntPtr(ptr7, cert_info.SubjectPublicKeyInfo.Algorithm.Parameters.pbData);
             IntPtr ptr8 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "RecipientPublicKey")));
             ptr6 = new IntPtr(((long) ptr8) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_BIT_BLOB), "cbData")));
             Marshal.WriteInt32(ptr6, (int) cert_info.SubjectPublicKeyInfo.PublicKey.cbData);
             ptr7 = new IntPtr(((long) ptr8) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_BIT_BLOB), "pbData")));
             Marshal.WriteIntPtr(ptr7, cert_info.SubjectPublicKeyInfo.PublicKey.pbData);
             IntPtr ptr9 = new IntPtr(((long) ptr8) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_BIT_BLOB), "cUnusedBits")));
             Marshal.WriteInt32(ptr9, (int) cert_info.SubjectPublicKeyInfo.PublicKey.cUnusedBits);
             IntPtr ptr10 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "RecipientId")));
             if (recipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier)
             {
                 uint pcbData = 0;
                 System.Security.Cryptography.SafeLocalAllocHandle invalidHandle = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle;
                 if (!System.Security.Cryptography.CAPI.CAPISafe.CertGetCertificateContextProperty(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate), 20, invalidHandle, ref pcbData))
                 {
                     throw new CryptographicException(Marshal.GetLastWin32Error());
                 }
                 invalidHandle = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long) pcbData));
                 if (!System.Security.Cryptography.CAPI.CAPISafe.CertGetCertificateContextProperty(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate), 20, invalidHandle, ref pcbData))
                 {
                     throw new CryptographicException(Marshal.GetLastWin32Error());
                 }
                 encryptParam.rgSubjectKeyIdentifier[index] = invalidHandle;
                 IntPtr ptr11 = new IntPtr(((long) ptr10) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ID), "dwIdChoice")));
                 Marshal.WriteInt32(ptr11, 2);
                 IntPtr ptr12 = new IntPtr(((long) ptr10) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ID), "Value")));
                 ptr6 = new IntPtr(((long) ptr12) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData")));
                 Marshal.WriteInt32(ptr6, (int) pcbData);
                 ptr7 = new IntPtr(((long) ptr12) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData")));
                 Marshal.WriteIntPtr(ptr7, invalidHandle.DangerousGetHandle());
             }
             else
             {
                 IntPtr ptr13 = new IntPtr(((long) ptr10) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ID), "dwIdChoice")));
                 Marshal.WriteInt32(ptr13, 1);
                 IntPtr ptr14 = new IntPtr(((long) ptr10) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ID), "Value")));
                 IntPtr ptr15 = new IntPtr(((long) ptr14) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ISSUER_SERIAL_NUMBER), "Issuer")));
                 ptr6 = new IntPtr(((long) ptr15) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData")));
                 Marshal.WriteInt32(ptr6, (int) cert_info.Issuer.cbData);
                 ptr7 = new IntPtr(((long) ptr15) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData")));
                 Marshal.WriteIntPtr(ptr7, cert_info.Issuer.pbData);
                 IntPtr ptr16 = new IntPtr(((long) ptr14) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ISSUER_SERIAL_NUMBER), "SerialNumber")));
                 ptr6 = new IntPtr(((long) ptr16) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData")));
                 Marshal.WriteInt32(ptr6, (int) cert_info.SerialNumber.cbData);
                 ptr7 = new IntPtr(((long) ptr16) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData")));
                 Marshal.WriteIntPtr(ptr7, cert_info.SerialNumber.pbData);
             }
             ptr = new IntPtr(((long) ptr) + Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO)));
         }
         else if (numArray[index] == 2)
         {
             IntPtr ptr17 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "cbSize")));
             Marshal.WriteInt32(ptr17, Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO)));
             IntPtr ptr18 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "KeyEncryptionAlgorithm")));
             byte[] source = Encoding.ASCII.GetBytes("1.2.840.113549.1.9.16.3.5");
             encryptParam.rgszObjId[index] = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(source.Length + 1));
             Marshal.Copy(source, 0, encryptParam.rgszObjId[index].DangerousGetHandle(), source.Length);
             IntPtr ptr19 = new IntPtr(((long) ptr18) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId")));
             Marshal.WriteIntPtr(ptr19, encryptParam.rgszObjId[index].DangerousGetHandle());
             IntPtr ptr20 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "KeyWrapAlgorithm")));
             uint num6 = System.Security.Cryptography.X509Certificates.X509Utils.OidToAlgId(contentEncryptionAlgorithm.Oid.Value);
             if (num6 == 0x6602)
             {
                 source = Encoding.ASCII.GetBytes("1.2.840.113549.1.9.16.3.7");
             }
             else
             {
                 source = Encoding.ASCII.GetBytes("1.2.840.113549.1.9.16.3.6");
             }
             encryptParam.rgszKeyWrapObjId[num2] = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(source.Length + 1));
             Marshal.Copy(source, 0, encryptParam.rgszKeyWrapObjId[num2].DangerousGetHandle(), source.Length);
             ptr19 = new IntPtr(((long) ptr20) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId")));
             Marshal.WriteIntPtr(ptr19, encryptParam.rgszKeyWrapObjId[num2].DangerousGetHandle());
             if (num6 == 0x6602)
             {
                 IntPtr ptr21 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "pvKeyWrapAuxInfo")));
                 Marshal.WriteIntPtr(ptr21, encryptParam.pvEncryptionAuxInfo.DangerousGetHandle());
             }
             IntPtr ptr22 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "dwKeyChoice")));
             Marshal.WriteInt32(ptr22, 1);
             IntPtr ptr23 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "pEphemeralAlgorithmOrSenderId")));
             encryptParam.rgEphemeralIdentifier[num2] = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER))));
             Marshal.WriteIntPtr(ptr23, encryptParam.rgEphemeralIdentifier[num2].DangerousGetHandle());
             source = Encoding.ASCII.GetBytes(cert_info.SubjectPublicKeyInfo.Algorithm.pszObjId);
             encryptParam.rgszEphemeralObjId[num2] = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(source.Length + 1));
             Marshal.Copy(source, 0, encryptParam.rgszEphemeralObjId[num2].DangerousGetHandle(), source.Length);
             ptr19 = new IntPtr(((long) encryptParam.rgEphemeralIdentifier[num2].DangerousGetHandle()) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId")));
             Marshal.WriteIntPtr(ptr19, encryptParam.rgszEphemeralObjId[num2].DangerousGetHandle());
             IntPtr ptr24 = new IntPtr(((long) encryptParam.rgEphemeralIdentifier[num2].DangerousGetHandle()) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters")));
             IntPtr ptr25 = new IntPtr(((long) ptr24) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData")));
             Marshal.WriteInt32(ptr25, (int) cert_info.SubjectPublicKeyInfo.Algorithm.Parameters.cbData);
             IntPtr ptr26 = new IntPtr(((long) ptr24) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData")));
             Marshal.WriteIntPtr(ptr26, cert_info.SubjectPublicKeyInfo.Algorithm.Parameters.pbData);
             IntPtr ptr27 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "cRecipientEncryptedKeys")));
             Marshal.WriteInt32(ptr27, 1);
             encryptParam.prgpEncryptedKey[num2] = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(Marshal.SizeOf(typeof(IntPtr))));
             IntPtr ptr28 = new IntPtr(((long) ptr) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "rgpRecipientEncryptedKeys")));
             Marshal.WriteIntPtr(ptr28, encryptParam.prgpEncryptedKey[num2].DangerousGetHandle());
             encryptParam.rgpEncryptedKey[num2] = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO))));
             Marshal.WriteIntPtr(encryptParam.prgpEncryptedKey[num2].DangerousGetHandle(), encryptParam.rgpEncryptedKey[num2].DangerousGetHandle());
             ptr17 = new IntPtr(((long) encryptParam.rgpEncryptedKey[num2].DangerousGetHandle()) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "cbSize")));
             Marshal.WriteInt32(ptr17, Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO)));
             IntPtr ptr29 = new IntPtr(((long) encryptParam.rgpEncryptedKey[num2].DangerousGetHandle()) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "RecipientPublicKey")));
             ptr25 = new IntPtr(((long) ptr29) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_BIT_BLOB), "cbData")));
             Marshal.WriteInt32(ptr25, (int) cert_info.SubjectPublicKeyInfo.PublicKey.cbData);
             ptr26 = new IntPtr(((long) ptr29) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_BIT_BLOB), "pbData")));
             Marshal.WriteIntPtr(ptr26, cert_info.SubjectPublicKeyInfo.PublicKey.pbData);
             IntPtr ptr30 = new IntPtr(((long) ptr29) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPT_BIT_BLOB), "cUnusedBits")));
             Marshal.WriteInt32(ptr30, (int) cert_info.SubjectPublicKeyInfo.PublicKey.cUnusedBits);
             IntPtr ptr31 = new IntPtr(((long) encryptParam.rgpEncryptedKey[num2].DangerousGetHandle()) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "RecipientId")));
             IntPtr ptr32 = new IntPtr(((long) ptr31) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ID), "dwIdChoice")));
             if (recipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier)
             {
                 Marshal.WriteInt32(ptr32, 2);
                 IntPtr ptr33 = new IntPtr(((long) ptr31) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ID), "Value")));
                 uint num7 = 0;
                 System.Security.Cryptography.SafeLocalAllocHandle pvData = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle;
                 if (!System.Security.Cryptography.CAPI.CAPISafe.CertGetCertificateContextProperty(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate), 20, pvData, ref num7))
                 {
                     throw new CryptographicException(Marshal.GetLastWin32Error());
                 }
                 pvData = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long) num7));
                 if (!System.Security.Cryptography.CAPI.CAPISafe.CertGetCertificateContextProperty(System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(certificate), 20, pvData, ref num7))
                 {
                     throw new CryptographicException(Marshal.GetLastWin32Error());
                 }
                 encryptParam.rgSubjectKeyIdentifier[num2] = pvData;
                 ptr25 = new IntPtr(((long) ptr33) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData")));
                 Marshal.WriteInt32(ptr25, (int) num7);
                 ptr26 = new IntPtr(((long) ptr33) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData")));
                 Marshal.WriteIntPtr(ptr26, pvData.DangerousGetHandle());
             }
             else
             {
                 Marshal.WriteInt32(ptr32, 1);
                 IntPtr ptr34 = new IntPtr(((long) ptr31) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ID), "Value")));
                 IntPtr ptr35 = new IntPtr(((long) ptr34) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ISSUER_SERIAL_NUMBER), "Issuer")));
                 ptr25 = new IntPtr(((long) ptr35) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData")));
                 Marshal.WriteInt32(ptr25, (int) cert_info.Issuer.cbData);
                 ptr26 = new IntPtr(((long) ptr35) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData")));
                 Marshal.WriteIntPtr(ptr26, cert_info.Issuer.pbData);
                 IntPtr ptr36 = new IntPtr(((long) ptr34) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CERT_ISSUER_SERIAL_NUMBER), "SerialNumber")));
                 ptr25 = new IntPtr(((long) ptr36) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "cbData")));
                 Marshal.WriteInt32(ptr25, (int) cert_info.SerialNumber.cbData);
                 ptr26 = new IntPtr(((long) ptr36) + ((long) Marshal.OffsetOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB), "pbData")));
                 Marshal.WriteIntPtr(ptr26, cert_info.SerialNumber.pbData);
             }
             num2++;
             ptr = new IntPtr(((long) ptr) + Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO)));
         }
     }
 }
        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));

            // 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));
        }
예제 #24
0
 // Perform a deep copy of a certificate collection
 private CmsRecipientCollection(CmsRecipientCollection other) {
     m_recipients = new ArrayList(other.m_recipients.Count);
     foreach (CmsRecipient recipient in other.m_recipients) {
         m_recipients.Add(new CmsRecipient(recipient.RecipientIdentifierType, new X509Certificate2(recipient.Certificate)));
     }
 }
예제 #25
0
        private static unsafe void SetCmsRecipientParams(CmsRecipientCollection           recipients, 
                                                         X509Certificate2Collection      certificates, 
                                                         CryptographicAttributeObjectCollection unprotectedAttributes,
                                                         AlgorithmIdentifier              contentEncryptionAlgorithm,
                                                         ref CMSG_ENCRYPT_PARAM           encryptParam) {
            checked {
                recipients = recipients.DeepCopy();
                certificates = new X509Certificate2Collection(certificates);

                int index = 0;
                uint[] recipientInfoTypes = new uint[recipients.Count];
                int cKeyAgree = 0;
                int reiSize = recipients.Count * Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCODE_INFO));
                int totalSize = reiSize;

                for (index = 0; index < recipients.Count; index++) {
                    recipientInfoTypes[index] = (uint) PkcsUtils.GetRecipientInfoType(recipients[index].Certificate);

                    if (recipientInfoTypes[index] == CAPI.CMSG_KEY_TRANS_RECIPIENT) {
                        totalSize += Marshal.SizeOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO));
                    }
                    else if (recipientInfoTypes[index] == CAPI.CMSG_KEY_AGREE_RECIPIENT) {
                        cKeyAgree++;
                        totalSize += Marshal.SizeOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO));
                    }
                    else {
                        throw new CryptographicException(CAPI.CRYPT_E_UNKNOWN_ALGO);
                    }
                }

                encryptParam.rgpRecipients = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(totalSize));
                encryptParam.rgCertEncoded = SafeLocalAllocHandle.InvalidHandle;
                encryptParam.rgUnprotectedAttr = SafeLocalAllocHandle.InvalidHandle;
                encryptParam.rgSubjectKeyIdentifier = new SafeLocalAllocHandle[recipients.Count];
                encryptParam.rgszObjId = new SafeLocalAllocHandle[recipients.Count];

                if (cKeyAgree > 0) {
                    encryptParam.rgszKeyWrapObjId = new SafeLocalAllocHandle[cKeyAgree];
                    encryptParam.rgKeyWrapAuxInfo = new SafeLocalAllocHandle[cKeyAgree];
                    encryptParam.rgEphemeralIdentifier = new SafeLocalAllocHandle[cKeyAgree];
                    encryptParam.rgszEphemeralObjId = new SafeLocalAllocHandle[cKeyAgree];
                    encryptParam.rgUserKeyingMaterial = new SafeLocalAllocHandle[cKeyAgree];
                    encryptParam.prgpEncryptedKey = new SafeLocalAllocHandle[cKeyAgree];
                    encryptParam.rgpEncryptedKey = new SafeLocalAllocHandle[cKeyAgree];
                }

                // Create encode certs array.
                if (certificates.Count > 0) {
                    encryptParam.rgCertEncoded = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(certificates.Count * Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB))));
                    for (index = 0; index < certificates.Count; index++) {
                        CAPI.CERT_CONTEXT pCertContext = (CAPI.CERT_CONTEXT) Marshal.PtrToStructure(X509Utils.GetCertContext(certificates[index]).DangerousGetHandle(), typeof(CAPI.CERT_CONTEXT));
                        CAPI.CRYPTOAPI_BLOB * pBlob = (CAPI.CRYPTOAPI_BLOB *) new IntPtr((long) encryptParam.rgCertEncoded.DangerousGetHandle() + 
                                                                                            (index * Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB))));
                        pBlob->cbData = pCertContext.cbCertEncoded;
                        pBlob->pbData = pCertContext.pbCertEncoded;
                    }
                }

                // Create unprotected attributes array.
                if (unprotectedAttributes.Count > 0) {
                    encryptParam.rgUnprotectedAttr = new SafeLocalAllocHandle(PkcsUtils.CreateCryptAttributes(unprotectedAttributes));
                }

                // pKeyInfo = CMSG_ENVELOPED_ENCODE_INFO.rgCmsRecipients
                cKeyAgree = 0;
                IntPtr pKeyInfo = new IntPtr((long) encryptParam.rgpRecipients.DangerousGetHandle() + reiSize);
                for (index = 0; index < recipients.Count; index++) {
                    CmsRecipient recipient = recipients[index];
                    X509Certificate2 certificate = recipient.Certificate;
                    CAPI.CERT_CONTEXT pCertContext = (CAPI.CERT_CONTEXT) Marshal.PtrToStructure(X509Utils.GetCertContext(certificate).DangerousGetHandle(), typeof(CAPI.CERT_CONTEXT));
                    CAPI.CERT_INFO certInfo = (CAPI.CERT_INFO) Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO));

                    CAPI.CMSG_RECIPIENT_ENCODE_INFO * pEncodeInfo = (CAPI.CMSG_RECIPIENT_ENCODE_INFO *) new IntPtr((long) encryptParam.rgpRecipients.DangerousGetHandle() + 
                                                                                                                    (index * Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCODE_INFO))));
                    // CMSG_RECIPIENT_ENCODE_INFO.dwRecipientChoice
                    pEncodeInfo->dwRecipientChoice = (uint) recipientInfoTypes[index];

                    // CMSG_RECIPIENT_ENCODE_INFO.pRecipientInfo (pKeyTrans or pKeyAgree)
                    pEncodeInfo->pRecipientInfo = pKeyInfo;

                    if (recipientInfoTypes[index] == CAPI.CMSG_KEY_TRANS_RECIPIENT) {
                        // Fill in CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO.

                        // cbSize
                        IntPtr pcbSize = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "cbSize"));
                        Marshal.WriteInt32(pcbSize, Marshal.SizeOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO)));

                        // KeyEncryptionAlgorithm
                        IntPtr pKeyEncryptionAlgorithm = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "KeyEncryptionAlgorithm"));

                        byte[] objId = Encoding.ASCII.GetBytes(certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId);
                        encryptParam.rgszObjId[index] = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(objId.Length + 1));
                        Marshal.Copy(objId, 0, encryptParam.rgszObjId[index].DangerousGetHandle(), objId.Length);

                        // KeyEncryptionAlgorithm.pszObjId
                        IntPtr pszObjId = new IntPtr((long) pKeyEncryptionAlgorithm + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId"));
                        Marshal.WriteIntPtr(pszObjId, encryptParam.rgszObjId[index].DangerousGetHandle());

                        // KeyEncryptionAlgorithm.Parameters
                        IntPtr pParameters = new IntPtr((long) pKeyEncryptionAlgorithm + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters"));

                        // KeyEncryptionAlgorithm.Parameters.cbData
                        IntPtr pcbData = new IntPtr((long) pParameters + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                        Marshal.WriteInt32(pcbData, (int) certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.cbData);

                        // KeyEncryptionAlgorithm.Parameters.pbData
                        IntPtr ppbData = new IntPtr((long) pParameters + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                        Marshal.WriteIntPtr(ppbData, certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.pbData);

                        // Skip pvKeyEncryptionAuxInfo
                        // Skip hCryptProv

                        // RecipientPublicKey
                        IntPtr pRecipientPublicKey = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "RecipientPublicKey"));

                        // RecipientPublicKey.cbData
                        pcbData = new IntPtr((long) pRecipientPublicKey + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cbData"));
                        Marshal.WriteInt32(pcbData, (int) certInfo.SubjectPublicKeyInfo.PublicKey.cbData);

                        // RecipientPublicKey.pbData
                        ppbData = new IntPtr((long) pRecipientPublicKey + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "pbData"));
                        Marshal.WriteIntPtr(ppbData, certInfo.SubjectPublicKeyInfo.PublicKey.pbData);

                        // RecipientPublicKey.cUnusedBits
                        IntPtr pcUnusedBIts = new IntPtr((long) pRecipientPublicKey + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cUnusedBits"));
                        Marshal.WriteInt32(pcUnusedBIts, (int) certInfo.SubjectPublicKeyInfo.PublicKey.cUnusedBits);

                        // RecipientId
                        IntPtr pRecipientId = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO), "RecipientId"));
                        if (recipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier) {
                            uint cbData = 0;
                            SafeLocalAllocHandle pbData = SafeLocalAllocHandle.InvalidHandle;
                            if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate),
                                                                                    CAPI.CERT_KEY_IDENTIFIER_PROP_ID,
                                                                                    pbData,
                                                                                    ref cbData))
                                throw new CryptographicException(Marshal.GetLastWin32Error());

                            pbData = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(cbData));

                            if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate),
                                                                                    CAPI.CERT_KEY_IDENTIFIER_PROP_ID,
                                                                                    pbData,
                                                                                    ref cbData))
                                throw new CryptographicException(Marshal.GetLastWin32Error());

                            encryptParam.rgSubjectKeyIdentifier[index] = pbData;

                            // RecipientId.dwIdChoice
                            IntPtr pdwIdChoice = new IntPtr((long) pRecipientId + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ID), "dwIdChoice"));
                            Marshal.WriteInt32(pdwIdChoice, (int) CAPI.CERT_ID_KEY_IDENTIFIER);

                            // RecipientId.KeyId
                            IntPtr pKeyId = new IntPtr((long) pRecipientId + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value"));

                            // RecipientId.KeyId.cbData
                            pcbData = new IntPtr((long) pKeyId + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                            Marshal.WriteInt32(pcbData, (int) cbData);

                            // RecipientId.KeyId.pbData
                            ppbData = new IntPtr((long) pKeyId + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                            Marshal.WriteIntPtr(ppbData, pbData.DangerousGetHandle());
                        }
                        else {
                            // RecipientId.dwIdChoice
                            IntPtr pdwIdChoice = new IntPtr((long) pRecipientId + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ID), "dwIdChoice"));
                            Marshal.WriteInt32(pdwIdChoice, (int) CAPI.CERT_ID_ISSUER_SERIAL_NUMBER);

                            // RecipientId.IssuerSerialNumber
                            IntPtr pIssuerSerialNumber = new IntPtr((long) pRecipientId + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value"));

                            // RecipientId.IssuerSerialNumber.Issuer
                            IntPtr pIssuer = new IntPtr((long) pIssuerSerialNumber + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "Issuer"));

                            // RecipientId.IssuerSerialNumber.Issuer.cbData
                            pcbData = new IntPtr((long) pIssuer + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                            Marshal.WriteInt32(pcbData, (int) certInfo.Issuer.cbData);

                            // RecipientId.IssuerSerialNumber.Issuer.pbData
                            ppbData = new IntPtr((long) pIssuer + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                            Marshal.WriteIntPtr(ppbData, certInfo.Issuer.pbData);

                            // RecipientId.IssuerSerialNumber.SerialNumber
                            IntPtr pSerialNumber = new IntPtr((long) pIssuerSerialNumber + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "SerialNumber"));

                            // RecipientId.IssuerSerialNumber.SerialNumber.cbData
                            pcbData = new IntPtr((long) pSerialNumber + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                            Marshal.WriteInt32(pcbData, (int) certInfo.SerialNumber.cbData);

                            // RecipientId.IssuerSerialNumber.SerialNumber.pbData
                            ppbData = new IntPtr((long) pSerialNumber + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                            Marshal.WriteIntPtr(ppbData, certInfo.SerialNumber.pbData);
                        }
                        pKeyInfo = new IntPtr((long) pKeyInfo + Marshal.SizeOf(typeof(CAPI.CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO)));
                    }
                    else if (recipientInfoTypes[index] == CAPI.CMSG_KEY_AGREE_RECIPIENT) {
                        // Fill in CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO.

                        // cbSize
                        IntPtr pcbSize = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "cbSize"));
                        Marshal.WriteInt32(pcbSize, Marshal.SizeOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO)));

                        // KeyEncryptionAlgorithm
                        IntPtr pKeyEncryptionAlgorithm = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "KeyEncryptionAlgorithm"));

                        byte[] objId = Encoding.ASCII.GetBytes(CAPI.szOID_RSA_SMIMEalgESDH);
                        encryptParam.rgszObjId[index] = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(objId.Length + 1));
                        Marshal.Copy(objId, 0, encryptParam.rgszObjId[index].DangerousGetHandle(), objId.Length);

                        // KeyEncryptionAlgorithm.pszObjId
                        IntPtr pszObjId = new IntPtr((long) pKeyEncryptionAlgorithm + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId"));
                        Marshal.WriteIntPtr(pszObjId, encryptParam.rgszObjId[index].DangerousGetHandle());

                        // Skip KeyEncryptionAlgorithm.Parameters
                        // Skip pvKeyEncryptionAuxInfo

                        // KeyWrapAlgorithm
                        IntPtr pKeyWrapAlgorithm = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "KeyWrapAlgorithm"));

                        uint algId = X509Utils.OidToAlgId(contentEncryptionAlgorithm.Oid.Value);
                        if (algId == CAPI.CALG_RC2) {
                            objId = Encoding.ASCII.GetBytes(CAPI.szOID_RSA_SMIMEalgCMSRC2wrap);
                        }
                        else {
                            objId = Encoding.ASCII.GetBytes(CAPI.szOID_RSA_SMIMEalgCMS3DESwrap);
                        }
                        encryptParam.rgszKeyWrapObjId[cKeyAgree] = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(objId.Length + 1));
                        Marshal.Copy(objId, 0, encryptParam.rgszKeyWrapObjId[cKeyAgree].DangerousGetHandle(), objId.Length);

                        // KeyWrapAlgorithm.pszObjId
                        pszObjId = new IntPtr((long) pKeyWrapAlgorithm + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId"));
                        Marshal.WriteIntPtr(pszObjId, encryptParam.rgszKeyWrapObjId[cKeyAgree].DangerousGetHandle());

                        // Skip KeyWrapAlgorithm.Parameters

                        // Fill in pvKeyWrapAuxInfo for RC2.
                        if (algId == CAPI.CALG_RC2) {
                            IntPtr pKeyWrapAuxInfo = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "pvKeyWrapAuxInfo"));
                            Marshal.WriteIntPtr(pKeyWrapAuxInfo, encryptParam.pvEncryptionAuxInfo.DangerousGetHandle());
                        }

                        // Skip hCryptProv
                        // Skip dwKeySpec

                        // dwKeyChoice
                        IntPtr pdwKeyChoice = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "dwKeyChoice"));
                        Marshal.WriteInt32(pdwKeyChoice, (int) CAPI.CMSG_KEY_AGREE_EPHEMERAL_KEY_CHOICE);

                        // pEphemeralAlgorithm
                        IntPtr pEphemeralAlgorithm = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "pEphemeralAlgorithmOrSenderId"));
                        encryptParam.rgEphemeralIdentifier[cKeyAgree] = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER))));
                        Marshal.WriteIntPtr(pEphemeralAlgorithm, encryptParam.rgEphemeralIdentifier[cKeyAgree].DangerousGetHandle());

                        // pEphemeralAlgorithm.pszObjId
                        objId = Encoding.ASCII.GetBytes(certInfo.SubjectPublicKeyInfo.Algorithm.pszObjId);
                        encryptParam.rgszEphemeralObjId[cKeyAgree] = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(objId.Length + 1));
                        Marshal.Copy(objId, 0, encryptParam.rgszEphemeralObjId[cKeyAgree].DangerousGetHandle(), objId.Length);

                        pszObjId = new IntPtr((long) encryptParam.rgEphemeralIdentifier[cKeyAgree].DangerousGetHandle() + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "pszObjId"));
                        Marshal.WriteIntPtr(pszObjId, encryptParam.rgszEphemeralObjId[cKeyAgree].DangerousGetHandle());

                        // pEphemeralAlgorithm.Parameters
                        IntPtr pParameters = new IntPtr((long) encryptParam.rgEphemeralIdentifier[cKeyAgree].DangerousGetHandle() + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER), "Parameters"));

                        // pEphemeralAlgorithm.Parameters.cbData
                        IntPtr pcbData = new IntPtr((long) pParameters + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                        Marshal.WriteInt32(pcbData, (int) certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.cbData);

                        // pEphemeralAlgorithm.Parameters.pbData
                        IntPtr ppbData = new IntPtr((long) pParameters + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                        Marshal.WriteIntPtr(ppbData, certInfo.SubjectPublicKeyInfo.Algorithm.Parameters.pbData);

                        // Skip UserKeyingMaterial

                        // cRecipientEncryptedKeys
                        IntPtr pcRecipientEncryptedKeys = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "cRecipientEncryptedKeys"));
                        Marshal.WriteInt32(pcRecipientEncryptedKeys, 1);

                        // rgpRecipientEncryptedKeys
                        encryptParam.prgpEncryptedKey[cKeyAgree] = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(IntPtr))));
                        IntPtr prgpRecipientEncryptedKeys = new IntPtr((long) pKeyInfo + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO), "rgpRecipientEncryptedKeys"));
                        Marshal.WriteIntPtr(prgpRecipientEncryptedKeys, encryptParam.prgpEncryptedKey[cKeyAgree].DangerousGetHandle());
                        encryptParam.rgpEncryptedKey[cKeyAgree] = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO))));
                        Marshal.WriteIntPtr(encryptParam.prgpEncryptedKey[cKeyAgree].DangerousGetHandle(), encryptParam.rgpEncryptedKey[cKeyAgree].DangerousGetHandle());

                        // rgpRecipientEncryptedKeys.cbSize
                        pcbSize = new IntPtr((long) encryptParam.rgpEncryptedKey[cKeyAgree].DangerousGetHandle() + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "cbSize"));
                        Marshal.WriteInt32(pcbSize, Marshal.SizeOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO)));

                        // rgpRecipientEncryptedKeys.RecipientPublicKey
                        IntPtr pRecipientPublicKey = new IntPtr((long) encryptParam.rgpEncryptedKey[cKeyAgree].DangerousGetHandle() + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "RecipientPublicKey"));

                        // rgpRecipientEncryptedKeys.RecipientPublicKey.cbData
                        pcbData = new IntPtr((long) pRecipientPublicKey + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cbData"));
                        Marshal.WriteInt32(pcbData, (int) certInfo.SubjectPublicKeyInfo.PublicKey.cbData);

                        // rgpRecipientEncryptedKeys.RecipientPublicKey.pbData
                        ppbData = new IntPtr((long) pRecipientPublicKey + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "pbData"));
                        Marshal.WriteIntPtr(ppbData, certInfo.SubjectPublicKeyInfo.PublicKey.pbData);

                        // rgpRecipientEncryptedKeys.RecipientPublicKey.cUnusedBits
                        IntPtr pcUnusedBits = new IntPtr((long) pRecipientPublicKey + (long) Marshal.OffsetOf(typeof(CAPI.CRYPT_BIT_BLOB), "cUnusedBits"));
                        Marshal.WriteInt32(pcUnusedBits, (int) certInfo.SubjectPublicKeyInfo.PublicKey.cUnusedBits);                    

                        // rgpRecipientEncryptedKeys.RecipientId
                        IntPtr pRecipientId = new IntPtr((long) encryptParam.rgpEncryptedKey[cKeyAgree].DangerousGetHandle() + (long) Marshal.OffsetOf(typeof(CAPI.CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO), "RecipientId"));

                        // rgpRecipientEncryptedKeys.RecipientId.dwIdChoice
                        IntPtr pdwIdChoice = new IntPtr((long) pRecipientId + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ID), "dwIdChoice"));

                        if (recipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier) {
                            Marshal.WriteInt32(pdwIdChoice, (int) CAPI.CERT_ID_KEY_IDENTIFIER);

                            // rgpRecipientEncryptedKeys.RecipientId.KeyId
                            IntPtr pKeyId = new IntPtr((long) pRecipientId + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value"));

                            uint cbKeyId = 0;
                            SafeLocalAllocHandle pbKeyId = SafeLocalAllocHandle.InvalidHandle;
                            if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate),
                                                                                    CAPI.CERT_KEY_IDENTIFIER_PROP_ID,
                                                                                    pbKeyId,
                                                                                    ref cbKeyId))
                                throw new CryptographicException(Marshal.GetLastWin32Error());

                            pbKeyId = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(cbKeyId));
                            if (!CAPI.CAPISafe.CertGetCertificateContextProperty(X509Utils.GetCertContext(certificate),
                                                                                    CAPI.CERT_KEY_IDENTIFIER_PROP_ID,
                                                                                    pbKeyId,
                                                                                    ref cbKeyId))
                                throw new CryptographicException(Marshal.GetLastWin32Error());

                            encryptParam.rgSubjectKeyIdentifier[cKeyAgree] = pbKeyId;

                            // rgpRecipientEncryptedKeys.RecipientId.KeyId.cbData
                            pcbData = new IntPtr((long) pKeyId + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                            Marshal.WriteInt32(pcbData, (int) cbKeyId);

                            // rgpRecipientEncryptedKeys.RecipientId.KeyId.pbData
                            ppbData = new IntPtr((long) pKeyId + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                            Marshal.WriteIntPtr(ppbData, pbKeyId.DangerousGetHandle());
                        }
                        else {
                            Marshal.WriteInt32(pdwIdChoice, (int) CAPI.CERT_ID_ISSUER_SERIAL_NUMBER);

                            // rgpRecipientEncryptedKeys.RecipientId.IssuerSerialNumber
                            IntPtr pIssuerSerial = new IntPtr((long) pRecipientId + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ID), "Value"));

                            // rgpRecipientEncryptedKeys.RecipientId.IssuerSerialNumber.Issuer
                            IntPtr pIssuer = new IntPtr((long) pIssuerSerial + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "Issuer"));

                            // rgpRecipientEncryptedKeys.RecipientId.IssuerSerialNumber.Issuer.cbData
                            pcbData = new IntPtr((long) pIssuer + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                            Marshal.WriteInt32(pcbData, (int) certInfo.Issuer.cbData);

                            // rgpRecipientEncryptedKeys.RecipientId.IssuerSerialNumber.Issuer.pbData
                            ppbData = new IntPtr((long) pIssuer + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                            Marshal.WriteIntPtr(ppbData, certInfo.Issuer.pbData);

                            // rgpRecipientEncryptedKeys.RecipientId.IssuerSerialNumber.SerialNumber
                            IntPtr pSerialNumber = new IntPtr((long) pIssuerSerial + (long) Marshal.OffsetOf(typeof(CAPI.CERT_ISSUER_SERIAL_NUMBER), "SerialNumber"));

                            // rgpRecipientEncryptedKeys.RecipientId.IssuerSerialNumber.SerialNumber.cbData
                            pcbData = new IntPtr((long) pSerialNumber + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "cbData"));
                            Marshal.WriteInt32(pcbData, (int) certInfo.SerialNumber.cbData);

                            // rgpRecipientEncryptedKeys.RecipientId.IssuerSerialNumber.SerialNumber.pbData
                            ppbData = new IntPtr((long) pSerialNumber + (long) Marshal.OffsetOf(typeof(CAPI.CRYPTOAPI_BLOB), "pbData"));
                            Marshal.WriteIntPtr(ppbData, certInfo.SerialNumber.pbData);
                        }

                        // Bump key agree count.
                        cKeyAgree++;
                        pKeyInfo = new IntPtr((long) pKeyInfo + Marshal.SizeOf(typeof(CAPI.CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO)));
                    }
                    else {
                        // Should never get here!
                        Debug.Assert(false);
                    }
                }
            }
        }
예제 #26
0
        private unsafe void EncryptContent (CmsRecipientCollection recipients) {
            CMSG_ENCRYPT_PARAM encryptParam = new CMSG_ENCRYPT_PARAM();

            if (recipients.Count < 1)
                throw new CryptographicException(CAPI.CRYPT_E_RECIPIENT_NOT_FOUND);

            foreach (CmsRecipient recipient in recipients) {
                if (recipient.Certificate == null)
                    throw new ArgumentNullException(SecurityResources.GetResourceString("Cryptography_Cms_RecipientCertificateNotFound"));

                if ((PkcsUtils.GetRecipientInfoType(recipient.Certificate) == RecipientInfoType.KeyAgreement) ||
                    (recipient.RecipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier))
                    encryptParam.useCms = true;
            }

            if (!encryptParam.useCms) {
                if (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 encodeInfo = new CAPI.CMSG_ENVELOPED_ENCODE_INFO(Marshal.SizeOf(typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO)));
            SafeLocalAllocHandle ceei = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO))));

            SetCspParams(this.ContentEncryptionAlgorithm, ref encryptParam);
            encodeInfo.ContentEncryptionAlgorithm.pszObjId = this.ContentEncryptionAlgorithm.Oid.Value;
            //encodeInfo.hCryptProv = encryptParam.safeCryptProvHandle.DangerousGetHandle(); 
            if (encryptParam.pvEncryptionAuxInfo != null && !encryptParam.pvEncryptionAuxInfo.IsInvalid) {
                encodeInfo.pvEncryptionAuxInfo = encryptParam.pvEncryptionAuxInfo.DangerousGetHandle();
            }

            encodeInfo.cRecipients = (uint) recipients.Count;

            List<SafeCertContextHandle> certContexts = null;
            if (encryptParam.useCms) {
                SetCmsRecipientParams(recipients, this.Certificates, this.UnprotectedAttributes, this.ContentEncryptionAlgorithm, ref encryptParam);
                encodeInfo.rgCmsRecipients = encryptParam.rgpRecipients.DangerousGetHandle();
                if (encryptParam.rgCertEncoded != null && !encryptParam.rgCertEncoded.IsInvalid) {
                    encodeInfo.cCertEncoded = (uint) this.Certificates.Count;
                    encodeInfo.rgCertEncoded = encryptParam.rgCertEncoded.DangerousGetHandle();
                }
                if (encryptParam.rgUnprotectedAttr != null && !encryptParam.rgUnprotectedAttr.IsInvalid) {
                    encodeInfo.cUnprotectedAttr = (uint) this.UnprotectedAttributes.Count;
                    encodeInfo.rgUnprotectedAttr = encryptParam.rgUnprotectedAttr.DangerousGetHandle();
                }
            }
            else {
                SetPkcs7RecipientParams(recipients, ref encryptParam, out certContexts);
                encodeInfo.rgpRecipients = encryptParam.rgpRecipients.DangerousGetHandle();
            }

            Marshal.StructureToPtr(encodeInfo, ceei.DangerousGetHandle(), false);

            try {
                SafeCryptMsgHandle safeCryptMsgHandle = CAPI.CryptMsgOpenToEncode(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                                  0,
                                                                                  CAPI.CMSG_ENVELOPED,
                                                                                  ceei.DangerousGetHandle(),
                                                                                  this.ContentInfo.ContentType.Value,
                                                                                  IntPtr.Zero);
                if (safeCryptMsgHandle == null || safeCryptMsgHandle.IsInvalid)
                    throw new CryptographicException(Marshal.GetLastWin32Error());

                if (m_safeCryptMsgHandle != null && !m_safeCryptMsgHandle.IsInvalid) {
                    m_safeCryptMsgHandle.Dispose();
                }

                m_safeCryptMsgHandle = safeCryptMsgHandle;
            }
            finally {
                Marshal.DestroyStructure(ceei.DangerousGetHandle(), typeof(CAPI.CMSG_ENVELOPED_ENCODE_INFO));
                ceei.Dispose();
            }

            byte[] encodedContent = new byte[0];
            if (String.Compare(this.ContentInfo.ContentType.Value, CAPI.szOID_RSA_data, StringComparison.OrdinalIgnoreCase) == 0) {
                byte[] content = this.ContentInfo.Content;
                fixed (byte * pbContent = content) {
                    CAPI.CRYPTOAPI_BLOB dataBlob = new CAPI.CRYPTOAPI_BLOB();
                    dataBlob.cbData = (uint) content.Length;
                    dataBlob.pbData = new IntPtr(pbContent);
                    if (!CAPI.EncodeObject(new IntPtr(CAPI.X509_OCTET_STRING), new IntPtr(&dataBlob), out encodedContent))
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                }
            }
            else {
                encodedContent = this.ContentInfo.Content;
            }
            if (encodedContent.Length > 0) {
                if (!CAPI.CAPISafe.CryptMsgUpdate(m_safeCryptMsgHandle, encodedContent, (uint) encodedContent.Length, true))
                    throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            // Keep alive
            GC.KeepAlive(encryptParam);
            GC.KeepAlive(recipients);
            GC.KeepAlive(certContexts);
        }
예제 #27
0
        private static unsafe void SetPkcs7RecipientParams (CmsRecipientCollection recipients,
                                                            ref CMSG_ENCRYPT_PARAM encryptParam,
                                                            out List<SafeCertContextHandle> certContexts) {
            int index = 0;

            // Must read recipients.Count only once to avoid a security issue where another thread
            // could add objects to recipients after we allocate the native buffer, but while we're
            // iterating. That could lead to a buffer overflow
            int numRecipients = recipients.Count;

            certContexts = new List<SafeCertContextHandle>();

            checked {
                uint totalSize = (uint)numRecipients * (uint)Marshal.SizeOf(typeof(IntPtr));
                encryptParam.rgpRecipients = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(totalSize));

                IntPtr pCertInfo = encryptParam.rgpRecipients.DangerousGetHandle();

                for (index = 0; index < numRecipients; index++) {
                    SafeCertContextHandle certContext = X509Utils.GetCertContext(recipients[index].Certificate);
                    certContexts.Add(certContext);
                    IntPtr dangerousCertContextHandle = certContext.DangerousGetHandle();
                    CAPI.CERT_CONTEXT pCertContext = (CAPI.CERT_CONTEXT) Marshal.PtrToStructure(dangerousCertContextHandle, typeof(CAPI.CERT_CONTEXT));

                    Marshal.WriteIntPtr(pCertInfo, pCertContext.pCertInfo);
                    pCertInfo = new IntPtr((long) pCertInfo + Marshal.SizeOf(typeof(IntPtr)));
                }
                Debug.Assert(index == totalSize / (uint)Marshal.SizeOf(typeof(IntPtr)));
            }
        }
예제 #28
0
 internal CmsRecipientEnumerator(CmsRecipientCollection recipients)
 {
     m_recipients = recipients;
     m_current    = -1;
 }
        private static void AssertEquals(CmsRecipientCollection c, IList<CmsRecipient> expected)
        {
            Assert.Equal(expected.Count, c.Count);

            for (int i = 0; i < c.Count; i++)
            {
                Assert.Equal(expected[i], c[i]);
            }

            int index = 0;
            foreach (CmsRecipient a in c)
            {
                Assert.Equal(expected[index++], a);
            }
            Assert.Equal(c.Count, index);

            ValidateEnumerator(c.GetEnumerator(), expected);
            ValidateEnumerator(((ICollection)c).GetEnumerator(), expected);

            {
                CmsRecipient[] dumped = new CmsRecipient[c.Count + 3];
                c.CopyTo(dumped, 2);
                Assert.Equal(null, dumped[0]);
                Assert.Equal(null, dumped[1]);
                Assert.Equal(null, dumped[dumped.Length - 1]);
                Assert.Equal<CmsRecipient>(expected, dumped.Skip(2).Take(c.Count));
            }

            {
                CmsRecipient[] dumped = new CmsRecipient[c.Count + 3];
                ((ICollection)c).CopyTo(dumped, 2);
                Assert.Equal(null, dumped[0]);
                Assert.Equal(null, dumped[1]);
                Assert.Equal(null, dumped[dumped.Length - 1]);
                Assert.Equal<CmsRecipient>(expected, dumped.Skip(2).Take(c.Count));
            }
        }
        Stream Envelope(RealCmsRecipientCollection recipients, Stream content)
        {
            var algorithm = GetPreferredEncryptionAlgorithm(recipients);

            return(Envelope(recipients, content, algorithm));
        }
 public static void Twoary_Negative()
 {
     object ignore;
     Assert.Throws<NullReferenceException>(() => ignore = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, null));
 }
예제 #32
0
		public void Encrypt (CmsRecipientCollection recipients)
		{
			if (recipients == null)
				throw new ArgumentNullException ("recipients");
			// ? foreach on Encrypt CmsRecipient ?
		}
 private static void SetPkcs7RecipientParams(CmsRecipientCollection recipients, ref CMSG_ENCRYPT_PARAM encryptParam, out List<System.Security.Cryptography.SafeCertContextHandle> certContexts)
 {
     int num = 0;
     int count = recipients.Count;
     certContexts = new List<System.Security.Cryptography.SafeCertContextHandle>();
     uint num3 = (uint) (count * Marshal.SizeOf(typeof(IntPtr)));
     encryptParam.rgpRecipients = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long) num3));
     IntPtr ptr = encryptParam.rgpRecipients.DangerousGetHandle();
     for (num = 0; num < count; num++)
     {
         System.Security.Cryptography.SafeCertContextHandle certContext = System.Security.Cryptography.X509Certificates.X509Utils.GetCertContext(recipients[num].Certificate);
         certContexts.Add(certContext);
         System.Security.Cryptography.CAPI.CERT_CONTEXT cert_context = (System.Security.Cryptography.CAPI.CERT_CONTEXT) Marshal.PtrToStructure(certContext.DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CERT_CONTEXT));
         Marshal.WriteIntPtr(ptr, cert_context.pCertInfo);
         ptr = new IntPtr(((long) ptr) + Marshal.SizeOf(typeof(IntPtr)));
     }
 }
예제 #34
0
            //
            // This returns an allocated native memory block. Its lifetime (and that of any allocated subblocks it may point to) is that of "hb". 
            //
            private static unsafe CMSG_ENVELOPED_ENCODE_INFO* CreateCmsEnvelopedEncodeInfo(CmsRecipientCollection recipients, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes, HeapBlockRetainer hb)
            {
                CMSG_ENVELOPED_ENCODE_INFO* pEnvelopedEncodeInfo = (CMSG_ENVELOPED_ENCODE_INFO*)(hb.Alloc(sizeof(CMSG_ENVELOPED_ENCODE_INFO)));
                pEnvelopedEncodeInfo->cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO);
                pEnvelopedEncodeInfo->hCryptProv = IntPtr.Zero;

                string algorithmOidValue = contentEncryptionAlgorithm.Oid.Value;
                pEnvelopedEncodeInfo->ContentEncryptionAlgorithm.pszObjId = hb.AllocAsciiString(algorithmOidValue);

                // Desktop compat: Though it seems like we could copy over the contents of contentEncryptionAlgorithm.Parameters, that property is for retrieving information from decoded Cms's only, and it 
                // massages the raw data so it wouldn't be usable here anyway. To hammer home that fact, the EncryptedCms constructer rather rudely forces contentEncryptionAlgorithm.Parameters to be the empty array.
                pEnvelopedEncodeInfo->ContentEncryptionAlgorithm.Parameters.cbData = 0;
                pEnvelopedEncodeInfo->ContentEncryptionAlgorithm.Parameters.pbData = IntPtr.Zero;

                pEnvelopedEncodeInfo->pvEncryptionAuxInfo = GenerateEncryptionAuxInfoIfNeeded(contentEncryptionAlgorithm, hb);

                int numRecipients = recipients.Count;
                pEnvelopedEncodeInfo->cRecipients = numRecipients;
                pEnvelopedEncodeInfo->rgpRecipients = IntPtr.Zero;

                CMSG_RECIPIENT_ENCODE_INFO* rgCmsRecipients = (CMSG_RECIPIENT_ENCODE_INFO*)(hb.Alloc(numRecipients, sizeof(CMSG_RECIPIENT_ENCODE_INFO)));
                for (int index = 0; index < numRecipients; index++)
                {
                    rgCmsRecipients[index] = EncodeRecipientInfo(recipients[index], contentEncryptionAlgorithm, hb);
                }
                pEnvelopedEncodeInfo->rgCmsRecipients = rgCmsRecipients;

                int numCertificates = originatorCerts.Count;
                pEnvelopedEncodeInfo->cCertEncoded = numCertificates;
                pEnvelopedEncodeInfo->rgCertEncoded = null;
                if (numCertificates != 0)
                {
                    DATA_BLOB* pCertEncoded = (DATA_BLOB*)(hb.Alloc(numCertificates, sizeof(DATA_BLOB)));
                    for (int i = 0; i < numCertificates; i++)
                    {
                        byte[] certEncoded = originatorCerts[i].Export(X509ContentType.Cert);
                        pCertEncoded[i].cbData = (uint)(certEncoded.Length);
                        pCertEncoded[i].pbData = hb.AllocBytes(certEncoded);
                    }
                    pEnvelopedEncodeInfo->rgCertEncoded = pCertEncoded;
                }

                pEnvelopedEncodeInfo->cCrlEncoded = 0;
                pEnvelopedEncodeInfo->rgCrlEncoded = null;

                pEnvelopedEncodeInfo->cAttrCertEncoded = 0;
                pEnvelopedEncodeInfo->rgAttrCertEncoded = null;

                int numUnprotectedAttributes = unprotectedAttributes.Count;
                pEnvelopedEncodeInfo->cUnprotectedAttr = numUnprotectedAttributes;
                pEnvelopedEncodeInfo->rgUnprotectedAttr = null;
                if (numUnprotectedAttributes != 0)
                {
                    CRYPT_ATTRIBUTE* pCryptAttribute = (CRYPT_ATTRIBUTE*)(hb.Alloc(numUnprotectedAttributes, sizeof(CRYPT_ATTRIBUTE)));
                    for (int i = 0; i < numUnprotectedAttributes; i++)
                    {
                        CryptographicAttributeObject attribute = unprotectedAttributes[i];
                        pCryptAttribute[i].pszObjId = hb.AllocAsciiString(attribute.Oid.Value);
                        AsnEncodedDataCollection values = attribute.Values;
                        int numValues = values.Count;
                        pCryptAttribute[i].cValue = numValues;
                        DATA_BLOB* pValues = (DATA_BLOB*)(hb.Alloc(numValues, sizeof(DATA_BLOB)));
                        for (int j = 0; j < numValues; j++)
                        {
                            byte[] rawData = values[j].RawData;
                            pValues[j].cbData = (uint)(rawData.Length);
                            pValues[j].pbData = hb.AllocBytes(rawData);
                        }
                        pCryptAttribute[i].rgValue = pValues;
                    }
                    pEnvelopedEncodeInfo->rgUnprotectedAttr = pCryptAttribute;
                }

                return pEnvelopedEncodeInfo;
            }
 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);
 }
예제 #36
0
        internal static string Encrypt(byte[] contentBytes, CmsMessageRecipient[] recipients, SessionState sessionState, out ErrorRecord error)
        {
            error = null;

            if ((contentBytes == null) || (contentBytes.Length == 0))
            {
                return String.Empty;
            }

            // After review with the crypto board, NIST_AES256_CBC is more appropriate
            // than .NET's default 3DES. Also, when specified, uses szOID_RSAES_OAEP for key
            // encryption to prevent padding attacks.
            const string szOID_NIST_AES256_CBC = "2.16.840.1.101.3.4.1.42";

            ContentInfo content = new ContentInfo(contentBytes);
            EnvelopedCms cms = new EnvelopedCms(content,
                new AlgorithmIdentifier(
                    Oid.FromOidValue(szOID_NIST_AES256_CBC, OidGroup.EncryptionAlgorithm)));

            CmsRecipientCollection recipientCollection = new CmsRecipientCollection();
            foreach (CmsMessageRecipient recipient in recipients)
            {
                // Resolve the recipient, if it hasn't been done yet.
                if ((recipient.Certificates != null) && (recipient.Certificates.Count == 0))
                {
                    recipient.Resolve(sessionState, ResolutionPurpose.Encryption, out error);
                }

                if (error != null)
                {
                    return null;
                }

                foreach (X509Certificate2 certificate in recipient.Certificates)
                {
                    recipientCollection.Add(new CmsRecipient(certificate));
                }
            }

            cms.Encrypt(recipientCollection);

            byte[] encodedBytes = cms.Encode();
            string encodedContent = CmsUtils.GetAsciiArmor(encodedBytes);
            return encodedContent;
        }
예제 #37
0
        /// <summary>
        /// Encrypts the message and envelopes it for multiple recipients.
        /// </summary>
        /// <param name="recipients">An object containing the recipients' certificates with public keys.</param>
        /// <example>
        /// <code>
        /// [C#]
        /// 
        /// CmsRecipientCollection recipients = new CmsRecipientCollection();
        /// 
        /// recipients.Add(new CmsRecipient(new X509Certificate2("C:\\recipient1.cer")));
        /// recipients.Add(new CmsRecipient(new X509Certificate2("C:\\recipient2.cer")));
        /// 
        /// message.SmimeEnvelopeAndEncryptFor(recipients);
        /// </code>
        /// </example>
        public void SmimeEnvelopeAndEncryptFor(CmsRecipientCollection recipients)
        {
            string mimeString = this.ToMimeString();
            byte[] toencrypt = Encoding.ASCII.GetBytes(mimeString);
            EnvelopedCms cms = new EnvelopedCms(new ContentInfo(toencrypt));
            cms.Encrypt(recipients);

            MimePart envelope = new MimePart();

            envelope.ContentType.MimeType = "application/pkcs7-mime";
            envelope.ContentType.Parameters.Add("smime-type", "encrypted-data");
            envelope.ContentType.Parameters.Add("name", "smime.p7m");
            envelope.ContentDisposition.Disposition = "attachment";
            envelope.ContentDisposition.FileName = "smime.p7m";
            envelope.ContentTransferEncoding = ContentTransferEncoding.Base64;

            envelope.BinaryContent = cms.Encode();

            this.PartTreeRoot = envelope;

            this.ContentType = this.PartTreeRoot.ContentType;
            this.ContentDisposition = this.PartTreeRoot.ContentDisposition;
            this.ContentTransferEncoding = this.PartTreeRoot.ContentTransferEncoding;
        }
 private unsafe void EncryptContent(CmsRecipientCollection recipients)
 {
     CMSG_ENCRYPT_PARAM encryptParam = new CMSG_ENCRYPT_PARAM();
     if (recipients.Count < 1)
     {
         throw new CryptographicException(-2146889717);
     }
     CmsRecipientEnumerator enumerator = recipients.GetEnumerator();
     while (enumerator.MoveNext())
     {
         CmsRecipient current = enumerator.Current;
         if (current.Certificate == null)
         {
             throw new ArgumentNullException(SecurityResources.GetResourceString("Cryptography_Cms_RecipientCertificateNotFound"));
         }
         if ((PkcsUtils.GetRecipientInfoType(current.Certificate) == RecipientInfoType.KeyAgreement) || (current.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"));
     }
     System.Security.Cryptography.CAPI.CMSG_ENVELOPED_ENCODE_INFO structure = new System.Security.Cryptography.CAPI.CMSG_ENVELOPED_ENCODE_INFO(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_ENVELOPED_ENCODE_INFO)));
     System.Security.Cryptography.SafeLocalAllocHandle handle = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_ENVELOPED_ENCODE_INFO))));
     SetCspParams(this.ContentEncryptionAlgorithm, ref encryptParam);
     structure.ContentEncryptionAlgorithm.pszObjId = this.ContentEncryptionAlgorithm.Oid.Value;
     if ((encryptParam.pvEncryptionAuxInfo != null) && !encryptParam.pvEncryptionAuxInfo.IsInvalid)
     {
         structure.pvEncryptionAuxInfo = encryptParam.pvEncryptionAuxInfo.DangerousGetHandle();
     }
     structure.cRecipients = (uint) recipients.Count;
     List<System.Security.Cryptography.SafeCertContextHandle> certContexts = null;
     if (encryptParam.useCms)
     {
         SetCmsRecipientParams(recipients, this.Certificates, this.UnprotectedAttributes, this.ContentEncryptionAlgorithm, ref encryptParam);
         structure.rgCmsRecipients = encryptParam.rgpRecipients.DangerousGetHandle();
         if ((encryptParam.rgCertEncoded != null) && !encryptParam.rgCertEncoded.IsInvalid)
         {
             structure.cCertEncoded = (uint) this.Certificates.Count;
             structure.rgCertEncoded = encryptParam.rgCertEncoded.DangerousGetHandle();
         }
         if ((encryptParam.rgUnprotectedAttr != null) && !encryptParam.rgUnprotectedAttr.IsInvalid)
         {
             structure.cUnprotectedAttr = (uint) this.UnprotectedAttributes.Count;
             structure.rgUnprotectedAttr = encryptParam.rgUnprotectedAttr.DangerousGetHandle();
         }
     }
     else
     {
         SetPkcs7RecipientParams(recipients, ref encryptParam, out certContexts);
         structure.rgpRecipients = encryptParam.rgpRecipients.DangerousGetHandle();
     }
     Marshal.StructureToPtr(structure, handle.DangerousGetHandle(), false);
     try
     {
         System.Security.Cryptography.SafeCryptMsgHandle handle2 = System.Security.Cryptography.CAPI.CryptMsgOpenToEncode(0x10001, 0, 3, handle.DangerousGetHandle(), this.ContentInfo.ContentType.Value, IntPtr.Zero);
         if ((handle2 == null) || handle2.IsInvalid)
         {
             throw new CryptographicException(Marshal.GetLastWin32Error());
         }
         if ((this.m_safeCryptMsgHandle != null) && !this.m_safeCryptMsgHandle.IsInvalid)
         {
             this.m_safeCryptMsgHandle.Dispose();
         }
         this.m_safeCryptMsgHandle = handle2;
     }
     finally
     {
         Marshal.DestroyStructure(handle.DangerousGetHandle(), typeof(System.Security.Cryptography.CAPI.CMSG_ENVELOPED_ENCODE_INFO));
         handle.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* numRef = content)
         {
             System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB cryptoapi_blob = new System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB {
                 cbData = (uint) content.Length,
                 pbData = new IntPtr((void*) numRef)
             };
             if (!System.Security.Cryptography.CAPI.EncodeObject(new IntPtr(0x19L), new IntPtr((void*) &cryptoapi_blob), out encodedData))
             {
                 throw new CryptographicException(Marshal.GetLastWin32Error());
             }
         }
     }
     else
     {
         encodedData = this.ContentInfo.Content;
     }
     if ((encodedData.Length > 0) && !System.Security.Cryptography.CAPI.CAPISafe.CryptMsgUpdate(this.m_safeCryptMsgHandle, encodedData, (uint) encodedData.Length, true))
     {
         throw new CryptographicException(Marshal.GetLastWin32Error());
     }
     GC.KeepAlive(encryptParam);
     GC.KeepAlive(recipients);
     GC.KeepAlive(certContexts);
 }
예제 #39
-1
        /// <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();
        }