private static unsafe CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA CreateUnsignedAddAttribute(CRYPT_ATTRIBUTE attr, HeapBlockRetainer hb) { var unmanagedAttr = hb.Alloc(Marshal.SizeOf(attr)); Marshal.StructureToPtr(attr, unmanagedAttr, fDeleteOld: false); uint encodedLength = 0; if (!NativeMethods.CryptEncodeObjectEx( CMSG_ENCODING.Any, lpszStructType: new IntPtr(NativeMethods.PKCS_ATTRIBUTE), pvStructInfo: unmanagedAttr, dwFlags: 0, pEncodePara: IntPtr.Zero, pvEncoded: IntPtr.Zero, pcbEncoded: ref encodedLength)) { var err = Marshal.GetLastWin32Error(); if (err != NativeMethods.ERROR_MORE_DATA) { Marshal.ThrowExceptionForHR(NativeMethods.GetHRForWin32Error(err)); } } var unmanagedEncoded = hb.Alloc((int)encodedLength); if (!NativeMethods.CryptEncodeObjectEx( CMSG_ENCODING.Any, lpszStructType: new IntPtr(NativeMethods.PKCS_ATTRIBUTE), pvStructInfo: unmanagedAttr, dwFlags: 0, pEncodePara: IntPtr.Zero, pvEncoded: unmanagedEncoded, pcbEncoded: ref encodedLength)) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } var addAttr = new CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA() { dwSignerIndex = 0, BLOB = new CRYPT_INTEGER_BLOB() { cbData = encodedLength, pbData = unmanagedEncoded } }; return(addAttr); }
internal unsafe void AddTimestamp(byte[] timeStampCms) { using (var hb = new HeapBlockRetainer()) { var unmanagedTimestamp = hb.Alloc(timeStampCms.Length); Marshal.Copy(timeStampCms, 0, unmanagedTimestamp, timeStampCms.Length); var blob = new CRYPT_INTEGER_BLOB() { cbData = (uint)timeStampCms.Length, pbData = unmanagedTimestamp }; var unmanagedBlob = hb.Alloc(Marshal.SizeOf(blob)); Marshal.StructureToPtr(blob, unmanagedBlob, fDeleteOld: false); var attr = new CRYPT_ATTRIBUTE() { pszObjId = hb.AllocAsciiString(Oids.SignatureTimeStampTokenAttribute), cValue = 1, rgValue = unmanagedBlob }; var unmanagedAttr = hb.Alloc(Marshal.SizeOf(attr)); Marshal.StructureToPtr(attr, unmanagedAttr, fDeleteOld: false); uint encodedLength = 0; if (!NativeMethods.CryptEncodeObjectEx( dwCertEncodingType: NativeMethods.X509_ASN_ENCODING | NativeMethods.PKCS_7_ASN_ENCODING, lpszStructType: new IntPtr(NativeMethods.PKCS_ATTRIBUTE), pvStructInfo: unmanagedAttr, dwFlags: 0, pEncodePara: IntPtr.Zero, pvEncoded: IntPtr.Zero, pcbEncoded: ref encodedLength)) { var err = Marshal.GetLastWin32Error(); if (err != NativeMethods.ERROR_MORE_DATA) { Marshal.ThrowExceptionForHR(NativeMethods.GetHRForWin32Error(err)); } } var unmanagedEncoded = hb.Alloc((int)encodedLength); if (!NativeMethods.CryptEncodeObjectEx( dwCertEncodingType: NativeMethods.X509_ASN_ENCODING | NativeMethods.PKCS_7_ASN_ENCODING, lpszStructType: new IntPtr(NativeMethods.PKCS_ATTRIBUTE), pvStructInfo: unmanagedAttr, dwFlags: 0, pEncodePara: IntPtr.Zero, pvEncoded: unmanagedEncoded, pcbEncoded: ref encodedLength)) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } var addAttr = new CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA() { dwSignerIndex = 0, BLOB = new CRYPT_INTEGER_BLOB() { cbData = encodedLength, pbData = unmanagedEncoded } }; addAttr.cbSize = (uint)Marshal.SizeOf(addAttr); var unmanagedAddAttr = hb.Alloc(Marshal.SizeOf(addAttr)); Marshal.StructureToPtr(addAttr, unmanagedAddAttr, fDeleteOld: false); if (!NativeMethods.CryptMsgControl( _handle, dwFlags: 0, dwCtrlType: CMSG_CONTROL_TYPE.CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR, pvCtrlPara: unmanagedAddAttr)) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } }