diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/CredentialParser.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/CredentialParser.java index 707e611b..41e25d56 100644 --- a/tools/tcg_rim_tool/src/main/java/hirs/swid/CredentialParser.java +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/CredentialParser.java @@ -107,9 +107,12 @@ public class CredentialParser { /** * This method returns the X509Certificate found in a PEM file. + * Unchecked typcase warnings are suppressed because the CertificateFactory + * implements X509Certificate objects explicitly. * @param filename pem file * @return a list containing all X509Certificates extracted */ + @SuppressWarnings("unchecked") private List parsePEMCertificates(String filename) { List certificates = null; FileInputStream fis = null; diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/Main.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/Main.java index 73cda086..60e6cb82 100644 --- a/tools/tcg_rim_tool/src/main/java/hirs/swid/Main.java +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/Main.java @@ -24,6 +24,7 @@ public class Main { String verifyFile = commander.getVerifyFile(); String rimel = commander.getRimEventLog(); String certificateFile = commander.getPublicCertificate(); + String trustStore = commander.getTruststoreFile(); if (!verifyFile.isEmpty()) { if (!rimel.isEmpty()) { validator.setRimEventLog(rimel); @@ -31,6 +32,9 @@ public class Main { if (!certificateFile.isEmpty()) { validator.setCertificateFile(certificateFile); } + if (!trustStore.isEmpty()) { + validator.setTrustStore(trustStore); + } try { validator.validateSwidTag(verifyFile); } catch (IOException e) { @@ -46,7 +50,7 @@ public class Main { System.out.println(commander.toString()); String createType = commander.getCreateType().toUpperCase(); String attributesFile = commander.getAttributesFile(); - String jksKeystoreFile = commander.getKeystoreFile(); + String jksTruststoreFile = commander.getTruststoreFile(); String certificateFile = commander.getPublicCertificate(); String privateKeyFile = commander.getPrivateKeyFile(); String rimEventLog = commander.getRimEventLog(); @@ -55,16 +59,16 @@ public class Main { if (!attributesFile.isEmpty()) { gateway.setAttributesFile(attributesFile); } - if (!jksKeystoreFile.isEmpty()) { + if (!jksTruststoreFile.isEmpty()) { gateway.setDefaultCredentials(true); - gateway.setJksKeystoreFile(jksKeystoreFile); + gateway.setJksTruststoreFile(jksTruststoreFile); } else if (!certificateFile.isEmpty() && !privateKeyFile.isEmpty()) { gateway.setDefaultCredentials(false); gateway.setPemCertificateFile(certificateFile); gateway.setPemPrivateKeyFile(privateKeyFile); } else { gateway.setDefaultCredentials(true); - gateway.setJksKeystoreFile(SwidTagConstants.DEFAULT_KEYSTORE_FILE); + gateway.setJksTruststoreFile(SwidTagConstants.DEFAULT_KEYSTORE_FILE); } if (rimEventLog.isEmpty()) { System.out.println("Error: a support RIM is required!"); @@ -74,6 +78,8 @@ public class Main { } gateway.generateSwidTag(commander.getOutFile()); break; + default: + System.out.println("No create type given, nothing to do"); } } } diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java index 46a90026..8d76241e 100644 --- a/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java @@ -80,7 +80,7 @@ public class SwidTagGateway { private Marshaller marshaller; private String attributesFile; private boolean defaultCredentials; - private String jksKeystoreFile; + private String jksTruststoreFile; private String pemPrivateKeyFile; private String pemCertificateFile; private String rimEventLog; @@ -120,9 +120,9 @@ public class SwidTagGateway { /** * Setter for JKS keystore file - * @param jksKeystoreFile + * @param jksTruststoreFile */ - public void setJksKeystoreFile(String jksKeystoreFile) { this.jksKeystoreFile = jksKeystoreFile; } + public void setJksTruststoreFile(String jksTruststoreFile) { this.jksTruststoreFile = jksTruststoreFile; } /** * Setter for private key file in PEM format @@ -440,7 +440,7 @@ public class SwidTagGateway { PublicKey publicKey; CredentialParser cp = new CredentialParser(); if (defaultCredentials) { - cp.parseJKSCredentials(jksKeystoreFile); + cp.parseJKSCredentials(jksTruststoreFile); privateKey = cp.getPrivateKey(); publicKey = cp.getPublicKey(); KeyName keyName = kiFactory.newKeyName(cp.getCertificateSubjectKeyIdentifier()); diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagValidator.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagValidator.java index a2eb1b83..c12f2a86 100644 --- a/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagValidator.java +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagValidator.java @@ -42,6 +42,7 @@ import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; +import java.security.Security; import java.security.SignatureException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; @@ -57,6 +58,14 @@ public class SwidTagValidator { private String certificateFile; private String trustStore; + /** + * Ensure that BouncyCastle is configured as a javax.security.Security provider, as this + * class expects it to be available. + */ + static { + Security.addProvider(new BouncyCastleProvider()); + } + /** * Setter for rimel file path. * @param rimEventLog the rimel file diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/Commander.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/Commander.java index d18282e5..70bbd3a9 100644 --- a/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/Commander.java +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/Commander.java @@ -1,11 +1,5 @@ package hirs.swid.utils; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.InvalidPathException; -import java.nio.file.Paths; - import com.beust.jcommander.Parameter; import hirs.swid.SwidTagConstants; @@ -29,9 +23,9 @@ public class Commander { @Parameter(names = {"-v", "--verify "}, order = 3, description = "Specify a RIM file to verify.") private String verifyFile = ""; - @Parameter(names = {"--keystore "}, order = 4, - description = "JKS keystore containing a private key to sign the base RIM created by the create function.") - private String keystoreFile = ""; + @Parameter(names = {"-t", "--truststore "}, order = 4, + description = "PEM truststore to sign the base RIM created.") + private String truststoreFile = ""; @Parameter(names = {"-k", "--privateKeyFile "}, order = 5, description = "File containing the private key used to sign the base RIM created by the create function.") private String privateKeyFile = ""; @@ -42,17 +36,7 @@ public class Commander { @Parameter(names = {"-l", "--rimel "}, order = 7, description = "The TCG eventlog file to use as a support RIM. By default the last system eventlog will be used.") private String rimEventLog = ""; -/* - @Parameter(names = {"-t", "--rimpcr "}, order = 7, - description = "The file containing TPM PCR values to use as a support RIM. By default the current platform TPM will be used.") - private String rimPcrs = ""; - //@Parameter(names = {}, order = 8, description = "") - private String toBeSigned = ""; - @Parameter(names = {"-s", "--addSignatureData "}, order = 8, - description = "The signature data in will be combined with the data in " + - "and written to , or will overwrite if is not given.") - private String signatureData = ""; -*/ + public boolean isHelp() { return help; } @@ -73,7 +57,7 @@ public class Commander { return verifyFile; } - public String getKeystoreFile() { return keystoreFile; } + public String getTruststoreFile() { return truststoreFile; } public String getPrivateKeyFile() { return privateKeyFile; @@ -84,19 +68,7 @@ public class Commander { } public String getRimEventLog() { return rimEventLog; } -/* - public String getRimPcrs() { - return rimPcrs; - } - public String getToBeSigned() { - return toBeSigned; - } - - public String getSignatureData() { - return signatureData; - } -*/ public String printHelpExamples() { StringBuilder sb = new StringBuilder(); sb.append("Create a base RIM using the values in attributes.json; " + @@ -108,8 +80,8 @@ public class Commander { 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"); + sb.append("Validate a base RIM (with an embedded cert) with a PEM truststore:\n\n"); + sb.append("\t\t-v base_rim.swidtag -t ca.crt\n\n\n"); return sb.toString(); @@ -120,8 +92,8 @@ public class Commander { sb.append("Using attributes file: " + this.getAttributesFile() + System.lineSeparator()); sb.append("Write to: " + this.getOutFile() + System.lineSeparator()); sb.append("Verify file: " + this.getVerifyFile() + System.lineSeparator()); - if (!this.getKeystoreFile().isEmpty()) { - sb.append("Keystore file: " + this.getKeystoreFile() + System.lineSeparator()); + if (!this.getTruststoreFile().isEmpty()) { + sb.append("Truststore file: " + this.getTruststoreFile() + System.lineSeparator()); } else if (!this.getPrivateKeyFile().isEmpty() && !this.getPublicCertificate().isEmpty()) { sb.append("Private key file: " + this.getPrivateKeyFile() + System.lineSeparator()); @@ -131,11 +103,6 @@ public class Commander { + System.lineSeparator()); } sb.append("Event log support RIM: " + this.getRimEventLog() + System.lineSeparator()); -/* - sb.append("TPM PCRs support RIM: " + getRimPcrs() + System.lineSeparator()); - sb.append("Base RIM to be signed: " + getToBeSigned() + System.lineSeparator()); - sb.append("External signature file: " + getSignatureData() + System.lineSeparator()); -*/ return sb.toString(); } } diff --git a/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java b/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java index 554f3ca5..9bf58ac8 100644 --- a/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java +++ b/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java @@ -1,13 +1,9 @@ package hirs.swid; -import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.nio.file.Paths; -import java.util.Scanner; -import java.net.URISyntaxException; import org.testng.Assert; import org.testng.annotations.BeforeClass; @@ -65,7 +61,7 @@ public class TestSwidTagGateway { @Test public void testCreateBaseWithoutCert() { gateway.setDefaultCredentials(true); - gateway.setJksKeystoreFile(JKS_KEYSTORE_FILE); + gateway.setJksTruststoreFile(JKS_KEYSTORE_FILE); gateway.generateSwidTag(DEFAULT_OUTPUT); expectedFile = TestSwidTagGateway.class.getClassLoader().getResourceAsStream(DEFAULT_NO_CERT); Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT)); diff --git a/tools/tcg_rim_tool/src/test/resources/generated_no_cert.swidtag b/tools/tcg_rim_tool/src/test/resources/generated_no_cert.swidtag index 51a45d76..7fb01eee 100644 --- a/tools/tcg_rim_tool/src/test/resources/generated_no_cert.swidtag +++ b/tools/tcg_rim_tool/src/test/resources/generated_no_cert.swidtag @@ -20,19 +20,19 @@ 97uWB7zSsO5WaGbrcQrlKd1Bju0aDTjK1/ktUYBje8A= - N1YtTeo2Ryuj+CtlXIpICEay+ni7vt8+4J7tAsYpa3efnLwtea69PIqEylPWm9LdA8Eo8XDdpgxV -7h3hi2LTOU+Wxq3bLiLamo99T1EtIwl+ZPcOv8bsfEkmShHdMC0dlfcj6r7x4tc0XkNAhhJgfRNz -FsmPWKJb6FYcsHFbHO/Uw1hSokbAGcWWTshEOqvKHMa8UVkrFMUPnrnMtdyJqZlhDBrZHNi4rWth -8TjlUnQVSCF9s9I04FxJ1cUAdeVMHtXKM8Pvjv68PaJMJK73dW5Yd3SbcgoKLesf/HPWeeZL0rr4 + N1YtTeo2Ryuj+CtlXIpICEay+ni7vt8+4J7tAsYpa3efnLwtea69PIqEylPWm9LdA8Eo8XDdpgxV +7h3hi2LTOU+Wxq3bLiLamo99T1EtIwl+ZPcOv8bsfEkmShHdMC0dlfcj6r7x4tc0XkNAhhJgfRNz +FsmPWKJb6FYcsHFbHO/Uw1hSokbAGcWWTshEOqvKHMa8UVkrFMUPnrnMtdyJqZlhDBrZHNi4rWth +8TjlUnQVSCF9s9I04FxJ1cUAdeVMHtXKM8Pvjv68PaJMJK73dW5Yd3SbcgoKLesf/HPWeeZL0rr4 TNjlqJ/wq61Ons45MFG9bIscVbnd+XxFHx8Skw== 2fdeb8e7d030a2209daa01861a964fedecf2bcc1 - p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx -xkM6N18jEhQIx/CEZePEJqpluBO5w2wTEOe7hqtMatqgDDMeDRxUuIpP8LGP00vh1wyDFFew90d9 -dvT3bcLvFh3a3ap9bTm6aBqPup5CXpzrwIU2wZfgkDytYVBm+8bHkMaUrgpNyM+5BAg2zl/Fqw0q -otjaGr7PzbH+urCvaGbKLMPoWkVLIgAE8Qw98HTfoYSFHC7VYQySrzIinaOBFSgViR72kHemH2lW + p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx +xkM6N18jEhQIx/CEZePEJqpluBO5w2wTEOe7hqtMatqgDDMeDRxUuIpP8LGP00vh1wyDFFew90d9 +dvT3bcLvFh3a3ap9bTm6aBqPup5CXpzrwIU2wZfgkDytYVBm+8bHkMaUrgpNyM+5BAg2zl/Fqw0q +otjaGr7PzbH+urCvaGbKLMPoWkVLIgAE8Qw98HTfoYSFHC7VYQySrzIinaOBFSgViR72kHemH2lW jDQeHiY0VIoPik/jVVIpjWe6zzeZ2S66Q/LmjQ== AQAB diff --git a/tools/tcg_rim_tool/src/test/resources/generated_with_cert.swidtag b/tools/tcg_rim_tool/src/test/resources/generated_with_cert.swidtag index 38a0cf0a..313cae3a 100644 --- a/tools/tcg_rim_tool/src/test/resources/generated_with_cert.swidtag +++ b/tools/tcg_rim_tool/src/test/resources/generated_with_cert.swidtag @@ -20,39 +20,39 @@ 97uWB7zSsO5WaGbrcQrlKd1Bju0aDTjK1/ktUYBje8A= - N1YtTeo2Ryuj+CtlXIpICEay+ni7vt8+4J7tAsYpa3efnLwtea69PIqEylPWm9LdA8Eo8XDdpgxV -7h3hi2LTOU+Wxq3bLiLamo99T1EtIwl+ZPcOv8bsfEkmShHdMC0dlfcj6r7x4tc0XkNAhhJgfRNz -FsmPWKJb6FYcsHFbHO/Uw1hSokbAGcWWTshEOqvKHMa8UVkrFMUPnrnMtdyJqZlhDBrZHNi4rWth -8TjlUnQVSCF9s9I04FxJ1cUAdeVMHtXKM8Pvjv68PaJMJK73dW5Yd3SbcgoKLesf/HPWeeZL0rr4 + N1YtTeo2Ryuj+CtlXIpICEay+ni7vt8+4J7tAsYpa3efnLwtea69PIqEylPWm9LdA8Eo8XDdpgxV +7h3hi2LTOU+Wxq3bLiLamo99T1EtIwl+ZPcOv8bsfEkmShHdMC0dlfcj6r7x4tc0XkNAhhJgfRNz +FsmPWKJb6FYcsHFbHO/Uw1hSokbAGcWWTshEOqvKHMa8UVkrFMUPnrnMtdyJqZlhDBrZHNi4rWth +8TjlUnQVSCF9s9I04FxJ1cUAdeVMHtXKM8Pvjv68PaJMJK73dW5Yd3SbcgoKLesf/HPWeeZL0rr4 TNjlqJ/wq61Ons45MFG9bIscVbnd+XxFHx8Skw== CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US - 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 5VGvm0npLO394ZihtsI1sRAR8ORJ - p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx -xkM6N18jEhQIx/CEZePEJqpluBO5w2wTEOe7hqtMatqgDDMeDRxUuIpP8LGP00vh1wyDFFew90d9 -dvT3bcLvFh3a3ap9bTm6aBqPup5CXpzrwIU2wZfgkDytYVBm+8bHkMaUrgpNyM+5BAg2zl/Fqw0q -otjaGr7PzbH+urCvaGbKLMPoWkVLIgAE8Qw98HTfoYSFHC7VYQySrzIinaOBFSgViR72kHemH2lW + p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx +xkM6N18jEhQIx/CEZePEJqpluBO5w2wTEOe7hqtMatqgDDMeDRxUuIpP8LGP00vh1wyDFFew90d9 +dvT3bcLvFh3a3ap9bTm6aBqPup5CXpzrwIU2wZfgkDytYVBm+8bHkMaUrgpNyM+5BAg2zl/Fqw0q +otjaGr7PzbH+urCvaGbKLMPoWkVLIgAE8Qw98HTfoYSFHC7VYQySrzIinaOBFSgViR72kHemH2lW jDQeHiY0VIoPik/jVVIpjWe6zzeZ2S66Q/LmjQ== AQAB