Beispiel #1
0
        private static unsafe IReadOnlyList <ICmsSignature> GetSignatures(CryptMsgSafeHandle messageHandle)
        {
            var countSize = 0u;

            if (!Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_SIGNER_COUNT_PARAM, 0, LocalBufferSafeHandle.Zero, ref countSize))
            {
                return(Array.Empty <ICmsSignature>());
            }
            uint signerCount;

            using (var countHandle = LocalBufferSafeHandle.Alloc(countSize))
            {
                if (!Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_SIGNER_COUNT_PARAM, 0, countHandle, ref countSize))
                {
                    return(Array.Empty <ICmsSignature>());
                }
                signerCount = (uint)Marshal.ReadInt32(countHandle.DangerousGetHandle());
            }
            var signatures  = new List <ICmsSignature>();
            var contentSize = 0u;

            byte[] content = null;
            if (Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_CONTENT_PARAM, 0, LocalBufferSafeHandle.Zero, ref contentSize))
            {
                using (var contentHandle = LocalBufferSafeHandle.Alloc(contentSize))
                {
                    if (Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_CONTENT_PARAM, 0, contentHandle, ref contentSize))
                    {
                        content = new byte[contentSize];
                        Marshal.Copy(contentHandle.DangerousGetHandle(), content, 0, (int)contentSize);
                    }
                }
            }
            for (var i = 0u; i < signerCount; i++)
            {
                var signerSize = 0u;
                if (!Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_SIGNER_INFO_PARAM, i, LocalBufferSafeHandle.Zero, ref signerSize))
                {
                    continue;
                }
                using (var signerHandle = LocalBufferSafeHandle.Alloc(signerSize))
                {
                    if (!Crypt32.CryptMsgGetParam(messageHandle, CryptMsgParamType.CMSG_SIGNER_INFO_PARAM, i, signerHandle, ref signerSize))
                    {
                        continue;
                    }
                    var signature = new CmsSignature(SignatureKind.Signature, messageHandle, signerHandle, content);
                    signatures.Add(signature);
                }
            }
            return(signatures.AsReadOnly());
        }
Beispiel #2
0
        internal unsafe Signature(AsnEncodedData data, SignatureKind kind)
        {
            Kind = kind;
            fixed(byte *pin = data.RawData)
            {
                EncodingType          encodingType;
                CryptQueryContentType contentType;
                CryptQueryFormatType  formatType;
                CryptMsgSafeHandle    msgHandle;
                var blob = new CRYPTOAPI_BLOB
                {
                    cbData = (uint)data.RawData.Length,
                    pbData = new IntPtr(pin)
                };
                var result = Crypt32.CryptQueryObject(
                    CryptQueryObjectType.CERT_QUERY_OBJECT_BLOB,
                    ref blob,
                    CryptQueryContentFlagType.CERT_QUERY_CONTENT_FLAG_ALL,
                    CryptQueryFormatFlagType.CERT_QUERY_FORMAT_FLAG_BINARY,
                    CryptQueryObjectFlags.NONE,
                    out encodingType,
                    out contentType,
                    out formatType,
                    IntPtr.Zero,
                    out msgHandle,
                    IntPtr.Zero);

                if (!result)
                {
                    msgHandle.Dispose();
                    throw new InvalidOperationException("Unable to read signature.");
                }
                var signerSize = 0u;

                if (!Crypt32.CryptMsgGetParam(msgHandle, CryptMsgParamType.CMSG_SIGNER_INFO_PARAM, 0, LocalBufferSafeHandle.Zero, ref signerSize))
                {
                    throw new InvalidOperationException();
                }
                using (var signerHandle = LocalBufferSafeHandle.Alloc(signerSize))
                {
                    if (!Crypt32.CryptMsgGetParam(msgHandle, CryptMsgParamType.CMSG_SIGNER_INFO_PARAM, 0, signerHandle, ref signerSize))
                    {
                        throw new InvalidOperationException();
                    }
                    InitFromHandles(msgHandle, signerHandle);
                }
            }
        }
        /// <summary>
        /// Gets PKCS#7 signature object of signed file. If file is not signed using authenticode signature, the method return null.
        /// </summary>
        /// <param name="fileInfo">An instance of file object.</param>
        /// <returns>Detached signature object.</returns>
        public static DefaultSignedPkcs7 GetSignatureObject(this FileInfo fileInfo)
        {
            if (!fileInfo.Exists)
            {
                return(null);
            }
            const Int32 CMSG_ENCODED_MESSAGE       = 29;
            const Int32 dwExpectedContentTypeFlags = Wincrypt.CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED
                                                     | Wincrypt.CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED;

            if (!Crypt32.CryptQueryObject(
                    Wincrypt.CERT_QUERY_OBJECT_FILE,
                    fileInfo.FullName,
                    dwExpectedContentTypeFlags,
                    Wincrypt.CERT_QUERY_FORMAT_FLAG_ALL,
                    0,
                    out Int32 _,
                    out Int32 pdwContentType,
                    out Int32 _,
                    out IntPtr phCertStore,
                    out IntPtr phMsg,
                    out IntPtr ppvContext
                    ))
            {
                return(null);
            }

            if (!Crypt32.CryptMsgGetParam(phMsg, CMSG_ENCODED_MESSAGE, 0, null, out Int32 pcbData))
            {
                return(null);
            }

            var pvData = new Byte[pcbData];

            Crypt32.CryptMsgGetParam(phMsg, CMSG_ENCODED_MESSAGE, 0, pvData, out pcbData);
            Crypt32.CryptMsgClose(phMsg);
            Crypt32.CertCloseStore(phCertStore, 0);
            switch (pdwContentType)
            {
            case Wincrypt.CERT_QUERY_CONTENT_FLAG_CERT:
            case Wincrypt.CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT:
                Crypt32.CertFreeCertificateContext(ppvContext);
                break;
            }
            return(new DefaultSignedPkcs7(pvData));
        }
Beispiel #4
0
        internal X509Certificate2Collection GetCertificatesFromMessage(CryptMsgSafeHandle handle)
        {
            var  size  = (uint)Marshal.SizeOf <uint>();
            var  certs = new X509Certificate2Collection();
            uint certCount;

            using (var certCountLocalBuffer = LocalBufferSafeHandle.Alloc(size))
            {
                if (!Crypt32.CryptMsgGetParam(handle, CryptMsgParamType.CMSG_CERT_COUNT_PARAM, 0, certCountLocalBuffer, ref size))
                {
                    return(certs);
                }
                certCount = unchecked ((uint)Marshal.ReadInt32(certCountLocalBuffer.DangerousGetHandle(), 0));
            }
            if (certCount == 0)
            {
                return(certs);
            }
            for (var i = 0u; i < certCount; i++)
            {
                uint certSize = 0;
                if (!Crypt32.CryptMsgGetParam(handle, CryptMsgParamType.CMSG_CERT_PARAM, i, LocalBufferSafeHandle.Zero, ref certSize))
                {
                    continue;
                }
                using (var certLocalBuffer = LocalBufferSafeHandle.Alloc(certSize))
                {
                    if (!Crypt32.CryptMsgGetParam(handle, CryptMsgParamType.CMSG_CERT_PARAM, i, certLocalBuffer, ref certSize))
                    {
                        continue;
                    }
                    var data = new byte[certSize];
                    Marshal.Copy(certLocalBuffer.DangerousGetHandle(), data, 0, data.Length);
                    var cert = new X509Certificate2(data);
                    certs.Add(cert);
                }
            }
            return(certs);
        }