mirror of
https://github.com/nsacyber/HIRS.git
synced 2025-03-22 12:05:59 +00:00
Consolidate timestamp parameters into --timestamp RFC3(339|852). Added a validator class for the parameter arguments.
This commit is contained in:
parent
6a84bb50c5
commit
b7f9c52fcb
@ -2,6 +2,9 @@ package hirs.swid;
|
||||
|
||||
import hirs.swid.utils.Commander;
|
||||
import com.beust.jcommander.JCommander;
|
||||
import hirs.swid.utils.TimestampArgumentValidator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
|
||||
@ -79,16 +82,16 @@ public class Main {
|
||||
} else {
|
||||
gateway.setRimEventLog(rimEventLog);
|
||||
}
|
||||
String filename = commander.getRfc3852Filename();
|
||||
if (!filename.isEmpty() && commander.getRfc3339() != null) {
|
||||
System.out.println("Only one timestamp format can be specified");
|
||||
System.exit(1);
|
||||
} else if (!filename.isEmpty()) {
|
||||
gateway.setTimestampFormat("RFC3852");
|
||||
gateway.setTimestampArgument(filename);
|
||||
} else if (commander.getRfc3339() != null) {
|
||||
gateway.setTimestampFormat("RFC3339");
|
||||
gateway.setTimestampArgument(commander.getRfc3339());
|
||||
List<String> timestampArguments = commander.getTimestampArguments();
|
||||
if (timestampArguments.size() > 0) {
|
||||
if (new TimestampArgumentValidator(timestampArguments).isValid()) {
|
||||
gateway.setTimestampFormat(timestampArguments.get(0));
|
||||
if (timestampArguments.size() > 1) {
|
||||
gateway.setTimestampArgument(timestampArguments.get(1));
|
||||
}
|
||||
} else {
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
gateway.generateSwidTag(commander.getOutFile());
|
||||
break;
|
||||
|
@ -652,7 +652,7 @@ public class SwidTagGateway {
|
||||
*/
|
||||
private XMLObject createXmlTimestamp(Document doc, XMLSignatureFactory sigFactory) {
|
||||
Element timeStampElement = doc.createElement("TimeStamp");
|
||||
switch (timestampFormat) {
|
||||
switch (timestampFormat.toUpperCase()) {
|
||||
case "RFC3852":
|
||||
try {
|
||||
byte[] counterSignature = Base64.getEncoder().encode(
|
||||
|
@ -3,6 +3,9 @@ package hirs.swid.utils;
|
||||
import com.beust.jcommander.Parameter;
|
||||
import hirs.swid.SwidTagConstants;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Commander is a class that handles the command line arguments for the SWID
|
||||
* Tags gateway by implementing the JCommander package.
|
||||
@ -45,15 +48,11 @@ public class Commander {
|
||||
@Parameter(names = {"-l", "--rimel <path>"}, order = 9,
|
||||
description = "The TCG eventlog file to use as a support RIM.")
|
||||
private String rimEventLog = "";
|
||||
@Parameter(names = {"--rfc3852"}, order = 10,
|
||||
description = "Add a placeholder for a base 64-encoded RFC3852 countersignature.")
|
||||
private String rfc3852Filename = "";
|
||||
@Parameter(names = {"--rfc3339"}, order = 11,
|
||||
description = "Add a timestamp to the signature that is compliant with RFC3339.")
|
||||
private boolean rfc3852 = false;
|
||||
@Parameter(names = {"--rfc3339"}, order = 11, validateWith = Rfc3339Format.class,
|
||||
description = "Add a timestamp to the signature that is compliant with RFC3339.")
|
||||
private String rfc3339 = "";
|
||||
@Parameter(names = {"--timestamp"}, order = 10, variableArity = true,
|
||||
description = "Add a timestamp to the signature. " +
|
||||
"Currently only RFC3339 and RFC3852 are supported:\n" +
|
||||
"\tRFC3339 [yyyy-MM-ddThh:mm:ssZ]\n\tRFC3852 <counterSignature.bin>")
|
||||
private List<String> timestampArguments = new ArrayList<String>(2);
|
||||
|
||||
public boolean isHelp() {
|
||||
return help;
|
||||
@ -91,11 +90,9 @@ public class Commander {
|
||||
|
||||
public String getRimEventLog() { return rimEventLog; }
|
||||
|
||||
public String getRfc3852Filename() { return rfc3852Filename; }
|
||||
|
||||
public boolean isRfc3852() { return rfc3852; }
|
||||
|
||||
public String getRfc3339() { return rfc3339; }
|
||||
public List<String> getTimestampArguments() {
|
||||
return timestampArguments;
|
||||
}
|
||||
|
||||
public String printHelpExamples() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@ -108,6 +105,11 @@ public class Commander {
|
||||
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 -e\n\n\n");
|
||||
sb.append("Create a base RIM using the values in attributes.json; " +
|
||||
"sign it with the default keystore; add a RFC3852 timestamp; ");
|
||||
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 " +
|
||||
"--timestamp RFC3852 counterSignature.bin -o base_rim.swidtag\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");
|
||||
@ -138,12 +140,12 @@ public class Commander {
|
||||
sb.append("Signing credential: (none given)" + System.lineSeparator());
|
||||
}
|
||||
sb.append("Event log support RIM: " + this.getRimEventLog() + System.lineSeparator());
|
||||
if (!this.getRfc3852Filename().isEmpty()) {
|
||||
sb.append("Timestamp format: RFC3852, " + this.getRfc3852Filename());
|
||||
} else if (getRfc3339().isEmpty()) {
|
||||
sb.append("Timestamp format: RFC3339 with generated timestamp");
|
||||
} else if (!getRfc3339().isEmpty()) {
|
||||
sb.append("Timestamp format: RFC3339 with timestamp input");
|
||||
List<String> timestampArguments = this.getTimestampArguments();
|
||||
if (timestampArguments.size() > 0) {
|
||||
sb.append("Timestamp format: " + timestampArguments.get(0));
|
||||
if (timestampArguments.size() == 2) {
|
||||
sb.append(", " + timestampArguments.get(1));
|
||||
}
|
||||
} else {
|
||||
sb.append("No timestamp included");
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
package hirs.swid.utils;
|
||||
|
||||
import com.beust.jcommander.IParameterValidator;
|
||||
import com.beust.jcommander.ParameterException;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeParseException;
|
||||
|
||||
public class Rfc3339Format implements IParameterValidator {
|
||||
public void validate(String name, String value) throws ParameterException {
|
||||
if (value != null) {
|
||||
try {
|
||||
Instant instant = Instant.parse(value);
|
||||
} catch (DateTimeParseException e) {
|
||||
e.printStackTrace();
|
||||
throw new ParameterException("Parameter " + name + "=" + value +
|
||||
" is not in valid RFC3339 format; " +
|
||||
"expected format is yyyy-MM-dd'T'hh:mm:ss'Z'");
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
package hirs.swid.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class TimestampArgumentValidator {
|
||||
List<String> args;
|
||||
/**
|
||||
* This class handles validation of the --timestamp commandline parameter.
|
||||
* Currently only RFC3339 and RFC3852 formats are supported.
|
||||
*
|
||||
* @param args list of arguments from command line
|
||||
*/
|
||||
public TimestampArgumentValidator(List<String> args) {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the public access method through which all other methods are called.
|
||||
*
|
||||
* @return true if all arguments are valid, false otherwise
|
||||
*/
|
||||
public boolean isValid() {
|
||||
if (isExactlyOneFormat(args)) {
|
||||
if (args.get(0).equalsIgnoreCase("RFC3852")) {
|
||||
if (args.size() == 2) {
|
||||
if (isRfc3852FileValid(args.get(1))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if (args.size() == 1){
|
||||
System.out.println("Countersignature file is required for RFC3852 timestamps");
|
||||
return false;
|
||||
}
|
||||
} else if (args.get(0).equalsIgnoreCase("RFC3339")) {
|
||||
if (args.size() == 2) {
|
||||
if (isRfc3339Format(args.get(1))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if (args.size() == 1) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
System.out.println("Unsupported timestamp format specified");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method ensures that exactly one of RFC3339 and RFC3852 are specified.
|
||||
*
|
||||
* @param args list of command line arguments
|
||||
* @return true if exactly one format is specified, false otherwise
|
||||
*/
|
||||
private boolean isExactlyOneFormat(List<String> args) {
|
||||
Pattern pattern = Pattern.compile("(R|r)(F|f)(C|c)(3339|3852)");
|
||||
String format = args.get(0);
|
||||
Matcher formatMatcher = pattern.matcher(format);
|
||||
|
||||
if (!formatMatcher.matches()) {
|
||||
System.out.println("Invalid timestamp format specified, expected RFC3339 or RFC3852.");
|
||||
return false;
|
||||
}
|
||||
if (args.size() == 2) {
|
||||
String argument = args.get(1);
|
||||
Matcher argumentMatcher = pattern.matcher(argument);
|
||||
if (argumentMatcher.matches()) {
|
||||
System.out.println("Exactly one timestamp format must be specified.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method verifies a user-given RFC3339 timestamp
|
||||
*
|
||||
* @param timestamp the timestamp string
|
||||
* @return true if valid RFC3339 format, false otherwise
|
||||
*/
|
||||
private boolean isRfc3339Format(String timestamp) {
|
||||
try {
|
||||
Instant instant = Instant.parse(timestamp);
|
||||
} catch (DateTimeParseException e) {
|
||||
System.out.println("Invalid RFC3339 timestamp given: " + timestamp);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method verifies the counter signature file
|
||||
*
|
||||
* @param file the counter signature
|
||||
* @return true if file exists and is valid, false otherwise
|
||||
*/
|
||||
private boolean isRfc3852FileValid(String file) {
|
||||
if (file != null && !file.isEmpty()) {
|
||||
try {
|
||||
Files.readAllBytes(Paths.get(file));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
System.out.println("RFC3852 requires a filename input of the countersignature file.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user