Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bundler): support custom sign command on Windows #9902

Merged
merged 2 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/custom-sign-command.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri-bundler": "patch:feat"
---

On Windows, add option to specify a custom signing command to be used. This opens an endless possibilities, for example use `osslsigncode` on non-Windows or use hardware tokens and HSM or even using Azure Trusted Signing.
5 changes: 5 additions & 0 deletions .changes/utils-sign-command.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri-utils": "patch:feat"
---

Add `sign_command` in `WindowsConfig`
10 changes: 10 additions & 0 deletions core/tauri-config-schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
"certificateThumbprint": null,
"digestAlgorithm": null,
"nsis": null,
"signCommand": null,
"timestampUrl": null,
"tsp": false,
"webviewFixedRuntimePath": null,
Expand Down Expand Up @@ -299,6 +300,7 @@
"certificateThumbprint": null,
"digestAlgorithm": null,
"nsis": null,
"signCommand": null,
"timestampUrl": null,
"tsp": false,
"webviewFixedRuntimePath": null,
Expand Down Expand Up @@ -1185,6 +1187,7 @@
"certificateThumbprint": null,
"digestAlgorithm": null,
"nsis": null,
"signCommand": null,
"timestampUrl": null,
"tsp": false,
"webviewFixedRuntimePath": null,
Expand Down Expand Up @@ -1560,6 +1563,13 @@
"type": "null"
}
]
},
"signCommand": {
"description": "Specify a custom command to sign the binaries. This command needs to have a `%1` in it which is just a placeholder for the binary path, which we will detect and replace before calling the command.\n\nExample: ```text sign-cli --arg1 --arg2 %1 ```\n\nBy Default we use `signtool.exe` which can be found only on Windows so if you are on another platform and want to cross-compile and sign you will need to use another tool like `osslsigncode`.",
"type": [
"string",
"null"
]
}
},
"additionalProperties": false
Expand Down
15 changes: 15 additions & 0 deletions core/tauri-utils/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,20 @@ pub struct WindowsConfig {
pub wix: Option<WixConfig>,
/// Configuration for the installer generated with NSIS.
pub nsis: Option<NsisConfig>,
/// Specify a custom command to sign the binaries.
/// This command needs to have a `%1` in it which is just a placeholder for the binary path,
/// which we will detect and replace before calling the command.
///
/// Example:
/// ```text
/// sign-cli --arg1 --arg2 %1
/// ```
///
/// By Default we use `signtool.exe` which can be found only on Windows so
/// if you are on another platform and want to cross-compile and sign you will
/// need to use another tool like `osslsigncode`.
#[serde(alias = "sign-command")]
pub sign_command: Option<String>,
}

impl Default for WindowsConfig {
Expand All @@ -688,6 +702,7 @@ impl Default for WindowsConfig {
allow_downgrades: true,
wix: None,
nsis: None,
sign_command: None,
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion tooling/bundler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ dunce = "1"

[target."cfg(target_os = \"windows\")".dependencies]
uuid = { version = "1", features = [ "v4", "v5" ] }
winreg = "0.51"
windows-registry = "0.1.1"
glob = "0.3"

[target."cfg(target_os = \"windows\")".dependencies.windows-sys]
Expand Down
19 changes: 12 additions & 7 deletions tooling/bundler/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ pub fn bundle_project(settings: Settings) -> crate::Result<Vec<Bundle>> {
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")]
{
if settings.can_sign() {
// 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);
Expand All @@ -75,16 +74,22 @@ pub fn bundle_project(settings: Settings) -> crate::Result<Vec<Bundle>> {
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)? {
if skip {
continue;
}
#[cfg(windows)]
if windows::sign::verify(&path)? {
info!(
"sidecar at \"{}\" already signed. Skipping...",
path.display()
)
} else {
windows::sign::try_sign(&path, &settings)?;
);
continue;
}
windows::sign::try_sign(&path, &settings)?;
}
} else {
#[cfg(not(target_os = "windows"))]
log::warn!("Signing, by default, is only supported on Windows hosts, but you can specify a custom signing command in `bundler > windows > sign_command`, for now, skipping signing the installer...");
}

for package_type in &package_types {
Expand Down
15 changes: 15 additions & 0 deletions tooling/bundler/src/bundle/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,20 @@ pub struct WindowsSettings {
///
/// /// The default value of this flag is `true`.
pub allow_downgrades: bool,

/// Specify a custom command to sign the binaries.
/// This command needs to have a `%1` in it which is just a placeholder for the binary path,
/// which we will detect and replace before calling the command.
///
/// Example:
/// ```text
/// sign-cli --arg1 --arg2 %1
/// ```
///
/// By Default we use `signtool.exe` which can be found only on Windows so
/// if you are on another platform and want to cross-compile and sign you will
/// need to use another tool like `osslsigncode`.
pub sign_command: Option<String>,
}

impl Default for WindowsSettings {
Expand All @@ -400,6 +414,7 @@ impl Default for WindowsSettings {
webview_install_mode: Default::default(),
webview_fixed_runtime_path: None,
allow_downgrades: true,
sign_command: None,
}
}
}
Expand Down
1 change: 0 additions & 1 deletion tooling/bundler/src/bundle/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#[cfg(target_os = "windows")]
pub mod msi;
pub mod nsis;
#[cfg(target_os = "windows")]
pub mod sign;

mod util;
Expand Down
4 changes: 3 additions & 1 deletion tooling/bundler/src/bundle/windows/msi/wix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,9 @@ pub fn build_wix_app_installer(
&msi_output_path,
)?;
rename(&msi_output_path, &msi_path)?;
try_sign(&msi_path, settings)?;
if settings.can_sign() {
try_sign(&msi_path, settings)?;
}
output_paths.push(msi_path);
}

Expand Down
36 changes: 13 additions & 23 deletions tooling/bundler/src/bundle/windows/nsis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

#[cfg(target_os = "windows")]
use crate::bundle::windows::sign::{sign_command, try_sign};
use crate::{
bundle::{
Expand Down Expand Up @@ -68,6 +67,7 @@ pub fn bundle_project(settings: &Settings, updater: bool) -> crate::Result<Vec<P
let nsis_toolset_path = tauri_tools_path.join("NSIS");

if !nsis_toolset_path.exists() {
create_dir_all(&nsis_toolset_path)?;
Copy link

@MystiPanda MystiPanda Jun 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating an NSIS folder in advance will cause subsequent renaming failures after extract

rename(_tauri_tools_path.join("nsis-3.08"), nsis_toolset_path)?;

get_and_extract_nsis(&nsis_toolset_path, &tauri_tools_path)?;
} else if NSIS_REQUIRED_FILES
.iter()
Expand Down Expand Up @@ -115,12 +115,10 @@ fn get_and_extract_nsis(nsis_toolset_path: &Path, _tauri_tools_path: &Path) -> c
NSIS_TAURI_UTILS_SHA1,
HashAlgorithm::Sha1,
)?;
write(
nsis_plugins
.join("x86-unicode")
.join("nsis_tauri_utils.dll"),
data,
)?;

let target_folder = nsis_plugins.join("x86-unicode");
create_dir_all(&target_folder)?;
write(target_folder.join("nsis_tauri_utils.dll"), data)?;

Ok(())
}
Expand Down Expand Up @@ -164,9 +162,6 @@ fn build_nsis_app_installer(

info!("Target: {}", arch);

#[cfg(not(target_os = "windows"))]
info!("Code signing is currently only supported on Windows hosts, skipping...");

let output_path = settings.project_out_directory().join("nsis").join(arch);
if output_path.exists() {
remove_dir_all(&output_path)?;
Expand Down Expand Up @@ -194,16 +189,9 @@ fn build_nsis_app_installer(
data.insert("short_description", to_json(settings.short_description()));
data.insert("copyright", to_json(settings.copyright_string()));

// Code signing is currently only supported on Windows hosts
#[cfg(target_os = "windows")]
if settings.can_sign() {
data.insert(
"uninstaller_sign_cmd",
to_json(format!(
"{:?}",
sign_command("%1", &settings.sign_params())?.0
)),
);
let sign_cmd = format!("{:?}", sign_command("%1", &settings.sign_params())?);
data.insert("uninstaller_sign_cmd", to_json(sign_cmd));
}

let version = settings.version_string();
Expand Down Expand Up @@ -498,10 +486,12 @@ fn build_nsis_app_installer(

rename(nsis_output_path, &nsis_installer_path)?;

// Code signing is currently only supported on Windows hosts
#[cfg(target_os = "windows")]
try_sign(&nsis_installer_path, settings)?;

if settings.can_sign() {
try_sign(&nsis_installer_path, settings)?;
} else {
#[cfg(not(target_os = "windows"))]
log::warn!("Signing, by default, is only supported on Windows hosts, but you can specify a custom signing command in `bundler > windows > sign_command`, for now, skipping signing the installer...");
}
Ok(vec![nsis_installer_path])
}

Expand Down
Loading
Loading