mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-02-20 17:52:47 +00:00
Merge pull request #284 from nsacyber/issue-273
[#273] Validate base RIM with external cert
This commit is contained in:
commit
df6a864c2d
@ -1,8 +1,8 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDoTCCAomgAwIBAgIJAPB+r6VBhBn5MA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNV
|
||||
MIID2jCCAsKgAwIBAgIJAP0uwoNdwZDFMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwI
|
||||
UENDbGllbnQxEjAQBgNVBAMMCUV4YW1wbGVDQTAeFw0yMDAzMTExODExMjJaFw0z
|
||||
MDAxMTgxODExMjJaMFwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UE
|
||||
UENDbGllbnQxEjAQBgNVBAMMCUV4YW1wbGVDQTAeFw0yMDA3MjEyMTQ1MDBaFw0z
|
||||
MDA1MzAyMTQ1MDBaMFwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UE
|
||||
CgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxGzAZBgNVBAMMEmV4YW1wbGUu
|
||||
UklNLnNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd1lWGk
|
||||
SRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44
|
||||
@ -10,13 +10,14 @@ SRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44
|
||||
j9NL4dcMgxRXsPdHfXb0923C7xYd2t2qfW05umgaj7qeQl6c68CFNsGX4JA8rWFQ
|
||||
ZvvGx5DGlK4KTcjPuQQINs5fxasNKqLY2hq+z82x/rqwr2hmyizD6FpFSyIABPEM
|
||||
PfB036GEhRwu1WEMkq8yIp2jgRUoFYke9pB3ph9pVow0Hh4mNFSKD4pP41VSKY1n
|
||||
us83mdkuukPy5o0CAwEAAaNvMG0wHQYDVR0OBBYEFC/euOfQMKIgnaoBhhqWT+3s
|
||||
8rzBMB8GA1UdIwQYMBaAFEahuO3bpnFf0NLneoo8XW6aw5Y4MAkGA1UdEwQCMAAw
|
||||
CwYDVR0PBAQDAgbAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUA
|
||||
A4IBAQBl2Bu9xpnHCCeeebjx+ILQXJXBd6q5+NQlV3zzBrf0bleZRtsOmsuFvWQo
|
||||
KQxsfZuk7QcSvVd/1v8mqwJ0PwbFKQmrhIPWP+iowiBNqpG5PH9YxhpHQ1osOfib
|
||||
NLOXMhudIQRY0yAgqQf+MOlXYa0stX8gkgftVBDRutuMKyOTf4a6d8TUcbG2Rnyz
|
||||
O/6S9bq4cPDYLqWRBM+aGN8e00UWTKpBl6/1EU8wkJA6WdllK2e8mVkXUPWYyHTZ
|
||||
0qQnrYiuLr36ycAznABDzEAoj4tMZbjIAfuscty6Ggzxl1WbyZLI6YzyXALwaYvr
|
||||
crTLeyFynlKxuCfDnr1SAHDM65BY
|
||||
us83mdkuukPy5o0CAwEAAaOBpzCBpDAdBgNVHQ4EFgQUL96459AwoiCdqgGGGpZP
|
||||
7ezyvMEwHwYDVR0jBBgwFoAURqG47dumcV/Q0ud6ijxdbprDljgwCQYDVR0TBAIw
|
||||
ADALBgNVHQ8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwNQYIKwYBBQUHAQEE
|
||||
KTAnMCUGCCsGAQUFBzAChhlodHRwczovL2V4YW1wbGUuY29tL2NlcnRzMA0GCSqG
|
||||
SIb3DQEBCwUAA4IBAQDpKx5oQlkS11cg7Qp58BmCvjCzFpof+qYePooJsD3i5SwK
|
||||
fRTa2CkDMww9qrwBK7G60y7jhe5InKTdqIlVqaji5ZImR0QMKTtk7zt9AJ9EaEzK
|
||||
xfDiE/qX34KxNe4ZmbvLH8N+BSujQXMMi56zGjW469Y/rbDMG8uU1dq3zqhO5b+d
|
||||
Ur1ecdkYLgzxu6O+oWy5JpVibmcjvNezJsUtjc+km2FYm24vU3/fCNzZ2z0EHQES
|
||||
cIEQ5OqfpdFrV3De238RhMH6J4xePSidnFpfBc6FrdyDI1A8eRFz36I4xfVL3ZnJ
|
||||
P/+j+NE4q6yz5VGvm0npLO394ZihtsI1sRAR8ORJ
|
||||
-----END CERTIFICATE-----
|
||||
|
@ -32,9 +32,7 @@
|
||||
"Directory": {
|
||||
"name": "iotBase",
|
||||
"File": {
|
||||
"name": "Example.com.iotBase.bin",
|
||||
"size": "15400",
|
||||
"hash": "688e293e3ccb522f6cf8a027c9ade7960f84bd0bf3a0b99812bc1fa498a2db8d"
|
||||
"name": "TpmLog.bin"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
package hirs.swid;
|
||||
|
||||
import org.bouncycastle.asn1.x509.AccessDescription;
|
||||
import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
|
||||
import org.bouncycastle.asn1.x509.Extension;
|
||||
import org.bouncycastle.asn1.x509.GeneralName;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.openssl.PEMKeyPair;
|
||||
@ -34,6 +38,10 @@ public class CredentialParser {
|
||||
return certificate;
|
||||
}
|
||||
|
||||
public void setCertificate(X509Certificate certificate) {
|
||||
this.certificate = certificate;
|
||||
}
|
||||
|
||||
public PrivateKey getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
@ -61,6 +69,16 @@ public class CredentialParser {
|
||||
publicKey = certificate.getPublicKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the X509Certificate object from a PEM certificate file.
|
||||
* @param certificateFile
|
||||
* @return
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
public X509Certificate parseCertFromPEM(String certificateFile) throws FileNotFoundException {
|
||||
return parsePEMCertificate(certificateFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the X509Certificate found in a PEM file.
|
||||
* @param filename
|
||||
@ -197,20 +215,39 @@ public class CredentialParser {
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method for extracting the subjectKeyIdentifier from an X509Certificate.
|
||||
* The subjectKeyIdentifier is stored as a DER-encoded octet and will be converted to a String.
|
||||
* This method returns the authorityInfoAccess from an X509Certificate.
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public String getCertificateAuthorityInfoAccess() throws IOException {
|
||||
StringBuilder sb = new StringBuilder("Authority Info Access:\n");
|
||||
byte[] extension = certificate.getExtensionValue(Extension.authorityInfoAccess.getId());
|
||||
if (extension != null && extension.length > 0) {
|
||||
AuthorityInformationAccess aia = AuthorityInformationAccess.getInstance(
|
||||
JcaX509ExtensionUtils.parseExtensionValue(extension));
|
||||
for (AccessDescription ad : aia.getAccessDescriptions()) {
|
||||
if (ad.getAccessMethod().toString().equals(SwidTagConstants.CA_ISSUERS)) {
|
||||
sb.append("CA issuers - ");
|
||||
}
|
||||
if (ad.getAccessLocation().getTagNo() == GeneralName.uniformResourceIdentifier) {
|
||||
sb.append("URI:" + ad.getAccessLocation().getName().toString() + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the subjectKeyIdentifier from an X509Certificate.
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public String getCertificateSubjectKeyIdentifier() throws IOException {
|
||||
String decodedValue = null;
|
||||
byte[] extension = certificate.getExtensionValue(SwidTagConstants.CERTIFICATE_SUBJECT_KEY_IDENTIFIER);
|
||||
if (extension != null) {
|
||||
byte[] extension = certificate.getExtensionValue(Extension.subjectKeyIdentifier.getId());
|
||||
if (extension != null && extension.length > 0) {
|
||||
decodedValue = JcaX509ExtensionUtils.parseExtensionValue(extension).toString();
|
||||
}
|
||||
//If there is a # symbol at the beginning of the string, remove it
|
||||
if (decodedValue.startsWith("#")) {
|
||||
decodedValue = decodedValue.substring(1);
|
||||
}
|
||||
return decodedValue;
|
||||
return decodedValue.substring(1);//Drop the # at the beginning of the string
|
||||
}
|
||||
}
|
||||
|
@ -12,23 +12,28 @@ public class Main {
|
||||
Commander commander = new Commander();
|
||||
JCommander jc = JCommander.newBuilder().addObject(commander).build();
|
||||
jc.parse(args);
|
||||
SwidTagGateway gateway = new SwidTagGateway();
|
||||
SwidTagGateway gateway;
|
||||
SwidTagValidator validator;
|
||||
|
||||
if (commander.isHelp()) {
|
||||
jc.usage();
|
||||
System.out.println(commander.printHelpExamples());
|
||||
} else {
|
||||
if (!commander.getVerifyFile().isEmpty()) {
|
||||
validator = new SwidTagValidator();
|
||||
System.out.println(commander.toString());
|
||||
String verifyFile = commander.getVerifyFile();
|
||||
String rimel = commander.getRimEventLog();
|
||||
//String publicCertificate = commander.getPublicCertificate();
|
||||
String certificateFile = commander.getPublicCertificate();
|
||||
if (!verifyFile.isEmpty()) {
|
||||
if (!rimel.isEmpty()) {
|
||||
gateway.setRimEventLog(rimel);
|
||||
validator.setRimEventLog(rimel);
|
||||
}
|
||||
if (!certificateFile.isEmpty()) {
|
||||
validator.setCertificateFile(certificateFile);
|
||||
}
|
||||
try {
|
||||
gateway.validateSwidTag(verifyFile);
|
||||
validator.validateSwidTag(verifyFile);
|
||||
} catch (IOException e) {
|
||||
System.out.println("Error validating RIM file: " + e.getMessage());
|
||||
System.exit(1);
|
||||
@ -38,6 +43,7 @@ public class Main {
|
||||
System.exit(1);
|
||||
}
|
||||
} else {
|
||||
gateway = new SwidTagGateway();
|
||||
System.out.println(commander.toString());
|
||||
String createType = commander.getCreateType().toUpperCase();
|
||||
String attributesFile = commander.getAttributesFile();
|
||||
|
@ -69,6 +69,9 @@ public class SwidTagConstants {
|
||||
public static final String SUPPORT_RIM_FORMAT = "supportRIMFormat";
|
||||
public static final String SUPPORT_RIM_URI_GLOBAL = "supportRIMURIGlobal";
|
||||
|
||||
public static final QName _SHA256_HASH = new QName(
|
||||
"http://www.w3.org/2001/04/xmlenc#sha256",
|
||||
"hash", "SHA256");
|
||||
public static final QName _COLLOQUIAL_VERSION = new QName(
|
||||
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
|
||||
"colloquialVersion", "n8060");
|
||||
@ -142,5 +145,5 @@ public class SwidTagConstants {
|
||||
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
|
||||
"pathSeparator", "n8060");
|
||||
|
||||
public static final String CERTIFICATE_SUBJECT_KEY_IDENTIFIER = "2.5.29.14";
|
||||
public static final String CA_ISSUERS = "1.3.6.1.5.5.7.48.2";
|
||||
}
|
||||
|
@ -1,90 +1,43 @@
|
||||
package hirs.swid;
|
||||
|
||||
import com.eclipsesource.json.Json;
|
||||
import com.eclipsesource.json.JsonObject;
|
||||
import com.eclipsesource.json.ParseException;
|
||||
import hirs.swid.utils.HashSwid;
|
||||
import hirs.swid.xjc.*;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
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.crypto.dsig.keyinfo.*;
|
||||
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.DOMResult;
|
||||
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.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.*;
|
||||
import javax.xml.crypto.dsig.dom.DOMSignContext;
|
||||
import javax.xml.crypto.dsig.dom.DOMValidateContext;
|
||||
import javax.xml.crypto.dsig.keyinfo.*;
|
||||
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
|
||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import hirs.swid.utils.HashSwid;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.transform.*;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.cert.Certificate;
|
||||
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.List;
|
||||
import java.util.Map;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import hirs.swid.xjc.Directory;
|
||||
import hirs.swid.xjc.Entity;
|
||||
import hirs.swid.xjc.Link;
|
||||
import hirs.swid.xjc.Meta;
|
||||
import hirs.swid.xjc.ObjectFactory;
|
||||
import hirs.swid.xjc.ResourceCollection;
|
||||
import hirs.swid.xjc.SoftwareIdentity;
|
||||
import hirs.swid.xjc.SoftwareMeta;
|
||||
|
||||
import com.eclipsesource.json.Json;
|
||||
import com.eclipsesource.json.JsonObject;
|
||||
import com.eclipsesource.json.ParseException;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@ -94,12 +47,8 @@ import com.eclipsesource.json.ParseException;
|
||||
*/
|
||||
public class SwidTagGateway {
|
||||
|
||||
private static final QName _SHA256_HASH = new QName(
|
||||
"http://www.w3.org/2001/04/xmlenc#sha256", "hash", "SHA256");
|
||||
private final ObjectFactory objectFactory = new ObjectFactory();
|
||||
private JAXBContext jaxbContext;
|
||||
private Marshaller marshaller;
|
||||
private Unmarshaller unmarshaller;
|
||||
private String attributesFile;
|
||||
private boolean defaultCredentials;
|
||||
private String pemPrivateKeyFile;
|
||||
@ -111,9 +60,8 @@ public class SwidTagGateway {
|
||||
*/
|
||||
public SwidTagGateway() {
|
||||
try {
|
||||
jaxbContext = JAXBContext.newInstance(SwidTagConstants.SCHEMA_PACKAGE);
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance(SwidTagConstants.SCHEMA_PACKAGE);
|
||||
marshaller = jaxbContext.createMarshaller();
|
||||
unmarshaller = jaxbContext.createUnmarshaller();
|
||||
attributesFile = SwidTagConstants.DEFAULT_ATTRIBUTES_FILE;
|
||||
defaultCredentials = true;
|
||||
pemCertificateFile = "";
|
||||
@ -220,26 +168,6 @@ public class SwidTagGateway {
|
||||
writeSwidTagFile(signedSoftwareIdentity, filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param path the location of the file to be validated
|
||||
*/
|
||||
public boolean validateSwidTag(String path) throws IOException {
|
||||
Document document = unmarshallSwidTag(path);
|
||||
Element softwareIdentity = (Element) document.getElementsByTagName("SoftwareIdentity").item(0);
|
||||
StringBuilder si = new StringBuilder("Base RIM detected:\n");
|
||||
si.append("SoftwareIdentity name: " + softwareIdentity.getAttribute("name") + "\n");
|
||||
si.append("SoftwareIdentity tagId: " + softwareIdentity.getAttribute("tagId") + "\n");
|
||||
System.out.println(si.toString());
|
||||
Element file = (Element) document.getElementsByTagName("File").item(0);
|
||||
validateFile(file);
|
||||
System.out.println("Signature core validity: " + validateSignedXMLDocument(document));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method writes a Document object out to the file specified by generatedFile.
|
||||
*
|
||||
@ -436,34 +364,11 @@ public class SwidTagGateway {
|
||||
File rimEventLogFile = new File(rimEventLog);
|
||||
file.setSize(new BigInteger(Long.toString(rimEventLogFile.length())));
|
||||
Map<QName, String> attributes = file.getOtherAttributes();
|
||||
addNonNullAttribute(attributes, _SHA256_HASH, HashSwid.get256Hash(rimEventLog));
|
||||
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, ""));
|
||||
addNonNullAttribute(attributes, SwidTagConstants._SHA256_HASH, HashSwid.get256Hash(rimEventLog));
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method validates a hirs.swid.xjc.File from an indirect payload
|
||||
*/
|
||||
private boolean validateFile(Element file) {
|
||||
String filepath;
|
||||
if (rimEventLog.isEmpty()) {
|
||||
filepath = file.getAttribute(SwidTagConstants.NAME);
|
||||
} else {
|
||||
filepath = rimEventLog;
|
||||
}
|
||||
System.out.println("Support rim found at " + filepath);
|
||||
if (HashSwid.get256Hash(filepath).equals(file.getAttribute(_SHA256_HASH.getPrefix() + ":" + _SHA256_HASH.getLocalPart()))) {
|
||||
System.out.println("Support RIM hash verified!");
|
||||
return true;
|
||||
} else {
|
||||
System.out.println("Support RIM hash does not match Base RIM!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates a hirs.swid.xjc.File from a direct payload type.
|
||||
*
|
||||
@ -519,6 +424,8 @@ public class SwidTagGateway {
|
||||
cp.parseJKSCredentials();
|
||||
privateKey = cp.getPrivateKey();
|
||||
publicKey = cp.getPublicKey();
|
||||
KeyName keyName = kiFactory.newKeyName(cp.getCertificateSubjectKeyIdentifier());
|
||||
keyInfoElements.add(keyName);
|
||||
} else {
|
||||
cp.parsePEMCredentials(pemCertificateFile, pemPrivateKeyFile);
|
||||
X509Certificate certificate = cp.getCertificate();
|
||||
@ -530,8 +437,6 @@ public class SwidTagGateway {
|
||||
X509Data data = kiFactory.newX509Data(x509Content);
|
||||
keyInfoElements.add(data);
|
||||
}
|
||||
KeyName keyName = kiFactory.newKeyName(cp.getCertificateSubjectKeyIdentifier());
|
||||
keyInfoElements.add(keyName);
|
||||
KeyValue keyValue = kiFactory.newKeyValue(publicKey);
|
||||
keyInfoElements.add(keyValue);
|
||||
KeyInfo keyinfo = kiFactory.newKeyInfo(keyInfoElements);
|
||||
@ -560,149 +465,4 @@ public class SwidTagGateway {
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new KeySelectorException("No key found!");
|
||||
}
|
||||
|
||||
public boolean areAlgorithmsEqual(String uri, String name) {
|
||||
if (uri.equals(SwidTagConstants.SIGNATURE_ALGORITHM_RSA_SHA256) && name.equalsIgnoreCase("RSA")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private class RIMKeySelectorResult implements KeySelectorResult {
|
||||
private Key key;
|
||||
|
||||
public RIMKeySelectorResult(Key key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public Key getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method unmarshalls the swidtag found at [path] into a Document object
|
||||
* and validates it according to the schema.
|
||||
*
|
||||
* @param path to the input swidtag
|
||||
* @return the SoftwareIdentity element at the root of the swidtag
|
||||
* @throws IOException if the swidtag cannot be unmarshalled or validated
|
||||
*/
|
||||
private Document unmarshallSwidTag(String path) {
|
||||
InputStream is = null;
|
||||
Document document = null;
|
||||
try {
|
||||
document = removeXMLWhitespace(path);
|
||||
is = SwidTagGateway.class.getClassLoader().getResourceAsStream(SwidTagConstants.SCHEMA_URL);
|
||||
SchemaFactory schemaFactory = SchemaFactory.newInstance(SwidTagConstants.SCHEMA_LANGUAGE);
|
||||
Schema schema = schemaFactory.newSchema(new StreamSource(is));
|
||||
unmarshaller.setSchema(schema);
|
||||
unmarshaller.unmarshal(document);
|
||||
} catch (IOException e) {
|
||||
System.out.println(e.getMessage());
|
||||
} catch (SAXException e) {
|
||||
System.out.println("Error setting schema for validation!");
|
||||
} catch (UnmarshalException e) {
|
||||
System.out.println("Error validating swidtag file!");
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("Input file empty.");
|
||||
} catch (JAXBException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
System.out.println("Error closing input stream");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method strips all whitespace from an xml file, including indents and spaces
|
||||
* added for human-readability.
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
private Document removeXMLWhitespace(String path) throws IOException {
|
||||
TransformerFactory tf = TransformerFactory.newInstance();
|
||||
Source source = new StreamSource(
|
||||
SwidTagGateway.class.getClassLoader().getResourceAsStream("identity_transform.xslt"));
|
||||
Document document = null;
|
||||
File input = new File(path);
|
||||
if (input.length() > 0) {
|
||||
try {
|
||||
Transformer transformer = tf.newTransformer(source);
|
||||
DOMResult result = new DOMResult();
|
||||
transformer.transform(new StreamSource(input), result);
|
||||
document = (Document) result.getNode();
|
||||
} catch (TransformerConfigurationException e) {
|
||||
System.out.println("Error configuring transformer!");
|
||||
e.printStackTrace();
|
||||
} catch (TransformerException e) {
|
||||
System.out.println("Error transforming input!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
throw new IOException("Input file is empty!");
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
}
|
||||
|
262
tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagValidator.java
Normal file
262
tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagValidator.java
Normal file
@ -0,0 +1,262 @@
|
||||
package hirs.swid;
|
||||
|
||||
import hirs.swid.utils.HashSwid;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.UnmarshalException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.crypto.*;
|
||||
import javax.xml.crypto.dsig.XMLSignature;
|
||||
import javax.xml.crypto.dsig.XMLSignatureException;
|
||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||
import javax.xml.crypto.dsig.dom.DOMValidateContext;
|
||||
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
|
||||
import javax.xml.crypto.dsig.keyinfo.X509Data;
|
||||
import javax.xml.transform.*;
|
||||
import javax.xml.transform.dom.DOMResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.Key;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class SwidTagValidator {
|
||||
private Unmarshaller unmarshaller;
|
||||
private String rimEventLog;
|
||||
private String certificateFile;
|
||||
|
||||
/**
|
||||
* Setter for rimel file path.
|
||||
* @param rimEventLog
|
||||
*/
|
||||
public void setRimEventLog(String rimEventLog) {
|
||||
this.rimEventLog = rimEventLog;
|
||||
}
|
||||
|
||||
public void setCertificateFile(String certificateFile) {
|
||||
this.certificateFile = certificateFile;
|
||||
}
|
||||
|
||||
public SwidTagValidator() {
|
||||
try {
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance(SwidTagConstants.SCHEMA_PACKAGE);
|
||||
unmarshaller = jaxbContext.createUnmarshaller();
|
||||
rimEventLog = "";
|
||||
certificateFile = "";
|
||||
} catch (JAXBException e) {
|
||||
System.out.println("Error initializing JAXBContext: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param path the location of the file to be validated
|
||||
*/
|
||||
public boolean validateSwidTag(String path) throws IOException {
|
||||
Document document = unmarshallSwidTag(path);
|
||||
Element softwareIdentity = (Element) document.getElementsByTagName("SoftwareIdentity").item(0);
|
||||
StringBuilder si = new StringBuilder("Base RIM detected:\n");
|
||||
si.append("SoftwareIdentity name: " + softwareIdentity.getAttribute("name") + "\n");
|
||||
si.append("SoftwareIdentity tagId: " + softwareIdentity.getAttribute("tagId") + "\n");
|
||||
System.out.println(si.toString());
|
||||
Element file = (Element) document.getElementsByTagName("File").item(0);
|
||||
validateFile(file);
|
||||
System.out.println("Signature core validity: " + validateSignedXMLDocument(document));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method validates a hirs.swid.xjc.File from an indirect payload
|
||||
*/
|
||||
private boolean validateFile(Element file) {
|
||||
String filepath;
|
||||
if (!rimEventLog.isEmpty()) {
|
||||
filepath = rimEventLog;
|
||||
} else {
|
||||
filepath = file.getAttribute(SwidTagConstants.NAME);
|
||||
}
|
||||
System.out.println("Support rim found at " + filepath);
|
||||
if (HashSwid.get256Hash(filepath).equals(
|
||||
file.getAttribute(SwidTagConstants._SHA256_HASH.getPrefix() + ":" +
|
||||
SwidTagConstants._SHA256_HASH.getLocalPart()))) {
|
||||
System.out.println("Support RIM hash verified!" + System.lineSeparator());
|
||||
return true;
|
||||
} else {
|
||||
System.out.println("Support RIM hash does not match Base RIM!" + System.lineSeparator());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method validates a Document with a signature element.
|
||||
*
|
||||
* @param doc
|
||||
*/
|
||||
private boolean validateSignedXMLDocument(Document doc) {
|
||||
DOMValidateContext context = null;
|
||||
boolean isValid = false;
|
||||
try {
|
||||
NodeList nodes = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
|
||||
if (nodes.getLength() == 0) {
|
||||
throw new Exception("Signature element not found!");
|
||||
}
|
||||
NodeList embeddedCert = doc.getElementsByTagName("X509Data");
|
||||
if (embeddedCert.getLength() > 0) {
|
||||
context = new DOMValidateContext(new SwidTagValidator.X509KeySelector(), nodes.item(0));
|
||||
} else {
|
||||
CredentialParser cp = new CredentialParser();
|
||||
if (!certificateFile.isEmpty()) {
|
||||
X509Certificate certificate = cp.parseCertFromPEM(certificateFile);
|
||||
cp.setCertificate(certificate);
|
||||
System.out.println(cp.getCertificateAuthorityInfoAccess());
|
||||
context = new DOMValidateContext(certificate.getPublicKey(), nodes.item(0));
|
||||
} else {
|
||||
System.out.println("Signing certificate not found for validation!");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
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 SwidTagValidator.X509KeySelector.RIMKeySelectorResult(publicKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new KeySelectorException("No key found!");
|
||||
}
|
||||
|
||||
public boolean areAlgorithmsEqual(String uri, String name) {
|
||||
if (uri.equals(SwidTagConstants.SIGNATURE_ALGORITHM_RSA_SHA256) && name.equalsIgnoreCase("RSA")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private class RIMKeySelectorResult implements KeySelectorResult {
|
||||
private Key key;
|
||||
|
||||
public RIMKeySelectorResult(Key key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public Key getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method unmarshalls the swidtag found at [path] into a Document object
|
||||
* and validates it according to the schema.
|
||||
*
|
||||
* @param path to the input swidtag
|
||||
* @return the SoftwareIdentity element at the root of the swidtag
|
||||
* @throws IOException if the swidtag cannot be unmarshalled or validated
|
||||
*/
|
||||
private Document unmarshallSwidTag(String path) {
|
||||
InputStream is = null;
|
||||
Document document = null;
|
||||
try {
|
||||
document = removeXMLWhitespace(path);
|
||||
is = SwidTagGateway.class.getClassLoader().getResourceAsStream(SwidTagConstants.SCHEMA_URL);
|
||||
SchemaFactory schemaFactory = SchemaFactory.newInstance(SwidTagConstants.SCHEMA_LANGUAGE);
|
||||
Schema schema = schemaFactory.newSchema(new StreamSource(is));
|
||||
unmarshaller.setSchema(schema);
|
||||
unmarshaller.unmarshal(document);
|
||||
} catch (IOException e) {
|
||||
System.out.println(e.getMessage());
|
||||
} catch (SAXException e) {
|
||||
System.out.println("Error setting schema for validation!");
|
||||
} catch (UnmarshalException e) {
|
||||
System.out.println("Error validating swidtag file!");
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("Input file empty.");
|
||||
} catch (JAXBException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
System.out.println("Error closing input stream");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method strips all whitespace from an xml file, including indents and spaces
|
||||
* added for human-readability.
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
private Document removeXMLWhitespace(String path) throws IOException {
|
||||
TransformerFactory tf = TransformerFactory.newInstance();
|
||||
Source source = new StreamSource(
|
||||
SwidTagGateway.class.getClassLoader().getResourceAsStream("identity_transform.xslt"));
|
||||
Document document = null;
|
||||
File input = new File(path);
|
||||
if (input.length() > 0) {
|
||||
try {
|
||||
Transformer transformer = tf.newTransformer(source);
|
||||
DOMResult result = new DOMResult();
|
||||
transformer.transform(new StreamSource(input), result);
|
||||
document = (Document) result.getNode();
|
||||
} catch (TransformerConfigurationException e) {
|
||||
System.out.println("Error configuring transformer!");
|
||||
e.printStackTrace();
|
||||
} catch (TransformerException e) {
|
||||
System.out.println("Error transforming input!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
throw new IOException("Input file is empty!");
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
}
|
@ -96,10 +96,15 @@ public class Commander {
|
||||
sb.append("Create a base RIM using the values in attributes.json; " +
|
||||
"sign it with the default keystore, alias, and password;\n");
|
||||
sb.append("and write the data to base_rim.swidtag:\n\n");
|
||||
sb.append("\t\t-c base -a attributes.json -l support_rim.swidtag -o base_rim.swidtag\n\n\n");
|
||||
sb.append("\t\t-c base -a attributes.json -l support_rim.bin -o base_rim.swidtag\n\n\n");
|
||||
sb.append("Create a base RIM using the default attribute values; sign it using privateKey.pem;\n");
|
||||
sb.append("and write the data to console output, to include cert.pem in the signature block:\n\n");
|
||||
sb.append("\t\t-c base -l support_rim.swidtag -k privateKey.pem -p cert.pem\n\n\n");
|
||||
sb.append("and write the data to console output, to embed cert.pem in the signature block:\n\n");
|
||||
sb.append("\t\t-c base -l support_rim.bin -k privateKey.pem -p cert.pem\n\n\n");
|
||||
sb.append("Validate a base RIM using an external support RIM to override the payload file:\n\n");
|
||||
sb.append("\t\t-v base_rim.swidtag -l support_rim.bin\n\n\n");
|
||||
sb.append("Validate a base RIM with an external cert:\n\n");
|
||||
sb.append("\t\t-v base_rim.swidtag -p signing_cert.pem\n\n\n");
|
||||
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import org.testng.annotations.Test;
|
||||
|
||||
public class TestSwidTagGateway {
|
||||
private SwidTagGateway gateway;
|
||||
private SwidTagValidator validator;
|
||||
private final String DEFAULT_OUTPUT = "generated_swidTag.swidtag";
|
||||
private final String DEFAULT_WITH_CERT = "generated_with_cert.swidtag";
|
||||
private final String DEFAULT_NO_CERT = "generated_no_cert.swidtag";
|
||||
@ -28,6 +29,8 @@ public class TestSwidTagGateway {
|
||||
public void setUp() throws Exception {
|
||||
gateway = new SwidTagGateway();
|
||||
gateway.setRimEventLog(supportRimFile);
|
||||
validator = new SwidTagValidator();
|
||||
validator.setRimEventLog(supportRimFile);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
@ -40,6 +43,7 @@ public class TestSwidTagGateway {
|
||||
/**
|
||||
* This test corresponds to the arguments:
|
||||
* -c base -l TpmLog.bin -k privateRimKey.pem -p RimSignCert.pem
|
||||
* where RimSignCert.pem has the AIA extension.
|
||||
*/
|
||||
@Test
|
||||
public void testCreateBaseWithCert() throws URISyntaxException {
|
||||
@ -70,7 +74,7 @@ public class TestSwidTagGateway {
|
||||
@Test
|
||||
public void testValidateSwidTag() {
|
||||
try {
|
||||
Assert.assertTrue(gateway.validateSwidTag(TestSwidTagGateway.class.getClassLoader().getResource(DEFAULT_WITH_CERT).getPath()));
|
||||
Assert.assertTrue(validator.validateSwidTag(TestSwidTagGateway.class.getClassLoader().getResource(DEFAULT_WITH_CERT).getPath()));
|
||||
} catch (IOException e) {
|
||||
Assert.fail("Invalid swidtag!");
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
<Meta xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" rim:bindingSpec="IOT RIM" rim:bindingSpecVersion="1.2" rim:platformManufacturerId="00201234" rim:platformManufacturerStr="Example.com" rim:platformModel="ProductA" rim:rimLinkHash="88f21d8e44d4271149297404df91caf207130bfa116582408abd04ede6db7f51"/>
|
||||
<Payload>
|
||||
<Directory name="iotBase">
|
||||
<File xmlns:SHA256="http://www.w3.org/2001/04/xmlenc#sha256" SHA256:hash="4479ca722623f8c47b703996ced3cbd981b06b1ae8a897db70137e0b7c546848" name="Example.com.iotBase.bin" size="7549"/>
|
||||
<File xmlns:SHA256="http://www.w3.org/2001/04/xmlenc#sha256" SHA256:hash="4479ca722623f8c47b703996ced3cbd981b06b1ae8a897db70137e0b7c546848" name="TpmLog.bin" size="7549"/>
|
||||
</Directory>
|
||||
</Payload>
|
||||
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
@ -17,14 +17,14 @@
|
||||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||
</Transforms>
|
||||
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
|
||||
<DigestValue>HEzVxviL8a3g7VhLtkMDabH2f9n/3mPwEg1NRJBYLA0=</DigestValue>
|
||||
<DigestValue>jpPZu16C8KjtwY2JpJuyR3SBc2XclVEaVsv/DgyZKTM=</DigestValue>
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue>Qjg51EQPVS5paqBbw8e0b8lu4yqzWUEdvE2S64bvt59f6LPaG+1EDgQCimgXMdIg/+tSR4Wou6Hr
|
||||
u0ym8K6RqoipWBbF2KNVtR8vCavJblVA+6tCd+iLnFiQ/b2Zud/v/DZq89wQ/hKX0WoskSy/3tiT
|
||||
ariMcpP75dYO1b/tYkMshPo0/F0p39VoZxhGDahmYTRT0Wt4KQeIVe/4nDXEu+EbIi18yHVHYFWq
|
||||
uO/hC+BoKd/xBKmQnhtGkT4y3vETOoCr0TOHpRUClKC/nL0FhL9hPtpwhPBhakLtbi1WOwBnpxjV
|
||||
zFAR1SzeOG87S2Cl8pSDXjwfzHzzcPaJKpXj2g==</SignatureValue>
|
||||
<SignatureValue>pWPozFWH2oytfgZse1Ai769c/cBFS/vapKj27asI8XDLdK8FkNs2K/+OTf4lScBiPLTCvWPIihoe
|
||||
hielmV8dWZqvR2z09pr+yCF7q/E8sCGhQXSsVlNZjElMXk2Qz2c6C9XtRk4UNmSfTSYsKEm2AST4
|
||||
oh6da+x1CeSHipALfuZZrXwa2AMtc9yTNfqaQFBxRqEDeTypLwNQqdr9va2T8C9ZNnEzooTf5FWw
|
||||
OUqc+Ewk5V9ZyOJ/0UdUxs40mGPpsIG90ikx59eu1A4qP4BzjHR3vrNbYDA4hBeIpDHC4vzwJrR4
|
||||
xqXw1SLqAm8ngL9Haj2Ww+y0PEZfo++JlOMZuQ==</SignatureValue>
|
||||
<KeyInfo>
|
||||
<KeyName>2fdeb8e7d030a2209daa01861a964fedecf2bcc1</KeyName>
|
||||
<KeyValue>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<Meta xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" rim:bindingSpec="IOT RIM" rim:bindingSpecVersion="1.2" rim:platformManufacturerId="00201234" rim:platformManufacturerStr="Example.com" rim:platformModel="ProductA" rim:rimLinkHash="88f21d8e44d4271149297404df91caf207130bfa116582408abd04ede6db7f51"/>
|
||||
<Payload>
|
||||
<Directory name="iotBase">
|
||||
<File xmlns:SHA256="http://www.w3.org/2001/04/xmlenc#sha256" SHA256:hash="4479ca722623f8c47b703996ced3cbd981b06b1ae8a897db70137e0b7c546848" name="Example.com.iotBase.bin" size="7549"/>
|
||||
<File xmlns:SHA256="http://www.w3.org/2001/04/xmlenc#sha256" SHA256:hash="4479ca722623f8c47b703996ced3cbd981b06b1ae8a897db70137e0b7c546848" name="TpmLog.bin" size="7549"/>
|
||||
</Directory>
|
||||
</Payload>
|
||||
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
@ -17,36 +17,36 @@
|
||||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||
</Transforms>
|
||||
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
|
||||
<DigestValue>HEzVxviL8a3g7VhLtkMDabH2f9n/3mPwEg1NRJBYLA0=</DigestValue>
|
||||
<DigestValue>jpPZu16C8KjtwY2JpJuyR3SBc2XclVEaVsv/DgyZKTM=</DigestValue>
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue>Qjg51EQPVS5paqBbw8e0b8lu4yqzWUEdvE2S64bvt59f6LPaG+1EDgQCimgXMdIg/+tSR4Wou6Hr
|
||||
u0ym8K6RqoipWBbF2KNVtR8vCavJblVA+6tCd+iLnFiQ/b2Zud/v/DZq89wQ/hKX0WoskSy/3tiT
|
||||
ariMcpP75dYO1b/tYkMshPo0/F0p39VoZxhGDahmYTRT0Wt4KQeIVe/4nDXEu+EbIi18yHVHYFWq
|
||||
uO/hC+BoKd/xBKmQnhtGkT4y3vETOoCr0TOHpRUClKC/nL0FhL9hPtpwhPBhakLtbi1WOwBnpxjV
|
||||
zFAR1SzeOG87S2Cl8pSDXjwfzHzzcPaJKpXj2g==</SignatureValue>
|
||||
<SignatureValue>pWPozFWH2oytfgZse1Ai769c/cBFS/vapKj27asI8XDLdK8FkNs2K/+OTf4lScBiPLTCvWPIihoe
|
||||
hielmV8dWZqvR2z09pr+yCF7q/E8sCGhQXSsVlNZjElMXk2Qz2c6C9XtRk4UNmSfTSYsKEm2AST4
|
||||
oh6da+x1CeSHipALfuZZrXwa2AMtc9yTNfqaQFBxRqEDeTypLwNQqdr9va2T8C9ZNnEzooTf5FWw
|
||||
OUqc+Ewk5V9ZyOJ/0UdUxs40mGPpsIG90ikx59eu1A4qP4BzjHR3vrNbYDA4hBeIpDHC4vzwJrR4
|
||||
xqXw1SLqAm8ngL9Haj2Ww+y0PEZfo++JlOMZuQ==</SignatureValue>
|
||||
<KeyInfo>
|
||||
<X509Data>
|
||||
<X509SubjectName>CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US</X509SubjectName>
|
||||
<X509Certificate>MIIDoTCCAomgAwIBAgIJAPB+r6VBhBn5MA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAlVTMQsw
|
||||
<X509Certificate>MIID2jCCAsKgAwIBAgIJAP0uwoNdwZDFMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAlVTMQsw
|
||||
CQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxEjAQBgNVBAMM
|
||||
CUV4YW1wbGVDQTAeFw0yMDAzMTExODExMjJaFw0zMDAxMTgxODExMjJaMFwxCzAJBgNVBAYTAlVT
|
||||
CUV4YW1wbGVDQTAeFw0yMDA3MjEyMTQ1MDBaFw0zMDA1MzAyMTQ1MDBaMFwxCzAJBgNVBAYTAlVT
|
||||
MQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxGzAZBgNV
|
||||
BAMMEmV4YW1wbGUuUklNLnNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd1
|
||||
lWGkSRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44/nBaccZD
|
||||
OjdfIxIUCMfwhGXjxCaqZbgTucNsExDnu4arTGraoAwzHg0cVLiKT/Cxj9NL4dcMgxRXsPdHfXb0
|
||||
923C7xYd2t2qfW05umgaj7qeQl6c68CFNsGX4JA8rWFQZvvGx5DGlK4KTcjPuQQINs5fxasNKqLY
|
||||
2hq+z82x/rqwr2hmyizD6FpFSyIABPEMPfB036GEhRwu1WEMkq8yIp2jgRUoFYke9pB3ph9pVow0
|
||||
Hh4mNFSKD4pP41VSKY1nus83mdkuukPy5o0CAwEAAaNvMG0wHQYDVR0OBBYEFC/euOfQMKIgnaoB
|
||||
hhqWT+3s8rzBMB8GA1UdIwQYMBaAFEahuO3bpnFf0NLneoo8XW6aw5Y4MAkGA1UdEwQCMAAwCwYD
|
||||
VR0PBAQDAgbAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUAA4IBAQBl2Bu9xpnH
|
||||
CCeeebjx+ILQXJXBd6q5+NQlV3zzBrf0bleZRtsOmsuFvWQoKQxsfZuk7QcSvVd/1v8mqwJ0PwbF
|
||||
KQmrhIPWP+iowiBNqpG5PH9YxhpHQ1osOfibNLOXMhudIQRY0yAgqQf+MOlXYa0stX8gkgftVBDR
|
||||
utuMKyOTf4a6d8TUcbG2RnyzO/6S9bq4cPDYLqWRBM+aGN8e00UWTKpBl6/1EU8wkJA6WdllK2e8
|
||||
mVkXUPWYyHTZ0qQnrYiuLr36ycAznABDzEAoj4tMZbjIAfuscty6Ggzxl1WbyZLI6YzyXALwaYvr
|
||||
crTLeyFynlKxuCfDnr1SAHDM65BY</X509Certificate>
|
||||
Hh4mNFSKD4pP41VSKY1nus83mdkuukPy5o0CAwEAAaOBpzCBpDAdBgNVHQ4EFgQUL96459AwoiCd
|
||||
qgGGGpZP7ezyvMEwHwYDVR0jBBgwFoAURqG47dumcV/Q0ud6ijxdbprDljgwCQYDVR0TBAIwADAL
|
||||
BgNVHQ8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwNQYIKwYBBQUHAQEEKTAnMCUGCCsGAQUF
|
||||
BzAChhlodHRwczovL2V4YW1wbGUuY29tL2NlcnRzMA0GCSqGSIb3DQEBCwUAA4IBAQDpKx5oQlkS
|
||||
11cg7Qp58BmCvjCzFpof+qYePooJsD3i5SwKfRTa2CkDMww9qrwBK7G60y7jhe5InKTdqIlVqaji
|
||||
5ZImR0QMKTtk7zt9AJ9EaEzKxfDiE/qX34KxNe4ZmbvLH8N+BSujQXMMi56zGjW469Y/rbDMG8uU
|
||||
1dq3zqhO5b+dUr1ecdkYLgzxu6O+oWy5JpVibmcjvNezJsUtjc+km2FYm24vU3/fCNzZ2z0EHQES
|
||||
cIEQ5OqfpdFrV3De238RhMH6J4xePSidnFpfBc6FrdyDI1A8eRFz36I4xfVL3ZnJP/+j+NE4q6yz
|
||||
5VGvm0npLO394ZihtsI1sRAR8ORJ</X509Certificate>
|
||||
</X509Data>
|
||||
<KeyName>2fdeb8e7d030a2209daa01861a964fedecf2bcc1</KeyName>
|
||||
<KeyValue>
|
||||
<RSAKeyValue>
|
||||
<Modulus>p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx
|
||||
|
Loading…
x
Reference in New Issue
Block a user