예제 #1
0
 public static extern SafeCryptMsgHandle CryptMsgOpenToEncode(
     CMSG_ENCODING dwMsgEncodingType,
     uint dwFlags,
     uint dwMsgType,
     ref CMSG_SIGNED_ENCODE_INFO pvMsgEncodeInfo,
     string pszInnerContentObjID,
     IntPtr pStreamInfo
     );
예제 #2
0
        internal static SignedCms NativeSign(CmsSigner cmsSigner, byte[] data, CngKey privateKey)
        {
            using (var hb = new HeapBlockRetainer())
            {
                var certificateBlobs = new BLOB[cmsSigner.Certificates.Count];

                for (var i = 0; i < cmsSigner.Certificates.Count; ++i)
                {
                    var cert    = cmsSigner.Certificates[i];
                    var context = Marshal.PtrToStructure <CERT_CONTEXT>(cert.Handle);

                    certificateBlobs[i] = new BLOB()
                    {
                        cbData = context.cbCertEncoded, pbData = context.pbCertEncoded
                    };
                }

                byte[] encodedData;
                var    signerInfo = CreateSignerInfo(cmsSigner, privateKey, hb);

                var signedInfo = new CMSG_SIGNED_ENCODE_INFO();
                signedInfo.cbSize   = Marshal.SizeOf(signedInfo);
                signedInfo.cSigners = 1;

                using (var signerInfoHandle = new SafeLocalAllocHandle(Marshal.AllocHGlobal(Marshal.SizeOf(signerInfo))))
                {
                    Marshal.StructureToPtr(signerInfo, signerInfoHandle.DangerousGetHandle(), fDeleteOld: false);

                    signedInfo.rgSigners    = signerInfoHandle.DangerousGetHandle();
                    signedInfo.cCertEncoded = certificateBlobs.Length;

                    using (var certificatesHandle = new SafeLocalAllocHandle(Marshal.AllocHGlobal(Marshal.SizeOf(certificateBlobs[0]) * certificateBlobs.Length)))
                    {
                        for (var i = 0; i < certificateBlobs.Length; ++i)
                        {
                            Marshal.StructureToPtr(certificateBlobs[i], new IntPtr(certificatesHandle.DangerousGetHandle().ToInt64() + Marshal.SizeOf(certificateBlobs[i]) * i), fDeleteOld: false);
                        }

                        signedInfo.rgCertEncoded = certificatesHandle.DangerousGetHandle();

                        var hMsg = NativeMethods.CryptMsgOpenToEncode(
                            NativeMethods.X509_ASN_ENCODING | NativeMethods.PKCS_7_ASN_ENCODING,
                            dwFlags: 0,
                            dwMsgType: NativeMethods.CMSG_SIGNED,
                            pvMsgEncodeInfo: ref signedInfo,
                            pszInnerContentObjID: null,
                            pStreamInfo: IntPtr.Zero);

                        ThrowIfFailed(!hMsg.IsInvalid);

                        ThrowIfFailed(NativeMethods.CryptMsgUpdate(
                                          hMsg,
                                          data,
                                          (uint)data.Length,
                                          fFinal: true));

                        uint valueLength = 0;

                        ThrowIfFailed(NativeMethods.CryptMsgGetParam(
                                          hMsg,
                                          CMSG_GETPARAM_TYPE.CMSG_CONTENT_PARAM,
                                          dwIndex: 0,
                                          pvData: null,
                                          pcbData: ref valueLength));

                        encodedData = new byte[(int)valueLength];

                        ThrowIfFailed(NativeMethods.CryptMsgGetParam(
                                          hMsg,
                                          CMSG_GETPARAM_TYPE.CMSG_CONTENT_PARAM,
                                          dwIndex: 0,
                                          pvData: encodedData,
                                          pcbData: ref valueLength));
                    }
                }

                var cms = new SignedCms();

                cms.Decode(encodedData);

                return(cms);
            }
        }