From 70504e74237fdad4547a7d7b459c43ea41c9797d Mon Sep 17 00:00:00 2001
From: Cyrus <24922493+cyrus-dev@users.noreply.github.com>
Date: Fri, 5 Jun 2020 11:54:41 -0400
Subject: [PATCH 1/3] Modified how TPM2 Provisioner pulls down sub module cpr
(#255)
---
HIRS_ProvisionerTPM2/lib/CPR.CMakeLists.txt.in | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/HIRS_ProvisionerTPM2/lib/CPR.CMakeLists.txt.in b/HIRS_ProvisionerTPM2/lib/CPR.CMakeLists.txt.in
index 132a0c4b..7c67b746 100644
--- a/HIRS_ProvisionerTPM2/lib/CPR.CMakeLists.txt.in
+++ b/HIRS_ProvisionerTPM2/lib/CPR.CMakeLists.txt.in
@@ -4,8 +4,8 @@ project(cpr-download NONE)
include(ExternalProject)
ExternalProject_Add(cpr
- GIT_REPOSITORY https://github.com/whoshuu/cpr
- GIT_TAG 1.3.0
+ URL https://github.com/whoshuu/cpr/archive/1.3.0.zip
+ URL_HASH SHA1=d669d94b41ffaa2de478923c35a83074e34fdc12
SOURCE_DIR "${CMAKE_BINARY_DIR}/lib/cpr-src"
BINARY_DIR "${CMAKE_BINARY_DIR}/lib/cpr-build"
CONFIGURE_COMMAND ""
From 6ae5a18f9934618b3380e00ebf2b8982083ec3fa Mon Sep 17 00:00:00 2001
From: chubtub <43381989+chubtub@users.noreply.github.com>
Date: Wed, 11 Mar 2020 13:02:43 -0400
Subject: [PATCH 2/3] 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
---
build.gradle | 2 +-
tools/tcg_rim_tool/RimSignCert.pem | 22 +
tools/tcg_rim_tool/build.gradle | 3 +
tools/tcg_rim_tool/identity_transform.xslt | 10 +
tools/tcg_rim_tool/keystore.jks | Bin 2226 -> 2290 bytes
tools/tcg_rim_tool/privateRimKey.pem | 28 ++
.../main/java/hirs/swid/CredentialParser.java | 213 ++++++++
.../src/main/java/hirs/swid/Main.java | 80 +--
.../main/java/hirs/swid/SwidTagConstants.java | 50 +-
.../main/java/hirs/swid/SwidTagGateway.java | 457 +++++-------------
.../main/java/hirs/swid/utils/Commander.java | 355 ++++----------
.../java/hirs/swid/TestSwidTagGateway.java | 58 +--
.../test/resources/generated_no_cert.swidtag | 14 +-
.../resources/generated_with_cert.swidtag | 30 +-
14 files changed, 592 insertions(+), 730 deletions(-)
create mode 100644 tools/tcg_rim_tool/RimSignCert.pem
create mode 100644 tools/tcg_rim_tool/identity_transform.xslt
create mode 100644 tools/tcg_rim_tool/privateRimKey.pem
create mode 100644 tools/tcg_rim_tool/src/main/java/hirs/swid/CredentialParser.java
diff --git a/build.gradle b/build.gradle
index 26d24f74..ae1424e2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -119,7 +119,7 @@ subprojects {
'com.fasterxml.jackson.core:jackson-databind:2.6.3',
'com.fasterxml.jackson.core:jackson-annotations:2.6.3'],
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',
jstl: [ 'org.apache.taglibs:taglibs-standard-impl:1.2.5',
'org.apache.taglibs:taglibs-standard-spec:1.2.5'],
diff --git a/tools/tcg_rim_tool/RimSignCert.pem b/tools/tcg_rim_tool/RimSignCert.pem
new file mode 100644
index 00000000..9d37a2fa
--- /dev/null
+++ b/tools/tcg_rim_tool/RimSignCert.pem
@@ -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-----
diff --git a/tools/tcg_rim_tool/build.gradle b/tools/tcg_rim_tool/build.gradle
index fd331228..15dc4693 100644
--- a/tools/tcg_rim_tool/build.gradle
+++ b/tools/tcg_rim_tool/build.gradle
@@ -7,6 +7,8 @@ repositories {
dependencies {
compile libs.minimal_json
+ compile libs.jcommander
+ compile libs.bouncy_castle
testCompile libs.testng
}
@@ -17,6 +19,7 @@ jar {
)
}
from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {}
+ exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
}
uploadArchives {
diff --git a/tools/tcg_rim_tool/identity_transform.xslt b/tools/tcg_rim_tool/identity_transform.xslt
new file mode 100644
index 00000000..d249ca61
--- /dev/null
+++ b/tools/tcg_rim_tool/identity_transform.xslt
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/tcg_rim_tool/keystore.jks b/tools/tcg_rim_tool/keystore.jks
index 1102b2c52673157be8475cf71df10832de6a1e9a..2877d7f4c9d5c1f8d1b80c74e05e60b1e1652a2b 100644
GIT binary patch
delta 1701
zcmV;W23q;D5%Lj`Ab-lyZz%u(1p+XF1pY7%1_~<%0R#am0uccL1pows1nMwU4?f)=
z{d2+;AXW3*4xbsj3B}Z@iloK5z9z&9ALv8Il}FJZ)6MZt9t(x0RQ#M!_ocq=TfI4R
zKLX#Q#fLDi-zcCzYE|-4`V=r8-sjWk&}w;tpBrE442>g`t$!hC;iUc{iwb)%?W2~q
zbeWbCC6`p-`Sb#QYBCM6pE~!ji&Qu*=rs-T
z_rZL>Dxqe$sDFCBuX28k-c+=eiq--O`#<
zZa&2$p5tf8;1v~U4}!&$=@U1t_JQ@}%?W`1W#g~$IdRH!%VcFs9Skz
z9IDBOHWHHycZ2GJST8zOq}nl@z&?Lo8aKSy<4EiC&P53EkX9x9G;$9nCDL0}iZ0xf
zLW%7?$ba-}pgF&1w9_5-f6?yHPi8C{dJt!!!`-_q_@0wz%JR?vdgtPjcTQ5q5(r
z0A%Lq;luL5;Py~)JFux1q@Aw>p$Wf2TE98k3B<#)X2@R^dAXLULtn#xL`IHWwjF7J~tlVVycL9
zGbjO+AgobOtKVc8Vh`t8{acGNCfvXI03GhYQTn|#A8Njn2o-gW*1XAwkWK=Audeg|
zuG50uSq{zaU(_}u#SDqP7oNv@c=9n#Qg|@MI-)o7aX()#C0G^>Wc@_08=UOFsVY<4(V$?6
zb^Loy|56twi9ohPiGK-_$*OIUC)U5S_|k-Ys6BQ@^lK*#0+W?>a(7S{R<7cEW3s@y
z(%~NJp#r0~vU@<@V(ERO=}D>5eNvyXP=Bu_cY;Zdp2jm&vN(HIm{kK{cuu~TmN@KJ
z1>w4I#sjud+x?3jV<3u@W0mM{5gUV$dZpFo$?QuWFuH{hciu?~-krjf{DE*6Wg4r-
zK%!D%azbl&YqiyThrM{rPiDx_Sqns7pgB~8z(tAP#`C9vFDa)#bzAzQ-whb#MSrCU
z`3MvH5-5lt)M_uXO+(D7;Ag30(ZQs0vh(8Q6~o5JKoqpG;V^AGy5
zr@QAB|6ql!DM#Z0F9yeQ8^TxvaW~6&eX}M163Uk1QrAoFW$K4&@iGPovHzb8kSG(?DD+9Fdqg3RUIP)7%&!q
z6h@)A?c1htU(nL$dWt+4eRG8>&C1X$A`AgKrbFzHuett_>FAd&~|R1nd++l(tClYf7P
zx_89Xaj~{We6u_LlJ&Z{aPZhJrI7^Bni$_6(?u3cszH~p^$|}nkdQiA*<~wdyqQ@S
zQ1zI|blK9RC#{ICF1`B6z%!fxL(D)ZkBdxYxX1zfta9AC8VvE5Rh!9@$mxvoTmtZE
vi|cZ<%X=Ymo>H;6C&Qk-QUGww>lTn$eT}17yFMkI*vsR;TdG6yTwCUFwOCLW
delta 1637
zcmV-r2AcWu5wa1GAb&7bvKasX1p+XF1pY7%1_~<%0R#am0uccL1pows1nR3ZBP*7y
z-j$R1MH?Y^vsBH0jxxv`1IvQz-T#@ceOUb!1qFoq`^^HRIa*|`BeBc`(JAy4yZ~xp
z57~uw7;({$$PaGs+`QX5EGD6qrHljDDvj(Nha~wu8&vOwXMc7IJ1%o$Ka_x5vag=Z=zEWuHsn)v1O+!e|P<1^%a_I&Kky)iqw9{VHkBHDxFLC1#lN4axDvrFFkVS8f}ILLQQ
zFs2I{Y$Tz4!`)Vsh-iUMm%rb6m^N9$$d-w3VF|L;`xF!XFbw8f5gzj>58(oNrI0;D
zP+tpwCTHodp{-F4YcVy&-bDGwe0=2conjHL9zd!oa~54`k?=k%k^F@_gtz+Y$~)&L
zmJD7gJAV-lW?3&1TU32X^nI6?&BmB4#sMEd-70^3;qxoAL+mxvz`M7573r6>2?vFi
zYAiFcf(!k&aOa-n#vQ*6Y)!5QiZpfjVO>#}Y_zn;{-LBpQD}h{p
zTu`w002dytQ*IAUB_=W0dsxG-V-`Jhq!QQ`7j@j^B2XnqM>8
zx&itmMi+qMGk=jdbm^&aG?NwuA{k{c
zf&*bNf&xjP0|Eg80to={ey^oLgcM`L@}h{Y7(@}z#?f&-
z(~Hy-<}ZeGHqG}g{)f_T8h!t1=?YA8Rrzo5k&a)y(3O!cB7fskaC8ai*$3B2tor>(
z7J}bb1EJ*UjjuwN&Z4KXq^h=AA%~2((R#VXvRc^dTWKrZNM;i+G5@T%Dkv-~%K^e;
zZ{XdJyL4%#;vA+nBjnXU)*KN7hn_M5Y1;3uu5IPkiZxKx^&Z5M1bTHl2R+S_=F_v~
j@jg0|k^th$=oSbCW7vS-Q&4(1tS=WW(EF7TN~oBafineJ
diff --git a/tools/tcg_rim_tool/privateRimKey.pem b/tools/tcg_rim_tool/privateRimKey.pem
new file mode 100644
index 00000000..afe282c4
--- /dev/null
+++ b/tools/tcg_rim_tool/privateRimKey.pem
@@ -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-----
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
new file mode 100644
index 00000000..96f3fe5a
--- /dev/null
+++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/CredentialParser.java
@@ -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;
+ }
+}
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 9c83b043..da3baed2 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,50 +1,58 @@
package hirs.swid;
import hirs.swid.utils.Commander;
+import com.beust.jcommander.JCommander;
+
+import java.io.FileNotFoundException;
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 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();
- if (commander.hasArguments()) {
- // we have arguments to work with
- if (commander.isAttributesGiven()) {
- gateway.setAttributesFile(commander.getAttributesFile());
- }
- if (commander.isKeystoreGiven()) {
- gateway.setKeystoreFile(commander.getKeystore());
- }
- if (commander.isShowCert()) {
- gateway.setShowCert(true);
- }
-
- if (commander.create()) {
- // parsing the arguments detected a create parameter (-c)
- gateway.generateSwidTag(commander.getCreateOutFile());
- }
- 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());
+ if (commander.isHelp()) {
+ jc.usage();
+ System.out.println(commander.printHelpExamples());
+ } else {
+ if (!commander.getVerifyFile().isEmpty()) {
+ System.out.println(commander.toString());
+ String verifyFile = commander.getVerifyFile();
+ String publicCertificate = commander.getPublicCertificate();
+ if (!verifyFile.isEmpty() && !publicCertificate.isEmpty()) {
+ try {
+ gateway.validateSwidTag(verifyFile);
+ } catch (IOException e) {
+ System.out.println("Error validating RIM file: " + e.getMessage());
+ }
+ } else {
+ System.out.println("Need both a RIM file to validate and a public certificate to validate with!");
}
- }
- if (commander.parse()) {
- try {
- gateway.parsePayload(commander.getParseFile());
- } catch (IOException e) {
- System.out.println("Unable to parse file: " + e.getMessage());
+ } else {
+ System.out.println(commander.toString());
+ String createType = commander.getCreateType().toUpperCase();
+ String attributesFile = commander.getAttributesFile();
+ String certificateFile = commander.getPublicCertificate();
+ 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;
}
}
}
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 bad1a213..1e19a0a5 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
@@ -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 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_LANGUAGE = XMLConstants.W3C_XML_SCHEMA_NS_URI;
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 ENTITY = "Entity";
public static final String LINK = "Link";
@@ -147,48 +142,5 @@ public class SwidTagConstants {
"http://csrc.nist.gov/ns/swid/2015-extensions/1.0",
"pathSeparator", "n8060");
-//Below properties can probably be deleted
- 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;
+ public static final String CERTIFICATE_SUBJECT_KEY_IDENTIFIER = "2.5.29.14";
}
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 8673ae36..4fbe8b52 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
@@ -1,18 +1,19 @@
package hirs.swid;
-import javax.xml.bind.JAXB;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.UnmarshalException;
+import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
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.DigestMethod;
import javax.xml.crypto.dsig.Reference;
-import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.Transform;
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.dom.DOMSignContext;
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.TransformParameterSpec;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.io.ByteArrayInputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
-import java.io.OutputStream;
-import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
-import java.nio.file.Path;
import java.nio.file.Paths;
-import java.security.InvalidAlgorithmParameterException;
-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.*;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Properties;
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.Entity;
import hirs.swid.xjc.Link;
import hirs.swid.xjc.ObjectFactory;
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.SoftwareMeta;
-import hirs.swid.xjc.TransformType;
-import hirs.swid.xjc.TransformsType;
import com.eclipsesource.json.Json;
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;
@@ -120,32 +90,16 @@ import com.eclipsesource.json.ParseException;
*/
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(
"http://www.w3.org/2001/04/xmlenc#sha256", "hash", "SHA256");
-
private final ObjectFactory objectFactory = new ObjectFactory();
- private final File generatedFile = new File("generated_swidTag.swidtag");
- private QName hashValue = null;
-
private JAXBContext jaxbContext;
private Marshaller marshaller;
private Unmarshaller unmarshaller;
private String attributesFile;
- /**
- * The keystoreFile is used in signXMLDocument() to pass in the keystore path.
- * The same method requires the keystore password and the alias of the private key,
- * which would need to be passed in if not using the default keystore.
- */
- private String keystoreFile;
- private boolean showCert;
+ private boolean defaultCredentials;
+ private String pemPrivateKeyFile;
+ private String pemCertificateFile;
/**
* Default constructor initializes jaxbcontext, marshaller, and unmarshaller
@@ -156,8 +110,8 @@ public class SwidTagGateway {
marshaller = jaxbContext.createMarshaller();
unmarshaller = jaxbContext.createUnmarshaller();
attributesFile = SwidTagConstants.DEFAULT_ATTRIBUTES_FILE;
- keystoreFile = SwidTagConstants.DEFAULT_KEYSTORE_PATH;
- showCert = false;
+ defaultCredentials = true;
+ pemCertificateFile = "";
} catch (JAXBException e) {
System.out.println("Error initializing jaxbcontext: " + e.getMessage());
}
@@ -172,107 +126,37 @@ public class SwidTagGateway {
}
/**
- * Setter for String holding keystore path
- * @param keystore
+ * Setter for boolean governing signing credentials
+ * @param defaultCredentials
+ * @return
*/
- public void setKeystoreFile(String keystoreFile) {
- this.keystoreFile = keystoreFile;
+ public void setDefaultCredentials(boolean defaultCredentials) {
+ this.defaultCredentials = defaultCredentials;
}
/**
- * Setter for boolean to display certificate block in xml signature
- * @param showCert
+ * Setter for private key file in PEM format
+ * @param pemPrivateKeyFile
*/
- public void setShowCert(boolean showCert) {
- this.showCert = showCert;
+ public void setPemPrivateKeyFile(String pemPrivateKeyFile) {
+ this.pemPrivateKeyFile = pemPrivateKeyFile;
}
- /**
- * default generator method that has no parameters
+ /** Setter for certificate file in PEM format
+ * @param pemCertificateFile
*/
- public void generateSwidTag() {
- generateSwidTag("");
- }
-
- /**
- * 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 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 = objectFactory.createSoftwareIdentityEntity(createEntity(new JsonObject()));
- swidTag.getEntityOrEvidenceOrLink().add(entity);
-
- // we should have resources, there for we need a collection
- JAXBElement resources = objectFactory.createSoftwareIdentityPayload(createPayload(tempList, hashValue));
- swidTag.getEntityOrEvidenceOrLink().add(resources);
-
- JAXBElement 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
- }
- }
- }
- }
+ public void setPemCertificateFile(String pemCertificateFile) {
+ this.pemCertificateFile = pemCertificateFile;
}
/**
* This method generates a base RIM from the values in a JSON file.
*
- * @param outputFile
+ * @param filename
*/
public void generateSwidTag(final String filename) {
SoftwareIdentity swidTag = null;
try {
- System.out.println("Reading base rim values from " + attributesFile);
BufferedReader jsonIn = Files.newBufferedReader(Paths.get(attributesFile), StandardCharsets.UTF_8);
JsonObject configProperties = Json.parse(jsonIn).asObject();
//SoftwareIdentity
@@ -318,12 +202,7 @@ public class SwidTagGateway {
}
Document signedSoftwareIdentity = signXMLDocument(objectFactory.createSoftwareIdentity(swidTag));
- System.out.println("Signature core validity: " + validateSignedXMLDocument(signedSoftwareIdentity));
- if (!filename.isEmpty()) {
- writeSwidTagFile(signedSoftwareIdentity, new File(filename));
- } else {
- writeSwidTagFile(signedSoftwareIdentity, generatedFile);
- }
+ writeSwidTagFile(signedSoftwareIdentity, filename);
}
/**
@@ -334,51 +213,33 @@ public class SwidTagGateway {
* @param path the location of the file to be validated
*/
public boolean validateSwidTag(String path) throws IOException {
- JAXBElement jaxbe = unmarshallSwidTag(path);
- SoftwareIdentity swidTag = (SoftwareIdentity) jaxbe.getValue();
- String output = String.format("name: %s;\ntagId: %s\n%s",
- swidTag.getName(), swidTag.getTagId(),
- SwidTagConstants.SCHEMA_STATEMENT);
- System.out.println("SWID Tag found: ");
- System.out.println(output);
+ Document document = unmarshallSwidTag(path);
+ 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");
+ System.out.println(si.toString());
+ System.out.println("Signature core validity: " + validateSignedXMLDocument(document));
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 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.
*
* @param swidTag
*/
- public void writeSwidTagFile(Document swidTag, File outputFile) {
+ public void writeSwidTagFile(Document swidTag, String output) {
try {
- OutputStream outStream = new FileOutputStream(outputFile);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
Source source = new DOMSource(swidTag);
- System.out.println("Writing to file: " + outputFile.getName());
- transformer.transform(source, new StreamResult(outStream));
- transformer.transform(source, new StreamResult(System.out));
+ if (output.isEmpty()) {
+ transformer.transform(source, new StreamResult(System.out));
+ } else {
+ transformer.transform(source, new StreamResult(new FileOutputStream(output)));
+ }
} catch (FileNotFoundException e) {
System.out.println("Unable to write to file: " + e.getMessage());
} catch (TransformerConfigurationException e) {
@@ -392,7 +253,7 @@ public class SwidTagGateway {
* This method creates SoftwareIdentity element based on 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 SoftwareIdentity object created from the properties
*/
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
* 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
*/
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
* 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
*/
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
* 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
*/
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.
*
- * @param properties the Properties object containing parameters from file
+ * @param jsonObject the Properties object containing parameters from file
* @return the Payload object created
*/
private ResourceCollection createPayload(JsonObject jsonObject) {
ResourceCollection payload = objectFactory.createResourceCollection();
Map attributes = payload.getOtherAttributes();
- addNonNullAttribute(attributes, SwidTagConstants._N8060_ENVVARPREFIX, jsonObject.getString(SwidTagConstants.PAYLOAD_ENVVARPREFIX, ""));
- addNonNullAttribute(attributes, SwidTagConstants._N8060_ENVVARSUFFIX, jsonObject.getString(SwidTagConstants.PAYLOAD_ENVVARSUFFIX, ""));
- addNonNullAttribute(attributes, SwidTagConstants._N8060_PATHSEPARATOR, jsonObject.getString(SwidTagConstants.PAYLOAD_PATHSEPARATOR, ""));
+ addNonNullAttribute(attributes, SwidTagConstants._N8060_ENVVARPREFIX, jsonObject.getString(SwidTagConstants._N8060_ENVVARPREFIX.getLocalPart(), ""));
+ addNonNullAttribute(attributes, SwidTagConstants._N8060_ENVVARSUFFIX, jsonObject.getString(SwidTagConstants._N8060_ENVVARSUFFIX.getLocalPart(), ""));
+ addNonNullAttribute(attributes, SwidTagConstants._N8060_PATHSEPARATOR, jsonObject.getString(SwidTagConstants._N8060_PATHSEPARATOR.getLocalPart(), ""));
return payload;
}
@@ -530,7 +391,7 @@ public class SwidTagGateway {
/**
* 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
*/
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_FORMAT, jsonObject.getString(SwidTagConstants.SUPPORT_RIM_FORMAT, ""));
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;
}
@@ -554,8 +409,7 @@ public class SwidTagGateway {
* This method creates a hirs.swid.xjc.File from three arguments, then calculates
* and stores its hash as an attribute in itself.
*
- * @param filename
- * @param location
+ * @param jsonObject
* @return hirs.swid.xjc.File object from File object
*/
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 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.
* 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),
Collections.singletonList(reference)
);
- KeyStore keystore = KeyStore.getInstance("JKS");
- 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();
+ List keyInfoElements = new ArrayList();
+
KeyInfoFactory kiFactory = sigFactory.getKeyInfoFactory();
- ArrayList
diff --git a/tools/tcg_rim_tool/src/test/resources/generated_with_cert.swidtag b/tools/tcg_rim_tool/src/test/resources/generated_with_cert.swidtag
index be75f5a0..336ea344 100644
--- a/tools/tcg_rim_tool/src/test/resources/generated_with_cert.swidtag
+++ b/tools/tcg_rim_tool/src/test/resources/generated_with_cert.swidtag
@@ -28,23 +28,35 @@ sLJl6RPCNcp+JNCXMMZiS8bmYPQnVJc1ze0I1A==
CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US
- MIIDYTCCAkmgAwIBAgIJAPB+r6VBhBn4MA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAlVTMQsw
+ MIIDoTCCAomgAwIBAgIJAPB+r6VBhBn5MA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAlVTMQsw
CQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxEjAQBgNVBAMM
-CUV4YW1wbGVDQTAeFw0yMDAyMTAxODE1MzRaFw0yOTEyMTkxODE1MzRaMFwxCzAJBgNVBAYTAlVT
+CUV4YW1wbGVDQTAeFw0yMDAzMTExODExMjJaFw0zMDAxMTgxODExMjJaMFwxCzAJBgNVBAYTAlVT
MQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxGzAZBgNV
BAMMEmV4YW1wbGUuUklNLnNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd1
lWGkSRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44/nBaccZD
OjdfIxIUCMfwhGXjxCaqZbgTucNsExDnu4arTGraoAwzHg0cVLiKT/Cxj9NL4dcMgxRXsPdHfXb0
923C7xYd2t2qfW05umgaj7qeQl6c68CFNsGX4JA8rWFQZvvGx5DGlK4KTcjPuQQINs5fxasNKqLY
2hq+z82x/rqwr2hmyizD6FpFSyIABPEMPfB036GEhRwu1WEMkq8yIp2jgRUoFYke9pB3ph9pVow0
-Hh4mNFSKD4pP41VSKY1nus83mdkuukPy5o0CAwEAAaMvMC0wCQYDVR0TBAIwADALBgNVHQ8EBAMC
-BsAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAGuJ+dasb3/Mb7TBJ1Oe
-al5ISq8d2LQD5ke5qnjgSQWKXfQ9fcUy3dWnt3Oked/i8B/Tyk3jCdTZJU3J3iRNgTqFfMLP8rU1
-w2tPYBjjuPKiiK4YRBHPxtFxPdOL1BPmL4ZzNs33Lv6H0m4aff9p6QpMclX5b/CRjl+80JWRLiLj
-U3B0CejZB9dJrPr9SBaC31cDoeTpja9Cl86ip7KkqrZZIYeMuNF6ucWyWtjrW2kr3UhmEy8x/6y4
-KigsK8sBwmNv4N2Pu3RppeIcpjYj5NVA1hwRA4eeMgJp2u+urm3l1oo1UNX1HsSSBHp1Owc9zZLm
-07Pl8T46kpIA4sroCAU=
+Hh4mNFSKD4pP41VSKY1nus83mdkuukPy5o0CAwEAAaNvMG0wHQYDVR0OBBYEFC/euOfQMKIgnaoB
+hhqWT+3s8rzBMB8GA1UdIwQYMBaAFEahuO3bpnFf0NLneoo8XW6aw5Y4MAkGA1UdEwQCMAAwCwYD
+VR0PBAQDAgbAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUAA4IBAQBl2Bu9xpnH
+CCeeebjx+ILQXJXBd6q5+NQlV3zzBrf0bleZRtsOmsuFvWQoKQxsfZuk7QcSvVd/1v8mqwJ0PwbF
+KQmrhIPWP+iowiBNqpG5PH9YxhpHQ1osOfibNLOXMhudIQRY0yAgqQf+MOlXYa0stX8gkgftVBDR
+utuMKyOTf4a6d8TUcbG2RnyzO/6S9bq4cPDYLqWRBM+aGN8e00UWTKpBl6/1EU8wkJA6WdllK2e8
+mVkXUPWYyHTZ0qQnrYiuLr36ycAznABDzEAoj4tMZbjIAfuscty6Ggzxl1WbyZLI6YzyXALwaYvr
+crTLeyFynlKxuCfDnr1SAHDM65BY
+ 2fdeb8e7d030a2209daa01861a964fedecf2bcc1
+
+
+ p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx
+xkM6N18jEhQIx/CEZePEJqpluBO5w2wTEOe7hqtMatqgDDMeDRxUuIpP8LGP00vh1wyDFFew90d9
+dvT3bcLvFh3a3ap9bTm6aBqPup5CXpzrwIU2wZfgkDytYVBm+8bHkMaUrgpNyM+5BAg2zl/Fqw0q
+otjaGr7PzbH+urCvaGbKLMPoWkVLIgAE8Qw98HTfoYSFHC7VYQySrzIinaOBFSgViR72kHemH2lW
+jDQeHiY0VIoPik/jVVIpjWe6zzeZ2S66Q/LmjQ==
+ AQAB
+
+
From 8eda518b0adfd2b03652b71bd7a113075a463bc0 Mon Sep 17 00:00:00 2001
From: chubtub <43381989+chubtub@users.noreply.github.com>
Date: Mon, 8 Jun 2020 06:50:16 -0400
Subject: [PATCH 3/3] Add exit code 1 for failed validation
---
tools/tcg_rim_tool/src/main/java/hirs/swid/Main.java | 2 ++
1 file changed, 2 insertions(+)
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 da3baed2..1f93b38c 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
@@ -27,9 +27,11 @@ public class Main {
gateway.validateSwidTag(verifyFile);
} catch (IOException e) {
System.out.println("Error validating RIM file: " + e.getMessage());
+ System.exit(1);
}
} else {
System.out.println("Need both a RIM file to validate and a public certificate to validate with!");
+ System.exit(1);
}
} else {
System.out.println(commander.toString());