diff --git a/.changes/bundler-windows-earlier-code-signing.md b/.changes/bundler-windows-earlier-code-signing.md new file mode 100644 index 000000000000..a6978e4d2a96 --- /dev/null +++ b/.changes/bundler-windows-earlier-code-signing.md @@ -0,0 +1,7 @@ +--- +'tauri-bundler': 'patch:enhance' +--- + +On Windows, code sign the application binaries before trying to create the WiX and NSIS bundles to always sign the executables even if no bundle types are enabled. + +On Windows, code sign the sidecar binaries if they are not signed already. diff --git a/tooling/bundler/src/bundle.rs b/tooling/bundler/src/bundle.rs index c458e2b6c5aa..763ca75b7696 100644 --- a/tooling/bundler/src/bundle.rs +++ b/tooling/bundler/src/bundle.rs @@ -63,6 +63,30 @@ pub fn bundle_project(settings: Settings) -> crate::Result> { warn!("Cross-platform compilation is experimental and does not support all features. Please use a matching host system for full compatibility."); } + #[cfg(target_os = "windows")] + { + // Sign windows binaries before the bundling step in case neither wix and nsis bundles are enabled + for bin in settings.binaries() { + let bin_path = settings.binary_path(bin); + windows::sign::try_sign(&bin_path, &settings)?; + } + + // Sign the sidecar binaries + for bin in settings.external_binaries() { + let path = bin?; + let skip = std::env::var("TAURI_SKIP_SIDECAR_SIGNATURE_CHECK").map_or(false, |v| v == "true"); + + if !skip && windows::sign::verify(&path)? { + info!( + "sidecar at \"{}\" already signed. Skipping...", + path.display() + ) + } else { + windows::sign::try_sign(&path, &settings)?; + } + } + } + for package_type in &package_types { // bundle was already built! e.g. DMG already built .app if bundles.iter().any(|b| b.package_type == *package_type) { diff --git a/tooling/bundler/src/bundle/windows/msi/wix.rs b/tooling/bundler/src/bundle/windows/msi/wix.rs index 26e6b0b9d82c..c78b659e3fb7 100644 --- a/tooling/bundler/src/bundle/windows/msi/wix.rs +++ b/tooling/bundler/src/bundle/windows/msi/wix.rs @@ -410,8 +410,6 @@ pub fn build_wix_app_installer( .ok_or_else(|| anyhow::anyhow!("Failed to get main binary"))?; let app_exe_source = settings.binary_path(main_binary); - try_sign(&app_exe_source, settings)?; - let output_path = settings.project_out_directory().join("wix").join(arch); if output_path.exists() { diff --git a/tooling/bundler/src/bundle/windows/nsis.rs b/tooling/bundler/src/bundle/windows/nsis.rs index ddf5d6075871..a3e018edf550 100644 --- a/tooling/bundler/src/bundle/windows/nsis.rs +++ b/tooling/bundler/src/bundle/windows/nsis.rs @@ -157,18 +157,6 @@ fn build_nsis_app_installer( info!("Target: {}", arch); - // Code signing is currently only supported on Windows hosts - #[cfg(target_os = "windows")] - { - let main_binary = settings - .binaries() - .iter() - .find(|bin| bin.main()) - .ok_or_else(|| anyhow::anyhow!("Failed to get main binary"))?; - let app_exe_source = settings.binary_path(main_binary); - try_sign(&app_exe_source, settings)?; - } - #[cfg(not(target_os = "windows"))] info!("Code signing is currently only supported on Windows hosts, skipping..."); diff --git a/tooling/bundler/src/bundle/windows/sign.rs b/tooling/bundler/src/bundle/windows/sign.rs index 8a2725a72163..95ca5bf62b7d 100644 --- a/tooling/bundler/src/bundle/windows/sign.rs +++ b/tooling/bundler/src/bundle/windows/sign.rs @@ -88,6 +88,20 @@ fn locate_signtool() -> crate::Result { Err(crate::Error::SignToolNotFound) } +/// Check if binary is already signed. +/// Used to skip sidecar binaries that are already signed. +pub fn verify(path: &Path) -> crate::Result { + // Construct SignTool command + let signtool = locate_signtool()?; + + let mut cmd = Command::new(&signtool); + cmd.arg("verify"); + cmd.arg("/pa"); + cmd.arg(path); + + Ok(cmd.status()?.success()) +} + pub fn sign_command(path: &str, params: &SignParams) -> crate::Result<(Command, PathBuf)> { // Construct SignTool command let signtool = locate_signtool()?;