Merge pull request #449 from nsacyber/issue-441

[#441] tcg_rim_tool option to embed cert in signature
This commit is contained in:
chubtub 2022-08-25 11:34:14 -04:00 committed by GitHub
commit a8a6b61e9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 413 additions and 191 deletions

View File

@ -49,6 +49,7 @@ public class Main {
String jksTruststoreFile = commander.getTruststoreFile();
String certificateFile = commander.getPublicCertificate();
String privateKeyFile = commander.getPrivateKeyFile();
boolean embeddedCert = commander.isEmbedded();
boolean defaultKey = commander.isDefaultKey();
String rimEventLog = commander.getRimEventLog();
switch (createType) {
@ -63,6 +64,9 @@ public class Main {
gateway.setDefaultCredentials(false);
gateway.setPemCertificateFile(certificateFile);
gateway.setPemPrivateKeyFile(privateKeyFile);
if (embeddedCert) {
gateway.setEmbeddedCert(true);
}
} else if (defaultKey){
gateway.setDefaultCredentials(true);
gateway.setJksTruststoreFile(SwidTagConstants.DEFAULT_KEYSTORE_FILE);

View File

@ -15,7 +15,7 @@ public class SwidTagConstants {
public static final String DEFAULT_KEYSTORE_FILE = "/opt/hirs/rimtool/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 = "rim_fields.json";
public static final String DEFAULT_ATTRIBUTES_FILE = "/opt/hirs/rimtool/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";

View File

@ -53,6 +53,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
@ -76,6 +77,7 @@ public class SwidTagGateway {
private String jksTruststoreFile;
private String pemPrivateKeyFile;
private String pemCertificateFile;
private boolean embeddedCert;
private String rimEventLog;
/**
@ -88,6 +90,7 @@ public class SwidTagGateway {
attributesFile = SwidTagConstants.DEFAULT_ATTRIBUTES_FILE;
defaultCredentials = true;
pemCertificateFile = "";
embeddedCert = false;
rimEventLog = "";
} catch (JAXBException e) {
System.out.println("Error initializing jaxbcontext: " + e.getMessage());
@ -99,7 +102,7 @@ public class SwidTagGateway {
*
* @param attributesFile
*/
public void setAttributesFile(String attributesFile) {
public void setAttributesFile(final String attributesFile) {
this.attributesFile = attributesFile;
}
@ -109,7 +112,7 @@ public class SwidTagGateway {
* @param defaultCredentials
* @return
*/
public void setDefaultCredentials(boolean defaultCredentials) {
public void setDefaultCredentials(final boolean defaultCredentials) {
this.defaultCredentials = defaultCredentials;
}
@ -118,7 +121,7 @@ public class SwidTagGateway {
*
* @param jksTruststoreFile
*/
public void setJksTruststoreFile(String jksTruststoreFile) {
public void setJksTruststoreFile(final String jksTruststoreFile) {
this.jksTruststoreFile = jksTruststoreFile;
}
@ -127,7 +130,7 @@ public class SwidTagGateway {
*
* @param pemPrivateKeyFile
*/
public void setPemPrivateKeyFile(String pemPrivateKeyFile) {
public void setPemPrivateKeyFile(final String pemPrivateKeyFile) {
this.pemPrivateKeyFile = pemPrivateKeyFile;
}
@ -136,16 +139,25 @@ public class SwidTagGateway {
*
* @param pemCertificateFile
*/
public void setPemCertificateFile(String pemCertificateFile) {
public void setPemCertificateFile(final String pemCertificateFile) {
this.pemCertificateFile = pemCertificateFile;
}
/**
* Setter to embed certificate file in signature block
*
* @param embeddedCert
*/
public void setEmbeddedCert(final boolean embeddedCert) {
this.embeddedCert = embeddedCert;
}
/**
* Setter for event log support RIM
*
* @param rimEventLog
*/
public void setRimEventLog(String rimEventLog) {
public void setRimEventLog(final String rimEventLog) {
this.rimEventLog = rimEventLog;
}
@ -210,7 +222,7 @@ public class SwidTagGateway {
*
* @param swidTag
*/
public void writeSwidTagFile(Document swidTag, String output) {
public void writeSwidTagFile(final Document swidTag, final String output) {
try {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
@ -238,7 +250,7 @@ public class SwidTagGateway {
* @param jsonObject the Properties object containing parameters from file
* @return SoftwareIdentity object created from the properties
*/
private SoftwareIdentity createSwidTag(JsonObject jsonObject) {
private SoftwareIdentity createSwidTag(final JsonObject jsonObject) {
SoftwareIdentity swidTag = objectFactory.createSoftwareIdentity();
swidTag.setLang(SwidTagConstants.DEFAULT_ENGLISH);
String name = jsonObject.getString(SwidTagConstants.NAME, "");
@ -271,7 +283,7 @@ public class SwidTagGateway {
* @param jsonObject the Properties object containing parameters from file
* @return Entity object created from the properties
*/
private Entity createEntity(JsonObject jsonObject) {
private Entity createEntity(final JsonObject jsonObject) {
boolean isTagCreator = false;
Entity entity = objectFactory.createEntity();
String name = jsonObject.getString(SwidTagConstants.NAME, "");
@ -309,7 +321,7 @@ public class SwidTagGateway {
* @param jsonObject the Properties object containing parameters from file
* @return Link element created from the properties
*/
private Link createLink(JsonObject jsonObject) {
private Link createLink(final JsonObject jsonObject) {
Link link = objectFactory.createLink();
String href = jsonObject.getString(SwidTagConstants.HREF, "");
if (!href.isEmpty()) {
@ -330,7 +342,7 @@ public class SwidTagGateway {
* @param jsonObject the Properties object containing parameters from file
* @return the Meta element created from the properties
*/
private SoftwareMeta createSoftwareMeta(JsonObject jsonObject) {
private SoftwareMeta createSoftwareMeta(final JsonObject jsonObject) {
SoftwareMeta softwareMeta = objectFactory.createSoftwareMeta();
Map<QName, String> attributes = softwareMeta.getOtherAttributes();
addNonNullAttribute(attributes, SwidTagConstants._COLLOQUIAL_VERSION,
@ -379,7 +391,7 @@ public class SwidTagGateway {
* @param jsonObject the Properties object containing parameters from file
* @return the Payload object created
*/
private ResourceCollection createPayload(JsonObject jsonObject) {
private ResourceCollection createPayload(final JsonObject jsonObject) {
ResourceCollection payload = objectFactory.createResourceCollection();
Map<QName, String> attributes = payload.getOtherAttributes();
addNonNullAttribute(attributes, SwidTagConstants._N8060_ENVVARPREFIX,
@ -388,6 +400,12 @@ public class SwidTagGateway {
jsonObject.getString(SwidTagConstants._N8060_ENVVARSUFFIX.getLocalPart(), ""));
addNonNullAttribute(attributes, SwidTagConstants._N8060_PATHSEPARATOR,
jsonObject.getString(SwidTagConstants._N8060_PATHSEPARATOR.getLocalPart(), ""));
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_FORMAT,
jsonObject.getString(SwidTagConstants.SUPPORT_RIM_FORMAT, ""));
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_TYPE,
jsonObject.getString(SwidTagConstants.SUPPORT_RIM_TYPE, ""));
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_URI_GLOBAL,
jsonObject.getString(SwidTagConstants.SUPPORT_RIM_URI_GLOBAL, ""));
return payload;
}
@ -398,7 +416,7 @@ public class SwidTagGateway {
* @param jsonObject the Properties object containing parameters from file
* @return Directory object created from the properties
*/
private Directory createDirectory(JsonObject jsonObject) {
private Directory createDirectory(final JsonObject jsonObject) {
Directory directory = objectFactory.createDirectory();
directory.setName(jsonObject.getString(SwidTagConstants.NAME, ""));
Map<QName, String> attributes = directory.getOtherAttributes();
@ -428,7 +446,7 @@ public class SwidTagGateway {
* @param jsonObject the Properties object containing parameters from file
* @return File object created from the properties
*/
private hirs.swid.xjc.File createFile(JsonObject jsonObject) {
private hirs.swid.xjc.File createFile(final JsonObject jsonObject) {
hirs.swid.xjc.File file = objectFactory.createFile();
file.setName(jsonObject.getString(SwidTagConstants.NAME, ""));
Map<QName, String> attributes = file.getOtherAttributes();
@ -448,7 +466,8 @@ public class SwidTagGateway {
jsonObject.getString(SwidTagConstants.SUPPORT_RIM_URI_GLOBAL, ""));
File rimEventLogFile = new File(rimEventLog);
file.setSize(new BigInteger(Long.toString(rimEventLogFile.length())));
addNonNullAttribute(attributes, SwidTagConstants._SHA256_HASH, HashSwid.get256Hash(rimEventLog));
addNonNullAttribute(attributes, SwidTagConstants._SHA256_HASH,
HashSwid.get256Hash(rimEventLog));
return file;
}
@ -460,7 +479,8 @@ public class SwidTagGateway {
* @param key
* @param value
*/
private void addNonNullAttribute(Map<QName, String> attributes, QName key, String value) {
private void addNonNullAttribute(final Map<QName, String> attributes,
final QName key, String value) {
if (!value.isEmpty()) {
attributes.put(key, value);
}
@ -470,20 +490,23 @@ public class SwidTagGateway {
* This method signs a SoftwareIdentity with an xmldsig in compatibility mode.
* Current assumptions: digest method SHA256, signature method SHA256, enveloped signature
*/
private Document signXMLDocument(JAXBElement<SoftwareIdentity> swidTag) {
private Document signXMLDocument(final 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)),
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),
sigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null),
sigFactory.newSignatureMethod(SwidTagConstants.SIGNATURE_ALGORITHM_RSA_SHA256,
null),
Collections.singletonList(reference)
);
List<XMLStructure> keyInfoElements = new ArrayList<XMLStructure>();
@ -500,11 +523,15 @@ public class SwidTagGateway {
cp.parsePEMCredentials(pemCertificateFile, pemPrivateKeyFile);
X509Certificate certificate = cp.getCertificate();
privateKey = cp.getPrivateKey();
ArrayList<Object> x509Content = new ArrayList<Object>();
x509Content.add(certificate.getSubjectX500Principal().getName());
x509Content.add(certificate);
X509Data data = kiFactory.newX509Data(x509Content);
keyInfoElements.add(data);
if (embeddedCert) {
ArrayList<Object> x509Content = new ArrayList<Object>();
x509Content.add(certificate.getSubjectX500Principal().getName());
x509Content.add(certificate);
X509Data data = kiFactory.newX509Data(x509Content);
keyInfoElements.add(data);
} else {
keyInfoElements.add(kiFactory.newKeyValue(certificate.getPublicKey()));
}
}
KeyInfo keyinfo = kiFactory.newKeyInfo(keyInfoElements);
@ -526,6 +553,9 @@ public class SwidTagGateway {
System.out.println("Error marshaling signed swidtag: " + e.getMessage());
} catch (MarshalException | XMLSignatureException e) {
System.out.println("Error while signing SoftwareIdentity: " + e.getMessage());
} catch (KeyException e) {
System.out.println("Public key algorithm not recognized or supported: "
+ e.getMessage());
}
return doc;

View File

@ -4,7 +4,6 @@ import hirs.swid.utils.HashSwid;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
@ -25,6 +24,7 @@ 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.KeyValue;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
@ -39,10 +39,9 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
@ -51,9 +50,7 @@ import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.util.Arrays;
import java.util.Base64;
import java.util.Iterator;
import java.util.List;
@ -65,6 +62,7 @@ public class SwidTagValidator {
private String rimEventLog;
private String certificateFile;
private String trustStoreFile;
private List<X509Certificate> trustStore;
/**
* Ensure that BouncyCastle is configured as a javax.security.Security provider, as this
@ -117,7 +115,7 @@ public class SwidTagValidator {
System.out.println(si.toString());
Element file = (Element) document.getElementsByTagName("File").item(0);
validateFile(file);
System.out.println("Signature core validity: " + validateSignedXMLDocument(document));
validateSignedXMLDocument(document);
return true;
}
@ -158,40 +156,49 @@ public class SwidTagValidator {
DOMValidateContext context;
CredentialParser cp = new CredentialParser();
X509Certificate signingCert = null;
List<X509Certificate> trustStore = cp.parseCertsFromPEM(trustStoreFile);
trustStore = cp.parseCertsFromPEM(trustStoreFile);
X509KeySelector keySelector = new X509KeySelector();
NodeList nodes = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
if (nodes.getLength() == 0) {
throw new Exception("Signature element not found!");
}
NodeList embeddedCert = doc.getElementsByTagName("X509Certificate");
if (embeddedCert.getLength() > 0) {
context = new DOMValidateContext(new X509KeySelector(), nodes.item(0));
signingCert = cp.parseCertFromPEMString(embeddedCert.item(0).getTextContent());
} else {
String skId = doc.getElementsByTagName("KeyName").item(0).getTextContent();
for (X509Certificate trustedCert : trustStore) {
String trustedSkId = cp.getCertificateSubjectKeyIdentifier(trustedCert);
if (skId.equals(trustedSkId)) {
signingCert = trustedCert;
break;
context = new DOMValidateContext(keySelector, nodes.item(0));
}
NodeList keyName = doc.getElementsByTagName("KeyName");
if (keyName.getLength() > 0) {
String skId = keyName.item(0).getTextContent();
if (skId != null && !skId.isEmpty()) {
for (X509Certificate trustedCert : trustStore) {
String trustedSkId = cp.getCertificateSubjectKeyIdentifier(trustedCert);
if (skId.equals(trustedSkId)) {
signingCert = trustedCert;
break;
}
}
}
if (signingCert == null) {
System.out.println("Issuer certificate with subject key identifier = "
+ skId + " not found");
if (signingCert != null) {
context = new DOMValidateContext(signingCert.getPublicKey(),
nodes.item(0));
} else {
System.out.println("Issuer certificate with subject key identifier = "
+ skId + " not found");
System.exit(1);
}
} else {
System.out.println("Base RIM must have a non-empty, non-null " +
"Subject Key Identifier (SKID) in the <KeyName> element");
System.exit(1);
}
context = new DOMValidateContext(signingCert.getPublicKey(), nodes.item(0));
}
cp.setCertificate(signingCert);
System.out.println(cp.getCertificateAuthorityInfoAccess());
XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
XMLSignature signature = sigFactory.unmarshalXMLSignature(context);
boolean signatureIsValid = signature.validate(context);
boolean certChainIsValid = validateCertChain(signingCert, trustStore);
System.out.println("Signature validity: " + signatureIsValid);
System.out.println("Cert chain validity: " + certChainIsValid);
return signatureIsValid && certChainIsValid;
if (signingCert == null) {
signingCert = keySelector.getSigningCert();
}
cp.setCertificate(signingCert);
System.out.println(System.lineSeparator() + cp.getCertificateAuthorityInfoAccess());
return signatureIsValid;
} catch (FileNotFoundException e) {
System.out.println("Error parsing truststore: " + e.getMessage());
} catch (NoSuchAlgorithmException e) {
@ -208,112 +215,21 @@ public class SwidTagValidator {
return false;
}
/**
* This method validates the cert chain for a given certificate. The truststore is iterated
* over until a root CA is found, otherwise an error is returned.
* @param cert the certificate at the start of the chain
* @param trustStore from which to find the chain of intermediate and root CAs
* @return true if the chain is valid
* @throws Exception if a valid chain is not found in the truststore
*/
private boolean validateCertChain(final X509Certificate cert,
final List<X509Certificate> trustStore)
throws Exception {
if (cert == null || trustStore == null) {
throw new Exception("Null certificate or truststore received");
} else if (trustStore.size() == 0) {
throw new Exception("Truststore is empty");
}
final String INT_CA_ERROR = "Intermediate CA found, searching for root CA";
String errorMessage = "";
X509Certificate startOfChain = cert;
do {
for (X509Certificate trustedCert : trustStore) {
boolean isIssuer = areYouMyIssuer(startOfChain, trustedCert);
boolean isSigner = areYouMySigner(startOfChain, trustedCert);
if (isIssuer && isSigner) {
if (isSelfSigned(trustedCert)) {
return true;
} else {
startOfChain = trustedCert;
errorMessage = INT_CA_ERROR;
break;
}
} else {
if (!isIssuer) {
errorMessage = "Issuer cert not found";
} else if (!isSigner) {
errorMessage = "Signing cert not found";
}
}
}
} while (errorMessage.equals(INT_CA_ERROR));
throw new Exception("Error while validating cert chain: " + errorMessage);
}
/**
* This method checks if cert's issuerDN matches issuer's subjectDN.
* @param cert the signed certificate
* @param issuer the signing certificate
* @return true if they match, false if not
* @throws Exception if either argument is null
*/
private boolean areYouMyIssuer(final X509Certificate cert, final X509Certificate issuer)
throws Exception {
if (cert == null || issuer == null) {
throw new Exception("Cannot verify issuer, null certificate received");
}
X500Principal issuerDN = new X500Principal(cert.getIssuerX500Principal().getName());
return issuer.getSubjectX500Principal().equals(issuerDN);
}
/**
* This method checks if cert's signature matches signer's public key.
* @param cert the signed certificate
* @param signer the signing certificate
* @return true if they match
* @throws Exception if an error occurs or there is no match
*/
private boolean areYouMySigner(final X509Certificate cert, final X509Certificate signer)
throws Exception {
if (cert == null || signer == null) {
throw new Exception("Cannot verify signature, null certificate received");
}
try {
cert.verify(signer.getPublicKey(), BouncyCastleProvider.PROVIDER_NAME);
return true;
} catch (NoSuchAlgorithmException e) {
throw new Exception("Signing algorithm in signing cert not supported");
} catch (InvalidKeyException e) {
throw new Exception("Signing certificate key does not match signature");
} catch (NoSuchProviderException e) {
throw new Exception("Error with BouncyCastleProvider: " + e.getMessage());
} catch (SignatureException e) {
String error = "Error with signature: " + e.getMessage()
+ System.lineSeparator()
+ "Certificate needed for verification is missing: "
+ signer.getSubjectX500Principal().getName();
throw new Exception(error);
} catch (CertificateException e) {
throw new Exception("Encoding error: " + e.getMessage());
}
}
/**
* This method checks if a given certificate is self signed or not.
* @param cert the cert to check
* @return true if self signed, false if not
*/
private boolean isSelfSigned(final X509Certificate cert) {
return cert.getIssuerX500Principal().equals(cert.getSubjectX500Principal());
}
/**
* This internal class handles parsing the public key from a KeyInfo element.
*/
public class X509KeySelector extends KeySelector {
PublicKey publicKey;
X509Certificate signingCert;
public PublicKey getPublicKey() {
return publicKey;
}
public X509Certificate getSigningCert() {
return signingCert;
}
/**
* This method extracts a public key from either an X509Certificate element
* or a KeyValue element. If the public key's algorithm matches the declared
@ -339,12 +255,41 @@ public class SwidTagValidator {
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);
X509Certificate embeddedCert = (X509Certificate) object;
try {
if (isCertChainValid(embeddedCert)) {
publicKey = ((X509Certificate) embeddedCert).getPublicKey();
signingCert = embeddedCert;
System.out.println("Certificate chain validity: true");
}
} catch (Exception e) {
System.out.println("Certificate chain invalid: "
+ e.getMessage());
}
}
}
} else if (element instanceof KeyValue) {
try {
PublicKey pk = ((KeyValue) element).getPublicKey();
if (isPublicKeyTrusted(pk)) {
publicKey = pk;
try {
System.out.println("Certificate chain validity: "
+ isCertChainValid(signingCert));
} catch (Exception e) {
System.out.println("Certificate chain invalid: "
+ e.getMessage());
}
}
} catch (KeyException e) {
System.out.println("Unable to convert KeyValue data to PK.");
}
}
if (publicKey != null) {
if (areAlgorithmsEqual(algorithm.getAlgorithm(), publicKey.getAlgorithm())) {
return new
SwidTagValidator.X509KeySelector.RIMKeySelectorResult(publicKey);
}
}
}
throw new KeySelectorException("No key found!");
@ -361,6 +306,123 @@ public class SwidTagValidator {
&& name.equalsIgnoreCase("RSA");
}
/**
* This method validates the cert chain for a given certificate. The truststore is iterated
* over until a root CA is found, otherwise an error is returned.
* @param cert the certificate at the start of the chain
* @return true if the chain is valid
* @throws Exception if a valid chain is not found in the truststore
*/
private boolean isCertChainValid(final X509Certificate cert)
throws Exception {
if (cert == null || trustStore == null) {
throw new Exception("Null certificate or truststore received");
} else if (trustStore.size() == 0) {
throw new Exception("Truststore is empty");
}
final String INT_CA_ERROR = "Intermediate CA found, searching for root CA";
String errorMessage = "";
X509Certificate startOfChain = cert;
do {
for (X509Certificate trustedCert : trustStore) {
boolean isIssuer = areYouMyIssuer(startOfChain, trustedCert);
boolean isSigner = areYouMySigner(startOfChain, trustedCert);
if (isIssuer && isSigner) {
if (isSelfSigned(trustedCert)) {
return true;
} else {
startOfChain = trustedCert;
errorMessage = INT_CA_ERROR;
break;
}
} else {
if (!isIssuer) {
errorMessage = "Issuer cert not found";
} else if (!isSigner) {
errorMessage = "Signing cert not found";
}
}
}
} while (errorMessage.equals(INT_CA_ERROR));
throw new Exception("Error while validating cert chain: " + errorMessage);
}
/**
* This method checks if cert's issuerDN matches issuer's subjectDN.
* @param cert the signed certificate
* @param issuer the signing certificate
* @return true if they match, false if not
* @throws Exception if either argument is null
*/
private boolean areYouMyIssuer(final X509Certificate cert, final X509Certificate issuer)
throws Exception {
if (cert == null || issuer == null) {
throw new Exception("Cannot verify issuer, null certificate received");
}
X500Principal issuerDN = new X500Principal(cert.getIssuerX500Principal().getName());
return issuer.getSubjectX500Principal().equals(issuerDN);
}
/**
* This method checks if cert's signature matches signer's public key.
* @param cert the signed certificate
* @param signer the signing certificate
* @return true if they match
* @throws Exception if an error occurs or there is no match
*/
private boolean areYouMySigner(final X509Certificate cert, final X509Certificate signer)
throws Exception {
if (cert == null || signer == null) {
throw new Exception("Cannot verify signature, null certificate received");
}
try {
cert.verify(signer.getPublicKey(), BouncyCastleProvider.PROVIDER_NAME);
return true;
} catch (NoSuchAlgorithmException e) {
throw new Exception("Signing algorithm in signing cert not supported");
} catch (InvalidKeyException e) {
throw new Exception("Signing certificate key does not match signature");
} catch (NoSuchProviderException e) {
throw new Exception("Error with BouncyCastleProvider: " + e.getMessage());
} catch (SignatureException e) {
String error = "Error with signature: " + e.getMessage()
+ System.lineSeparator()
+ "Certificate needed for verification is missing: "
+ signer.getSubjectX500Principal().getName();
throw new Exception(error);
} catch (CertificateException e) {
throw new Exception("Encoding error: " + e.getMessage());
}
}
/**
* This method checks if a given certificate is self signed or not.
* @param cert the cert to check
* @return true if self signed, false if not
*/
private boolean isSelfSigned(final X509Certificate cert) {
return cert.getIssuerX500Principal().equals(cert.getSubjectX500Principal());
}
/**
* This method compares a public key against those in the truststore.
* @param pk a public key
* @return true if pk is found in the trust store, false otherwise
*/
private boolean isPublicKeyTrusted(final PublicKey pk) {
for (X509Certificate trustedCert : trustStore) {
if (Arrays.equals(trustedCert.getPublicKey().getEncoded(),
pk.getEncoded())) {
signingCert = trustedCert;
return true;
}
}
return false;
}
private class RIMKeySelectorResult implements KeySelectorResult {
private Key key;

View File

@ -36,10 +36,13 @@ public class Commander {
description = "The public key certificate to embed in the base RIM created by "
+ "this tool.")
private String publicCertificate = "";
@Parameter(names = {"-d", "--default-key"},
@Parameter(names = {"-e", "--embed-cert"}, order = 7,
description = "Embed the provided certificate in the signed swidtag.")
private boolean embedded = false;
@Parameter(names = {"-d", "--default-key"}, order = 8,
description = "Use default signing credentials.")
private boolean defaultKey = false;
@Parameter(names = {"-l", "--rimel <path>"}, order = 7,
@Parameter(names = {"-l", "--rimel <path>"}, order = 9,
description = "The TCG eventlog file to use as a support RIM.")
private String rimEventLog = "";
@ -73,6 +76,8 @@ public class Commander {
return publicCertificate;
}
public boolean isEmbedded() { return embedded; }
public boolean isDefaultKey() { return defaultKey; }
public String getRimEventLog() { return rimEventLog; }
@ -82,11 +87,12 @@ public class Commander {
sb.append("Create a base RIM using the values in attributes.json; " +
"sign it with the default keystore; ");
sb.append("and write the data to base_rim.swidtag:\n\n");
sb.append("\t\t-c base -a attributes.json -d -l support_rim.bin -o base_rim.swidtag\n\n\n");
sb.append("\t\t-c base -a attributes.json -d -l support_rim.bin -o base_rim.swidtag" +
"\n\n\n");
sb.append("Create a base RIM using the default attribute values; ");
sb.append("sign it using privateKey.pem; embed cert.pem in the signature block; ");
sb.append("and write the data to console output:\n\n");
sb.append("\t\t-c base -l support_rim.bin -k privateKey.pem -p cert.pem\n\n\n");
sb.append("\t\t-c base -l support_rim.bin -k privateKey.pem -p cert.pem -e\n\n\n");
sb.append("Validate a base RIM using an external support RIM to override the ");
sb.append("payload file:\n\n");
sb.append("\t\t-v base_rim.swidtag -l support_rim.bin\n\n\n");
@ -107,7 +113,9 @@ public class Commander {
} else if (!this.getPrivateKeyFile().isEmpty() &&
!this.getPublicCertificate().isEmpty()) {
sb.append("Private key file: " + this.getPrivateKeyFile() + System.lineSeparator());
sb.append("Public certificate: " + this.getPublicCertificate() + System.lineSeparator());
sb.append("Public certificate: " + this.getPublicCertificate()
+ System.lineSeparator());
sb.append("Embedded certificate: " + this.isEmbedded() + System.lineSeparator());
} else if (this.isDefaultKey()){
sb.append("Truststore file: default (" + SwidTagConstants.DEFAULT_KEYSTORE_FILE + ")"
+ System.lineSeparator());

View File

@ -14,13 +14,21 @@ 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";
private final String ATTRIBUTES_FILE = TestSwidTagGateway.class.getClassLoader().getResource("rim_fields.json").getPath();
private final String JKS_KEYSTORE_FILE = TestSwidTagGateway.class.getClassLoader().getResource("keystore.jks").getPath();
private final String SIGNING_CERT_FILE = TestSwidTagGateway.class.getClassLoader().getResource("RimSignCert.pem").getPath();
private final String PRIVATE_KEY_FILE = TestSwidTagGateway.class.getClassLoader().getResource("privateRimKey.pem").getPath();
private final String SUPPORT_RIM_FILE = TestSwidTagGateway.class.getClassLoader().getResource("TpmLog.bin").getPath();
private final String BASE_USER_CERT = "generated_user_cert.swidtag";
private final String BASE_USER_CERT_EMBED = "generated_user_cert_embed.swidtag";
private final String BASE_DEFAULT_CERT = "generated_default_cert.swidtag";
private final String ATTRIBUTES_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("rim_fields.json").getPath();
private final String JKS_KEYSTORE_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("keystore.jks").getPath();
private final String SIGNING_CERT_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("RimSignCert.pem").getPath();
private final String PRIVATE_KEY_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("privateRimKey.pem").getPath();
private final String CA_CHAIN_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("RimCertChain.pem").getPath();
private final String SUPPORT_RIM_FILE = TestSwidTagGateway.class.getClassLoader()
.getResource("TpmLog.bin").getPath();
private InputStream expectedFile;
@BeforeClass
@ -30,6 +38,7 @@ public class TestSwidTagGateway {
gateway.setAttributesFile(ATTRIBUTES_FILE);
validator = new SwidTagValidator();
validator.setRimEventLog(SUPPORT_RIM_FILE);
validator.setTrustStoreFile(CA_CHAIN_FILE);
}
@AfterClass
@ -45,13 +54,35 @@ public class TestSwidTagGateway {
* where RimSignCert.pem has the AIA extension.
*/
@Test
public void testCreateBaseWithCert() {
public void testCreateBaseUserCertNotEmbedded() {
gateway.setDefaultCredentials(false);
gateway.setPemCertificateFile(SIGNING_CERT_FILE);
gateway.setPemPrivateKeyFile(PRIVATE_KEY_FILE);
gateway.setEmbeddedCert(false);
gateway.generateSwidTag(DEFAULT_OUTPUT);
expectedFile = TestSwidTagGateway.class.getClassLoader().getResourceAsStream(DEFAULT_WITH_CERT);
expectedFile = TestSwidTagGateway.class.getClassLoader()
.getResourceAsStream(BASE_USER_CERT);
Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT));
}
/**
* This test creates the following base RIM:
* -c base -l TpmLog.bin -k privateRimKey.pem -p RimSignCert.pem -e
* And then validates it:
* -v [base RIM] -l TpmLog.bin -t RimCertChain.pem
*/
@Test
public void testCreateBaseUserCertEmbedded() {
gateway.setDefaultCredentials(false);
gateway.setPemCertificateFile(SIGNING_CERT_FILE);
gateway.setPemPrivateKeyFile(PRIVATE_KEY_FILE);
gateway.setEmbeddedCert(true);
gateway.generateSwidTag(DEFAULT_OUTPUT);
expectedFile = TestSwidTagGateway.class.getClassLoader()
.getResourceAsStream(BASE_USER_CERT_EMBED);
Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT));
}
/**
@ -59,21 +90,24 @@ public class TestSwidTagGateway {
* -c base -l TpmLog.bin
*/
@Test
public void testCreateBaseWithoutCert() {
public void testCreateBaseDefaultCert() {
gateway.setDefaultCredentials(true);
gateway.setJksTruststoreFile(JKS_KEYSTORE_FILE);
gateway.generateSwidTag(DEFAULT_OUTPUT);
expectedFile = TestSwidTagGateway.class.getClassLoader().getResourceAsStream(DEFAULT_NO_CERT);
expectedFile = TestSwidTagGateway.class.getClassLoader()
.getResourceAsStream(BASE_DEFAULT_CERT);
Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT));
}
/**
* This test corresponds to the arguments:
* -v <path>
*/
@Test
public void testValidateSwidTag() {
String filepath = TestSwidTagGateway.class.getClassLoader().getResource(DEFAULT_WITH_CERT).getPath();
String filepath = TestSwidTagGateway.class.getClassLoader()
.getResource(BASE_USER_CERT).getPath();
System.out.println("Validating file at " + filepath);
Assert.assertTrue(validator.validateSwidTag(filepath));
}

View File

@ -0,0 +1,43 @@
-----BEGIN CERTIFICATE-----
MIIDjDCCAnSgAwIBAgIJALEA1Q472tZoMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNV
BAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwI
UENDbGllbnQxEjAQBgNVBAMMCUV4YW1wbGVDQTAeFw0yMDAyMTAxNzI2MDdaFw0y
OTEyMTkxNzI2MDdaMFMxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UE
CgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxEjAQBgNVBAMMCUV4YW1wbGVD
QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPN0k+ULqFxdHZ14CCio
HAvn56T1Ca4t3ClmZoHSAiKsqzLV+rErk5SbMTIdi0vHQ+3sPYf9Opy0EeUXzh4J
g6CeGdDn247has1k135KBD9iJCaErJfZPnJ22CjKey8rvJM8fH3CAR7M/5uwYcPH
yRICwGAJMA/Qss4nsMRQpfZg4ReKVW+kAoa9eekG3q1sLu/QlCb0NC766X0ANP+8
AuGuHJmNV22fjvwSNfWbsJElcMrLbK4kliPyy05YVs19p+cBM1ADxGw2fJqsNsUy
34SXL1ATqOp7VCslRR5TJBzhxfM56xZbszry7BaqTSFDRGn1FuMw/4+qtPMAB88u
eXECAwEAAaNjMGEwHQYDVR0OBBYEFEahuO3bpnFf0NLneoo8XW6aw5Y4MB8GA1Ud
IwQYMBaAFEahuO3bpnFf0NLneoo8XW6aw5Y4MA8GA1UdEwEB/wQFMAMBAf8wDgYD
VR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IBAQCwCUSV6VjOR+v85z18q5UX
bla0gEsfbc2mx0kGtNqi2im2Xt8UoSJDnfMXzfQq3IP3en943mqgIeYUl3f9UQBT
KgGfyHNbEfa0FzqfKpxJdT37C9ilSQ85GtThffc4I50QgBHaRXOvwBdrGpU2O11V
x35VLyYoycIlg+CizVywEX53aoMil1hEbv0TPtbNnFZGwM/fxvere65GeQld9gEP
9krGtSXYlMktvr66cqPzmG0ciA6dMBZN8dpTgUopmYNz8HVoHDq/KBmXYA7CMzrX
pVNx4kMW/KxA+XAHT82xE7PCiLIJx4z9uPn0O4PBDw0tQ0mxuDpeoi1i9PuBfe6Y
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDoTCCAomgAwIBAgIJAIKly+6bklZlMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNV
BAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwI
UENDbGllbnQxEjAQBgNVBAMMCUV4YW1wbGVDQTAeFw0yMDA2MTExNjUzMDFaFw0z
MDA0MjAxNjUzMDFaMFwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UE
CgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxGzAZBgNVBAMMEmV4YW1wbGUu
UklNLnNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd1lWGk
SRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44
/nBaccZDOjdfIxIUCMfwhGXjxCaqZbgTucNsExDnu4arTGraoAwzHg0cVLiKT/Cx
j9NL4dcMgxRXsPdHfXb0923C7xYd2t2qfW05umgaj7qeQl6c68CFNsGX4JA8rWFQ
ZvvGx5DGlK4KTcjPuQQINs5fxasNKqLY2hq+z82x/rqwr2hmyizD6FpFSyIABPEM
PfB036GEhRwu1WEMkq8yIp2jgRUoFYke9pB3ph9pVow0Hh4mNFSKD4pP41VSKY1n
us83mdkuukPy5o0CAwEAAaNvMG0wHQYDVR0OBBYEFC/euOfQMKIgnaoBhhqWT+3s
8rzBMB8GA1UdIwQYMBaAFEahuO3bpnFf0NLneoo8XW6aw5Y4MAkGA1UdEwQCMAAw
CwYDVR0PBAQDAgbAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUA
A4IBAQC1mG0naE0W4E9vujPhygf7LXHMFkMPs5uWyvkxe4zWgTg0RHTClbOFJQJ+
pGLOcthSG6vIC6xYJxT5EKtB9rzRlEYHOi4MxuwXz9rLWQhA2zdbSo54Fb/BPoca
5K9kxvAanRltEfqEFhCcRmqIX1i6mpOWiZsrdMs7IflHKBsylUTn+v636BAz3p2H
8/lpJbF4LUFUxFU5FWB3tLuasxYTsbeE6YyNAnQIS95ML7c5H8z2aEQs5TCNHZJD
yc0PZT2aPOuEj5lGv9oyBHbYDitszUWSVxF7z86uVGmYR/2oTIj6tqb+IwuvFtnO
wiXFRS5ctLCdESr3SjdQF5wmIN4n
-----END CERTIFICATE-----

View File

@ -3,7 +3,7 @@
<Entity name="Example Inc" regid="http://Example.com" role="softwareCreator tagCreator"/>
<Link href="https://Example.com/support/ProductA/firmware/installfiles" rel="installationmedia"/>
<Meta xmlns:n8060="http://csrc.nist.gov/ns/swid/2015-extensions/1.0" xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" n8060:colloquialVersion="Firmware_2019" n8060:edition="12" n8060:product="ProductA" n8060:revision="r2" rim:BindingSpec="PC Client RIM" rim:BindingSpecVersion="1.2" rim:PayloadType="direct" rim:firmwareManufacturerId="00213022" rim:firmwareManufacturerStr="BIOSVendorA" rim:firmwareModel="A0" rim:firmwareVersion="12" rim:pcURIGlobal="https://Example.com/support/ProductA/" rim:pcURILocal="/boot/tcg/manifest/switag/" rim:platformManufacturerId="00201234" rim:platformManufacturerStr="Example.com" rim:platformModel="ProductA" rim:platformVersion="01"/>
<Payload>
<Payload xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" rim:supportRIMFormat="TCG_EventLog_Assertion" rim:supportRIMURIGlobal="https://Example.com/support/ProductA/firmware/rims/">
<Directory name="rim">
<File xmlns:SHA256="http://www.w3.org/2001/04/xmlenc#sha256" SHA256:hash="4479ca722623f8c47b703996ced3cbd981b06b1ae8a897db70137e0b7c546848" name="Example.com.BIOS.01.rimel" size="7549"/>
</Directory>
@ -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>K3XoBeYvgJBAKl8z273sL7z38qLLVBKLfUPt/gPUzBI=</DigestValue>
<DigestValue>97uWB7zSsO5WaGbrcQrlKd1Bju0aDTjK1/ktUYBje8A=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>cIl1gPsUyEj2gDv3HTWNFDVxtcBjz4Revxxf2LJejtOXQW8mGepZH8CnvgO7zCAbZYlYUZXjYZ9M&#13;
jONVv8dcsAjVHRnP6YHywFfmSm8LUCwxsfuZQqn5jClqzu5VaqLzBhuJYvCpiEdIDJwDINQuORUB&#13;
nzul1CWc3Sm1Ms2wjlIq5ctWWJcddhdyIOjl8/oD4EC5E2rOSfNcRMZxldXtie9iinFGVbr0YNE+&#13;
+lQ7hAU+SyV8RMx9tGnnsO8otwV4ddF+OfemcbzWGYBenLs3A8ZqWZyTvWphCgGqDUbOLssYciCC&#13;
mnYm5QOeh4QcE9H2kqTgZvcyCgPL/hDC7xhyjQ==</SignatureValue>
<SignatureValue>N1YtTeo2Ryuj+CtlXIpICEay+ni7vt8+4J7tAsYpa3efnLwtea69PIqEylPWm9LdA8Eo8XDdpgxV&#13;
7h3hi2LTOU+Wxq3bLiLamo99T1EtIwl+ZPcOv8bsfEkmShHdMC0dlfcj6r7x4tc0XkNAhhJgfRNz&#13;
FsmPWKJb6FYcsHFbHO/Uw1hSokbAGcWWTshEOqvKHMa8UVkrFMUPnrnMtdyJqZlhDBrZHNi4rWth&#13;
8TjlUnQVSCF9s9I04FxJ1cUAdeVMHtXKM8Pvjv68PaJMJK73dW5Yd3SbcgoKLesf/HPWeeZL0rr4&#13;
TNjlqJ/wq61Ons45MFG9bIscVbnd+XxFHx8Skw==</SignatureValue>
<KeyInfo>
<KeyName>2fdeb8e7d030a2209daa01861a964fedecf2bcc1</KeyName>
</KeyInfo>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<SoftwareIdentity xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" corpus="false" name="Example.com BIOS" patch="false" supplemental="false" tagId="94f6b457-9ac9-4d35-9b3f-78804173b65as" tagVersion="0" version="01" versionScheme="multipartnumeric" xml:lang="en">
<Entity name="Example Inc" regid="http://Example.com" role="softwareCreator tagCreator"/>
<Link href="https://Example.com/support/ProductA/firmware/installfiles" rel="installationmedia"/>
<Meta xmlns:n8060="http://csrc.nist.gov/ns/swid/2015-extensions/1.0" xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" n8060:colloquialVersion="Firmware_2019" n8060:edition="12" n8060:product="ProductA" n8060:revision="r2" rim:BindingSpec="PC Client RIM" rim:BindingSpecVersion="1.2" rim:PayloadType="direct" rim:firmwareManufacturerId="00213022" rim:firmwareManufacturerStr="BIOSVendorA" rim:firmwareModel="A0" rim:firmwareVersion="12" rim:pcURIGlobal="https://Example.com/support/ProductA/" rim:pcURILocal="/boot/tcg/manifest/switag/" rim:platformManufacturerId="00201234" rim:platformManufacturerStr="Example.com" rim:platformModel="ProductA" rim:platformVersion="01"/>
<Payload xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" rim:supportRIMFormat="TCG_EventLog_Assertion" rim:supportRIMURIGlobal="https://Example.com/support/ProductA/firmware/rims/">
<Directory name="rim">
<File xmlns:SHA256="http://www.w3.org/2001/04/xmlenc#sha256" SHA256:hash="4479ca722623f8c47b703996ced3cbd981b06b1ae8a897db70137e0b7c546848" name="Example.com.BIOS.01.rimel" size="7549"/>
</Directory>
</Payload>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>97uWB7zSsO5WaGbrcQrlKd1Bju0aDTjK1/ktUYBje8A=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>N1YtTeo2Ryuj+CtlXIpICEay+ni7vt8+4J7tAsYpa3efnLwtea69PIqEylPWm9LdA8Eo8XDdpgxV&#13;
7h3hi2LTOU+Wxq3bLiLamo99T1EtIwl+ZPcOv8bsfEkmShHdMC0dlfcj6r7x4tc0XkNAhhJgfRNz&#13;
FsmPWKJb6FYcsHFbHO/Uw1hSokbAGcWWTshEOqvKHMa8UVkrFMUPnrnMtdyJqZlhDBrZHNi4rWth&#13;
8TjlUnQVSCF9s9I04FxJ1cUAdeVMHtXKM8Pvjv68PaJMJK73dW5Yd3SbcgoKLesf/HPWeeZL0rr4&#13;
TNjlqJ/wq61Ons45MFG9bIscVbnd+XxFHx8Skw==</SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus>p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx&#13;
xkM6N18jEhQIx/CEZePEJqpluBO5w2wTEOe7hqtMatqgDDMeDRxUuIpP8LGP00vh1wyDFFew90d9&#13;
dvT3bcLvFh3a3ap9bTm6aBqPup5CXpzrwIU2wZfgkDytYVBm+8bHkMaUrgpNyM+5BAg2zl/Fqw0q&#13;
otjaGr7PzbH+urCvaGbKLMPoWkVLIgAE8Qw98HTfoYSFHC7VYQySrzIinaOBFSgViR72kHemH2lW&#13;
jDQeHiY0VIoPik/jVVIpjWe6zzeZ2S66Q/LmjQ==</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
</SoftwareIdentity>

View File

@ -3,7 +3,7 @@
<Entity name="Example Inc" regid="http://Example.com" role="softwareCreator tagCreator"/>
<Link href="https://Example.com/support/ProductA/firmware/installfiles" rel="installationmedia"/>
<Meta xmlns:n8060="http://csrc.nist.gov/ns/swid/2015-extensions/1.0" xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" n8060:colloquialVersion="Firmware_2019" n8060:edition="12" n8060:product="ProductA" n8060:revision="r2" rim:BindingSpec="PC Client RIM" rim:BindingSpecVersion="1.2" rim:PayloadType="direct" rim:firmwareManufacturerId="00213022" rim:firmwareManufacturerStr="BIOSVendorA" rim:firmwareModel="A0" rim:firmwareVersion="12" rim:pcURIGlobal="https://Example.com/support/ProductA/" rim:pcURILocal="/boot/tcg/manifest/switag/" rim:platformManufacturerId="00201234" rim:platformManufacturerStr="Example.com" rim:platformModel="ProductA" rim:platformVersion="01"/>
<Payload>
<Payload xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" rim:supportRIMFormat="TCG_EventLog_Assertion" rim:supportRIMURIGlobal="https://Example.com/support/ProductA/firmware/rims/">
<Directory name="rim">
<File xmlns:SHA256="http://www.w3.org/2001/04/xmlenc#sha256" SHA256:hash="4479ca722623f8c47b703996ced3cbd981b06b1ae8a897db70137e0b7c546848" name="Example.com.BIOS.01.rimel" size="7549"/>
</Directory>
@ -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>K3XoBeYvgJBAKl8z273sL7z38qLLVBKLfUPt/gPUzBI=</DigestValue>
<DigestValue>97uWB7zSsO5WaGbrcQrlKd1Bju0aDTjK1/ktUYBje8A=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>cIl1gPsUyEj2gDv3HTWNFDVxtcBjz4Revxxf2LJejtOXQW8mGepZH8CnvgO7zCAbZYlYUZXjYZ9M&#13;
jONVv8dcsAjVHRnP6YHywFfmSm8LUCwxsfuZQqn5jClqzu5VaqLzBhuJYvCpiEdIDJwDINQuORUB&#13;
nzul1CWc3Sm1Ms2wjlIq5ctWWJcddhdyIOjl8/oD4EC5E2rOSfNcRMZxldXtie9iinFGVbr0YNE+&#13;
+lQ7hAU+SyV8RMx9tGnnsO8otwV4ddF+OfemcbzWGYBenLs3A8ZqWZyTvWphCgGqDUbOLssYciCC&#13;
mnYm5QOeh4QcE9H2kqTgZvcyCgPL/hDC7xhyjQ==</SignatureValue>
<SignatureValue>N1YtTeo2Ryuj+CtlXIpICEay+ni7vt8+4J7tAsYpa3efnLwtea69PIqEylPWm9LdA8Eo8XDdpgxV&#13;
7h3hi2LTOU+Wxq3bLiLamo99T1EtIwl+ZPcOv8bsfEkmShHdMC0dlfcj6r7x4tc0XkNAhhJgfRNz&#13;
FsmPWKJb6FYcsHFbHO/Uw1hSokbAGcWWTshEOqvKHMa8UVkrFMUPnrnMtdyJqZlhDBrZHNi4rWth&#13;
8TjlUnQVSCF9s9I04FxJ1cUAdeVMHtXKM8Pvjv68PaJMJK73dW5Yd3SbcgoKLesf/HPWeeZL0rr4&#13;
TNjlqJ/wq61Ons45MFG9bIscVbnd+XxFHx8Skw==</SignatureValue>
<KeyInfo>
<X509Data>
<X509SubjectName>CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US</X509SubjectName>