Skip to content

Commit 8164073

Browse files
committed
Support signing APPX/MSIX Windows packages (Fixes ebourg#81)
1 parent 1e3f1ed commit 8164073

34 files changed

+2398
-28
lines changed

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ Jsign - Java implementation of Microsoft Authenticode
88

99
Jsign is a Java implementation of Microsoft Authenticode that lets you sign
1010
and timestamp executable files for Windows, Microsoft Installers (MSI), Cabinet
11-
files (CAB), Catalog files (CAT) and scripts. Jsign is platform independent and
12-
provides an alternative to native tools like signcode/signtool on Windows or the
13-
Mono development tools on Unix systems.
11+
files (CAB), Catalog files (CAT), Windows packages (APPX/MSIX) and scripts.
12+
Jsign is platform independent and provides an alternative to native tools like
13+
signcode/signtool on Windows or the Mono development tools on Unix systems.
1414

1515
Jsign comes as an easy-to-use task/plugin for the main build systems (Maven,
1616
Gradle, Ant). It's especially suitable for signing executable wrappers and
@@ -20,7 +20,7 @@ Jsign can also be used programmatically or standalone as a command line tool.
2020
Jsign is free to use and licensed under the [Apache License version 2.0](https://www.apache.org/licenses/LICENSE-2.0).
2121

2222
## Features
23-
* Platform independent signing of Windows executables, DLLs, Microsoft Installers (MSI), Cabinet files (CAB), Catalog files (CAT) and scripts (PowerShell, VBScript, JScript, WSF)
23+
* Platform independent signing of Windows executables, DLLs, Microsoft Installers (MSI), Cabinet files (CAB), Catalog files (CAT), Windows packages (APPX/MSIX) and scripts (PowerShell, VBScript, JScript, WSF)
2424
* Timestamping with retries and fallback on alternative servers (RFC 3161 and Authenticode protocols supported)
2525
* Supports multiple signatures per file, for all file types
2626
* Extracts and embeds detached signatures to support [reproducible builds](https://reproducible-builds.org/docs/embedded-signatures/)
@@ -40,6 +40,9 @@ See https://ebourg.github.io/jsign for more information.
4040

4141
## Changes
4242

43+
#### Version 5.1 (in development)
44+
* APPX/MSIX package signing has been implemented (thanks to Maciej Panek for the help)
45+
4346
#### Version 5.0 (2023-06-06)
4447

4548
* The AWS KMS signing service has been integrated (with contributions from Vincent Malmedy)

docs/index.html

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<head>
55
<meta charset='utf-8' />
66
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
7-
<meta name="description" content="Jsign : Pure Java implementation of Microsoft Authenticode for signing Windows executable files, Microsoft Installers (MSI), Cabinet files (CAB), Catalog files (CAT) and scripts (PowerShell, VBScript, JScript, WSF)" />
7+
<meta name="description" content="Jsign : Pure Java implementation of Microsoft Authenticode for signing Windows executable files, Microsoft Installers (MSI), Cabinet files (CAB), Catalog files (CAT), Windows packages (APPX/MSIX) and scripts (PowerShell, VBScript, JScript, WSF)" />
88
<meta name="google-site-verification" content="p912kgAnTBOzVbswrU43k3FXUbPnxLHdeW6xsVcq1uU" />
99
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
1010

@@ -37,8 +37,8 @@ <h2 id="project_tagline">Java implementation of Microsoft Authenticode <br class
3737

3838
<p>Jsign is a Java implementation of Microsoft Authenticode that lets you sign
3939
and timestamp executable files for Windows, Microsoft Installers (MSI), Cabinet files (CAB),
40-
Catalog files (CAT) and scripts (PowerShell, VBScript, JScript, WSF). Jsign is platform
41-
independent and provides an alternative to native tools like <em>signcode/signtool</em>
40+
Catalog files (CAT), Windows packages (APPX/MSIX) and scripts (PowerShell, VBScript, JScript, WSF).
41+
Jsign is platform independent and provides an alternative to native tools like <em>signcode/signtool</em>
4242
on Windows or the Mono development tools on Unix systems.</p>
4343

4444
<p>Jsign comes as an easy to use task/plugin for the main build systems (Maven,
@@ -56,7 +56,7 @@ <h2 id="project_tagline">Java implementation of Microsoft Authenticode <br class
5656
<h3>Features</h3>
5757

5858
<ul>
59-
<li>Platform independent signing of Windows executables, DLLs, Microsoft Installers (MSI), Cabinet files (CAB), Catalog files (CAT) and scripts (PowerShell, VBScript, JScript, WSF)</li>
59+
<li>Platform independent signing of Windows executables, DLLs, Microsoft Installers (MSI), Cabinet files (CAB), Catalog files (CAT), Windows packages (APPX/MSIX) and scripts (PowerShell, VBScript, JScript, WSF)</li>
6060
<li>Timestamping with retries and fallback on alternative servers (RFC 3161 and Authenticode protocols supported)</li>
6161
<li>Supports multiple signatures per file, for all file types</li>
6262
<li>Extracts and embeds detached signatures to support <a href="https://reproducible-builds.org/docs/embedded-signatures/">reproducible builds</a></li>
@@ -132,7 +132,8 @@ <h4 class="mobile-only">Attributes</h4>
132132
<td class="attribute">file</td>
133133
<td class="description">
134134
The file to be signed. The supported files are Windows executables (EXE), DLLs, Microsoft Installers (MSI),
135-
Cabinet files (CAB), Catalog files (CAT) and scripts (PowerShell, VBScript, JScript, WSF)</td>
135+
Cabinet files (CAB), Catalog files (CAT), Windows packages (APPX/MSIX) and scripts
136+
(PowerShell, VBScript, JScript, WSF)</td>
136137
<td class="required">Yes, unless a fileset is specified.</td>
137138
</tr>
138139
<tr>
@@ -213,8 +214,11 @@ <h4 class="mobile-only">Attributes</h4>
213214
</tr>
214215
<tr>
215216
<td class="attribute">alg</td>
216-
<td class="description">The digest algorithm (SHA-1, SHA-256, SHA-384 or SHA-512)</td>
217-
<td class="required">No; defaults to SHA-256</td>
217+
<td class="description">
218+
The digest algorithm (SHA-1, SHA-256, SHA-384 or SHA-512). For some formats such as APPX/MSIX packages
219+
the algorithm is automatically detected and setting this parameter has no effect.
220+
</td>
221+
<td class="required">No; defaults to SHA-256 or a format specific value</td>
218222
</tr>
219223
<tr>
220224
<td class="attribute">tsaurl</td>
@@ -437,7 +441,8 @@ <h3>Command Line Tool</h3>
437441
<pre>
438442
usage: jsign [OPTIONS] [FILE]...
439443
Sign and timestamp Windows executable files, Microsoft Installers (MSI), Cabinet
440-
files (CAB), Catalog files (CAT) or scripts (PowerShell, VBScript, JScript, WSF).
444+
files (CAB), Catalog files (CAT), Windows packages (APPX/MSIX) or scripts
445+
(PowerShell, VBScript, JScript, WSF).
441446

442447
-s,--keystore &lt;FILE> The keystore file, the SunPKCS11 configuration file or
443448
the cloud keystore name

jsign-cli/src/main/java/net/jsign/JsignCLI.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ private void setOption(String key, SignerHelper helper, CommandLine cmd) {
139139
}
140140

141141
private void printHelp() {
142-
String header = "Sign and timestamp Windows executable files, Microsoft Installers (MSI), Cabinet files (CAB), Catalog files (CAT) or scripts (PowerShell, VBScript, JScript, WSF).\n\n";
142+
String header = "Sign and timestamp Windows executable files, Microsoft Installers (MSI), Cabinet files (CAB), Catalog files (CAT), Windows packages (APPX/MSIX) or scripts (PowerShell, VBScript, JScript, WSF).\n\n";
143143
String footer ="\n" +
144144
"Examples:\n\n" +
145145
" Signing with a PKCS#12 keystore and timestamping:\n\n" +

jsign-core/src/main/java/net/jsign/AuthenticodeSigner.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,14 @@ public void sign(Signable file) throws Exception {
367367
* @throws Exception if an error occurs
368368
*/
369369
protected CMSSignedData createSignedData(Signable file) throws Exception {
370+
DigestAlgorithm digestAlgorithm = file.getRequiredDigestAlgorithm();
371+
if (digestAlgorithm == null) {
372+
digestAlgorithm = this.digestAlgorithm;
373+
}
374+
370375
// compute the signature
371376
ContentInfo contentInfo = file.createContentInfo(digestAlgorithm);
372-
AuthenticodeSignedDataGenerator generator = createSignedDataGenerator();
377+
AuthenticodeSignedDataGenerator generator = createSignedDataGenerator(digestAlgorithm);
373378
CMSSignedData sigData = generator.generate(contentInfo.getContentType(), contentInfo.getContent());
374379

375380
// verify the signature
@@ -396,7 +401,7 @@ protected CMSSignedData createSignedData(Signable file) throws Exception {
396401
return sigData;
397402
}
398403

399-
private AuthenticodeSignedDataGenerator createSignedDataGenerator() throws CMSException, OperatorCreationException, CertificateEncodingException {
404+
private AuthenticodeSignedDataGenerator createSignedDataGenerator(DigestAlgorithm digestAlgorithm) throws CMSException, OperatorCreationException, CertificateEncodingException {
400405
// create content signer
401406
final String sigAlg;
402407
if (signatureAlgorithm != null) {

jsign-core/src/main/java/net/jsign/Signable.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import net.jsign.cat.CatalogFile;
3232
import net.jsign.mscab.MSCabinetFile;
3333
import net.jsign.msi.MSIFile;
34+
import net.jsign.appx.APPXFile;
3435
import net.jsign.pe.PEFile;
3536
import net.jsign.script.JScript;
3637
import net.jsign.script.PowerShellScript;
@@ -45,6 +46,17 @@
4546
*/
4647
public interface Signable extends Closeable {
4748

49+
/**
50+
* Returns the digests algorithm required for the signature.
51+
* Some formats such as APPX/MSIX require a specific digest algorithm defined in the file metadata.
52+
*
53+
* @return the digest algorithm required for the signature, or null to use the default algorithm
54+
* @since 5.1
55+
*/
56+
default DigestAlgorithm getRequiredDigestAlgorithm() throws IOException {
57+
return null;
58+
}
59+
4860
/**
4961
* Creates the ContentInfo structure to be signed.
5062
*
@@ -152,6 +164,12 @@ static Signable of(File file, Charset encoding) throws IOException {
152164
} else if (file.getName().endsWith(".wsf")) {
153165
return new WindowsScript(file, encoding);
154166

167+
} else if (file.getName().endsWith(".msix")
168+
|| file.getName().endsWith(".msixbundle")
169+
|| file.getName().endsWith(".appx")
170+
|| file.getName().endsWith(".appxbundle")) {
171+
return new APPXFile(file);
172+
155173
} else {
156174
throw new UnsupportedOperationException("Unsupported file: " + file);
157175
}

0 commit comments

Comments
 (0)