mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-19 21:17:59 +00:00
* Support reading conf settings from a json file * Add optional RIM attributes * Add xml signature element * New commandline arguments for attributes conf file and privatekey or cert specification * Add fields to satisfy NIST checks * Print generated base rim contents to console also
This commit is contained in:
parent
9a835d8923
commit
1f52dd3c27
@ -7,4 +7,4 @@ include 'TPM_Utils',
|
||||
'HIRS_AttestationCA',
|
||||
'HIRS_AttestationCAPortal',
|
||||
'tpm_module',
|
||||
'tools'
|
||||
'tools/tcg_rim_tool'
|
||||
|
@ -6,13 +6,17 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testCompile 'org.testng:testng:6.8.8'
|
||||
compile libs.minimal_json
|
||||
testCompile libs.testng
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes("Main-Class": "hirs.swid.Main")
|
||||
attributes("Main-Class": "hirs.swid.Main",
|
||||
"Class-Path": configurations.runtime.files.collect { "lib/$it.name" }.join(' ')
|
||||
)
|
||||
}
|
||||
from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {}
|
||||
}
|
||||
|
||||
uploadArchives {
|
||||
|
BIN
tools/tcg_rim_tool/keystore.jks
Normal file
BIN
tools/tcg_rim_tool/keystore.jks
Normal file
Binary file not shown.
41
tools/tcg_rim_tool/rim_fields.json
Normal file
41
tools/tcg_rim_tool/rim_fields.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"SoftwareIdentity": {
|
||||
"name": "TCG RIM example",
|
||||
"version": "0.1",
|
||||
"tagId": "hirs.swid.SwidTags.example",
|
||||
"tagVersion": "1",
|
||||
"patch": false
|
||||
},
|
||||
"Entity": {
|
||||
"name": "HIRS",
|
||||
"role": "softwareCreator,tagCreator",
|
||||
"regid": "www.example.com",
|
||||
"thumbprint": ""
|
||||
},
|
||||
"Link": {
|
||||
"href": "https://Example.com/support/ProductA/firmware/installfiles",
|
||||
"rel": "installationmedia"
|
||||
},
|
||||
"Meta": {
|
||||
"colloquialVersion": "",
|
||||
"edition": "",
|
||||
"product": "",
|
||||
"revision": "",
|
||||
"platformManufacturerStr": "Example.com",
|
||||
"platformManufacturerId": "00201234",
|
||||
"platformModel": "ProductA",
|
||||
"bindingSpec": "IOT RIM",
|
||||
"bindingSpecVersion": "1.2",
|
||||
"rimLinkHash": "88f21d8e44d4271149297404df91caf207130bfa116582408abd04ede6db7f51"
|
||||
},
|
||||
"Payload": {
|
||||
"Directory": {
|
||||
"name": "iotBase",
|
||||
"File": {
|
||||
"name": "Example.com.iotBase.bin",
|
||||
"size": "15400",
|
||||
"hash": "688e293e3ccb522f6cf8a027c9ade7960f84bd0bf3a0b99812bc1fa498a2db8d"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -14,31 +14,40 @@ public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Commander commander = new Commander(args);
|
||||
SwidTagGateway gateway = new SwidTagGateway();
|
||||
|
||||
if (commander.hasArguments()) {
|
||||
// we have arguments to work with
|
||||
if (commander.isAttributesGiven()) {
|
||||
gateway.setAttributesFile(commander.getAttributesFile());
|
||||
}
|
||||
/* if (commander.isKeystoreGiven()) {
|
||||
|
||||
}
|
||||
*/
|
||||
if (commander.create()) {
|
||||
String keystore = commander.getKeystore();
|
||||
if (!keystore.isEmpty()) {
|
||||
//set keystore for gateway if given
|
||||
}
|
||||
// parsing the arguments detected a create parameter (-c)
|
||||
(new SwidTagGateway()).generateSwidTag(commander.getCreateInFile(),
|
||||
commander.getCreateOutFile(), commander.getHashAlg());
|
||||
} else if (commander.validate()) {
|
||||
gateway.generateSwidTag(commander.getCreateOutFile());
|
||||
}
|
||||
if (commander.validate()) {
|
||||
// parsing the arguments detected a validation parameter (-v)
|
||||
try {
|
||||
(new SwidTagGateway()).validateSwidTag(commander.getValidateFile());
|
||||
gateway.validateSwidTag(commander.getValidateFile());
|
||||
} catch (IOException e) {
|
||||
System.out.println("Unable to validate file: " + e.getMessage());
|
||||
}
|
||||
} else if (commander.parse()) {
|
||||
}
|
||||
if (commander.parse()) {
|
||||
try {
|
||||
(new SwidTagGateway()).parsePayload(commander.getParseFile());
|
||||
gateway.parsePayload(commander.getParseFile());
|
||||
} catch (IOException e) {
|
||||
System.out.println("Unable to parse file: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// development stage in which no valid arguments were given
|
||||
// therefore generate a mock tag file
|
||||
(new SwidTagGateway()).generateSwidTag();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package hirs.swid;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* This class contains the String constants that are referenced by the gateway
|
||||
@ -10,6 +12,14 @@ import javax.xml.XMLConstants;
|
||||
*/
|
||||
public class SwidTagConstants {
|
||||
|
||||
public static final String DEFAULT_KEYSTORE_PATH = "keystore.jks";
|
||||
public static final String DEFAULT_KEYSTORE_PASSWORD = "password";
|
||||
public static final String DEFAULT_PRIVATE_KEY_ALIAS = "selfsigned";
|
||||
public static final String DEFAULT_ATTRIBUTES_FILE = "/etc/hirs/rim_fields.json";
|
||||
public static final String DEFAULT_ENGLISH = "en";
|
||||
|
||||
public static final String SIGNATURE_ALGORITHM_RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
|
||||
|
||||
public static final String SCHEMA_STATEMENT = "ISO/IEC 19770-2:2015 Schema (XSD 1.0) "
|
||||
+ "- September 2015, see http://standards.iso.org/iso/19770/-2/2015/schema.xsd";
|
||||
public static final String SCHEMA_PACKAGE = "hirs.swid.xjc";
|
||||
@ -19,6 +29,125 @@ public class SwidTagConstants {
|
||||
public static final String HIRS_SWIDTAG_HEADERS = "hirsSwidTagHeader.properties";
|
||||
public static final String EXAMPLE_PROPERTIES = "swidExample.properties";
|
||||
|
||||
public static final String SOFTWARE_IDENTITY = "SoftwareIdentity";
|
||||
public static final String ENTITY = "Entity";
|
||||
public static final String LINK = "Link";
|
||||
public static final String META = "Meta";
|
||||
public static final String PAYLOAD = "Payload";
|
||||
public static final String DIRECTORY = "Directory";
|
||||
public static final String FILE = "File";
|
||||
public static final String NAME = "name";
|
||||
public static final String VERSION = "version";
|
||||
public static final String VERSION_SCHEME = "versionScheme";
|
||||
public static final String TAGID = "tagId";
|
||||
public static final String TAGVERSION = "tagVersion";
|
||||
public static final String CORPUS = "corpus";
|
||||
public static final String PATCH = "patch";
|
||||
public static final String SUPPLEMENTAL = "supplemental";
|
||||
public static final String REGID = "regid";
|
||||
public static final String ROLE = "role";
|
||||
public static final String THUMBPRINT = "thumbprint";
|
||||
public static final String HREF = "href";
|
||||
public static final String REL = "rel";
|
||||
public static final String COLLOQUIAL_VERSION = "colloquialVersion";
|
||||
public static final String EDITION = "edition";
|
||||
public static final String PRODUCT = "product";
|
||||
public static final String REVISION = "revision";
|
||||
public static final String PAYLOAD_TYPE = "payloadType";
|
||||
public static final String HYBRID = "hybrid";
|
||||
public static final String PLATFORM_MANUFACTURER_STR = "platformManufacturerStr";
|
||||
public static final String PLATFORM_MANUFACTURER_ID = "platformManufacturerId";
|
||||
public static final String PLATFORM_MODEL = "platformModel";
|
||||
public static final String PLATFORM_VERSION = "platformVersion";
|
||||
public static final String FIRMWARE_MANUFACTURER_STR = "firmwareManufacturerStr";
|
||||
public static final String FIRMWARE_MANUFACTURER_ID = "firmwareManufacturerId";
|
||||
public static final String FIRMWARE_MODEL = "firmwareModel";
|
||||
public static final String FIRMWARE_VERSION = "firmwareVersion";
|
||||
public static final String BINDING_SPEC = "bindingSpec";
|
||||
public static final String BINDING_SPEC_VERSION = "bindingSpecVersion";
|
||||
public static final String PC_URI_LOCAL = "pcURILocal";
|
||||
public static final String PC_URI_GLOBAL = "pcURIGlobal";
|
||||
public static final String RIM_LINK_HASH = "rimLinkHash";
|
||||
public static final String SIZE = "size";
|
||||
public static final String HASH = "hash";
|
||||
public static final String SUPPORT_RIM_TYPE = "supportRIMType";
|
||||
public static final String SUPPORT_RIM_FORMAT = "supportRIMFormat";
|
||||
public static final String SUPPORT_RIM_URI_GLOBAL = "supportRIMURIGlobal";
|
||||
|
||||
public static final QName _COLLOQUIAL_VERSION = new QName(
|
||||
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
|
||||
"colloquialVersion", "n8060");
|
||||
public static final QName _EDITION = new QName(
|
||||
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
|
||||
"edition", "n8060");
|
||||
public static final QName _PRODUCT = new QName(
|
||||
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
|
||||
"product", "n8060");
|
||||
public static final QName _REVISION = new QName(
|
||||
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
|
||||
"revision", "n8060");
|
||||
public static final QName _PAYLOAD_TYPE = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"payloadType", "rim");
|
||||
public static final QName _PLATFORM_MANUFACTURER_STR = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"platformManufacturerStr", "rim");
|
||||
public static final QName _PLATFORM_MANUFACTURER_ID = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"platformManufacturerId", "rim");
|
||||
public static final QName _PLATFORM_MODEL = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"platformModel", "rim");
|
||||
public static final QName _PLATFORM_VERSION = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"platformVersion", "rim");
|
||||
public static final QName _FIRMWARE_MANUFACTURER_STR = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"platformManufacturerStr", "rim");
|
||||
public static final QName _FIRMWARE_MANUFACTURER_ID = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"platformManufacturerId", "rim");
|
||||
public static final QName _FIRMWARE_MODEL = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"platformModel", "rim");
|
||||
public static final QName _FIRMWARE_VERSION = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"platformVersion", "rim");
|
||||
public static final QName _BINDING_SPEC = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"bindingSpec", "rim");
|
||||
public static final QName _BINDING_SPEC_VERSION = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"bindingSpecVersion", "rim");
|
||||
public static final QName _PC_URI_LOCAL = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"pcURILocal", "rim");
|
||||
public static final QName _PC_URI_GLOBAL = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"pcURIGlobal", "rim");
|
||||
public static final QName _RIM_LINK_HASH = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"rimLinkHash", "rim");
|
||||
public static final QName _SUPPORT_RIM_TYPE = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"supportRIMType", "rim");
|
||||
public static final QName _SUPPORT_RIM_FORMAT = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"supportRIMFormat", "rim");
|
||||
public static final QName _SUPPORT_RIM_URI_GLOBAL = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"supportRIMURIGlobal", "rim");
|
||||
public static final QName _N8060_ENVVARPREFIX = new QName(
|
||||
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
|
||||
"envVarPrefix", "n8060");
|
||||
public static final QName _N8060_ENVVARSUFFIX = new QName(
|
||||
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
|
||||
"envVarSuffix", "n8060");
|
||||
public static final QName _N8060_PATHSEPARATOR = new QName(
|
||||
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
|
||||
"pathSeparator", "n8060");
|
||||
|
||||
//Below properties can probably be deleted
|
||||
public static final String SOFTWARE_IDENTITY_NAME = "softwareIdentity.name";
|
||||
public static final String SOFTWARE_IDENTITY_TAGID = "softwareIdentity.tagId";
|
||||
public static final String SOFTWARE_IDENTITY_VERSION = "softwareIdentity.version";
|
||||
|
@ -1,27 +1,92 @@
|
||||
package hirs.swid;
|
||||
|
||||
import javax.xml.bind.JAXB;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.bind.UnmarshalException;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.crypto.AlgorithmMethod;
|
||||
import javax.xml.crypto.KeySelector;
|
||||
import javax.xml.crypto.KeySelectorException;
|
||||
import javax.xml.crypto.KeySelectorResult;
|
||||
import javax.xml.crypto.MarshalException;
|
||||
import javax.xml.crypto.XMLCryptoContext;
|
||||
import javax.xml.crypto.XMLStructure;
|
||||
import javax.xml.crypto.dsig.CanonicalizationMethod;
|
||||
import javax.xml.crypto.dsig.DigestMethod;
|
||||
import javax.xml.crypto.dsig.Reference;
|
||||
import javax.xml.crypto.dsig.SignatureMethod;
|
||||
import javax.xml.crypto.dsig.SignedInfo;
|
||||
import javax.xml.crypto.dsig.Transform;
|
||||
import javax.xml.crypto.dsig.XMLSignature;
|
||||
import javax.xml.crypto.dsig.XMLSignatureException;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
import javax.xml.crypto.dsig.dom.DOMSignContext;
|
||||
import javax.xml.crypto.dsig.dom.DOMValidateContext;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
|
||||
import javax.xml.crypto.dsig.keyinfo.X509Data;
|
||||
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.UnrecoverableEntryException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import hirs.swid.utils.CsvParser;
|
||||
import hirs.swid.utils.HashSwid;
|
||||
import hirs.swid.xjc.BaseElement;
|
||||
import hirs.swid.xjc.CanonicalizationMethodType;
|
||||
import hirs.swid.xjc.DigestMethodType;
|
||||
import hirs.swid.xjc.Directory;
|
||||
@ -39,15 +104,14 @@ import hirs.swid.xjc.SoftwareMeta;
|
||||
import hirs.swid.xjc.TransformType;
|
||||
import hirs.swid.xjc.TransformsType;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import com.eclipsesource.json.Json;
|
||||
import com.eclipsesource.json.JsonObject;
|
||||
import com.eclipsesource.json.JsonObject.Member;
|
||||
import com.eclipsesource.json.JsonValue;
|
||||
import com.eclipsesource.json.Location;
|
||||
import com.eclipsesource.json.ParseException;
|
||||
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* This class provides interaction with the SWID Tag schema as defined in
|
||||
@ -66,58 +130,39 @@ public class SwidTagGateway {
|
||||
"http://www.w3.org/2000/09/xmldsig#", "SHA512", "ds");
|
||||
private static final QName _SHA256_HASH = new QName(
|
||||
"http://www.w3.org/2001/04/xmlenc#sha256", "hash", "SHA256");
|
||||
private static final QName _RIM_PCURILOCAL = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"pcURILocal", "rim");
|
||||
private static final QName _RIM_BINDINGSPEC = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"bindingSpec", "rim");
|
||||
private static final QName _RIM_BINDINGSPECVERSION = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"bindingSpecVersion", "rim");
|
||||
private static final QName _RIM_PLATFORMMANUFACTURERID = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"platformManufacturerId", "rim");
|
||||
private static final QName _RIM_PLATFORMMANUFACTURERSTR = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"platformManufacturerStr", "rim");
|
||||
private static final QName _RIM_PLATFORMMODEL = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"platformModel", "rim");
|
||||
private static final QName _RIM_COMPONENTCLASS = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"componentClass", "rim");
|
||||
private static final QName _RIM_COMPONENTMANUFACTURER = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"componentManufacturer", "rim");
|
||||
private static final QName _RIM_COMPONENTMANUFACTURERID = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"componentManufacturerId", "rim");
|
||||
private static final QName _RIM_RIMLINKHASH = new QName(
|
||||
"https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model",
|
||||
"rimLinkHash", "rim");
|
||||
private static final QName _N8060_ENVVARPREFIX = new QName(
|
||||
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
|
||||
"envVarPrefix", "n8060");
|
||||
private static final QName _N8060_ENVVARSUFFIX = new QName(
|
||||
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
|
||||
"envVarSuffix", "n8060");
|
||||
private static final QName _N8060_PATHSEPARATOR = new QName(
|
||||
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
|
||||
"pathSeparator", "n8060");
|
||||
|
||||
private final ObjectFactory objectFactory = new ObjectFactory();
|
||||
private final File generatedFile = new File("generated_swidTag.swidtag");
|
||||
private QName hashValue = null;
|
||||
|
||||
private static final String ENTITY = "Entity";
|
||||
private static final String PAYLOAD = "Payload";
|
||||
|
||||
private JAXBContext jaxbContext;
|
||||
private Marshaller marshaller;
|
||||
private Unmarshaller unmarshaller;
|
||||
private String attributesFile;
|
||||
|
||||
/**
|
||||
* Default constructor initializes jaxbcontext, marshaller, and unmarshaller
|
||||
*/
|
||||
public SwidTagGateway() {
|
||||
try {
|
||||
jaxbContext = JAXBContext.newInstance(SwidTagConstants.SCHEMA_PACKAGE);
|
||||
marshaller = jaxbContext.createMarshaller();
|
||||
unmarshaller = jaxbContext.createUnmarshaller();
|
||||
attributesFile = SwidTagConstants.DEFAULT_ATTRIBUTES_FILE;
|
||||
} catch (JAXBException e) {
|
||||
System.out.println("Error initializing jaxbcontext: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void setAttributesFile(String attributesFile) {
|
||||
this.attributesFile = attributesFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* default generator method that has no parameters
|
||||
*/
|
||||
public void generateSwidTag() {
|
||||
generateSwidTag(generatedFile);
|
||||
generateSwidTag("");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,9 +209,9 @@ public class SwidTagGateway {
|
||||
is = SwidTagGateway.class.getClassLoader().getResourceAsStream(SwidTagConstants.HIRS_SWIDTAG_HEADERS);
|
||||
properties.load(is);
|
||||
|
||||
SoftwareIdentity swidTag = createSwidTag(properties);
|
||||
SoftwareIdentity swidTag = createSwidTag(new JsonObject());
|
||||
|
||||
JAXBElement<Entity> entity = objectFactory.createSoftwareIdentityEntity(createEntity(properties));
|
||||
JAXBElement<Entity> entity = objectFactory.createSoftwareIdentityEntity(createEntity(new JsonObject()));
|
||||
swidTag.getEntityOrEvidenceOrLink().add(entity);
|
||||
|
||||
// we should have resources, there for we need a collection
|
||||
@ -191,59 +236,68 @@ public class SwidTagGateway {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method generates a primary SWID tag from the values in
|
||||
* resources/swidExamples.properties.
|
||||
* This method generates a base RIM from the values in a JSON file.
|
||||
*
|
||||
* @param outputFile
|
||||
*/
|
||||
public void generateSwidTag(final File outputFile) {
|
||||
Properties properties = new Properties();
|
||||
InputStream is = null;
|
||||
public void generateSwidTag(final String filename) {
|
||||
SoftwareIdentity swidTag = null;
|
||||
try {
|
||||
is = SwidTagGateway.class.getClassLoader().getResourceAsStream(SwidTagConstants.EXAMPLE_PROPERTIES);
|
||||
properties.load(is);
|
||||
|
||||
SoftwareIdentity swidTag = createSwidTag(properties);
|
||||
|
||||
JAXBElement<Entity> entity = objectFactory.createSoftwareIdentityEntity(createEntity(properties));
|
||||
System.out.println("Reading base rim values from " + attributesFile);
|
||||
BufferedReader jsonIn = Files.newBufferedReader(Paths.get(attributesFile), StandardCharsets.UTF_8);
|
||||
JsonObject configProperties = Json.parse(jsonIn).asObject();
|
||||
//SoftwareIdentity
|
||||
swidTag = createSwidTag(configProperties.get(SwidTagConstants.SOFTWARE_IDENTITY).asObject());
|
||||
//Entity
|
||||
JAXBElement<Entity> entity = objectFactory.createSoftwareIdentityEntity(
|
||||
createEntity(configProperties.get(SwidTagConstants.ENTITY).asObject()));
|
||||
swidTag.getEntityOrEvidenceOrLink().add(entity);
|
||||
|
||||
JAXBElement<Link> link = objectFactory.createSoftwareIdentityLink(createLink(properties));
|
||||
//Link
|
||||
JAXBElement<Link> link = objectFactory.createSoftwareIdentityLink(
|
||||
createLink(configProperties.get(SwidTagConstants.LINK).asObject()));
|
||||
swidTag.getEntityOrEvidenceOrLink().add(link);
|
||||
|
||||
JAXBElement<SoftwareMeta> meta = objectFactory.createSoftwareIdentityMeta(createSoftwareMeta(properties));
|
||||
//Meta
|
||||
JAXBElement<SoftwareMeta> meta = objectFactory.createSoftwareIdentityMeta(
|
||||
createSoftwareMeta(configProperties.get(SwidTagConstants.META).asObject()));
|
||||
swidTag.getEntityOrEvidenceOrLink().add(meta);
|
||||
|
||||
ResourceCollection payload = createPayload(properties);
|
||||
Directory directory = createDirectory(properties);
|
||||
hirs.swid.xjc.File file1 = createFile("Example.com.iotBase.bin", "01.00", "15400");
|
||||
hirs.swid.xjc.File file2 = createFile("iotExec.bin", "01.00", "1024");
|
||||
directory.getDirectoryOrFile().add(file1);
|
||||
directory.getDirectoryOrFile().add(file2);
|
||||
//File
|
||||
hirs.swid.xjc.File file = createFile(
|
||||
configProperties.get(SwidTagConstants.PAYLOAD).asObject()
|
||||
.get(SwidTagConstants.DIRECTORY).asObject()
|
||||
.get(SwidTagConstants.FILE).asObject());
|
||||
//Directory
|
||||
Directory directory = createDirectory(
|
||||
configProperties.get(SwidTagConstants.PAYLOAD).asObject()
|
||||
.get(SwidTagConstants.DIRECTORY).asObject());
|
||||
directory.getDirectoryOrFile().add(file);
|
||||
//Payload
|
||||
ResourceCollection payload = createPayload(
|
||||
configProperties.get(SwidTagConstants.PAYLOAD).asObject());
|
||||
payload.getDirectoryOrFileOrProcess().add(directory);
|
||||
JAXBElement<ResourceCollection> jaxbPayload = objectFactory.createSoftwareIdentityPayload(payload);
|
||||
JAXBElement<ResourceCollection> jaxbPayload =
|
||||
objectFactory.createSoftwareIdentityPayload(payload);
|
||||
swidTag.getEntityOrEvidenceOrLink().add(jaxbPayload);
|
||||
|
||||
// JAXBElement<SignatureType> swidtagSignature = objectFactory.createSignature(createSignature());
|
||||
// swidTag.getEntityOrEvidenceOrLink().add(swidtagSignature);
|
||||
|
||||
JAXBElement<SoftwareIdentity> jaxbe = objectFactory.createSoftwareIdentity(swidTag);
|
||||
writeSwidTagFile(jaxbe, outputFile);
|
||||
} catch (FileNotFoundException e) {
|
||||
System.out.println("File does not exist or cannot be read: " + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
System.out.println("Error reading properties file: ");
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
System.out.println("Error in file reader: " + e.getMessage());
|
||||
} catch (ParseException e) {
|
||||
System.out.println("Invalid JSON detected at " + e.getLocation().toString());
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
|
||||
Document signedSoftwareIdentity = signXMLDocument(objectFactory.createSoftwareIdentity(swidTag));
|
||||
System.out.println("Signature core validity: " + validateSignedXMLDocument(signedSoftwareIdentity));
|
||||
if (!filename.isEmpty()) {
|
||||
writeSwidTagFile(signedSoftwareIdentity, new File(filename));
|
||||
} else {
|
||||
writeSwidTagFile(signedSoftwareIdentity, generatedFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* This method validates the .swidtag file at the given filepath against the
|
||||
* schema. A successful validation results in the output of the tag's name
|
||||
* and tagId attributes, otherwise a generic error message is printed.
|
||||
@ -279,6 +333,31 @@ public class SwidTagGateway {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method writes a Document object out to the file specified by generatedFile.
|
||||
*
|
||||
* @param swidTag
|
||||
*/
|
||||
public void writeSwidTagFile(Document swidTag, File outputFile) {
|
||||
try {
|
||||
OutputStream outStream = new FileOutputStream(outputFile);
|
||||
TransformerFactory tf = TransformerFactory.newInstance();
|
||||
Transformer transformer = tf.newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
|
||||
Source source = new DOMSource(swidTag);
|
||||
System.out.println("Writing to file: " + outputFile.getName());
|
||||
transformer.transform(source, new StreamResult(outStream));
|
||||
transformer.transform(source, new StreamResult(System.out));
|
||||
} catch (FileNotFoundException e) {
|
||||
System.out.println("Unable to write to file: " + e.getMessage());
|
||||
} catch (TransformerConfigurationException e) {
|
||||
System.out.println("Error instantiating TransformerFactory class: " + e.getMessage());
|
||||
} catch (TransformerException e) {
|
||||
System.out.println("Error instantiating Transformer class: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an input swidtag at [path] parse any PCRs in the payload into an InputStream object.
|
||||
@ -298,7 +377,7 @@ public class SwidTagGateway {
|
||||
try {
|
||||
JAXBElement element = (JAXBElement) obj;
|
||||
String elementName = element.getName().getLocalPart();
|
||||
if (elementName.equals(PAYLOAD)) {
|
||||
if (elementName.equals(SwidTagConstants.PAYLOAD)) {
|
||||
ResourceCollection rc = (ResourceCollection) element.getValue();
|
||||
if (!rc.getDirectoryOrFileOrProcess().isEmpty()) {
|
||||
pcrs = parsePCRs(rc.getDirectoryOrFileOrProcess());
|
||||
@ -320,14 +399,29 @@ public class SwidTagGateway {
|
||||
* @param properties the Properties object containing parameters from file
|
||||
* @return SoftwareIdentity object created from the properties
|
||||
*/
|
||||
private SoftwareIdentity createSwidTag(Properties properties) {
|
||||
private SoftwareIdentity createSwidTag(JsonObject jsonObject) {
|
||||
SoftwareIdentity swidTag = objectFactory.createSoftwareIdentity();
|
||||
swidTag.setName(properties.getProperty(SwidTagConstants.SOFTWARE_IDENTITY_NAME));
|
||||
swidTag.setTagId(properties.getProperty(SwidTagConstants.SOFTWARE_IDENTITY_TAGID));
|
||||
swidTag.setVersion(properties.getProperty(SwidTagConstants.SOFTWARE_IDENTITY_VERSION));
|
||||
swidTag.setCorpus(Boolean.parseBoolean(properties.getProperty(SwidTagConstants.SOFTWARE_IDENTITY_CORPUS)));
|
||||
swidTag.setPatch(Boolean.parseBoolean(properties.getProperty(SwidTagConstants.SOFTWARE_IDENTITY_PATCH)));
|
||||
swidTag.setSupplemental(Boolean.parseBoolean(properties.getProperty(SwidTagConstants.SOFTWARE_IDENTITY_SUPPLEMENTAL)));
|
||||
swidTag.setLang(SwidTagConstants.DEFAULT_ENGLISH);
|
||||
String name = jsonObject.getString(SwidTagConstants.NAME, "");
|
||||
if (!name.isEmpty()) {
|
||||
swidTag.setName(name);
|
||||
}
|
||||
String tagId = jsonObject.getString(SwidTagConstants.TAGID, "");
|
||||
if (!tagId.isEmpty()) {
|
||||
swidTag.setTagId(tagId);
|
||||
}
|
||||
swidTag.setTagVersion(new BigInteger(jsonObject.getString(SwidTagConstants.TAGVERSION, "0")));
|
||||
String version = jsonObject.getString(SwidTagConstants.VERSION, "");
|
||||
if (!version.isEmpty()) {
|
||||
swidTag.setVersion(version);
|
||||
}
|
||||
swidTag.setCorpus(jsonObject.getBoolean(SwidTagConstants.CORPUS, false));
|
||||
swidTag.setPatch(jsonObject.getBoolean(SwidTagConstants.PATCH, false));
|
||||
swidTag.setSupplemental(jsonObject.getBoolean(SwidTagConstants.SUPPLEMENTAL, false));
|
||||
if (!swidTag.isCorpus() && !swidTag.isPatch()
|
||||
&& !swidTag.isSupplemental() && swidTag.getVersion() != "0.0") {
|
||||
swidTag.setVersionScheme(jsonObject.getString(SwidTagConstants.VERSION_SCHEME, "multipartnumeric"));
|
||||
}
|
||||
|
||||
return swidTag;
|
||||
}
|
||||
@ -339,16 +433,34 @@ public class SwidTagGateway {
|
||||
* @param properties the Properties object containing parameters from file
|
||||
* @return Entity object created from the properties
|
||||
*/
|
||||
private Entity createEntity(Properties properties) {
|
||||
private Entity createEntity(JsonObject jsonObject) {
|
||||
boolean isTagCreator = false;
|
||||
Entity entity = objectFactory.createEntity();
|
||||
entity.setName(properties.getProperty(SwidTagConstants.ENTITY_NAME));
|
||||
entity.setRegid(properties.getProperty(SwidTagConstants.ENTITY_REGID));
|
||||
String[] roles = properties.getProperty(SwidTagConstants.ENTITY_ROLE).split(",");
|
||||
String name = jsonObject.getString(SwidTagConstants.NAME, "");
|
||||
if (!name.isEmpty()) {
|
||||
entity.setName(name);
|
||||
}
|
||||
String[] roles = jsonObject.getString(SwidTagConstants.ROLE, "").split(",");
|
||||
for (int i = 0; i < roles.length; i++) {
|
||||
entity.getRole().add(roles[i]);
|
||||
if (roles[i].equals("tagCreator")) {
|
||||
isTagCreator = true;
|
||||
}
|
||||
}
|
||||
if (isTagCreator) {
|
||||
String regid = jsonObject.getString(SwidTagConstants.REGID, "");
|
||||
if (regid.isEmpty()) {
|
||||
//throw exception that regid is required
|
||||
} else {
|
||||
entity.setRegid(regid);
|
||||
}
|
||||
} else {
|
||||
entity.setRegid(jsonObject.getString(SwidTagConstants.REGID, "invalid.unavailable"));
|
||||
}
|
||||
String thumbprint = jsonObject.getString(SwidTagConstants.THUMBPRINT, "");
|
||||
if (!thumbprint.isEmpty()) {
|
||||
entity.setThumbprint(thumbprint);
|
||||
}
|
||||
entity.setThumbprint(properties.getProperty(SwidTagConstants.ENTITY_THUMBPRINT));
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
@ -358,10 +470,16 @@ public class SwidTagGateway {
|
||||
* @param properties the Properties object containing parameters from file
|
||||
* @return Link element created from the properties
|
||||
*/
|
||||
private Link createLink(Properties properties) {
|
||||
private Link createLink(JsonObject jsonObject) {
|
||||
Link link = objectFactory.createLink();
|
||||
link.setHref(properties.getProperty(SwidTagConstants.LINK_HREF));
|
||||
link.setRel(properties.getProperty(SwidTagConstants.LINK_REL));
|
||||
String href = jsonObject.getString(SwidTagConstants.HREF, "");
|
||||
if (!href.isEmpty()) {
|
||||
link.setHref(href);
|
||||
}
|
||||
String rel = jsonObject.getString(SwidTagConstants.REL, "");
|
||||
if (!rel.isEmpty()) {
|
||||
link.setRel(rel);
|
||||
}
|
||||
|
||||
return link;
|
||||
}
|
||||
@ -372,85 +490,95 @@ public class SwidTagGateway {
|
||||
* @param properties the Properties object containing parameters from file
|
||||
* @return the Meta element created from the properties
|
||||
*/
|
||||
private SoftwareMeta createSoftwareMeta(Properties properties) {
|
||||
private SoftwareMeta createSoftwareMeta(JsonObject jsonObject) {
|
||||
SoftwareMeta softwareMeta = objectFactory.createSoftwareMeta();
|
||||
Map<QName, String> attributes = softwareMeta.getOtherAttributes();
|
||||
attributes.put(_RIM_PCURILOCAL, properties.getProperty(SwidTagConstants.META_PCURILOCAL));
|
||||
attributes.put(_RIM_BINDINGSPEC, properties.getProperty(SwidTagConstants.META_BINDINGSPEC));
|
||||
attributes.put(_RIM_BINDINGSPECVERSION, properties.getProperty(SwidTagConstants.META_BINDINGSPECVERSION));
|
||||
attributes.put(_RIM_PLATFORMMANUFACTURERID, properties.getProperty(SwidTagConstants.META_PLATFORMMANUFACTURERID));
|
||||
attributes.put(_RIM_PLATFORMMANUFACTURERSTR, properties.getProperty(SwidTagConstants.META_PLATFORMMANUFACTURERSTR));
|
||||
attributes.put(_RIM_PLATFORMMODEL, properties.getProperty(SwidTagConstants.META_PLATFORMMODEL));
|
||||
attributes.put(_RIM_COMPONENTCLASS, properties.getProperty(SwidTagConstants.META_COMPONENTCLASS));
|
||||
attributes.put(_RIM_COMPONENTMANUFACTURER, properties.getProperty(SwidTagConstants.META_COMPONENTMANUFACTURER));
|
||||
attributes.put(_RIM_COMPONENTMANUFACTURERID, properties.getProperty(SwidTagConstants.META_COMPONENTMANUFACTURERID));
|
||||
attributes.put(_RIM_RIMLINKHASH, properties.getProperty(SwidTagConstants.META_RIMLINKHASH));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._COLLOQUIAL_VERSION, jsonObject.getString(SwidTagConstants.COLLOQUIAL_VERSION, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._EDITION, jsonObject.getString(SwidTagConstants.EDITION, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._PRODUCT, jsonObject.getString(SwidTagConstants.PRODUCT, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._REVISION, jsonObject.getString(SwidTagConstants.REVISION, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._PAYLOAD_TYPE, jsonObject.getString(SwidTagConstants.PAYLOAD_TYPE, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._PLATFORM_MANUFACTURER_STR, jsonObject.getString(SwidTagConstants.PLATFORM_MANUFACTURER_STR, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._PLATFORM_MANUFACTURER_ID, jsonObject.getString(SwidTagConstants.PLATFORM_MANUFACTURER_ID, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._PLATFORM_MODEL, jsonObject.getString(SwidTagConstants.PLATFORM_MODEL, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._PLATFORM_VERSION, jsonObject.getString(SwidTagConstants.PLATFORM_VERSION, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._FIRMWARE_MANUFACTURER_STR, jsonObject.getString(SwidTagConstants.FIRMWARE_MANUFACTURER_STR, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._FIRMWARE_MANUFACTURER_ID, jsonObject.getString(SwidTagConstants.FIRMWARE_MANUFACTURER_ID, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._FIRMWARE_MODEL, jsonObject.getString(SwidTagConstants.FIRMWARE_MODEL, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._FIRMWARE_VERSION, jsonObject.getString(SwidTagConstants.FIRMWARE_VERSION, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._BINDING_SPEC, jsonObject.getString(SwidTagConstants.BINDING_SPEC, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._BINDING_SPEC_VERSION, jsonObject.getString(SwidTagConstants.BINDING_SPEC_VERSION, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._PC_URI_LOCAL, jsonObject.getString(SwidTagConstants.PC_URI_LOCAL, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._PC_URI_GLOBAL, jsonObject.getString(SwidTagConstants.PC_URI_GLOBAL, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._RIM_LINK_HASH, jsonObject.getString(SwidTagConstants.RIM_LINK_HASH, ""));
|
||||
|
||||
return softwareMeta;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates a Directory from the parameters read in from a properties file.
|
||||
*
|
||||
* @param properties the Properties object containing parameters from file
|
||||
* @return Directory object created from the properties
|
||||
*/
|
||||
private Directory createDirectory(Properties properties) {
|
||||
Directory directory = objectFactory.createDirectory();
|
||||
directory.setLocation(properties.getProperty(SwidTagConstants.DIRECTORY_LOCATION));
|
||||
directory.setName(properties.getProperty(SwidTagConstants.DIRECTORY_NAME));
|
||||
String directoryRoot = properties.getProperty(SwidTagConstants.DIRECTORY_ROOT);
|
||||
if (!directoryRoot.isEmpty()) {
|
||||
directory.setRoot(directoryRoot);
|
||||
}
|
||||
|
||||
return directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates a hirs.swid.xjc.File from a java.nio.File object.
|
||||
* This method signature is not currently used and may be removed later.
|
||||
*
|
||||
* @param file
|
||||
* @return hirs.swid.xjc.File object from File object
|
||||
*/
|
||||
private hirs.swid.xjc.File createFile(File file) {
|
||||
return createFile(file.getName(), "01.00", Long.toString(file.length()));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates a hirs.swid.xjc.File from three arguments, then calculates
|
||||
* and stores its hash as an attribute in itself.
|
||||
*
|
||||
* @param filename
|
||||
* @param location
|
||||
* @return hirs.swid.xjc.File object from File object
|
||||
*/
|
||||
private hirs.swid.xjc.File createFile(String filename, String version, String size) {
|
||||
hirs.swid.xjc.File file = objectFactory.createFile();
|
||||
file.setName(filename);
|
||||
file.setVersion(version);
|
||||
file.setSize(new BigInteger(size));
|
||||
String hash = HashSwid.get256Hash(file.getName());
|
||||
file.getOtherAttributes().put(_SHA256_HASH, hash);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates a Payload from the parameters read in from a properties file.
|
||||
*
|
||||
* @param properties the Properties object containing parameters from file
|
||||
* @return the Payload object created
|
||||
*/
|
||||
private ResourceCollection createPayload(Properties properties) {
|
||||
ResourceCollection rc = objectFactory.createResourceCollection();
|
||||
private ResourceCollection createPayload(JsonObject jsonObject) {
|
||||
ResourceCollection payload = objectFactory.createResourceCollection();
|
||||
Map<QName, String> attributes = payload.getOtherAttributes();
|
||||
addNonNullAttribute(attributes, SwidTagConstants._N8060_ENVVARPREFIX, jsonObject.getString(SwidTagConstants.PAYLOAD_ENVVARPREFIX, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._N8060_ENVVARSUFFIX, jsonObject.getString(SwidTagConstants.PAYLOAD_ENVVARSUFFIX, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._N8060_PATHSEPARATOR, jsonObject.getString(SwidTagConstants.PAYLOAD_PATHSEPARATOR, ""));
|
||||
|
||||
rc.getOtherAttributes().put(_N8060_ENVVARPREFIX, properties.getProperty(SwidTagConstants.PAYLOAD_ENVVARPREFIX));
|
||||
rc.getOtherAttributes().put(_N8060_ENVVARSUFFIX, properties.getProperty(SwidTagConstants.PAYLOAD_ENVVARSUFFIX));
|
||||
rc.getOtherAttributes().put(_N8060_PATHSEPARATOR, properties.getProperty(SwidTagConstants.PAYLOAD_PATHSEPARATOR));
|
||||
return payload;
|
||||
}
|
||||
|
||||
return rc;
|
||||
/**
|
||||
* This method creates a Directory from the parameters read in from a properties file.
|
||||
*
|
||||
* @param properties the Properties object containing parameters from file
|
||||
* @return Directory object created from the properties
|
||||
*/
|
||||
private Directory createDirectory(JsonObject jsonObject) {
|
||||
Directory directory = objectFactory.createDirectory();
|
||||
directory.setName(jsonObject.getString(SwidTagConstants.NAME, ""));
|
||||
Map<QName, String> attributes = directory.getOtherAttributes();
|
||||
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_TYPE, jsonObject.getString(SwidTagConstants.SUPPORT_RIM_TYPE, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_FORMAT, jsonObject.getString(SwidTagConstants.SUPPORT_RIM_FORMAT, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_URI_GLOBAL, jsonObject.getString(SwidTagConstants.SUPPORT_RIM_URI_GLOBAL, ""));
|
||||
/*
|
||||
directory.setLocation(jsonObject.getString(SwidTagConstants.DIRECTORY_LOCATION));
|
||||
String directoryRoot = jsonObject.getString(SwidTagConstants.DIRECTORY_ROOT);
|
||||
if (!directoryRoot.isEmpty()) {
|
||||
directory.setRoot(directoryRoot);
|
||||
}
|
||||
*/
|
||||
return directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates a hirs.swid.xjc.File from three arguments, then calculates
|
||||
* and stores its hash as an attribute in itself.
|
||||
*
|
||||
* @param filename
|
||||
* @param location
|
||||
* @return hirs.swid.xjc.File object from File object
|
||||
*/
|
||||
private hirs.swid.xjc.File createFile(JsonObject jsonObject) {
|
||||
hirs.swid.xjc.File file = objectFactory.createFile();
|
||||
file.setName(jsonObject.getString(SwidTagConstants.NAME, ""));
|
||||
file.setSize(new BigInteger(jsonObject.getString(SwidTagConstants.SIZE, "0")));
|
||||
Map<QName, String> attributes = file.getOtherAttributes();
|
||||
addNonNullAttribute(attributes, _SHA256_HASH, jsonObject.getString(SwidTagConstants.HASH, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_TYPE, jsonObject.getString(SwidTagConstants.SUPPORT_RIM_TYPE, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_FORMAT, jsonObject.getString(SwidTagConstants.SUPPORT_RIM_FORMAT, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_URI_GLOBAL, jsonObject.getString(SwidTagConstants.SUPPORT_RIM_URI_GLOBAL, ""));
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
private void addNonNullAttribute(Map<QName, String> attributes, QName key, String value) {
|
||||
if (!value.isEmpty()) {
|
||||
attributes.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -480,45 +608,130 @@ public class SwidTagGateway {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates an xml signature based on the xmldsig schema.
|
||||
* This method is incomplete and not yet implemented.
|
||||
*
|
||||
* @return the Signature object created
|
||||
* This method signs a SoftwareIdentity with an xmldsig in compatibility mode.
|
||||
* Current assumptions: digest method SHA256, signature method SHA256, enveloped signature
|
||||
*/
|
||||
private SignatureType createSignature() {
|
||||
SignatureType signature = objectFactory.createSignatureType();
|
||||
SignedInfoType signedInfo = objectFactory.createSignedInfoType();
|
||||
private Document signXMLDocument(JAXBElement<SoftwareIdentity> swidTag) {
|
||||
Document doc = null;
|
||||
try {
|
||||
XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
|
||||
Reference reference = sigFactory.newReference(
|
||||
"",
|
||||
sigFactory.newDigestMethod(DigestMethod.SHA256, null),
|
||||
Collections.singletonList(sigFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)),
|
||||
null,
|
||||
null
|
||||
);
|
||||
SignedInfo signedInfo = sigFactory.newSignedInfo(
|
||||
sigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null),
|
||||
sigFactory.newSignatureMethod(SwidTagConstants.SIGNATURE_ALGORITHM_RSA_SHA256, null),
|
||||
Collections.singletonList(reference)
|
||||
);
|
||||
KeyStore keystore = KeyStore.getInstance("JKS");
|
||||
keystore.load(new FileInputStream(SwidTagConstants.DEFAULT_KEYSTORE_PATH), SwidTagConstants.DEFAULT_KEYSTORE_PASSWORD.toCharArray());
|
||||
KeyStore.PrivateKeyEntry privateKey = (KeyStore.PrivateKeyEntry) keystore.getEntry(SwidTagConstants.DEFAULT_PRIVATE_KEY_ALIAS,
|
||||
new KeyStore.PasswordProtection(SwidTagConstants.DEFAULT_KEYSTORE_PASSWORD.toCharArray()));
|
||||
X509Certificate certificate = (X509Certificate) privateKey.getCertificate();
|
||||
KeyInfoFactory kiFactory = sigFactory.getKeyInfoFactory();
|
||||
ArrayList<Object> x509Content = new ArrayList<Object>();
|
||||
x509Content.add(certificate.getSubjectX500Principal().getName());
|
||||
x509Content.add(certificate);
|
||||
X509Data data = kiFactory.newX509Data(x509Content);
|
||||
KeyInfo keyinfo = kiFactory.newKeyInfo(Collections.singletonList(data));
|
||||
|
||||
CanonicalizationMethodType canonicalizationMethod = objectFactory.createCanonicalizationMethodType();
|
||||
canonicalizationMethod.setAlgorithm("http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
|
||||
doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
|
||||
marshaller.marshal(swidTag, doc);
|
||||
DOMSignContext context = new DOMSignContext(privateKey.getPrivateKey(), doc.getDocumentElement());
|
||||
XMLSignature signature = sigFactory.newXMLSignature(signedInfo, keyinfo);
|
||||
signature.sign(context);
|
||||
} catch (FileNotFoundException e) {
|
||||
System.out.println("Keystore not found! " + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
System.out.println("Error loading keystore: " + e.getMessage());
|
||||
} catch (NoSuchAlgorithmException | KeyStoreException | InvalidAlgorithmParameterException |
|
||||
ParserConfigurationException | UnrecoverableEntryException e) {
|
||||
System.out.println(e.getMessage());
|
||||
} catch (CertificateException e) {
|
||||
System.out.println("Certificate error: " + e.getMessage());
|
||||
} catch (JAXBException e) {
|
||||
System.out.println("Error marshaling signed swidtag: " + e.getMessage());
|
||||
} catch (MarshalException | XMLSignatureException e) {
|
||||
System.out.println("Error while signing SoftwareIdentity: " + e.getMessage());
|
||||
}
|
||||
|
||||
SignatureMethodType signatureMethod = objectFactory.createSignatureMethodType();
|
||||
signatureMethod.setAlgorithm("http://www.w3.org/2000/09/xmldsig#rsa-sha512");
|
||||
return doc;
|
||||
}
|
||||
|
||||
ReferenceType reference = objectFactory.createReferenceType();
|
||||
TransformsType transforms = objectFactory.createTransformsType();
|
||||
/**
|
||||
* This method validates a Document with a signature element.
|
||||
*
|
||||
* @param doc
|
||||
*/
|
||||
private boolean validateSignedXMLDocument(Document doc) {
|
||||
boolean isValid = false;
|
||||
try {
|
||||
NodeList nodes = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
|
||||
if (nodes.getLength() == 0) {
|
||||
throw new Exception("Signature element not found!");
|
||||
}
|
||||
DOMValidateContext context = new DOMValidateContext(new X509KeySelector(), nodes.item(0));
|
||||
XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
|
||||
XMLSignature signature = sigFactory.unmarshalXMLSignature(context);
|
||||
isValid = signature.validate(context);
|
||||
} catch (MarshalException | XMLSignatureException e) {
|
||||
System.out.println(e.getMessage());
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
|
||||
TransformType transform = objectFactory.createTransformType();
|
||||
transform.setAlgorithm("http://www.w3.org/2000/09/xmldsig#enveloped-signature");
|
||||
transforms.getTransform().add(transform);
|
||||
return isValid;
|
||||
}
|
||||
|
||||
DigestMethodType digestMethod = objectFactory.createDigestMethodType();
|
||||
digestMethod.setAlgorithm("http://www.w3.org/2000/09/xmldsig#sha256");
|
||||
public class X509KeySelector extends KeySelector {
|
||||
public KeySelectorResult select(KeyInfo keyinfo,
|
||||
KeySelector.Purpose purpose,
|
||||
AlgorithmMethod algorithm,
|
||||
XMLCryptoContext context) throws KeySelectorException {
|
||||
Iterator keyinfoItr = keyinfo.getContent().iterator();
|
||||
while(keyinfoItr.hasNext()) {
|
||||
XMLStructure element = (XMLStructure) keyinfoItr.next();
|
||||
if (element instanceof X509Data) {
|
||||
X509Data data = (X509Data) element;
|
||||
Iterator dataItr = data.getContent().iterator();
|
||||
while (dataItr.hasNext()) {
|
||||
Object object = dataItr.next();
|
||||
if (object instanceof X509Certificate) {
|
||||
final PublicKey publicKey = ((X509Certificate) object).getPublicKey();
|
||||
if (areAlgorithmsEqual(algorithm.getAlgorithm(), publicKey.getAlgorithm())) {
|
||||
return new RIMKeySelectorResult(publicKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reference.setTransforms(transforms);
|
||||
reference.setDigestMethod(digestMethod);
|
||||
reference.setDigestValue(new byte[10]);
|
||||
throw new KeySelectorException("No key found!");
|
||||
}
|
||||
|
||||
signedInfo.setCanonicalizationMethod(canonicalizationMethod);
|
||||
signedInfo.setSignatureMethod(signatureMethod);
|
||||
signedInfo.getReference().add(reference);
|
||||
public boolean areAlgorithmsEqual(String uri, String name) {
|
||||
if (uri.equals(SwidTagConstants.SIGNATURE_ALGORITHM_RSA_SHA256) && name.equalsIgnoreCase("RSA")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SignatureValueType signatureValue = objectFactory.createSignatureValueType();
|
||||
signatureValue.setValue(new byte[10]);
|
||||
private class RIMKeySelectorResult implements KeySelectorResult {
|
||||
private Key key;
|
||||
|
||||
signature.setSignedInfo(signedInfo);
|
||||
public RIMKeySelectorResult(Key key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
return signature;
|
||||
public Key getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -572,8 +785,6 @@ public class SwidTagGateway {
|
||||
is = SwidTagGateway.class.getClassLoader().getResourceAsStream(SwidTagConstants.SCHEMA_URL);
|
||||
SchemaFactory schemaFactory = SchemaFactory.newInstance(SwidTagConstants.SCHEMA_LANGUAGE);
|
||||
Schema schema = schemaFactory.newSchema(new StreamSource(is));
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance(SwidTagConstants.SCHEMA_PACKAGE);
|
||||
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
|
||||
unmarshaller.setSchema(schema);
|
||||
jaxbe = (JAXBElement) unmarshaller.unmarshal(input);
|
||||
} catch (SAXException e) {
|
||||
|
@ -17,21 +17,24 @@ public class Commander {
|
||||
private static final String CREATE_STRING = "create";
|
||||
private static final String VERIFY_STRING = "verify";
|
||||
private static final String HELP_STRING = "help";
|
||||
private static final String EXAMPLE_STRING = "example";
|
||||
private static final String PARSE_STRING = "parse";
|
||||
private static final String IN_STRING = "in";
|
||||
private static final String OUT_STRING = "out";
|
||||
private static final String HASH_STRING = "hash";
|
||||
private static final String ATTRIBUTES_STRING = "attributes";
|
||||
private static final String KEY_STRING = "key";
|
||||
private static final String PRIVATE_KEY_STRING = "privatekey";
|
||||
private static final String CERT_STRING = "cert";
|
||||
|
||||
private boolean hasArguments = false;
|
||||
private boolean validate = false;
|
||||
private boolean create = false;
|
||||
private boolean parse = false;
|
||||
private boolean attributesGiven = false;
|
||||
private boolean keystoreGiven = false;
|
||||
|
||||
private String validateFile;
|
||||
private String createInFile;
|
||||
private String createOutFile;
|
||||
private String createOutFile = "";
|
||||
private String parseFile;
|
||||
private String attributesFile = "";
|
||||
private String keystore = "";
|
||||
private String hashAlg = null;
|
||||
|
||||
/**
|
||||
@ -45,31 +48,18 @@ public class Commander {
|
||||
if (hasArguments) {
|
||||
parseArguments(args);
|
||||
} else {
|
||||
//printHelp();
|
||||
printHelp();
|
||||
}
|
||||
|
||||
if (create) {
|
||||
if (!Files.exists(Paths.get(getCreateInFile()))) {
|
||||
create = false;
|
||||
printHelp("Input file doesn't exist...");
|
||||
}
|
||||
|
||||
if (hashAlg == null) {
|
||||
hashAlg = "256";
|
||||
}
|
||||
|
||||
if (!isValidPath(getCreateOutFile())) {
|
||||
printHelp(String.format("Invalid file path on creation file...(%s)",
|
||||
getCreateOutFile()));
|
||||
if (!getCreateOutFile().isEmpty() && !isValidPath(getCreateOutFile())) {
|
||||
printHelp(String.format("Invalid file path %s!", getCreateOutFile()));
|
||||
}
|
||||
}
|
||||
|
||||
if (validate && create) {
|
||||
// there maybe a time in which you could validate what you created
|
||||
// but not right now
|
||||
// print the help information
|
||||
printHelp();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,15 +85,15 @@ public class Commander {
|
||||
case FULL_COMMAND_PREFIX + CREATE_STRING:
|
||||
case COMMAND_PREFIX + "c":
|
||||
create = true;
|
||||
break;
|
||||
case COMMAND_PREFIX + IN_STRING:
|
||||
if (create) {
|
||||
createInFile = args[++i];
|
||||
if (i+1 < args.length && !args[i+1].substring(0,1).equals(COMMAND_PREFIX)) {
|
||||
createOutFile = args[++i];
|
||||
}
|
||||
break;
|
||||
case COMMAND_PREFIX + OUT_STRING:
|
||||
if (create) {
|
||||
createOutFile = args[++i];
|
||||
case FULL_COMMAND_PREFIX + ATTRIBUTES_STRING:
|
||||
case COMMAND_PREFIX + "a":
|
||||
attributesGiven = true;
|
||||
if (i+1 < args.length && !args[i+1].substring(0,1).equals(COMMAND_PREFIX)) {
|
||||
attributesFile = args[++i];
|
||||
}
|
||||
break;
|
||||
case FULL_COMMAND_PREFIX + VERIFY_STRING:
|
||||
@ -111,27 +101,18 @@ public class Commander {
|
||||
validate = true;
|
||||
validateFile = args[++i];
|
||||
break;
|
||||
case FULL_COMMAND_PREFIX + EXAMPLE_STRING:
|
||||
case COMMAND_PREFIX + "e":
|
||||
hasArguments = false;
|
||||
return; // default is generate
|
||||
case COMMAND_PREFIX + HASH_STRING:
|
||||
hashAlg = args[++i];
|
||||
break;
|
||||
case FULL_COMMAND_PREFIX + PARSE_STRING:
|
||||
case COMMAND_PREFIX + "p":
|
||||
parse = true;
|
||||
parseFile = args[++i];
|
||||
break;
|
||||
case FULL_COMMAND_PREFIX + KEY_STRING:
|
||||
case COMMAND_PREFIX + "k":
|
||||
keystore = args[++i];
|
||||
break;
|
||||
case FULL_COMMAND_PREFIX + HELP_STRING:
|
||||
case COMMAND_PREFIX + "h":
|
||||
default:
|
||||
if (Files.exists(Paths.get(args[i]))) {
|
||||
validate = true;
|
||||
validateFile = args[i];
|
||||
break;
|
||||
}
|
||||
|
||||
printHelp();
|
||||
}
|
||||
}
|
||||
@ -146,15 +127,6 @@ public class Commander {
|
||||
return validateFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the input create file associated with the create flag
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public final String getCreateInFile() {
|
||||
return createInFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the output file for the create flag
|
||||
*
|
||||
@ -218,7 +190,39 @@ public class Commander {
|
||||
public final String getParseFile() {
|
||||
return parseFile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for the attributes file given flag
|
||||
* @return
|
||||
*/
|
||||
public boolean isAttributesGiven() {
|
||||
return attributesGiven;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the file containing attribute key-value pairs
|
||||
* @return
|
||||
*/
|
||||
public String getAttributesFile() {
|
||||
return attributesFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the keystore given flag
|
||||
* @return
|
||||
*/
|
||||
public boolean isKeystoreGiven() {
|
||||
return keystoreGiven;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the keystore used for digital signatures
|
||||
* @return
|
||||
*/
|
||||
public String getKeystore() {
|
||||
return keystore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default no parameter help method.
|
||||
*/
|
||||
@ -237,20 +241,29 @@ public class Commander {
|
||||
sb.append(String.format("ERROR: %s\n\n", message));
|
||||
}
|
||||
sb.append("Usage: HIRS_SwidTag\n");
|
||||
sb.append(" -c, --create \tTakes given input in the csv format\n"
|
||||
+ " \t-in <file>\tand produces swidtag payloads.\n"
|
||||
+ " \t-out <file>\tThe -hash argument is optional.\n"
|
||||
+ " \t-hash <algorithm>\n");
|
||||
sb.append(" -v, --verify\t\tTakes the provided input file and\n"
|
||||
+ " \t\t\tvalidates it against the schema at\n"
|
||||
+ " \t\t\thttp://standards.iso.org/iso/19770/-2/2015/schema.xsd\n");
|
||||
sb.append(" -e, --example\tCreate example swid tag file (generated_swidTag.swidtag)\n");
|
||||
sb.append(" -h, --help\t\tPrints the command help information\n");
|
||||
sb.append(" <no file>\t\tListing no command with no argument will\n"
|
||||
+ " \t\t\tcreate an example tag file\n");
|
||||
sb.append(" <file>\t\tValidate the given file argument\n");
|
||||
sb.append(" -p, --parse\t\tParse a swidtag's payload\n"
|
||||
+ " <file>\t\tInput swidtag");
|
||||
sb.append(" -c, --create <file>\t\tCreate a base rim and write to\n"
|
||||
+ " \t\t\t\tthe given file. If no file is given the default is\n"
|
||||
+ " \t\t\t\tgenerated_swidTag.swidtag\n\n");
|
||||
sb.append(" -a, --attributes <file>\tSpecify the JSON file that contains\n"
|
||||
+ " \t\t\t\tthe xml attributes to add to the RIM\n\n");
|
||||
sb.append(" -v, --verify\t\t\tTakes the provided input file and\n"
|
||||
+ " \t\t\t\tvalidates it against the schema at\n"
|
||||
+ " \t\t\t\thttp://standards.iso.org/iso/19770/-2/2015/schema.xsd\n\n");
|
||||
sb.append(" -p, --parse <file>\t\tParse the given swidtag's payload\n\n");
|
||||
/* sb.append(" -k, --key\t\t\tSpecify the credential and its location to use\n"
|
||||
+ " \t-privatekey <file>\tfor digital signatures\n"
|
||||
+ " \t-cert <file>\n\n");
|
||||
*/ sb.append(" -h, --help, <no args>\tPrints this command help information.\n");
|
||||
sb.append(" \t\t\t\tListing no command arguments will also\n"
|
||||
+ " \t\t\t\tprint this help text.\n\n");
|
||||
sb.append("Example commands: \n"
|
||||
+ " Create a base rim from the default attribute file and write the rim\n"
|
||||
+ " to generated_swidTag.swidtag:\n\n"
|
||||
+ " \t\tjava -jar tcg_rim_tool-1.0.jar -c\n\n"
|
||||
+ " Create a base rim from the values in config.json and write the rim\n"
|
||||
+ " to base_rim.swidtag:\n\n"
|
||||
+ " \t\tjava -jar tcg_rim_tool-1.0.jar -c base_rim.swidtag -a config.json\n\n"
|
||||
+ " ");
|
||||
|
||||
System.out.println(sb.toString());
|
||||
System.exit(1);
|
||||
|
Loading…
Reference in New Issue
Block a user