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))); } }
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))); } } }
private static void SetCspParams(AlgorithmIdentifier contentEncryptionAlgorithm, ref CMSG_ENCRYPT_PARAM encryptParam) { encryptParam.safeCryptProvHandle = System.Security.Cryptography.SafeCryptProvHandle.InvalidHandle; encryptParam.pvEncryptionAuxInfo = System.Security.Cryptography.SafeLocalAllocHandle.InvalidHandle; System.Security.Cryptography.SafeCryptProvHandle invalidHandle = System.Security.Cryptography.SafeCryptProvHandle.InvalidHandle; if (!System.Security.Cryptography.CAPI.CryptAcquireContext(ref invalidHandle, IntPtr.Zero, IntPtr.Zero, 1, 0xf0000000)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } uint algId = System.Security.Cryptography.X509Certificates.X509Utils.OidToAlgId(contentEncryptionAlgorithm.Oid.Value); switch (algId) { case 0x6602: case 0x6801: { System.Security.Cryptography.CAPI.CMSG_RC2_AUX_INFO structure = new System.Security.Cryptography.CAPI.CMSG_RC2_AUX_INFO(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_RC2_AUX_INFO))); uint keyLength = (uint) contentEncryptionAlgorithm.KeyLength; if (keyLength == 0) { keyLength = (uint) PkcsUtils.GetMaxKeyLength(invalidHandle, algId); } structure.dwBitLen = keyLength; System.Security.Cryptography.SafeLocalAllocHandle handle2 = System.Security.Cryptography.CAPI.LocalAlloc(0x40, new IntPtr(Marshal.SizeOf(typeof(System.Security.Cryptography.CAPI.CMSG_RC2_AUX_INFO)))); Marshal.StructureToPtr(structure, handle2.DangerousGetHandle(), false); encryptParam.pvEncryptionAuxInfo = handle2; break; } } encryptParam.safeCryptProvHandle = invalidHandle; }
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); }
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); } } } }
private static void SetCspParams (AlgorithmIdentifier contentEncryptionAlgorithm, ref CMSG_ENCRYPT_PARAM encryptParam) { encryptParam.safeCryptProvHandle = SafeCryptProvHandle.InvalidHandle; encryptParam.pvEncryptionAuxInfo = SafeLocalAllocHandle.InvalidHandle; // Try with CRYPT_VERIFYCONTEXT SafeCryptProvHandle hCryptProv = SafeCryptProvHandle.InvalidHandle; if (!CAPI.CryptAcquireContext(ref hCryptProv, IntPtr.Zero, IntPtr.Zero, CAPI.PROV_RSA_FULL, CAPI.CRYPT_VERIFYCONTEXT)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } uint algId = X509Utils.OidToAlgId(contentEncryptionAlgorithm.Oid.Value); if (algId == CAPI.CALG_RC2 || algId == CAPI.CALG_RC4) { CAPI.CMSG_RC2_AUX_INFO auxInfo = new CAPI.CMSG_RC2_AUX_INFO(Marshal.SizeOf(typeof(CAPI.CMSG_RC2_AUX_INFO))); uint keyLength = (uint) contentEncryptionAlgorithm.KeyLength; if (keyLength == 0) { keyLength = (uint) PkcsUtils.GetMaxKeyLength(hCryptProv, algId); } auxInfo.dwBitLen = keyLength; SafeLocalAllocHandle pvAuxInfo = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_RC2_AUX_INFO)))); Marshal.StructureToPtr(auxInfo, pvAuxInfo.DangerousGetHandle(), false); encryptParam.pvEncryptionAuxInfo = pvAuxInfo; } encryptParam.safeCryptProvHandle = hCryptProv; }
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); }
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))); } }