mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-01-14 16:59:53 +00:00
Merge pull request #528 from nsacyber/issue-507
[#507] RFC2315 timestamps
This commit is contained in:
commit
25a59098ac
@ -76,6 +76,7 @@ public class SwidTagConstants {
|
|||||||
public static final String TCG_NS = "https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model";
|
public static final String TCG_NS = "https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model";
|
||||||
public static final String RFC3852_NS = "https://www.ietf.org/rfc/rfc3852.txt";
|
public static final String RFC3852_NS = "https://www.ietf.org/rfc/rfc3852.txt";
|
||||||
public static final String RFC3339_NS = "https://www.ietf.org/rfc/rfc3339.txt";
|
public static final String RFC3339_NS = "https://www.ietf.org/rfc/rfc3339.txt";
|
||||||
|
public static final String RFC2315_NS = "https://www.ietf.org/rfc/rfc2315.txt";
|
||||||
public static final String PCRIM_NS = "https://trustedcomputinggroup.org/resource/" +
|
public static final String PCRIM_NS = "https://trustedcomputinggroup.org/resource/" +
|
||||||
"tcg-pc-client-reference-integrity-manifest-specification/";
|
"tcg-pc-client-reference-integrity-manifest-specification/";
|
||||||
|
|
||||||
@ -83,6 +84,7 @@ public class SwidTagConstants {
|
|||||||
public static final String RIM_PFX = "rim";
|
public static final String RIM_PFX = "rim";
|
||||||
public static final String RFC3852_PFX = "rcf3852";
|
public static final String RFC3852_PFX = "rcf3852";
|
||||||
public static final String RFC3339_PFX = "rcf3339";
|
public static final String RFC3339_PFX = "rcf3339";
|
||||||
|
public static final String RFC2315_PFX = "rcf2315";
|
||||||
public static final String PCRIM_PFX = "pcRim";
|
public static final String PCRIM_PFX = "pcRim";
|
||||||
|
|
||||||
public static final QName _SHA256_HASH = new QName(
|
public static final QName _SHA256_HASH = new QName(
|
||||||
|
@ -200,7 +200,7 @@ public class SwidTagGateway {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setter for timestamp input - RFC3852 + file or RFC3339 + value
|
* Setter for timestamp input - RFC3852|RFC2315 + file or RFC3339 + value
|
||||||
*
|
*
|
||||||
* @param timestampArgument
|
* @param timestampArgument
|
||||||
*/
|
*/
|
||||||
@ -813,6 +813,20 @@ public class SwidTagGateway {
|
|||||||
private XMLObject createXmlTimestamp(Document doc, XMLSignatureFactory sigFactory) {
|
private XMLObject createXmlTimestamp(Document doc, XMLSignatureFactory sigFactory) {
|
||||||
Element timeStampElement = null;
|
Element timeStampElement = null;
|
||||||
switch (timestampFormat.toUpperCase()) {
|
switch (timestampFormat.toUpperCase()) {
|
||||||
|
case "RFC2315":
|
||||||
|
try {
|
||||||
|
byte[] counterSignature = Base64.getEncoder().encode(
|
||||||
|
Files.readAllBytes(Paths.get(timestampArgument)));
|
||||||
|
timeStampElement.setAttributeNS("http://www.w3.org/2000/xmlns/",
|
||||||
|
"xmlns:" + SwidTagConstants.RFC2315_PFX,
|
||||||
|
SwidTagConstants.RFC2315_NS);
|
||||||
|
timeStampElement.setAttribute(SwidTagConstants.DATETIME,
|
||||||
|
new String(counterSignature));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "RFC3852":
|
case "RFC3852":
|
||||||
try {
|
try {
|
||||||
timeStampElement =
|
timeStampElement =
|
||||||
|
@ -54,7 +54,7 @@ public class Commander {
|
|||||||
private String rimEventLog = "";
|
private String rimEventLog = "";
|
||||||
@Parameter(names = {"--timestamp"}, order = 11, variableArity = true,
|
@Parameter(names = {"--timestamp"}, order = 11, variableArity = true,
|
||||||
description = "Add a timestamp to the signature. " +
|
description = "Add a timestamp to the signature. " +
|
||||||
"Currently only RFC3339 and RFC3852 are supported:\n" +
|
"Currently RFC3339, RFC3852, and RFC2315 (PKCS7) formats are supported:\n" +
|
||||||
"\tRFC3339 [yyyy-MM-ddThh:mm:ssZ]\n\tRFC3852 <counterSignature.bin>")
|
"\tRFC3339 [yyyy-MM-ddThh:mm:ssZ]\n\tRFC3852 <counterSignature.bin>")
|
||||||
private List<String> timestampArguments = new ArrayList<String>(2);
|
private List<String> timestampArguments = new ArrayList<String>(2);
|
||||||
@Parameter(names = {"--directory"}, validateWith = DirectoryArgumentValidator.class,
|
@Parameter(names = {"--directory"}, validateWith = DirectoryArgumentValidator.class,
|
||||||
|
@ -14,7 +14,7 @@ public class TimestampArgumentValidator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This class handles validation of the --timestamp commandline parameter.
|
* This class handles validation of the --timestamp commandline parameter.
|
||||||
* Currently only RFC3339 and RFC3852 formats are supported.
|
* Currently RFC3339, RFC3852, and RFC2315 (PKCS7) formats are supported.
|
||||||
*
|
*
|
||||||
* @param args list of arguments from command line
|
* @param args list of arguments from command line
|
||||||
*/
|
*/
|
||||||
@ -29,15 +29,17 @@ public class TimestampArgumentValidator {
|
|||||||
*/
|
*/
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
if (isExactlyOneFormat(args)) {
|
if (isExactlyOneFormat(args)) {
|
||||||
if (args.get(0).equalsIgnoreCase("RFC3852")) {
|
if (args.get(0).equalsIgnoreCase("RFC3852") ||
|
||||||
|
args.get(0).equalsIgnoreCase("RFC2315")) {
|
||||||
if (args.size() > 1) {
|
if (args.size() > 1) {
|
||||||
if (isRfc3852FileValid(args.get(1))) {
|
if (isCountersignatureFileValid(args.get(1))) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (args.size() == 1) {
|
} else if (args.size() == 1) {
|
||||||
System.out.println("Countersignature file is required for RFC3852 timestamps");
|
System.out.println("Countersignature file is required for " +
|
||||||
|
"RFC3852 and RFC2315 (PKCS7) timestamps");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (args.get(0).equalsIgnoreCase("RFC3339")) {
|
} else if (args.get(0).equalsIgnoreCase("RFC3339")) {
|
||||||
@ -59,25 +61,26 @@ public class TimestampArgumentValidator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method ensures that exactly one of RFC3339 and RFC3852 are specified.
|
* This method ensures that exactly one format is specified.
|
||||||
*
|
*
|
||||||
* @param args list of command line arguments
|
* @param args list of command line arguments
|
||||||
* @return true if exactly one format is specified, false otherwise
|
* @return true if exactly one format is specified, false otherwise
|
||||||
*/
|
*/
|
||||||
private boolean isExactlyOneFormat(List<String> args) {
|
private boolean isExactlyOneFormat(List<String> args) {
|
||||||
Pattern pattern = Pattern.compile("(R|r)(F|f)(C|c)(3339|3852)");
|
Pattern pattern = Pattern.compile("(R|r)(F|f)(C|c)(3339|3852|2315)");
|
||||||
String format = args.get(0);
|
String format = args.get(0);
|
||||||
Matcher formatMatcher = pattern.matcher(format);
|
Matcher formatMatcher = pattern.matcher(format);
|
||||||
|
|
||||||
if (!formatMatcher.matches()) {
|
if (!formatMatcher.matches()) {
|
||||||
System.out.println("Invalid timestamp format specified, expected RFC3339 or RFC3852.");
|
System.out.println("Invalid timestamp format specified. " +
|
||||||
|
"Please choose from RFC3339, RFC3852, or RFC2315.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (args.size() == 2) {
|
if (args.size() == 2) {
|
||||||
String argument = args.get(1);
|
String argument = args.get(1);
|
||||||
Matcher argumentMatcher = pattern.matcher(argument);
|
Matcher argumentMatcher = pattern.matcher(argument);
|
||||||
if (argumentMatcher.matches()) {
|
if (argumentMatcher.matches()) {
|
||||||
System.out.println("Exactly one timestamp format must be specified.");
|
System.out.println("Only one timestamp format may be specified at a time.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,7 +111,7 @@ public class TimestampArgumentValidator {
|
|||||||
* @param file the counter signature
|
* @param file the counter signature
|
||||||
* @return true if file exists and is valid, false otherwise
|
* @return true if file exists and is valid, false otherwise
|
||||||
*/
|
*/
|
||||||
private boolean isRfc3852FileValid(String file) {
|
private boolean isCountersignatureFileValid(String file) {
|
||||||
if (file != null && !file.isEmpty()) {
|
if (file != null && !file.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
Files.readAllBytes(Paths.get(file));
|
Files.readAllBytes(Paths.get(file));
|
||||||
@ -117,7 +120,8 @@ public class TimestampArgumentValidator {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.out.println("RFC3852 requires a filename input of the countersignature file.");
|
System.out.println("RFC3852 and RFC2315 (PKCS7) formats require " +
|
||||||
|
"a filename input of the countersignature file.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -23,6 +23,7 @@ public class TestSwidTagGateway {
|
|||||||
private final String BASE_DEFAULT_CERT = "generated_default_cert.swidtag";
|
private final String BASE_DEFAULT_CERT = "generated_default_cert.swidtag";
|
||||||
private final String BASE_RFC3339_TIMESTAMP = "generated_timestamp_rfc3339.swidtag";
|
private final String BASE_RFC3339_TIMESTAMP = "generated_timestamp_rfc3339.swidtag";
|
||||||
private final String BASE_RFC3852_TIMESTAMP = "generated_timestamp_rfc3852.swidtag";
|
private final String BASE_RFC3852_TIMESTAMP = "generated_timestamp_rfc3852.swidtag";
|
||||||
|
private final String BASE_RFC2315_TIMESTAMP = "generated_timestamp_rfc2315.swidtag";
|
||||||
private final String ATTRIBUTES_FILE = TestSwidTagGateway.class.getClassLoader()
|
private final String ATTRIBUTES_FILE = TestSwidTagGateway.class.getClassLoader()
|
||||||
.getResource("rim_fields.json").getPath();
|
.getResource("rim_fields.json").getPath();
|
||||||
private final String JKS_KEYSTORE_FILE = TestSwidTagGateway.class.getClassLoader()
|
private final String JKS_KEYSTORE_FILE = TestSwidTagGateway.class.getClassLoader()
|
||||||
@ -162,7 +163,24 @@ public class TestSwidTagGateway {
|
|||||||
Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT, "DEFAULT"));
|
Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT, "DEFAULT"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This test corresponds to the arguments:
|
||||||
|
* -c base -l TpmLog.bin -d --timestamp rfc2315 countersignature.file
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCreateTimestampRfc2315() {
|
||||||
|
gateway.setDefaultCredentials(true);
|
||||||
|
gateway.setTruststoreFile(JKS_KEYSTORE_FILE);
|
||||||
|
gateway.setTimestampFormat("RFC2315");
|
||||||
|
gateway.setTimestampArgument(RFC3852_COUNTERSIGNATURE_FILE);
|
||||||
|
gateway.generateSwidTag(DEFAULT_OUTPUT);
|
||||||
|
expectedFile = TestSwidTagGateway.class.getClassLoader()
|
||||||
|
.getResourceAsStream(BASE_RFC2315_TIMESTAMP);
|
||||||
|
Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
|
||||||
|
Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT, "DEFAULT"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* This test corresponds to the arguments:
|
* This test corresponds to the arguments:
|
||||||
* -s <signed swidtag> -d
|
* -s <signed swidtag> -d
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
<?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" id="94f6b457-9ac9-4d35-9b3f-78804173b65as" 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:PayloadType="direct" rim:bindingSpec="PC Client RIM" rim:bindingSpecVersion="1.2" 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>
|
||||||
|
<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#" Id="RimSignature">
|
||||||
|
<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>f3ulvid12X4b4EqgAQrriXwqvqlNd1GXoSf/wI+zf2A=</DigestValue>
|
||||||
|
</Reference>
|
||||||
|
<Reference URI="#TST">
|
||||||
|
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
|
||||||
|
<DigestValue>ibBq+F0kVcZzamIb0aN2cfyexARJYg0zGFA/T+fZvFY=</DigestValue>
|
||||||
|
</Reference>
|
||||||
|
</SignedInfo>
|
||||||
|
<SignatureValue>RYidnj7kzYjZxy22BKR9bjHktaxaKf8XgzvdKX5aG/x4Ieuu9XFDphDahoD1gkWG0WnJzaPZAoXn
|
||||||
|
+TU25X9As7MTo2CVIcbg09ZRJIg735GlYX28dFphmiYUCEwoJ6bloSdJbt8u/GgrW/dVkldySpci
|
||||||
|
88Y3dQoqXio2i2R7R5hIBEEdCmuQL8SmPNsAtD9pJRe5YoP8sfHo3IAL9AkYqW/+U4GkqOJyNI8G
|
||||||
|
/Kxy4TWdzuOz2N6zqNCsDQ2FyzRUVyhQgvsHSDbaJL3IXIobxBpAUHemfVI0tO8MsTS0+v1uNypQ
|
||||||
|
MvAQALhV43eoBKQyzmFlKHYSGlj8AC0zktXTlg==</SignatureValue>
|
||||||
|
<KeyInfo>
|
||||||
|
<KeyName>2fdeb8e7d030a2209daa01861a964fedecf2bcc1</KeyName>
|
||||||
|
</KeyInfo>
|
||||||
|
<Object>
|
||||||
|
<SignatureProperties>
|
||||||
|
<SignatureProperty Id="TST" Target="RimSignature">
|
||||||
|
<TimeStamp xmlns:rcf2315="https://www.ietf.org/rfc/rfc2315.txt" dateTime="dGVzdAo="/>
|
||||||
|
</SignatureProperty>
|
||||||
|
</SignatureProperties>
|
||||||
|
</Object>
|
||||||
|
</Signature>
|
||||||
|
</SoftwareIdentity>
|
Loading…
Reference in New Issue
Block a user