Selaa lähdekoodia

feat(bundler) code signing (#473)

Co-authored-by: Rajiv Shah <rajivshah1@icloud.com>
Co-authored-by: David Lemarier <david@lemarier.ca>
Lucas Fernandes Nogueira 4 vuotta sitten
vanhempi
sitoutus
fd5bb2c201

+ 194 - 76
cli/core/Cargo.lock

@@ -1,5 +1,14 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
+[[package]]
+name = "addr2line"
+version = "0.14.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7"
+dependencies = [
+ "gimli",
+]
+
 [[package]]
 name = "adler"
 version = "1.0.2"
@@ -23,9 +32,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.38"
+version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
+checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
 
 [[package]]
 name = "ar"
@@ -71,6 +80,20 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
 
+[[package]]
+name = "backtrace"
+version = "0.3.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc"
+dependencies = [
+ "addr2line",
+ "cfg-if 1.0.0",
+ "libc",
+ "miniz_oxide 0.4.4",
+ "object",
+ "rustc-demangle",
+]
+
 [[package]]
 name = "base64"
 version = "0.13.0"
@@ -83,6 +106,18 @@ version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
 
+[[package]]
+name = "bitness"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57792b99d555ebf109c83169228076f7d997e2b37ba1a653850ccd703ac7bab0"
+dependencies = [
+ "sysctl",
+ "thiserror",
+ "uname",
+ "winapi 0.3.9",
+]
+
 [[package]]
 name = "block-buffer"
 version = "0.7.3"
@@ -92,7 +127,7 @@ dependencies = [
  "block-padding",
  "byte-tools",
  "byteorder",
- "generic-array 0.12.3",
+ "generic-array 0.12.4",
 ]
 
 [[package]]
@@ -133,9 +168,9 @@ checksum = "bed57e2090563b83ba8f83366628ce535a7584c9afa4c9fc0612a03925c6df58"
 
 [[package]]
 name = "byteorder"
-version = "1.4.2"
+version = "1.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
 
 [[package]]
 name = "bytes"
@@ -418,7 +453,7 @@ version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
 dependencies = [
- "generic-array 0.12.3",
+ "generic-array 0.12.4",
 ]
 
 [[package]]
@@ -469,6 +504,28 @@ version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
 
+[[package]]
+name = "failure"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
+dependencies = [
+ "backtrace",
+ "failure_derive",
+]
+
+[[package]]
+name = "failure_derive"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
 [[package]]
 name = "fake-simd"
 version = "0.1.2"
@@ -567,9 +624,9 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 
 [[package]]
 name = "generic-array"
-version = "0.12.3"
+version = "0.12.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
+checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
 dependencies = [
  "typenum",
 ]
@@ -608,14 +665,20 @@ dependencies = [
 
 [[package]]
 name = "gif"
-version = "0.11.1"
+version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02efba560f227847cb41463a7395c514d127d4f74fff12ef0137fff1b84b96c4"
+checksum = "5a668f699973d0f573d15749b7002a9ac9e1f9c6b220e7b165601334c173d8de"
 dependencies = [
  "color_quant",
  "weezl",
 ]
 
+[[package]]
+name = "gimli"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
+
 [[package]]
 name = "glob"
 version = "0.3.0"
@@ -624,9 +687,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
 
 [[package]]
 name = "handlebars"
-version = "3.5.3"
+version = "3.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdb0867bbc5a3da37a753e78021d5fcf8a4db00e18dd2dd90fd36e24190e162d"
+checksum = "580b6f551b29a3a02436318aed09ba1c58eea177dc49e39beac627ad356730a5"
 dependencies = [
  "log",
  "pest",
@@ -662,9 +725,9 @@ dependencies = [
 
 [[package]]
 name = "hex"
-version = "0.4.2"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
 
 [[package]]
 name = "http"
@@ -749,9 +812,9 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "1.6.1"
+version = "1.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b"
+checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
 dependencies = [
  "autocfg",
  "hashbrown",
@@ -864,15 +927,15 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
 
 [[package]]
 name = "libc"
-version = "0.2.86"
+version = "0.2.91"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
+checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7"
 
 [[package]]
 name = "libflate"
-version = "1.0.3"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "389de7875e06476365974da3e7ff85d55f1972188ccd9f6020dd7c8156e17914"
+checksum = "158ae2ca09a761eaf6050894f5a6f013f2773dafe24f67bfa73a7504580e2916"
 dependencies = [
  "adler32",
  "crc32fast",
@@ -927,9 +990,9 @@ checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
 
 [[package]]
 name = "memoffset"
-version = "0.6.1"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
+checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d"
 dependencies = [
  "autocfg",
 ]
@@ -1094,11 +1157,17 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "object"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
+
 [[package]]
 name = "once_cell"
-version = "1.7.0"
+version = "1.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10acf907b94fc1b1a152d08ef97e7759650268cf986bf127f387e602b02c7e5a"
+checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
 
 [[package]]
 name = "opaque-debug"
@@ -1114,15 +1183,15 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
 
 [[package]]
 name = "openssl"
-version = "0.10.32"
+version = "0.10.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "038d43985d1ddca7a9900630d8cd031b56e4794eecc2e9ea39dd17aa04399a70"
+checksum = "a61075b62a23fef5a29815de7536d940aa35ce96d18ce0cc5076272db678a577"
 dependencies = [
  "bitflags",
  "cfg-if 1.0.0",
  "foreign-types",
- "lazy_static",
  "libc",
+ "once_cell",
  "openssl-sys",
 ]
 
@@ -1134,9 +1203,9 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.60"
+version = "0.9.61"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6"
+checksum = "313752393519e876837e09e1fa183ddef0be7735868dced3196f4472d536277f"
 dependencies = [
  "autocfg",
  "cc",
@@ -1474,21 +1543,20 @@ dependencies = [
 
 [[package]]
 name = "regex"
-version = "1.4.3"
+version = "1.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
+checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19"
 dependencies = [
  "aho-corasick",
  "memchr",
  "regex-syntax",
- "thread_local",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.22"
+version = "0.6.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
+checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
 
 [[package]]
 name = "remove_dir_all"
@@ -1520,6 +1588,12 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac"
 
+[[package]]
+name = "rustc-demangle"
+version = "0.1.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
+
 [[package]]
 name = "rustls"
 version = "0.19.0"
@@ -1533,6 +1607,12 @@ dependencies = [
  "webpki",
 ]
 
+[[package]]
+name = "rustversion"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd"
+
 [[package]]
 name = "ryu"
 version = "1.0.5"
@@ -1560,9 +1640,9 @@ dependencies = [
 
 [[package]]
 name = "schemars"
-version = "0.8.0"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "763f667253711994847f7e73befe859d6fff7bea2b7a7f01669d2c5b60765c37"
+checksum = "f81b69175bfb19653b59983e78701ebda5ee6a6f1e4875f65f9b92e2efde48f3"
 dependencies = [
  "dyn-clone",
  "schemars_derive",
@@ -1572,9 +1652,9 @@ dependencies = [
 
 [[package]]
 name = "schemars_derive"
-version = "0.8.0"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1d457e2e37415f32b7628ddc5a7fea06ef63bd029ed180d65166e87ca25ce21"
+checksum = "f3a9f7bf22f96bc98cebd33a9286118c4e588b6a2fc26ab83469c18e12ae7678"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1606,9 +1686,9 @@ dependencies = [
 
 [[package]]
 name = "security-framework"
-version = "2.1.1"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dfd318104249865096c8da1dfabf09ddbb6d0330ea176812a62ec75e40c4166"
+checksum = "3670b1d2fdf6084d192bc71ead7aabe6c06aa2ea3fbd9cc3ac111fa5c2b1bd84"
 dependencies = [
  "bitflags",
  "core-foundation",
@@ -1619,9 +1699,9 @@ dependencies = [
 
 [[package]]
 name = "security-framework-sys"
-version = "2.1.1"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dee48cdde5ed250b0d3252818f646e174ab414036edb884dde62d80a3ac6082d"
+checksum = "3676258fd3cfe2c9a0ec99ce3038798d847ce3e4bb17746373eb9f0f1ac16339"
 dependencies = [
  "core-foundation-sys",
  "libc",
@@ -1647,18 +1727,18 @@ dependencies = [
 
 [[package]]
 name = "serde"
-version = "1.0.123"
+version = "1.0.125"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
+checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.123"
+version = "1.0.125"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
+checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1689,10 +1769,11 @@ dependencies = [
 
 [[package]]
 name = "serde_with"
-version = "1.6.4"
+version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b44be9227e214a0420707c9ca74c2d4991d9955bae9415a8f93f05cebf561be5"
+checksum = "7f23bb4df023db259e4423c8a5c248d75d83c0e20c8f0063254f41b859a65ab3"
 dependencies = [
+ "rustversion",
  "serde",
  "serde_with_macros",
 ]
@@ -1742,9 +1823,9 @@ dependencies = [
 
 [[package]]
 name = "shared_child"
-version = "0.3.4"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cebcf3a403e4deafaf34dc882c4a1b6a648b43e5670aa2e4bb985914eaeb2d2"
+checksum = "6be9f7d5565b1483af3e72975e2dee33879b3b86bd48c0929fccf6585d79e65a"
 dependencies = [
  "libc",
  "winapi 0.3.9",
@@ -1752,9 +1833,9 @@ dependencies = [
 
 [[package]]
 name = "siphasher"
-version = "0.3.3"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7"
+checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27"
 
 [[package]]
 name = "slab"
@@ -1776,15 +1857,40 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
 
 [[package]]
 name = "syn"
-version = "1.0.60"
+version = "1.0.65"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
+checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663"
 dependencies = [
  "proc-macro2",
  "quote",
  "unicode-xid",
 ]
 
+[[package]]
+name = "synstructure"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "unicode-xid",
+]
+
+[[package]]
+name = "sysctl"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0501f0d0c2aa64b419abff97c209f4b82c4e67caa63e8dc5b222ecc1b574cb5c"
+dependencies = [
+ "bitflags",
+ "byteorder",
+ "failure",
+ "libc",
+ "walkdir",
+]
+
 [[package]]
 name = "tar"
 version = "0.4.33"
@@ -1803,6 +1909,7 @@ dependencies = [
  "anyhow",
  "ar",
  "attohttpc",
+ "bitness",
  "chrono",
  "dirs-next",
  "glob",
@@ -1819,11 +1926,13 @@ dependencies = [
  "sha2",
  "strsim",
  "tar",
+ "tempfile",
  "termcolor",
  "thiserror",
  "toml",
  "uuid",
  "walkdir",
+ "winreg",
  "zip",
 ]
 
@@ -1919,15 +2028,6 @@ dependencies = [
  "syn",
 ]
 
-[[package]]
-name = "thread_local"
-version = "1.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
-dependencies = [
- "once_cell",
-]
-
 [[package]]
 name = "tiff"
 version = "0.6.1"
@@ -1995,9 +2095,9 @@ dependencies = [
 
 [[package]]
 name = "typenum"
-version = "1.12.0"
+version = "1.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
+checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
 
 [[package]]
 name = "ucd-trie"
@@ -2005,6 +2105,15 @@ version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
 
+[[package]]
+name = "uname"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "unicode-bidi"
 version = "0.3.4"
@@ -2058,9 +2167,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
 
 [[package]]
 name = "ureq"
-version = "2.0.2"
+version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6585dcbf3483242f77b502864478ede62431baf3442b99367d3456ec20c1707b"
+checksum = "6fbeb1aabb07378cf0e084971a74f24241273304653184f54cdce113c0d7df1b"
 dependencies = [
  "base64",
  "chunked_transfer",
@@ -2139,9 +2248,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
 
 [[package]]
 name = "version_check"
-version = "0.9.2"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
+checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
 
 [[package]]
 name = "void"
@@ -2151,9 +2260,9 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 
 [[package]]
 name = "walkdir"
-version = "2.3.1"
+version = "2.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
+checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
 dependencies = [
  "same-file",
  "winapi 0.3.9",
@@ -2263,19 +2372,19 @@ checksum = "4a32b378380f4e9869b22f0b5177c68a5519f03b3454fde0b291455ddbae266c"
 
 [[package]]
 name = "which"
-version = "4.0.2"
+version = "4.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87c14ef7e1b8b8ecfc75d5eca37949410046e66f15d185c01d70824f1f8111ef"
+checksum = "b55551e42cbdf2ce2bedd2203d0cc08dba002c27510f86dab6d0ce304cba3dfe"
 dependencies = [
+ "either",
  "libc",
- "thiserror",
 ]
 
 [[package]]
 name = "wildmatch"
-version = "1.0.13"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2399814fda0d6999a6bfe9b5c7660d836334deb162a09db8b73d5b38fd8c40a"
+checksum = "7f44b95f62d34113cf558c93511ac93027e03e9c29a60dd0fd70e6e025c7270a"
 
 [[package]]
 name = "winapi"
@@ -2320,6 +2429,15 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
+[[package]]
+name = "winreg"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
+dependencies = [
+ "winapi 0.3.9",
+]
+
 [[package]]
 name = "ws2_32-sys"
 version = "0.2.1"

+ 12 - 0
cli/core/config_definition.rs

@@ -33,6 +33,16 @@ pub struct MacConfig {
   pub license: Option<String>,
   #[serde(default)]
   pub use_bootstrapper: bool,
+  pub signing_identity: Option<String>,
+  pub entitlements: Option<String>,
+}
+
+#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
+#[serde(rename_all = "camelCase", deny_unknown_fields)]
+pub struct WindowsConfig {
+  pub digest_algorithm: Option<String>,
+  pub certificate_thumbprint: Option<String>,
+  pub timestamp_url: Option<String>,
 }
 
 #[skip_serializing_none]
@@ -70,6 +80,8 @@ pub struct BundleConfig {
   #[serde(rename = "macOS", default)]
   pub macos: MacConfig,
   pub external_bin: Option<Vec<String>>,
+  #[serde(default)]
+  pub windows: WindowsConfig,
 }
 
 /// A CLI argument definition

+ 58 - 0
cli/core/schema.json

@@ -86,6 +86,11 @@
           },
           "macOS": {
             "useBootstrapper": false
+          },
+          "windows": {
+            "certificateThumbprint": null,
+            "digestAlgorithm": null,
+            "timestampUrl": null
           }
         },
         "windows": []
@@ -332,6 +337,18 @@
               "type": "null"
             }
           ]
+        },
+        "windows": {
+          "default": {
+            "certificateThumbprint": null,
+            "digestAlgorithm": null,
+            "timestampUrl": null
+          },
+          "allOf": [
+            {
+              "$ref": "#/definitions/WindowsConfig"
+            }
+          ]
         }
       },
       "additionalProperties": false
@@ -720,6 +737,12 @@
     "MacConfig": {
       "type": "object",
       "properties": {
+        "entitlements": {
+          "type": [
+            "string",
+            "null"
+          ]
+        },
         "exceptionDomain": {
           "type": [
             "string",
@@ -747,6 +770,12 @@
             "null"
           ]
         },
+        "signingIdentity": {
+          "type": [
+            "string",
+            "null"
+          ]
+        },
         "useBootstrapper": {
           "default": false,
           "type": "boolean"
@@ -875,6 +904,11 @@
             },
             "macOS": {
               "useBootstrapper": false
+            },
+            "windows": {
+              "certificateThumbprint": null,
+              "digestAlgorithm": null,
+              "timestampUrl": null
             }
           },
           "allOf": [
@@ -1055,6 +1089,30 @@
         }
       },
       "additionalProperties": false
+    },
+    "WindowsConfig": {
+      "type": "object",
+      "properties": {
+        "certificateThumbprint": {
+          "type": [
+            "string",
+            "null"
+          ]
+        },
+        "digestAlgorithm": {
+          "type": [
+            "string",
+            "null"
+          ]
+        },
+        "timestampUrl": {
+          "type": [
+            "string",
+            "null"
+          ]
+        }
+      },
+      "additionalProperties": false
     }
   }
 }

+ 10 - 0
cli/core/src/build/rust.rs

@@ -3,6 +3,8 @@ use std::{fs::File, io::Read, path::PathBuf, process::Command, str::FromStr};
 use serde::Deserialize;
 
 use crate::helpers::{app_paths::tauri_dir, config::Config};
+#[cfg(windows)]
+use tauri_bundler::WindowsSettings;
 use tauri_bundler::{
   AppCategory, BundleBinary, BundleSettings, DebianSettings, MacOSSettings, PackageSettings,
 };
@@ -330,6 +332,14 @@ fn tauri_config_to_bundle_settings(
       license: config.macos.license,
       use_bootstrapper: Some(config.macos.use_bootstrapper),
       exception_domain: config.macos.exception_domain,
+      signing_identity: config.macos.signing_identity,
+      entitlements: config.macos.entitlements,
+    },
+    #[cfg(windows)]
+    windows: WindowsSettings {
+      timestamp_url: config.windows.timestamp_url,
+      digest_algorithm: config.windows.digest_algorithm,
+      certificate_thumbprint: config.windows.certificate_thumbprint,
     },
     ..Default::default()
   })

+ 9 - 2
cli/core/templates/src-tauri/tauri.conf.json

@@ -35,7 +35,14 @@
         "frameworks": [],
         "minimumSystemVersion": "",
         "useBootstrapper": false,
-        "exceptionDomain": ""
+        "exceptionDomain": "",
+        "signingIdentity": null,
+        "entitlements": null
+      },
+      "windows": {
+        "certificateThumbprint": null,
+        "digestAlgorithm": "sha256",
+        "timestampUrl": ""
       }
     },
     "allowlist": {
@@ -54,4 +61,4 @@
       "csp": "default-src blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline'"
     }
   }
-}
+}

+ 157 - 47
cli/tauri-bundler/Cargo.lock

@@ -1,5 +1,14 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
+[[package]]
+name = "addr2line"
+version = "0.14.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7"
+dependencies = [
+ "gimli",
+]
+
 [[package]]
 name = "adler"
 version = "1.0.2"
@@ -54,12 +63,38 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
 
+[[package]]
+name = "backtrace"
+version = "0.3.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc"
+dependencies = [
+ "addr2line",
+ "cfg-if 1.0.0",
+ "libc",
+ "miniz_oxide 0.4.4",
+ "object",
+ "rustc-demangle",
+]
+
 [[package]]
 name = "bitflags"
 version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
 
+[[package]]
+name = "bitness"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57792b99d555ebf109c83169228076f7d997e2b37ba1a653850ccd703ac7bab0"
+dependencies = [
+ "sysctl",
+ "thiserror",
+ "uname",
+ "winapi",
+]
+
 [[package]]
 name = "block-buffer"
 version = "0.7.3"
@@ -69,7 +104,7 @@ dependencies = [
  "block-padding",
  "byte-tools",
  "byteorder",
- "generic-array 0.12.3",
+ "generic-array 0.12.4",
 ]
 
 [[package]]
@@ -104,9 +139,9 @@ checksum = "bed57e2090563b83ba8f83366628ce535a7584c9afa4c9fc0612a03925c6df58"
 
 [[package]]
 name = "byteorder"
-version = "1.4.2"
+version = "1.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
 
 [[package]]
 name = "bytes"
@@ -264,7 +299,7 @@ version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
 dependencies = [
- "generic-array 0.12.3",
+ "generic-array 0.12.4",
 ]
 
 [[package]]
@@ -303,6 +338,28 @@ version = "1.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
 
+[[package]]
+name = "failure"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
+dependencies = [
+ "backtrace",
+ "failure_derive",
+]
+
+[[package]]
+name = "failure_derive"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
 [[package]]
 name = "fake-simd"
 version = "0.1.2"
@@ -366,9 +423,9 @@ dependencies = [
 
 [[package]]
 name = "generic-array"
-version = "0.12.3"
+version = "0.12.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
+checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
 dependencies = [
  "typenum",
 ]
@@ -404,6 +461,12 @@ dependencies = [
  "weezl",
 ]
 
+[[package]]
+name = "gimli"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
+
 [[package]]
 name = "glob"
 version = "0.3.0"
@@ -435,9 +498,9 @@ dependencies = [
 
 [[package]]
 name = "hex"
-version = "0.4.2"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
 
 [[package]]
 name = "http"
@@ -513,15 +576,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "libc"
-version = "0.2.86"
+version = "0.2.89"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
+checksum = "538c092e5586f4cdd7dd8078c4a79220e3e168880218124dcbce860f0ea938c6"
 
 [[package]]
 name = "libflate"
-version = "1.0.3"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "389de7875e06476365974da3e7ff85d55f1972188ccd9f6020dd7c8156e17914"
+checksum = "158ae2ca09a761eaf6050894f5a6f013f2773dafe24f67bfa73a7504580e2916"
 dependencies = [
  "adler32",
  "crc32fast",
@@ -665,11 +728,17 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "object"
+version = "0.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
+
 [[package]]
 name = "once_cell"
-version = "1.7.0"
+version = "1.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10acf907b94fc1b1a152d08ef97e7759650268cf986bf127f387e602b02c7e5a"
+checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
 
 [[package]]
 name = "opaque-debug"
@@ -685,15 +754,15 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
 
 [[package]]
 name = "openssl"
-version = "0.10.32"
+version = "0.10.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "038d43985d1ddca7a9900630d8cd031b56e4794eecc2e9ea39dd17aa04399a70"
+checksum = "a61075b62a23fef5a29815de7536d940aa35ce96d18ce0cc5076272db678a577"
 dependencies = [
  "bitflags",
  "cfg-if 1.0.0",
  "foreign-types",
- "lazy_static",
  "libc",
+ "once_cell",
  "openssl-sys",
 ]
 
@@ -705,9 +774,9 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.60"
+version = "0.9.61"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6"
+checksum = "313752393519e876837e09e1fa183ddef0be7735868dced3196f4472d536277f"
 dependencies = [
  "autocfg",
  "cc",
@@ -899,21 +968,20 @@ dependencies = [
 
 [[package]]
 name = "regex"
-version = "1.4.3"
+version = "1.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
+checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19"
 dependencies = [
  "aho-corasick",
  "memchr",
  "regex-syntax",
- "thread_local",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.22"
+version = "0.6.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
+checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
 
 [[package]]
 name = "remove_dir_all"
@@ -930,6 +998,12 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac"
 
+[[package]]
+name = "rustc-demangle"
+version = "0.1.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
+
 [[package]]
 name = "ryu"
 version = "1.0.5"
@@ -969,9 +1043,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 
 [[package]]
 name = "security-framework"
-version = "2.1.1"
+version = "2.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dfd318104249865096c8da1dfabf09ddbb6d0330ea176812a62ec75e40c4166"
+checksum = "d493c5f39e02dfb062cd8f33301f90f9b13b650e8c1b1d0fd75c19dd64bff69d"
 dependencies = [
  "bitflags",
  "core-foundation",
@@ -992,18 +1066,18 @@ dependencies = [
 
 [[package]]
 name = "serde"
-version = "1.0.123"
+version = "1.0.124"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
+checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.123"
+version = "1.0.124"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
+checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1060,15 +1134,40 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
 
 [[package]]
 name = "syn"
-version = "1.0.60"
+version = "1.0.64"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fd9d1e9976102a03c542daa2eff1b43f9d72306342f3f8b3ed5fb8908195d6f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.12.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
+checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
 dependencies = [
  "proc-macro2",
  "quote",
+ "syn",
  "unicode-xid",
 ]
 
+[[package]]
+name = "sysctl"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0501f0d0c2aa64b419abff97c209f4b82c4e67caa63e8dc5b222ecc1b574cb5c"
+dependencies = [
+ "bitflags",
+ "byteorder",
+ "failure",
+ "libc",
+ "walkdir",
+]
+
 [[package]]
 name = "tar"
 version = "0.4.33"
@@ -1087,6 +1186,7 @@ dependencies = [
  "anyhow",
  "ar",
  "attohttpc",
+ "bitness",
  "chrono",
  "dirs-next",
  "glob",
@@ -1109,6 +1209,7 @@ dependencies = [
  "toml",
  "uuid",
  "walkdir",
+ "winreg",
  "zip",
 ]
 
@@ -1155,15 +1256,6 @@ dependencies = [
  "syn",
 ]
 
-[[package]]
-name = "thread_local"
-version = "1.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
-dependencies = [
- "once_cell",
-]
-
 [[package]]
 name = "tiff"
 version = "0.6.1"
@@ -1211,9 +1303,9 @@ dependencies = [
 
 [[package]]
 name = "typenum"
-version = "1.12.0"
+version = "1.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
+checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
 
 [[package]]
 name = "ucd-trie"
@@ -1221,6 +1313,15 @@ version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
 
+[[package]]
+name = "uname"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "unicode-bidi"
 version = "0.3.4"
@@ -1274,9 +1375,9 @@ checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
 
 [[package]]
 name = "version_check"
-version = "0.9.2"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
+checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
 
 [[package]]
 name = "walkdir"
@@ -1303,9 +1404,9 @@ checksum = "4a32b378380f4e9869b22f0b5177c68a5519f03b3454fde0b291455ddbae266c"
 
 [[package]]
 name = "wildmatch"
-version = "1.0.13"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2399814fda0d6999a6bfe9b5c7660d836334deb162a09db8b73d5b38fd8c40a"
+checksum = "7f44b95f62d34113cf558c93511ac93027e03e9c29a60dd0fd70e6e025c7270a"
 
 [[package]]
 name = "winapi"
@@ -1338,6 +1439,15 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
+[[package]]
+name = "winreg"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
+dependencies = [
+ "winapi",
+]
+
 [[package]]
 name = "xattr"
 version = "0.2.2"

+ 5 - 3
cli/tauri-bundler/Cargo.toml

@@ -36,19 +36,21 @@ toml = "0.5.8"
 walkdir = "2"
 lazy_static = { version = "1.4" }
 handlebars = { version = "3.5" }
+zip = { version = "0.5" }
+tempfile = "3.1.0"
+regex = { version = "1" }
 
 [target."cfg(target_os = \"windows\")".dependencies]
 attohttpc = { version = "0.16.3" }
 regex = { version = "1" }
 uuid = { version = "0.8", features = [ "v5" ] }
+bitness = "0.4"
+winreg = "0.7"
 
 [target."cfg(not(target_os = \"linux\"))".dependencies]
-zip = { version = "0.5" }
 sha2 = { version = "0.9" }
 hex = { version = "0.4" }
 
-[dev-dependencies]
-tempfile = "3"
 
 [lib]
 name = "tauri_bundler"

+ 3 - 0
cli/tauri-bundler/src/bundle.rs

@@ -22,6 +22,9 @@ pub use self::{
     Settings, SettingsBuilder,
   },
 };
+#[cfg(windows)]
+pub use settings::WindowsSettings;
+
 use common::print_finished;
 
 use std::path::PathBuf;

+ 3 - 3
cli/tauri-bundler/src/bundle/common.rs

@@ -247,7 +247,7 @@ pub fn execute_with_verbosity(cmd: &mut Command, settings: &Settings) -> crate::
 
 #[cfg(test)]
 mod tests {
-  use super::{copy_dir, create_file, is_retina, resource_relpath, symlink_file};
+  use super::{create_file, is_retina, resource_relpath};
   use std::{io::Write, path::PathBuf};
 
   #[test]
@@ -277,7 +277,7 @@ mod tests {
         create_file(&tmp.path().join("orig/sub/file.txt")).expect("Unable to create file");
       writeln!(file, "Hello, world!").expect("Unable to write to file");
     }
-    symlink_file(
+    super::symlink_file(
       &PathBuf::from("sub/file.txt"),
       &tmp.path().join("orig/link"),
     )
@@ -290,7 +290,7 @@ mod tests {
     );
     // Copy ${TMP}/orig to ${TMP}/parent/copy, and make sure that the
     // directory structure, file, and symlink got copied correctly.
-    copy_dir(&tmp.path().join("orig"), &tmp.path().join("parent/copy"))
+    super::copy_dir(&tmp.path().join("orig"), &tmp.path().join("parent/copy"))
       .expect("Failed to copy dir");
     assert!(tmp.path().join("parent/copy").is_dir());
     assert!(tmp.path().join("parent/copy/sub").is_dir());

+ 6 - 2
cli/tauri-bundler/src/bundle/deb_bundle.rs

@@ -166,13 +166,17 @@ exit 0",
   )?;
   bootstrapper_file.flush()?;
 
-  Command::new("chmod")
+  let status = Command::new("chmod")
     .arg("+x")
     .arg(bootstrap_file_name)
     .current_dir(&bin_dir)
     .stdout(Stdio::piped())
     .stderr(Stdio::piped())
-    .spawn()?;
+    .status()?;
+
+  if !status.success() {
+    return Err(anyhow::anyhow!("failed to make the bootstrapper an executable",).into());
+  }
 
   Ok(())
 }

+ 5 - 0
cli/tauri-bundler/src/bundle/dmg_bundle.rs

@@ -129,5 +129,10 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
   })?;
 
   fs::rename(bundle_dir.join(dmg_name), dmg_path.clone())?;
+
+  // Sign DMG if needed
+  if let Some(identity) = &settings.macos().signing_identity {
+    crate::bundle::macos_bundle::sign(dmg_path.clone(), identity, &settings, false)?;
+  }
   Ok(vec![bundle_path, dmg_path])
 }

+ 432 - 12
cli/tauri-bundler/src/bundle/macos_bundle.rs

@@ -32,19 +32,14 @@ use std::{
   process::{Command, Stdio},
 };
 
+use regex::Regex;
+
 /// Bundles the project.
 /// Returns a vector of PathBuf that shows where the .app was created.
 pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
-  let package_base_name = format!(
-    "{}_{}_{}",
-    settings.main_binary_name(),
-    settings.version_string(),
-    match settings.binary_arch() {
-      "x86_64" => "x64",
-      other => other,
-    }
-  );
-  let app_product_name = format!("{}.app", package_base_name);
+  // we should use the bundle name (App name) as a MacOS standard.
+  // version or platform shouldn't be included in the App name.
+  let app_product_name = format!("{}.app", settings.product_name());
   common::print_bundling(&app_product_name)?;
   let app_bundle_path = settings
     .project_out_directory()
@@ -87,9 +82,430 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
     create_bootstrapper(&bundle_directory, settings)
       .with_context(|| "Failed to create macOS bootstrapper")?;
   }
+
+  if let Some(identity) = &settings.macos().signing_identity {
+    // setup keychain allow you to import your certificate
+    // for CI build
+    setup_keychain_if_needed()?;
+    // sign application
+    sign(app_bundle_path.clone(), identity, &settings, true)?;
+    // notarization is required for distribution
+    match notarize_auth_args() {
+      Ok(args) => {
+        notarize(app_bundle_path.clone(), args, settings)?;
+      }
+      Err(e) => {
+        common::print_info(format!("skipping app notarization, {}", e.to_string()).as_str())?;
+      }
+    }
+  }
+
   Ok(vec![app_bundle_path])
 }
 
+pub fn sign(
+  path_to_sign: PathBuf,
+  identity: &str,
+  settings: &Settings,
+  is_an_executable: bool,
+) -> crate::Result<()> {
+  common::print_info(format!(r#"signing with identity "{}""#, identity).as_str())?;
+  let mut args = vec!["--force", "-s", identity];
+  if let Some(entitlements_path) = &settings.macos().entitlements {
+    common::print_info(format!("using entitlements file at {}", entitlements_path).as_str())?;
+    args.push("--entitlements");
+    args.push(entitlements_path);
+  }
+
+  if is_an_executable {
+    args.push("--options");
+    args.push("runtime");
+  }
+
+  if path_to_sign.is_dir() {
+    args.push("--deep");
+  }
+
+  let status = Command::new("codesign")
+    .args(args)
+    .arg(path_to_sign.to_string_lossy().to_string())
+    .status()?;
+
+  if !status.success() {
+    return Err(anyhow::anyhow!("failed to sign app").into());
+  }
+
+  Ok(())
+}
+
+fn notarize(
+  app_bundle_path: PathBuf,
+  auth_args: Vec<String>,
+  settings: &Settings,
+) -> crate::Result<()> {
+  let identifier = settings.bundle_identifier();
+
+  let bundle_stem = app_bundle_path
+    .file_stem()
+    .expect("failed to get bundle filename");
+
+  let tmp_dir = tempfile::tempdir()?;
+  let zip_path = tmp_dir
+    .path()
+    .join(format!("{}.zip", bundle_stem.to_string_lossy()));
+  let zip_args = vec![
+    "-c",
+    "-k",
+    "--keepParent",
+    "--sequesterRsrc",
+    app_bundle_path
+      .to_str()
+      .expect("failed to convert bundle_path to string"),
+    zip_path
+      .to_str()
+      .expect("failed to convert zip_path to string"),
+  ];
+
+  // use ditto to create a PKZip almost identical to Finder
+  // this remove almost 99% of false alarm in notarization
+  let zip_app = Command::new("ditto")
+    .args(zip_args)
+    .stderr(Stdio::inherit())
+    .status()?;
+
+  if !zip_app.success() {
+    return Err(anyhow::anyhow!("failed to zip app with ditto").into());
+  }
+
+  // sign the zip file
+  if let Some(identity) = &settings.macos().signing_identity {
+    sign(zip_path.clone(), identity, &settings, false)?;
+  };
+
+  let notarize_args = vec![
+    "altool",
+    "--notarize-app",
+    "-f",
+    zip_path
+      .to_str()
+      .expect("failed to convert zip_path to string"),
+    "--primary-bundle-id",
+    identifier,
+  ];
+  common::print_info("notarizing app")?;
+  let output = Command::new("xcrun")
+    .args(notarize_args)
+    .args(auth_args.clone())
+    .stderr(Stdio::inherit())
+    .output()?;
+
+  if !output.status.success() {
+    return Err(
+      anyhow::anyhow!(format!(
+        "failed to upload app to Apple's notarization servers. {}",
+        std::str::from_utf8(&output.stdout)?
+      ))
+      .into(),
+    );
+  }
+
+  let stdout = std::str::from_utf8(&output.stdout)?;
+  if let Some(uuid) = Regex::new(r"\nRequestUUID = (.+?)\n")?
+    .captures_iter(stdout)
+    .next()
+  {
+    common::print_info("notarization started; waiting for Apple response...")?;
+    let uuid = uuid[1].to_string();
+    get_notarization_status(uuid, auth_args)?;
+    staple_app(app_bundle_path.clone())?;
+  } else {
+    return Err(
+      anyhow::anyhow!(format!(
+        "failed to parse RequestUUID from upload output. {}",
+        stdout
+      ))
+      .into(),
+    );
+  }
+
+  Ok(())
+}
+
+fn staple_app(mut app_bundle_path: PathBuf) -> crate::Result<()> {
+  let app_bundle_path_clone = app_bundle_path.clone();
+  let filename = app_bundle_path_clone
+    .file_name()
+    .expect("failed to get bundle filename")
+    .to_str()
+    .expect("failed to convert bundle filename to string");
+
+  app_bundle_path.pop();
+
+  let output = Command::new("xcrun")
+    .args(vec!["stapler", "staple", "-v", filename])
+    .current_dir(app_bundle_path)
+    .stderr(Stdio::inherit())
+    .output()?;
+
+  if !output.status.success() {
+    Err(
+      anyhow::anyhow!(format!(
+        "failed to staple app. {}",
+        std::str::from_utf8(&output.stdout)?
+      ))
+      .into(),
+    )
+  } else {
+    Ok(())
+  }
+}
+
+fn get_notarization_status(uuid: String, auth_args: Vec<String>) -> crate::Result<()> {
+  std::thread::sleep(std::time::Duration::from_secs(10));
+  let output = Command::new("xcrun")
+    .args(vec!["altool", "--notarization-info", &uuid])
+    .args(auth_args.clone())
+    .stderr(Stdio::inherit())
+    .output()?;
+
+  if !output.status.success() {
+    get_notarization_status(uuid, auth_args)
+  } else {
+    let stdout = std::str::from_utf8(&output.stdout)?;
+    if let Some(status) = Regex::new(r"\n *Status: (.+?)\n")?
+      .captures_iter(stdout)
+      .next()
+    {
+      let status = status[1].to_string();
+      if status == "in progress" {
+        get_notarization_status(uuid, auth_args)
+      } else if status == "invalid" {
+        Err(
+          anyhow::anyhow!(format!(
+            "Apple failed to notarize your app. {}",
+            std::str::from_utf8(&output.stdout)?
+          ))
+          .into(),
+        )
+      } else if status != "success" {
+        Err(
+          anyhow::anyhow!(format!(
+            "Unknown notarize status {}. {}",
+            status,
+            std::str::from_utf8(&output.stdout)?
+          ))
+          .into(),
+        )
+      } else {
+        Ok(())
+      }
+    } else {
+      get_notarization_status(uuid, auth_args)
+    }
+  }
+}
+
+fn notarize_auth_args() -> crate::Result<Vec<String>> {
+  match (
+    std::env::var_os("APPLE_ID"),
+    std::env::var_os("APPLE_PASSWORD"),
+  ) {
+    (Some(apple_id), Some(apple_password)) => {
+      let apple_id = apple_id
+        .to_str()
+        .expect("failed to convert APPLE_ID to string")
+        .to_string();
+      let apple_password = apple_password
+        .to_str()
+        .expect("failed to convert APPLE_PASSWORD to string")
+        .to_string();
+      Ok(vec![
+        "-u".to_string(),
+        apple_id,
+        "-p".to_string(),
+        apple_password,
+      ])
+    }
+    _ => {
+      match (std::env::var_os("APPLE_API_KEY"), std::env::var_os("APPLE_API_ISSUER")) {
+        (Some(api_key), Some(api_issuer)) => {
+          let api_key = api_key.to_str().expect("failed to convert APPLE_API_KEY to string").to_string();
+          let api_issuer = api_issuer.to_str().expect("failed to convert APPLE_API_ISSUER to string").to_string();
+          Ok(vec!["--apiKey".to_string(), api_key, "--apiIssuer".to_string(), api_issuer])
+        },
+        _ => Err(anyhow::anyhow!("no APPLE_ID & APPLE_PASSWORD or APPLE_API_KEY & APPLE_API_ISSUER environment variables found").into())
+      }
+    }
+  }
+}
+
+// Import certificate from ENV variables.
+// APPLE_CERTIFICATE is the p12 certificate base64 encoded.
+// By example you can use; openssl base64 -in MyCertificate.p12 -out MyCertificate-base64.txt
+// Then use the value of the base64 in APPLE_CERTIFICATE env variable.
+// You need to set APPLE_CERTIFICATE_PASSWORD to the password you set when youy exported your certificate.
+// https://help.apple.com/xcode/mac/current/#/dev154b28f09 see: `Export a signing certificate`
+fn setup_keychain_if_needed() -> crate::Result<()> {
+  match (
+    std::env::var_os("APPLE_CERTIFICATE"),
+    std::env::var_os("APPLE_CERTIFICATE_PASSWORD"),
+  ) {
+    (Some(certificate_encoded), Some(certificate_password)) => {
+      // we delete any previous version of our keychain if present
+      delete_keychain_if_needed();
+      common::print_info("setup keychain from environment variables...")?;
+
+      let key_chain_id = "tauri-build.keychain";
+      let key_chain_name = "tauri-build";
+      let tmp_dir = tempfile::tempdir()?;
+      let cert_path = tmp_dir
+        .path()
+        .join("cert.p12")
+        .to_string_lossy()
+        .to_string();
+      let cert_path_tmp = tmp_dir
+        .path()
+        .join("cert.p12.tmp")
+        .to_string_lossy()
+        .to_string();
+      let certificate_encoded = certificate_encoded
+        .to_str()
+        .expect("failed to convert APPLE_CERTIFICATE to string")
+        .as_bytes();
+
+      let certificate_password = certificate_password
+        .to_str()
+        .expect("failed to convert APPLE_CERTIFICATE_PASSWORD to string")
+        .to_string();
+
+      // as certificate contain whitespace decoding may be broken
+      // https://github.com/marshallpierce/rust-base64/issues/105
+      // we'll use builtin base64 command from the OS
+      let mut tmp_cert = File::create(cert_path_tmp.clone())?;
+      tmp_cert.write_all(certificate_encoded)?;
+
+      let decode_certificate = Command::new("base64")
+        .args(vec!["--decode", "-i", &cert_path_tmp, "-o", &cert_path])
+        .stderr(Stdio::piped())
+        .status()?;
+
+      if !decode_certificate.success() {
+        return Err(anyhow::anyhow!("failed to decode certificate",).into());
+      }
+
+      let create_key_chain = Command::new("security")
+        .args(vec!["create-keychain", "-p", key_chain_name, key_chain_id])
+        .stdout(Stdio::piped())
+        .stderr(Stdio::piped())
+        .status()?;
+
+      if !create_key_chain.success() {
+        return Err(anyhow::anyhow!("failed to create keychain",).into());
+      }
+
+      let set_default_keychain = Command::new("security")
+        .args(vec!["default-keychain", "-s", key_chain_id])
+        .stdout(Stdio::piped())
+        .stderr(Stdio::piped())
+        .status()?;
+
+      if !set_default_keychain.success() {
+        return Err(anyhow::anyhow!("failed to set default keychain",).into());
+      }
+
+      let unlock_keychain = Command::new("security")
+        .args(vec!["unlock-keychain", "-p", key_chain_name, key_chain_id])
+        .stdout(Stdio::piped())
+        .stderr(Stdio::piped())
+        .status()?;
+
+      if !unlock_keychain.success() {
+        return Err(anyhow::anyhow!("failed to set unlock keychain",).into());
+      }
+
+      let import_certificate = Command::new("security")
+        .arg("import")
+        .arg(cert_path)
+        .arg("-k")
+        .arg(key_chain_id)
+        .arg("-P")
+        .arg(certificate_password)
+        .arg("-T")
+        .arg("/usr/bin/codesign")
+        .arg("-T")
+        .arg("/usr/bin/pkgbuild")
+        .arg("-T")
+        .arg("/usr/bin/productbuild")
+        .stderr(Stdio::inherit())
+        .output()?;
+
+      if !import_certificate.status.success() {
+        return Err(
+          anyhow::anyhow!(format!(
+            "failed to import keychain certificate {:?}",
+            std::str::from_utf8(&import_certificate.stdout)
+          ))
+          .into(),
+        );
+      }
+
+      let settings_keychain = Command::new("security")
+        .args(vec![
+          "set-keychain-settings",
+          "-t",
+          "3600",
+          "-u",
+          key_chain_id,
+        ])
+        .stdout(Stdio::piped())
+        .stderr(Stdio::piped())
+        .status()?;
+
+      if !settings_keychain.success() {
+        return Err(anyhow::anyhow!("failed to set keychain settings",).into());
+      }
+
+      let partition_list = Command::new("security")
+        .args(vec![
+          "set-key-partition-list",
+          "-S",
+          "apple-tool:,apple:,codesign:",
+          "-s",
+          "-k",
+          key_chain_name,
+          key_chain_id,
+        ])
+        .stdout(Stdio::piped())
+        .stderr(Stdio::piped())
+        .status()?;
+
+      if !partition_list.success() {
+        return Err(anyhow::anyhow!("failed to set keychain settings",).into());
+      }
+
+      Ok(())
+    }
+    // skip it
+    _ => Ok(()),
+  }
+}
+
+fn delete_keychain_if_needed() {
+  if let (Some(_cert), Some(_password)) = (
+    std::env::var_os("APPLE_CERTIFICATE"),
+    std::env::var_os("APPLE_CERTIFICATE_PASSWORD"),
+  ) {
+    let key_chain_id = "tauri-build.keychain";
+    // delete keychain if needed and skip any error
+    let _result = Command::new("security")
+      .arg("delete-keychain")
+      .arg(key_chain_id)
+      .stdout(Stdio::piped())
+      .stderr(Stdio::piped())
+      .status();
+  }
+}
+
 // Copies the app's binaries to the bundle.
 fn copy_binaries_to_bundle(bundle_directory: &Path, settings: &Settings) -> crate::Result<()> {
   let dest_dir = bundle_directory.join("MacOS");
@@ -143,13 +559,17 @@ exit 0",
   file.flush()?;
 
   // We have to make the __bootstrapper executable, or the bundle will not work
-  Command::new("chmod")
+  let status = Command::new("chmod")
     .arg("+x")
     .arg("__bootstrapper")
     .current_dir(&bundle_dir.join("MacOS/"))
     .stdout(Stdio::piped())
     .stderr(Stdio::piped())
-    .spawn()?;
+    .status()?;
+
+  if !status.success() {
+    return Err(anyhow::anyhow!("failed to make the bootstrapper an executable",).into());
+  }
 
   Ok(())
 }

+ 20 - 0
cli/tauri-bundler/src/bundle/settings.rs

@@ -139,6 +139,17 @@ pub struct MacOSSettings {
   ///
   /// This allows communication to the outside world e.g. a web server you're shipping.
   pub exception_domain: Option<String>,
+  pub signing_identity: Option<String>,
+  pub entitlements: Option<String>,
+}
+
+/// The Windows bundle settings.
+#[cfg(windows)]
+#[derive(Clone, Debug, Deserialize, Default)]
+pub struct WindowsSettings {
+  pub digest_algorithm: Option<String>,
+  pub certificate_thumbprint: Option<String>,
+  pub timestamp_url: Option<String>,
 }
 
 /// The bundle settings of the BuildArtifact we're bundling.
@@ -178,6 +189,9 @@ pub struct BundleSettings {
   pub deb: DebianSettings,
   /// MacOS-specific settings.
   pub macos: MacOSSettings,
+  /// Windows-specific settings.
+  #[cfg(windows)]
+  pub windows: WindowsSettings,
 }
 
 #[derive(Clone, Debug)]
@@ -515,6 +529,12 @@ impl Settings {
   pub fn macos(&self) -> &MacOSSettings {
     &self.bundle_settings.macos
   }
+
+  /// Returns the Windows settings.
+  #[cfg(windows)]
+  pub fn windows(&self) -> &WindowsSettings {
+    &self.bundle_settings.windows
+  }
 }
 
 /// Parses the external binaries to bundle, adding the target triple suffix to each of them.

+ 139 - 11
cli/tauri-bundler/src/bundle/wix.rs

@@ -20,6 +20,12 @@ use std::{
   process::{Command, Stdio},
 };
 
+use bitness::{self, Bitness};
+use winreg::{
+  enums::{HKEY_LOCAL_MACHINE, KEY_READ, KEY_WOW64_32KEY},
+  RegKey,
+};
+
 // URLS for the WIX toolchain.  Can be used for crossplatform compilation.
 pub const WIX_URL: &str =
   "https://github.com/wixtoolset/wix3/releases/download/wix3112rtm/wix311-binaries.zip";
@@ -98,6 +104,12 @@ struct ResourceDirectory {
   directories: Vec<ResourceDirectory>,
 }
 
+pub struct SignParams {
+  pub digest_algorithm: String,
+  pub certificate_thumbprint: String,
+  pub timestamp_url: Option<String>,
+}
+
 impl ResourceDirectory {
   /// Adds a file to this directory descriptor.
   fn add_file(&mut self, file: ResourceFile) {
@@ -435,10 +447,34 @@ pub fn build_wix_app_installer(
   // target only supports x64.
   common::print_info(format!("Target: {}", arch).as_str())?;
 
-  let output_path = settings
-    .project_out_directory()
-    .join("bundle/msi")
-    .join(arch);
+  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);
+
+  if let Some(certificate_thumbprint) = &settings.windows().certificate_thumbprint {
+    common::print_info("signing app")?;
+    sign(
+      &app_exe_source,
+      &SignParams {
+        digest_algorithm: settings
+          .windows()
+          .digest_algorithm
+          .as_ref()
+          .map(|algorithm| algorithm.to_string())
+          .unwrap_or_else(|| "sha256".to_string()),
+        certificate_thumbprint: certificate_thumbprint.to_string(),
+        timestamp_url: match &settings.windows().timestamp_url {
+          Some(url) => Some(url.to_string()),
+          None => None,
+        },
+      },
+    )?;
+  }
+
+  let output_path = settings.project_out_directory().join("wix").join(arch);
 
   let mut data = BTreeMap::new();
 
@@ -485,13 +521,6 @@ pub fn build_wix_app_installer(
   let merge_modules = get_merge_modules(&settings)?;
   data.insert("merge_modules", to_json(merge_modules));
 
-  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).display().to_string();
-
   data.insert("app_exe_source", to_json(&app_exe_source));
 
   // copy icon from $CWD/icons/icon.ico folder to resource folder near msi
@@ -529,6 +558,105 @@ pub fn build_wix_app_installer(
   Ok(target)
 }
 
+// sign code forked from https://github.com/forbjok/rust-codesign
+fn locate_signtool() -> crate::Result<PathBuf> {
+  const INSTALLED_ROOTS_REGKEY_PATH: &str = r"SOFTWARE\Microsoft\Windows Kits\Installed Roots";
+  const KITS_ROOT_REGVALUE_NAME: &str = r"KitsRoot10";
+
+  let installed_roots_key_path = Path::new(INSTALLED_ROOTS_REGKEY_PATH);
+
+  // Open 32-bit HKLM "Installed Roots" key
+  let installed_roots_key = RegKey::predef(HKEY_LOCAL_MACHINE)
+    .open_subkey_with_flags(installed_roots_key_path, KEY_READ | KEY_WOW64_32KEY)
+    .map_err(|_| crate::Error::OpenRegistry(INSTALLED_ROOTS_REGKEY_PATH.to_string()))?;
+
+  // Get the Windows SDK root path
+  let kits_root_10_path: String = installed_roots_key
+    .get_value(KITS_ROOT_REGVALUE_NAME)
+    .map_err(|_| crate::Error::GetRegistryValue(KITS_ROOT_REGVALUE_NAME.to_string()))?;
+
+  // Construct Windows SDK bin path
+  let kits_root_10_bin_path = Path::new(&kits_root_10_path).join("bin");
+
+  let mut installed_kits: Vec<String> = installed_roots_key
+    .enum_keys()
+    /* Report and ignore errors, pass on values. */
+    .filter_map(|res| match res {
+      Ok(v) => Some(v),
+      Err(_) => None,
+    })
+    .collect();
+
+  // Sort installed kits
+  installed_kits.sort();
+
+  /* Iterate through installed kit version keys in reverse (from newest to oldest),
+  adding their bin paths to the list.
+  Windows SDK 10 v10.0.15063.468 and later will have their signtools located there. */
+  let mut kit_bin_paths: Vec<PathBuf> = installed_kits
+    .iter()
+    .rev()
+    .map(|kit| kits_root_10_bin_path.join(kit).to_path_buf())
+    .collect();
+
+  /* Add kits root bin path.
+  For Windows SDK 10 versions earlier than v10.0.15063.468, signtool will be located there. */
+  kit_bin_paths.push(kits_root_10_bin_path.to_path_buf());
+
+  // Choose which version of SignTool to use based on OS bitness
+  let arch_dir = match bitness::os_bitness().expect("failed to get os bitness") {
+    Bitness::X86_32 => "x86",
+    Bitness::X86_64 => "x64",
+    _ => return Err(crate::Error::UnsupportedBitness),
+  };
+
+  /* Iterate through all bin paths, checking for existence of a SignTool executable. */
+  for kit_bin_path in &kit_bin_paths {
+    /* Construct SignTool path. */
+    let signtool_path = kit_bin_path.join(arch_dir).join("signtool.exe");
+
+    /* Check if SignTool exists at this location. */
+    if signtool_path.exists() {
+      // SignTool found. Return it.
+      return Ok(signtool_path.to_path_buf());
+    }
+  }
+
+  Err(crate::Error::SignToolNotFound)
+}
+
+fn sign<P: AsRef<Path>>(path: P, params: &SignParams) -> crate::Result<()> {
+  // Convert path to string reference, as we need to pass it as a commandline parameter to signtool
+  let path_str = path.as_ref().to_str().unwrap();
+
+  // Construct SignTool command
+  let signtool = locate_signtool()?;
+  common::print_info(format!("running signtool {:?}", signtool).as_str())?;
+  let mut cmd = Command::new(signtool);
+  cmd.arg("sign");
+  cmd.args(&["/fd", &params.digest_algorithm]);
+  cmd.args(&["/sha1", &params.certificate_thumbprint]);
+
+  if let Some(ref timestamp_url) = params.timestamp_url {
+    cmd.args(&["/t", timestamp_url]);
+  }
+
+  cmd.arg(path_str);
+
+  // Execute SignTool command
+  let output = cmd.output()?;
+
+  if !output.status.success() {
+    let stderr = String::from_utf8_lossy(output.stderr.as_slice()).into_owned();
+    return Err(crate::Error::Sign(stderr));
+  }
+
+  let stdout = String::from_utf8_lossy(output.stdout.as_slice()).into_owned();
+  common::print_info(format!("{:?}", stdout).as_str())?;
+
+  Ok(())
+}
+
 /// Generates the data required for the external binaries and extra binaries bundling.
 fn generate_binaries_data(settings: &Settings) -> crate::Result<Vec<Binary>> {
   let mut binaries = Vec::new();

+ 18 - 2
cli/tauri-bundler/src/error.rs

@@ -22,7 +22,6 @@ pub enum Error {
   StripError(#[from] path::StripPrefixError),
   #[error("`{0}`")]
   ConvertError(#[from] num::TryFromIntError),
-  #[cfg(not(target_os = "linux"))]
   #[error("`{0}`")]
   ZipError(#[from] zip::result::ZipError),
   #[cfg(not(target_os = "linux"))]
@@ -32,7 +31,6 @@ pub enum Error {
   HandleBarsError(#[from] handlebars::RenderError),
   #[error("`{0}`")]
   JsonError(#[from] serde_json::error::Error),
-  #[cfg(windows)]
   #[error("`{0}`")]
   RegexError(#[from] regex::Error),
   #[cfg(windows)]
@@ -54,6 +52,24 @@ pub enum Error {
   ShellScriptError(String),
   #[error("`{0}`")]
   GenericError(String),
+  #[error("string is not UTF-8")]
+  Utf8(#[from] std::str::Utf8Error),
+  /// Windows SignTool not found.
+  #[cfg(target_os = "windows")]
+  #[error("SignTool not found")]
+  SignToolNotFound,
+  #[cfg(target_os = "windows")]
+  #[error("failed to open registry {0}")]
+  OpenRegistry(String),
+  #[cfg(target_os = "windows")]
+  #[error("failed to get {0} value on registry")]
+  GetRegistryValue(String),
+  #[cfg(target_os = "windows")]
+  #[error("unsupported OS bitness")]
+  UnsupportedBitness,
+  #[cfg(target_os = "windows")]
+  #[error("failed to sign app: {0}")]
+  Sign(String),
 }
 
 pub type Result<T> = anyhow::Result<T, Error>;