diff --git a/tools/tcg_rim_tool/keystore.jks b/tools/tcg_rim_tool/keystore.jks index 2877d7f4..3c4bd316 100644 Binary files a/tools/tcg_rim_tool/keystore.jks and b/tools/tcg_rim_tool/keystore.jks differ 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 013095d8..3f297a5f 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 @@ -12,22 +12,43 @@ import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.DecoderException; -import java.io.*; -import java.security.*; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Security; +import java.security.Signature; +import java.security.UnrecoverableEntryException; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; +import java.util.ArrayList; import java.util.List; /** - * This class parses private key, public key, and certificate for use in their respective java.security objects. + * This class parses private key, public key, and certificates for use in + * their respective java.security objects. */ public class CredentialParser { private static final String X509 = "X.509"; - private static final String JKS = "JKS"; - private static final String PEM = "PEM"; + private static final String DEFAULT_ALGORITHM = "RSA"; private static final String PKCS1_HEADER = "-----BEGIN RSA PRIVATE KEY-----"; private static final String PKCS1_FOOTER = "-----END RSA PRIVATE KEY-----"; private static final String PKCS8_HEADER = "-----BEGIN PRIVATE KEY-----"; @@ -54,14 +75,94 @@ public class CredentialParser { return publicKey; } - public void parseJKSCredentials(String jksKeystore) { - KeyStore.PrivateKeyEntry privateKeyEntry = - parseKeystorePrivateKey(jksKeystore, - SwidTagConstants.DEFAULT_PRIVATE_KEY_ALIAS, - SwidTagConstants.DEFAULT_KEYSTORE_PASSWORD); - certificate = (X509Certificate) privateKeyEntry.getCertificate(); - privateKey = privateKeyEntry.getPrivateKey(); - publicKey = certificate.getPublicKey(); + /** + * This method parses the CA cert chain, private key, and public key from + * a JKS truststore. + * + * @param jksKeystore the truststore file + */ + public List parseJKSCredentials(String jksKeystore, + String alias, + String password) { + ArrayList keystoreAsList = new ArrayList<>(); + try { + KeyStore keystore = KeyStore.getInstance("JKS"); + keystore.load(new FileInputStream(jksKeystore), password.toCharArray()); + for (Certificate cert : keystore.getCertificateChain(alias)) { + keystoreAsList.add((X509Certificate) cert); + } + KeyStore.PrivateKeyEntry privateKeyEntry = + (KeyStore.PrivateKeyEntry) keystore.getEntry(alias, + new KeyStore.PasswordProtection(password.toCharArray())); + certificate = (X509Certificate) privateKeyEntry.getCertificate(); + privateKey = privateKeyEntry.getPrivateKey(); + publicKey = certificate.getPublicKey(); + } catch (KeyStoreException e) { + System.out.println("JKS keystore type not supported"); + } catch (FileNotFoundException e) { + System.out.println("Unable to locate " + jksKeystore); + } catch (IOException e) { + if (e.getCause() instanceof UnrecoverableKeyException) { + System.out.println("Password is incorrect, please resubmit"); + } else if (password.isEmpty()) { + System.out.println("No password given, please resubmit"); + } else { + System.out.println("Error importing keystore data:"); + e.printStackTrace(); + } + } catch (NoSuchAlgorithmException e) { + System.out.println("Unable to verify keystore integrity"); + e.printStackTrace(); + } catch (CertificateException e) { + System.out.println("Error loading certificates from keystore:"); + e.printStackTrace(); + } catch (UnrecoverableEntryException e) { + e.printStackTrace(); + } + + return keystoreAsList; + } + + /** + * Convenience method for parsing the default JKS. + */ + public List parseDefaultCredentials() { + return parseJKSCredentials(SwidTagConstants.DEFAULT_KEYSTORE_FILE, + SwidTagConstants.DEFAULT_PRIVATE_KEY_ALIAS, + SwidTagConstants.DEFAULT_KEYSTORE_PASSWORD); + } + + /** + * This method returns the X509Certificate object from a PEM truststore. + * + * @param truststore the PEM truststore + * @return a list of X509 certs + */ + public List parseCertsFromPEM(String truststore) { + return parsePEMCertificates(truststore); + } + + public void parsePEMCredentials(List truststore, String privateKeyFile) + throws Exception { + byte[] challengeString = new byte[15]; + for (X509Certificate cert : truststore) { + certificate = cert; + privateKey = parsePEMPrivateKey(privateKeyFile, DEFAULT_ALGORITHM); + publicKey = certificate.getPublicKey(); + SecureRandom.getInstanceStrong().nextBytes(challengeString); + Signature signature = Signature.getInstance("SHA256withRSA"); + signature.initSign(privateKey); + signature.update(challengeString); + byte[] signedChallenge = signature.sign(); + signature.initVerify(publicKey); + signature.update(challengeString); + if (signature.verify(signedChallenge)) { + System.out.println("Matched private key to truststore certificate"); + break; + } else { + publicKey = null; + } + } } public void parsePEMCredentials(String certificateFile, String privateKeyFile) @@ -70,7 +171,7 @@ public class CredentialParser { if (certificate.getIssuerX500Principal().equals(certificate.getSubjectX500Principal())) { throw new CertificateException("Signing certificate cannot be self-signed!"); } - privateKey = parsePEMPrivateKey(privateKeyFile, "RSA"); + privateKey = parsePEMPrivateKey(privateKeyFile, DEFAULT_ALGORITHM); publicKey = certificate.getPublicKey(); } @@ -78,6 +179,7 @@ public class CredentialParser { * This method extracts certificate bytes from a string. The bytes are assumed to be * PEM format, and a header and footer are concatenated with the input string to * facilitate proper parsing. + * * @param pemString the input string * @return an X509Certificate created from the string * @throws CertificateException if instantiating the CertificateFactory errors @@ -86,31 +188,21 @@ public class CredentialParser { try { CertificateFactory factory = CertificateFactory.getInstance(X509); InputStream inputStream = new ByteArrayInputStream((CERTIFICATE_HEADER - + System.lineSeparator() - + pemString - + System.lineSeparator() - + CERTIFICATE_FOOTER).getBytes()); + + System.lineSeparator() + + pemString + + System.lineSeparator() + + CERTIFICATE_FOOTER).getBytes()); return (X509Certificate) factory.generateCertificate(inputStream); } catch (CertificateException e) { throw e; } } - /** - * This method returns the X509Certificate object from a PEM certificate file. - * @param certificateFile - * @return - * @throws FileNotFoundException - */ - public List parseCertsFromPEM(String certificateFile) - throws FileNotFoundException { - return parsePEMCertificates(certificateFile); - } - /** * 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 */ @@ -136,7 +228,8 @@ public class CredentialParser { } catch (CertificateException e) { System.out.println("Error in certificate factory: " + e.getMessage()); } catch (IOException e) { - System.out.println("Error reading from input stream: " + e.getMessage()); + System.out.println("Error reading from input stream: " + filename); + e.printStackTrace(); } finally { try { if (fis != null) { @@ -158,6 +251,7 @@ public class CredentialParser { * Both PKCS1 and PKCS8 formats are handled. * Algorithm argument is present to allow handling of multiple encryption algorithms, * but for now it is always RSA. + * * @param filename * @return */ @@ -218,6 +312,7 @@ public class CredentialParser { /** * This method reads a PKCS1 keypair from a PEM file. + * * @param filename * @return */ @@ -232,12 +327,15 @@ public class CredentialParser { /** * This method returns the private key from a JKS keystore. + * * @param keystoreFile * @param alias * @param password * @return KeyStore.PrivateKeyEntry */ - private KeyStore.PrivateKeyEntry parseKeystorePrivateKey(String keystoreFile, String alias, String password) { + private KeyStore.PrivateKeyEntry parseKeystorePrivateKey(String keystoreFile, + String alias, + String password) { KeyStore keystore = null; KeyStore.PrivateKeyEntry privateKey = null; try { @@ -247,7 +345,8 @@ public class CredentialParser { new KeyStore.PasswordProtection(password.toCharArray())); } catch (FileNotFoundException e) { System.out.println("Cannot locate keystore " + keystoreFile); - } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableEntryException | CertificateException | IOException e) { + } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableEntryException | + CertificateException | IOException e) { e.printStackTrace(); } @@ -256,6 +355,7 @@ public class CredentialParser { /** * This method returns the authorityInfoAccess from an X509Certificate. + * * @return * @throws IOException */ @@ -264,7 +364,7 @@ public class CredentialParser { byte[] extension = certificate.getExtensionValue(Extension.authorityInfoAccess.getId()); if (extension != null && extension.length > 0) { AuthorityInformationAccess aia = AuthorityInformationAccess.getInstance( - JcaX509ExtensionUtils.parseExtensionValue(extension)); + JcaX509ExtensionUtils.parseExtensionValue(extension)); for (AccessDescription ad : aia.getAccessDescriptions()) { if (ad.getAccessMethod().toString().equals(SwidTagConstants.CA_ISSUERS)) { sb.append("CA issuers - "); @@ -279,6 +379,7 @@ public class CredentialParser { /** * This method returns the subjectKeyIdentifier from the local X509Certificate. + * * @return the String representation of the subjectKeyIdentifier * @throws IOException */ @@ -293,6 +394,7 @@ public class CredentialParser { /** * This method returns the subjectKeyIdentifier from a given X509Certificate. + * * @param certificate the cert to pull the subjectKeyIdentifier from * @return the String representation of the subjectKeyIdentifier * @throws IOException 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 6356f0cd..30f68048 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 @@ -1,7 +1,8 @@ package hirs.swid; -import hirs.swid.utils.Commander; import com.beust.jcommander.JCommander; +import hirs.swid.utils.Commander; +import hirs.swid.utils.CredentialArgumentValidator; import hirs.swid.utils.TimestampArgumentValidator; import java.util.List; @@ -14,6 +15,7 @@ public class Main { jc.parse(args); SwidTagGateway gateway; SwidTagValidator validator; + CredentialArgumentValidator caValidator; if (commander.isHelp()) { jc.usage(); @@ -26,28 +28,28 @@ public class Main { String rimel = commander.getRimEventLog(); String certificateFile = commander.getPublicCertificate(); String trustStore = commander.getTruststoreFile(); - if (!verifyFile.isEmpty()) { - if (!rimel.isEmpty()) { - validator.setRimEventLog(rimel); - } - if (!trustStore.isEmpty()) { - validator.setTrustStoreFile(trustStore); - } - if (!certificateFile.isEmpty()) { - System.out.println("A single cert cannot be used for verification. " + - "The signing cert will be searched for in the trust store."); - } - validator.validateSwidTag(verifyFile); + boolean defaultKey = commander.isDefaultKey(); + validator.setRimEventLog(rimel); + if (defaultKey) { + validator.validateSwidTag(verifyFile, "DEFAULT"); } else { - System.out.println("Need a RIM file to validate!"); - System.exit(1); + caValidator = new CredentialArgumentValidator(trustStore, + certificateFile, "", "", "", true); + if (caValidator.isValid()) { + validator.setTrustStoreFile(trustStore); + validator.validateSwidTag(verifyFile, caValidator.getFormat()); + } else { + System.out.println("Invalid combination of credentials given: " + + caValidator.getErrorMessage()); + System.exit(1); + } } } else { gateway = new SwidTagGateway(); System.out.println(commander.toString()); String createType = commander.getCreateType().toUpperCase(); String attributesFile = commander.getAttributesFile(); - String jksTruststoreFile = commander.getTruststoreFile(); + String truststoreFile = commander.getTruststoreFile(); String certificateFile = commander.getPublicCertificate(); String privateKeyFile = commander.getPrivateKeyFile(); boolean embeddedCert = commander.isEmbedded(); @@ -58,30 +60,27 @@ public class Main { if (!attributesFile.isEmpty()) { gateway.setAttributesFile(attributesFile); } - if (!jksTruststoreFile.isEmpty()) { + if (defaultKey) { gateway.setDefaultCredentials(true); - gateway.setJksTruststoreFile(jksTruststoreFile); - } else if (!certificateFile.isEmpty() && !privateKeyFile.isEmpty()) { + gateway.setTruststoreFile(SwidTagConstants.DEFAULT_KEYSTORE_FILE); + } else { gateway.setDefaultCredentials(false); - gateway.setPemCertificateFile(certificateFile); - gateway.setPemPrivateKeyFile(privateKeyFile); + caValidator = new CredentialArgumentValidator(truststoreFile, + certificateFile, privateKeyFile, "", "", false); + if (caValidator.isValid()) { + gateway.setTruststoreFile(truststoreFile); + gateway.setPemCertificateFile(certificateFile); + gateway.setPemPrivateKeyFile(privateKeyFile); + } else { + System.out.println("Invalid combination of credentials given: " + + caValidator.getErrorMessage()); + System.exit(1); + } if (embeddedCert) { gateway.setEmbeddedCert(true); } - } else if (defaultKey){ - gateway.setDefaultCredentials(true); - gateway.setJksTruststoreFile(SwidTagConstants.DEFAULT_KEYSTORE_FILE); - } else { - System.out.println("A private key (-k) and public certificate (-p) " + - "are required, or the default key (-d) must be indicated."); - System.exit(1); - } - if (rimEventLog.isEmpty()) { - System.out.println("Error: a support RIM is required!"); - System.exit(1); - } else { - gateway.setRimEventLog(rimEventLog); } + gateway.setRimEventLog(rimEventLog); List timestampArguments = commander.getTimestampArguments(); if (timestampArguments.size() > 0) { if (new TimestampArgumentValidator(timestampArguments).isValid()) { diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagConstants.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagConstants.java index 3ca76778..1f2331a4 100644 --- a/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagConstants.java +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagConstants.java @@ -8,13 +8,12 @@ import javax.xml.namespace.QName; * This class contains the String constants that are referenced by the gateway * class. It is expected that member properties of this class will expand as * more functionality is added to SwidTagGateway. - * */ public class SwidTagConstants { - public static final String DEFAULT_KEYSTORE_FILE = "/opt/hirs/rimtool/keystore.jks"; + public static final String DEFAULT_KEYSTORE_FILE = "keystore.jks";//"/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_PRIVATE_KEY_ALIAS = "1"; public static final String DEFAULT_ATTRIBUTES_FILE = "/opt/hirs/rimtool/rim_fields.json"; public static final String DEFAULT_ENGLISH = "en"; @@ -43,7 +42,7 @@ public class SwidTagConstants { public static final String ROLE = "role"; public static final String THUMBPRINT = "thumbprint"; public static final String HREF = "href"; - public static final String REL = "rel"; + public static final String REL = "rel"; public static final String COLLOQUIAL_VERSION = "colloquialVersion"; public static final String EDITION = "edition"; public static final String PRODUCT = "product"; @@ -72,12 +71,12 @@ public class SwidTagConstants { public static final String SUPPORT_RIM_FORMAT_MISSING = "supportRIMFormat missing"; public static final String SUPPORT_RIM_URI_GLOBAL = "supportRIMURIGlobal"; public static final String DATETIME = "dateTime"; - + public static final String NIST_NS = "http://csrc.nist.gov/ns/swid/2015-extensions/1.0"; - 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 RFC3339_NS = "https://www.ietf.org/rfc/rfc3339.txt"; - + public static final String N8060_PFX = "n8060"; public static final String RIM_PFX = "rim"; public static final String RFC3852_PFX = "rcf3852"; @@ -119,7 +118,7 @@ public class SwidTagConstants { TCG_NS, PC_URI_LOCAL, RIM_PFX); public static final QName _PC_URI_GLOBAL = new QName( TCG_NS, PC_URI_GLOBAL, RIM_PFX); - public static final QName _RIM_LINK_HASH = new QName( + public static final QName _RIM_LINK_HASH = new QName( TCG_NS, RIM_LINK_HASH, RIM_PFX); public static final QName _SUPPORT_RIM_TYPE = new QName( TCG_NS, SUPPORT_RIM_TYPE, RIM_PFX); 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 9c9af605..9e8e197d 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 @@ -84,7 +84,7 @@ public class SwidTagGateway { private Marshaller marshaller; private String attributesFile; private boolean defaultCredentials; - private String jksTruststoreFile; + private String truststoreFile; private String pemPrivateKeyFile; private String pemCertificateFile; private boolean embeddedCert; @@ -102,6 +102,7 @@ public class SwidTagGateway { marshaller = jaxbContext.createMarshaller(); attributesFile = SwidTagConstants.DEFAULT_ATTRIBUTES_FILE; defaultCredentials = true; + truststoreFile = ""; pemCertificateFile = ""; embeddedCert = false; rimEventLog = ""; @@ -133,12 +134,12 @@ public class SwidTagGateway { } /** - * Setter for JKS keystore file + * Setter for keystore file * - * @param jksTruststoreFile + * @param truststoreFile */ - public void setJksTruststoreFile(final String jksTruststoreFile) { - this.jksTruststoreFile = jksTruststoreFile; + public void setTruststoreFile(final String truststoreFile) { + this.truststoreFile = truststoreFile; } /** @@ -179,6 +180,7 @@ public class SwidTagGateway { /** * Setter for timestamp format in XML signature + * * @param timestampFormat */ public void setTimestampFormat(String timestampFormat) { @@ -187,6 +189,7 @@ public class SwidTagGateway { /** * Setter for timestamp input - RFC3852 + file or RFC3339 + value + * * @param timestampArgument */ public void setTimestampArgument(String timestampArgument) { @@ -245,7 +248,7 @@ public class SwidTagGateway { writeSwidTagFile(signedSoftwareIdentity, filename); } else { System.out.println("The following fields cannot be empty or null: " - + errorRequiredFields.substring(0, errorRequiredFields.length()-2)); + + errorRequiredFields.substring(0, errorRequiredFields.length() - 2)); System.exit(1); } } catch (JsonException e) { @@ -531,6 +534,7 @@ public class SwidTagGateway { addNonNullAttribute(attributes, key, value); } } + /** * This utility method checks if an attribute value is empty before adding it to the map. * @@ -593,14 +597,19 @@ public class SwidTagGateway { PrivateKey privateKey; CredentialParser cp = new CredentialParser(); if (defaultCredentials) { - cp.parseJKSCredentials(jksTruststoreFile); + cp.parseDefaultCredentials(); privateKey = cp.getPrivateKey(); KeyName keyName = kiFactory.newKeyName(cp.getCertificateSubjectKeyIdentifier()); keyInfoElements.add(keyName); } else { - cp.parsePEMCredentials(pemCertificateFile, pemPrivateKeyFile); - X509Certificate certificate = cp.getCertificate(); + if (!truststoreFile.isEmpty()) { + List truststore = cp.parseCertsFromPEM(truststoreFile); + cp.parsePEMCredentials(truststore, pemPrivateKeyFile); + } else { + cp.parsePEMCredentials(pemCertificateFile, pemPrivateKeyFile); + } privateKey = cp.getPrivateKey(); + X509Certificate certificate = cp.getCertificate(); if (embeddedCert) { ArrayList x509Content = new ArrayList(); x509Content.add(certificate.getSubjectX500Principal().getName()); @@ -608,6 +617,8 @@ public class SwidTagGateway { X509Data data = kiFactory.newX509Data(x509Content); keyInfoElements.add(data); } else { + KeyName keyName = kiFactory.newKeyName(cp.getCertificateSubjectKeyIdentifier()); + keyInfoElements.add(keyName); keyInfoElements.add(kiFactory.newKeyValue(certificate.getPublicKey())); } } @@ -646,7 +657,8 @@ public class SwidTagGateway { /** * This method creates a timestamp element and populates it with data according to * the RFC format set in timestampFormat. The element is returned within an XMLObject. - * @param doc the Document representing the XML to be signed + * + * @param doc the Document representing the XML to be signed * @param sigFactory the SignatureFactory object * @return an XMLObject containing the timestamp element */ @@ -687,7 +699,7 @@ public class SwidTagGateway { SignatureProperties signatureProperties = sigFactory.newSignatureProperties( Collections.singletonList(signatureProperty), null); XMLObject xmlObject = sigFactory.newXMLObject( - Collections.singletonList(signatureProperties), null,null,null); + Collections.singletonList(signatureProperties), null, null, null); return xmlObject; } 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 10d83a91..e2cabca2 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 @@ -36,7 +36,6 @@ 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.InvalidKeyException; @@ -74,6 +73,7 @@ public class SwidTagValidator { /** * Setter for rimel file path. + * * @param rimEventLog the rimel file */ public void setRimEventLog(String rimEventLog) { @@ -82,6 +82,7 @@ public class SwidTagValidator { /** * Setter for the truststore file path. + * * @param trustStoreFile the truststore */ public void setTrustStoreFile(String trustStoreFile) { @@ -99,6 +100,7 @@ public class SwidTagValidator { 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 @@ -106,9 +108,10 @@ public class SwidTagValidator { * * @param path the location of the file to be validated */ - public boolean validateSwidTag(String path) { + public boolean validateSwidTag(String path, String format) { Document document = unmarshallSwidTag(path); - Element softwareIdentity = (Element) document.getElementsByTagName("SoftwareIdentity").item(0); + 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"); @@ -120,8 +123,14 @@ public class SwidTagValidator { System.out.println(e.getMessage()); return false; } - System.out.println("Signature core validity: " + validateSignedXMLDocument(document)); - return true; + boolean swidtagValidity = validateSignedXMLDocument(document, format); + if (swidtagValidity) { + System.out.println("Signature core validity: true"); + return true; + } else { + System.out.println("Signature core validity: false"); + return false; + } } /** @@ -153,15 +162,22 @@ public class SwidTagValidator { * Next, the signature is inspected for two things: * 1. valid signature * 2. valid certificate chain + * * @param doc XML document * @return true if both the signature and cert chain are valid; false otherwise */ - private boolean validateSignedXMLDocument(Document doc) { + private boolean validateSignedXMLDocument(Document doc, String credentialFormat) { try { DOMValidateContext context; CredentialParser cp = new CredentialParser(); X509Certificate signingCert = null; - trustStore = cp.parseCertsFromPEM(trustStoreFile); + switch (credentialFormat) { + case "DEFAULT": + trustStore = cp.parseDefaultCredentials(); + break; + case "PEM": + trustStore = cp.parseCertsFromPEM(trustStoreFile); + } X509KeySelector keySelector = new X509KeySelector(); NodeList nodes = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature"); if (nodes.getLength() == 0) { @@ -190,7 +206,7 @@ public class SwidTagValidator { } } else { System.out.println("Base RIM must have a non-empty, non-null " + - "Subject Key Identifier (SKID) in the element"); + "Subject Key Identifier (SKID) in the element"); System.exit(1); } } @@ -204,8 +220,6 @@ public class SwidTagValidator { 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) { System.out.println("Error instantiating a KeyFactory to generate pk: " + e.getMessage()); @@ -214,7 +228,7 @@ public class SwidTagValidator { } catch (MarshalException | XMLSignatureException e) { System.out.println(e.getMessage()); } catch (Exception e) { - System.out.println(e.getMessage()); + e.printStackTrace(); } return false; @@ -239,7 +253,8 @@ public class SwidTagValidator { * This method extracts a public key from either an X509Certificate element * or a KeyValue element. If the public key's algorithm matches the declared * algorithm it is returned in a KeySelecctorResult. - * @param keyinfo the KeyInfo element + * + * @param keyinfo the KeyInfo element * @param purpose * @param algorithm the encapsulating signature's declared signing algorithm * @param context @@ -250,9 +265,9 @@ public class SwidTagValidator { final KeySelector.Purpose purpose, final AlgorithmMethod algorithm, final XMLCryptoContext context) - throws KeySelectorException { + throws KeySelectorException { Iterator keyinfoItr = keyinfo.getContent().iterator(); - while(keyinfoItr.hasNext()) { + while (keyinfoItr.hasNext()) { XMLStructure element = (XMLStructure) keyinfoItr.next(); if (element instanceof X509Data) { X509Data data = (X509Data) element; @@ -302,7 +317,8 @@ public class SwidTagValidator { /** * This method checks that the signature and public key algorithms match. - * @param uri to match the signature algorithm + * + * @param uri to match the signature algorithm * @param name to match the public key algorithm * @return true if both match, false otherwise */ @@ -314,6 +330,7 @@ public class SwidTagValidator { /** * 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 @@ -356,7 +373,8 @@ public class SwidTagValidator { /** * This method checks if cert's issuerDN matches issuer's subjectDN. - * @param cert the signed certificate + * + * @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 @@ -372,7 +390,8 @@ public class SwidTagValidator { /** * This method checks if cert's signature matches signer's public key. - * @param cert the signed certificate + * + * @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 @@ -404,6 +423,7 @@ public class SwidTagValidator { /** * 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 */ @@ -413,6 +433,7 @@ public class SwidTagValidator { /** * 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 */ @@ -485,6 +506,7 @@ public class SwidTagValidator { /** * This method strips all whitespace from an xml file, including indents and spaces * added for human-readability. + * * @param path to the xml file * @return Document object without whitespace */ 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 d84f4dbf..bdb448ae 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 @@ -19,33 +19,33 @@ public class Commander { private String createType = ""; @Parameter(names = {"-a", "--attributes "}, order = 1, description = "The configuration file holding attributes " - + "to populate the base RIM with.") + + "to populate the base RIM with.") private String attributesFile = ""; @Parameter(names = {"-o", "--out "}, order = 2, description = "The file to write the RIM out to. " - + "The RIM will be written to stdout by default.") + + "The RIM will be written to stdout by default.") private String outFile = ""; @Parameter(names = {"-v", "--verify "}, order = 3, description = "Specify a RIM file to verify.") private String verifyFile = ""; @Parameter(names = {"-t", "--truststore "}, order = 4, description = "The truststore to sign the base RIM created " - + "or to validate the signed base RIM.") + + "or to validate the signed base RIM.") private String truststoreFile = ""; @Parameter(names = {"-k", "--privateKeyFile "}, order = 5, description = "The private key used to sign the base RIM created by this tool.") private String privateKeyFile = ""; @Parameter(names = {"-p", "--publicCertificate "}, order = 6, description = "The public key certificate to embed in the base RIM created by " - + "this tool.") + + "this tool.") private String publicCertificate = ""; @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.") + description = "Use keystore.jks from the rimtool installation to sign.") private boolean defaultKey = false; - @Parameter(names = {"-l", "--rimel "}, order = 9, + @Parameter(names = {"-l", "--rimel "}, order = 9, required = true, description = "The TCG eventlog file to use as a support RIM.") private String rimEventLog = ""; @Parameter(names = {"--timestamp"}, order = 10, variableArity = true, @@ -74,7 +74,9 @@ public class Commander { return verifyFile; } - public String getTruststoreFile() { return truststoreFile; } + public String getTruststoreFile() { + return truststoreFile; + } public String getPrivateKeyFile() { return privateKeyFile; @@ -84,11 +86,17 @@ public class Commander { return publicCertificate; } - public boolean isEmbedded() { return embedded; } + public boolean isEmbedded() { + return embedded; + } - public boolean isDefaultKey() { return defaultKey; } + public boolean isDefaultKey() { + return defaultKey; + } - public String getRimEventLog() { return rimEventLog; } + public String getRimEventLog() { + return rimEventLog; + } public List getTimestampArguments() { return timestampArguments; @@ -119,25 +127,22 @@ public class Commander { return sb.toString(); } + public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Creating: " + this.getCreateType() + System.lineSeparator()); 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.getTruststoreFile().isEmpty()) { + if (this.isDefaultKey()) { + sb.append("Truststore file: default (" + SwidTagConstants.DEFAULT_KEYSTORE_FILE + ")" + + System.lineSeparator()); + } else { 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()); 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()); - } else { - sb.append("Signing credential: (none given)" + System.lineSeparator()); } sb.append("Event log support RIM: " + this.getRimEventLog() + System.lineSeparator()); List timestampArguments = this.getTimestampArguments(); diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/CredentialArgumentValidator.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/CredentialArgumentValidator.java new file mode 100644 index 00000000..58caeebc --- /dev/null +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/CredentialArgumentValidator.java @@ -0,0 +1,79 @@ +package hirs.swid.utils; + +public class CredentialArgumentValidator { + private String truststoreFile; + private String certificateFile; + private String privateKeyFile; + private String password; + private String alias; + private String format; + private boolean isValidating; + private String errorMessage; + private static final String JKS = "JKS"; + private static final String PEM = "PEM"; + + public CredentialArgumentValidator(String truststoreFile, + String certificateFile, + String privateKeyFile, + String password, + String alias, + boolean isValidating) { + this.truststoreFile = truststoreFile; + this.certificateFile = certificateFile; + this.privateKeyFile = privateKeyFile; + this.password = password; + this.alias = alias; + this.isValidating = isValidating; + errorMessage = ""; + } + + /** + * Getter for format property + * + * @return string + */ + public String getFormat() { + return format; + } + + /** + * Getter for error message + * + * @return string + */ + public String getErrorMessage() { + return errorMessage; + } + + /** + * This method checks for the following valid configurations of input arguments: + * 1. truststore + password + alias (JKS format) + * 2. truststore + private key (PEM format) + * 3. truststore only for validating (PEM format) + * 4. certificate + private key (PEM format) + * 5. certificate only for validating (PEM format) + * + * @return true if the above are found, false otherwise + */ + public boolean isValid() { + if (!truststoreFile.isEmpty()) { + if (!password.isEmpty() && !alias.isEmpty()) { + format = JKS; + return true; + } else if (!privateKeyFile.isEmpty() || isValidating) { + format = PEM; + return true; + } else { + errorMessage = "A JKS truststore needs a password and alias; " + + "a PEM truststore needs a private key file."; + return false; + } + } else if (!certificateFile.isEmpty() && !privateKeyFile.isEmpty()) { + format = PEM; + return true; + } else { + errorMessage = "A public certificate must be accompanied by a private key file."; + return false; + } + } +} diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/TimestampArgumentValidator.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/TimestampArgumentValidator.java index 1b1be43d..5d25a074 100644 --- a/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/TimestampArgumentValidator.java +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/TimestampArgumentValidator.java @@ -11,6 +11,7 @@ import java.util.regex.Pattern; public class TimestampArgumentValidator { List args; + /** * This class handles validation of the --timestamp commandline parameter. * Currently only RFC3339 and RFC3852 formats are supported. @@ -35,7 +36,7 @@ public class TimestampArgumentValidator { } else { return false; } - } else if (args.size() == 1){ + } else if (args.size() == 1) { System.out.println("Countersignature file is required for RFC3852 timestamps"); return false; } 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 a1768ef7..4d4960b3 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,200 +1,213 @@ package hirs.swid; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import org.testng.Assert; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.AfterClass; -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 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 BASE_RFC3339_TIMESTAMP = "generated_timestamp_rfc3339.swidtag"; - private final String BASE_RFC3852_TIMESTAMP = "generated_timestamp_rfc3852.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 final String RFC3852_COUNTERSIGNATURE_FILE = TestSwidTagGateway.class.getClassLoader() - .getResource("counterSignature.file").getPath(); - private InputStream expectedFile; + private SwidTagGateway gateway; + private SwidTagValidator validator; + private final String JKS = "JKS"; + private final String PEM = "PEM"; + private final String DEFAULT_OUTPUT = "generated_swidTag.swidtag"; + 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_TRUSTSTORE_EMBED = "generated_truststore_embed.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_RFC3852_TIMESTAMP = "generated_timestamp_rfc3852.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 final String RFC3852_COUNTERSIGNATURE_FILE = TestSwidTagGateway.class.getClassLoader() + .getResource("counterSignature.file").getPath(); + private InputStream expectedFile; - @BeforeClass - public void setUp() throws Exception { - gateway = new SwidTagGateway(); - gateway.setRimEventLog(SUPPORT_RIM_FILE); - gateway.setAttributesFile(ATTRIBUTES_FILE); - validator = new SwidTagValidator(); - validator.setRimEventLog(SUPPORT_RIM_FILE); - validator.setTrustStoreFile(CA_CHAIN_FILE); - } + @BeforeClass + public void setUp() throws Exception { + gateway = new SwidTagGateway(); + gateway.setRimEventLog(SUPPORT_RIM_FILE); + gateway.setAttributesFile(ATTRIBUTES_FILE); + validator = new SwidTagValidator(); + validator.setRimEventLog(SUPPORT_RIM_FILE); + validator.setTrustStoreFile(CA_CHAIN_FILE); + } - @AfterClass - public void tearDown() throws Exception { - if (expectedFile != null) { - expectedFile.close(); - } - } + @AfterClass + public void tearDown() throws Exception { + if (expectedFile != null) { + expectedFile.close(); + } + } - /** - * 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 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(BASE_USER_CERT); - Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT)); - Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT)); - } + /** + * 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 testCreateBasePemCertNotEmbedded() { + 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(BASE_USER_CERT); + Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT)); + Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT, PEM)); + } - /** - * 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)); - } + /** + * 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 testCreateBasePemCertEmbedded() { + gateway.setDefaultCredentials(false); + gateway.setTruststoreFile(""); + 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, PEM)); + } - /** - * This test corresponds to the arguments: - * -c base -l TpmLog.bin -d - */ - @Test - public void testCreateBaseDefaultCert() { - gateway.setDefaultCredentials(true); - gateway.setJksTruststoreFile(JKS_KEYSTORE_FILE); - gateway.generateSwidTag(DEFAULT_OUTPUT); - expectedFile = TestSwidTagGateway.class.getClassLoader() - .getResourceAsStream(BASE_DEFAULT_CERT); - Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT)); - Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT)); - } + /** + * This test corresponds to: + * -c base -l TpmLog.bin -t RimCertChain.pem -k privateRimKey.pem -e + * And then validates it: + * -v [base RIM] -l TpmLog.bin -t RimCertChain.pem + */ + @Test + public void testCreateBasePemTruststoreEmbedded() { + gateway.setDefaultCredentials(false); + gateway.setTruststoreFile(CA_CHAIN_FILE); + gateway.setPemCertificateFile(""); + gateway.setPemPrivateKeyFile(PRIVATE_KEY_FILE); + gateway.setEmbeddedCert(true); + gateway.generateSwidTag(DEFAULT_OUTPUT); + expectedFile = TestSwidTagGateway.class.getClassLoader() + .getResourceAsStream(BASE_TRUSTSTORE_EMBED); + Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT)); + Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT, PEM)); + } - /** - * This test corresponds to the arguments: - * -c base -l TpmLog.bin -d --timestamp rfc3339 2023-01-01T00:00:00Z - */ - @Test - public void testCreateTimestampRfc3339() { - gateway.setDefaultCredentials(true); - gateway.setJksTruststoreFile(JKS_KEYSTORE_FILE); - gateway.setTimestampFormat("RFC3339"); - gateway.setTimestampArgument("2023-01-01T00:00:00Z"); - gateway.generateSwidTag(DEFAULT_OUTPUT); - expectedFile = TestSwidTagGateway.class.getClassLoader() - .getResourceAsStream(BASE_RFC3339_TIMESTAMP); - Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT)); - Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT)); - } + /** + * This test corresponds to the arguments: + * -c base -l TpmLog.bin -d + */ + @Test + public void testCreateBaseDefaultCert() { + gateway.setDefaultCredentials(true); + gateway.setTruststoreFile(JKS_KEYSTORE_FILE); + gateway.generateSwidTag(DEFAULT_OUTPUT); + expectedFile = TestSwidTagGateway.class.getClassLoader() + .getResourceAsStream(BASE_DEFAULT_CERT); + Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT)); + Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT, "DEFAULT")); + } - /** - * This test corresponds to the arguments: - * -c base -l TpmLog.bin -d --timestamp rfc3852 countersignature.file - */ - @Test - public void testCreateTimestampRfc3852() { - gateway.setDefaultCredentials(true); - gateway.setJksTruststoreFile(JKS_KEYSTORE_FILE); - gateway.setTimestampFormat("RFC3852"); - gateway.setTimestampArgument(RFC3852_COUNTERSIGNATURE_FILE); - gateway.generateSwidTag(DEFAULT_OUTPUT); - expectedFile = TestSwidTagGateway.class.getClassLoader() - .getResourceAsStream(BASE_RFC3852_TIMESTAMP); - Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT)); - Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT)); - } + /** + * This test corresponds to the arguments: + * -c base -l TpmLog.bin -d --timestamp rfc3339 2023-01-01T00:00:00Z + */ + @Test + public void testCreateTimestampRfc3339() { + gateway.setDefaultCredentials(true); + gateway.setTruststoreFile(JKS_KEYSTORE_FILE); + gateway.setTimestampFormat("RFC3339"); + gateway.setTimestampArgument("2023-01-01T00:00:00Z"); + gateway.generateSwidTag(DEFAULT_OUTPUT); + expectedFile = TestSwidTagGateway.class.getClassLoader() + .getResourceAsStream(BASE_RFC3339_TIMESTAMP); + Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT)); + Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT, "DEFAULT")); + } - /** - * This test corresponds to the arguments: - * -v - */ + /** + * This test corresponds to the arguments: + * -c base -l TpmLog.bin -d --timestamp rfc3852 countersignature.file + */ + @Test + public void testCreateTimestampRfc3852() { + gateway.setDefaultCredentials(true); + gateway.setTruststoreFile(JKS_KEYSTORE_FILE); + gateway.setTimestampFormat("RFC3852"); + gateway.setTimestampArgument(RFC3852_COUNTERSIGNATURE_FILE); + gateway.generateSwidTag(DEFAULT_OUTPUT); + expectedFile = TestSwidTagGateway.class.getClassLoader() + .getResourceAsStream(BASE_RFC3852_TIMESTAMP); + Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT)); + Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT, "DEFAULT")); + } - public void testValidateSwidTag() { - String filepath = TestSwidTagGateway.class.getClassLoader() - .getResource(BASE_USER_CERT).getPath(); - System.out.println("Validating file at " + filepath); - Assert.assertTrue(validator.validateSwidTag(filepath)); - } - - /** - * This method compares two files by bytes to determine if they are the same or not. - * @param file to be compared to the expected value. - * @return true if they are equal, false if not. - */ - private boolean compareFileBytesToExpectedFile(String file) { - FileInputStream testFile = null; - try { - int data; - testFile = new FileInputStream(file); - while ((data = testFile.read()) != -1) { - int expected = expectedFile.read(); - if (data != expected) { - System.out.println("Expected: " + expected); - System.out.println("Got: " + data); - return false; - } - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - return false; - } catch (IOException e) { - e.printStackTrace(); - return false; - } catch (NullPointerException e) { - e.printStackTrace(); - return false; - } finally { - if (testFile != null) { - try { - testFile.close(); - } catch (IOException e) { - e.printStackTrace(); - return false; - } - } - if (expectedFile != null) { - try { - expectedFile.close(); - } catch (IOException e) { - e.printStackTrace(); - return false; - } - } - } - return true; - } + /** + * This method compares two files by bytes to determine if they are the same or not. + * + * @param file to be compared to the expected value. + * @return true if they are equal, false if not. + */ + private boolean compareFileBytesToExpectedFile(String file) { + FileInputStream testFile = null; + try { + int data; + testFile = new FileInputStream(file); + while ((data = testFile.read()) != -1) { + int expected = expectedFile.read(); + if (data != expected) { + System.out.println("Expected: " + expected); + System.out.println("Got: " + data); + return false; + } + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + return false; + } catch (IOException e) { + e.printStackTrace(); + return false; + } catch (NullPointerException e) { + e.printStackTrace(); + return false; + } finally { + if (testFile != null) { + try { + testFile.close(); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + if (expectedFile != null) { + try { + expectedFile.close(); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + } + return true; + } } diff --git a/tools/tcg_rim_tool/src/test/resources/generated_truststore_embed.swidtag b/tools/tcg_rim_tool/src/test/resources/generated_truststore_embed.swidtag new file mode 100644 index 00000000..9387733a --- /dev/null +++ b/tools/tcg_rim_tool/src/test/resources/generated_truststore_embed.swidtag @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + DJMc0n3VHHwU+F3HNpiY/l3EMcjRZAQOYlrjhD5v9qE= + + + ojJ6v8ToxLWWekCKmBoZ+Yg2V4MYMPbKB9FjDs/QG/AMP+LKjnb55Z7FSLhC8+CvvShKPAoS9mv1 +QepwI17NEqbfnC1U4WH0u578A3J6wiHMXIDnIQqKAAXb8v2c/wjMDArzFl8CXmDA7HUDIt+3C4VC +tA598YY7o0Hf6hK5qO8oWGQxXUKfpUwvtGLxHpbDWYFuVSPa+uk6OTzutt/QyzTERzxyO9Le1i6K +nrpzh4lgHn6EfGs6HR1ffdHQ069q0bE61zDx0VC18nK9DmszW6p6FlMzApiTVW/4PiVt+dSFeVGR +9///OdtxcoBCeofDDFPRyO+s+kY1pXd92Q3nfg== + + + CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US + MIIDoTCCAomgAwIBAgIJAIKly+6bklZlMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAlVTMQsw +CQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxEjAQBgNVBAMM +CUV4YW1wbGVDQTAeFw0yMDA2MTExNjUzMDFaFw0zMDA0MjAxNjUzMDFaMFwxCzAJBgNVBAYTAlVT +MQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxGzAZBgNV +BAMMEmV4YW1wbGUuUklNLnNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd1 +lWGkSRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44/nBaccZD +OjdfIxIUCMfwhGXjxCaqZbgTucNsExDnu4arTGraoAwzHg0cVLiKT/Cxj9NL4dcMgxRXsPdHfXb0 +923C7xYd2t2qfW05umgaj7qeQl6c68CFNsGX4JA8rWFQZvvGx5DGlK4KTcjPuQQINs5fxasNKqLY +2hq+z82x/rqwr2hmyizD6FpFSyIABPEMPfB036GEhRwu1WEMkq8yIp2jgRUoFYke9pB3ph9pVow0 +Hh4mNFSKD4pP41VSKY1nus83mdkuukPy5o0CAwEAAaNvMG0wHQYDVR0OBBYEFC/euOfQMKIgnaoB +hhqWT+3s8rzBMB8GA1UdIwQYMBaAFEahuO3bpnFf0NLneoo8XW6aw5Y4MAkGA1UdEwQCMAAwCwYD +VR0PBAQDAgbAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUAA4IBAQC1mG0naE0W +4E9vujPhygf7LXHMFkMPs5uWyvkxe4zWgTg0RHTClbOFJQJ+pGLOcthSG6vIC6xYJxT5EKtB9rzR +lEYHOi4MxuwXz9rLWQhA2zdbSo54Fb/BPoca5K9kxvAanRltEfqEFhCcRmqIX1i6mpOWiZsrdMs7 +IflHKBsylUTn+v636BAz3p2H8/lpJbF4LUFUxFU5FWB3tLuasxYTsbeE6YyNAnQIS95ML7c5H8z2 +aEQs5TCNHZJDyc0PZT2aPOuEj5lGv9oyBHbYDitszUWSVxF7z86uVGmYR/2oTIj6tqb+IwuvFtnO +wiXFRS5ctLCdESr3SjdQF5wmIN4n + + + + diff --git a/tools/tcg_rim_tool/src/test/resources/generated_user_cert.swidtag b/tools/tcg_rim_tool/src/test/resources/generated_user_cert.swidtag index eaf50f57..b9588ce9 100644 --- a/tools/tcg_rim_tool/src/test/resources/generated_user_cert.swidtag +++ b/tools/tcg_rim_tool/src/test/resources/generated_user_cert.swidtag @@ -26,6 +26,7 @@ tA598YY7o0Hf6hK5qO8oWGQxXUKfpUwvtGLxHpbDWYFuVSPa+uk6OTzutt/QyzTERzxyO9Le1i6K nrpzh4lgHn6EfGs6HR1ffdHQ069q0bE61zDx0VC18nK9DmszW6p6FlMzApiTVW/4PiVt+dSFeVGR 9///OdtxcoBCeofDDFPRyO+s+kY1pXd92Q3nfg== + 2fdeb8e7d030a2209daa01861a964fedecf2bcc1 p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx diff --git a/tools/tcg_rim_tool/src/test/resources/keystore.jks b/tools/tcg_rim_tool/src/test/resources/keystore.jks index 2877d7f4..3c4bd316 100644 Binary files a/tools/tcg_rim_tool/src/test/resources/keystore.jks and b/tools/tcg_rim_tool/src/test/resources/keystore.jks differ