예제 #1
0
        private unsafe void Sign(CmsSigner signer, bool silent)
        {
            CAPI.CMSG_SIGNED_ENCODE_INFO signedEncodeInfo = new CAPI.CMSG_SIGNED_ENCODE_INFO(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNED_ENCODE_INFO)));
            CAPI.CMSG_SIGNER_ENCODE_INFO signerEncodeInfo = PkcsUtils.CreateSignerEncodeInfo(signer, silent);
            byte[] encodedMessage = (byte[])null;
            try
            {
                SafeLocalAllocHandle localAllocHandle = CAPI.LocalAlloc(0U, new IntPtr(Marshal.SizeOf(typeof(CAPI.CMSG_SIGNER_ENCODE_INFO))));
                try
                {
                    Marshal.StructureToPtr((object)signerEncodeInfo, localAllocHandle.DangerousGetHandle(), false);
                    X509Certificate2Collection bagOfCertificates = PkcsUtils.CreateBagOfCertificates(signer);
                    SafeLocalAllocHandle       encodedCertBlob   = PkcsUtils.CreateEncodedCertBlob(bagOfCertificates);
                    signedEncodeInfo.cSigners     = 1U;
                    signedEncodeInfo.rgSigners    = localAllocHandle.DangerousGetHandle();
                    signedEncodeInfo.cCertEncoded = (uint)bagOfCertificates.Count;
                    if (bagOfCertificates.Count > 0)
                    {
                        signedEncodeInfo.rgCertEncoded = encodedCertBlob.DangerousGetHandle();
                    }
                    SafeCryptMsgHandle safeCryptMsgHandle = string.Compare(this.ContentInfo.ContentType.Value, "1.2.840.113549.1.7.1", StringComparison.OrdinalIgnoreCase) != 0 ? CAPI.CryptMsgOpenToEncode(65537U, this.Detached ? 4U : 0U, 2U, new IntPtr((void *)&signedEncodeInfo), this.ContentInfo.ContentType.Value, IntPtr.Zero) : CAPI.CryptMsgOpenToEncode(65537U, this.Detached ? 4U : 0U, 2U, new IntPtr((void *)&signedEncodeInfo), IntPtr.Zero, IntPtr.Zero);
                    if (safeCryptMsgHandle == null || safeCryptMsgHandle.IsInvalid)
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    if (this.ContentInfo.Content.Length > 0 && !CAPI.CAPISafe.CryptMsgUpdate(safeCryptMsgHandle, this.ContentInfo.pContent, (uint)this.ContentInfo.Content.Length, true))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    encodedMessage = PkcsUtils.GetContent(safeCryptMsgHandle);
                    safeCryptMsgHandle.Dispose();
                    encodedCertBlob.Dispose();
                }
                finally
                {
                    Marshal.DestroyStructure(localAllocHandle.DangerousGetHandle(), typeof(CAPI.CMSG_SIGNER_ENCODE_INFO));
                    localAllocHandle.Dispose();
                }
            }
            finally
            {
                signerEncodeInfo.Dispose();
            }
            SafeCryptMsgHandle safeCryptMsgHandle1 = SignedCms.OpenToDecode(encodedMessage, this.ContentInfo, this.Detached);

            if (this.m_safeCryptMsgHandle != null && !this.m_safeCryptMsgHandle.IsInvalid)
            {
                this.m_safeCryptMsgHandle.Dispose();
            }
            this.m_safeCryptMsgHandle = safeCryptMsgHandle1;
            GC.KeepAlive((object)signer);
        }