mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-20 05:28:22 +00:00
Implement --create, --attributes, --out, and --help in JCommander
Add KeyName (subjectKeyIdentifier) and KeyValue (public key) to KeyInfo element Implement --privateKeyFile and --publicCertificate in JCommander Implement -v in JCommander. Clean up unit tests. Implement support for PKCS1 in CredentialParser class. Truncate # symbol after parsing subject key identifier Close input streams in CredentialParser class Closes #237
This commit is contained in:
parent
70504e7423
commit
6ae5a18f99
@ -119,7 +119,7 @@ subprojects {
|
|||||||
'com.fasterxml.jackson.core:jackson-databind:2.6.3',
|
'com.fasterxml.jackson.core:jackson-databind:2.6.3',
|
||||||
'com.fasterxml.jackson.core:jackson-annotations:2.6.3'],
|
'com.fasterxml.jackson.core:jackson-annotations:2.6.3'],
|
||||||
jadira_usertype: 'org.jadira.usertype:usertype.core:4.0.0.GA',
|
jadira_usertype: 'org.jadira.usertype:usertype.core:4.0.0.GA',
|
||||||
jcommander: 'com.beust:jcommander:1.35',
|
jcommander: 'com.beust:jcommander:1.72',
|
||||||
joda_time: 'joda-time:joda-time:2.9.4',
|
joda_time: 'joda-time:joda-time:2.9.4',
|
||||||
jstl: [ 'org.apache.taglibs:taglibs-standard-impl:1.2.5',
|
jstl: [ 'org.apache.taglibs:taglibs-standard-impl:1.2.5',
|
||||||
'org.apache.taglibs:taglibs-standard-spec:1.2.5'],
|
'org.apache.taglibs:taglibs-standard-spec:1.2.5'],
|
||||||
|
22
tools/tcg_rim_tool/RimSignCert.pem
Normal file
22
tools/tcg_rim_tool/RimSignCert.pem
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDoTCCAomgAwIBAgIJAPB+r6VBhBn5MA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNV
|
||||||
|
BAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwI
|
||||||
|
UENDbGllbnQxEjAQBgNVBAMMCUV4YW1wbGVDQTAeFw0yMDAzMTExODExMjJaFw0z
|
||||||
|
MDAxMTgxODExMjJaMFwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UE
|
||||||
|
CgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxGzAZBgNVBAMMEmV4YW1wbGUu
|
||||||
|
UklNLnNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd1lWGk
|
||||||
|
SRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44
|
||||||
|
/nBaccZDOjdfIxIUCMfwhGXjxCaqZbgTucNsExDnu4arTGraoAwzHg0cVLiKT/Cx
|
||||||
|
j9NL4dcMgxRXsPdHfXb0923C7xYd2t2qfW05umgaj7qeQl6c68CFNsGX4JA8rWFQ
|
||||||
|
ZvvGx5DGlK4KTcjPuQQINs5fxasNKqLY2hq+z82x/rqwr2hmyizD6FpFSyIABPEM
|
||||||
|
PfB036GEhRwu1WEMkq8yIp2jgRUoFYke9pB3ph9pVow0Hh4mNFSKD4pP41VSKY1n
|
||||||
|
us83mdkuukPy5o0CAwEAAaNvMG0wHQYDVR0OBBYEFC/euOfQMKIgnaoBhhqWT+3s
|
||||||
|
8rzBMB8GA1UdIwQYMBaAFEahuO3bpnFf0NLneoo8XW6aw5Y4MAkGA1UdEwQCMAAw
|
||||||
|
CwYDVR0PBAQDAgbAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUA
|
||||||
|
A4IBAQBl2Bu9xpnHCCeeebjx+ILQXJXBd6q5+NQlV3zzBrf0bleZRtsOmsuFvWQo
|
||||||
|
KQxsfZuk7QcSvVd/1v8mqwJ0PwbFKQmrhIPWP+iowiBNqpG5PH9YxhpHQ1osOfib
|
||||||
|
NLOXMhudIQRY0yAgqQf+MOlXYa0stX8gkgftVBDRutuMKyOTf4a6d8TUcbG2Rnyz
|
||||||
|
O/6S9bq4cPDYLqWRBM+aGN8e00UWTKpBl6/1EU8wkJA6WdllK2e8mVkXUPWYyHTZ
|
||||||
|
0qQnrYiuLr36ycAznABDzEAoj4tMZbjIAfuscty6Ggzxl1WbyZLI6YzyXALwaYvr
|
||||||
|
crTLeyFynlKxuCfDnr1SAHDM65BY
|
||||||
|
-----END CERTIFICATE-----
|
@ -7,6 +7,8 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile libs.minimal_json
|
compile libs.minimal_json
|
||||||
|
compile libs.jcommander
|
||||||
|
compile libs.bouncy_castle
|
||||||
testCompile libs.testng
|
testCompile libs.testng
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,6 +19,7 @@ jar {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {}
|
from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {}
|
||||||
|
exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadArchives {
|
uploadArchives {
|
||||||
|
10
tools/tcg_rim_tool/identity_transform.xslt
Normal file
10
tools/tcg_rim_tool/identity_transform.xslt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||||
|
<xsl:output indent="no" />
|
||||||
|
<xsl:strip-space elements="*"/>
|
||||||
|
<xsl:template match="@*|node()">
|
||||||
|
<xsl:copy>
|
||||||
|
<xsl:apply-templates select="@*|node()"/>
|
||||||
|
</xsl:copy>
|
||||||
|
</xsl:template>
|
||||||
|
</xsl:stylesheet>
|
Binary file not shown.
28
tools/tcg_rim_tool/privateRimKey.pem
Normal file
28
tools/tcg_rim_tool/privateRimKey.pem
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCndZVhpEkbsQAG
|
||||||
|
NsB2oNhlcVJNXWcdj06X0Dn5by3nHAFcGvJkIZbEREavkCvIpY/F36rOOP5wWnHG
|
||||||
|
Qzo3XyMSFAjH8IRl48QmqmW4E7nDbBMQ57uGq0xq2qAMMx4NHFS4ik/wsY/TS+HX
|
||||||
|
DIMUV7D3R3129Pdtwu8WHdrdqn1tObpoGo+6nkJenOvAhTbBl+CQPK1hUGb7xseQ
|
||||||
|
xpSuCk3Iz7kECDbOX8WrDSqi2Noavs/Nsf66sK9oZsosw+haRUsiAATxDD3wdN+h
|
||||||
|
hIUcLtVhDJKvMiKdo4EVKBWJHvaQd6YfaVaMNB4eJjRUig+KT+NVUimNZ7rPN5nZ
|
||||||
|
LrpD8uaNAgMBAAECggEAcnG8npd9U0x7HMQMcsZoPaPdwHvF/gCzkLNA+8RM1bZh
|
||||||
|
A4ZzA5WlCQs0V8Wq9pyXjn7Wp8txsG1PdlT5k2AUgsVoXuR0R4IKyvYHQG9StEjH
|
||||||
|
GvWURmwJdLlnSg8hSYqEJ/52taNUDO6+MI8fgiaQDd8w0ryF4OCpLy9GJdnfkGYZ
|
||||||
|
Ayemb3USFUdj/S67NVqxnvAfFMM5FqkKGhkoy7wBRgO6eOeJvoTq8LMiPiponwwF
|
||||||
|
DW409ZStbrk1f1Oszst/UvFUWA9BdDfeoPmFR61y3eB5zlMQG8Mhr2v5hvkj9TPX
|
||||||
|
FU4Fm4EzZ1h/60cdWoP6XYCP7F2NqZ8N8u4UBQNAIQKBgQDcGIw5GJEvRF+FFTTR
|
||||||
|
hYatMRn80DGTVjdT32MgajdKx05OWxBmQsFob34fiSnr0wAXPJeDXG4ruMBE2bSk
|
||||||
|
EC8rCO08G8ihQoH8x0cvuERe1fpVWk3RWNucVGIiJSEXAIwWrlYZLTfYd5GqBkPE
|
||||||
|
OQxxo4MtOyqeHmVH1mOywk9ABQKBgQDCxt95luzqQZV9Xl78QQvOIbjOdHLjY23Z
|
||||||
|
yp8sGt9birL/WZ33TCRgmH1e61BdrSqO7Om/ail2Y59XM5UU6kLbDj0IgmOPTsrJ
|
||||||
|
JmIVf8r3bKltVUaLePgr4yex7dmtHRH8OkLXKnE0RCO0kCi9kJMB12yE3pWxk+Pu
|
||||||
|
zztQd3a66QKBgBNJd2g9deONe01fOVyu9clRhzR3ThDaOkj4R2h8xlGgO4V0R3Ce
|
||||||
|
ovIy6vt6epj2yYg/wAs720+rhfXCmijSXj/ILXnZ+W/gMyHimKNe42boG2LFYhJZ
|
||||||
|
Vg1R+7OAS3EHlD8ckeDs7Hrkp3gdymx0j1mZ+ZHKIIbwpPFxoRT2IBm9AoGBAI0Z
|
||||||
|
bIK0puP8psKvPrgWluq42xwUl7XKLaX8dtqIjQ3PqGP7E8g2TJP9Y7UDWrDB5Xas
|
||||||
|
gZi821R8Ts3o/DKukcgGxIgJjP4f4h9dwug4L1yWRxaBFB2tgHqqj/MBjxMtX/4M
|
||||||
|
Zqdgg6mNQyBm3lyVAynuWRrX9DE0JYa2cQ2VvVkhAoGBAMBv/oT813w00759PmkO
|
||||||
|
Uxv3LXTJuYBbq0Rmga25jN3ow8LrGQdSVg7F/af3I5KUF7mLiegDy1pkRfauyXH7
|
||||||
|
+WhEqnf86vDrzPpytDMxinWOQZusCqeWHb+nuVTuL3Fv+GxEdwVGYI/7lFJ7B//h
|
||||||
|
P5rU93ZoYY7sWcGVqaaEkMRU
|
||||||
|
-----END PRIVATE KEY-----
|
213
tools/tcg_rim_tool/src/main/java/hirs/swid/CredentialParser.java
Normal file
213
tools/tcg_rim_tool/src/main/java/hirs/swid/CredentialParser.java
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
package hirs.swid;
|
||||||
|
|
||||||
|
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
|
||||||
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
import org.bouncycastle.openssl.PEMKeyPair;
|
||||||
|
import org.bouncycastle.openssl.PEMParser;
|
||||||
|
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
|
||||||
|
import org.bouncycastle.util.encoders.Base64;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.security.*;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class parses private key, public key, and certificate 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 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-----";
|
||||||
|
private static final String PKCS8_FOOTER = "-----END PRIVATE KEY-----";
|
||||||
|
private X509Certificate certificate;
|
||||||
|
private PrivateKey privateKey;
|
||||||
|
private PublicKey publicKey;
|
||||||
|
|
||||||
|
public X509Certificate getCertificate() {
|
||||||
|
return certificate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrivateKey getPrivateKey() {
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PublicKey getPublicKey() {
|
||||||
|
return publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void parseJKSCredentials() {
|
||||||
|
KeyStore.PrivateKeyEntry privateKeyEntry =
|
||||||
|
parseKeystorePrivateKey(SwidTagConstants.DEFAULT_KEYSTORE_PATH,
|
||||||
|
SwidTagConstants.DEFAULT_PRIVATE_KEY_ALIAS,
|
||||||
|
SwidTagConstants.DEFAULT_KEYSTORE_PASSWORD);
|
||||||
|
certificate = (X509Certificate) privateKeyEntry.getCertificate();
|
||||||
|
privateKey = privateKeyEntry.getPrivateKey();
|
||||||
|
publicKey = certificate.getPublicKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void parsePEMCredentials(String certificateFile, String privateKeyFile) throws FileNotFoundException {
|
||||||
|
certificate = parsePEMCertificate(certificateFile);
|
||||||
|
privateKey = parsePEMPrivateKey(privateKeyFile, "RSA");
|
||||||
|
publicKey = certificate.getPublicKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the X509Certificate found in a PEM file.
|
||||||
|
* @param filename
|
||||||
|
* @return
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
*/
|
||||||
|
private X509Certificate parsePEMCertificate(String filename) throws FileNotFoundException {
|
||||||
|
X509Certificate certificate = null;
|
||||||
|
FileInputStream fis = null;
|
||||||
|
BufferedInputStream bis = null;
|
||||||
|
try {
|
||||||
|
fis = new FileInputStream(filename);
|
||||||
|
bis = new BufferedInputStream(fis);
|
||||||
|
CertificateFactory certificateFactory = CertificateFactory.getInstance(X509);
|
||||||
|
|
||||||
|
while (bis.available() > 0) {
|
||||||
|
certificate = (X509Certificate) certificateFactory.generateCertificate(bis);
|
||||||
|
}
|
||||||
|
|
||||||
|
bis.close();
|
||||||
|
} 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());
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (fis != null) {
|
||||||
|
fis.close();
|
||||||
|
}
|
||||||
|
if (bis != null) {
|
||||||
|
bis.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Error closing input stream: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return certificate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method extracts the private key from a PEM file.
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
private PrivateKey parsePEMPrivateKey(String filename, String algorithm) {
|
||||||
|
PrivateKey privateKey = null;
|
||||||
|
FileInputStream fis = null;
|
||||||
|
DataInputStream dis = null;
|
||||||
|
try {
|
||||||
|
File file = new File(filename);
|
||||||
|
fis = new FileInputStream(file);
|
||||||
|
dis = new DataInputStream(fis);
|
||||||
|
byte[] key = new byte[(int) file.length()];
|
||||||
|
dis.readFully(key);
|
||||||
|
dis.close();
|
||||||
|
|
||||||
|
String privateKeyStr = new String(key);
|
||||||
|
if (privateKeyStr.contains(PKCS1_HEADER)) {
|
||||||
|
privateKey = getPKCS1KeyPair(filename).getPrivate();
|
||||||
|
} else if (privateKeyStr.contains(PKCS8_HEADER)) {
|
||||||
|
privateKeyStr = privateKeyStr.replace(PKCS8_HEADER, "");
|
||||||
|
privateKeyStr = privateKeyStr.replace(PKCS8_FOOTER, "");
|
||||||
|
|
||||||
|
byte[] decodedKey = Base64.decode(privateKeyStr);
|
||||||
|
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decodedKey);
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
|
||||||
|
|
||||||
|
privateKey = keyFactory.generatePrivate(spec);
|
||||||
|
}
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
System.out.println("Unable to locate private key file: " + filename);
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
System.out.println("Unable to instantiate KeyFactory with algorithm: " + algorithm);
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("IOException: " + e.getMessage());
|
||||||
|
} catch (InvalidKeySpecException e) {
|
||||||
|
System.out.println("Error instantiating PKCS8EncodedKeySpec object: " + e.getMessage());
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (fis != null) {
|
||||||
|
fis.close();
|
||||||
|
}
|
||||||
|
if (dis != null) {
|
||||||
|
dis.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Error closing input stream: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method reads a PKCS1 keypair from a PEM file.
|
||||||
|
* @param filename
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private KeyPair getPKCS1KeyPair(String filename) throws IOException {
|
||||||
|
Security.addProvider(new BouncyCastleProvider());
|
||||||
|
PEMParser pemParser = new PEMParser(new FileReader(filename));
|
||||||
|
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
|
||||||
|
KeyPair keyPair = converter.getKeyPair((PEMKeyPair) pemParser.readObject());
|
||||||
|
|
||||||
|
return keyPair;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
KeyStore keystore = null;
|
||||||
|
KeyStore.PrivateKeyEntry privateKey = null;
|
||||||
|
try {
|
||||||
|
keystore = KeyStore.getInstance("JKS");
|
||||||
|
keystore.load(new FileInputStream(keystoreFile), password.toCharArray());
|
||||||
|
privateKey = (KeyStore.PrivateKeyEntry) keystore.getEntry(alias,
|
||||||
|
new KeyStore.PasswordProtection(password.toCharArray()));
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
System.out.println("Cannot locate keystore " + keystoreFile);
|
||||||
|
} catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableEntryException | CertificateException | IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility method for extracting the subjectKeyIdentifier from an X509Certificate.
|
||||||
|
* The subjectKeyIdentifier is stored as a DER-encoded octet and will be converted to a String.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getCertificateSubjectKeyIdentifier() throws IOException {
|
||||||
|
String decodedValue = null;
|
||||||
|
byte[] extension = certificate.getExtensionValue(SwidTagConstants.CERTIFICATE_SUBJECT_KEY_IDENTIFIER);
|
||||||
|
if (extension != null) {
|
||||||
|
decodedValue = JcaX509ExtensionUtils.parseExtensionValue(extension).toString();
|
||||||
|
}
|
||||||
|
//If there is a # symbol at the beginning of the string, remove it
|
||||||
|
if (decodedValue.startsWith("#")) {
|
||||||
|
decodedValue = decodedValue.substring(1);
|
||||||
|
}
|
||||||
|
return decodedValue;
|
||||||
|
}
|
||||||
|
}
|
@ -1,50 +1,58 @@
|
|||||||
package hirs.swid;
|
package hirs.swid;
|
||||||
|
|
||||||
import hirs.swid.utils.Commander;
|
import hirs.swid.utils.Commander;
|
||||||
|
import com.beust.jcommander.JCommander;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/*
|
|
||||||
* Command-line application for generating and validating SWID tags.
|
|
||||||
* Input arg: path to *.swidtag file
|
|
||||||
*
|
|
||||||
* If an argument is given it will be validated against the schema at http://standards.iso.org/iso/19770/-2/2015/schema.xsd
|
|
||||||
* If an argument is not given a SWID tag file will be generated.
|
|
||||||
*/
|
|
||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Commander commander = new Commander(args);
|
Commander commander = new Commander();
|
||||||
|
JCommander jc = JCommander.newBuilder().addObject(commander).build();
|
||||||
|
jc.parse(args);
|
||||||
SwidTagGateway gateway = new SwidTagGateway();
|
SwidTagGateway gateway = new SwidTagGateway();
|
||||||
|
|
||||||
if (commander.hasArguments()) {
|
if (commander.isHelp()) {
|
||||||
// we have arguments to work with
|
jc.usage();
|
||||||
if (commander.isAttributesGiven()) {
|
System.out.println(commander.printHelpExamples());
|
||||||
gateway.setAttributesFile(commander.getAttributesFile());
|
} else {
|
||||||
}
|
if (!commander.getVerifyFile().isEmpty()) {
|
||||||
if (commander.isKeystoreGiven()) {
|
System.out.println(commander.toString());
|
||||||
gateway.setKeystoreFile(commander.getKeystore());
|
String verifyFile = commander.getVerifyFile();
|
||||||
}
|
String publicCertificate = commander.getPublicCertificate();
|
||||||
if (commander.isShowCert()) {
|
if (!verifyFile.isEmpty() && !publicCertificate.isEmpty()) {
|
||||||
gateway.setShowCert(true);
|
try {
|
||||||
}
|
gateway.validateSwidTag(verifyFile);
|
||||||
|
} catch (IOException e) {
|
||||||
if (commander.create()) {
|
System.out.println("Error validating RIM file: " + e.getMessage());
|
||||||
// parsing the arguments detected a create parameter (-c)
|
}
|
||||||
gateway.generateSwidTag(commander.getCreateOutFile());
|
} else {
|
||||||
}
|
System.out.println("Need both a RIM file to validate and a public certificate to validate with!");
|
||||||
if (commander.validate()) {
|
|
||||||
// parsing the arguments detected a validation parameter (-v)
|
|
||||||
try {
|
|
||||||
gateway.validateSwidTag(commander.getValidateFile());
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("Unable to validate file: " + e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
if (commander.parse()) {
|
System.out.println(commander.toString());
|
||||||
try {
|
String createType = commander.getCreateType().toUpperCase();
|
||||||
gateway.parsePayload(commander.getParseFile());
|
String attributesFile = commander.getAttributesFile();
|
||||||
} catch (IOException e) {
|
String certificateFile = commander.getPublicCertificate();
|
||||||
System.out.println("Unable to parse file: " + e.getMessage());
|
String privateKeyFile = commander.getPrivateKeyFile();
|
||||||
|
switch (createType) {
|
||||||
|
case "BASE":
|
||||||
|
if (!attributesFile.isEmpty()) {
|
||||||
|
gateway.setAttributesFile(attributesFile);
|
||||||
|
}
|
||||||
|
if (!certificateFile.isEmpty() && !privateKeyFile.isEmpty()) {
|
||||||
|
gateway.setDefaultCredentials(false);
|
||||||
|
gateway.setPemCertificateFile(certificateFile);
|
||||||
|
gateway.setPemPrivateKeyFile(privateKeyFile);
|
||||||
|
}
|
||||||
|
gateway.generateSwidTag(commander.getOutFile());
|
||||||
|
break;
|
||||||
|
case "EVENTLOG":
|
||||||
|
break;
|
||||||
|
case "PCR":
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,15 +20,10 @@ public class SwidTagConstants {
|
|||||||
|
|
||||||
public static final String SIGNATURE_ALGORITHM_RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
|
public static final String SIGNATURE_ALGORITHM_RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
|
||||||
|
|
||||||
public static final String SCHEMA_STATEMENT = "ISO/IEC 19770-2:2015 Schema (XSD 1.0) "
|
|
||||||
+ "- September 2015, see http://standards.iso.org/iso/19770/-2/2015/schema.xsd";
|
|
||||||
public static final String SCHEMA_PACKAGE = "hirs.swid.xjc";
|
public static final String SCHEMA_PACKAGE = "hirs.swid.xjc";
|
||||||
public static final String SCHEMA_LANGUAGE = XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
public static final String SCHEMA_LANGUAGE = XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
||||||
public static final String SCHEMA_URL = "swid_schema.xsd";
|
public static final String SCHEMA_URL = "swid_schema.xsd";
|
||||||
|
|
||||||
public static final String HIRS_SWIDTAG_HEADERS = "hirsSwidTagHeader.properties";
|
|
||||||
public static final String EXAMPLE_PROPERTIES = "swidExample.properties";
|
|
||||||
|
|
||||||
public static final String SOFTWARE_IDENTITY = "SoftwareIdentity";
|
public static final String SOFTWARE_IDENTITY = "SoftwareIdentity";
|
||||||
public static final String ENTITY = "Entity";
|
public static final String ENTITY = "Entity";
|
||||||
public static final String LINK = "Link";
|
public static final String LINK = "Link";
|
||||||
@ -147,48 +142,5 @@ public class SwidTagConstants {
|
|||||||
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
|
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
|
||||||
"pathSeparator", "n8060");
|
"pathSeparator", "n8060");
|
||||||
|
|
||||||
//Below properties can probably be deleted
|
public static final String CERTIFICATE_SUBJECT_KEY_IDENTIFIER = "2.5.29.14";
|
||||||
public static final String SOFTWARE_IDENTITY_NAME = "softwareIdentity.name";
|
|
||||||
public static final String SOFTWARE_IDENTITY_TAGID = "softwareIdentity.tagId";
|
|
||||||
public static final String SOFTWARE_IDENTITY_VERSION = "softwareIdentity.version";
|
|
||||||
public static final String SOFTWARE_IDENTITY_CORPUS = "softwareIdentity.corpus";
|
|
||||||
public static final String SOFTWARE_IDENTITY_PATCH = "softwareIdentity.patch";
|
|
||||||
public static final String SOFTWARE_IDENTITY_SUPPLEMENTAL = "softwareIdentity.supplemental";
|
|
||||||
|
|
||||||
public static final String ENTITY_NAME = "entity.name";
|
|
||||||
public static final String ENTITY_REGID = "entity.regid";
|
|
||||||
public static final String ENTITY_ROLE = "entity.role";
|
|
||||||
public static final String ENTITY_THUMBPRINT = "entity.thumbprint";
|
|
||||||
|
|
||||||
public static final String LINK_HREF = "link.href";
|
|
||||||
public static final String LINK_REL = "link.rel";
|
|
||||||
|
|
||||||
public static final String META_PCURILOCAL = "softwareMeta.pcUriLocal";
|
|
||||||
public static final String META_BINDINGSPEC = "softwareMeta.bindingSpec";
|
|
||||||
public static final String META_BINDINGSPECVERSION = "softwareMeta.bindingSpecVersion";
|
|
||||||
public static final String META_PLATFORMMANUFACTURERID = "softwareMeta.platformManufacturerId";
|
|
||||||
public static final String META_PLATFORMMANUFACTURERSTR = "softwareMeta.platformManufacturerStr";
|
|
||||||
public static final String META_PLATFORMMODEL = "softwareMeta.platformModel";
|
|
||||||
public static final String META_COMPONENTCLASS = "softwareMeta.componentClass";
|
|
||||||
public static final String META_COMPONENTMANUFACTURER = "softwareMeta.componentManufacturer";
|
|
||||||
public static final String META_COMPONENTMANUFACTURERID = "softwareMeta.componentManufacturerId";
|
|
||||||
public static final String META_RIMLINKHASH = "softwareMeta.rimLinkHash";
|
|
||||||
|
|
||||||
public static final String PAYLOAD_ENVVARPREFIX = "n8060.envvarprefix";
|
|
||||||
public static final String PAYLOAD_ENVVARSUFFIX = "n8060.envvarsuffix";
|
|
||||||
public static final String PAYLOAD_PATHSEPARATOR = "n8060.pathseparator";
|
|
||||||
|
|
||||||
public static final String DIRECTORY_KEY = "directory.key";
|
|
||||||
public static final String DIRECTORY_LOCATION = "directory.location";
|
|
||||||
public static final String DIRECTORY_NAME = "directory.name";
|
|
||||||
public static final String DIRECTORY_ROOT = "directory.root";
|
|
||||||
public static final String FILE_KEY = "file.key";
|
|
||||||
public static final String FILE_LOCATION = "file.location";
|
|
||||||
public static final String FILE_NAME = "file.name";
|
|
||||||
public static final String FILE_ROOT = "file.root";
|
|
||||||
public static final String FILE_SIZE = "file.size";
|
|
||||||
public static final String FILE_VERSION = "file.version";
|
|
||||||
|
|
||||||
public static final int PCR_NUMBER = 0;
|
|
||||||
public static final int PCR_VALUE = 1;
|
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
package hirs.swid;
|
package hirs.swid;
|
||||||
|
|
||||||
import javax.xml.bind.JAXB;
|
|
||||||
import javax.xml.bind.JAXBContext;
|
import javax.xml.bind.JAXBContext;
|
||||||
import javax.xml.bind.JAXBElement;
|
import javax.xml.bind.JAXBElement;
|
||||||
import javax.xml.bind.JAXBException;
|
import javax.xml.bind.JAXBException;
|
||||||
import javax.xml.bind.Marshaller;
|
import javax.xml.bind.Marshaller;
|
||||||
import javax.xml.bind.Unmarshaller;
|
import javax.xml.bind.Unmarshaller;
|
||||||
import javax.xml.bind.UnmarshalException;
|
import javax.xml.bind.UnmarshalException;
|
||||||
|
import javax.xml.crypto.dsig.keyinfo.*;
|
||||||
import javax.xml.transform.OutputKeys;
|
import javax.xml.transform.OutputKeys;
|
||||||
import javax.xml.transform.Source;
|
import javax.xml.transform.Source;
|
||||||
import javax.xml.transform.TransformerFactory;
|
import javax.xml.transform.TransformerFactory;
|
||||||
import javax.xml.transform.Transformer;
|
import javax.xml.transform.Transformer;
|
||||||
import javax.xml.transform.TransformerConfigurationException;
|
import javax.xml.transform.TransformerConfigurationException;
|
||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.transform.TransformerException;
|
||||||
|
import javax.xml.transform.dom.DOMResult;
|
||||||
import javax.xml.transform.dom.DOMSource;
|
import javax.xml.transform.dom.DOMSource;
|
||||||
import javax.xml.transform.stream.StreamResult;
|
import javax.xml.transform.stream.StreamResult;
|
||||||
import javax.xml.transform.stream.StreamSource;
|
import javax.xml.transform.stream.StreamSource;
|
||||||
@ -29,7 +30,6 @@ import javax.xml.crypto.XMLStructure;
|
|||||||
import javax.xml.crypto.dsig.CanonicalizationMethod;
|
import javax.xml.crypto.dsig.CanonicalizationMethod;
|
||||||
import javax.xml.crypto.dsig.DigestMethod;
|
import javax.xml.crypto.dsig.DigestMethod;
|
||||||
import javax.xml.crypto.dsig.Reference;
|
import javax.xml.crypto.dsig.Reference;
|
||||||
import javax.xml.crypto.dsig.SignatureMethod;
|
|
||||||
import javax.xml.crypto.dsig.SignedInfo;
|
import javax.xml.crypto.dsig.SignedInfo;
|
||||||
import javax.xml.crypto.dsig.Transform;
|
import javax.xml.crypto.dsig.Transform;
|
||||||
import javax.xml.crypto.dsig.XMLSignature;
|
import javax.xml.crypto.dsig.XMLSignature;
|
||||||
@ -37,78 +37,48 @@ import javax.xml.crypto.dsig.XMLSignatureException;
|
|||||||
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
import javax.xml.crypto.dsig.XMLSignatureFactory;
|
||||||
import javax.xml.crypto.dsig.dom.DOMSignContext;
|
import javax.xml.crypto.dsig.dom.DOMSignContext;
|
||||||
import javax.xml.crypto.dsig.dom.DOMValidateContext;
|
import javax.xml.crypto.dsig.dom.DOMValidateContext;
|
||||||
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
|
|
||||||
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
|
|
||||||
import javax.xml.crypto.dsig.keyinfo.X509Data;
|
|
||||||
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
|
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
|
||||||
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.*;
|
||||||
import java.security.Key;
|
|
||||||
import java.security.KeyStore;
|
|
||||||
import java.security.KeyStoreException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PublicKey;
|
|
||||||
import java.security.UnrecoverableEntryException;
|
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
import hirs.swid.utils.CsvParser;
|
|
||||||
import hirs.swid.utils.HashSwid;
|
|
||||||
import hirs.swid.xjc.BaseElement;
|
|
||||||
import hirs.swid.xjc.CanonicalizationMethodType;
|
|
||||||
import hirs.swid.xjc.DigestMethodType;
|
|
||||||
import hirs.swid.xjc.Directory;
|
import hirs.swid.xjc.Directory;
|
||||||
import hirs.swid.xjc.Entity;
|
import hirs.swid.xjc.Entity;
|
||||||
import hirs.swid.xjc.Link;
|
import hirs.swid.xjc.Link;
|
||||||
import hirs.swid.xjc.ObjectFactory;
|
import hirs.swid.xjc.ObjectFactory;
|
||||||
import hirs.swid.xjc.ResourceCollection;
|
import hirs.swid.xjc.ResourceCollection;
|
||||||
import hirs.swid.xjc.ReferenceType;
|
|
||||||
import hirs.swid.xjc.SignatureType;
|
|
||||||
import hirs.swid.xjc.SignatureValueType;
|
|
||||||
import hirs.swid.xjc.SignatureMethodType;
|
|
||||||
import hirs.swid.xjc.SignedInfoType;
|
|
||||||
import hirs.swid.xjc.SoftwareIdentity;
|
import hirs.swid.xjc.SoftwareIdentity;
|
||||||
import hirs.swid.xjc.SoftwareMeta;
|
import hirs.swid.xjc.SoftwareMeta;
|
||||||
import hirs.swid.xjc.TransformType;
|
|
||||||
import hirs.swid.xjc.TransformsType;
|
|
||||||
|
|
||||||
import com.eclipsesource.json.Json;
|
import com.eclipsesource.json.Json;
|
||||||
import com.eclipsesource.json.JsonObject;
|
import com.eclipsesource.json.JsonObject;
|
||||||
import com.eclipsesource.json.JsonObject.Member;
|
|
||||||
import com.eclipsesource.json.JsonValue;
|
|
||||||
import com.eclipsesource.json.Location;
|
|
||||||
import com.eclipsesource.json.ParseException;
|
import com.eclipsesource.json.ParseException;
|
||||||
|
|
||||||
|
|
||||||
@ -120,32 +90,16 @@ import com.eclipsesource.json.ParseException;
|
|||||||
*/
|
*/
|
||||||
public class SwidTagGateway {
|
public class SwidTagGateway {
|
||||||
|
|
||||||
private static final QName _DEFAULT_QNAME = new QName(
|
|
||||||
"http://www.w3.org/2000/09/xmldsig#", "SHA256", "ds");
|
|
||||||
private static final QName _SHA1Value_QNAME = new QName(
|
|
||||||
"http://www.w3.org/2000/09/xmldsig#", "SHA1", "ds");
|
|
||||||
private static final QName _SHA384Value_QNAME = new QName(
|
|
||||||
"http://www.w3.org/2000/09/xmldsig#", "SHA384", "ds");
|
|
||||||
private static final QName _SHA512Value_QNAME = new QName(
|
|
||||||
"http://www.w3.org/2000/09/xmldsig#", "SHA512", "ds");
|
|
||||||
private static final QName _SHA256_HASH = new QName(
|
private static final QName _SHA256_HASH = new QName(
|
||||||
"http://www.w3.org/2001/04/xmlenc#sha256", "hash", "SHA256");
|
"http://www.w3.org/2001/04/xmlenc#sha256", "hash", "SHA256");
|
||||||
|
|
||||||
private final ObjectFactory objectFactory = new ObjectFactory();
|
private final ObjectFactory objectFactory = new ObjectFactory();
|
||||||
private final File generatedFile = new File("generated_swidTag.swidtag");
|
|
||||||
private QName hashValue = null;
|
|
||||||
|
|
||||||
private JAXBContext jaxbContext;
|
private JAXBContext jaxbContext;
|
||||||
private Marshaller marshaller;
|
private Marshaller marshaller;
|
||||||
private Unmarshaller unmarshaller;
|
private Unmarshaller unmarshaller;
|
||||||
private String attributesFile;
|
private String attributesFile;
|
||||||
/**
|
private boolean defaultCredentials;
|
||||||
* The keystoreFile is used in signXMLDocument() to pass in the keystore path.
|
private String pemPrivateKeyFile;
|
||||||
* The same method requires the keystore password and the alias of the private key,
|
private String pemCertificateFile;
|
||||||
* which would need to be passed in if not using the default keystore.
|
|
||||||
*/
|
|
||||||
private String keystoreFile;
|
|
||||||
private boolean showCert;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor initializes jaxbcontext, marshaller, and unmarshaller
|
* Default constructor initializes jaxbcontext, marshaller, and unmarshaller
|
||||||
@ -156,8 +110,8 @@ public class SwidTagGateway {
|
|||||||
marshaller = jaxbContext.createMarshaller();
|
marshaller = jaxbContext.createMarshaller();
|
||||||
unmarshaller = jaxbContext.createUnmarshaller();
|
unmarshaller = jaxbContext.createUnmarshaller();
|
||||||
attributesFile = SwidTagConstants.DEFAULT_ATTRIBUTES_FILE;
|
attributesFile = SwidTagConstants.DEFAULT_ATTRIBUTES_FILE;
|
||||||
keystoreFile = SwidTagConstants.DEFAULT_KEYSTORE_PATH;
|
defaultCredentials = true;
|
||||||
showCert = false;
|
pemCertificateFile = "";
|
||||||
} catch (JAXBException e) {
|
} catch (JAXBException e) {
|
||||||
System.out.println("Error initializing jaxbcontext: " + e.getMessage());
|
System.out.println("Error initializing jaxbcontext: " + e.getMessage());
|
||||||
}
|
}
|
||||||
@ -172,107 +126,37 @@ public class SwidTagGateway {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setter for String holding keystore path
|
* Setter for boolean governing signing credentials
|
||||||
* @param keystore
|
* @param defaultCredentials
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
public void setKeystoreFile(String keystoreFile) {
|
public void setDefaultCredentials(boolean defaultCredentials) {
|
||||||
this.keystoreFile = keystoreFile;
|
this.defaultCredentials = defaultCredentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setter for boolean to display certificate block in xml signature
|
* Setter for private key file in PEM format
|
||||||
* @param showCert
|
* @param pemPrivateKeyFile
|
||||||
*/
|
*/
|
||||||
public void setShowCert(boolean showCert) {
|
public void setPemPrivateKeyFile(String pemPrivateKeyFile) {
|
||||||
this.showCert = showCert;
|
this.pemPrivateKeyFile = pemPrivateKeyFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Setter for certificate file in PEM format
|
||||||
* default generator method that has no parameters
|
* @param pemCertificateFile
|
||||||
*/
|
*/
|
||||||
public void generateSwidTag() {
|
public void setPemCertificateFile(String pemCertificateFile) {
|
||||||
generateSwidTag("");
|
this.pemCertificateFile = pemCertificateFile;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This generator method is used by the create method.
|
|
||||||
*
|
|
||||||
* This method should be updated to incorporate the RIM fields that are implemented
|
|
||||||
* in generateSwidTag(final File outputFile) below.
|
|
||||||
*
|
|
||||||
* @param inputFile - the file in csv format that is used as data
|
|
||||||
* @param outputFile - output specific to the given file
|
|
||||||
* @param hashType - the optional labeling of the hash type
|
|
||||||
*/
|
|
||||||
public void generateSwidTag(final String inputFile,
|
|
||||||
final String outputFile, final String hashType) {
|
|
||||||
// create file instances
|
|
||||||
File input = new File(inputFile);
|
|
||||||
File output = new File(outputFile);
|
|
||||||
List<String> tempList = new LinkedList<>();
|
|
||||||
|
|
||||||
// I need to go over this again about which needs to be checked.
|
|
||||||
if (input.exists()) {
|
|
||||||
// parse the csv file
|
|
||||||
CsvParser parser = new CsvParser(input);
|
|
||||||
for (String line : parser.getContent()) {
|
|
||||||
tempList.add(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hashType.contains("256")) {
|
|
||||||
hashValue = _DEFAULT_QNAME;
|
|
||||||
} else if (hashType.contains("384")) {
|
|
||||||
hashValue = _SHA384Value_QNAME;
|
|
||||||
} else if (hashType.contains("512")) {
|
|
||||||
hashValue = _SHA512Value_QNAME;
|
|
||||||
} else if (hashType.contains("1")) {
|
|
||||||
hashValue = _SHA1Value_QNAME;
|
|
||||||
} else {
|
|
||||||
hashValue = _DEFAULT_QNAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate a swid tag
|
|
||||||
Properties properties = new Properties();
|
|
||||||
InputStream is = null;
|
|
||||||
try {
|
|
||||||
is = SwidTagGateway.class.getClassLoader().getResourceAsStream(SwidTagConstants.HIRS_SWIDTAG_HEADERS);
|
|
||||||
properties.load(is);
|
|
||||||
|
|
||||||
SoftwareIdentity swidTag = createSwidTag(new JsonObject());
|
|
||||||
|
|
||||||
JAXBElement<Entity> entity = objectFactory.createSoftwareIdentityEntity(createEntity(new JsonObject()));
|
|
||||||
swidTag.getEntityOrEvidenceOrLink().add(entity);
|
|
||||||
|
|
||||||
// we should have resources, there for we need a collection
|
|
||||||
JAXBElement<ResourceCollection> resources = objectFactory.createSoftwareIdentityPayload(createPayload(tempList, hashValue));
|
|
||||||
swidTag.getEntityOrEvidenceOrLink().add(resources);
|
|
||||||
|
|
||||||
JAXBElement<SoftwareIdentity> jaxbe = objectFactory.createSoftwareIdentity(swidTag);
|
|
||||||
writeSwidTagFile(jaxbe, output);
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("Error reading properties file: ");
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
if (is != null) {
|
|
||||||
try {
|
|
||||||
is.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method generates a base RIM from the values in a JSON file.
|
* This method generates a base RIM from the values in a JSON file.
|
||||||
*
|
*
|
||||||
* @param outputFile
|
* @param filename
|
||||||
*/
|
*/
|
||||||
public void generateSwidTag(final String filename) {
|
public void generateSwidTag(final String filename) {
|
||||||
SoftwareIdentity swidTag = null;
|
SoftwareIdentity swidTag = null;
|
||||||
try {
|
try {
|
||||||
System.out.println("Reading base rim values from " + attributesFile);
|
|
||||||
BufferedReader jsonIn = Files.newBufferedReader(Paths.get(attributesFile), StandardCharsets.UTF_8);
|
BufferedReader jsonIn = Files.newBufferedReader(Paths.get(attributesFile), StandardCharsets.UTF_8);
|
||||||
JsonObject configProperties = Json.parse(jsonIn).asObject();
|
JsonObject configProperties = Json.parse(jsonIn).asObject();
|
||||||
//SoftwareIdentity
|
//SoftwareIdentity
|
||||||
@ -318,12 +202,7 @@ public class SwidTagGateway {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Document signedSoftwareIdentity = signXMLDocument(objectFactory.createSoftwareIdentity(swidTag));
|
Document signedSoftwareIdentity = signXMLDocument(objectFactory.createSoftwareIdentity(swidTag));
|
||||||
System.out.println("Signature core validity: " + validateSignedXMLDocument(signedSoftwareIdentity));
|
writeSwidTagFile(signedSoftwareIdentity, filename);
|
||||||
if (!filename.isEmpty()) {
|
|
||||||
writeSwidTagFile(signedSoftwareIdentity, new File(filename));
|
|
||||||
} else {
|
|
||||||
writeSwidTagFile(signedSoftwareIdentity, generatedFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -334,51 +213,33 @@ public class SwidTagGateway {
|
|||||||
* @param path the location of the file to be validated
|
* @param path the location of the file to be validated
|
||||||
*/
|
*/
|
||||||
public boolean validateSwidTag(String path) throws IOException {
|
public boolean validateSwidTag(String path) throws IOException {
|
||||||
JAXBElement jaxbe = unmarshallSwidTag(path);
|
Document document = unmarshallSwidTag(path);
|
||||||
SoftwareIdentity swidTag = (SoftwareIdentity) jaxbe.getValue();
|
Element softwareIdentity = (Element) document.getElementsByTagName("SoftwareIdentity").item(0);
|
||||||
String output = String.format("name: %s;\ntagId: %s\n%s",
|
StringBuilder si = new StringBuilder("Base RIM detected:\n");
|
||||||
swidTag.getName(), swidTag.getTagId(),
|
si.append("SoftwareIdentity name: " + softwareIdentity.getAttribute("name") + "\n");
|
||||||
SwidTagConstants.SCHEMA_STATEMENT);
|
si.append("SoftwareIdentity tagId: " + softwareIdentity.getAttribute("tagId") + "\n");
|
||||||
System.out.println("SWID Tag found: ");
|
System.out.println(si.toString());
|
||||||
System.out.println(output);
|
System.out.println("Signature core validity: " + validateSignedXMLDocument(document));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method calls the marshal() method that writes the swidtag data to the output file.
|
|
||||||
*
|
|
||||||
* @param jaxbe
|
|
||||||
* @param outputFile
|
|
||||||
*/
|
|
||||||
public void writeSwidTagFile(JAXBElement<SoftwareIdentity> jaxbe, File outputFile) {
|
|
||||||
JAXBContext jaxbContext;
|
|
||||||
try {
|
|
||||||
jaxbContext = JAXBContext.newInstance(SwidTagConstants.SCHEMA_PACKAGE);
|
|
||||||
Marshaller marshaller = jaxbContext.createMarshaller();
|
|
||||||
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
|
|
||||||
marshaller.marshal(jaxbe, outputFile);
|
|
||||||
} catch (JAXBException e) {
|
|
||||||
System.out.println("Error generating xml: ");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method writes a Document object out to the file specified by generatedFile.
|
* This method writes a Document object out to the file specified by generatedFile.
|
||||||
*
|
*
|
||||||
* @param swidTag
|
* @param swidTag
|
||||||
*/
|
*/
|
||||||
public void writeSwidTagFile(Document swidTag, File outputFile) {
|
public void writeSwidTagFile(Document swidTag, String output) {
|
||||||
try {
|
try {
|
||||||
OutputStream outStream = new FileOutputStream(outputFile);
|
|
||||||
TransformerFactory tf = TransformerFactory.newInstance();
|
TransformerFactory tf = TransformerFactory.newInstance();
|
||||||
Transformer transformer = tf.newTransformer();
|
Transformer transformer = tf.newTransformer();
|
||||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||||
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
|
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
|
||||||
Source source = new DOMSource(swidTag);
|
Source source = new DOMSource(swidTag);
|
||||||
System.out.println("Writing to file: " + outputFile.getName());
|
if (output.isEmpty()) {
|
||||||
transformer.transform(source, new StreamResult(outStream));
|
transformer.transform(source, new StreamResult(System.out));
|
||||||
transformer.transform(source, new StreamResult(System.out));
|
} else {
|
||||||
|
transformer.transform(source, new StreamResult(new FileOutputStream(output)));
|
||||||
|
}
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
System.out.println("Unable to write to file: " + e.getMessage());
|
System.out.println("Unable to write to file: " + e.getMessage());
|
||||||
} catch (TransformerConfigurationException e) {
|
} catch (TransformerConfigurationException e) {
|
||||||
@ -392,7 +253,7 @@ public class SwidTagGateway {
|
|||||||
* This method creates SoftwareIdentity element based on the parameters read in from
|
* This method creates SoftwareIdentity element based on the parameters read in from
|
||||||
* a properties file.
|
* a properties file.
|
||||||
*
|
*
|
||||||
* @param properties the Properties object containing parameters from file
|
* @param jsonObject the Properties object containing parameters from file
|
||||||
* @return SoftwareIdentity object created from the properties
|
* @return SoftwareIdentity object created from the properties
|
||||||
*/
|
*/
|
||||||
private SoftwareIdentity createSwidTag(JsonObject jsonObject) {
|
private SoftwareIdentity createSwidTag(JsonObject jsonObject) {
|
||||||
@ -426,7 +287,7 @@ public class SwidTagGateway {
|
|||||||
* This method creates an Entity object based on the parameters read in from
|
* This method creates an Entity object based on the parameters read in from
|
||||||
* a properties file.
|
* a properties file.
|
||||||
*
|
*
|
||||||
* @param properties the Properties object containing parameters from file
|
* @param jsonObject the Properties object containing parameters from file
|
||||||
* @return Entity object created from the properties
|
* @return Entity object created from the properties
|
||||||
*/
|
*/
|
||||||
private Entity createEntity(JsonObject jsonObject) {
|
private Entity createEntity(JsonObject jsonObject) {
|
||||||
@ -463,7 +324,7 @@ public class SwidTagGateway {
|
|||||||
/**
|
/**
|
||||||
* Thsi method creates a Link element based on the parameters read in from a properties
|
* Thsi method creates a Link element based on the parameters read in from a properties
|
||||||
* file.
|
* file.
|
||||||
* @param properties the Properties object containing parameters from file
|
* @param jsonObject the Properties object containing parameters from file
|
||||||
* @return Link element created from the properties
|
* @return Link element created from the properties
|
||||||
*/
|
*/
|
||||||
private Link createLink(JsonObject jsonObject) {
|
private Link createLink(JsonObject jsonObject) {
|
||||||
@ -483,7 +344,7 @@ public class SwidTagGateway {
|
|||||||
/**
|
/**
|
||||||
* This method creates a Meta element based on the parameters read in from a properties
|
* This method creates a Meta element based on the parameters read in from a properties
|
||||||
* file.
|
* file.
|
||||||
* @param properties the Properties object containing parameters from file
|
* @param jsonObject the Properties object containing parameters from file
|
||||||
* @return the Meta element created from the properties
|
* @return the Meta element created from the properties
|
||||||
*/
|
*/
|
||||||
private SoftwareMeta createSoftwareMeta(JsonObject jsonObject) {
|
private SoftwareMeta createSoftwareMeta(JsonObject jsonObject) {
|
||||||
@ -514,15 +375,15 @@ public class SwidTagGateway {
|
|||||||
/**
|
/**
|
||||||
* This method creates a Payload from the parameters read in from a properties file.
|
* This method creates a Payload from the parameters read in from a properties file.
|
||||||
*
|
*
|
||||||
* @param properties the Properties object containing parameters from file
|
* @param jsonObject the Properties object containing parameters from file
|
||||||
* @return the Payload object created
|
* @return the Payload object created
|
||||||
*/
|
*/
|
||||||
private ResourceCollection createPayload(JsonObject jsonObject) {
|
private ResourceCollection createPayload(JsonObject jsonObject) {
|
||||||
ResourceCollection payload = objectFactory.createResourceCollection();
|
ResourceCollection payload = objectFactory.createResourceCollection();
|
||||||
Map<QName, String> attributes = payload.getOtherAttributes();
|
Map<QName, String> attributes = payload.getOtherAttributes();
|
||||||
addNonNullAttribute(attributes, SwidTagConstants._N8060_ENVVARPREFIX, jsonObject.getString(SwidTagConstants.PAYLOAD_ENVVARPREFIX, ""));
|
addNonNullAttribute(attributes, SwidTagConstants._N8060_ENVVARPREFIX, jsonObject.getString(SwidTagConstants._N8060_ENVVARPREFIX.getLocalPart(), ""));
|
||||||
addNonNullAttribute(attributes, SwidTagConstants._N8060_ENVVARSUFFIX, jsonObject.getString(SwidTagConstants.PAYLOAD_ENVVARSUFFIX, ""));
|
addNonNullAttribute(attributes, SwidTagConstants._N8060_ENVVARSUFFIX, jsonObject.getString(SwidTagConstants._N8060_ENVVARSUFFIX.getLocalPart(), ""));
|
||||||
addNonNullAttribute(attributes, SwidTagConstants._N8060_PATHSEPARATOR, jsonObject.getString(SwidTagConstants.PAYLOAD_PATHSEPARATOR, ""));
|
addNonNullAttribute(attributes, SwidTagConstants._N8060_PATHSEPARATOR, jsonObject.getString(SwidTagConstants._N8060_PATHSEPARATOR.getLocalPart(), ""));
|
||||||
|
|
||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
@ -530,7 +391,7 @@ public class SwidTagGateway {
|
|||||||
/**
|
/**
|
||||||
* This method creates a Directory from the parameters read in from a properties file.
|
* This method creates a Directory from the parameters read in from a properties file.
|
||||||
*
|
*
|
||||||
* @param properties the Properties object containing parameters from file
|
* @param jsonObject the Properties object containing parameters from file
|
||||||
* @return Directory object created from the properties
|
* @return Directory object created from the properties
|
||||||
*/
|
*/
|
||||||
private Directory createDirectory(JsonObject jsonObject) {
|
private Directory createDirectory(JsonObject jsonObject) {
|
||||||
@ -540,13 +401,7 @@ public class SwidTagGateway {
|
|||||||
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_TYPE, jsonObject.getString(SwidTagConstants.SUPPORT_RIM_TYPE, ""));
|
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_TYPE, jsonObject.getString(SwidTagConstants.SUPPORT_RIM_TYPE, ""));
|
||||||
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_FORMAT, jsonObject.getString(SwidTagConstants.SUPPORT_RIM_FORMAT, ""));
|
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_FORMAT, jsonObject.getString(SwidTagConstants.SUPPORT_RIM_FORMAT, ""));
|
||||||
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_URI_GLOBAL, jsonObject.getString(SwidTagConstants.SUPPORT_RIM_URI_GLOBAL, ""));
|
addNonNullAttribute(attributes, SwidTagConstants._SUPPORT_RIM_URI_GLOBAL, jsonObject.getString(SwidTagConstants.SUPPORT_RIM_URI_GLOBAL, ""));
|
||||||
/*
|
|
||||||
directory.setLocation(jsonObject.getString(SwidTagConstants.DIRECTORY_LOCATION));
|
|
||||||
String directoryRoot = jsonObject.getString(SwidTagConstants.DIRECTORY_ROOT);
|
|
||||||
if (!directoryRoot.isEmpty()) {
|
|
||||||
directory.setRoot(directoryRoot);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return directory;
|
return directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,8 +409,7 @@ public class SwidTagGateway {
|
|||||||
* This method creates a hirs.swid.xjc.File from three arguments, then calculates
|
* This method creates a hirs.swid.xjc.File from three arguments, then calculates
|
||||||
* and stores its hash as an attribute in itself.
|
* and stores its hash as an attribute in itself.
|
||||||
*
|
*
|
||||||
* @param filename
|
* @param jsonObject
|
||||||
* @param location
|
|
||||||
* @return hirs.swid.xjc.File object from File object
|
* @return hirs.swid.xjc.File object from File object
|
||||||
*/
|
*/
|
||||||
private hirs.swid.xjc.File createFile(JsonObject jsonObject) {
|
private hirs.swid.xjc.File createFile(JsonObject jsonObject) {
|
||||||
@ -577,32 +431,6 @@ public class SwidTagGateway {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method creates a Payload from a list of Strings and a hash algorithm.
|
|
||||||
* The Strings in the list are expected to be in the form of "[PCR_NUMBER],[PCR_VALUE]"
|
|
||||||
* and the hash algorithm is attached as the file's xml namespace identifier.
|
|
||||||
*
|
|
||||||
* @param populate
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private ResourceCollection createPayload(List<String> populate, QName hashStr) {
|
|
||||||
ResourceCollection rc = objectFactory.createResourceCollection();
|
|
||||||
hirs.swid.xjc.File xjcFile = null;
|
|
||||||
String[] tempArray = null;
|
|
||||||
|
|
||||||
for (String item : populate) {
|
|
||||||
xjcFile = objectFactory.createFile();
|
|
||||||
|
|
||||||
tempArray = item.split(",");
|
|
||||||
|
|
||||||
xjcFile.setName(tempArray[SwidTagConstants.PCR_NUMBER]);
|
|
||||||
xjcFile.getOtherAttributes().put(hashStr, tempArray[SwidTagConstants.PCR_VALUE]);
|
|
||||||
rc.getDirectoryOrFileOrProcess().add(xjcFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method signs a SoftwareIdentity with an xmldsig in compatibility mode.
|
* This method signs a SoftwareIdentity with an xmldsig in compatibility mode.
|
||||||
* Current assumptions: digest method SHA256, signature method SHA256, enveloped signature
|
* Current assumptions: digest method SHA256, signature method SHA256, enveloped signature
|
||||||
@ -623,34 +451,47 @@ public class SwidTagGateway {
|
|||||||
sigFactory.newSignatureMethod(SwidTagConstants.SIGNATURE_ALGORITHM_RSA_SHA256, null),
|
sigFactory.newSignatureMethod(SwidTagConstants.SIGNATURE_ALGORITHM_RSA_SHA256, null),
|
||||||
Collections.singletonList(reference)
|
Collections.singletonList(reference)
|
||||||
);
|
);
|
||||||
KeyStore keystore = KeyStore.getInstance("JKS");
|
List<XMLStructure> keyInfoElements = new ArrayList<XMLStructure>();
|
||||||
keystore.load(new FileInputStream(keystoreFile), SwidTagConstants.DEFAULT_KEYSTORE_PASSWORD.toCharArray());
|
|
||||||
KeyStore.PrivateKeyEntry privateKey = (KeyStore.PrivateKeyEntry) keystore.getEntry(SwidTagConstants.DEFAULT_PRIVATE_KEY_ALIAS,
|
|
||||||
new KeyStore.PasswordProtection(SwidTagConstants.DEFAULT_KEYSTORE_PASSWORD.toCharArray()));
|
|
||||||
X509Certificate certificate = (X509Certificate) privateKey.getCertificate();
|
|
||||||
KeyInfoFactory kiFactory = sigFactory.getKeyInfoFactory();
|
KeyInfoFactory kiFactory = sigFactory.getKeyInfoFactory();
|
||||||
ArrayList<Object> x509Content = new ArrayList<Object>();
|
PrivateKey privateKey;
|
||||||
x509Content.add(certificate.getSubjectX500Principal().getName());
|
PublicKey publicKey;
|
||||||
if (showCert) {
|
CredentialParser cp = new CredentialParser();
|
||||||
|
if (defaultCredentials) {
|
||||||
|
cp.parseJKSCredentials();
|
||||||
|
privateKey = cp.getPrivateKey();
|
||||||
|
publicKey = cp.getPublicKey();
|
||||||
|
} else {
|
||||||
|
cp.parsePEMCredentials(pemCertificateFile, pemPrivateKeyFile);
|
||||||
|
X509Certificate certificate = cp.getCertificate();
|
||||||
|
privateKey = cp.getPrivateKey();
|
||||||
|
publicKey = cp.getPublicKey();
|
||||||
|
ArrayList<Object> x509Content = new ArrayList<Object>();
|
||||||
|
x509Content.add(certificate.getSubjectX500Principal().getName());
|
||||||
x509Content.add(certificate);
|
x509Content.add(certificate);
|
||||||
|
X509Data data = kiFactory.newX509Data(x509Content);
|
||||||
|
keyInfoElements.add(data);
|
||||||
}
|
}
|
||||||
X509Data data = kiFactory.newX509Data(x509Content);
|
KeyName keyName = kiFactory.newKeyName(cp.getCertificateSubjectKeyIdentifier());
|
||||||
KeyInfo keyinfo = kiFactory.newKeyInfo(Collections.singletonList(data));
|
keyInfoElements.add(keyName);
|
||||||
|
KeyValue keyValue = kiFactory.newKeyValue(publicKey);
|
||||||
|
keyInfoElements.add(keyValue);
|
||||||
|
KeyInfo keyinfo = kiFactory.newKeyInfo(keyInfoElements);
|
||||||
|
|
||||||
doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
|
doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
|
||||||
marshaller.marshal(swidTag, doc);
|
marshaller.marshal(swidTag, doc);
|
||||||
DOMSignContext context = new DOMSignContext(privateKey.getPrivateKey(), doc.getDocumentElement());
|
DOMSignContext context = new DOMSignContext(privateKey, doc.getDocumentElement());
|
||||||
XMLSignature signature = sigFactory.newXMLSignature(signedInfo, keyinfo);
|
XMLSignature signature = sigFactory.newXMLSignature(signedInfo, keyinfo);
|
||||||
signature.sign(context);
|
signature.sign(context);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
System.out.println("Keystore not found! " + e.getMessage());
|
System.out.println("Keystore not found! " + e.getMessage());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.out.println("Error loading keystore: " + e.getMessage());
|
System.out.println("Error loading keystore: " + e.getMessage());
|
||||||
} catch (NoSuchAlgorithmException | KeyStoreException | InvalidAlgorithmParameterException |
|
} catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException |
|
||||||
ParserConfigurationException | UnrecoverableEntryException e) {
|
ParserConfigurationException e) {
|
||||||
System.out.println(e.getMessage());
|
System.out.println(e.getMessage());
|
||||||
} catch (CertificateException e) {
|
} catch (KeyException e) {
|
||||||
System.out.println("Certificate error: " + e.getMessage());
|
System.out.println("Error setting public key in KeyValue: " + e.getMessage());
|
||||||
} catch (JAXBException e) {
|
} catch (JAXBException e) {
|
||||||
System.out.println("Error marshaling signed swidtag: " + e.getMessage());
|
System.out.println("Error marshaling signed swidtag: " + e.getMessage());
|
||||||
} catch (MarshalException | XMLSignatureException e) {
|
} catch (MarshalException | XMLSignatureException e) {
|
||||||
@ -733,92 +574,26 @@ public class SwidTagGateway {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an input swidtag at [path] parse any PCRs in the payload into an InputStream object.
|
* This method unmarshalls the swidtag found at [path] into a Document object
|
||||||
* This method will be used in a following pull request.
|
|
||||||
*
|
|
||||||
* @param path
|
|
||||||
* @return
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public ByteArrayInputStream parsePayload(String path) throws IOException {
|
|
||||||
JAXBElement jaxbe = unmarshallSwidTag(path);
|
|
||||||
SoftwareIdentity softwareIdentity = (SoftwareIdentity) jaxbe.getValue();
|
|
||||||
String pcrs = "";
|
|
||||||
if (!softwareIdentity.getEntityOrEvidenceOrLink().isEmpty()) {
|
|
||||||
List<Object> swidtag = softwareIdentity.getEntityOrEvidenceOrLink();
|
|
||||||
for (Object obj : swidtag) {
|
|
||||||
try {
|
|
||||||
JAXBElement element = (JAXBElement) obj;
|
|
||||||
String elementName = element.getName().getLocalPart();
|
|
||||||
if (elementName.equals(SwidTagConstants.PAYLOAD)) {
|
|
||||||
ResourceCollection rc = (ResourceCollection) element.getValue();
|
|
||||||
if (!rc.getDirectoryOrFileOrProcess().isEmpty()) {
|
|
||||||
pcrs = parsePCRs(rc.getDirectoryOrFileOrProcess());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
System.out.println("Found a non-JAXBElement object!" + e.getMessage());
|
|
||||||
throw new IOException("Found an invalid element in the swidtag file!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new ByteArrayInputStream(pcrs.getBytes(StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method traverses a hirs.swid.xjc.Directory recursively until it finds at
|
|
||||||
* least one hirs.swid.xjc.File. This File is expected to have an attribute of the form
|
|
||||||
* "[hash algorithm]=[hash value]."
|
|
||||||
*
|
|
||||||
* @param list of swidtag elements
|
|
||||||
* @return the hash value(s) parsed from the File object(s)
|
|
||||||
*/
|
|
||||||
private String parsePCRs(List list) {
|
|
||||||
final String newline = System.lineSeparator();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (Object listItem : list) {
|
|
||||||
if (listItem instanceof Directory) {
|
|
||||||
Directory dir = (Directory) listItem;
|
|
||||||
if (!dir.getDirectoryOrFile().isEmpty()) {
|
|
||||||
parsePCRs(dir.getDirectoryOrFile());
|
|
||||||
}
|
|
||||||
} else if (listItem instanceof hirs.swid.xjc.File){
|
|
||||||
hirs.swid.xjc.File pcr = (hirs.swid.xjc.File) listItem;
|
|
||||||
String pcrHash = "";
|
|
||||||
if (!pcr.getOtherAttributes().isEmpty()) {
|
|
||||||
Object[] fileAttributes = pcr.getOtherAttributes().values().toArray();
|
|
||||||
pcrHash = (String) fileAttributes[0];
|
|
||||||
}
|
|
||||||
if (pcrHash.isEmpty()) {
|
|
||||||
pcrHash = "null";
|
|
||||||
}
|
|
||||||
sb.append(pcr.getName() + "," + pcrHash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println(sb.toString());
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method unmarshalls the swidtag found at [path] into a JAXBElement object
|
|
||||||
* and validates it according to the schema.
|
* and validates it according to the schema.
|
||||||
*
|
*
|
||||||
* @param path to the input swidtag
|
* @param path to the input swidtag
|
||||||
* @return the SoftwareIdentity element at the root of the swidtag
|
* @return the SoftwareIdentity element at the root of the swidtag
|
||||||
* @throws IOException if the swidtag cannot be unmarshalled or validated
|
* @throws IOException if the swidtag cannot be unmarshalled or validated
|
||||||
*/
|
*/
|
||||||
private JAXBElement unmarshallSwidTag(String path) throws IOException {
|
private Document unmarshallSwidTag(String path) {
|
||||||
File input = null;
|
InputStream is = null;
|
||||||
InputStream is = null;
|
Document document = null;
|
||||||
JAXBElement swidtag = null;
|
try {
|
||||||
try {
|
document = removeXMLWhitespace(path);
|
||||||
input = new File(path);
|
is = SwidTagGateway.class.getClassLoader().getResourceAsStream(SwidTagConstants.SCHEMA_URL);
|
||||||
is = SwidTagGateway.class.getClassLoader().getResourceAsStream(SwidTagConstants.SCHEMA_URL);
|
SchemaFactory schemaFactory = SchemaFactory.newInstance(SwidTagConstants.SCHEMA_LANGUAGE);
|
||||||
SchemaFactory schemaFactory = SchemaFactory.newInstance(SwidTagConstants.SCHEMA_LANGUAGE);
|
Schema schema = schemaFactory.newSchema(new StreamSource(is));
|
||||||
Schema schema = schemaFactory.newSchema(new StreamSource(is));
|
unmarshaller.setSchema(schema);
|
||||||
unmarshaller.setSchema(schema);
|
unmarshaller.unmarshal(document);
|
||||||
swidtag = (JAXBElement) unmarshaller.unmarshal(input);
|
} catch (IOException e) {
|
||||||
} catch (SAXException e) {
|
System.out.println(e.getMessage());
|
||||||
|
} catch (SAXException e) {
|
||||||
System.out.println("Error setting schema for validation!");
|
System.out.println("Error setting schema for validation!");
|
||||||
} catch (UnmarshalException e) {
|
} catch (UnmarshalException e) {
|
||||||
System.out.println("Error validating swidtag file!");
|
System.out.println("Error validating swidtag file!");
|
||||||
@ -827,18 +602,46 @@ public class SwidTagGateway {
|
|||||||
} catch (JAXBException e) {
|
} catch (JAXBException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
if (is != null) {
|
if (is != null) {
|
||||||
try {
|
try {
|
||||||
is.close();
|
is.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.out.println("Error closing input stream");
|
System.out.println("Error closing input stream");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (swidtag != null) {
|
|
||||||
return swidtag;
|
|
||||||
} else {
|
|
||||||
throw new IOException("Invalid swidtag file!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method strips all whitespace from an xml file, including indents and spaces
|
||||||
|
* added for human-readability.
|
||||||
|
* @param path
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Document removeXMLWhitespace(String path) throws IOException {
|
||||||
|
TransformerFactory tf = TransformerFactory.newInstance();
|
||||||
|
Source source = new StreamSource(new File("identity_transform.xslt"));
|
||||||
|
Document document = null;
|
||||||
|
File input = new File(path);
|
||||||
|
if (input.length() > 0) {
|
||||||
|
try {
|
||||||
|
Transformer transformer = tf.newTransformer(source);
|
||||||
|
DOMResult result = new DOMResult();
|
||||||
|
transformer.transform(new StreamSource(input), result);
|
||||||
|
document = (Document) result.getNode();
|
||||||
|
} catch (TransformerConfigurationException e) {
|
||||||
|
System.out.println("Error configuring transformer!");
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (TransformerException e) {
|
||||||
|
System.out.println("Error transforming input!");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IOException("Input file is empty!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return document;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,292 +6,119 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.InvalidPathException;
|
import java.nio.file.InvalidPathException;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import com.beust.jcommander.Parameter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Commander is a class that handles the command line arguments for the SWID
|
* Commander is a class that handles the command line arguments for the SWID
|
||||||
* Tags gateway.
|
* Tags gateway by implementing the JCommander package.
|
||||||
*/
|
*/
|
||||||
public class Commander {
|
public class Commander {
|
||||||
|
|
||||||
private static final String COMMAND_PREFIX = "-";
|
@Parameter(names = {"-h", "--help"}, help = true, description = "Print this help text.")
|
||||||
private static final String FULL_COMMAND_PREFIX = "--";
|
private boolean help;
|
||||||
private static final String CREATE_STRING = "create";
|
@Parameter(names = {"-c", "--create \"base\""}, order = 0,
|
||||||
private static final String VERIFY_STRING = "verify";
|
description = "The type of RIM to create. A base RIM will be created by default.")
|
||||||
private static final String HELP_STRING = "help";
|
private String createType = "";//other possible values: "eventlog" and "pcr"
|
||||||
private static final String PARSE_STRING = "parse";
|
@Parameter(names = {"-a", "--attributes <path>"}, order = 1,
|
||||||
private static final String ATTRIBUTES_STRING = "attributes";
|
description = "The configuration file holding attributes to populate the base RIM with.")
|
||||||
private static final String KEYSTORE_STRING = "keystore";
|
|
||||||
private static final String SHOW_CERT_STRING = "show-cert";
|
|
||||||
|
|
||||||
private boolean hasArguments = false;
|
|
||||||
private boolean validate = false;
|
|
||||||
private boolean create = false;
|
|
||||||
private boolean parse = false;
|
|
||||||
private boolean attributesGiven = false;
|
|
||||||
private boolean keystoreGiven = false;
|
|
||||||
private boolean showCert = false;
|
|
||||||
|
|
||||||
private String validateFile;
|
|
||||||
private String createOutFile = "";
|
|
||||||
private String parseFile;
|
|
||||||
private String attributesFile = "";
|
private String attributesFile = "";
|
||||||
private String keystore = "";
|
@Parameter(names = {"-o", "--out <path>"}, order = 2,
|
||||||
private String hashAlg = null;
|
description = "The file to write the RIM out to. The RIM will be written to stdout by default.")
|
||||||
|
private String outFile = "";
|
||||||
/**
|
@Parameter(names = {"-v", "--verify <path>"}, order = 3,
|
||||||
* The main constructor for the Commander class
|
description = "Specify a RIM file to verify.")
|
||||||
*
|
private String verifyFile = "";
|
||||||
* @param args
|
@Parameter(names = {"-k", "--privateKeyFile <path>"}, order = 4,
|
||||||
*/
|
description = "File containing the private key used to sign the base RIM created by the create function.")
|
||||||
public Commander(final String[] args) {
|
private String privateKeyFile = "";
|
||||||
hasArguments = args.length > 0;
|
@Parameter(names = {"-p", "--publicCertificate <path>"}, order = 5,
|
||||||
|
description = "The public key certificate used to verify a RIM file or to embed in a signed RIM. " +
|
||||||
if (hasArguments) {
|
"A signed RIM generated by this tool by default will not show the signing certificate without this parameter present.")
|
||||||
parseArguments(args);
|
private String publicCertificate = "";
|
||||||
} else {
|
/*
|
||||||
printHelp();
|
@Parameter(names = {"-l", "--rimel <path>"}, order = 6,
|
||||||
}
|
description = "The TCG eventlog file to use as a support RIM. By default the last system eventlog will be used.")
|
||||||
|
private String rimEventLog = "";
|
||||||
if (create) {
|
@Parameter(names = {"-t", "--rimpcr <path>"}, order = 7,
|
||||||
if (hashAlg == null) {
|
description = "The file containing TPM PCR values to use as a support RIM. By default the current platform TPM will be used.")
|
||||||
hashAlg = "256";
|
private String rimPcrs = "";
|
||||||
}
|
//@Parameter(names = {}, order = 8, description = "")
|
||||||
|
private String toBeSigned = "";
|
||||||
if (!getCreateOutFile().isEmpty() && !isValidPath(getCreateOutFile())) {
|
@Parameter(names = {"-s", "--addSignatureData <originalBaseRIM> <signatureFile> <outputFile>"}, order = 8,
|
||||||
printHelp(String.format("Invalid file path %s!", getCreateOutFile()));
|
description = "The signature data in <signatureFile> will be combined with the data in <originalBaseRIM>" +
|
||||||
}
|
"and written to <outputFile>, or will overwrite <originalBaseRIM> if <outputFile> is not given.")
|
||||||
}
|
private String signatureData = "";
|
||||||
|
*/
|
||||||
|
public boolean isHelp() {
|
||||||
|
return help;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String getCreateType() {
|
||||||
* The default blank constructor
|
return createType;
|
||||||
*/
|
|
||||||
public Commander() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is called if an empty Commander was created, and later gets
|
|
||||||
* args. Will be used by the main constructor.
|
|
||||||
*
|
|
||||||
* @param args
|
|
||||||
*/
|
|
||||||
public final void parseArguments(final String[] args) {
|
|
||||||
String tempValue;
|
|
||||||
|
|
||||||
for (int i = 0; i < args.length; i++) {
|
|
||||||
tempValue = args[i];
|
|
||||||
|
|
||||||
switch (tempValue) {
|
|
||||||
case FULL_COMMAND_PREFIX + CREATE_STRING:
|
|
||||||
case COMMAND_PREFIX + "c":
|
|
||||||
create = true;
|
|
||||||
if (i+1 < args.length && !args[i+1].substring(0,1).equals(COMMAND_PREFIX)) {
|
|
||||||
createOutFile = args[++i];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FULL_COMMAND_PREFIX + ATTRIBUTES_STRING:
|
|
||||||
case COMMAND_PREFIX + "a":
|
|
||||||
attributesGiven = true;
|
|
||||||
if (i+1 < args.length && !args[i+1].substring(0,1).equals(COMMAND_PREFIX)) {
|
|
||||||
attributesFile = args[++i];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FULL_COMMAND_PREFIX + VERIFY_STRING:
|
|
||||||
case COMMAND_PREFIX + "v":
|
|
||||||
validate = true;
|
|
||||||
validateFile = args[++i];
|
|
||||||
break;
|
|
||||||
case FULL_COMMAND_PREFIX + PARSE_STRING:
|
|
||||||
case COMMAND_PREFIX + "p":
|
|
||||||
parse = true;
|
|
||||||
parseFile = args[++i];
|
|
||||||
break;
|
|
||||||
case FULL_COMMAND_PREFIX + SHOW_CERT_STRING:
|
|
||||||
showCert = true;
|
|
||||||
break;
|
|
||||||
case FULL_COMMAND_PREFIX + HELP_STRING:
|
|
||||||
case COMMAND_PREFIX + "h":
|
|
||||||
default:
|
|
||||||
printHelp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter for the input validate file associated with the validate flag
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public final String getValidateFile() {
|
|
||||||
return validateFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter for the output file for the create flag
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public final String getCreateOutFile() {
|
|
||||||
return createOutFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter for the property that indicates if something was given at the
|
|
||||||
* commandline.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public final boolean hasArguments() {
|
|
||||||
return hasArguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter for the validate command flag.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public final boolean validate() {
|
|
||||||
return validate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter for the create command flag.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public final boolean create() {
|
|
||||||
return create;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter for the hash algorithm to be used for hash functions.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public final String getHashAlg() {
|
|
||||||
return hashAlg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter for the parse command flag
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public final boolean parse() {
|
|
||||||
return parse;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter for the file to be parsed by the parse command flag
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public final String getParseFile() {
|
|
||||||
return parseFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter for the attributes file given flag
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public boolean isAttributesGiven() {
|
|
||||||
return attributesGiven;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter for the file containing attribute key-value pairs
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public String getAttributesFile() {
|
public String getAttributesFile() {
|
||||||
return attributesFile;
|
return attributesFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String getOutFile() {
|
||||||
* Getter for the keystore given flag
|
return outFile;
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public boolean isKeystoreGiven() {
|
|
||||||
return keystoreGiven;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String getVerifyFile() {
|
||||||
* Getter for the keystore used for digital signatures
|
return verifyFile;
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public String getKeystore() {
|
|
||||||
return keystore;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String getPrivateKeyFile() {
|
||||||
* Getter for boolean to show certificate data or not
|
return privateKeyFile;
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public boolean isShowCert() {
|
|
||||||
return showCert;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String getPublicCertificate() {
|
||||||
* Default no parameter help method.
|
return publicCertificate;
|
||||||
*/
|
|
||||||
private void printHelp() {
|
|
||||||
printHelp(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is used to inform the user of the allowed functionality of
|
|
||||||
* the program.
|
|
||||||
*/
|
|
||||||
private void printHelp(String message) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
|
|
||||||
if (message != null && !message.isEmpty()) {
|
|
||||||
sb.append(String.format("ERROR: %s\n\n", message));
|
|
||||||
}
|
|
||||||
sb.append("Usage: HIRS_SwidTag\n");
|
|
||||||
sb.append(" -c, --create <file>\t\tCreate a base rim and write to\n"
|
|
||||||
+ " \t\t\t\tthe given file. If no file is given the default is\n"
|
|
||||||
+ " \t\t\t\tgenerated_swidTag.swidtag\n\n");
|
|
||||||
sb.append(" -a, --attributes <file>\tSpecify the JSON file that contains\n"
|
|
||||||
+ " \t\t\t\tthe xml attributes to add to the RIM\n\n");
|
|
||||||
sb.append(" -v, --verify\t\t\tTakes the provided input file and\n"
|
|
||||||
+ " \t\t\t\tvalidates it against the schema at\n"
|
|
||||||
+ " \t\t\t\thttp://standards.iso.org/iso/19770/-2/2015/schema.xsd\n\n");
|
|
||||||
sb.append(" -p, --parse <file>\t\tParse the given swidtag's payload\n\n");
|
|
||||||
/*
|
/*
|
||||||
sb.append(" -k, --keystore <file>\tSpecify the keystore and its location to use\n"
|
public String getRimEventLog() {
|
||||||
+ " \t\t\t\tfor digital signatures\n");
|
return rimEventLog;
|
||||||
*/
|
|
||||||
sb.append(" --show-cert\t\t\tPrint the certificate in the signature block of\n"
|
|
||||||
+ " \t\t\t\tthe base RIM\n\n");
|
|
||||||
sb.append(" -h, --help, <no args>\tPrints this command help information.\n");
|
|
||||||
sb.append(" \t\t\t\tListing no command arguments will also\n"
|
|
||||||
+ " \t\t\t\tprint this help text.\n\n");
|
|
||||||
sb.append("Example commands: \n"
|
|
||||||
+ " Create a base rim from the default attribute file and write the rim\n"
|
|
||||||
+ " to generated_swidTag.swidtag:\n\n"
|
|
||||||
+ " \t\tjava -jar tcg_rim_tool-1.0.jar -c\n\n"
|
|
||||||
+ " Create a base rim from the values in config.json and write the rim\n"
|
|
||||||
+ " to base_rim.swidtag:\n\n"
|
|
||||||
+ " \t\tjava -jar tcg_rim_tool-1.0.jar -c base_rim.swidtag -a config.json\n\n"
|
|
||||||
+ " ");
|
|
||||||
|
|
||||||
System.out.println(sb.toString());
|
|
||||||
System.exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String getRimPcrs() {
|
||||||
* Checks that the file given to create a new swidtag is a valid path.
|
return rimPcrs;
|
||||||
* @param filepath
|
}
|
||||||
* @return
|
|
||||||
*/
|
public String getToBeSigned() {
|
||||||
public static boolean isValidPath(String filepath) {
|
return toBeSigned;
|
||||||
try {
|
}
|
||||||
System.out.println("Checking for a valid creation path...");
|
|
||||||
File file = new File(filepath);
|
public String getSignatureData() {
|
||||||
file.createNewFile();
|
return signatureData;
|
||||||
} catch (IOException | InvalidPathException | NullPointerException ex) {
|
}
|
||||||
return false;
|
*/
|
||||||
}
|
public String printHelpExamples() {
|
||||||
return true;
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Create a base RIM using the values in attributes.json; " +
|
||||||
|
"sign it with the default keystore, alias, and password;\n");
|
||||||
|
sb.append("and write the data to base_rim.swidtag:\n\n");
|
||||||
|
sb.append("\t\t-c base -a attributes.json -o base_rim.swidtag\n\n\n");
|
||||||
|
sb.append("Create a base RIM using the default attribute values; sign it using privateKey.pem;\n");
|
||||||
|
sb.append("and write the data to console output, to include cert.pem in the signature block:\n\n");
|
||||||
|
sb.append("\t\t-c base -k privateKey.pem -p cert.pem\n\n\n");
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Creating: " + getCreateType() + System.lineSeparator());
|
||||||
|
sb.append("Using attributes file: " + getAttributesFile() + System.lineSeparator());
|
||||||
|
sb.append("Write to: " + getOutFile() + System.lineSeparator());
|
||||||
|
sb.append("Verify file: " + getVerifyFile() + System.lineSeparator());
|
||||||
|
sb.append("Private key file: " + getPrivateKeyFile() + System.lineSeparator());
|
||||||
|
sb.append("Public certificate: " + getPublicCertificate() + System.lineSeparator());
|
||||||
|
/*
|
||||||
|
sb.append("Event log support RIM: " + 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,17 +14,16 @@ import org.testng.annotations.Test;
|
|||||||
|
|
||||||
public class TestSwidTagGateway {
|
public class TestSwidTagGateway {
|
||||||
private SwidTagGateway gateway;
|
private SwidTagGateway gateway;
|
||||||
private String inputFile, outputFile, hashType;
|
|
||||||
private final String DEFAULT_OUTPUT = "generated_swidTag.swidtag";
|
private final String DEFAULT_OUTPUT = "generated_swidTag.swidtag";
|
||||||
private final String DEFAULT_WITH_CERT = "generated_with_cert.swidtag";
|
private final String DEFAULT_WITH_CERT = "generated_with_cert.swidtag";
|
||||||
private final String DEFAULT_NO_CERT = "generated_no_cert.swidtag";
|
private final String DEFAULT_NO_CERT = "generated_no_cert.swidtag";
|
||||||
|
private final String certificateFile = "RimSignCert.pem";
|
||||||
|
private final String privateKeyFile = "privateRimKey.pem";
|
||||||
private InputStream expectedFile;
|
private InputStream expectedFile;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
gateway = new SwidTagGateway();
|
gateway = new SwidTagGateway();
|
||||||
inputFile = TestSwidTagGateway.class.getClassLoader().getResource("examplecsv.csv").getFile();
|
|
||||||
hashType = "SHA256";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
@ -35,29 +34,35 @@ public class TestSwidTagGateway {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creating a base RIM with default attributes with an X509Certificate element.
|
* This test corresponds to the arguments:
|
||||||
|
* -c base -k privateRimKey.pem -p RimSignCert.pem
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGenerateDefaultWithCert() {
|
public void testCreateBaseWithCert() {
|
||||||
gateway.setShowCert(true);
|
gateway.setDefaultCredentials(false);
|
||||||
gateway.generateSwidTag();
|
gateway.setPemCertificateFile(certificateFile);
|
||||||
|
gateway.setPemPrivateKeyFile(privateKeyFile);
|
||||||
|
gateway.generateSwidTag(DEFAULT_OUTPUT);
|
||||||
expectedFile = (InputStream) TestSwidTagGateway.class.getClassLoader().getResourceAsStream(DEFAULT_WITH_CERT);
|
expectedFile = (InputStream) TestSwidTagGateway.class.getClassLoader().getResourceAsStream(DEFAULT_WITH_CERT);
|
||||||
Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
|
Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a base RIM with default attributes without an X509Certificate element.
|
* This test corresponds to the arguments:
|
||||||
|
* -c base
|
||||||
|
* -c base -a <path>
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGenerateDefaultNoCert() {
|
public void testCreateBaseWithoutCert() {
|
||||||
gateway.setShowCert(false);
|
gateway.setDefaultCredentials(true);
|
||||||
gateway.generateSwidTag();
|
gateway.generateSwidTag(DEFAULT_OUTPUT);
|
||||||
expectedFile = (InputStream) TestSwidTagGateway.class.getClassLoader().getResourceAsStream(DEFAULT_NO_CERT);
|
expectedFile = (InputStream) TestSwidTagGateway.class.getClassLoader().getResourceAsStream(DEFAULT_NO_CERT);
|
||||||
Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
|
Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate a base RIM with default attributes with an X509Certificate element.
|
* This test corresponds to the arguments:
|
||||||
|
* -v <path> -p RimSignCert.pem
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testValidateSwidTag() {
|
public void testValidateSwidTag() {
|
||||||
@ -68,35 +73,6 @@ public class TestSwidTagGateway {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify expected values of a File element in a Payload element.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testParsePayload() {
|
|
||||||
InputStream is = null;
|
|
||||||
outputFile = TestSwidTagGateway.class.getClassLoader().getResource(DEFAULT_WITH_CERT).getPath();
|
|
||||||
try {
|
|
||||||
is = gateway.parsePayload(outputFile);
|
|
||||||
Scanner scanner = new Scanner(is, "UTF-8");
|
|
||||||
String test = "Example.com.iotBase.bin,688e293e3ccb522f6cf8a027c9ade7960f84bd0bf3a0b99812bc1fa498a2db8d";
|
|
||||||
String temp = "";
|
|
||||||
while (scanner.hasNext()) {
|
|
||||||
temp = scanner.next();
|
|
||||||
Assert.assertEquals(temp, test, "temp: " + temp + ", test: " + test);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Assert.fail("Error parsing test file!");
|
|
||||||
} finally {
|
|
||||||
if (is != null) {
|
|
||||||
try {
|
|
||||||
is.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Assert.fail("Failed to close input stream!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method compares two files by bytes to determine if they are the same or not.
|
* 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.
|
* @param file to be compared to the expected value.
|
||||||
|
@ -26,9 +26,17 @@ zu3HTmQfeRYs/c6Ck1k3bL1jnyWoNzhBqCuPYrZtPbv9opVP0YOxM5IjRkRgkZIDgYbh1k4WXw8O
|
|||||||
/iIMZuVJDfKQJSNCTAZsIbUatGDQc/nOihLHdI90wG8zu9amgrl1AEKzH8z864Fan5uuXolfAaak
|
/iIMZuVJDfKQJSNCTAZsIbUatGDQc/nOihLHdI90wG8zu9amgrl1AEKzH8z864Fan5uuXolfAaak
|
||||||
sLJl6RPCNcp+JNCXMMZiS8bmYPQnVJc1ze0I1A==</SignatureValue>
|
sLJl6RPCNcp+JNCXMMZiS8bmYPQnVJc1ze0I1A==</SignatureValue>
|
||||||
<KeyInfo>
|
<KeyInfo>
|
||||||
<X509Data>
|
<KeyName>2fdeb8e7d030a2209daa01861a964fedecf2bcc1</KeyName>
|
||||||
<X509SubjectName>CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US</X509SubjectName>
|
<KeyValue>
|
||||||
</X509Data>
|
<RSAKeyValue>
|
||||||
|
<Modulus>p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx
|
||||||
|
xkM6N18jEhQIx/CEZePEJqpluBO5w2wTEOe7hqtMatqgDDMeDRxUuIpP8LGP00vh1wyDFFew90d9
|
||||||
|
dvT3bcLvFh3a3ap9bTm6aBqPup5CXpzrwIU2wZfgkDytYVBm+8bHkMaUrgpNyM+5BAg2zl/Fqw0q
|
||||||
|
otjaGr7PzbH+urCvaGbKLMPoWkVLIgAE8Qw98HTfoYSFHC7VYQySrzIinaOBFSgViR72kHemH2lW
|
||||||
|
jDQeHiY0VIoPik/jVVIpjWe6zzeZ2S66Q/LmjQ==</Modulus>
|
||||||
|
<Exponent>AQAB</Exponent>
|
||||||
|
</RSAKeyValue>
|
||||||
|
</KeyValue>
|
||||||
</KeyInfo>
|
</KeyInfo>
|
||||||
</Signature>
|
</Signature>
|
||||||
</SoftwareIdentity>
|
</SoftwareIdentity>
|
||||||
|
@ -28,23 +28,35 @@ sLJl6RPCNcp+JNCXMMZiS8bmYPQnVJc1ze0I1A==</SignatureValue>
|
|||||||
<KeyInfo>
|
<KeyInfo>
|
||||||
<X509Data>
|
<X509Data>
|
||||||
<X509SubjectName>CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US</X509SubjectName>
|
<X509SubjectName>CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US</X509SubjectName>
|
||||||
<X509Certificate>MIIDYTCCAkmgAwIBAgIJAPB+r6VBhBn4MA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAlVTMQsw
|
<X509Certificate>MIIDoTCCAomgAwIBAgIJAPB+r6VBhBn5MA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAlVTMQsw
|
||||||
CQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxEjAQBgNVBAMM
|
CQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxEjAQBgNVBAMM
|
||||||
CUV4YW1wbGVDQTAeFw0yMDAyMTAxODE1MzRaFw0yOTEyMTkxODE1MzRaMFwxCzAJBgNVBAYTAlVT
|
CUV4YW1wbGVDQTAeFw0yMDAzMTExODExMjJaFw0zMDAxMTgxODExMjJaMFwxCzAJBgNVBAYTAlVT
|
||||||
MQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxGzAZBgNV
|
MQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxGzAZBgNV
|
||||||
BAMMEmV4YW1wbGUuUklNLnNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd1
|
BAMMEmV4YW1wbGUuUklNLnNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd1
|
||||||
lWGkSRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44/nBaccZD
|
lWGkSRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44/nBaccZD
|
||||||
OjdfIxIUCMfwhGXjxCaqZbgTucNsExDnu4arTGraoAwzHg0cVLiKT/Cxj9NL4dcMgxRXsPdHfXb0
|
OjdfIxIUCMfwhGXjxCaqZbgTucNsExDnu4arTGraoAwzHg0cVLiKT/Cxj9NL4dcMgxRXsPdHfXb0
|
||||||
923C7xYd2t2qfW05umgaj7qeQl6c68CFNsGX4JA8rWFQZvvGx5DGlK4KTcjPuQQINs5fxasNKqLY
|
923C7xYd2t2qfW05umgaj7qeQl6c68CFNsGX4JA8rWFQZvvGx5DGlK4KTcjPuQQINs5fxasNKqLY
|
||||||
2hq+z82x/rqwr2hmyizD6FpFSyIABPEMPfB036GEhRwu1WEMkq8yIp2jgRUoFYke9pB3ph9pVow0
|
2hq+z82x/rqwr2hmyizD6FpFSyIABPEMPfB036GEhRwu1WEMkq8yIp2jgRUoFYke9pB3ph9pVow0
|
||||||
Hh4mNFSKD4pP41VSKY1nus83mdkuukPy5o0CAwEAAaMvMC0wCQYDVR0TBAIwADALBgNVHQ8EBAMC
|
Hh4mNFSKD4pP41VSKY1nus83mdkuukPy5o0CAwEAAaNvMG0wHQYDVR0OBBYEFC/euOfQMKIgnaoB
|
||||||
BsAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAGuJ+dasb3/Mb7TBJ1Oe
|
hhqWT+3s8rzBMB8GA1UdIwQYMBaAFEahuO3bpnFf0NLneoo8XW6aw5Y4MAkGA1UdEwQCMAAwCwYD
|
||||||
al5ISq8d2LQD5ke5qnjgSQWKXfQ9fcUy3dWnt3Oked/i8B/Tyk3jCdTZJU3J3iRNgTqFfMLP8rU1
|
VR0PBAQDAgbAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUAA4IBAQBl2Bu9xpnH
|
||||||
w2tPYBjjuPKiiK4YRBHPxtFxPdOL1BPmL4ZzNs33Lv6H0m4aff9p6QpMclX5b/CRjl+80JWRLiLj
|
CCeeebjx+ILQXJXBd6q5+NQlV3zzBrf0bleZRtsOmsuFvWQoKQxsfZuk7QcSvVd/1v8mqwJ0PwbF
|
||||||
U3B0CejZB9dJrPr9SBaC31cDoeTpja9Cl86ip7KkqrZZIYeMuNF6ucWyWtjrW2kr3UhmEy8x/6y4
|
KQmrhIPWP+iowiBNqpG5PH9YxhpHQ1osOfibNLOXMhudIQRY0yAgqQf+MOlXYa0stX8gkgftVBDR
|
||||||
KigsK8sBwmNv4N2Pu3RppeIcpjYj5NVA1hwRA4eeMgJp2u+urm3l1oo1UNX1HsSSBHp1Owc9zZLm
|
utuMKyOTf4a6d8TUcbG2RnyzO/6S9bq4cPDYLqWRBM+aGN8e00UWTKpBl6/1EU8wkJA6WdllK2e8
|
||||||
07Pl8T46kpIA4sroCAU=</X509Certificate>
|
mVkXUPWYyHTZ0qQnrYiuLr36ycAznABDzEAoj4tMZbjIAfuscty6Ggzxl1WbyZLI6YzyXALwaYvr
|
||||||
|
crTLeyFynlKxuCfDnr1SAHDM65BY</X509Certificate>
|
||||||
</X509Data>
|
</X509Data>
|
||||||
|
<KeyName>2fdeb8e7d030a2209daa01861a964fedecf2bcc1</KeyName>
|
||||||
|
<KeyValue>
|
||||||
|
<RSAKeyValue>
|
||||||
|
<Modulus>p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx
|
||||||
|
xkM6N18jEhQIx/CEZePEJqpluBO5w2wTEOe7hqtMatqgDDMeDRxUuIpP8LGP00vh1wyDFFew90d9
|
||||||
|
dvT3bcLvFh3a3ap9bTm6aBqPup5CXpzrwIU2wZfgkDytYVBm+8bHkMaUrgpNyM+5BAg2zl/Fqw0q
|
||||||
|
otjaGr7PzbH+urCvaGbKLMPoWkVLIgAE8Qw98HTfoYSFHC7VYQySrzIinaOBFSgViR72kHemH2lW
|
||||||
|
jDQeHiY0VIoPik/jVVIpjWe6zzeZ2S66Q/LmjQ==</Modulus>
|
||||||
|
<Exponent>AQAB</Exponent>
|
||||||
|
</RSAKeyValue>
|
||||||
|
</KeyValue>
|
||||||
</KeyInfo>
|
</KeyInfo>
|
||||||
</Signature>
|
</Signature>
|
||||||
</SoftwareIdentity>
|
</SoftwareIdentity>
|
||||||
|
Loading…
Reference in New Issue
Block a user