private static System.Management.Automation.Signature GetSignatureFromWintrustData(string filePath, uint error, NativeStructs.WINTRUST_DATA wtd)
        {
            System.Management.Automation.Signature signature = (System.Management.Automation.Signature)null;
            X509Certificate2 timestamper = (X509Certificate2)null;

            IntPtr pProvData = WINTRUST.WTHelperProvDataFromStateData(wtd.hWVTStateData);

            if (pProvData != IntPtr.Zero)
            {
                IntPtr provSignerFromChain = WINTRUST.WTHelperGetProvSignerFromChain(pProvData, 0U, 0U, 0U);
                if (provSignerFromChain != IntPtr.Zero)
                {
                    X509Certificate2 certFromChain = SignatureHelper.GetCertFromChain(provSignerFromChain);
                    if (certFromChain != null)
                    {
                        NativeStructs.CRYPT_PROVIDER_SGNR cryptProviderSgnr = (NativeStructs.CRYPT_PROVIDER_SGNR)Marshal.PtrToStructure(provSignerFromChain, typeof(NativeStructs.CRYPT_PROVIDER_SGNR));
                        if ((int)cryptProviderSgnr.csCounterSigners == 1)
                        {
                            timestamper = SignatureHelper.GetCertFromChain(cryptProviderSgnr.pasCounterSigners);
                        }
                        signature = timestamper == null?SignatureProxy.GenerateSignature(filePath, error, certFromChain) : SignatureProxy.GenerateSignature(filePath, error, certFromChain, timestamper);
                    }
                }
            }
            if (signature == null && (int)error != 0)
            {
                signature = SignatureProxy.GenerateSignature(filePath, error);
            }
            return(signature);
        }
Exemple #2
0
        private void UntrustPublisher(System.Management.Automation.Signature signature)
        {
            X509Certificate2 signerCertificate = signature.SignerCertificate;
            X509Store        x509Store1        = new X509Store(StoreName.Disallowed);
            X509Store        x509Store2        = new X509Store(StoreName.TrustedPublisher);

            try
            {
                x509Store2.Open(OpenFlags.ReadWrite);
                x509Store2.Remove(signerCertificate);
            }
            finally
            {
                x509Store2.Close();
            }
            try
            {
                x509Store1.Open(OpenFlags.ReadWrite);
                x509Store1.Add(signerCertificate);
            }
            finally
            {
                x509Store1.Close();
            }
        }
Exemple #3
0
        private bool SetPolicyFromAuthenticodePrompt(
            string path,
            PSHost host,
            ref Exception reason,
            System.Management.Automation.Signature signature)
        {
            bool flag = false;

            switch (this.AuthenticodePrompt(path, signature, host))
            {
            case PSAuthorizationManager.RunPromptDecision.NeverRun:
                this.UntrustPublisher(signature);
                string message1 = ResourceManagerCache.FormatResourceString("Authenticode", "Reason_NeverRun", (object)path);
                reason = (Exception) new UnauthorizedAccessException(message1);
                flag   = false;
                break;

            case PSAuthorizationManager.RunPromptDecision.DoNotRun:
                flag = false;
                string message2 = ResourceManagerCache.FormatResourceString("Authenticode", "Reason_DoNotRun", (object)path);
                reason = (Exception) new UnauthorizedAccessException(message2);
                break;

            case PSAuthorizationManager.RunPromptDecision.RunOnce:
                flag = true;
                break;

            case PSAuthorizationManager.RunPromptDecision.AlwaysRun:
                this.TrustPublisher(signature);
                flag = true;
                break;
            }
            return(flag);
        }
Exemple #4
0
        private void TrustPublisher(System.Management.Automation.Signature signature)
        {
            X509Certificate2 signerCertificate = signature.SignerCertificate;
            X509Store        x509Store         = new X509Store(StoreName.TrustedPublisher);

            try
            {
                x509Store.Open(OpenFlags.ReadWrite);
                x509Store.Add(signerCertificate);
            }
            finally
            {
                x509Store.Close();
            }
        }
Exemple #5
0
        private bool IsUntrustedPublisher(System.Management.Automation.Signature signature, string file)
        {
            string    thumbprint = signature.SignerCertificate.Thumbprint;
            X509Store x509Store  = new X509Store(StoreName.Disallowed);

            x509Store.Open(OpenFlags.ReadOnly);
            foreach (X509Certificate2 certificate in x509Store.Certificates)
            {
                if (string.Equals(certificate.Thumbprint, thumbprint, StringComparison.OrdinalIgnoreCase))
                {
                    return(true);
                }
            }
            return(false);
        }
        private System.Management.Automation.Signature GetSignatureWithEncodingRetry(string path, ExternalScriptInfo script)
        {
            string fileContent = Encoding.Unicode.GetString(script.OriginalEncoding.GetPreamble()) + script.ScriptContents;

            System.Management.Automation.Signature signature = SignatureHelper.GetSignature(path, fileContent);
            if ((signature.Status != SignatureStatus.Valid) && (script.OriginalEncoding != Encoding.Unicode))
            {
                fileContent = Encoding.Unicode.GetString(Encoding.Unicode.GetPreamble()) + script.ScriptContents;
                System.Management.Automation.Signature signature2 = SignatureHelper.GetSignature(path, fileContent);
                if (signature2.Status == SignatureStatus.Valid)
                {
                    signature = signature2;
                }
            }
            return(signature);
        }
        private bool IsUntrustedPublisher(System.Management.Automation.Signature signature, string file)
        {
            string    thumbprint = signature.SignerCertificate.Thumbprint;
            X509Store store      = new X509Store(StoreName.Disallowed);

            store.Open(OpenFlags.ReadOnly);
            X509Certificate2Enumerator enumerator = store.Certificates.GetEnumerator();

            while (enumerator.MoveNext())
            {
                if (string.Equals(enumerator.Current.Thumbprint, thumbprint, StringComparison.OrdinalIgnoreCase))
                {
                    return(true);
                }
            }
            return(false);
        }
Exemple #8
0
        private PSAuthorizationManager.RunPromptDecision AuthenticodePrompt(
            string path,
            System.Management.Automation.Signature signature,
            PSHost host)
        {
            if (host == null || host.UI == null)
            {
                return(PSAuthorizationManager.RunPromptDecision.DoNotRun);
            }
            PSAuthorizationManager.RunPromptDecision runPromptDecision1 = PSAuthorizationManager.RunPromptDecision.DoNotRun;
            if (signature == null)
            {
                return(runPromptDecision1);
            }
            PSAuthorizationManager.RunPromptDecision runPromptDecision2;
            switch (signature.Status)
            {
            case SignatureStatus.Valid:
                Collection <ChoiceDescription> authenticodePromptChoices = this.GetAuthenticodePromptChoices();
                string resourceString = ResourceManagerCache.GetResourceString("Authenticode", "AuthenticodePromptCaption");
                string message;
                if (signature.SignerCertificate == null)
                {
                    message = ResourceManagerCache.FormatResourceString("Authenticode", "AuthenticodePromptText_UnknownPublisher", (object)path);
                }
                else
                {
                    message = ResourceManagerCache.FormatResourceString("Authenticode", "AuthenticodePromptText", (object)path, (object)signature.SignerCertificate.SubjectName.Name);
                }
                runPromptDecision2 = (PSAuthorizationManager.RunPromptDecision)host.UI.PromptForChoice(resourceString, message, authenticodePromptChoices, 1);
                break;

            case SignatureStatus.UnknownError:
            case SignatureStatus.NotSigned:
            case SignatureStatus.HashMismatch:
            case SignatureStatus.NotSupportedFileFormat:
                runPromptDecision2 = PSAuthorizationManager.RunPromptDecision.DoNotRun;
                break;

            default:
                runPromptDecision2 = PSAuthorizationManager.RunPromptDecision.DoNotRun;
                break;
            }
            return(runPromptDecision2);
        }
        private RunPromptDecision AuthenticodePrompt(string path, System.Management.Automation.Signature signature, PSHost host)
        {
            Collection <ChoiceDescription> authenticodePromptChoices;
            string authenticodePromptCaption;
            string str2;

            if ((host == null) || (host.UI == null))
            {
                return(RunPromptDecision.DoNotRun);
            }
            RunPromptDecision doNotRun = RunPromptDecision.DoNotRun;

            if (signature == null)
            {
                return(doNotRun);
            }
            switch (signature.Status)
            {
            case SignatureStatus.Valid:
                authenticodePromptChoices = this.GetAuthenticodePromptChoices();
                authenticodePromptCaption = Authenticode.AuthenticodePromptCaption;
                if (signature.SignerCertificate != null)
                {
                    str2 = StringUtil.Format(Authenticode.AuthenticodePromptText, path, signature.SignerCertificate.SubjectName.Name);
                    break;
                }
                str2 = StringUtil.Format(Authenticode.AuthenticodePromptText_UnknownPublisher, path);
                break;

            case SignatureStatus.UnknownError:
            case SignatureStatus.NotSigned:
            case SignatureStatus.HashMismatch:
            case SignatureStatus.NotSupportedFileFormat:
                return(RunPromptDecision.DoNotRun);

            default:
                return(RunPromptDecision.DoNotRun);
            }
            return((RunPromptDecision)host.UI.PromptForChoice(authenticodePromptCaption, str2, authenticodePromptChoices, 1));
        }
        private static Signature SignFile(NativeStructs.SigningOption option, string fileName, X509Certificate2 certificate, string timeStampServerUrl, string hashAlgorithm)
        {
            System.Management.Automation.Signature signature = (System.Management.Automation.Signature)null;
            IntPtr num            = IntPtr.Zero;
            uint   error          = 0U;
            string hashAlgorithm1 = (string)null;

            CheckArgForNullOrEmpty(fileName, "fileName");
            CheckArgForNull((object)certificate, "certificate");

            if (!string.IsNullOrEmpty(timeStampServerUrl) && (timeStampServerUrl.Length <= 7 || timeStampServerUrl.IndexOf("http://", StringComparison.OrdinalIgnoreCase) != 0))
            {
                throw new ArgumentException("Time stamp server url required");
            }

            if (!string.IsNullOrEmpty(hashAlgorithm))
            {
                IntPtr oidInfo = CRYPT32.CryptFindOIDInfo(2U, Marshal.StringToHGlobalUni(hashAlgorithm), 0U);
                if (oidInfo == IntPtr.Zero)
                {
                    throw new ArgumentException("Invalid hash algorithm");
                }

                hashAlgorithm1 = ((NativeStructs.CRYPT_OID_INFO)Marshal.PtrToStructure(oidInfo, typeof(NativeStructs.CRYPT_OID_INFO))).pszOID;
            }
            if (!CertIsGoodForSigning(certificate))
            {
                throw new ArgumentException("Supplied certificate cannot be used to sign files.");
            }

            CheckIfFileExists(fileName);
            try
            {
                string timeStampServerUrl1 = (string)null;
                if (!string.IsNullOrEmpty(timeStampServerUrl))
                {
                    timeStampServerUrl1 = timeStampServerUrl;
                }
                NativeStructs.CRYPTUI_WIZ_DIGITAL_SIGN_INFO wizDigitalSignInfo = NativeStructs.InitSignInfoStruct(fileName, certificate, timeStampServerUrl1, hashAlgorithm1, option);
                num = Marshal.AllocCoTaskMem(Marshal.SizeOf((object)wizDigitalSignInfo));
                Marshal.StructureToPtr((object)wizDigitalSignInfo, num, false);
                bool flag = CRYPTUI.CryptUIWizDigitalSign(1U, IntPtr.Zero, IntPtr.Zero, num, IntPtr.Zero);
                Marshal.DestroyStructure(wizDigitalSignInfo.pSignExtInfo, typeof(NativeStructs.CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO));
                Marshal.FreeCoTaskMem(wizDigitalSignInfo.pSignExtInfo);
                if (!flag)
                {
                    error = SignatureHelper.GetLastWin32Error();
                    switch (error)
                    {
                    case 2147500037U:
                    case 2147942401U:
                    case 2147954407U:
                        flag = true;
                        break;

                    case 2148073480U:
                        throw new ArgumentException("InvalidHashAlgorithm");

                    default:
                        throw new ArgumentException(string.Format("CryptUIWizDigitalSign: failed: {0:x}", new object[1]
                        {
                            (object)error
                        }));
                    }
                }
                signature = !flag?SignatureProxy.GenerateSignature(fileName, error) : SignatureHelper.GetSignature(fileName);
            }
            finally
            {
                Marshal.DestroyStructure(num, typeof(NativeStructs.CRYPTUI_WIZ_DIGITAL_SIGN_INFO));
                Marshal.FreeCoTaskMem(num);
            }
            return(signature);
        }
Exemple #11
0
        private bool CheckPolicy(ExternalScriptInfo script, PSHost host, out Exception reason)
        {
            bool flag1 = false;

            reason = (Exception)null;
            string path = script.Path;

            if (path.IndexOf('\\') < 0)
            {
                throw PSAuthorizationManager.tracer.NewArgumentException("path");
            }
            FileInfo fileInfo = path.LastIndexOf('\\') != path.Length - 1 ? new FileInfo(path) : throw PSAuthorizationManager.tracer.NewArgumentException("path");

            if (!fileInfo.Exists)
            {
                return(false);
            }
            if (!PSAuthorizationManager.IsSupportedExtension(fileInfo.Extension) || this.IsProductBinary(path))
            {
                return(true);
            }
            this.executionPolicy = SecuritySupport.GetExecutionPolicy(this.shellId);
            if (this.executionPolicy == ExecutionPolicy.Bypass)
            {
                return(true);
            }
            if (SecuritySupport.GetSaferPolicy(path) == SaferPolicy.Disallowed)
            {
                string message = ResourceManagerCache.FormatResourceString("Authenticode", "Reason_DisallowedBySafer", (object)path);
                reason = (Exception) new UnauthorizedAccessException(message);
                return(false);
            }
            if (this.executionPolicy == ExecutionPolicy.Unrestricted)
            {
                if (!this.IsLocalFile(fileInfo.FullName))
                {
                    if (string.IsNullOrEmpty(script.ScriptContents))
                    {
                        string message = ResourceManagerCache.FormatResourceString("Authenticode", "Reason_FileContentUnavailable", (object)path);
                        reason = (Exception) new UnauthorizedAccessException(message);
                        return(false);
                    }
                    System.Management.Automation.Signature withEncodingRetry = this.GetSignatureWithEncodingRetry(path, script);
                    if (withEncodingRetry.Status == SignatureStatus.Valid && this.IsTrustedPublisher(withEncodingRetry, path))
                    {
                        flag1 = true;
                    }
                    if (!flag1)
                    {
                        PSAuthorizationManager.RunPromptDecision runPromptDecision;
                        do
                        {
                            runPromptDecision = this.RemoteFilePrompt(path, host);
                            if (runPromptDecision == PSAuthorizationManager.RunPromptDecision.Suspend)
                            {
                                host.EnterNestedPrompt();
                            }
                        }while (runPromptDecision == PSAuthorizationManager.RunPromptDecision.Suspend);
                        switch (runPromptDecision - 1)
                        {
                        case PSAuthorizationManager.RunPromptDecision.DoNotRun:
                            flag1 = true;
                            break;

                        default:
                            flag1 = false;
                            string message = ResourceManagerCache.FormatResourceString("Authenticode", "Reason_DoNotRun", (object)path);
                            reason = (Exception) new UnauthorizedAccessException(message);
                            break;
                        }
                    }
                }
                else
                {
                    flag1 = true;
                }
            }
            else if (this.IsLocalFile(fileInfo.FullName) && this.executionPolicy == ExecutionPolicy.RemoteSigned)
            {
                flag1 = true;
            }
            else if (this.executionPolicy == ExecutionPolicy.AllSigned || this.executionPolicy == ExecutionPolicy.RemoteSigned)
            {
                if (string.IsNullOrEmpty(script.ScriptContents))
                {
                    string message = ResourceManagerCache.FormatResourceString("Authenticode", "Reason_FileContentUnavailable", (object)path);
                    reason = (Exception) new UnauthorizedAccessException(message);
                    return(false);
                }
                System.Management.Automation.Signature withEncodingRetry = this.GetSignatureWithEncodingRetry(path, script);
                if (withEncodingRetry.Status == SignatureStatus.Valid)
                {
                    flag1 = this.IsTrustedPublisher(withEncodingRetry, path) || this.SetPolicyFromAuthenticodePrompt(path, host, ref reason, withEncodingRetry);
                }
                else
                {
                    flag1 = false;
                    if (withEncodingRetry.Status == SignatureStatus.NotTrusted)
                    {
                        reason = (Exception) new UnauthorizedAccessException(ResourceManagerCache.FormatResourceString("Authenticode", "Reason_NotTrusted", (object)path, (object)withEncodingRetry.SignerCertificate.SubjectName.Name));
                    }
                    else
                    {
                        reason = (Exception) new UnauthorizedAccessException(ResourceManagerCache.FormatResourceString("Authenticode", "Reason_Unknown", (object)path, (object)withEncodingRetry.StatusMessage));
                    }
                }
            }
            else
            {
                flag1 = false;
                bool flag2 = false;
                if (string.Equals(fileInfo.Extension, ".ps1xml", StringComparison.OrdinalIgnoreCase))
                {
                    string[] strArray = new string[2]
                    {
                        Environment.GetFolderPath(Environment.SpecialFolder.System),
                        Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)
                    };
                    foreach (string str in strArray)
                    {
                        if (fileInfo.FullName.StartsWith(str, StringComparison.OrdinalIgnoreCase))
                        {
                            flag1 = true;
                        }
                    }
                    if (!flag1)
                    {
                        System.Management.Automation.Signature withEncodingRetry = this.GetSignatureWithEncodingRetry(path, script);
                        if (withEncodingRetry.Status == SignatureStatus.Valid)
                        {
                            if (this.IsTrustedPublisher(withEncodingRetry, path))
                            {
                                flag1 = true;
                            }
                            else
                            {
                                flag1 = this.SetPolicyFromAuthenticodePrompt(path, host, ref reason, withEncodingRetry);
                                flag2 = true;
                            }
                        }
                    }
                }
                if (!flag1 && !flag2)
                {
                    reason = (Exception) new UnauthorizedAccessException(ResourceManagerCache.FormatResourceString("Authenticode", "Reason_RestrictedMode", (object)path));
                }
            }
            return(flag1);
        }
        private bool CheckPolicy(ExternalScriptInfo script, PSHost host, out Exception reason)
        {
            string str2;
            bool   flag = false;

            reason = null;
            string path = script.Path;

            if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            {
                if (path.IndexOf('\\') < 0)
                {
                    throw PSTraceSource.NewArgumentException("path");
                }
                if (path.LastIndexOf('\\') == (path.Length - 1))
                {
                    throw PSTraceSource.NewArgumentException("path");
                }
            }
            FileInfo info = new FileInfo(path);

            if (!info.Exists)
            {
                reason = new FileNotFoundException(path);
                return(false);
            }
            if (!IsSupportedExtension(info.Extension))
            {
                return(true);
            }
            if (this.IsProductBinary(path))
            {
                return(true);
            }
            this.executionPolicy = SecuritySupport.GetExecutionPolicy(this.shellId);
            if (this.executionPolicy == ExecutionPolicy.Bypass)
            {
                return(true);
            }
            SaferPolicy disallowed = SaferPolicy.Disallowed;
            int         num        = 0;
            bool        flag2      = false;

            while (!flag2 && (num < 5))
            {
                try
                {
                    disallowed = SecuritySupport.GetSaferPolicy(path);
                    flag2      = true;
                    continue;
                }
                catch (Win32Exception)
                {
                    if (num > 4)
                    {
                        throw;
                    }
                    num++;
                    Thread.Sleep(100);
                    continue;
                }
            }
            if (disallowed == SaferPolicy.Disallowed)
            {
                str2   = StringUtil.Format(Authenticode.Reason_DisallowedBySafer, path);
                reason = new UnauthorizedAccessException(str2);
                return(false);
            }
            if (this.executionPolicy != ExecutionPolicy.Unrestricted)
            {
                if (this.IsLocalFile(info.FullName) && (this.executionPolicy == ExecutionPolicy.RemoteSigned))
                {
                    return(true);
                }
                if ((this.executionPolicy == ExecutionPolicy.AllSigned) || (this.executionPolicy == ExecutionPolicy.RemoteSigned))
                {
                    if (string.IsNullOrEmpty(script.ScriptContents))
                    {
                        str2   = StringUtil.Format(Authenticode.Reason_FileContentUnavailable, path);
                        reason = new UnauthorizedAccessException(str2);
                        return(false);
                    }
                    System.Management.Automation.Signature signature = this.GetSignatureWithEncodingRetry(path, script);
                    if (signature.Status == SignatureStatus.Valid)
                    {
                        return(this.IsTrustedPublisher(signature, path) || this.SetPolicyFromAuthenticodePrompt(path, host, ref reason, signature));
                    }
                    flag = false;
                    if (signature.Status == SignatureStatus.NotTrusted)
                    {
                        reason = new UnauthorizedAccessException(StringUtil.Format(Authenticode.Reason_NotTrusted, path, signature.SignerCertificate.SubjectName.Name));
                        return(flag);
                    }
                    reason = new UnauthorizedAccessException(StringUtil.Format(Authenticode.Reason_Unknown, path, signature.StatusMessage));
                    return(flag);
                }
                flag = false;
                bool flag3 = false;
                if (string.Equals(info.Extension, ".ps1xml", StringComparison.OrdinalIgnoreCase))
                {
                    string[] strArray = new string[] { Environment.GetFolderPath(Environment.SpecialFolder.System), Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) };
                    foreach (string str3 in strArray)
                    {
                        if (info.FullName.StartsWith(str3, StringComparison.OrdinalIgnoreCase))
                        {
                            flag = true;
                        }
                    }
                    if (!flag)
                    {
                        System.Management.Automation.Signature signature3 = this.GetSignatureWithEncodingRetry(path, script);
                        if (signature3.Status == SignatureStatus.Valid)
                        {
                            if (this.IsTrustedPublisher(signature3, path))
                            {
                                flag = true;
                            }
                            else
                            {
                                flag  = this.SetPolicyFromAuthenticodePrompt(path, host, ref reason, signature3);
                                flag3 = true;
                            }
                        }
                    }
                }
                if (!flag && !flag3)
                {
                    reason = new UnauthorizedAccessException(StringUtil.Format(Authenticode.Reason_RestrictedMode, path));
                }
                return(flag);
            }
            if (this.IsLocalFile(info.FullName))
            {
                return(true);
            }
            if (string.IsNullOrEmpty(script.ScriptContents))
            {
                str2   = StringUtil.Format(Authenticode.Reason_FileContentUnavailable, path);
                reason = new UnauthorizedAccessException(str2);
                return(false);
            }
            System.Management.Automation.Signature signatureWithEncodingRetry = this.GetSignatureWithEncodingRetry(path, script);
            if ((signatureWithEncodingRetry.Status == SignatureStatus.Valid) && this.IsTrustedPublisher(signatureWithEncodingRetry, path))
            {
                flag = true;
            }
            if (flag)
            {
                return(flag);
            }
            RunPromptDecision doNotRun = RunPromptDecision.DoNotRun;

Label_0149:
            doNotRun = this.RemoteFilePrompt(path, host);
            if (doNotRun == RunPromptDecision.Suspend)
            {
                host.EnterNestedPrompt();
            }
            switch (doNotRun)
            {
            case RunPromptDecision.RunOnce:
                return(true);

            case RunPromptDecision.Suspend:
                goto Label_0149;
            }
            flag   = false;
            str2   = StringUtil.Format(Authenticode.Reason_DoNotRun, path);
            reason = new UnauthorizedAccessException(str2);
            return(flag);
        }
        private bool SetPolicyFromAuthenticodePrompt(string path, PSHost host, ref Exception reason, System.Management.Automation.Signature signature)
        {
            string str;
            bool   flag = false;

            switch (this.AuthenticodePrompt(path, signature, host))
            {
            case RunPromptDecision.NeverRun:
                this.UntrustPublisher(signature);
                str    = StringUtil.Format(Authenticode.Reason_NeverRun, path);
                reason = new UnauthorizedAccessException(str);
                return(false);

            case RunPromptDecision.DoNotRun:
                flag   = false;
                str    = StringUtil.Format(Authenticode.Reason_DoNotRun, path);
                reason = new UnauthorizedAccessException(str);
                return(flag);

            case RunPromptDecision.RunOnce:
                return(true);

            case RunPromptDecision.AlwaysRun:
                this.TrustPublisher(signature);
                return(true);
            }
            return(flag);
        }
Exemple #14
0
        internal static Signature SignFile(SigningOption option,
                                           string fileName,
                                           X509Certificate2 certificate,
                                           string timeStampServerUrl,
                                           string hashAlgorithm)
        {
            bool      result    = false;
            Signature signature = null;
            IntPtr    pSignInfo = IntPtr.Zero;
            DWORD     error     = 0;
            string    hashOid   = null;

            Utils.CheckArgForNullOrEmpty(fileName, "fileName");
            Utils.CheckArgForNull(certificate, "certificate");

            // If given, TimeStamp server URLs must begin with http://
            if (!String.IsNullOrEmpty(timeStampServerUrl))
            {
                if ((timeStampServerUrl.Length <= 7) ||
                    (timeStampServerUrl.IndexOf("http://", StringComparison.OrdinalIgnoreCase) != 0))
                {
                    throw PSTraceSource.NewArgumentException(
                              "certificate",
                              Authenticode.TimeStampUrlRequired);
                }
            }

            // Validate that the hash algorithm is valid
            if (!String.IsNullOrEmpty(hashAlgorithm))
            {
                IntPtr intptrAlgorithm = Marshal.StringToHGlobalUni(hashAlgorithm);

                IntPtr oidPtr = NativeMethods.CryptFindOIDInfo(NativeConstants.CRYPT_OID_INFO_NAME_KEY,
                                                               intptrAlgorithm,
                                                               0);

                // If we couldn't find an OID for the hash
                // algorithm, it was invalid.
                if (oidPtr == IntPtr.Zero)
                {
                    throw PSTraceSource.NewArgumentException(
                              "certificate",
                              Authenticode.InvalidHashAlgorithm);
                }
                else
                {
                    NativeMethods.CRYPT_OID_INFO oidInfo =
                        Marshal.PtrToStructure <NativeMethods.CRYPT_OID_INFO>(oidPtr);

                    hashOid = oidInfo.pszOID;
                }
            }

            if (!SecuritySupport.CertIsGoodForSigning(certificate))
            {
                throw PSTraceSource.NewArgumentException(
                          "certificate",
                          Authenticode.CertNotGoodForSigning);
            }

            SecuritySupport.CheckIfFileExists(fileName);
            //SecurityUtils.CheckIfFileSmallerThan4Bytes(fileName);

            try
            {
                // CryptUI is not documented either way, but does not
                // support empty strings for the timestamp server URL.
                // It expects null, only.  Instead, it randomly AVs if you
                // try.
                string timeStampServerUrlForCryptUI = null;
                if (!String.IsNullOrEmpty(timeStampServerUrl))
                {
                    timeStampServerUrlForCryptUI = timeStampServerUrl;
                }

                //
                // first initialize the struct to pass to
                // CryptUIWizDigitalSign() function
                //
                NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO si = NativeMethods.InitSignInfoStruct(fileName,
                                                                                                  certificate,
                                                                                                  timeStampServerUrlForCryptUI,
                                                                                                  hashOid,
                                                                                                  option);

                pSignInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(si));
                Marshal.StructureToPtr(si, pSignInfo, false);

                //
                // sign the file
                //
                // The GetLastWin32Error of this is checked, but PreSharp doesn't seem to be
                // able to see that.
#pragma warning disable 56523
                result = NativeMethods.CryptUIWizDigitalSign(
                    (DWORD)NativeMethods.CryptUIFlags.CRYPTUI_WIZ_NO_UI,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    pSignInfo,
                    IntPtr.Zero);
#pragma warning enable 56523

                if (si.pSignExtInfo != null)
                {
                    Marshal.DestroyStructure <NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO>(si.pSignExtInfo);
                    Marshal.FreeCoTaskMem(si.pSignExtInfo);
                }

                if (!result)
                {
                    error = GetLastWin32Error();

                    //
                    // ISSUE-2004/05/08-kumarp : there seems to be a bug
                    // in CryptUIWizDigitalSign().
                    // It returns 80004005 or 80070001
                    // but it signs the file correctly. Mask this error
                    // till we figure out this odd behavior.
                    //
                    if ((error == 0x80004005) ||
                        (error == 0x80070001) ||

                        // CryptUIWizDigitalSign introduced a breaking change in Win8 to return this
                        // error code (ERROR_INTERNET_NAME_NOT_RESOLVED) when you provide an invalid
                        // timestamp server. It used to be 0x80070001.
                        // Also masking this out so that we don't introduce a breaking change ourselves.
                        (error == 0x80072EE7)
                        )
                    {
                        result = true;
                    }
                    else
                    {
                        if (error == Win32Errors.NTE_BAD_ALGID)
                        {
                            throw PSTraceSource.NewArgumentException(
                                      "certificate",
                                      Authenticode.InvalidHashAlgorithm);
                        }

                        s_tracer.TraceError("CryptUIWizDigitalSign: failed: {0:x}",
                                            error);
                    }
                }

                if (result)
                {
                    signature = GetSignature(fileName, null);
                }
                else
                {
                    signature = new Signature(fileName, (DWORD)error);
                }
            }
            finally
            {
                Marshal.DestroyStructure <NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO>(pSignInfo);
                Marshal.FreeCoTaskMem(pSignInfo);
            }

            return(signature);
        }
Exemple #15
0
        private static Signature GetSignatureFromCatalog(string filename)
        {
            if (Signature.CatalogApiAvailable.HasValue && !Signature.CatalogApiAvailable.Value)
            {
                // Signature.CatalogApiAvailable would be set to false the first time it is detected that
                // WTGetSignatureInfo API does not exist on the platform, or if the API is not functional on the target platform.
                // Just return from the function instead of revalidating.
                return(null);
            }

            Signature signature = null;

            Utils.CheckArgForNullOrEmpty(filename, "fileName");
            SecuritySupport.CheckIfFileExists(filename);

            try
            {
                using (FileStream stream = File.OpenRead(filename))
                {
                    NativeMethods.SIGNATURE_INFO sigInfo = new NativeMethods.SIGNATURE_INFO();
                    sigInfo.cbSize = (uint)Marshal.SizeOf(sigInfo);

                    IntPtr ppCertContext = IntPtr.Zero;
                    IntPtr phStateData   = IntPtr.Zero;

                    try
                    {
                        int hresult = NativeMethods.WTGetSignatureInfo(filename, stream.SafeFileHandle.DangerousGetHandle(),
                                                                       NativeMethods.SIGNATURE_INFO_FLAGS.SIF_CATALOG_SIGNED |
                                                                       NativeMethods.SIGNATURE_INFO_FLAGS.SIF_CATALOG_FIRST |
                                                                       NativeMethods.SIGNATURE_INFO_FLAGS.SIF_AUTHENTICODE_SIGNED |
                                                                       NativeMethods.SIGNATURE_INFO_FLAGS.SIF_BASE_VERIFICATION |
                                                                       NativeMethods.SIGNATURE_INFO_FLAGS.SIF_CHECK_OS_BINARY,
                                                                       ref sigInfo, ref ppCertContext, ref phStateData);

                        if (Utils.Succeeded(hresult))
                        {
                            DWORD error = GetErrorFromSignatureState(sigInfo.nSignatureState);

                            X509Certificate2 cert = null;

                            if (ppCertContext != IntPtr.Zero)
                            {
                                cert = new X509Certificate2(ppCertContext);

                                // Get the time stamper certificate if available
                                TryGetProviderSigner(phStateData, out IntPtr pProvSigner, out X509Certificate2 timestamperCert);
                                if (timestamperCert != null)
                                {
                                    signature = new Signature(filename, error, cert, timestamperCert);
                                }
                                else
                                {
                                    signature = new Signature(filename, error, cert);
                                }

                                switch (sigInfo.nSignatureType)
                                {
                                case NativeMethods.SIGNATURE_INFO_TYPE.SIT_AUTHENTICODE: signature.SignatureType = SignatureType.Authenticode; break;

                                case NativeMethods.SIGNATURE_INFO_TYPE.SIT_CATALOG: signature.SignatureType = SignatureType.Catalog; break;
                                }

                                if (sigInfo.fOSBinary == 1)
                                {
                                    signature.IsOSBinary = true;
                                }
                            }
                            else
                            {
                                signature = new Signature(filename, error);
                            }

                            if (!Signature.CatalogApiAvailable.HasValue)
                            {
                                string productFile = Path.Combine(Utils.DefaultPowerShellAppBase, "Modules\\PSDiagnostics\\PSDiagnostics.psm1");
                                if (signature.Status != SignatureStatus.Valid)
                                {
                                    if (string.Equals(filename, productFile, StringComparison.OrdinalIgnoreCase))
                                    {
                                        Signature.CatalogApiAvailable = false;
                                    }
                                    else
                                    {
                                        // ProductFile has to be Catalog signed. Hence validating
                                        // to see if the Catalog API is functional using the ProductFile.
                                        Signature productFileSignature = GetSignatureFromCatalog(productFile);
                                        Signature.CatalogApiAvailable = (productFileSignature != null && productFileSignature.Status == SignatureStatus.Valid);
                                    }
                                }
                            }
                        }
                        else
                        {
                            // If calling NativeMethods.WTGetSignatureInfo failed (returned a non-zero value), we still want to set Signature.CatalogApiAvailable to false.
                            Signature.CatalogApiAvailable = false;
                        }
                    }
                    finally
                    {
                        if (phStateData != IntPtr.Zero)
                        {
                            NativeMethods.FreeWVTStateData(phStateData);
                        }

                        if (ppCertContext != IntPtr.Zero)
                        {
                            NativeMethods.CertFreeCertificateContext(ppCertContext);
                        }
                    }
                }
            }
            catch (TypeLoadException)
            {
                // If we don't have WTGetSignatureInfo, don't return a Signature.
                Signature.CatalogApiAvailable = false;
                return(null);
            }

            return(signature);
        }
Exemple #16
0
        private static Signature GetSignatureFromWintrustData(
            string filePath,
            DWORD error,
            NativeMethods.WINTRUST_DATA wtd)
        {
            Signature        signature       = null;
            X509Certificate2 signerCert      = null;
            X509Certificate2 timestamperCert = null;

            s_tracer.WriteLine("GetSignatureFromWintrustData: error: {0}", error);

            // The GetLastWin32Error of this is checked, but PreSharp doesn't seem to be
            // able to see that.
#pragma warning disable 56523
            IntPtr pProvData =
                NativeMethods.WTHelperProvDataFromStateData(wtd.hWVTStateData);
#pragma warning enable 56523

            if (pProvData != IntPtr.Zero)
            {
                IntPtr pProvSigner =
                    NativeMethods.WTHelperGetProvSignerFromChain(pProvData, 0, 0, 0);
                if (pProvSigner != IntPtr.Zero)
                {
                    //
                    // get cert of the signer
                    //
                    signerCert = GetCertFromChain(pProvSigner);

                    if (signerCert != null)
                    {
                        NativeMethods.CRYPT_PROVIDER_SGNR provSigner =
                            (NativeMethods.CRYPT_PROVIDER_SGNR)
                            ClrFacade.PtrToStructure <NativeMethods.CRYPT_PROVIDER_SGNR>(pProvSigner);
                        if (provSigner.csCounterSigners == 1)
                        {
                            //
                            // time stamper cert available
                            //
                            timestamperCert = GetCertFromChain(provSigner.pasCounterSigners);
                        }

                        if (timestamperCert != null)
                        {
                            signature = new Signature(filePath,
                                                      error,
                                                      signerCert,
                                                      timestamperCert);
                        }
                        else
                        {
                            signature = new Signature(filePath,
                                                      error,
                                                      signerCert);
                        }

                        signature.SignatureType = SignatureType.Authenticode;
                    }
                }
            }

            Diagnostics.Assert(((error == 0) && (signature != null)) || (error != 0), "GetSignatureFromWintrustData: general crypto failure");

            if ((signature == null) && (error != 0))
            {
                signature = new Signature(filePath, error);
            }

            return(signature);
        }