public void One_CryptographicAttributeObject () { Oid o = new Oid (defaultOid); CryptographicAttributeObject cao = new CryptographicAttributeObject (o); coll = new CryptographicAttributeObjectCollection (cao); Count (1); }
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(); }
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"); }
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; } } }
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)); } }
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); }
/// <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);
/// <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"); }
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); }
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))); } } }
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); } }
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); } } } }