Наследование: System.Collections.ICollection, System.Collections.IEnumerable
		public void One_CryptographicAttributeObject () 
		{
			Oid o = new Oid (defaultOid);
			CryptographicAttributeObject cao = new CryptographicAttributeObject (o);
			coll = new CryptographicAttributeObjectCollection (cao);
			Count (1);
		}
Пример #2
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;
            }
        }
		private void CommonStuff (CryptographicAttributeObjectCollection coll)
		{
			Assert.IsFalse (coll.IsSynchronized, "IsSynchronized");
			Assert.AreSame (coll, coll.SyncRoot, "SyncRoot");
			Assert.IsNotNull (coll.GetEnumerator (), "GetEnumerator");

			int i = coll.Count;
			Oid o1 = new Oid ("1.2.840.113549.1.7.3");
			AsnEncodedData aed = new AsnEncodedData (o1, new byte[] { 0x05, 0x00 });
			Assert.AreEqual (i, coll.Add (aed), "Add(AsnEncodedData)");
			Assert.IsTrue ((coll[i++] is CryptographicAttributeObject), "converted");

			Oid o2 = new Oid ("1.2.840.113549.1.7.2");
			CryptographicAttributeObject cao = new CryptographicAttributeObject (o2);
			Assert.AreEqual (i, coll.Add (cao), "Add(CryptographicAttributeObject)");

			CryptographicAttributeObject[] array = new CryptographicAttributeObject [coll.Count];
			coll.CopyTo (array, 0);

			Array a = (Array) new object [coll.Count];
			ICollection c = (ICollection) coll;
			c.CopyTo (a, 0);

			IEnumerable e = (IEnumerable) coll;
			Assert.IsNotNull (e.GetEnumerator (), "GetEnumerator");

			coll.Remove (cao);
			Assert.AreEqual (i, coll.Count, "Remove(CryptographicAttributeObject)");
		}
        public CmsSigner(SubjectIdentifierType signerIdentifierType, X509Certificate2 certificate)
        {
            switch (signerIdentifierType)
            {
                case SubjectIdentifierType.Unknown:
                    this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
                    this.IncludeOption = X509IncludeOption.ExcludeRoot;
                    break;

                case SubjectIdentifierType.IssuerAndSerialNumber:
                    this.SignerIdentifierType = signerIdentifierType;
                    this.IncludeOption = X509IncludeOption.ExcludeRoot;
                    break;

                case SubjectIdentifierType.SubjectKeyIdentifier:
                    this.SignerIdentifierType = signerIdentifierType;
                    this.IncludeOption = X509IncludeOption.ExcludeRoot;
                    break;

                case SubjectIdentifierType.NoSignature:
                    this.SignerIdentifierType = signerIdentifierType;
                    this.IncludeOption = X509IncludeOption.None;
                    break;

                default:
                    this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
                    this.IncludeOption = X509IncludeOption.ExcludeRoot;
                    break;
            }
            this.Certificate = certificate;
            this.DigestAlgorithm = new Oid("1.3.14.3.2.26");
            this.m_signedAttributes = new CryptographicAttributeObjectCollection();
            this.m_unsignedAttributes = new CryptographicAttributeObjectCollection();
            this.m_certificates = new X509Certificate2Collection();
        }
Пример #5
0
        public CmsSigner (SubjectIdentifierType signerIdentifierType, X509Certificate2 certificate) {
            switch (signerIdentifierType) {
            case SubjectIdentifierType.Unknown:
                this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
                this.IncludeOption = X509IncludeOption.ExcludeRoot;
                break;
            case SubjectIdentifierType.IssuerAndSerialNumber:
                this.SignerIdentifierType = signerIdentifierType;
                this.IncludeOption = X509IncludeOption.ExcludeRoot;
                break;
            case SubjectIdentifierType.SubjectKeyIdentifier:
                this.SignerIdentifierType = signerIdentifierType;
                this.IncludeOption = X509IncludeOption.ExcludeRoot;
                break;
            case SubjectIdentifierType.NoSignature:
                this.SignerIdentifierType = signerIdentifierType;
                this.IncludeOption        = X509IncludeOption.None;
                break;
            default:
                this.SignerIdentifierType = SubjectIdentifierType.IssuerAndSerialNumber;
                this.IncludeOption = X509IncludeOption.ExcludeRoot;
                break;
            }
            this.Certificate = certificate;
            this.DigestAlgorithm = Oid.FromOidValue(CAPI.szOID_OIWSEC_sha1, OidGroup.HashAlgorithm);

            m_signedAttributes = new CryptographicAttributeObjectCollection();
            m_unsignedAttributes = new CryptographicAttributeObjectCollection();
            m_certificates = new X509Certificate2Collection();
        }
		public void LinkDemand_Deny_Unrestricted ()
		{
			Oid o = new Oid (defaultOid);
			CryptographicAttributeObject cao = new CryptographicAttributeObject (o);
			CryptographicAttributeObjectCollection coll = new CryptographicAttributeObjectCollection (cao);
			CryptographicAttributeObjectEnumerator e = coll.GetEnumerator ();

			MethodInfo mi = typeof (CryptographicAttributeObjectEnumerator).GetMethod ("MoveNext");
			Assert.IsNotNull (mi, "default .ctor()");
			Assert.IsTrue ((bool)mi.Invoke (e, null), "invoke");
		}
Пример #7
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;
                    }
                }
            }
Пример #8
0
        internal static DecryptorPalWindows Decode(
            byte[] encodedMessage,
            out int version,
            out ContentInfo contentInfo,
            out AlgorithmIdentifier contentEncryptionAlgorithm,
            out X509Certificate2Collection originatorCerts,
            out CryptographicAttributeObjectCollection unprotectedAttributes
            )
        {
            SafeCryptMsgHandle hCryptMsg = Interop.Crypt32.CryptMsgOpenToDecode(MsgEncodingType.All, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
            if (hCryptMsg == null || hCryptMsg.IsInvalid)
                throw Marshal.GetLastWin32Error().ToCryptographicException();

            if (!Interop.Crypt32.CryptMsgUpdate(hCryptMsg, encodedMessage, encodedMessage.Length, fFinal: true))
                throw Marshal.GetLastWin32Error().ToCryptographicException();

            CryptMsgType cryptMsgType = hCryptMsg.GetMessageType();
            if (cryptMsgType != CryptMsgType.CMSG_ENVELOPED)
                throw ErrorCode.CRYPT_E_INVALID_MSG_TYPE.ToCryptographicException();

            version = hCryptMsg.GetVersion();

            contentInfo = hCryptMsg.GetContentInfo();

            using (SafeHandle sh = hCryptMsg.GetMsgParamAsMemory(CryptMsgParamType.CMSG_ENVELOPE_ALGORITHM_PARAM))
            {
                unsafe
                {
                    CRYPT_ALGORITHM_IDENTIFIER* pCryptAlgorithmIdentifier = (CRYPT_ALGORITHM_IDENTIFIER*)(sh.DangerousGetHandle());
                    contentEncryptionAlgorithm = (*pCryptAlgorithmIdentifier).ToAlgorithmIdentifier();
                }
            }

            originatorCerts = hCryptMsg.GetOriginatorCerts();
            unprotectedAttributes = hCryptMsg.GetUnprotectedAttributes();

            RecipientInfoCollection recipientInfos = CreateRecipientInfos(hCryptMsg);
            return new DecryptorPalWindows(hCryptMsg, recipientInfos);
        }
 public EnvelopedCms(SubjectIdentifierType recipientIdentifierType, System.Security.Cryptography.Pkcs.ContentInfo contentInfo, AlgorithmIdentifier encryptionAlgorithm)
 {
     if (contentInfo == null)
     {
         throw new ArgumentNullException("contentInfo");
     }
     if (contentInfo.Content == null)
     {
         throw new ArgumentNullException("contentInfo.Content");
     }
     if (encryptionAlgorithm == null)
     {
         throw new ArgumentNullException("encryptionAlgorithm");
     }
     this.m_safeCryptMsgHandle = System.Security.Cryptography.SafeCryptMsgHandle.InvalidHandle;
     this.m_version = (recipientIdentifierType == SubjectIdentifierType.SubjectKeyIdentifier) ? 2 : 0;
     this.m_recipientIdentifierType = recipientIdentifierType;
     this.m_contentInfo = contentInfo;
     this.m_encryptionAlgorithm = encryptionAlgorithm;
     this.m_encryptionAlgorithm.Parameters = new byte[0];
     this.m_certificates = new X509Certificate2Collection();
     this.m_unprotectedAttributes = new CryptographicAttributeObjectCollection();
 }
		public void Remove_MultipleSameOid_Last ()
		{
			Oid o = new Oid (defaultOid);
			CryptographicAttributeObject cao = new CryptographicAttributeObject (o);
			CryptographicAttributeObjectCollection coll = new CryptographicAttributeObjectCollection (cao);

			Oid o1 = new Oid (defaultOid);
			AsnEncodedData aed = new AsnEncodedData (o1, new byte[] { 0x04, (byte) 0 });
			coll.Add (aed);

			aed = new AsnEncodedData (o1, new byte[] { 0x04, (byte) 0 });
			coll.Add (aed);

			Oid o2 = new Oid (defaultOid);
			CryptographicAttributeObject last = new CryptographicAttributeObject (o2);
			coll.Add (last);

			Assert.AreEqual (1, coll.Count, "before Remove");
			coll.Remove (last);
			Assert.AreEqual (1, coll.Count, "after Remove");
		}
		public void Remove_Null_WithNullItem ()
		{
			CryptographicAttributeObjectCollection coll = new CryptographicAttributeObjectCollection (null);
			Assert.AreEqual (1, coll.Count, "Count");
			Assert.IsNull (coll[0], "this[int]");
			coll.Remove (null);
		}
		public void ICollection_CopyTo_Null ()
		{
			CryptographicAttributeObjectCollection coll = new CryptographicAttributeObjectCollection ();
			ICollection c = (coll as ICollection);
			c.CopyTo (null, 0);
		}
		public void Add_MultipleSameOid ()
		{
			Oid o = new Oid (defaultOid);
			CryptographicAttributeObject cao = new CryptographicAttributeObject (o);
			CryptographicAttributeObjectCollection coll = new CryptographicAttributeObjectCollection (cao);

			int i = 0;
			while (i < 10) {
				Assert.AreEqual (1, coll.Count, String.Format ("Count-{0}", i));
				Assert.AreEqual (i * 2, coll[0].Values.Count, String.Format ("Values.Count-{0}", i++));

				Oid o1 = new Oid (defaultOid);
				AsnEncodedData aed = new AsnEncodedData (o1, new byte[] { 0x04, (byte)i });
				coll.Add (aed);

				aed = new AsnEncodedData (o1, new byte[] { 0x04, (byte) i });
				coll.Add (aed);

				Oid o2 = new Oid (defaultOid);
				coll.Add (new CryptographicAttributeObject (o2));
			}
		}
Пример #14
0
        internal static unsafe IntPtr CreateCryptAttributes (CryptographicAttributeObjectCollection attributes) {
            attributes = attributes.DeepCopy();

            // NULL if no attribute.
            if (attributes.Count == 0)
                return IntPtr.Zero;

            //
            // The goal here is to compute the size needed for the attributes we are passing to CMSG_SIGNER_ENCODE_INFO
            // The unmanaged memory structure we are creating here has the following layout:
            //
            // Let cAttr = number of attributes.
            //
            // This to create the array of CRYPT_ATTRIBUTE
            // for i = 0 to cAttr {
            //     CRYPT_ATTRRIBUTE[i]                           // pszObjId | cValue | rgValue
            // }
            //
            // This is to fill in the data for each entry of CRYPT_ATTRIBUTE array above.
            // for i = 0 to cAttr {
            //     objId[i]                                      // Value of the Oid, i.e "1.2.3.4"
            //     for j = 0 to CRYPT_ATTRIBUTE[i].cValue - 1 {  // Array of CRYPTOAPI_BLOB
            //        CRYPT_ATTRIBUTE[i].rgValue[j].cbData       // Data size
            //        CRYPT_ATTRIBUTE[i].rgValue[j].pbData       // Pointer to data
            //     }
            //     for j = 0 to CRYPT_ATTRIBUTE[i].cValue - 1 {  // Data for each entry of the CRYPTOAPI_BLOB array above.
            //        *CRYPT_ATTRIBUTE[i].rgValue[j].pbData      // The actual data
            //    }
            // }

            checked {
                uint totalLength = 0;
                uint cryptAttrSize = AlignedLength((uint) Marshal.SizeOf(typeof(I_CRYPT_ATTRIBUTE)));
                uint cryptBlobSize = AlignedLength((uint) Marshal.SizeOf(typeof(CAPI.CRYPTOAPI_BLOB)));

                // First compute the total serialized unmanaged memory size needed.
                // For each attribute, we add the CRYPT_ATTRIBUTE size, the size
                // needed for the ObjId, and the size needed for all the values
                // inside each attribute which is computed in inner loop.
                foreach (CryptographicAttributeObject attribute in attributes) {
                    totalLength += cryptAttrSize;  // sizeof(CRYPT_ATTRIBUTE)
                    totalLength += AlignedLength((uint) (attribute.Oid.Value.Length + 1));  // strlen(pszObjId) + 1

                    // For each value within the attribute, we add the CRYPT_ATTR_BLOB size and 
                    // the actual size needed for the data.
                    foreach (AsnEncodedData attributeValue in attribute.Values) {
                        totalLength += cryptBlobSize;   // Add CRYPT_ATTR_BLOB size
                        totalLength += AlignedLength((uint) attributeValue.RawData.Length); // Data size
                    }
                }

                // Allocate the unmanaged memory blob to hold the entire serialized CRYPT_ATTRIBUTE array.
                SafeLocalAllocHandle pCryptAttributes = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(totalLength));

                // Now fill up unmanaged memory with data from the managed side.
                I_CRYPT_ATTRIBUTE * pCryptAttribute = (I_CRYPT_ATTRIBUTE *) pCryptAttributes.DangerousGetHandle();
                IntPtr pAttrData = new IntPtr((long) pCryptAttributes.DangerousGetHandle() + (cryptAttrSize * attributes.Count));

                foreach (CryptographicAttributeObject attribute in attributes) {
                    byte * pszObjId = (byte *) pAttrData;
                    byte[] objId = new byte[attribute.Oid.Value.Length + 1];
                    CAPI.CRYPTOAPI_BLOB * pDataBlob = (CAPI.CRYPTOAPI_BLOB *) (pszObjId + AlignedLength((uint) objId.Length));

                    // CRYPT_ATTRIBUTE.pszObjId
                    pCryptAttribute->pszObjId = (IntPtr) pszObjId;

                    // CRYPT_ATTRIBUTE.cValue
                    pCryptAttribute->cValue = (uint) attribute.Values.Count;

                    // CRYPT_ATTRIBUTE.rgValue
                    pCryptAttribute->rgValue = (IntPtr) pDataBlob;

                    // ObjId - The actual dotted value of the OID.
                    Encoding.ASCII.GetBytes(attribute.Oid.Value, 0, attribute.Oid.Value.Length, objId, 0);
                    Marshal.Copy(objId, 0, pCryptAttribute->pszObjId, objId.Length);

                    // cValue of CRYPT_ATTR_BLOBs followed by cValue of actual data.
                    IntPtr pbEncodedData = new IntPtr((long) pDataBlob + (attribute.Values.Count * cryptBlobSize));
                    foreach (AsnEncodedData value in attribute.Values) {
                        // Retrieve encoded data.
                        byte[] encodedData = value.RawData;

                        // Write data
                        if (encodedData.Length > 0) {
                            // CRYPT_ATTR_BLOB.cbData
                            pDataBlob->cbData = (uint) encodedData.Length;

                            // CRYPT_ATTR_BLOB.pbData
                            pDataBlob->pbData = pbEncodedData;

                            Marshal.Copy(encodedData, 0, pbEncodedData, encodedData.Length);
                            pbEncodedData = new IntPtr((long) pbEncodedData + AlignedLength((uint) encodedData.Length));
                        }

                        // Advance pointer.
                        pDataBlob++;
                    }

                    // Advance pointers.
                    pCryptAttribute++;
                    pAttrData = pbEncodedData;
                }

                // Since we are returning IntPtr, we MUST supress finalizer, otherwise
                // the GC can collect the memory underneath us!!!
                GC.SuppressFinalize(pCryptAttributes);

                return pCryptAttributes.DangerousGetHandle();
            }
        }
		public void Constructor_Empty ()
		{
			CryptographicAttributeObjectCollection coll = new CryptographicAttributeObjectCollection ();
			Assert.AreEqual (0, coll.Count, "Count");
			CommonStuff (coll);
		}
		public void Empty ()
		{
			coll = new CryptographicAttributeObjectCollection ();
			Count (0);
		}
Пример #17
0
 /// <summary>
 /// Decode an encoded CMS.
 ///    Call RecipientInfos on the returned pal object to get the recipients.
 ///    Call TryDecrypt() on the returned pal object to attempt a decrypt for a single recipient.
 /// </summary>
 public abstract DecryptorPal Decode(byte[] encodedMessage, out int version, out ContentInfo contentInfo, out AlgorithmIdentifier contentEncryptionAlgorithm, out X509Certificate2Collection originatorCerts, out CryptographicAttributeObjectCollection unprotectedAttributes);
Пример #18
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);
 internal static unsafe CryptographicAttributeObjectCollection GetUnprotectedAttributes(System.Security.Cryptography.SafeCryptMsgHandle safeCryptMsgHandle)
 {
     uint num = 0;
     CryptographicAttributeObjectCollection objects = new CryptographicAttributeObjectCollection();
     System.Security.Cryptography.SafeLocalAllocHandle invalidHandle = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle;
     if (!System.Security.Cryptography.CAPI.CAPISafe.CryptMsgGetParam(safeCryptMsgHandle, 0x25, 0, invalidHandle, new IntPtr((void*) &num)) && (Marshal.GetLastWin32Error() != -2146889713))
     {
         checkErr(Marshal.GetLastWin32Error());
     }
     if (num <= 0)
     {
         return objects;
     }
     using (invalidHandle = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long) num)))
     {
         if (!System.Security.Cryptography.CAPI.CAPISafe.CryptMsgGetParam(safeCryptMsgHandle, 0x25, 0, invalidHandle, new IntPtr((void*) &num)))
         {
             checkErr(Marshal.GetLastWin32Error());
         }
         return new CryptographicAttributeObjectCollection(invalidHandle);
     }
 }
 internal static unsafe IntPtr CreateCryptAttributes(CryptographicAttributeObjectCollection attributes)
 {
     if (attributes.Count == 0)
     {
         return IntPtr.Zero;
     }
     uint num = 0;
     uint num2 = AlignedLength((uint) Marshal.SizeOf(typeof(I_CRYPT_ATTRIBUTE)));
     uint num3 = AlignedLength((uint) Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB)));
     CryptographicAttributeObjectEnumerator enumerator = attributes.GetEnumerator();
     while (enumerator.MoveNext())
     {
         CryptographicAttributeObject current = enumerator.Current;
         num += num2;
         num += AlignedLength((uint) (current.Oid.Value.Length + 1));
         AsnEncodedDataEnumerator enumerator2 = current.Values.GetEnumerator();
         while (enumerator2.MoveNext())
         {
             AsnEncodedData data = enumerator2.Current;
             num += num3;
             num += AlignedLength((uint) data.RawData.Length);
         }
     }
     System.Security.Cryptography.SafeLocalAllocHandle handle = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr((long) num));
     I_CRYPT_ATTRIBUTE* i_crypt_attributePtr = (I_CRYPT_ATTRIBUTE*) handle.DangerousGetHandle();
     IntPtr ptr = new IntPtr(((long) handle.DangerousGetHandle()) + (num2 * attributes.Count));
     CryptographicAttributeObjectEnumerator enumerator3 = attributes.GetEnumerator();
     while (enumerator3.MoveNext())
     {
         CryptographicAttributeObject obj3 = enumerator3.Current;
         byte* numPtr = (byte*) ptr;
         byte[] bytes = new byte[obj3.Oid.Value.Length + 1];
         System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB* cryptoapi_blobPtr = (System.Security.Cryptography.CAPI.CRYPTOAPI_BLOB*) (numPtr + AlignedLength((uint) bytes.Length));
         i_crypt_attributePtr->pszObjId = (IntPtr) numPtr;
         i_crypt_attributePtr->cValue = (uint) obj3.Values.Count;
         i_crypt_attributePtr->rgValue = (IntPtr) cryptoapi_blobPtr;
         Encoding.ASCII.GetBytes(obj3.Oid.Value, 0, obj3.Oid.Value.Length, bytes, 0);
         Marshal.Copy(bytes, 0, i_crypt_attributePtr->pszObjId, bytes.Length);
         IntPtr destination = new IntPtr(((long) ((ulong) cryptoapi_blobPtr)) + (obj3.Values.Count * num3));
         AsnEncodedDataEnumerator enumerator4 = obj3.Values.GetEnumerator();
         while (enumerator4.MoveNext())
         {
             byte[] rawData = enumerator4.Current.RawData;
             if (rawData.Length > 0)
             {
                 cryptoapi_blobPtr->cbData = (uint) rawData.Length;
                 cryptoapi_blobPtr->pbData = destination;
                 Marshal.Copy(rawData, 0, destination, rawData.Length);
                 destination = new IntPtr(((long) destination) + AlignedLength((uint) rawData.Length));
             }
             cryptoapi_blobPtr++;
         }
         i_crypt_attributePtr++;
         ptr = destination;
     }
     GC.SuppressFinalize(handle);
     return handle.DangerousGetHandle();
 }
		public void Remove_WithDifferentInstance ()
		{
			Oid o = new Oid (defaultOid);
			CryptographicAttributeObject cao = new CryptographicAttributeObject (o);
			CryptographicAttributeObjectCollection coll = new CryptographicAttributeObjectCollection (cao);

			Assert.AreEqual (1, coll.Count, "before Remove");
			cao = new CryptographicAttributeObject (o);
			coll.Remove (cao);
			Assert.AreEqual (1, coll.Count, "after Remove");
		}
Пример #22
0
 private static unsafe CryptographicAttributeObjectCollection ToCryptographicAttributeObjectCollection(CRYPT_ATTRIBUTES* pCryptAttributes)
 {
     CryptographicAttributeObjectCollection collection = new CryptographicAttributeObjectCollection();
     for (int i = 0; i < pCryptAttributes->cAttr; i++)
     {
         CRYPT_ATTRIBUTE* pCryptAttribute = &(pCryptAttributes->rgAttr[i]);
         AddCryptAttribute(collection, pCryptAttribute);
     }
     return collection;
 }
 public void Decode(byte[] encodedMessage)
 {
     if (encodedMessage == null)
     {
         throw new ArgumentNullException("encodedMessage");
     }
     if ((this.m_safeCryptMsgHandle != null) && !this.m_safeCryptMsgHandle.IsInvalid)
     {
         this.m_safeCryptMsgHandle.Dispose();
     }
     this.m_safeCryptMsgHandle = OpenToDecode(encodedMessage);
     this.m_version = (int) PkcsUtils.GetVersion(this.m_safeCryptMsgHandle);
     Oid contentType = PkcsUtils.GetContentType(this.m_safeCryptMsgHandle);
     byte[] content = PkcsUtils.GetContent(this.m_safeCryptMsgHandle);
     this.m_contentInfo = new System.Security.Cryptography.Pkcs.ContentInfo(contentType, content);
     this.m_encryptionAlgorithm = PkcsUtils.GetAlgorithmIdentifier(this.m_safeCryptMsgHandle);
     this.m_certificates = PkcsUtils.GetCertificates(this.m_safeCryptMsgHandle);
     this.m_unprotectedAttributes = PkcsUtils.GetUnprotectedAttributes(this.m_safeCryptMsgHandle);
 }
Пример #24
0
        internal static unsafe CryptographicAttributeObjectCollection GetUnprotectedAttributes (SafeCryptMsgHandle safeCryptMsgHandle) {
            uint cbUnprotectedAttr = 0;
            CryptographicAttributeObjectCollection attributes = new CryptographicAttributeObjectCollection();
            SafeLocalAllocHandle pbUnprotectedAttr = SafeLocalAllocHandle.InvalidHandle;
            if (!CAPI.CAPISafe.CryptMsgGetParam(safeCryptMsgHandle,
                                                CAPI.CMSG_UNPROTECTED_ATTR_PARAM,
                                                0,
                                                pbUnprotectedAttr,
                                                new IntPtr(&cbUnprotectedAttr))) {
                int lastWin32Error = Marshal.GetLastWin32Error();
                if (lastWin32Error != CAPI.CRYPT_E_ATTRIBUTES_MISSING)
                    checkErr(Marshal.GetLastWin32Error());
            }

            if (cbUnprotectedAttr > 0) {
                using (pbUnprotectedAttr = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(cbUnprotectedAttr))) {
                    if (!CAPI.CAPISafe.CryptMsgGetParam(safeCryptMsgHandle,
                                                        CAPI.CMSG_UNPROTECTED_ATTR_PARAM,
                                                        0,
                                                        pbUnprotectedAttr,
                                                        new IntPtr(&cbUnprotectedAttr)))
                        checkErr(Marshal.GetLastWin32Error());

                    attributes = new CryptographicAttributeObjectCollection(pbUnprotectedAttr);
                }
            }
            return attributes;
        }
		public void Constructor_CryptographicAttributeObject () 
		{
			Oid o = new Oid (defaultOid);
			CryptographicAttributeObject cao = new CryptographicAttributeObject (o);
			CryptographicAttributeObjectCollection coll = new CryptographicAttributeObjectCollection (cao);
			Assert.AreEqual (1, coll.Count, "Count");
			Assert.AreSame (cao, coll[0], "this[int]");
			CommonStuff (coll);
		}
		public void Two_Both ()
		{
			coll = new CryptographicAttributeObjectCollection ();

			Oid o1 = new Oid (defaultOid + ".1");
			AsnEncodedData aed = new AsnEncodedData (o1, new byte[] { 0x05, 0x00 });
			coll.Add (aed);

			Oid o2 = new Oid (defaultOid + ".2");
			coll.Add (new CryptographicAttributeObject (o2));

			Count (2);
		}
		public void One_AsnEncodedData ()
		{
			Oid o = new Oid (defaultOid);
			AsnEncodedData aed = new AsnEncodedData (o, new byte[] { 0x05, 0x00 });
			coll = new CryptographicAttributeObjectCollection ();
			coll.Add (aed);
			Count (1);
		}
 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)));
         }
     }
 }
Пример #29
0
        private static unsafe void AddCryptAttribute(CryptographicAttributeObjectCollection collection, CRYPT_ATTRIBUTE* pCryptAttribute)
        {
            string oidValue = pCryptAttribute->pszObjId.ToStringAnsi();
            Oid oid = new Oid(oidValue);

            for (int i = 0; i < pCryptAttribute->cValue; i++)
            {
                byte[] encodedAttribute = pCryptAttribute->rgValue[i].ToByteArray();
                AsnEncodedData attributeObject = Helpers.CreateBestPkcs9AttributeObjectAvailable(oid, encodedAttribute);
                collection.Add(attributeObject);
            }
        }
Пример #30
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);
                    }
                }
            }
        }