Skip to content

Instantly share code, notes, and snippets.

@ecki
Last active July 17, 2020 18:44
Show Gist options
  • Save ecki/42aaa3a8621344c1cd0034c440a73400 to your computer and use it in GitHub Desktop.
Save ecki/42aaa3a8621344c1cd0034c440a73400 to your computer and use it in GitHub Desktop.
/*
* JarTimestampChecker.java
*
* created at 2020-07-17 by Bernd Eckenfels <b.eckenfels@seeburger.de>
*
* Copyright (c) SEEBURGER AG, Germany. All Rights Reserved.
*
* This test code is Licensed under the ASL2.0
*/
package net.eckenfels.test.jartest;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.cert.CertificateException;
import java.util.Iterator;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.cms.Attribute;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.SignerId;
import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.cms.SignerInformationVerifier;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.tsp.TSPException;
import org.bouncycastle.tsp.TimeStampToken;
import org.bouncycastle.tsp.TimeStampTokenInfo;
import org.bouncycastle.util.Selector;
import org.bouncycastle.util.Store;
import sun.security.tools.jarsigner.Main;
public class JarTimestampChecker
{
static final Selector<X509CertificateHolder> ALL = new Selector<X509CertificateHolder>() {
public Object clone() { return this; }
@Override
public boolean match(X509CertificateHolder obj) { return true; }};
public static void main(String[] args) throws CMSException, TSPException, IOException, OperatorCreationException, CertificateException
{
/*String f = new File("commons-configuration2.jar").getAbsolutePath();
String[] a = new String[] {"-verify", "-verbose", "-debug", f};
Main js = new Main();
js.run(a);*/
// the signature file from .jar!META-INF/CA.RSA
String test = "SECTIGO_.RSA";
//String test = "COMODO_C.RSA";
File sigFile = new File(test).getAbsoluteFile();
System.out.println("TS validating sig file: " + sigFile);
CMSSignedData cms;
try (InputStream in = new FileInputStream(sigFile);)
{
cms = new CMSSignedData(in);
}
SignerInformationStore si = cms.getSignerInfos();
Store<X509CertificateHolder> certs = cms.getCertificates();
System.out.println("Signature has " + certs.getMatches(ALL).size() + " certs.");
System.out.println("Has " + si.getSigners().size() + " signers");
// extract timestamp
Attribute attribute = si.getSigners().iterator().next().getUnsignedAttributes().get(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken);
System.out.println("Has " + attribute.getAttributeValues().length + " timestamps"); // ?
ASN1Object obj = (ASN1Object) attribute.getAttrValues().getObjectAt(0);
CMSSignedData signedTSTData = new CMSSignedData(obj.getEncoded());
TimeStampToken ts = new TimeStampToken(signedTSTData);
TimeStampTokenInfo tsi = ts.getTimeStampInfo();
SignerId signerId = ts.getSID();
System.out.println("TS Signer issuer: " + signerId.getIssuer());
TimeStampTokenInfo tstInfo = ts.getTimeStampInfo();
System.out.println("TS generated: " + tstInfo.getGenTime());
// check against all timestamp certs
Iterator<X509CertificateHolder> it = ts.getCertificates().getMatches(ALL).iterator();
while(it.hasNext()) {
X509CertificateHolder certHolder = it.next();
System.out.println("Checking " + certHolder.getSubject() + " <- " + certHolder.getIssuer());
java.security.cert.X509Certificate tstCert = new JcaX509CertificateConverter().getCertificate(certHolder);
SignerInformationVerifier siv = new JcaSimpleSignerInfoVerifierBuilder().build(tstCert);
try { ts.validate(siv); System.out.println("ok");} catch (Exception e ) { System.err.print("Failed "); e.printStackTrace(); }
}
}
}
TS validating sig file: COMODO_C.RSA
Signature has 3 certs.
Has 1 signers
Has 1 timestamps
TS Signer issuer: C=US,ST=UT,L=Salt Lake City,O=The USERTRUST Network,OU=http://www.usertrust.com,CN=UTN-USERFirst-Object
TS generated: Mon Mar 11 12:16:10 CET 2019
Checking C=GB,ST=Greater Manchester,L=Salford,O=COMODO CA Limited,CN=COMODO SHA-256 Time Stamping Signer <- C=US,ST=UT,L=Salt Lake City,O=The USERTRUST Network,OU=http://www.usertrust.com,CN=UTN-USERFirst-Object
ok
The signer certificate will expire on 2023-06-04.
The timestamp will expire on 2030-08-02.
TS validating sig file: SECTIGO2.RSA
Signature has 3 certs.
Has 1 signers
Has 1 timestamps
TS Signer issuer: C=GB,ST=Greater Manchester,L=Salford,O=Sectigo Limited,CN=Sectigo RSA Time Stamping CA
TS generated: Mon Jul 13 16:10:10 CEST 2020
Checking C=GB,ST=Greater Manchester,L=Salford,O=Sectigo Limited,CN=Sectigo RSA Time Stamping Signer #1 <- C=GB,ST=Greater Manchester,L=Salford,O=Sectigo Limited,CN=Sectigo RSA Time Stamping CA
ok
Checking C=GB,ST=Greater Manchester,L=Salford,O=Sectigo Limited,CN=Sectigo RSA Time Stamping CA <- C=US,ST=New Jersey,L=Jersey City,O=The USERTRUST Network,CN=USERTrust RSA Certification Authority
Failed org.bouncycastle.tsp.TSPValidationException: certificate hash does not match certID hash.
at org.bouncycastle.tsp.TimeStampToken.validate(Unknown Source)
at net.eckenfels.test.jartest.JarTimestampChecker.main(JarTimestampChecker.java:88)
TS validating sig file: SECTIGO_.RSA
Signature has 3 certs.
Has 1 signers
Has 1 timestamps
TS Signer: C=GB,ST=Greater Manchester,L=Salford,O=Sectigo Limited,CN=Sectigo RSA Time Stamping CA
TS generated: Fri Jul 17 15:43:20 CEST 2020
Checking C=GB,ST=Greater Manchester,L=Salford,O=Sectigo Limited,CN=Sectigo RSA Time Stamping Signer #1 <- C=GB,ST=Greater Manchester,L=Salford,O=Sectigo Limited,CN=Sectigo RSA Time Stamping CA
Failed org.bouncycastle.tsp.TSPValidationException: signature not created by certificate.
at org.bouncycastle.tsp.TimeStampToken.validate(Unknown Source)
at net.eckenfels.test.jartest.JarTimestampChecker.main(JarTimestampChecker.java:87)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment