removed TPM_Utils

This commit is contained in:
iadgovuser26 iadgovuser26@empire.eclipse.ncsc.mil 2024-08-21 14:01:36 -04:00
parent c929ee3bb3
commit fd3bbd26a3
11 changed files with 0 additions and 526 deletions

View File

@ -1,45 +0,0 @@
apply plugin: 'java'
apply plugin: 'checkstyle'
apply plugin: 'jacoco'
sourceCompatibility = 1.8
dependencies {
compile libs.log4j2
compile libs.commons_codec
compile libs.commons_io
compile libs.commons_lang
compile libs.spring_core
testCompile libs.testng
}
ext.configDir = new File(projectDir, 'config')
ext.checkstyleConfigDir = "$configDir/checkstyle"
checkstyle {
toolVersion = '5.7'
configFile = checkstyleConfigFile
configProperties.put('basedir', checkstyleConfigDir)
ignoreFailures = false
showViolations = true
}
jacocoTestReport {
reports {
xml.enabled true
csv.enabled true
html.enabled true
html.destination "${buildDir}/reports/jacoco/html"
}
}
publishing {
publications {
maven(MavenPublication) {
artifactId 'hirs-tpm-utils'
from components.java
}
}
}

View File

@ -1,13 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<suppress checks="MagicNumber" files=".*[/\\]src[/\\]test[/\\]+" />
<suppress checks="FinalParameters" files=".*[/\\]src[/\\]test[/\\]+" />
<suppress checks="JavadocPackage" files=".*[/\\]src[/\\]test[/\\]+" />
</suppressions>

View File

@ -1,60 +0,0 @@
package hirs.tpm.tss;
import java.io.IOException;
/**
* Defines the functionality of a Tpm as specified in the TCG TSS Specification.
*/
public interface Tpm {
/**
* Takes ownership of an active but unowned Tpm.
*/
void takeOwnership();
/**
* Obtain the public Endorsement Credential modulus.
*
* @return the endorsement credential modulus
* @see #collateIdentityRequest(byte[], String)
*/
byte[] getEndorsementCredentialModulus();
/**
* Obtains the full Endorsement Credential stored in the TPM.
* @return the EC on the TPM, if present, otherwise null
* @throws IOException if there's an error writing the EC to a temporary file for processing
*/
byte[] getEndorsementCredential() throws IOException;
/**
* Instructs the Tpm to collate an identity request as stated in the TSS specification.
*
* @param acaPublicKey non null, ACA PK information.
* @param uuid non null, non empty, UUID for the identity.
* @return the identity request. to be later attested.
*/
byte[] collateIdentityRequest(byte[] acaPublicKey, String uuid);
/**
* Activates the identity within the TPM given the label and ACA symmetric and asymmetric
* identity response blobs. The return will be the identity credential that is activated within
* the TPM.
*
* @param asymmetricBlob from ACA identity response
* @param symmetricBlob from ACA identity response
* @param uuid of the identity request
* @return the activated identity credential
*/
byte[] activateIdentity(byte[] asymmetricBlob, byte[] symmetricBlob, String uuid);
/**
* Queries the TPM for quote data given the specified pcrValues using the specified UUID.
*
* @param pcrValues cannot be null or empty
* @param nonce cannot be null or empty
* @param uuid cannot be null or empty
* @return quote data
*/
byte[] getQuote(String pcrValues, String nonce, String uuid);
}

View File

@ -1,28 +0,0 @@
package hirs.tpm.tss.command;
/**
* Exception that is thrown by the {@link CommandTpm} when executing operations.
*/
public class CommandException extends RuntimeException {
private CommandResult commandResult;
/**
* Constructs this exception with the specified message and the command result.
*
* @param message as to why this exception occurred
* @param commandResult the result of the command that caused this exception
*/
public CommandException(final String message, final CommandResult commandResult) {
super(message);
this.commandResult = commandResult;
}
/**
* @return {@link CommandResult} of the command that caused this exception
*/
public CommandResult getCommandResult() {
return this.commandResult;
}
}

View File

@ -1,42 +0,0 @@
package hirs.tpm.tss.command;
/**
* Encapsulates the results of executing a command.
*/
public class CommandResult {
/**
* The exit status when attempting to take ownership of an already owned TPM.
*/
public static final int TPM_PREVIOUSLY_OWNED_ERROR = 20;
private String output;
private int exitStatus;
/**
* Creates the command result with the specified output and exist status.
*
* @param output of the command
* @param exitStatus of the command
*/
public CommandResult(final String output, final int exitStatus) {
this.output = output;
this.exitStatus = exitStatus;
}
/**
* @return command output.
*/
public String getOutput() {
return output;
}
/**
* @return command exit status.
*/
public int getExitStatus() {
return exitStatus;
}
}

View File

@ -1,245 +0,0 @@
package hirs.tpm.tss.command;
import hirs.tpm.tss.Tpm;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
/**
* Implementation of a {@link Tpm} that uses the TPM_MODULE command as the interface to the TPM.
*/
public class CommandTpm implements Tpm {
private static final String TPM_COMMAND = "/usr/bin/tpm_module";
private static final String TPM_TOOLS_READ_COMMAND = "tpm_nvread";
private static final String TPM_TOOLS_INFO_COMMAND = "tpm_nvinfo";
// The fixed location of the endorsement credential (TPM 1.2 only)
private static final int EC_INDEX = 0xf000;
private static final int EC_INDEX_MASK = 0x0000ffff;
private static final String IDENTITY_LABEL = "HISIdentityKey";
@Override
public void takeOwnership() {
// take ownership if the TPM is currently unowned
try {
sendTPMCommand("-nr -m 1 -z");
} catch (CommandException ex) {
// if the error isn't that the TPM is already owned, bubble the exception up.
if (ex.getCommandResult().getExitStatus() != CommandResult.TPM_PREVIOUSLY_OWNED_ERROR) {
throw ex;
}
}
}
@Override
public byte[] getEndorsementCredentialModulus() {
return sendTPMCommand("-m 17 -z -nr -t ek").getOutput().getBytes();
}
@Override
public byte[] getEndorsementCredential() throws IOException {
File tempExtractFile = File.createTempFile("nvread-extract", ".tmp");
try {
int ecIndex = findEndorsementCredentialIndex();
int ecSize = getEndorsementCredentialSize(ecIndex);
// don't care about the stdout from this command. If the command fails, an exception
// is thrown, otherwise, read the temp file content
String argList = "-i " + ecIndex
+ " -s " + ecSize + " -z -f " + tempExtractFile.getAbsolutePath();
sendCommand(TPM_TOOLS_READ_COMMAND, argList);
return FileUtils.readFileToByteArray(tempExtractFile);
} finally {
FileUtils.deleteQuietly(tempExtractFile);
}
}
private int findEndorsementCredentialIndex() {
CommandResult command = sendCommand(TPM_TOOLS_INFO_COMMAND, "");
return parseEcIndexFromNvInfoOutput(command.getOutput());
}
/**
* Parses the output from tpm_nvinfo to find the index for the endorsement credential.
* @param commandOutput the output of the tpm_nvinfo command
* @return the index of the EC
*/
static int parseEcIndexFromNvInfoOutput(final String commandOutput) {
String[] lines = commandOutput.trim().split("\\r?\\n");
for (String line: lines) {
if (line.startsWith("NVRAM index")) {
String rawIndex = line.split(":")[1].trim();
String hexIndexStr = rawIndex.split(" ")[0];
int index = Integer.decode(hexIndexStr);
if ((EC_INDEX_MASK & index) == EC_INDEX) {
return index;
}
}
}
throw new RuntimeException("Failed to find index for EC");
}
private int getEndorsementCredentialSize(final int index) {
try {
String args = "-i " + index;
CommandResult command = sendCommand(TPM_TOOLS_INFO_COMMAND, args);
return parseNvramSizeFromNvInfoOutput(command.getOutput());
} catch (Exception ex) {
throw new RuntimeException("Failed to get EC size: ", ex);
}
}
/**
* Parses the output from tpm_nvinfo for a particular address, returning the size of the
* data at the queried address.
* @param commandOutput the output of a tpm_nvinfo -i [address] command
* @return the size at the address, as a decimal integer
*/
static int parseNvramSizeFromNvInfoOutput(final String commandOutput) {
// trim the ends and split on lines.
String[] lines = commandOutput.trim().split("\\r?\\n");
// search lines for the first "Size" line, which contains the # of bytes to
// read at the location
for (String line : lines) {
if (line.startsWith("Size")) {
String rawSizeValue = line.split(":")[1].trim();
// The value after the ":" contains the decimal and hex values.
// Parse out the decimal portion
String decimalSizeStr = rawSizeValue.split(" ")[0];
return Integer.parseInt(decimalSizeStr);
}
}
throw new RuntimeException("Failed to find size from EC's NVRAM area");
}
@Override
public byte[] collateIdentityRequest(final byte[] acaPublicKey, final String uuid) {
Assert.notNull(acaPublicKey, "acaPublicKey is null");
Assert.hasLength(uuid, "uuid must not be empty or null");
// encode the aca PK to a hex string.
String hexAcaBlob = Hex.encodeHexString(acaPublicKey);
// send the collate identity request
String request = sendTPMCommand(
String.format("-nr -z -o -m 6 -p %s -u %s -l %s -nvram -debug",
hexAcaBlob, uuid, IDENTITY_LABEL)).getOutput();
try {
// attempt to decode the response
return Hex.decodeHex(request.toCharArray());
} catch (DecoderException e) {
throw new RuntimeException(
"Encountered error decoding response from tpm_module: " + e.getMessage(), e);
}
}
@Override
public byte[] activateIdentity(final byte[] asymmetricBlob, final byte[] symmetricBlob,
final String uuid) {
Assert.notNull(asymmetricBlob, "asymmetricBlob is null");
Assert.notNull(symmetricBlob, "symmetricBlob is null");
Assert.hasLength(uuid, "uuid must not be empty or null");
// encode the blobs into hex strings
String hexAsymmetric = Hex.encodeHexString(asymmetricBlob);
String hexSymmetric = Hex.encodeHexString(symmetricBlob);
// issue the activate identity command
CommandResult result = sendTPMCommand(String.format("-asym %s -sym %s -u %s -m 7 -z - nr",
hexAsymmetric, hexSymmetric, uuid));
try {
return Hex.decodeHex(result.getOutput().toCharArray());
} catch (DecoderException e) {
throw new RuntimeException(
"Encountered error decoding response from tpm_module: " + e.getMessage(), e);
}
}
@Override
public byte[] getQuote(final String pcr, final String nonce, final String uuid) {
Assert.hasLength(pcr, "pcr must not be empty or null");
Assert.hasLength(nonce, "nonce must not be empty or null");
Assert.hasLength(uuid, "uuid must not be empty or null");
// issues the quote 2 command (-m 9) to retrieve the quote for the selected PCR (-p #).
CommandResult result =
sendTPMCommand(String.format("-m 9 -z -n %s -c -u %s -p %s", nonce, uuid, pcr));
try {
return Hex.decodeHex(result.getOutput().toCharArray());
} catch (DecoderException e) {
throw new RuntimeException(
"Encountered error decoding response from tpm_module: " + e.getMessage(), e);
}
}
private CommandResult sendTPMCommand(final String arguments) {
// always run the tpm_module with debug (-d).
// otherwise the exit status and error messages are squelched.
return sendCommand(TPM_COMMAND, "-d " + arguments);
}
/**
* Issues the specified command to the tpm_module process.
*/
private CommandResult sendCommand(final String application, final String arguments) {
String[] command = {application};
// add the specified arguments to the command
command = ArrayUtils.addAll(command, arguments.split("\\s+"));
// build up the process
ProcessBuilder processBuilder = new ProcessBuilder(command);
// merge the error stream into the standard output
processBuilder.redirectErrorStream(true);
try {
// issue the command
Process process = processBuilder.start();
// block and wait for the process to be complete
int returnCode = process.waitFor();
try (InputStream processInputStream = process.getInputStream()) {
// grab the command output
String output = IOUtils.toString(processInputStream);
// construct the command result
CommandResult result = new CommandResult(output, returnCode);
// if the command wasn't successful, generate an exception with command output
if (returnCode != 0) {
throw new CommandException(
String.format("Encountered error: %s while executing command: %s",
output, StringUtils.join(command, " ")), result);
}
return result;
}
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}

View File

@ -1,4 +0,0 @@
/**
* Defines command line interface to the TPM/TSS.
*/
package hirs.tpm.tss.command;

View File

@ -1,4 +0,0 @@
/**
* Defines high level interfaces for communicating and interacting with a TPM.
*/
package hirs.tpm.tss;

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t @ %C.%M] %-5p : %m%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="WARN">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>

View File

@ -1,68 +0,0 @@
package hirs.tpm.tss.command;
import org.testng.Assert;
import org.testng.annotations.Test;
/**
* Unit tests for {@see CommandTpm}.
*/
public class CommandTpmTest {
/**
* Tests retrieving the size given a valid output from tpm_nvinfo.
*/
@Test
public void parseSizeValid() {
final int expectedSize = 1129;
String nvInfoOutput =
"\n"
+ "NVRAM index : 0x1000f000 (268496896)\n"
+ "PCR read selection:\n"
+ " Localities : ALL\n"
+ "PCR write selection:\n"
+ " Localities : ALL\n"
+ "Permissions : 0x00020002 (OWNERREAD|OWNERWRITE)\n"
+ "bReadSTClear : FALSE\n"
+ "bWriteSTClear : FALSE\n"
+ "bWriteDefine : FALSE\n"
+ "Size : 1129 (0x469)\n"
+ "\n";
int readSize = CommandTpm.parseNvramSizeFromNvInfoOutput(nvInfoOutput);
Assert.assertEquals(readSize, expectedSize);
}
/**
* Tests failure to get the size given output from tpm_nvinfo with missing size value.
*/
@Test(expectedExceptions = RuntimeException.class)
public void parseSizeMissingSizeValue() {
String nvInfoOutput =
"\n"
+ "NVRAM index : 0x1000f000 (268496896)\n"
+ "PCR read selection:\n"
+ " Localities : ALL\n"
+ "PCR write selection:\n"
+ " Localities : ALL\n"
+ "Permissions : 0x00020002 (OWNERREAD|OWNERWRITE)\n"
+ "bReadSTClear : FALSE\n"
+ "bWriteSTClear : FALSE\n"
+ "bWriteDefine : FALSE\n"
+ "Strength : 1129 (0x469)\n"
+ "\n";
CommandTpm.parseNvramSizeFromNvInfoOutput(nvInfoOutput);
}
/**
* Tests failure to get the EC size given a completely garbage tpm_nvifo output.
*/
@Test(expectedExceptions = RuntimeException.class)
public void parseSizeBadOutput() {
String nvInfoOutput = "bad data here. FAILURE TO READ SOMETHING!";
CommandTpm.parseNvramSizeFromNvInfoOutput(nvInfoOutput);
}
}

View File

@ -1,4 +0,0 @@
/**
* Tests for the TPM command classes.
*/
package hirs.tpm.tss.command;