mirror of
https://github.com/nsacyber/HIRS.git
synced 2024-12-21 05:53:27 +00:00
Overload CredentialParser method to handle parsing correct signing cert from a PEM truststore.
This commit is contained in:
parent
4b80a32129
commit
12338e40c2
@ -28,7 +28,9 @@ import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.security.Signature;
|
||||
import java.security.UnrecoverableEntryException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
@ -45,6 +47,7 @@ public class CredentialParser {
|
||||
private static final String X509 = "X.509";
|
||||
private static final String JKS = "JKS";
|
||||
private static final String PEM = "PEM";
|
||||
private static final String DEFAULT_ALGORITHM = "RSA";
|
||||
private static final String PKCS1_HEADER = "-----BEGIN RSA PRIVATE KEY-----";
|
||||
private static final String PKCS1_FOOTER = "-----END RSA PRIVATE KEY-----";
|
||||
private static final String PKCS8_HEADER = "-----BEGIN PRIVATE KEY-----";
|
||||
@ -98,17 +101,41 @@ public class CredentialParser {
|
||||
* @param truststore the PEM truststore
|
||||
* @return a list of X509 certs
|
||||
*/
|
||||
public List<X509Certificate> parseCertsFromPEM(String truststore) {
|
||||
public List<X509Certificate> parseCertsFromPEM(String truststore) {
|
||||
return parsePEMCertificates(truststore);
|
||||
}
|
||||
|
||||
public void parsePEMCredentials(List<X509Certificate> truststore,
|
||||
String privateKeyFile)
|
||||
throws Exception {
|
||||
byte[] challengeString = new byte[15];
|
||||
for (X509Certificate cert : truststore) {
|
||||
certificate = cert;
|
||||
privateKey = parsePEMPrivateKey(privateKeyFile, DEFAULT_ALGORITHM);
|
||||
publicKey = certificate.getPublicKey();
|
||||
SecureRandom.getInstanceStrong().nextBytes(challengeString);
|
||||
Signature signature = Signature.getInstance("SHA256withRSA");
|
||||
signature.initSign(privateKey);
|
||||
signature.update(challengeString);
|
||||
byte[] signedChallenge = signature.sign();
|
||||
signature.initVerify(publicKey);
|
||||
signature.update(challengeString);
|
||||
if (signature.verify(signedChallenge)) {
|
||||
System.out.println("Matched private key to truststore certificate");
|
||||
break;
|
||||
} else {
|
||||
publicKey = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void parsePEMCredentials(String certificateFile, String privateKeyFile)
|
||||
throws Exception {
|
||||
certificate = parsePEMCertificates(certificateFile).get(0);
|
||||
if (certificate.getIssuerX500Principal().equals(certificate.getSubjectX500Principal())) {
|
||||
throw new CertificateException("Signing certificate cannot be self-signed!");
|
||||
}
|
||||
privateKey = parsePEMPrivateKey(privateKeyFile, "RSA");
|
||||
privateKey = parsePEMPrivateKey(privateKeyFile, DEFAULT_ALGORITHM);
|
||||
publicKey = certificate.getPublicKey();
|
||||
}
|
||||
|
||||
@ -163,7 +190,8 @@ public class CredentialParser {
|
||||
} catch (CertificateException e) {
|
||||
System.out.println("Error in certificate factory: " + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
System.out.println("Error reading from input stream: " + e.getMessage());
|
||||
System.out.println("Error reading from input stream: " + filename);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (fis != null) {
|
||||
|
@ -58,28 +58,26 @@ public class Main {
|
||||
if (!attributesFile.isEmpty()) {
|
||||
gateway.setAttributesFile(attributesFile);
|
||||
}
|
||||
if (!defaultKey) {
|
||||
if (defaultKey) {
|
||||
gateway.setDefaultCredentials(true);
|
||||
gateway.setTruststoreFile(SwidTagConstants.DEFAULT_KEYSTORE_FILE);
|
||||
} else {
|
||||
gateway.setDefaultCredentials(false);
|
||||
if (!truststoreFile.isEmpty()) {
|
||||
gateway.setTruststoreFile(truststoreFile);
|
||||
} else if (!certificateFile.isEmpty() && !privateKeyFile.isEmpty()) {
|
||||
gateway.setPemCertificateFile(certificateFile);
|
||||
gateway.setPemPrivateKeyFile(privateKeyFile);
|
||||
if (embeddedCert) {
|
||||
gateway.setEmbeddedCert(true);
|
||||
}
|
||||
} else {
|
||||
gateway.setTruststoreFile(truststoreFile);
|
||||
gateway.setPemCertificateFile(certificateFile);
|
||||
gateway.setPemPrivateKeyFile(privateKeyFile);
|
||||
/*
|
||||
if () {
|
||||
System.out.println("Signing credentials must be provided " +
|
||||
"if not using defaults");
|
||||
System.exit(1);
|
||||
}
|
||||
*/
|
||||
if (embeddedCert) {
|
||||
gateway.setEmbeddedCert(true);
|
||||
}
|
||||
}
|
||||
if (rimEventLog.isEmpty()) {
|
||||
System.out.println("Error: a support RIM is required!");
|
||||
System.exit(1);
|
||||
} else {
|
||||
gateway.setRimEventLog(rimEventLog);
|
||||
}
|
||||
gateway.setRimEventLog(rimEventLog);
|
||||
List<String> timestampArguments = commander.getTimestampArguments();
|
||||
if (timestampArguments.size() > 0) {
|
||||
if (new TimestampArgumentValidator(timestampArguments).isValid()) {
|
||||
|
@ -102,7 +102,7 @@ public class SwidTagGateway {
|
||||
marshaller = jaxbContext.createMarshaller();
|
||||
attributesFile = SwidTagConstants.DEFAULT_ATTRIBUTES_FILE;
|
||||
defaultCredentials = true;
|
||||
truststoreFile = SwidTagConstants.DEFAULT_KEYSTORE_FILE;
|
||||
truststoreFile = "";
|
||||
pemCertificateFile = "";
|
||||
embeddedCert = false;
|
||||
rimEventLog = "";
|
||||
@ -599,11 +599,14 @@ public class SwidTagGateway {
|
||||
KeyName keyName = kiFactory.newKeyName(cp.getCertificateSubjectKeyIdentifier());
|
||||
keyInfoElements.add(keyName);
|
||||
} else {
|
||||
//If JKS or PEM...
|
||||
|
||||
cp.parsePEMCredentials(pemCertificateFile, pemPrivateKeyFile);
|
||||
X509Certificate certificate = cp.getCertificate();
|
||||
if (!truststoreFile.isEmpty()) {
|
||||
List<X509Certificate> truststore = cp.parseCertsFromPEM(truststoreFile);
|
||||
cp.parsePEMCredentials(truststore, pemPrivateKeyFile);
|
||||
} else {
|
||||
cp.parsePEMCredentials(pemCertificateFile, pemPrivateKeyFile);
|
||||
}
|
||||
privateKey = cp.getPrivateKey();
|
||||
X509Certificate certificate = cp.getCertificate();
|
||||
if (embeddedCert) {
|
||||
ArrayList<Object> x509Content = new ArrayList<Object>();
|
||||
x509Content.add(certificate.getSubjectX500Principal().getName());
|
||||
|
@ -45,7 +45,7 @@ public class Commander {
|
||||
@Parameter(names = {"-d", "--default-key"}, order = 8,
|
||||
description = "Use default signing credentials.")
|
||||
private boolean defaultKey = false;
|
||||
@Parameter(names = {"-l", "--rimel <path>"}, order = 9,
|
||||
@Parameter(names = {"-l", "--rimel <path>"}, order = 9, required = true,
|
||||
description = "The TCG eventlog file to use as a support RIM.")
|
||||
private String rimEventLog = "";
|
||||
@Parameter(names = {"--timestamp"}, order = 10, variableArity = true,
|
||||
@ -125,19 +125,15 @@ public class Commander {
|
||||
sb.append("Using attributes file: " + this.getAttributesFile() + System.lineSeparator());
|
||||
sb.append("Write to: " + this.getOutFile() + System.lineSeparator());
|
||||
sb.append("Verify file: " + this.getVerifyFile() + System.lineSeparator());
|
||||
if (!this.getTruststoreFile().isEmpty()) {
|
||||
if (this.isDefaultKey()) {
|
||||
sb.append("Truststore file: default (" + SwidTagConstants.DEFAULT_KEYSTORE_FILE + ")"
|
||||
+ System.lineSeparator());
|
||||
} else {
|
||||
sb.append("Truststore file: " + this.getTruststoreFile() + System.lineSeparator());
|
||||
} else if (!this.getPrivateKeyFile().isEmpty() &&
|
||||
!this.getPublicCertificate().isEmpty()) {
|
||||
sb.append("Private key file: " + this.getPrivateKeyFile() + System.lineSeparator());
|
||||
sb.append("Public certificate: " + this.getPublicCertificate()
|
||||
+ System.lineSeparator());
|
||||
sb.append("Embedded certificate: " + this.isEmbedded() + System.lineSeparator());
|
||||
} else if (this.isDefaultKey()){
|
||||
sb.append("Truststore file: default (" + SwidTagConstants.DEFAULT_KEYSTORE_FILE + ")"
|
||||
+ System.lineSeparator());
|
||||
} else {
|
||||
sb.append("Signing credential: (none given)" + System.lineSeparator());
|
||||
}
|
||||
sb.append("Event log support RIM: " + this.getRimEventLog() + System.lineSeparator());
|
||||
List<String> timestampArguments = this.getTimestampArguments();
|
||||
|
@ -16,6 +16,7 @@ public class TestSwidTagGateway {
|
||||
private final String DEFAULT_OUTPUT = "generated_swidTag.swidtag";
|
||||
private final String BASE_USER_CERT = "generated_user_cert.swidtag";
|
||||
private final String BASE_USER_CERT_EMBED = "generated_user_cert_embed.swidtag";
|
||||
private final String BASE_TRUSTSTORE_EMBED = "generated_truststore_embed.swidtag";
|
||||
private final String BASE_DEFAULT_CERT = "generated_default_cert.swidtag";
|
||||
private final String BASE_RFC3339_TIMESTAMP = "generated_timestamp_rfc3339.swidtag";
|
||||
private final String BASE_RFC3852_TIMESTAMP = "generated_timestamp_rfc3852.swidtag";
|
||||
@ -58,7 +59,7 @@ public class TestSwidTagGateway {
|
||||
* where RimSignCert.pem has the AIA extension.
|
||||
*/
|
||||
@Test
|
||||
public void testCreateBaseUserCertNotEmbedded() {
|
||||
public void testCreateBasePemCertNotEmbedded() {
|
||||
gateway.setDefaultCredentials(false);
|
||||
gateway.setPemCertificateFile(SIGNING_CERT_FILE);
|
||||
gateway.setPemPrivateKeyFile(PRIVATE_KEY_FILE);
|
||||
@ -77,8 +78,9 @@ public class TestSwidTagGateway {
|
||||
* -v [base RIM] -l TpmLog.bin -t RimCertChain.pem
|
||||
*/
|
||||
@Test
|
||||
public void testCreateBaseUserCertEmbedded() {
|
||||
public void testCreateBasePemCertEmbedded() {
|
||||
gateway.setDefaultCredentials(false);
|
||||
gateway.setTruststoreFile("");
|
||||
gateway.setPemCertificateFile(SIGNING_CERT_FILE);
|
||||
gateway.setPemPrivateKeyFile(PRIVATE_KEY_FILE);
|
||||
gateway.setEmbeddedCert(true);
|
||||
@ -89,6 +91,26 @@ public class TestSwidTagGateway {
|
||||
Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT));
|
||||
}
|
||||
|
||||
/**
|
||||
* This test corresponds to:
|
||||
* -c base -l TpmLog.bin -t RimCertChain.pem -k privateRimKey.pem -e
|
||||
* And then validates it:
|
||||
* -v [base RIM] -l TpmLog.bin -t RimCertChain.pem
|
||||
*/
|
||||
@Test
|
||||
public void testCreateBasePemTruststoreEmbedded() {
|
||||
gateway.setDefaultCredentials(false);
|
||||
gateway.setTruststoreFile(CA_CHAIN_FILE);
|
||||
gateway.setPemCertificateFile("");
|
||||
gateway.setPemPrivateKeyFile(PRIVATE_KEY_FILE);
|
||||
gateway.setEmbeddedCert(true);
|
||||
gateway.generateSwidTag(DEFAULT_OUTPUT);
|
||||
expectedFile = TestSwidTagGateway.class.getClassLoader()
|
||||
.getResourceAsStream(BASE_TRUSTSTORE_EMBED);
|
||||
Assert.assertTrue(compareFileBytesToExpectedFile(DEFAULT_OUTPUT));
|
||||
Assert.assertTrue(validator.validateSwidTag(DEFAULT_OUTPUT));
|
||||
}
|
||||
|
||||
/**
|
||||
* This test corresponds to the arguments:
|
||||
* -c base -l TpmLog.bin -d
|
||||
@ -111,7 +133,7 @@ public class TestSwidTagGateway {
|
||||
@Test
|
||||
public void testCreateTimestampRfc3339() {
|
||||
gateway.setDefaultCredentials(true);
|
||||
gateway.setJksTruststoreFile(JKS_KEYSTORE_FILE);
|
||||
gateway.setTruststoreFile(JKS_KEYSTORE_FILE);
|
||||
gateway.setTimestampFormat("RFC3339");
|
||||
gateway.setTimestampArgument("2023-01-01T00:00:00Z");
|
||||
gateway.generateSwidTag(DEFAULT_OUTPUT);
|
||||
@ -128,7 +150,7 @@ public class TestSwidTagGateway {
|
||||
@Test
|
||||
public void testCreateTimestampRfc3852() {
|
||||
gateway.setDefaultCredentials(true);
|
||||
gateway.setJksTruststoreFile(JKS_KEYSTORE_FILE);
|
||||
gateway.setTruststoreFile(JKS_KEYSTORE_FILE);
|
||||
gateway.setTimestampFormat("RFC3852");
|
||||
gateway.setTimestampArgument(RFC3852_COUNTERSIGNATURE_FILE);
|
||||
gateway.generateSwidTag(DEFAULT_OUTPUT);
|
||||
|
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<SoftwareIdentity xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" corpus="false" name="Example.com BIOS" patch="false" supplemental="false" tagId="94f6b457-9ac9-4d35-9b3f-78804173b65as" tagVersion="0" version="01" versionScheme="multipartnumeric" xml:lang="en">
|
||||
<Entity name="Example Inc" regid="http://Example.com" role="softwareCreator tagCreator"/>
|
||||
<Link href="https://Example.com/support/ProductA/firmware/installfiles" rel="installationmedia"/>
|
||||
<Meta xmlns:n8060="http://csrc.nist.gov/ns/swid/2015-extensions/1.0" xmlns:rim="https://trustedcomputinggroup.org/wp-content/uploads/TCG_RIM_Model" n8060:colloquialVersion="Firmware_2019" n8060:edition="12" n8060:product="ProductA" n8060:revision="r2" rim:PayloadType="direct" rim:bindingSpec="PC Client RIM" rim:bindingSpecVersion="1.2" rim:firmwareManufacturerId="00213022" rim:firmwareManufacturerStr="BIOSVendorA" rim:firmwareModel="A0" rim:firmwareVersion="12" rim:pcURIGlobal="https://Example.com/support/ProductA/" rim:pcURIlocal="/boot/tcg/manifest/switag/" rim:platformManufacturerId="00201234" rim:platformManufacturerStr="Example.com" rim:platformModel="ProductA" rim:platformVersion="01"/>
|
||||
<Payload>
|
||||
<Directory name="rim">
|
||||
<File xmlns:SHA256="http://www.w3.org/2001/04/xmlenc#sha256" SHA256:hash="4479ca722623f8c47b703996ced3cbd981b06b1ae8a897db70137e0b7c546848" name="Example.com.BIOS.01.rimel" size="7549"/>
|
||||
</Directory>
|
||||
</Payload>
|
||||
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<SignedInfo>
|
||||
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
|
||||
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
|
||||
<Reference URI="">
|
||||
<Transforms>
|
||||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||
</Transforms>
|
||||
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
|
||||
<DigestValue>DJMc0n3VHHwU+F3HNpiY/l3EMcjRZAQOYlrjhD5v9qE=</DigestValue>
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue>ojJ6v8ToxLWWekCKmBoZ+Yg2V4MYMPbKB9FjDs/QG/AMP+LKjnb55Z7FSLhC8+CvvShKPAoS9mv1
|
||||
QepwI17NEqbfnC1U4WH0u578A3J6wiHMXIDnIQqKAAXb8v2c/wjMDArzFl8CXmDA7HUDIt+3C4VC
|
||||
tA598YY7o0Hf6hK5qO8oWGQxXUKfpUwvtGLxHpbDWYFuVSPa+uk6OTzutt/QyzTERzxyO9Le1i6K
|
||||
nrpzh4lgHn6EfGs6HR1ffdHQ069q0bE61zDx0VC18nK9DmszW6p6FlMzApiTVW/4PiVt+dSFeVGR
|
||||
9///OdtxcoBCeofDDFPRyO+s+kY1pXd92Q3nfg==</SignatureValue>
|
||||
<KeyInfo>
|
||||
<X509Data>
|
||||
<X509SubjectName>CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US</X509SubjectName>
|
||||
<X509Certificate>MIIDoTCCAomgAwIBAgIJAIKly+6bklZlMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAlVTMQsw
|
||||
CQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxEjAQBgNVBAMM
|
||||
CUV4YW1wbGVDQTAeFw0yMDA2MTExNjUzMDFaFw0zMDA0MjAxNjUzMDFaMFwxCzAJBgNVBAYTAlVT
|
||||
MQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxGzAZBgNV
|
||||
BAMMEmV4YW1wbGUuUklNLnNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd1
|
||||
lWGkSRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44/nBaccZD
|
||||
OjdfIxIUCMfwhGXjxCaqZbgTucNsExDnu4arTGraoAwzHg0cVLiKT/Cxj9NL4dcMgxRXsPdHfXb0
|
||||
923C7xYd2t2qfW05umgaj7qeQl6c68CFNsGX4JA8rWFQZvvGx5DGlK4KTcjPuQQINs5fxasNKqLY
|
||||
2hq+z82x/rqwr2hmyizD6FpFSyIABPEMPfB036GEhRwu1WEMkq8yIp2jgRUoFYke9pB3ph9pVow0
|
||||
Hh4mNFSKD4pP41VSKY1nus83mdkuukPy5o0CAwEAAaNvMG0wHQYDVR0OBBYEFC/euOfQMKIgnaoB
|
||||
hhqWT+3s8rzBMB8GA1UdIwQYMBaAFEahuO3bpnFf0NLneoo8XW6aw5Y4MAkGA1UdEwQCMAAwCwYD
|
||||
VR0PBAQDAgbAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUAA4IBAQC1mG0naE0W
|
||||
4E9vujPhygf7LXHMFkMPs5uWyvkxe4zWgTg0RHTClbOFJQJ+pGLOcthSG6vIC6xYJxT5EKtB9rzR
|
||||
lEYHOi4MxuwXz9rLWQhA2zdbSo54Fb/BPoca5K9kxvAanRltEfqEFhCcRmqIX1i6mpOWiZsrdMs7
|
||||
IflHKBsylUTn+v636BAz3p2H8/lpJbF4LUFUxFU5FWB3tLuasxYTsbeE6YyNAnQIS95ML7c5H8z2
|
||||
aEQs5TCNHZJDyc0PZT2aPOuEj5lGv9oyBHbYDitszUWSVxF7z86uVGmYR/2oTIj6tqb+IwuvFtnO
|
||||
wiXFRS5ctLCdESr3SjdQF5wmIN4n</X509Certificate>
|
||||
</X509Data>
|
||||
</KeyInfo>
|
||||
</Signature>
|
||||
</SoftwareIdentity>
|
Loading…
Reference in New Issue
Block a user