diff --git a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/rim/BaseReferenceManifest.java b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/rim/BaseReferenceManifest.java index 067e07a5..c5da6001 100644 --- a/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/rim/BaseReferenceManifest.java +++ b/HIRS_AttestationCA/src/main/java/hirs/attestationca/persist/entity/userdefined/rim/BaseReferenceManifest.java @@ -116,10 +116,14 @@ public class BaseReferenceManifest extends ReferenceManifest { // begin parsing valid swid tag if (document != null) { - softwareIdentity = (Element) document.getElementsByTagName(SwidTagConstants.SOFTWARE_IDENTITY).item(0); - entity = (Element) document.getElementsByTagName(SwidTagConstants.ENTITY).item(0); - link = (Element) document.getElementsByTagName(SwidTagConstants.LINK).item(0); - meta = (Element) document.getElementsByTagName(SwidTagConstants.META).item(0); + softwareIdentity = (Element) document.getElementsByTagNameNS( + SwidTagConstants.SWIDTAG_NAMESPACE, SwidTagConstants.SOFTWARE_IDENTITY).item(0); + entity = (Element) document.getElementsByTagNameNS( + SwidTagConstants.SWIDTAG_NAMESPACE, SwidTagConstants.ENTITY).item(0); + link = (Element) document.getElementsByTagNameNS( + SwidTagConstants.SWIDTAG_NAMESPACE, SwidTagConstants.LINK).item(0); + meta = (Element) document.getElementsByTagNameNS( + SwidTagConstants.SWIDTAG_NAMESPACE, SwidTagConstants.META).item(0); setTagId(softwareIdentity.getAttribute(SwidTagConstants.TAGID)); this.swidName = softwareIdentity.getAttribute(SwidTagConstants.NAME); this.swidCorpus = Boolean.parseBoolean(softwareIdentity.getAttribute(SwidTagConstants.CORPUS)) ? 1 : 0; @@ -217,7 +221,8 @@ public class BaseReferenceManifest extends ReferenceManifest { private Element getDirectoryTag(final ByteArrayInputStream byteArrayInputStream) { Document document = unmarshallSwidTag(byteArrayInputStream); Element softwareIdentity = - (Element) document.getElementsByTagName("SoftwareIdentity").item(0); + (Element) document.getElementsByTagNameNS( + SwidTagConstants.SWIDTAG_NAMESPACE,"SoftwareIdentity").item(0); if (softwareIdentity != null) { Element directory = (Element) document.getElementsByTagName("Directory").item(0); diff --git a/HIRS_Utils/src/main/java/hirs/utils/rim/ReferenceManifestValidator.java b/HIRS_Utils/src/main/java/hirs/utils/rim/ReferenceManifestValidator.java index 95a42d1f..82a16d8d 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/rim/ReferenceManifestValidator.java +++ b/HIRS_Utils/src/main/java/hirs/utils/rim/ReferenceManifestValidator.java @@ -252,7 +252,8 @@ public class ReferenceManifestValidator { * @return true if both the file element and signature are valid, false otherwise */ public boolean validateRim(String signingCertPath) { - Element fileElement = (Element) rim.getElementsByTagName("File").item(0); + Element fileElement = (Element) rim.getElementsByTagNameNS( + SwidTagConstants.SWIDTAG_NAMESPACE, "File").item(0); X509Certificate signingCert = parseCertificatesFromPem(signingCertPath).get(0); if (signingCert == null) { return failWithError("Unable to parse the signing cert from " + signingCertPath); diff --git a/HIRS_Utils/src/main/java/hirs/utils/swid/SwidTagConstants.java b/HIRS_Utils/src/main/java/hirs/utils/swid/SwidTagConstants.java index 0f6ebdd1..a74e2e49 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/swid/SwidTagConstants.java +++ b/HIRS_Utils/src/main/java/hirs/utils/swid/SwidTagConstants.java @@ -22,6 +22,7 @@ public class SwidTagConstants { public static final String SCHEMA_PACKAGE = "hirs.swid.xjc"; public static final String SCHEMA_LANGUAGE = XMLConstants.W3C_XML_SCHEMA_NS_URI; public static final String SCHEMA_URL = "swid_schema.xsd"; + public static final String SWIDTAG_NAMESPACE = "http://standards.iso.org/iso/19770/-2/2015/schema.xsd"; public static final String SOFTWARE_IDENTITY = "SoftwareIdentity"; public static final String ENTITY = "Entity"; diff --git a/HIRS_Utils/src/main/java/hirs/utils/xjc/ObjectFactory.java b/HIRS_Utils/src/main/java/hirs/utils/xjc/ObjectFactory.java index 598d2f0b..b2a8d0d9 100644 --- a/HIRS_Utils/src/main/java/hirs/utils/xjc/ObjectFactory.java +++ b/HIRS_Utils/src/main/java/hirs/utils/xjc/ObjectFactory.java @@ -66,6 +66,8 @@ public class ObjectFactory { private final static QName _SoftwareIdentityLink_QNAME = new QName("http://standards.iso.org/iso/19770/-2/2015/schema.xsd", "Link"); private final static QName _SoftwareIdentityEvidence_QNAME = new QName("http://standards.iso.org/iso/19770/-2/2015/schema.xsd", "Evidence"); private final static QName _SoftwareIdentityPayload_QNAME = new QName("http://standards.iso.org/iso/19770/-2/2015/schema.xsd", "Payload"); + private final static QName _PayloadDirectory_QNAME = new QName("http://standards.iso.org/iso/19770/-2/2015/schema.xsd", "Directory"); + private final static QName _DirectoryFile_QNAME = new QName("http://standards.iso.org/iso/19770/-2/2015/schema.xsd", "File"); private final static QName _SoftwareIdentityEntity_QNAME = new QName("http://standards.iso.org/iso/19770/-2/2015/schema.xsd", "Entity"); private final static QName _SoftwareIdentityMeta_QNAME = new QName("http://standards.iso.org/iso/19770/-2/2015/schema.xsd", "Meta"); private final static QName _SignatureMethodTypeHMACOutputLength_QNAME = new QName("http://www.w3.org/2000/09/xmldsig#", "HMACOutputLength"); @@ -666,6 +668,24 @@ public class ObjectFactory { return new JAXBElement(_SoftwareIdentityPayload_QNAME, ResourceCollection.class, SoftwareIdentity.class, value); } + /** + * Create an instance of {@link JAXBElement }{@code <}{@link FilesystemItem }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://standards.iso.org/iso/19770/-2/2015/schema.xsd", name = "Directory", scope = ResourceCollection.class) + public JAXBElement createPayloadDirectory(FilesystemItem value) { + return new JAXBElement(_PayloadDirectory_QNAME, FilesystemItem.class, ResourceCollection.class, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link FilesystemItem }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://standards.iso.org/iso/19770/-2/2015/schema.xsd", name = "File", scope = ResourceCollection.class) + public JAXBElement createDirectoryFile(FilesystemItem value) { + return new JAXBElement(_DirectoryFile_QNAME, FilesystemItem.class, ResourceCollection.class, value); + } + /** * Create an instance of {@link JAXBElement }{@code <}{@link Entity }{@code >}} * diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagConstants.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagConstants.java index 480320ff..b7e5ff94 100644 --- a/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagConstants.java +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagConstants.java @@ -28,6 +28,7 @@ public class SwidTagConstants { public static final String SCHEMA_PACKAGE = "hirs.utils.xjc"; public static final String SCHEMA_LANGUAGE = XMLConstants.W3C_XML_SCHEMA_NS_URI; public static final String SCHEMA_URL = "swid_schema.xsd"; + public static final String SWIDTAG_NAMESPACE = "http://standards.iso.org/iso/19770/-2/2015/schema.xsd"; public static final String SOFTWARE_IDENTITY = "SoftwareIdentity"; public static final String ENTITY = "Entity"; diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java index aa9b23d2..43e4d7f8 100644 --- a/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java @@ -3,22 +3,24 @@ package hirs.swid; import hirs.swid.utils.HashSwid; import hirs.utils.xjc.Directory; import hirs.utils.xjc.Entity; +import hirs.utils.xjc.FilesystemItem; import hirs.utils.xjc.Link; import hirs.utils.xjc.ObjectFactory; import hirs.utils.xjc.ResourceCollection; import hirs.utils.xjc.SoftwareIdentity; import hirs.utils.xjc.SoftwareMeta; +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.Node; import javax.json.Json; import javax.json.JsonException; import javax.json.JsonObject; import javax.json.JsonReader; -import jakarta.xml.bind.JAXBContext; -import jakarta.xml.bind.JAXBElement; -import jakarta.xml.bind.JAXBException; -import jakarta.xml.bind.Marshaller; import javax.xml.crypto.MarshalException; import javax.xml.crypto.XMLStructure; import javax.xml.crypto.dom.DOMStructure; @@ -41,6 +43,7 @@ import javax.xml.crypto.dsig.keyinfo.X509Data; import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec; import javax.xml.crypto.dsig.spec.TransformParameterSpec; import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; @@ -91,6 +94,8 @@ public class SwidTagGateway { private String timestampFormat; private String timestampArgument; private String errorRequiredFields; + private DocumentBuilderFactory dbf; + private DocumentBuilder builder; /** * Default constructor initializes jaxbcontext, marshaller, and unmarshaller @@ -107,8 +112,15 @@ public class SwidTagGateway { timestampFormat = ""; timestampArgument = ""; errorRequiredFields = ""; + dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + builder = dbf.newDocumentBuilder(); } catch (JAXBException e) { System.out.println("Error initializing jaxbcontext: " + e.getMessage()); + } catch (ParserConfigurationException e) { + System.out.println("Error instantiating Document object for parsing swidtag: " + + e.getMessage()); + System.exit(1); } } @@ -198,49 +210,62 @@ public class SwidTagGateway { * @param filename */ public void generateSwidTag(final String filename) { - SoftwareIdentity swidTag = null; + Document swidtag = builder.newDocument(); + SoftwareIdentity softwareIdentity = null; try { InputStream is = new FileInputStream(attributesFile); JsonReader reader = Json.createReader(is); JsonObject configProperties = reader.readObject(); reader.close(); //SoftwareIdentity - swidTag = createSwidTag( + softwareIdentity = createSwidTag( configProperties.getJsonObject(SwidTagConstants.SOFTWARE_IDENTITY)); //Entity JAXBElement entity = objectFactory.createSoftwareIdentityEntity( createEntity(configProperties.getJsonObject(SwidTagConstants.ENTITY))); - swidTag.getEntityOrEvidenceOrLink().add(entity); + softwareIdentity.getEntityOrEvidenceOrLink().add(entity); //Link JAXBElement link = objectFactory.createSoftwareIdentityLink( createLink(configProperties.getJsonObject(SwidTagConstants.LINK))); - swidTag.getEntityOrEvidenceOrLink().add(link); + softwareIdentity.getEntityOrEvidenceOrLink().add(link); //Meta JAXBElement meta = objectFactory.createSoftwareIdentityMeta( createSoftwareMeta(configProperties.getJsonObject(SwidTagConstants.META))); - swidTag.getEntityOrEvidenceOrLink().add(meta); - //Payload - ResourceCollection payload = createPayload( - configProperties.getJsonObject(SwidTagConstants.PAYLOAD)); - //Directory - Directory directory = createDirectory( - configProperties.getJsonObject(SwidTagConstants.PAYLOAD) - .getJsonObject(SwidTagConstants.DIRECTORY)); + softwareIdentity.getEntityOrEvidenceOrLink().add(meta); + + swidtag = convertToDocument(objectFactory.createSoftwareIdentity(softwareIdentity)); + Element rootElement = swidtag.getDocumentElement(); + //File hirs.utils.xjc.File file = createFile( configProperties.getJsonObject(SwidTagConstants.PAYLOAD) .getJsonObject(SwidTagConstants.DIRECTORY) .getJsonObject(SwidTagConstants.FILE)); - //Nest File in Directory in Payload - directory.getDirectoryOrFile().add(file); - payload.getDirectoryOrFileOrProcess().add(directory); + JAXBElement jaxbFile = objectFactory.createDirectoryFile(file); + Document fileDoc = convertToDocument(jaxbFile); + //Directory + Directory directory = createDirectory( + configProperties.getJsonObject(SwidTagConstants.PAYLOAD) + .getJsonObject(SwidTagConstants.DIRECTORY)); + JAXBElement jaxbDirectory = objectFactory.createPayloadDirectory(directory); + Document dirDoc = convertToDocument(jaxbDirectory); + Node fileNode = dirDoc.importNode(fileDoc.getDocumentElement(), true); + dirDoc.getDocumentElement().appendChild(fileNode); + //Payload + ResourceCollection payload = createPayload( + configProperties.getJsonObject(SwidTagConstants.PAYLOAD)); JAXBElement jaxbPayload = objectFactory.createSoftwareIdentityPayload(payload); - swidTag.getEntityOrEvidenceOrLink().add(jaxbPayload); + Document payloadDoc = convertToDocument(jaxbPayload); + Node dirNode = payloadDoc.importNode(dirDoc.getDocumentElement(), true); + payloadDoc.getDocumentElement().appendChild(dirNode); + + Node payloadNode = swidtag.importNode(payloadDoc.getDocumentElement(), true); + rootElement.appendChild(payloadNode); + //Signature if (errorRequiredFields.isEmpty()) { - Document signedSoftwareIdentity = signXMLDocument( - objectFactory.createSoftwareIdentity(swidTag)); + Document signedSoftwareIdentity = signXMLDocument(swidtag); writeSwidTagFile(signedSoftwareIdentity, filename); } else { System.out.println("The following fields cannot be empty or null: " @@ -545,23 +570,31 @@ public class SwidTagGateway { } /** - * This method signs a SoftwareIdentity with an xmldsig in compatibility mode. - * Current assumptions: digest method SHA256, signature method SHA256, enveloped signature + * This method converts a JAXBElement object generated from the hirs.utils.xjc package into + * a Document object. + * + * @param element to convert + * @return a Document object */ - private Document signXMLDocument(JAXBElement swidTag) { + private Document convertToDocument(JAXBElement element) { Document doc = null; try { - doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); - marshaller.marshal(swidTag, doc); - } catch (ParserConfigurationException e) { - System.out.println("Error instantiating Document object for parsing swidtag: " - + e.getMessage()); - System.exit(1); + doc = builder.newDocument(); + marshaller.marshal(element, doc); } catch (JAXBException e) { System.out.println("Error while marshaling swidtag: " + e.getMessage()); e.printStackTrace(); System.exit(1); } + + return doc; + } + + /** + * This method signs a SoftwareIdentity with an xmldsig in compatibility mode. + * Current assumptions: digest method SHA256, signature method SHA256, enveloped signature + */ + private Document signXMLDocument(Document doc) { XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM"); List xmlObjectList = null; String signatureId = null;