Skip to content

Commit 78d68f1

Browse files
committed
Add command to show details about a signed object
It's useful to know whether an executable is already signed and by whom. Either to make sure that you have properly signed it or to check if somebody else has signed it. Example: ``` > java -jar jsign/target/jsign-7.2-SNAPSHOT.jar show foo.exe jsign show foo.exe Signature 0 Digest Algorithm: SHA256 Digest Value: c481bb3892d066ffacba0650adaa4c252580b776b1dd6026cf4a8bea6c813939 Is Timestamped? false Certificate Subject: CN=net.jsign.signing-cert Issuer: CN=net.jsign.issuing-cert Not Before: Fri Dec 03 14:34:46 CST 2021 Not After: Wed May 24 14:34:46 CST 2119 Expired: false Serial: 148957645726085760686199624248870688956 ``` Signed-off-by: Daniel Schaefer <[email protected]>
1 parent 103c51a commit 78d68f1

File tree

3 files changed

+67
-1
lines changed

3 files changed

+67
-1
lines changed

docs/index.html

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ <h3 id="cli">Command Line Tool</h3>
527527
files (CAB), Catalog files (CAT), Windows packages (APPX/MSIX), Microsoft Dynamics
528528
365 extension packages, NuGet packages and scripts (PowerShell, VBScript, JScript, WSF)
529529

530-
commands: sign (default), timestamp, extract, remove, tag
530+
commands: sign (default), timestamp, extract, remove, tag, show
531531

532532
sign:
533533
-s,--keystore &lt;FILE> The keystore file, the SunPKCS11 configuration file,
@@ -1032,6 +1032,25 @@ <h4 id="tagging">Tagging</h4>
10321032
<code style="white-space: nowrap">-----BEGIN TAG-----</code> and <code style="white-space: nowrap">-----END TAG-----</code>
10331033
markers.</p>
10341034

1035+
<h4 id="show">Show signature</h4>
1036+
1037+
<p>To check whether a file has been signed and with which certificate, use the show command to list details about any signature present on the file.</p>
1038+
1039+
<pre>
1040+
jsign show foo.exe
1041+
Signature 0
1042+
Digest Algorithm: SHA256
1043+
Digest Value: c481bb3892d066ffacba0650adaa4c252580b776b1dd6026cf4a8bea6c813939
1044+
Is Timestamped? false
1045+
Certificate
1046+
Subject: CN=net.jsign.signing-cert
1047+
Issuer: CN=net.jsign.issuing-cert
1048+
Not Before: Fri Dec 03 14:34:46 CST 2021
1049+
Not After: Wed May 24 14:34:46 CST 2119
1050+
Expired: false
1051+
Serial: 148957645726085760686199624248870688956
1052+
</pre>
1053+
10351054
<h3 id="api">API</h3>
10361055

10371056
<p>Jsign also provides a simple API for signing files and can be embedded in another application.</p>

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ private Map<String, Options> getOptions() {
146146

147147
map.put("remove", options);
148148

149+
options = new Options();
150+
151+
map.put("show", options);
152+
149153
options = new Options();
150154
options.addOption(Option.builder().hasArg().longOpt(PARAM_VALUE).argName("VALUE").desc(" The value of the unsigned attribute").build());
151155

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,9 @@ public void execute(File file) throws SignerException {
313313
case "remove":
314314
remove(file);
315315
break;
316+
case "show":
317+
show(file);
318+
break;
316319
case "tag":
317320
tag(file);
318321
break;
@@ -476,6 +479,32 @@ private void attach(Signable signable, File detachedSignature) throws IOExceptio
476479
// todo warn if the hashes don't match
477480
}
478481

482+
private void printSignatures(Signable signable) throws IOException {
483+
List<CMSSignedData> signatures = signable.getSignatures();
484+
for (int i = 0; i < signatures.size(); i++) {
485+
CMSSignedData signature = signatures.get(i);
486+
SignerInformation signerInformation = signature.getSignerInfos().iterator().next();
487+
488+
String digestAlgorithmName = new DefaultAlgorithmNameFinder().getAlgorithmName(signerInformation.getDigestAlgorithmID());
489+
SignerId signerId = signerInformation.getSID();
490+
X509CertificateHolder cert = (X509CertificateHolder) signature.getCertificates().getMatches(signerId).iterator().next();
491+
492+
byte[] digest = signable.computeDigest(DigestAlgorithm.of(signerInformation.getDigestAlgorithmID().getAlgorithm()));
493+
494+
System.out.println("Signature " + i);
495+
System.out.println(" Digest Algorithm: " + digestAlgorithmName);
496+
System.out.println(" Digest Value: " + Hex.toHexString(digest));
497+
System.out.println(" Is Timestamped? " + SignatureUtils.isTimestamped(signature));
498+
System.out.println(" Certificate");
499+
System.out.println(" Subject: " + cert.getSubject());
500+
System.out.println(" Issuer: " + cert.getIssuer());
501+
System.out.println(" Not Before: " + cert.getNotBefore());
502+
System.out.println(" Not After: " + cert.getNotAfter());
503+
System.out.println(" Expired: " + cert.getNotAfter().before(new Date()));
504+
System.out.println(" Serial: " + cert.getSerialNumber());
505+
}
506+
}
507+
479508
private void detach(Signable signable, File detachedSignature) throws IOException {
480509
CMSSignedData signedData = signable.getSignatures().get(0);
481510
byte[] content = signedData.toASN1Structure().getEncoded("DER");
@@ -548,6 +577,20 @@ private void remove(File file) throws SignerException {
548577
}
549578
}
550579

580+
private void show(File file) throws SignerException {
581+
if (!file.exists()) {
582+
throw new SignerException("Couldn't find " + file);
583+
}
584+
585+
try (Signable signable = Signable.of(file)) {
586+
printSignatures(signable);
587+
} catch (UnsupportedOperationException | IllegalArgumentException e) {
588+
throw new SignerException(e.getMessage(), e);
589+
} catch (Exception e) {
590+
throw new SignerException("Couldn't show the signatures of" + file, e);
591+
}
592+
}
593+
551594
private void tag(File file) throws SignerException {
552595
if (!file.exists()) {
553596
throw new SignerException("Couldn't find " + file);

0 commit comments

Comments
 (0)