Add support for timestamping a signature

This commit is contained in:
chubtub 2022-09-08 20:35:42 -04:00
parent 224c14d943
commit dffcbf59bd

View File

@ -9,6 +9,7 @@ import hirs.swid.xjc.ResourceCollection;
import hirs.swid.xjc.SoftwareIdentity;
import hirs.swid.xjc.SoftwareMeta;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.json.Json;
import javax.json.JsonException;
@ -20,11 +21,15 @@ import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.crypto.MarshalException;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dom.DOMStructure;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.SignatureProperties;
import javax.xml.crypto.dsig.SignatureProperty;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLObject;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.crypto.dsig.XMLSignatureFactory;
@ -59,6 +64,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -523,8 +529,11 @@ public class SwidTagGateway {
private Document signXMLDocument(JAXBElement<SoftwareIdentity> swidTag) throws Exception {
Document doc = null;
try {
doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
marshaller.marshal(swidTag, doc);
XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
Reference reference = sigFactory.newReference(
Reference documentRef = sigFactory.newReference(
"",
sigFactory.newDigestMethod(DigestMethod.SHA256, null),
Collections.singletonList(sigFactory.newTransform(Transform.ENVELOPED,
@ -532,12 +541,37 @@ public class SwidTagGateway {
null,
null
);
//Create TimeStamp element
Element timeStampElement = doc.createElement("TimeStamp");
/*
This line is for demonstration purposes only!
Must be replaced with a call to a trusted timestamp authority (TSA).
*/
timeStampElement.setAttribute("TimeStamp", LocalDateTime.now().toString());
DOMStructure timestampObject = new DOMStructure(timeStampElement);
SignatureProperty signatureProperty = sigFactory.newSignatureProperty(
Collections.singletonList(timestampObject), "RimSignature", "TST"
);
SignatureProperties signatureProperties = sigFactory.newSignatureProperties(
Collections.singletonList(signatureProperty), null);
XMLObject xmlObject = sigFactory.newXMLObject(
Collections.singletonList(signatureProperties), null,null,null);
Reference timestampRef = sigFactory.newReference(
"#TST",
sigFactory.newDigestMethod(DigestMethod.SHA256, null)
);
List<Reference> refList = new ArrayList<Reference>();
refList.add(documentRef);
refList.add(timestampRef);
SignedInfo signedInfo = sigFactory.newSignedInfo(
sigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null),
sigFactory.newSignatureMethod(SwidTagConstants.SIGNATURE_ALGORITHM_RSA_SHA256,
null),
Collections.singletonList(reference)
refList
);
List<XMLStructure> keyInfoElements = new ArrayList<XMLStructure>();
@ -565,10 +599,14 @@ public class SwidTagGateway {
}
KeyInfo keyinfo = kiFactory.newKeyInfo(keyInfoElements);
doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
marshaller.marshal(swidTag, doc);
DOMSignContext context = new DOMSignContext(privateKey, doc.getDocumentElement());
XMLSignature signature = sigFactory.newXMLSignature(signedInfo, keyinfo);
XMLSignature signature = sigFactory.newXMLSignature(
signedInfo,
keyinfo,
Collections.singletonList(xmlObject),
"RimSignature",
null
);
signature.sign(context);
} catch (FileNotFoundException e) {
System.out.println("Keystore not found! " + e.getMessage());