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); }
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(); } }
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); }
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(); } }
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); }
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); }
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); }
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); }
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); }
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); }