Skip to content

Commit 134cdea

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 5d16e80 commit 134cdea

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

docs/index.html

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ <h3 id="cli">Command Line Tool</h3>
131131
<li><a href="#timestamp-options">timestamp</a></li>
132132
<li><a href="#extract-options">extract</a></li>
133133
<li>remove</li>
134+
<li><a href="#show">show</a></li>
134135
<li><a href="#tag-options">tag</a></li>
135136
</ul>
136137

@@ -368,6 +369,27 @@ <h4 id="extract-options">extract</h4>
368369

369370
<br>
370371

372+
<h4 id="show">Show signature</h4>
373+
374+
<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>
375+
376+
<pre>
377+
jsign show foo.exe
378+
Signature 0
379+
Digest Algorithm: SHA256
380+
Digest Value: c481bb3892d066ffacba0650adaa4c252580b776b1dd6026cf4a8bea6c813939
381+
Is Timestamped? false
382+
Certificate
383+
Subject: CN=net.jsign.signing-cert
384+
Issuer: CN=net.jsign.issuing-cert
385+
Not Before: Fri Dec 03 14:34:46 CST 2021
386+
Not After: Wed May 24 14:34:46 CST 2119
387+
Expired: false
388+
Serial: 148957645726085760686199624248870688956
389+
</pre>
390+
391+
<br>
392+
371393
<h4 id="tag-options">tag</h4>
372394

373395
<dl>
@@ -1040,7 +1062,6 @@ <h3 id="github-actions">GitHub Actions</h3>
10401062
${{ github.workspace }}/dist/application.exe
10411063
</pre>
10421064

1043-
10441065
<h3 id="api">API</h3>
10451066

10461067
<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
@@ -147,6 +147,10 @@ private Map<String, Options> getOptions() {
147147

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

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

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ public void execute(File file) throws SignerException {
333333
case "remove":
334334
remove(file);
335335
break;
336+
case "show":
337+
show(file);
338+
break;
336339
case "tag":
337340
tag(file);
338341
break;
@@ -496,6 +499,32 @@ private void attach(Signable signable, File detachedSignature) throws IOExceptio
496499
// todo warn if the hashes don't match
497500
}
498501

502+
private void printSignatures(Signable signable) throws IOException {
503+
List<CMSSignedData> signatures = signable.getSignatures();
504+
for (int i = 0; i < signatures.size(); i++) {
505+
CMSSignedData signature = signatures.get(i);
506+
SignerInformation signerInformation = signature.getSignerInfos().iterator().next();
507+
508+
String digestAlgorithmName = new DefaultAlgorithmNameFinder().getAlgorithmName(signerInformation.getDigestAlgorithmID());
509+
SignerId signerId = signerInformation.getSID();
510+
X509CertificateHolder cert = (X509CertificateHolder) signature.getCertificates().getMatches(signerId).iterator().next();
511+
512+
byte[] digest = signable.computeDigest(DigestAlgorithm.of(signerInformation.getDigestAlgorithmID().getAlgorithm()));
513+
514+
System.out.println("Signature " + i);
515+
System.out.println(" Digest Algorithm: " + digestAlgorithmName);
516+
System.out.println(" Digest Value: " + Hex.toHexString(digest));
517+
System.out.println(" Is Timestamped? " + SignatureUtils.isTimestamped(signature));
518+
System.out.println(" Certificate");
519+
System.out.println(" Subject: " + cert.getSubject());
520+
System.out.println(" Issuer: " + cert.getIssuer());
521+
System.out.println(" Not Before: " + cert.getNotBefore());
522+
System.out.println(" Not After: " + cert.getNotAfter());
523+
System.out.println(" Expired: " + cert.getNotAfter().before(new Date()));
524+
System.out.println(" Serial: " + cert.getSerialNumber());
525+
}
526+
}
527+
499528
private void detach(Signable signable, File detachedSignature) throws IOException {
500529
List<CMSSignedData> signatures = signable.getSignatures();
501530

@@ -576,6 +605,20 @@ private void remove(File file) throws SignerException {
576605
}
577606
}
578607

608+
private void show(File file) throws SignerException {
609+
if (!file.exists()) {
610+
throw new SignerException("Couldn't find " + file);
611+
}
612+
613+
try (Signable signable = Signable.of(file)) {
614+
printSignatures(signable);
615+
} catch (UnsupportedOperationException | IllegalArgumentException e) {
616+
throw new SignerException(e.getMessage(), e);
617+
} catch (Exception e) {
618+
throw new SignerException("Couldn't show the signatures of" + file, e);
619+
}
620+
}
621+
579622
private void tag(File file) throws SignerException {
580623
if (!file.exists()) {
581624
throw new SignerException("Couldn't find " + file);

0 commit comments

Comments
 (0)