private unsafe void CounterSign(CmsSigner signer) { // Sanity check. Debug.Assert(signer != null); // CspParameters parameters = new CspParameters(); if (X509Utils.GetPrivateKeyInfo(X509Utils.GetCertContext(signer.Certificate), ref parameters) == false) { throw new CryptographicException(Marshal.GetLastWin32Error()); } KeyContainerPermission kp = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags); KeyContainerPermissionAccessEntry entry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Open | KeyContainerPermissionFlags.Sign); kp.AccessEntries.Add(entry); kp.Demand(); // Get the signer's index. uint index = (uint)PkcsUtils.GetSignerIndex(m_signedCms.GetCryptMsgHandle(), this, 0); // Create CMSG_SIGNER_ENCODE_INFO structure. SafeLocalAllocHandle pSignerEncodeInfo = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO)))); CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer); try { // Marshal to unmanaged memory. Marshal.StructureToPtr(signerEncodeInfo, pSignerEncodeInfo.DangerousGetHandle(), false); // Counter sign. if (!CAPI.CryptMsgCountersign(m_signedCms.GetCryptMsgHandle(), index, 1, pSignerEncodeInfo.DangerousGetHandle())) { throw new CryptographicException(Marshal.GetLastWin32Error()); } // CAPI requires that the messge be re-encoded if any unauthenticated // attribute has been added. So, let's re-open it to decode to work // around this limitation. m_signedCms.ReopenToDecode(); } finally { Marshal.DestroyStructure(pSignerEncodeInfo.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO)); pSignerEncodeInfo.Dispose(); // and don't forget to dispose of resources allocated for the structure. signerEncodeInfo.Dispose(); } // Finally, add certs to bag of certs. PkcsUtils.AddCertsToMessage(m_signedCms.GetCryptMsgHandle(), m_signedCms.Certificates, PkcsUtils.CreateBagOfCertificates(signer)); return; }
private void CounterSign(CmsSigner signer) { CspParameters parameters = new CspParameters(); if (!X509Utils.GetPrivateKeyInfo(X509Utils.GetCertContext(signer.Certificate), ref parameters)) { throw new CryptographicException(Marshal.GetLastWin32Error()); } KeyContainerPermission containerPermission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags); KeyContainerPermissionAccessEntry accessEntry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Open | KeyContainerPermissionFlags.Sign); containerPermission.AccessEntries.Add(accessEntry); containerPermission.Demand(); uint dwIndex = (uint)PkcsUtils.GetSignerIndex(this.m_signedCms.GetCryptMsgHandle(), this, 0); SafeLocalAllocHandle localAllocHandle = CAPI.LocalAlloc(64U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO)))); CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer); try { Marshal.StructureToPtr((object)signerEncodeInfo, localAllocHandle.DangerousGetHandle(), false); if (!CAPI.CryptMsgCountersign(this.m_signedCms.GetCryptMsgHandle(), dwIndex, 1U, localAllocHandle.DangerousGetHandle())) { throw new CryptographicException(Marshal.GetLastWin32Error()); } this.m_signedCms.ReopenToDecode(); } finally { Marshal.DestroyStructure(localAllocHandle.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO)); localAllocHandle.Dispose(); signerEncodeInfo.Dispose(); } int num = (int)PkcsUtils.AddCertsToMessage(this.m_signedCms.GetCryptMsgHandle(), this.m_signedCms.Certificates, PkcsUtils.CreateBagOfCertificates(signer)); }