public string GetSignedUrl(SigningOption options) { ValidateOptions(options); var signingPayloadAsString = string.Join("\n", BuildSigningPayload(options)); var encryptedBase64String = EncryptPayload(signingPayloadAsString); return(PrepareSignedUrl(options, encryptedBase64String)); }
private IList <string> BuildSigningPayload(SigningOption options) { var payload = new List <string> { BuildActionMethod(options.Action), BuildContentMD5(options.ContentMD5), BuildContentType(options.ContentType), BuildExpiration(options.ExpireDate), BuildCanonicalizedResource(options.Path) }; return(payload); }
private string PrepareSignedUrl(SigningOption options, string signature) { var uri = new UriBuilder { Scheme = "https", Host = $"{_configuration.StorageBaseAuthority.TrimSlashes().Replace("https://", "")}/{_credentials.GetDefaultBucket().TrimSlashes()}", Path = options.Path.Trim().TrimSlashes(), Query = $"GoogleAccessId={_credentials.GetServiceAccountEmail()}&Expires={BuildExpiration(options.ExpireDate)}&Signature={WebUtility.UrlEncode(signature)}" }; return(uri.Uri.AbsoluteUri); }
internal static int GetCertChoiceFromSigningOption(SigningOption option) { switch (option) { case SigningOption.AddOnlyCertificate: return(0); case SigningOption.AddFullCertificateChain: return(1); case SigningOption.AddFullCertificateChainExceptRoot: return(2); } return(2); }
private void ValidateOptions(SigningOption options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (options.ExpireDate.ToUnixSeconds() == 0) { throw new ArgumentOutOfRangeException(nameof(options.ExpireDate), "ExpireDate should be reasonable value"); } if (string.IsNullOrWhiteSpace(options.Path)) { throw new ArgumentNullException(nameof(options.Path)); } }
private static SigningOption GetSigningOption(string optionName) { SetAuthenticodeSignatureCommand.SigningOptionInfo[] signingOptionInfoArray = SetAuthenticodeSignatureCommand.sigOptionInfo; int num = 0; while (num < (int)signingOptionInfoArray.Length) { SetAuthenticodeSignatureCommand.SigningOptionInfo signingOptionInfo = signingOptionInfoArray[num]; if (!string.Equals(optionName, signingOptionInfo.optionName, StringComparison.OrdinalIgnoreCase)) { num++; } else { SigningOption signingOption = signingOptionInfo.option; return(signingOption); } } return(SigningOption.AddFullCertificateChainExceptRoot); }
internal static NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO InitSignInfoStruct( string fileName, X509Certificate2 signingCert, string timeStampServerUrl, string hashAlgorithm, SigningOption option) { NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO wizDigitalSignInfo = new NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO(); wizDigitalSignInfo.dwSize = (uint)Marshal.SizeOf((object)wizDigitalSignInfo); wizDigitalSignInfo.dwSubjectChoice = 1U; wizDigitalSignInfo.pwszFileName = fileName; wizDigitalSignInfo.dwSigningCertChoice = 1U; wizDigitalSignInfo.pSigningCertContext = signingCert.Handle; wizDigitalSignInfo.pwszTimestampURL = timeStampServerUrl; wizDigitalSignInfo.dwAdditionalCertChoice = NativeMethods.GetCertChoiceFromSigningOption(option); NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO signExtendedInfo = NativeMethods.InitSignInfoExtendedStruct("", "", hashAlgorithm); IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf((object)signExtendedInfo)); Marshal.StructureToPtr((object)signExtendedInfo, ptr, false); wizDigitalSignInfo.pSignExtInfo = ptr; return(wizDigitalSignInfo); }
internal static uint GetCertChoiceFromSigningOption(SigningOption option) { uint num; switch (option) { case SigningOption.AddOnlyCertificate: num = 0U; break; case SigningOption.AddFullCertificateChain: num = 1U; break; case SigningOption.AddFullCertificateChainExceptRoot: num = 2U; break; default: num = 2U; break; } return(num); }
internal static CRYPTUI_WIZ_DIGITAL_SIGN_INFO InitSignInfoStruct(string fileName, X509Certificate2 signingCert, string timeStampServerUrl, string hashAlgorithm, SigningOption option) { CRYPTUI_WIZ_DIGITAL_SIGN_INFO cryptui_wiz_digital_sign_info; cryptui_wiz_digital_sign_info = new CRYPTUI_WIZ_DIGITAL_SIGN_INFO { dwSize = (int) Marshal.SizeOf(typeof(CRYPTUI_WIZ_DIGITAL_SIGN_INFO)), dwSubjectChoice = 1, pwszFileName = fileName, dwSigningCertChoice = 1, pSigningCertContext = signingCert.Handle, pwszTimestampURL = timeStampServerUrl, dwAdditionalCertChoice = GetCertChoiceFromSigningOption(option) }; CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO structure = InitSignInfoExtendedStruct("", "", hashAlgorithm); IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(structure)); Marshal.StructureToPtr(structure, ptr, false); cryptui_wiz_digital_sign_info.pSignExtInfo = ptr; return cryptui_wiz_digital_sign_info; }
internal SigningOptionInfo(SigningOption o, string n) { this.option = o; this.optionName = n; }
internal static int GetCertChoiceFromSigningOption(SigningOption option) { switch (option) { case SigningOption.AddOnlyCertificate: return 0; case SigningOption.AddFullCertificateChain: return 1; case SigningOption.AddFullCertificateChainExceptRoot: return 2; } return 2; }
internal static DWORD GetCertChoiceFromSigningOption( SigningOption option) { DWORD cc = 0; switch (option) { case SigningOption.AddOnlyCertificate: cc = 0; break; case SigningOption.AddFullCertificateChain: cc = (DWORD)SignInfoAdditionalCertChoice.CRYPTUI_WIZ_DIGITAL_SIGN_ADD_CHAIN; break; case SigningOption.AddFullCertificateChainExceptRoot: cc = (DWORD)SignInfoAdditionalCertChoice.CRYPTUI_WIZ_DIGITAL_SIGN_ADD_CHAIN_NO_ROOT; break; default: cc = (DWORD)SignInfoAdditionalCertChoice.CRYPTUI_WIZ_DIGITAL_SIGN_ADD_CHAIN_NO_ROOT; break; } return cc; }
protected override Signature PerformAction(string filePath) { Signature signature; SigningOption signingOption = SetAuthenticodeSignatureCommand.GetSigningOption(this.IncludeChain); if (this.Certificate != null) { if (SecuritySupport.CertIsGoodForSigning(this.Certificate)) { if (base.ShouldProcess(filePath)) { FileInfo fileInfo = null; try { if (this.Force) { try { FileInfo fileInfo1 = new FileInfo(filePath); if (fileInfo1 != null && (fileInfo1.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) { fileInfo = fileInfo1; FileInfo attributes = fileInfo1; attributes.Attributes = attributes.Attributes & (FileAttributes.Hidden | FileAttributes.System | FileAttributes.Directory | FileAttributes.Archive | FileAttributes.Device | FileAttributes.Normal | FileAttributes.Temporary | FileAttributes.SparseFile | FileAttributes.ReparsePoint | FileAttributes.Compressed | FileAttributes.Offline | FileAttributes.NotContentIndexed | FileAttributes.Encrypted #if !MONO | FileAttributes.IntegrityStream | FileAttributes.NoScrubData #endif ); } } catch (ArgumentException argumentException1) { ArgumentException argumentException = argumentException1; ErrorRecord errorRecord = new ErrorRecord(argumentException, "ForceArgumentException", ErrorCategory.WriteError, filePath); base.WriteError(errorRecord); signature = null; return(signature); } catch (IOException oException1) { IOException oException = oException1; ErrorRecord errorRecord1 = new ErrorRecord(oException, "ForceIOException", ErrorCategory.WriteError, filePath); base.WriteError(errorRecord1); signature = null; return(signature); } catch (UnauthorizedAccessException unauthorizedAccessException1) { UnauthorizedAccessException unauthorizedAccessException = unauthorizedAccessException1; ErrorRecord errorRecord2 = new ErrorRecord(unauthorizedAccessException, "ForceUnauthorizedAccessException", ErrorCategory.PermissionDenied, filePath); base.WriteError(errorRecord2); signature = null; return(signature); } catch (NotSupportedException notSupportedException1) { NotSupportedException notSupportedException = notSupportedException1; ErrorRecord errorRecord3 = new ErrorRecord(notSupportedException, "ForceNotSupportedException", ErrorCategory.WriteError, filePath); base.WriteError(errorRecord3); signature = null; return(signature); } catch (SecurityException securityException1) { SecurityException securityException = securityException1; ErrorRecord errorRecord4 = new ErrorRecord(securityException, "ForceSecurityException", ErrorCategory.PermissionDenied, filePath); base.WriteError(errorRecord4); signature = null; return(signature); } } if (SecurityUtils.GetFileSize(filePath) >= (long)4) { signature = SignatureHelper.SignFile(signingOption, filePath, this.Certificate, this.TimestampServer, this.hashAlgorithm); } else { object[] objArray = new object[1]; objArray[0] = filePath; string str = string.Format(CultureInfo.CurrentCulture, UtilsStrings.FileSmallerThan4Bytes, objArray); PSArgumentException pSArgumentException = new PSArgumentException(str, "filePath"); ErrorRecord errorRecord5 = SecurityUtils.CreateInvalidArgumentErrorRecord(pSArgumentException, "SignatureCommandsBaseFileSmallerThan4Bytes"); base.WriteError(errorRecord5); signature = null; } } finally { if (fileInfo != null) { FileInfo attributes1 = fileInfo; attributes1.Attributes = attributes1.Attributes | FileAttributes.ReadOnly; } } return(signature); } else { return(null); } } else { Exception exception = PSTraceSource.NewArgumentException("certificate", "SignatureCommands", "CertNotGoodForSigning", new object[0]); throw exception; } } else { throw PSTraceSource.NewArgumentNullException("certificate"); } }
/// <summary> /// Sets the digital signature on the specified file. /// </summary> /// <param name="filePath"> /// The name of the file on which to perform the action. /// </param> /// <returns> /// The signature on the specified file. /// </returns> protected override Signature PerformAction(string filePath) { SigningOption option = GetSigningOption(IncludeChain); if (Certificate == null) { throw PSTraceSource.NewArgumentNullException("certificate"); } // // if the cert is not good for signing, we cannot // process any more files. Exit the command. // if (!SecuritySupport.CertIsGoodForSigning(Certificate)) { Exception e = PSTraceSource.NewArgumentException( "certificate", SignatureCommands.CertNotGoodForSigning); throw e; } if (!ShouldProcess(filePath)) { return(null); } FileInfo readOnlyFileInfo = null; try { if (this.Force) { try { // remove readonly attributes on the file FileInfo fInfo = new(filePath); if (fInfo != null) { // Save some disk write time by checking whether file is readonly.. if ((fInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) { // remember to reset the read-only attribute later readOnlyFileInfo = fInfo; // Make sure the file is not read only fInfo.Attributes &= ~(FileAttributes.ReadOnly); } } } // These are the known exceptions for File.Load and StreamWriter.ctor catch (ArgumentException e) { ErrorRecord er = new( e, "ForceArgumentException", ErrorCategory.WriteError, filePath); WriteError(er); return(null); } catch (IOException e) { ErrorRecord er = new( e, "ForceIOException", ErrorCategory.WriteError, filePath); WriteError(er); return(null); } catch (UnauthorizedAccessException e) { ErrorRecord er = new( e, "ForceUnauthorizedAccessException", ErrorCategory.PermissionDenied, filePath); WriteError(er); return(null); } catch (NotSupportedException e) { ErrorRecord er = new( e, "ForceNotSupportedException", ErrorCategory.WriteError, filePath); WriteError(er); return(null); } catch (System.Security.SecurityException e) { ErrorRecord er = new( e, "ForceSecurityException", ErrorCategory.PermissionDenied, filePath); WriteError(er); return(null); } } // // ProcessRecord() code in base class has already // ascertained that filePath really represents an existing // file. Thus we can safely call GetFileSize() below. // if (SecurityUtils.GetFileSize(filePath) < 4) { // Note that the message param comes first string message = string.Format( System.Globalization.CultureInfo.CurrentCulture, UtilsStrings.FileSmallerThan4Bytes, filePath); PSArgumentException e = new(message, nameof(filePath)); ErrorRecord er = SecurityUtils.CreateInvalidArgumentErrorRecord( e, "SignatureCommandsBaseFileSmallerThan4Bytes" ); WriteError(er); return(null); } return(SignatureHelper.SignFile(option, filePath, Certificate, TimestampServer, _hashAlgorithm)); } finally { // reset the read-only attribute if (readOnlyFileInfo != null) { readOnlyFileInfo.Attributes |= FileAttributes.ReadOnly; } } }
internal static Signature SignFile( SigningOption option, string fileName, X509Certificate2 certificate, string timeStampServerUrl, string hashAlgorithm) { using (SignatureHelper.tracer.TraceMethod("file: {0}, cert: {1}", (object)SignatureHelper.GetStringValue(fileName), (object)SignatureHelper.GetCertName(certificate))) { Signature signature = (Signature)null; IntPtr num = IntPtr.Zero; uint error = 0; string hashAlgorithm1 = (string)null; Utils.CheckArgForNullOrEmpty(SignatureHelper.tracer, fileName, nameof(fileName)); Utils.CheckArgForNull(SignatureHelper.tracer, (object)certificate, nameof(certificate)); if (!string.IsNullOrEmpty(timeStampServerUrl) && (timeStampServerUrl.Length <= 7 || timeStampServerUrl.IndexOf("http://", StringComparison.OrdinalIgnoreCase) != 0)) { throw SignatureHelper.tracer.NewArgumentException(nameof(certificate), "Authenticode", "TimeStampUrlRequired"); } if (!string.IsNullOrEmpty(hashAlgorithm)) { IntPtr oidInfo = System.Management.Automation.Security.NativeMethods.CryptFindOIDInfo(2U, hashAlgorithm, 0U); hashAlgorithm1 = !(oidInfo == IntPtr.Zero) ? ((System.Management.Automation.Security.NativeMethods.CRYPT_OID_INFO)Marshal.PtrToStructure(oidInfo, typeof(System.Management.Automation.Security.NativeMethods.CRYPT_OID_INFO))).pszOID : throw SignatureHelper.tracer.NewArgumentException(nameof(certificate), "Authenticode", "InvalidHashAlgorithm"); } if (!SecuritySupport.CertIsGoodForSigning(certificate)) { throw SignatureHelper.tracer.NewArgumentException(nameof(certificate), "Authenticode", "CertNotGoodForSigning"); } SecuritySupport.CheckIfFileExists(fileName); try { string timeStampServerUrl1 = ""; if (!string.IsNullOrEmpty(timeStampServerUrl)) { timeStampServerUrl1 = timeStampServerUrl; } System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO wizDigitalSignInfo = System.Management.Automation.Security.NativeMethods.InitSignInfoStruct(fileName, certificate, timeStampServerUrl1, hashAlgorithm1, option); num = Marshal.AllocCoTaskMem(Marshal.SizeOf((object)wizDigitalSignInfo)); Marshal.StructureToPtr((object)wizDigitalSignInfo, num, false); bool flag = System.Management.Automation.Security.NativeMethods.CryptUIWizDigitalSign(1U, IntPtr.Zero, IntPtr.Zero, num, IntPtr.Zero); Marshal.DestroyStructure(wizDigitalSignInfo.pSignExtInfo, typeof(System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO)); Marshal.FreeCoTaskMem(wizDigitalSignInfo.pSignExtInfo); if (!flag) { error = SignatureHelper.GetLastWin32Error(); switch (error) { case 2147500037: case 2147942401: flag = true; break; case 2148073480: throw SignatureHelper.tracer.NewArgumentException(nameof(certificate), "Authenticode", "InvalidHashAlgorithm"); default: SignatureHelper.tracer.TraceError("CryptUIWizDigitalSign: failed: {0:x}", (object)error); break; } } signature = !flag ? new Signature(fileName, error) : (string.IsNullOrEmpty(timeStampServerUrl) ? new Signature(fileName, certificate) : SignatureHelper.GetSignature(fileName, (string)null)); } finally { Marshal.DestroyStructure(num, typeof(System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO)); Marshal.FreeCoTaskMem(num); } return(signature); } }
internal static System.Management.Automation.Signature SignFile(SigningOption option, string fileName, X509Certificate2 certificate, string timeStampServerUrl, string hashAlgorithm) { bool flag = false; System.Management.Automation.Signature signature = null; IntPtr zero = IntPtr.Zero; uint error = 0; string pszOID = null; Utils.CheckArgForNullOrEmpty(fileName, "fileName"); Utils.CheckArgForNull(certificate, "certificate"); if (!string.IsNullOrEmpty(timeStampServerUrl) && ((timeStampServerUrl.Length <= 7) || (timeStampServerUrl.IndexOf("http://", StringComparison.OrdinalIgnoreCase) != 0))) { throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "TimeStampUrlRequired", new object[0]); } if (!string.IsNullOrEmpty(hashAlgorithm)) { IntPtr pvKey = Marshal.StringToHGlobalUni(hashAlgorithm); IntPtr ptr = System.Management.Automation.Security.NativeMethods.CryptFindOIDInfo(2, pvKey, 0); if (ptr == IntPtr.Zero) { throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "InvalidHashAlgorithm", new object[0]); } System.Management.Automation.Security.NativeMethods.CRYPT_OID_INFO crypt_oid_info = (System.Management.Automation.Security.NativeMethods.CRYPT_OID_INFO)Marshal.PtrToStructure(ptr, typeof(System.Management.Automation.Security.NativeMethods.CRYPT_OID_INFO)); pszOID = crypt_oid_info.pszOID; } if (!SecuritySupport.CertIsGoodForSigning(certificate)) { throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "CertNotGoodForSigning", new object[0]); } SecuritySupport.CheckIfFileExists(fileName); try { string str2 = null; if (!string.IsNullOrEmpty(timeStampServerUrl)) { str2 = timeStampServerUrl; } System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO structure = System.Management.Automation.Security.NativeMethods.InitSignInfoStruct(fileName, certificate, str2, pszOID, option); zero = Marshal.AllocCoTaskMem(Marshal.SizeOf(structure)); Marshal.StructureToPtr(structure, zero, false); flag = System.Management.Automation.Security.NativeMethods.CryptUIWizDigitalSign(1, IntPtr.Zero, IntPtr.Zero, zero, IntPtr.Zero); Marshal.DestroyStructure(structure.pSignExtInfo, typeof(System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO)); Marshal.FreeCoTaskMem(structure.pSignExtInfo); if (!flag) { error = GetLastWin32Error(); switch (error) { case 0x80004005: case 0x80070001: case 0x80072ee7: flag = true; goto Label_01CF; case 0x80090008: throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "InvalidHashAlgorithm", new object[0]); } tracer.TraceError("CryptUIWizDigitalSign: failed: {0:x}", new object[] { error }); } Label_01CF: if (flag) { return(GetSignature(fileName, null)); } signature = new System.Management.Automation.Signature(fileName, error); } finally { Marshal.DestroyStructure(zero, typeof(System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO)); Marshal.FreeCoTaskMem(zero); } return(signature); }
InitSignInfoStruct(string fileName, X509Certificate2 signingCert, string timeStampServerUrl, string hashAlgorithm, SigningOption option) { CRYPTUI_WIZ_DIGITAL_SIGN_INFO si = new CRYPTUI_WIZ_DIGITAL_SIGN_INFO(); si.dwSize = (DWORD)Marshal.SizeOf(si); si.dwSubjectChoice = (DWORD)SignInfoSubjectChoice.CRYPTUI_WIZ_DIGITAL_SIGN_SUBJECT_FILE; si.pwszFileName = fileName; si.dwSigningCertChoice = (DWORD)SignInfoCertChoice.CRYPTUI_WIZ_DIGITAL_SIGN_CERT; si.pSigningCertContext = signingCert.Handle; si.pwszTimestampURL = timeStampServerUrl; si.dwAdditionalCertChoice = GetCertChoiceFromSigningOption(option); CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO siex = InitSignInfoExtendedStruct("", "", hashAlgorithm); IntPtr pSiexBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(siex)); Marshal.StructureToPtr(siex, pSiexBuffer, false); si.pSignExtInfo = pSiexBuffer; return si; }
internal SigningOptionInfo(SigningOption o, string n) { option = o; optionName = n; }
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 = ClrFacade.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) { ClrFacade.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 { ClrFacade.DestroyStructure <NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO>(pSignInfo); Marshal.FreeCoTaskMem(pSignInfo); } return(signature); }
internal static CRYPTUI_WIZ_DIGITAL_SIGN_INFO InitSignInfoStruct(string fileName, X509Certificate2 signingCert, string timeStampServerUrl, string hashAlgorithm, SigningOption option) { CRYPTUI_WIZ_DIGITAL_SIGN_INFO cryptui_wiz_digital_sign_info; cryptui_wiz_digital_sign_info = new CRYPTUI_WIZ_DIGITAL_SIGN_INFO { dwSize = (int)Marshal.SizeOf(typeof(CRYPTUI_WIZ_DIGITAL_SIGN_INFO)), dwSubjectChoice = 1, pwszFileName = fileName, dwSigningCertChoice = 1, pSigningCertContext = signingCert.Handle, pwszTimestampURL = timeStampServerUrl, dwAdditionalCertChoice = GetCertChoiceFromSigningOption(option) }; CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO structure = InitSignInfoExtendedStruct("", "", hashAlgorithm); IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(structure)); Marshal.StructureToPtr(structure, ptr, false); cryptui_wiz_digital_sign_info.pSignExtInfo = ptr; return(cryptui_wiz_digital_sign_info); }
internal static System.Management.Automation.Signature SignFile(SigningOption option, string fileName, X509Certificate2 certificate, string timeStampServerUrl, string hashAlgorithm) { bool flag = false; System.Management.Automation.Signature signature = null; IntPtr zero = IntPtr.Zero; uint error = 0; string pszOID = null; Utils.CheckArgForNullOrEmpty(fileName, "fileName"); Utils.CheckArgForNull(certificate, "certificate"); if (!string.IsNullOrEmpty(timeStampServerUrl) && ((timeStampServerUrl.Length <= 7) || (timeStampServerUrl.IndexOf("http://", StringComparison.OrdinalIgnoreCase) != 0))) { throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "TimeStampUrlRequired", new object[0]); } if (!string.IsNullOrEmpty(hashAlgorithm)) { IntPtr pvKey = Marshal.StringToHGlobalUni(hashAlgorithm); IntPtr ptr = System.Management.Automation.Security.NativeMethods.CryptFindOIDInfo(2, pvKey, 0); if (ptr == IntPtr.Zero) { throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "InvalidHashAlgorithm", new object[0]); } System.Management.Automation.Security.NativeMethods.CRYPT_OID_INFO crypt_oid_info = (System.Management.Automation.Security.NativeMethods.CRYPT_OID_INFO) Marshal.PtrToStructure(ptr, typeof(System.Management.Automation.Security.NativeMethods.CRYPT_OID_INFO)); pszOID = crypt_oid_info.pszOID; } if (!SecuritySupport.CertIsGoodForSigning(certificate)) { throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "CertNotGoodForSigning", new object[0]); } SecuritySupport.CheckIfFileExists(fileName); try { string str2 = null; if (!string.IsNullOrEmpty(timeStampServerUrl)) { str2 = timeStampServerUrl; } System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO structure = System.Management.Automation.Security.NativeMethods.InitSignInfoStruct(fileName, certificate, str2, pszOID, option); zero = Marshal.AllocCoTaskMem(Marshal.SizeOf(structure)); Marshal.StructureToPtr(structure, zero, false); flag = System.Management.Automation.Security.NativeMethods.CryptUIWizDigitalSign(1, IntPtr.Zero, IntPtr.Zero, zero, IntPtr.Zero); Marshal.DestroyStructure(structure.pSignExtInfo, typeof(System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO)); Marshal.FreeCoTaskMem(structure.pSignExtInfo); if (!flag) { error = GetLastWin32Error(); switch (error) { case 0x80004005: case 0x80070001: case 0x80072ee7: flag = true; goto Label_01CF; case 0x80090008: throw PSTraceSource.NewArgumentException("certificate", "Authenticode", "InvalidHashAlgorithm", new object[0]); } tracer.TraceError("CryptUIWizDigitalSign: failed: {0:x}", new object[] { error }); } Label_01CF: if (flag) { return GetSignature(fileName, null); } signature = new System.Management.Automation.Signature(fileName, error); } finally { Marshal.DestroyStructure(zero, typeof(System.Management.Automation.Security.NativeMethods.CRYPTUI_WIZ_DIGITAL_SIGN_INFO)); Marshal.FreeCoTaskMem(zero); } return signature; }